Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  SkSLVariable.cpp   Sprache: C

 
/*
 * Copyright 2021 Google LLC.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#include "src/sksl/ir/SkSLVariable.h"

#include "src/base/SkEnumBitMask.h"
#include "src/base/SkStringView.h"
#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/SkSLContext.h"
#include "src/sksl/SkSLErrorReporter.h"
#include "src/sksl/SkSLIntrinsicList.h"
#include "src/sksl/SkSLMangler.h"
#include "src/sksl/SkSLProgramSettings.h"
#include "src/sksl/ir/SkSLExpression.h"
#include "src/sksl/ir/SkSLIRNode.h"
#include "src/sksl/ir/SkSLInterfaceBlock.h"
#include "src/sksl/ir/SkSLLayout.h"
#include "src/sksl/ir/SkSLSymbolTable.h"
#include "src/sksl/ir/SkSLVarDeclarations.h"

#include <utility>

namespace SkSL {

static constexpr Layout kDefaultLayout;

Variable::~Variable() {
    // Unhook this Variable from its associated VarDeclaration, since we're being deleted.
    if (VarDeclaration* declaration = this->varDeclaration()) {
        declaration->detachDeadVariable();
    }
}

ExtendedVariable::~ExtendedVariable() {
    // Unhook this Variable from its associated InterfaceBlock, since we're being deleted.
    if (fInterfaceBlockElement) {
        fInterfaceBlockElement->detachDeadVariable();
    }
}

const Expression* Variable::initialValue() const {
    VarDeclaration* declaration = this->varDeclaration();
    return declaration ? declaration->value().get() : nullptr;
}

VarDeclaration* Variable::varDeclaration() const {
    if (!fDeclaringElement) {
        return nullptr;
    }
    SkASSERT(fDeclaringElement->is<VarDeclaration>() ||
             fDeclaringElement->is<GlobalVarDeclaration>());
    return fDeclaringElement->is<GlobalVarDeclaration>()
               ? &fDeclaringElement->as<GlobalVarDeclaration>().varDeclaration()
               : &fDeclaringElement->as<VarDeclaration>();
}

GlobalVarDeclaration* Variable::globalVarDeclaration() const {
    if (!fDeclaringElement) {
        return nullptr;
    }
    SkASSERT(fDeclaringElement->is<VarDeclaration>() ||
             fDeclaringElement->is<GlobalVarDeclaration>());
    return fDeclaringElement->is<GlobalVarDeclaration>()
               ? &fDeclaringElement->as<GlobalVarDeclaration>()
               : nullptr;
}

void Variable::setVarDeclaration(VarDeclaration* declaration) {
    SkASSERT(!fDeclaringElement || this == declaration->var());
    if (!fDeclaringElement) {
        fDeclaringElement = declaration;
    }
}

void Variable::setGlobalVarDeclaration(GlobalVarDeclaration* global) {
    SkASSERT(!fDeclaringElement || this == global->varDeclaration().var());
    fDeclaringElement = global;
}

const Layout& Variable::layout() const {
    return kDefaultLayout;
}

std::string_view ExtendedVariable::mangledName() const {
    return fMangledName.empty() ? this->name() : fMangledName;
}

std::unique_ptr<Variable> Variable::Convert(const Context& context,
                                            Position pos,
                                            Position modifiersPos,
                                            const Layout& layout,
                                            ModifierFlags flags,
                                            const Type* type,
                                            Position namePos,
                                            std::string_view name,
                                            Storage storage) {
    if (layout.fLocation == 0 &&
        layout.fIndex == 0 &&
        (flags & ModifierFlag::kOut) &&
        ProgramConfig::IsFragment(context.fConfig->fKind) &&
        name != Compiler::FRAGCOLOR_NAME) {
        context.fErrors->error(modifiersPos,
                               "out location=0, index=0 is reserved for sk_FragColor");
    }
    if (type->isUnsizedArray() && storage != Variable::Storage::kInterfaceBlock
                               && storage != Variable::Storage::kParameter) {
        context.fErrors->error(pos, "unsized arrays are not permitted here");
    }
    if (ProgramConfig::IsCompute(context.fConfig->fKind) && layout.fBuiltin == -1) {
        if (storage == Variable::Storage::kGlobal) {
            if (flags & ModifierFlag::kIn) {
                context.fErrors->error(pos, "pipeline inputs not permitted in compute shaders");
            } else if (flags & ModifierFlag::kOut) {
                context.fErrors->error(pos, "pipeline outputs not permitted in compute shaders");
            }
        }
    }
    if (storage == Variable::Storage::kParameter) {
        // The `in` modifier on function parameters is implicit, so we can replace `in float x` with
        // `float x`. This prevents any ambiguity when matching a function by its param types.
        if ((flags & (ModifierFlag::kOut | ModifierFlag::kIn)) == ModifierFlag::kIn) {
            flags &= ~(ModifierFlag::kOut | ModifierFlag::kIn);
        }
    }

    // Invent a mangled name for the variable, if it needs one.
    std::string mangledName;
    if (skstd::starts_with(name, '$')) {
        // The $ prefix will fail to compile in GLSL, so replace it with `sk_Priv`.
        mangledName = "sk_Priv" + std::string(name.substr(1));
    } else if (FindIntrinsicKind(name) != kNotIntrinsic) {
        // Having a variable name overlap an intrinsic name will prevent us from calling the
        // intrinsic, but it's not illegal for user names to shadow a global symbol.
        // Mangle the name to avoid a possible collision.
        mangledName = Mangler{}.uniqueName(name, context.fSymbolTable);
    }

    return Make(pos, modifiersPos, layout, flags, type, name, std::move(mangledName),
                context.fConfig->isBuiltinCode(), storage);
}

std::unique_ptr<Variable> Variable::Make(Position pos,
                                         Position modifiersPosition,
                                         const Layout& layout,
                                         ModifierFlags flags,
                                         const Type* type,
                                         std::string_view name,
                                         std::string mangledName,
                                         bool builtin,
                                         Variable::Storage storage) {
    // the `in` modifier on function parameters is implicit and should have been removed
    SkASSERT(!(storage == Variable::Storage::kParameter &&
               (flags & (ModifierFlag::kOut | ModifierFlag::kIn)) == ModifierFlag::kIn));

    if (type->componentType().isInterfaceBlock() || !mangledName.empty() ||
        layout != kDefaultLayout) {
        return std::make_unique<ExtendedVariable>(pos,
                                                  modifiersPosition,
                                                  layout,
                                                  flags,
                                                  name,
                                                  type,
                                                  builtin,
                                                  storage,
                                                  std::move(mangledName));
    } else {
        return std::make_unique<Variable>(pos,
                                          modifiersPosition,
                                          flags,
                                          name,
                                          type,
                                          builtin,
                                          storage);
    }
}

Variable::ScratchVariable Variable::MakeScratchVariable(const Context& context,
                                                        Mangler& mangler,
                                                        std::string_view baseName,
                                                        const Type* type,
                                                        SymbolTable* symbolTable,
                                                        std::unique_ptr<Expression> initialValue) {
    // $floatLiteral or $intLiteral aren't real types that we can use for scratch variables, so
    // replace them if they ever appear here. If this happens, we likely forgot to coerce a type
    // somewhere during compilation.
    if (type->isLiteral()) {
        SkDEBUGFAIL("found a $literal type in MakeScratchVariable");
        type = &type->scalarTypeForLiteral();
    }

    // Provide our new variable with a unique name, and add it to our symbol table.
    const std::string* name =
            symbolTable->takeOwnershipOfString(mangler.uniqueName(baseName, symbolTable));

    // Create our new variable and add it to the symbol table.
    ScratchVariable result;
    auto var = std::make_unique<Variable>(initialValue ? initialValue->fPosition : Position(),
                                          /*modifiersPosition=*/Position(),
                                          ModifierFlag::kNone,
                                          name->c_str(),
                                          type,
                                          symbolTable->isBuiltin(),
                                          Variable::Storage::kLocal);

    // If we are creating an array type, reduce it to base type plus array-size.
    int arraySize = 0;
    if (type->isArray()) {
        arraySize = type->columns();
        type = &type->componentType();
    }
    // Create our variable declaration.
    result.fVarDecl = VarDeclaration::Make(context, var.get(), type, arraySize,
                                           std::move(initialValue));
    result.fVarSymbol = symbolTable->add(context, std::move(var));
    return result;
}

// namespace SkSL

Messung V0.5
C=89 H=91 G=89

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge