From 484bb127030b2132ae98f4cd73b933fb4230e128 Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Wed, 5 Aug 2015 11:56:14 -0400 Subject: [PATCH] Create a new ppRequireExtensions method for preprocessor. Now extensions required by preprocessor should be checked via the ppRequireExtensions method. This is more clear and coherent with the rest of the code. --- glslang/MachineIndependent/ParseHelper.h | 6 ++- glslang/MachineIndependent/Versions.cpp | 50 +++++++++++++------ .../MachineIndependent/preprocessor/Pp.cpp | 6 +-- 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index 83d0d563..e008c0f2 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -236,7 +236,8 @@ public: void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc); void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc); void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc); - void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc, bool requiredByPreprocessor = false); + void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc); + void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc); TExtensionBehavior getExtensionBehavior(const char*); bool extensionTurnedOn(const char* const extension); bool extensionsTurnedOn(int numExtensions, const char* const extensions[]); @@ -252,13 +253,14 @@ public: protected: void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type); - void inheritGlobalDefaults(TQualifier& dst) const; + void inheritGlobalDefaults(TQualifier& dst) const; TVariable* makeInternalVariable(const char* name, const TType&) const; TVariable* declareNonArray(const TSourceLoc&, TString& identifier, TType&, bool& newDeclaration); void declareArray(const TSourceLoc&, TString& identifier, const TType&, TSymbol*&, bool& newDeclaration); TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable); TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer); TOperator mapTypeToConstructorOp(const TType&) const; + bool checkExtensionsRequested(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc); void updateExtensionBehavior(const char* const extension, TExtensionBehavior); void finalErrorCheck(); void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken, diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp index 46275b6c..c751076f 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -411,17 +411,15 @@ void TParseContext::requireNotRemoved(const TSourceLoc& loc, int profileMask, in } } -// -// Use when there are no profile/version to check, it's just an error if one of the -// extensions is not present. -// -void TParseContext::requireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc, bool requiredByPreprocessor) +// Returns true if at least one of the extensions in the extensions parameter is requested. Otherwise, returns false. +// Warns appropriately if the requested behavior of an extension is "warn". +bool TParseContext::checkExtensionsRequested(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc) { // First, see if any of the extensions are enabled for (int i = 0; i < numExtensions; ++i) { TExtensionBehavior behavior = getExtensionBehavior(extensions[i]); if (behavior == EBhEnable || behavior == EBhRequire) - return; + return true; } // See if any extensions want to give a warning on use; give warnings for all such extensions @@ -438,19 +436,41 @@ void TParseContext::requireExtensions(const TSourceLoc& loc, int numExtensions, } } if (warned) - return; + return true; + return false; +} + +// +// Use when there are no profile/version to check, it's just an error if one of the +// extensions is not present. +// +void TParseContext::requireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc) +{ + if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc)) return; // If we get this far, give errors explaining what extensions are needed if (numExtensions == 1) - if (requiredByPreprocessor) - ppError(loc, "required extension not requested:", featureDesc, extensions[0]); - else - error(loc, "required extension not requested:", featureDesc, extensions[0]); + error(loc, "required extension not requested:", featureDesc, extensions[0]); else { - if (requiredByPreprocessor) - ppError(loc, "required extension not requested:", featureDesc, "Possible extensions include:"); - else - error(loc, "required extension not requested:", featureDesc, "Possible extensions include:"); + error(loc, "required extension not requested:", featureDesc, "Possible extensions include:"); + for (int i = 0; i < numExtensions; ++i) + infoSink.info.message(EPrefixNone, extensions[i]); + } +} + +// +// Use by preprocessor when there are no profile/version to check, it's just an error if one of the +// extensions is not present. +// +void TParseContext::ppRequireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc) +{ + if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc)) return; + + // If we get this far, give errors explaining what extensions are needed + if (numExtensions == 1) + ppError(loc, "required extension not requested:", featureDesc, extensions[0]); + else { + ppError(loc, "required extension not requested:", featureDesc, "Possible extensions include:"); for (int i = 0; i < numExtensions; ++i) infoSink.info.message(EPrefixNone, extensions[i]); } diff --git a/glslang/MachineIndependent/preprocessor/Pp.cpp b/glslang/MachineIndependent/preprocessor/Pp.cpp index 2ec7e74c..d62b7369 100644 --- a/glslang/MachineIndependent/preprocessor/Pp.cpp +++ b/glslang/MachineIndependent/preprocessor/Pp.cpp @@ -675,7 +675,7 @@ int TPpContext::CPPline(TPpToken* ppToken) if (token != '\n') { if (token == PpAtomConstString) { - parseContext.requireExtensions(directiveLoc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based #line", true); + parseContext.ppRequireExtensions(directiveLoc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based #line"); // We need to save a copy of the string instead of pointing // to the name field of the token since the name field // will likely be overwritten by the next token scan. @@ -892,7 +892,7 @@ int TPpContext::readCPPline(TPpToken* ppToken) token = CPPifdef(0, ppToken); break; case PpAtomInclude: - parseContext.requireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_include_directive, "#include", true); + parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_include_directive, "#include"); token = CPPinclude(ppToken); break; case PpAtomLine: @@ -1017,7 +1017,7 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool case PpAtomFileMacro: { if (const char* current_file = parseContext.getCurrentLoc().name) { - parseContext.requireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based __FILE__", true); + parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based __FILE__"); sprintf(ppToken->name, "\"%s\"", current_file); } else { ppToken->ival = parseContext.getCurrentLoc().string;