Fix code styles in OutputGLSLBase, SymbolTable, and Types.

I came across these three classes in the last CL, so do some
cleanup as I touched these classes.

BUG=
TEST=webgl conformance, no regressions

Change-Id: I2819bab5965fcb4917f85c2eded571a7f95ab9a2
Reviewed-on: https://chromium-review.googlesource.com/199423
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Tested-by: Zhenyao Mo <zmo@chromium.org>
This commit is contained in:
Zhenyao Mo 2014-05-12 16:02:35 -07:00
Родитель 487456a36d
Коммит 9eedea031c
6 изменённых файлов: 1361 добавлений и 814 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -15,52 +15,53 @@
class TOutputGLSLBase : public TIntermTraverser
{
public:
TOutputGLSLBase(TInfoSinkBase& objSink,
public:
TOutputGLSLBase(TInfoSinkBase &objSink,
ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction,
NameMap& nameMap,
NameMap &nameMap,
TSymbolTable& symbolTable,
int shaderVersion);
protected:
TInfoSinkBase& objSink() { return mObjSink; }
void writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr);
void writeVariableType(const TType& type);
protected:
TInfoSinkBase &objSink() { return mObjSink; }
void writeTriplet(Visit visit, const char *preStr, const char *inStr, const char *postStr);
void writeVariableType(const TType &type);
virtual bool writeVariablePrecision(TPrecision precision) = 0;
void writeFunctionParameters(const TIntermSequence& args);
const ConstantUnion* writeConstantUnion(const TType& type, const ConstantUnion* pConstUnion);
TString getTypeName(const TType& type);
void writeFunctionParameters(const TIntermSequence &args);
const ConstantUnion *writeConstantUnion(const TType &type, const ConstantUnion *pConstUnion);
TString getTypeName(const TType &type);
virtual void visitSymbol(TIntermSymbol* node);
virtual void visitConstantUnion(TIntermConstantUnion* node);
virtual bool visitBinary(Visit visit, TIntermBinary* node);
virtual bool visitUnary(Visit visit, TIntermUnary* node);
virtual bool visitSelection(Visit visit, TIntermSelection* node);
virtual bool visitAggregate(Visit visit, TIntermAggregate* node);
virtual bool visitLoop(Visit visit, TIntermLoop* node);
virtual bool visitBranch(Visit visit, TIntermBranch* node);
void visitCodeBlock(TIntermNode* node);
virtual void visitSymbol(TIntermSymbol *node);
virtual void visitConstantUnion(TIntermConstantUnion *node);
virtual bool visitBinary(Visit visit, TIntermBinary *node);
virtual bool visitUnary(Visit visit, TIntermUnary *node);
virtual bool visitSelection(Visit visit, TIntermSelection *node);
virtual bool visitAggregate(Visit visit, TIntermAggregate *node);
virtual bool visitLoop(Visit visit, TIntermLoop *node);
virtual bool visitBranch(Visit visit, TIntermBranch *node);
void visitCodeBlock(TIntermNode *node);
// Return the original name if hash function pointer is NULL;
// otherwise return the hashed name.
TString hashName(const TString& name);
TString hashName(const TString &name);
// Same as hashName(), but without hashing built-in variables.
TString hashVariableName(const TString& name);
TString hashVariableName(const TString &name);
// Same as hashName(), but without hashing built-in functions.
TString hashFunctionName(const TString& mangled_name);
TString hashFunctionName(const TString &mangled_name);
// Used to translate function names for differences between ESSL and GLSL
virtual TString translateTextureFunction(TString& name) { return name; }
virtual TString translateTextureFunction(TString &name) { return name; }
private:
bool structDeclared(const TStructure* structure) const;
void declareStruct(const TStructure* structure);
private:
bool structDeclared(const TStructure *structure) const;
void declareStruct(const TStructure *structure);
void pushDeclaredStructsScope();
void popDeclaredStructsScope();
TInfoSinkBase& mObjSink;
void writeBuiltInFunctionTriplet(Visit visit, const char *preStr, bool useEmulatedFunction);
TInfoSinkBase &mObjSink;
bool mDeclaringVariables;
// Structs are declared as the tree is traversed. This list contains all
@ -80,9 +81,9 @@ private:
// name hashing.
ShHashFunction64 mHashFunction;
NameMap& mNameMap;
NameMap &mNameMap;
TSymbolTable& mSymbolTable;
TSymbolTable &mSymbolTable;
const int mShaderVersion;
};

Просмотреть файл

@ -44,12 +44,13 @@ TSymbolTableLevel::~TSymbolTableLevel()
// performance operation, and only intended for symbol tables that
// live across a large number of compiles.
//
void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
void TSymbolTableLevel::relateToOperator(const char *name, TOperator op)
{
tLevel::iterator it;
for (it = level.begin(); it != level.end(); ++it) {
if ((*it).second->isFunction()) {
TFunction* function = static_cast<TFunction*>((*it).second);
for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
{
if ((*it).second->isFunction())
{
TFunction *function = static_cast<TFunction*>((*it).second);
if (function->getName() == name)
function->relateToOperator(op);
}
@ -62,17 +63,17 @@ void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
// performance operation, and only intended for symbol tables that
// live across a large number of compiles.
//
void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext)
void TSymbolTableLevel::relateToExtension(const char *name, const TString &ext)
{
for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
TSymbol* symbol = it->second;
if (symbol->getName() == name) {
for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
{
TSymbol *symbol = it->second;
if (symbol->getName() == name)
symbol->relateToExtension(ext);
}
}
}
TSymbol::TSymbol(const TSymbol& copyOf)
TSymbol::TSymbol(const TSymbol &copyOf)
{
name = NewPoolTString(copyOf.name->c_str());
uniqueId = copyOf.uniqueId;
@ -85,8 +86,10 @@ TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtI
do
{
if (level == ESSL3_BUILTINS && shaderVersion != 300) level--;
if (level == ESSL1_BUILTINS && shaderVersion != 100) level--;
if (level == ESSL3_BUILTINS && shaderVersion != 300)
level--;
if (level == ESSL1_BUILTINS && shaderVersion != 100)
level--;
symbol = table[level]->find(name);
}
@ -104,8 +107,10 @@ TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion)
{
for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
{
if (level == ESSL3_BUILTINS && shaderVersion != 300) level--;
if (level == ESSL1_BUILTINS && shaderVersion != 100) level--;
if (level == ESSL3_BUILTINS && shaderVersion != 300)
level--;
if (level == ESSL1_BUILTINS && shaderVersion != 100)
level--;
TSymbol *symbol = table[level]->find(name);
@ -121,3 +126,92 @@ TSymbolTable::~TSymbolTable()
while (table.size() > 0)
pop();
}
void TSymbolTable::insertBuiltIn(
ESymbolLevel level, TType *rvalue, const char *name,
TType *ptype1, TType *ptype2, TType *ptype3, TType *ptype4, TType *ptype5)
{
if (ptype1->getBasicType() == EbtGSampler2D)
{
bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name,
new TType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name,
new TType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name,
new TType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
return;
}
if (ptype1->getBasicType() == EbtGSampler3D)
{
bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name,
new TType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name,
new TType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name,
new TType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
return;
}
if (ptype1->getBasicType() == EbtGSamplerCube)
{
bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name,
new TType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name,
new TType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name,
new TType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
return;
}
if (ptype1->getBasicType() == EbtGSampler2DArray)
{
bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name,
new TType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name,
new TType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name,
new TType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
return;
}
TFunction *function = new TFunction(NewPoolTString(name), *rvalue);
TType *types[] = {ptype1, ptype2, ptype3, ptype4, ptype5};
for (size_t ii = 0; ii < sizeof(types) / sizeof(types[0]); ++ii)
{
if (types[ii])
{
TParameter param = {NULL, types[ii]};
function->addParameter(param);
}
}
insert(level, *function);
}
TPrecision TSymbolTable::getDefaultPrecision(TBasicType type)
{
if (!SupportsPrecision(type))
return EbpUndefined;
// unsigned integers use the same precision as signed
TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
int level = static_cast<int>(precisionStack.size()) - 1;
assert(level >= 0); // Just to be safe. Should not happen.
// If we dont find anything we return this. Should we error check this?
TPrecision prec = EbpUndefined;
while (level >= 0)
{
PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
if (it != precisionStack[level]->end())
{
prec = (*it).second;
break;
}
level--;
}
return prec;
}

Просмотреть файл

@ -36,33 +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 */ }
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; }
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:
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;
@ -71,18 +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); }
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()
ConstantUnion *getConstPointer()
{
if (!unionArray)
unionArray = new ConstantUnion[type.getObjectSize()];
@ -90,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;
@ -101,69 +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;
};
//
// 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, 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; }
const TString &getMangledName() const
{
return mangledName;
}
const TType &getReturnType() const
{
return returnType;
}
void relateToOperator(TOperator o) { op = o; }
TOperator getBuiltInOp() const { return op; }
void relateToOperator(TOperator o)
{
op = o;
}
TOperator getBuiltInOp() const
{
return op;
}
void setDefined() { defined = true; }
bool isDefined() { return defined; }
void setDefined()
{
defined = true;
}
bool isDefined()
{
return defined;
}
size_t getParamCount() const { return parameters.size(); }
const TParameter& getParam(size_t i) const { return parameters[i]; }
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;
@ -174,36 +261,38 @@ private:
bool defined;
};
//
// Interface block name sub-symbol
//
class TInterfaceBlockName : public TSymbol
{
public:
public:
TInterfaceBlockName(const TString *name)
: TSymbol(name)
{}
{
}
virtual ~TInterfaceBlockName() {}
virtual ~TInterfaceBlockName()
{
}
};
class TSymbolTableLevel {
public:
typedef TMap<TString, TSymbol*> tLevel;
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()
{
}
~TSymbolTableLevel();
bool insert(const TString &name, TSymbol &symbol)
{
symbol.setUniqueId(++uniqueId);
//
// returning true means symbol was added to the table
//
tInsertResult result = level.insert(tLevelPair(name, &symbol));
return result.second;
@ -214,7 +303,7 @@ public:
return insert(symbol.getMangledName(), symbol);
}
TSymbol* find(const TString& name) const
TSymbol *find(const TString &name) const
{
tLevel::const_iterator it = level.find(name);
if (it == level.end())
@ -223,12 +312,12 @@ public:
return (*it).second;
}
void relateToOperator(const char* name, TOperator op);
void relateToExtension(const char* name, const TString& ext);
void relateToOperator(const char *name, TOperator op);
void relateToExtension(const char *name, const TString &ext);
protected:
protected:
tLevel level;
static int uniqueId; // for unique identification in code generation
static int uniqueId; // for unique identification in code generation
};
enum ESymbolLevel
@ -240,27 +329,33 @@ enum ESymbolLevel
GLOBAL_LEVEL = 3
};
class TSymbolTable {
public:
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.empty(); }
bool atBuiltInLevel() { return currentLevel() <= LAST_BUILTIN_LEVEL; }
bool atGlobalLevel() { return currentLevel() <= GLOBAL_LEVEL; }
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);
@ -288,134 +383,61 @@ public:
bool insertConstInt(ESymbolLevel level, const char *name, int value)
{
TVariable *constant = new TVariable(NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1));
TVariable *constant = new TVariable(
NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1));
constant->getConstPointer()->setIConst(value);
return insert(level, *constant);
}
void insertBuiltIn(ESymbolLevel level, TType *rvalue, const char *name, TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0)
{
if (ptype1->getBasicType() == EbtGSampler2D)
{
bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
return;
}
else if (ptype1->getBasicType() == EbtGSampler3D)
{
bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
return;
}
else if (ptype1->getBasicType() == EbtGSamplerCube)
{
bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
return;
}
else if (ptype1->getBasicType() == EbtGSampler2DArray)
{
bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
return;
}
void insertBuiltIn(ESymbolLevel level, TType *rvalue, const char *name,
TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0,
TType *ptype4 = 0, TType *ptype5 = 0);
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);
}
if (ptype4)
{
TParameter param4 = {NULL, ptype4};
function->addParameter(param4);
}
if (ptype5)
{
TParameter param5 = {NULL, ptype5};
function->addParameter(param5);
}
insert(level, *function);
}
TSymbol *find(const TString &name, int shaderVersion, bool *builtIn = NULL, bool *sameScope = NULL);
TSymbol *find(const TString &name, int shaderVersion,
bool *builtIn = NULL, bool *sameScope = NULL);
TSymbol *findBuiltIn(const TString &name, int shaderVersion);
TSymbolTableLevel *getOuterLevel() {
TSymbolTableLevel *getOuterLevel()
{
assert(currentLevel() >= 1);
return table[currentLevel() - 1];
}
void relateToOperator(ESymbolLevel level, const char* name, TOperator op) {
void relateToOperator(ESymbolLevel level, const char *name, TOperator op)
{
table[level]->relateToOperator(name, op);
}
void relateToExtension(ESymbolLevel level, const char* name, const TString& 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) {
bool setDefaultPrecision(const TPublicType &type, TPrecision prec)
{
if (!SupportsPrecision(type.type))
return false;
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){
// Searches down the precisionStack for a precision qualifier
// for the specified TBasicType
TPrecision getDefaultPrecision(TBasicType type);
if (!SupportsPrecision(type))
return EbpUndefined;
// unsigned integers use the same precision as signed
TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
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(baseType);
if (it != precisionStack[level]->end()) {
prec = (*it).second;
break;
}
level--;
}
return prec;
private:
ESymbolLevel currentLevel() const
{
return static_cast<ESymbolLevel>(table.size() - 1);
}
private:
ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); }
std::vector<TSymbolTableLevel*> table;
std::vector<TSymbolTableLevel *> table;
typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
std::vector< PrecisionStackLevel*> precisionStack;
std::vector< PrecisionStackLevel *> precisionStack;
};
#endif // _SYMBOL_TABLE_INCLUDED_

Просмотреть файл

@ -19,9 +19,7 @@ TType::TType(const TPublicType &p)
interfaceBlock(0), structure(0)
{
if (p.userDef)
{
structure = p.userDef->getStruct();
}
}
bool TType::equals(const TType &other) const
@ -34,13 +32,9 @@ bool TType::equals(const TType &other) const
return false;
}
if (interfaceBlock && !interfaceBlock->equals(*(other.interfaceBlock)))
{
return false;
}
if (structure && !structure->equals(*(other.structure)))
{
return false;
}
return true;
}
@ -89,30 +83,77 @@ TString TType::buildMangledName() const
switch (type)
{
case EbtFloat: mangledName += 'f'; break;
case EbtInt: mangledName += 'i'; break;
case EbtUInt: mangledName += 'u'; break;
case EbtBool: mangledName += 'b'; break;
case EbtSampler2D: mangledName += "s2"; break;
case EbtSampler3D: mangledName += "s3"; break;
case EbtSamplerCube: mangledName += "sC"; break;
case EbtSampler2DArray: mangledName += "s2a"; break;
case EbtSamplerExternalOES: mangledName += "sext"; break;
case EbtSampler2DRect: mangledName += "s2r"; break;
case EbtISampler2D: mangledName += "is2"; break;
case EbtISampler3D: mangledName += "is3"; break;
case EbtISamplerCube: mangledName += "isC"; break;
case EbtISampler2DArray: mangledName += "is2a"; break;
case EbtUSampler2D: mangledName += "us2"; break;
case EbtUSampler3D: mangledName += "us3"; break;
case EbtUSamplerCube: mangledName += "usC"; break;
case EbtUSampler2DArray: mangledName += "us2a"; break;
case EbtSampler2DShadow: mangledName += "s2s"; break;
case EbtSamplerCubeShadow: mangledName += "sCs"; break;
case EbtSampler2DArrayShadow: mangledName += "s2as"; break;
case EbtStruct: mangledName += structure->mangledName(); break;
case EbtInterfaceBlock: mangledName += interfaceBlock->mangledName(); break;
default: UNREACHABLE();
case EbtFloat:
mangledName += 'f';
break;
case EbtInt:
mangledName += 'i';
break;
case EbtUInt:
mangledName += 'u';
break;
case EbtBool:
mangledName += 'b';
break;
case EbtSampler2D:
mangledName += "s2";
break;
case EbtSampler3D:
mangledName += "s3";
break;
case EbtSamplerCube:
mangledName += "sC";
break;
case EbtSampler2DArray:
mangledName += "s2a";
break;
case EbtSamplerExternalOES:
mangledName += "sext";
break;
case EbtSampler2DRect:
mangledName += "s2r";
break;
case EbtISampler2D:
mangledName += "is2";
break;
case EbtISampler3D:
mangledName += "is3";
break;
case EbtISamplerCube:
mangledName += "isC";
break;
case EbtISampler2DArray:
mangledName += "is2a";
break;
case EbtUSampler2D:
mangledName += "us2";
break;
case EbtUSampler3D:
mangledName += "us3";
break;
case EbtUSamplerCube:
mangledName += "usC";
break;
case EbtUSampler2DArray:
mangledName += "us2a";
break;
case EbtSampler2DShadow:
mangledName += "s2s";
break;
case EbtSamplerCubeShadow:
mangledName += "sCs";
break;
case EbtSampler2DArrayShadow:
mangledName += "s2as";
break;
case EbtStruct:
mangledName += structure->mangledName();
break;
case EbtInterfaceBlock:
mangledName += interfaceBlock->mangledName();
break;
default:
UNREACHABLE();
}
if (isMatrix())
@ -160,8 +201,9 @@ size_t TType::getObjectSize() const
bool TStructure::containsArrays() const
{
for (size_t i = 0; i < mFields->size(); ++i) {
const TType* fieldType = (*mFields)[i]->type();
for (size_t i = 0; i < mFields->size(); ++i)
{
const TType *fieldType = (*mFields)[i]->type();
if (fieldType->isArray() || fieldType->isStructureContainingArrays())
return true;
}
@ -183,7 +225,8 @@ TString TFieldListCollection::buildMangledName() const
size_t TFieldListCollection::calculateObjectSize() const
{
size_t size = 0;
for (size_t i = 0; i < mFields->size(); ++i) {
for (size_t i = 0; i < mFields->size(); ++i)
{
size_t fieldSize = (*mFields)[i]->type()->getObjectSize();
if (fieldSize > INT_MAX - size)
size = INT_MAX;
@ -196,8 +239,7 @@ size_t TFieldListCollection::calculateObjectSize() const
int TStructure::calculateDeepestNesting() const
{
int maxNesting = 0;
for (size_t i = 0; i < mFields->size(); ++i) {
for (size_t i = 0; i < mFields->size(); ++i)
maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
}
return 1 + maxNesting;
}

Просмотреть файл

@ -18,46 +18,71 @@ class TType;
class TField
{
public:
public:
POOL_ALLOCATOR_NEW_DELETE();
TField(TType* type, TString* name, const TSourceLoc& line) : mType(type), mName(name), mLine(line) {}
TField(TType *type, TString *name, const TSourceLoc &line)
: mType(type),
mName(name),
mLine(line)
{
}
// TODO(alokp): We should only return const type.
// Fix it by tweaking grammar.
TType* type() { return mType; }
const TType* type() const { return mType; }
TType *type()
{
return mType;
}
const TType *type() const
{
return mType;
}
const TString& name() const { return *mName; }
const TSourceLoc& line() const { return mLine; }
const TString &name() const
{
return *mName;
}
const TSourceLoc &line() const
{
return mLine;
}
bool equals(const TField &other) const;
private:
private:
DISALLOW_COPY_AND_ASSIGN(TField);
TType* mType;
TString* mName;
TType *mType;
TString *mName;
TSourceLoc mLine;
};
typedef TVector<TField*> TFieldList;
inline TFieldList* NewPoolTFieldList()
typedef TVector<TField *> TFieldList;
inline TFieldList *NewPoolTFieldList()
{
void* memory = GetGlobalPoolAllocator()->allocate(sizeof(TFieldList));
void *memory = GetGlobalPoolAllocator()->allocate(sizeof(TFieldList));
return new(memory) TFieldList;
}
class TFieldListCollection
{
public:
const TString& name() const { return *mName; }
const TFieldList& fields() const { return *mFields; }
public:
const TString &name() const
{
return *mName;
}
const TFieldList &fields() const
{
return *mFields;
}
const TString& mangledName() const {
const TString &mangledName() const
{
if (mMangledName.empty())
mMangledName = buildMangledName();
return mMangledName;
}
size_t objectSize() const {
size_t objectSize() const
{
if (mObjectSize == 0)
mObjectSize = calculateObjectSize();
return mObjectSize;
@ -65,18 +90,19 @@ public:
virtual bool equals(const TFieldListCollection &other) const;
protected:
TFieldListCollection(const TString* name, TFieldList* fields)
protected:
TFieldListCollection(const TString *name, TFieldList *fields)
: mName(name),
mFields(fields),
mObjectSize(0) {
mObjectSize(0)
{
}
TString buildMangledName() const;
size_t calculateObjectSize() const;
virtual TString mangledNamePrefix() const = 0;
const TString* mName;
TFieldList* mFields;
const TString *mName;
TFieldList *mFields;
mutable TString mMangledName;
mutable size_t mObjectSize;
@ -85,23 +111,28 @@ protected:
// May also represent interface blocks
class TStructure : public TFieldListCollection
{
public:
public:
POOL_ALLOCATOR_NEW_DELETE();
TStructure(const TString* name, TFieldList* fields)
TStructure(const TString *name, TFieldList *fields)
: TFieldListCollection(name, fields),
mDeepestNesting(0) {
mDeepestNesting(0)
{
}
int deepestNesting() const {
int deepestNesting() const
{
if (mDeepestNesting == 0)
mDeepestNesting = calculateDeepestNesting();
return mDeepestNesting;
}
bool containsArrays() const;
private:
private:
DISALLOW_COPY_AND_ASSIGN(TStructure);
virtual TString mangledNamePrefix() const { return "struct-"; }
virtual TString mangledNamePrefix() const
{
return "struct-";
}
int calculateDeepestNesting() const;
mutable int mDeepestNesting;
@ -109,30 +140,53 @@ private:
class TInterfaceBlock : public TFieldListCollection
{
public:
public:
POOL_ALLOCATOR_NEW_DELETE();
TInterfaceBlock(const TString* name, TFieldList* fields, const TString* instanceName, int arraySize, const TLayoutQualifier& layoutQualifier)
TInterfaceBlock(const TString *name, TFieldList *fields, const TString *instanceName,
int arraySize, const TLayoutQualifier &layoutQualifier)
: TFieldListCollection(name, fields),
mInstanceName(instanceName),
mArraySize(arraySize),
mBlockStorage(layoutQualifier.blockStorage),
mMatrixPacking(layoutQualifier.matrixPacking) {
mMatrixPacking(layoutQualifier.matrixPacking)
{
}
const TString& instanceName() const { return *mInstanceName; }
bool hasInstanceName() const { return mInstanceName != NULL; }
bool isArray() const { return mArraySize > 0; }
int arraySize() const { return mArraySize; }
TLayoutBlockStorage blockStorage() const { return mBlockStorage; }
TLayoutMatrixPacking matrixPacking() const { return mMatrixPacking; }
const TString &instanceName() const
{
return *mInstanceName;
}
bool hasInstanceName() const
{
return mInstanceName != NULL;
}
bool isArray() const
{
return mArraySize > 0;
}
int arraySize() const
{
return mArraySize;
}
TLayoutBlockStorage blockStorage() const
{
return mBlockStorage;
}
TLayoutMatrixPacking matrixPacking() const
{
return mMatrixPacking;
}
virtual bool equals(const TInterfaceBlock &other) const;
private:
private:
DISALLOW_COPY_AND_ASSIGN(TInterfaceBlock);
virtual TString mangledNamePrefix() const { return "iblock-"; }
virtual TString mangledNamePrefix() const
{
return "iblock-";
}
const TString* mInstanceName; // for interface block instance names
const TString *mInstanceName; // for interface block instance names
int mArraySize; // 0 if not an array
TLayoutBlockStorage mBlockStorage;
TLayoutMatrixPacking mMatrixPacking;
@ -143,72 +197,171 @@ private:
//
class TType
{
public:
public:
POOL_ALLOCATOR_NEW_DELETE();
TType() {}
TType(TBasicType t, unsigned char ps = 1, unsigned char ss = 1) :
type(t), precision(EbpUndefined), qualifier(EvqGlobal), layoutQualifier(TLayoutQualifier::create()), primarySize(ps), secondarySize(ss), array(false), arraySize(0),
interfaceBlock(0), structure(0)
TType()
{
}
TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, unsigned char ps = 1, unsigned char ss = 1, bool a = false) :
type(t), precision(p), qualifier(q), layoutQualifier(TLayoutQualifier::create()), primarySize(ps), secondarySize(ss), array(a), arraySize(0),
interfaceBlock(0), structure(0)
TType(TBasicType t, unsigned char ps = 1, unsigned char ss = 1)
: type(t), precision(EbpUndefined), qualifier(EvqGlobal),
layoutQualifier(TLayoutQualifier::create()),
primarySize(ps), secondarySize(ss), array(false), arraySize(0),
interfaceBlock(0), structure(0)
{
}
TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary,
unsigned char ps = 1, unsigned char ss = 1, bool a = false)
: type(t), precision(p), qualifier(q),
layoutQualifier(TLayoutQualifier::create()),
primarySize(ps), secondarySize(ss), array(a), arraySize(0),
interfaceBlock(0), structure(0)
{
}
explicit TType(const TPublicType &p);
TType(TStructure* userDef, TPrecision p = EbpUndefined) :
type(EbtStruct), precision(p), qualifier(EvqTemporary), layoutQualifier(TLayoutQualifier::create()), primarySize(1), secondarySize(1), array(false), arraySize(0),
interfaceBlock(0), structure(userDef)
TType(TStructure *userDef, TPrecision p = EbpUndefined)
: type(EbtStruct), precision(p), qualifier(EvqTemporary),
layoutQualifier(TLayoutQualifier::create()),
primarySize(1), secondarySize(1), array(false), arraySize(0),
interfaceBlock(0), structure(userDef)
{
}
TType(TInterfaceBlock* interfaceBlockIn, TQualifier qualifierIn, TLayoutQualifier layoutQualifierIn, int arraySizeIn) :
type(EbtInterfaceBlock), precision(EbpUndefined), qualifier(qualifierIn), layoutQualifier(layoutQualifierIn), primarySize(1), secondarySize(1), array(arraySizeIn > 0), arraySize(arraySizeIn),
interfaceBlock(interfaceBlockIn), structure(0)
TType(TInterfaceBlock *interfaceBlockIn, TQualifier qualifierIn,
TLayoutQualifier layoutQualifierIn, int arraySizeIn)
: type(EbtInterfaceBlock), precision(EbpUndefined), qualifier(qualifierIn),
layoutQualifier(layoutQualifierIn),
primarySize(1), secondarySize(1), array(arraySizeIn > 0), arraySize(arraySizeIn),
interfaceBlock(interfaceBlockIn), structure(0)
{
}
TBasicType getBasicType() const { return type; }
void setBasicType(TBasicType t) { type = t; }
TBasicType getBasicType() const
{
return type;
}
void setBasicType(TBasicType t)
{
type = t;
}
TPrecision getPrecision() const { return precision; }
void setPrecision(TPrecision p) { precision = p; }
TPrecision getPrecision() const
{
return precision;
}
void setPrecision(TPrecision p)
{
precision = p;
}
TQualifier getQualifier() const { return qualifier; }
void setQualifier(TQualifier q) { qualifier = q; }
TQualifier getQualifier() const
{
return qualifier;
}
void setQualifier(TQualifier q)
{
qualifier = q;
}
TLayoutQualifier getLayoutQualifier() const { return layoutQualifier; }
void setLayoutQualifier(TLayoutQualifier lq) { layoutQualifier = lq; }
TLayoutQualifier getLayoutQualifier() const
{
return layoutQualifier;
}
void setLayoutQualifier(TLayoutQualifier lq)
{
layoutQualifier = lq;
}
int getNominalSize() const { return primarySize; }
int getSecondarySize() const { return secondarySize; }
int getCols() const { ASSERT(isMatrix()); return primarySize; }
int getRows() const { ASSERT(isMatrix()); return secondarySize; }
void setPrimarySize(unsigned char ps) { primarySize = ps; }
void setSecondarySize(unsigned char ss) { secondarySize = ss; }
int getNominalSize() const
{
return primarySize;
}
int getSecondarySize() const
{
return secondarySize;
}
int getCols() const
{
ASSERT(isMatrix());
return primarySize;
}
int getRows() const
{
ASSERT(isMatrix());
return secondarySize;
}
void setPrimarySize(unsigned char ps)
{
primarySize = ps;
}
void setSecondarySize(unsigned char ss)
{
secondarySize = ss;
}
// Full size of single instance of type
size_t getObjectSize() const;
bool isMatrix() const { return primarySize > 1 && secondarySize > 1; }
bool isArray() const { return array ? true : false; }
int getArraySize() const { return arraySize; }
void setArraySize(int s) { array = true; arraySize = s; }
void clearArrayness() { array = false; arraySize = 0; }
bool isMatrix() const
{
return primarySize > 1 && secondarySize > 1;
}
bool isArray() const
{
return array ? true : false;
}
int getArraySize() const
{
return arraySize;
}
void setArraySize(int s)
{
array = true;
arraySize = s;
}
void clearArrayness()
{
array = false;
arraySize = 0;
}
TInterfaceBlock* getInterfaceBlock() const { return interfaceBlock; }
void setInterfaceBlock(TInterfaceBlock* interfaceBlockIn) { interfaceBlock = interfaceBlockIn; }
bool isInterfaceBlock() const { return type == EbtInterfaceBlock; }
TInterfaceBlock *getInterfaceBlock() const
{
return interfaceBlock;
}
void setInterfaceBlock(TInterfaceBlock *interfaceBlockIn)
{
interfaceBlock = interfaceBlockIn;
}
bool isInterfaceBlock() const
{
return type == EbtInterfaceBlock;
}
bool isVector() const { return primarySize > 1 && secondarySize == 1; }
bool isScalar() const { return primarySize == 1 && secondarySize == 1 && !structure; }
bool isScalarInt() const { return isScalar() && (type == EbtInt || type == EbtUInt); }
bool isVector() const
{
return primarySize > 1 && secondarySize == 1;
}
bool isScalar() const
{
return primarySize == 1 && secondarySize == 1 && !structure;
}
bool isScalarInt() const
{
return isScalar() && (type == EbtInt || type == EbtUInt);
}
TStructure* getStruct() const { return structure; }
void setStruct(TStructure* s) { structure = s; }
TStructure *getStruct() const
{
return structure;
}
void setStruct(TStructure *s)
{
structure = s;
}
const TString& getMangledName() {
if (mangled.empty()) {
const TString &getMangledName()
{
if (mangled.empty())
{
mangled = buildMangledName();
mangled += ';';
}
@ -220,37 +373,56 @@ public:
// precision here.
bool equals(const TType &other) const;
bool sameElementType(const TType& right) const {
return type == right.type &&
primarySize == right.primarySize &&
secondarySize == right.secondarySize &&
structure == right.structure;
bool sameElementType(const TType &right) const
{
return type == right.type &&
primarySize == right.primarySize &&
secondarySize == right.secondarySize &&
structure == right.structure;
}
bool operator==(const TType& right) const {
return type == right.type &&
primarySize == right.primarySize &&
secondarySize == right.secondarySize &&
array == right.array && (!array || arraySize == right.arraySize) &&
structure == right.structure;
bool operator==(const TType &right) const
{
return type == right.type &&
primarySize == right.primarySize &&
secondarySize == right.secondarySize &&
array == right.array && (!array || arraySize == right.arraySize) &&
structure == right.structure;
// don't check the qualifier, it's not ever what's being sought after
}
bool operator!=(const TType& right) const {
bool operator!=(const TType &right) const
{
return !operator==(right);
}
bool operator<(const TType& right) const {
if (type != right.type) return type < right.type;
if (primarySize != right.primarySize) return primarySize < right.primarySize;
if (secondarySize != right.secondarySize) return secondarySize < right.secondarySize;
if (array != right.array) return array < right.array;
if (arraySize != right.arraySize) return arraySize < right.arraySize;
if (structure != right.structure) return structure < right.structure;
bool operator<(const TType &right) const
{
if (type != right.type)
return type < right.type;
if (primarySize != right.primarySize)
return primarySize < right.primarySize;
if (secondarySize != right.secondarySize)
return secondarySize < right.secondarySize;
if (array != right.array)
return array < right.array;
if (arraySize != right.arraySize)
return arraySize < right.arraySize;
if (structure != right.structure)
return structure < right.structure;
return false;
}
const char* getBasicString() const { return ::getBasicString(type); }
const char* getPrecisionString() const { return ::getPrecisionString(precision); }
const char* getQualifierString() const { return ::getQualifierString(qualifier); }
const char *getBasicString() const
{
return ::getBasicString(type);
}
const char *getPrecisionString() const
{
return ::getPrecisionString(precision);
}
const char *getQualifierString() const
{
return ::getQualifierString(qualifier);
}
TString getCompleteString() const;
// If this type is a struct, returns the deepest struct nesting of
@ -265,15 +437,17 @@ public:
// For type "nesting2", this method would return 2 -- the number
// of structures through which indirection must occur to reach the
// deepest field (nesting2.field1.position).
int getDeepestStructNesting() const {
int getDeepestStructNesting() const
{
return structure ? structure->deepestNesting() : 0;
}
bool isStructureContainingArrays() const {
bool isStructureContainingArrays() const
{
return structure ? structure->containsArrays() : false;
}
protected:
protected:
TString buildMangledName() const;
size_t getStructSize() const;
void computeDeepestStructNesting();
@ -288,10 +462,10 @@ protected:
int arraySize;
// 0 unless this is an interface block, or interface block member variable
TInterfaceBlock* interfaceBlock;
TInterfaceBlock *interfaceBlock;
// 0 unless this is a struct
TStructure* structure;
TStructure *structure;
mutable TString mangled;
};
@ -315,10 +489,10 @@ struct TPublicType
unsigned char secondarySize; // rows of matrix
bool array;
int arraySize;
TType* userDef;
TType *userDef;
TSourceLoc line;
void setBasic(TBasicType bt, TQualifier q, const TSourceLoc& ln)
void setBasic(TBasicType bt, TQualifier q, const TSourceLoc &ln)
{
type = bt;
layoutQualifier = TLayoutQualifier::create();