summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/compiler/translator/Symbol.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src/compiler/translator/Symbol.h')
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Symbol.h402
1 files changed, 402 insertions, 0 deletions
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<TExtension, 3u> &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<TExtension, 3u> extensions() const { return mExtensions; }
+
+ template <size_t ExtensionCount>
+ constexpr const std::array<TExtension, 3u> CreateExtensionList(
+ const std::array<TExtension, ExtensionCount> &extensions)
+ {
+ switch (extensions.size())
+ {
+ case 1:
+ return std::array<TExtension, 3u>{
+ {extensions[0], TExtension::UNDEFINED, TExtension::UNDEFINED}};
+ case 2:
+ return std::array<TExtension, 3u>{
+ {extensions[0], extensions[1], TExtension::UNDEFINED}};
+ case 3:
+ return std::array<TExtension, 3u>{{extensions[0], extensions[1], extensions[2]}};
+ default:
+ UNREACHABLE();
+ return std::array<TExtension, 3u>{
+ {TExtension::UNDEFINED, TExtension::UNDEFINED, TExtension::UNDEFINED}};
+ }
+ }
+
+ protected:
+ template <size_t ExtensionCount>
+ constexpr TSymbol(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ SymbolType symbolType,
+ const std::array<TExtension, ExtensionCount> &extensions,
+ SymbolClass symbolClass)
+ : mName(name),
+ mUniqueId(id),
+ mExtensions(CreateExtensionList(extensions)),
+ mSymbolType(symbolType),
+ mSymbolClass(symbolClass)
+ {}
+
+ const ImmutableString mName;
+
+ private:
+ const TSymbolUniqueId mUniqueId;
+ const std::array<TExtension, 3u> 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<TExtension, 3u> &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<TExtension, 1u>{{extension}},
+ SymbolClass::Variable),
+ mType(type),
+ unionArray(nullptr)
+ {}
+
+ template <size_t ExtensionCount>
+ constexpr TVariable(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ SymbolType symbolType,
+ const std::array<TExtension, ExtensionCount> &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<const TVariable *> *outputSymbols,
+ TMap<const TVariable *, TString> *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<TExtension, 1u>{{extension}},
+ SymbolClass::Struct),
+ TFieldListCollection(fields)
+ {}
+
+ template <size_t ExtensionCount>
+ TStructure(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ const std::array<TExtension, ExtensionCount> &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<TExtension, 3u> &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<TExtension, 1u>{{extension}},
+ SymbolClass::InterfaceBlock),
+ TFieldListCollection(fields),
+ mBlockStorage(EbsUnspecified),
+ mBinding(0)
+ {}
+
+ template <size_t ExtensionCount>
+ TInterfaceBlock(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ const std::array<TExtension, ExtensionCount> &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 &parametersSource);
+
+ 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<TExtension, 1u>{{extension}},
+ SymbolClass::Function),
+ mParametersVector(nullptr),
+ mParameters(parameters),
+ returnType(retType),
+ mMangledName(nullptr),
+ mParamCount(paramCount),
+ mOp(op),
+ defined(false),
+ mHasPrototypeDeclaration(false),
+ mKnownToNotHaveSideEffects(knownToNotHaveSideEffects),
+ mHasVoidParameter(false)
+ {}
+
+ template <size_t ExtensionCount>
+ constexpr TFunction(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ const std::array<TExtension, ExtensionCount> &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<const TVariable *> 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_