External interface change: PP: Full <> and "" semantics for the Includer.
authorJohn Kessenich <cepheus@frii.com>
Fri, 6 Jan 2017 22:01:48 +0000 (15:01 -0700)
committerJohn Kessenich <cepheus@frii.com>
Fri, 6 Jan 2017 22:08:54 +0000 (15:08 -0700)
Any previous use would only be for "", which would probably mean changing

    include(...)  -> includeLocal(...)

See comments about includeLocal() being an additional search over
includeSystem(), not a superset search.

This also removed ForbidIncluder, as
 - the message in ForbidIncluder was redundant: error results were
   already returned to the caller, which then gives the error it
   wants to
 - there is a trivial default implementation that a subclass can
   override any subset of (I still like abstract base classes though)
 - trying to get less implementation out of the interface file anyway

StandAlone/StandAlone.cpp
Test/baseResults/preprocessor.include.disabled.vert.err
Test/baseResults/preprocessor.include.enabled.vert.err
glslang/Include/revision.h
glslang/MachineIndependent/ShaderLang.cpp
glslang/MachineIndependent/preprocessor/Pp.cpp
glslang/Public/ShaderLang.h
gtests/TestFixture.h

index 4ea9613..37313fd 100644 (file)
@@ -582,7 +582,7 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
 
         if (Options & EOptionOutputPreprocessed) {
             std::string str;
-            glslang::TShader::ForbidInclude includer;
+            glslang::TShader::Includer includer;
             if (shader->preprocess(&Resources, defaultVersion, ENoProfile, false, false,
                                    messages, &str, includer)) {
                 PutsIfNonEmpty(str.c_str());
index 836a3d6..1419204 100644 (file)
@@ -3,7 +3,7 @@ ERROR: 0:8000: '#include' : must be followed by a header name
 ERROR: 0:8001: '#include' : required extension not requested: GL_GOOGLE_include_directive
 ERROR: 0:8001: '#include' : must be followed by a header name 
 ERROR: 0:8002: '#include' : required extension not requested: GL_GOOGLE_include_directive
-ERROR: 0:8002: '#include' : unexpected include directive for header name: foo
+ERROR: 0:8002: '#include' : Could not process include directive for header name: foo
 ERROR: 0:8003: '#include' : required extension not requested: GL_GOOGLE_include_directive
 ERROR: 0:8003: '#include' : extra content after header name: foo
 ERROR: 0:8004: '#include' : required extension not requested: GL_GOOGLE_include_directive
index 0b0cbae..252e661 100644 (file)
@@ -1,19 +1,19 @@
 ERROR: 0:8000: '#include' : must be followed by a header name 
 ERROR: 0:8001: '#include' : must be followed by a header name 
-ERROR: 0:8002: '#include' : unexpected include directive for header name: foo.oeu
-ERROR: 0:8003: '#include' : unexpected include directive for header name: foo.oeu/ao eu/ao.h
-ERROR: 0:8004: '#include' : unexpected include directive for header name: foo<oeu
-ERROR: 0:8005: '#include' : unexpected include directive for header name: foo.oe>
-ERROR: 0:8006: '#include' : unexpected include directive for header name: foo.oe
-ERROR: 0:8007: '#include' : unexpected include directive for header name: foo"bar"
-ERROR: 0:8008: '#include' : unexpected include directive for header name: foo\bar
-ERROR: 0:8009: '#include' : unexpected include directive for header name: foo.oe>
-ERROR: 0:8010: '#include' : unexpected include directive for header name: foo
+ERROR: 0:8002: '#include' : Could not process include directive for header name: foo.oeu
+ERROR: 0:8003: '#include' : Could not process include directive for header name: foo.oeu/ao eu/ao.h
+ERROR: 0:8004: '#include' : Could not process include directive for header name: foo<oeu
+ERROR: 0:8005: '#include' : Could not process include directive for header name: foo.oe>
+ERROR: 0:8006: '#include' : Could not process include directive for header name: foo.oe
+ERROR: 0:8007: '#include' : Could not process include directive for header name: foo"bar"
+ERROR: 0:8008: '#include' : Could not process include directive for header name: foo\bar
+ERROR: 0:8009: '#include' : Could not process include directive for header name: foo.oe>
+ERROR: 0:8010: '#include' : Could not process include directive for header name: foo
 ERROR: 0:8011: '#include' : extra content after header name: foo2.h
 ERROR: 0:8012: '#include' : extra content after header name: foo.h
-ERROR: 0:8014: '#include' : unexpected include directive for header name: ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789
+ERROR: 0:8014: '#include' : Could not process include directive for header name: ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789
 ERROR: 0:8016: '' : header name too long 
-ERROR: 0:8016: '#include' : unexpected include directive for header name: ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789
+ERROR: 0:8016: '#include' : Could not process include directive for header name: ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789
 ERROR: 0:8017: '#include' : expected newline after header name: no-eol
 ERROR: 17 compilation errors.  No code generated.
 
index 020d697..852dd2e 100644 (file)
@@ -2,5 +2,5 @@
 // For the version, it uses the latest git tag followed by the number of commits.
 // For the date, it uses the current date (when then script is run).
 
-#define GLSLANG_REVISION "Overload400-PrecQual.1748"
+#define GLSLANG_REVISION "Overload400-PrecQual.1750"
 #define GLSLANG_DATE "06-Jan-2017"
index b5e08a7..ac1156e 100644 (file)
@@ -221,7 +221,7 @@ bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profil
                                                                        language, infoSink, spvVersion, true, EShMsgDefault,
                                                                        true));
 
-    TShader::ForbidInclude includer;
+    TShader::Includer includer;
     TPpContext ppContext(*parseContext, "", includer);
     TScanContext scanContext(*parseContext);
     parseContext->setScanContext(&scanContext);
@@ -1217,7 +1217,7 @@ int ShCompile(
     compiler->infoSink.debug.erase();
 
     TIntermediate intermediate(compiler->getLanguage());
-    TShader::ForbidInclude includer;
+    TShader::Includer includer;
     bool success = CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, nullptr,
                                    "", optLevel, resources, defaultVersion, ENoProfile, false,
                                    forwardCompatible, messages, intermediate, includer);
index ca949f5..411806f 100644 (file)
@@ -576,12 +576,12 @@ int TPpContext::CPPifdef(int defined, TPpToken* ppToken)
 int TPpContext::CPPinclude(TPpToken* ppToken)
 {
     const TSourceLoc directiveLoc = ppToken->loc;
-    TShader::Includer::IncludeType includeType = TShader::Includer::EIncludeRelative;
+    bool addLocalSearch = true; // to additionally include the extra "" paths
     int token = scanToken(ppToken);
 
     // handle <header-name>-style #include
     if (token == '<') {
-        includeType = TShader::Includer::EIncludeStandard;
+        addLocalSearch = false;
         token = scanHeaderName(ppToken, '>');
     }
     // otherwise ppToken already has the header name and it was "header-name" style
@@ -605,8 +605,18 @@ int TPpContext::CPPinclude(TPpToken* ppToken)
     }
 
     // Process well-formed directive
-    TShader::Includer::IncludeResult* res = includer.include(filename.c_str(), includeType, currentSourceFile.c_str(),
-                                                             includeStack.size() + 1);
+
+    // Find the inclusion, first look in "Local" ("") paths, if requested,
+    // otherwise, only search the "System" (<>) paths.
+    TShader::Includer::IncludeResult* res = nullptr;
+    if (addLocalSearch)
+        res = includer.includeLocal(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
+    if (! res || res->headerName.empty()) {
+        includer.releaseInclude(res);
+        res = includer.includeSystem(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
+    }
+
+    // Process the results
     if (res && !res->headerName.empty()) {
         if (res->headerData && res->headerLength) {
             // path for processing one or more tokens from an included header, hand off 'res'
index 76ded8d..4b3b1f6 100644 (file)
@@ -331,11 +331,6 @@ public:
     // release the IncludeResult object.
     class Includer {
     public:
-        typedef enum {
-          EIncludeRelative, // For #include "something"
-          EIncludeStandard  // Reserved. For #include <something>
-        } IncludeType;
-
         // An IncludeResult contains the resolved name and content of a source
         // inclusion.
         struct IncludeResult {
@@ -360,7 +355,9 @@ public:
             IncludeResult();
         };
 
-        // Resolves an inclusion request by name, type, current source name,
+        // For both include methods below:
+        //
+        // Resolves an inclusion request by name, current source name,
         // and include depth.
         // On success, returns an IncludeResult containing the resolved name
         // and content of the include.  On failure, returns an IncludeResult
@@ -369,34 +366,33 @@ public:
         // of the returned IncludeResult value, and those contents must
         // remain valid until the releaseInclude method is called on that
         // IncludeResult object.
-        virtual IncludeResult* include(const char* headerName,
-                                      IncludeType type,
-                                      const char* includerName,
-                                      size_t inclusionDepth) = 0;
+        //
+        // Note "local" vs. "system" is not an "either/or": "local" is an
+        // extra thing to do over "system". Both might get called, as per
+        // the C++ specification.
+
+        // For the "system" or <>-style includes; search the "system" paths.
+        virtual IncludeResult* includeSystem(const char* headerName,
+                                             const char* includerName,
+                                             size_t inclusionDepth) { return nullptr; }
+
+        // For the "local"-only aspect of a "" include. Should not search in the
+        // "system" paths, because on returning a failure, the parser will
+        // call includeSystem() to look in the "system" locations.
+        virtual IncludeResult* includeLocal(const char* headerName,
+                                            const char* includerName,
+                                            size_t inclusionDepth) { return nullptr; }
+
         // Signals that the parser will no longer use the contents of the
         // specified IncludeResult.
-        virtual void releaseInclude(IncludeResult* result) = 0;
+        virtual void releaseInclude(IncludeResult* result) { }
         virtual ~Includer() {}
     };
 
-    // Returns an error message for any #include directive.
-    class ForbidInclude : public Includer {
-    public:
-        IncludeResult* include(const char*, IncludeType, const char*, size_t) override
-        {
-            const char* unexpected_include = "unexpected include directive";
-            return new IncludeResult(std::string(""), unexpected_include, strlen(unexpected_include), nullptr);
-        }
-        virtual void releaseInclude(IncludeResult* result) override
-        {
-            delete result;
-        }
-    };
-
     bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
                bool forwardCompatible, EShMessages messages)
     {
-        TShader::ForbidInclude includer;
+        TShader::Includer includer;
         return parse(res, defaultVersion, defaultProfile, forceDefaultVersionAndProfile, forwardCompatible, messages, includer);
     }
 
index e795e8d..ea37714 100644 (file)
@@ -521,7 +521,7 @@ public:
         glslang::TShader shader(EShLangVertex);
         shader.setStringsWithLengths(&shaderStrings, &shaderLengths, 1);
         std::string ppShader;
-        glslang::TShader::ForbidInclude includer;
+        glslang::TShader::Includer includer;
         const bool success = shader.preprocess(
             &glslang::DefaultTBuiltInResource, defaultVersion, defaultProfile,
             forceVersionProfile, isForwardCompatible, (EShMessages)(EShMsgOnlyPreprocessor | EShMsgCascadingErrors),