From 5f1a0b7998132b39c41fbe28d44bcb4bbd53bcd9 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Sat, 6 Jul 2013 19:54:21 +0000 Subject: [PATCH] Eliminate flex as the GLSL lexical analyzer, going from two nested lexical analyzers down to one, leaving just the preprocessor's lexical analysis. A new layer replaces it, to translate from the preprocessor's view of tokenization to glslang's view of tokenization. Also: - change source locations from an int to TSourceLoc (shader number, line number) throughout - various improvements to the preprocessor git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@22277 e7fa87d3-cd2b-0410-9028-fcbf551c1848 --- Test/cppSimple.vert | 4 + Test/lineContinuation.vert | 8 +- Test/tokenLength.vert | 8 +- glslang.vcxproj | 20 +- glslang.vcxproj.filters | 12 +- glslang/Include/Common.h | 25 +- glslang/Include/InfoSink.h | 5 +- glslang/Include/Types.h | 24 +- glslang/Include/intermediate.h | 8 +- glslang/MachineIndependent/Constant.cpp | 24 +- glslang/MachineIndependent/Initialize.h | 2 - glslang/MachineIndependent/Intermediate.cpp | 161 +-- glslang/MachineIndependent/ParseHelper.cpp | 852 +++++++++++---- glslang/MachineIndependent/ParseHelper.h | 120 +- glslang/MachineIndependent/Scan.cpp | 815 +++++++++++++- glslang/MachineIndependent/Scan.h | 2 +- glslang/MachineIndependent/ScanContext.h | 80 ++ glslang/MachineIndependent/ShaderLang.cpp | 31 +- glslang/MachineIndependent/Versions.cpp | 42 +- glslang/MachineIndependent/glslang.l | 1155 -------------------- glslang/MachineIndependent/glslang.y | 1068 +++++++++--------- glslang/MachineIndependent/intermOut.cpp | 8 +- glslang/MachineIndependent/localintermediate.h | 2 + glslang/MachineIndependent/parseConst.cpp | 16 +- glslang/MachineIndependent/preprocessor/atom.c | 17 +- glslang/MachineIndependent/preprocessor/compile.h | 132 --- glslang/MachineIndependent/preprocessor/cpp.c | 35 +- glslang/MachineIndependent/preprocessor/cpp.h | 3 +- .../MachineIndependent/preprocessor/cppstruct.c | 2 - glslang/MachineIndependent/preprocessor/parser.h | 25 +- .../MachineIndependent/preprocessor/preprocess.h | 84 +- glslang/MachineIndependent/preprocessor/scanner.c | 183 ++-- glslang/MachineIndependent/preprocessor/scanner.h | 19 +- .../MachineIndependent/preprocessor/slglobals.h | 3 +- glslang/MachineIndependent/preprocessor/tokens.c | 59 +- 35 files changed, 2537 insertions(+), 2517 deletions(-) create mode 100644 glslang/MachineIndependent/ScanContext.h delete mode 100644 glslang/MachineIndependent/glslang.l delete mode 100644 glslang/MachineIndependent/preprocessor/compile.h diff --git a/Test/cppSimple.vert b/Test/cppSimple.vert index 2b48c01..d242de3 100644 --- a/Test/cppSimple.vert +++ b/Test/cppSimple.vert @@ -125,5 +125,9 @@ int linenumber = __LINE__; int filenumber = __FILE__; int version = __VERSION__; +#define PI (3.14) +#define TWOPI (2.0 * PI) +float twoPi = TWOPI; + #define PASTE(a,b) a ## b float PASTE(tod, ay) = 17; diff --git a/Test/lineContinuation.vert b/Test/lineContinuation.vert index c6222ef..eb2f819 100644 --- a/Test/lineContinuation.vert +++ b/Test/lineContinuation.vert @@ -1,14 +1,20 @@ #version 300 es // this file cont\ -ains no errors +ains no errors other than the #error which are there to see if line numbering for errors is correct + +#error e1 float f\ oo; // same as 'float foo;' +#error e2 + #define MAIN void main() \ { \ gl_Position = vec4(foo); \ } +#error e3 + MAIN diff --git a/Test/tokenLength.vert b/Test/tokenLength.vert index 57e3b7f..dfec2b4 100644 --- a/Test/tokenLength.vert +++ b/Test/tokenLength.vert @@ -14,13 +14,13 @@ int OE = 0777777777777777777777; // ERROR int HE = 0x1234567890ABCDEF0; // ERROR // 1023 character fraction -float F = 1.012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012; +float F = 1.0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890; // 1024 character value -float G = 1.0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890; +float G = 1.01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678890; -// 1027 character fraction -float E3 = 1.01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234; +// 1025 character fraction +float E3 = 1.012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012; void main() { diff --git a/glslang.vcxproj b/glslang.vcxproj index 80024de..c50b18f 100644 --- a/glslang.vcxproj +++ b/glslang.vcxproj @@ -150,7 +150,6 @@ xcopy /y $(IntDir)$(TargetName)$(TargetExt) Test - @@ -192,7 +191,6 @@ xcopy /y $(IntDir)$(TargetName)$(TargetExt) Test - @@ -206,6 +204,7 @@ xcopy /y $(IntDir)$(TargetName)$(TargetExt) Test + @@ -238,23 +237,6 @@ cd %(RootDir)%(Directory) %(RootDir)%(Directory)%(Filename)_tab.cpp;%(Outputs) - - - Document - cd %(RootDir)%(Directory) -%(RootDir)%(Directory)..\..\tools\flex.exe glslang.l - - Executing flex on glslang.l - %(RootDir)%(Directory)gen_glslang.cpp - %(RootDir)%(Directory)glslang_tab.cpp.h - cd %(RootDir)%(Directory) -%(RootDir)%(Directory)..\..\tools\flex.exe glslang.l - - Executing flex on glslang.l - %(RootDir)%(Directory)gen_glslang.cpp - %(RootDir)%(Directory)glslang_tab.cpp.h - - diff --git a/glslang.vcxproj.filters b/glslang.vcxproj.filters index 3e5cfbd..624bcaf 100644 --- a/glslang.vcxproj.filters +++ b/glslang.vcxproj.filters @@ -97,9 +97,6 @@ OSDependent\Linux - - Machine Independent\Generated Source - Machine Independent\Generated Source @@ -135,9 +132,6 @@ Machine Independent\CPP - - Machine Independent\CPP - Machine Independent\CPP @@ -222,13 +216,13 @@ Machine Independent + + Machine Independent + Machine Independent - - Machine Independent - \ No newline at end of file diff --git a/glslang/Include/Common.h b/glslang/Include/Common.h index dd74232..e936683 100644 --- a/glslang/Include/Common.h +++ b/glslang/Include/Common.h @@ -66,8 +66,6 @@ #include #include -typedef int TSourceLoc; - #include "PoolAlloc.h" // @@ -162,25 +160,10 @@ inline const TString String(const int i, const int base = 10) return text; } -const unsigned int SourceLocLineMask = 0xffff; -const unsigned int SourceLocStringShift = 16; - -__inline TPersistString FormatSourceLoc(const TSourceLoc loc) -{ - const int maxSize = 64; - char locText[maxSize]; - - int string = loc >> SourceLocStringShift; - int line = loc & SourceLocLineMask; - - if (line) - snprintf(locText, maxSize, "%d:%d", string, line); - else - snprintf(locText, maxSize, "%d:? ", string); - - return TPersistString(locText); -} - +struct TSourceLoc { + int string; + int line; +}; typedef TMap TPragmaTable; typedef TMap::tAllocator TPragmaTableAllocator; diff --git a/glslang/Include/InfoSink.h b/glslang/Include/InfoSink.h index be0f762..a251182 100644 --- a/glslang/Include/InfoSink.h +++ b/glslang/Include/InfoSink.h @@ -94,7 +94,10 @@ public: } } void location(TSourceLoc loc) { - append(FormatSourceLoc(loc).c_str()); + const int maxSize = 24; + char locText[maxSize]; + snprintf(locText, maxSize, "%d:%d", loc.string, loc.line); + append(locText); append(": "); } void message(TPrefixType message, const char* s) { diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index 1a7215d..4b7681a 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -142,11 +142,11 @@ struct TSampler { // Need to have association of line numbers to types in a list for building structs. // class TType; -struct TTypeLine { +struct TTypeLoc { TType* type; - int line; + TSourceLoc loc; }; -typedef TVector TTypeList; +typedef TVector TTypeList; inline TTypeList* NewPoolTTypeList() { @@ -347,9 +347,9 @@ public: int matrixRows : 4; TArraySizes arraySizes; const TType* userDef; - int line; + TSourceLoc loc; - void initType(int ln = 0) + void initType(TSourceLoc l) { basicType = EbtVoid; vectorSize = 1; @@ -357,7 +357,7 @@ public: matrixCols = 0; arraySizes = 0; userDef = 0; - line = ln; + loc = l; } void initQualifiers(bool global = false) @@ -367,9 +367,9 @@ public: qualifier.storage = EvqGlobal; } - void init(int line = 0, bool global = false) + void init(TSourceLoc loc, bool global = false) { - initType(line); + initType(loc); sampler.clear(); initQualifiers(global); } @@ -479,10 +479,10 @@ public: // create the new structure here structure = NewPoolTTypeList(); for (unsigned int i = 0; i < copyOf.structure->size(); ++i) { - TTypeLine typeLine; - typeLine.line = (*copyOf.structure)[i].line; - typeLine.type = (*copyOf.structure)[i].type->clone(remapper); - structure->push_back(typeLine); + TTypeLoc typeLoc; + typeLoc.loc = (*copyOf.structure)[i].loc; + typeLoc.type = (*copyOf.structure)[i].type->clone(remapper); + structure->push_back(typeLoc); } } else { structure = iter->second; diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h index 725de03..6ced6a4 100644 --- a/glslang/Include/intermediate.h +++ b/glslang/Include/intermediate.h @@ -320,9 +320,9 @@ class TIntermNode { public: POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator) - TIntermNode() : line(0) {} - virtual TSourceLoc getLine() const { return line; } - virtual void setLine(TSourceLoc l) { line = l; } + TIntermNode() { loc.line = 0; loc.string = 0; } + virtual TSourceLoc getLoc() const { return loc; } + virtual void setLoc(TSourceLoc l) { loc = l; } virtual void traverse(TIntermTraverser*) = 0; virtual TIntermTyped* getAsTyped() { return 0; } virtual TIntermConstantUnion* getAsConstantUnion() { return 0; } @@ -336,7 +336,7 @@ public: virtual TIntermBranch* getAsBranchNode() { return 0; } virtual ~TIntermNode() { } protected: - TSourceLoc line; + TSourceLoc loc; }; // diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp index f40a693..831f799 100644 --- a/glslang/MachineIndependent/Constant.cpp +++ b/glslang/MachineIndependent/Constant.cpp @@ -195,7 +195,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod newConstArray[i].setUConst(unionArray[i].getUConst() / rightUnionArray[i].getUConst()); break; default: - infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", getLine()); + infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", getLoc()); return 0; } } @@ -352,13 +352,13 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod break; default: - infoSink.info.message(EPrefixInternalError, "Invalid operator for constant folding", getLine()); + infoSink.info.message(EPrefixInternalError, "Invalid operator for constant folding", getLoc()); return 0; } TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, returnType); - newNode->setLine(getLine()); + newNode->setLoc(getLoc()); return newNode; } @@ -416,7 +416,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType, case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); break; case EbtUint: newConstArray[i].setUConst(static_cast(-static_cast(unionArray[i].getUConst()))); break; default: - infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine()); + infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLoc()); return 0; } break; @@ -425,7 +425,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType, switch (getType().getBasicType()) { case EbtBool: newConstArray[i].setBConst(!unionArray[i].getBConst()); break; default: - infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine()); + infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLoc()); return 0; } break; @@ -570,14 +570,14 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType, case EOpAll: default: - infoSink.info.message(EPrefixInternalError, "missing operator for unary constant folding", getLine()); + infoSink.info.message(EPrefixInternalError, "missing operator for unary constant folding", getLoc()); return 0; } } TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, returnType); newNode->getTypePointer()->getQualifier().storage = EvqConst; - newNode->setLine(getLine()); + newNode->setLoc(getLoc()); return newNode; } @@ -667,7 +667,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) case EOpReflect: case EOpRefract: case EOpOuterProduct: - infoSink.info.message(EPrefixInternalError, "constant folding operation not implemented", aggrNode->getLine()); + infoSink.info.message(EPrefixInternalError, "constant folding operation not implemented", aggrNode->getLoc()); return aggrNode; default: @@ -676,7 +676,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, aggrNode->getType()); newNode->getTypePointer()->getQualifier().storage = EvqConst; - newNode->setLine(aggrNode->getLine()); + newNode->setLoc(aggrNode->getLoc()); return newNode; } @@ -705,12 +705,12 @@ TIntermTyped* TIntermediate::foldConstructor(TIntermAggregate* aggrNode) constUnion* unionArray = new constUnion[aggrNode->getType().getObjectSize()]; if (aggrNode->getSequence().size() == 1) - returnVal = parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType(), true); + returnVal = parseConstTree(aggrNode->getLoc(), aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType(), true); else - returnVal = parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType()); + returnVal = parseConstTree(aggrNode->getLoc(), aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType()); if (returnVal) return aggrNode; - return addConstantUnion(unionArray, aggrNode->getType(), aggrNode->getLine()); + return addConstantUnion(unionArray, aggrNode->getType(), aggrNode->getLoc()); } diff --git a/glslang/MachineIndependent/Initialize.h b/glslang/MachineIndependent/Initialize.h index b341b61..c3e9b0e 100644 --- a/glslang/MachineIndependent/Initialize.h +++ b/glslang/MachineIndependent/Initialize.h @@ -70,7 +70,5 @@ protected: void IdentifyBuiltIns(int version, EProfile profile, EShLanguage, TSymbolTable&); void IdentifyBuiltIns(int version, EProfile profile, EShLanguage, TSymbolTable&, const TBuiltInResource &resources); -extern "C" int InitPreprocessor(void); -extern "C" int FinalizePreprocessor(void); #endif // _INITIALIZE_INCLUDED_ diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp index 6a1e65f..dd9c1d7 100644 --- a/glslang/MachineIndependent/Intermediate.cpp +++ b/glslang/MachineIndependent/Intermediate.cpp @@ -56,10 +56,10 @@ // // Returns the added node. // -TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, TSourceLoc line) +TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, TSourceLoc loc) { TIntermSymbol* node = new TIntermSymbol(id, name, type); - node->setLine(line); + node->setLoc(loc); return node; } @@ -69,7 +69,7 @@ TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType // // Returns the added node. // -TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line) +TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) { // No operations work on blocks if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock) @@ -92,9 +92,9 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn // one and promote it to the right type. // TIntermBinary* node = new TIntermBinary(op); - if (line == 0) - line = right->getLine(); - node->setLine(line); + if (loc.line == 0) + loc = right->getLoc(); + node->setLoc(loc); node->setLeft(left); node->setRight(right); @@ -114,7 +114,7 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn if (folded) return folded; else - infoSink.info.message(EPrefixInternalError, "Constant folding failed", line); + infoSink.info.message(EPrefixInternalError, "Constant folding failed", loc); } return node; @@ -125,7 +125,7 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn // // Returns the added node. // -TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line) +TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) { // No block assignment if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock) @@ -136,9 +136,9 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm // from right to left. // TIntermBinary* node = new TIntermBinary(op); - if (line == 0) - line = left->getLine(); - node->setLine(line); + if (loc.line == 0) + loc = left->getLoc(); + node->setLoc(loc); TIntermTyped* child = addConversion(op, left->getType(), right); if (child == 0) @@ -161,12 +161,12 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm // Returns the added node. // The caller should set the type of the returned node. // -TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc line) +TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc loc) { TIntermBinary* node = new TIntermBinary(op); - if (line == 0) - line = index->getLine(); - node->setLine(line); + if (loc.line == 0) + loc = index->getLoc(); + node->setLoc(loc); node->setLeft(base); node->setRight(index); @@ -180,7 +180,7 @@ TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermT // // Returns the added node. // -TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TSourceLoc line) +TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TSourceLoc loc) { TIntermTyped* child = childNode->getAsTyped(); @@ -188,7 +188,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, return 0; if (child == 0) { - infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", line); + infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", loc); return 0; } @@ -248,9 +248,9 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, // Make a new node for the operator. // TIntermUnary* node = new TIntermUnary(op); - if (line == 0) - line = child->getLine(); - node->setLine(line); + if (loc.line == 0) + loc = child->getLoc(); + node->setLoc(loc); node->setOperand(child); if (! node->promote(infoSink)) @@ -274,7 +274,7 @@ TIntermTyped* TIntermediate::addBuiltInFunctionCall(TOperator op, bool unary, TI // TIntermTyped* child = childNode->getAsTyped(); if (child == 0) { - infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", child->getLine()); + infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", child->getLoc()); return 0; } @@ -284,7 +284,7 @@ TIntermTyped* TIntermediate::addBuiltInFunctionCall(TOperator op, bool unary, TI return child->getAsConstantUnion()->fold(op, returnType, infoSink); TIntermUnary* node = new TIntermUnary(op); - node->setLine(child->getLine()); + node->setLoc(child->getLoc()); node->setOperand(child); node->setType(returnType); @@ -299,7 +299,7 @@ TIntermTyped* TIntermediate::addBuiltInFunctionCall(TOperator op, bool unary, TI return node; } else { // setAggregateOperater() calls fold() for constant folding - TIntermTyped* node = setAggregateOperator(childNode, op, returnType, childNode->getLine()); + TIntermTyped* node = setAggregateOperator(childNode, op, returnType, childNode->getLoc()); TPrecisionQualifier correctPrecision = returnType.getQualifier().precision; if (correctPrecision == EpqNone && profile == EEsProfile) { @@ -328,7 +328,7 @@ TIntermTyped* TIntermediate::addBuiltInFunctionCall(TOperator op, bool unary, TI // Returns an aggregate node, which could be the one passed in if // it was already an aggregate. // -TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TType& type, TSourceLoc line) +TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TType& type, TSourceLoc loc) { TIntermAggregate* aggNode; @@ -343,8 +343,8 @@ TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator o // aggNode = new TIntermAggregate(); aggNode->getSequence().push_back(node); - if (line == 0) - line = node->getLine(); + if (loc.line == 0) + loc = node->getLoc(); } } else aggNode = new TIntermAggregate(); @@ -353,8 +353,8 @@ TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator o // Set the operator. // aggNode->setOperator(op); - if (line != 0) - aggNode->setLine(line); + if (loc.line != 0) + aggNode->setLoc(loc); aggNode->setType(type); @@ -510,7 +510,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt //case EbtBool: newOp = EOpConvBoolToDouble; break; //case EbtFloat: newOp = EOpConvFloatToDouble; break; //default: - infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine()); + infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLoc()); return 0; //} break; @@ -521,7 +521,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt case EbtBool: newOp = EOpConvBoolToFloat; break; case EbtDouble: newOp = EOpConvDoubleToFloat; break; default: - infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine()); + infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLoc()); return 0; } break; @@ -532,7 +532,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt case EbtFloat: newOp = EOpConvFloatToBool; break; case EbtDouble: newOp = EOpConvDoubleToBool; break; default: - infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine()); + infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLoc()); return 0; } break; @@ -543,7 +543,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt case EbtFloat: newOp = EOpConvFloatToInt; break; case EbtDouble: newOp = EOpConvDoubleToInt; break; default: - infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine()); + infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLoc()); return 0; } break; @@ -554,18 +554,18 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt case EbtFloat: newOp = EOpConvFloatToUint; break; case EbtDouble: newOp = EOpConvDoubleToUint; break; default: - infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine()); + infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLoc()); return 0; } break; default: - infoSink.info.message(EPrefixInternalError, "Bad promotion type", node->getLine()); + infoSink.info.message(EPrefixInternalError, "Bad promotion type", node->getLoc()); return 0; } TType type(promoteTo, EvqTemporary, node->getVectorSize(), node->getMatrixCols(), node->getMatrixRows()); newNode = new TIntermUnary(newOp, type); - newNode->setLine(node->getLine()); + newNode->setLoc(node->getLoc()); newNode->setOperand(node); return newNode; @@ -628,7 +628,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to) // Returns the resulting aggregate, unless 0 was passed in for // both existing nodes. // -TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc line) +TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right) { if (left == 0 && right == 0) return 0; @@ -645,8 +645,13 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r if (right) aggNode->getSequence().push_back(right); - if (line != 0) - aggNode->setLine(line); + return aggNode; +} + +TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc loc) +{ + TIntermAggregate* aggNode = growAggregate(left, right); + aggNode->setLoc(loc); return aggNode; } @@ -656,18 +661,26 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r // // Returns an aggregate, unless 0 was passed in for the existing node. // -TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc line) +TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node) { if (node == 0) return 0; TIntermAggregate* aggNode = new TIntermAggregate; aggNode->getSequence().push_back(node); + aggNode->setLoc(node->getLoc()); + + return aggNode; +} - if (line != 0) - aggNode->setLine(line); - else - aggNode->setLine(node->getLine()); +TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc loc) +{ + if (node == 0) + return 0; + + TIntermAggregate* aggNode = new TIntermAggregate; + aggNode->getSequence().push_back(node); + aggNode->setLoc(loc); return aggNode; } @@ -679,7 +692,7 @@ TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc lin // // Returns the selection node created. // -TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, TSourceLoc line) +TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, TSourceLoc loc) { // // For compile time constant selections, prune the code and @@ -694,20 +707,20 @@ TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nod } TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2); - node->setLine(line); + node->setLoc(loc); return node; } -TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc line) +TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) { if (left->getType().getQualifier().storage == EvqConst && right->getType().getQualifier().storage == EvqConst) { return right; } else { - TIntermTyped *commaAggregate = growAggregate(left, right, line); + TIntermTyped *commaAggregate = growAggregate(left, right, loc); commaAggregate->getAsAggregate()->setOperator(EOpComma); commaAggregate->setType(right->getType()); commaAggregate->getTypePointer()->getQualifier().storage = EvqTemporary; @@ -717,10 +730,10 @@ TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, T } } -TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type, const TString* name, TSourceLoc line) +TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type, const TString* name, TSourceLoc loc) { TIntermMethod* method = new TIntermMethod(object, type, *name); - method->setLine(line); + method->setLoc(loc); return method; } @@ -732,7 +745,7 @@ TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type, // // Returns the selection node created, or 0 if one could not be. // -TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc line) +TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc loc) { // // Get compatible types. @@ -767,7 +780,7 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true // Make a selection node. // TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType()); - node->setLine(line); + node->setLoc(loc); node->getQualifier().precision = std::max(trueBlock->getQualifier().precision, falseBlock->getQualifier().precision); return node; @@ -779,20 +792,20 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true // Returns the constant union node created. // -TIntermConstantUnion* TIntermediate::addConstantUnion(constUnion* unionArrayPointer, const TType& t, TSourceLoc line) +TIntermConstantUnion* TIntermediate::addConstantUnion(constUnion* unionArrayPointer, const TType& t, TSourceLoc loc) { TIntermConstantUnion* node = new TIntermConstantUnion(unionArrayPointer, t); - node->setLine(line); + node->setLoc(loc); return node; } -TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line) +TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc loc) { TIntermAggregate* node = new TIntermAggregate(EOpSequence); - node->setLine(line); + node->setLoc(loc); TIntermConstantUnion* constIntNode; TIntermSequence &sequenceVector = node->getSequence(); constUnion* unionArray; @@ -800,7 +813,7 @@ TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line) for (int i = 0; i < fields.num; i++) { unionArray = new constUnion[1]; unionArray->setIConst(fields.offsets[i]); - constIntNode = addConstantUnion(unionArray, TType(EbtInt, EvqConst), line); + constIntNode = addConstantUnion(unionArray, TType(EbtInt, EvqConst), loc); sequenceVector.push_back(constIntNode); } @@ -810,10 +823,10 @@ TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line) // // Create loop nodes. // -TIntermNode* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, TSourceLoc line) +TIntermNode* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, TSourceLoc loc) { TIntermNode* node = new TIntermLoop(body, test, terminal, testFirst); - node->setLine(line); + node->setLoc(loc); return node; } @@ -821,15 +834,15 @@ TIntermNode* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TInte // // Add branches. // -TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TSourceLoc line) +TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TSourceLoc loc) { - return addBranch(branchOp, 0, line); + return addBranch(branchOp, 0, loc); } -TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, TSourceLoc line) +TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, TSourceLoc loc) { TIntermBranch* node = new TIntermBranch(branchOp, expression); - node->setLine(line); + node->setLoc(loc); return node; } @@ -886,7 +899,7 @@ void TIntermediate::addSymbolLinkageNodes(TIntermNode* root, TIntermAggregate*& linkage->setOperator(EOpLinkerObjects); // Add a child to the root node for the linker objects - growAggregate(root, linkage, 0); + growAggregate(root, linkage); } } @@ -900,7 +913,7 @@ void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTabl void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, const TVariable& variable) { TIntermSymbol* node = new TIntermSymbol(variable.getUniqueId(), variable.getName(), variable.getType()); - linkage = growAggregate(linkage, node, 0); + linkage = growAggregate(linkage, node); } // @@ -1218,7 +1231,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink) setType(TType(basicType, EvqTemporary, right->getVectorSize())); } } else { - infoSink.info.message(EPrefixInternalError, "Missing elses", getLine()); + infoSink.info.message(EPrefixInternalError, "Missing elses", getLoc()); return false; } break; @@ -1250,7 +1263,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink) op = EOpVectorTimesScalarAssign; } } else { - infoSink.info.message(EPrefixInternalError, "Missing elses", getLine()); + infoSink.info.message(EPrefixInternalError, "Missing elses", getLoc()); return false; } break; @@ -1381,7 +1394,7 @@ void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision) TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node) { if (node->getType().isArray()) - infoSink.info.message(EPrefixInternalError, "Cannot promote array", node->getLine()); + infoSink.info.message(EPrefixInternalError, "Cannot promote array", node->getLoc()); constUnion *rightUnionArray = node->getUnionArrayPointer(); int size = node->getType().getObjectSize(); @@ -1408,7 +1421,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getBConst())); break; default: - infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine()); + infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLoc()); return 0; } break; @@ -1428,7 +1441,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC leftUnionArray[i] = rightUnionArray[i]; break; default: - infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine()); + infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLoc()); return 0; } break; @@ -1448,7 +1461,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC leftUnionArray[i].setIConst(static_cast(rightUnionArray[i].getDConst())); break; default: - infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine()); + infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLoc()); return 0; } break; @@ -1468,7 +1481,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC leftUnionArray[i].setUConst(static_cast(rightUnionArray[i].getDConst())); break; default: - infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine()); + infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLoc()); return 0; } break; @@ -1488,12 +1501,12 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC leftUnionArray[i].setBConst(rightUnionArray[i].getDConst() != 0.0); break; default: - infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine()); + infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLoc()); return 0; } break; default: - infoSink.info.message(EPrefixInternalError, "Incorrect data type found", node->getLine()); + infoSink.info.message(EPrefixInternalError, "Incorrect data type found", node->getLoc()); return 0; } } @@ -1501,7 +1514,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC const TType& t = node->getType(); return addConstantUnion(leftUnionArray, TType(promoteTo, t.getQualifier().storage, t.getVectorSize(), t.getMatrixCols(), t.getMatrixRows()), - node->getLine()); + node->getLoc()); } void TIntermAggregate::addToPragmaTable(const TPragmaTable& pTable) diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index e6006c2..9c2efa9 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -40,10 +40,14 @@ #include #include +extern "C" { + #include "./preprocessor/preprocess.h" +} + TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb, int v, EProfile p, EShLanguage L, TInfoSink& is, bool fc, EShMessages m) : intermediate(interm), symbolTable(symt), infoSink(is), language(L), treeRoot(0), linkage(0), - numErrors(0), lexAfterType(false), loopNestingLevel(0), + numErrors(0), loopNestingLevel(0), structNestingLevel(0), inTypeParen(false), parsingBuiltins(pb), version(v), profile(p), forwardCompatible(fc), messages(m), contextPragma(true, false) @@ -77,7 +81,7 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb, defaultPrecision[EbtSampler] = EpqLow; break; default: - error(1, "INTERNAL ERROR", "unexpected language", ""); + infoSink.info.message(EPrefixError, "unexpected language"); } } @@ -90,8 +94,8 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb, globalOutputDefaults.clear(); } -// Get code that is not part of a shared symbol table, specific to this shader -// or needed by CPP (which does not have a shared symbol table). +// Get code that is not part of a shared symbol table, is specific to this shader, +// or needed by CPP (which does not use a shared symbol table). const char* TParseContext::getPreamble() { if (profile == EEsProfile) @@ -100,6 +104,370 @@ const char* TParseContext::getPreamble() return 0; } +TSourceLoc currentLine; // TODO: thread: get this into the scan context, sort out with return from PP +#ifdef _WIN32 + extern int yyparse(TParseContext&); +#else + extern int yyparse(void*); + #define parseContext (*((TParseContext*)(parseContextLocal))) +#endif + +// +// Parse an array of strings using yyparse. We set up globals used by +// yywrap. +// +// Returns true for success, false for failure. +// +bool TParseContext::parseShaderStrings(char* strings[], int strLen[], int numStrings) +{ + if (! strings || numStrings == 0) + return false; + + for (int i = 0; i < numStrings; ++i) { + if (! strings[i]) { + TSourceLoc loc; + loc.string = i; + loc.line = 1; + error(loc, "Null shader source string", "", ""); + + return false; + } + } + + // set up all the cpp fields... + // TODO: thread safety: don't move 'this' into the global + cpp->pC = (void*)this; + const char* preamble = getPreamble(); + char *writeablePreamble = 0; + if (preamble) { + // preAmble could be a hard-coded string; make writable copy + // TODO: efficiency PP: make it not need writable strings + int size = strlen(preamble) + 1; + writeablePreamble = new char[size]; + memcpy(writeablePreamble, preamble, size); + ScanFromString(writeablePreamble); + cpp->PaWhichStr = -1; + } else { + ScanFromString(strings[0]); + cpp->PaWhichStr = 0; + } + + afterEOF = false; + cpp->PaArgv = strings; + cpp->PaArgc = numStrings; + int string0len; + if (! strLen) { + string0len = (int) strlen(strings[0]); + cpp->PaStrLen = &string0len; + } else + cpp->PaStrLen = strLen; + cpp->notAVersionToken = 0; + currentLine.string = 0; + currentLine.line = 1; + + // TODO: desktop PP: a shader containing nothing but white space and comments is valid, even though it has no parse tokens + int len = 0; + while (strings[0][len] == ' ' || + strings[0][len] == '\t' || + strings[0][len] == '\n' || + strings[0][len] == '\r') { + if (++len >= strLen[0]) { + delete writeablePreamble; + return true; + } + } + + if (*cpp->PaStrLen > 0) { + int ret; + #ifdef _WIN32 + ret = yyparse(*this); + #else + ret = yyparse((void*)this); + #endif + delete writeablePreamble; + if (cpp->CompileError == 1 || numErrors > 0) + return false; + else + return true; + } + + delete writeablePreamble; + + return true; +} + +// TODO: fix this for threads +void yyerror(const char *s) +{ + TParseContext& pc = *((TParseContext *)cpp->pC); + + if (pc.afterEOF) { + if (cpp->tokensBeforeEOF == 1) + ThreadLocalParseContext()->error(currentLine, "", "pre-mature EOF", s, ""); + } else + ThreadLocalParseContext()->error(currentLine, "", "", s, ""); +} + + +extern "C" { + +// Communications with the preprocess. +// TODO: threads: this all needs redoing for thread safety + +void ShPpDebugLogMsg(const char *msg) +{ + TParseContext& pc = *((TParseContext *)cpp->pC); + + pc.infoSink.debug.message(EPrefixNone, msg); +} + +void ShPpWarningToInfoLog(const char *msg) +{ + TParseContext& pc = *((TParseContext *)cpp->pC); + + pc.warn(currentLine, msg, "Preprocessor", ""); +} + +void ShPpErrorToInfoLog(const char *msg) +{ + TParseContext& pc = *((TParseContext *)cpp->pC); + + pc.error(currentLine, msg, "Preprocessor", ""); +} + +// return 1 if error +// return 0 if no error +int ShPpMacrosMustBeDefinedError() +{ + TParseContext& pc = *((TParseContext *)cpp->pC); + + if (pc.profile == EEsProfile) { + if (pc.messages & EShMsgRelaxedErrors) + ShPpWarningToInfoLog("undefined macro in expression not allowed in es profile"); + else { + ShPpErrorToInfoLog("undefined macro in expression"); + + return 1; + } + } + + return 0; +} + +// TODO: PP/threads: integrate this with location from token +void SetLineNumber(int line) +{ + currentLine.line = line; +} + +void SetStringNumber(int string) +{ + currentLine.string = string; +} + +int GetStringNumber(void) +{ + return currentLine.string; +} + +int GetLineNumber(void) +{ + return currentLine.line; +} + +void IncLineNumber(void) +{ + ++currentLine.line; +} + +void DecLineNumber(void) +{ + --currentLine.line; +} + +void HandlePragma(const char **tokens, int numTokens) +{ + TParseContext& pc = *((TParseContext *)cpp->pC); + + if (!strcmp(tokens[0], "optimize")) { + if (numTokens != 4) { + ShPpErrorToInfoLog("optimize pragma syntax is incorrect"); + return; + } + + if (strcmp(tokens[1], "(")) { + ShPpErrorToInfoLog("\"(\" expected after 'optimize' keyword"); + return; + } + + if (!strcmp(tokens[2], "on")) + pc.contextPragma.optimize = true; + else if (!strcmp(tokens[2], "off")) + pc.contextPragma.optimize = false; + else { + ShPpErrorToInfoLog("\"on\" or \"off\" expected after '(' for 'optimize' pragma"); + return; + } + + if (strcmp(tokens[3], ")")) { + ShPpErrorToInfoLog("\")\" expected to end 'optimize' pragma"); + return; + } + } else if (!strcmp(tokens[0], "debug")) { + if (numTokens != 4) { + ShPpErrorToInfoLog("debug pragma syntax is incorrect"); + return; + } + + if (strcmp(tokens[1], "(")) { + ShPpErrorToInfoLog("\"(\" expected after 'debug' keyword"); + return; + } + + if (!strcmp(tokens[2], "on")) + pc.contextPragma.debug = true; + else if (!strcmp(tokens[2], "off")) + pc.contextPragma.debug = false; + else { + ShPpErrorToInfoLog("\"on\" or \"off\" expected after '(' for 'debug' pragma"); + return; + } + + if (strcmp(tokens[3], ")")) { + ShPpErrorToInfoLog("\")\" expected to end 'debug' pragma"); + return; + } + } else { + +#ifdef PRAGMA_TABLE + // + // implementation specific pragma + // use parseContext.contextPragma.pragmaTable to store the information about pragma + // For now, just ignore the pragma that the implementation cannot recognize + // An Example of one such implementation for a pragma that has a syntax like + // #pragma pragmaname(pragmavalue) + // This implementation stores the current pragmavalue against the pragma name in pragmaTable. + // + if (numTokens == 4 && !strcmp(tokens[1], "(") && !strcmp(tokens[3], ")")) { + TPragmaTable& pragmaTable = parseContext.contextPragma.pragmaTable; + TPragmaTable::iterator iter; + iter = pragmaTable.find(TString(tokens[0])); + if (iter != pragmaTable.end()) { + iter->second = tokens[2]; + } else { + pragmaTable[tokens[0]] = tokens[2]; + } + } else if (numTokens >= 2) { + TPragmaTable& pragmaTable = parseContext.contextPragma.pragmaTable; + TPragmaTable::iterator iter; + iter = pragmaTable.find(TString(tokens[0])); + if (iter != pragmaTable.end()) { + iter->second = tokens[1]; + } else { + pragmaTable[tokens[0]] = tokens[1]; + } + } +#endif // PRAGMA_TABLE + } +} + +void StoreStr(const char *string) +{ + TParseContext& pc = *((TParseContext *)cpp->pC); + + TString strSrc; + strSrc = TString(string); + + pc.HashErrMsg = pc.HashErrMsg + " " + strSrc; +} + +const char* GetStrfromTStr(void) +{ + TParseContext& pc = *((TParseContext *)cpp->pC); + + cpp->ErrMsg = pc.HashErrMsg.c_str(); + return cpp->ErrMsg; +} + +void ResetTString(void) +{ + TParseContext& pc = *((TParseContext *)cpp->pC); + + pc.HashErrMsg = ""; +} + +void SetVersion(int version) +{ + // called by the CPP, but this functionality is currently + // taken over by ScanVersion() before parsing starts + + // CPP should still report errors in semantics +} + +int GetShaderVersion(void* cppPc) +{ + TParseContext& pc = *((TParseContext *)cppPc); + + return pc.version; +} + +TBehavior GetBehavior(const char* behavior) +{ + if (!strcmp("require", behavior)) + return EBhRequire; + else if (!strcmp("enable", behavior)) + return EBhEnable; + else if (!strcmp("disable", behavior)) + return EBhDisable; + else if (!strcmp("warn", behavior)) + return EBhWarn; + else { + ShPpErrorToInfoLog((TString("behavior '") + behavior + "' is not supported").c_str()); + return EBhDisable; + } +} + +void updateExtensionBehavior(const char* extName, const char* behavior) +{ + TParseContext& pc = *((TParseContext *)cpp->pC); + TBehavior behaviorVal = GetBehavior(behavior); + TMap:: iterator iter; + TString msg; + + // special cased for all extension + if (!strcmp(extName, "all")) { + if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) { + ShPpErrorToInfoLog("extension 'all' cannot have 'require' or 'enable' behavior"); + return; + } else { + for (iter = pc.extensionBehavior.begin(); iter != pc.extensionBehavior.end(); ++iter) + iter->second = behaviorVal; + } + } else { + iter = pc.extensionBehavior.find(TString(extName)); + if (iter == pc.extensionBehavior.end()) { + switch (behaviorVal) { + case EBhRequire: + ShPpErrorToInfoLog((TString("extension '") + extName + "' is not supported").c_str()); + break; + case EBhEnable: + case EBhWarn: + case EBhDisable: + pc.warn(currentLine, "extension not supported", extName, ""); + break; + default: + assert(0 && "unexpected behaviorVal"); + } + + return; + } else + iter->second = behaviorVal; + } +} + +} // extern "C" + + /////////////////////////////////////////////////////////////////////// // // Sub- vector and matrix fields @@ -112,11 +480,11 @@ const char* TParseContext::getPreamble() // // Returns true if there is no error. // -bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, int line) +bool TParseContext::parseVectorFields(TSourceLoc loc, const TString& compString, int vecSize, TVectorFields& fields) { fields.num = (int) compString.size(); if (fields.num > 4) { - error(line, "illegal vector field selection", compString.c_str(), ""); + error(loc, "illegal vector field selection", compString.c_str(), ""); return false; } @@ -178,20 +546,20 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV fieldSet[i] = estpq; break; default: - error(line, "illegal vector field selection", compString.c_str(), ""); + error(loc, "illegal vector field selection", compString.c_str(), ""); return false; } } for (int i = 0; i < fields.num; ++i) { if (fields.offsets[i] >= vecSize) { - error(line, "vector field selection out of range", compString.c_str(), ""); + error(loc, "vector field selection out of range", compString.c_str(), ""); return false; } if (i > 0) { if (fieldSet[i] != fieldSet[i-1]) { - error(line, "illegal - vector component fields not from the same set", compString.c_str(), ""); + error(loc, "illegal - vector component fields not from the same set", compString.c_str(), ""); return false; } } @@ -209,7 +577,7 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV // // Used to output syntax, parsing, and semantic errors. // -void C_DECL TParseContext::error(TSourceLoc nLine, const char *szReason, const char *szToken, +void C_DECL TParseContext::error(TSourceLoc loc, const char *szReason, const char *szToken, const char *szExtraInfoFormat, ...) { const int maxSize = GlslangMaxTokenLength + 200; @@ -221,7 +589,7 @@ void C_DECL TParseContext::error(TSourceLoc nLine, const char *szReason, const c safe_vsprintf(szExtraInfo, maxSize, szExtraInfoFormat, marker); infoSink.info.prefix(EPrefixError); - infoSink.info.location(nLine); + infoSink.info.location(loc); infoSink.info << "'" << szToken << "' : " << szReason << " " << szExtraInfo << "\n"; va_end(marker); @@ -229,7 +597,7 @@ void C_DECL TParseContext::error(TSourceLoc nLine, const char *szReason, const c ++numErrors; } -void C_DECL TParseContext::warn(TSourceLoc nLine, const char *szReason, const char *szToken, +void C_DECL TParseContext::warn(TSourceLoc loc, const char *szReason, const char *szToken, const char *szExtraInfoFormat, ...) { if (messages & EShMsgSuppressWarnings) @@ -244,13 +612,13 @@ void C_DECL TParseContext::warn(TSourceLoc nLine, const char *szReason, const ch safe_vsprintf(szExtraInfo, maxSize, szExtraInfoFormat, marker); infoSink.info.prefix(EPrefixWarning); - infoSink.info.location(nLine); + infoSink.info.location(loc); infoSink.info << "'" << szToken << "' : " << szReason << " " << szExtraInfo << "\n"; va_end(marker); } -TIntermTyped* TParseContext::handleVariable(int line, TSymbol* symbol, TString* string) +TIntermTyped* TParseContext::handleVariable(TSourceLoc loc, TSymbol* symbol, TString* string) { TIntermTyped* node = 0; @@ -258,19 +626,19 @@ TIntermTyped* TParseContext::handleVariable(int line, TSymbol* symbol, TString* if (anon) { // it was a member of an anonymous container, have to insert its dereference TVariable* variable = anon->getAnonContainer().getAsVariable(); - TIntermTyped* container = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line); + TIntermTyped* container = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), loc); constUnion* unionArray = new constUnion[1]; unionArray->setUConst(anon->getMemberNumber()); - TIntermTyped* constNode = intermediate.addConstantUnion(unionArray, TType(EbtUint, EvqConst), line); + TIntermTyped* constNode = intermediate.addConstantUnion(unionArray, TType(EbtUint, EvqConst), loc); - node = intermediate.addIndex(EOpIndexDirectStruct, container, constNode, line); + node = intermediate.addIndex(EOpIndexDirectStruct, container, constNode, loc); node->setType(*(*variable->getType().getStruct())[anon->getMemberNumber()].type); } else { // The symbol table search was done in the lexical phase, but // if this is a new symbol, it wouldn't have found it. const TVariable* variable = symbol ? symbol->getAsVariable() : 0; if (symbol && ! variable) - error(line, "variable name expected", string->c_str(), ""); + error(loc, "variable name expected", string->c_str(), ""); if (! variable) variable = new TVariable(string, TType(EbtVoid)); @@ -281,9 +649,9 @@ TIntermTyped* TParseContext::handleVariable(int line, TSymbol* symbol, TString* if (variable->getType().getQualifier().storage == EvqConst ) { constUnion* constArray = variable->getConstUnionPointer(); TType t(variable->getType()); - node = intermediate.addConstantUnion(constArray, t, line); + node = intermediate.addConstantUnion(constArray, t, loc); } else - node = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line); + node = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), loc); } return node; @@ -292,18 +660,18 @@ TIntermTyped* TParseContext::handleVariable(int line, TSymbol* symbol, TString* // // Same error message for all places assignments don't work. // -void TParseContext::assignError(int line, const char* op, TString left, TString right) +void TParseContext::assignError(TSourceLoc loc, const char* op, TString left, TString right) { - error(line, "", op, "cannot convert from '%s' to '%s'", + error(loc, "", op, "cannot convert from '%s' to '%s'", right.c_str(), left.c_str()); } // // Same error message for all places unary operations don't work. // -void TParseContext::unaryOpError(int line, const char* op, TString operand) +void TParseContext::unaryOpError(TSourceLoc loc, const char* op, TString operand) { - error(line, " wrong operand type", op, + error(loc, " wrong operand type", op, "no operation '%s' exists that takes an operand of type %s (or there is no acceptable conversion)", op, operand.c_str()); } @@ -311,9 +679,9 @@ void TParseContext::unaryOpError(int line, const char* op, TString operand) // // Same error message for all binary operations don't work. // -void TParseContext::binaryOpError(int line, const char* op, TString left, TString right) +void TParseContext::binaryOpError(TSourceLoc loc, const char* op, TString left, TString right) { - error(line, " wrong operand types:", op, + error(loc, " wrong operand types:", op, "no operation '%s' exists that takes a left-hand operand of type '%s' and " "a right operand of type '%s' (or there is no acceptable conversion)", op, left.c_str(), right.c_str()); @@ -331,7 +699,7 @@ void TParseContext::variableCheck(TIntermTyped*& nodePtr) return; if (symbol->getType().getBasicType() == EbtVoid) { - error(symbol->getLine(), "undeclared identifier", symbol->getName().c_str(), ""); + error(symbol->getLoc(), "undeclared identifier", symbol->getName().c_str(), ""); // Add to symbol table to prevent future error messages on the same name @@ -341,11 +709,11 @@ void TParseContext::variableCheck(TIntermTyped*& nodePtr) // substitute a symbol node for this new variable nodePtr = intermediate.addSymbol(fakeVariable->getUniqueId(), fakeVariable->getName(), - fakeVariable->getType(), symbol->getLine()); + fakeVariable->getType(), symbol->getLoc()); } else { switch (symbol->getQualifier().storage) { case EvqPointCoord: - profileRequires(symbol->getLine(), ENoProfile, 120, 0, "gl_PointCoord"); + profileRequires(symbol->getLoc(), ENoProfile, 120, 0, "gl_PointCoord"); break; default: break; // some compilers want this } @@ -358,7 +726,7 @@ void TParseContext::variableCheck(TIntermTyped*& nodePtr) // // Returns true if the was an error. // -bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* node) +bool TParseContext::lValueErrorCheck(TSourceLoc loc, const char* op, TIntermTyped* node) { TIntermSymbol* symNode = node->getAsSymbolNode(); TIntermBinary* binaryNode = node->getAsBinaryNode(); @@ -370,9 +738,9 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod case EOpIndexDirect: case EOpIndexIndirect: case EOpIndexDirectStruct: - return lValueErrorCheck(line, op, binaryNode->getLeft()); + return lValueErrorCheck(loc, op, binaryNode->getLeft()); case EOpVectorSwizzle: - errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft()); + errorReturn = lValueErrorCheck(loc, op, binaryNode->getLeft()); if (!errorReturn) { int offset[4] = {0,0,0,0}; @@ -384,7 +752,7 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod int value = (*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->getIConst(); offset[value]++; if (offset[value] > 1) { - error(line, " l-value of swizzle cannot have duplicate components", op, "", ""); + error(loc, " l-value of swizzle cannot have duplicate components", op, "", ""); return true; } @@ -395,7 +763,7 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod default: break; } - error(line, " l-value required", op, "", ""); + error(loc, " l-value required", op, "", ""); return true; } @@ -434,7 +802,7 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod } if (message == 0 && binaryNode == 0 && symNode == 0) { - error(line, " l-value required", op, "", ""); + error(loc, " l-value required", op, "", ""); return true; } @@ -450,9 +818,9 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod // If we get here, we have an error and a message. // if (symNode) - error(line, " l-value required", op, "\"%s\" (%s)", symbol, message); + error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message); else - error(line, " l-value required", op, "(%s)", message); + error(loc, " l-value required", op, "(%s)", message); return true; } @@ -464,7 +832,7 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod void TParseContext::constCheck(TIntermTyped* node, const char* token) { if (node->getQualifier().storage != EvqConst) - error(node->getLine(), "constant expression required", token, ""); + error(node->getLoc(), "constant expression required", token, ""); } // @@ -476,17 +844,17 @@ void TParseContext::integerCheck(TIntermTyped* node, const char* token) if ((node->getBasicType() == EbtInt || node->getBasicType() == EbtUint) && node->isScalar() && ! node->isArray()) return; - error(node->getLine(), "scalar integer expression required", token, ""); + error(node->getLoc(), "scalar integer expression required", token, ""); } // // Both test, and if necessary spit out an error, to see if we are currently // globally scoped. // -void TParseContext::globalCheck(int line, bool global, const char* token) +void TParseContext::globalCheck(TSourceLoc loc, bool global, const char* token) { if (! global) - error(line, "only allowed at global scope", token, ""); + error(loc, "only allowed at global scope", token, ""); } // @@ -494,16 +862,16 @@ void TParseContext::globalCheck(int line, bool global, const char* token) // of scope. Except, if the symbol table is at the built-in push-level, // which is when we are parsing built-ins. // -bool TParseContext::reservedErrorCheck(int line, const TString& identifier) +bool TParseContext::reservedErrorCheck(TSourceLoc loc, const TString& identifier) { if (!symbolTable.atBuiltInLevel()) { if (identifier.substr(0, 3) == TString("gl_")) { - error(line, "reserved built-in name", "gl_", ""); + error(loc, "reserved built-in name", "gl_", ""); return true; } if (identifier.find("__") != TString::npos) { - error(line, "Two consecutive underscores are reserved for future use.", identifier.c_str(), "", ""); + error(loc, "Two consecutive underscores are reserved for future use.", identifier.c_str(), "", ""); return true; } @@ -519,7 +887,7 @@ bool TParseContext::reservedErrorCheck(int line, const TString& identifier) // // Returns true if there was an error in construction. // -bool TParseContext::constructorError(int line, TIntermNode* node, TFunction& function, TOperator op, TType& type) +bool TParseContext::constructorError(TSourceLoc loc, TIntermNode* node, TFunction& function, TOperator op, TType& type) { type = function.getReturnType(); @@ -584,48 +952,48 @@ bool TParseContext::constructorError(int line, TIntermNode* node, TFunction& fun // auto adapt the constructor type to the number of arguments type.changeArraySize(function.getParamCount()); } else if (type.getArraySize() != function.getParamCount()) { - error(line, "array constructor needs one argument per array element", "constructor", ""); + error(loc, "array constructor needs one argument per array element", "constructor", ""); return true; } } if (arrayArg && op != EOpConstructStruct) { - error(line, "constructing from a non-dereferenced array", "constructor", ""); + error(loc, "constructing from a non-dereferenced array", "constructor", ""); return true; } if (matrixInMatrix && ! type.isArray()) { - profileRequires(line, ENoProfile, 120, 0, "constructing matrix from matrix"); + profileRequires(loc, ENoProfile, 120, 0, "constructing matrix from matrix"); return false; } if (overFull) { - error(line, "too many arguments", "constructor", ""); + error(loc, "too many arguments", "constructor", ""); return true; } if (op == EOpConstructStruct && ! type.isArray() && type.getStruct()->size() != function.getParamCount()) { - error(line, "Number of constructor parameters does not match the number of structure fields", "constructor", ""); + error(loc, "Number of constructor parameters does not match the number of structure fields", "constructor", ""); return true; } if ((op != EOpConstructStruct && size != 1 && size < type.getObjectSize()) || (op == EOpConstructStruct && size < type.getObjectSize())) { - error(line, "not enough data provided for construction", "constructor", ""); + error(loc, "not enough data provided for construction", "constructor", ""); return true; } TIntermTyped* typed = node->getAsTyped(); if (typed == 0) { - error(line, "constructor argument does not have a type", "constructor", ""); + error(loc, "constructor argument does not have a type", "constructor", ""); return true; } if (op != EOpConstructStruct && typed->getBasicType() == EbtSampler) { - error(line, "cannot convert a sampler", "constructor", ""); + error(loc, "cannot convert a sampler", "constructor", ""); return true; } if (typed->getBasicType() == EbtVoid) { - error(line, "cannot convert a void", "constructor", ""); + error(loc, "cannot convert a void", "constructor", ""); return true; } @@ -636,10 +1004,10 @@ bool TParseContext::constructorError(int line, TIntermNode* node, TFunction& fun // // returns true in case of an error // -bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TPublicType& pubType) +bool TParseContext::voidErrorCheck(TSourceLoc loc, const TString& identifier, const TPublicType& pubType) { if (pubType.basicType == EbtVoid) { - error(line, "illegal use of type 'void'", identifier.c_str(), ""); + error(loc, "illegal use of type 'void'", identifier.c_str(), ""); return true; } @@ -647,31 +1015,31 @@ bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TP } // Checks to see if the node (for the expression) contains a scalar boolean expression or not -void TParseContext::boolCheck(int line, const TIntermTyped* type) +void TParseContext::boolCheck(TSourceLoc loc, const TIntermTyped* type) { if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) - error(line, "boolean expression expected", "", ""); + error(loc, "boolean expression expected", "", ""); } // This function checks to see if the node (for the expression) contains a scalar boolean expression or not -void TParseContext::boolCheck(int line, const TPublicType& pType) +void TParseContext::boolCheck(TSourceLoc loc, const TPublicType& pType) { if (pType.basicType != EbtBool || pType.arraySizes || pType.matrixCols > 1 || (pType.vectorSize > 1)) - error(line, "boolean expression expected", "", ""); + error(loc, "boolean expression expected", "", ""); } -bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const char* reason) +bool TParseContext::samplerErrorCheck(TSourceLoc loc, const TPublicType& pType, const char* reason) { if (pType.basicType == EbtStruct) { if (containsSampler(*pType.userDef)) { - error(line, reason, TType::getBasicString(pType.basicType), "(structure cannot contain a sampler or image)"); + error(loc, reason, TType::getBasicString(pType.basicType), "(structure cannot contain a sampler or image)"); return true; } return false; } else if (pType.basicType == EbtSampler) { - error(line, reason, TType::getBasicString(pType.basicType), ""); + error(loc, reason, TType::getBasicString(pType.basicType), ""); return true; } @@ -679,7 +1047,7 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const return false; } -void TParseContext::globalQualifierFix(int line, TQualifier& qualifier, const TPublicType& publicType) +void TParseContext::globalQualifierFix(TSourceLoc loc, TQualifier& qualifier, const TPublicType& publicType) { if (! symbolTable.atGlobalLevel()) return; @@ -688,13 +1056,13 @@ void TParseContext::globalQualifierFix(int line, TQualifier& qualifier, const TP switch (qualifier.storage) { case EvqIn: - profileRequires(line, ENoProfile, 130, 0, "in for stage inputs"); - profileRequires(line, EEsProfile, 300, 0, "in for stage inputs"); + profileRequires(loc, ENoProfile, 130, 0, "in for stage inputs"); + profileRequires(loc, EEsProfile, 300, 0, "in for stage inputs"); qualifier.storage = EvqVaryingIn; break; case EvqOut: - profileRequires(line, ENoProfile, 130, 0, "out for stage outputs"); - profileRequires(line, EEsProfile, 300, 0, "out for stage outputs"); + profileRequires(loc, ENoProfile, 130, 0, "out for stage outputs"); + profileRequires(loc, EEsProfile, 300, 0, "out for stage outputs"); qualifier.storage = EvqVaryingOut; break; case EvqVaryingIn: @@ -702,7 +1070,7 @@ void TParseContext::globalQualifierFix(int line, TQualifier& qualifier, const TP break; case EvqInOut: qualifier.storage = EvqVaryingIn; - error(line, "cannot use 'inout' at global scope", "", ""); + error(loc, "cannot use 'inout' at global scope", "", ""); return; default: @@ -711,7 +1079,7 @@ void TParseContext::globalQualifierFix(int line, TQualifier& qualifier, const TP // Do non-in/out error checks - if (qualifier.storage != EvqUniform && samplerErrorCheck(line, publicType, "samplers and images must be uniform")) + if (qualifier.storage != EvqUniform && samplerErrorCheck(loc, publicType, "samplers and images must be uniform")) return; if (qualifier.storage != EvqVaryingIn && qualifier.storage != EvqVaryingOut) @@ -720,37 +1088,37 @@ void TParseContext::globalQualifierFix(int line, TQualifier& qualifier, const TP // now, knowing it is a shader in/out, do all the in/out semantic checks if (publicType.basicType == EbtBool) { - error(line, "cannot be bool", getStorageQualifierString(qualifier.storage), ""); + error(loc, "cannot be bool", getStorageQualifierString(qualifier.storage), ""); return; } if (language == EShLangVertex && qualifier.storage == EvqVaryingIn) { if (publicType.basicType == EbtStruct) { - error(line, "cannot be a structure or array", getStorageQualifierString(qualifier.storage), ""); + error(loc, "cannot be a structure or array", getStorageQualifierString(qualifier.storage), ""); return; } if (publicType.arraySizes) { - requireProfile(line, (EProfileMask)~EEsProfileMask, "vertex input arrays"); - profileRequires(line, ENoProfile, 150, 0, "vertex input arrays"); + requireProfile(loc, (EProfileMask)~EEsProfileMask, "vertex input arrays"); + profileRequires(loc, ENoProfile, 150, 0, "vertex input arrays"); } } if (language == EShLangFragment && qualifier.storage == EvqVaryingOut) { - profileRequires(line, EEsProfile, 300, 0, "fragment shader output"); + profileRequires(loc, EEsProfile, 300, 0, "fragment shader output"); if (publicType.basicType == EbtStruct) { - error(line, "cannot be a structure", getStorageQualifierString(qualifier.storage), ""); + error(loc, "cannot be a structure", getStorageQualifierString(qualifier.storage), ""); return; } } if (publicType.basicType == EbtInt || publicType.basicType == EbtUint || publicType.basicType == EbtDouble) { - profileRequires(line, EEsProfile, 300, 0, "shader input/output"); + profileRequires(loc, EEsProfile, 300, 0, "shader input/output"); if (language != EShLangVertex && qualifier.storage == EvqVaryingIn && ! qualifier.flat || language != EShLangFragment && qualifier.storage == EvqVaryingOut && ! qualifier.flat) { - error(line, "must be qualified as 'flat'", getStorageQualifierString(qualifier.storage), TType::getBasicString(publicType.basicType)); + error(loc, "must be qualified as 'flat'", getStorageQualifierString(qualifier.storage), TType::getBasicString(publicType.basicType)); return; } @@ -758,7 +1126,7 @@ void TParseContext::globalQualifierFix(int line, TQualifier& qualifier, const TP if (language == EShLangVertex && qualifier.storage == EvqVaryingIn && (qualifier.isAuxiliary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.invariant)) { - error(line, "vertex input cannot be further qualified", "", ""); + error(loc, "vertex input cannot be further qualified", "", ""); return; } @@ -773,31 +1141,31 @@ void TParseContext::globalQualifierFix(int line, TQualifier& qualifier, const TP // 'dst', for the purpose of error checking order for versions // that require specific orderings of qualifiers. // -void TParseContext::mergeQualifiers(int line, TQualifier& dst, const TQualifier& src, bool force) +void TParseContext::mergeQualifiers(TSourceLoc loc, TQualifier& dst, const TQualifier& src, bool force) { // Multiple auxiliary qualifiers (mostly done later by 'individual qualifiers') if (src.isAuxiliary() && dst.isAuxiliary()) - error(line, "can only have one auxiliary qualifier (centroid, patch, and sample)", "", ""); + error(loc, "can only have one auxiliary qualifier (centroid, patch, and sample)", "", ""); // Multiple interpolation qualifiers (mostly done later by 'individual qualifiers') if (src.isInterpolation() && dst.isInterpolation()) - error(line, "can only have one interpolation qualifier (flat, smooth, noperspective)", "", ""); + error(loc, "can only have one interpolation qualifier (flat, smooth, noperspective)", "", ""); // Ordering if (! force && version < 420) { // non-function parameters if (src.invariant && (dst.isInterpolation() || dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone)) - error(line, "invariant qualifier must appear first", "", ""); + error(loc, "invariant qualifier must appear first", "", ""); else if (src.isInterpolation() && (dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone)) - error(line, "interpolation qualifiers must appear before storage and precision qualifiers", "", ""); + error(loc, "interpolation qualifiers must appear before storage and precision qualifiers", "", ""); else if (src.isAuxiliary() && (dst.storage != EvqTemporary || dst.precision != EpqNone)) - error(line, "Auxiliary qualifiers (centroid, patch, and sample) must appear before storage and precision qualifiers", "", ""); + error(loc, "Auxiliary qualifiers (centroid, patch, and sample) must appear before storage and precision qualifiers", "", ""); else if (src.storage != EvqTemporary && (dst.precision != EpqNone)) - error(line, "precision qualifier must appear as last qualifier", "", ""); + error(loc, "precision qualifier must appear as last qualifier", "", ""); // function parameters if (src.storage == EvqConst && (dst.storage == EvqIn || dst.storage == EvqOut)) - error(line, "in/out must appear before const", "", ""); + error(loc, "in/out must appear before const", "", ""); } // Storage qualification @@ -810,16 +1178,16 @@ void TParseContext::mergeQualifiers(int line, TQualifier& dst, const TQualifier& dst.storage == EvqConst && src.storage == EvqIn) dst.storage = EvqConstReadOnly; else if (src.storage != EvqTemporary) - error(line, "too many storage qualifiers", getStorageQualifierString(src.storage), ""); + error(loc, "too many storage qualifiers", getStorageQualifierString(src.storage), ""); // Precision qualifiers if (! force && src.precision != EpqNone && dst.precision != EpqNone) - error(line, "only one precision qualifier allowed", getPrecisionQualifierString(src.precision), ""); + error(loc, "only one precision qualifier allowed", getPrecisionQualifierString(src.precision), ""); if (dst.precision == EpqNone || force && src.precision != EpqNone) dst.precision = src.precision; // Layout qualifiers - mergeLayoutQualifiers(line, dst, src); + mergeLayoutQualifiers(loc, dst, src); // individual qualifiers bool repeated = false; @@ -839,10 +1207,10 @@ void TParseContext::mergeQualifiers(int line, TQualifier& dst, const TQualifier& MERGE_SINGLETON(writeonly); if (repeated) - error(line, "replicated qualifiers", "", ""); + error(loc, "replicated qualifiers", "", ""); } -void TParseContext::setDefaultPrecision(int line, TPublicType& publicType, TPrecisionQualifier qualifier) +void TParseContext::setDefaultPrecision(TSourceLoc loc, TPublicType& publicType, TPrecisionQualifier qualifier) { TBasicType basicType = publicType.basicType; @@ -862,7 +1230,7 @@ void TParseContext::setDefaultPrecision(int line, TPublicType& publicType, TPrec } } - error(line, "cannot apply precision statement to this type; use 'float', 'int' or a sampler type", TType::getBasicString(basicType), ""); + error(loc, "cannot apply precision statement to this type; use 'float', 'int' or a sampler type", TType::getBasicString(basicType), ""); } // used to flatten the sampler type space into a single dimension @@ -883,7 +1251,7 @@ TPrecisionQualifier TParseContext::getDefaultPrecision(TPublicType& publicType) return defaultPrecision[publicType.basicType]; } -void TParseContext::precisionQualifierCheck(int line, TPublicType& publicType) +void TParseContext::precisionQualifierCheck(TSourceLoc loc, TPublicType& publicType) { // Built-in symbols are allowed some ambiguous precisions, to be pinned down // later by context. @@ -892,18 +1260,18 @@ void TParseContext::precisionQualifierCheck(int line, TPublicType& publicType) if (publicType.basicType == EbtFloat || publicType.basicType == EbtUint || publicType.basicType == EbtInt || publicType.basicType == EbtSampler) { if (publicType.qualifier.precision == EpqNone) { - error(line, "type requires declaration of default precision qualifier", TType::getBasicString(publicType.basicType), ""); + error(loc, "type requires declaration of default precision qualifier", TType::getBasicString(publicType.basicType), ""); publicType.qualifier.precision = EpqMedium; defaultPrecision[publicType.basicType] = EpqMedium; } } else if (publicType.qualifier.precision != EpqNone) - error(line, "type cannot have precision qualifier", TType::getBasicString(publicType.basicType), ""); + error(loc, "type cannot have precision qualifier", TType::getBasicString(publicType.basicType), ""); } -void TParseContext::parameterSamplerCheck(int line, TStorageQualifier qualifier, const TType& type) +void TParseContext::parameterSamplerCheck(TSourceLoc loc, TStorageQualifier qualifier, const TType& type) { if ((qualifier == EvqOut || qualifier == EvqInOut) && type.getBasicType() != EbtStruct && type.getBasicType() == EbtSampler) - error(line, "samplers cannot be output parameters", type.getCompleteTypeString().c_str(), ""); + error(loc, "samplers cannot be output parameters", type.getCompleteTypeString().c_str(), ""); } bool TParseContext::containsSampler(const TType& type) @@ -934,7 +1302,7 @@ bool TParseContext::insertBuiltInArrayAtGlobalLevel() TVariable* variable = symbol->getAsVariable(); if (! variable) { - error(0, "INTERNAL ERROR, variable expected", name->c_str(), ""); + infoSink.info.message(EPrefixInternalError, "variable expected"); return true; } @@ -942,7 +1310,7 @@ bool TParseContext::insertBuiltInArrayAtGlobalLevel() if (! symbolTable.insert(*newVariable)) { delete newVariable; - error(0, "INTERNAL ERROR inserting new symbol", name->c_str(), ""); + infoSink.info.message(EPrefixInternalError, "inserting new symbol"); return true; } @@ -952,11 +1320,11 @@ bool TParseContext::insertBuiltInArrayAtGlobalLevel() // // Do size checking for an array type's size. // -void TParseContext::arraySizeCheck(int line, TIntermTyped* expr, int& size) +void TParseContext::arraySizeCheck(TSourceLoc loc, TIntermTyped* expr, int& size) { TIntermConstantUnion* constant = expr->getAsConstantUnion(); if (constant == 0 || (constant->getBasicType() != EbtInt && constant->getBasicType() != EbtUint)) { - error(line, "array size must be a constant integer expression", "", ""); + error(loc, "array size must be a constant integer expression", "", ""); size = 1; return; @@ -965,7 +1333,7 @@ void TParseContext::arraySizeCheck(int line, TIntermTyped* expr, int& size) size = constant->getUnionArrayPointer()->getIConst(); if (size <= 0) { - error(line, "array size must be a positive integer", "", ""); + error(loc, "array size must be a positive integer", "", ""); size = 1; return; @@ -977,14 +1345,14 @@ void TParseContext::arraySizeCheck(int line, TIntermTyped* expr, int& size) // // Returns true if there is an error. // -bool TParseContext::arrayQualifierError(int line, const TPublicType& type) +bool TParseContext::arrayQualifierError(TSourceLoc loc, const TPublicType& type) { if (type.qualifier.storage == EvqConst) - profileRequires(line, ENoProfile, 120, "GL_3DL_array_objects", "const array"); + profileRequires(loc, ENoProfile, 120, "GL_3DL_array_objects", "const array"); if (type.qualifier.storage == EvqVaryingIn && language == EShLangVertex) { - requireProfile(line, (EProfileMask)~EEsProfileMask, "vertex input arrays"); - profileRequires(line, ENoProfile, 150, 0, "vertex input arrays"); + requireProfile(loc, (EProfileMask)~EEsProfileMask, "vertex input arrays"); + profileRequires(loc, ENoProfile, 150, 0, "vertex input arrays"); } return false; @@ -993,34 +1361,34 @@ bool TParseContext::arrayQualifierError(int line, const TPublicType& type) // // Require array to have size // -void TParseContext::arraySizeRequiredCheck(int line, int& size) +void TParseContext::arraySizeRequiredCheck(TSourceLoc loc, int& size) { if (size == 0) { - error(line, "array size required", "", ""); + error(loc, "array size required", "", ""); size = 1; } } -void TParseContext::arrayDimError(int line) +void TParseContext::arrayDimError(TSourceLoc loc) { - requireProfile(line, (EProfileMask)(ECoreProfileMask | ECompatibilityProfileMask), "arrays of arrays"); - profileRequires(line, ECoreProfile, 430, 0, "arrays of arrays"); - profileRequires(line, ECompatibilityProfile, 430, 0, "arrays of arrays"); + requireProfile(loc, (EProfileMask)(ECoreProfileMask | ECompatibilityProfileMask), "arrays of arrays"); + profileRequires(loc, ECoreProfile, 430, 0, "arrays of arrays"); + profileRequires(loc, ECompatibilityProfile, 430, 0, "arrays of arrays"); } -void TParseContext::arrayDimCheck(int line, TArraySizes sizes1, TArraySizes sizes2) +void TParseContext::arrayDimCheck(TSourceLoc loc, TArraySizes sizes1, TArraySizes sizes2) { if (sizes1 && sizes2 || sizes1 && sizes1->size() > 1 || sizes2 && sizes2->size() > 1) - arrayDimError(line); + arrayDimError(loc); } -void TParseContext::arrayDimCheck(int line, const TType* type, TArraySizes sizes2) +void TParseContext::arrayDimCheck(TSourceLoc loc, const TType* type, TArraySizes sizes2) { if (type && type->isArray() && sizes2 || sizes2 && sizes2->size() > 1) - arrayDimError(line); + arrayDimError(loc); } // @@ -1029,7 +1397,7 @@ void TParseContext::arrayDimCheck(int line, const TType* type, TArraySizes sizes // // size == 0 means no specified size. // -void TParseContext::arrayCheck(int line, TString& identifier, const TPublicType& type, TVariable*& variable) +void TParseContext::arrayCheck(TSourceLoc loc, TString& identifier, const TPublicType& type, TVariable*& variable) { // // Don't check for reserved word use until after we know it's not in the symbol table, @@ -1039,14 +1407,14 @@ void TParseContext::arrayCheck(int line, TString& identifier, const TPublicType& bool sameScope = false; TSymbol* symbol = symbolTable.find(identifier, 0, &sameScope); if (symbol == 0 || !sameScope) { - if (reservedErrorCheck(line, identifier)) + if (reservedErrorCheck(loc, identifier)) return; variable = new TVariable(&identifier, TType(type)); if (! symbolTable.insert(*variable)) { delete variable; - error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str(), ""); + error(loc, "INTERNAL ERROR inserting new symbol", identifier.c_str(), ""); return; } @@ -1054,28 +1422,28 @@ void TParseContext::arrayCheck(int line, TString& identifier, const TPublicType& variable = symbol->getAsVariable(); if (! variable) { - error(line, "array variable name expected", identifier.c_str(), ""); + error(loc, "array variable name expected", identifier.c_str(), ""); return; } if (! variable->getType().isArray()) { - error(line, "redeclaring non-array as array", identifier.c_str(), ""); + error(loc, "redeclaring non-array as array", identifier.c_str(), ""); return; } if (variable->getType().getArraySize() > 0) { - error(line, "redeclaration of array with size", identifier.c_str(), ""); + error(loc, "redeclaration of array with size", identifier.c_str(), ""); return; } if (! variable->getType().sameElementType(TType(type))) { - error(line, "redeclaration of array with a different type", identifier.c_str(), ""); + error(loc, "redeclaration of array with a different type", identifier.c_str(), ""); return; } TType* t = variable->getArrayInformationType(); while (t != 0) { if (t->getMaxArraySize() > type.arraySizes->front()) { - error(line, "higher index value already used for the array", identifier.c_str(), ""); + error(loc, "higher index value already used for the array", identifier.c_str(), ""); return; } t->setArraySizes(type.arraySizes); @@ -1085,20 +1453,20 @@ void TParseContext::arrayCheck(int line, TString& identifier, const TPublicType& variable->getType().setArraySizes(type.arraySizes); } - voidErrorCheck(line, identifier, type); + voidErrorCheck(loc, identifier, type); } -bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, TSourceLoc line) +bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, TSourceLoc loc) { TSymbol* symbol = symbolTable.find(node->getName()); if (symbol == 0) { - error(line, " undeclared identifier", node->getName().c_str(), ""); + error(loc, " undeclared identifier", node->getName().c_str(), ""); return true; } TVariable* variable = symbol->getAsVariable(); if (! variable) { - error(0, "array variable name expected", node->getName().c_str(), ""); + error(loc, "array variable name expected", node->getName().c_str(), ""); return true; } @@ -1110,13 +1478,13 @@ bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, if (node->getName() == "gl_TexCoord") { TSymbol* texCoord = symbolTable.find("gl_MaxTextureCoords"); if (! texCoord || ! texCoord->getAsVariable()) { - infoSink.info.message(EPrefixInternalError, "gl_MaxTextureCoords not defined", line); + infoSink.info.message(EPrefixInternalError, "gl_MaxTextureCoords not defined", loc); return true; } int texCoordValue = texCoord->getAsVariable()->getConstUnionPointer()[0].getIConst(); if (texCoordValue <= size) { - error(line, "", "[", "gl_TexCoord can only have a max array size of up to gl_MaxTextureCoords", ""); + error(loc, "", "[", "gl_TexCoord can only have a max array size of up to gl_MaxTextureCoords", ""); return true; } } @@ -1142,14 +1510,14 @@ bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, // // Enforce non-initializer type/qualifier rules. // -void TParseContext::nonInitConstCheck(int line, TString& identifier, TPublicType& type) +void TParseContext::nonInitConstCheck(TSourceLoc loc, TString& identifier, TPublicType& type) { // // Make the qualifier make sense. // if (type.qualifier.storage == EvqConst) { type.qualifier.storage = EvqTemporary; - error(line, "variables with qualifier 'const' must be initialized", identifier.c_str(), ""); + error(loc, "variables with qualifier 'const' must be initialized", identifier.c_str(), ""); } } @@ -1157,16 +1525,16 @@ void TParseContext::nonInitConstCheck(int line, TString& identifier, TPublicType // Do semantic checking for a variable declaration that has no initializer, // and update the symbol table. // -void TParseContext::nonInitCheck(int line, TString& identifier, TPublicType& type) +void TParseContext::nonInitCheck(TSourceLoc loc, TString& identifier, TPublicType& type) { - reservedErrorCheck(line, identifier); + reservedErrorCheck(loc, identifier); TVariable* variable = new TVariable(&identifier, TType(type)); if (! symbolTable.insert(*variable)) - error(line, "redefinition", variable->getName().c_str(), ""); + error(loc, "redefinition", variable->getName().c_str(), ""); else { - voidErrorCheck(line, identifier, type); + voidErrorCheck(loc, identifier, type); // see if it's a linker-level object to track if (type.qualifier.isUniform() || type.qualifier.isPipeInput() || type.qualifier.isPipeOutput()) @@ -1174,7 +1542,7 @@ void TParseContext::nonInitCheck(int line, TString& identifier, TPublicType& typ } } -void TParseContext::paramCheck(int line, TStorageQualifier qualifier, TType* type) +void TParseContext::paramCheck(TSourceLoc loc, TStorageQualifier qualifier, TType* type) { switch (qualifier) { case EvqConst: @@ -1191,22 +1559,22 @@ void TParseContext::paramCheck(int line, TStorageQualifier qualifier, TType* typ break; default: type->getQualifier().storage = EvqIn; - error(line, "qualifier not allowed on function parameter", getStorageQualifierString(qualifier), ""); + error(loc, "qualifier not allowed on function parameter", getStorageQualifierString(qualifier), ""); break; } } -void TParseContext::nestedBlockCheck(int line) +void TParseContext::nestedBlockCheck(TSourceLoc loc) { if (structNestingLevel > 0) - error(line, "cannot nest a block definition inside a structure or block", "", ""); + error(loc, "cannot nest a block definition inside a structure or block", "", ""); ++structNestingLevel; } -void TParseContext::nestedStructCheck(int line) +void TParseContext::nestedStructCheck(TSourceLoc loc) { if (structNestingLevel > 0) - error(line, "cannot nest a structure definition inside a structure or block", "", ""); + error(loc, "cannot nest a structure definition inside a structure or block", "", ""); ++structNestingLevel; } @@ -1215,7 +1583,7 @@ void TParseContext::nestedStructCheck(int line) // // Put the id's layout qualification into the public type. -void TParseContext::setLayoutQualifier(int line, TPublicType& publicType, TString& id) +void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, TString& id) { std::transform(id.begin(), id.end(), id.begin(), ::tolower); if (id == TQualifier::getLayoutMatrixString(ElmColumnMajor)) @@ -1231,26 +1599,26 @@ void TParseContext::setLayoutQualifier(int line, TPublicType& publicType, TStrin else if (id == TQualifier::getLayoutPackingString(ElpStd430)) publicType.qualifier.layoutPacking = ElpStd430; else if (id == "location") - error(line, "requires an integer assignment (e.g., location = 4)", "location", ""); + error(loc, "requires an integer assignment (e.g., location = 4)", "location", ""); else if (id == "binding") - error(line, "requires an integer assignment (e.g., binding = 4)", "binding", ""); + error(loc, "requires an integer assignment (e.g., binding = 4)", "binding", ""); else - error(line, "unrecognized layout identifier", id.c_str(), ""); + error(loc, "unrecognized layout identifier", id.c_str(), ""); } // Put the id's layout qualifier value into the public type. -void TParseContext::setLayoutQualifier(int line, TPublicType& publicType, TString& id, int value) +void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, TString& id, int value) { std::transform(id.begin(), id.end(), id.begin(), ::tolower); if (id == "location") { if ((unsigned int)value >= TQualifier::layoutLocationEnd) - error(line, "value is too large", id.c_str(), ""); + error(loc, "value is too large", id.c_str(), ""); else publicType.qualifier.layoutSlotLocation = value; } else if (id == "binding") - error(line, "not supported", "binding", ""); + error(loc, "not supported", "binding", ""); else - error(line, "there is no such layout identifier taking an assigned value", id.c_str(), ""); + error(loc, "there is no such layout identifier taking an assigned value", id.c_str(), ""); // TODO: semantics: error check: make sure locations are non-overlapping across the whole stage // TODO: semantics: error check: if more than one fragment output, all must have a location @@ -1258,7 +1626,7 @@ void TParseContext::setLayoutQualifier(int line, TPublicType& publicType, TStrin } // Merge any layout qualifier information from src into dst, leaving everything else in dst alone -void TParseContext::mergeLayoutQualifiers(int line, TQualifier& dst, const TQualifier& src) +void TParseContext::mergeLayoutQualifiers(TSourceLoc loc, TQualifier& dst, const TQualifier& src) { if (src.layoutMatrix != ElmNone) dst.layoutMatrix = src.layoutMatrix; @@ -1281,19 +1649,19 @@ void TParseContext::mergeLayoutQualifiers(int line, TQualifier& dst, const TQual // // Return the function symbol if found, otherwise 0. // -const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *builtIn) +const TFunction* TParseContext::findFunction(TSourceLoc loc, TFunction* call, bool *builtIn) { TSymbol* symbol = symbolTable.find(call->getMangledName(), builtIn); if (symbol == 0) { - error(line, "no matching overloaded function found", call->getName().c_str(), ""); + error(loc, "no matching overloaded function found", call->getName().c_str(), ""); return 0; } const TFunction* function = symbol->getAsFunction(); if (! function) { - error(line, "function name expected", call->getName().c_str(), ""); + error(loc, "function name expected", call->getName().c_str(), ""); return 0; } @@ -1305,16 +1673,16 @@ const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *bu // Initializers show up in several places in the grammar. Have one set of // code to handle them here. // -bool TParseContext::executeInitializerError(TSourceLoc line, TString& identifier, TPublicType& pType, +bool TParseContext::executeInitializerError(TSourceLoc loc, TString& identifier, TPublicType& pType, TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable) { TType type(pType); if (variable == 0) { - if (reservedErrorCheck(line, identifier)) + if (reservedErrorCheck(loc, identifier)) return true; - if (voidErrorCheck(line, identifier, pType)) + if (voidErrorCheck(loc, identifier, pType)) return true; // @@ -1322,7 +1690,7 @@ bool TParseContext::executeInitializerError(TSourceLoc line, TString& identifier // variable = new TVariable(&identifier, type); if (! symbolTable.insert(*variable)) { - error(line, "redefinition", variable->getName().c_str(), ""); + error(loc, "redefinition", variable->getName().c_str(), ""); return true; // don't delete variable, it's used by error recovery, and the pool // pop will take care of the memory @@ -1334,7 +1702,7 @@ bool TParseContext::executeInitializerError(TSourceLoc line, TString& identifier // TStorageQualifier qualifier = variable->getType().getQualifier().storage; if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) { - error(line, " cannot initialize this type of qualifier ", variable->getType().getStorageQualifierString(), ""); + error(loc, " cannot initialize this type of qualifier ", variable->getType().getStorageQualifierString(), ""); return true; } @@ -1348,12 +1716,12 @@ bool TParseContext::executeInitializerError(TSourceLoc line, TString& identifier // if (qualifier == EvqConst) { if (qualifier != initializer->getType().getQualifier().storage) { - error(line, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str()); + error(loc, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str()); variable->getType().getQualifier().storage = EvqTemporary; return true; } if (type != initializer->getType()) { - error(line, " non-matching types for const initializer ", + error(loc, " non-matching types for const initializer ", variable->getType().getStorageQualifierString(), ""); variable->getType().getQualifier().storage = EvqTemporary; return true; @@ -1372,21 +1740,21 @@ bool TParseContext::executeInitializerError(TSourceLoc line, TString& identifier constUnion* constArray = tVar->getConstUnionPointer(); variable->shareConstPointer(constArray); } else { - error(line, "expected variable", initializer->getAsSymbolNode()->getName().c_str(), ""); + error(loc, "expected variable", initializer->getAsSymbolNode()->getName().c_str(), ""); return true; } } else { - error(line, " cannot assign to", "=", "'%s'", variable->getType().getCompleteString().c_str()); + error(loc, " cannot assign to", "=", "'%s'", variable->getType().getCompleteString().c_str()); variable->getType().getQualifier().storage = EvqTemporary; return true; } } if (qualifier != EvqConst) { - TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line); - intermNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, line); + TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), loc); + intermNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, loc); if (intermNode == 0) { - assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString()); + assignError(loc, "=", intermSymbol->getCompleteString(), initializer->getCompleteString()); return true; } } else @@ -1400,7 +1768,7 @@ bool TParseContext::executeInitializerError(TSourceLoc line, TString& identifier // // Returns 0 for an error or the constructed node (aggregate or typed) for no error. // -TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType& type, TOperator op, TFunction* fnCall, TSourceLoc line) +TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType& type, TOperator op, TFunction* fnCall, TSourceLoc loc) { if (node == 0) return 0; @@ -1429,14 +1797,14 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType& type // If structure constructor or array constructor is being called // for only one parameter inside the structure, we need to call constructStruct function once. if (type.isArray()) - newNode = constructStruct(node, elementType, 1, node->getLine()); + newNode = constructStruct(node, elementType, 1, node->getLoc()); else if (op == EOpConstructStruct) - newNode = constructStruct(node, *(*memberTypes).type, 1, node->getLine()); + newNode = constructStruct(node, *(*memberTypes).type, 1, node->getLoc()); else - newNode = constructBuiltIn(type, op, node, node->getLine(), false); + newNode = constructBuiltIn(type, op, node, node->getLoc(), false); if (newNode && (type.isArray() || op == EOpConstructStruct)) - newNode = intermediate.setAggregateOperator(newNode, EOpConstructStruct, type, line); + newNode = intermediate.setAggregateOperator(newNode, EOpConstructStruct, type, loc); return newNode; } @@ -1457,11 +1825,11 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType& type for (TIntermSequence::iterator p = sequenceVector.begin(); p != sequenceVector.end(); p++, paramCount++) { if (type.isArray()) - newNode = constructStruct(*p, elementType, paramCount+1, node->getLine()); + newNode = constructStruct(*p, elementType, paramCount+1, node->getLoc()); else if (op == EOpConstructStruct) - newNode = constructStruct(*p, *(memberTypes[paramCount]).type, paramCount+1, node->getLine()); + newNode = constructStruct(*p, *(memberTypes[paramCount]).type, paramCount+1, node->getLoc()); else - newNode = constructBuiltIn(type, op, *p, node->getLine(), true); + newNode = constructBuiltIn(type, op, *p, node->getLoc(), true); if (newNode) { p = sequenceVector.erase(p); @@ -1469,7 +1837,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType& type } } - TIntermTyped* constructor = intermediate.setAggregateOperator(aggrNode, op, type, line); + TIntermTyped* constructor = intermediate.setAggregateOperator(aggrNode, op, type, loc); return constructor; } @@ -1481,7 +1849,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType& type // // Returns 0 for an error or the constructed node. // -TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, TIntermNode* node, TSourceLoc line, bool subset) +TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, TIntermNode* node, TSourceLoc loc, bool subset) { TIntermTyped* newNode; TOperator basicOp; @@ -1544,13 +1912,13 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T break; default: - error(line, "unsupported construction", "", ""); + error(loc, "unsupported construction", "", ""); return 0; } - newNode = intermediate.addUnaryMath(basicOp, node, node->getLine()); + newNode = intermediate.addUnaryMath(basicOp, node, node->getLoc()); if (newNode == 0) { - error(line, "can't convert", "constructor", ""); + error(loc, "can't convert", "constructor", ""); return 0; } @@ -1563,7 +1931,7 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T return newNode; // setAggregateOperator will insert a new node for the constructor, as needed. - return intermediate.setAggregateOperator(newNode, op, type, line); + return intermediate.setAggregateOperator(newNode, op, type, loc); } // This function tests for the type of the parameters to the structures constructors. Raises @@ -1571,11 +1939,11 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T // // Returns 0 for an error or the input node itself if the expected and the given parameter types match. // -TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& type, int paramCount, TSourceLoc line) +TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& type, int paramCount, TSourceLoc loc) { TIntermTyped* converted = intermediate.addConversion(EOpConstructStruct, type, node->getAsTyped()); if (! converted || converted->getType() != type) { - error(line, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount, + error(loc, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount, node->getAsTyped()->getType().getCompleteTypeString().c_str(), type.getCompleteTypeString().c_str()); return 0; @@ -1587,41 +1955,41 @@ TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& typ // // Do everything needed to add an interface block. // -void TParseContext::addBlock(int line, TTypeList& typeList, const TString* instanceName, TArraySizes arraySizes) +void TParseContext::addBlock(TSourceLoc loc, TTypeList& typeList, const TString* instanceName, TArraySizes arraySizes) { // First, error checks - if (reservedErrorCheck(line, *blockName)) + if (reservedErrorCheck(loc, *blockName)) return; - if (instanceName && reservedErrorCheck(line, *instanceName)) + if (instanceName && reservedErrorCheck(loc, *instanceName)) return; if (profile == EEsProfile && arraySizes) - arraySizeRequiredCheck(line, arraySizes->front()); + arraySizeRequiredCheck(loc, arraySizes->front()); if (currentBlockDefaults.storage == EvqUniform) { - requireProfile(line, (EProfileMask)(~ENoProfileMask), "uniform block"); - profileRequires(line, EEsProfile, 300, 0, "uniform block"); + requireProfile(loc, (EProfileMask)(~ENoProfileMask), "uniform block"); + profileRequires(loc, EEsProfile, 300, 0, "uniform block"); } else { - error(line, "only uniform interface blocks are supported", blockName->c_str(), ""); + error(loc, "only uniform interface blocks are supported", blockName->c_str(), ""); return; } - arrayDimCheck(line, arraySizes, 0); + arrayDimCheck(loc, arraySizes, 0); // check for qualifiers and types that don't belong within a block for (unsigned int member = 0; member < typeList.size(); ++member) { TQualifier memberQualifier = typeList[member].type->getQualifier(); if (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal && memberQualifier.storage != currentBlockDefaults.storage) - error(line, "member storage qualifier cannot contradict block storage qualifier", typeList[member].type->getFieldName().c_str(), ""); + error(loc, "member storage qualifier cannot contradict block storage qualifier", typeList[member].type->getFieldName().c_str(), ""); if (currentBlockDefaults.storage == EvqUniform && memberQualifier.isInterpolation() || memberQualifier.isAuxiliary()) - error(line, "member of uniform block cannot have an auxiliary or interpolation qualifier", typeList[member].type->getFieldName().c_str(), ""); + error(loc, "member of uniform block cannot have an auxiliary or interpolation qualifier", typeList[member].type->getFieldName().c_str(), ""); TBasicType basicType = typeList[member].type->getBasicType(); if (basicType == EbtSampler) - error(line, "member of block cannot be a sampler type", typeList[member].type->getFieldName().c_str(), ""); + error(loc, "member of block cannot be a sampler type", typeList[member].type->getFieldName().c_str(), ""); } // Make default block qualification, and adjust the member qualifications @@ -1634,10 +2002,10 @@ void TParseContext::addBlock(int line, TTypeList& typeList, const TString* insta default: defaultQualification.clear(); break; } - mergeLayoutQualifiers(line, defaultQualification, currentBlockDefaults); + mergeLayoutQualifiers(loc, defaultQualification, currentBlockDefaults); for (unsigned int member = 0; member < typeList.size(); ++member) { TQualifier memberQualification = defaultQualification; - mergeQualifiers(line, memberQualification, typeList[member].type->getQualifier(), false); + mergeQualifiers(loc, memberQualification, typeList[member].type->getQualifier(), false); typeList[member].type->getQualifier() = memberQualification; } @@ -1649,7 +2017,7 @@ void TParseContext::addBlock(int line, TTypeList& typeList, const TString* insta blockType.getQualifier().layoutPacking = defaultQualification.layoutPacking; TVariable* userTypeDef = new TVariable(blockName, blockType, true); if (! symbolTable.insert(*userTypeDef)) { - error(line, "redefinition", blockName->c_str(), "block name"); + error(loc, "redefinition", blockName->c_str(), "block name"); return; } @@ -1663,9 +2031,9 @@ void TParseContext::addBlock(int line, TTypeList& typeList, const TString* insta TVariable* variable = new TVariable(instanceName, blockType); if (! symbolTable.insert(*variable)) { if (*instanceName == "") - error(line, "nameless block contains a member that already has a name at global scope", blockName->c_str(), ""); + error(loc, "nameless block contains a member that already has a name at global scope", blockName->c_str(), ""); else - error(line, "block instance name redefinition", variable->getName().c_str(), ""); + error(loc, "block instance name redefinition", variable->getName().c_str(), ""); return; } @@ -1675,12 +2043,12 @@ void TParseContext::addBlock(int line, TTypeList& typeList, const TString* insta } // For an identifier that is already declared, add more qualification to it. -void TParseContext::addQualifierToExisting(int line, TQualifier qualifier, const TString& identifier) +void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier, const TString& identifier) { TSymbol* existing = symbolTable.find(identifier); TVariable* variable = existing ? existing->getAsVariable() : 0; if (! variable) { - error(line, "identifier not previously declared", identifier.c_str(), ""); + error(loc, "identifier not previously declared", identifier.c_str(), ""); return; } @@ -1690,7 +2058,7 @@ void TParseContext::addQualifierToExisting(int line, TQualifier qualifier, const qualifier.isInterpolation() || qualifier.storage != EvqTemporary || qualifier.precision != EpqNone) { - error(line, "cannot add storage, auxiliary, memory, interpolation, or precision qualifier to an existing variable", identifier.c_str(), ""); + error(loc, "cannot add storage, auxiliary, memory, interpolation, or precision qualifier to an existing variable", identifier.c_str(), ""); return; } @@ -1699,10 +2067,10 @@ void TParseContext::addQualifierToExisting(int line, TQualifier qualifier, const variable->getType().getQualifier().invariant = true; } -void TParseContext::addQualifierToExisting(int line, TQualifier qualifier, TIdentifierList& identifiers) +void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier, TIdentifierList& identifiers) { for (unsigned int i = 0; i < identifiers.size(); ++i) - addQualifierToExisting(line, qualifier, *identifiers[i]); + addQualifierToExisting(loc, qualifier, *identifiers[i]); } void TParseContext::updateQualifierDefaults(TQualifier qualifier) @@ -1728,13 +2096,13 @@ void TParseContext::updateQualifierDefaults(TQualifier qualifier) } } -void TParseContext::updateQualifierDefaults(int line, TQualifier qualifier) +void TParseContext::updateQualifierDefaults(TSourceLoc loc, TQualifier qualifier) { if (qualifier.isAuxiliary() || qualifier.isMemory() || qualifier.isInterpolation() || qualifier.precision != EpqNone) - error(line, "cannot use auxiliary, memory, interpolation, or precision qualifier in a standalone qualifier", "", ""); + error(loc, "cannot use auxiliary, memory, interpolation, or precision qualifier in a standalone qualifier", "", ""); switch (qualifier.storage) { case EvqUniform: @@ -1742,47 +2110,47 @@ void TParseContext::updateQualifierDefaults(int line, TQualifier qualifier) case EvqOut: break; default: - error(line, "standalone qualifier requires 'uniform', 'in', or 'out' storage qualification", "", ""); + error(loc, "standalone qualifier requires 'uniform', 'in', or 'out' storage qualification", "", ""); return; } updateQualifierDefaults(qualifier); } -void TParseContext::updateTypedDefaults(int line, TQualifier qualifier, const TString* id) +void TParseContext::updateTypedDefaults(TSourceLoc loc, TQualifier qualifier, const TString* id) { bool cantHaveId = false; if (! id) { if (qualifier.hasLayout()) - warn(line, "cannot set qualifier defaults when using a type and no identifier", "", ""); + warn(loc, "cannot set qualifier defaults when using a type and no identifier", "", ""); return; } if (qualifier.storage == EvqUniform) { if (qualifier.layoutMatrix != ElmNone) - error(line, "cannot specify matrix layout on a variable declaration", id->c_str(), ""); + error(loc, "cannot specify matrix layout on a variable declaration", id->c_str(), ""); if (qualifier.layoutPacking != ElpNone) - error(line, "cannot specify packing on a variable declaration", id->c_str(), ""); + error(loc, "cannot specify packing on a variable declaration", id->c_str(), ""); } else if (qualifier.storage == EvqVaryingIn) { if (qualifier.hasLayout() && language != EShLangVertex) { - error(line, "can only use location layout qualifier on a vertex input or fragment output", id->c_str(), ""); + error(loc, "can only use location layout qualifier on a vertex input or fragment output", id->c_str(), ""); } } else if (qualifier.storage == EvqVaryingOut) { if (qualifier.hasLayout() && language != EShLangFragment) { - error(line, "can only use location layout qualifier on a vertex input or fragment output", id->c_str(), ""); + error(loc, "can only use location layout qualifier on a vertex input or fragment output", id->c_str(), ""); } } else { if (qualifier.layoutMatrix != ElmNone || qualifier.layoutPacking != ElpNone) - error(line, "layout qualifiers for matrix layout and packing only apply to uniform blocks", id->c_str(), ""); + error(loc, "layout qualifiers for matrix layout and packing only apply to uniform blocks", id->c_str(), ""); else if (qualifier.hasLocation()) - error(line, "location qualifiers only appy to uniform, in, or out storage qualifiers", id->c_str(), ""); + error(loc, "location qualifiers only appy to uniform, in, or out storage qualifiers", id->c_str(), ""); } if (cantHaveId) - error(line, "cannot set global layout qualifiers on uniform variable, use just 'uniform' or a block", id->c_str(), ""); + error(loc, "cannot set global layout qualifiers on uniform variable, use just 'uniform' or a block", id->c_str(), ""); updateQualifierDefaults(qualifier); } @@ -1799,7 +2167,7 @@ void TParseContext::wrapupSwitchSubsequence(TIntermAggregate* statements, TInter if (statements) { if (switchSequence->size() == 0) - error(statements->getLine(), "cannot have statements before first case/default label", "switch", ""); + error(statements->getLoc(), "cannot have statements before first case/default label", "switch", ""); statements->setOperator(EOpSequence); switchSequence->push_back(statements); } @@ -1811,14 +2179,14 @@ void TParseContext::wrapupSwitchSubsequence(TIntermAggregate* statements, TInter TIntermTyped* prevExpression = prevBranch->getExpression(); TIntermTyped* newExpression = branchNode->getAsBranchNode()->getExpression(); if (prevExpression == 0 && newExpression == 0) - error(branchNode->getLine(), "duplicate label", "default", ""); + error(branchNode->getLoc(), "duplicate label", "default", ""); else if (prevExpression != 0 && newExpression != 0 && prevExpression->getAsConstantUnion() && newExpression->getAsConstantUnion() && prevExpression->getAsConstantUnion()->getUnionArrayPointer()->getIConst() == newExpression->getAsConstantUnion()->getUnionArrayPointer()->getIConst()) - error(branchNode->getLine(), "duplicated value", "case", ""); + error(branchNode->getLoc(), "duplicated value", "case", ""); } } switchSequence->push_back(branchNode); @@ -1829,17 +2197,17 @@ void TParseContext::wrapupSwitchSubsequence(TIntermAggregate* statements, TInter // Turn the top-level node sequence built up of wrapupSwitchSubsequence9) // into a switch node. // -TIntermNode* TParseContext::addSwitch(int line, TIntermTyped* expression, TIntermAggregate* lastStatements) +TIntermNode* TParseContext::addSwitch(TSourceLoc loc, TIntermTyped* expression, TIntermAggregate* lastStatements) { - profileRequires(line, EEsProfile, 300, 0, "switch statements"); - profileRequires(line, ENoProfile, 130, 0, "switch statements"); + profileRequires(loc, EEsProfile, 300, 0, "switch statements"); + profileRequires(loc, ENoProfile, 130, 0, "switch statements"); wrapupSwitchSubsequence(lastStatements, 0); if (expression == 0 || expression->getBasicType() != EbtInt && expression->getBasicType() != EbtUint || expression->getType().isArray() || expression->getType().isMatrix() || expression->getType().isVector()) - error(line, "condition must be a scalar integer expression", "switch", ""); + error(loc, "condition must be a scalar integer expression", "switch", ""); // If there is nothing to do, drop the switch but still execute the expression TIntermSequence* switchSequence = switchSequenceStack.back(); @@ -1847,17 +2215,17 @@ TIntermNode* TParseContext::addSwitch(int line, TIntermTyped* expression, TInter return expression; if (lastStatements == 0) { - error(line, "last case/default label must be followed by statements", "switch", ""); + error(loc, "last case/default label must be followed by statements", "switch", ""); return expression; } TIntermAggregate* body = new TIntermAggregate(EOpSequence); body->getSequence() = *switchSequenceStack.back(); - body->setLine(line); + body->setLoc(loc); TIntermSwitch* switchNode = new TIntermSwitch(expression, body); - switchNode->setLine(line); + switchNode->setLoc(loc); return switchNode; } @@ -1869,7 +2237,7 @@ TIntermNode* TParseContext::addSwitch(int line, TIntermTyped* expression, TInter // node or it could be the intermediate tree representation of accessing fields in a constant structure or column of // a constant matrix. // -TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, TSourceLoc line) +TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, TSourceLoc loc) { TIntermTyped* typedNode; TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); @@ -1879,12 +2247,12 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy unionArray = tempConstantNode->getUnionArrayPointer(); if (!unionArray) { // this error message should never be raised - infoSink.info.message(EPrefixInternalError, "constUnion not initialized in addConstVectorNode function", line); + infoSink.info.message(EPrefixInternalError, "constUnion not initialized in addConstVectorNode function", loc); return node; } } else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error - error(line, "Cannot offset into the vector", "Error", ""); + error(loc, "Cannot offset into the vector", "Error", ""); return 0; } @@ -1893,13 +2261,13 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy for (int i = 0; i < fields.num; i++) { if (fields.offsets[i] >= node->getType().getObjectSize()) { - error(line, "", "[", "vector index out of range '%d'", fields.offsets[i]); + error(loc, "", "[", "vector index out of range '%d'", fields.offsets[i]); fields.offsets[i] = 0; } constArray[i] = unionArray[fields.offsets[i]]; } - typedNode = intermediate.addConstantUnion(constArray, node->getType(), line); + typedNode = intermediate.addConstantUnion(constArray, node->getType(), loc); return typedNode; } @@ -1910,13 +2278,13 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy // to the function could either be a symbol node (m[0] where m is a constant matrix)that represents a // constant matrix or it could be the tree representation of the constant matrix (s.m1[0] where s is a constant structure) // -TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, TSourceLoc line) +TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, TSourceLoc loc) { TIntermTyped* typedNode; TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); if (index >= node->getType().getMatrixCols()) { - error(line, "", "[", "matrix field selection out of range '%d'", index); + error(loc, "", "[", "matrix field selection out of range '%d'", index); index = 0; } @@ -1924,9 +2292,9 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T constUnion* unionArray = tempConstantNode->getUnionArrayPointer(); int size = tempConstantNode->getType().getMatrixRows(); // Note: the type is corrected (dereferenced) by the caller - typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line); + typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), loc); } else { - error(line, "Cannot offset into the matrix", "Error", ""); + error(loc, "Cannot offset into the matrix", "Error", ""); return 0; } @@ -1941,7 +2309,7 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T // to the function could either be a symbol node (a[0] where a is a constant array)that represents a // constant array or it could be the tree representation of the constant array (s.a1[0] where s is a constant structure) // -TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line) +TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TSourceLoc loc) { TIntermTyped* typedNode; TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); @@ -1950,7 +2318,7 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS arrayElementType.dereference(); if (index >= node->getType().getArraySize() || index < 0) { - error(line, "", "[", "array index '%d' out of range", index); + error(loc, "", "[", "array index '%d' out of range", index); index = 0; } @@ -1958,9 +2326,9 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS if (tempConstantNode) { constUnion* unionArray = tempConstantNode->getUnionArrayPointer(); - typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line); + typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), loc); } else { - error(line, "Cannot offset into the array", "Error", ""); + error(loc, "Cannot offset into the array", "Error", ""); return 0; } @@ -1974,7 +2342,7 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS // If there is an embedded/nested struct, it appropriately calls addConstStructNested or addConstStructFromAggr // function and returns the parse-tree with the values of the embedded/nested struct. // -TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, TSourceLoc line) +TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, TSourceLoc loc) { TTypeList* fields = node->getType().getStruct(); TIntermTyped *typedNode; @@ -1993,9 +2361,9 @@ TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* n if (tempConstantNode) { constUnion* constArray = tempConstantNode->getUnionArrayPointer(); - typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function + typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), loc); // type will be changed in the calling function } else { - error(line, "Cannot offset into the structure", "Error", ""); + error(loc, "Cannot offset into the structure", "Error", ""); return 0; } diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index 990fd3f..8f72eac 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -55,7 +55,9 @@ struct TPragma { TPragmaTable pragmaTable; }; - +namespace glslang { + class TScanContext; +}; // // The following are extra variables needed during parsing, grouped together so @@ -64,6 +66,7 @@ struct TPragma { struct TParseContext { TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, EShLanguage, TInfoSink&, bool forwardCompatible = false, EShMessages messages = EShMsgDefault); + glslang::TScanContext *scanContext; TIntermediate& intermediate; // to hold and build a parse tree TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile TInfoSink& infoSink; @@ -71,7 +74,6 @@ struct TParseContext { TIntermNode* treeRoot; // root of parse tree being created TIntermAggregate *linkage; // aggregate node of objects the linker may need, if not reference by the rest of the AST int numErrors; // number of compile-time errors encountered - bool lexAfterType; // true if we've recognized a type, so can only be looking for an identifier int loopNestingLevel; // 0 if outside all loops int structNestingLevel; // 0 if outside blocks and structures TList switchSequenceStack; // case, node, case, case, node, ...; ensure only one node between cases; stack of them for nesting @@ -91,7 +93,7 @@ struct TParseContext { static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2)); // see computeSamplerTypeIndex() TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex]; TString HashErrMsg; - bool AfterEOF; + bool afterEOF; const TString* blockName; TQualifier globalUniformDefaults; TQualifier globalInputDefaults; @@ -100,93 +102,91 @@ struct TParseContext { void initializeExtensionBehavior(); const char* getPreamble(); + bool parseShaderStrings(char* strings[], int strLen[], int numStrings); void C_DECL error(TSourceLoc, const char *szReason, const char *szToken, const char *szExtraInfoFormat, ...); void C_DECL warn(TSourceLoc, const char *szReason, const char *szToken, const char *szExtraInfoFormat, ...); - bool reservedErrorCheck(int line, const TString& identifier); + bool reservedErrorCheck(TSourceLoc, const TString& identifier); - TIntermTyped* handleVariable(int line, TSymbol* symbol, TString* string); - bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line); - void assignError(int line, const char* op, TString left, TString right); - void unaryOpError(int line, const char* op, TString operand); - void binaryOpError(int line, const char* op, TString left, TString right); + TIntermTyped* handleVariable(TSourceLoc, TSymbol* symbol, TString* string); + bool parseVectorFields(TSourceLoc, const TString&, int vecSize, TVectorFields&); + void assignError(TSourceLoc, const char* op, TString left, TString right); + void unaryOpError(TSourceLoc, const char* op, TString operand); + void binaryOpError(TSourceLoc, const char* op, TString left, TString right); void variableCheck(TIntermTyped*& nodePtr); - bool lValueErrorCheck(int line, const char* op, TIntermTyped*); + bool lValueErrorCheck(TSourceLoc, const char* op, TIntermTyped*); void constCheck(TIntermTyped* node, const char* token); void integerCheck(TIntermTyped* node, const char* token); - void globalCheck(int line, bool global, const char* token); - bool constructorError(int line, TIntermNode*, TFunction&, TOperator, TType&); - void arraySizeCheck(int line, TIntermTyped* expr, int& size); - bool arrayQualifierError(int line, const TPublicType&); - void arraySizeRequiredCheck(int line, int& size); - void arrayDimError(int line); - void arrayDimCheck(int line, TArraySizes sizes1, TArraySizes sizes2); - void arrayDimCheck(int line, const TType*, TArraySizes); - void arrayCheck(int line, TString& identifier, const TPublicType&, TVariable*& variable); + void globalCheck(TSourceLoc, bool global, const char* token); + bool constructorError(TSourceLoc, TIntermNode*, TFunction&, TOperator, TType&); + void arraySizeCheck(TSourceLoc, TIntermTyped* expr, int& size); + bool arrayQualifierError(TSourceLoc, const TPublicType&); + void arraySizeRequiredCheck(TSourceLoc, int& size); + void arrayDimError(TSourceLoc); + void arrayDimCheck(TSourceLoc, TArraySizes sizes1, TArraySizes sizes2); + void arrayDimCheck(TSourceLoc, const TType*, TArraySizes); + void arrayCheck(TSourceLoc, TString& identifier, const TPublicType&, TVariable*& variable); bool insertBuiltInArrayAtGlobalLevel(); - bool voidErrorCheck(int, const TString&, const TPublicType&); - void boolCheck(int, const TIntermTyped*); - void boolCheck(int, const TPublicType&); - bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason); - void globalQualifierFix(int line, TQualifier&, const TPublicType&); - bool structQualifierErrorCheck(int line, const TPublicType& pType); - void mergeQualifiers(int line, TQualifier& dst, const TQualifier& src, bool force); - void setDefaultPrecision(int line, TPublicType&, TPrecisionQualifier); + bool voidErrorCheck(TSourceLoc, const TString&, const TPublicType&); + void boolCheck(TSourceLoc, const TIntermTyped*); + void boolCheck(TSourceLoc, const TPublicType&); + bool samplerErrorCheck(TSourceLoc, const TPublicType& pType, const char* reason); + void globalQualifierFix(TSourceLoc, TQualifier&, const TPublicType&); + bool structQualifierErrorCheck(TSourceLoc, const TPublicType& pType); + void mergeQualifiers(TSourceLoc, TQualifier& dst, const TQualifier& src, bool force); + void setDefaultPrecision(TSourceLoc, TPublicType&, TPrecisionQualifier); int computeSamplerTypeIndex(TSampler&); TPrecisionQualifier getDefaultPrecision(TPublicType&); - void precisionQualifierCheck(int line, TPublicType&); - void parameterSamplerCheck(int line, TStorageQualifier qualifier, const TType& type); + void precisionQualifierCheck(TSourceLoc, TPublicType&); + void parameterSamplerCheck(TSourceLoc, TStorageQualifier qualifier, const TType& type); bool containsSampler(const TType& type); - void nonInitConstCheck(int line, TString& identifier, TPublicType& type); - void nonInitCheck(int line, TString& identifier, TPublicType& type); - void paramCheck(int line, TStorageQualifier qualifier, TType* type); - void nestedBlockCheck(int line); - void nestedStructCheck(int line); - - void setLayoutQualifier(int line, TPublicType&, TString&); - void setLayoutQualifier(int line, TPublicType&, TString&, int); - void mergeLayoutQualifiers(int line, TQualifier& dest, const TQualifier& src); - - const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0); - bool executeInitializerError(TSourceLoc line, TString& identifier, TPublicType& pType, + void nonInitConstCheck(TSourceLoc, TString& identifier, TPublicType& type); + void nonInitCheck(TSourceLoc, TString& identifier, TPublicType& type); + void paramCheck(TSourceLoc, TStorageQualifier qualifier, TType* type); + void nestedBlockCheck(TSourceLoc); + void nestedStructCheck(TSourceLoc); + + void setLayoutQualifier(TSourceLoc, TPublicType&, TString&); + void setLayoutQualifier(TSourceLoc, TPublicType&, TString&, int); + void mergeLayoutQualifiers(TSourceLoc, TQualifier& dest, const TQualifier& src); + + const TFunction* findFunction(TSourceLoc, TFunction* pfnCall, bool *builtIn = 0); + bool executeInitializerError(TSourceLoc, TString& identifier, TPublicType& pType, TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0); TIntermTyped* addConstructor(TIntermNode*, const TType&, TOperator, TFunction*, TSourceLoc); TIntermTyped* constructStruct(TIntermNode*, const TType&, int, TSourceLoc); TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermNode*, TSourceLoc, bool subset); - void addBlock(int line, TTypeList& typeList, const TString* instanceName = 0, TArraySizes arraySizes = 0); - void addQualifierToExisting(int line, TQualifier, const TString& identifier); - void addQualifierToExisting(int line, TQualifier, TIdentifierList&); + void addBlock(TSourceLoc, TTypeList& typeList, const TString* instanceName = 0, TArraySizes arraySizes = 0); + void addQualifierToExisting(TSourceLoc, TQualifier, const TString& identifier); + void addQualifierToExisting(TSourceLoc, TQualifier, TIdentifierList&); void updateQualifierDefaults(TQualifier); - void updateQualifierDefaults(int line, TQualifier); - void updateTypedDefaults(int line, TQualifier, const TString* id); + void updateQualifierDefaults(TSourceLoc, TQualifier); + void updateTypedDefaults(TSourceLoc, TQualifier, const TString* id); void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode); - TIntermNode* addSwitch(int line, TIntermTyped* expression, TIntermAggregate* body); + TIntermNode* addSwitch(TSourceLoc, TIntermTyped* expression, TIntermAggregate* body); TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc); TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc); - TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line); + TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc); TIntermTyped* addConstStruct(TString& , TIntermTyped*, TSourceLoc); bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, TSourceLoc); - void requireProfile(int line, EProfileMask profileMask, const char *featureDesc); - void requireStage(int line, EShLanguageMask languageMask, const char *featureDesc); - void profileRequires(int line, EProfile callingProfile, int minVersion, int numExtensions, const char* extensions[], const char *featureDesc); - void profileRequires(int line, EProfile callingProfile, int minVersion, const char* extension, const char *featureDesc); - void checkDeprecated(int line, EProfile callingProfile, int depVersion, const char *featureDesc); - void requireNotRemoved(int line, EProfile callingProfile, int removedVersion, const char *featureDesc); - void fullIntegerCheck(int line, const char* op); - void doubleCheck(int line, const char* op); + void requireProfile(TSourceLoc, EProfileMask profileMask, const char *featureDesc); + void requireStage(TSourceLoc, EShLanguageMask languageMask, const char *featureDesc); + void profileRequires(TSourceLoc, EProfile callingProfile, int minVersion, int numExtensions, const char* extensions[], const char *featureDesc); + void profileRequires(TSourceLoc, EProfile callingProfile, int minVersion, const char* extension, const char *featureDesc); + void checkDeprecated(TSourceLoc, EProfile callingProfile, int depVersion, const char *featureDesc); + void requireNotRemoved(TSourceLoc, EProfile callingProfile, int removedVersion, const char *featureDesc); + void fullIntegerCheck(TSourceLoc, const char* op); + void doubleCheck(TSourceLoc, const char* op); }; -int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext&, const char* preamble); -int PaParseComment(int &lineno, TParseContext&); -void ResetFlex(); - typedef TParseContext* TParseContextPointer; TParseContextPointer& ThreadLocalParseContext(); +// TODO: threading: typedef struct TThreadParseContextRec { TParseContext *lpGlobalParseContext; diff --git a/glslang/MachineIndependent/Scan.cpp b/glslang/MachineIndependent/Scan.cpp index d7f1119..ca9af6a 100644 --- a/glslang/MachineIndependent/Scan.cpp +++ b/glslang/MachineIndependent/Scan.cpp @@ -34,9 +34,24 @@ //POSSIBILITY OF SUCH DAMAGE. // +// +// GLSL scanning, leveraging the scanning done by the preprocessor. +// + #include #include "Scan.h" +#include "Include/Types.h" +#include "SymbolTable.h" +#include "glslang_tab.cpp.h" +#include "ParseHelper.h" +#include "ScanContext.h" + +// preprocessor includes +extern "C" { + #include "preprocessor/parser.h" + #include "preprocessor/preprocess.h" +} namespace glslang { @@ -138,10 +153,14 @@ void ConsumeWhitespaceComment(TInputScanner& input, bool& foundNonSpaceTab) } while (true); } -// Returns true if there was non-white space (e.g., a comment, newline) before the #version; -// otherwise, returns true. +// Returns true if there was non-white space (e.g., a comment, newline) before the #version +// or no #version was found; otherwise, returns false. There is no error case, it always +// succeeds, but will leave version == 0 if no #version was found. +// +// N.B. does not attempt to leave input in any particular known state. The assumption +// is that scanning will start anew, following the rules for the chosen version/profile, +// and with a corresponding parsing context. // -// N.B. does not attempt to leave input in any particular known state bool ScanVersion(TInputScanner& input, int& version, EProfile& profile) { // This function doesn't have to get all the semantics correct, @@ -214,3 +233,793 @@ bool ScanVersion(TInputScanner& input, int& version, EProfile& profile) } }; // end glslang namespace + +namespace glslang { + +// This gets filled in by the preprocessor scanner. +class TPpToken{ +public: + yystypepp lexer; +}; + +// Fill this in when doing glslang-level scanning, to hand back to the parser. +class TParserToken { +public: + explicit TParserToken(YYSTYPE& b) : sType(b) { } + + YYSTYPE& sType; +}; + +}; // end namespace glslang + +// This is the function the glslang parser (i.e., bison) calls to get its next token +int yylex(YYSTYPE* glslangTokenDesc, TParseContext& parseContext) +{ + glslang::TParserToken token(*glslangTokenDesc); + + return parseContext.scanContext->tokenize(token); +} + +namespace { + +// A single global usable by all threads, by all versions, by all languages. +// After a single process-level initialization, this is read only and thread safe +std::map* KeywordMap = 0; +std::set* ReservedSet = 0; + +}; + +namespace glslang { + +void TScanContext::fillInKeywordMap() +{ + if (KeywordMap != 0) { + // this is really an error, as this should called only once per process + // but, the only risk is if two threads called simultaneously + return; + } + KeywordMap = new std::map; + + (*KeywordMap)["const"] = CONST; + (*KeywordMap)["uniform"] = UNIFORM; + (*KeywordMap)["in"] = IN; + (*KeywordMap)["out"] = OUT; + (*KeywordMap)["inout"] = INOUT; + (*KeywordMap)["struct"] = STRUCT; + (*KeywordMap)["break"] = BREAK; + (*KeywordMap)["continue"] = CONTINUE; + (*KeywordMap)["do"] = DO; + (*KeywordMap)["for"] = FOR; + (*KeywordMap)["while"] = WHILE; + (*KeywordMap)["switch"] = SWITCH; + (*KeywordMap)["case"] = CASE; + (*KeywordMap)["default"] = DEFAULT; + (*KeywordMap)["if"] = IF; + (*KeywordMap)["else"] = ELSE; + (*KeywordMap)["discard"] = DISCARD; + (*KeywordMap)["return"] = RETURN; + (*KeywordMap)["void"] = VOID; + (*KeywordMap)["bool"] = BOOL; + (*KeywordMap)["float"] = FLOAT; + (*KeywordMap)["int"] = INT; + (*KeywordMap)["bvec2"] = BVEC2; + (*KeywordMap)["bvec3"] = BVEC3; + (*KeywordMap)["bvec4"] = BVEC4; + (*KeywordMap)["vec2"] = VEC2; + (*KeywordMap)["vec3"] = VEC3; + (*KeywordMap)["vec4"] = VEC4; + (*KeywordMap)["ivec2"] = IVEC2; + (*KeywordMap)["ivec3"] = IVEC3; + (*KeywordMap)["ivec4"] = IVEC4; + (*KeywordMap)["mat2"] = MAT2; + (*KeywordMap)["mat3"] = MAT3; + (*KeywordMap)["mat4"] = MAT4; + (*KeywordMap)["sampler2D"] = SAMPLER2D; + (*KeywordMap)["samplerCube"] = SAMPLERCUBE; + (*KeywordMap)["true"] = BOOLCONSTANT; + (*KeywordMap)["false"] = BOOLCONSTANT; + (*KeywordMap)["attribute"] = ATTRIBUTE; + (*KeywordMap)["varying"] = VARYING; + (*KeywordMap)["buffer"] = BUFFER; + (*KeywordMap)["coherent"] = COHERENT; + (*KeywordMap)["restrict"] = RESTRICT; + (*KeywordMap)["readonly"] = READONLY; + (*KeywordMap)["writeonly"] = WRITEONLY; + (*KeywordMap)["atomic_uint"] = ATOMIC_UINT; + (*KeywordMap)["volatile"] = VOLATILE; + (*KeywordMap)["layout"] = LAYOUT; + (*KeywordMap)["shared"] = SHARED; + (*KeywordMap)["patch"] = PATCH; + (*KeywordMap)["sample"] = SAMPLE; + (*KeywordMap)["subroutine"] = SUBROUTINE; + (*KeywordMap)["highp"] = HIGH_PRECISION; + (*KeywordMap)["mediump"] = MEDIUM_PRECISION; + (*KeywordMap)["lowp"] = LOW_PRECISION; + (*KeywordMap)["precision"] = PRECISION; + (*KeywordMap)["mat2x2"] = MAT2X2; + (*KeywordMap)["mat2x3"] = MAT2X3; + (*KeywordMap)["mat2x4"] = MAT2X4; + (*KeywordMap)["mat3x2"] = MAT3X2; + (*KeywordMap)["mat3x3"] = MAT3X3; + (*KeywordMap)["mat3x4"] = MAT3X4; + (*KeywordMap)["mat4x2"] = MAT4X2; + (*KeywordMap)["mat4x3"] = MAT4X3; + (*KeywordMap)["mat4x4"] = MAT4X4; + (*KeywordMap)["dmat2"] = DMAT2; + (*KeywordMap)["dmat3"] = DMAT3; + (*KeywordMap)["dmat4"] = DMAT4; + (*KeywordMap)["dmat2x2"] = DMAT2X2; + (*KeywordMap)["dmat2x3"] = DMAT2X3; + (*KeywordMap)["dmat2x4"] = DMAT2X4; + (*KeywordMap)["dmat3x2"] = DMAT3X2; + (*KeywordMap)["dmat3x3"] = DMAT3X3; + (*KeywordMap)["dmat3x4"] = DMAT3X4; + (*KeywordMap)["dmat4x2"] = DMAT4X2; + (*KeywordMap)["dmat4x3"] = DMAT4X3; + (*KeywordMap)["dmat4x4"] = DMAT4X4; + (*KeywordMap)["image1D"] = IMAGE1D; + (*KeywordMap)["iimage1D"] = IIMAGE1D; + (*KeywordMap)["uimage1D"] = UIMAGE1D; + (*KeywordMap)["image2D"] = IMAGE2D; + (*KeywordMap)["iimage2D"] = IIMAGE2D; + (*KeywordMap)["uimage2D"] = UIMAGE2D; + (*KeywordMap)["image3D"] = IMAGE3D; + (*KeywordMap)["iimage3D"] = IIMAGE3D; + (*KeywordMap)["uimage3D"] = UIMAGE3D; + (*KeywordMap)["image2DRect"] = IMAGE2DRECT; + (*KeywordMap)["iimage2DRect"] = IIMAGE2DRECT; + (*KeywordMap)["uimage2DRect"] = UIMAGE2DRECT; + (*KeywordMap)["imageCube"] = IMAGECUBE; + (*KeywordMap)["iimageCube"] = IIMAGECUBE; + (*KeywordMap)["uimageCube"] = UIMAGECUBE; + (*KeywordMap)["imageBuffer"] = IMAGEBUFFER; + (*KeywordMap)["iimageBuffer"] = IIMAGEBUFFER; + (*KeywordMap)["uimageBuffer"] = UIMAGEBUFFER; + (*KeywordMap)["image1DArray"] = IMAGE1DARRAY; + (*KeywordMap)["iimage1DArray"] = IIMAGE1DARRAY; + (*KeywordMap)["uimage1DArray"] = UIMAGE1DARRAY; + (*KeywordMap)["image2DArray"] = IMAGE2DARRAY; + (*KeywordMap)["iimage2DArray"] = IIMAGE2DARRAY; + (*KeywordMap)["uimage2DArray"] = UIMAGE2DARRAY; + (*KeywordMap)["imageCubeArray"] = IMAGECUBEARRAY; + (*KeywordMap)["iimageCubeArray"] = IIMAGECUBEARRAY; + (*KeywordMap)["uimageCubeArray"] = UIMAGECUBEARRAY; + (*KeywordMap)["image2DMS"] = IMAGE2DMS; + (*KeywordMap)["iimage2DMS"] = IIMAGE2DMS; + (*KeywordMap)["uimage2DMS"] = UIMAGE2DMS; + (*KeywordMap)["image2DMSArray"] = IMAGE2DMSARRAY; + (*KeywordMap)["iimage2DMSArray"] = IIMAGE2DMSARRAY; + (*KeywordMap)["uimage2DMSArray"] = UIMAGE2DMSARRAY; + (*KeywordMap)["double"] = DOUBLE; + (*KeywordMap)["dvec2"] = DVEC2; + (*KeywordMap)["dvec3"] = DVEC3; + (*KeywordMap)["dvec4"] = DVEC4; + (*KeywordMap)["samplerCubeArray"] = SAMPLERCUBEARRAY; + (*KeywordMap)["samplerCubeArrayShadow"] = SAMPLERCUBEARRAYSHADOW; + (*KeywordMap)["isamplerCubeArray"] = ISAMPLERCUBEARRAY; + (*KeywordMap)["usamplerCubeArray"] = USAMPLERCUBEARRAY; + (*KeywordMap)["sampler1DArrayShadow"] = SAMPLER1DARRAYSHADOW; + (*KeywordMap)["isampler1DArray"] = ISAMPLER1DARRAY; + (*KeywordMap)["usampler1D"] = USAMPLER1D; + (*KeywordMap)["isampler1D"] = ISAMPLER1D; + (*KeywordMap)["usampler1DArray"] = USAMPLER1DARRAY; + (*KeywordMap)["samplerBuffer"] = SAMPLERBUFFER; + (*KeywordMap)["uint"] = UINT; + (*KeywordMap)["uvec2"] = UVEC2; + (*KeywordMap)["uvec3"] = UVEC3; + (*KeywordMap)["uvec4"] = UVEC4; + (*KeywordMap)["samplerCubeShadow"] = SAMPLERCUBESHADOW; + (*KeywordMap)["sampler2DArray"] = SAMPLER2DARRAY; + (*KeywordMap)["sampler2DArrayShadow"] = SAMPLER2DARRAYSHADOW; + (*KeywordMap)["isampler2D"] = ISAMPLER2D; + (*KeywordMap)["isampler3D"] = ISAMPLER3D; + (*KeywordMap)["isamplerCube"] = ISAMPLERCUBE; + (*KeywordMap)["isampler2DArray"] = ISAMPLER2DARRAY; + (*KeywordMap)["usampler2D"] = USAMPLER2D; + (*KeywordMap)["usampler3D"] = USAMPLER3D; + (*KeywordMap)["usamplerCube"] = USAMPLERCUBE; + (*KeywordMap)["usampler2DArray"] = USAMPLER2DARRAY; + (*KeywordMap)["isampler2DRect"] = ISAMPLER2DRECT; + (*KeywordMap)["usampler2DRect"] = USAMPLER2DRECT; + (*KeywordMap)["isamplerBuffer"] = ISAMPLERBUFFER; + (*KeywordMap)["usamplerBuffer"] = USAMPLERBUFFER; + (*KeywordMap)["sampler2DMS"] = SAMPLER2DMS; + (*KeywordMap)["isampler2DMS"] = ISAMPLER2DMS; + (*KeywordMap)["usampler2DMS"] = USAMPLER2DMS; + (*KeywordMap)["sampler2DMSArray"] = SAMPLER2DMSARRAY; + (*KeywordMap)["isampler2DMSArray"] = ISAMPLER2DMSARRAY; + (*KeywordMap)["usampler2DMSArray"] = USAMPLER2DMSARRAY; + (*KeywordMap)["sampler1D"] = SAMPLER1D; + (*KeywordMap)["sampler1DShadow"] = SAMPLER1DSHADOW; + (*KeywordMap)["sampler3D"] = SAMPLER3D; + (*KeywordMap)["sampler2DShadow"] = SAMPLER2DSHADOW; + (*KeywordMap)["sampler2DRect"] = SAMPLER2DRECT; + (*KeywordMap)["sampler2DRectShadow"] = SAMPLER2DRECTSHADOW; + (*KeywordMap)["sampler1DArray"] = SAMPLER1DARRAY; + (*KeywordMap)["noperspective"] = NOPERSPECTIVE; + (*KeywordMap)["smooth"] = SMOOTH; + (*KeywordMap)["flat"] = FLAT; + (*KeywordMap)["centroid"] = CENTROID; + (*KeywordMap)["precise"] = PRECISE; + (*KeywordMap)["invariant"] = INVARIANT; + (*KeywordMap)["packed"] = PACKED; + (*KeywordMap)["resource"] = RESOURCE; + (*KeywordMap)["superp"] = SUPERP; + + ReservedSet = new std::set; + + ReservedSet->insert("common"); + ReservedSet->insert("partition"); + ReservedSet->insert("active"); + ReservedSet->insert("asm"); + ReservedSet->insert("class"); + ReservedSet->insert("union"); + ReservedSet->insert("enum"); + ReservedSet->insert("typedef"); + ReservedSet->insert("template"); + ReservedSet->insert("this"); + ReservedSet->insert("goto"); + ReservedSet->insert("inline"); + ReservedSet->insert("noinline"); + ReservedSet->insert("public"); + ReservedSet->insert("static"); + ReservedSet->insert("extern"); + ReservedSet->insert("external"); + ReservedSet->insert("interface"); + ReservedSet->insert("long"); + ReservedSet->insert("short"); + ReservedSet->insert("half"); + ReservedSet->insert("fixed"); + ReservedSet->insert("unsigned"); + ReservedSet->insert("input"); + ReservedSet->insert("output"); + ReservedSet->insert("hvec2"); + ReservedSet->insert("hvec3"); + ReservedSet->insert("hvec4"); + ReservedSet->insert("fvec2"); + ReservedSet->insert("fvec3"); + ReservedSet->insert("fvec4"); + ReservedSet->insert("sampler3DRect"); + ReservedSet->insert("filter"); + ReservedSet->insert("sizeof"); + ReservedSet->insert("cast"); + ReservedSet->insert("namespace"); + ReservedSet->insert("using"); +} + +int TScanContext::tokenize(TParserToken& token) +{ + parserToken = &token; + TPpToken ppTokenStorage; + ppToken = &ppTokenStorage; + tokenText = PpTokenize(&ppToken->lexer); + + loc.string = cpp->tokenLoc->file; + loc.line = cpp->tokenLoc->line; + parserToken->sType.lex.loc = loc; + switch (ppToken->lexer.ppToken) { + case ';': afterType = false; return SEMICOLON; + case ',': afterType = false; return COMMA; + case ':': return COLON; + case '=': afterType = false; return EQUAL; + case '(': afterType = false; return LEFT_PAREN; + case ')': afterType = false; return RIGHT_PAREN; + case '.': field = true; return DOT; + case '!': return BANG; + case '-': return DASH; + case '~': return TILDE; + case '+': return PLUS; + case '*': return STAR; + case '/': return SLASH; + case '%': return PERCENT; + case '<': return LEFT_ANGLE; + case '>': return RIGHT_ANGLE; + case '|': return VERTICAL_BAR; + case '^': return CARET; + case '&': return AMPERSAND; + case '?': return QUESTION; + case '[': return LEFT_BRACKET; + case ']': return RIGHT_BRACKET; + case '{': return LEFT_BRACE; + case '}': return RIGHT_BRACE; + + case CPP_AND_OP: return AND_OP; + case CPP_SUB_ASSIGN: return SUB_ASSIGN; + case CPP_MOD_ASSIGN: return MOD_ASSIGN; + case CPP_ADD_ASSIGN: return ADD_ASSIGN; + case CPP_DIV_ASSIGN: return DIV_ASSIGN; + case CPP_MUL_ASSIGN: return MUL_ASSIGN; + case CPP_EQ_OP: return EQ_OP; + case CPP_XOR_OP: return XOR_OP; + case CPP_GE_OP: return GE_OP; + case CPP_RIGHT_OP: return RIGHT_OP; + case CPP_LE_OP: return LE_OP; + case CPP_LEFT_OP: return LEFT_OP; + case CPP_DEC_OP: return DEC_OP; + case CPP_NE_OP: return NE_OP; + case CPP_OR_OP: return OR_OP; + case CPP_INC_OP: return INC_OP; + case CPP_RIGHT_ASSIGN: return RIGHT_ASSIGN; + case CPP_LEFT_ASSIGN: return LEFT_ASSIGN; + case CPP_AND_ASSIGN: return AND_ASSIGN; + case CPP_OR_ASSIGN: return OR_ASSIGN; + case CPP_XOR_ASSIGN: return XOR_ASSIGN; + + case CPP_INTCONSTANT: parserToken->sType.lex.i = ppToken->lexer.sc_int; return INTCONSTANT; + case CPP_UINTCONSTANT: parserToken->sType.lex.i = ppToken->lexer.sc_int; return UINTCONSTANT; + case CPP_FLOATCONSTANT: parserToken->sType.lex.d = ppToken->lexer.sc_dval; return FLOATCONSTANT; + case CPP_DOUBLECONSTANT: parserToken->sType.lex.d = ppToken->lexer.sc_dval; return DOUBLECONSTANT; + case CPP_IDENTIFIER: return tokenizeIdentifier(); + + case EOF: return 0; + + default: + parseContext.infoSink.info.message(EPrefixInternalError, "Unknown PP token", loc); + return 0; + } +} + +int TScanContext::tokenizeIdentifier() +{ + if (ReservedSet->find(tokenText) != ReservedSet->end()) + return reservedWord(); + + keyword = (*KeywordMap)[tokenText]; + if (keyword == 0) { + // Should have an identifier of some sort + return identifierOrType(); + } + field = false; + + switch (keyword) { + case CONST: + case UNIFORM: + case IN: + case OUT: + case INOUT: + case STRUCT: + case BREAK: + case CONTINUE: + case DO: + case FOR: + case WHILE: + case IF: + case ELSE: + case DISCARD: + case RETURN: + case CASE: + return keyword; + + case SWITCH: + case DEFAULT: + if (parseContext.profile == EEsProfile && parseContext.version < 300 || + parseContext.profile != EEsProfile && parseContext.version < 130) + reservedWord(); + return keyword; + + case VOID: + case BOOL: + case FLOAT: + case INT: + case BVEC2: + case BVEC3: + case BVEC4: + case VEC2: + case VEC3: + case VEC4: + case IVEC2: + case IVEC3: + case IVEC4: + case MAT2: + case MAT3: + case MAT4: + case SAMPLER2D: + case SAMPLERCUBE: + afterType = true; + return keyword; + + case BOOLCONSTANT: + if (strcmp("true", tokenText) == 0) + parserToken->sType.lex.b = true; + else + parserToken->sType.lex.b = false; + return keyword; + + case ATTRIBUTE: + case VARYING: + if (parseContext.profile == EEsProfile && parseContext.version >= 300) + reservedWord(); + return keyword; + + case BUFFER: + if (parseContext.version < 430) + return identifierOrType(); + return keyword; + + case COHERENT: + case RESTRICT: + case READONLY: + case WRITEONLY: + case ATOMIC_UINT: + return es30ReservedFromGLSL(420); + + case VOLATILE: + if (parseContext.profile == EEsProfile || parseContext.version < 420) + reservedWord(); + return keyword; + + case LAYOUT: + case SHARED: + if (parseContext.profile == EEsProfile && parseContext.version < 300 || + parseContext.profile != EEsProfile && parseContext.version < 140) + return identifierOrType(); + return keyword; + + case PATCH: + case SAMPLE: + case SUBROUTINE: + return es30ReservedFromGLSL(400); + + case HIGH_PRECISION: + case MEDIUM_PRECISION: + case LOW_PRECISION: + case PRECISION: + return precisionKeyword(); + + case MAT2X2: + case MAT2X3: + case MAT2X4: + case MAT3X2: + case MAT3X3: + case MAT3X4: + case MAT4X2: + case MAT4X3: + case MAT4X4: + return matNxM(); + + case DMAT2: + case DMAT3: + case DMAT4: + case DMAT2X2: + case DMAT2X3: + case DMAT2X4: + case DMAT3X2: + case DMAT3X3: + case DMAT3X4: + case DMAT4X2: + case DMAT4X3: + case DMAT4X4: + return dMat(); + + case IMAGE1D: + case IIMAGE1D: + case UIMAGE1D: + case IMAGE2D: + case IIMAGE2D: + case UIMAGE2D: + case IMAGE3D: + case IIMAGE3D: + case UIMAGE3D: + case IMAGE2DRECT: + case IIMAGE2DRECT: + case UIMAGE2DRECT: + case IMAGECUBE: + case IIMAGECUBE: + case UIMAGECUBE: + case IMAGEBUFFER: + case IIMAGEBUFFER: + case UIMAGEBUFFER: + case IMAGE1DARRAY: + case IIMAGE1DARRAY: + case UIMAGE1DARRAY: + case IMAGE2DARRAY: + case IIMAGE2DARRAY: + case UIMAGE2DARRAY: + return firstGenerationImage(); + + case IMAGECUBEARRAY: + case IIMAGECUBEARRAY: + case UIMAGECUBEARRAY: + case IMAGE2DMS: + case IIMAGE2DMS: + case UIMAGE2DMS: + case IMAGE2DMSARRAY: + case IIMAGE2DMSARRAY: + case UIMAGE2DMSARRAY: + return secondGenerationImage(); + + case DOUBLE: + case DVEC2: + case DVEC3: + case DVEC4: + case SAMPLERCUBEARRAY: + case SAMPLERCUBEARRAYSHADOW: + case ISAMPLERCUBEARRAY: + case USAMPLERCUBEARRAY: + afterType = true; + if (parseContext.profile == EEsProfile || parseContext.version < 400) + reservedWord(); + return keyword; + + case ISAMPLER1D: + case ISAMPLER1DARRAY: + case SAMPLER1DARRAYSHADOW: + case USAMPLER1D: + case USAMPLER1DARRAY: + case SAMPLERBUFFER: + afterType = true; + return es30ReservedFromGLSL(130); + + case UINT: + case UVEC2: + case UVEC3: + case UVEC4: + case SAMPLERCUBESHADOW: + case SAMPLER2DARRAY: + case SAMPLER2DARRAYSHADOW: + case ISAMPLER2D: + case ISAMPLER3D: + case ISAMPLERCUBE: + case ISAMPLER2DARRAY: + case USAMPLER2D: + case USAMPLER3D: + case USAMPLERCUBE: + case USAMPLER2DARRAY: + afterType = true; + return nonreservedKeyword(300, 130); + + case ISAMPLER2DRECT: + case USAMPLER2DRECT: + case ISAMPLERBUFFER: + case USAMPLERBUFFER: + afterType = true; + return es30ReservedFromGLSL(140); + + case SAMPLER2DMS: + case ISAMPLER2DMS: + case USAMPLER2DMS: + case SAMPLER2DMSARRAY: + case ISAMPLER2DMSARRAY: + case USAMPLER2DMSARRAY: + afterType = true; + return es30ReservedFromGLSL(150); + + case SAMPLER1D: + case SAMPLER1DSHADOW: + afterType = true; + if (parseContext.profile == EEsProfile) + reservedWord(); + return keyword; + + case SAMPLER3D: + case SAMPLER2DSHADOW: + afterType = true; + if (parseContext.profile == EEsProfile && parseContext.version < 300) + reservedWord(); + return keyword; + + case SAMPLER2DRECT: + case SAMPLER2DRECTSHADOW: + afterType = true; + if (parseContext.profile == EEsProfile || + parseContext.profile != EEsProfile && parseContext.version < 140) + reservedWord(); + return keyword; + + case SAMPLER1DARRAY: + afterType = true; + if (parseContext.profile == EEsProfile && parseContext.version == 300) + reservedWord(); + else if (parseContext.profile == EEsProfile && parseContext.version < 300 || + parseContext.profile != EEsProfile && parseContext.version < 130) + return identifierOrType(); + return keyword; + + case NOPERSPECTIVE: + return es30ReservedFromGLSL(130); + + case SMOOTH: + if (parseContext.profile == EEsProfile && parseContext.version < 300 || + parseContext.profile != EEsProfile && parseContext.version < 130) + return identifierOrType(); + return keyword; + + case FLAT: + if (parseContext.profile == EEsProfile && parseContext.version < 300) + reservedWord(); + else if (parseContext.profile != EEsProfile && parseContext.version < 130) + return identifierOrType(); + return keyword; + + case CENTROID: + if (parseContext.version < 120) + return identifierOrType(); + return keyword; + + case PRECISE: + if (parseContext.profile == EEsProfile || + parseContext.profile != EEsProfile && parseContext.version < 400) + return identifierOrType(); + return keyword; + + case INVARIANT: + if (parseContext.profile != EEsProfile && parseContext.version < 120) + return identifierOrType(); + return keyword; + + case PACKED: + if (parseContext.profile == EEsProfile && parseContext.version < 300 || + parseContext.profile != EEsProfile && parseContext.version < 330) + return reservedWord(); + return identifierOrType(); + + case RESOURCE: + { + bool reserved = parseContext.profile == EEsProfile && parseContext.version >= 300 || + parseContext.profile != EEsProfile && parseContext.version >= 420; + return identifierOrReserved(reserved); + } + case SUPERP: + { + bool reserved = parseContext.profile == EEsProfile || parseContext.version >= 130; + return identifierOrReserved(reserved); + } + + default: + parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc); + return 0; + } +} + +int TScanContext::identifierOrType() +{ + parserToken->sType.lex.string = NewPoolTString(tokenText); + if (field) { + field = false; + + return FIELD_SELECTION; + } + + parserToken->sType.lex.symbol = parseContext.symbolTable.find(*parserToken->sType.lex.string); + if (afterType == false && parserToken->sType.lex.symbol) { + if (TVariable* variable = parserToken->sType.lex.symbol->getAsVariable()) { + if (variable->isUserType()) { + afterType = true; + + return TYPE_NAME; + } + } + } + + return IDENTIFIER; +} + +int TScanContext::reservedWord() +{ + ThreadLocalParseContext()->error(loc, "Reserved word.", tokenText, "", ""); + + return 0; +} + +int TScanContext::identifierOrReserved(bool reserved) +{ + if (reserved) { + reservedWord(); + + return 0; + } + + if (parseContext.forwardCompatible) + parseContext.warn(loc, "using future reserved keyword", tokenText, ""); + + return identifierOrType(); +} + +// For keywords that suddenly showed up on non-ES (not previously reserved) +// but then got reserved by ES 3.0. +int TScanContext::es30ReservedFromGLSL(int version) +{ + if (parseContext.profile == EEsProfile && parseContext.version < 300 || + parseContext.profile != EEsProfile && parseContext.version < version) { + if (parseContext.forwardCompatible) + parseContext.warn(loc, "future reserved word in ES 300 and keyword in GLSL", tokenText, ""); + + return identifierOrType(); + } else if (parseContext.profile == EEsProfile && parseContext.version >= 300) + reservedWord(); + + return keyword; +} + +// For a keyword that was never reserved, until it suddenly +// showed up, both in an es version and a non-ES version. +int TScanContext::nonreservedKeyword(int esVersion, int nonEsVersion) +{ + if (parseContext.profile == EEsProfile && parseContext.version < esVersion || + parseContext.profile != EEsProfile && parseContext.version < nonEsVersion) { + if (parseContext.forwardCompatible) + parseContext.warn(loc, "using future keyword", tokenText, ""); + + return identifierOrType(); + } + + return keyword; +} + +int TScanContext::precisionKeyword() +{ + if (parseContext.profile == EEsProfile || parseContext.version >= 130) + return keyword; + + if (parseContext.forwardCompatible) + parseContext.warn(loc, "using ES precision qualifier keyword", tokenText, ""); + + return identifierOrType(); +} + +int TScanContext::matNxM() +{ + afterType = true; + + if (parseContext.version > 110) + return keyword; + + if (parseContext.forwardCompatible) + parseContext.warn(loc, "using future non-square matrix type keyword", tokenText, ""); + + return identifierOrType(); +} + +int TScanContext::dMat() +{ + afterType = true; + + if (parseContext.profile == EEsProfile && parseContext.version >= 300) { + reservedWord(); + + return keyword; + } + + if (parseContext.profile != EEsProfile && parseContext.version >= 400) + return keyword; + + if (parseContext.forwardCompatible) + parseContext.warn(loc, "using future type keyword", tokenText, ""); + + return identifierOrType(); +} + +int TScanContext::firstGenerationImage() +{ + afterType = true; + + if (parseContext.profile != EEsProfile && parseContext.version >= 420) + return keyword; + + if (parseContext.profile == EEsProfile && parseContext.version >= 300 || + parseContext.profile != EEsProfile && parseContext.version >= 130) { + reservedWord(); + + return keyword; + } + + if (parseContext.forwardCompatible) + parseContext.warn(loc, "using future type keyword", tokenText, ""); + + return identifierOrType(); +} + +int TScanContext::secondGenerationImage() +{ + afterType = true; + + if (parseContext.profile != EEsProfile && parseContext.version >= 420) + return keyword; + + if (parseContext.forwardCompatible) + parseContext.warn(loc, "using future type keyword", tokenText, ""); + + return identifierOrType(); +} + +}; diff --git a/glslang/MachineIndependent/Scan.h b/glslang/MachineIndependent/Scan.h index 1ea57ee..81a6fb3 100644 --- a/glslang/MachineIndependent/Scan.h +++ b/glslang/MachineIndependent/Scan.h @@ -105,7 +105,7 @@ protected: int currentChar; }; -// The location of these is still pending a grand design for going to a singular +// TODO: The location of these is still pending a grand design for going to a singular // scanner for version finding, preprocessing, and tokenizing: void ConsumeWhiteSpace(TInputScanner& input, bool& foundNonSpaceTab); bool ConsumeComment(TInputScanner& input); diff --git a/glslang/MachineIndependent/ScanContext.h b/glslang/MachineIndependent/ScanContext.h new file mode 100644 index 0000000..116a36b --- /dev/null +++ b/glslang/MachineIndependent/ScanContext.h @@ -0,0 +1,80 @@ +// +//Copyright (C) 2013 LunarG, Inc. +// +//All rights reserved. +// +//Redistribution and use in source and binary forms, with or without +//modification, are permitted provided that the following conditions +//are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +//POSSIBILITY OF SUCH DAMAGE. +// + +// +// This holds context specific to the GLSL scanner, which +// sits between the preprocessor scanner and parser. +// + +#include "ParseHelper.h" + +namespace glslang { + +class TParserToken; +class TPpToken; + +class TScanContext { +public: + explicit TScanContext(TParseContext& pc) : parseContext(pc), afterType(false), field(false) { } + virtual ~TScanContext() { } + + static void fillInKeywordMap(); + int tokenize(TParserToken&); + +protected: + int tokenizeIdentifier(); + int identifierOrType(); + int reservedWord(); + int identifierOrReserved(bool reserved); + int es30ReservedFromGLSL(int version); + int nonreservedKeyword(int esVersion, int nonEsVersion); + int precisionKeyword(); + int matNxM(); + int dMat(); + int firstGenerationImage(); + int secondGenerationImage(); + + TParseContext& parseContext; + bool afterType; // true if we've recognized a type, so can only be looking for an identifier + bool field; // true if we're on a field, right after a '.' + TSourceLoc loc; + TParserToken* parserToken; + TPpToken* ppToken; + + const char* tokenText; + int keyword; +}; + +}; diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index 6c84330..0a1a12a 100644 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -44,10 +44,15 @@ #include "SymbolTable.h" #include "ParseHelper.h" #include "Scan.h" +#include "ScanContext.h" #include "../Include/ShHandle.h" #include "InitializeDll.h" +extern "C" { +#include "preprocessor/preprocess.h" +} + #define SH_EXPORTING #include "../Public/ShaderLang.h" #include "Initialize.h" @@ -99,8 +104,9 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, int version, EProfil symbolTable = &symbolTables[language]; TParseContext parseContext(*symbolTable, intermediate, true, version, profile, language, infoSink); - ThreadLocalParseContext() = &parseContext; + glslang::TScanContext scanContext(parseContext); + parseContext.scanContext = &scanContext; assert(symbolTable->isEmpty() || symbolTable->atSharedBuiltInLevel()); @@ -123,8 +129,6 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, int version, EProfil return false; } - ResetFlex(); - for (TBuiltInStrings::iterator i = BuiltInStrings[parseContext.language].begin(); i != BuiltInStrings[parseContext.language].end(); ++i) { const char* builtInShaders[1]; @@ -132,7 +136,7 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, int version, EProfil builtInShaders[0] = (*i).c_str(); builtInLengths[0] = (int) (*i).size(); - if (PaParseStrings(const_cast(builtInShaders), builtInLengths, 1, parseContext, 0) != 0) { + if (! parseContext.parseShaderStrings(const_cast(builtInShaders), builtInLengths, 1) != 0) { infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins"); printf("Unable to parse built-ins\n"); @@ -271,6 +275,8 @@ int ShInitialize() PerProcessGPA = new TPoolAllocator(true); } + glslang::TScanContext::fillInKeywordMap(); + return true; } @@ -411,19 +417,24 @@ int ShCompile( AddContextSpecificSymbols(resources, compiler->infoSink, &symbolTable, version, profile, compiler->getLanguage()); TParseContext parseContext(symbolTable, intermediate, false, version, profile, compiler->getLanguage(), compiler->infoSink, forwardCompatible, messages); + glslang::TScanContext scanContext(parseContext); + parseContext.scanContext = &scanContext; + + TSourceLoc beginning; + beginning.line = 1; + beginning.string = 0; if (! goodProfile) - parseContext.error(1, "incorrect", "#version", ""); + parseContext.error(beginning, "incorrect", "#version", ""); parseContext.initializeExtensionBehavior(); if (versionStatementMissing) - parseContext.warn(1, "statement missing: use #version on first line of shader", "#version", ""); + parseContext.warn(beginning, "statement missing: use #version on first line of shader", "#version", ""); else if (profile == EEsProfile && version >= 300 && versionNotFirst) - parseContext.error(1, "statement must appear first in ESSL shader; before comments or newlines", "#version", ""); + parseContext.error(beginning, "statement must appear first in ESSL shader; before comments or newlines", "#version", ""); ThreadLocalParseContext() = &parseContext; - ResetFlex(); InitPreprocessor(); // @@ -440,8 +451,8 @@ int ShCompile( if (parseContext.insertBuiltInArrayAtGlobalLevel()) success = false; - int ret = PaParseStrings(const_cast(shaderStrings), lengths, numStrings, parseContext, parseContext.getPreamble()); - if (ret) + bool ret = parseContext.parseShaderStrings(const_cast(shaderStrings), lengths, numStrings); + if (! ret) success = false; intermediate.addSymbolLinkageNodes(parseContext.treeRoot, parseContext.linkage, parseContext.language, symbolTable); diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp index 9bb38b4..cfcc931 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -64,10 +64,10 @@ const char* ProfileName[EProfileCount] = { // which subset allows the feature. If the current profile is not present, // give an error message. // -void TParseContext::requireProfile(int line, EProfileMask profileMask, const char *featureDesc) +void TParseContext::requireProfile(TSourceLoc loc, EProfileMask profileMask, const char *featureDesc) { if (((1 << profile) & profileMask) == 0) - error(line, "not supported with this profile:", featureDesc, ProfileName[profile]); + error(loc, "not supported with this profile:", featureDesc, ProfileName[profile]); } // @@ -75,10 +75,10 @@ void TParseContext::requireProfile(int line, EProfileMask profileMask, const cha // which subset allows the feature. If the current stage is not present, // give an error message. // -void TParseContext::requireStage(int line, EShLanguageMask languageMask, const char *featureDesc) +void TParseContext::requireStage(TSourceLoc loc, EShLanguageMask languageMask, const char *featureDesc) { if (((1 << language) & languageMask) == 0) - error(line, "not supported in this stage:", featureDesc, StageName[language]); + error(loc, "not supported in this stage:", featureDesc, StageName[language]); } // @@ -88,7 +88,7 @@ void TParseContext::requireStage(int line, EShLanguageMask languageMask, const c // // one that takes multiple extensions -void TParseContext::profileRequires(int line, EProfile callingProfile, int minVersion, int numExtensions, const char* extensions[], const char *featureDesc) +void TParseContext::profileRequires(TSourceLoc loc, EProfile callingProfile, int minVersion, int numExtensions, const char* extensions[], const char *featureDesc) { if (profile == callingProfile) { bool okay = false; @@ -98,7 +98,7 @@ void TParseContext::profileRequires(int line, EProfile callingProfile, int minVe TBehavior behavior = extensionBehavior[extensions[i]]; switch (behavior) { case EBhWarn: - infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), line); + infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc); // fall through case EBhRequire: case EBhEnable: @@ -109,29 +109,29 @@ void TParseContext::profileRequires(int line, EProfile callingProfile, int minVe } if (! okay) - error(line, "not supported for this version or the enabled extensions", featureDesc, ""); + error(loc, "not supported for this version or the enabled extensions", featureDesc, ""); } } // one that takes a single extension -void TParseContext::profileRequires(int line, EProfile callingProfile, int minVersion, const char* extension, const char *featureDesc) +void TParseContext::profileRequires(TSourceLoc loc, EProfile callingProfile, int minVersion, const char* extension, const char *featureDesc) { - profileRequires(line, callingProfile, minVersion, extension ? 1 : 0, &extension, featureDesc); + profileRequires(loc, callingProfile, minVersion, extension ? 1 : 0, &extension, featureDesc); } // // Within a profile, see if a feature is deprecated and error or warn based on whether // a future compatibility context is being use. // -void TParseContext::checkDeprecated(int line, EProfile callingProfile, int depVersion, const char *featureDesc) +void TParseContext::checkDeprecated(TSourceLoc loc, EProfile callingProfile, int depVersion, const char *featureDesc) { if (profile == callingProfile) { if (version >= depVersion) { if (forwardCompatible) - error(line, "deprecated, may be removed in future release", featureDesc, ""); + error(loc, "deprecated, may be removed in future release", featureDesc, ""); else if (! (messages & EShMsgSuppressWarnings)) infoSink.info.message(EPrefixWarning, (TString(featureDesc) + " deprecated in version " + - String(depVersion) + "; may be removed in future release").c_str(), line); + String(depVersion) + "; may be removed in future release").c_str(), loc); } } } @@ -140,27 +140,27 @@ void TParseContext::checkDeprecated(int line, EProfile callingProfile, int depVe // Within a profile, see if a feature has now been removed and if so, give an error. // The version argument is the first version no longer having the feature. // -void TParseContext::requireNotRemoved(int line, EProfile callingProfile, int removedVersion, const char *featureDesc) +void TParseContext::requireNotRemoved(TSourceLoc loc, EProfile callingProfile, int removedVersion, const char *featureDesc) { if (profile == callingProfile) { if (version >= removedVersion) { const int maxSize = 60; char buf[maxSize]; snprintf(buf, maxSize, "%s profile; removed in version %d", ProfileName[profile], removedVersion); - error(line, "no longer supported in", featureDesc, buf); + error(loc, "no longer supported in", featureDesc, buf); } } } -void TParseContext::fullIntegerCheck(int line, const char* op) +void TParseContext::fullIntegerCheck(TSourceLoc loc, const char* op) { - profileRequires(line, ENoProfile, 130, 0, op); - profileRequires(line, EEsProfile, 300, 0, op); + profileRequires(loc, ENoProfile, 130, 0, op); + profileRequires(loc, EEsProfile, 300, 0, op); } -void TParseContext::doubleCheck(int line, const char* op) +void TParseContext::doubleCheck(TSourceLoc loc, const char* op) { - requireProfile(line, (EProfileMask)(ECoreProfileMask | ECompatibilityProfileMask), op); - profileRequires(line, ECoreProfile, 400, 0, op); - profileRequires(line, ECompatibilityProfile, 400, 0, op); + requireProfile(loc, (EProfileMask)(ECoreProfileMask | ECompatibilityProfileMask), op); + profileRequires(loc, ECoreProfile, 400, 0, op); + profileRequires(loc, ECompatibilityProfile, 400, 0, op); } diff --git a/glslang/MachineIndependent/glslang.l b/glslang/MachineIndependent/glslang.l deleted file mode 100644 index 1ca307d..0000000 --- a/glslang/MachineIndependent/glslang.l +++ /dev/null @@ -1,1155 +0,0 @@ -/* -// -//Copyright (C) 2002-2005 3Dlabs Inc. Ltd. -//Copyright (C) 2012-2013 LunarG, Inc. -// -//All rights reserved. -// -//Redistribution and use in source and binary forms, with or without -//modification, are permitted provided that the following conditions -//are met: -// -// Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// -// Neither the name of 3Dlabs Inc. Ltd. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -//POSSIBILITY OF SUCH DAMAGE. -// -*/ -/* Based on -ANSI C grammar, Lex specification - -In 1985, Jeff Lee published this Lex specification together with a Yacc -grammar for the April 30, 1985 ANSI C draft. Tom Stockfisch reposted -both to net.sources in 1987; that original, as mentioned in the answer -to question 17.25 of the comp.lang.c FAQ, can be ftp'ed from ftp.uu.net, -file usenet/net.sources/ansi.c.grammar.Z. - -I intend to keep this version as close to the current C Standard grammar -as possible; please let me know if you discover discrepancies. - -Jutta Degener, 1995 -*/ - -D [0-9] -L [a-zA-Z_] -H [a-fA-F0-9] -E [Ee][+-]?{D}+ -O [0-7] -U [uU] -F [fF] -LF [lL][fF] - -%option nounput -%{ -#include -#include -#include "ParseHelper.h" -#include "glslang_tab.cpp.h" - -void PaReservedWord(); -int PaIdentOrType(const char* yytext, TParseContext&, YYSTYPE* pyylval); -int PaIdentOrReserved(bool reserved, TParseContext&, int line, const char* text, YYSTYPE* pyylval); -int PaES30ReservedFromGLSL(int version, TParseContext& pc, int line, const char* text, YYSTYPE* pyylval, int keyword); -int PaNonreservedKeyword(int esVersion, int nonEsVersion, TParseContext& pc, int line, const char* text, YYSTYPE* pyylval, int keyword); -int PaPrecisionKeyword(TParseContext&, int line, const char* text, YYSTYPE* pyylval, int keyword); -int PaMatNxM(TParseContext&, int line, const char* text, YYSTYPE* pyylval, int keyword); -int PaDMat(TParseContext&, int line, const char* text, YYSTYPE* pyylval, int keyword); -int Pa1stGenerationImage(TParseContext&, int line, const char* text, YYSTYPE* pyylval, int keyword); -int Pa2ndGenerationImage(TParseContext&, int line, const char* text, YYSTYPE* pyylval, int keyword); - -/* windows only pragma */ -#ifdef _MSC_VER -#pragma warning(disable : 4102) -#endif - -int yy_input(char* buf, int max_size); - -#ifdef _WIN32 - TSourceLoc yylineno; - extern int yyparse(TParseContext&); - #define YY_DECL int yylex(YYSTYPE* pyylval, TParseContext& parseContext) -#else - extern int yyparse(void*); - #define YY_DECL int yylex(YYSTYPE* pyylval, void* parseContextLocal) - #define parseContext (*((TParseContext*)(parseContextLocal))) -#endif - -#define YY_INPUT(buf,result,max_size) (result = yy_input(buf, max_size)) - -%} - -%option noyywrap -%option never-interactive -%option outfile="gen_glslang.cpp" -%x FIELDS - -%% -<*>"//"[^\n]*"\n" { /* CPP should have taken care of this */ }; - -"attribute" { pyylval->lex.line = yylineno; - if (parseContext.profile == EEsProfile && parseContext.version >= 300) - PaReservedWord(); - return ATTRIBUTE; - } -"const" { pyylval->lex.line = yylineno; - return CONST; - } -"uniform" { pyylval->lex.line = yylineno; - return UNIFORM; - } -"varying" { pyylval->lex.line = yylineno; - if (parseContext.profile == EEsProfile && parseContext.version >= 300) - PaReservedWord(); - return VARYING; - } -"buffer" { pyylval->lex.line = yylineno; - if (parseContext.version < 430) - return PaIdentOrType(yytext, parseContext, pyylval); - return BUFFER; - } -"shared" { pyylval->lex.line = yylineno; - if (parseContext.profile == EEsProfile && parseContext.version < 300 || - parseContext.profile != EEsProfile && parseContext.version < 140) - return PaIdentOrType(yytext, parseContext, pyylval); - return SHARED; - } -"coherent" { return PaES30ReservedFromGLSL(420, parseContext, yylineno, yytext, pyylval, COHERENT); } -"volatile" { pyylval->lex.line = yylineno; - if (parseContext.profile == EEsProfile || parseContext.version < 420) - PaReservedWord(); - return VOLATILE; - } -"restrict" { return PaES30ReservedFromGLSL(420, parseContext, yylineno, yytext, pyylval, RESTRICT); } -"readonly" { return PaES30ReservedFromGLSL(420, parseContext, yylineno, yytext, pyylval, READONLY); } -"writeonly" { return PaES30ReservedFromGLSL(420, parseContext, yylineno, yytext, pyylval, WRITEONLY); } - -"layout" { pyylval->lex.line = yylineno; - if (parseContext.profile == EEsProfile && parseContext.version < 300 || - parseContext.profile != EEsProfile && parseContext.version < 140) - return PaIdentOrType(yytext, parseContext, pyylval); - return LAYOUT; - } -"centroid" { pyylval->lex.line = yylineno; - if (parseContext.version < 120) - return PaIdentOrType(yytext, parseContext, pyylval); - return CENTROID; - } -"flat" { pyylval->lex.line = yylineno; - if (parseContext.profile == EEsProfile && parseContext.version < 300) - PaReservedWord(); - else if (parseContext.profile != EEsProfile && parseContext.version < 130) - return PaIdentOrType(yytext, parseContext, pyylval); - return FLAT; - } -"smooth" { pyylval->lex.line = yylineno; - if (parseContext.profile == EEsProfile && parseContext.version < 300 || - parseContext.profile != EEsProfile && parseContext.version < 130) - return PaIdentOrType(yytext, parseContext, pyylval); - return SMOOTH; - } -"noperspective" { return PaES30ReservedFromGLSL(130, parseContext, yylineno, yytext, pyylval, NOPERSPECTIVE); } -"patch" { return PaES30ReservedFromGLSL(400, parseContext, yylineno, yytext, pyylval, PATCH); } -"sample" { return PaES30ReservedFromGLSL(400, parseContext, yylineno, yytext, pyylval, SAMPLE); } - -"break" { pyylval->lex.line = yylineno; return BREAK; } -"continue" { pyylval->lex.line = yylineno; return CONTINUE; } -"do" { pyylval->lex.line = yylineno; return DO; } -"for" { pyylval->lex.line = yylineno; return FOR; } -"while" { pyylval->lex.line = yylineno; return WHILE; } -"switch" { pyylval->lex.line = yylineno; return SWITCH; } -"case" { pyylval->lex.line = yylineno; return CASE; } -"default" { pyylval->lex.line = yylineno; return DEFAULT; } - -"if" { pyylval->lex.line = yylineno; return IF; } -"else" { pyylval->lex.line = yylineno; return ELSE; } - -"subroutine" { return PaES30ReservedFromGLSL(400, parseContext, yylineno, yytext, pyylval, SUBROUTINE); } - -"in" { pyylval->lex.line = yylineno; return IN; } -"out" { pyylval->lex.line = yylineno; return OUT; } -"inout" { pyylval->lex.line = yylineno; return INOUT; } - -"precise" { pyylval->lex.line = yylineno; - if (parseContext.profile == EEsProfile || - parseContext.profile != EEsProfile && parseContext.version < 400) - return PaIdentOrType(yytext, parseContext, pyylval); - return PRECISE; - } -"invariant" { pyylval->lex.line = yylineno;; - if (parseContext.profile != EEsProfile && parseContext.version < 120) - return PaIdentOrType(yytext, parseContext, pyylval); - return INVARIANT; - } - -"highp" { return PaPrecisionKeyword(parseContext, yylineno, yytext, pyylval, HIGH_PRECISION); } -"mediump" { return PaPrecisionKeyword(parseContext, yylineno, yytext, pyylval, MEDIUM_PRECISION); } -"lowp" { return PaPrecisionKeyword(parseContext, yylineno, yytext, pyylval, LOW_PRECISION); } -"precision" { return PaPrecisionKeyword(parseContext, yylineno, yytext, pyylval, PRECISION); } - -"float" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return FLOAT; } -"double" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - if (parseContext.profile == EEsProfile || parseContext.version < 400) - PaReservedWord(); - return DOUBLE; - } -"int" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return INT; } -"uint" { parseContext.lexAfterType = true; - return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, UINT); - } -"void" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return VOID; } -"bool" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return BOOL; } -"true" { pyylval->lex.line = yylineno; pyylval->lex.b = true; return BOOLCONSTANT; } -"false" { pyylval->lex.line = yylineno; pyylval->lex.b = false; return BOOLCONSTANT; } - -"discard" { pyylval->lex.line = yylineno; return DISCARD; } -"return" { pyylval->lex.line = yylineno; return RETURN; } - -"atomic_uint" { return PaES30ReservedFromGLSL(420, parseContext, yylineno, yytext, pyylval, ATOMIC_UINT); } - -"mat2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return MAT2; } -"mat3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return MAT3; } -"mat4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return MAT4; } - -"mat2x2" { return PaMatNxM(parseContext, yylineno, yytext, pyylval, MAT2X2); } -"mat2x3" { return PaMatNxM(parseContext, yylineno, yytext, pyylval, MAT2X3); } -"mat2x4" { return PaMatNxM(parseContext, yylineno, yytext, pyylval, MAT2X4); } -"mat3x2" { return PaMatNxM(parseContext, yylineno, yytext, pyylval, MAT3X2); } -"mat3x3" { return PaMatNxM(parseContext, yylineno, yytext, pyylval, MAT3X3); } -"mat3x4" { return PaMatNxM(parseContext, yylineno, yytext, pyylval, MAT3X4); } -"mat4x2" { return PaMatNxM(parseContext, yylineno, yytext, pyylval, MAT4X2); } -"mat4x3" { return PaMatNxM(parseContext, yylineno, yytext, pyylval, MAT4X3); } -"mat4x4" { return PaMatNxM(parseContext, yylineno, yytext, pyylval, MAT4X4); } -"dmat2" { return PaDMat(parseContext, yylineno, yytext, pyylval, DMAT2); } -"dmat3" { return PaDMat(parseContext, yylineno, yytext, pyylval, DMAT3); } -"dmat4" { return PaDMat(parseContext, yylineno, yytext, pyylval, DMAT4); } -"dmat2x2" { return PaDMat(parseContext, yylineno, yytext, pyylval, DMAT2X2); } -"dmat2x3" { return PaDMat(parseContext, yylineno, yytext, pyylval, DMAT2X3); } -"dmat2x4" { return PaDMat(parseContext, yylineno, yytext, pyylval, DMAT2X4); } -"dmat3x2" { return PaDMat(parseContext, yylineno, yytext, pyylval, DMAT3X2); } -"dmat3x3" { return PaDMat(parseContext, yylineno, yytext, pyylval, DMAT3X3); } -"dmat3x4" { return PaDMat(parseContext, yylineno, yytext, pyylval, DMAT3X4); } -"dmat4x2" { return PaDMat(parseContext, yylineno, yytext, pyylval, DMAT4X2); } -"dmat4x3" { return PaDMat(parseContext, yylineno, yytext, pyylval, DMAT4X3); } -"dmat4x4" { return PaDMat(parseContext, yylineno, yytext, pyylval, DMAT4X4); } - -"vec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return VEC2; } -"vec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return VEC3; } -"vec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return VEC4; } -"dvec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - if (parseContext.profile == EEsProfile || parseContext.version < 400) - PaReservedWord(); - return DVEC2; - } -"dvec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - if (parseContext.profile == EEsProfile || parseContext.version < 400) - PaReservedWord(); - return DVEC3; - } -"dvec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - if (parseContext.profile == EEsProfile || parseContext.version < 400) - PaReservedWord(); - return DVEC4; - } -"ivec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return IVEC2; } -"ivec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return IVEC3; } -"ivec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return IVEC4; } -"uvec2" { parseContext.lexAfterType = true; - return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, UVEC2); - } -"uvec3" { parseContext.lexAfterType = true; - return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, UVEC3); - } -"uvec4" { parseContext.lexAfterType = true; - return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, UVEC4); - } -"bvec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return BVEC2; } -"bvec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return BVEC3; } -"bvec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return BVEC4; } - -"sampler2D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2D; } -"samplerCube" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLERCUBE; } - -"sampler1D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - if (parseContext.profile == EEsProfile) - PaReservedWord(); - return SAMPLER1D; - } -"sampler3D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - if (parseContext.profile == EEsProfile && parseContext.version < 300) - PaReservedWord(); - return SAMPLER3D; - } -"sampler1DShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - if (parseContext.profile == EEsProfile) - PaReservedWord(); - return SAMPLER1DSHADOW; - } -"sampler2DShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - if (parseContext.profile == EEsProfile && parseContext.version < 300) - PaReservedWord(); - return SAMPLER2DSHADOW; - } -"sampler2DRect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - if (parseContext.profile == EEsProfile || - parseContext.profile != EEsProfile && parseContext.version < 140) - PaReservedWord(); - return SAMPLER2DRECT; - } -"sampler2DRectShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - if (parseContext.profile == EEsProfile || - parseContext.profile != EEsProfile && parseContext.version < 140) - PaReservedWord(); - return SAMPLER2DRECTSHADOW; - } -"samplerCubeShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, SAMPLERCUBESHADOW); - } -"sampler1DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - if (parseContext.profile == EEsProfile && parseContext.version == 300) - PaReservedWord(); - else if (parseContext.profile == EEsProfile && parseContext.version < 300 || - parseContext.profile != EEsProfile && parseContext.version < 130) - return PaIdentOrType(yytext, parseContext, pyylval); - return SAMPLER1DARRAY; - } -"sampler2DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, SAMPLER2DARRAY); - } -"sampler2DArrayShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, SAMPLER2DARRAYSHADOW); - } -"samplerCubeArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - if (parseContext.profile == EEsProfile || parseContext.version < 400) - return PaIdentOrType(yytext, parseContext, pyylval); - return SAMPLERCUBEARRAY; - } -"sampler1DArrayShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaES30ReservedFromGLSL(130, parseContext, yylineno, yytext, pyylval, SAMPLER1DARRAYSHADOW); - } -"samplerCubeArrayShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - if (parseContext.profile == EEsProfile || parseContext.version < 400) - return PaIdentOrType(yytext, parseContext, pyylval); - return SAMPLERCUBEARRAYSHADOW; - } -"isampler1D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaES30ReservedFromGLSL(130, parseContext, yylineno, yytext, pyylval, ISAMPLER1D); - } -"isampler2D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, ISAMPLER2D); - } -"isampler3D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, ISAMPLER3D); - } -"isamplerCube" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, ISAMPLERCUBE); - } -"isampler1DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaES30ReservedFromGLSL(130, parseContext, yylineno, yytext, pyylval, ISAMPLER1DARRAY); - } -"isampler2DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, ISAMPLER2DARRAY); - } -"usampler1D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaES30ReservedFromGLSL(130, parseContext, yylineno, yytext, pyylval, USAMPLER1D); - } -"usampler2D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, USAMPLER2D); - } -"usampler3D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, USAMPLER3D); - } -"usamplerCube" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, USAMPLERCUBE); - } -"usampler1DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaES30ReservedFromGLSL(130, parseContext, yylineno, yytext, pyylval, USAMPLER1DARRAY); - } -"usampler2DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaNonreservedKeyword(300, 130, parseContext, yylineno, yytext, pyylval, USAMPLER2DARRAY); - } -"isampler2DRect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaES30ReservedFromGLSL(140, parseContext, yylineno, yytext, pyylval, ISAMPLER2DRECT); - } -"usampler2DRect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaES30ReservedFromGLSL(140, parseContext, yylineno, yytext, pyylval, USAMPLER2DRECT); - } -"isamplerCubeArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - if (parseContext.profile == EEsProfile || parseContext.version < 400) - return PaIdentOrType(yytext, parseContext, pyylval); - return ISAMPLERCUBEARRAY; - } -"usamplerCubeArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - if (parseContext.profile == EEsProfile || parseContext.version < 400) - return PaIdentOrType(yytext, parseContext, pyylval); - return USAMPLERCUBEARRAY; - } -"samplerBuffer" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaES30ReservedFromGLSL(130, parseContext, yylineno, yytext, pyylval, SAMPLERBUFFER); - } -"isamplerBuffer" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaES30ReservedFromGLSL(140, parseContext, yylineno, yytext, pyylval, ISAMPLERBUFFER); - } -"usamplerBuffer" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaES30ReservedFromGLSL(140, parseContext, yylineno, yytext, pyylval, USAMPLERBUFFER); - } -"sampler2DMS" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaES30ReservedFromGLSL(150, parseContext, yylineno, yytext, pyylval, SAMPLER2DMS); - } -"isampler2DMS" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaES30ReservedFromGLSL(150, parseContext, yylineno, yytext, pyylval, ISAMPLER2DMS); - } -"usampler2DMS" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaES30ReservedFromGLSL(150, parseContext, yylineno, yytext, pyylval, USAMPLER2DMS); - } -"sampler2DMSArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaES30ReservedFromGLSL(150, parseContext, yylineno, yytext, pyylval, SAMPLER2DMSARRAY); - } -"isampler2DMSArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaES30ReservedFromGLSL(150, parseContext, yylineno, yytext, pyylval, ISAMPLER2DMSARRAY); - } -"usampler2DMSArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; - return PaES30ReservedFromGLSL(150, parseContext, yylineno, yytext, pyylval, USAMPLER2DMSARRAY); - } -"image1D" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGE1D); } -"iimage1D" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGE1D); } -"uimage1D" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGE1D); } -"image2D" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGE2D); } -"iimage2D" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGE2D); } -"uimage2D" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGE2D); } -"image3D" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGE3D); } -"iimage3D" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGE3D); } -"uimage3D" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGE3D); } -"image2DRect" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGE2DRECT); } -"iimage2DRect" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGE2DRECT); } -"uimage2DRect" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGE2DRECT); } -"imageCube" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGECUBE); } -"iimageCube" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGECUBE); } -"uimageCube" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGECUBE); } -"imageBuffer" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGEBUFFER); } -"iimageBuffer" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGEBUFFER); } -"uimageBuffer" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGEBUFFER); } -"image1DArray" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGE1DARRAY); } -"iimage1DArray" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGE1DARRAY); } -"uimage1DArray" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGE1DARRAY); } -"image2DArray" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGE2DARRAY); } -"iimage2DArray" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGE2DARRAY); } -"uimage2DArray" { return Pa1stGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGE2DARRAY); } - -"imageCubeArray" { return Pa2ndGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGECUBEARRAY); } -"iimageCubeArray" { return Pa2ndGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGECUBEARRAY); } -"uimageCubeArray" { return Pa2ndGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGECUBEARRAY); } -"image2DMS" { return Pa2ndGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGE2DMS); } -"iimage2DMS" { return Pa2ndGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGE2DMS); } -"uimage2DMS" { return Pa2ndGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGE2DMS); } -"image2DMSArray" { return Pa2ndGenerationImage(parseContext, yylineno, yytext, pyylval, IMAGE2DMSARRAY); } -"iimage2DMSArray" { return Pa2ndGenerationImage(parseContext, yylineno, yytext, pyylval, IIMAGE2DMSARRAY); } -"uimage2DMSArray" { return Pa2ndGenerationImage(parseContext, yylineno, yytext, pyylval, UIMAGE2DMSARRAY); } - -"struct" { pyylval->lex.line = yylineno; return STRUCT; } - -"common" { PaReservedWord(); return 0; } -"partition" { PaReservedWord(); return 0; } -"active" { PaReservedWord(); return 0; } -"asm" { PaReservedWord(); return 0; } -"class" { PaReservedWord(); return 0; } -"union" { PaReservedWord(); return 0; } -"enum" { PaReservedWord(); return 0; } -"typedef" { PaReservedWord(); return 0; } -"template" { PaReservedWord(); return 0; } -"this" { PaReservedWord(); return 0; } - -"packed" { pyylval->lex.line = yylineno; - if (parseContext.profile == EEsProfile && parseContext.version < 300 || - parseContext.profile != EEsProfile && parseContext.version < 330) { - PaReservedWord(); - return 0; - } else - return PaIdentOrType(yytext, parseContext, pyylval); - } -"resource" { bool reserved = parseContext.profile == EEsProfile && parseContext.version >= 300 || - parseContext.profile != EEsProfile && parseContext.version >= 420; - return PaIdentOrReserved(reserved, parseContext, yylineno, yytext, pyylval); - } -"goto" { PaReservedWord(); return 0; } - -"inline" { PaReservedWord(); return 0; } -"noinline" { PaReservedWord(); return 0; } -"public" { PaReservedWord(); return 0; } -"static" { PaReservedWord(); return 0; } -"extern" { PaReservedWord(); return 0; } -"external" { PaReservedWord(); return 0; } -"interface" { PaReservedWord(); return 0; } - -"long" { PaReservedWord(); return 0; } -"short" { PaReservedWord(); return 0; } -"half" { PaReservedWord(); return 0; } -"fixed" { PaReservedWord(); return 0; } -"unsigned" { PaReservedWord(); return 0; } - -"superp" { bool reserved = parseContext.profile == EEsProfile || parseContext.version >= 130; - return PaIdentOrReserved(reserved, parseContext, yylineno, yytext, pyylval); - } -"input" { PaReservedWord(); return 0; } -"output" { PaReservedWord(); return 0; } - -"hvec2" { PaReservedWord(); return 0; } -"hvec3" { PaReservedWord(); return 0; } -"hvec4" { PaReservedWord(); return 0; } -"fvec2" { PaReservedWord(); return 0; } -"fvec3" { PaReservedWord(); return 0; } -"fvec4" { PaReservedWord(); return 0; } - -"sampler3DRect" { PaReservedWord(); return 0; } - -"filter" { PaReservedWord(); return 0; } - -"sizeof" { PaReservedWord(); return 0; } -"cast" { PaReservedWord(); return 0; } - -"namespace" { PaReservedWord(); return 0; } -"using" { PaReservedWord(); return 0; } - -{L}({L}|{D})* { - pyylval->lex.line = yylineno; - return PaIdentOrType(yytext, parseContext, pyylval); -} - -0[xX]{H}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtoul(yytext, 0, 0); return INTCONSTANT; } -0{O}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtoul(yytext, 0, 0); return INTCONSTANT; } -0{D}+ { pyylval->lex.line = yylineno; parseContext.error(yylineno, "Invalid Octal number.", yytext, "", ""); return 0;} -{D}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtoul(yytext, 0, 0); return INTCONSTANT; } - -0[xX]{H}+{U} { pyylval->lex.line = yylineno; pyylval->lex.u = strtoul(yytext, 0, 0); return UINTCONSTANT; } -0{O}+{U} { pyylval->lex.line = yylineno; pyylval->lex.u = strtoul(yytext, 0, 0); return UINTCONSTANT; } -0{D}+{U} { pyylval->lex.line = yylineno; parseContext.error(yylineno, "Invalid Octal number.", yytext, "", ""); return 0;} -{D}+{U} { pyylval->lex.line = yylineno; pyylval->lex.u = strtoul(yytext, 0, 0); return UINTCONSTANT; } - -{D}+{F} { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return FLOATCONSTANT; } -{D}+{E}{F}? { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return FLOATCONSTANT; } -{D}+"."{D}*({E})?{F}? { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return FLOATCONSTANT; } -"."{D}+({E})?{F}? { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return FLOATCONSTANT; } - -{D}+{LF} { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return DOUBLECONSTANT; } -{D}+{E}{LF} { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return DOUBLECONSTANT; } -{D}+"."{D}*({E})?{LF} { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return DOUBLECONSTANT; } -"."{D}+({E})?{LF} { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return DOUBLECONSTANT; } - -"+=" { pyylval->lex.line = yylineno; return ADD_ASSIGN; } -"-=" { pyylval->lex.line = yylineno; return SUB_ASSIGN; } -"*=" { pyylval->lex.line = yylineno; return MUL_ASSIGN; } -"/=" { pyylval->lex.line = yylineno; return DIV_ASSIGN; } -"%=" { pyylval->lex.line = yylineno; return MOD_ASSIGN; } -"<<=" { pyylval->lex.line = yylineno; return LEFT_ASSIGN; } -">>=" { pyylval->lex.line = yylineno; return RIGHT_ASSIGN; } -"&=" { pyylval->lex.line = yylineno; return AND_ASSIGN; } -"^=" { pyylval->lex.line = yylineno; return XOR_ASSIGN; } -"|=" { pyylval->lex.line = yylineno; return OR_ASSIGN; } - -"++" { pyylval->lex.line = yylineno; return INC_OP; } -"--" { pyylval->lex.line = yylineno; return DEC_OP; } -"&&" { pyylval->lex.line = yylineno; return AND_OP; } -"||" { pyylval->lex.line = yylineno; return OR_OP; } -"^^" { pyylval->lex.line = yylineno; return XOR_OP; } -"<=" { pyylval->lex.line = yylineno; return LE_OP; } -">=" { pyylval->lex.line = yylineno; return GE_OP; } -"==" { pyylval->lex.line = yylineno; return EQ_OP; } -"!=" { pyylval->lex.line = yylineno; return NE_OP; } -"<<" { pyylval->lex.line = yylineno; return LEFT_OP; } -">>" { pyylval->lex.line = yylineno; return RIGHT_OP; } -";" { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return SEMICOLON; } -("{"|"<%") { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return LEFT_BRACE; } -("}"|"%>") { pyylval->lex.line = yylineno; return RIGHT_BRACE; } -"," { pyylval->lex.line = yylineno; if (parseContext.inTypeParen) parseContext.lexAfterType = false; return COMMA; } -":" { pyylval->lex.line = yylineno; return COLON; } -"=" { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return EQUAL; } -"(" { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; parseContext.inTypeParen = true; return LEFT_PAREN; } -")" { pyylval->lex.line = yylineno; parseContext.inTypeParen = false; return RIGHT_PAREN; } -("["|"<:") { pyylval->lex.line = yylineno; return LEFT_BRACKET; } -("]"|":>") { pyylval->lex.line = yylineno; return RIGHT_BRACKET; } -"." { BEGIN(FIELDS); return DOT; } -"!" { pyylval->lex.line = yylineno; return BANG; } -"-" { pyylval->lex.line = yylineno; return DASH; } -"~" { pyylval->lex.line = yylineno; return TILDE; } -"+" { pyylval->lex.line = yylineno; return PLUS; } -"*" { pyylval->lex.line = yylineno; return STAR; } -"/" { pyylval->lex.line = yylineno; return SLASH; } -"%" { pyylval->lex.line = yylineno; return PERCENT; } -"<" { pyylval->lex.line = yylineno; return LEFT_ANGLE; } -">" { pyylval->lex.line = yylineno; return RIGHT_ANGLE; } -"|" { pyylval->lex.line = yylineno; return VERTICAL_BAR; } -"^" { pyylval->lex.line = yylineno; return CARET; } -"&" { pyylval->lex.line = yylineno; return AMPERSAND; } -"?" { pyylval->lex.line = yylineno; return QUESTION; } - -{L}({L}|{D})* { -BEGIN(INITIAL); - pyylval->lex.line = yylineno; - pyylval->lex.string = NewPoolTString(yytext); - return FIELD_SELECTION; } -[ \t\v\f\r] {} - -[ \t\v\n\f\r] { } -<*><> { (&parseContext)->AfterEOF = true; yy_delete_buffer(YY_CURRENT_BUFFER); yyterminate();} -<*>. { parseContext.infoSink.info << "FLEX: Unknown char " << yytext << "\n"; - return 0; } - -%% - - -//Including Pre-processor. -extern "C" { - #include "./preprocessor/preprocess.h" -} - -// -// The YY_INPUT macro just calls this. Maybe this could be just put into -// the macro directly. -// - -int yy_input(char* buf, int max_size) -{ - char *char_token =NULL; - int len; - - if ((len = yylex_CPP(buf, max_size)) == 0) - return 0; - if (len >= max_size) - YY_FATAL_ERROR( "input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); - - buf[len] = ' '; - return len+1; -} - - -// -// Parse an array of strings using yyparse. We set up globals used by -// yywrap. -// -// Returns 0 for success, as per yyparse(). -// -int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext& parseContextLocal, const char* preamble) -{ - if (!argv || argc == 0) - return 1; - - for (int i = 0; i < argc; ++i) { - if (! argv[i]) { - parseContextLocal.error(0, "Null shader source string", "", ""); - - return 1; - } - } - - // set up all the cpp fields... - cpp->pC = (void*)&parseContextLocal; - char *writeablePreamble = 0; - if (preamble) { - // preAmble could be a hard-coded string; make writable copy - // TODO: efficiency PP: make it not need writable strings - int size = strlen(preamble) + 1; - writeablePreamble = new char[size]; - memcpy(writeablePreamble, preamble, size); - ScanFromString(writeablePreamble); - cpp->PaWhichStr = -1; - } else { - ScanFromString(argv[0]); - cpp->PaWhichStr = 0; - } - if (! strLen) { - int argv0len = (int) strlen(argv[0]); - strLen = &argv0len; - } - yyrestart(0); - (&parseContextLocal)->AfterEOF = false; - cpp->PaArgv = argv; - cpp->PaArgc = argc; - cpp->PaStrLen = strLen; - cpp->notAVersionToken = 0; - yylineno = 1; - - // TODO: desktop PP: a shader containing nothing but white space and comments is valid, even though it has no parse tokens - int len = 0; - while (argv[0][len] == ' ' || - argv[0][len] == '\t' || - argv[0][len] == '\n' || - argv[0][len] == '\r') { - if (++len >= strLen[0]) { - delete writeablePreamble; - return 0; - } - } - - if (*cpp->PaStrLen > 0) { - int ret; - #ifdef _WIN32 - ret = yyparse(parseContextLocal); - #else - ret = yyparse((void*)(&parseContextLocal)); - #endif - delete writeablePreamble; - if (cpp->CompileError == 1 || parseContextLocal.numErrors > 0) - return 1; - else - return 0; - } - - delete writeablePreamble; - - return 0; -} - -void yyerror(const char *s) -{ - TParseContext& pc = *((TParseContext *)cpp->pC); - - if (pc.AfterEOF) { - if (cpp->tokensBeforeEOF == 1) - ThreadLocalParseContext()->error(yylineno, "", "pre-mature EOF", s, ""); - } else - ThreadLocalParseContext()->error(yylineno, "", yytext, s, ""); -} - -void PaReservedWord() -{ - ThreadLocalParseContext()->error(yylineno, "Reserved word.", yytext, "", ""); -} - -int PaIdentOrType(const char* yytext, TParseContext& parseContextLocal, YYSTYPE* pyylval) -{ - pyylval->lex.string = NewPoolTString(yytext); - pyylval->lex.symbol = parseContextLocal.symbolTable.find(*pyylval->lex.string); - if (parseContextLocal.lexAfterType == false && pyylval->lex.symbol) { - if (TVariable* variable = pyylval->lex.symbol->getAsVariable()) { - if (variable->isUserType()) { - parseContextLocal.lexAfterType = true; - - return TYPE_NAME; - } - } - } - - return IDENTIFIER; -} - -int PaIdentOrReserved(bool reserved, TParseContext& pc, int line, const char* text, YYSTYPE* pyylval) -{ - pyylval->lex.line = line; - - if (reserved) { - PaReservedWord(); - - return 0; - } - - if (pc.forwardCompatible) - pc.warn(yylineno, "using future reserved keyword", text, ""); - - return PaIdentOrType(text, pc, pyylval); -} - -// For keywords that suddenly showed up on non-ES (not previously reserved) -// but then got reserved by ES 3.0. -int PaES30ReservedFromGLSL(int version, TParseContext& pc, int line, const char* text, YYSTYPE* pyylval, int keyword) -{ - pyylval->lex.line = line; - - if (pc.profile == EEsProfile && pc.version < 300 || - pc.profile != EEsProfile && pc.version < version) { - if (pc.forwardCompatible) - pc.warn(yylineno, "future reserved word in ES 300 and keyword in GLSL", text, ""); - - return PaIdentOrType(text, pc, pyylval); - } else if (pc.profile == EEsProfile && pc.version >= 300) - PaReservedWord(); - - return keyword; -} - -// For a keyword that was never reserved, until it suddenly -// showed up, both in an es version and a non-ES version. -int PaNonreservedKeyword(int esVersion, int nonEsVersion, TParseContext& pc, int line, const char* text, YYSTYPE* pyylval, int keyword) -{ - pyylval->lex.line = line; - - if (pc.profile == EEsProfile && pc.version < esVersion || - pc.profile != EEsProfile && pc.version < nonEsVersion) { - if (pc.forwardCompatible) - pc.warn(yylineno, "using future keyword", text, ""); - - return PaIdentOrType(text, pc, pyylval); - } - - return keyword; -} - -int PaPrecisionKeyword(TParseContext& pc, int line, const char* text, YYSTYPE* pyylval, int keyword) -{ - pyylval->lex.line = line; - - if (pc.profile == EEsProfile || pc.version >= 130) - return keyword; - - if (pc.forwardCompatible) - pc.warn(yylineno, "using ES precision qualifier keyword", text, ""); - - return PaIdentOrType(text, pc, pyylval); -} - -int PaMatNxM(TParseContext& pc, int line, const char* text, YYSTYPE* pyylval, int keyword) -{ - pyylval->lex.line = line; - pc.lexAfterType = true; - - if (pc.version > 110) - return keyword; - - if (pc.forwardCompatible) - pc.warn(yylineno, "using future non-square matrix type keyword", text, ""); - - return PaIdentOrType(text, pc, pyylval); -} - -int PaDMat(TParseContext& pc, int line, const char* text, YYSTYPE* pyylval, int keyword) -{ - pyylval->lex.line = line; - pc.lexAfterType = true; - - if (pc.profile == EEsProfile && pc.version >= 300) { - PaReservedWord(); - - return keyword; - } - - if (pc.profile != EEsProfile && pc.version >= 400) - return keyword; - - if (pc.forwardCompatible) - pc.warn(yylineno, "using future type keyword", text, ""); - - return PaIdentOrType(text, pc, pyylval); -} - -int Pa1stGenerationImage(TParseContext& pc, int line, const char* text, YYSTYPE* pyylval, int keyword) -{ - pyylval->lex.line = line; - pc.lexAfterType = true; - - if (pc.profile != EEsProfile && pc.version >= 420) - return keyword; - - if (pc.profile == EEsProfile && pc.version >= 300 || - pc.profile != EEsProfile && pc.version >= 130) { - PaReservedWord(); - - return keyword; - } - - if (pc.forwardCompatible) - pc.warn(yylineno, "using future type keyword", text, ""); - - return PaIdentOrType(text, pc, pyylval); -} - -int Pa2ndGenerationImage(TParseContext& pc, int line, const char* text, YYSTYPE* pyylval, int keyword) -{ - pyylval->lex.line = line; - pc.lexAfterType = true; - - if (pc.profile != EEsProfile && pc.version >= 420) - return keyword; - - if (pc.forwardCompatible) - pc.warn(yylineno, "using future type keyword", text, ""); - - return PaIdentOrType(text, pc, pyylval); -} - -extern "C" { - -void ShPpDebugLogMsg(const char *msg) -{ - TParseContext& pc = *((TParseContext *)cpp->pC); - - pc.infoSink.debug.message(EPrefixNone, msg); -} - -void ShPpWarningToInfoLog(const char *msg) -{ - TParseContext& pc = *((TParseContext *)cpp->pC); - - pc.warn(yylineno, msg, "Preprocessor", ""); -} - -void ShPpErrorToInfoLog(const char *msg) -{ - TParseContext& pc = *((TParseContext *)cpp->pC); - - pc.error(yylineno, msg, "Preprocessor", ""); -} - -// return 1 if error -// return 0 if no error -int ShPpMacrosMustBeDefinedError() -{ - TParseContext& pc = *((TParseContext *)cpp->pC); - - if (pc.profile == EEsProfile) { - if (pc.messages & EShMsgRelaxedErrors) - ShPpWarningToInfoLog("undefined macro in expression not allowed in es profile"); - else { - ShPpErrorToInfoLog("undefined macro in expression"); - - return 1; - } - } - - return 0; -} - -void SetLineNumber(int line) -{ - yylineno &= ~SourceLocLineMask; - yylineno |= line; -} - -void SetStringNumber(int string) -{ - yylineno = (string << SourceLocStringShift) | (yylineno & SourceLocLineMask); -} - -int GetStringNumber(void) -{ - return yylineno >> 16; -} - -int GetLineNumber(void) -{ - return yylineno & SourceLocLineMask; -} - -void IncLineNumber(void) -{ - if ((yylineno & SourceLocLineMask) <= SourceLocLineMask) - ++yylineno; -} - -void DecLineNumber(void) -{ - if ((yylineno & SourceLocLineMask) > 0) - --yylineno; -} - -void HandlePragma(const char **tokens, int numTokens) -{ - TParseContext& pc = *((TParseContext *)cpp->pC); - - if (!strcmp(tokens[0], "optimize")) { - if (numTokens != 4) { - ShPpErrorToInfoLog("optimize pragma syntax is incorrect"); - return; - } - - if (strcmp(tokens[1], "(")) { - ShPpErrorToInfoLog("\"(\" expected after 'optimize' keyword"); - return; - } - - if (!strcmp(tokens[2], "on")) - pc.contextPragma.optimize = true; - else if (!strcmp(tokens[2], "off")) - pc.contextPragma.optimize = false; - else { - ShPpErrorToInfoLog("\"on\" or \"off\" expected after '(' for 'optimize' pragma"); - return; - } - - if (strcmp(tokens[3], ")")) { - ShPpErrorToInfoLog("\")\" expected to end 'optimize' pragma"); - return; - } - } else if (!strcmp(tokens[0], "debug")) { - if (numTokens != 4) { - ShPpErrorToInfoLog("debug pragma syntax is incorrect"); - return; - } - - if (strcmp(tokens[1], "(")) { - ShPpErrorToInfoLog("\"(\" expected after 'debug' keyword"); - return; - } - - if (!strcmp(tokens[2], "on")) - pc.contextPragma.debug = true; - else if (!strcmp(tokens[2], "off")) - pc.contextPragma.debug = false; - else { - ShPpErrorToInfoLog("\"on\" or \"off\" expected after '(' for 'debug' pragma"); - return; - } - - if (strcmp(tokens[3], ")")) { - ShPpErrorToInfoLog("\")\" expected to end 'debug' pragma"); - return; - } - } else { - -#ifdef PRAGMA_TABLE - // - // implementation specific pragma - // use parseContext.contextPragma.pragmaTable to store the information about pragma - // For now, just ignore the pragma that the implementation cannot recognize - // An Example of one such implementation for a pragma that has a syntax like - // #pragma pragmaname(pragmavalue) - // This implementation stores the current pragmavalue against the pragma name in pragmaTable. - // - if (numTokens == 4 && !strcmp(tokens[1], "(") && !strcmp(tokens[3], ")")) { - TPragmaTable& pragmaTable = parseContext.contextPragma.pragmaTable; - TPragmaTable::iterator iter; - iter = pragmaTable.find(TString(tokens[0])); - if (iter != pragmaTable.end()) { - iter->second = tokens[2]; - } else { - pragmaTable[tokens[0]] = tokens[2]; - } - } else if (numTokens >= 2) { - TPragmaTable& pragmaTable = parseContext.contextPragma.pragmaTable; - TPragmaTable::iterator iter; - iter = pragmaTable.find(TString(tokens[0])); - if (iter != pragmaTable.end()) { - iter->second = tokens[1]; - } else { - pragmaTable[tokens[0]] = tokens[1]; - } - } -#endif // PRAGMA_TABLE - } -} - -void StoreStr(const char *string) -{ - TParseContext& pc = *((TParseContext *)cpp->pC); - - TString strSrc; - strSrc = TString(string); - - pc.HashErrMsg = pc.HashErrMsg + " " + strSrc; -} - -const char* GetStrfromTStr(void) -{ - TParseContext& pc = *((TParseContext *)cpp->pC); - - cpp->ErrMsg = pc.HashErrMsg.c_str(); - return cpp->ErrMsg; -} - -void ResetTString(void) -{ - TParseContext& pc = *((TParseContext *)cpp->pC); - - pc.HashErrMsg = ""; -} - -void SetVersion(int version) -{ - // called by the CPP, but this functionality is currently - // taken over by ScanVersion() before parsing starts - - // CPP should still report errors in semantics -} - -int GetVersion(void* cppPc) -{ - TParseContext& pc = *((TParseContext *)cppPc); - - return pc.version; -} - -void SetProfile(EProfile profile) -{ - // called by the CPP, but this functionality is currently - // taken over by ScanVersion() before parsing starts - - // CPP should still report errors in semantics -} - -TBehavior GetBehavior(const char* behavior) -{ - if (!strcmp("require", behavior)) - return EBhRequire; - else if (!strcmp("enable", behavior)) - return EBhEnable; - else if (!strcmp("disable", behavior)) - return EBhDisable; - else if (!strcmp("warn", behavior)) - return EBhWarn; - else { - ShPpErrorToInfoLog((TString("behavior '") + behavior + "' is not supported").c_str()); - return EBhDisable; - } -} - -void updateExtensionBehavior(const char* extName, const char* behavior) -{ - TParseContext& pc = *((TParseContext *)cpp->pC); - TBehavior behaviorVal = GetBehavior(behavior); - TMap:: iterator iter; - TString msg; - - // special cased for all extension - if (!strcmp(extName, "all")) { - if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) { - ShPpErrorToInfoLog("extension 'all' cannot have 'require' or 'enable' behavior"); - return; - } else { - for (iter = pc.extensionBehavior.begin(); iter != pc.extensionBehavior.end(); ++iter) - iter->second = behaviorVal; - } - } else { - iter = pc.extensionBehavior.find(TString(extName)); - if (iter == pc.extensionBehavior.end()) { - switch (behaviorVal) { - case EBhRequire: - ShPpErrorToInfoLog((TString("extension '") + extName + "' is not supported").c_str()); - break; - case EBhEnable: - case EBhWarn: - case EBhDisable: - pc.warn(yylineno, "extension not supported", extName, ""); - break; - default: - assert(0 && "unexpected behaviorVal"); - } - - return; - } else - iter->second = behaviorVal; - } -} - -} // extern "C" - -void ResetFlex() -{ - yy_start = 1; -} diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y index a342956..f824400 100644 --- a/glslang/MachineIndependent/glslang.y +++ b/glslang/MachineIndependent/glslang.y @@ -77,7 +77,7 @@ extern void yyerror(const char*); %union { struct { - TSourceLoc line; + TSourceLoc loc; union { TString *string; int i; @@ -88,7 +88,7 @@ extern void yyerror(const char*); TSymbol* symbol; } lex; struct { - TSourceLoc line; + TSourceLoc loc; TOperator op; union { TIntermNode* intermNode; @@ -100,7 +100,7 @@ extern void yyerror(const char*); TPublicType type; TFunction* function; TParameter param; - TTypeLine typeLine; + TTypeLoc typeLine; TTypeList* typeList; TArraySizes arraySizes; TIdentifierList* identifierList; @@ -176,6 +176,8 @@ extern void yyerror(const char*); %token INVARIANT PRECISE %token HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION +%token PACKED RESOURCE SUPERP + %type assignment_operator unary_operator %type variable_identifier primary_expression postfix_expression %type expression integer_expression assignment_expression @@ -222,7 +224,7 @@ extern void yyerror(const char*); variable_identifier : IDENTIFIER { - $$ = parseContext.handleVariable($1.line, $1.symbol, $1.string); + $$ = parseContext.handleVariable($1.loc, $1.symbol, $1.string); } ; @@ -233,29 +235,29 @@ primary_expression | INTCONSTANT { constUnion *unionArray = new constUnion[1]; unionArray->setIConst($1.i); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.line); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.loc); } | UINTCONSTANT { - parseContext.fullIntegerCheck($1.line, "unsigned literal"); + parseContext.fullIntegerCheck($1.loc, "unsigned literal"); constUnion *unionArray = new constUnion[1]; unionArray->setUConst($1.u); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtUint, EvqConst), $1.line); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtUint, EvqConst), $1.loc); } | FLOATCONSTANT { constUnion *unionArray = new constUnion[1]; unionArray->setDConst($1.d); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.line); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.loc); } | DOUBLECONSTANT { - parseContext.doubleCheck($1.line, "double literal"); + parseContext.doubleCheck($1.loc, "double literal"); constUnion *unionArray = new constUnion[1]; unionArray->setDConst($1.d); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtDouble, EvqConst), $1.line); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtDouble, EvqConst), $1.loc); } | BOOLCONSTANT { constUnion *unionArray = new constUnion[1]; unionArray->setBConst($1.b); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $1.line); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $1.loc); } | LEFT_PAREN expression RIGHT_PAREN { $$ = $2; @@ -270,58 +272,58 @@ postfix_expression parseContext.variableCheck($1); if (!$1->isArray() && !$1->isMatrix() && !$1->isVector()) { if ($1->getAsSymbolNode()) - parseContext.error($2.line, " left of '[' is not of type array, matrix, or vector ", $1->getAsSymbolNode()->getName().c_str(), ""); + parseContext.error($2.loc, " left of '[' is not of type array, matrix, or vector ", $1->getAsSymbolNode()->getName().c_str(), ""); else - parseContext.error($2.line, " left of '[' is not of type array, matrix, or vector ", "expression", ""); + parseContext.error($2.loc, " left of '[' is not of type array, matrix, or vector ", "expression", ""); } 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); + $$ = parseContext.addConstArrayNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.loc); } else if ($1->isVector()) { // constant folding for vectors TVectorFields fields; fields.num = 1; fields.offsets[0] = $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(); // need to do it this way because v.xy sends fields integer array - $$ = parseContext.addConstVectorNode(fields, $1, $2.line); + $$ = parseContext.addConstVectorNode(fields, $1, $2.loc); } else if ($1->isMatrix()) { // constant folding for matrices - $$ = parseContext.addConstMatrixNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.line); + $$ = parseContext.addConstMatrixNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.loc); } } else { if ($3->getQualifier().storage == EvqConst) { int index = $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(); if (! $1->isArray() && ($1->isVector() && $1->getType().getVectorSize() <= index || $1->isMatrix() && $1->getType().getMatrixCols() <= index)) - parseContext.error($2.line, "", "[", "index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst()); + parseContext.error($2.loc, "", "[", "index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst()); else { if ($1->isArray()) { if ($1->getType().getArraySize() == 0) { if ($1->getType().getMaxArraySize() <= $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst()) - parseContext.arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), true, $2.line); + parseContext.arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), true, $2.loc); else - parseContext.arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, $2.line); + parseContext.arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, $2.loc); } else if ( $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= $1->getType().getArraySize() || $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() < 0) - parseContext.error($2.line, "", "[", "array index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst()); + parseContext.error($2.loc, "", "[", "array index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst()); } - $$ = parseContext.intermediate.addIndex(EOpIndexDirect, $1, $3, $2.line); + $$ = parseContext.intermediate.addIndex(EOpIndexDirect, $1, $3, $2.loc); } } else { if ($1->isArray() && $1->getType().getArraySize() == 0) - parseContext.error($2.line, "", "[", "array must be redeclared with a size before being indexed with a variable"); + parseContext.error($2.loc, "", "[", "array must be redeclared with a size before being indexed with a variable"); if ($1->getBasicType() == EbtBlock) - parseContext.requireProfile($1->getLine(), static_cast(~EEsProfileMask), "variable indexing block array"); + parseContext.requireProfile($1->getLoc(), static_cast(~EEsProfileMask), "variable indexing block array"); if ($1->getBasicType() == EbtSampler) { - parseContext.requireProfile($1->getLine(), static_cast(ECoreProfileMask | ECompatibilityProfileMask), "variable indexing sampler array"); - parseContext.profileRequires($1->getLine(), ECoreProfile, 400, 0, "variable indexing sampler array"); + parseContext.requireProfile($1->getLoc(), static_cast(ECoreProfileMask | ECompatibilityProfileMask), "variable indexing sampler array"); + parseContext.profileRequires($1->getLoc(), ECoreProfile, 400, 0, "variable indexing sampler array"); } - $$ = parseContext.intermediate.addIndex(EOpIndexIndirect, $1, $3, $2.line); + $$ = parseContext.intermediate.addIndex(EOpIndexIndirect, $1, $3, $2.loc); } } if ($$ == 0) { constUnion *unionArray = new constUnion[1]; unionArray->setDConst(0.0); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $2.line); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $2.loc); } else { TType newType($1->getType()); newType.dereference(); @@ -340,21 +342,21 @@ postfix_expression // if (*$3.string == "length") { - parseContext.profileRequires($3.line, ENoProfile, 120, "GL_3DL_array_objects", ".length"); - $$ = parseContext.intermediate.addMethod($1, TType(EbtInt), $3.string, $2.line); + parseContext.profileRequires($3.loc, ENoProfile, 120, "GL_3DL_array_objects", ".length"); + $$ = parseContext.intermediate.addMethod($1, TType(EbtInt), $3.string, $2.loc); } else { - parseContext.error($3.line, "only the length method is supported for array", $3.string->c_str(), ""); + parseContext.error($3.loc, "only the length method is supported for array", $3.string->c_str(), ""); $$ = $1; } } else if ($1->isVector()) { TVectorFields fields; - if (! parseContext.parseVectorFields(*$3.string, $1->getVectorSize(), fields, $3.line)) { + if (! parseContext.parseVectorFields($3.loc, *$3.string, $1->getVectorSize(), fields)) { fields.num = 1; fields.offsets[0] = 0; } if ($1->getType().getQualifier().storage == EvqConst) { // constant folding for vector fields - $$ = parseContext.addConstVectorNode(fields, $1, $3.line); + $$ = parseContext.addConstVectorNode(fields, $1, $3.loc); if ($$ == 0) $$ = $1; else @@ -363,23 +365,23 @@ postfix_expression if (fields.num == 1) { constUnion *unionArray = new constUnion[1]; unionArray->setIConst(fields.offsets[0]); - TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $3.line); - $$ = parseContext.intermediate.addIndex(EOpIndexDirect, $1, index, $2.line); + TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $3.loc); + $$ = parseContext.intermediate.addIndex(EOpIndexDirect, $1, index, $2.loc); $$->setType(TType($1->getBasicType(), EvqTemporary, $1->getType().getQualifier().precision)); } else { TString vectorString = *$3.string; - TIntermTyped* index = parseContext.intermediate.addSwizzle(fields, $3.line); - $$ = parseContext.intermediate.addIndex(EOpVectorSwizzle, $1, index, $2.line); + TIntermTyped* index = parseContext.intermediate.addSwizzle(fields, $3.loc); + $$ = parseContext.intermediate.addIndex(EOpVectorSwizzle, $1, index, $2.loc); $$->setType(TType($1->getBasicType(), EvqTemporary, $1->getType().getQualifier().precision, (int) vectorString.size())); } } } else if ($1->isMatrix()) - parseContext.error($2.line, "field selection not allowed on matrix", ".", ""); + parseContext.error($2.loc, "field selection not allowed on matrix", ".", ""); else if ($1->getBasicType() == EbtStruct || $1->getBasicType() == EbtBlock) { bool fieldFound = false; TTypeList* fields = $1->getType().getStruct(); if (fields == 0) { - parseContext.error($2.line, "structure has no fields", "Internal Error", ""); + parseContext.error($2.loc, "structure has no fields", "Internal Error", ""); $$ = $1; } else { unsigned int i; @@ -391,7 +393,7 @@ postfix_expression } if (fieldFound) { if ($1->getType().getQualifier().storage == EvqConst) { - $$ = parseContext.addConstStruct(*$3.string, $1, $2.line); + $$ = parseContext.addConstStruct(*$3.string, $1, $2.loc); if ($$ == 0) $$ = $1; else { @@ -403,36 +405,36 @@ postfix_expression } else { constUnion *unionArray = new constUnion[1]; unionArray->setIConst(i); - TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $3.line); - $$ = parseContext.intermediate.addIndex(EOpIndexDirectStruct, $1, index, $2.line); + TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $3.loc); + $$ = parseContext.intermediate.addIndex(EOpIndexDirectStruct, $1, index, $2.loc); $$->setType(*(*fields)[i].type); } } else { - parseContext.error($2.line, " no such field in structure", $3.string->c_str(), ""); + parseContext.error($2.loc, " no such field in structure", $3.string->c_str(), ""); $$ = $1; } } } else { - parseContext.error($2.line, " dot operator requires structure, array, vector, or matrix on left hand side", $3.string->c_str(), ""); + parseContext.error($2.loc, " dot operator requires structure, array, vector, or matrix on left hand side", $3.string->c_str(), ""); $$ = $1; } // don't delete $3.string, it's from the pool } | postfix_expression INC_OP { parseContext.variableCheck($1); - parseContext.lValueErrorCheck($2.line, "++", $1); - $$ = parseContext.intermediate.addUnaryMath(EOpPostIncrement, $1, $2.line); + parseContext.lValueErrorCheck($2.loc, "++", $1); + $$ = parseContext.intermediate.addUnaryMath(EOpPostIncrement, $1, $2.loc); if ($$ == 0) { - parseContext.unaryOpError($2.line, "++", $1->getCompleteString()); + parseContext.unaryOpError($2.loc, "++", $1->getCompleteString()); $$ = $1; } } | postfix_expression DEC_OP { parseContext.variableCheck($1); - parseContext.lValueErrorCheck($2.line, "--", $1); - $$ = parseContext.intermediate.addUnaryMath(EOpPostDecrement, $1, $2.line); + parseContext.lValueErrorCheck($2.loc, "--", $1); + $$ = parseContext.intermediate.addUnaryMath(EOpPostDecrement, $1, $2.loc); if ($$ == 0) { - parseContext.unaryOpError($2.line, "--", $1->getCompleteString()); + parseContext.unaryOpError($2.loc, "--", $1->getCompleteString()); $$ = $1; } } @@ -451,17 +453,17 @@ function_call TOperator op = fnCall->getBuiltInOp(); if (op == EOpArrayLength) { if (fnCall->getParamCount() > 0) - parseContext.error($1.line, "method does not accept any arguments", fnCall->getName().c_str(), ""); + parseContext.error($1.loc, "method does not accept any arguments", fnCall->getName().c_str(), ""); int length; if ($1.intermNode->getAsTyped() == 0 || ! $1.intermNode->getAsTyped()->getType().isArray() || $1.intermNode->getAsTyped()->getType().getArraySize() == 0) { - parseContext.error($1.line, "", fnCall->getName().c_str(), "array must be declared with a size before using this method"); + parseContext.error($1.loc, "", fnCall->getName().c_str(), "array must be declared with a size before using this method"); length = 1; } else length = $1.intermNode->getAsTyped()->getType().getArraySize(); constUnion *unionArray = new constUnion[1]; unionArray->setIConst(length); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.line); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.loc); } else if (op != EOpNull) { // // Then this should be a constructor. @@ -469,26 +471,26 @@ function_call // Their parameters will be verified algorithmically. // TType type(EbtVoid); // use this to get the type back - if (parseContext.constructorError($1.line, $1.intermNode, *fnCall, op, type)) { + if (parseContext.constructorError($1.loc, $1.intermNode, *fnCall, op, type)) { $$ = 0; } else { // // It's a constructor, of type 'type'. // - $$ = parseContext.addConstructor($1.intermNode, type, op, fnCall, $1.line); + $$ = parseContext.addConstructor($1.intermNode, type, op, fnCall, $1.loc); if ($$ == 0) - parseContext.error($1.line, "cannot construct with these arguments", type.getCompleteString().c_str(), ""); + parseContext.error($1.loc, "cannot construct with these arguments", type.getCompleteString().c_str(), ""); } if ($$ == 0) - $$ = parseContext.intermediate.setAggregateOperator(0, op, type, $1.line); + $$ = parseContext.intermediate.setAggregateOperator(0, op, type, $1.loc); } else { // // Not a constructor. Find it in the symbol table. // const TFunction* fnCandidate; bool builtIn; - fnCandidate = parseContext.findFunction($1.line, fnCall, &builtIn); + fnCandidate = parseContext.findFunction($1.loc, fnCall, &builtIn); if (fnCandidate) { // // A declared function. But, it might still map to a built-in @@ -499,14 +501,14 @@ function_call // A function call mapped to a built-in operation. $$ = parseContext.intermediate.addBuiltInFunctionCall(op, fnCandidate->getParamCount() == 1, $1.intermNode, fnCandidate->getReturnType()); if ($$ == 0) { - parseContext.error($1.intermNode->getLine(), " wrong operand type", "Internal Error", + parseContext.error($1.intermNode->getLoc(), " wrong operand type", "Internal Error", "built in unary operator function. Type: %s", static_cast($1.intermNode)->getCompleteString().c_str()); YYERROR; } } else { // This is a real function call - $$ = parseContext.intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, fnCandidate->getReturnType(), $1.line); + $$ = parseContext.intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, fnCandidate->getReturnType(), $1.loc); // this is how we know whether the given function is a builtIn function or a user defined function // if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also @@ -520,8 +522,8 @@ function_call for (int i = 0; i < fnCandidate->getParamCount(); ++i) { 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", ""); + if (parseContext.lValueErrorCheck($$->getLoc(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) + parseContext.error($1.intermNode->getLoc(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", ""); } qualifierList.push_back(qual); } @@ -536,7 +538,7 @@ function_call // Put on a dummy node for error recovery constUnion *unionArray = new constUnion[1]; unionArray->setDConst(0.0); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.line); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.loc); } } delete fnCall; @@ -552,11 +554,11 @@ function_call_or_method function_call_generic : function_call_header_with_parameters RIGHT_PAREN { $$ = $1; - $$.line = $2.line; + $$.loc = $2.loc; } | function_call_header_no_parameters RIGHT_PAREN { $$ = $1; - $$.line = $2.line; + $$.loc = $2.loc; } ; @@ -580,7 +582,7 @@ function_call_header_with_parameters TParameter param = { 0, new TType($3->getType()) }; $1.function->addParameter(param); $$.function = $1.function; - $$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, $3, $2.line); + $$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, $3, $2.loc); } ; @@ -601,8 +603,8 @@ function_identifier $$.intermNode = 0; if ($1.arraySizes) { - parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed constructor"); - parseContext.profileRequires($1.line, EEsProfile, 300, "GL_3DL_array_objects", "arrayed constructor"); + parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed constructor"); + parseContext.profileRequires($1.loc, EEsProfile, 300, "GL_3DL_array_objects", "arrayed constructor"); } $1.qualifier.precision = EpqNone; @@ -721,7 +723,7 @@ function_identifier default: break; // some compilers want this } if (op == EOpNull) { - parseContext.error($1.line, "cannot construct this type", TType::getBasicString($1.basicType), ""); + parseContext.error($1.loc, "cannot construct this type", TType::getBasicString($1.basicType), ""); $1.basicType = EbtFloat; op = EOpConstructFloat; } @@ -744,15 +746,15 @@ function_identifier $$.function = new TFunction(&method->getMethodName(), TType(EbtInt), EOpArrayLength); $$.intermNode = method->getObject(); } else - parseContext.error(method->getLine(), "only arrays have methods", "", ""); + parseContext.error(method->getLoc(), "only arrays have methods", "", ""); } else { TIntermSymbol* symbol = $1->getAsSymbolNode(); if (symbol) { - parseContext.reservedErrorCheck(symbol->getLine(), symbol->getName()); + parseContext.reservedErrorCheck(symbol->getLoc(), symbol->getName()); TFunction *function = new TFunction(&symbol->getName(), TType(EbtVoid)); $$.function = function; } else - parseContext.error($1->getLine(), "function call, method, or subroutine call expected", "", ""); + parseContext.error($1->getLoc(), "function call, method, or subroutine call expected", "", ""); } if ($$.function == 0) { @@ -768,27 +770,27 @@ unary_expression parseContext.variableCheck($1); $$ = $1; if (TIntermMethod* method = $1->getAsMethodNode()) - parseContext.error($1->getLine(), "incomplete method syntax", method->getMethodName().c_str(), ""); + parseContext.error($1->getLoc(), "incomplete method syntax", method->getMethodName().c_str(), ""); } | INC_OP unary_expression { - parseContext.lValueErrorCheck($1.line, "++", $2); - $$ = parseContext.intermediate.addUnaryMath(EOpPreIncrement, $2, $1.line); + parseContext.lValueErrorCheck($1.loc, "++", $2); + $$ = parseContext.intermediate.addUnaryMath(EOpPreIncrement, $2, $1.loc); if ($$ == 0) { - parseContext.unaryOpError($1.line, "++", $2->getCompleteString()); + parseContext.unaryOpError($1.loc, "++", $2->getCompleteString()); $$ = $2; } } | DEC_OP unary_expression { - parseContext.lValueErrorCheck($1.line, "--", $2); - $$ = parseContext.intermediate.addUnaryMath(EOpPreDecrement, $2, $1.line); + parseContext.lValueErrorCheck($1.loc, "--", $2); + $$ = parseContext.intermediate.addUnaryMath(EOpPreDecrement, $2, $1.loc); if ($$ == 0) { - parseContext.unaryOpError($1.line, "--", $2->getCompleteString()); + parseContext.unaryOpError($1.loc, "--", $2->getCompleteString()); $$ = $2; } } | unary_operator unary_expression { if ($1.op != EOpNull) { - $$ = parseContext.intermediate.addUnaryMath($1.op, $2, $1.line); + $$ = parseContext.intermediate.addUnaryMath($1.op, $2, $1.loc); if ($$ == 0) { char errorOp[2] = {0, 0}; switch($1.op) { @@ -797,7 +799,7 @@ unary_expression case EOpBitwiseNot: errorOp[0] = '~'; break; default: break; // some compilers want this } - parseContext.unaryOpError($1.line, errorOp, $2->getCompleteString()); + parseContext.unaryOpError($1.loc, errorOp, $2->getCompleteString()); $$ = $2; } } else @@ -807,33 +809,33 @@ unary_expression // Grammar Note: No traditional style type casts. unary_operator - : PLUS { $$.line = $1.line; $$.op = EOpNull; } - | DASH { $$.line = $1.line; $$.op = EOpNegative; } - | BANG { $$.line = $1.line; $$.op = EOpLogicalNot; } - | TILDE { $$.line = $1.line; $$.op = EOpBitwiseNot; } + : PLUS { $$.loc = $1.loc; $$.op = EOpNull; } + | DASH { $$.loc = $1.loc; $$.op = EOpNegative; } + | BANG { $$.loc = $1.loc; $$.op = EOpLogicalNot; } + | TILDE { $$.loc = $1.loc; $$.op = EOpBitwiseNot; } ; // Grammar Note: No '*' or '&' unary ops. Pointers are not supported. multiplicative_expression : unary_expression { $$ = $1; } | multiplicative_expression STAR unary_expression { - $$ = parseContext.intermediate.addBinaryMath(EOpMul, $1, $3, $2.line); + $$ = parseContext.intermediate.addBinaryMath(EOpMul, $1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.line, "*", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, "*", $1->getCompleteString(), $3->getCompleteString()); $$ = $1; } } | multiplicative_expression SLASH unary_expression { - $$ = parseContext.intermediate.addBinaryMath(EOpDiv, $1, $3, $2.line); + $$ = parseContext.intermediate.addBinaryMath(EOpDiv, $1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.line, "/", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, "/", $1->getCompleteString(), $3->getCompleteString()); $$ = $1; } } | multiplicative_expression PERCENT unary_expression { - $$ = parseContext.intermediate.addBinaryMath(EOpMod, $1, $3, $2.line); + $$ = parseContext.intermediate.addBinaryMath(EOpMod, $1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.line, "%", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, "%", $1->getCompleteString(), $3->getCompleteString()); $$ = $1; } } @@ -842,16 +844,16 @@ multiplicative_expression additive_expression : multiplicative_expression { $$ = $1; } | additive_expression PLUS multiplicative_expression { - $$ = parseContext.intermediate.addBinaryMath(EOpAdd, $1, $3, $2.line); + $$ = parseContext.intermediate.addBinaryMath(EOpAdd, $1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.line, "+", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, "+", $1->getCompleteString(), $3->getCompleteString()); $$ = $1; } } | additive_expression DASH multiplicative_expression { - $$ = parseContext.intermediate.addBinaryMath(EOpSub, $1, $3, $2.line); + $$ = parseContext.intermediate.addBinaryMath(EOpSub, $1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.line, "-", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, "-", $1->getCompleteString(), $3->getCompleteString()); $$ = $1; } } @@ -860,18 +862,18 @@ additive_expression shift_expression : additive_expression { $$ = $1; } | shift_expression LEFT_OP additive_expression { - parseContext.fullIntegerCheck($2.line, "bit shift left"); - $$ = parseContext.intermediate.addBinaryMath(EOpLeftShift, $1, $3, $2.line); + parseContext.fullIntegerCheck($2.loc, "bit shift left"); + $$ = parseContext.intermediate.addBinaryMath(EOpLeftShift, $1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.line, "<<", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, "<<", $1->getCompleteString(), $3->getCompleteString()); $$ = $1; } } | shift_expression RIGHT_OP additive_expression { - parseContext.fullIntegerCheck($2.line, "bit shift right"); - $$ = parseContext.intermediate.addBinaryMath(EOpRightShift, $1, $3, $2.line); + parseContext.fullIntegerCheck($2.loc, "bit shift right"); + $$ = parseContext.intermediate.addBinaryMath(EOpRightShift, $1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.line, ">>", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, ">>", $1->getCompleteString(), $3->getCompleteString()); $$ = $1; } } @@ -880,39 +882,39 @@ shift_expression relational_expression : shift_expression { $$ = $1; } | relational_expression LEFT_ANGLE shift_expression { - $$ = parseContext.intermediate.addBinaryMath(EOpLessThan, $1, $3, $2.line); + $$ = parseContext.intermediate.addBinaryMath(EOpLessThan, $1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.line, "<", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, "<", $1->getCompleteString(), $3->getCompleteString()); constUnion *unionArray = new constUnion[1]; unionArray->setBConst(false); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc); } } | relational_expression RIGHT_ANGLE shift_expression { - $$ = parseContext.intermediate.addBinaryMath(EOpGreaterThan, $1, $3, $2.line); + $$ = parseContext.intermediate.addBinaryMath(EOpGreaterThan, $1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.line, ">", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, ">", $1->getCompleteString(), $3->getCompleteString()); constUnion *unionArray = new constUnion[1]; unionArray->setBConst(false); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc); } } | relational_expression LE_OP shift_expression { - $$ = parseContext.intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, $2.line); + $$ = parseContext.intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.line, "<=", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, "<=", $1->getCompleteString(), $3->getCompleteString()); constUnion *unionArray = new constUnion[1]; unionArray->setBConst(false); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc); } } | relational_expression GE_OP shift_expression { - $$ = parseContext.intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, $2.line); + $$ = parseContext.intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.line, ">=", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, ">=", $1->getCompleteString(), $3->getCompleteString()); constUnion *unionArray = new constUnion[1]; unionArray->setBConst(false); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc); } } ; @@ -920,34 +922,34 @@ relational_expression equality_expression : relational_expression { $$ = $1; } | equality_expression EQ_OP relational_expression { - $$ = parseContext.intermediate.addBinaryMath(EOpEqual, $1, $3, $2.line); + $$ = parseContext.intermediate.addBinaryMath(EOpEqual, $1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.line, "==", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, "==", $1->getCompleteString(), $3->getCompleteString()); constUnion *unionArray = new constUnion[1]; unionArray->setBConst(false); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc); } else if (($1->isArray() || $3->isArray())) - parseContext.profileRequires($2.line, ENoProfile, 120, "GL_3DL_array_objects", "=="); + parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "=="); } | equality_expression NE_OP relational_expression { - $$ = parseContext.intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.line); + $$ = parseContext.intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.line, "!=", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, "!=", $1->getCompleteString(), $3->getCompleteString()); constUnion *unionArray = new constUnion[1]; unionArray->setBConst(false); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc); } else if (($1->isArray() || $3->isArray())) - parseContext.profileRequires($2.line, ENoProfile, 120, "GL_3DL_array_objects", "!="); + parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "!="); } ; and_expression : equality_expression { $$ = $1; } | and_expression AMPERSAND equality_expression { - parseContext.fullIntegerCheck($2.line, "bitwise and"); - $$ = parseContext.intermediate.addBinaryMath(EOpAnd, $1, $3, $2.line); + parseContext.fullIntegerCheck($2.loc, "bitwise and"); + $$ = parseContext.intermediate.addBinaryMath(EOpAnd, $1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.line, "&", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, "&", $1->getCompleteString(), $3->getCompleteString()); $$ = $1; } } @@ -956,10 +958,10 @@ and_expression exclusive_or_expression : and_expression { $$ = $1; } | exclusive_or_expression CARET and_expression { - parseContext.fullIntegerCheck($2.line, "bitwise exclusive or"); - $$ = parseContext.intermediate.addBinaryMath(EOpExclusiveOr, $1, $3, $2.line); + parseContext.fullIntegerCheck($2.loc, "bitwise exclusive or"); + $$ = parseContext.intermediate.addBinaryMath(EOpExclusiveOr, $1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.line, "^", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, "^", $1->getCompleteString(), $3->getCompleteString()); $$ = $1; } } @@ -968,10 +970,10 @@ exclusive_or_expression inclusive_or_expression : exclusive_or_expression { $$ = $1; } | inclusive_or_expression VERTICAL_BAR exclusive_or_expression { - parseContext.fullIntegerCheck($2.line, "bitwise inclusive or"); - $$ = parseContext.intermediate.addBinaryMath(EOpInclusiveOr, $1, $3, $2.line); + parseContext.fullIntegerCheck($2.loc, "bitwise inclusive or"); + $$ = parseContext.intermediate.addBinaryMath(EOpInclusiveOr, $1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.line, "|", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, "|", $1->getCompleteString(), $3->getCompleteString()); $$ = $1; } } @@ -980,12 +982,12 @@ inclusive_or_expression logical_and_expression : inclusive_or_expression { $$ = $1; } | logical_and_expression AND_OP inclusive_or_expression { - $$ = parseContext.intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, $2.line); + $$ = parseContext.intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.line, "&&", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, "&&", $1->getCompleteString(), $3->getCompleteString()); constUnion *unionArray = new constUnion[1]; unionArray->setBConst(false); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc); } } ; @@ -993,12 +995,12 @@ logical_and_expression logical_xor_expression : logical_and_expression { $$ = $1; } | logical_xor_expression XOR_OP logical_and_expression { - $$ = parseContext.intermediate.addBinaryMath(EOpLogicalXor, $1, $3, $2.line); + $$ = parseContext.intermediate.addBinaryMath(EOpLogicalXor, $1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.line, "^^", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, "^^", $1->getCompleteString(), $3->getCompleteString()); constUnion *unionArray = new constUnion[1]; unionArray->setBConst(false); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc); } } ; @@ -1006,12 +1008,12 @@ logical_xor_expression logical_or_expression : logical_xor_expression { $$ = $1; } | logical_or_expression OR_OP logical_xor_expression { - $$ = parseContext.intermediate.addBinaryMath(EOpLogicalOr, $1, $3, $2.line); + $$ = parseContext.intermediate.addBinaryMath(EOpLogicalOr, $1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.line, "||", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, "||", $1->getCompleteString(), $3->getCompleteString()); constUnion *unionArray = new constUnion[1]; unionArray->setBConst(false); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.loc); } } ; @@ -1019,11 +1021,11 @@ logical_or_expression conditional_expression : logical_or_expression { $$ = $1; } | logical_or_expression QUESTION expression COLON assignment_expression { - parseContext.boolCheck($2.line, $1); + parseContext.boolCheck($2.loc, $1); - $$ = parseContext.intermediate.addSelection($1, $3, $5, $2.line); + $$ = parseContext.intermediate.addSelection($1, $3, $5, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.line, ":", $3->getCompleteString(), $5->getCompleteString()); + parseContext.binaryOpError($2.loc, ":", $3->getCompleteString(), $5->getCompleteString()); $$ = $5; } } @@ -1032,42 +1034,42 @@ conditional_expression assignment_expression : conditional_expression { $$ = $1; } | unary_expression assignment_operator assignment_expression { - parseContext.lValueErrorCheck($2.line, "assign", $1); - $$ = parseContext.intermediate.addAssign($2.op, $1, $3, $2.line); + parseContext.lValueErrorCheck($2.loc, "assign", $1); + $$ = parseContext.intermediate.addAssign($2.op, $1, $3, $2.loc); if ($$ == 0) { - parseContext.assignError($2.line, "assign", $1->getCompleteString(), $3->getCompleteString()); + parseContext.assignError($2.loc, "assign", $1->getCompleteString(), $3->getCompleteString()); $$ = $1; } else if (($1->isArray() || $3->isArray())) - parseContext.profileRequires($2.line, ENoProfile, 120, "GL_3DL_array_objects", "="); + parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "="); } ; assignment_operator - : EQUAL { $$.line = $1.line; $$.op = EOpAssign; } - | MUL_ASSIGN { $$.line = $1.line; $$.op = EOpMulAssign; } - | DIV_ASSIGN { $$.line = $1.line; $$.op = EOpDivAssign; } - | MOD_ASSIGN { $$.line = $1.line; $$.op = EOpModAssign; } - | ADD_ASSIGN { $$.line = $1.line; $$.op = EOpAddAssign; } - | SUB_ASSIGN { $$.line = $1.line; $$.op = EOpSubAssign; } + : EQUAL { $$.loc = $1.loc; $$.op = EOpAssign; } + | MUL_ASSIGN { $$.loc = $1.loc; $$.op = EOpMulAssign; } + | DIV_ASSIGN { $$.loc = $1.loc; $$.op = EOpDivAssign; } + | MOD_ASSIGN { $$.loc = $1.loc; $$.op = EOpModAssign; } + | ADD_ASSIGN { $$.loc = $1.loc; $$.op = EOpAddAssign; } + | SUB_ASSIGN { $$.loc = $1.loc; $$.op = EOpSubAssign; } | LEFT_ASSIGN { - parseContext.fullIntegerCheck($1.line, "bit-shift left assign"); - $$.line = $1.line; $$.op = EOpLeftShiftAssign; + parseContext.fullIntegerCheck($1.loc, "bit-shift left assign"); + $$.loc = $1.loc; $$.op = EOpLeftShiftAssign; } | RIGHT_ASSIGN { - parseContext.fullIntegerCheck($1.line, "bit-shift right assign"); - $$.line = $1.line; $$.op = EOpRightShiftAssign; + parseContext.fullIntegerCheck($1.loc, "bit-shift right assign"); + $$.loc = $1.loc; $$.op = EOpRightShiftAssign; } | AND_ASSIGN { - parseContext.fullIntegerCheck($1.line, "bitwise-and assign"); - $$.line = $1.line; $$.op = EOpAndAssign; + parseContext.fullIntegerCheck($1.loc, "bitwise-and assign"); + $$.loc = $1.loc; $$.op = EOpAndAssign; } | XOR_ASSIGN { - parseContext.fullIntegerCheck($1.line, "bitwise-xor assign"); - $$.line = $1.line; $$.op = EOpExclusiveOrAssign; + parseContext.fullIntegerCheck($1.loc, "bitwise-xor assign"); + $$.loc = $1.loc; $$.op = EOpExclusiveOrAssign; } | OR_ASSIGN { - parseContext.fullIntegerCheck($1.line, "bitwise-or assign"); - $$.line = $1.line; $$.op = EOpInclusiveOrAssign; + parseContext.fullIntegerCheck($1.loc, "bitwise-or assign"); + $$.loc = $1.loc; $$.op = EOpInclusiveOrAssign; } ; @@ -1076,9 +1078,9 @@ expression $$ = $1; } | expression COMMA assignment_expression { - $$ = parseContext.intermediate.addComma($1, $3, $2.line); + $$ = parseContext.intermediate.addComma($1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.line, ",", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, ",", $1->getCompleteString(), $3->getCompleteString()); $$ = $3; } } @@ -1102,47 +1104,47 @@ declaration $$ = $1.intermAggregate; } | PRECISION precision_qualifier type_specifier SEMICOLON { - parseContext.profileRequires($1.line, ENoProfile, 130, 0, "precision statement"); + parseContext.profileRequires($1.loc, 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, $2.qualifier.precision); + parseContext.setDefaultPrecision($1.loc, $3, $2.qualifier.precision); $$ = 0; } | block_structure SEMICOLON { - parseContext.addBlock($1.line, *$1.typeList); + parseContext.addBlock($1.loc, *$1.typeList); $$ = 0; } | block_structure IDENTIFIER SEMICOLON { - parseContext.addBlock($1.line, *$1.typeList, $2.string); + parseContext.addBlock($1.loc, *$1.typeList, $2.string); $$ = 0; } | block_structure IDENTIFIER array_specifier SEMICOLON { - parseContext.addBlock($1.line, *$1.typeList, $2.string, $3.arraySizes); + parseContext.addBlock($1.loc, *$1.typeList, $2.string, $3.arraySizes); $$ = 0; } | type_qualifier SEMICOLON { - parseContext.updateQualifierDefaults($1.line, $1.qualifier); + parseContext.updateQualifierDefaults($1.loc, $1.qualifier); $$ = 0; } | type_qualifier IDENTIFIER SEMICOLON { - parseContext.addQualifierToExisting($1.line, $1.qualifier, *$2.string); + parseContext.addQualifierToExisting($1.loc, $1.qualifier, *$2.string); $$ = 0; } | type_qualifier IDENTIFIER identifier_list SEMICOLON { $3->push_back($2.string); - parseContext.addQualifierToExisting($1.line, $1.qualifier, *$3); + parseContext.addQualifierToExisting($1.loc, $1.qualifier, *$3); $$ = 0; } ; block_structure - : type_qualifier IDENTIFIER LEFT_BRACE { parseContext.nestedBlockCheck($1.line); } struct_declaration_list RIGHT_BRACE { + : type_qualifier IDENTIFIER LEFT_BRACE { parseContext.nestedBlockCheck($1.loc); } struct_declaration_list RIGHT_BRACE { --parseContext.structNestingLevel; parseContext.blockName = $2.string; parseContext.currentBlockDefaults = $1.qualifier; - $$.line = $1.line; + $$.loc = $1.loc; $$.typeList = $5; } @@ -1161,7 +1163,7 @@ function_prototype : function_declarator RIGHT_PAREN { // ES can't declare prototypes inside functions if (! parseContext.symbolTable.atGlobalLevel()) - parseContext.requireProfile($2.line, static_cast(~EEsProfileMask), "local function declaration"); + parseContext.requireProfile($2.loc, static_cast(~EEsProfileMask), "local function declaration"); // // Multiple declarations of the same function are allowed. @@ -1176,15 +1178,15 @@ function_prototype bool builtIn; TSymbol* symbol = parseContext.symbolTable.find($1->getMangledName(), &builtIn); if (symbol && symbol->getAsFunction() && builtIn) - parseContext.requireProfile($2.line, static_cast(~EEsProfileMask), "redeclaration of built-in function"); + parseContext.requireProfile($2.loc, static_cast(~EEsProfileMask), "redeclaration of built-in function"); TFunction* prevDec = symbol ? symbol->getAsFunction() : 0; if (prevDec) { if (prevDec->getReturnType() != $1->getReturnType()) { - parseContext.error($2.line, "overloaded functions must have the same return type", $1->getReturnType().getCompleteTypeString().c_str(), ""); + parseContext.error($2.loc, "overloaded functions must have the same return type", $1->getReturnType().getCompleteTypeString().c_str(), ""); } for (int i = 0; i < prevDec->getParamCount(); ++i) { 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.error($2.loc, "overloaded functions must have the same parameter qualifiers", (*$1)[i].type->getStorageQualifierString(), ""); } } @@ -1194,10 +1196,10 @@ function_prototype // being redeclared. So, pass back up this declaration, not the one in the symbol table. // $$.function = $1; - $$.line = $2.line; + $$.loc = $2.loc; if (! parseContext.symbolTable.insert(*$$.function)) - parseContext.error($2.line, "illegal redeclaration", $$.function->getName().c_str(), ""); + parseContext.error($2.loc, "illegal redeclaration", $$.function->getName().c_str(), ""); } ; @@ -1229,7 +1231,7 @@ function_header_with_parameters // // This parameter > first is void // - parseContext.error($2.line, "cannot be an argument type except for '(void)'", "void", ""); + parseContext.error($2.loc, "cannot be an argument type except for '(void)'", "void", ""); delete $3.param.type; } else { // Add the parameter @@ -1242,7 +1244,7 @@ function_header_with_parameters function_header : fully_specified_type IDENTIFIER LEFT_PAREN { if ($1.qualifier.storage != EvqGlobal && $1.qualifier.storage != EvqTemporary) { - parseContext.error($2.line, "no qualifiers allowed for function return", + parseContext.error($2.loc, "no qualifiers allowed for function return", getStorageQualifierString($1.qualifier.storage), ""); } @@ -1258,34 +1260,34 @@ parameter_declarator // Type + name : type_specifier IDENTIFIER { if ($1.arraySizes) { - parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type"); - parseContext.profileRequires($1.line, EEsProfile, 300, 0, "arrayed type"); - parseContext.arraySizeRequiredCheck($1.line, $1.arraySizes->front()); + parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); + parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->front()); } if ($1.basicType == EbtVoid) { - parseContext.error($2.line, "illegal use of type 'void'", $2.string->c_str(), ""); + parseContext.error($2.loc, "illegal use of type 'void'", $2.string->c_str(), ""); } - parseContext.reservedErrorCheck($2.line, *$2.string); + parseContext.reservedErrorCheck($2.loc, *$2.string); TParameter param = {$2.string, new TType($1)}; - $$.line = $2.line; + $$.loc = $2.loc; $$.param = param; } | type_specifier IDENTIFIER array_specifier { if ($1.arraySizes) { - parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type"); - parseContext.profileRequires($1.line, EEsProfile, 300, 0, "arrayed type"); - parseContext.arraySizeRequiredCheck($1.line, $1.arraySizes->front()); + parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); + parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->front()); } - parseContext.arrayDimCheck($2.line, $1.arraySizes, $3.arraySizes); + parseContext.arrayDimCheck($2.loc, $1.arraySizes, $3.arraySizes); - parseContext.arraySizeRequiredCheck($3.line, $3.arraySizes->front()); - parseContext.reservedErrorCheck($2.line, *$2.string); + parseContext.arraySizeRequiredCheck($3.loc, $3.arraySizes->front()); + parseContext.reservedErrorCheck($2.loc, *$2.string); $1.arraySizes = $3.arraySizes; TParameter param = { $2.string, new TType($1)}; - $$.line = $2.line; + $$.loc = $2.loc; $$.param = param; } ; @@ -1299,14 +1301,14 @@ parameter_declaration if ($1.qualifier.precision != EpqNone) $$.param.type->getQualifier().precision = $1.qualifier.precision; - parseContext.parameterSamplerCheck($2.line, $1.qualifier.storage, *$$.param.type); - parseContext.paramCheck($1.line, $1.qualifier.storage, $$.param.type); + parseContext.parameterSamplerCheck($2.loc, $1.qualifier.storage, *$$.param.type); + parseContext.paramCheck($1.loc, $1.qualifier.storage, $$.param.type); } | parameter_declarator { $$ = $1; - parseContext.parameterSamplerCheck($1.line, EvqIn, *$1.param.type); - parseContext.paramCheck($1.line, EvqTemporary, $$.param.type); + parseContext.parameterSamplerCheck($1.loc, EvqIn, *$1.param.type); + parseContext.paramCheck($1.loc, EvqTemporary, $$.param.type); } // // Without name @@ -1316,14 +1318,14 @@ parameter_declaration if ($1.qualifier.precision != EpqNone) $$.param.type->getQualifier().precision = $1.qualifier.precision; - parseContext.parameterSamplerCheck($2.line, $1.qualifier.storage, *$$.param.type); - parseContext.paramCheck($1.line, $1.qualifier.storage, $$.param.type); + parseContext.parameterSamplerCheck($2.loc, $1.qualifier.storage, *$$.param.type); + parseContext.paramCheck($1.loc, $1.qualifier.storage, $$.param.type); } | parameter_type_specifier { $$ = $1; - parseContext.parameterSamplerCheck($1.line, EvqIn, *$1.param.type); - parseContext.paramCheck($1.line, EvqTemporary, $$.param.type); + parseContext.parameterSamplerCheck($1.loc, EvqIn, *$1.param.type); + parseContext.paramCheck($1.loc, EvqTemporary, $$.param.type); } ; @@ -1340,42 +1342,42 @@ init_declarator_list } | init_declarator_list COMMA IDENTIFIER { $$ = $1; - parseContext.nonInitConstCheck($3.line, *$3.string, $$.type); - parseContext.nonInitCheck($3.line, *$3.string, $$.type); + parseContext.nonInitConstCheck($3.loc, *$3.string, $$.type); + parseContext.nonInitCheck($3.loc, *$3.string, $$.type); } | init_declarator_list COMMA IDENTIFIER array_specifier { - parseContext.nonInitConstCheck($3.line, *$3.string, $1.type); + parseContext.nonInitConstCheck($3.loc, *$3.string, $1.type); if (parseContext.profile == EEsProfile) - parseContext.arraySizeRequiredCheck($4.line, $4.arraySizes->front()); - parseContext.arrayDimCheck($3.line, $1.type.arraySizes, $4.arraySizes); + parseContext.arraySizeRequiredCheck($4.loc, $4.arraySizes->front()); + parseContext.arrayDimCheck($3.loc, $1.type.arraySizes, $4.arraySizes); $$ = $1; - if (! parseContext.arrayQualifierError($4.line, $1.type)) { + if (! parseContext.arrayQualifierError($4.loc, $1.type)) { $1.type.arraySizes = $4.arraySizes; TVariable* variable; - parseContext.arrayCheck($4.line, *$3.string, $1.type, variable); + parseContext.arrayCheck($4.loc, *$3.string, $1.type, variable); } } | init_declarator_list COMMA IDENTIFIER array_specifier EQUAL initializer { $$ = $1; TVariable* variable = 0; - if (! parseContext.arrayQualifierError($4.line, $1.type)) { + if (! parseContext.arrayQualifierError($4.loc, $1.type)) { $1.type.arraySizes = $4.arraySizes; - parseContext.arrayCheck($4.line, *$3.string, $1.type, variable); + parseContext.arrayCheck($4.loc, *$3.string, $1.type, variable); } - parseContext.arrayDimCheck($3.line, $1.type.arraySizes, $4.arraySizes); + parseContext.arrayDimCheck($3.loc, $1.type.arraySizes, $4.arraySizes); - parseContext.profileRequires($5.line, ENoProfile, 120, "GL_3DL_array_objects", "initializer"); + parseContext.profileRequires($5.loc, ENoProfile, 120, "GL_3DL_array_objects", "initializer"); TIntermNode* intermNode; - if (! parseContext.executeInitializerError($3.line, *$3.string, $1.type, $6, intermNode, variable)) { + if (! parseContext.executeInitializerError($3.loc, *$3.string, $1.type, $6, intermNode, variable)) { // // build the intermediate representation // if (intermNode) - $$.intermAggregate = parseContext.intermediate.growAggregate($1.intermNode, intermNode, $5.line); + $$.intermAggregate = parseContext.intermediate.growAggregate($1.intermNode, intermNode, $5.loc); else $$.intermAggregate = $1.intermAggregate; } else @@ -1385,12 +1387,12 @@ init_declarator_list $$ = $1; TIntermNode* intermNode; - if (!parseContext.executeInitializerError($3.line, *$3.string, $1.type, $5, intermNode)) { + if (!parseContext.executeInitializerError($3.loc, *$3.string, $1.type, $5, intermNode)) { // // build the intermediate representation // if (intermNode) - $$.intermAggregate = parseContext.intermediate.growAggregate($1.intermNode, intermNode, $4.line); + $$.intermAggregate = parseContext.intermediate.growAggregate($1.intermNode, intermNode, $4.loc); else $$.intermAggregate = $1.intermAggregate; } else @@ -1402,54 +1404,54 @@ single_declaration : fully_specified_type { $$.type = $1; $$.intermAggregate = 0; - parseContext.updateTypedDefaults($1.line, $$.type.qualifier, 0); + parseContext.updateTypedDefaults($1.loc, $$.type.qualifier, 0); } | fully_specified_type IDENTIFIER { $$.intermAggregate = 0; $$.type = $1; - parseContext.nonInitConstCheck($2.line, *$2.string, $$.type); - parseContext.nonInitCheck($2.line, *$2.string, $$.type); + parseContext.nonInitConstCheck($2.loc, *$2.string, $$.type); + parseContext.nonInitCheck($2.loc, *$2.string, $$.type); - parseContext.updateTypedDefaults($2.line, $$.type.qualifier, $2.string); + parseContext.updateTypedDefaults($2.loc, $$.type.qualifier, $2.string); } | fully_specified_type IDENTIFIER array_specifier { $$.intermAggregate = 0; - parseContext.nonInitConstCheck($2.line, *$2.string, $1); + parseContext.nonInitConstCheck($2.loc, *$2.string, $1); if (parseContext.profile == EEsProfile) - parseContext.arraySizeRequiredCheck($3.line, $3.arraySizes->front()); - parseContext.arrayDimCheck($2.line, $1.arraySizes, $3.arraySizes); + parseContext.arraySizeRequiredCheck($3.loc, $3.arraySizes->front()); + parseContext.arrayDimCheck($2.loc, $1.arraySizes, $3.arraySizes); $$.type = $1; - if (! parseContext.arrayQualifierError($3.line, $1)) { + if (! parseContext.arrayQualifierError($3.loc, $1)) { $1.arraySizes = $3.arraySizes; TVariable* variable; - parseContext.arrayCheck($3.line, *$2.string, $1, variable); + parseContext.arrayCheck($3.loc, *$2.string, $1, variable); } - parseContext.updateTypedDefaults($2.line, $$.type.qualifier, $2.string); + parseContext.updateTypedDefaults($2.loc, $$.type.qualifier, $2.string); } | fully_specified_type IDENTIFIER array_specifier EQUAL initializer { - parseContext.arrayDimCheck($3.line, $1.arraySizes, $3.arraySizes); + parseContext.arrayDimCheck($3.loc, $1.arraySizes, $3.arraySizes); $$.intermAggregate = 0; $$.type = $1; TVariable* variable = 0; - if (! parseContext.arrayQualifierError($3.line, $1)) { + if (! parseContext.arrayQualifierError($3.loc, $1)) { $1.arraySizes = $3.arraySizes; - parseContext.arrayCheck($3.line, *$2.string, $1, variable); + parseContext.arrayCheck($3.loc, *$2.string, $1, variable); } - parseContext.profileRequires($4.line, ENoProfile, 120, "GL_3DL_array_objects", "initializer"); + parseContext.profileRequires($4.loc, ENoProfile, 120, "GL_3DL_array_objects", "initializer"); TIntermNode* intermNode; - if (!parseContext.executeInitializerError($2.line, *$2.string, $1, $5, intermNode, variable)) { + if (!parseContext.executeInitializerError($2.loc, *$2.string, $1, $5, intermNode, variable)) { // // Build intermediate representation // if (intermNode) - $$.intermAggregate = parseContext.intermediate.makeAggregate(intermNode, $4.line); + $$.intermAggregate = parseContext.intermediate.makeAggregate(intermNode, $4.loc); else $$.intermAggregate = 0; } else @@ -1459,12 +1461,12 @@ single_declaration $$.type = $1; TIntermNode* intermNode; - if (!parseContext.executeInitializerError($2.line, *$2.string, $1, $4, intermNode)) { + if (!parseContext.executeInitializerError($2.loc, *$2.string, $1, $4, intermNode)) { // // Build intermediate representation // if (intermNode) - $$.intermAggregate = parseContext.intermediate.makeAggregate(intermNode, $3.line); + $$.intermAggregate = parseContext.intermediate.makeAggregate(intermNode, $3.loc); else $$.intermAggregate = 0; } else @@ -1478,29 +1480,29 @@ fully_specified_type $$ = $1; if ($1.arraySizes) { - parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type"); - parseContext.profileRequires($1.line, EEsProfile, 300, 0, "arrayed type"); + parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); if (parseContext.profile == EEsProfile) - parseContext.arraySizeRequiredCheck($1.line, $1.arraySizes->front()); + parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->front()); } - parseContext.precisionQualifierCheck($$.line, $$); + parseContext.precisionQualifierCheck($$.loc, $$); } | type_qualifier type_specifier { - parseContext.globalQualifierFix($1.line, $1.qualifier, $2); + parseContext.globalQualifierFix($1.loc, $1.qualifier, $2); if ($2.arraySizes) { - parseContext.profileRequires($2.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type"); - parseContext.profileRequires($2.line, EEsProfile, 300, 0, "arrayed type"); + parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type"); + parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type"); if (parseContext.profile == EEsProfile) - parseContext.arraySizeRequiredCheck($2.line, $2.arraySizes->front()); + parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->front()); } - if ($2.arraySizes && parseContext.arrayQualifierError($2.line, $1)) + if ($2.arraySizes && parseContext.arrayQualifierError($2.loc, $1)) $2.arraySizes = 0; - parseContext.mergeQualifiers($2.line, $2.qualifier, $1.qualifier, true); - parseContext.precisionQualifierCheck($2.line, $2); + parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true); + parseContext.precisionQualifierCheck($2.loc, $2); $$ = $2; @@ -1513,32 +1515,32 @@ fully_specified_type invariant_qualifier : INVARIANT { - parseContext.profileRequires($$.line, ENoProfile, 120, 0, "invariant"); - $$.init($1.line); + parseContext.profileRequires($$.loc, ENoProfile, 120, 0, "invariant"); + $$.init($1.loc); $$.qualifier.invariant = true; } ; interpolation_qualifier : SMOOTH { - parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "smooth"); - parseContext.profileRequires($1.line, ENoProfile, 130, 0, "smooth"); - parseContext.profileRequires($1.line, EEsProfile, 300, 0, "smooth"); - $$.init($1.line); + parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "smooth"); + parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "smooth"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "smooth"); + $$.init($1.loc); $$.qualifier.smooth = true; } | FLAT { - parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "flat"); - parseContext.profileRequires($1.line, ENoProfile, 130, 0, "flat"); - parseContext.profileRequires($1.line, EEsProfile, 300, 0, "flat"); - $$.init($1.line); + parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "flat"); + parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "flat"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "flat"); + $$.init($1.loc); $$.qualifier.flat = true; } | NOPERSPECTIVE { - parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "noperspective"); - parseContext.requireProfile($1.line, static_cast(~EEsProfileMask), "noperspective"); - parseContext.profileRequires($1.line, ENoProfile, 130, 0, "noperspective"); - $$.init($1.line); + parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "noperspective"); + parseContext.requireProfile($1.loc, static_cast(~EEsProfileMask), "noperspective"); + parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "noperspective"); + $$.init($1.loc); $$.qualifier.nopersp = true; } ; @@ -1555,28 +1557,28 @@ layout_qualifier_id_list } | layout_qualifier_id_list COMMA layout_qualifier_id { $$ = $1; - parseContext.mergeLayoutQualifiers($2.line, $$.qualifier, $3.qualifier); + parseContext.mergeLayoutQualifiers($2.loc, $$.qualifier, $3.qualifier); } layout_qualifier_id : IDENTIFIER { - $$.init($1.line); - parseContext.setLayoutQualifier($1.line, $$, *$1.string); + $$.init($1.loc); + parseContext.setLayoutQualifier($1.loc, $$, *$1.string); } | IDENTIFIER EQUAL INTCONSTANT { - $$.init($1.line); - parseContext.setLayoutQualifier($1.line, $$, *$1.string, $3.i); + $$.init($1.loc); + parseContext.setLayoutQualifier($1.loc, $$, *$1.string, $3.i); } | SHARED { // because "shared" is both an identifier and a keyword - $$.init($1.line); + $$.init($1.loc); TString strShared("shared"); - parseContext.setLayoutQualifier($1.line, $$, strShared); + parseContext.setLayoutQualifier($1.loc, $$, strShared); } ; precise_qualifier : PRECISE { - $$.init($1.line); + $$.init($1.loc); } ; @@ -1589,7 +1591,7 @@ type_qualifier if ($$.basicType == EbtVoid) $$.basicType = $2.basicType; - parseContext.mergeQualifiers($$.line, $$.qualifier, $2.qualifier, false); + parseContext.mergeQualifiers($$.loc, $$.qualifier, $2.qualifier, false); } ; @@ -1619,112 +1621,112 @@ single_type_qualifier storage_qualifier : CONST { - $$.init($1.line); + $$.init($1.loc); $$.qualifier.storage = EvqConst; } | ATTRIBUTE { - parseContext.requireStage($1.line, EShLangVertexMask, "attribute"); - parseContext.checkDeprecated($1.line, ECoreProfile, 130, "attribute"); - parseContext.checkDeprecated($1.line, ENoProfile, 130, "attribute"); - parseContext.requireNotRemoved($1.line, ECoreProfile, 420, "attribute"); - parseContext.requireNotRemoved($1.line, EEsProfile, 300, "attribute"); + parseContext.requireStage($1.loc, EShLangVertexMask, "attribute"); + parseContext.checkDeprecated($1.loc, ECoreProfile, 130, "attribute"); + parseContext.checkDeprecated($1.loc, ENoProfile, 130, "attribute"); + parseContext.requireNotRemoved($1.loc, ECoreProfile, 420, "attribute"); + parseContext.requireNotRemoved($1.loc, EEsProfile, 300, "attribute"); - parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "attribute"); + parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "attribute"); - $$.init($1.line); + $$.init($1.loc); $$.qualifier.storage = EvqVaryingIn; } | VARYING { - parseContext.checkDeprecated($1.line, ENoProfile, 130, "varying"); - parseContext.checkDeprecated($1.line, ECoreProfile, 130, "varying"); - parseContext.requireNotRemoved($1.line, ECoreProfile, 420, "varying"); - parseContext.requireNotRemoved($1.line, EEsProfile, 300, "varying"); + parseContext.checkDeprecated($1.loc, ENoProfile, 130, "varying"); + parseContext.checkDeprecated($1.loc, ECoreProfile, 130, "varying"); + parseContext.requireNotRemoved($1.loc, ECoreProfile, 420, "varying"); + parseContext.requireNotRemoved($1.loc, EEsProfile, 300, "varying"); - parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "varying"); + parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "varying"); - $$.init($1.line); + $$.init($1.loc); if (parseContext.language == EShLangVertex) $$.qualifier.storage = EvqVaryingOut; else $$.qualifier.storage = EvqVaryingIn; } | INOUT { - parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "out"); - $$.init($1.line); + parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "out"); + $$.init($1.loc); $$.qualifier.storage = EvqInOut; } | IN { - parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "in"); - $$.init($1.line); + parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "in"); + $$.init($1.loc); $$.qualifier.storage = EvqIn; } | OUT { - parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "out"); - $$.init($1.line); + parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "out"); + $$.init($1.loc); $$.qualifier.storage = EvqOut; } | CENTROID { - parseContext.profileRequires($1.line, ENoProfile, 120, 0, "centroid"); - parseContext.profileRequires($1.line, EEsProfile, 300, 0, "centroid"); - parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "centroid"); - $$.init($1.line); + parseContext.profileRequires($1.loc, ENoProfile, 120, 0, "centroid"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "centroid"); + parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "centroid"); + $$.init($1.loc); $$.qualifier.centroid = true; } | PATCH { - parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "patch"); - $$.init($1.line); + parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "patch"); + $$.init($1.loc); $$.qualifier.patch = true; } | SAMPLE { - parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "sample"); - $$.init($1.line); + parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "sample"); + $$.init($1.loc); $$.qualifier.sample = true; } | UNIFORM { - parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "uniform"); - $$.init($1.line); + parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "uniform"); + $$.init($1.loc); $$.qualifier.storage = EvqUniform; } | BUFFER { - parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "buffer"); - $$.init($1.line); + parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "buffer"); + $$.init($1.loc); $$.qualifier.storage = EvqUniform; // TODO: 4.0 functionality: implement BUFFER } | SHARED { - parseContext.requireProfile($1.line, static_cast(~EEsProfileMask), "shared"); - parseContext.profileRequires($1.line, ECoreProfile, 430, 0, "shared"); - parseContext.requireStage($1.line, EShLangComputeMask, "shared"); - $$.init($1.line); + parseContext.requireProfile($1.loc, static_cast(~EEsProfileMask), "shared"); + parseContext.profileRequires($1.loc, ECoreProfile, 430, 0, "shared"); + parseContext.requireStage($1.loc, EShLangComputeMask, "shared"); + $$.init($1.loc); $$.qualifier.shared = true; } | COHERENT { - $$.init($1.line); + $$.init($1.loc); $$.qualifier.coherent = true; } | VOLATILE { - $$.init($1.line); + $$.init($1.loc); $$.qualifier.volatil = true; } | RESTRICT { - $$.init($1.line); + $$.init($1.loc); $$.qualifier.restrict = true; } | READONLY { - $$.init($1.line); + $$.init($1.loc); $$.qualifier.readonly = true; } | WRITEONLY { - $$.init($1.line); + $$.init($1.loc); $$.qualifier.writeonly = true; } | SUBROUTINE { - parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "subroutine"); - $$.init($1.line); + parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "subroutine"); + $$.init($1.loc); $$.qualifier.storage = EvqUniform; } | SUBROUTINE LEFT_PAREN type_name_list RIGHT_PAREN { - parseContext.globalCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "subroutine"); - $$.init($1.line); + parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "subroutine"); + $$.init($1.loc); $$.qualifier.storage = EvqUniform; // TODO: 4.0 semantics: subroutines // 1) make sure each identifier is a type declared earlier with SUBROUTINE @@ -1746,7 +1748,7 @@ type_specifier $$.qualifier.precision = parseContext.getDefaultPrecision($$); } | type_specifier_nonarray array_specifier { - parseContext.arrayDimCheck($2.line, $2.arraySizes, 0); + parseContext.arrayDimCheck($2.loc, $2.arraySizes, 0); $$ = $1; $$.qualifier.precision = parseContext.getDefaultPrecision($$); $$.arraySizes = $2.arraySizes; @@ -1755,16 +1757,16 @@ type_specifier array_specifier : LEFT_BRACKET RIGHT_BRACKET { - $$.line = $1.line; + $$.loc = $1.loc; $$.arraySizes = NewPoolTArraySizes(); $$.arraySizes->push_back(0); } | LEFT_BRACKET constant_expression RIGHT_BRACKET { - $$.line = $1.line; + $$.loc = $1.loc; $$.arraySizes = NewPoolTArraySizes(); int size; - parseContext.arraySizeCheck($2->getLine(), $2, size); + parseContext.arraySizeCheck($2->getLoc(), $2, size); $$.arraySizes->push_back(size); } | array_specifier LEFT_BRACKET RIGHT_BRACKET { @@ -1775,626 +1777,626 @@ array_specifier $$ = $1; int size; - parseContext.arraySizeCheck($3->getLine(), $3, size); + parseContext.arraySizeCheck($3->getLoc(), $3, size); $$.arraySizes->push_back(size); } ; type_specifier_nonarray : VOID { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtVoid; } | FLOAT { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtFloat; } | DOUBLE { - parseContext.doubleCheck($1.line, "double"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + parseContext.doubleCheck($1.loc, "double"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; } | INT { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtInt; } | UINT { - parseContext.fullIntegerCheck($1.line, "unsigned integer"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + parseContext.fullIntegerCheck($1.loc, "unsigned integer"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtUint; } | BOOL { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtBool; } | VEC2 { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtFloat; $$.setVector(2); } | VEC3 { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtFloat; $$.setVector(3); } | VEC4 { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtFloat; $$.setVector(4); } | DVEC2 { - parseContext.doubleCheck($1.line, "double vector"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + parseContext.doubleCheck($1.loc, "double vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setVector(2); } | DVEC3 { - parseContext.doubleCheck($1.line, "double vector"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + parseContext.doubleCheck($1.loc, "double vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setVector(3); } | DVEC4 { - parseContext.doubleCheck($1.line, "double vector"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + parseContext.doubleCheck($1.loc, "double vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setVector(4); } | BVEC2 { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtBool; $$.setVector(2); } | BVEC3 { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtBool; $$.setVector(3); } | BVEC4 { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtBool; $$.setVector(4); } | IVEC2 { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtInt; $$.setVector(2); } | IVEC3 { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtInt; $$.setVector(3); } | IVEC4 { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtInt; $$.setVector(4); } | UVEC2 { - parseContext.fullIntegerCheck($1.line, "unsigned integer vector"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + parseContext.fullIntegerCheck($1.loc, "unsigned integer vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtUint; $$.setVector(2); } | UVEC3 { - parseContext.fullIntegerCheck($1.line, "unsigned integer vector"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + parseContext.fullIntegerCheck($1.loc, "unsigned integer vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtUint; $$.setVector(3); } | UVEC4 { - parseContext.fullIntegerCheck($1.line, "unsigned integer vector"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + parseContext.fullIntegerCheck($1.loc, "unsigned integer vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtUint; $$.setVector(4); } | MAT2 { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtFloat; $$.setMatrix(2, 2); } | MAT3 { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtFloat; $$.setMatrix(3, 3); } | MAT4 { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtFloat; $$.setMatrix(4, 4); } | MAT2X2 { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtFloat; $$.setMatrix(2, 2); } | MAT2X3 { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtFloat; $$.setMatrix(2, 3); } | MAT2X4 { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtFloat; $$.setMatrix(2, 4); } | MAT3X2 { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtFloat; $$.setMatrix(3, 2); } | MAT3X3 { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtFloat; $$.setMatrix(3, 3); } | MAT3X4 { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtFloat; $$.setMatrix(3, 4); } | MAT4X2 { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtFloat; $$.setMatrix(4, 2); } | MAT4X3 { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtFloat; $$.setMatrix(4, 3); } | MAT4X4 { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtFloat; $$.setMatrix(4, 4); } | DMAT2 { - parseContext.doubleCheck($1.line, "double matrix"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(2, 2); } | DMAT3 { - parseContext.doubleCheck($1.line, "double matrix"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(3, 3); } | DMAT4 { - parseContext.doubleCheck($1.line, "double matrix"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(4, 4); } | DMAT2X2 { - parseContext.doubleCheck($1.line, "double matrix"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(2, 2); } | DMAT2X3 { - parseContext.doubleCheck($1.line, "double matrix"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(2, 3); } | DMAT2X4 { - parseContext.doubleCheck($1.line, "double matrix"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(2, 4); } | DMAT3X2 { - parseContext.doubleCheck($1.line, "double matrix"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(3, 2); } | DMAT3X3 { - parseContext.doubleCheck($1.line, "double matrix"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(3, 3); } | DMAT3X4 { - parseContext.doubleCheck($1.line, "double matrix"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(3, 4); } | DMAT4X2 { - parseContext.doubleCheck($1.line, "double matrix"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(4, 2); } | DMAT4X3 { - parseContext.doubleCheck($1.line, "double matrix"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(4, 3); } | DMAT4X4 { - parseContext.doubleCheck($1.line, "double matrix"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(4, 4); } | ATOMIC_UINT { // TODO: 4.2 functionality: add type - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtInt; } | SAMPLER1D { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, Esd1D); } | SAMPLER2D { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, Esd2D); } | SAMPLER3D { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, Esd3D); } | SAMPLERCUBE { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, EsdCube); } | SAMPLER1DSHADOW { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, Esd1D, false, true); } | SAMPLER2DSHADOW { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, Esd2D, false, true); } | SAMPLERCUBESHADOW { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, EsdCube, false, true); } | SAMPLER1DARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, Esd1D, true); } | SAMPLER2DARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, Esd2D, true); } | SAMPLER1DARRAYSHADOW { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, Esd1D, true, true); } | SAMPLER2DARRAYSHADOW { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, Esd2D, true, true); } | SAMPLERCUBEARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, EsdCube, true); } | SAMPLERCUBEARRAYSHADOW { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, EsdCube, true, true); } | ISAMPLER1D { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtInt, Esd1D); } | ISAMPLER2D { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtInt, Esd2D); } | ISAMPLER3D { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtInt, Esd3D); } | ISAMPLERCUBE { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtInt, EsdCube); } | ISAMPLER1DARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtInt, Esd1D, true); } | ISAMPLER2DARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtInt, Esd2D, true); } | ISAMPLERCUBEARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtInt, Esd3D, true); } | USAMPLER1D { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtUint, Esd1D); } | USAMPLER2D { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtUint, Esd2D); } | USAMPLER3D { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtUint, Esd3D); } | USAMPLERCUBE { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtUint, EsdCube); } | USAMPLER1DARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtUint, Esd1D, true); } | USAMPLER2DARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtUint, Esd2D, true); } | USAMPLERCUBEARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtUint, EsdCube, true); } | SAMPLER2DRECT { - parseContext.profileRequires($1.line, ENoProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture"); + parseContext.profileRequires($1.loc, ENoProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, EsdRect); } | SAMPLER2DRECTSHADOW { - parseContext.profileRequires($1.line, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture"); + parseContext.profileRequires($1.loc, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, EsdRect, false, true); } | ISAMPLER2DRECT { - parseContext.profileRequires($1.line, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture"); + parseContext.profileRequires($1.loc, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtInt, EsdRect); } | USAMPLER2DRECT { - parseContext.profileRequires($1.line, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture"); + parseContext.profileRequires($1.loc, ECoreProfile, 140, "GL_ARB_texture_rectangle", "rectangle texture"); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtUint, EsdRect); } | SAMPLERBUFFER { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, EsdBuffer); } | ISAMPLERBUFFER { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtInt, EsdBuffer); } | USAMPLERBUFFER { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtUint, EsdBuffer); } | SAMPLER2DMS { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, Esd2D, false, false, true); } | ISAMPLER2DMS { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtInt, Esd2D, false, false, true); } | USAMPLER2DMS { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtUint, Esd2D, false, false, true); } | SAMPLER2DMSARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, Esd2D, true, false, true); } | ISAMPLER2DMSARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtInt, Esd2D, true, false, true); } | USAMPLER2DMSARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtUint, Esd2D, true, false, true); } | IMAGE1D { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat, Esd1D); } | IIMAGE1D { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtInt, Esd1D); } | UIMAGE1D { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtUint, Esd1D); } | IMAGE2D { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat, Esd2D); } | IIMAGE2D { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtInt, Esd2D); } | UIMAGE2D { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtUint, Esd2D); } | IMAGE3D { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat, Esd3D); } | IIMAGE3D { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtInt, Esd3D); } | UIMAGE3D { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtUint, Esd3D); } | IMAGE2DRECT { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat, EsdRect); } | IIMAGE2DRECT { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtInt, EsdRect); } | UIMAGE2DRECT { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtUint, EsdRect); } | IMAGECUBE { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat, EsdCube); } | IIMAGECUBE { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtInt, EsdCube); } | UIMAGECUBE { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtUint, EsdCube); } | IMAGEBUFFER { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat, EsdBuffer); } | IIMAGEBUFFER { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtInt, EsdBuffer); } | UIMAGEBUFFER { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtUint, EsdBuffer); } | IMAGE1DARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat, Esd1D, true); } | IIMAGE1DARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtInt, Esd1D, true); } | UIMAGE1DARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtUint, Esd1D, true); } | IMAGE2DARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat, Esd2D, true); } | IIMAGE2DARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtInt, Esd2D, true); } | UIMAGE2DARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtUint, Esd2D, true); } | IMAGECUBEARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat, EsdCube, true); } | IIMAGECUBEARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtInt, EsdCube, true); } | UIMAGECUBEARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtUint, EsdCube, true); } | IMAGE2DMS { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat, Esd2D, false, false, true); } | IIMAGE2DMS { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtInt, Esd2D, false, false, true); } | UIMAGE2DMS { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtUint, Esd2D, false, false, true); } | IMAGE2DMSARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat, Esd2D, true, false, true); } | IIMAGE2DMSARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtInt, Esd2D, true, false, true); } | UIMAGE2DMSARRAY { - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtUint, Esd2D, true, false, true); } @@ -2409,49 +2411,49 @@ type_specifier_nonarray // if (TVariable* variable = ($1.symbol)->getAsVariable()) { const TType& structure = variable->getType(); - $$.init($1.line, parseContext.symbolTable.atGlobalLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtStruct; $$.userDef = &structure; } else - parseContext.error($1.line, "expected type name", $1.string->c_str(), ""); + parseContext.error($1.loc, "expected type name", $1.string->c_str(), ""); } ; precision_qualifier : HIGH_PRECISION { - parseContext.profileRequires($1.line, ENoProfile, 130, 0, "highp precision qualifier"); - $$.init($1.line); + parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "highp precision qualifier"); + $$.init($1.loc); if (parseContext.profile == EEsProfile) $$.qualifier.precision = EpqHigh; } | MEDIUM_PRECISION { - parseContext.profileRequires($1.line, ENoProfile, 130, 0, "mediump precision qualifier"); - $$.init($1.line); + parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "mediump precision qualifier"); + $$.init($1.loc); if (parseContext.profile == EEsProfile) $$.qualifier.precision = EpqMedium; } | LOW_PRECISION { - parseContext.profileRequires($1.line, ENoProfile, 130, 0, "lowp precision qualifier"); - $$.init($1.line); + parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "lowp precision qualifier"); + $$.init($1.loc); if (parseContext.profile == EEsProfile) $$.qualifier.precision = EpqLow; } ; struct_specifier - : STRUCT IDENTIFIER LEFT_BRACE { parseContext.nestedStructCheck($1.line); } struct_declaration_list RIGHT_BRACE { + : STRUCT IDENTIFIER LEFT_BRACE { parseContext.nestedStructCheck($1.loc); } struct_declaration_list RIGHT_BRACE { TType* structure = new TType($5, *$2.string); TVariable* userTypeDef = new TVariable($2.string, *structure, true); if (! parseContext.symbolTable.insert(*userTypeDef)) - parseContext.error($2.line, "redefinition", $2.string->c_str(), "struct"); - $$.init($1.line); + parseContext.error($2.loc, "redefinition", $2.string->c_str(), "struct"); + $$.init($1.loc); $$.basicType = EbtStruct; $$.userDef = structure; --parseContext.structNestingLevel; } - | STRUCT LEFT_BRACE { parseContext.nestedStructCheck($1.line); } struct_declaration_list RIGHT_BRACE { + | STRUCT LEFT_BRACE { parseContext.nestedStructCheck($1.loc); } struct_declaration_list RIGHT_BRACE { TType* structure = new TType($4, TString("")); - $$.init($1.line); + $$.init($1.loc); $$.basicType = EbtStruct; $$.userDef = structure; --parseContext.structNestingLevel; @@ -2467,7 +2469,7 @@ struct_declaration_list for (unsigned int i = 0; i < $2->size(); ++i) { for (unsigned int j = 0; j < $$->size(); ++j) { if ((*$$)[j].type->getFieldName() == (*$2)[i].type->getFieldName()) - parseContext.error((*$2)[i].line, "duplicate member name:", "", (*$2)[i].type->getFieldName().c_str()); + parseContext.error((*$2)[i].loc, "duplicate member name:", "", (*$2)[i].type->getFieldName().c_str()); } $$->push_back((*$2)[i]); } @@ -2477,38 +2479,38 @@ struct_declaration_list struct_declaration : type_specifier struct_declarator_list SEMICOLON { if ($1.arraySizes) { - parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type"); - parseContext.profileRequires($1.line, EEsProfile, 300, 0, "arrayed type"); + parseContext.profileRequires($1.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); if (parseContext.profile == EEsProfile) - parseContext.arraySizeRequiredCheck($1.line, $1.arraySizes->front()); + parseContext.arraySizeRequiredCheck($1.loc, $1.arraySizes->front()); } $$ = $2; - parseContext.voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1); - parseContext.precisionQualifierCheck($1.line, $1); + parseContext.voidErrorCheck($1.loc, (*$2)[0].type->getFieldName(), $1); + parseContext.precisionQualifierCheck($1.loc, $1); for (unsigned int i = 0; i < $$->size(); ++i) { - parseContext.arrayDimCheck($1.line, (*$$)[i].type, $1.arraySizes); + parseContext.arrayDimCheck($1.loc, (*$$)[i].type, $1.arraySizes); (*$$)[i].type->mergeType($1); } } | type_qualifier type_specifier struct_declarator_list SEMICOLON { if ($2.arraySizes) { - parseContext.profileRequires($2.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type"); - parseContext.profileRequires($2.line, EEsProfile, 300, 0, "arrayed type"); + parseContext.profileRequires($2.loc, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type"); + parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type"); if (parseContext.profile == EEsProfile) - parseContext.arraySizeRequiredCheck($2.line, $2.arraySizes->front()); + parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->front()); } $$ = $3; - parseContext.voidErrorCheck($2.line, (*$3)[0].type->getFieldName(), $2); - parseContext.mergeQualifiers($2.line, $2.qualifier, $1.qualifier, true); - parseContext.precisionQualifierCheck($2.line, $2); + parseContext.voidErrorCheck($2.loc, (*$3)[0].type->getFieldName(), $2); + parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true); + parseContext.precisionQualifierCheck($2.loc, $2); for (unsigned int i = 0; i < $$->size(); ++i) { - parseContext.arrayDimCheck($1.line, (*$$)[i].type, $2.arraySizes); + parseContext.arrayDimCheck($1.loc, (*$$)[i].type, $2.arraySizes); (*$$)[i].type->mergeType($2); } } @@ -2527,16 +2529,16 @@ struct_declarator_list struct_declarator : IDENTIFIER { $$.type = new TType(EbtVoid); - $$.line = $1.line; + $$.loc = $1.loc; $$.type->setFieldName(*$1.string); } | IDENTIFIER array_specifier { if (parseContext.profile == EEsProfile) - parseContext.arraySizeRequiredCheck($2.line, $2.arraySizes->front()); - parseContext.arrayDimCheck($1.line, $2.arraySizes, 0); + parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->front()); + parseContext.arrayDimCheck($1.loc, $2.arraySizes, 0); $$.type = new TType(EbtVoid); - $$.line = $1.line; + $$.loc = $1.loc; $$.type->setFieldName(*$1.string); $$.type->setArraySizes($2.arraySizes); } @@ -2615,7 +2617,7 @@ compound_statement_no_new_scope statement_list : statement { - $$ = parseContext.intermediate.makeAggregate($1, 0); + $$ = parseContext.intermediate.makeAggregate($1); if ($1 && $1->getAsBranchNode() && ($1->getAsBranchNode()->getFlowOp() == EOpCase || $1->getAsBranchNode()->getFlowOp() == EOpDefault)) { parseContext.wrapupSwitchSubsequence(0, $1); @@ -2628,7 +2630,7 @@ statement_list parseContext.wrapupSwitchSubsequence($1, $2); $$ = 0; // start a fresh subsequence for what's after this case } else - $$ = parseContext.intermediate.growAggregate($1, $2, 0); + $$ = parseContext.intermediate.growAggregate($1, $2); } ; @@ -2639,8 +2641,8 @@ expression_statement selection_statement : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement { - parseContext.boolCheck($1.line, $3); - $$ = parseContext.intermediate.addSelection($3, $5, $1.line); + parseContext.boolCheck($1.loc, $3); + $$ = parseContext.intermediate.addSelection($3, $5, $1.loc); } ; @@ -2659,13 +2661,13 @@ condition // In 1996 c++ draft, conditions can include single declarations : expression { $$ = $1; - parseContext.boolCheck($1->getLine(), $1); + parseContext.boolCheck($1->getLoc(), $1); } | fully_specified_type IDENTIFIER EQUAL initializer { TIntermNode* intermNode; - parseContext.boolCheck($2.line, $1); + parseContext.boolCheck($2.loc, $1); - if (parseContext.executeInitializerError($2.line, *$2.string, $1, $4, intermNode)) + if (parseContext.executeInitializerError($2.loc, *$2.string, $1, $4, intermNode)) $$ = 0; else $$ = $4; @@ -2678,7 +2680,7 @@ switch_statement parseContext.switchSequenceStack.push_back(new TIntermSequence); } LEFT_BRACE switch_statement_list RIGHT_BRACE { - $$ = parseContext.addSwitch($1.line, $3, $7); + $$ = parseContext.addSwitch($1.loc, $3, $7); delete parseContext.switchSequenceStack.back(); parseContext.switchSequenceStack.pop_back(); } @@ -2697,10 +2699,10 @@ case_label : CASE expression COLON { parseContext.constCheck($2, "case"); parseContext.integerCheck($2, "case"); - $$ = parseContext.intermediate.addBranch(EOpCase, $2, $1.line); + $$ = parseContext.intermediate.addBranch(EOpCase, $2, $1.loc); } | DEFAULT COLON { - $$ = parseContext.intermediate.addBranch(EOpDefault, $1.line); + $$ = parseContext.intermediate.addBranch(EOpDefault, $1.loc); } ; @@ -2711,13 +2713,13 @@ iteration_statement } 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.loc); --parseContext.loopNestingLevel; } | DO { ++parseContext.loopNestingLevel; } statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON { - parseContext.boolCheck($8.line, $6); + parseContext.boolCheck($8.loc, $6); - $$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.line); + $$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc); --parseContext.loopNestingLevel; } | FOR LEFT_PAREN { @@ -2726,11 +2728,11 @@ iteration_statement } 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.loc); $$ = parseContext.intermediate.growAggregate( $$, - parseContext.intermediate.addLoop($7, reinterpret_cast($5.node1), reinterpret_cast($5.node2), true, $1.line), - $1.line); + parseContext.intermediate.addLoop($7, reinterpret_cast($5.node1), reinterpret_cast($5.node2), true, $1.loc), + $1.loc); $$->getAsAggregate()->setOperator(EOpSequence); --parseContext.loopNestingLevel; } @@ -2768,30 +2770,30 @@ for_rest_statement jump_statement : CONTINUE SEMICOLON { if (parseContext.loopNestingLevel <= 0) - parseContext.error($1.line, "continue statement only allowed in loops", "", ""); - $$ = parseContext.intermediate.addBranch(EOpContinue, $1.line); + parseContext.error($1.loc, "continue statement only allowed in loops", "", ""); + $$ = parseContext.intermediate.addBranch(EOpContinue, $1.loc); } | BREAK SEMICOLON { if (parseContext.loopNestingLevel + parseContext.switchSequenceStack.size() <= 0) - parseContext.error($1.line, "break statement only allowed in switch and loops", "", ""); - $$ = parseContext.intermediate.addBranch(EOpBreak, $1.line); + parseContext.error($1.loc, "break statement only allowed in switch and loops", "", ""); + $$ = parseContext.intermediate.addBranch(EOpBreak, $1.loc); } | RETURN SEMICOLON { - $$ = parseContext.intermediate.addBranch(EOpReturn, $1.line); + $$ = parseContext.intermediate.addBranch(EOpReturn, $1.loc); if (parseContext.currentFunctionType->getBasicType() != EbtVoid) - parseContext.error($1.line, "non-void function must return a value", "return", ""); + parseContext.error($1.loc, "non-void function must return a value", "return", ""); } | RETURN expression SEMICOLON { - $$ = parseContext.intermediate.addBranch(EOpReturn, $2, $1.line); + $$ = parseContext.intermediate.addBranch(EOpReturn, $2, $1.loc); parseContext.functionReturnsValue = true; if (parseContext.currentFunctionType->getBasicType() == EbtVoid) - parseContext.error($1.line, "void function cannot return a value", "return", ""); + parseContext.error($1.loc, "void function cannot return a value", "return", ""); else if (*(parseContext.currentFunctionType) != $2->getType()) - parseContext.error($1.line, "function return is not matching type:", "return", ""); + parseContext.error($1.loc, "function return is not matching type:", "return", ""); } | DISCARD SEMICOLON { - parseContext.requireStage($1.line, EShLangFragmentMask, "discard"); - $$ = parseContext.intermediate.addBranch(EOpKill, $1.line); + parseContext.requireStage($1.loc, EShLangFragmentMask, "discard"); + $$ = parseContext.intermediate.addBranch(EOpKill, $1.loc); } ; @@ -2803,7 +2805,7 @@ translation_unit parseContext.treeRoot = $$; } | translation_unit external_declaration { - $$ = parseContext.intermediate.growAggregate($1, $2, 0); + $$ = parseContext.intermediate.growAggregate($1, $2); parseContext.treeRoot = $$; } ; @@ -2824,7 +2826,7 @@ function_definition TFunction* prevDec = symbol ? symbol->getAsFunction() : 0; if (! prevDec) - parseContext.error($1.line, "can't find function name", function.getName().c_str(), ""); + parseContext.error($1.loc, "can't find function name", function.getName().c_str(), ""); // // Note: 'prevDec' could be 'function' if this is the first time we've seen function @@ -2835,7 +2837,7 @@ function_definition // // Then this function already has a body. // - parseContext.error($1.line, "function already has a body", function.getName().c_str(), ""); + parseContext.error($1.loc, "function already has a body", function.getName().c_str(), ""); } if (prevDec) { prevDec->setDefined(); @@ -2852,9 +2854,9 @@ function_definition // if (function.getName() == "main") { if (function.getParamCount() > 0) - parseContext.error($1.line, "function cannot take any parameter(s)", function.getName().c_str(), ""); + parseContext.error($1.loc, "function cannot take any parameter(s)", function.getName().c_str(), ""); if (function.getReturnType().getBasicType() != EbtVoid) - parseContext.error($1.line, "", function.getReturnType().getCompleteTypeString().c_str(), "main function cannot return a value"); + parseContext.error($1.loc, "", function.getReturnType().getCompleteTypeString().c_str(), "main function cannot return a value"); } // @@ -2879,7 +2881,7 @@ function_definition // Insert the parameters with name in the symbol table. // if (! parseContext.symbolTable.insert(*variable)) { - parseContext.error($1.line, "redefinition", variable->getName().c_str(), ""); + parseContext.error($1.loc, "redefinition", variable->getName().c_str(), ""); delete variable; } // @@ -2894,23 +2896,23 @@ function_definition paramNodes, parseContext.intermediate.addSymbol(variable->getUniqueId(), variable->getName(), - variable->getType(), $1.line), - $1.line); + variable->getType(), $1.loc), + $1.loc); } else { - paramNodes = parseContext.intermediate.growAggregate(paramNodes, parseContext.intermediate.addSymbol(0, "", *param.type, $1.line), $1.line); + paramNodes = parseContext.intermediate.growAggregate(paramNodes, parseContext.intermediate.addSymbol(0, "", *param.type, $1.loc), $1.loc); } } - parseContext.intermediate.setAggregateOperator(paramNodes, EOpParameters, TType(EbtVoid), $1.line); + parseContext.intermediate.setAggregateOperator(paramNodes, EOpParameters, TType(EbtVoid), $1.loc); $1.intermAggregate = paramNodes; parseContext.loopNestingLevel = 0; } compound_statement_no_new_scope { // May be best done as post process phase on intermediate code if (parseContext.currentFunctionType->getBasicType() != EbtVoid && ! parseContext.functionReturnsValue) - parseContext.error($1.line, "function does not return a value:", "", $1.function->getName().c_str()); + parseContext.error($1.loc, "function does not return a value:", "", $1.function->getName().c_str()); parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); - $$ = parseContext.intermediate.growAggregate($1.intermAggregate, $3, 0); - parseContext.intermediate.setAggregateOperator($$, EOpFunction, $1.function->getReturnType(), $1.line); + $$ = parseContext.intermediate.growAggregate($1.intermAggregate, $3); + parseContext.intermediate.setAggregateOperator($$, EOpFunction, $1.function->getReturnType(), $1.loc); $$->getAsAggregate()->setName($1.function->getMangledName().c_str()); // store the pragma information for debug and optimize and other vendor specific diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp index bbab55b..e538f6a 100644 --- a/glslang/MachineIndependent/intermOut.cpp +++ b/glslang/MachineIndependent/intermOut.cpp @@ -63,7 +63,11 @@ void OutputTreeText(TInfoSink& infoSink, TIntermNode* node, const int depth) { int i; - infoSink.debug << FormatSourceLoc(node->getLine()); + infoSink.debug << node->getLoc().string << ":"; + if (node->getLoc().line) + infoSink.debug << node->getLoc().line; + else + infoSink.debug << "? "; for (i = 0; i < depth; ++i) infoSink.debug << " "; @@ -445,7 +449,7 @@ void OutputConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it) } break; default: - out.info.message(EPrefixInternalError, "Unknown constant", node->getLine()); + out.info.message(EPrefixInternalError, "Unknown constant", node->getLoc()); break; } } diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index 4332d82..fb7602d 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -62,7 +62,9 @@ public: TIntermTyped* addUnaryMath(TOperator, TIntermNode* child, TSourceLoc); TIntermTyped* addBuiltInFunctionCall(TOperator, bool unary, TIntermNode*, const TType& returnType); bool canImplicitlyPromote(TBasicType from, TBasicType to); + TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right); TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc); + TIntermAggregate* makeAggregate(TIntermNode* node); TIntermAggregate* makeAggregate(TIntermNode* node, TSourceLoc); TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, TSourceLoc); bool areAllChildConst(TIntermAggregate* aggrNode); diff --git a/glslang/MachineIndependent/parseConst.cpp b/glslang/MachineIndependent/parseConst.cpp index 5ddb177..84b5bb0 100644 --- a/glslang/MachineIndependent/parseConst.cpp +++ b/glslang/MachineIndependent/parseConst.cpp @@ -69,7 +69,7 @@ public: void ParseSymbol(TIntermSymbol* node, TIntermTraverser* it) { TConstTraverser* oit = static_cast(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->getLoc()); return; } @@ -84,13 +84,13 @@ bool ParseBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it) const int maxSize = GlslangMaxTypeLength + 50; char buf[maxSize]; snprintf(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->getLoc()); oit->error = true; return false; } - oit->infoSink.info.message(EPrefixInternalError, "Binary Node found in constant constructor", node->getLine()); + oit->infoSink.info.message(EPrefixInternalError, "Binary Node found in constant constructor", node->getLoc()); return false; } @@ -102,7 +102,7 @@ bool ParseUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it) const int maxSize = GlslangMaxTypeLength + 50; char buf[maxSize]; snprintf(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->getLoc()); oit->error = true; return false; @@ -116,7 +116,7 @@ bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverse const int maxSize = GlslangMaxTypeLength + 50; char buf[maxSize]; snprintf(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->getLoc()); oit->error = true; return false; @@ -165,7 +165,7 @@ bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverse bool ParseSelection(bool /* preVisit */, TIntermSelection* node, TIntermTraverser* it) { TConstTraverser* oit = static_cast(it); - oit->infoSink.info.message(EPrefixInternalError, "Selection Node found in constant constructor", node->getLine()); + oit->infoSink.info.message(EPrefixInternalError, "Selection Node found in constant constructor", node->getLoc()); oit->error = true; return false; } @@ -235,7 +235,7 @@ void ParseConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it) bool ParseLoop(bool /* preVisit */, TIntermLoop* node, TIntermTraverser* it) { TConstTraverser* oit = static_cast(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->getLoc()); oit->error = true; return false; @@ -244,7 +244,7 @@ bool ParseLoop(bool /* preVisit */, TIntermLoop* node, TIntermTraverser* it) bool ParseBranch(bool /* previsit*/, TIntermBranch* node, TIntermTraverser* it) { TConstTraverser* oit = static_cast(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->getLoc()); oit->error = true; return false; diff --git a/glslang/MachineIndependent/preprocessor/atom.c b/glslang/MachineIndependent/preprocessor/atom.c index 2f43c48..e473e78 100644 --- a/glslang/MachineIndependent/preprocessor/atom.c +++ b/glslang/MachineIndependent/preprocessor/atom.c @@ -107,29 +107,20 @@ static const struct { { CPP_ADD_ASSIGN, "+=" }, { CPP_DIV_ASSIGN, "/=" }, { CPP_MUL_ASSIGN, "*=" }, - { CPP_RIGHT_BRACKET, ":>" }, { CPP_EQ_OP, "==" }, { CPP_XOR_OP, "^^" }, { CPP_XOR_ASSIGN, "^=" }, - { CPP_FLOATCONSTANT, "" }, { CPP_GE_OP, ">=" }, { CPP_RIGHT_OP, ">>" }, - { CPP_RIGHT_ASSIGN, ">>=" }, - { CPP_IDENTIFIER, "" }, - { CPP_INTCONSTANT, "" }, + { CPP_RIGHT_ASSIGN, ">>="}, { CPP_LE_OP, "<=" }, { CPP_LEFT_OP, "<<" }, - { CPP_LEFT_ASSIGN, "<<=" }, - { CPP_LEFT_BRACKET, "<:" }, - { CPP_LEFT_BRACE, "<%" }, + { CPP_LEFT_ASSIGN, "<<="}, { CPP_DEC_OP, "--" }, - { CPP_RIGHT_BRACE, "%>" }, { CPP_NE_OP, "!=" }, { CPP_OR_OP, "||" }, { CPP_OR_ASSIGN, "|=" }, { CPP_INC_OP, "++" }, - { CPP_STRCONSTANT, "" }, - { CPP_TYPEIDENTIFIER, "" }, }; /////////////////////////////////////////////////////////////////////////////////////////////// @@ -672,7 +663,7 @@ int InitAtomTable(AtomTable *atable, int htsize) // Initialize lower part of atom table to "" atom: AddAtomFixed(atable, "", 0); - for (ii = 0; ii < FIRST_USER_TOKEN_SY; ii++) + for (ii = 0; ii < CPP_FIRST_USER_TOKEN_SY; ii++) atable->amap[ii] = atable->amap[0]; // Add single character tokens to the atom table: @@ -697,7 +688,7 @@ int InitAtomTable(AtomTable *atable, int htsize) // Add error symbol if running in error mode: if (cpp->options.ErrorMode) - AddAtomFixed(atable, "error", ERROR_SY); + AddAtomFixed(atable, "error", CPP_ERROR_SY); AddAtom(atable, "<*** end fixed atoms ***>"); diff --git a/glslang/MachineIndependent/preprocessor/compile.h b/glslang/MachineIndependent/preprocessor/compile.h deleted file mode 100644 index 08a9280..0000000 --- a/glslang/MachineIndependent/preprocessor/compile.h +++ /dev/null @@ -1,132 +0,0 @@ -// -//Copyright (C) 2002-2005 3Dlabs Inc. Ltd. -//All rights reserved. -// -//Redistribution and use in source and binary forms, with or without -//modification, are permitted provided that the following conditions -//are met: -// -// Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// -// Neither the name of 3Dlabs Inc. Ltd. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -//POSSIBILITY OF SUCH DAMAGE. -// -/****************************************************************************\ -Copyright (c) 2002, NVIDIA Corporation. - -NVIDIA Corporation("NVIDIA") supplies this software to you in -consideration of your agreement to the following terms, and your use, -installation, modification or redistribution of this NVIDIA software -constitutes acceptance of these terms. If you do not agree with these -terms, please do not use, install, modify or redistribute this NVIDIA -software. - -In consideration of your agreement to abide by the following terms, and -subject to these terms, NVIDIA grants you a personal, non-exclusive -license, under NVIDIA's copyrights in this original NVIDIA software (the -"NVIDIA Software"), to use, reproduce, modify and redistribute the -NVIDIA Software, with or without modifications, in source and/or binary -forms; provided that if you redistribute the NVIDIA Software, you must -retain the copyright notice of NVIDIA, this notice and the following -text and disclaimers in all such redistributions of the NVIDIA Software. -Neither the name, trademarks, service marks nor logos of NVIDIA -Corporation may be used to endorse or promote products derived from the -NVIDIA Software without specific prior written permission from NVIDIA. -Except as expressly stated in this notice, no other rights or licenses -express or implied, are granted by NVIDIA herein, including but not -limited to any patent rights that may be infringed by your derivative -works or by other works in which the NVIDIA Software may be -incorporated. No hardware is licensed hereunder. - -THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT -WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, -INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR -ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER -PRODUCTS. - -IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, -INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY -OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE -NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, -TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF -NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -\****************************************************************************/ -// -// compile.h -// - -#if !defined(__COMPILE_H) -#define __COMPILE_H 1 - -int InitCPPStruct(void); - -typedef struct Options_Rec{ - const char *profileString; - int ErrorMode; - int Quiet; - - // Debug The Compiler options: - int DumpAtomTable; -} Options; - -struct CPPStruct_Rec { - // Public members - SourceLoc *pLastSourceLoc; // Set at the start of each statement by the tree walkers - Options options; // Compile options and parameters - - // Private members - SourceLoc lastSourceLoc; - - // Scanner data: - - SourceLoc *tokenLoc; // Source location of most recent token seen by the scanner - int mostRecentToken; // Most recent token seen by the scanner - InputSrc *currentInput; - int previous_token; - int notAVersionToken; // used to make sure that #version is the first token seen in the file, if present - - void *pC; // storing the parseContext of the compile object in cpp. - - // Private members: - SourceLoc ltokenLoc; - int ifdepth; //current #if-#else-#endif nesting in the cpp.c file (pre-processor) - int elsedepth[64]; //Keep a track of #if depth..Max allowed is 64. - int elsetracker; //#if-#else and #endif constructs...Counter. - const char *ErrMsg; - int CompileError; //Indicate compile error when #error, #else,#elif mismatch. - - // - // Globals used to communicate between PaParseStrings() and yy_input()and - // also across the files.(gen_glslang.cpp and scanner.c) - // - int PaWhichStr; // which string we're parsing - int* PaStrLen; // array of lengths of the PaArgv strings - int PaArgc; // count of strings in the array - char** PaArgv; // our array of strings to parse - unsigned int tokensBeforeEOF : 1; -}; - -#endif // !defined(__COMPILE_H) diff --git a/glslang/MachineIndependent/preprocessor/cpp.c b/glslang/MachineIndependent/preprocessor/cpp.c index 82da285..d001da7 100644 --- a/glslang/MachineIndependent/preprocessor/cpp.c +++ b/glslang/MachineIndependent/preprocessor/cpp.c @@ -630,7 +630,8 @@ static int CPPerror(yystypepp * yylvalpp) const char *message; while (token != '\n') { - if (token == CPP_FLOATCONSTANT || token == CPP_INTCONSTANT){ + if (token == CPP_INTCONSTANT || token == CPP_UINTCONSTANT || + token == CPP_FLOATCONSTANT || token == CPP_DOUBLECONSTANT) { StoreStr(yylvalpp->symbol_name); }else if(token == CPP_IDENTIFIER || token == CPP_STRCONSTANT){ StoreStr(GetStringOfAtom(atable, yylvalpp->sc_ident)); @@ -681,11 +682,9 @@ static int CPPpragma(yystypepp * yylvalpp) strcpy(allTokens[tokenCount++], SrcStr); break; case CPP_INTCONSTANT: - SrcStr = yylvalpp->symbol_name; - allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1); - strcpy(allTokens[tokenCount++], SrcStr); - break; + case CPP_UINTCONSTANT: case CPP_FLOATCONSTANT: + case CPP_DOUBLECONSTANT: SrcStr = yylvalpp->symbol_name; allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1); strcpy(allTokens[tokenCount++], SrcStr); @@ -715,41 +714,35 @@ static int CPPpragma(yystypepp * yylvalpp) return token; } // CPPpragma +// This is just for error checking: the version and profile are decided before preprocessing starts static int CPPversion(yystypepp * yylvalpp) { - int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); if (cpp->notAVersionToken == 1) ShPpErrorToInfoLog("#version must occur before any other statement in the program"); - if(token=='\n'){ + if (token == '\n'){ DecLineNumber(); ShPpErrorToInfoLog("#version"); IncLineNumber(); + return token; } + if (token != CPP_INTCONSTANT) ShPpErrorToInfoLog("#version"); - yylvalpp->sc_int=atoi(yylvalpp->symbol_name); - - SetVersion(yylvalpp->sc_int); + yylvalpp->sc_int = atoi(yylvalpp->symbol_name); token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); - if (token == '\n') { - SetProfile(ENoProfile); + if (token == '\n') return token; - } else { - if (yylvalpp->sc_ident == coreAtom) - SetProfile(ECoreProfile); - else if (yylvalpp->sc_ident == compatibilityAtom) - SetProfile(ECompatibilityProfile); - else if (yylvalpp->sc_ident == esAtom) - SetProfile(EEsProfile); - else + if (yylvalpp->sc_ident != coreAtom && + yylvalpp->sc_ident != compatibilityAtom && + yylvalpp->sc_ident != esAtom) ShPpErrorToInfoLog("#version profile name"); token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); @@ -1025,7 +1018,7 @@ int MacroExpand(int atom, yystypepp* yylvalpp, int expandUndef) } if (atom == __VERSION__Atom) { - yylvalpp->sc_int = GetVersion(cpp->pC); + yylvalpp->sc_int = GetShaderVersion(cpp->pC); sprintf(yylvalpp->symbol_name, "%d", yylvalpp->sc_int); UngetToken(CPP_INTCONSTANT, yylvalpp); diff --git a/glslang/MachineIndependent/preprocessor/cpp.h b/glslang/MachineIndependent/preprocessor/cpp.h index cdedb62..7fcab55 100644 --- a/glslang/MachineIndependent/preprocessor/cpp.h +++ b/glslang/MachineIndependent/preprocessor/cpp.h @@ -116,8 +116,7 @@ int GetLineNumber(void); // Get the current String Number. int GetStringNumber(void); // Get the current String Number. const char* GetStrfromTStr(void); // Convert TString to String. void SetVersion(int); -void SetProfile(EProfile); -int GetVersion(void*); +int GetShaderVersion(void*); void updateExtensionBehavior(const char* extName, const char* behavior); int FreeCPP(void); diff --git a/glslang/MachineIndependent/preprocessor/cppstruct.c b/glslang/MachineIndependent/preprocessor/cppstruct.c index b1b15fa..b7b6533 100644 --- a/glslang/MachineIndependent/preprocessor/cppstruct.c +++ b/glslang/MachineIndependent/preprocessor/cppstruct.c @@ -86,10 +86,8 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. CPPStruct *cpp = NULL; static int refCount = 0; -int InitPreprocessor(void); int ResetPreprocessor(void); int FreeCPPStruct(void); -int FinalizePreprocessor(void); /* * InitCPPStruct() - Initilaize the CPP structure. diff --git a/glslang/MachineIndependent/preprocessor/parser.h b/glslang/MachineIndependent/preprocessor/parser.h index 98a9afb..5cd32b8 100644 --- a/glslang/MachineIndependent/preprocessor/parser.h +++ b/glslang/MachineIndependent/preprocessor/parser.h @@ -75,20 +75,9 @@ TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \****************************************************************************/ -#ifndef BISON_PARSER_H -# define BISON_PARSER_H +#ifndef PARSER_H +# define PARSER_H -#ifndef yystypepp -typedef struct { - int sc_int; - float sc_fval; - double sc_dval; - int sc_ident; - char symbol_name[MAX_SYMBOL_NAME_LEN+1]; -} yystypepp; - -# define YYSTYPE_IS_TRIVIAL 1 -#endif # define CPP_AND_OP 257 # define CPP_SUB_ASSIGN 259 # define CPP_MOD_ASSIGN 260 @@ -97,7 +86,7 @@ typedef struct { # define CPP_MUL_ASSIGN 263 # define CPP_EQ_OP 264 # define CPP_XOR_OP 265 -# define ERROR_SY 266 +# define CPP_ERROR_SY 266 # define CPP_FLOATCONSTANT 267 # define CPP_GE_OP 268 # define CPP_RIGHT_OP 269 @@ -111,9 +100,6 @@ typedef struct { # define CPP_INC_OP 277 # define CPP_STRCONSTANT 278 # define CPP_TYPEIDENTIFIER 279 - -# define FIRST_USER_TOKEN_SY 289 - # define CPP_RIGHT_ASSIGN 280 # define CPP_LEFT_ASSIGN 281 # define CPP_AND_ASSIGN 282 @@ -123,5 +109,8 @@ typedef struct { # define CPP_RIGHT_BRACKET 286 # define CPP_LEFT_BRACE 287 # define CPP_RIGHT_BRACE 288 +# define CPP_UINTCONSTANT 289 +# define CPP_DOUBLECONSTANT 290 +# define CPP_FIRST_USER_TOKEN_SY 291 -#endif /* not BISON_PARSER_H */ +#endif /* not PARSER_H */ diff --git a/glslang/MachineIndependent/preprocessor/preprocess.h b/glslang/MachineIndependent/preprocessor/preprocess.h index 0af2759..22c8a28 100644 --- a/glslang/MachineIndependent/preprocessor/preprocess.h +++ b/glslang/MachineIndependent/preprocessor/preprocess.h @@ -75,10 +75,84 @@ TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \****************************************************************************/ -#include "slglobals.h" +#ifndef PREPROCESS_H +#define PREPROCESS_H + +typedef struct SourceLoc_Rec { + int file; + int line; +} SourceLoc; + +typedef struct Options_Rec { + const char *profileString; + int ErrorMode; + int Quiet; + + // Debug The Compiler options: + int DumpAtomTable; +} Options; + +#define MAX_TOKEN_LENGTH 1024 + +typedef struct { + int ppToken; + int sc_int; + double sc_dval; + int sc_ident; + char symbol_name[MAX_TOKEN_LENGTH+1]; +} yystypepp; + +typedef struct InputSrc { + struct InputSrc *prev; + int (*scan)(struct InputSrc *, yystypepp *); + int (*getch)(struct InputSrc *, yystypepp *); + void (*ungetch)(struct InputSrc *, int, yystypepp *); + int name; /* atom */ + int line; +} InputSrc; + +typedef struct CPPStruct { + // Public members + SourceLoc *pLastSourceLoc; // Set at the start of each statement by the tree walkers + Options options; // Compile options and parameters + + // Private members + SourceLoc lastSourceLoc; + + // Scanner data: + + SourceLoc *tokenLoc; // Source location of most recent token seen by the scanner + int mostRecentToken; // Most recent token seen by the scanner + InputSrc *currentInput; + int previous_token; + int notAVersionToken; // used to make sure that #version is the first token seen in the file, if present + + void *pC; // storing the parseContext of the compile object in cpp. + + // Private members: + SourceLoc ltokenLoc; + int ifdepth; //current #if-#else-#endif nesting in the cpp.c file (pre-processor) + int elsedepth[64]; //Keep a track of #if depth..Max allowed is 64. + int elsetracker; //#if-#else and #endif constructs...Counter. + const char *ErrMsg; + int CompileError; //Indicate compile error when #error, #else,#elif mismatch. + + // + // Globals used to communicate between parseStrings() and yy_input()and + // also across the files.(gen_glslang.cpp and scanner.c) + // + int PaWhichStr; // which string we're parsing + int* PaStrLen; // array of lengths of the PaArgv strings + int PaArgc; // count of strings in the array + char** PaArgv; // our array of strings to parse + unsigned int tokensBeforeEOF : 1; +} CPPStruct; + extern CPPStruct *cpp; -int InitCPPStruct(void); -int InitScanner(CPPStruct *cpp); -int InitAtomTable(AtomTable *atable, int htsize); + +int InitPreprocessor(void); +int FinalizePreprocessor(void); int ScanFromString(char *s); -char* GetStringOfAtom(AtomTable *atable, int atom); +const char* PpTokenize(yystypepp*); + +#endif diff --git a/glslang/MachineIndependent/preprocessor/scanner.c b/glslang/MachineIndependent/preprocessor/scanner.c index 06cba8d..f117625 100644 --- a/glslang/MachineIndependent/preprocessor/scanner.c +++ b/glslang/MachineIndependent/preprocessor/scanner.c @@ -222,7 +222,7 @@ int ScanFromString(char *s) cpp->currentInput = &in->base; return 1; -} // ScanFromString; +} /////////////////////////////////////////////////////////////////////////////////////////////// @@ -239,6 +239,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp) { int HasDecimal, declen, exp, ExpSign; int str_len; + int isDouble = 0; HasDecimal = 0; declen = 0; @@ -250,7 +251,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp) HasDecimal = 1; ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); while (ch >= '0' && ch <= '9') { - if (len < MAX_SYMBOL_NAME_LEN) { + if (len < MAX_TOKEN_LENGTH) { declen++; if (len > 0 || ch != '0') { str[len] = ch; @@ -267,7 +268,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp) // Exponent: if (ch == 'e' || ch == 'E') { - if (len >= MAX_SYMBOL_NAME_LEN) { + if (len >= MAX_TOKEN_LENGTH) { ShPpErrorToInfoLog("floating-point literal too long"); len = 1,str_len=1; } else { @@ -284,7 +285,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp) } if (ch >= '0' && ch <= '9') { while (ch >= '0' && ch <= '9') { - if (len < MAX_SYMBOL_NAME_LEN) { + if (len < MAX_TOKEN_LENGTH) { exp = exp*10 + ch - '0'; str[len++]=ch; ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); @@ -301,7 +302,6 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp) } if (len == 0) { - yylvalpp->sc_fval = 0.0f; yylvalpp->sc_dval = 0.0; strcpy(str, "0.0"); } else { @@ -311,16 +311,17 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp) cpp->currentInput->ungetch(cpp->currentInput, ch2, yylvalpp); cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); } else { - if (len < MAX_SYMBOL_NAME_LEN) { + if (len < MAX_TOKEN_LENGTH) { str[len++] = ch; str[len++] = ch2; + isDouble = 1; } else { ShPpErrorToInfoLog("floating-point literal too long"); len = 1,str_len=1; } } } else if (ch == 'f' || ch == 'F') { - if (len < MAX_SYMBOL_NAME_LEN) + if (len < MAX_TOKEN_LENGTH) str[len++] = ch; else { ShPpErrorToInfoLog("floating-point literal too long"); @@ -332,12 +333,14 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp) str[len]='\0'; yylvalpp->sc_dval = strtod(str, 0); - yylvalpp->sc_fval = (float)yylvalpp->sc_dval; } // Suffix: strcpy(yylvalpp->symbol_name, str); - return CPP_FLOATCONSTANT; + if (isDouble) + return CPP_DOUBLECONSTANT; + else + return CPP_FLOATCONSTANT; } // lFloatConst /////////////////////////////////////////////////////////////////////////////////////////////// @@ -346,8 +349,7 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp) static int byte_scan(InputSrc *in, yystypepp * yylvalpp) { - char symbol_name[MAX_SYMBOL_NAME_LEN + 1]; - char string_val[MAX_STRING_LEN + 1]; + char tokenText[MAX_TOKEN_LENGTH + 1]; int AlreadyComplained = 0; int len, ch, ii; unsigned ival = 0; @@ -368,7 +370,7 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp) default: return ch; // Single character token case EOF: - return -1; + return EOF; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': @@ -393,30 +395,32 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp) ch = nextch; } else ShPpErrorToInfoLog("can only escape newlines"); - } else if (len < MAX_SYMBOL_NAME_LEN) { - symbol_name[len] = ch; - len++; + } else if (len < MAX_TOKEN_LENGTH) { + tokenText[len++] = ch; ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); } else { - ShPpErrorToInfoLog("name too long"); - break; + if (! AlreadyComplained) { + ShPpErrorToInfoLog("name too long"); + AlreadyComplained = 1; + } + ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); } } while ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || ch == '_' || ch == '\\'); - if (len > MAX_SYMBOL_NAME_LEN) - len = MAX_SYMBOL_NAME_LEN; - symbol_name[len] = '\0'; + + tokenText[len] = '\0'; cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); - yylvalpp->sc_ident = LookUpAddString(atable, symbol_name); + yylvalpp->sc_ident = LookUpAddString(atable, tokenText); + return CPP_IDENTIFIER; - break; case '0': yylvalpp->symbol_name[len++] = ch; ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); if (ch == 'x' || ch == 'X') { + int uint = 0; yylvalpp->symbol_name[len++] = ch; ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); if ((ch >= '0' && ch <= '9') || @@ -425,10 +429,8 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp) { ival = 0; do { - if (len >= MAX_SYMBOL_NAME_LEN) - break; - yylvalpp->symbol_name[len++] = ch; if (ival <= 0x0fffffff) { + yylvalpp->symbol_name[len++] = ch; if (ch >= '0' && ch <= '9') { ii = ch - '0'; } else if (ch >= 'A' && ch <= 'F') { @@ -440,9 +442,10 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp) ival = (ival << 4) | ii; } else { if (! AlreadyComplained) { - ShPpErrorToInfoLog("hexidecimal literal too long"); + ShPpErrorToInfoLog("hexidecimal literal too big"); AlreadyComplained = 1; } + ival = 0xffffffff; } ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); } while ((ch >= '0' && ch <= '9') || @@ -451,38 +454,51 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp) } else { ShPpErrorToInfoLog("bad digit in hexidecimal literal"); } - if (ch == 'u' || ch == 'U') - yylvalpp->symbol_name[len++] = ch; - else + if (ch == 'u' || ch == 'U') { + if (len < MAX_TOKEN_LENGTH) + yylvalpp->symbol_name[len++] = ch; + uint = 1; + } else cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); yylvalpp->symbol_name[len] = '\0'; yylvalpp->sc_int = (int)ival; - return CPP_INTCONSTANT; + if (uint) + return CPP_UINTCONSTANT; + else + return CPP_INTCONSTANT; } else if (ch >= '0' && ch <= '7') { // octal integer constants + int uint = 0; ival = 0; do { - if (len >= MAX_SYMBOL_NAME_LEN) - break; - yylvalpp->symbol_name[len++] = ch; if (ival <= 0x1fffffff) { + yylvalpp->symbol_name[len++] = ch; ii = ch - '0'; ival = (ival << 3) | ii; } else { if (!AlreadyComplained) { - ShPpErrorToInfoLog("octal literal too long"); + ShPpErrorToInfoLog("octal literal too big"); AlreadyComplained = 1; } + ival = 0xffffffff; } ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); } while (ch >= '0' && ch <= '7'); if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E' || ch == 'F' || ch == 'l' || ch == 'L') return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp); + else if (ch == 'u' || ch == 'U') { + if (len < MAX_TOKEN_LENGTH) + yylvalpp->symbol_name[len++] = ch; + uint = 1; + } else + cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); yylvalpp->symbol_name[len] = '\0'; - cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); yylvalpp->sc_int = (int)ival; - return CPP_INTCONSTANT; + if (uint) + return CPP_UINTCONSTANT; + else + return CPP_INTCONSTANT; } else { cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); ch = '0'; @@ -491,25 +507,30 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp) case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': do { - if (len < MAX_SYMBOL_NAME_LEN) { + if (len < MAX_TOKEN_LENGTH) { if (len > 0 || ch != '0') { yylvalpp->symbol_name[len] = ch; len++; } - ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); } else { - ShPpErrorToInfoLog("token too long"); - break; + if (! AlreadyComplained) { + ShPpErrorToInfoLog("integer literal too long"); + AlreadyComplained = 1; + } } + ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); } while (ch >= '0' && ch <= '9'); if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E' || ch == 'F' || ch == 'l' || ch == 'L') { return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp); } else { // Finish handling signed and unsigned integers int numericLen = len; - if (ch == 'u' || ch == 'U') - yylvalpp->symbol_name[len++] = ch; - else + int uint = 0; + if (ch == 'u' || ch == 'U') { + if (len < MAX_TOKEN_LENGTH) + yylvalpp->symbol_name[len++] = ch; + uint = 1; + } else cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); yylvalpp->symbol_name[len] = '\0'; @@ -517,16 +538,18 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp) for (ii = 0; ii < numericLen; ii++) { ch = yylvalpp->symbol_name[ii] - '0'; if ((ival > 429496729) || (ival == 429496729 && ch >= 6)) { - if (! AlreadyComplained) { - ShPpErrorToInfoLog("integral literal too long"); - AlreadyComplained = 1; - } - } - ival = ival * 10 + ch; + ShPpErrorToInfoLog("integral literal too big"); + ival = -1; + break; + } else + ival = ival * 10 + ch; } yylvalpp->sc_int = (int)ival; - return CPP_INTCONSTANT; + if (uint) + return CPP_UINTCONSTANT; + else + return CPP_INTCONSTANT; } break; case '-': @@ -737,39 +760,39 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp) break; } } - if (len < MAX_STRING_LEN) { - string_val[len] = ch; + if (len < MAX_TOKEN_LENGTH) { + tokenText[len] = ch; len++; ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); } else break; }; - string_val[len] = '\0'; + tokenText[len] = '\0'; if (ch == '"') { - yylvalpp->sc_ident = LookUpAddString(atable, string_val); + yylvalpp->sc_ident = LookUpAddString(atable, tokenText); return CPP_STRCONSTANT; } else { ShPpErrorToInfoLog("end of line in string"); - return ERROR_SY; + return CPP_ERROR_SY; } } } } // byte_scan -int yylex_CPP(char* buf, int maxSize) +const char* PpTokenize(yystypepp* yylvalpp) { - yystypepp yylvalpp; int token = '\n'; for(;;) { char* tokenString = 0; - token = cpp->currentInput->scan(cpp->currentInput, &yylvalpp); - if(check_EOF(token)) + token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); + yylvalpp->ppToken = token; + if (check_EOF(token)) return 0; if (token == '#') { if (cpp->previous_token == '\n'|| cpp->previous_token == 0) { - token = readCPPline(&yylvalpp); + token = readCPPline(yylvalpp); if(check_EOF(token)) return 0; continue; @@ -779,42 +802,34 @@ int yylex_CPP(char* buf, int maxSize) } } cpp->previous_token = token; - // expand macros - if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp.sc_ident, &yylvalpp, 0) == 1) { - cpp->notAVersionToken = 1; - continue; - } if (token == '\n') continue; - if (token == CPP_IDENTIFIER) { - cpp->notAVersionToken = 1; - tokenString = GetStringOfAtom(atable,yylvalpp.sc_ident); - } else if (token == CPP_FLOATCONSTANT||token == CPP_INTCONSTANT){ - cpp->notAVersionToken = 1; - tokenString = yylvalpp.symbol_name; - } else { - cpp->notAVersionToken = 1; - tokenString = GetStringOfAtom(atable,token); - } + cpp->notAVersionToken = 1; + + // expand macros + if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp->sc_ident, yylvalpp, 0) == 1) + continue; + + if (token == CPP_IDENTIFIER) + tokenString = GetStringOfAtom(atable, yylvalpp->sc_ident); + else if (token == CPP_INTCONSTANT || token == CPP_UINTCONSTANT || + token == CPP_FLOATCONSTANT || token == CPP_DOUBLECONSTANT) + tokenString = yylvalpp->symbol_name; + else + tokenString = GetStringOfAtom(atable, token); if (tokenString) { - if ((signed)strlen(tokenString) >= maxSize) { + if (tokenString[0] != 0) cpp->tokensBeforeEOF = 1; - return maxSize; - } else if (strlen(tokenString) > 0) { - strcpy(buf, tokenString); - cpp->tokensBeforeEOF = 1; - return (int)strlen(tokenString); - } - return 0; + return tokenString; } } return 0; -} // yylex +} // PpTokenize //Checks if the token just read is EOF or not. int check_EOF(int token) diff --git a/glslang/MachineIndependent/preprocessor/scanner.h b/glslang/MachineIndependent/preprocessor/scanner.h index 0c90b44..86d3008 100644 --- a/glslang/MachineIndependent/preprocessor/scanner.h +++ b/glslang/MachineIndependent/preprocessor/scanner.h @@ -81,9 +81,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #if !defined(__SCANNER_H) #define __SCANNER_H 1 -#define MAX_SYMBOL_NAME_LEN 1025 -#define MAX_STRING_LEN 1025 - +#include "preprocess.h" #include "parser.h" // Not really atom table stuff but needed first... @@ -91,23 +89,8 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. extern "C" { #endif -typedef struct SourceLoc_Rec { - unsigned short file, line; -} SourceLoc; - int yyparse (void); -int yylex_CPP(char* buf, int maxSize); - -typedef struct InputSrc { - struct InputSrc *prev; - int (*scan)(struct InputSrc *, yystypepp *); - int (*getch)(struct InputSrc *, yystypepp *); - void (*ungetch)(struct InputSrc *, int, yystypepp *); - int name; /* atom */ - int line; -} InputSrc; - int InitScanner(CPPStruct *cpp); // Intialise the cpp scanner. int ScanFromString(char *); // Start scanning the input from the string mentioned. int check_EOF(int); // check if we hit a EOF abruptly diff --git a/glslang/MachineIndependent/preprocessor/slglobals.h b/glslang/MachineIndependent/preprocessor/slglobals.h index 3af2386..9027f0a 100644 --- a/glslang/MachineIndependent/preprocessor/slglobals.h +++ b/glslang/MachineIndependent/preprocessor/slglobals.h @@ -81,7 +81,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #if !defined(__SLGLOBALS_H) #define __SLGLOBALS_H 1 -typedef struct CPPStruct_Rec CPPStruct; +#include "preprocess.h" // TODO: threading: Multi-threading note: The existence of this global makes // this preprocessing single-threaded only. @@ -101,7 +101,6 @@ extern CPPStruct *cpp; #include "cpp.h" #include "tokens.h" #include "symbols.h" -#include "compile.h" #if !defined(NO_PARSER) #include "parser.h" #endif diff --git a/glslang/MachineIndependent/preprocessor/tokens.c b/glslang/MachineIndependent/preprocessor/tokens.c index 8677713..a5e7669 100644 --- a/glslang/MachineIndependent/preprocessor/tokens.c +++ b/glslang/MachineIndependent/preprocessor/tokens.c @@ -257,8 +257,10 @@ void RecordToken(TokenStream *pTok, int token, yystypepp * yylvalpp) lAddByte(pTok, (unsigned char) *s++); lAddByte(pTok, 0); break; - case CPP_FLOATCONSTANT: case CPP_INTCONSTANT: + case CPP_UINTCONSTANT: + case CPP_FLOATCONSTANT: + case CPP_DOUBLECONSTANT: str = yylvalpp->symbol_name; while (*str){ lAddByte(pTok, (unsigned char) *str); @@ -293,8 +295,9 @@ void RewindTokenStream(TokenStream *pTok) int ReadToken(TokenStream *pTok, yystypepp * yylvalpp) { - char symbol_name[MAX_SYMBOL_NAME_LEN + 1]; - char string_val[MAX_STRING_LEN + 1]; + //TODO: PP: why is this different than byte_scan + + char tokenText[MAX_TOKEN_LENGTH + 1]; int ltoken, len; char ch; @@ -312,8 +315,8 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp) (ch >= '0' && ch <= '9') || ch == '_') { - if (len < MAX_SYMBOL_NAME_LEN) { - symbol_name[len] = ch; + if (len < MAX_TOKEN_LENGTH) { + tokenText[len] = ch; len++; ch = lReadByte(pTok); } else { @@ -321,30 +324,31 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp) break; } } - symbol_name[len] = '\0'; + tokenText[len] = '\0'; assert(ch == '\0'); - yylvalpp->sc_ident = LookUpAddString(atable, symbol_name); + yylvalpp->sc_ident = LookUpAddString(atable, tokenText); return CPP_IDENTIFIER; break; case CPP_STRCONSTANT: len = 0; while ((ch = lReadByte(pTok)) != 0) { - if (len < MAX_STRING_LEN) - string_val[len++] = ch; + if (len < MAX_TOKEN_LENGTH) + tokenText[len++] = ch; else break; } - string_val[len] = 0; - yylvalpp->sc_ident = LookUpAddString(atable, string_val); + tokenText[len] = 0; + yylvalpp->sc_ident = LookUpAddString(atable, tokenText); break; case CPP_FLOATCONSTANT: + case CPP_DOUBLECONSTANT: len = 0; ch = lReadByte(pTok); - while ((ch >= '0' && ch <= '9')||(ch=='e'||ch=='E'||ch=='.')||(ch=='+'||ch=='-')) + while ((ch >= '0' && ch <= '9') || ch=='e' || ch=='E' || ch=='.' || ch=='+' || ch=='-' || ch=='l' || ch=='L' || ch=='f'|| ch=='F') { - if (len < MAX_SYMBOL_NAME_LEN) { - symbol_name[len] = ch; + if (len < MAX_TOKEN_LENGTH) { + tokenText[len] = ch; len++; ch = lReadByte(pTok); } else { @@ -352,18 +356,19 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp) break; } } - symbol_name[len] = '\0'; + tokenText[len] = '\0'; assert(ch == '\0'); - strcpy(yylvalpp->symbol_name,symbol_name); - yylvalpp->sc_fval=(float)atof(yylvalpp->symbol_name); + strcpy(yylvalpp->symbol_name, tokenText); + yylvalpp->sc_dval = atof(yylvalpp->symbol_name); break; case CPP_INTCONSTANT: + case CPP_UINTCONSTANT: len = 0; ch = lReadByte(pTok); - while ((ch >= '0' && ch <= '9')) + while ((ch >= '0' && ch <= '9') || ch == 'u' || ch == 'U') { - if (len < MAX_SYMBOL_NAME_LEN) { - symbol_name[len] = ch; + if (len < MAX_TOKEN_LENGTH) { + tokenText[len] = ch; len++; ch = lReadByte(pTok); } else { @@ -371,10 +376,10 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp) break; } } - symbol_name[len] = '\0'; + tokenText[len] = '\0'; assert(ch == '\0'); - strcpy(yylvalpp->symbol_name,symbol_name); - yylvalpp->sc_int=atoi(yylvalpp->symbol_name); + strcpy(yylvalpp->symbol_name,tokenText); + yylvalpp->sc_int = atoi(yylvalpp->symbol_name); break; case '(': yylvalpp->sc_int = lReadByte(pTok); @@ -456,7 +461,7 @@ void UngetToken(int token, yystypepp * yylvalpp) { void DumpTokenStream(FILE *fp, TokenStream *s, yystypepp * yylvalpp) { int token; - const int maxSize = MAX_SYMBOL_NAME_LEN + 5; + const int maxSize = MAX_TOKEN_LENGTH + 5; char str[100]; if (fp == 0) fp = stdout; @@ -471,10 +476,12 @@ void DumpTokenStream(FILE *fp, TokenStream *s, yystypepp * yylvalpp) { snprintf(str, maxSize, "\"%s\"", GetAtomString(atable, yylvalpp->sc_ident)); break; case CPP_FLOATCONSTANT: - //printf("%g9.6 ", yylvalpp->sc_fval); + case CPP_DOUBLECONSTANT: + printf("%g9.6 ", yylvalpp->sc_dval); break; case CPP_INTCONSTANT: - //printf("%d ", yylvalpp->sc_int); + case CPP_UINTCONSTANT: + printf("%d ", yylvalpp->sc_int); break; default: if (token >= 127) -- 2.7.4