Merge pull request #43 from google/cpp-style-line-directive

Extend the syntax of #line and __FILE__ to support filename strings.

The implementation is done via introducing a new extension 
GL_GOOGLE_cpp_style_line_directive using the extension framework.

The purpose is to support cpp-style #line directives, which is
required by #include.
This commit is contained in:
John Kessenich 2015-07-28 18:55:44 -06:00
commit d9b89d3e9a
21 changed files with 462 additions and 292 deletions

View File

@ -0,0 +1,37 @@
#extension GL_GOOGLE_cpp_style_line_directive : enable
0
#line 150 "a.h"
"a.h"
#line 24
"a.h"
#line 42
"a.h"
#line 30 "b.cc"
"b.cc"
#line 10 3
3
#line 48
3
#line 4
3
#line 55 100
100
#line 1000 "c"
"c"
#line 42 1
1
#line 42 "this-is-a-quite-long-name-maybe-i-should-shorten-it"
"this-is-a-quite-long-name-maybe-i-should-shorten-it"

View File

@ -0,0 +1,15 @@
ERROR: 0:3: '#error' : at 0:3
ERROR: a.h:150: '#error' : at a.h:150
ERROR: a.h:24: '#error' : at a.h:24
ERROR: a.h:42: '#error' : at a.h:42
ERROR: b.cc:30: '#error' : at b.cc:30
ERROR: 3:10: '#error' : at 3:10
ERROR: 3:48: '#error' : at 3:48
ERROR: 3:4: '#error' : at 3:4
ERROR: 100:55: '#error' : at 100:55
ERROR: c:1000: '#error' : at c:1000
ERROR: 1:42: '#error' : at 1:42
ERROR: this-is-a-quite-long-name-maybe-i-should-shorten-it:42: '#error' : at this-is-a-quite-long-name-maybe-i-should-shorten-it:42
ERROR: 12 compilation errors. No code generated.

View File

@ -0,0 +1,36 @@
#extension GL_GOOGLE_cpp_style_line_directive : enable
__FILE__
#line 150 "a.h"
__FILE__
#line 24
__FILE__
#line 42
__FILE__
#line 30 "b.cc"
__FILE__
#line 10 3
__FILE__
#line 48
__FILE__
#line 4
__FILE__
#line 55 100
__FILE__
#line 1000 "c"
__FILE__
#line 42 1
__FILE__
#line 42 "this-is-a-quite-long-name-maybe-i-should-shorten-it"
__FILE__

View File

@ -0,0 +1,36 @@
#extension GL_GOOGLE_cpp_style_line_directive : enable
#error at "0:3"
#line 150 "a.h"
#error at "a.h:150"
#line 24
#error at "a.h:24"
#line 42
#error at "a.h:42"
#line 30 "b.cc"
#error at "b.cc:30"
#line 10 3
#error at "3:10"
#line 48
#error at "3:48"
#line 4
#error at "3:4"
#line 55 100
#error at "100:55"
#line 1000 "c"
#error at "c:1000"
#line 42 1
#error at "1:42"
#line 42 "this-is-a-quite-long-name-maybe-i-should-shorten-it"
#error at "this-is-a-quite-long-name-maybe-i-should-shorten-it:42"

View File

@ -1,3 +1,5 @@
preprocessor.cpp_style_line_directive.vert
preprocessor.cpp_style___FILE__.vert
preprocessor.edge_cases.vert preprocessor.edge_cases.vert
preprocessor.errors.vert preprocessor.errors.vert
preprocessor.extensions.vert preprocessor.extensions.vert

View File

@ -189,7 +189,8 @@ inline const TString String(const int i, const int base = 10)
} }
struct TSourceLoc { struct TSourceLoc {
void init() { string = 0; line = 0; column = 0; } void init() { name = nullptr; string = 0; line = 0; column = 0; }
const char* name; // descriptive name for this string
int string; int string;
int line; int line;
int column; int column;

View File

@ -95,10 +95,15 @@ public:
default: append("UNKOWN ERROR: "); break; default: append("UNKOWN ERROR: "); break;
} }
} }
void location(TSourceLoc loc) { void location(const TSourceLoc& loc) {
const int maxSize = 24; const int maxSize = 24;
char locText[maxSize]; char locText[maxSize];
snprintf(locText, maxSize, "%d:%d", loc.string, loc.line); if (loc.name != nullptr) {
append(loc.name);
snprintf(locText, maxSize, ":%d", loc.line);
} else {
snprintf(locText, maxSize, "%d:%d", loc.string, loc.line);
}
append(locText); append(locText);
append(": "); append(": ");
} }
@ -107,7 +112,7 @@ public:
append(s); append(s);
append("\n"); append("\n");
} }
void message(TPrefixType message, const char* s, TSourceLoc loc) { void message(TPrefixType message, const char* s, const TSourceLoc& loc) {
prefix(message); prefix(message);
location(loc); location(loc);
append(s); append(s);

View File

@ -798,7 +798,7 @@ public:
const TType* userDef; const TType* userDef;
TSourceLoc loc; TSourceLoc loc;
void initType(TSourceLoc l) void initType(const TSourceLoc& l)
{ {
basicType = EbtVoid; basicType = EbtVoid;
vectorSize = 1; vectorSize = 1;
@ -816,7 +816,7 @@ public:
qualifier.storage = EvqGlobal; qualifier.storage = EvqGlobal;
} }
void init(TSourceLoc loc, bool global = false) void init(const TSourceLoc& loc, bool global = false)
{ {
initType(loc); initType(loc);
sampler.clear(); sampler.clear();

View File

@ -407,8 +407,8 @@ public:
POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator()) POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator())
TIntermNode() { loc.init(); } TIntermNode() { loc.init(); }
virtual glslang::TSourceLoc getLoc() const { return loc; } virtual const glslang::TSourceLoc& getLoc() const { return loc; }
virtual void setLoc(glslang::TSourceLoc l) { loc = l; } virtual void setLoc(const glslang::TSourceLoc& l) { loc = l; }
virtual void traverse(glslang::TIntermTraverser*) = 0; virtual void traverse(glslang::TIntermTraverser*) = 0;
virtual glslang::TIntermTyped* getAsTyped() { return 0; } virtual glslang::TIntermTyped* getAsTyped() { return 0; }
virtual glslang::TIntermOperator* getAsOperator() { return 0; } virtual glslang::TIntermOperator* getAsOperator() { return 0; }

View File

@ -854,7 +854,7 @@ TIntermTyped* TIntermediate::foldConstructor(TIntermAggregate* aggrNode)
// dereference. Can handle any thing except a multi-character swizzle, though // dereference. Can handle any thing except a multi-character swizzle, though
// all swizzles may go to foldSwizzle(). // all swizzles may go to foldSwizzle().
// //
TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, TSourceLoc loc) TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, const TSourceLoc& loc)
{ {
TType dereferencedType(node->getType(), index); TType dereferencedType(node->getType(), index);
dereferencedType.getQualifier().storage = EvqConst; dereferencedType.getQualifier().storage = EvqConst;
@ -883,7 +883,7 @@ TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, TSou
// Make a constant vector node or constant scalar node, representing a given // Make a constant vector node or constant scalar node, representing a given
// constant vector and constant swizzle into it. // constant vector and constant swizzle into it.
// //
TIntermTyped* TIntermediate::foldSwizzle(TIntermTyped* node, TVectorFields& fields, TSourceLoc loc) TIntermTyped* TIntermediate::foldSwizzle(TIntermTyped* node, TVectorFields& fields, const TSourceLoc& loc)
{ {
const TConstUnionArray& unionArray = node->getAsConstantUnion()->getConstArray(); const TConstUnionArray& unionArray = node->getAsConstantUnion()->getConstArray();
TConstUnionArray constArray(fields.num); TConstUnionArray constArray(fields.num);

View File

@ -59,7 +59,7 @@ namespace glslang {
// //
// Returns the added node. // Returns the added node.
// //
TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, TSourceLoc loc) TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, const TSourceLoc& loc)
{ {
TIntermSymbol* node = new TIntermSymbol(id, name, type); TIntermSymbol* node = new TIntermSymbol(id, name, type);
node->setLoc(loc); node->setLoc(loc);
@ -67,7 +67,7 @@ TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType
return node; return node;
} }
TIntermSymbol* TIntermediate::addSymbol(const TVariable& variable, TSourceLoc loc) TIntermSymbol* TIntermediate::addSymbol(const TVariable& variable, const TSourceLoc& loc)
{ {
return addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), loc); return addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), loc);
} }
@ -267,7 +267,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSo
return node; return node;
} }
TIntermTyped* TIntermediate::addBuiltInFunctionCall(TSourceLoc loc, TOperator op, bool unary, TIntermNode* childNode, const TType& returnType) TIntermTyped* TIntermediate::addBuiltInFunctionCall(const TSourceLoc& loc, TOperator op, bool unary, TIntermNode* childNode, const TType& returnType)
{ {
if (unary) { if (unary) {
// //
@ -658,7 +658,7 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r
return aggNode; return aggNode;
} }
TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc loc) TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc& loc)
{ {
TIntermAggregate* aggNode = growAggregate(left, right); TIntermAggregate* aggNode = growAggregate(left, right);
if (aggNode) if (aggNode)
@ -684,7 +684,7 @@ TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node)
return aggNode; return aggNode;
} }
TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc loc) TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, const TSourceLoc& loc)
{ {
if (node == 0) if (node == 0)
return 0; return 0;
@ -703,7 +703,7 @@ TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc loc
// //
// Returns the selection node created. // Returns the selection node created.
// //
TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, TSourceLoc loc) TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& loc)
{ {
// //
// Don't prune the false path for compile-time constants; it's needed // Don't prune the false path for compile-time constants; it's needed
@ -717,7 +717,7 @@ TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nod
} }
TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc& loc)
{ {
// However, the lowest precedence operators of the sequence operator ( , ) and the assignment operators // However, the lowest precedence operators of the sequence operator ( , ) and the assignment operators
// ... are not included in the operators that can create a constant expression. // ... are not included in the operators that can create a constant expression.
@ -736,7 +736,7 @@ TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, T
return commaAggregate; return commaAggregate;
} }
TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type, const TString* name, TSourceLoc loc) TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type, const TString* name, const TSourceLoc& loc)
{ {
TIntermMethod* method = new TIntermMethod(object, type, *name); TIntermMethod* method = new TIntermMethod(object, type, *name);
method->setLoc(loc); method->setLoc(loc);
@ -751,7 +751,7 @@ TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type,
// //
// Returns the selection node created, or 0 if one could not be. // Returns the selection node created, or 0 if one could not be.
// //
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc loc) TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& loc)
{ {
// //
// Get compatible types. // Get compatible types.
@ -799,7 +799,7 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
// Returns the constant union node created. // Returns the constant union node created.
// //
TIntermConstantUnion* TIntermediate::addConstantUnion(const TConstUnionArray& unionArray, const TType& t, TSourceLoc loc, bool literal) const TIntermConstantUnion* TIntermediate::addConstantUnion(const TConstUnionArray& unionArray, const TType& t, const TSourceLoc& loc, bool literal) const
{ {
TIntermConstantUnion* node = new TIntermConstantUnion(unionArray, t); TIntermConstantUnion* node = new TIntermConstantUnion(unionArray, t);
node->setLoc(loc); node->setLoc(loc);
@ -809,7 +809,7 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(const TConstUnionArray& un
return node; return node;
} }
TIntermConstantUnion* TIntermediate::addConstantUnion(int i, TSourceLoc loc, bool literal) const TIntermConstantUnion* TIntermediate::addConstantUnion(int i, const TSourceLoc& loc, bool literal) const
{ {
TConstUnionArray unionArray(1); TConstUnionArray unionArray(1);
unionArray[0].setIConst(i); unionArray[0].setIConst(i);
@ -817,7 +817,7 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(int i, TSourceLoc loc, boo
return addConstantUnion(unionArray, TType(EbtInt, EvqConst), loc, literal); return addConstantUnion(unionArray, TType(EbtInt, EvqConst), loc, literal);
} }
TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned int u, TSourceLoc loc, bool literal) const TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned int u, const TSourceLoc& loc, bool literal) const
{ {
TConstUnionArray unionArray(1); TConstUnionArray unionArray(1);
unionArray[0].setUConst(u); unionArray[0].setUConst(u);
@ -825,7 +825,7 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned int u, TSourceLoc
return addConstantUnion(unionArray, TType(EbtUint, EvqConst), loc, literal); return addConstantUnion(unionArray, TType(EbtUint, EvqConst), loc, literal);
} }
TIntermConstantUnion* TIntermediate::addConstantUnion(bool b, TSourceLoc loc, bool literal) const TIntermConstantUnion* TIntermediate::addConstantUnion(bool b, const TSourceLoc& loc, bool literal) const
{ {
TConstUnionArray unionArray(1); TConstUnionArray unionArray(1);
unionArray[0].setBConst(b); unionArray[0].setBConst(b);
@ -833,7 +833,7 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(bool b, TSourceLoc loc, bo
return addConstantUnion(unionArray, TType(EbtBool, EvqConst), loc, literal); return addConstantUnion(unionArray, TType(EbtBool, EvqConst), loc, literal);
} }
TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseType, TSourceLoc loc, bool literal) const TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseType, const TSourceLoc& loc, bool literal) const
{ {
assert(baseType == EbtFloat || baseType == EbtDouble); assert(baseType == EbtFloat || baseType == EbtDouble);
@ -843,7 +843,7 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseT
return addConstantUnion(unionArray, TType(baseType, EvqConst), loc, literal); return addConstantUnion(unionArray, TType(baseType, EvqConst), loc, literal);
} }
TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc loc) TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, const TSourceLoc& loc)
{ {
TIntermAggregate* node = new TIntermAggregate(EOpSequence); TIntermAggregate* node = new TIntermAggregate(EOpSequence);
@ -863,7 +863,7 @@ TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc loc)
// //
// Create loop nodes. // Create loop nodes.
// //
TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, TSourceLoc loc) TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc)
{ {
TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst); TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
node->setLoc(loc); node->setLoc(loc);
@ -874,12 +874,12 @@ TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TInte
// //
// Add branches. // Add branches.
// //
TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TSourceLoc loc) TIntermBranch* TIntermediate::addBranch(TOperator branchOp, const TSourceLoc& loc)
{ {
return addBranch(branchOp, 0, loc); return addBranch(branchOp, 0, loc);
} }
TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, TSourceLoc loc) TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, const TSourceLoc& loc)
{ {
TIntermBranch* node = new TIntermBranch(branchOp, expression); TIntermBranch* node = new TIntermBranch(branchOp, expression);
node->setLoc(loc); node->setLoc(loc);

View File

@ -173,7 +173,7 @@ void TParseContext::parserError(const char* s)
error(getCurrentLoc(), "", "", s, ""); error(getCurrentLoc(), "", "", s, "");
} }
void TParseContext::handlePragma(TSourceLoc loc, const TVector<TString>& tokens) void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>& tokens)
{ {
if (pragmaCallback) if (pragmaCallback)
pragmaCallback(loc.line, tokens); pragmaCallback(loc.line, tokens);
@ -244,7 +244,7 @@ void TParseContext::handlePragma(TSourceLoc loc, const TVector<TString>& tokens)
// //
// Returns true if there is no error. // Returns true if there is no error.
// //
bool TParseContext::parseVectorFields(TSourceLoc loc, const TString& compString, int vecSize, TVectorFields& fields) bool TParseContext::parseVectorFields(const TSourceLoc& loc, const TString& compString, int vecSize, TVectorFields& fields)
{ {
fields.num = (int) compString.size(); fields.num = (int) compString.size();
if (fields.num > 4) { if (fields.num > 4) {
@ -342,7 +342,7 @@ bool TParseContext::parseVectorFields(TSourceLoc loc, const TString& compString,
// Used to output syntax, parsing, and semantic errors. // Used to output syntax, parsing, and semantic errors.
// //
void TParseContext::outputMessage(TSourceLoc loc, const char* szReason, void TParseContext::outputMessage(const TSourceLoc& loc, const char* szReason,
const char* szToken, const char* szToken,
const char* szExtraInfoFormat, const char* szExtraInfoFormat,
TPrefixType prefix, va_list args) TPrefixType prefix, va_list args)
@ -361,7 +361,7 @@ void TParseContext::outputMessage(TSourceLoc loc, const char* szReason,
} }
} }
void C_DECL TParseContext::error(TSourceLoc loc, const char* szReason, const char* szToken, void C_DECL TParseContext::error(const TSourceLoc& loc, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...) const char* szExtraInfoFormat, ...)
{ {
if (messages & EShMsgOnlyPreprocessor) if (messages & EShMsgOnlyPreprocessor)
@ -372,7 +372,7 @@ void C_DECL TParseContext::error(TSourceLoc loc, const char* szReason, const cha
va_end(args); va_end(args);
} }
void C_DECL TParseContext::warn(TSourceLoc loc, const char* szReason, const char* szToken, void C_DECL TParseContext::warn(const TSourceLoc& loc, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...) const char* szExtraInfoFormat, ...)
{ {
if (suppressWarnings()) if (suppressWarnings())
@ -383,7 +383,7 @@ void C_DECL TParseContext::warn(TSourceLoc loc, const char* szReason, const char
va_end(args); va_end(args);
} }
void C_DECL TParseContext::ppError(TSourceLoc loc, const char* szReason, const char* szToken, void C_DECL TParseContext::ppError(const TSourceLoc& loc, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...) const char* szExtraInfoFormat, ...)
{ {
va_list args; va_list args;
@ -392,7 +392,7 @@ void C_DECL TParseContext::ppError(TSourceLoc loc, const char* szReason, const c
va_end(args); va_end(args);
} }
void C_DECL TParseContext::ppWarn(TSourceLoc loc, const char* szReason, const char* szToken, void C_DECL TParseContext::ppWarn(const TSourceLoc& loc, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...) const char* szExtraInfoFormat, ...)
{ {
va_list args; va_list args;
@ -404,7 +404,7 @@ void C_DECL TParseContext::ppWarn(TSourceLoc loc, const char* szReason, const ch
// //
// Handle seeing a variable identifier in the grammar. // Handle seeing a variable identifier in the grammar.
// //
TIntermTyped* TParseContext::handleVariable(TSourceLoc loc, TSymbol* symbol, const TString* string) TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symbol, const TString* string)
{ {
TIntermTyped* node = 0; TIntermTyped* node = 0;
@ -478,7 +478,7 @@ TIntermTyped* TParseContext::handleVariable(TSourceLoc loc, TSymbol* symbol, con
// //
// Handle seeing a base[index] dereference in the grammar. // Handle seeing a base[index] dereference in the grammar.
// //
TIntermTyped* TParseContext::handleBracketDereference(TSourceLoc loc, TIntermTyped* base, TIntermTyped* index) TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIntermTyped* base, TIntermTyped* index)
{ {
TIntermTyped* result = 0; TIntermTyped* result = 0;
@ -552,7 +552,7 @@ TIntermTyped* TParseContext::handleBracketDereference(TSourceLoc loc, TIntermTyp
return result; return result;
} }
void TParseContext::checkIndex(TSourceLoc loc, const TType& type, int& index) void TParseContext::checkIndex(const TSourceLoc& loc, const TType& type, int& index)
{ {
if (index < 0) { if (index < 0) {
error(loc, "", "[", "index out of range '%d'", index); error(loc, "", "[", "index out of range '%d'", index);
@ -576,7 +576,7 @@ void TParseContext::checkIndex(TSourceLoc loc, const TType& type, int& index)
} }
// for ES 2.0 (version 100) limitations for almost all index operations except vertex-shader uniforms // for ES 2.0 (version 100) limitations for almost all index operations except vertex-shader uniforms
void TParseContext::handleIndexLimits(TSourceLoc /*loc*/, TIntermTyped* base, TIntermTyped* index) void TParseContext::handleIndexLimits(const TSourceLoc& /*loc*/, TIntermTyped* base, TIntermTyped* index)
{ {
if ((! limits.generalSamplerIndexing && base->getBasicType() == EbtSampler) || if ((! limits.generalSamplerIndexing && base->getBasicType() == EbtSampler) ||
(! limits.generalUniformIndexing && base->getQualifier().isUniformOrBuffer() && language != EShLangVertex) || (! limits.generalUniformIndexing && base->getQualifier().isUniformOrBuffer() && language != EShLangVertex) ||
@ -618,7 +618,7 @@ bool TParseContext::isIoResizeArray(const TType& type) const
} }
// If an array is not isIoResizeArray() but is an io array, make sure it has the right size // If an array is not isIoResizeArray() but is an io array, make sure it has the right size
void TParseContext::fixIoArraySize(TSourceLoc loc, TType& type) void TParseContext::fixIoArraySize(const TSourceLoc& loc, TType& type)
{ {
if (! type.isArray() || type.getQualifier().patch || symbolTable.atBuiltInLevel()) if (! type.isArray() || type.getQualifier().patch || symbolTable.atBuiltInLevel())
return; return;
@ -640,7 +640,7 @@ void TParseContext::fixIoArraySize(TSourceLoc loc, TType& type)
// Issue any errors if the non-array object is missing arrayness WRT // Issue any errors if the non-array object is missing arrayness WRT
// shader I/O that has array requirements. // shader I/O that has array requirements.
// All arrayness checking is handled in array paths, this is for // All arrayness checking is handled in array paths, this is for
void TParseContext::ioArrayCheck(TSourceLoc loc, const TType& type, const TString& identifier) void TParseContext::ioArrayCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
{ {
if (! type.isArray() && ! symbolTable.atBuiltInLevel()) { if (! type.isArray() && ! symbolTable.atBuiltInLevel()) {
if (type.getQualifier().isArrayedIo(language)) if (type.getQualifier().isArrayedIo(language))
@ -651,7 +651,7 @@ void TParseContext::ioArrayCheck(TSourceLoc loc, const TType& type, const TStrin
// Handle a dereference of a geometry shader input array or tessellation control output array. // Handle a dereference of a geometry shader input array or tessellation control output array.
// See ioArraySymbolResizeList comment in ParseHelper.h. // See ioArraySymbolResizeList comment in ParseHelper.h.
// //
void TParseContext::handleIoResizeArrayAccess(TSourceLoc /*loc*/, TIntermTyped* base) void TParseContext::handleIoResizeArrayAccess(const TSourceLoc& /*loc*/, TIntermTyped* base)
{ {
TIntermSymbol* symbolNode = base->getAsSymbolNode(); TIntermSymbol* symbolNode = base->getAsSymbolNode();
assert(symbolNode); assert(symbolNode);
@ -674,7 +674,7 @@ void TParseContext::handleIoResizeArrayAccess(TSourceLoc /*loc*/, TIntermTyped*
// Types without an array size will be given one. // Types without an array size will be given one.
// Types already having a size that is wrong will get an error. // Types already having a size that is wrong will get an error.
// //
void TParseContext::checkIoArraysConsistency(TSourceLoc loc, bool tailOnly) void TParseContext::checkIoArraysConsistency(const TSourceLoc& loc, bool tailOnly)
{ {
int requiredSize = getIoArrayImplicitSize(); int requiredSize = getIoArrayImplicitSize();
if (requiredSize == 0) if (requiredSize == 0)
@ -707,7 +707,7 @@ int TParseContext::getIoArrayImplicitSize() const
return 0; return 0;
} }
void TParseContext::checkIoArrayConsistency(TSourceLoc loc, int requiredSize, const char* feature, TType& type, const TString& name) void TParseContext::checkIoArrayConsistency(const TSourceLoc& loc, int requiredSize, const char* feature, TType& type, const TString& name)
{ {
if (type.isImplicitlySizedArray()) if (type.isImplicitlySizedArray())
type.changeArraySize(requiredSize); type.changeArraySize(requiredSize);
@ -722,7 +722,7 @@ void TParseContext::checkIoArrayConsistency(TSourceLoc loc, int requiredSize, co
} }
// Handle seeing a binary node with a math operation. // Handle seeing a binary node with a math operation.
TIntermTyped* TParseContext::handleBinaryMath(TSourceLoc loc, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right) TIntermTyped* TParseContext::handleBinaryMath(const TSourceLoc& loc, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right)
{ {
rValueErrorCheck(loc, str, left->getAsTyped()); rValueErrorCheck(loc, str, left->getAsTyped());
rValueErrorCheck(loc, str, right->getAsTyped()); rValueErrorCheck(loc, str, right->getAsTyped());
@ -735,7 +735,7 @@ TIntermTyped* TParseContext::handleBinaryMath(TSourceLoc loc, const char* str, T
} }
// Handle seeing a unary node with a math operation. // Handle seeing a unary node with a math operation.
TIntermTyped* TParseContext::handleUnaryMath(TSourceLoc loc, const char* str, TOperator op, TIntermTyped* childNode) TIntermTyped* TParseContext::handleUnaryMath(const TSourceLoc& loc, const char* str, TOperator op, TIntermTyped* childNode)
{ {
rValueErrorCheck(loc, str, childNode); rValueErrorCheck(loc, str, childNode);
@ -752,7 +752,7 @@ TIntermTyped* TParseContext::handleUnaryMath(TSourceLoc loc, const char* str, TO
// //
// Handle seeing a base.field dereference in the grammar. // Handle seeing a base.field dereference in the grammar.
// //
TIntermTyped* TParseContext::handleDotDereference(TSourceLoc loc, TIntermTyped* base, const TString& field) TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TIntermTyped* base, const TString& field)
{ {
variableCheck(base); variableCheck(base);
@ -853,7 +853,7 @@ TIntermTyped* TParseContext::handleDotDereference(TSourceLoc loc, TIntermTyped*
return result; return result;
} }
void TParseContext::blockMemberExtensionCheck(TSourceLoc loc, const TIntermTyped* /*base*/, const TString& field) void TParseContext::blockMemberExtensionCheck(const TSourceLoc& loc, const TIntermTyped* /*base*/, const TString& field)
{ {
if (profile == EEsProfile && field == "gl_PointSize") { if (profile == EEsProfile && field == "gl_PointSize") {
if (language == EShLangGeometry) if (language == EShLangGeometry)
@ -867,7 +867,7 @@ void TParseContext::blockMemberExtensionCheck(TSourceLoc loc, const TIntermTyped
// Handle seeing a function declarator in the grammar. This is the precursor // Handle seeing a function declarator in the grammar. This is the precursor
// to recognizing a function prototype or function definition. // to recognizing a function prototype or function definition.
// //
TFunction* TParseContext::handleFunctionDeclarator(TSourceLoc loc, TFunction& function, bool prototype) TFunction* TParseContext::handleFunctionDeclarator(const TSourceLoc& loc, TFunction& function, bool prototype)
{ {
// ES can't declare prototypes inside functions // ES can't declare prototypes inside functions
if (! symbolTable.atGlobalLevel()) if (! symbolTable.atGlobalLevel())
@ -935,7 +935,7 @@ TFunction* TParseContext::handleFunctionDeclarator(TSourceLoc loc, TFunction& fu
// Handle seeing the function prototype in front of a function definition in the grammar. // Handle seeing the function prototype in front of a function definition in the grammar.
// The body is handled after this function returns. // The body is handled after this function returns.
// //
TIntermAggregate* TParseContext::handleFunctionDefinition(TSourceLoc loc, TFunction& function) TIntermAggregate* TParseContext::handleFunctionDefinition(const TSourceLoc& loc, TFunction& function)
{ {
currentCaller = function.getMangledName(); currentCaller = function.getMangledName();
TSymbol* symbol = symbolTable.find(function.getMangledName()); TSymbol* symbol = symbolTable.find(function.getMangledName());
@ -1025,7 +1025,7 @@ TIntermAggregate* TParseContext::handleFunctionDefinition(TSourceLoc loc, TFunct
// - user function // - user function
// - subroutine call (not implemented yet) // - subroutine call (not implemented yet)
// //
TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* function, TIntermNode* arguments) TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction* function, TIntermNode* arguments)
{ {
TIntermTyped* result = 0; TIntermTyped* result = 0;
@ -1151,7 +1151,7 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* funct
} }
// See if the operation is being done in an illegal location. // See if the operation is being done in an illegal location.
void TParseContext::checkLocation(TSourceLoc loc, TOperator op) void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op)
{ {
switch (op) { switch (op) {
case EOpBarrier: case EOpBarrier:
@ -1174,7 +1174,7 @@ void TParseContext::checkLocation(TSourceLoc loc, TOperator op)
// function syntax "()" is recognized. // function syntax "()" is recognized.
// //
// Return resulting tree node. // Return resulting tree node.
TIntermTyped* TParseContext::handleLengthMethod(TSourceLoc loc, TFunction* function, TIntermNode* intermNode) TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction* function, TIntermNode* intermNode)
{ {
int length = 0; int length = 0;
@ -1330,7 +1330,7 @@ TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& funct
// //
// Assumes there has been a semantically correct match to a built-in function. // Assumes there has been a semantically correct match to a built-in function.
// //
void TParseContext::nonOpBuiltInCheck(TSourceLoc loc, const TFunction& fnCandidate, TIntermAggregate& callNode) void TParseContext::nonOpBuiltInCheck(const TSourceLoc& loc, const TFunction& fnCandidate, TIntermAggregate& callNode)
{ {
// built-in texturing functions get their return value precision from the precision of the sampler // built-in texturing functions get their return value precision from the precision of the sampler
if (fnCandidate.getType().getQualifier().precision == EpqNone && if (fnCandidate.getType().getQualifier().precision == EpqNone &&
@ -1436,7 +1436,7 @@ void TParseContext::nonOpBuiltInCheck(TSourceLoc loc, const TFunction& fnCandida
// //
// Handle seeing a built-in constructor in a grammar production. // Handle seeing a built-in constructor in a grammar production.
// //
TFunction* TParseContext::handleConstructorCall(TSourceLoc loc, const TPublicType& publicType) TFunction* TParseContext::handleConstructorCall(const TSourceLoc& loc, const TPublicType& publicType)
{ {
TType type(publicType); TType type(publicType);
type.getQualifier().precision = EpqNone; type.getQualifier().precision = EpqNone;
@ -1584,7 +1584,7 @@ TOperator TParseContext::mapTypeToConstructorOp(const TType& type) const
// //
// Same error message for all places assignments don't work. // Same error message for all places assignments don't work.
// //
void TParseContext::assignError(TSourceLoc loc, const char* op, TString left, TString right) void TParseContext::assignError(const TSourceLoc& loc, const char* op, TString left, TString right)
{ {
error(loc, "", op, "cannot convert from '%s' to '%s'", error(loc, "", op, "cannot convert from '%s' to '%s'",
right.c_str(), left.c_str()); right.c_str(), left.c_str());
@ -1593,7 +1593,7 @@ void TParseContext::assignError(TSourceLoc loc, const char* op, TString left, TS
// //
// Same error message for all places unary operations don't work. // Same error message for all places unary operations don't work.
// //
void TParseContext::unaryOpError(TSourceLoc loc, const char* op, TString operand) void TParseContext::unaryOpError(const TSourceLoc& loc, const char* op, TString operand)
{ {
error(loc, " 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)", "no operation '%s' exists that takes an operand of type %s (or there is no acceptable conversion)",
@ -1603,7 +1603,7 @@ void TParseContext::unaryOpError(TSourceLoc loc, const char* op, TString operand
// //
// Same error message for all binary operations don't work. // Same error message for all binary operations don't work.
// //
void TParseContext::binaryOpError(TSourceLoc loc, const char* op, TString left, TString right) void TParseContext::binaryOpError(const TSourceLoc& loc, const char* op, TString left, TString right)
{ {
error(loc, " wrong operand types:", op, error(loc, " wrong operand types:", op,
"no operation '%s' exists that takes a left-hand operand of type '%s' and " "no operation '%s' exists that takes a left-hand operand of type '%s' and "
@ -1649,7 +1649,7 @@ void TParseContext::variableCheck(TIntermTyped*& nodePtr)
// //
// Returns true if the was an error. // Returns true if the was an error.
// //
bool TParseContext::lValueErrorCheck(TSourceLoc loc, const char* op, TIntermTyped* node) bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node)
{ {
TIntermBinary* binaryNode = node->getAsBinaryNode(); TIntermBinary* binaryNode = node->getAsBinaryNode();
@ -1761,7 +1761,7 @@ bool TParseContext::lValueErrorCheck(TSourceLoc loc, const char* op, TIntermType
} }
// Test for and give an error if the node can't be read from. // Test for and give an error if the node can't be read from.
void TParseContext::rValueErrorCheck(TSourceLoc loc, const char* op, TIntermTyped* node) void TParseContext::rValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node)
{ {
if (! node) if (! node)
return; return;
@ -1812,7 +1812,7 @@ void TParseContext::integerCheck(const TIntermTyped* node, const char* token)
// Both test, and if necessary spit out an error, to see if we are currently // Both test, and if necessary spit out an error, to see if we are currently
// globally scoped. // globally scoped.
// //
void TParseContext::globalCheck(TSourceLoc loc, const char* token) void TParseContext::globalCheck(const TSourceLoc& loc, const char* token)
{ {
if (! symbolTable.atGlobalLevel()) if (! symbolTable.atGlobalLevel())
error(loc, "not allowed in nested scope", token, ""); error(loc, "not allowed in nested scope", token, "");
@ -1821,7 +1821,7 @@ void TParseContext::globalCheck(TSourceLoc loc, const char* token)
// //
// Reserved errors for GLSL. // Reserved errors for GLSL.
// //
void TParseContext::reservedErrorCheck(TSourceLoc loc, const TString& identifier) void TParseContext::reservedErrorCheck(const TSourceLoc& loc, const TString& identifier)
{ {
// "Identifiers starting with "gl_" are reserved for use by OpenGL, and may not be // "Identifiers starting with "gl_" are reserved for use by OpenGL, and may not be
// declared in a shader; this results in a compile-time error." // declared in a shader; this results in a compile-time error."
@ -1846,7 +1846,7 @@ void TParseContext::reservedErrorCheck(TSourceLoc loc, const TString& identifier
// //
// Reserved errors for the preprocessor. // Reserved errors for the preprocessor.
// //
void TParseContext::reservedPpErrorCheck(TSourceLoc loc, const char* identifier, const char* op) void TParseContext::reservedPpErrorCheck(const TSourceLoc& loc, const char* identifier, const char* op)
{ {
// "__" are not supposed to be an error. ES 310 (and desktop) added the clarification: // "__" are not supposed to be an error. ES 310 (and desktop) added the clarification:
// "All macro names containing two consecutive underscores ( __ ) are reserved; // "All macro names containing two consecutive underscores ( __ ) are reserved;
@ -1877,7 +1877,7 @@ void TParseContext::reservedPpErrorCheck(TSourceLoc loc, const char* identifier,
// //
// Returns true if a line continuation should be done. // Returns true if a line continuation should be done.
// //
bool TParseContext::lineContinuationCheck(TSourceLoc loc, bool endOfComment) bool TParseContext::lineContinuationCheck(const TSourceLoc& loc, bool endOfComment)
{ {
const char* message = "line continuation"; const char* message = "line continuation";
@ -1917,7 +1917,7 @@ bool TParseContext::builtInName(const TString& identifier)
// //
// Returns true if there was an error in construction. // Returns true if there was an error in construction.
// //
bool TParseContext::constructorError(TSourceLoc loc, TIntermNode* node, TFunction& function, TOperator op, TType& type) bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, TFunction& function, TOperator op, TType& type)
{ {
type.shallowCopy(function.getType()); type.shallowCopy(function.getType());
@ -2058,7 +2058,7 @@ bool TParseContext::constructorError(TSourceLoc loc, TIntermNode* node, TFunctio
// //
// returns true in case of an error // returns true in case of an error
// //
bool TParseContext::voidErrorCheck(TSourceLoc loc, const TString& identifier, const TBasicType basicType) bool TParseContext::voidErrorCheck(const TSourceLoc& loc, const TString& identifier, const TBasicType basicType)
{ {
if (basicType == EbtVoid) { if (basicType == EbtVoid) {
error(loc, "illegal use of type 'void'", identifier.c_str(), ""); error(loc, "illegal use of type 'void'", identifier.c_str(), "");
@ -2069,20 +2069,20 @@ bool TParseContext::voidErrorCheck(TSourceLoc loc, const TString& identifier, co
} }
// Checks to see if the node (for the expression) contains a scalar boolean expression or not // Checks to see if the node (for the expression) contains a scalar boolean expression or not
void TParseContext::boolCheck(TSourceLoc loc, const TIntermTyped* type) void TParseContext::boolCheck(const TSourceLoc& loc, const TIntermTyped* type)
{ {
if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector())
error(loc, "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 // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
void TParseContext::boolCheck(TSourceLoc loc, const TPublicType& pType) void TParseContext::boolCheck(const TSourceLoc& loc, const TPublicType& pType)
{ {
if (pType.basicType != EbtBool || pType.arraySizes || pType.matrixCols > 1 || (pType.vectorSize > 1)) if (pType.basicType != EbtBool || pType.arraySizes || pType.matrixCols > 1 || (pType.vectorSize > 1))
error(loc, "boolean expression expected", "", ""); error(loc, "boolean expression expected", "", "");
} }
void TParseContext::samplerCheck(TSourceLoc loc, const TType& type, const TString& identifier) void TParseContext::samplerCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
{ {
if (type.getQualifier().storage == EvqUniform) if (type.getQualifier().storage == EvqUniform)
return; return;
@ -2093,7 +2093,7 @@ void TParseContext::samplerCheck(TSourceLoc loc, const TType& type, const TStrin
error(loc, "sampler/image types can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str()); error(loc, "sampler/image types can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str());
} }
void TParseContext::atomicUintCheck(TSourceLoc loc, const TType& type, const TString& identifier) void TParseContext::atomicUintCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
{ {
if (type.getQualifier().storage == EvqUniform) if (type.getQualifier().storage == EvqUniform)
return; return;
@ -2107,7 +2107,7 @@ void TParseContext::atomicUintCheck(TSourceLoc loc, const TType& type, const TSt
// //
// Check/fix just a full qualifier (no variables or types yet, but qualifier is complete) at global level. // Check/fix just a full qualifier (no variables or types yet, but qualifier is complete) at global level.
// //
void TParseContext::globalQualifierFixCheck(TSourceLoc loc, TQualifier& qualifier) void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& qualifier)
{ {
// move from parameter/unknown qualifiers to pipeline in/out qualifiers // move from parameter/unknown qualifiers to pipeline in/out qualifiers
switch (qualifier.storage) { switch (qualifier.storage) {
@ -2135,7 +2135,7 @@ void TParseContext::globalQualifierFixCheck(TSourceLoc loc, TQualifier& qualifie
// //
// Check a full qualifier and type (no variable yet) at global level. // Check a full qualifier and type (no variable yet) at global level.
// //
void TParseContext::globalQualifierTypeCheck(TSourceLoc loc, const TQualifier& qualifier, const TPublicType& publicType) void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQualifier& qualifier, const TPublicType& publicType)
{ {
if (! symbolTable.atGlobalLevel()) if (! symbolTable.atGlobalLevel())
return; return;
@ -2271,7 +2271,7 @@ void TParseContext::globalQualifierTypeCheck(TSourceLoc loc, const TQualifier& q
// 'dst', for the purpose of error checking order for versions // 'dst', for the purpose of error checking order for versions
// that require specific orderings of qualifiers. // that require specific orderings of qualifiers.
// //
void TParseContext::mergeQualifiers(TSourceLoc loc, TQualifier& dst, const TQualifier& src, bool force) void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, const TQualifier& src, bool force)
{ {
// Multiple auxiliary qualifiers (mostly done later by 'individual qualifiers') // Multiple auxiliary qualifiers (mostly done later by 'individual qualifiers')
if (src.isAuxiliary() && dst.isAuxiliary()) if (src.isAuxiliary() && dst.isAuxiliary())
@ -2342,7 +2342,7 @@ void TParseContext::mergeQualifiers(TSourceLoc loc, TQualifier& dst, const TQual
error(loc, "replicated qualifiers", "", ""); error(loc, "replicated qualifiers", "", "");
} }
void TParseContext::setDefaultPrecision(TSourceLoc loc, TPublicType& publicType, TPrecisionQualifier qualifier) void TParseContext::setDefaultPrecision(const TSourceLoc& loc, TPublicType& publicType, TPrecisionQualifier qualifier)
{ {
TBasicType basicType = publicType.basicType; TBasicType basicType = publicType.basicType;
@ -2391,7 +2391,7 @@ TPrecisionQualifier TParseContext::getDefaultPrecision(TPublicType& publicType)
return defaultPrecision[publicType.basicType]; return defaultPrecision[publicType.basicType];
} }
void TParseContext::precisionQualifierCheck(TSourceLoc loc, TBasicType baseType, TQualifier& qualifier) void TParseContext::precisionQualifierCheck(const TSourceLoc& loc, TBasicType baseType, TQualifier& qualifier)
{ {
// Built-in symbols are allowed some ambiguous precisions, to be pinned down // Built-in symbols are allowed some ambiguous precisions, to be pinned down
// later by context. // later by context.
@ -2414,7 +2414,7 @@ void TParseContext::precisionQualifierCheck(TSourceLoc loc, TBasicType baseType,
error(loc, "type cannot have precision qualifier", TType::getBasicString(baseType), ""); error(loc, "type cannot have precision qualifier", TType::getBasicString(baseType), "");
} }
void TParseContext::parameterTypeCheck(TSourceLoc loc, TStorageQualifier qualifier, const TType& type) void TParseContext::parameterTypeCheck(const TSourceLoc& loc, TStorageQualifier qualifier, const TType& type)
{ {
if ((qualifier == EvqOut || qualifier == EvqInOut) && (type.getBasicType() == EbtSampler || type.getBasicType() == EbtAtomicUint)) if ((qualifier == EvqOut || qualifier == EvqInOut) && (type.getBasicType() == EbtSampler || type.getBasicType() == EbtAtomicUint))
error(loc, "samplers and atomic_uints cannot be output parameters", type.getBasicTypeString().c_str(), ""); error(loc, "samplers and atomic_uints cannot be output parameters", type.getBasicTypeString().c_str(), "");
@ -2439,7 +2439,7 @@ bool TParseContext::containsFieldWithBasicType(const TType& type, TBasicType bas
// //
// Do size checking for an array type's size. // Do size checking for an array type's size.
// //
void TParseContext::arraySizeCheck(TSourceLoc loc, TIntermTyped* expr, int& size) void TParseContext::arraySizeCheck(const TSourceLoc& loc, TIntermTyped* expr, int& size)
{ {
TIntermConstantUnion* constant = expr->getAsConstantUnion(); TIntermConstantUnion* constant = expr->getAsConstantUnion();
if (constant == 0 || (constant->getBasicType() != EbtInt && constant->getBasicType() != EbtUint)) { if (constant == 0 || (constant->getBasicType() != EbtInt && constant->getBasicType() != EbtUint)) {
@ -2464,7 +2464,7 @@ void TParseContext::arraySizeCheck(TSourceLoc loc, TIntermTyped* expr, int& size
// //
// Returns true if there is an error. // Returns true if there is an error.
// //
bool TParseContext::arrayQualifierError(TSourceLoc loc, const TQualifier& qualifier) bool TParseContext::arrayQualifierError(const TSourceLoc& loc, const TQualifier& qualifier)
{ {
if (qualifier.storage == EvqConst) { if (qualifier.storage == EvqConst) {
profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, "const array"); profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, "const array");
@ -2485,7 +2485,7 @@ bool TParseContext::arrayQualifierError(TSourceLoc loc, const TQualifier& qualif
// //
// Returns true if there is an error. // Returns true if there is an error.
// //
bool TParseContext::arrayError(TSourceLoc loc, const TType& type) bool TParseContext::arrayError(const TSourceLoc& loc, const TType& type)
{ {
if (type.getQualifier().storage == EvqVaryingOut && language == EShLangVertex) { if (type.getQualifier().storage == EvqVaryingOut && language == EShLangVertex) {
if (type.isArrayOfArrays()) if (type.isArrayOfArrays())
@ -2506,13 +2506,13 @@ bool TParseContext::arrayError(TSourceLoc loc, const TType& type)
// //
// Require array to have size // Require array to have size
// //
void TParseContext::arraySizeRequiredCheck(TSourceLoc loc, int size) void TParseContext::arraySizeRequiredCheck(const TSourceLoc& loc, int size)
{ {
if (size == 0) if (size == 0)
error(loc, "array size required", "", ""); error(loc, "array size required", "", "");
} }
void TParseContext::structArrayCheck(TSourceLoc /*loc*/, const TType& type) void TParseContext::structArrayCheck(const TSourceLoc& /*loc*/, const TType& type)
{ {
const TTypeList& structure = *type.getStruct(); const TTypeList& structure = *type.getStruct();
for (int m = 0; m < (int)structure.size(); ++m) { for (int m = 0; m < (int)structure.size(); ++m) {
@ -2522,7 +2522,7 @@ void TParseContext::structArrayCheck(TSourceLoc /*loc*/, const TType& type)
} }
} }
void TParseContext::arrayUnsizedCheck(TSourceLoc loc, const TQualifier& qualifier, int size, bool initializer) void TParseContext::arrayUnsizedCheck(const TSourceLoc& loc, const TQualifier& qualifier, int size, bool initializer)
{ {
// desktop always allows unsized variable arrays, // desktop always allows unsized variable arrays,
// ES always allows them if there is an initializer present to get the size from // ES always allows them if there is an initializer present to get the size from
@ -2556,7 +2556,7 @@ void TParseContext::arrayUnsizedCheck(TSourceLoc loc, const TQualifier& qualifie
arraySizeRequiredCheck(loc, size); arraySizeRequiredCheck(loc, size);
} }
void TParseContext::arrayOfArrayVersionCheck(TSourceLoc loc) void TParseContext::arrayOfArrayVersionCheck(const TSourceLoc& loc)
{ {
const char* feature = "arrays of arrays"; const char* feature = "arrays of arrays";
@ -2571,7 +2571,7 @@ void TParseContext::arrayOfArrayVersionCheck(TSourceLoc loc)
} }
} }
void TParseContext::arrayDimCheck(TSourceLoc loc, TArraySizes* sizes1, TArraySizes* sizes2) void TParseContext::arrayDimCheck(const TSourceLoc& loc, TArraySizes* sizes1, TArraySizes* sizes2)
{ {
if ((sizes1 && sizes2) || if ((sizes1 && sizes2) ||
(sizes1 && sizes1->getNumDims() > 1) || (sizes1 && sizes1->getNumDims() > 1) ||
@ -2579,7 +2579,7 @@ void TParseContext::arrayDimCheck(TSourceLoc loc, TArraySizes* sizes1, TArraySiz
arrayOfArrayVersionCheck(loc); arrayOfArrayVersionCheck(loc);
} }
void TParseContext::arrayDimCheck(TSourceLoc loc, const TType* type, TArraySizes* sizes2) void TParseContext::arrayDimCheck(const TSourceLoc& loc, const TType* type, TArraySizes* sizes2)
{ {
if ((type && type->isArray() && sizes2) || if ((type && type->isArray() && sizes2) ||
(sizes2 && sizes2->getNumDims() > 1)) (sizes2 && sizes2->getNumDims() > 1))
@ -2592,7 +2592,7 @@ void TParseContext::arrayDimCheck(TSourceLoc loc, const TType* type, TArraySizes
// //
// size == 0 means no specified size. // size == 0 means no specified size.
// //
void TParseContext::declareArray(TSourceLoc loc, TString& identifier, const TType& type, TSymbol*& symbol, bool& newDeclaration) void TParseContext::declareArray(const TSourceLoc& loc, TString& identifier, const TType& type, TSymbol*& symbol, bool& newDeclaration)
{ {
if (! symbol) { if (! symbol) {
bool currentScope; bool currentScope;
@ -2664,7 +2664,7 @@ void TParseContext::declareArray(TSourceLoc loc, TString& identifier, const TTyp
checkIoArraysConsistency(loc); checkIoArraysConsistency(loc);
} }
void TParseContext::updateImplicitArraySize(TSourceLoc loc, TIntermNode *node, int index) void TParseContext::updateImplicitArraySize(const TSourceLoc& loc, TIntermNode *node, int index)
{ {
// maybe there is nothing to do... // maybe there is nothing to do...
TIntermTyped* typedNode = node->getAsTyped(); TIntermTyped* typedNode = node->getAsTyped();
@ -2726,7 +2726,7 @@ bool TParseContext::lineDirectiveShouldSetNextLine() const {
// //
// Enforce non-initializer type/qualifier rules. // Enforce non-initializer type/qualifier rules.
// //
void TParseContext::nonInitConstCheck(TSourceLoc loc, TString& identifier, TType& type) void TParseContext::nonInitConstCheck(const TSourceLoc& loc, TString& identifier, TType& type)
{ {
// //
// Make the qualifier make sense, given that there is an initializer. // Make the qualifier make sense, given that there is an initializer.
@ -2748,7 +2748,7 @@ void TParseContext::nonInitConstCheck(TSourceLoc loc, TString& identifier, TType
// //
// Returns a redeclared and type-modified variable if a redeclarated occurred. // Returns a redeclared and type-modified variable if a redeclarated occurred.
// //
TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString& identifier, const TQualifier& qualifier, const TShaderQualifiers& publicType, bool& newDeclaration) TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TString& identifier, const TQualifier& qualifier, const TShaderQualifiers& publicType, bool& newDeclaration)
{ {
if (! builtInName(identifier) || symbolTable.atBuiltInLevel() || ! symbolTable.atGlobalLevel()) if (! builtInName(identifier) || symbolTable.atBuiltInLevel() || ! symbolTable.atGlobalLevel())
return 0; return 0;
@ -2873,7 +2873,7 @@ TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString&
// Either redeclare the requested block, or give an error message why it can't be done. // Either redeclare the requested block, or give an error message why it can't be done.
// //
// TODO: functionality: explicitly sizing members of redeclared blocks is not giving them an explicit size // TODO: functionality: explicitly sizing members of redeclared blocks is not giving them an explicit size
void TParseContext::redeclareBuiltinBlock(TSourceLoc loc, TTypeList& newTypeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes) void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newTypeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes)
{ {
const char* feature = "built-in block redeclaration"; const char* feature = "built-in block redeclaration";
profileRequires(loc, EEsProfile, 0, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, feature); profileRequires(loc, EEsProfile, 0, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, feature);
@ -3014,7 +3014,7 @@ void TParseContext::redeclareBuiltinBlock(TSourceLoc loc, TTypeList& newTypeList
intermediate.addSymbolLinkageNode(linkage, *block); intermediate.addSymbolLinkageNode(linkage, *block);
} }
void TParseContext::paramCheckFix(TSourceLoc loc, const TStorageQualifier& qualifier, TType& type) void TParseContext::paramCheckFix(const TSourceLoc& loc, const TStorageQualifier& qualifier, TType& type)
{ {
switch (qualifier) { switch (qualifier) {
case EvqConst: case EvqConst:
@ -3037,7 +3037,7 @@ void TParseContext::paramCheckFix(TSourceLoc loc, const TStorageQualifier& quali
} }
} }
void TParseContext::paramCheckFix(TSourceLoc loc, const TQualifier& qualifier, TType& type) void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& qualifier, TType& type)
{ {
if (qualifier.isMemory()) { if (qualifier.isMemory()) {
type.getQualifier().volatil = qualifier.volatil; type.getQualifier().volatil = qualifier.volatil;
@ -3057,21 +3057,21 @@ void TParseContext::paramCheckFix(TSourceLoc loc, const TQualifier& qualifier, T
paramCheckFix(loc, qualifier.storage, type); paramCheckFix(loc, qualifier.storage, type);
} }
void TParseContext::nestedBlockCheck(TSourceLoc loc) void TParseContext::nestedBlockCheck(const TSourceLoc& loc)
{ {
if (structNestingLevel > 0) if (structNestingLevel > 0)
error(loc, "cannot nest a block definition inside a structure or block", "", ""); error(loc, "cannot nest a block definition inside a structure or block", "", "");
++structNestingLevel; ++structNestingLevel;
} }
void TParseContext::nestedStructCheck(TSourceLoc loc) void TParseContext::nestedStructCheck(const TSourceLoc& loc)
{ {
if (structNestingLevel > 0) if (structNestingLevel > 0)
error(loc, "cannot nest a structure definition inside a structure or block", "", ""); error(loc, "cannot nest a structure definition inside a structure or block", "", "");
++structNestingLevel; ++structNestingLevel;
} }
void TParseContext::arrayObjectCheck(TSourceLoc loc, const TType& type, const char* op) void TParseContext::arrayObjectCheck(const TSourceLoc& loc, const TType& type, const char* op)
{ {
// Some versions don't allow comparing arrays or structures containing arrays // Some versions don't allow comparing arrays or structures containing arrays
if (type.containsArray()) { if (type.containsArray()) {
@ -3080,20 +3080,20 @@ void TParseContext::arrayObjectCheck(TSourceLoc loc, const TType& type, const ch
} }
} }
void TParseContext::opaqueCheck(TSourceLoc loc, const TType& type, const char* op) void TParseContext::opaqueCheck(const TSourceLoc& loc, const TType& type, const char* op)
{ {
if (containsFieldWithBasicType(type, EbtSampler)) if (containsFieldWithBasicType(type, EbtSampler))
error(loc, "can't use with samplers or structs containing samplers", op, ""); error(loc, "can't use with samplers or structs containing samplers", op, "");
} }
void TParseContext::structTypeCheck(TSourceLoc /*loc*/, TPublicType& publicType) void TParseContext::structTypeCheck(const TSourceLoc& /*loc*/, TPublicType& publicType)
{ {
const TTypeList& typeList = *publicType.userDef->getStruct(); const TTypeList& typeList = *publicType.userDef->getStruct();
// fix and check for member storage qualifiers and types that don't belong within a structure // fix and check for member storage qualifiers and types that don't belong within a structure
for (unsigned int member = 0; member < typeList.size(); ++member) { for (unsigned int member = 0; member < typeList.size(); ++member) {
TQualifier& memberQualifier = typeList[member].type->getQualifier(); TQualifier& memberQualifier = typeList[member].type->getQualifier();
TSourceLoc memberLoc = typeList[member].loc; const TSourceLoc& memberLoc = typeList[member].loc;
if (memberQualifier.isAuxiliary() || if (memberQualifier.isAuxiliary() ||
memberQualifier.isInterpolation() || memberQualifier.isInterpolation() ||
(memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal)) (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal))
@ -3127,7 +3127,7 @@ void TParseContext::structTypeCheck(TSourceLoc /*loc*/, TPublicType& publicType)
// //
// The body is handled in an AST traversal. // The body is handled in an AST traversal.
// //
void TParseContext::inductiveLoopCheck(TSourceLoc loc, TIntermNode* init, TIntermLoop* loop) void TParseContext::inductiveLoopCheck(const TSourceLoc& loc, TIntermNode* init, TIntermLoop* loop)
{ {
// loop index init must exist and be a declaration, which shows up in the AST as an aggregate of size 1 of the declaration // loop index init must exist and be a declaration, which shows up in the AST as an aggregate of size 1 of the declaration
bool badInit = false; bool badInit = false;
@ -3227,7 +3227,7 @@ void TParseContext::inductiveLoopCheck(TSourceLoc loc, TIntermNode* init, TInter
} }
// Do limit checks against for all built-in arrays. // Do limit checks against for all built-in arrays.
void TParseContext::arrayLimitCheck(TSourceLoc loc, const TString& identifier, int size) void TParseContext::arrayLimitCheck(const TSourceLoc& loc, const TString& identifier, int size)
{ {
if (identifier.compare("gl_TexCoord") == 0) if (identifier.compare("gl_TexCoord") == 0)
limitCheck(loc, size, "gl_MaxTextureCoords", "gl_TexCoord array size"); limitCheck(loc, size, "gl_MaxTextureCoords", "gl_TexCoord array size");
@ -3237,7 +3237,7 @@ void TParseContext::arrayLimitCheck(TSourceLoc loc, const TString& identifier, i
// See if the provided value is less than the symbol indicated by limit, // See if the provided value is less than the symbol indicated by limit,
// which should be a constant in the symbol table. // which should be a constant in the symbol table.
void TParseContext::limitCheck(TSourceLoc loc, int value, const char* limit, const char* feature) void TParseContext::limitCheck(const TSourceLoc& loc, int value, const char* limit, const char* feature)
{ {
TSymbol* symbol = symbolTable.find(limit); TSymbol* symbol = symbolTable.find(limit);
assert(symbol->getAsVariable()); assert(symbol->getAsVariable());
@ -3288,7 +3288,7 @@ void TParseContext::finalErrorCheck()
// Put the id's layout qualification into the public type, for qualifiers not having a number set. // Put the id's layout qualification into the public type, for qualifiers not having a number set.
// This is before we know any type information for error checking. // This is before we know any type information for error checking.
void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, TString& id) void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publicType, TString& id)
{ {
std::transform(id.begin(), id.end(), id.begin(), ::tolower); std::transform(id.begin(), id.end(), id.begin(), ::tolower);
@ -3440,7 +3440,7 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
// Put the id's layout qualifier value into the public type, for qualifiers having a number set. // Put the id's layout qualifier value into the public type, for qualifiers having a number set.
// This is before we know any type information for error checking. // This is before we know any type information for error checking.
void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, TString& id, const TIntermTyped* node) void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publicType, TString& id, const TIntermTyped* node)
{ {
const char* feature = "layout-id value"; const char* feature = "layout-id value";
const char* nonLiteralFeature = "non-literal layout-id value"; const char* nonLiteralFeature = "non-literal layout-id value";
@ -3677,7 +3677,7 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie
} }
// Do error layout error checking given a full variable/block declaration. // Do error layout error checking given a full variable/block declaration.
void TParseContext::layoutObjectCheck(TSourceLoc loc, const TSymbol& symbol) void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symbol)
{ {
const TType& type = symbol.getType(); const TType& type = symbol.getType();
const TQualifier& qualifier = type.getQualifier(); const TQualifier& qualifier = type.getQualifier();
@ -3725,7 +3725,7 @@ void TParseContext::layoutObjectCheck(TSourceLoc loc, const TSymbol& symbol)
} }
// Do layout error checking with respect to a type. // Do layout error checking with respect to a type.
void TParseContext::layoutTypeCheck(TSourceLoc loc, const TType& type) void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
{ {
const TQualifier& qualifier = type.getQualifier(); const TQualifier& qualifier = type.getQualifier();
@ -3859,7 +3859,7 @@ void TParseContext::layoutTypeCheck(TSourceLoc loc, const TType& type)
// Do layout error checking that can be done within a layout qualifier proper, not needing to know // Do layout error checking that can be done within a layout qualifier proper, not needing to know
// if there are blocks, atomic counters, variables, etc. // if there are blocks, atomic counters, variables, etc.
void TParseContext::layoutQualifierCheck(TSourceLoc loc, const TQualifier& qualifier) void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier& qualifier)
{ {
if (qualifier.storage == EvqShared && qualifier.hasLayout()) if (qualifier.storage == EvqShared && qualifier.hasLayout())
error(loc, "cannot apply layout qualifiers to a shared variable", "shared", ""); error(loc, "cannot apply layout qualifiers to a shared variable", "shared", "");
@ -3952,7 +3952,7 @@ void TParseContext::layoutQualifierCheck(TSourceLoc loc, const TQualifier& quali
} }
// For places that can't have shader-level layout qualifiers // For places that can't have shader-level layout qualifiers
void TParseContext::checkNoShaderLayouts(TSourceLoc loc, const TShaderQualifiers& shaderQualifiers) void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQualifiers& shaderQualifiers)
{ {
const char* message = "can only apply to a standalone qualifier"; const char* message = "can only apply to a standalone qualifier";
@ -3975,7 +3975,7 @@ void TParseContext::checkNoShaderLayouts(TSourceLoc loc, const TShaderQualifiers
} }
// Correct and/or advance an object's offset layout qualifier. // Correct and/or advance an object's offset layout qualifier.
void TParseContext::fixOffset(TSourceLoc loc, TSymbol& symbol) void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol)
{ {
const TQualifier& qualifier = symbol.getType().getQualifier(); const TQualifier& qualifier = symbol.getType().getQualifier();
if (symbol.getType().getBasicType() == EbtAtomicUint) { if (symbol.getType().getBasicType() == EbtAtomicUint) {
@ -4008,7 +4008,7 @@ void TParseContext::fixOffset(TSourceLoc loc, TSymbol& symbol)
// //
// Return the function symbol if found, otherwise 0. // Return the function symbol if found, otherwise 0.
// //
const TFunction* TParseContext::findFunction(TSourceLoc loc, const TFunction& call, bool& builtIn) const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
{ {
const TFunction* function = 0; const TFunction* function = 0;
@ -4028,7 +4028,7 @@ const TFunction* TParseContext::findFunction(TSourceLoc loc, const TFunction& ca
} }
// Function finding algorithm for ES and desktop 110. // Function finding algorithm for ES and desktop 110.
const TFunction* TParseContext::findFunctionExact(TSourceLoc loc, const TFunction& call, bool& builtIn) const TFunction* TParseContext::findFunctionExact(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
{ {
TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn); TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn);
if (symbol == 0) { if (symbol == 0) {
@ -4041,7 +4041,7 @@ const TFunction* TParseContext::findFunctionExact(TSourceLoc loc, const TFunctio
} }
// Function finding algorithm for desktop versions 120 through 330. // Function finding algorithm for desktop versions 120 through 330.
const TFunction* TParseContext::findFunction120(TSourceLoc loc, const TFunction& call, bool& builtIn) const TFunction* TParseContext::findFunction120(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
{ {
// first, look for an exact match // first, look for an exact match
TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn); TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn);
@ -4109,7 +4109,7 @@ const TFunction* TParseContext::findFunction120(TSourceLoc loc, const TFunction&
} }
// Function finding algorithm for desktop version 400 and above. // Function finding algorithm for desktop version 400 and above.
const TFunction* TParseContext::findFunction400(TSourceLoc loc, const TFunction& call, bool& builtIn) const TFunction* TParseContext::findFunction400(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
{ {
// TODO: 4.00 functionality: findFunction400() // TODO: 4.00 functionality: findFunction400()
return findFunction120(loc, call, builtIn); return findFunction120(loc, call, builtIn);
@ -4117,7 +4117,7 @@ const TFunction* TParseContext::findFunction400(TSourceLoc loc, const TFunction&
// When a declaration includes a type, but not a variable name, it can be // When a declaration includes a type, but not a variable name, it can be
// to establish defaults. // to establish defaults.
void TParseContext::declareTypeDefaults(TSourceLoc loc, const TPublicType& publicType) void TParseContext::declareTypeDefaults(const TSourceLoc& loc, const TPublicType& publicType)
{ {
if (publicType.basicType == EbtAtomicUint && publicType.qualifier.hasBinding() && publicType.qualifier.hasOffset()) { if (publicType.basicType == EbtAtomicUint && publicType.qualifier.hasBinding() && publicType.qualifier.hasOffset()) {
if (publicType.qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) { if (publicType.qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) {
@ -4140,7 +4140,7 @@ void TParseContext::declareTypeDefaults(TSourceLoc loc, const TPublicType& publi
// Returns a subtree node that computes an initializer, if needed. // Returns a subtree node that computes an initializer, if needed.
// Returns 0 if there is no code to execute for initialization. // Returns 0 if there is no code to execute for initialization.
// //
TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier, const TPublicType& publicType, TArraySizes* arraySizes, TIntermTyped* initializer) TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& identifier, const TPublicType& publicType, TArraySizes* arraySizes, TIntermTyped* initializer)
{ {
TType type(publicType); TType type(publicType);
@ -4252,7 +4252,7 @@ TVariable* TParseContext::makeInternalVariable(const char* name, const TType& ty
// //
// Return the successfully declared variable. // Return the successfully declared variable.
// //
TVariable* TParseContext::declareNonArray(TSourceLoc loc, TString& identifier, TType& type, bool& newDeclaration) TVariable* TParseContext::declareNonArray(const TSourceLoc& loc, TString& identifier, TType& type, bool& newDeclaration)
{ {
// make a new variable // make a new variable
TVariable* variable = new TVariable(&identifier, type); TVariable* variable = new TVariable(&identifier, type);
@ -4274,7 +4274,7 @@ TVariable* TParseContext::declareNonArray(TSourceLoc loc, TString& identifier, T
// Returning 0 just means there is no code to execute to handle the // Returning 0 just means there is no code to execute to handle the
// initializer, which will, for example, be the case for constant initializers. // initializer, which will, for example, be the case for constant initializers.
// //
TIntermNode* TParseContext::executeInitializer(TSourceLoc loc, TIntermTyped* initializer, TVariable* variable) TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyped* initializer, TVariable* variable)
{ {
// //
// Identifier must be of type constant, a global, or a temporary, and // Identifier must be of type constant, a global, or a temporary, and
@ -4373,7 +4373,7 @@ TIntermNode* TParseContext::executeInitializer(TSourceLoc loc, TIntermTyped* ini
// creating a constructor-style initializer, ensuring we get the // creating a constructor-style initializer, ensuring we get the
// same form. // same form.
// //
TIntermTyped* TParseContext::convertInitializerList(TSourceLoc loc, const TType& type, TIntermTyped* initializer) TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const TType& type, TIntermTyped* initializer)
{ {
// Will operate recursively. Once a subtree is found that is constructor style, // Will operate recursively. Once a subtree is found that is constructor style,
// everything below it is already good: Only the "top part" of the initializer // everything below it is already good: Only the "top part" of the initializer
@ -4444,7 +4444,7 @@ TIntermTyped* TParseContext::convertInitializerList(TSourceLoc loc, const TType&
// //
// Returns 0 for an error or the constructed node (aggregate or typed) for no error. // Returns 0 for an error or the constructed node (aggregate or typed) for no error.
// //
TIntermTyped* TParseContext::addConstructor(TSourceLoc loc, TIntermNode* node, const TType& type, TOperator op) TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode* node, const TType& type, TOperator op)
{ {
if (node == 0 || node->getAsTyped() == 0) if (node == 0 || node->getAsTyped() == 0)
return 0; return 0;
@ -4527,7 +4527,7 @@ TIntermTyped* TParseContext::addConstructor(TSourceLoc loc, TIntermNode* node, c
// //
// Returns 0 for an error or the constructed node. // Returns 0 for an error or the constructed node.
// //
TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, TIntermTyped* node, TSourceLoc loc, bool subset) TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, TIntermTyped* node, const TSourceLoc& loc, bool subset)
{ {
TIntermTyped* newNode; TIntermTyped* newNode;
TOperator basicOp; TOperator basicOp;
@ -4617,7 +4617,7 @@ 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. // 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 loc) TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& type, int paramCount, const TSourceLoc& loc)
{ {
TIntermTyped* converted = intermediate.addConversion(EOpConstructStruct, type, node->getAsTyped()); TIntermTyped* converted = intermediate.addConversion(EOpConstructStruct, type, node->getAsTyped());
if (! converted || converted->getType() != type) { if (! converted || converted->getType() != type) {
@ -4633,7 +4633,7 @@ TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& typ
// //
// Do everything needed to add an interface block. // Do everything needed to add an interface block.
// //
void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TString* instanceName, TArraySizes* arraySizes) void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, const TString* instanceName, TArraySizes* arraySizes)
{ {
blockStageIoCheck(loc, currentBlockQualifier); blockStageIoCheck(loc, currentBlockQualifier);
blockQualifierCheck(loc, currentBlockQualifier); blockQualifierCheck(loc, currentBlockQualifier);
@ -4645,7 +4645,7 @@ void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TStr
for (unsigned int member = 0; member < typeList.size(); ++member) { for (unsigned int member = 0; member < typeList.size(); ++member) {
TType& memberType = *typeList[member].type; TType& memberType = *typeList[member].type;
TQualifier& memberQualifier = memberType.getQualifier(); TQualifier& memberQualifier = memberType.getQualifier();
TSourceLoc memberLoc = typeList[member].loc; const TSourceLoc& memberLoc = typeList[member].loc;
globalQualifierFixCheck(memberLoc, memberQualifier); globalQualifierFixCheck(memberLoc, memberQualifier);
if (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal && memberQualifier.storage != currentBlockQualifier.storage) if (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal && memberQualifier.storage != currentBlockQualifier.storage)
error(memberLoc, "member storage qualifier cannot contradict block storage qualifier", memberType.getFieldName().c_str(), ""); error(memberLoc, "member storage qualifier cannot contradict block storage qualifier", memberType.getFieldName().c_str(), "");
@ -4708,7 +4708,7 @@ void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TStr
bool memberWithoutLocation = false; bool memberWithoutLocation = false;
for (unsigned int member = 0; member < typeList.size(); ++member) { for (unsigned int member = 0; member < typeList.size(); ++member) {
TQualifier& memberQualifier = typeList[member].type->getQualifier(); TQualifier& memberQualifier = typeList[member].type->getQualifier();
TSourceLoc memberLoc = typeList[member].loc; const TSourceLoc& memberLoc = typeList[member].loc;
if (memberQualifier.hasStream()) { if (memberQualifier.hasStream()) {
if (defaultQualification.layoutStream != memberQualifier.layoutStream) if (defaultQualification.layoutStream != memberQualifier.layoutStream)
error(memberLoc, "member cannot contradict block", "stream", ""); error(memberLoc, "member cannot contradict block", "stream", "");
@ -4830,7 +4830,7 @@ void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TStr
// Do all block-declaration checking regarding the combination of in/out/uniform/buffer // Do all block-declaration checking regarding the combination of in/out/uniform/buffer
// with a particular stage. // with a particular stage.
void TParseContext::blockStageIoCheck(TSourceLoc loc, const TQualifier& qualifier) void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& qualifier)
{ {
switch (qualifier.storage) { switch (qualifier.storage) {
case EvqUniform: case EvqUniform:
@ -4866,7 +4866,7 @@ void TParseContext::blockStageIoCheck(TSourceLoc loc, const TQualifier& qualifie
} }
// Do all block-declaration checking regarding its qualifers. // Do all block-declaration checking regarding its qualifers.
void TParseContext::blockQualifierCheck(TSourceLoc loc, const TQualifier& qualifier) void TParseContext::blockQualifierCheck(const TSourceLoc& loc, const TQualifier& qualifier)
{ {
// The 4.5 specification says: // The 4.5 specification says:
// //
@ -4902,7 +4902,7 @@ void TParseContext::blockQualifierCheck(TSourceLoc loc, const TQualifier& qualif
// declaration. Subsequent members are again assigned consecutive locations, based on the newest location, // declaration. Subsequent members are again assigned consecutive locations, based on the newest location,
// until the next member declared with a location qualifier. The values used for locations do not have to be // until the next member declared with a location qualifier. The values used for locations do not have to be
// declared in increasing order." // declared in increasing order."
void TParseContext::fixBlockLocations(TSourceLoc loc, TQualifier& qualifier, TTypeList& typeList, bool memberWithLocation, bool memberWithoutLocation) void TParseContext::fixBlockLocations(const TSourceLoc& loc, TQualifier& qualifier, TTypeList& typeList, bool memberWithLocation, bool memberWithoutLocation)
{ {
// "If a block has no block-level location layout qualifier, it is required that either all or none of its members // "If a block has no block-level location layout qualifier, it is required that either all or none of its members
// have a location layout qualifier, or a compile-time error results." // have a location layout qualifier, or a compile-time error results."
@ -4925,7 +4925,7 @@ void TParseContext::fixBlockLocations(TSourceLoc loc, TQualifier& qualifier, TTy
} }
for (unsigned int member = 0; member < typeList.size(); ++member) { for (unsigned int member = 0; member < typeList.size(); ++member) {
TQualifier& memberQualifier = typeList[member].type->getQualifier(); TQualifier& memberQualifier = typeList[member].type->getQualifier();
TSourceLoc memberLoc = typeList[member].loc; const TSourceLoc& memberLoc = typeList[member].loc;
if (! memberQualifier.hasLocation()) { if (! memberQualifier.hasLocation()) {
if (nextLocation >= TQualifier::layoutLocationEnd) if (nextLocation >= TQualifier::layoutLocationEnd)
error(memberLoc, "location is too large", "location", ""); error(memberLoc, "location is too large", "location", "");
@ -4986,7 +4986,7 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ
int memberSize; int memberSize;
for (unsigned int member = 0; member < typeList.size(); ++member) { for (unsigned int member = 0; member < typeList.size(); ++member) {
TQualifier& memberQualifier = typeList[member].type->getQualifier(); TQualifier& memberQualifier = typeList[member].type->getQualifier();
TSourceLoc memberLoc = typeList[member].loc; const TSourceLoc& memberLoc = typeList[member].loc;
// "When align is applied to an array, it effects only the start of the array, not the array's internal stride." // "When align is applied to an array, it effects only the start of the array, not the array's internal stride."
@ -5024,7 +5024,7 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ
} }
// For an identifier that is already declared, add more qualification to it. // For an identifier that is already declared, add more qualification to it.
void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier, const TString& identifier) void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qualifier, const TString& identifier)
{ {
TSymbol* symbol = symbolTable.find(identifier); TSymbol* symbol = symbolTable.find(identifier);
if (! symbol) { if (! symbol) {
@ -5060,13 +5060,13 @@ void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier,
warn(loc, "unknown requalification", "", ""); warn(loc, "unknown requalification", "", "");
} }
void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier, TIdentifierList& identifiers) void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qualifier, TIdentifierList& identifiers)
{ {
for (unsigned int i = 0; i < identifiers.size(); ++i) for (unsigned int i = 0; i < identifiers.size(); ++i)
addQualifierToExisting(loc, qualifier, *identifiers[i]); addQualifierToExisting(loc, qualifier, *identifiers[i]);
} }
void TParseContext::invariantCheck(TSourceLoc loc, const TQualifier& qualifier) void TParseContext::invariantCheck(const TSourceLoc& loc, const TQualifier& qualifier)
{ {
if (! qualifier.invariant) if (! qualifier.invariant)
return; return;
@ -5086,7 +5086,7 @@ void TParseContext::invariantCheck(TSourceLoc loc, const TQualifier& qualifier)
// Updating default qualifier for the case of a declaration with just a qualifier, // Updating default qualifier for the case of a declaration with just a qualifier,
// no type, block, or identifier. // no type, block, or identifier.
// //
void TParseContext::updateStandaloneQualifierDefaults(TSourceLoc loc, const TPublicType& publicType) void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, const TPublicType& publicType)
{ {
if (publicType.shaderQualifiers.vertices) { if (publicType.shaderQualifiers.vertices) {
assert(language == EShLangTessControl || language == EShLangGeometry); assert(language == EShLangTessControl || language == EShLangGeometry);
@ -5289,7 +5289,7 @@ void TParseContext::wrapupSwitchSubsequence(TIntermAggregate* statements, TInter
// Turn the top-level node sequence built up of wrapupSwitchSubsequence9) // Turn the top-level node sequence built up of wrapupSwitchSubsequence9)
// into a switch node. // into a switch node.
// //
TIntermNode* TParseContext::addSwitch(TSourceLoc loc, TIntermTyped* expression, TIntermAggregate* lastStatements) TIntermNode* TParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expression, TIntermAggregate* lastStatements)
{ {
profileRequires(loc, EEsProfile, 300, nullptr, "switch statements"); profileRequires(loc, EEsProfile, 300, nullptr, "switch statements");
profileRequires(loc, ENoProfile, 130, nullptr, "switch statements"); profileRequires(loc, ENoProfile, 130, nullptr, "switch statements");
@ -5346,10 +5346,10 @@ void TParseContext::notifyErrorDirective(int line, const char* error_message)
} }
} }
void TParseContext::notifyLineDirective(int curLineNo, int newLineNo, bool hasSource, int sourceNum) void TParseContext::notifyLineDirective(int curLineNo, int newLineNo, bool hasSource, int sourceNum, const char* sourceName)
{ {
if (lineCallback) { if (lineCallback) {
lineCallback(curLineNo, newLineNo, hasSource, sourceNum); lineCallback(curLineNo, newLineNo, hasSource, sourceNum, sourceName);
} }
} }

View File

@ -74,13 +74,13 @@ public:
void parserError(const char* s); // for bison's yyerror void parserError(const char* s); // for bison's yyerror
const char* getPreamble(); const char* getPreamble();
void C_DECL error(TSourceLoc, const char* szReason, const char* szToken, void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...); const char* szExtraInfoFormat, ...);
void C_DECL warn(TSourceLoc, const char* szReason, const char* szToken, void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...); const char* szExtraInfoFormat, ...);
void C_DECL ppError(TSourceLoc, const char* szReason, const char* szToken, void C_DECL ppError(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...); const char* szExtraInfoFormat, ...);
void C_DECL ppWarn(TSourceLoc, const char* szReason, const char* szToken, void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...); const char* szExtraInfoFormat, ...);
bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; } bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; }
@ -88,123 +88,123 @@ public:
bool vulkanRules() const { return (messages & EShMsgVulkanRules) != 0; } bool vulkanRules() const { return (messages & EShMsgVulkanRules) != 0; }
bool spirvRules() const { return (messages & EShMsgSpvRules) != 0; } bool spirvRules() const { return (messages & EShMsgSpvRules) != 0; }
void reservedErrorCheck(TSourceLoc, const TString&); void reservedErrorCheck(const TSourceLoc&, const TString&);
void reservedPpErrorCheck(TSourceLoc, const char* name, const char* op); void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op);
bool lineContinuationCheck(TSourceLoc, bool endOfComment); bool lineContinuationCheck(const TSourceLoc&, bool endOfComment);
bool builtInName(const TString&); bool builtInName(const TString&);
void handlePragma(TSourceLoc, const TVector<TString>&); void handlePragma(const TSourceLoc&, const TVector<TString>&);
TIntermTyped* handleVariable(TSourceLoc, TSymbol* symbol, const TString* string); TIntermTyped* handleVariable(const TSourceLoc&, TSymbol* symbol, const TString* string);
TIntermTyped* handleBracketDereference(TSourceLoc, TIntermTyped* base, TIntermTyped* index); TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
void checkIndex(TSourceLoc, const TType&, int& index); void checkIndex(const TSourceLoc&, const TType&, int& index);
void handleIndexLimits(TSourceLoc, TIntermTyped* base, TIntermTyped* index); void handleIndexLimits(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
void makeEditable(TSymbol*&); void makeEditable(TSymbol*&);
bool isIoResizeArray(const TType&) const; bool isIoResizeArray(const TType&) const;
void fixIoArraySize(TSourceLoc, TType&); void fixIoArraySize(const TSourceLoc&, TType&);
void ioArrayCheck(TSourceLoc, const TType&, const TString& identifier); void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier);
void handleIoResizeArrayAccess(TSourceLoc, TIntermTyped* base); void handleIoResizeArrayAccess(const TSourceLoc&, TIntermTyped* base);
void checkIoArraysConsistency(TSourceLoc, bool tailOnly = false); void checkIoArraysConsistency(const TSourceLoc&, bool tailOnly = false);
int getIoArrayImplicitSize() const; int getIoArrayImplicitSize() const;
void checkIoArrayConsistency(TSourceLoc, int requiredSize, const char* feature, TType&, const TString&); void checkIoArrayConsistency(const TSourceLoc&, int requiredSize, const char* feature, TType&, const TString&);
TIntermTyped* handleBinaryMath(TSourceLoc, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right); TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);
TIntermTyped* handleUnaryMath(TSourceLoc, const char* str, TOperator op, TIntermTyped* childNode); TIntermTyped* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode);
TIntermTyped* handleDotDereference(TSourceLoc, TIntermTyped* base, const TString& field); TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field);
void blockMemberExtensionCheck(TSourceLoc, const TIntermTyped* base, const TString& field); void blockMemberExtensionCheck(const TSourceLoc&, const TIntermTyped* base, const TString& field);
TFunction* handleFunctionDeclarator(TSourceLoc, TFunction& function, bool prototype); TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
TIntermAggregate* handleFunctionDefinition(TSourceLoc, TFunction&); TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
TIntermTyped* handleFunctionCall(TSourceLoc, TFunction*, TIntermNode*); TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
void checkLocation(TSourceLoc, TOperator); void checkLocation(const TSourceLoc&, TOperator);
TIntermTyped* handleLengthMethod(TSourceLoc, TFunction*, TIntermNode*); TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*);
void addInputArgumentConversions(const TFunction&, TIntermNode*&) const; void addInputArgumentConversions(const TFunction&, TIntermNode*&) const;
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const; TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const;
void nonOpBuiltInCheck(TSourceLoc, const TFunction&, TIntermAggregate&); void nonOpBuiltInCheck(const TSourceLoc&, const TFunction&, TIntermAggregate&);
TFunction* handleConstructorCall(TSourceLoc, const TPublicType&); TFunction* handleConstructorCall(const TSourceLoc&, const TPublicType&);
bool parseVectorFields(TSourceLoc, const TString&, int vecSize, TVectorFields&); bool parseVectorFields(const TSourceLoc&, const TString&, int vecSize, TVectorFields&);
void assignError(TSourceLoc, const char* op, TString left, TString right); void assignError(const TSourceLoc&, const char* op, TString left, TString right);
void unaryOpError(TSourceLoc, const char* op, TString operand); void unaryOpError(const TSourceLoc&, const char* op, TString operand);
void binaryOpError(TSourceLoc, const char* op, TString left, TString right); void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right);
void variableCheck(TIntermTyped*& nodePtr); void variableCheck(TIntermTyped*& nodePtr);
bool lValueErrorCheck(TSourceLoc, const char* op, TIntermTyped*); bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
void rValueErrorCheck(TSourceLoc, const char* op, TIntermTyped*); void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
void constantValueCheck(TIntermTyped* node, const char* token); void constantValueCheck(TIntermTyped* node, const char* token);
void integerCheck(const TIntermTyped* node, const char* token); void integerCheck(const TIntermTyped* node, const char* token);
void globalCheck(TSourceLoc, const char* token); void globalCheck(const TSourceLoc&, const char* token);
bool constructorError(TSourceLoc, TIntermNode*, TFunction&, TOperator, TType&); bool constructorError(const TSourceLoc&, TIntermNode*, TFunction&, TOperator, TType&);
void arraySizeCheck(TSourceLoc, TIntermTyped* expr, int& size); void arraySizeCheck(const TSourceLoc&, TIntermTyped* expr, int& size);
bool arrayQualifierError(TSourceLoc, const TQualifier&); bool arrayQualifierError(const TSourceLoc&, const TQualifier&);
bool arrayError(TSourceLoc, const TType&); bool arrayError(const TSourceLoc&, const TType&);
void arraySizeRequiredCheck(TSourceLoc, int size); void arraySizeRequiredCheck(const TSourceLoc&, int size);
void structArrayCheck(TSourceLoc, const TType& structure); void structArrayCheck(const TSourceLoc&, const TType& structure);
void arrayUnsizedCheck(TSourceLoc, const TQualifier&, int size, bool initializer); void arrayUnsizedCheck(const TSourceLoc&, const TQualifier&, int size, bool initializer);
void arrayOfArrayVersionCheck(TSourceLoc); void arrayOfArrayVersionCheck(const TSourceLoc&);
void arrayDimCheck(TSourceLoc, TArraySizes* sizes1, TArraySizes* sizes2); void arrayDimCheck(const TSourceLoc&, TArraySizes* sizes1, TArraySizes* sizes2);
void arrayDimCheck(TSourceLoc, const TType*, TArraySizes*); void arrayDimCheck(const TSourceLoc&, const TType*, TArraySizes*);
bool voidErrorCheck(TSourceLoc, const TString&, TBasicType); bool voidErrorCheck(const TSourceLoc&, const TString&, TBasicType);
void boolCheck(TSourceLoc, const TIntermTyped*); void boolCheck(const TSourceLoc&, const TIntermTyped*);
void boolCheck(TSourceLoc, const TPublicType&); void boolCheck(const TSourceLoc&, const TPublicType&);
void samplerCheck(TSourceLoc, const TType&, const TString& identifier); void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier);
void atomicUintCheck(TSourceLoc, const TType&, const TString& identifier); void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier);
void globalQualifierFixCheck(TSourceLoc, TQualifier&); void globalQualifierFixCheck(const TSourceLoc&, TQualifier&);
void globalQualifierTypeCheck(TSourceLoc, const TQualifier&, const TPublicType&); void globalQualifierTypeCheck(const TSourceLoc&, const TQualifier&, const TPublicType&);
bool structQualifierErrorCheck(TSourceLoc, const TPublicType& pType); bool structQualifierErrorCheck(const TSourceLoc&, const TPublicType& pType);
void mergeQualifiers(TSourceLoc, TQualifier& dst, const TQualifier& src, bool force); void mergeQualifiers(const TSourceLoc&, TQualifier& dst, const TQualifier& src, bool force);
void setDefaultPrecision(TSourceLoc, TPublicType&, TPrecisionQualifier); void setDefaultPrecision(const TSourceLoc&, TPublicType&, TPrecisionQualifier);
int computeSamplerTypeIndex(TSampler&); int computeSamplerTypeIndex(TSampler&);
TPrecisionQualifier getDefaultPrecision(TPublicType&); TPrecisionQualifier getDefaultPrecision(TPublicType&);
void precisionQualifierCheck(TSourceLoc, TBasicType, TQualifier&); void precisionQualifierCheck(const TSourceLoc&, TBasicType, TQualifier&);
void parameterTypeCheck(TSourceLoc, TStorageQualifier qualifier, const TType& type); void parameterTypeCheck(const TSourceLoc&, TStorageQualifier qualifier, const TType& type);
bool containsFieldWithBasicType(const TType& type ,TBasicType basicType); bool containsFieldWithBasicType(const TType& type ,TBasicType basicType);
TSymbol* redeclareBuiltinVariable(TSourceLoc, const TString&, const TQualifier&, const TShaderQualifiers&, bool& newDeclaration); TSymbol* redeclareBuiltinVariable(const TSourceLoc&, const TString&, const TQualifier&, const TShaderQualifiers&, bool& newDeclaration);
void redeclareBuiltinBlock(TSourceLoc, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes); void redeclareBuiltinBlock(const TSourceLoc&, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes);
void paramCheckFix(TSourceLoc, const TStorageQualifier&, TType& type); void paramCheckFix(const TSourceLoc&, const TStorageQualifier&, TType& type);
void paramCheckFix(TSourceLoc, const TQualifier&, TType& type); void paramCheckFix(const TSourceLoc&, const TQualifier&, TType& type);
void nestedBlockCheck(TSourceLoc); void nestedBlockCheck(const TSourceLoc&);
void nestedStructCheck(TSourceLoc); void nestedStructCheck(const TSourceLoc&);
void arrayObjectCheck(TSourceLoc, const TType&, const char* op); void arrayObjectCheck(const TSourceLoc&, const TType&, const char* op);
void opaqueCheck(TSourceLoc, const TType&, const char* op); void opaqueCheck(const TSourceLoc&, const TType&, const char* op);
void structTypeCheck(TSourceLoc, TPublicType&); void structTypeCheck(const TSourceLoc&, TPublicType&);
void inductiveLoopCheck(TSourceLoc, TIntermNode* init, TIntermLoop* loop); void inductiveLoopCheck(const TSourceLoc&, TIntermNode* init, TIntermLoop* loop);
void arrayLimitCheck(TSourceLoc, const TString&, int size); void arrayLimitCheck(const TSourceLoc&, const TString&, int size);
void limitCheck(TSourceLoc, int value, const char* limit, const char* feature); void limitCheck(const TSourceLoc&, int value, const char* limit, const char* feature);
void inductiveLoopBodyCheck(TIntermNode*, int loopIndexId, TSymbolTable&); void inductiveLoopBodyCheck(TIntermNode*, int loopIndexId, TSymbolTable&);
void constantIndexExpressionCheck(TIntermNode*); void constantIndexExpressionCheck(TIntermNode*);
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&); void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&);
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&, const TIntermTyped*); void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&, const TIntermTyped*);
void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly); void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly);
void layoutObjectCheck(TSourceLoc, const TSymbol&); void layoutObjectCheck(const TSourceLoc&, const TSymbol&);
void layoutTypeCheck(TSourceLoc, const TType&); void layoutTypeCheck(const TSourceLoc&, const TType&);
void layoutQualifierCheck(TSourceLoc, const TQualifier&); void layoutQualifierCheck(const TSourceLoc&, const TQualifier&);
void checkNoShaderLayouts(TSourceLoc, const TShaderQualifiers&); void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);
void fixOffset(TSourceLoc, TSymbol&); void fixOffset(const TSourceLoc&, TSymbol&);
const TFunction* findFunction(TSourceLoc loc, const TFunction& call, bool& builtIn); const TFunction* findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
const TFunction* findFunctionExact(TSourceLoc loc, const TFunction& call, bool& builtIn); const TFunction* findFunctionExact(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
const TFunction* findFunction120(TSourceLoc loc, const TFunction& call, bool& builtIn); const TFunction* findFunction120(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
const TFunction* findFunction400(TSourceLoc loc, const TFunction& call, bool& builtIn); const TFunction* findFunction400(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
void declareTypeDefaults(TSourceLoc, const TPublicType&); void declareTypeDefaults(const TSourceLoc&, const TPublicType&);
TIntermNode* declareVariable(TSourceLoc, TString& identifier, const TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0); TIntermNode* declareVariable(const TSourceLoc&, TString& identifier, const TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0);
TIntermTyped* addConstructor(TSourceLoc, TIntermNode*, const TType&, TOperator); TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&, TOperator);
TIntermTyped* constructStruct(TIntermNode*, const TType&, int, TSourceLoc); TIntermTyped* constructStruct(TIntermNode*, const TType&, int, const TSourceLoc&);
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, TSourceLoc, bool subset); TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
void declareBlock(TSourceLoc, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0); void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
void blockStageIoCheck(TSourceLoc, const TQualifier&); void blockStageIoCheck(const TSourceLoc&, const TQualifier&);
void blockQualifierCheck(TSourceLoc, const TQualifier&); void blockQualifierCheck(const TSourceLoc&, const TQualifier&);
void fixBlockLocations(TSourceLoc, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation); void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
void fixBlockXfbOffsets(TQualifier&, TTypeList&); void fixBlockXfbOffsets(TQualifier&, TTypeList&);
void fixBlockUniformOffsets(TQualifier&, TTypeList&); void fixBlockUniformOffsets(TQualifier&, TTypeList&);
void addQualifierToExisting(TSourceLoc, TQualifier, const TString& identifier); void addQualifierToExisting(const TSourceLoc&, TQualifier, const TString& identifier);
void addQualifierToExisting(TSourceLoc, TQualifier, TIdentifierList&); void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&);
void invariantCheck(TSourceLoc, const TQualifier&); void invariantCheck(const TSourceLoc&, const TQualifier&);
void updateStandaloneQualifierDefaults(TSourceLoc, const TPublicType&); void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&);
void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode); void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
TIntermNode* addSwitch(TSourceLoc, TIntermTyped* expression, TIntermAggregate* body); TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body);
void updateImplicitArraySize(TSourceLoc, TIntermNode*, int index); void updateImplicitArraySize(const TSourceLoc&, TIntermNode*, int index);
void setScanContext(TScanContext* c) { scanContext = c; } void setScanContext(TScanContext* c) { scanContext = c; }
TScanContext* getScanContext() const { return scanContext; } TScanContext* getScanContext() const { return scanContext; }
@ -214,6 +214,7 @@ public:
int getNumErrors() const { return numErrors; } int getNumErrors() const { return numErrors; }
const TSourceLoc& getCurrentLoc() const { return currentScanner->getSourceLoc(); } const TSourceLoc& getCurrentLoc() const { return currentScanner->getSourceLoc(); }
void setCurrentLine(int line) { currentScanner->setLine(line); } void setCurrentLine(int line) { currentScanner->setLine(line); }
void setCurrentSourceName(const char* name) { currentScanner->setFile(name); }
void setCurrentString(int string) { currentScanner->setString(string); } void setCurrentString(int string) { currentScanner->setString(string); }
void setScanner(TInputScanner* scanner) { currentScanner = scanner; } void setScanner(TInputScanner* scanner) { currentScanner = scanner; }
@ -221,44 +222,44 @@ public:
void notifyVersion(int line, int version, const char* type_string); void notifyVersion(int line, int version, const char* type_string);
void notifyErrorDirective(int line, const char* error_message); void notifyErrorDirective(int line, const char* error_message);
void notifyLineDirective(int curLineNo, int newLineNo, bool hasSource, int sourceNum); void notifyLineDirective(int curLineNo, int newLineNo, bool hasSource, int sourceNum, const char* sourceName);
void notifyExtensionDirective(int line, const char* extension, const char* behavior); void notifyExtensionDirective(int line, const char* extension, const char* behavior);
// The following are implemented in Versions.cpp to localize version/profile/stage/extensions control // The following are implemented in Versions.cpp to localize version/profile/stage/extensions control
void initializeExtensionBehavior(); void initializeExtensionBehavior();
void requireProfile(TSourceLoc, int queryProfiles, const char* featureDesc); void requireProfile(const TSourceLoc&, int queryProfiles, const char* featureDesc);
void profileRequires(TSourceLoc, int queryProfiles, int minVersion, int numExtensions, const char* const extensions[], const char* featureDesc); void profileRequires(const TSourceLoc&, int queryProfiles, int minVersion, int numExtensions, const char* const extensions[], const char* featureDesc);
void profileRequires(TSourceLoc, int queryProfiles, int minVersion, const char* const extension, const char* featureDesc); void profileRequires(const TSourceLoc&, int queryProfiles, int minVersion, const char* const extension, const char* featureDesc);
void requireStage(TSourceLoc, EShLanguageMask, const char* featureDesc); void requireStage(const TSourceLoc&, EShLanguageMask, const char* featureDesc);
void requireStage(TSourceLoc, EShLanguage, const char* featureDesc); void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc);
void checkDeprecated(TSourceLoc, int queryProfiles, int depVersion, const char* featureDesc); void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc);
void requireNotRemoved(TSourceLoc, int queryProfiles, int removedVersion, const char* featureDesc); void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc);
void requireExtensions(TSourceLoc, int numExtensions, const char* const extensions[], const char* featureDesc); void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
TExtensionBehavior getExtensionBehavior(const char*); TExtensionBehavior getExtensionBehavior(const char*);
bool extensionTurnedOn(const char* const extension); bool extensionTurnedOn(const char* const extension);
bool extensionsTurnedOn(int numExtensions, const char* const extensions[]); bool extensionsTurnedOn(int numExtensions, const char* const extensions[]);
void updateExtensionBehavior(int line, const char* const extension, const char* behavior); void updateExtensionBehavior(int line, const char* const extension, const char* behavior);
void fullIntegerCheck(TSourceLoc, const char* op); void fullIntegerCheck(const TSourceLoc&, const char* op);
void doubleCheck(TSourceLoc, const char* op); void doubleCheck(const TSourceLoc&, const char* op);
void setVersionCallback(const std::function<void(int, int, const char*)>& func) { versionCallback = func; } void setVersionCallback(const std::function<void(int, int, const char*)>& func) { versionCallback = func; }
void setPragmaCallback(const std::function<void(int, const TVector<TString>&)>& func) { pragmaCallback = func; } void setPragmaCallback(const std::function<void(int, const TVector<TString>&)>& func) { pragmaCallback = func; }
void setLineCallback(const std::function<void(int, int, bool, int)>& func) { lineCallback = func; } void setLineCallback(const std::function<void(int, int, bool, int, const char*)>& func) { lineCallback = func; }
void setExtensionCallback(const std::function<void(int, const char*, const char*)>& func) { extensionCallback = func; } void setExtensionCallback(const std::function<void(int, const char*, const char*)>& func) { extensionCallback = func; }
void setErrorCallback(const std::function<void(int, const char*)>& func) { errorCallback = func; } void setErrorCallback(const std::function<void(int, const char*)>& func) { errorCallback = func; }
protected: protected:
void nonInitConstCheck(TSourceLoc, TString& identifier, TType& type); void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type);
void inheritGlobalDefaults(TQualifier& dst) const; void inheritGlobalDefaults(TQualifier& dst) const;
TVariable* makeInternalVariable(const char* name, const TType&) const; TVariable* makeInternalVariable(const char* name, const TType&) const;
TVariable* declareNonArray(TSourceLoc, TString& identifier, TType&, bool& newDeclaration); TVariable* declareNonArray(const TSourceLoc&, TString& identifier, TType&, bool& newDeclaration);
void declareArray(TSourceLoc, TString& identifier, const TType&, TSymbol*&, bool& newDeclaration); void declareArray(const TSourceLoc&, TString& identifier, const TType&, TSymbol*&, bool& newDeclaration);
TIntermNode* executeInitializer(TSourceLoc, TIntermTyped* initializer, TVariable* variable); TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
TIntermTyped* convertInitializerList(TSourceLoc, const TType&, TIntermTyped* initializer); TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
TOperator mapTypeToConstructorOp(const TType&) const; TOperator mapTypeToConstructorOp(const TType&) const;
void updateExtensionBehavior(const char* const extension, TExtensionBehavior); void updateExtensionBehavior(const char* const extension, TExtensionBehavior);
void finalErrorCheck(); void finalErrorCheck();
void outputMessage(TSourceLoc, const char* szReason, const char* szToken, void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, TPrefixType prefix, const char* szExtraInfoFormat, TPrefixType prefix,
va_list args); va_list args);
@ -357,7 +358,7 @@ protected:
// These, if set, will be called when a line, pragma ... is preprocessed. // These, if set, will be called when a line, pragma ... is preprocessed.
// They will be called with any parameters to the original directive. // They will be called with any parameters to the original directive.
std::function<void(int, int, bool, int)> lineCallback; std::function<void(int, int, bool, int, const char*)> lineCallback;
std::function<void(int, const TVector<TString>&)> pragmaCallback; std::function<void(int, const TVector<TString>&)> pragmaCallback;
std::function<void(int, int, const char*)> versionCallback; std::function<void(int, int, const char*)> versionCallback;
std::function<void(int, const char*, const char*)> extensionCallback; std::function<void(int, const char*, const char*)> extensionCallback;

View File

@ -57,6 +57,9 @@ public:
lengths(L), currentSource(0), currentChar(0), stringBias(b), finale(f) lengths(L), currentSource(0), currentChar(0), stringBias(b), finale(f)
{ {
loc = new TSourceLoc[numSources]; loc = new TSourceLoc[numSources];
for (int i = 0; i < numSources; ++i) {
loc[i].init();
}
loc[currentSource].string = -stringBias; loc[currentSource].string = -stringBias;
loc[currentSource].line = 1; loc[currentSource].line = 1;
loc[currentSource].column = 0; loc[currentSource].column = 0;
@ -140,7 +143,12 @@ public:
// for #line override // for #line override
void setLine(int newLine) { loc[getLastValidSourceIndex()].line = newLine; } void setLine(int newLine) { loc[getLastValidSourceIndex()].line = newLine; }
void setString(int newString) { loc[getLastValidSourceIndex()].string = newString; } void setFile(const char* filename) { loc[getLastValidSourceIndex()].name = filename; }
void setString(int newString)
{
loc[getLastValidSourceIndex()].string = newString;
loc[getLastValidSourceIndex()].name = nullptr;
}
const TSourceLoc& getSourceLoc() const { return loc[std::max(0, std::min(currentSource, numSources - finale - 1))]; } const TSourceLoc& getSourceLoc() const { return loc[std::max(0, std::min(currentSource, numSources - finale - 1))]; }
// Returns the index (starting from 0) of the most recent valid source string we are reading from. // Returns the index (starting from 0) of the most recent valid source string we are reading from.

View File

@ -690,12 +690,17 @@ struct DoPreprocessing {
}); });
parseContext.setLineCallback([&lineSync, &outputStream, &parseContext]( parseContext.setLineCallback([&lineSync, &outputStream, &parseContext](
int curLineNum, int newLineNum, bool hasSource, int sourceNum) { int curLineNum, int newLineNum, bool hasSource, int sourceNum, const char* sourceName) {
// SourceNum is the number of the source-string that is being parsed. // SourceNum is the number of the source-string that is being parsed.
lineSync.syncToLine(curLineNum); lineSync.syncToLine(curLineNum);
outputStream << "#line " << newLineNum; outputStream << "#line " << newLineNum;
if (hasSource) { if (hasSource) {
outputStream << " " << sourceNum; outputStream << " ";
if (sourceName != nullptr) {
outputStream << "\"" << sourceName << "\"";
} else {
outputStream << sourceNum;
}
} }
if (parseContext.lineDirectiveShouldSetNextLine()) { if (parseContext.lineDirectiveShouldSetNextLine()) {
// newLineNum is the new line number for the line following the #line // newLineNum is the new line number for the line following the #line

View File

@ -190,6 +190,7 @@ void TParseContext::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_tessellation_point_size] = EBhDisable; extensionBehavior[E_GL_EXT_tessellation_point_size] = EBhDisable;
extensionBehavior[E_GL_EXT_texture_buffer] = EBhDisablePartial; extensionBehavior[E_GL_EXT_texture_buffer] = EBhDisablePartial;
extensionBehavior[E_GL_EXT_texture_cube_map_array] = EBhDisablePartial; extensionBehavior[E_GL_EXT_texture_cube_map_array] = EBhDisablePartial;
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
// OES matching AEP // OES matching AEP
extensionBehavior[E_GL_OES_geometry_shader] = EBhDisable; extensionBehavior[E_GL_OES_geometry_shader] = EBhDisable;
@ -233,6 +234,7 @@ const char* TParseContext::getPreamble()
"#define GL_EXT_tessellation_point_size 1\n" "#define GL_EXT_tessellation_point_size 1\n"
"#define GL_EXT_texture_buffer 1\n" "#define GL_EXT_texture_buffer 1\n"
"#define GL_EXT_texture_cube_map_array 1\n" "#define GL_EXT_texture_cube_map_array 1\n"
"#define GL_GOOGLE_cpp_style_line_directive 1\n"
// OES matching AEP // OES matching AEP
"#define GL_OES_geometry_shader 1\n" "#define GL_OES_geometry_shader 1\n"
@ -264,6 +266,7 @@ const char* TParseContext::getPreamble()
"#define GL_ARB_derivative_control 1\n" "#define GL_ARB_derivative_control 1\n"
"#define GL_ARB_shader_texture_image_samples 1\n" "#define GL_ARB_shader_texture_image_samples 1\n"
"#define GL_ARB_viewport_array 1\n" "#define GL_ARB_viewport_array 1\n"
"#define GL_GOOGLE_cpp_style_line_directive 1\n"
// "#define GL_ARB_cull_distance 1\n" // present for 4.5, but need extension control over block members // "#define GL_ARB_cull_distance 1\n" // present for 4.5, but need extension control over block members
; ;
} }
@ -278,7 +281,7 @@ const char* TParseContext::getPreamble()
// Operation: If the current profile is not one of the profileMask, // Operation: If the current profile is not one of the profileMask,
// give an error message. // give an error message.
// //
void TParseContext::requireProfile(TSourceLoc loc, int profileMask, const char* featureDesc) void TParseContext::requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc)
{ {
if (! (profile & profileMask)) if (! (profile & profileMask))
error(loc, "not supported with this profile:", featureDesc, ProfileName(profile)); error(loc, "not supported with this profile:", featureDesc, ProfileName(profile));
@ -317,7 +320,7 @@ const char* StageName(EShLanguage stage)
// //
// entry point that takes multiple extensions // entry point that takes multiple extensions
void TParseContext::profileRequires(TSourceLoc loc, int profileMask, int minVersion, int numExtensions, const char* const extensions[], const char* featureDesc) void TParseContext::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions, const char* const extensions[], const char* featureDesc)
{ {
if (profile & profileMask) { if (profile & profileMask) {
bool okay = false; bool okay = false;
@ -342,7 +345,7 @@ void TParseContext::profileRequires(TSourceLoc loc, int profileMask, int minVers
} }
// entry point for the above that takes a single extension // entry point for the above that takes a single extension
void TParseContext::profileRequires(TSourceLoc loc, int profileMask, int minVersion, const char* extension, const char* featureDesc) void TParseContext::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension, const char* featureDesc)
{ {
profileRequires(loc, profileMask, minVersion, extension ? 1 : 0, &extension, featureDesc); profileRequires(loc, profileMask, minVersion, extension ? 1 : 0, &extension, featureDesc);
} }
@ -354,7 +357,7 @@ void TParseContext::profileRequires(TSourceLoc loc, int profileMask, int minVers
// //
// Operation: If the current stage is not present, give an error message. // Operation: If the current stage is not present, give an error message.
// //
void TParseContext::requireStage(TSourceLoc loc, EShLanguageMask languageMask, const char* featureDesc) void TParseContext::requireStage(const TSourceLoc& loc, EShLanguageMask languageMask, const char* featureDesc)
{ {
if (((1 << language) & languageMask) == 0) if (((1 << language) & languageMask) == 0)
error(loc, "not supported in this stage:", featureDesc, StageName(language)); error(loc, "not supported in this stage:", featureDesc, StageName(language));
@ -362,7 +365,7 @@ void TParseContext::requireStage(TSourceLoc loc, EShLanguageMask languageMask, c
// If only one stage supports a feature, this can be called. But, all supporting stages // If only one stage supports a feature, this can be called. But, all supporting stages
// must be specified with one call. // must be specified with one call.
void TParseContext::requireStage(TSourceLoc loc, EShLanguage stage, const char* featureDesc) void TParseContext::requireStage(const TSourceLoc& loc, EShLanguage stage, const char* featureDesc)
{ {
requireStage(loc, static_cast<EShLanguageMask>(1 << stage), featureDesc); requireStage(loc, static_cast<EShLanguageMask>(1 << stage), featureDesc);
} }
@ -371,7 +374,7 @@ void TParseContext::requireStage(TSourceLoc loc, EShLanguage stage, const char*
// Within a set of profiles, see if a feature is deprecated and give an error or warning based on whether // Within a set of profiles, see if a feature is deprecated and give an error or warning based on whether
// a future compatibility context is being use. // a future compatibility context is being use.
// //
void TParseContext::checkDeprecated(TSourceLoc loc, int profileMask, int depVersion, const char* featureDesc) void TParseContext::checkDeprecated(const TSourceLoc& loc, int profileMask, int depVersion, const char* featureDesc)
{ {
if (profile & profileMask) { if (profile & profileMask) {
if (version >= depVersion) { if (version >= depVersion) {
@ -388,7 +391,7 @@ void TParseContext::checkDeprecated(TSourceLoc loc, int profileMask, int depVers
// Within a set of profiles, see if a feature has now been removed and if so, give an error. // Within a set of profiles, 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. // The version argument is the first version no longer having the feature.
// //
void TParseContext::requireNotRemoved(TSourceLoc loc, int profileMask, int removedVersion, const char* featureDesc) void TParseContext::requireNotRemoved(const TSourceLoc& loc, int profileMask, int removedVersion, const char* featureDesc)
{ {
if (profile & profileMask) { if (profile & profileMask) {
if (version >= removedVersion) { if (version >= removedVersion) {
@ -404,7 +407,7 @@ void TParseContext::requireNotRemoved(TSourceLoc loc, int profileMask, int remov
// Use when there are no profile/version to check, it's just an error if one of the // Use when there are no profile/version to check, it's just an error if one of the
// extensions is not present. // extensions is not present.
// //
void TParseContext::requireExtensions(TSourceLoc loc, int numExtensions, const char* const extensions[], const char* featureDesc) void TParseContext::requireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
{ {
// First, see if any of the extensions are enabled // First, see if any of the extensions are enabled
for (int i = 0; i < numExtensions; ++i) { for (int i = 0; i < numExtensions; ++i) {
@ -564,7 +567,7 @@ void TParseContext::updateExtensionBehavior(const char* extension, TExtensionBeh
// //
// Call for any operation needing full GLSL integer data-type support. // Call for any operation needing full GLSL integer data-type support.
// //
void TParseContext::fullIntegerCheck(TSourceLoc loc, const char* op) void TParseContext::fullIntegerCheck(const TSourceLoc& loc, const char* op)
{ {
profileRequires(loc, ENoProfile, 130, nullptr, op); profileRequires(loc, ENoProfile, 130, nullptr, op);
profileRequires(loc, EEsProfile, 300, nullptr, op); profileRequires(loc, EEsProfile, 300, nullptr, op);
@ -573,7 +576,7 @@ void TParseContext::fullIntegerCheck(TSourceLoc loc, const char* op)
// //
// Call for any operation needing GLSL double data-type support. // Call for any operation needing GLSL double data-type support.
// //
void TParseContext::doubleCheck(TSourceLoc loc, const char* op) void TParseContext::doubleCheck(const TSourceLoc& loc, const char* op)
{ {
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op); requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
profileRequires(loc, ECoreProfile, 400, nullptr, op); profileRequires(loc, ECoreProfile, 400, nullptr, op);

View File

@ -129,6 +129,8 @@ const char* const E_GL_EXT_tessellation_point_size = "GL_EXT_tessel
const char* const E_GL_EXT_texture_buffer = "GL_EXT_texture_buffer"; const char* const E_GL_EXT_texture_buffer = "GL_EXT_texture_buffer";
const char* const E_GL_EXT_texture_cube_map_array = "GL_EXT_texture_cube_map_array"; const char* const E_GL_EXT_texture_cube_map_array = "GL_EXT_texture_cube_map_array";
const char* const E_GL_GOOGLE_cpp_style_line_directive = "GL_GOOGLE_cpp_style_line_directive";
// OES matching AEP // OES matching AEP
const char* const E_GL_OES_geometry_shader = "GL_OES_geometry_shader"; const char* const E_GL_OES_geometry_shader = "GL_OES_geometry_shader";
const char* const E_GL_OES_geometry_point_size = "GL_OES_geometry_point_size"; const char* const E_GL_OES_geometry_point_size = "GL_OES_geometry_point_size";

View File

@ -155,42 +155,42 @@ public:
int getNumErrors() const { return numErrors; } int getNumErrors() const { return numErrors; }
bool isRecursive() const { return recursive; } bool isRecursive() const { return recursive; }
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, TSourceLoc); TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TSourceLoc&);
TIntermSymbol* addSymbol(const TVariable&, TSourceLoc); TIntermSymbol* addSymbol(const TVariable&, const TSourceLoc&);
TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*) const; TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*) const;
TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc); TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc); TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc); TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc);
TIntermTyped* addUnaryMath(TOperator, TIntermTyped* child, TSourceLoc); TIntermTyped* addUnaryMath(TOperator, TIntermTyped* child, TSourceLoc);
TIntermTyped* addBuiltInFunctionCall(TSourceLoc line, TOperator, bool unary, TIntermNode*, const TType& returnType); TIntermTyped* addBuiltInFunctionCall(const TSourceLoc& line, TOperator, bool unary, TIntermNode*, const TType& returnType);
bool canImplicitlyPromote(TBasicType from, TBasicType to) const; bool canImplicitlyPromote(TBasicType from, TBasicType to) const;
TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right); TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right);
TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc); TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&);
TIntermAggregate* makeAggregate(TIntermNode* node); TIntermAggregate* makeAggregate(TIntermNode* node);
TIntermAggregate* makeAggregate(TIntermNode* node, TSourceLoc); TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&);
TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, TSourceLoc); TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, TSourceLoc);
bool areAllChildConst(TIntermAggregate* aggrNode); bool areAllChildConst(TIntermAggregate* aggrNode);
TIntermNode* addSelection(TIntermTyped* cond, TIntermNodePair code, TSourceLoc); TIntermNode* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&);
TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc); TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&);
TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc); TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, TSourceLoc); TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, const TSourceLoc&);
TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, TSourceLoc, bool literal = false) const; TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, const TSourceLoc&, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(int, TSourceLoc, bool literal = false) const; TIntermConstantUnion* addConstantUnion(int, const TSourceLoc&, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(unsigned int, TSourceLoc, bool literal = false) const; TIntermConstantUnion* addConstantUnion(unsigned int, const TSourceLoc&, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(bool, TSourceLoc, bool literal = false) const; TIntermConstantUnion* addConstantUnion(bool, const TSourceLoc&, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(double, TBasicType, TSourceLoc, bool literal = false) const; TIntermConstantUnion* addConstantUnion(double, TBasicType, const TSourceLoc&, bool literal = false) const;
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const; TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const;
bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false); bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false);
TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, TSourceLoc); TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&);
TIntermBranch* addBranch(TOperator, TSourceLoc); TIntermBranch* addBranch(TOperator, const TSourceLoc&);
TIntermBranch* addBranch(TOperator, TIntermTyped*, TSourceLoc); TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&);
TIntermTyped* addSwizzle(TVectorFields&, TSourceLoc); TIntermTyped* addSwizzle(TVectorFields&, const TSourceLoc&);
// Constant folding (in Constant.cpp) // Constant folding (in Constant.cpp)
TIntermTyped* fold(TIntermAggregate* aggrNode); TIntermTyped* fold(TIntermAggregate* aggrNode);
TIntermTyped* foldConstructor(TIntermAggregate* aggrNode); TIntermTyped* foldConstructor(TIntermAggregate* aggrNode);
TIntermTyped* foldDereference(TIntermTyped* node, int index, TSourceLoc); TIntermTyped* foldDereference(TIntermTyped* node, int index, const TSourceLoc&);
TIntermTyped* foldSwizzle(TIntermTyped* node, TVectorFields& fields, TSourceLoc); TIntermTyped* foldSwizzle(TIntermTyped* node, TVectorFields& fields, const TSourceLoc&);
// Linkage related // Linkage related
void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&); void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);

View File

@ -604,7 +604,7 @@ int TPpContext::CPPline(TPpToken* ppToken)
// "#line line source-string-number" // "#line line source-string-number"
int token = scanToken(ppToken); int token = scanToken(ppToken);
const int directiveLoc = ppToken->loc.line; const TSourceLoc directiveLoc = ppToken->loc;
if (token == '\n') { if (token == '\n') {
parseContext.ppError(ppToken->loc, "must by followed by an integral literal", "#line", ""); parseContext.ppError(ppToken->loc, "must by followed by an integral literal", "#line", "");
return token; return token;
@ -612,8 +612,9 @@ int TPpContext::CPPline(TPpToken* ppToken)
int lineRes = 0; // Line number after macro expansion. int lineRes = 0; // Line number after macro expansion.
int lineToken = 0; int lineToken = 0;
int fileRes = 0; // Source file number after macro expansion.
bool hasFile = false; bool hasFile = false;
int fileRes = 0; // Source file number after macro expansion.
const char* sourceName = nullptr; // Optional source file name.
bool lineErr = false; bool lineErr = false;
bool fileErr = false; bool fileErr = false;
token = eval(token, MIN_PRECEDENCE, false, lineRes, lineErr, ppToken); token = eval(token, MIN_PRECEDENCE, false, lineRes, lineErr, ppToken);
@ -627,14 +628,26 @@ int TPpContext::CPPline(TPpToken* ppToken)
parseContext.setCurrentLine(lineRes); parseContext.setCurrentLine(lineRes);
if (token != '\n') { if (token != '\n') {
token = eval(token, MIN_PRECEDENCE, false, fileRes, fileErr, ppToken); if (token == PpAtomConstString) {
if (! fileErr) parseContext.requireExtensions(directiveLoc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based #line");
parseContext.setCurrentString(fileRes); // We need to save a copy of the string instead of pointing
// to the name field of the token since the name field
// will likely be overwritten by the next token scan.
sourceName = GetAtomString(LookUpAddString(ppToken->name));
parseContext.setCurrentSourceName(sourceName);
hasFile = true; hasFile = true;
token = scanToken(ppToken);
} else {
token = eval(token, MIN_PRECEDENCE, false, fileRes, fileErr, ppToken);
if (! fileErr) {
parseContext.setCurrentString(fileRes);
hasFile = true;
}
}
} }
} }
if (!fileErr && !lineErr) { if (!fileErr && !lineErr) {
parseContext.notifyLineDirective(directiveLoc, lineToken, hasFile, fileRes); parseContext.notifyLineDirective(directiveLoc.line, lineToken, hasFile, fileRes, sourceName);
} }
token = extraTokenCheck(PpAtomLine, ppToken, token); token = extraTokenCheck(PpAtomLine, ppToken, token);
@ -952,11 +965,17 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool
UngetToken(PpAtomConstInt, ppToken); UngetToken(PpAtomConstInt, ppToken);
return 1; return 1;
case PpAtomFileMacro: case PpAtomFileMacro: {
ppToken->ival = parseContext.getCurrentLoc().string; if (const char* current_file = parseContext.getCurrentLoc().name) {
sprintf(ppToken->name, "%d", ppToken->ival); parseContext.requireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based __FILE__");
sprintf(ppToken->name, "\"%s\"", current_file);
} else {
ppToken->ival = parseContext.getCurrentLoc().string;
sprintf(ppToken->name, "%d", ppToken->ival);
}
UngetToken(PpAtomConstInt, ppToken); UngetToken(PpAtomConstInt, ppToken);
return 1; return 1;
}
case PpAtomVersionMacro: case PpAtomVersionMacro:
ppToken->ival = parseContext.version; ppToken->ival = parseContext.version;