Commit 55218627 by John Kessenich

Implement the full scheme for ES precision qualifiers, generalizing existing…

Implement the full scheme for ES precision qualifiers, generalizing existing storage qualifiers to be able to include multiple independent kinds of qualifiers. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@20317 e7fa87d3-cd2b-0410-9028-fcbf551c1848
parent 674014bf
...@@ -55,7 +55,7 @@ enum TBasicType { ...@@ -55,7 +55,7 @@ enum TBasicType {
EbtSamplerRectShadow, // ARB_texture_rectangle EbtSamplerRectShadow, // ARB_texture_rectangle
EbtGuardSamplerEnd, // non type: see implementation of IsSampler() EbtGuardSamplerEnd, // non type: see implementation of IsSampler()
EbtStruct, EbtStruct,
EbtAddress, // should be deprecated?? EbtNumTypes
}; };
__inline bool IsSampler(TBasicType type) __inline bool IsSampler(TBasicType type)
...@@ -69,7 +69,7 @@ __inline bool IsSampler(TBasicType type) ...@@ -69,7 +69,7 @@ __inline bool IsSampler(TBasicType type)
// to allocate variables in. Since built-ins tend to go to different registers // to allocate variables in. Since built-ins tend to go to different registers
// than varying or uniform, it makes sense they are peers, not sub-classes. // than varying or uniform, it makes sense they are peers, not sub-classes.
// //
enum TQualifier { enum TStorageQualifier {
EvqTemporary, // For temporaries (within a function), read/write EvqTemporary, // For temporaries (within a function), read/write
EvqGlobal, // For globals read/write EvqGlobal, // For globals read/write
EvqConst, // User defined constants and non-output parameters in functions EvqConst, // User defined constants and non-output parameters in functions
...@@ -104,7 +104,7 @@ enum TQualifier { ...@@ -104,7 +104,7 @@ enum TQualifier {
// //
// This is just for debug print out, carried along with the definitions above. // This is just for debug print out, carried along with the definitions above.
// //
__inline const char* getQualifierString(TQualifier q) __inline const char* getStorageQualifierString(TStorageQualifier q)
{ {
switch (q) { switch (q) {
case EvqTemporary: return "Temporary"; break; case EvqTemporary: return "Temporary"; break;
...@@ -129,4 +129,22 @@ __inline const char* getQualifierString(TQualifier q) ...@@ -129,4 +129,22 @@ __inline const char* getQualifierString(TQualifier q)
} }
} }
enum TPrecisionQualifier {
EpqNone,
EpqLow,
EpqMedium,
EpqHigh
};
__inline const char* getPrecisionQualifierString(TPrecisionQualifier p)
{
switch(p) {
case EpqNone: return ""; break;
case EpqLow: return "lowp"; break;
case EpqMedium: return "mediump"; break;
case EpqHigh: return "highp"; break;
default: return "unknown precision qualifier";
}
}
#endif // _BASICTYPES_INCLUDED_ #endif // _BASICTYPES_INCLUDED_
...@@ -56,13 +56,20 @@ inline TTypeList* NewPoolTTypeList() ...@@ -56,13 +56,20 @@ inline TTypeList* NewPoolTTypeList()
// //
// This is a workaround for a problem with the yacc stack, It can't have // This is a workaround for a problem with the yacc stack, It can't have
// types that it thinks have non-trivial constructors. It should // types that it thinks have non-trivial constructors. It should
// just be used while recognizing the grammar, not anything else. Pointers // just be used while recognizing the grammar, not anything else. Pointers
// could be used, but also trying to avoid lots of memory management overhead. // could be used, but also trying to avoid lots of memory management overhead.
// //
// Not as bad as it looks, there is no actual assumption that the fields // Not as bad as it looks, there is no actual assumption that the fields
// match up or are name the same or anything like that. // match up or are name the same or anything like that.
// //
class TQualifier {
public:
TStorageQualifier storage : 7;
TPrecisionQualifier precision : 3;
};
class TPublicType { class TPublicType {
public: public:
TBasicType type; TBasicType type;
...@@ -74,10 +81,9 @@ public: ...@@ -74,10 +81,9 @@ public:
TType* userDef; TType* userDef;
int line; int line;
void setBasic(TBasicType bt, TQualifier q, int ln = 0) void initType(int ln = 0)
{ {
type = bt; type = EbtVoid;
qualifier = q;
size = 1; size = 1;
matrix = false; matrix = false;
array = false; array = false;
...@@ -86,6 +92,18 @@ public: ...@@ -86,6 +92,18 @@ public:
line = ln; line = ln;
} }
void initQualifiers(bool global = false)
{
qualifier.storage = global ? EvqGlobal : EvqTemporary;
qualifier.precision = EpqNone;
}
void init(int line = 0, bool global = false)
{
initType(line);
initQualifiers(global);
}
void setAggregate(int s, bool m = false) void setAggregate(int s, bool m = false)
{ {
size = s; size = s;
...@@ -107,22 +125,28 @@ typedef std::map<TTypeList*, TTypeList*>::iterator TStructureMapIterator; ...@@ -107,22 +125,28 @@ typedef std::map<TTypeList*, TTypeList*>::iterator TStructureMapIterator;
class TType { class TType {
public: public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator) POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
explicit TType(TBasicType t, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) : explicit TType(TBasicType t, TStorageQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
type(t), qualifier(q), size(s), matrix(m), array(a), arraySize(0), type(t), size(s), matrix(m), array(a), arraySize(0),
structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0) structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0),
{ } fieldName(0), mangled(0), typeName(0) {
qualifier.storage = q;
qualifier.precision = EpqNone;
}
explicit TType(const TPublicType &p) : explicit TType(const TPublicType &p) :
type(p.type), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize), type(p.type), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize),
structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0) structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
{ {
if (p.userDef) { qualifier = p.qualifier;
structure = p.userDef->getStruct(); if (p.userDef) {
typeName = NewPoolTString(p.userDef->getTypeName().c_str()); structure = p.userDef->getStruct();
} typeName = NewPoolTString(p.userDef->getTypeName().c_str());
}
} }
explicit TType(TTypeList* userDef, const TString& n) : explicit TType(TTypeList* userDef, const TString& n) :
type(EbtStruct), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0), type(EbtStruct), size(1), matrix(false), array(false), arraySize(0),
structure(userDef), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0) { structure(userDef), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0) {
qualifier.storage = EvqTemporary;
qualifier.precision = EpqNone;
typeName = NewPoolTString(n.c_str()); typeName = NewPoolTString(n.c_str());
} }
explicit TType() {} explicit TType() {}
...@@ -180,47 +204,47 @@ public: ...@@ -180,47 +204,47 @@ public:
return newType; return newType;
} }
virtual void setType(TBasicType t, int s, bool m, bool a, int aS = 0) virtual void setType(TBasicType t, int s, bool m, bool a, int aS = 0)
{ type = t; size = s; matrix = m; array = a; arraySize = aS; } { type = t; size = s; matrix = m; array = a; arraySize = aS; }
virtual void setType(TBasicType t, int s, bool m, TType* userDef = 0) virtual void setType(TBasicType t, int s, bool m, TType* userDef = 0)
{ type = t; { type = t;
size = s; size = s;
matrix = m; matrix = m;
if (userDef) if (userDef)
structure = userDef->getStruct(); structure = userDef->getStruct();
// leave array information intact. // leave array information intact.
} }
virtual void setTypeName(const TString& n) { typeName = NewPoolTString(n.c_str()); } virtual void setTypeName(const TString& n) { typeName = NewPoolTString(n.c_str()); }
virtual void setFieldName(const TString& n) { fieldName = NewPoolTString(n.c_str()); } virtual void setFieldName(const TString& n) { fieldName = NewPoolTString(n.c_str()); }
virtual const TString& getTypeName() const virtual const TString& getTypeName() const
{ {
assert(typeName); assert(typeName);
return *typeName; return *typeName;
} }
virtual const TString& getFieldName() const virtual const TString& getFieldName() const
{ {
assert(fieldName); assert(fieldName);
return *fieldName; return *fieldName;
} }
virtual TBasicType getBasicType() const { return type; } virtual TBasicType getBasicType() const { return type; }
virtual TQualifier getQualifier() const { return qualifier; } virtual TQualifier& getQualifier() { return qualifier; }
virtual void changeQualifier(TQualifier q) { qualifier = q; } virtual const TQualifier& getQualifier() const { return qualifier; }
// One-dimensional size of single instance type // One-dimensional size of single instance type
virtual int getNominalSize() const { return size; } virtual int getNominalSize() const { return size; }
// Full-dimensional size of single instance of type // Full-dimensional size of single instance of type
virtual int getInstanceSize() const virtual int getInstanceSize() const
{ {
if (matrix) if (matrix)
return size * size; return size * size;
else else
return size; return size;
} }
virtual bool isMatrix() const { return matrix ? true : false; } virtual bool isMatrix() const { return matrix ? true : false; }
virtual bool isArray() const { return array ? true : false; } virtual bool isArray() const { return array ? true : false; }
int getArraySize() const { return arraySize; } int getArraySize() const { return arraySize; }
...@@ -251,18 +275,19 @@ public: ...@@ -251,18 +275,19 @@ public:
} }
} }
const char* getBasicString() const { return TType::getBasicString(type); } const char* getBasicString() const { return TType::getBasicString(type); }
const char* getQualifierString() const { return ::getQualifierString(qualifier); } const char* getStorageQualifierString() const { return ::getStorageQualifierString(qualifier.storage); }
const char* getPrecisionQualifierString() const { return ::getPrecisionQualifierString(qualifier.precision); }
TTypeList* getStruct() { return structure; } TTypeList* getStruct() { return structure; }
int getObjectSize() const int getObjectSize() const
{ {
int totalSize; int totalSize;
if (getBasicType() == EbtStruct) if (getBasicType() == EbtStruct)
totalSize = getStructSize(); totalSize = getStructSize();
else if (matrix) else if (matrix)
totalSize = size * size; totalSize = size * size;
else else
totalSize = size; totalSize = size;
if (isArray()) if (isArray())
...@@ -275,10 +300,10 @@ public: ...@@ -275,10 +300,10 @@ public:
TString& getMangledName() { TString& getMangledName() {
if (!mangled) { if (!mangled) {
mangled = NewPoolTString(""); mangled = NewPoolTString("");
buildMangledName(*mangled); buildMangledName(*mangled);
*mangled += ';' ; *mangled += ';' ;
} }
return *mangled; return *mangled;
} }
bool sameElementType(const TType& right) const { bool sameElementType(const TType& right) const {
...@@ -299,16 +324,17 @@ public: ...@@ -299,16 +324,17 @@ public:
return !operator==(right); return !operator==(right);
} }
TString getCompleteString() const; TString getCompleteString() const;
protected: protected:
void buildMangledName(TString&); void buildMangledName(TString&);
int getStructSize() const; int getStructSize() const;
TBasicType type : 6; TBasicType type : 8;
TQualifier qualifier : 7;
int size : 8; // size of vector or matrix, not size of array int size : 8; // size of vector or matrix, not size of array
unsigned int matrix : 1; unsigned int matrix : 1;
unsigned int array : 1; unsigned int array : 1;
TQualifier qualifier;
int arraySize; int arraySize;
TTypeList* structure; // 0 unless this is a struct TTypeList* structure; // 0 unless this is a struct
......
...@@ -285,14 +285,14 @@ public: ...@@ -285,14 +285,14 @@ public:
virtual TType* getTypePointer() { return &type; } virtual TType* getTypePointer() { return &type; }
virtual TBasicType getBasicType() const { return type.getBasicType(); } virtual TBasicType getBasicType() const { return type.getBasicType(); }
virtual TQualifier getQualifier() const { return type.getQualifier(); } virtual TQualifier& getQualifier() { return type.getQualifier(); }
virtual int getNominalSize() const { return type.getNominalSize(); } virtual int getNominalSize() const { return type.getNominalSize(); }
virtual int getSize() const { return type.getInstanceSize(); } virtual int getSize() const { return type.getInstanceSize(); }
virtual bool isMatrix() const { return type.isMatrix(); } virtual bool isMatrix() const { return type.isMatrix(); }
virtual bool isArray() const { return type.isArray(); } virtual bool isArray() const { return type.isArray(); }
virtual bool isVector() const { return type.isVector(); } virtual bool isVector() const { return type.isVector(); }
const char* getBasicString() const { return type.getBasicString(); } const char* getBasicString() const { return type.getBasicString(); }
const char* getQualifierString() const { return type.getQualifierString(); } const char* getStorageQualifierString() const { return type.getStorageQualifierString(); }
TString getCompleteString() const { return type.getCompleteString(); } TString getCompleteString() const { return type.getCompleteString(); }
protected: protected:
...@@ -451,7 +451,7 @@ public: ...@@ -451,7 +451,7 @@ public:
virtual void traverse(TIntermTraverser*); virtual void traverse(TIntermTraverser*);
virtual void setUserDefined() { userDefined = true; } virtual void setUserDefined() { userDefined = true; }
virtual bool isUserDefined() { return userDefined; } virtual bool isUserDefined() { return userDefined; }
virtual TQualifierList& getQualifier() { return qualifier; } virtual TQualifierList& getQualifierList() { return qualifier; }
void setOptimize(bool o) { optimize = o; } void setOptimize(bool o) { optimize = o; }
void setDebug(bool d) { debug = d; } void setDebug(bool d) { debug = d; }
bool getOptimize() { return optimize; } bool getOptimize() { return optimize; }
......
...@@ -546,13 +546,14 @@ TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nod ...@@ -546,13 +546,14 @@ TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nod
TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc line) TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
{ {
if (left->getType().getQualifier() == EvqConst && right->getType().getQualifier() == EvqConst) { if (left->getType().getQualifier().storage == EvqConst &&
right->getType().getQualifier().storage == EvqConst) {
return right; return right;
} else { } else {
TIntermTyped *commaAggregate = growAggregate(left, right, line); TIntermTyped *commaAggregate = growAggregate(left, right, line);
commaAggregate->getAsAggregate()->setOperator(EOpComma); commaAggregate->getAsAggregate()->setOperator(EOpComma);
commaAggregate->setType(right->getType()); commaAggregate->setType(right->getType());
commaAggregate->getTypePointer()->changeQualifier(EvqTemporary); commaAggregate->getTypePointer()->getQualifier().storage = EvqTemporary;
return commaAggregate; return commaAggregate;
} }
} }
...@@ -830,7 +831,11 @@ bool TIntermBinary::promote(TInfoSink& infoSink) ...@@ -830,7 +831,11 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
// operand. Then only deviations from this need be coded. // operand. Then only deviations from this need be coded.
// //
setType(left->getType()); setType(left->getType());
type.changeQualifier(EvqTemporary); type.getQualifier().storage = EvqTemporary;
// Fix precision qualifiers
if (right->getQualifier().precision > getQualifier().precision)
getQualifier().precision = right->getQualifier().precision;
// //
// Array operations. // Array operations.
...@@ -1510,7 +1515,8 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC ...@@ -1510,7 +1515,8 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
const TType& t = node->getType(); const TType& t = node->getType();
return addConstantUnion(leftUnionArray, TType(promoteTo, t.getQualifier(), t.getNominalSize(), t.isMatrix(), t.isArray()), node->getLine()); return addConstantUnion(leftUnionArray, TType(promoteTo, t.getQualifier().storage, t.getNominalSize(), t.isMatrix(),
t.isArray()), node->getLine());
} }
void TIntermAggregate::addToPragmaTable(const TPragmaTable& pTable) void TIntermAggregate::addToPragmaTable(const TPragmaTable& pTable)
......
...@@ -44,6 +44,25 @@ ...@@ -44,6 +44,25 @@
// //
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, EShLanguage L, TInfoSink& is) :
intermediate(interm), symbolTable(symt), infoSink(is), language(L), treeRoot(0),
recoveredFromError(false), numErrors(0), lexAfterType(false), loopNestingLevel(0),
switchNestingLevel(0), inTypeParen(false),
version(110), profile(ENoProfile), futureCompatibility(false),
contextPragma(true, false)
{
// Default precisions for version 110, to be overridden for
// other versions/profiles/stage combinations
for (int type = 0; type < EbtNumTypes; ++type)
defaultPrecision[type] = EpqHigh;
defaultPrecision[EbtVoid] = EpqNone;
defaultPrecision[EbtDouble] = EpqNone;
defaultPrecision[EbtBool] = EpqNone;
defaultPrecision[EbtVoid] = EpqNone;
}
// //
// Look at a '.' field selector string and change it into offsets // Look at a '.' field selector string and change it into offsets
// for a vector. // for a vector.
...@@ -331,7 +350,7 @@ bool TParseContext::lValueErrorCheck(int line, char* op, TIntermTyped* node) ...@@ -331,7 +350,7 @@ bool TParseContext::lValueErrorCheck(int line, char* op, TIntermTyped* node)
symbol = symNode->getSymbol().c_str(); symbol = symNode->getSymbol().c_str();
char* message = 0; char* message = 0;
switch (node->getQualifier()) { switch (node->getQualifier().storage) {
case EvqConst: message = "can't modify a const"; break; case EvqConst: message = "can't modify a const"; break;
case EvqConstReadOnly: message = "can't modify a const"; break; case EvqConstReadOnly: message = "can't modify a const"; break;
case EvqAttribute: message = "can't modify an attribute"; break; case EvqAttribute: message = "can't modify an attribute"; break;
...@@ -395,7 +414,7 @@ bool TParseContext::lValueErrorCheck(int line, char* op, TIntermTyped* node) ...@@ -395,7 +414,7 @@ bool TParseContext::lValueErrorCheck(int line, char* op, TIntermTyped* node)
// //
bool TParseContext::constErrorCheck(TIntermTyped* node) bool TParseContext::constErrorCheck(TIntermTyped* node)
{ {
if (node->getQualifier() == EvqConst) if (node->getQualifier().storage == EvqConst)
return false; return false;
error(node->getLine(), "constant expression required", "", ""); error(node->getLine(), "constant expression required", "", "");
...@@ -503,14 +522,14 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction ...@@ -503,14 +522,14 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
overFull = true; overFull = true;
if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize()) if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize())
full = true; full = true;
if (function[i].type->getQualifier() != EvqConst) if (function[i].type->getQualifier().storage != EvqConst)
constType = false; constType = false;
if (function[i].type->isArray()) if (function[i].type->isArray())
arrayArg = true; arrayArg = true;
} }
if (constType) if (constType)
type->changeQualifier(EvqConst); type->getQualifier().storage = EvqConst;
if (type->isArray() && type->getArraySize() != function.getParamCount()) { if (type->isArray() && type->getArraySize() != function.getParamCount()) {
error(line, "array constructor needs one argument per array element", "constructor", ""); error(line, "array constructor needs one argument per array element", "constructor", "");
...@@ -623,19 +642,19 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const ...@@ -623,19 +642,19 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const
bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualifier) bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualifier)
{ {
switch (qualifier) { switch (qualifier.storage) {
case EvqIn: case EvqIn:
profileRequires(line, ENoProfile, 130, 0, "in for stage inputs"); profileRequires(line, ENoProfile, 130, 0, "in for stage inputs");
profileRequires(line, EEsProfile, 300, 0, "in for stage inputs"); profileRequires(line, EEsProfile, 300, 0, "in for stage inputs");
qualifier = EvqVaryingIn; qualifier.storage = EvqVaryingIn;
break; break;
case EvqOut: case EvqOut:
profileRequires(line, ENoProfile, 130, 0, "out for stage outputs"); profileRequires(line, ENoProfile, 130, 0, "out for stage outputs");
profileRequires(line, EEsProfile, 300, 0, "out for stage outputs"); profileRequires(line, EEsProfile, 300, 0, "out for stage outputs");
qualifier = EvqVaryingOut; qualifier.storage = EvqVaryingOut;
break; break;
case EvqInOut: case EvqInOut:
qualifier = EvqVaryingIn; qualifier.storage = EvqVaryingIn;
error(line, "cannot use 'inout' at global scope", "", ""); error(line, "cannot use 'inout' at global scope", "", "");
return true; return true;
...@@ -646,20 +665,34 @@ bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualif ...@@ -646,20 +665,34 @@ bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualif
bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType) bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType)
{ {
if ((pType.qualifier == EvqVaryingIn || pType.qualifier == EvqVaryingOut || pType.qualifier == EvqAttribute) && if ((pType.qualifier.storage == EvqVaryingIn ||
pType.qualifier.storage == EvqVaryingOut ||
pType.qualifier.storage == EvqAttribute) &&
pType.type == EbtStruct) { pType.type == EbtStruct) {
error(line, "cannot be used with a structure", getQualifierString(pType.qualifier), "");
error(line, "cannot be used with a structure", getStorageQualifierString(pType.qualifier.storage), "");
return true; return true;
} }
if (pType.qualifier != EvqUniform && samplerErrorCheck(line, pType, "samplers must be uniform")) if (pType.qualifier.storage != EvqUniform && samplerErrorCheck(line, pType, "samplers must be uniform"))
return true; return true;
return false; return false;
} }
bool TParseContext::parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type) void TParseContext::setDefaultPrecision(int line, TBasicType type, TPrecisionQualifier qualifier)
{
// TODO: push and pop for nested scopes
if (IsSampler(type) || type == EbtInt || type == EbtFloat) {
defaultPrecision[type] = qualifier;
} else {
error(line, "cannot apply precision statement to this type", TType::getBasicString(type), "");
recover();
}
}
bool TParseContext::parameterSamplerErrorCheck(int line, TStorageQualifier qualifier, const TType& type)
{ {
if ((qualifier == EvqOut || qualifier == EvqInOut) && if ((qualifier == EvqOut || qualifier == EvqInOut) &&
type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) { type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) {
...@@ -741,12 +774,12 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size) ...@@ -741,12 +774,12 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
// //
bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type) bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type)
{ {
if (type.qualifier == EvqAttribute) { if (type.qualifier.storage == EvqAttribute) {
error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str(), ""); error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str(), "");
return true; return true;
} }
if (type.qualifier == EvqConst) if (type.qualifier.storage == EvqConst)
profileRequires(line, ENoProfile, 120, "GL_3DL_array_objects", "const array"); profileRequires(line, ENoProfile, 120, "GL_3DL_array_objects", "const array");
return false; return false;
...@@ -899,8 +932,8 @@ bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPubli ...@@ -899,8 +932,8 @@ bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPubli
// //
// Make the qualifier make sense. // Make the qualifier make sense.
// //
if (type.qualifier == EvqConst) { if (type.qualifier.storage == EvqConst) {
type.qualifier = EvqTemporary; type.qualifier.storage = EvqTemporary;
error(line, "variables with qualifier 'const' must be initialized", identifier.c_str(), ""); error(line, "variables with qualifier 'const' must be initialized", identifier.c_str(), "");
return true; return true;
} }
...@@ -933,24 +966,24 @@ bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType ...@@ -933,24 +966,24 @@ bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType
return false; return false;
} }
bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TType* type) bool TParseContext::paramErrorCheck(int line, TStorageQualifier qualifier, TType* type)
{ {
switch (qualifier) { switch (qualifier) {
case EvqConst: case EvqConst:
case EvqConstReadOnly: case EvqConstReadOnly:
type->changeQualifier(EvqConstReadOnly); type->getQualifier().storage = EvqConstReadOnly;
return false; return false;
case EvqIn: case EvqIn:
case EvqOut: case EvqOut:
case EvqInOut: case EvqInOut:
type->changeQualifier(qualifier); type->getQualifier().storage = qualifier;
return false; return false;
case EvqTemporary: case EvqTemporary:
type->changeQualifier(EvqIn); type->getQualifier().storage = EvqIn;
return false; return false;
default: default:
type->changeQualifier(EvqIn); type->getQualifier().storage = EvqIn;
error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier), ""); error(line, "qualifier not allowed on function parameter", getStorageQualifierString(qualifier), "");
return true; return true;
} }
} }
...@@ -1016,9 +1049,9 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu ...@@ -1016,9 +1049,9 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
// //
// identifier must be of type constant, a global, or a temporary // identifier must be of type constant, a global, or a temporary
// //
TQualifier qualifier = variable->getType().getQualifier(); TStorageQualifier qualifier = variable->getType().getQualifier().storage;
if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) { if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) {
error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString(), ""); error(line, " cannot initialize this type of qualifier ", variable->getType().getStorageQualifierString(), "");
return true; return true;
} }
// //
...@@ -1026,15 +1059,15 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu ...@@ -1026,15 +1059,15 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
// //
if (qualifier == EvqConst) { if (qualifier == EvqConst) {
if (qualifier != initializer->getType().getQualifier()) { if (qualifier != initializer->getType().getQualifier().storage) {
error(line, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str()); error(line, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str());
variable->getType().changeQualifier(EvqTemporary); variable->getType().getQualifier().storage = EvqTemporary;
return true; return true;
} }
if (type != initializer->getType()) { if (type != initializer->getType()) {
error(line, " non-matching types for const initializer ", error(line, " non-matching types for const initializer ",
variable->getType().getQualifierString(), ""); variable->getType().getStorageQualifierString(), "");
variable->getType().changeQualifier(EvqTemporary); variable->getType().getQualifier().storage = EvqTemporary;
return true; return true;
} }
if (initializer->getAsConstantUnion()) { if (initializer->getAsConstantUnion()) {
...@@ -1053,7 +1086,7 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu ...@@ -1053,7 +1086,7 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
variable->shareConstPointer(constArray); variable->shareConstPointer(constArray);
} else { } else {
error(line, " cannot assign to", "=", "'%s'", variable->getType().getCompleteString().c_str()); error(line, " cannot assign to", "=", "'%s'", variable->getType().getCompleteString().c_str());
variable->getType().changeQualifier(EvqTemporary); variable->getType().getQualifier().storage = EvqTemporary;
return true; return true;
} }
} }
......
...@@ -45,7 +45,7 @@ struct TMatrixFields { ...@@ -45,7 +45,7 @@ struct TMatrixFields {
bool wholeRow; bool wholeRow;
bool wholeCol; bool wholeCol;
int row; int row;
int col; int col;
}; };
typedef enum { typedef enum {
...@@ -67,12 +67,7 @@ struct TPragma { ...@@ -67,12 +67,7 @@ struct TPragma {
// they can be passed to the parser without needing a global. // they can be passed to the parser without needing a global.
// //
struct TParseContext { struct TParseContext {
TParseContext(TSymbolTable& symt, TIntermediate& interm, EShLanguage L, TInfoSink& is) : TParseContext(TSymbolTable& symt, TIntermediate& interm, EShLanguage L, TInfoSink& is);
intermediate(interm), symbolTable(symt), infoSink(is), language(L), treeRoot(0),
recoveredFromError(false), numErrors(0), lexAfterType(false), loopNestingLevel(0),
switchNestingLevel(0), inTypeParen(false),
version(110), profile(ENoProfile), futureCompatibility(false),
contextPragma(true, false) { }
TIntermediate& intermediate; // to hold and build a parse tree TIntermediate& intermediate; // to hold and build a parse tree
TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed
TInfoSink& infoSink; TInfoSink& infoSink;
...@@ -91,18 +86,19 @@ struct TParseContext { ...@@ -91,18 +86,19 @@ struct TParseContext {
EProfile profile; // the declared profile in the shader (core by default) EProfile profile; // the declared profile in the shader (core by default)
bool futureCompatibility; // true if requesting errors for future compatibility (false by default) bool futureCompatibility; // true if requesting errors for future compatibility (false by default)
TMap<TString, TBehavior> extensionBehavior; // for each extension string, what it's current enablement is TMap<TString, TBehavior> extensionBehavior; // for each extension string, what it's current enablement is
struct TPragma contextPragma; struct TPragma contextPragma;
TString HashErrMsg; TPrecisionQualifier defaultPrecision[EbtNumTypes];
TString HashErrMsg;
bool AfterEOF; bool AfterEOF;
void initializeExtensionBehavior(); void initializeExtensionBehavior();
void C_DECL error(TSourceLoc, const char *szReason, const char *szToken, void C_DECL error(TSourceLoc, const char *szReason, const char *szToken,
const char *szExtraInfoFormat, ...); const char *szExtraInfoFormat, ...);
bool reservedErrorCheck(int line, const TString& identifier); bool reservedErrorCheck(int line, const TString& identifier);
void recover(); void recover();
bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line); bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line);
bool parseMatrixFields(const TString&, int matSize, TMatrixFields&, int line); bool parseMatrixFields(const TString&, int matSize, TMatrixFields&, int line);
void assignError(int line, const char* op, TString left, TString right); void assignError(int line, const char* op, TString left, TString right);
...@@ -125,13 +121,14 @@ struct TParseContext { ...@@ -125,13 +121,14 @@ struct TParseContext {
bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason); bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason);
bool globalQualifierFixAndErrorCheck(int line, TQualifier&); bool globalQualifierFixAndErrorCheck(int line, TQualifier&);
bool structQualifierErrorCheck(int line, const TPublicType& pType); bool structQualifierErrorCheck(int line, const TPublicType& pType);
bool parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type); void setDefaultPrecision(int line, TBasicType, TPrecisionQualifier);
bool parameterSamplerErrorCheck(int line, TStorageQualifier qualifier, const TType& type);
bool containsSampler(TType& type); bool containsSampler(TType& type);
bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type); bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type);
bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type); bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type);
bool paramErrorCheck(int line, TQualifier qualifier, TType* type); bool paramErrorCheck(int line, TStorageQualifier qualifier, TType* type);
const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0); const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0);
bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType, bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0); TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
bool areAllChildConst(TIntermAggregate* aggrNode); bool areAllChildConst(TIntermAggregate* aggrNode);
TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, TSourceLoc); TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, TSourceLoc);
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
class TAliveTraverser : public TIntermTraverser { class TAliveTraverser : public TIntermTraverser {
public: public:
TAliveTraverser(TQualifier q) : TIntermTraverser(), found(false), qualifier(q) TAliveTraverser(TStorageQualifier q) : TIntermTraverser(), found(false), qualifier(q)
{ {
visitSymbol = AliveSymbol; visitSymbol = AliveSymbol;
visitSelection = AliveSelection; visitSelection = AliveSelection;
...@@ -45,7 +45,7 @@ public: ...@@ -45,7 +45,7 @@ public:
bool wasFound() { return found; } bool wasFound() { return found; }
protected: protected:
bool found; bool found;
TQualifier qualifier; TStorageQualifier qualifier;
friend void AliveSymbol(TIntermSymbol*, TIntermTraverser*); friend void AliveSymbol(TIntermSymbol*, TIntermTraverser*);
friend bool AliveSelection(bool, TIntermSelection*, TIntermTraverser*); friend bool AliveSelection(bool, TIntermSelection*, TIntermTraverser*);
...@@ -59,7 +59,7 @@ protected: ...@@ -59,7 +59,7 @@ protected:
// ?? It does not do this well yet, this is just a place holder // ?? It does not do this well yet, this is just a place holder
// that simply determines if it was reference at all, anywhere. // that simply determines if it was reference at all, anywhere.
// //
bool QualifierWritten(TIntermNode* node, TQualifier qualifier) bool QualifierWritten(TIntermNode* node, TStorageQualifier qualifier)
{ {
TAliveTraverser it(qualifier); TAliveTraverser it(qualifier);
...@@ -76,7 +76,7 @@ void AliveSymbol(TIntermSymbol* node, TIntermTraverser* it) ...@@ -76,7 +76,7 @@ void AliveSymbol(TIntermSymbol* node, TIntermTraverser* it)
// //
// If it's what we're looking for, record it. // If it's what we're looking for, record it.
// //
if (node->getQualifier() == lit->qualifier) if (node->getQualifier().storage == lit->qualifier)
lit->found = true; lit->found = true;
} }
......
...@@ -32,4 +32,4 @@ ...@@ -32,4 +32,4 @@
//POSSIBILITY OF SUCH DAMAGE. //POSSIBILITY OF SUCH DAMAGE.
// //
bool QualifierWritten(TIntermNode* root, TQualifier); bool QualifierWritten(TIntermNode* root, TStorageQualifier);
...@@ -92,12 +92,11 @@ int ShInitialize() ...@@ -92,12 +92,11 @@ int ShInitialize()
SetGlobalPoolAllocatorPtr(gPoolAllocator); SetGlobalPoolAllocatorPtr(gPoolAllocator);
symTables[EShLangVertex].pop(); symTables[EShLangVertex].pop(0);
symTables[EShLangFragment].pop(); symTables[EShLangFragment].pop(0);
builtInPoolAllocator->popAll(); builtInPoolAllocator->popAll();
delete builtInPoolAllocator; delete builtInPoolAllocator;
} }
return ret ? 1 : 0; return ret ? 1 : 0;
...@@ -343,7 +342,7 @@ int ShCompile( ...@@ -343,7 +342,7 @@ int ShCompile(
// throwing away all but the built-ins. // throwing away all but the built-ins.
// //
while (! symbolTable.atSharedBuiltInLevel()) while (! symbolTable.atSharedBuiltInLevel())
symbolTable.pop(); symbolTable.pop(0);
FinalizePreprocessor(); FinalizePreprocessor();
// //
......
...@@ -111,7 +111,7 @@ int TType::getStructSize() const ...@@ -111,7 +111,7 @@ int TType::getStructSize() const
void TVariable::dump(TInfoSink& infoSink) const void TVariable::dump(TInfoSink& infoSink) const
{ {
infoSink.debug << getName().c_str() << ": " << type.getQualifierString() << " " << type.getBasicString(); infoSink.debug << getName().c_str() << ": " << type.getStorageQualifierString() << " " << type.getBasicString();
if (type.isArray()) { if (type.isArray()) {
infoSink.debug << "[0]"; infoSink.debug << "[0]";
} }
...@@ -154,6 +154,8 @@ TSymbolTableLevel::~TSymbolTableLevel() ...@@ -154,6 +154,8 @@ TSymbolTableLevel::~TSymbolTableLevel()
{ {
for (tLevel::iterator it = level.begin(); it != level.end(); ++it) for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
delete (*it).second; delete (*it).second;
delete [] defaultPrecision;
} }
// //
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
// so that symbol table lookups are never ambiguous. This allows // so that symbol table lookups are never ambiguous. This allows
// a simpler symbol table structure. // a simpler symbol table structure.
// //
// * Pushing and popping of scope, so symbol table will really be a stack // * Pushing and popping of scope, so symbol table will really be a stack
// of symbol tables. Searched from the top, with new inserts going into // of symbol tables. Searched from the top, with new inserts going into
// the top. // the top.
// //
...@@ -61,11 +61,11 @@ ...@@ -61,11 +61,11 @@
#include "../Include/Common.h" #include "../Include/Common.h"
#include "../Include/intermediate.h" #include "../Include/intermediate.h"
#include "../Include/InfoSink.h" #include "../Include/InfoSink.h"
// //
// Symbol base class. (Can build functions or variables out of these...) // Symbol base class. (Can build functions or variables out of these...)
// //
class TSymbol { class TSymbol {
public: public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator) POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
TSymbol(const TString *n) : name(n) { } TSymbol(const TString *n) : name(n) { }
...@@ -87,29 +87,29 @@ protected: ...@@ -87,29 +87,29 @@ protected:
// //
// Variable class, meaning a symbol that's not a function. // Variable class, meaning a symbol that's not a function.
// //
// There could be a separate class heirarchy for Constant variables; // There could be a separate class heirarchy for Constant variables;
// Only one of int, bool, or float, (or none) is correct for // Only one of int, bool, or float, (or none) is correct for
// any particular use, but it's easy to do this way, and doesn't // any particular use, but it's easy to do this way, and doesn't
// seem worth having separate classes, and "getConst" can't simply return // seem worth having separate classes, and "getConst" can't simply return
// different values for different types polymorphically, so this is // different values for different types polymorphically, so this is
// just simple and pragmatic. // just simple and pragmatic.
// //
class TVariable : public TSymbol { class TVariable : public TSymbol {
public: public:
TVariable(const TString *name, const TType& t, bool uT = false ) : TSymbol(name), type(t), userType(uT), unionArray(0), arrayInformationType(0) { } TVariable(const TString *name, const TType& t, bool uT = false ) : TSymbol(name), type(t), userType(uT), unionArray(0), arrayInformationType(0) { }
virtual ~TVariable() { } virtual ~TVariable() { }
virtual bool isVariable() const { return true; } virtual bool isVariable() const { return true; }
TType& getType() { return type; } TType& getType() { return type; }
const TType& getType() const { return type; } const TType& getType() const { return type; }
bool isUserType() const { return userType; } bool isUserType() const { return userType; }
void changeQualifier(TQualifier qualifier) { type.changeQualifier(qualifier); } void setStorageQualifier(TStorageQualifier qualifier) { type.getQualifier().storage = qualifier; }
void updateArrayInformationType(TType *t) { arrayInformationType = t; } void updateArrayInformationType(TType *t) { arrayInformationType = t; }
TType* getArrayInformationType() { return arrayInformationType; } TType* getArrayInformationType() { return arrayInformationType; }
virtual void dump(TInfoSink &infoSink) const; virtual void dump(TInfoSink &infoSink) const;
constUnion* getConstPointer() { constUnion* getConstPointer() {
if (!unionArray) if (!unionArray)
unionArray = new constUnion[type.getObjectSize()]; unionArray = new constUnion[type.getObjectSize()];
...@@ -121,11 +121,11 @@ public: ...@@ -121,11 +121,11 @@ public:
void shareConstPointer( constUnion *constArray) void shareConstPointer( constUnion *constArray)
{ {
delete unionArray; delete unionArray;
unionArray = constArray; unionArray = constArray;
} }
TVariable(const TVariable&, TStructureMap& remapper); // copy constructor TVariable(const TVariable&, TStructureMap& remapper); // copy constructor
virtual TVariable* clone(TStructureMap& remapper); virtual TVariable* clone(TStructureMap& remapper);
protected: protected:
TType type; TType type;
bool userType; bool userType;
...@@ -149,7 +149,7 @@ struct TParameter { ...@@ -149,7 +149,7 @@ struct TParameter {
}; };
// //
// The function sub-class of a symbol. // The function sub-class of a symbol.
// //
class TFunction : public TSymbol { class TFunction : public TSymbol {
public: public:
...@@ -158,21 +158,21 @@ public: ...@@ -158,21 +158,21 @@ public:
returnType(TType(EbtVoid)), returnType(TType(EbtVoid)),
op(o), op(o),
defined(false) { } defined(false) { }
TFunction(const TString *name, TType& retType, TOperator tOp = EOpNull) : TFunction(const TString *name, TType& retType, TOperator tOp = EOpNull) :
TSymbol(name), TSymbol(name),
returnType(retType), returnType(retType),
mangledName(*name + '('), mangledName(*name + '('),
op(tOp), op(tOp),
defined(false) { } defined(false) { }
virtual ~TFunction(); virtual ~TFunction();
virtual bool isFunction() const { return true; } virtual bool isFunction() const { return true; }
void addParameter(TParameter& p) void addParameter(TParameter& p)
{ {
parameters.push_back(p); parameters.push_back(p);
mangledName = mangledName + p.type->getMangledName(); mangledName = mangledName + p.type->getMangledName();
} }
const TString& getMangledName() const { return mangledName; } const TString& getMangledName() const { return mangledName; }
const TType& getReturnType() const { return returnType; } const TType& getReturnType() const { return returnType; }
void relateToOperator(TOperator o) { op = o; } void relateToOperator(TOperator o) { op = o; }
...@@ -180,14 +180,14 @@ public: ...@@ -180,14 +180,14 @@ public:
void setDefined() { defined = true; } void setDefined() { defined = true; }
bool isDefined() { return defined; } bool isDefined() { return defined; }
int getParamCount() const { return static_cast<int>(parameters.size()); } int getParamCount() const { return static_cast<int>(parameters.size()); }
TParameter& operator [](int i) { return parameters[i]; } TParameter& operator [](int i) { return parameters[i]; }
const TParameter& operator [](int i) const { return parameters[i]; } const TParameter& operator [](int i) const { return parameters[i]; }
virtual void dump(TInfoSink &infoSink) const; virtual void dump(TInfoSink &infoSink) const;
TFunction(const TFunction&, TStructureMap& remapper); TFunction(const TFunction&, TStructureMap& remapper);
virtual TFunction* clone(TStructureMap& remapper); virtual TFunction* clone(TStructureMap& remapper);
protected: protected:
typedef TVector<TParameter> TParamList; typedef TVector<TParameter> TParamList;
TParamList parameters; TParamList parameters;
...@@ -201,17 +201,17 @@ protected: ...@@ -201,17 +201,17 @@ protected:
class TSymbolTableLevel { class TSymbolTableLevel {
public: public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator) POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
TSymbolTableLevel() { } TSymbolTableLevel() : defaultPrecision (0) { }
~TSymbolTableLevel(); ~TSymbolTableLevel();
bool insert(TSymbol& symbol) bool insert(TSymbol& symbol)
{ {
// //
// returning true means symbol was added to the table // returning true means symbol was added to the table
// //
tInsertResult result; tInsertResult result;
result = level.insert(tLevelPair(symbol.getMangledName(), &symbol)); result = level.insert(tLevelPair(symbol.getMangledName(), &symbol));
return result.second; return result.second;
} }
...@@ -224,17 +224,44 @@ public: ...@@ -224,17 +224,44 @@ public:
return (*it).second; return (*it).second;
} }
// Use this to do a lazy 'push' of precision defaults the first time
// a precision statement is seen in a new scope. Leave it at 0 for
// when no push was needed. Thus, it is not the current defaults,
// it is what to restore the defaults to when popping a level.
void setPreviousDefaultPrecisions(const TPrecisionQualifier *p)
{
// can call multiple times at one scope, will only latch on first call,
// as we're tracking the previous scope's values, not the current values
if (defaultPrecision != 0)
return;
defaultPrecision = new TPrecisionQualifier[EbtNumTypes];
for (int t = 0; t < EbtNumTypes; ++t)
defaultPrecision[t] = p[t];
}
void getPreviousDefaultPrecisions(TPrecisionQualifier *p)
{
// can be called for table level pops that didn't set the
// defaults
if (defaultPrecision == 0 || p == 0)
return;
for (int t = 0; t < EbtNumTypes; ++t)
p[t] = defaultPrecision[t];
}
void relateToOperator(const char* name, TOperator op); void relateToOperator(const char* name, TOperator op);
void dump(TInfoSink &infoSink) const; void dump(TInfoSink &infoSink) const;
TSymbolTableLevel* clone(TStructureMap& remapper); TSymbolTableLevel* clone(TStructureMap& remapper);
protected: protected:
typedef std::map<TString, TSymbol*, std::less<TString>, pool_allocator<std::pair<const TString, TSymbol*> > > tLevel; typedef std::map<TString, TSymbol*, std::less<TString>, pool_allocator<std::pair<const TString, TSymbol*> > > tLevel;
typedef const tLevel::value_type tLevelPair; typedef const tLevel::value_type tLevelPair;
typedef std::pair<tLevel::iterator, bool> tInsertResult; typedef std::pair<tLevel::iterator, bool> tInsertResult;
tLevel level; tLevel level;
TPrecisionQualifier *defaultPrecision;
}; };
class TSymbolTable { class TSymbolTable {
...@@ -258,7 +285,7 @@ public: ...@@ -258,7 +285,7 @@ public:
{ {
// level 0 is always built In symbols, so we never pop that out // level 0 is always built In symbols, so we never pop that out
while (table.size() > 1) while (table.size() > 1)
pop(); pop(0);
} }
// //
...@@ -270,13 +297,17 @@ public: ...@@ -270,13 +297,17 @@ public:
bool atBuiltInLevel() { return atSharedBuiltInLevel() || atDynamicBuiltInLevel(); } bool atBuiltInLevel() { return atSharedBuiltInLevel() || atDynamicBuiltInLevel(); }
bool atSharedBuiltInLevel() { return table.size() == 1; } bool atSharedBuiltInLevel() { return table.size() == 1; }
bool atGlobalLevel() { return table.size() <= 3; } bool atGlobalLevel() { return table.size() <= 3; }
void push() {
void push()
{
table.push_back(new TSymbolTableLevel); table.push_back(new TSymbolTableLevel);
} }
void pop() { void pop(TPrecisionQualifier *p)
delete table[currentLevel()]; {
table.pop_back(); table[currentLevel()]->getPreviousDefaultPrecisions(p);
delete table[currentLevel()];
table.pop_back();
} }
bool insert(TSymbol& symbol) bool insert(TSymbol& symbol)
...@@ -284,8 +315,8 @@ public: ...@@ -284,8 +315,8 @@ public:
symbol.setUniqueId(++uniqueId); symbol.setUniqueId(++uniqueId);
return table[currentLevel()]->insert(symbol); return table[currentLevel()]->insert(symbol);
} }
TSymbol* find(const TString& name, bool* builtIn = 0, bool *sameScope = 0) TSymbol* find(const TString& name, bool* builtIn = 0, bool *sameScope = 0)
{ {
int level = currentLevel(); int level = currentLevel();
TSymbol* symbol; TSymbol* symbol;
...@@ -307,7 +338,9 @@ public: ...@@ -307,7 +338,9 @@ public:
void dump(TInfoSink &infoSink) const; void dump(TInfoSink &infoSink) const;
void copyTable(const TSymbolTable& copyOf); void copyTable(const TSymbolTable& copyOf);
protected: void setPreviousDefaultPrecisions(TPrecisionQualifier *p) { table[currentLevel()]->setPreviousDefaultPrecisions(p); }
protected:
int currentLevel() const { return static_cast<int>(table.size()) - 1; } int currentLevel() const { return static_cast<int>(table.size()) - 1; }
bool atDynamicBuiltInLevel() { return table.size() == 2; } bool atDynamicBuiltInLevel() { return table.size() == 2; }
......
...@@ -732,6 +732,24 @@ void SetVersion(int version) ...@@ -732,6 +732,24 @@ void SetVersion(int version)
{ {
TParseContext& parseContext = *((TParseContext *)cpp->pC); TParseContext& parseContext = *((TParseContext *)cpp->pC);
parseContext.version = version; parseContext.version = version;
if (version == 100 || version == 300) {
for (int type = 0; type < EbtNumTypes; ++type)
parseContext.defaultPrecision[type] = EpqNone;
if (parseContext.language == EShLangVertex) {
parseContext.defaultPrecision[EbtInt] = EpqHigh;
parseContext.defaultPrecision[EbtFloat] = EpqHigh;
parseContext.defaultPrecision[EbtSampler2D] = EpqLow;
parseContext.defaultPrecision[EbtSamplerCube] = EpqLow;
}
if (parseContext.language == EShLangFragment) {
parseContext.defaultPrecision[EbtInt] = EpqMedium;
parseContext.defaultPrecision[EbtSampler2D] = EpqLow;
parseContext.defaultPrecision[EbtSamplerCube] = EpqLow;
}
}
} }
const int FirstProfileVersion = 150; const int FirstProfileVersion = 150;
......
...@@ -96,7 +96,6 @@ Jutta Degener, 1995 ...@@ -96,7 +96,6 @@ Jutta Degener, 1995
}; };
union { union {
TPublicType type; TPublicType type;
TQualifier qualifier;
TFunction* function; TFunction* function;
TParameter param; TParameter param;
TTypeLine typeLine; TTypeLine typeLine;
...@@ -235,7 +234,7 @@ variable_identifier ...@@ -235,7 +234,7 @@ variable_identifier
// don't delete $1.string, it's used by error recovery, and the pool // don't delete $1.string, it's used by error recovery, and the pool
// pop will reclaim the memory // pop will reclaim the memory
if (variable->getType().getQualifier() == EvqConst ) { if (variable->getType().getQualifier().storage == EvqConst ) {
constUnion* constArray = variable->getConstPointer(); constUnion* constArray = variable->getConstPointer();
TType t(variable->getType()); TType t(variable->getType());
$$ = parseContext.intermediate.addConstantUnion(constArray, t, $1.line); $$ = parseContext.intermediate.addConstantUnion(constArray, t, $1.line);
...@@ -293,7 +292,7 @@ postfix_expression ...@@ -293,7 +292,7 @@ postfix_expression
parseContext.error($2.line, " left of '[' is not of type array, matrix, or vector ", "expression", ""); parseContext.error($2.line, " left of '[' is not of type array, matrix, or vector ", "expression", "");
parseContext.recover(); parseContext.recover();
} }
if ($1->getType().getQualifier() == EvqConst && $3->getQualifier() == EvqConst) { if ($1->getType().getQualifier().storage == EvqConst && $3->getQualifier().storage == EvqConst) {
if ($1->isArray()) { // constant folding for arrays if ($1->isArray()) { // constant folding for arrays
$$ = parseContext.addConstArrayNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.line); $$ = parseContext.addConstArrayNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.line);
} else if ($1->isVector()) { // constant folding for vectors } else if ($1->isVector()) { // constant folding for vectors
...@@ -305,7 +304,7 @@ postfix_expression ...@@ -305,7 +304,7 @@ postfix_expression
$$ = parseContext.addConstMatrixNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.line); $$ = parseContext.addConstMatrixNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.line);
} }
} else { } else {
if ($3->getQualifier() == EvqConst) { if ($3->getQualifier().storage == EvqConst) {
if (($1->isVector() || $1->isMatrix()) && $1->getType().getNominalSize() <= $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() && !$1->isArray() ) { if (($1->isVector() || $1->isMatrix()) && $1->getType().getNominalSize() <= $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() && !$1->isArray() ) {
parseContext.error($2.line, "", "[", "field selection out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst()); parseContext.error($2.line, "", "[", "field selection out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst());
parseContext.recover(); parseContext.recover();
...@@ -345,13 +344,13 @@ postfix_expression ...@@ -345,13 +344,13 @@ postfix_expression
else else
$$->setType(TType($1->getBasicType(), EvqTemporary, $1->getNominalSize(), $1->isMatrix())); $$->setType(TType($1->getBasicType(), EvqTemporary, $1->getNominalSize(), $1->isMatrix()));
if ($1->getType().getQualifier() == EvqConst) if ($1->getType().getQualifier().storage == EvqConst)
$$->getTypePointer()->changeQualifier(EvqConst); $$->getTypePointer()->getQualifier().storage = EvqConst;
} else if ($1->isMatrix() && $1->getType().getQualifier() == EvqConst) } else if ($1->isMatrix() && $1->getType().getQualifier().storage == EvqConst)
$$->setType(TType($1->getBasicType(), EvqConst, $1->getNominalSize())); $$->setType(TType($1->getBasicType(), EvqConst, $1->getNominalSize()));
else if ($1->isMatrix()) else if ($1->isMatrix())
$$->setType(TType($1->getBasicType(), EvqTemporary, $1->getNominalSize())); $$->setType(TType($1->getBasicType(), EvqTemporary, $1->getNominalSize()));
else if ($1->isVector() && $1->getType().getQualifier() == EvqConst) else if ($1->isVector() && $1->getType().getQualifier().storage == EvqConst)
$$->setType(TType($1->getBasicType(), EvqConst)); $$->setType(TType($1->getBasicType(), EvqConst));
else if ($1->isVector()) else if ($1->isVector())
$$->setType(TType($1->getBasicType(), EvqTemporary)); $$->setType(TType($1->getBasicType(), EvqTemporary));
...@@ -387,7 +386,7 @@ postfix_expression ...@@ -387,7 +386,7 @@ postfix_expression
parseContext.recover(); parseContext.recover();
} }
if ($1->getType().getQualifier() == EvqConst) { // constant folding for vector fields if ($1->getType().getQualifier().storage == EvqConst) { // constant folding for vector fields
$$ = parseContext.addConstVectorNode(fields, $1, $3.line); $$ = parseContext.addConstVectorNode(fields, $1, $3.line);
if ($$ == 0) { if ($$ == 0) {
parseContext.recover(); parseContext.recover();
...@@ -450,7 +449,7 @@ postfix_expression ...@@ -450,7 +449,7 @@ postfix_expression
} }
} }
if (fieldFound) { if (fieldFound) {
if ($1->getType().getQualifier() == EvqConst) { if ($1->getType().getQualifier().storage == EvqConst) {
$$ = parseContext.addConstStruct(*$3.string, $1, $2.line); $$ = parseContext.addConstStruct(*$3.string, $1, $2.line);
if ($$ == 0) { if ($$ == 0) {
parseContext.recover(); parseContext.recover();
...@@ -460,7 +459,7 @@ postfix_expression ...@@ -460,7 +459,7 @@ postfix_expression
$$->setType(*(*fields)[i].type); $$->setType(*(*fields)[i].type);
// change the qualifier of the return type, not of the structure field // change the qualifier of the return type, not of the structure field
// as the structure definition is shared between various structures. // as the structure definition is shared between various structures.
$$->getTypePointer()->changeQualifier(EvqConst); $$->getTypePointer()->getQualifier().storage = EvqConst;
} }
} else { } else {
constUnion *unionArray = new constUnion[1]; constUnion *unionArray = new constUnion[1];
...@@ -593,10 +592,10 @@ function_call ...@@ -593,10 +592,10 @@ function_call
$$->getAsAggregate()->setUserDefined(); $$->getAsAggregate()->setUserDefined();
$$->getAsAggregate()->setName(fnCandidate->getMangledName()); $$->getAsAggregate()->setName(fnCandidate->getMangledName());
TQualifier qual; TStorageQualifier qual;
TQualifierList& qualifierList = $$->getAsAggregate()->getQualifier(); TQualifierList& qualifierList = $$->getAsAggregate()->getQualifierList();
for (int i = 0; i < fnCandidate->getParamCount(); ++i) { for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
qual = (*fnCandidate)[i].type->getQualifier(); qual = (*fnCandidate)[i].type->getQualifier().storage;
if (qual == EvqOut || qual == EvqInOut) { if (qual == EvqOut || qual == EvqInOut) {
if (parseContext.lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) { if (parseContext.lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) {
parseContext.error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", ""); parseContext.error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", "");
...@@ -682,6 +681,7 @@ function_identifier ...@@ -682,6 +681,7 @@ function_identifier
parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "array"); parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "array");
} }
$1.qualifier.precision = EpqNone;
if ($1.userDef) { if ($1.userDef) {
TString tempString = ""; TString tempString = "";
TType type($1); TType type($1);
...@@ -1122,6 +1122,11 @@ declaration ...@@ -1122,6 +1122,11 @@ declaration
} }
| PRECISION precision_qualifier type_specifier SEMICOLON { | PRECISION precision_qualifier type_specifier SEMICOLON {
parseContext.profileRequires($1.line, ENoProfile, 130, 0, "precision statement"); parseContext.profileRequires($1.line, ENoProfile, 130, 0, "precision statement");
// lazy setting of the previous scope's defaults, only takes on first one in a particular scope
parseContext.symbolTable.setPreviousDefaultPrecisions(&parseContext.defaultPrecision[0]);
parseContext.setDefaultPrecision($1.line, $3.type, $2.qualifier.precision);
$$ = 0; $$ = 0;
} }
| type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE SEMICOLON { | type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE SEMICOLON {
...@@ -1176,8 +1181,9 @@ function_prototype ...@@ -1176,8 +1181,9 @@ function_prototype
parseContext.recover(); parseContext.recover();
} }
for (int i = 0; i < prevDec->getParamCount(); ++i) { for (int i = 0; i < prevDec->getParamCount(); ++i) {
if ((*prevDec)[i].type->getQualifier() != (*$1)[i].type->getQualifier()) { if ((*prevDec)[i].type->getQualifier().storage != (*$1)[i].type->getQualifier().storage) {
parseContext.error($2.line, "overloaded functions must have the same parameter qualifiers", (*$1)[i].type->getQualifierString(), ""); parseContext.error($2.line, "overloaded functions must have the same parameter qualifiers",
(*$1)[i].type->getStorageQualifierString(), "");
parseContext.recover(); parseContext.recover();
} }
} }
...@@ -1236,8 +1242,9 @@ function_header_with_parameters ...@@ -1236,8 +1242,9 @@ function_header_with_parameters
function_header function_header
: fully_specified_type IDENTIFIER LEFT_PAREN { : fully_specified_type IDENTIFIER LEFT_PAREN {
if ($1.qualifier != EvqGlobal && $1.qualifier != EvqTemporary) { if ($1.qualifier.storage != EvqGlobal && $1.qualifier.storage != EvqTemporary) {
parseContext.error($2.line, "no qualifiers allowed for function return", getQualifierString($1.qualifier), ""); parseContext.error($2.line, "no qualifiers allowed for function return",
getStorageQualifierString($1.qualifier.storage), "");
parseContext.recover(); parseContext.recover();
} }
// make sure a sampler is not involved as well... // make sure a sampler is not involved as well...
...@@ -1261,6 +1268,7 @@ parameter_declarator ...@@ -1261,6 +1268,7 @@ parameter_declarator
} }
if (parseContext.reservedErrorCheck($2.line, *$2.string)) if (parseContext.reservedErrorCheck($2.line, *$2.string))
parseContext.recover(); parseContext.recover();
TParameter param = {$2.string, new TType($1)}; TParameter param = {$2.string, new TType($1)};
$$.line = $2.line; $$.line = $2.line;
$$.param = param; $$.param = param;
...@@ -1286,10 +1294,12 @@ parameter_declaration ...@@ -1286,10 +1294,12 @@ parameter_declaration
// //
: type_qualifier parameter_declarator { : type_qualifier parameter_declarator {
$$ = $2; $$ = $2;
if ($1.qualifier.precision != EpqNone)
$$.param.type->getQualifier().precision = $1.qualifier.precision;
if (parseContext.parameterSamplerErrorCheck($2.line, $1.qualifier, *$2.param.type)) if (parseContext.parameterSamplerErrorCheck($2.line, $1.qualifier.storage, *$$.param.type))
parseContext.recover(); parseContext.recover();
if (parseContext.paramErrorCheck($1.line, $1.qualifier, $$.param.type)) if (parseContext.paramErrorCheck($1.line, $1.qualifier.storage, $$.param.type))
parseContext.recover(); parseContext.recover();
} }
| parameter_declarator { | parameter_declarator {
...@@ -1305,16 +1315,18 @@ parameter_declaration ...@@ -1305,16 +1315,18 @@ parameter_declaration
// //
| type_qualifier parameter_type_specifier { | type_qualifier parameter_type_specifier {
$$ = $2; $$ = $2;
if ($1.qualifier.precision != EpqNone)
$$.param.type->getQualifier().precision = $1.qualifier.precision;
if (parseContext.parameterSamplerErrorCheck($2.line, $1.qualifier, *$2.param.type)) if (parseContext.parameterSamplerErrorCheck($2.line, $1.qualifier.storage, *$$.param.type))
parseContext.recover(); parseContext.recover();
if (parseContext.paramErrorCheck($1.line, $1.qualifier, $$.param.type)) if (parseContext.paramErrorCheck($1.line, $1.qualifier.storage, $$.param.type))
parseContext.recover(); parseContext.recover();
} }
| parameter_type_specifier { | parameter_type_specifier {
$$ = $1; $$ = $1;
if (parseContext.parameterSamplerErrorCheck($1.line, $1.qualifier, *$1.param.type)) if (parseContext.parameterSamplerErrorCheck($1.line, EvqIn, *$1.param.type))
parseContext.recover(); parseContext.recover();
if (parseContext.paramErrorCheck($1.line, EvqTemporary, $$.param.type)) if (parseContext.paramErrorCheck($1.line, EvqTemporary, $$.param.type))
parseContext.recover(); parseContext.recover();
...@@ -1535,18 +1547,20 @@ fully_specified_type ...@@ -1535,18 +1547,20 @@ fully_specified_type
$2.setArray(false); $2.setArray(false);
} }
if ($1.qualifier == EvqAttribute && if ($1.qualifier.storage == EvqAttribute &&
($2.type == EbtBool || $2.type == EbtInt)) { ($2.type == EbtBool || $2.type == EbtInt)) {
parseContext.error($2.line, "cannot be bool or int", getQualifierString($1.qualifier), ""); parseContext.error($2.line, "cannot be bool or int", getStorageQualifierString($1.qualifier.storage), "");
parseContext.recover(); parseContext.recover();
} }
if (($1.qualifier == EvqVaryingIn || $1.qualifier == EvqVaryingOut) && if (($1.qualifier.storage == EvqVaryingIn || $1.qualifier.storage == EvqVaryingOut) &&
($2.type == EbtBool || $2.type == EbtInt)) { ($2.type == EbtBool || $2.type == EbtInt)) {
parseContext.error($2.line, "cannot be bool or int", getQualifierString($1.qualifier), ""); parseContext.error($2.line, "cannot be bool or int", getStorageQualifierString($1.qualifier.storage), "");
parseContext.recover(); parseContext.recover();
} }
$$ = $2; $$ = $2;
$$.qualifier = $1.qualifier; $$.qualifier = $1.qualifier;
if ($$.qualifier.precision == EpqNone)
$$.qualifier.precision = $2.qualifier.precision;
} }
; ;
...@@ -1601,15 +1615,18 @@ type_qualifier ...@@ -1601,15 +1615,18 @@ type_qualifier
$$.type = $2.type; $$.type = $2.type;
} }
if ($$.qualifier == EvqTemporary) { if ($$.qualifier.storage == EvqTemporary) {
$$.qualifier = $2.qualifier; $$.qualifier.storage = $2.qualifier.storage;
} else if ($$.qualifier == EvqIn && $2.qualifier == EvqOut || } else if ($$.qualifier.storage == EvqIn && $2.qualifier.storage == EvqOut ||
$$.qualifier == EvqOut && $2.qualifier == EvqIn) { $$.qualifier.storage == EvqOut && $2.qualifier.storage == EvqIn) {
$$.qualifier = EvqInOut; $$.qualifier.storage = EvqInOut;
} else if ($$.qualifier == EvqIn && $2.qualifier == EvqConst || } else if ($$.qualifier.storage == EvqIn && $2.qualifier.storage == EvqConst ||
$$.qualifier == EvqConst && $2.qualifier == EvqIn) { $$.qualifier.storage == EvqConst && $2.qualifier.storage == EvqIn) {
$$.qualifier = EvqConstReadOnly; $$.qualifier.storage = EvqConstReadOnly;
} }
if ($$.qualifier.precision == EpqNone)
$$.qualifier.precision = $2.qualifier.precision;
} }
; ;
...@@ -1639,7 +1656,8 @@ single_type_qualifier ...@@ -1639,7 +1656,8 @@ single_type_qualifier
storage_qualifier storage_qualifier
: CONST { : CONST {
$$.setBasic(EbtVoid, EvqConst, $1.line); $$.init($1.line);
$$.qualifier.storage = EvqConst;
} }
| ATTRIBUTE { | ATTRIBUTE {
parseContext.requireStage($1.line, EShLangVertexMask, "attribute"); parseContext.requireStage($1.line, EShLangVertexMask, "attribute");
...@@ -1649,7 +1667,9 @@ storage_qualifier ...@@ -1649,7 +1667,9 @@ storage_qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "attribute")) if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "attribute"))
parseContext.recover(); parseContext.recover();
$$.setBasic(EbtVoid, EvqAttribute, $1.line);
$$.init($1.line);
$$.qualifier.storage = EvqAttribute;
} }
| VARYING { | VARYING {
parseContext.checkDeprecated($1.line, ENoProfile, 140, "varying"); parseContext.checkDeprecated($1.line, ENoProfile, 140, "varying");
...@@ -1657,97 +1677,115 @@ storage_qualifier ...@@ -1657,97 +1677,115 @@ storage_qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "varying")) if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "varying"))
parseContext.recover(); parseContext.recover();
if (parseContext.language == EShLangVertex)
$$.setBasic(EbtVoid, EvqVaryingOut, $1.line); $$.init($1.line);
if (parseContext.language == EShLangVertex)
$$.qualifier.storage = EvqVaryingOut;
else else
$$.setBasic(EbtVoid, EvqVaryingIn, $1.line); $$.qualifier.storage = EvqVaryingIn;
} }
| INOUT { | INOUT {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "out")) if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "out"))
parseContext.recover(); parseContext.recover();
$$.setBasic(EbtVoid, EvqInOut, $1.line); $$.init($1.line);
$$.qualifier.storage = EvqInOut;
} }
| IN { | IN {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "in")) if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "in"))
parseContext.recover(); parseContext.recover();
$$.setBasic(EbtVoid, EvqIn, $1.line); $$.init($1.line);
$$.qualifier.storage = EvqIn;
} }
| OUT { | OUT {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "out")) if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "out"))
parseContext.recover(); parseContext.recover();
$$.setBasic(EbtVoid, EvqOut, $1.line); $$.init($1.line);
$$.qualifier.storage = EvqOut;
} }
| CENTROID { | CENTROID {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "centroid")) if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "centroid"))
parseContext.recover(); parseContext.recover();
$$.setBasic(EbtVoid, EvqVaryingIn, $1.line); $$.init($1.line);
$$.qualifier.storage = EvqVaryingIn;
} }
| PATCH { | PATCH {
// TODO: implement this qualifier // TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "patch")) if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "patch"))
parseContext.recover(); parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line); $$.init($1.line);
$$.qualifier.storage = EvqUniform;
} }
| SAMPLE { | SAMPLE {
// TODO: implement this qualifier // TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "sample")) if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "sample"))
parseContext.recover(); parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line); $$.init($1.line);
$$.qualifier.storage = EvqUniform;
} }
| UNIFORM { | UNIFORM {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "uniform")) if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "uniform"))
parseContext.recover(); parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line); $$.init($1.line);
$$.qualifier.storage = EvqUniform;
} }
| BUFFER { | BUFFER {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "buffer")) if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "buffer"))
parseContext.recover(); parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line); $$.init($1.line);
$$.qualifier.storage = EvqUniform;
} }
| SHARED { | SHARED {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "shared")) if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "shared"))
parseContext.recover(); parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line); $$.init($1.line);
$$.qualifier.storage = EvqUniform;
} }
| COHERENT { | COHERENT {
// TODO: implement this qualifier // TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "coherent")) if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "coherent"))
parseContext.recover(); parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line); $$.init($1.line);
$$.qualifier.storage = EvqUniform;
} }
| VOLATILE { | VOLATILE {
// TODO: implement this qualifier // TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "volatile")) if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "volatile"))
parseContext.recover(); parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line); $$.init($1.line);
$$.qualifier.storage = EvqUniform;
} }
| RESTRICT { | RESTRICT {
// TODO: implement this qualifier // TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "restrict")) if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "restrict"))
parseContext.recover(); parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line); $$.init($1.line);
$$.qualifier.storage = EvqUniform;
} }
| READONLY { | READONLY {
// TODO: implement this qualifier // TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "readonly")) if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "readonly"))
parseContext.recover(); parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line); $$.init($1.line);
$$.qualifier.storage = EvqUniform;
} }
| WRITEONLY { | WRITEONLY {
// TODO: implement this qualifier // TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "writeonly")) if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "writeonly"))
parseContext.recover(); parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line); $$.init($1.line);
$$.qualifier.storage = EvqUniform;
} }
| SUBROUTINE { | SUBROUTINE {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "subroutine")) if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "subroutine"))
parseContext.recover(); parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line); $$.init($1.line);
$$.qualifier.storage = EvqUniform;
} }
| SUBROUTINE LEFT_PAREN type_name_list RIGHT_PAREN { | SUBROUTINE LEFT_PAREN type_name_list RIGHT_PAREN {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "subroutine")) if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "subroutine"))
parseContext.recover(); parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line); $$.init($1.line);
$$.qualifier.storage = EvqUniform;
// TODO: subroutine semantics // TODO: subroutine semantics
// 1) make sure each identifier is a type declared earlier with SUBROUTINE // 1) make sure each identifier is a type declared earlier with SUBROUTINE
// 2) save all of the identifiers for future comparison with the declared function // 2) save all of the identifiers for future comparison with the declared function
...@@ -1766,9 +1804,11 @@ type_name_list ...@@ -1766,9 +1804,11 @@ type_name_list
type_specifier type_specifier
: type_specifier_nonarray { : type_specifier_nonarray {
$$ = $1; $$ = $1;
$$.qualifier.precision = parseContext.defaultPrecision[$$.type];
} }
| type_specifier_nonarray array_specifier { | type_specifier_nonarray array_specifier {
$$ = $1; $$ = $1;
$$.qualifier.precision = parseContext.defaultPrecision[$$.type];
$$.setArray(true, $2.intVector->front()); $$.setArray(true, $2.intVector->front());
} }
; ;
...@@ -1804,588 +1844,587 @@ array_specifier ...@@ -1804,588 +1844,587 @@ array_specifier
type_specifier_nonarray type_specifier_nonarray
: VOID { : VOID {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtVoid, qual, $1.line); $$.type = EbtVoid;
} }
| FLOAT { | FLOAT {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtFloat, qual, $1.line); $$.type = EbtFloat;
} }
| DOUBLE { | DOUBLE {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
// TODO: implement EbtDouble, check all float types $$.type = EbtDouble;
$$.setBasic(EbtDouble, qual, $1.line);
} }
| INT { | INT {
// TODO: implement EbtUint, check all int types $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.type = EbtInt;
$$.setBasic(EbtInt, qual, $1.line);
} }
| UINT { | UINT {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; // TODO: implement EbtUint, check all int types
$$.setBasic(EbtInt, qual, $1.line); $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtInt;
} }
| BOOL { | BOOL {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtBool, qual, $1.line); $$.type = EbtBool;
} }
| VEC2 { | VEC2 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtFloat, qual, $1.line); $$.type = EbtFloat;
$$.setAggregate(2); $$.setAggregate(2);
} }
| VEC3 { | VEC3 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtFloat, qual, $1.line); $$.type = EbtFloat;
$$.setAggregate(3); $$.setAggregate(3);
} }
| VEC4 { | VEC4 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtFloat, qual, $1.line); $$.type = EbtFloat;
$$.setAggregate(4); $$.setAggregate(4);
} }
| DVEC2 { | DVEC2 {
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtDouble;
$$.setAggregate(2);
} }
| DVEC3 { | DVEC3 {
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtDouble;
$$.setAggregate(3);
} }
| DVEC4 { | DVEC4 {
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtDouble;
$$.setAggregate(4);
} }
| BVEC2 { | BVEC2 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtBool, qual, $1.line); $$.type = EbtBool;
$$.setAggregate(2); $$.setAggregate(2);
} }
| BVEC3 { | BVEC3 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtBool, qual, $1.line); $$.type = EbtBool;
$$.setAggregate(3); $$.setAggregate(3);
} }
| BVEC4 { | BVEC4 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtBool, qual, $1.line); $$.type = EbtBool;
$$.setAggregate(4); $$.setAggregate(4);
} }
| IVEC2 { | IVEC2 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtInt, qual, $1.line); $$.type = EbtInt;
$$.setAggregate(2); $$.setAggregate(2);
} }
| IVEC3 { | IVEC3 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtInt, qual, $1.line); $$.type = EbtInt;
$$.setAggregate(3); $$.setAggregate(3);
} }
| IVEC4 { | IVEC4 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtInt, qual, $1.line); $$.type = EbtInt;
$$.setAggregate(4); $$.setAggregate(4);
} }
| UVEC2 { | UVEC2 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtInt, qual, $1.line); $$.type = EbtInt;
$$.setAggregate(2); $$.setAggregate(2);
} }
| UVEC3 { | UVEC3 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtInt, qual, $1.line); $$.type = EbtInt;
$$.setAggregate(3); $$.setAggregate(3);
} }
| UVEC4 { | UVEC4 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtInt, qual, $1.line); $$.type = EbtInt;
$$.setAggregate(4); $$.setAggregate(4);
} }
| MAT2 { | MAT2 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtFloat, qual, $1.line); $$.type = EbtFloat;
$$.setAggregate(2, true); $$.setAggregate(2, true);
} }
| MAT3 { | MAT3 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtFloat, qual, $1.line); $$.type = EbtFloat;
$$.setAggregate(3, true); $$.setAggregate(3, true);
} }
| MAT4 { | MAT4 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtFloat, qual, $1.line); $$.type = EbtFloat;
$$.setAggregate(4, true); $$.setAggregate(4, true);
} }
| MAT2X2 { | MAT2X2 {
// TODO: implement this type $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.type = EbtFloat;
$$.setBasic(EbtFloat, qual, $1.line); $$.setAggregate(2, true);
$$.setAggregate(4, true);
} }
| MAT2X3 { | MAT2X3 {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtFloat, qual, $1.line); $$.type = EbtFloat;
$$.setAggregate(4, true); $$.setAggregate(3, true);
} }
| MAT2X4 { | MAT2X4 {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtFloat, qual, $1.line); $$.type = EbtFloat;
$$.setAggregate(4, true); $$.setAggregate(4, true);
} }
| MAT3X2 { | MAT3X2 {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtFloat, qual, $1.line); $$.type = EbtFloat;
$$.setAggregate(4, true); $$.setAggregate(3, true);
} }
| MAT3X3 { | MAT3X3 {
// TODO: implement this type $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.type = EbtFloat;
$$.setBasic(EbtFloat, qual, $1.line); $$.setAggregate(3, true);
$$.setAggregate(4, true);
} }
| MAT3X4 { | MAT3X4 {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtFloat, qual, $1.line); $$.type = EbtFloat;
$$.setAggregate(4, true); $$.setAggregate(4, true);
} }
| MAT4X2 { | MAT4X2 {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtFloat, qual, $1.line); $$.type = EbtFloat;
$$.setAggregate(4, true); $$.setAggregate(4, true);
} }
| MAT4X3 { | MAT4X3 {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtFloat, qual, $1.line); $$.type = EbtFloat;
$$.setAggregate(4, true); $$.setAggregate(4, true);
} }
| MAT4X4 { | MAT4X4 {
// TODO: implement this type $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.type = EbtFloat;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true); $$.setAggregate(4, true);
} }
| DMAT2 { | DMAT2 {
// TODO: implement this type $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.type = EbtDouble;
$$.setBasic(EbtFloat, qual, $1.line); $$.setAggregate(2, true);
$$.setAggregate(4, true);
} }
| DMAT3 { | DMAT3 {
// TODO: implement this type $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.type = EbtDouble;
$$.setBasic(EbtFloat, qual, $1.line); $$.setAggregate(3, true);
$$.setAggregate(4, true);
} }
| DMAT4 { | DMAT4 {
// TODO: implement this type $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.type = EbtDouble;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true); $$.setAggregate(4, true);
} }
| DMAT2X2 { | DMAT2X2 {
// TODO: implement this type $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.type = EbtDouble;
$$.setBasic(EbtFloat, qual, $1.line); $$.setAggregate(2, true);
$$.setAggregate(4, true);
} }
| DMAT2X3 { | DMAT2X3 {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtFloat, qual, $1.line); $$.type = EbtDouble;
$$.setAggregate(4, true); $$.setAggregate(3, true);
} }
| DMAT2X4 { | DMAT2X4 {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtFloat, qual, $1.line); $$.type = EbtDouble;
$$.setAggregate(4, true); $$.setAggregate(4, true);
} }
| DMAT3X2 { | DMAT3X2 {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtFloat, qual, $1.line); $$.type = EbtDouble;
$$.setAggregate(4, true); $$.setAggregate(3, true);
} }
| DMAT3X3 { | DMAT3X3 {
// TODO: implement this type $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.type = EbtDouble;
$$.setBasic(EbtFloat, qual, $1.line); $$.setAggregate(3, true);
$$.setAggregate(4, true);
} }
| DMAT3X4 { | DMAT3X4 {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtFloat, qual, $1.line); $$.type = EbtDouble;
$$.setAggregate(4, true); $$.setAggregate(4, true);
} }
| DMAT4X2 { | DMAT4X2 {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtFloat, qual, $1.line); $$.type = EbtDouble;
$$.setAggregate(4, true); $$.setAggregate(4, true);
} }
| DMAT4X3 { | DMAT4X3 {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtFloat, qual, $1.line); $$.type = EbtDouble;
$$.setAggregate(4, true); $$.setAggregate(4, true);
} }
| DMAT4X4 { | DMAT4X4 {
// TODO: implement this type $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.type = EbtDouble;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true); $$.setAggregate(4, true);
} }
| ATOMIC_UINT { | ATOMIC_UINT {
// TODO: add type // TODO: add type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtInt, qual, $1.line); $$.type = EbtInt;
} }
| SAMPLER1D { | SAMPLER1D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler1D, qual, $1.line); $$.type = EbtSampler1D;
} }
| SAMPLER2D { | SAMPLER2D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| SAMPLER3D { | SAMPLER3D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler3D, qual, $1.line); $$.type = EbtSampler3D;
} }
| SAMPLERCUBE { | SAMPLERCUBE {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSamplerCube, qual, $1.line); $$.type = EbtSamplerCube;
} }
| SAMPLER1DSHADOW { | SAMPLER1DSHADOW {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler1DShadow, qual, $1.line); $$.type = EbtSampler1DShadow;
} }
| SAMPLER2DSHADOW { | SAMPLER2DSHADOW {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| SAMPLERCUBESHADOW { | SAMPLERCUBESHADOW {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| SAMPLER1DARRAY { | SAMPLER1DARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| SAMPLER2DARRAY { | SAMPLER2DARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| SAMPLER1DARRAYSHADOW { | SAMPLER1DARRAYSHADOW {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| SAMPLER2DARRAYSHADOW { | SAMPLER2DARRAYSHADOW {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| SAMPLERCUBEARRAY { | SAMPLERCUBEARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| SAMPLERCUBEARRAYSHADOW { | SAMPLERCUBEARRAYSHADOW {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| ISAMPLER1D { | ISAMPLER1D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| ISAMPLER2D { | ISAMPLER2D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| ISAMPLER3D { | ISAMPLER3D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| ISAMPLERCUBE { | ISAMPLERCUBE {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| ISAMPLER1DARRAY { | ISAMPLER1DARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| ISAMPLER2DARRAY { | ISAMPLER2DARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| ISAMPLERCUBEARRAY { | ISAMPLERCUBEARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| USAMPLER1D { | USAMPLER1D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| USAMPLER2D { | USAMPLER2D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| USAMPLER3D { | USAMPLER3D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| USAMPLERCUBE { | USAMPLERCUBE {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| USAMPLER1DARRAY { | USAMPLER1DARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| USAMPLER2DARRAY { | USAMPLER2DARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| USAMPLERCUBEARRAY { | USAMPLERCUBEARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.type = EbtSampler2DShadow;
} }
| SAMPLER2DRECT { | SAMPLER2DRECT {
parseContext.profileRequires($1.line, ENoProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture"); parseContext.profileRequires($1.line, ENoProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSamplerRect, qual, $1.line); $$.type = EbtSamplerRect;
} }
| SAMPLER2DRECTSHADOW { | SAMPLER2DRECTSHADOW {
parseContext.profileRequires($1.line, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture"); parseContext.profileRequires($1.line, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSamplerRectShadow, qual, $1.line); $$.type = EbtSamplerRectShadow;
} }
| ISAMPLER2DRECT { | ISAMPLER2DRECT {
parseContext.profileRequires($1.line, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture"); parseContext.profileRequires($1.line, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSamplerRect, qual, $1.line); $$.type = EbtSamplerRect;
} }
| USAMPLER2DRECT { | USAMPLER2DRECT {
parseContext.profileRequires($1.line, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture"); parseContext.profileRequires($1.line, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSamplerRect, qual, $1.line); $$.type = EbtSamplerRect;
} }
| SAMPLERBUFFER { | SAMPLERBUFFER {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| ISAMPLERBUFFER { | ISAMPLERBUFFER {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| USAMPLERBUFFER { | USAMPLERBUFFER {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| SAMPLER2DMS { | SAMPLER2DMS {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| ISAMPLER2DMS { | ISAMPLER2DMS {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| USAMPLER2DMS { | USAMPLER2DMS {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| SAMPLER2DMSARRAY { | SAMPLER2DMSARRAY {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| ISAMPLER2DMSARRAY { | ISAMPLER2DMSARRAY {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| USAMPLER2DMSARRAY { | USAMPLER2DMSARRAY {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IMAGE1D { | IMAGE1D {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IIMAGE1D { | IIMAGE1D {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| UIMAGE1D { | UIMAGE1D {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IMAGE2D { | IMAGE2D {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IIMAGE2D { | IIMAGE2D {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| UIMAGE2D { | UIMAGE2D {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IMAGE3D { | IMAGE3D {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IIMAGE3D { | IIMAGE3D {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| UIMAGE3D { | UIMAGE3D {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IMAGE2DRECT { | IMAGE2DRECT {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IIMAGE2DRECT { | IIMAGE2DRECT {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| UIMAGE2DRECT { | UIMAGE2DRECT {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IMAGECUBE { | IMAGECUBE {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IIMAGECUBE { | IIMAGECUBE {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| UIMAGECUBE { | UIMAGECUBE {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IMAGEBUFFER { | IMAGEBUFFER {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IIMAGEBUFFER { | IIMAGEBUFFER {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| UIMAGEBUFFER { | UIMAGEBUFFER {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IMAGE1DARRAY { | IMAGE1DARRAY {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IIMAGE1DARRAY { | IIMAGE1DARRAY {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| UIMAGE1DARRAY { | UIMAGE1DARRAY {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IMAGE2DARRAY { | IMAGE2DARRAY {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IIMAGE2DARRAY { | IIMAGE2DARRAY {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| UIMAGE2DARRAY { | UIMAGE2DARRAY {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IMAGECUBEARRAY { | IMAGECUBEARRAY {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IIMAGECUBEARRAY { | IIMAGECUBEARRAY {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| UIMAGECUBEARRAY { | UIMAGECUBEARRAY {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IMAGE2DMS { | IMAGE2DMS {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IIMAGE2DMS { | IIMAGE2DMS {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| UIMAGE2DMS { | UIMAGE2DMS {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IMAGE2DMSARRAY { | IMAGE2DMSARRAY {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| IIMAGE2DMSARRAY { | IIMAGE2DMSARRAY {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| UIMAGE2DMSARRAY { | UIMAGE2DMSARRAY {
// TODO: implement this type // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtSampler2D, qual, $1.line); $$.type = EbtSampler2D;
} }
| struct_specifier { | struct_specifier {
$$ = $1; $$ = $1;
$$.qualifier = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.qualifier.storage = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
} }
| TYPE_NAME { | TYPE_NAME {
// //
...@@ -2393,8 +2432,8 @@ type_specifier_nonarray ...@@ -2393,8 +2432,8 @@ type_specifier_nonarray
// type. // type.
// //
TType& structure = static_cast<TVariable*>($1.symbol)->getType(); TType& structure = static_cast<TVariable*>($1.symbol)->getType();
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.setBasic(EbtStruct, qual, $1.line); $$.type = EbtStruct;
$$.userDef = &structure; $$.userDef = &structure;
} }
; ;
...@@ -2402,12 +2441,18 @@ type_specifier_nonarray ...@@ -2402,12 +2441,18 @@ type_specifier_nonarray
precision_qualifier precision_qualifier
: HIGH_PRECISION { : HIGH_PRECISION {
parseContext.profileRequires($1.line, ENoProfile, 130, 0, "highp precision qualifier"); parseContext.profileRequires($1.line, ENoProfile, 130, 0, "highp precision qualifier");
$$.init($1.line);
$$.qualifier.precision = EpqHigh;
} }
| MEDIUM_PRECISION { | MEDIUM_PRECISION {
parseContext.profileRequires($1.line, ENoProfile, 130, 0, "mediump precision qualifier"); parseContext.profileRequires($1.line, ENoProfile, 130, 0, "mediump precision qualifier");
$$.init($1.line);
$$.qualifier.precision = EpqMedium;
} }
| LOW_PRECISION { | LOW_PRECISION {
parseContext.profileRequires($1.line, ENoProfile, 130, 0, "lowp precision qualifier"); parseContext.profileRequires($1.line, ENoProfile, 130, 0, "lowp precision qualifier");
$$.init($1.line);
$$.qualifier.precision = EpqLow;
} }
; ;
...@@ -2419,12 +2464,14 @@ struct_specifier ...@@ -2419,12 +2464,14 @@ struct_specifier
parseContext.error($2.line, "redefinition", $2.string->c_str(), "struct"); parseContext.error($2.line, "redefinition", $2.string->c_str(), "struct");
parseContext.recover(); parseContext.recover();
} }
$$.setBasic(EbtStruct, EvqTemporary, $1.line); $$.init($1.line);
$$.type = EbtStruct;
$$.userDef = structure; $$.userDef = structure;
} }
| STRUCT LEFT_BRACE struct_declaration_list RIGHT_BRACE { | STRUCT LEFT_BRACE struct_declaration_list RIGHT_BRACE {
TType* structure = new TType($3, TString("")); TType* structure = new TType($3, TString(""));
$$.setBasic(EbtStruct, EvqTemporary, $1.line); $$.init($1.line);
$$.type = EbtStruct;
$$.userDef = structure; $$.userDef = structure;
} }
; ;
...@@ -2555,7 +2602,9 @@ simple_statement ...@@ -2555,7 +2602,9 @@ simple_statement
compound_statement compound_statement
: LEFT_BRACE RIGHT_BRACE { $$ = 0; } : LEFT_BRACE RIGHT_BRACE { $$ = 0; }
| LEFT_BRACE { parseContext.symbolTable.push(); } statement_list { parseContext.symbolTable.pop(); } RIGHT_BRACE { | LEFT_BRACE { parseContext.symbolTable.push(); }
statement_list { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); }
RIGHT_BRACE {
if ($3 != 0) if ($3 != 0)
$3->setOperator(EOpSequence); $3->setOperator(EOpSequence);
$$ = $3; $$ = $3;
...@@ -2660,8 +2709,12 @@ case_label ...@@ -2660,8 +2709,12 @@ case_label
; ;
iteration_statement iteration_statement
: WHILE LEFT_PAREN { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope { : WHILE LEFT_PAREN {
parseContext.symbolTable.pop(); parseContext.symbolTable.push();
++parseContext.loopNestingLevel;
}
condition RIGHT_PAREN statement_no_new_scope {
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
$$ = parseContext.intermediate.addLoop($6, $4, 0, true, $1.line); $$ = parseContext.intermediate.addLoop($6, $4, 0, true, $1.line);
--parseContext.loopNestingLevel; --parseContext.loopNestingLevel;
} }
...@@ -2672,8 +2725,12 @@ iteration_statement ...@@ -2672,8 +2725,12 @@ iteration_statement
$$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.line); $$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.line);
--parseContext.loopNestingLevel; --parseContext.loopNestingLevel;
} }
| FOR LEFT_PAREN { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope { | FOR LEFT_PAREN {
parseContext.symbolTable.pop(); parseContext.symbolTable.push();
++parseContext.loopNestingLevel;
}
for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
$$ = parseContext.intermediate.makeAggregate($4, $2.line); $$ = parseContext.intermediate.makeAggregate($4, $2.line);
$$ = parseContext.intermediate.growAggregate( $$ = parseContext.intermediate.growAggregate(
$$, $$,
...@@ -2867,7 +2924,7 @@ function_definition ...@@ -2867,7 +2924,7 @@ function_definition
parseContext.error($1.line, "function does not return a value:", "", $1.function->getName().c_str()); parseContext.error($1.line, "function does not return a value:", "", $1.function->getName().c_str());
parseContext.recover(); parseContext.recover();
} }
parseContext.symbolTable.pop(); parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
$$ = parseContext.intermediate.growAggregate($1.intermAggregate, $3, 0); $$ = parseContext.intermediate.growAggregate($1.intermAggregate, $3, 0);
parseContext.intermediate.setAggregateOperator($$, EOpFunction, $1.line); parseContext.intermediate.setAggregateOperator($$, EOpFunction, $1.line);
$$->getAsAggregate()->setName($1.function->getMangledName().c_str()); $$->getAsAggregate()->setName($1.function->getMangledName().c_str());
......
...@@ -60,10 +60,12 @@ TString TType::getCompleteString() const ...@@ -60,10 +60,12 @@ TString TType::getCompleteString() const
char *p = &buf[0]; char *p = &buf[0];
char *end = &buf[maxSize]; char *end = &buf[maxSize];
if (qualifier != EvqTemporary && qualifier != EvqGlobal) if (qualifier.storage != EvqTemporary && qualifier.storage != EvqGlobal)
p += sprintf_s(p, end - p, "%s ", getQualifierString()); p += sprintf_s(p, end - p, "%s ", getStorageQualifierString());
if (array) if (array)
p += sprintf_s(p, end - p, "array of "); p += sprintf_s(p, end - p, "array of ");
if (qualifier.precision != EpqNone)
p += sprintf_s(p, end - p, "%s ", getPrecisionQualifierString());
if (matrix) if (matrix)
p += sprintf_s(p, end - p, "%dX%d matrix of ", size, size); p += sprintf_s(p, end - p, "%dX%d matrix of ", size, size);
else if (size > 1) else if (size > 1)
......
...@@ -69,15 +69,15 @@ void ParseSymbol(TIntermSymbol* node, TIntermTraverser* it) ...@@ -69,15 +69,15 @@ void ParseSymbol(TIntermSymbol* node, TIntermTraverser* it)
{ {
TConstTraverser* oit = static_cast<TConstTraverser*>(it); TConstTraverser* oit = static_cast<TConstTraverser*>(it);
oit->infoSink.info.message(EPrefixInternalError, "Symbol Node found in constant constructor", node->getLine()); oit->infoSink.info.message(EPrefixInternalError, "Symbol Node found in constant constructor", node->getLine());
return;
return;
} }
bool ParseBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it) bool ParseBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it)
{ {
TConstTraverser* oit = static_cast<TConstTraverser*>(it); TConstTraverser* oit = static_cast<TConstTraverser*>(it);
TQualifier qualifier = node->getType().getQualifier(); TStorageQualifier qualifier = node->getType().getQualifier().storage;
if (qualifier != EvqConst) { if (qualifier != EvqConst) {
const int maxSize = 200; const int maxSize = 200;
...@@ -85,6 +85,7 @@ bool ParseBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it) ...@@ -85,6 +85,7 @@ bool ParseBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it)
sprintf_s(buf, maxSize, "'constructor' : assigning non-constant to %s", oit->type.getCompleteString().c_str()); sprintf_s(buf, maxSize, "'constructor' : assigning non-constant to %s", oit->type.getCompleteString().c_str());
oit->infoSink.info.message(EPrefixError, buf, node->getLine()); oit->infoSink.info.message(EPrefixError, buf, node->getLine());
oit->error = true; oit->error = true;
return false; return false;
} }
...@@ -102,6 +103,7 @@ bool ParseUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it) ...@@ -102,6 +103,7 @@ bool ParseUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it)
sprintf_s(buf, maxSize, "'constructor' : assigning non-constant to '%s'", oit->type.getCompleteString().c_str()); sprintf_s(buf, maxSize, "'constructor' : assigning non-constant to '%s'", oit->type.getCompleteString().c_str());
oit->infoSink.info.message(EPrefixError, buf, node->getLine()); oit->infoSink.info.message(EPrefixError, buf, node->getLine());
oit->error = true; oit->error = true;
return false; return false;
} }
...@@ -115,11 +117,13 @@ bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverse ...@@ -115,11 +117,13 @@ bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverse
sprintf_s(buf, maxSize, "'constructor' : assigning non-constant to '%s'", oit->type.getCompleteString().c_str()); sprintf_s(buf, maxSize, "'constructor' : assigning non-constant to '%s'", oit->type.getCompleteString().c_str());
oit->infoSink.info.message(EPrefixError, buf, node->getLine()); oit->infoSink.info.message(EPrefixError, buf, node->getLine());
oit->error = true; oit->error = true;
return false; return false;
} }
if (node->getSequence().size() == 0) { if (node->getSequence().size() == 0) {
oit->error = true; oit->error = true;
return false; return false;
} }
...@@ -152,6 +156,7 @@ bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverse ...@@ -152,6 +156,7 @@ bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverse
oit->isMatrix = false; oit->isMatrix = false;
oit->matrixSize = 0; oit->matrixSize = 0;
} }
return false; return false;
} }
...@@ -229,6 +234,7 @@ bool ParseLoop(bool /* preVisit */, TIntermLoop* node, TIntermTraverser* it) ...@@ -229,6 +234,7 @@ bool ParseLoop(bool /* preVisit */, TIntermLoop* node, TIntermTraverser* it)
TConstTraverser* oit = static_cast<TConstTraverser*>(it); TConstTraverser* oit = static_cast<TConstTraverser*>(it);
oit->infoSink.info.message(EPrefixInternalError, "Loop Node found in constant constructor", node->getLine()); oit->infoSink.info.message(EPrefixInternalError, "Loop Node found in constant constructor", node->getLine());
oit->error = true; oit->error = true;
return false; return false;
} }
...@@ -237,6 +243,7 @@ bool ParseBranch(bool /* previsit*/, TIntermBranch* node, TIntermTraverser* it) ...@@ -237,6 +243,7 @@ bool ParseBranch(bool /* previsit*/, TIntermBranch* node, TIntermTraverser* it)
TConstTraverser* oit = static_cast<TConstTraverser*>(it); TConstTraverser* oit = static_cast<TConstTraverser*>(it);
oit->infoSink.info.message(EPrefixInternalError, "Branch Node found in constant constructor", node->getLine()); oit->infoSink.info.message(EPrefixInternalError, "Branch Node found in constant constructor", node->getLine());
oit->error = true; oit->error = true;
return false; return false;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment