Output wrapping #line directives for included content.
authorLei Zhang <antiagainst@google.com>
Mon, 6 Jul 2015 14:32:46 +0000 (10:32 -0400)
committerLei Zhang <antiagainst@google.com>
Fri, 31 Jul 2015 23:41:19 +0000 (19:41 -0400)
Also changed the includer interface to let it return the actual
full path of the included file.

Test/baseResults/preprocessor.include.disabled.vert.err
Test/baseResults/preprocessor.include.enabled.vert.err
glslang/MachineIndependent/preprocessor/Pp.cpp
glslang/Public/ShaderLang.h

index 85428de..1145a31 100644 (file)
@@ -3,11 +3,11 @@ ERROR: 0:8000: '#include' : must be followed by a file designation
 ERROR: 0:8001: '#include' : required extension not requested: GL_GOOGLE_include_directive\r
 ERROR: 0:8001: '#include' : must be followed by a file designation\r
 ERROR: 0:8002: '#include' : required extension not requested: GL_GOOGLE_include_directive\r
-ERROR: 0:8002: '#error' : unexpected include directive\r
+ERROR: 0:8002: '#include' : unexpected include directive\r
 ERROR: 0:8003: '#include' : required extension not requested: GL_GOOGLE_include_directive\r
 ERROR: 0:8003: '#include' : extra content after file designation\r
 ERROR: 0:8004: '#include' : required extension not requested: GL_GOOGLE_include_directive\r
-ERROR: 0:8004: '#error' : unexpected include directive\r
+ERROR: 0:8004: '#include' : unexpected include directive\r
 ERROR: 10 compilation errors.  No code generated.\r
 \r
 \r
index edc9ba9..2cdf3f2 100644 (file)
@@ -1,8 +1,8 @@
-ERROR: 0:8000: '#include' : must be followed by a file designation \r
-ERROR: 0:8001: '#include' : must be followed by a file designation \r
-ERROR: 0:8002: '#error' : unexpected include directive  \r
-ERROR: 0:8003: '#include' : extra content after file designation \r
-ERROR: 0:8004: '#error' : unexpected include directive  \r
+ERROR: 0:8000: '#include' : must be followed by a file designation\r
+ERROR: 0:8001: '#include' : must be followed by a file designation\r
+ERROR: 0:8002: '#include' : unexpected include directive\r
+ERROR: 0:8003: '#include' : extra content after file designation\r
+ERROR: 0:8004: '#include' : unexpected include directive\r
 ERROR: 5 compilation errors.  No code generated.\r
 \r
 \r
index 8e58a8c..2ec7e74 100644 (file)
@@ -83,6 +83,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <stdarg.h>
 #include <stdio.h>
+#include <sstream>
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
@@ -605,23 +606,36 @@ int TPpContext::CPPinclude(TPpToken* ppToken)
         // TODO: handle angle brackets.
         parseContext.ppError(directiveLoc, "must be followed by a file designation", "#include", "");
     } else {
-        const char* name = GetAtomString(ppToken->atom);
+        // Make a copy of the name because it will be overwritten by the next token scan.
+        const std::string filename = ppToken->name;
         token = scanToken(ppToken);
         if (token != '\n' && token != EndOfInput) {
             parseContext.ppError(ppToken->loc, "extra content after file designation", "#include", "");
         } else {
-            if (!inputStack.empty()) ungetChar();
+            std::string sourceName;
             std::string replacement;
-            bool success;
-            std::tie(success, replacement) = includer.include(name);
-            if (success) {
-                pushInput(new TokenizableString(directiveLoc, replacement, this));
+            std::tie(sourceName, replacement) = includer.include(filename.c_str());
+            if (!sourceName.empty()) {
+                if (!replacement.empty()) {
+                    const bool forNextLine = parseContext.lineDirectiveShouldSetNextLine();
+                    std::ostringstream content;
+                    content << "#line " << forNextLine << " " << "\"" << sourceName << "\"\n";
+                    content << replacement << (replacement.back() == '\n' ? "" : "\n");
+                    content << "#line " << directiveLoc.line + forNextLine << " ";
+                    if (directiveLoc.name != nullptr) {
+                        content << "\"" << directiveLoc.name << "\"";
+                    } else {
+                        content << directiveLoc.string;
+                    }
+                    content << "\n";
+                    pushInput(new TokenizableString(directiveLoc, content.str(), this));
+                }
                 // At EOF, there's no "current" location anymore.
                 if (token != EndOfInput) parseContext.setCurrentColumn(0);
                 // Don't accidentally return EndOfInput, which will end all preprocessing.
                 return '\n';
             } else {
-                parseContext.ppError(ppToken->loc, "not found", name, "");
+                parseContext.ppError(directiveLoc, replacement.c_str(), "#include", "");
             }
         }
     }
index 7b12ad0..3fbfe35 100644 (file)
@@ -293,17 +293,18 @@ public:
     // Interface to #include handlers.
     class Includer {
     public:
-        // On success, returns true and the content that replaces "#include
-        // filename".  On failure, returns false and an arbitrary string.
-        virtual std::pair<bool, std::string> include(const char* filename) const = 0;
+        // On success, returns the full path and content of the file with the given
+        // filename that replaces "#include filename". On failure, returns an empty
+        // string and an error message.
+        virtual std::pair<std::string, std::string> include(const char* filename) const = 0;
     };
 
-    // Generates #error as #include content.
+    // Returns an error message for any #include directive.
     class ForbidInclude : public Includer {
     public:
-        std::pair<bool, std::string> include(const char* filename) const override
+        std::pair<std::string, std::string> include(const char* filename) const override
         {
-            return std::make_pair<bool, std::string>(true, "#error unexpected include directive\n");
+            return std::make_pair<std::string, std::string>("", "unexpected include directive");
         }
     };