diff options
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/SymbolTable.h')
-rw-r--r-- | src/3rdparty/angle/src/compiler/translator/SymbolTable.h | 455 |
1 files changed, 251 insertions, 204 deletions
diff --git a/src/3rdparty/angle/src/compiler/translator/SymbolTable.h b/src/3rdparty/angle/src/compiler/translator/SymbolTable.h index 6c7211f2a9..d3ddf19e34 100644 --- a/src/3rdparty/angle/src/compiler/translator/SymbolTable.h +++ b/src/3rdparty/angle/src/compiler/translator/SymbolTable.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2014 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. // @@ -36,34 +36,62 @@ #include "compiler/translator/InfoSink.h" #include "compiler/translator/intermediate.h" -// -// Symbol base class. (Can build functions or variables out of these...) -// -class TSymbol { -public: +// Symbol base class. (Can build functions or variables out of these...) +class TSymbol +{ + public: POOL_ALLOCATOR_NEW_DELETE(); - TSymbol(const TString* n) : uniqueId(0), name(n) { } - virtual ~TSymbol() { /* don't delete name, it's from the pool */ } - - const TString& getName() const { return *name; } - virtual const TString& getMangledName() const { return getName(); } - virtual bool isFunction() const { return false; } - virtual bool isVariable() const { return false; } - void setUniqueId(int id) { uniqueId = id; } - int getUniqueId() const { return uniqueId; } - virtual void dump(TInfoSink &infoSink) const = 0; - void relateToExtension(const TString& ext) { extension = ext; } - const TString& getExtension() const { return extension; } - -private: + TSymbol(const TString *n) + : uniqueId(0), + name(n) + { + } + virtual ~TSymbol() + { + // don't delete name, it's from the pool + } + + const TString &getName() const + { + return *name; + } + virtual const TString &getMangledName() const + { + return getName(); + } + virtual bool isFunction() const + { + return false; + } + virtual bool isVariable() const + { + return false; + } + void setUniqueId(int id) + { + uniqueId = id; + } + int getUniqueId() const + { + return uniqueId; + } + void relateToExtension(const TString &ext) + { + extension = ext; + } + const TString &getExtension() const + { + return extension; + } + + private: DISALLOW_COPY_AND_ASSIGN(TSymbol); - int uniqueId; // For real comparing during code generation + int uniqueId; // For real comparing during code generation const TString *name; TString extension; }; -// // Variable class, meaning a symbol that's not a function. // // There could be a separate class heirarchy for Constant variables; @@ -72,20 +100,41 @@ private: // seem worth having separate classes, and "getConst" can't simply return // different values for different types polymorphically, so this is // just simple and pragmatic. -// -class TVariable : public TSymbol { -public: - TVariable(const TString *name, const TType& t, bool uT = false ) : TSymbol(name), type(t), userType(uT), unionArray(0) { } - virtual ~TVariable() { } - virtual bool isVariable() const { return true; } - TType& getType() { return type; } - const TType& getType() const { return type; } - bool isUserType() const { return userType; } - void setQualifier(TQualifier qualifier) { type.setQualifier(qualifier); } - - virtual void dump(TInfoSink &infoSink) const; - - ConstantUnion* getConstPointer() +class TVariable : public TSymbol +{ + public: + TVariable(const TString *name, const TType &t, bool uT = false) + : TSymbol(name), + type(t), + userType(uT), + unionArray(0) + { + } + virtual ~TVariable() + { + } + virtual bool isVariable() const + { + return true; + } + TType &getType() + { + return type; + } + const TType &getType() const + { + return type; + } + bool isUserType() const + { + return userType; + } + void setQualifier(TQualifier qualifier) + { + type.setQualifier(qualifier); + } + + ConstantUnion *getConstPointer() { if (!unionArray) unionArray = new ConstantUnion[type.getObjectSize()]; @@ -93,9 +142,12 @@ public: return unionArray; } - ConstantUnion* getConstPointer() const { return unionArray; } + ConstantUnion *getConstPointer() const + { + return unionArray; + } - void shareConstPointer( ConstantUnion *constArray) + void shareConstPointer(ConstantUnion *constArray) { if (unionArray == constArray) return; @@ -104,71 +156,101 @@ public: unionArray = constArray; } -private: + private: DISALLOW_COPY_AND_ASSIGN(TVariable); TType type; bool userType; - // we are assuming that Pool Allocator will free the memory allocated to unionArray - // when this object is destroyed + // we are assuming that Pool Allocator will free the memory + // allocated to unionArray when this object is destroyed. ConstantUnion *unionArray; }; -// // The function sub-class of symbols and the parser will need to // share this definition of a function parameter. -// -struct TParameter { +struct TParameter +{ TString *name; - TType* type; + TType *type; }; -// // The function sub-class of a symbol. -// -class TFunction : public TSymbol { -public: - TFunction(TOperator o) : - TSymbol(0), - returnType(TType(EbtVoid, EbpUndefined)), - op(o), - defined(false) { } - TFunction(const TString *name, TType& retType, TOperator tOp = EOpNull) : - TSymbol(name), - returnType(retType), - mangledName(TFunction::mangleName(*name)), - op(tOp), - defined(false) { } +class TFunction : public TSymbol +{ + public: + TFunction(TOperator o) + : TSymbol(0), + returnType(TType(EbtVoid, EbpUndefined)), + op(o), + defined(false) + { + } + TFunction(const TString *name, const TType &retType, TOperator tOp = EOpNull) + : TSymbol(name), + returnType(retType), + mangledName(TFunction::mangleName(*name)), + op(tOp), + defined(false) + { + } virtual ~TFunction(); - virtual bool isFunction() const { return true; } + virtual bool isFunction() const + { + return true; + } - static TString mangleName(const TString& name) { return name + '('; } - static TString unmangleName(const TString& mangledName) + static TString mangleName(const TString &name) + { + return name + '('; + } + static TString unmangleName(const TString &mangledName) { return TString(mangledName.c_str(), mangledName.find_first_of('(')); } - void addParameter(TParameter& p) + void addParameter(TParameter &p) { parameters.push_back(p); mangledName = mangledName + p.type->getMangledName(); } - const TString& getMangledName() const { return mangledName; } - const TType& getReturnType() const { return returnType; } - - void relateToOperator(TOperator o) { op = o; } - TOperator getBuiltInOp() const { return op; } + const TString &getMangledName() const + { + return mangledName; + } + const TType &getReturnType() const + { + return returnType; + } - void setDefined() { defined = true; } - bool isDefined() { return defined; } + void relateToOperator(TOperator o) + { + op = o; + } + TOperator getBuiltInOp() const + { + return op; + } - size_t getParamCount() const { return parameters.size(); } - const TParameter& getParam(size_t i) const { return parameters[i]; } + void setDefined() + { + defined = true; + } + bool isDefined() + { + return defined; + } - virtual void dump(TInfoSink &infoSink) const; + size_t getParamCount() const + { + return parameters.size(); + } + const TParameter &getParam(size_t i) const + { + return parameters[i]; + } -private: + private: DISALLOW_COPY_AND_ASSIGN(TFunction); typedef TVector<TParameter> TParamList; @@ -179,79 +261,80 @@ private: bool defined; }; - -class TSymbolTableLevel { -public: - typedef TMap<TString, TSymbol*> tLevel; - typedef tLevel::const_iterator const_iterator; - typedef const tLevel::value_type tLevelPair; - typedef std::pair<tLevel::iterator, bool> tInsertResult; - - TSymbolTableLevel() { } - ~TSymbolTableLevel(); - - bool insert(const TString &name, TSymbol &symbol) +// Interface block name sub-symbol +class TInterfaceBlockName : public TSymbol +{ + public: + TInterfaceBlockName(const TString *name) + : TSymbol(name) { - // - // returning true means symbol was added to the table - // - tInsertResult result = level.insert(tLevelPair(name, &symbol)); - - return result.second; } - bool insert(TSymbol &symbol) + virtual ~TInterfaceBlockName() { - return insert(symbol.getMangledName(), symbol); } +}; - TSymbol* find(const TString& name) const - { - tLevel::const_iterator it = level.find(name); - if (it == level.end()) - return 0; - else - return (*it).second; - } +class TSymbolTableLevel +{ + public: + typedef TMap<TString, TSymbol *> tLevel; + typedef tLevel::const_iterator const_iterator; + typedef const tLevel::value_type tLevelPair; + typedef std::pair<tLevel::iterator, bool> tInsertResult; - const_iterator begin() const + TSymbolTableLevel() { - return level.begin(); } + ~TSymbolTableLevel(); - const_iterator end() const - { - return level.end(); - } + bool insert(TSymbol *symbol); - void relateToOperator(const char* name, TOperator op); - void relateToExtension(const char* name, const TString& ext); - void dump(TInfoSink &infoSink) const; + TSymbol *find(const TString &name) const; -protected: + void relateToOperator(const char *name, TOperator op); + void relateToExtension(const char *name, const TString &ext); + + protected: tLevel level; }; -class TSymbolTable { -public: - TSymbolTable() : uniqueId(0) +enum ESymbolLevel +{ + COMMON_BUILTINS = 0, + ESSL1_BUILTINS = 1, + ESSL3_BUILTINS = 2, + LAST_BUILTIN_LEVEL = ESSL3_BUILTINS, + GLOBAL_LEVEL = 3 +}; + +class TSymbolTable +{ + public: + TSymbolTable() { - // // The symbol table cannot be used until push() is called, but // the lack of an initial call to push() can be used to detect // that the symbol table has not been preloaded with built-ins. - // } + ~TSymbolTable(); - // // When the symbol table is initialized with the built-ins, there should // 'push' calls, so that built-ins are at level 0 and the shader // globals are at level 1. - // - bool isEmpty() { return table.size() == 0; } - bool atBuiltInLevel() { return table.size() == 1; } - bool atGlobalLevel() { return table.size() <= 2; } + bool isEmpty() + { + return table.empty(); + } + bool atBuiltInLevel() + { + return currentLevel() <= LAST_BUILTIN_LEVEL; + } + bool atGlobalLevel() + { + return currentLevel() <= GLOBAL_LEVEL; + } void push() { table.push_back(new TSymbolTableLevel); @@ -267,116 +350,80 @@ public: precisionStack.pop_back(); } - bool insert(TSymbol& symbol) + bool declare(TSymbol *symbol) { - symbol.setUniqueId(++uniqueId); - return table[currentLevel()]->insert(symbol); + return insert(currentLevel(), symbol); } - bool insertConstInt(const char *name, int value) + bool insert(ESymbolLevel level, TSymbol *symbol) { - TVariable *constant = new TVariable(NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1)); - constant->getConstPointer()->setIConst(value); - return insert(*constant); + return table[level]->insert(symbol); } - bool insertBuiltIn(TType *rvalue, const char *name, TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0) + bool insertConstInt(ESymbolLevel level, const char *name, int value) { - TFunction *function = new TFunction(NewPoolTString(name), *rvalue); - - TParameter param1 = {NULL, ptype1}; - function->addParameter(param1); - - if(ptype2) - { - TParameter param2 = {NULL, ptype2}; - function->addParameter(param2); - } - - if(ptype3) - { - TParameter param3 = {NULL, ptype3}; - function->addParameter(param3); - } - - return insert(*function); + TVariable *constant = new TVariable( + NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1)); + constant->getConstPointer()->setIConst(value); + return insert(level, constant); } - TSymbol* find(const TString& name, bool* builtIn = 0, bool *sameScope = 0) - { - int level = currentLevel(); - TSymbol* symbol; - do { - symbol = table[level]->find(name); - --level; - } while (symbol == 0 && level >= 0); - level++; - if (builtIn) - *builtIn = level == 0; - if (sameScope) - *sameScope = level == currentLevel(); - return symbol; - } + void insertBuiltIn(ESymbolLevel level, TType *rvalue, const char *name, + TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, + TType *ptype4 = 0, TType *ptype5 = 0); - TSymbol* findBuiltIn(const TString &name) + TSymbol *find(const TString &name, int shaderVersion, + bool *builtIn = NULL, bool *sameScope = NULL); + TSymbol *findBuiltIn(const TString &name, int shaderVersion); + + TSymbolTableLevel *getOuterLevel() { - return table[0]->find(name); - } - - TSymbolTableLevel* getOuterLevel() { - assert(table.size() >= 2); + assert(currentLevel() >= 1); return table[currentLevel() - 1]; } - void relateToOperator(const char* name, TOperator op) { - table[0]->relateToOperator(name, op); + void relateToOperator(ESymbolLevel level, const char *name, TOperator op) + { + table[level]->relateToOperator(name, op); } - void relateToExtension(const char* name, const TString& ext) { - table[0]->relateToExtension(name, ext); + void relateToExtension(ESymbolLevel level, const char *name, const TString &ext) + { + table[level]->relateToExtension(name, ext); } void dump(TInfoSink &infoSink) const; - bool setDefaultPrecision(const TPublicType& type, TPrecision prec) { - if (!supportsPrecision(type.type)) + bool setDefaultPrecision(const TPublicType &type, TPrecision prec) + { + if (!SupportsPrecision(type.type)) return false; - if (type.size != 1 || type.matrix || type.array) + if (type.isAggregate()) return false; // Not allowed to set for aggregate types int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1; - (*precisionStack[indexOfLastElement])[type.type] = prec; // Uses map operator [], overwrites the current value + // Uses map operator [], overwrites the current value + (*precisionStack[indexOfLastElement])[type.type] = prec; return true; } - // Searches down the precisionStack for a precision qualifier for the specified TBasicType - TPrecision getDefaultPrecision(TBasicType type) { - if (!supportsPrecision(type)) - return EbpUndefined; - int level = static_cast<int>(precisionStack.size()) - 1; - assert(level >= 0); // Just to be safe. Should not happen. - PrecisionStackLevel::iterator it; - TPrecision prec = EbpUndefined; // If we dont find anything we return this. Should we error check this? - while (level >= 0) { - it = precisionStack[level]->find(type); - if (it != precisionStack[level]->end()) { - prec = (*it).second; - break; - } - level--; - } - return prec; - } + // Searches down the precisionStack for a precision qualifier + // for the specified TBasicType + TPrecision getDefaultPrecision(TBasicType type); -private: - int currentLevel() const { return static_cast<int>(table.size()) - 1; } + static int nextUniqueId() + { + return ++uniqueIdCounter; + } - bool supportsPrecision(TBasicType type) { - // Only supports precision for int, float, and sampler types. - return type == EbtFloat || type == EbtInt || IsSampler(type); + private: + ESymbolLevel currentLevel() const + { + return static_cast<ESymbolLevel>(table.size() - 1); } - int uniqueId; // for unique identification in code generation - std::vector<TSymbolTableLevel*> table; + std::vector<TSymbolTableLevel *> table; typedef TMap<TBasicType, TPrecision> PrecisionStackLevel; - std::vector<PrecisionStackLevel*> precisionStack; + std::vector< PrecisionStackLevel *> precisionStack; + + static int uniqueIdCounter; }; #endif // _SYMBOL_TABLE_INCLUDED_ |