Commit 5cbc990a by Lei Zhang

Fix line number handling in line directive callback.

The line argument passed into the lineCallback function is the literal value of the first argument of the #line directive. lastLine in DoPreprocessing() should be updated taking into consideration the different definitions for #line between specs. Add a test to reveal the bug.
parent 3a194f7b
Warning, version 310 is not yet complete; most version-specific features are present, but some are missing.
#version 310 es
#line 1 2
#pragma something
void main(){ }
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#line 2 #line 2
#line 0 #line 0
#line 4 #line 4
#line 8 #line 8
......
#version 310 es
#line 1 2
#pragma something
void main() {}
...@@ -3,5 +3,6 @@ preprocessor.errors.vert ...@@ -3,5 +3,6 @@ preprocessor.errors.vert
preprocessor.extensions.vert preprocessor.extensions.vert
preprocessor.function_macro.vert preprocessor.function_macro.vert
preprocessor.line.vert preprocessor.line.vert
preprocessor.line.frag
preprocessor.pragma.vert preprocessor.pragma.vert
preprocessor.simple.vert preprocessor.simple.vert
...@@ -2654,6 +2654,19 @@ void TParseContext::updateImplicitArraySize(TSourceLoc loc, TIntermNode *node, i ...@@ -2654,6 +2654,19 @@ void TParseContext::updateImplicitArraySize(TSourceLoc loc, TIntermNode *node, i
symbol->getWritableType().setImplicitArraySize(index + 1); symbol->getWritableType().setImplicitArraySize(index + 1);
} }
// Returns true if the first argument to the #line directive is the line number for the next line.
//
// Desktop, pre-version 3.30: "After processing this directive
// (including its new-line), the implementation will behave as if it is compiling at line number line+1 and
// source string number source-string-number."
//
// Desktop, version 3.30 and later, and ES: "After processing this directive
// (including its new-line), the implementation will behave as if it is compiling at line number line and
// source string number source-string-number.
bool TParseContext::lineDirectiveShouldSetNextLine() const {
return profile == EEsProfile || version >= 330;
}
// //
// Enforce non-initializer type/qualifier rules. // Enforce non-initializer type/qualifier rules.
// //
......
...@@ -212,6 +212,8 @@ public: ...@@ -212,6 +212,8 @@ public:
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; }
bool lineDirectiveShouldSetNextLine() const;
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 line, bool has_source, int source); void notifyLineDirective(int line, bool has_source, int source);
......
...@@ -639,18 +639,25 @@ struct DoPreprocessing { ...@@ -639,18 +639,25 @@ struct DoPreprocessing {
adjustLine(line); adjustLine(line);
outputStream << "#extension " << extension << " : " << behavior; outputStream << "#extension " << extension << " : " << behavior;
}); });
parseContext.setLineCallback([&lastLine, &outputStream]( parseContext.setLineCallback([&lastLine, &outputStream, &parseContext](
int line, bool hasSource, int sourceNum) { int newLineNo, bool hasSource, int sourceNum) {
// SourceNum is the number of the source-string that is being parsed. // SourceNum is the number of the source-string that is being parsed.
if (lastLine != -1) { if (lastLine != -1) {
outputStream << std::endl; outputStream << std::endl;
} }
outputStream << "#line " << line; outputStream << "#line " << newLineNo;
if (hasSource) { if (hasSource) {
outputStream << " " << sourceNum; outputStream << " " << sourceNum;
} }
if (parseContext.lineDirectiveShouldSetNextLine()) {
// newLineNo is the new line number for the line following the #line
// directive. So the new line number for the current line is
newLineNo -= 1;
}
outputStream << std::endl; outputStream << std::endl;
lastLine = std::max(line - 1, 1); // Line number starts from 1. And we are at the next line of the #line
// directive now. So lastLine (from 0) should be (newLineNo - 1) + 1.
lastLine = newLineNo;
}); });
......
...@@ -641,14 +641,7 @@ int TPpContext::CPPline(TPpToken* ppToken) ...@@ -641,14 +641,7 @@ int TPpContext::CPPline(TPpToken* ppToken)
if (token == '\n') if (token == '\n')
++lineRes; ++lineRes;
// Desktop, pre-version 3.30: "After processing this directive if (parseContext.lineDirectiveShouldSetNextLine())
// (including its new-line), the implementation will behave as if it is compiling at line number line+1 and
// source string number source-string-number."
//
// Desktop, version 3.30 and later, and ES: "After processing this directive
// (including its new-line), the implementation will behave as if it is compiling at line number line and
// source string number source-string-number.
if (parseContext.profile == EEsProfile || parseContext.version >= 330)
--lineRes; --lineRes;
parseContext.setCurrentLine(lineRes); parseContext.setCurrentLine(lineRes);
......
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