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.errors.vert
preprocessor.extensions.vert
......
......@@ -189,7 +189,8 @@ inline const TString String(const int i, const int base = 10)
}
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 line;
int column;
......
......@@ -95,10 +95,15 @@ public:
default: append("UNKOWN ERROR: "); break;
}
}
void location(TSourceLoc loc) {
const int maxSize = 24;
void location(const TSourceLoc& loc) {
const int maxSize = 24;
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(": ");
}
......@@ -107,7 +112,7 @@ public:
append(s);
append("\n");
}
void message(TPrefixType message, const char* s, TSourceLoc loc) {
void message(TPrefixType message, const char* s, const TSourceLoc& loc) {
prefix(message);
location(loc);
append(s);
......
......@@ -798,7 +798,7 @@ public:
const TType* userDef;
TSourceLoc loc;
void initType(TSourceLoc l)
void initType(const TSourceLoc& l)
{
basicType = EbtVoid;
vectorSize = 1;
......@@ -816,7 +816,7 @@ public:
qualifier.storage = EvqGlobal;
}
void init(TSourceLoc loc, bool global = false)
void init(const TSourceLoc& loc, bool global = false)
{
initType(loc);
sampler.clear();
......
......@@ -407,8 +407,8 @@ public:
POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator())
TIntermNode() { loc.init(); }
virtual glslang::TSourceLoc getLoc() const { return loc; }
virtual void setLoc(glslang::TSourceLoc l) { loc = l; }
virtual const glslang::TSourceLoc& getLoc() const { return loc; }
virtual void setLoc(const glslang::TSourceLoc& l) { loc = l; }
virtual void traverse(glslang::TIntermTraverser*) = 0;
virtual glslang::TIntermTyped* getAsTyped() { return 0; }
virtual glslang::TIntermOperator* getAsOperator() { return 0; }
......
......@@ -854,7 +854,7 @@ TIntermTyped* TIntermediate::foldConstructor(TIntermAggregate* aggrNode)
// dereference. Can handle any thing except a multi-character swizzle, though
// 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);
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
// 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();
TConstUnionArray constArray(fields.num);
......
......@@ -59,7 +59,7 @@ namespace glslang {
//
// 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);
node->setLoc(loc);
......@@ -67,7 +67,7 @@ TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType
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);
}
......@@ -267,7 +267,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSo
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) {
//
......@@ -658,7 +658,7 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r
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);
if (aggNode)
......@@ -684,7 +684,7 @@ TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node)
return aggNode;
}
TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc loc)
TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, const TSourceLoc& loc)
{
if (node == 0)
return 0;
......@@ -703,7 +703,7 @@ TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc loc
//
// 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
......@@ -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
// ... 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;
}
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);
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.
//
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.
......@@ -799,7 +799,7 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
// 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);
node->setLoc(loc);
......@@ -809,7 +809,7 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(const TConstUnionArray& un
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);
unionArray[0].setIConst(i);
......@@ -817,7 +817,7 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(int i, TSourceLoc loc, boo
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);
unionArray[0].setUConst(u);
......@@ -825,7 +825,7 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned int u, TSourceLoc
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);
unionArray[0].setBConst(b);
......@@ -833,7 +833,7 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(bool b, TSourceLoc loc, bo
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);
......@@ -843,7 +843,7 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseT
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);
......@@ -863,7 +863,7 @@ TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc loc)
//
// 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);
node->setLoc(loc);
......@@ -874,12 +874,12 @@ TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TInte
//
// Add branches.
//
TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TSourceLoc loc)
TIntermBranch* TIntermediate::addBranch(TOperator branchOp, const TSourceLoc& 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);
node->setLoc(loc);
......
......@@ -57,6 +57,9 @@ public:
lengths(L), currentSource(0), currentChar(0), stringBias(b), finale(f)
{
loc = new TSourceLoc[numSources];
for (int i = 0; i < numSources; ++i) {
loc[i].init();
}
loc[currentSource].string = -stringBias;
loc[currentSource].line = 1;
loc[currentSource].column = 0;
......@@ -140,7 +143,12 @@ public:
// for #line override
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))]; }
// Returns the index (starting from 0) of the most recent valid source string we are reading from.
......
......@@ -690,12 +690,17 @@ struct DoPreprocessing {
});
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.
lineSync.syncToLine(curLineNum);
outputStream << "#line " << newLineNum;
if (hasSource) {
outputStream << " " << sourceNum;
outputStream << " ";
if (sourceName != nullptr) {
outputStream << "\"" << sourceName << "\"";
} else {
outputStream << sourceNum;
}
}
if (parseContext.lineDirectiveShouldSetNextLine()) {
// newLineNum is the new line number for the line following the #line
......
......@@ -190,6 +190,7 @@ void TParseContext::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_tessellation_point_size] = EBhDisable;
extensionBehavior[E_GL_EXT_texture_buffer] = EBhDisablePartial;
extensionBehavior[E_GL_EXT_texture_cube_map_array] = EBhDisablePartial;
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
// OES matching AEP
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_texture_buffer 1\n"
"#define GL_EXT_texture_cube_map_array 1\n"
"#define GL_GOOGLE_cpp_style_line_directive 1\n"
// OES matching AEP
"#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_shader_texture_image_samples 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
;
}
......@@ -278,7 +281,7 @@ const char* TParseContext::getPreamble()
// Operation: If the current profile is not one of the profileMask,
// 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))
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
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) {
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
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);
}
......@@ -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.
//
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)
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
// 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);
}
......@@ -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
// 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 (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.
// 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 (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
// 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
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.
//
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, 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.
//
void TParseContext::doubleCheck(TSourceLoc loc, const char* op)
void TParseContext::doubleCheck(const TSourceLoc& loc, const char* op)
{
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
profileRequires(loc, ECoreProfile, 400, nullptr, op);
......
......@@ -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_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
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";
......
......@@ -155,42 +155,42 @@ public:
int getNumErrors() const { return numErrors; }
bool isRecursive() const { return recursive; }
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, TSourceLoc);
TIntermSymbol* addSymbol(const TVariable&, TSourceLoc);
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TSourceLoc&);
TIntermSymbol* addSymbol(const TVariable&, const TSourceLoc&);
TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*) const;
TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, 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;
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, TSourceLoc);
TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&);
TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, TSourceLoc);
bool areAllChildConst(TIntermAggregate* aggrNode);
TIntermNode* addSelection(TIntermTyped* cond, TIntermNodePair code, TSourceLoc);
TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc);
TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc);
TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, TSourceLoc);
TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, TSourceLoc, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(int, TSourceLoc, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(unsigned int, TSourceLoc, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(bool, TSourceLoc, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(double, TBasicType, TSourceLoc, bool literal = false) const;
TIntermNode* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&);
TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&);
TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, const TSourceLoc&);
TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, const TSourceLoc&, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(int, const TSourceLoc&, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(unsigned int, const TSourceLoc&, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(bool, const TSourceLoc&, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(double, TBasicType, const TSourceLoc&, bool literal = false) const;
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const;
bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false);
TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, TSourceLoc);
TIntermBranch* addBranch(TOperator, TSourceLoc);
TIntermBranch* addBranch(TOperator, TIntermTyped*, TSourceLoc);
TIntermTyped* addSwizzle(TVectorFields&, TSourceLoc);
TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&);
TIntermBranch* addBranch(TOperator, const TSourceLoc&);
TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&);
TIntermTyped* addSwizzle(TVectorFields&, const TSourceLoc&);
// Constant folding (in Constant.cpp)
TIntermTyped* fold(TIntermAggregate* aggrNode);
TIntermTyped* foldConstructor(TIntermAggregate* aggrNode);
TIntermTyped* foldDereference(TIntermTyped* node, int index, TSourceLoc);
TIntermTyped* foldSwizzle(TIntermTyped* node, TVectorFields& fields, TSourceLoc);
TIntermTyped* foldDereference(TIntermTyped* node, int index, const TSourceLoc&);
TIntermTyped* foldSwizzle(TIntermTyped* node, TVectorFields& fields, const TSourceLoc&);
// Linkage related
void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
......
......@@ -604,7 +604,7 @@ int TPpContext::CPPline(TPpToken* ppToken)
// "#line line source-string-number"
int token = scanToken(ppToken);
const int directiveLoc = ppToken->loc.line;
const TSourceLoc directiveLoc = ppToken->loc;
if (token == '\n') {
parseContext.ppError(ppToken->loc, "must by followed by an integral literal", "#line", "");
return token;
......@@ -612,8 +612,9 @@ int TPpContext::CPPline(TPpToken* ppToken)
int lineRes = 0; // Line number after macro expansion.
int lineToken = 0;
int fileRes = 0; // Source file number after macro expansion.
bool hasFile = false;
int fileRes = 0; // Source file number after macro expansion.
const char* sourceName = nullptr; // Optional source file name.
bool lineErr = false;
bool fileErr = false;
token = eval(token, MIN_PRECEDENCE, false, lineRes, lineErr, ppToken);
......@@ -627,14 +628,26 @@ int TPpContext::CPPline(TPpToken* ppToken)
parseContext.setCurrentLine(lineRes);
if (token != '\n') {
token = eval(token, MIN_PRECEDENCE, false, fileRes, fileErr, ppToken);
if (! fileErr)
parseContext.setCurrentString(fileRes);
if (token == PpAtomConstString) {
parseContext.requireExtensions(directiveLoc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based #line");
// 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;
token = scanToken(ppToken);
} else {
token = eval(token, MIN_PRECEDENCE, false, fileRes, fileErr, ppToken);
if (! fileErr) {
parseContext.setCurrentString(fileRes);
hasFile = true;
}
}
}
}
if (!fileErr && !lineErr) {
parseContext.notifyLineDirective(directiveLoc, lineToken, hasFile, fileRes);
parseContext.notifyLineDirective(directiveLoc.line, lineToken, hasFile, fileRes, sourceName);
}
token = extraTokenCheck(PpAtomLine, ppToken, token);
......@@ -952,11 +965,17 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool
UngetToken(PpAtomConstInt, ppToken);
return 1;
case PpAtomFileMacro:
ppToken->ival = parseContext.getCurrentLoc().string;
sprintf(ppToken->name, "%d", ppToken->ival);
case PpAtomFileMacro: {
if (const char* current_file = parseContext.getCurrentLoc().name) {
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);
return 1;
}
case PpAtomVersionMacro:
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