add ability to record accessed and declared "named defines"
authorSt0fF <st0ff.npl@gmail.com>
Mon, 9 Apr 2018 17:28:45 +0000 (19:28 +0200)
committerSt0fF <st0ff.npl@gmail.com>
Mon, 9 Apr 2018 17:28:45 +0000 (19:28 +0200)
Added the needed 2 sets to TIntermediate, added accessor-functions, inserter functions.  Implemented recording of such named defines inside the preprocessor parser.

glslang/MachineIndependent/Intermediate.cpp
glslang/MachineIndependent/localintermediate.h
glslang/MachineIndependent/preprocessor/Pp.cpp

index 0333e5d..7f4d7d0 100644 (file)
@@ -3812,4 +3812,15 @@ const char* TIntermediate::getResourceName(TResourceType res)
 }
 
 
+// Access recorded named preprocessor-defines from the outside
+// ->  needs to take into account, that the outside may want to use the set
+//             even after the memory pool got released
+void TIntermediate::getAddDefines( std::unordered_set< std::string > &targetSet, const std::unordered_set< TString > &sourceSet ) const
+{
+       targetSet.reserve( targetSet.size() + sourceSet.size() );
+       for ( auto &i: sourceSet )
+               targetSet.emplace( i.c_str() );         // need to convert from TString (pool-allocated) to normal std::basic_string, so it may be used after the pool is released
+}
+
+
 } // end namespace glslang
index 17e0765..28509e6 100644 (file)
@@ -637,6 +637,11 @@ public:
     const char* const implicitThisName;
     const char* const implicitCounterName;
 
+       void insertAccessedNamedDefine( const char *defName ) { accessedNamedDefines.emplace( defName ); }
+       void insertDeclaredNamedDefine( const char *defName ) { declaredNamedDefines.emplace( defName ); }
+       void getAddAccessedNamedDefines( std::unordered_set< std::string > &targetSet ) const { getAddDefines( targetSet, accessedNamedDefines ); }
+       void getAddDeclaredNamedDefines( std::unordered_set< std::string > &targetSet ) const { getAddDefines( targetSet, declaredNamedDefines ); }
+
 protected:
     TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
     void error(TInfoSink& infoSink, const char*);
@@ -665,6 +670,7 @@ protected:
     std::tuple<TBasicType, TBasicType> getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const;
     bool extensionRequested(const char *extension) const {return requestedExtensions.find(extension) != requestedExtensions.end();}
     static const char* getResourceName(TResourceType);
+       void getAddDefines( std::unordered_set< std::string > &targetSet, const std::unordered_set< TString > &sourceSet ) const;
 
     const EShLanguage language;  // stage, known at construction time
     EShSource source;            // source language, known a bit later
@@ -743,6 +749,9 @@ protected:
 
     bool needToLegalize;
 
+       // storage for (accessed/declared) "named defines"
+       std::unordered_set< TString > accessedNamedDefines, declaredNamedDefines;
+
 private:
     void operator=(TIntermediate&); // prevent assignments
 };
index 8048fa5..b756084 100644 (file)
@@ -102,7 +102,8 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
         parseContext.ppError(ppToken->loc, "must be followed by macro name", "#define", "");
         return token;
     }
-    if (ppToken->loc.string >= 0) {
+       bool inUserCode(ppToken->loc.string >= 0);
+    if (inUserCode) {
         // We are in user code; check for reserved name use:
         parseContext.reservedPpErrorCheck(ppToken->loc, ppToken->name, "#define");
     }
@@ -186,8 +187,11 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
             }
         }
         *existing = mac;
-    } else
-        addMacroDef(defAtom, mac);
+    } else {
+               addMacroDef(defAtom, mac);
+               if ( inUserCode && mac.args.empty() && mac.body.atEnd() )
+                       parseContext.intermediate.insertDeclaredNamedDefine( atomStrings.getString( defAtom ) );
+       }
 
     return '\n';
 }
@@ -248,6 +252,8 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
             } else {
                 ifdepth++;
                 elsetracker++;
+                               if ( nextAtom != PpAtomIf && scanToken( ppToken ) == PpAtomIdentifier )
+                                       parseContext.intermediate.insertAccessedNamedDefine( ppToken->name );
             }
         } else if (nextAtom == PpAtomEndif) {
             token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken));
@@ -420,7 +426,7 @@ int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, boo
 
                 return token;
             }
-
+            parseContext.intermediate.insertAccessedNamedDefine( ppToken->name );
             MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name));
             res = macro != nullptr ? !macro->undef : 0;
             token = scanToken(ppToken);
@@ -577,6 +583,7 @@ int TPpContext::CPPifdef(int defined, TPpToken* ppToken)
         else
             parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifndef", "");
     } else {
+        parseContext.intermediate.insertAccessedNamedDefine( ppToken->name );
         MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name));
         token = scanToken(ppToken);
         if (token != '\n') {