diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp index 0333e5d01f87c5265d5bc640c9b49e4d57b89d29..7f4d7d06c350d37fce9096ad9a18c63ec60a8433 100644 --- a/glslang/MachineIndependent/Intermediate.cpp +++ b/glslang/MachineIndependent/Intermediate.cpp @@ -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 diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index 17e076519282225cfb3e7b3edfb8ecb6ff159f07..28509e62493aadee573deb09cdc4f6ca6f431bb7 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -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 }; diff --git a/glslang/MachineIndependent/preprocessor/Pp.cpp b/glslang/MachineIndependent/preprocessor/Pp.cpp index 8048fa513d2837dc1bb9e4a47d76987f709774dd..b7560846274f5b82d80efba1be84b41f1f365768 100644 --- a/glslang/MachineIndependent/preprocessor/Pp.cpp +++ b/glslang/MachineIndependent/preprocessor/Pp.cpp @@ -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') {