From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- .../checkout/src/compiler/translator/Symbol.h | 402 +++++++++++++++++++++ 1 file changed, 402 insertions(+) create mode 100644 gfx/angle/checkout/src/compiler/translator/Symbol.h (limited to 'gfx/angle/checkout/src/compiler/translator/Symbol.h') diff --git a/gfx/angle/checkout/src/compiler/translator/Symbol.h b/gfx/angle/checkout/src/compiler/translator/Symbol.h new file mode 100644 index 0000000000..cb34306be8 --- /dev/null +++ b/gfx/angle/checkout/src/compiler/translator/Symbol.h @@ -0,0 +1,402 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Symbol.h: Symbols representing variables, functions, structures and interface blocks. +// + +#ifndef COMPILER_TRANSLATOR_SYMBOL_H_ +#define COMPILER_TRANSLATOR_SYMBOL_H_ + +#include "common/angleutils.h" +#include "compiler/translator/ExtensionBehavior.h" +#include "compiler/translator/ImmutableString.h" +#include "compiler/translator/IntermNode.h" +#include "compiler/translator/SymbolUniqueId.h" + +namespace sh +{ + +class TSymbolTable; + +// Symbol base class. (Can build functions or variables out of these...) +class TSymbol : angle::NonCopyable +{ + public: + POOL_ALLOCATOR_NEW_DELETE + TSymbol(TSymbolTable *symbolTable, + const ImmutableString &name, + SymbolType symbolType, + SymbolClass symbolClass, + TExtension extension = TExtension::UNDEFINED); + + TSymbol(TSymbolTable *symbolTable, + const ImmutableString &name, + SymbolType symbolType, + SymbolClass symbolClass, + const std::array &extensions); + + // Note that we can't have a virtual destructor in order to support constexpr symbols. Data is + // either statically allocated or pool allocated. + ~TSymbol() = default; + + // Calling name() for empty symbols (symbolType == SymbolType::Empty) generates a similar name + // as for internal variables. + ImmutableString name() const; + // Don't call getMangledName() for empty symbols (symbolType == SymbolType::Empty). + ImmutableString getMangledName() const; + + bool isFunction() const { return mSymbolClass == SymbolClass::Function; } + bool isVariable() const { return mSymbolClass == SymbolClass::Variable; } + bool isStruct() const { return mSymbolClass == SymbolClass::Struct; } + bool isInterfaceBlock() const { return mSymbolClass == SymbolClass::InterfaceBlock; } + + const TSymbolUniqueId &uniqueId() const { return mUniqueId; } + SymbolType symbolType() const { return mSymbolType; } + const std::array extensions() const { return mExtensions; } + + template + constexpr const std::array CreateExtensionList( + const std::array &extensions) + { + switch (extensions.size()) + { + case 1: + return std::array{ + {extensions[0], TExtension::UNDEFINED, TExtension::UNDEFINED}}; + case 2: + return std::array{ + {extensions[0], extensions[1], TExtension::UNDEFINED}}; + case 3: + return std::array{{extensions[0], extensions[1], extensions[2]}}; + default: + UNREACHABLE(); + return std::array{ + {TExtension::UNDEFINED, TExtension::UNDEFINED, TExtension::UNDEFINED}}; + } + } + + protected: + template + constexpr TSymbol(const TSymbolUniqueId &id, + const ImmutableString &name, + SymbolType symbolType, + const std::array &extensions, + SymbolClass symbolClass) + : mName(name), + mUniqueId(id), + mExtensions(CreateExtensionList(extensions)), + mSymbolType(symbolType), + mSymbolClass(symbolClass) + {} + + const ImmutableString mName; + + private: + const TSymbolUniqueId mUniqueId; + const std::array mExtensions; + const SymbolType mSymbolType : 4; + + // We use this instead of having virtual functions for querying the class in order to support + // constexpr symbols. + const SymbolClass mSymbolClass : 4; +}; + +static_assert(sizeof(TSymbol) <= 24, "Size check failed"); + +// Variable. +// May store the value of a constant variable of any type (float, int, bool or struct). +class TVariable : public TSymbol +{ + public: + TVariable(TSymbolTable *symbolTable, + const ImmutableString &name, + const TType *type, + SymbolType symbolType, + TExtension ext = TExtension::UNDEFINED); + + TVariable(TSymbolTable *symbolTable, + const ImmutableString &name, + const TType *type, + SymbolType symbolType, + const std::array &extensions); + + const TType &getType() const { return *mType; } + + const TConstantUnion *getConstPointer() const { return unionArray; } + + void shareConstPointer(const TConstantUnion *constArray) { unionArray = constArray; } + + // Note: only to be used for built-in variables with autogenerated ids! + constexpr TVariable(const TSymbolUniqueId &id, + const ImmutableString &name, + SymbolType symbolType, + TExtension extension, + const TType *type) + : TSymbol(id, + name, + symbolType, + std::array{{extension}}, + SymbolClass::Variable), + mType(type), + unionArray(nullptr) + {} + + template + constexpr TVariable(const TSymbolUniqueId &id, + const ImmutableString &name, + SymbolType symbolType, + const std::array &extensions, + const TType *type) + : TSymbol(id, name, symbolType, extensions, SymbolClass::Variable), + mType(type), + unionArray(nullptr) + {} + + private: + const TType *mType; + const TConstantUnion *unionArray; +}; + +// Struct type. +class TStructure : public TSymbol, public TFieldListCollection +{ + public: + TStructure(TSymbolTable *symbolTable, + const ImmutableString &name, + const TFieldList *fields, + SymbolType symbolType); + + // The char arrays passed in must be pool allocated or static. + void createSamplerSymbols(const char *namePrefix, + const TString &apiNamePrefix, + TVector *outputSymbols, + TMap *outputSymbolsToAPINames, + TSymbolTable *symbolTable) const; + + void setAtGlobalScope(bool atGlobalScope) { mAtGlobalScope = atGlobalScope; } + bool atGlobalScope() const { return mAtGlobalScope; } + + private: + friend class TSymbolTable; + // For creating built-in structs. + TStructure(const TSymbolUniqueId &id, + const ImmutableString &name, + TExtension extension, + const TFieldList *fields) + : TSymbol(id, + name, + SymbolType::BuiltIn, + std::array{{extension}}, + SymbolClass::Struct), + TFieldListCollection(fields) + {} + + template + TStructure(const TSymbolUniqueId &id, + const ImmutableString &name, + const std::array &extensions, + const TFieldList *fields) + : TSymbol(id, name, SymbolType::BuiltIn, extensions, SymbolClass::Struct), + TFieldListCollection(fields) + {} + + // TODO(zmo): Find a way to get rid of the const_cast in function + // setName(). At the moment keep this function private so only + // friend class RegenerateStructNames may call it. + friend class RegenerateStructNamesTraverser; + void setName(const ImmutableString &name); + + bool mAtGlobalScope; +}; + +// Interface block. Note that this contains the block name, not the instance name. Interface block +// instances are stored as TVariable. +class TInterfaceBlock : public TSymbol, public TFieldListCollection +{ + public: + TInterfaceBlock(TSymbolTable *symbolTable, + const ImmutableString &name, + const TFieldList *fields, + const TLayoutQualifier &layoutQualifier, + SymbolType symbolType, + TExtension extension = TExtension::UNDEFINED); + + TInterfaceBlock(TSymbolTable *symbolTable, + const ImmutableString &name, + const TFieldList *fields, + const TLayoutQualifier &layoutQualifier, + SymbolType symbolType, + const std::array &extensions); + + TLayoutBlockStorage blockStorage() const { return mBlockStorage; } + int blockBinding() const { return mBinding; } + + private: + friend class TSymbolTable; + // For creating built-in interface blocks. + TInterfaceBlock(const TSymbolUniqueId &id, + const ImmutableString &name, + TExtension extension, + const TFieldList *fields) + : TSymbol(id, + name, + SymbolType::BuiltIn, + std::array{{extension}}, + SymbolClass::InterfaceBlock), + TFieldListCollection(fields), + mBlockStorage(EbsUnspecified), + mBinding(0) + {} + + template + TInterfaceBlock(const TSymbolUniqueId &id, + const ImmutableString &name, + const std::array &extensions, + const TFieldList *fields) + : TSymbol(id, name, SymbolType::BuiltIn, extensions, SymbolClass::InterfaceBlock), + TFieldListCollection(fields), + mBlockStorage(EbsUnspecified), + mBinding(0) + {} + + TLayoutBlockStorage mBlockStorage; + int mBinding; + + // Note that we only record matrix packing on a per-field granularity. +}; + +// Parameter class used for parsing user-defined function parameters. +struct TParameter +{ + // Destructively converts to TVariable. + // This method resets name and type to nullptrs to make sure + // their content cannot be modified after the call. + const TVariable *createVariable(TSymbolTable *symbolTable) + { + const ImmutableString constName(name); + const TType *constType = type; + name = nullptr; + type = nullptr; + return new TVariable(symbolTable, constName, constType, + constName.empty() ? SymbolType::Empty : SymbolType::UserDefined); + } + + const char *name; // either pool allocated or static. + TType *type; +}; + +// The function sub-class of a symbol. +class TFunction : public TSymbol +{ + public: + // User-defined function + TFunction(TSymbolTable *symbolTable, + const ImmutableString &name, + SymbolType symbolType, + const TType *retType, + bool knownToNotHaveSideEffects); + + void addParameter(const TVariable *p); + void shareParameters(const TFunction ¶metersSource); + + ImmutableString getFunctionMangledName() const + { + ASSERT(symbolType() != SymbolType::BuiltIn); + if (mMangledName.empty()) + { + mMangledName = buildMangledName(); + } + return mMangledName; + } + + const TType &getReturnType() const { return *returnType; } + + TOperator getBuiltInOp() const { return mOp; } + + void setDefined() { defined = true; } + bool isDefined() const { return defined; } + void setHasPrototypeDeclaration() { mHasPrototypeDeclaration = true; } + bool hasPrototypeDeclaration() const { return mHasPrototypeDeclaration; } + void setHasVoidParameter() { mHasVoidParameter = true; } + bool hasVoidParameter() const { return mHasVoidParameter; } + + size_t getParamCount() const { return mParamCount; } + const TVariable *getParam(size_t i) const { return mParameters[i]; } + + bool isKnownToNotHaveSideEffects() const { return mKnownToNotHaveSideEffects; } + + bool isMain() const; + bool isImageFunction() const; + bool isAtomicCounterFunction() const; + + // Note: Only to be used for static built-in functions! + constexpr TFunction(const TSymbolUniqueId &id, + const ImmutableString &name, + TExtension extension, + const TVariable *const *parameters, + size_t paramCount, + const TType *retType, + TOperator op, + bool knownToNotHaveSideEffects) + : TSymbol(id, + name, + SymbolType::BuiltIn, + std::array{{extension}}, + SymbolClass::Function), + mParametersVector(nullptr), + mParameters(parameters), + returnType(retType), + mMangledName(nullptr), + mParamCount(paramCount), + mOp(op), + defined(false), + mHasPrototypeDeclaration(false), + mKnownToNotHaveSideEffects(knownToNotHaveSideEffects), + mHasVoidParameter(false) + {} + + template + constexpr TFunction(const TSymbolUniqueId &id, + const ImmutableString &name, + const std::array &extensions, + const TVariable *const *parameters, + size_t paramCount, + const TType *retType, + TOperator op, + bool knownToNotHaveSideEffects) + : TSymbol(id, name, SymbolType::BuiltIn, extensions, SymbolClass::Function), + mParametersVector(nullptr), + mParameters(parameters), + returnType(retType), + mMangledName(nullptr), + mParamCount(paramCount), + mOp(op), + defined(false), + mHasPrototypeDeclaration(false), + mKnownToNotHaveSideEffects(knownToNotHaveSideEffects), + mHasVoidParameter(false) + {} + + private: + ImmutableString buildMangledName() const; + + typedef TVector TParamVector; + TParamVector *mParametersVector; + const TVariable *const *mParameters; + const TType *const returnType; + mutable ImmutableString mMangledName; + size_t mParamCount : 32; + const TOperator mOp; // Only set for built-ins + bool defined : 1; + bool mHasPrototypeDeclaration : 1; + bool mKnownToNotHaveSideEffects : 1; + // Whether the parameter list of the function starts with void. This is used to generate an + // error if any other parameter follows. + bool mHasVoidParameter : 1; +}; + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_SYMBOL_H_ -- cgit v1.2.3