зеркало из https://github.com/AvaloniaUI/angle.git
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:
Родитель
487456a36d
Коммит
9eedea031c
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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 ©Of)
|
||||
{
|
||||
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();
|
||||
|
|
Загрузка…
Ссылка в новой задаче