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 {
EbtSamplerRectShadow, // ARB_texture_rectangle
EbtGuardSamplerEnd, // non type: see implementation of IsSampler()
EbtStruct,
EbtAddress, // should be deprecated??
EbtNumTypes
};
__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
// 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
EvqGlobal, // For globals read/write
EvqConst, // User defined constants and non-output parameters in functions
......@@ -104,7 +104,7 @@ enum TQualifier {
//
// 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) {
case EvqTemporary: return "Temporary"; break;
......@@ -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_
......@@ -56,13 +56,20 @@ inline TTypeList* NewPoolTTypeList()
//
// 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
// 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
// match up or are name the same or anything like that.
//
class TQualifier {
public:
TStorageQualifier storage : 7;
TPrecisionQualifier precision : 3;
};
class TPublicType {
public:
TBasicType type;
......@@ -74,10 +81,9 @@ public:
TType* userDef;
int line;
void setBasic(TBasicType bt, TQualifier q, int ln = 0)
{
type = bt;
qualifier = q;
void initType(int ln = 0)
{
type = EbtVoid;
size = 1;
matrix = false;
array = false;
......@@ -86,6 +92,18 @@ public:
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)
{
size = s;
......@@ -107,22 +125,28 @@ typedef std::map<TTypeList*, TTypeList*>::iterator TStructureMapIterator;
class TType {
public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
explicit TType(TBasicType t, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
type(t), qualifier(q), size(s), matrix(m), array(a), arraySize(0),
structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
{ }
explicit TType(TBasicType t, TStorageQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
type(t), size(s), matrix(m), array(a), arraySize(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) :
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)
{
if (p.userDef) {
structure = p.userDef->getStruct();
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
}
qualifier = p.qualifier;
if (p.userDef) {
structure = p.userDef->getStruct();
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
}
}
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) {
qualifier.storage = EvqTemporary;
qualifier.precision = EpqNone;
typeName = NewPoolTString(n.c_str());
}
explicit TType() {}
......@@ -180,47 +204,47 @@ public:
return newType;
}
virtual void setType(TBasicType t, int s, bool m, bool a, int aS = 0)
{ type = t; size = s; matrix = m; array = a; arraySize = aS; }
virtual void setType(TBasicType t, int s, bool m, TType* userDef = 0)
{ type = t;
size = s;
matrix = m;
{ type = t;
size = s;
matrix = m;
if (userDef)
structure = userDef->getStruct();
structure = userDef->getStruct();
// leave array information intact.
}
virtual void setTypeName(const TString& n) { typeName = NewPoolTString(n.c_str()); }
virtual void setFieldName(const TString& n) { fieldName = NewPoolTString(n.c_str()); }
virtual const TString& getTypeName() const
{
{
assert(typeName);
return *typeName;
return *typeName;
}
virtual const TString& getFieldName() const
{
{
assert(fieldName);
return *fieldName;
return *fieldName;
}
virtual TBasicType getBasicType() const { return type; }
virtual TQualifier getQualifier() const { return qualifier; }
virtual void changeQualifier(TQualifier q) { qualifier = q; }
virtual TQualifier& getQualifier() { return qualifier; }
virtual const TQualifier& getQualifier() const { return qualifier; }
// 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
virtual int getInstanceSize() const
virtual int getInstanceSize() const
{
if (matrix)
return size * size;
else
return size;
}
virtual bool isMatrix() const { return matrix ? true : false; }
virtual bool isArray() const { return array ? true : false; }
int getArraySize() const { return arraySize; }
......@@ -251,18 +275,19 @@ public:
}
}
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; }
int getObjectSize() const
{
int totalSize;
if (getBasicType() == EbtStruct)
totalSize = getStructSize();
else if (matrix)
totalSize = size * size;
else
totalSize = size * size;
else
totalSize = size;
if (isArray())
......@@ -275,10 +300,10 @@ public:
TString& getMangledName() {
if (!mangled) {
mangled = NewPoolTString("");
buildMangledName(*mangled);
buildMangledName(*mangled);
*mangled += ';' ;
}
return *mangled;
}
bool sameElementType(const TType& right) const {
......@@ -299,16 +324,17 @@ public:
return !operator==(right);
}
TString getCompleteString() const;
protected:
void buildMangledName(TString&);
int getStructSize() const;
TBasicType type : 6;
TQualifier qualifier : 7;
TBasicType type : 8;
int size : 8; // size of vector or matrix, not size of array
unsigned int matrix : 1;
unsigned int array : 1;
TQualifier qualifier;
int arraySize;
TTypeList* structure; // 0 unless this is a struct
......
......@@ -285,14 +285,14 @@ public:
virtual TType* getTypePointer() { return &type; }
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 getSize() const { return type.getInstanceSize(); }
virtual bool isMatrix() const { return type.isMatrix(); }
virtual bool isArray() const { return type.isArray(); }
virtual bool isVector() const { return type.isVector(); }
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(); }
protected:
......@@ -451,7 +451,7 @@ public:
virtual void traverse(TIntermTraverser*);
virtual void setUserDefined() { userDefined = true; }
virtual bool isUserDefined() { return userDefined; }
virtual TQualifierList& getQualifier() { return qualifier; }
virtual TQualifierList& getQualifierList() { return qualifier; }
void setOptimize(bool o) { optimize = o; }
void setDebug(bool d) { debug = d; }
bool getOptimize() { return optimize; }
......
......@@ -546,13 +546,14 @@ TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nod
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;
} else {
TIntermTyped *commaAggregate = growAggregate(left, right, line);
commaAggregate->getAsAggregate()->setOperator(EOpComma);
commaAggregate->setType(right->getType());
commaAggregate->getTypePointer()->changeQualifier(EvqTemporary);
commaAggregate->getTypePointer()->getQualifier().storage = EvqTemporary;
return commaAggregate;
}
}
......@@ -830,7 +831,11 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
// operand. Then only deviations from this need be coded.
//
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.
......@@ -1510,7 +1515,8 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
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)
......
......@@ -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
// for a vector.
......@@ -331,7 +350,7 @@ bool TParseContext::lValueErrorCheck(int line, char* op, TIntermTyped* node)
symbol = symNode->getSymbol().c_str();
char* message = 0;
switch (node->getQualifier()) {
switch (node->getQualifier().storage) {
case EvqConst: 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;
......@@ -395,7 +414,7 @@ bool TParseContext::lValueErrorCheck(int line, char* op, TIntermTyped* node)
//
bool TParseContext::constErrorCheck(TIntermTyped* node)
{
if (node->getQualifier() == EvqConst)
if (node->getQualifier().storage == EvqConst)
return false;
error(node->getLine(), "constant expression required", "", "");
......@@ -503,14 +522,14 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
overFull = true;
if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize())
full = true;
if (function[i].type->getQualifier() != EvqConst)
if (function[i].type->getQualifier().storage != EvqConst)
constType = false;
if (function[i].type->isArray())
arrayArg = true;
}
if (constType)
type->changeQualifier(EvqConst);
type->getQualifier().storage = EvqConst;
if (type->isArray() && type->getArraySize() != function.getParamCount()) {
error(line, "array constructor needs one argument per array element", "constructor", "");
......@@ -623,19 +642,19 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const
bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualifier)
{
switch (qualifier) {
switch (qualifier.storage) {
case EvqIn:
profileRequires(line, ENoProfile, 130, 0, "in for stage inputs");
profileRequires(line, EEsProfile, 300, 0, "in for stage inputs");
qualifier = EvqVaryingIn;
qualifier.storage = EvqVaryingIn;
break;
case EvqOut:
profileRequires(line, ENoProfile, 130, 0, "out for stage outputs");
profileRequires(line, EEsProfile, 300, 0, "out for stage outputs");
qualifier = EvqVaryingOut;
qualifier.storage = EvqVaryingOut;
break;
case EvqInOut:
qualifier = EvqVaryingIn;
qualifier.storage = EvqVaryingIn;
error(line, "cannot use 'inout' at global scope", "", "");
return true;
......@@ -646,20 +665,34 @@ bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualif
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) {
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;
}
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 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) &&
type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) {
......@@ -741,12 +774,12 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
//
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(), "");
return true;
}
if (type.qualifier == EvqConst)
if (type.qualifier.storage == EvqConst)
profileRequires(line, ENoProfile, 120, "GL_3DL_array_objects", "const array");
return false;
......@@ -899,8 +932,8 @@ bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPubli
//
// Make the qualifier make sense.
//
if (type.qualifier == EvqConst) {
type.qualifier = EvqTemporary;
if (type.qualifier.storage == EvqConst) {
type.qualifier.storage = EvqTemporary;
error(line, "variables with qualifier 'const' must be initialized", identifier.c_str(), "");
return true;
}
......@@ -933,24 +966,24 @@ bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType
return false;
}
bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TType* type)
bool TParseContext::paramErrorCheck(int line, TStorageQualifier qualifier, TType* type)
{
switch (qualifier) {
case EvqConst:
case EvqConstReadOnly:
type->changeQualifier(EvqConstReadOnly);
type->getQualifier().storage = EvqConstReadOnly;
return false;
case EvqIn:
case EvqOut:
case EvqInOut:
type->changeQualifier(qualifier);
type->getQualifier().storage = qualifier;
return false;
case EvqTemporary:
type->changeQualifier(EvqIn);
type->getQualifier().storage = EvqIn;
return false;
default:
type->changeQualifier(EvqIn);
error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier), "");
type->getQualifier().storage = EvqIn;
error(line, "qualifier not allowed on function parameter", getStorageQualifierString(qualifier), "");
return true;
}
}
......@@ -1016,9 +1049,9 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
//
// 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)) {
error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString(), "");
error(line, " cannot initialize this type of qualifier ", variable->getType().getStorageQualifierString(), "");
return true;
}
//
......@@ -1026,15 +1059,15 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
//
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());
variable->getType().changeQualifier(EvqTemporary);
variable->getType().getQualifier().storage = EvqTemporary;
return true;
}
if (type != initializer->getType()) {
error(line, " non-matching types for const initializer ",
variable->getType().getQualifierString(), "");
variable->getType().changeQualifier(EvqTemporary);
variable->getType().getStorageQualifierString(), "");
variable->getType().getQualifier().storage = EvqTemporary;
return true;
}
if (initializer->getAsConstantUnion()) {
......@@ -1053,7 +1086,7 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
variable->shareConstPointer(constArray);
} else {
error(line, " cannot assign to", "=", "'%s'", variable->getType().getCompleteString().c_str());
variable->getType().changeQualifier(EvqTemporary);
variable->getType().getQualifier().storage = EvqTemporary;
return true;
}
}
......
......@@ -45,7 +45,7 @@ struct TMatrixFields {
bool wholeRow;
bool wholeCol;
int row;
int col;
int col;
};
typedef enum {
......@@ -67,12 +67,7 @@ struct TPragma {
// they can be passed to the parser without needing a global.
//
struct 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) { }
TParseContext(TSymbolTable& symt, TIntermediate& interm, EShLanguage L, TInfoSink& is);
TIntermediate& intermediate; // to hold and build a parse tree
TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed
TInfoSink& infoSink;
......@@ -91,18 +86,19 @@ struct TParseContext {
EProfile profile; // the declared profile in the shader (core 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
struct TPragma contextPragma;
TString HashErrMsg;
TPrecisionQualifier defaultPrecision[EbtNumTypes];
TString HashErrMsg;
bool AfterEOF;
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, ...);
bool reservedErrorCheck(int line, const TString& identifier);
void recover();
bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line);
bool parseMatrixFields(const TString&, int matSize, TMatrixFields&, int line);
void assignError(int line, const char* op, TString left, TString right);
......@@ -125,13 +121,14 @@ struct TParseContext {
bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason);
bool globalQualifierFixAndErrorCheck(int line, TQualifier&);
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 nonInitConstErrorCheck(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);
bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
bool areAllChildConst(TIntermAggregate* aggrNode);
TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, TSourceLoc);
......
......@@ -36,7 +36,7 @@
class TAliveTraverser : public TIntermTraverser {
public:
TAliveTraverser(TQualifier q) : TIntermTraverser(), found(false), qualifier(q)
TAliveTraverser(TStorageQualifier q) : TIntermTraverser(), found(false), qualifier(q)
{
visitSymbol = AliveSymbol;
visitSelection = AliveSelection;
......@@ -45,7 +45,7 @@ public:
bool wasFound() { return found; }
protected:
bool found;
TQualifier qualifier;
TStorageQualifier qualifier;
friend void AliveSymbol(TIntermSymbol*, TIntermTraverser*);
friend bool AliveSelection(bool, TIntermSelection*, TIntermTraverser*);
......@@ -59,7 +59,7 @@ protected:
// ?? It does not do this well yet, this is just a place holder
// 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);
......@@ -76,7 +76,7 @@ void AliveSymbol(TIntermSymbol* node, TIntermTraverser* 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;
}
......
......@@ -32,4 +32,4 @@
//POSSIBILITY OF SUCH DAMAGE.
//
bool QualifierWritten(TIntermNode* root, TQualifier);
bool QualifierWritten(TIntermNode* root, TStorageQualifier);
......@@ -92,12 +92,11 @@ int ShInitialize()
SetGlobalPoolAllocatorPtr(gPoolAllocator);
symTables[EShLangVertex].pop();
symTables[EShLangFragment].pop();
symTables[EShLangVertex].pop(0);
symTables[EShLangFragment].pop(0);
builtInPoolAllocator->popAll();
delete builtInPoolAllocator;
delete builtInPoolAllocator;
}
return ret ? 1 : 0;
......@@ -343,7 +342,7 @@ int ShCompile(
// throwing away all but the built-ins.
//
while (! symbolTable.atSharedBuiltInLevel())
symbolTable.pop();
symbolTable.pop(0);
FinalizePreprocessor();
//
......
......@@ -111,7 +111,7 @@ int TType::getStructSize() 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()) {
infoSink.debug << "[0]";
}
......@@ -154,6 +154,8 @@ TSymbolTableLevel::~TSymbolTableLevel()
{
for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
delete (*it).second;
delete [] defaultPrecision;
}
//
......
......@@ -46,7 +46,7 @@
// so that symbol table lookups are never ambiguous. This allows
// 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
// the top.
//
......@@ -61,11 +61,11 @@
#include "../Include/Common.h"
#include "../Include/intermediate.h"
#include "../Include/InfoSink.h"
//
// Symbol base class. (Can build functions or variables out of these...)
//
class TSymbol {
class TSymbol {
public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
TSymbol(const TString *n) : name(n) { }
......@@ -87,29 +87,29 @@ protected:
//
// Variable class, meaning a symbol that's not a function.
//
//
// There could be a separate class heirarchy for Constant variables;
// 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
// 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.
//
class TVariable : public TSymbol {
public:
TVariable(const TString *name, const TType& t, bool uT = false ) : TSymbol(name), type(t), userType(uT), unionArray(0), arrayInformationType(0) { }
virtual ~TVariable() { }
virtual bool isVariable() const { return true; }
TType& getType() { return type; }
virtual bool isVariable() const { return true; }
TType& getType() { return type; }
const TType& getType() const { return type; }
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; }
TType* getArrayInformationType() { return arrayInformationType; }
virtual void dump(TInfoSink &infoSink) const;
constUnion* getConstPointer() {
constUnion* getConstPointer() {
if (!unionArray)
unionArray = new constUnion[type.getObjectSize()];
......@@ -121,11 +121,11 @@ public:
void shareConstPointer( constUnion *constArray)
{
delete unionArray;
unionArray = constArray;
unionArray = constArray;
}
TVariable(const TVariable&, TStructureMap& remapper); // copy constructor
virtual TVariable* clone(TStructureMap& remapper);
protected:
TType type;
bool userType;
......@@ -149,7 +149,7 @@ struct TParameter {
};
//
// The function sub-class of a symbol.
// The function sub-class of a symbol.
//
class TFunction : public TSymbol {
public:
......@@ -158,21 +158,21 @@ public:
returnType(TType(EbtVoid)),
op(o),
defined(false) { }
TFunction(const TString *name, TType& retType, TOperator tOp = EOpNull) :
TSymbol(name),
TFunction(const TString *name, TType& retType, TOperator tOp = EOpNull) :
TSymbol(name),
returnType(retType),
mangledName(*name + '('),
op(tOp),
defined(false) { }
virtual ~TFunction();
virtual bool isFunction() const { return true; }
void addParameter(TParameter& p)
{
virtual bool isFunction() const { return true; }
void addParameter(TParameter& p)
{
parameters.push_back(p);
mangledName = mangledName + p.type->getMangledName();
}
const TString& getMangledName() const { return mangledName; }
const TType& getReturnType() const { return returnType; }
void relateToOperator(TOperator o) { op = o; }
......@@ -180,14 +180,14 @@ public:
void setDefined() { defined = true; }
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]; }
const TParameter& operator [](int i) const { return parameters[i]; }
virtual void dump(TInfoSink &infoSink) const;
TFunction(const TFunction&, TStructureMap& remapper);
virtual TFunction* clone(TStructureMap& remapper);
protected:
typedef TVector<TParameter> TParamList;
TParamList parameters;
......@@ -201,17 +201,17 @@ protected:
class TSymbolTableLevel {
public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
TSymbolTableLevel() { }
TSymbolTableLevel() : defaultPrecision (0) { }
~TSymbolTableLevel();
bool insert(TSymbol& symbol)
bool insert(TSymbol& symbol)
{
//
// returning true means symbol was added to the table
//
tInsertResult result;
result = level.insert(tLevelPair(symbol.getMangledName(), &symbol));
return result.second;
}
......@@ -224,17 +224,44 @@ public:
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 dump(TInfoSink &infoSink) const;
TSymbolTableLevel* clone(TStructureMap& remapper);
protected:
typedef std::map<TString, TSymbol*, std::less<TString>, pool_allocator<std::pair<const TString, TSymbol*> > > tLevel;
typedef const tLevel::value_type tLevelPair;
typedef std::pair<tLevel::iterator, bool> tInsertResult;
tLevel level;
TPrecisionQualifier *defaultPrecision;
};
class TSymbolTable {
......@@ -258,7 +285,7 @@ public:
{
// level 0 is always built In symbols, so we never pop that out
while (table.size() > 1)
pop();
pop(0);
}
//
......@@ -270,13 +297,17 @@ public:
bool atBuiltInLevel() { return atSharedBuiltInLevel() || atDynamicBuiltInLevel(); }
bool atSharedBuiltInLevel() { return table.size() == 1; }
bool atGlobalLevel() { return table.size() <= 3; }
void push() {
void push()
{
table.push_back(new TSymbolTableLevel);
}
void pop() {
delete table[currentLevel()];
table.pop_back();
void pop(TPrecisionQualifier *p)
{
table[currentLevel()]->getPreviousDefaultPrecisions(p);
delete table[currentLevel()];
table.pop_back();
}
bool insert(TSymbol& symbol)
......@@ -284,8 +315,8 @@ public:
symbol.setUniqueId(++uniqueId);
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();
TSymbol* symbol;
......@@ -307,7 +338,9 @@ public:
void dump(TInfoSink &infoSink) const;
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; }
bool atDynamicBuiltInLevel() { return table.size() == 2; }
......
......@@ -732,6 +732,24 @@ void SetVersion(int version)
{
TParseContext& parseContext = *((TParseContext *)cpp->pC);
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;
......
......@@ -96,7 +96,6 @@ Jutta Degener, 1995
};
union {
TPublicType type;
TQualifier qualifier;
TFunction* function;
TParameter param;
TTypeLine typeLine;
......@@ -235,7 +234,7 @@ variable_identifier
// don't delete $1.string, it's used by error recovery, and the pool
// pop will reclaim the memory
if (variable->getType().getQualifier() == EvqConst ) {
if (variable->getType().getQualifier().storage == EvqConst ) {
constUnion* constArray = variable->getConstPointer();
TType t(variable->getType());
$$ = parseContext.intermediate.addConstantUnion(constArray, t, $1.line);
......@@ -293,7 +292,7 @@ postfix_expression
parseContext.error($2.line, " left of '[' is not of type array, matrix, or vector ", "expression", "");
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
$$ = parseContext.addConstArrayNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.line);
} else if ($1->isVector()) { // constant folding for vectors
......@@ -305,7 +304,7 @@ postfix_expression
$$ = parseContext.addConstMatrixNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.line);
}
} else {
if ($3->getQualifier() == EvqConst) {
if ($3->getQualifier().storage == EvqConst) {
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.recover();
......@@ -345,13 +344,13 @@ postfix_expression
else
$$->setType(TType($1->getBasicType(), EvqTemporary, $1->getNominalSize(), $1->isMatrix()));
if ($1->getType().getQualifier() == EvqConst)
$$->getTypePointer()->changeQualifier(EvqConst);
} else if ($1->isMatrix() && $1->getType().getQualifier() == EvqConst)
if ($1->getType().getQualifier().storage == EvqConst)
$$->getTypePointer()->getQualifier().storage = EvqConst;
} else if ($1->isMatrix() && $1->getType().getQualifier().storage == EvqConst)
$$->setType(TType($1->getBasicType(), EvqConst, $1->getNominalSize()));
else if ($1->isMatrix())
$$->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));
else if ($1->isVector())
$$->setType(TType($1->getBasicType(), EvqTemporary));
......@@ -387,7 +386,7 @@ postfix_expression
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);
if ($$ == 0) {
parseContext.recover();
......@@ -450,7 +449,7 @@ postfix_expression
}
}
if (fieldFound) {
if ($1->getType().getQualifier() == EvqConst) {
if ($1->getType().getQualifier().storage == EvqConst) {
$$ = parseContext.addConstStruct(*$3.string, $1, $2.line);
if ($$ == 0) {
parseContext.recover();
......@@ -460,7 +459,7 @@ postfix_expression
$$->setType(*(*fields)[i].type);
// change the qualifier of the return type, not of the structure field
// as the structure definition is shared between various structures.
$$->getTypePointer()->changeQualifier(EvqConst);
$$->getTypePointer()->getQualifier().storage = EvqConst;
}
} else {
constUnion *unionArray = new constUnion[1];
......@@ -593,10 +592,10 @@ function_call
$$->getAsAggregate()->setUserDefined();
$$->getAsAggregate()->setName(fnCandidate->getMangledName());
TQualifier qual;
TQualifierList& qualifierList = $$->getAsAggregate()->getQualifier();
TStorageQualifier qual;
TQualifierList& qualifierList = $$->getAsAggregate()->getQualifierList();
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 (parseContext.lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) {
parseContext.error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", "");
......@@ -682,6 +681,7 @@ function_identifier
parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "array");
}
$1.qualifier.precision = EpqNone;
if ($1.userDef) {
TString tempString = "";
TType type($1);
......@@ -1122,6 +1122,11 @@ declaration
}
| PRECISION precision_qualifier type_specifier SEMICOLON {
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;
}
| type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE SEMICOLON {
......@@ -1176,8 +1181,9 @@ function_prototype
parseContext.recover();
}
for (int i = 0; i < prevDec->getParamCount(); ++i) {
if ((*prevDec)[i].type->getQualifier() != (*$1)[i].type->getQualifier()) {
parseContext.error($2.line, "overloaded functions must have the same parameter qualifiers", (*$1)[i].type->getQualifierString(), "");
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->getStorageQualifierString(), "");
parseContext.recover();
}
}
......@@ -1236,8 +1242,9 @@ function_header_with_parameters
function_header
: fully_specified_type IDENTIFIER LEFT_PAREN {
if ($1.qualifier != EvqGlobal && $1.qualifier != EvqTemporary) {
parseContext.error($2.line, "no qualifiers allowed for function return", getQualifierString($1.qualifier), "");
if ($1.qualifier.storage != EvqGlobal && $1.qualifier.storage != EvqTemporary) {
parseContext.error($2.line, "no qualifiers allowed for function return",
getStorageQualifierString($1.qualifier.storage), "");
parseContext.recover();
}
// make sure a sampler is not involved as well...
......@@ -1261,6 +1268,7 @@ parameter_declarator
}
if (parseContext.reservedErrorCheck($2.line, *$2.string))
parseContext.recover();
TParameter param = {$2.string, new TType($1)};
$$.line = $2.line;
$$.param = param;
......@@ -1286,10 +1294,12 @@ parameter_declaration
//
: type_qualifier parameter_declarator {
$$ = $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();
if (parseContext.paramErrorCheck($1.line, $1.qualifier, $$.param.type))
if (parseContext.paramErrorCheck($1.line, $1.qualifier.storage, $$.param.type))
parseContext.recover();
}
| parameter_declarator {
......@@ -1305,16 +1315,18 @@ parameter_declaration
//
| type_qualifier parameter_type_specifier {
$$ = $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();
if (parseContext.paramErrorCheck($1.line, $1.qualifier, $$.param.type))
if (parseContext.paramErrorCheck($1.line, $1.qualifier.storage, $$.param.type))
parseContext.recover();
}
| parameter_type_specifier {
$$ = $1;
if (parseContext.parameterSamplerErrorCheck($1.line, $1.qualifier, *$1.param.type))
if (parseContext.parameterSamplerErrorCheck($1.line, EvqIn, *$1.param.type))
parseContext.recover();
if (parseContext.paramErrorCheck($1.line, EvqTemporary, $$.param.type))
parseContext.recover();
......@@ -1535,18 +1547,20 @@ fully_specified_type
$2.setArray(false);
}
if ($1.qualifier == EvqAttribute &&
if ($1.qualifier.storage == EvqAttribute &&
($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();
}
if (($1.qualifier == EvqVaryingIn || $1.qualifier == EvqVaryingOut) &&
if (($1.qualifier.storage == EvqVaryingIn || $1.qualifier.storage == EvqVaryingOut) &&
($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();
}
$$ = $2;
$$.qualifier = $1.qualifier;
if ($$.qualifier.precision == EpqNone)
$$.qualifier.precision = $2.qualifier.precision;
}
;
......@@ -1601,15 +1615,18 @@ type_qualifier
$$.type = $2.type;
}
if ($$.qualifier == EvqTemporary) {
$$.qualifier = $2.qualifier;
} else if ($$.qualifier == EvqIn && $2.qualifier == EvqOut ||
$$.qualifier == EvqOut && $2.qualifier == EvqIn) {
$$.qualifier = EvqInOut;
} else if ($$.qualifier == EvqIn && $2.qualifier == EvqConst ||
$$.qualifier == EvqConst && $2.qualifier == EvqIn) {
$$.qualifier = EvqConstReadOnly;
if ($$.qualifier.storage == EvqTemporary) {
$$.qualifier.storage = $2.qualifier.storage;
} else if ($$.qualifier.storage == EvqIn && $2.qualifier.storage == EvqOut ||
$$.qualifier.storage == EvqOut && $2.qualifier.storage == EvqIn) {
$$.qualifier.storage = EvqInOut;
} else if ($$.qualifier.storage == EvqIn && $2.qualifier.storage == EvqConst ||
$$.qualifier.storage == EvqConst && $2.qualifier.storage == EvqIn) {
$$.qualifier.storage = EvqConstReadOnly;
}
if ($$.qualifier.precision == EpqNone)
$$.qualifier.precision = $2.qualifier.precision;
}
;
......@@ -1639,7 +1656,8 @@ single_type_qualifier
storage_qualifier
: CONST {
$$.setBasic(EbtVoid, EvqConst, $1.line);
$$.init($1.line);
$$.qualifier.storage = EvqConst;
}
| ATTRIBUTE {
parseContext.requireStage($1.line, EShLangVertexMask, "attribute");
......@@ -1649,7 +1667,9 @@ storage_qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "attribute"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqAttribute, $1.line);
$$.init($1.line);
$$.qualifier.storage = EvqAttribute;
}
| VARYING {
parseContext.checkDeprecated($1.line, ENoProfile, 140, "varying");
......@@ -1657,97 +1677,115 @@ storage_qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "varying"))
parseContext.recover();
if (parseContext.language == EShLangVertex)
$$.setBasic(EbtVoid, EvqVaryingOut, $1.line);
$$.init($1.line);
if (parseContext.language == EShLangVertex)
$$.qualifier.storage = EvqVaryingOut;
else
$$.setBasic(EbtVoid, EvqVaryingIn, $1.line);
$$.qualifier.storage = EvqVaryingIn;
}
| INOUT {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "out"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqInOut, $1.line);
$$.init($1.line);
$$.qualifier.storage = EvqInOut;
}
| IN {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "in"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqIn, $1.line);
$$.init($1.line);
$$.qualifier.storage = EvqIn;
}
| OUT {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "out"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqOut, $1.line);
$$.init($1.line);
$$.qualifier.storage = EvqOut;
}
| CENTROID {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "centroid"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqVaryingIn, $1.line);
$$.init($1.line);
$$.qualifier.storage = EvqVaryingIn;
}
| PATCH {
// TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "patch"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
}
| SAMPLE {
// TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "sample"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
}
| UNIFORM {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "uniform"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
}
| BUFFER {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "buffer"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
}
| SHARED {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "shared"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
}
| COHERENT {
// TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "coherent"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
}
| VOLATILE {
// TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "volatile"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
}
| RESTRICT {
// TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "restrict"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
}
| READONLY {
// TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "readonly"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
}
| WRITEONLY {
// TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "writeonly"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
}
| SUBROUTINE {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "subroutine"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
}
| SUBROUTINE LEFT_PAREN type_name_list RIGHT_PAREN {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "subroutine"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
// TODO: subroutine semantics
// 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
......@@ -1766,9 +1804,11 @@ type_name_list
type_specifier
: type_specifier_nonarray {
$$ = $1;
$$.qualifier.precision = parseContext.defaultPrecision[$$.type];
}
| type_specifier_nonarray array_specifier {
$$ = $1;
$$.qualifier.precision = parseContext.defaultPrecision[$$.type];
$$.setArray(true, $2.intVector->front());
}
;
......@@ -1804,588 +1844,587 @@ array_specifier
type_specifier_nonarray
: VOID {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtVoid, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtVoid;
}
| FLOAT {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtFloat;
}
| DOUBLE {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
// TODO: implement EbtDouble, check all float types
$$.setBasic(EbtDouble, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtDouble;
}
| INT {
// TODO: implement EbtUint, check all int types
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtInt;
}
| UINT {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line);
// TODO: implement EbtUint, check all int types
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtInt;
}
| BOOL {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtBool, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtBool;
}
| VEC2 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtFloat;
$$.setAggregate(2);
}
| VEC3 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtFloat;
$$.setAggregate(3);
}
| VEC4 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtFloat;
$$.setAggregate(4);
}
| DVEC2 {
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtDouble;
$$.setAggregate(2);
}
| DVEC3 {
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtDouble;
$$.setAggregate(3);
}
| DVEC4 {
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtDouble;
$$.setAggregate(4);
}
| BVEC2 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtBool, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtBool;
$$.setAggregate(2);
}
| BVEC3 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtBool, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtBool;
$$.setAggregate(3);
}
| BVEC4 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtBool, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtBool;
$$.setAggregate(4);
}
| IVEC2 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtInt;
$$.setAggregate(2);
}
| IVEC3 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtInt;
$$.setAggregate(3);
}
| IVEC4 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtInt;
$$.setAggregate(4);
}
| UVEC2 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtInt;
$$.setAggregate(2);
}
| UVEC3 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtInt;
$$.setAggregate(3);
}
| UVEC4 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtInt;
$$.setAggregate(4);
}
| MAT2 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtFloat;
$$.setAggregate(2, true);
}
| MAT3 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtFloat;
$$.setAggregate(3, true);
}
| MAT4 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtFloat;
$$.setAggregate(4, true);
}
| MAT2X2 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtFloat;
$$.setAggregate(2, true);
}
| MAT2X3 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtFloat;
$$.setAggregate(3, true);
}
| MAT2X4 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtFloat;
$$.setAggregate(4, true);
}
| MAT3X2 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtFloat;
$$.setAggregate(3, true);
}
| MAT3X3 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtFloat;
$$.setAggregate(3, true);
}
| MAT3X4 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtFloat;
$$.setAggregate(4, true);
}
| MAT4X2 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtFloat;
$$.setAggregate(4, true);
}
| MAT4X3 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtFloat;
$$.setAggregate(4, true);
}
| MAT4X4 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtFloat;
$$.setAggregate(4, true);
}
| DMAT2 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtDouble;
$$.setAggregate(2, true);
}
| DMAT3 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtDouble;
$$.setAggregate(3, true);
}
| DMAT4 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtDouble;
$$.setAggregate(4, true);
}
| DMAT2X2 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtDouble;
$$.setAggregate(2, true);
}
| DMAT2X3 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtDouble;
$$.setAggregate(3, true);
}
| DMAT2X4 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtDouble;
$$.setAggregate(4, true);
}
| DMAT3X2 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtDouble;
$$.setAggregate(3, true);
}
| DMAT3X3 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtDouble;
$$.setAggregate(3, true);
}
| DMAT3X4 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtDouble;
$$.setAggregate(4, true);
}
| DMAT4X2 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtDouble;
$$.setAggregate(4, true);
}
| DMAT4X3 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtDouble;
$$.setAggregate(4, true);
}
| DMAT4X4 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtDouble;
$$.setAggregate(4, true);
}
| ATOMIC_UINT {
// TODO: add type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtInt;
}
| SAMPLER1D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler1D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler1D;
}
| SAMPLER2D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| SAMPLER3D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler3D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler3D;
}
| SAMPLERCUBE {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSamplerCube, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSamplerCube;
}
| SAMPLER1DSHADOW {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler1DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler1DShadow;
}
| SAMPLER2DSHADOW {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| SAMPLERCUBESHADOW {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| SAMPLER1DARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| SAMPLER2DARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| SAMPLER1DARRAYSHADOW {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| SAMPLER2DARRAYSHADOW {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| SAMPLERCUBEARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| SAMPLERCUBEARRAYSHADOW {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| ISAMPLER1D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| ISAMPLER2D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| ISAMPLER3D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| ISAMPLERCUBE {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| ISAMPLER1DARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| ISAMPLER2DARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| ISAMPLERCUBEARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| USAMPLER1D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| USAMPLER2D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| USAMPLER3D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| USAMPLERCUBE {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| USAMPLER1DARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| USAMPLER2DARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| USAMPLERCUBEARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2DShadow;
}
| SAMPLER2DRECT {
parseContext.profileRequires($1.line, ENoProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSamplerRect, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSamplerRect;
}
| SAMPLER2DRECTSHADOW {
parseContext.profileRequires($1.line, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSamplerRectShadow, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSamplerRectShadow;
}
| ISAMPLER2DRECT {
parseContext.profileRequires($1.line, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSamplerRect, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSamplerRect;
}
| USAMPLER2DRECT {
parseContext.profileRequires($1.line, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture");
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSamplerRect, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSamplerRect;
}
| SAMPLERBUFFER {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| ISAMPLERBUFFER {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| USAMPLERBUFFER {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| SAMPLER2DMS {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| ISAMPLER2DMS {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| USAMPLER2DMS {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| SAMPLER2DMSARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| ISAMPLER2DMSARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| USAMPLER2DMSARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IMAGE1D {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IIMAGE1D {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| UIMAGE1D {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IMAGE2D {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IIMAGE2D {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| UIMAGE2D {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IMAGE3D {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IIMAGE3D {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| UIMAGE3D {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IMAGE2DRECT {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IIMAGE2DRECT {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| UIMAGE2DRECT {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IMAGECUBE {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IIMAGECUBE {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| UIMAGECUBE {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IMAGEBUFFER {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IIMAGEBUFFER {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| UIMAGEBUFFER {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IMAGE1DARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IIMAGE1DARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| UIMAGE1DARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IMAGE2DARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IIMAGE2DARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| UIMAGE2DARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IMAGECUBEARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IIMAGECUBEARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| UIMAGECUBEARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IMAGE2DMS {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IIMAGE2DMS {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| UIMAGE2DMS {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IMAGE2DMSARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| IIMAGE2DMSARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| UIMAGE2DMSARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtSampler2D;
}
| struct_specifier {
$$ = $1;
$$.qualifier = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.qualifier.storage = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
}
| TYPE_NAME {
//
......@@ -2393,8 +2432,8 @@ type_specifier_nonarray
// type.
//
TType& structure = static_cast<TVariable*>($1.symbol)->getType();
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtStruct, qual, $1.line);
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
$$.type = EbtStruct;
$$.userDef = &structure;
}
;
......@@ -2402,12 +2441,18 @@ type_specifier_nonarray
precision_qualifier
: HIGH_PRECISION {
parseContext.profileRequires($1.line, ENoProfile, 130, 0, "highp precision qualifier");
$$.init($1.line);
$$.qualifier.precision = EpqHigh;
}
| MEDIUM_PRECISION {
parseContext.profileRequires($1.line, ENoProfile, 130, 0, "mediump precision qualifier");
$$.init($1.line);
$$.qualifier.precision = EpqMedium;
}
| LOW_PRECISION {
parseContext.profileRequires($1.line, ENoProfile, 130, 0, "lowp precision qualifier");
$$.init($1.line);
$$.qualifier.precision = EpqLow;
}
;
......@@ -2419,12 +2464,14 @@ struct_specifier
parseContext.error($2.line, "redefinition", $2.string->c_str(), "struct");
parseContext.recover();
}
$$.setBasic(EbtStruct, EvqTemporary, $1.line);
$$.init($1.line);
$$.type = EbtStruct;
$$.userDef = structure;
}
| STRUCT LEFT_BRACE struct_declaration_list RIGHT_BRACE {
TType* structure = new TType($3, TString(""));
$$.setBasic(EbtStruct, EvqTemporary, $1.line);
$$.init($1.line);
$$.type = EbtStruct;
$$.userDef = structure;
}
;
......@@ -2555,7 +2602,9 @@ simple_statement
compound_statement
: 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)
$3->setOperator(EOpSequence);
$$ = $3;
......@@ -2660,8 +2709,12 @@ case_label
;
iteration_statement
: WHILE LEFT_PAREN { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope {
parseContext.symbolTable.pop();
: WHILE LEFT_PAREN {
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.loopNestingLevel;
}
......@@ -2672,8 +2725,12 @@ iteration_statement
$$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.line);
--parseContext.loopNestingLevel;
}
| FOR LEFT_PAREN { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
parseContext.symbolTable.pop();
| FOR LEFT_PAREN {
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.growAggregate(
$$,
......@@ -2867,7 +2924,7 @@ function_definition
parseContext.error($1.line, "function does not return a value:", "", $1.function->getName().c_str());
parseContext.recover();
}
parseContext.symbolTable.pop();
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
$$ = parseContext.intermediate.growAggregate($1.intermAggregate, $3, 0);
parseContext.intermediate.setAggregateOperator($$, EOpFunction, $1.line);
$$->getAsAggregate()->setName($1.function->getMangledName().c_str());
......
......@@ -60,10 +60,12 @@ TString TType::getCompleteString() const
char *p = &buf[0];
char *end = &buf[maxSize];
if (qualifier != EvqTemporary && qualifier != EvqGlobal)
p += sprintf_s(p, end - p, "%s ", getQualifierString());
if (qualifier.storage != EvqTemporary && qualifier.storage != EvqGlobal)
p += sprintf_s(p, end - p, "%s ", getStorageQualifierString());
if (array)
p += sprintf_s(p, end - p, "array of ");
if (qualifier.precision != EpqNone)
p += sprintf_s(p, end - p, "%s ", getPrecisionQualifierString());
if (matrix)
p += sprintf_s(p, end - p, "%dX%d matrix of ", size, size);
else if (size > 1)
......
......@@ -69,15 +69,15 @@ void ParseSymbol(TIntermSymbol* node, TIntermTraverser* it)
{
TConstTraverser* oit = static_cast<TConstTraverser*>(it);
oit->infoSink.info.message(EPrefixInternalError, "Symbol Node found in constant constructor", node->getLine());
return;
return;
}
bool ParseBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it)
{
TConstTraverser* oit = static_cast<TConstTraverser*>(it);
TQualifier qualifier = node->getType().getQualifier();
TStorageQualifier qualifier = node->getType().getQualifier().storage;
if (qualifier != EvqConst) {
const int maxSize = 200;
......@@ -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());
oit->infoSink.info.message(EPrefixError, buf, node->getLine());
oit->error = true;
return false;
}
......@@ -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());
oit->infoSink.info.message(EPrefixError, buf, node->getLine());
oit->error = true;
return false;
}
......@@ -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());
oit->infoSink.info.message(EPrefixError, buf, node->getLine());
oit->error = true;
return false;
}
if (node->getSequence().size() == 0) {
oit->error = true;
return false;
}
......@@ -152,6 +156,7 @@ bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverse
oit->isMatrix = false;
oit->matrixSize = 0;
}
return false;
}
......@@ -229,6 +234,7 @@ bool ParseLoop(bool /* preVisit */, TIntermLoop* node, TIntermTraverser* it)
TConstTraverser* oit = static_cast<TConstTraverser*>(it);
oit->infoSink.info.message(EPrefixInternalError, "Loop Node found in constant constructor", node->getLine());
oit->error = true;
return false;
}
......@@ -237,6 +243,7 @@ bool ParseBranch(bool /* previsit*/, TIntermBranch* node, TIntermTraverser* it)
TConstTraverser* oit = static_cast<TConstTraverser*>(it);
oit->infoSink.info.message(EPrefixInternalError, "Branch Node found in constant constructor", node->getLine());
oit->error = true;
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