Commit d9b89d3e by John Kessenich

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.
parents c777fc2c 54e47cc2
#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"
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.
#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__
#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"
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
......
...@@ -189,7 +189,8 @@ inline const TString String(const int i, const int base = 10) ...@@ -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;
......
...@@ -95,10 +95,15 @@ public: ...@@ -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: ...@@ -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);
......
...@@ -798,7 +798,7 @@ public: ...@@ -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: ...@@ -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();
......
...@@ -407,8 +407,8 @@ public: ...@@ -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; }
......
...@@ -854,7 +854,7 @@ TIntermTyped* TIntermediate::foldConstructor(TIntermAggregate* aggrNode) ...@@ -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 ...@@ -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);
......
...@@ -59,7 +59,7 @@ namespace glslang { ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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) ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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, ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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) ...@@ -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 ...@@ -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);
......
...@@ -57,6 +57,9 @@ public: ...@@ -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: ...@@ -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.
......
...@@ -690,12 +690,17 @@ struct DoPreprocessing { ...@@ -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
......
...@@ -190,6 +190,7 @@ void TParseContext::initializeExtensionBehavior() ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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) ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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* ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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) ...@@ -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);
......
...@@ -129,6 +129,8 @@ const char* const E_GL_EXT_tessellation_point_size = "GL_EXT_tessel ...@@ -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";
......
...@@ -155,42 +155,42 @@ public: ...@@ -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&);
......
...@@ -604,7 +604,7 @@ int TPpContext::CPPline(TPpToken* ppToken) ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment