Refactor TParseContext into 3 level inheritance.
Adds parseVersions.h as the base TParseVersions for versioning, and splits the remainder between TParseContextBase (sharable across parsers) and TParseContext (now the GLSL-specific part).
This commit is contained in:
parent
66e2faf844
commit
b3dc3acd59
@ -63,6 +63,7 @@ set(HEADERS
|
|||||||
MachineIndependent/ScanContext.h
|
MachineIndependent/ScanContext.h
|
||||||
MachineIndependent/SymbolTable.h
|
MachineIndependent/SymbolTable.h
|
||||||
MachineIndependent/Versions.h
|
MachineIndependent/Versions.h
|
||||||
|
MachineIndependent/parseVersions.h
|
||||||
MachineIndependent/preprocessor/PpContext.h
|
MachineIndependent/preprocessor/PpContext.h
|
||||||
MachineIndependent/preprocessor/PpTokens.h)
|
MachineIndependent/preprocessor/PpTokens.h)
|
||||||
|
|
||||||
|
@ -48,14 +48,14 @@ extern int yyparse(glslang::TParseContext*);
|
|||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb, int v, EProfile p, int spv, int vulkan, EShLanguage L, TInfoSink& is,
|
TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, bool parsingBuiltins,
|
||||||
bool fc, EShMessages m) :
|
int version, EProfile profile, int spv, int vulkan, EShLanguage language,
|
||||||
intermediate(interm), symbolTable(symt), infoSink(is), language(L),
|
TInfoSink& infoSink, bool forwardCompatible, EShMessages messages) :
|
||||||
version(v), profile(p), spv(spv), vulkan(vulkan), forwardCompatible(fc),
|
TParseContextBase(symbolTable, interm, version, profile, spv, vulkan, language, infoSink, forwardCompatible, messages),
|
||||||
contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0), statementNestingLevel(0),
|
contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0), statementNestingLevel(0),
|
||||||
postMainReturn(false),
|
inMain(false), postMainReturn(false), currentFunctionType(nullptr), blockName(nullptr),
|
||||||
tokensBeforeEOF(false), limits(resources.limits), messages(m), currentScanner(nullptr),
|
limits(resources.limits), parsingBuiltins(parsingBuiltins),
|
||||||
numErrors(0), parsingBuiltins(pb), afterEOF(false),
|
afterEOF(false),
|
||||||
atomicUintOffsets(nullptr), anyIndexLimits(false)
|
atomicUintOffsets(nullptr), anyIndexLimits(false)
|
||||||
{
|
{
|
||||||
// ensure we always have a linkage node, even if empty, to simplify tree topology algorithms
|
// ensure we always have a linkage node, even if empty, to simplify tree topology algorithms
|
||||||
@ -3133,7 +3133,8 @@ void TParseContext::updateImplicitArraySize(const TSourceLoc& loc, TIntermNode *
|
|||||||
// Desktop, version 3.30 and later, and ES: "After processing this directive
|
// Desktop, version 3.30 and later, and ES: "After processing this directive
|
||||||
// (including its new-line), the implementation will behave as if it is compiling at line number line and
|
// (including its new-line), the implementation will behave as if it is compiling at line number line and
|
||||||
// source string number source-string-number.
|
// source string number source-string-number.
|
||||||
bool TParseContext::lineDirectiveShouldSetNextLine() const {
|
bool TParseContext::lineDirectiveShouldSetNextLine() const
|
||||||
|
{
|
||||||
return profile == EEsProfile || version >= 330;
|
return profile == EEsProfile || version >= 330;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5941,32 +5942,4 @@ TIntermNode* TParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expre
|
|||||||
return switchNode;
|
return switchNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TParseContext::notifyVersion(int line, int version, const char* type_string)
|
|
||||||
{
|
|
||||||
if (versionCallback) {
|
|
||||||
versionCallback(line, version, type_string);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TParseContext::notifyErrorDirective(int line, const char* error_message)
|
|
||||||
{
|
|
||||||
if (errorCallback) {
|
|
||||||
errorCallback(line, error_message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TParseContext::notifyLineDirective(int curLineNo, int newLineNo, bool hasSource, int sourceNum, const char* sourceName)
|
|
||||||
{
|
|
||||||
if (lineCallback) {
|
|
||||||
lineCallback(curLineNo, newLineNo, hasSource, sourceNum, sourceName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TParseContext::notifyExtensionDirective(int line, const char* extension, const char* behavior)
|
|
||||||
{
|
|
||||||
if (extensionCallback) {
|
|
||||||
extensionCallback(line, extension, behavior);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
@ -33,10 +33,18 @@
|
|||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
//POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// This header defines a two-level parse-helper hierarchy, derived from
|
||||||
|
// TParseVersions:
|
||||||
|
// - TParseContextBase: sharable across multiple parsers
|
||||||
|
// - TParseContext: GLSL specific helper
|
||||||
|
//
|
||||||
|
|
||||||
#ifndef _PARSER_HELPER_INCLUDED_
|
#ifndef _PARSER_HELPER_INCLUDED_
|
||||||
#define _PARSER_HELPER_INCLUDED_
|
#define _PARSER_HELPER_INCLUDED_
|
||||||
|
|
||||||
#include "Versions.h"
|
#include "parseVersions.h"
|
||||||
#include "../Include/ShHandle.h"
|
#include "../Include/ShHandle.h"
|
||||||
#include "SymbolTable.h"
|
#include "SymbolTable.h"
|
||||||
#include "localintermediate.h"
|
#include "localintermediate.h"
|
||||||
@ -60,10 +68,88 @@ class TPpContext;
|
|||||||
typedef std::set<int> TIdSetType;
|
typedef std::set<int> TIdSetType;
|
||||||
|
|
||||||
//
|
//
|
||||||
// The following are extra variables needed during parsing, grouped together so
|
// Sharable code (as well as what's in TParseVersions) across
|
||||||
// they can be passed to the parser without needing a global.
|
// parse helpers.
|
||||||
//
|
//
|
||||||
class TParseContext {
|
class TParseContextBase : public TParseVersions {
|
||||||
|
public:
|
||||||
|
TParseContextBase(TSymbolTable& symbolTable, TIntermediate& interm, int version,
|
||||||
|
EProfile profile, int spv, int vulkan, EShLanguage language,
|
||||||
|
TInfoSink& infoSink, bool forwardCompatible, EShMessages messages)
|
||||||
|
: TParseVersions(interm, version, profile, spv, vulkan, language, infoSink, forwardCompatible, messages),
|
||||||
|
symbolTable(symbolTable), tokensBeforeEOF(false),
|
||||||
|
linkage(nullptr), scanContext(nullptr), ppContext(nullptr) { }
|
||||||
|
virtual ~TParseContextBase() { }
|
||||||
|
|
||||||
|
virtual void setLimits(const TBuiltInResource&) = 0;
|
||||||
|
|
||||||
|
EShLanguage getLanguage() const { return language; }
|
||||||
|
TIntermAggregate*& getLinkage() { return linkage; }
|
||||||
|
void setScanContext(TScanContext* c) { scanContext = c; }
|
||||||
|
TScanContext* getScanContext() const { return scanContext; }
|
||||||
|
void setPpContext(TPpContext* c) { ppContext = c; }
|
||||||
|
TPpContext* getPpContext() const { return ppContext; }
|
||||||
|
|
||||||
|
virtual void setLineCallback(const std::function<void(int, int, bool, int, const char*)>& func) { lineCallback = func; }
|
||||||
|
virtual void setExtensionCallback(const std::function<void(int, const char*, const char*)>& func) { extensionCallback = func; }
|
||||||
|
virtual void setVersionCallback(const std::function<void(int, int, const char*)>& func) { versionCallback = func; }
|
||||||
|
virtual void setPragmaCallback(const std::function<void(int, const TVector<TString>&)>& func) { pragmaCallback = func; }
|
||||||
|
virtual void setErrorCallback(const std::function<void(int, const char*)>& func) { errorCallback = func; }
|
||||||
|
|
||||||
|
virtual void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op) = 0;
|
||||||
|
virtual bool lineContinuationCheck(const TSourceLoc&, bool endOfComment) = 0;
|
||||||
|
virtual bool lineDirectiveShouldSetNextLine() const = 0;
|
||||||
|
virtual void handlePragma(const TSourceLoc&, const TVector<TString>&) = 0;
|
||||||
|
|
||||||
|
virtual bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) = 0;
|
||||||
|
|
||||||
|
virtual void notifyVersion(int line, int version, const char* type_string)
|
||||||
|
{
|
||||||
|
if (versionCallback)
|
||||||
|
versionCallback(line, version, type_string);
|
||||||
|
}
|
||||||
|
virtual void notifyErrorDirective(int line, const char* error_message)
|
||||||
|
{
|
||||||
|
if (errorCallback)
|
||||||
|
errorCallback(line, error_message);
|
||||||
|
}
|
||||||
|
virtual void notifyLineDirective(int curLineNo, int newLineNo, bool hasSource, int sourceNum, const char* sourceName)
|
||||||
|
{
|
||||||
|
if (lineCallback)
|
||||||
|
lineCallback(curLineNo, newLineNo, hasSource, sourceNum, sourceName);
|
||||||
|
}
|
||||||
|
virtual void notifyExtensionDirective(int line, const char* extension, const char* behavior)
|
||||||
|
{
|
||||||
|
if (extensionCallback)
|
||||||
|
extensionCallback(line, extension, behavior);
|
||||||
|
}
|
||||||
|
|
||||||
|
TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile
|
||||||
|
bool tokensBeforeEOF;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
TParseContextBase(TParseContextBase&);
|
||||||
|
TParseContextBase& operator=(TParseContextBase&);
|
||||||
|
|
||||||
|
TIntermAggregate* linkage; // aggregate node of objects the linker may need, if not referenced by the rest of the AST
|
||||||
|
TScanContext* scanContext;
|
||||||
|
TPpContext* ppContext;
|
||||||
|
|
||||||
|
// These, if set, will be called when a line, pragma ... is preprocessed.
|
||||||
|
// They will be called with any parameters to the original directive.
|
||||||
|
std::function<void(int, int, bool, int, const char*)> lineCallback;
|
||||||
|
std::function<void(int, const TVector<TString>&)> pragmaCallback;
|
||||||
|
std::function<void(int, int, const char*)> versionCallback;
|
||||||
|
std::function<void(int, const char*, const char*)> extensionCallback;
|
||||||
|
std::function<void(int, const char*)> errorCallback;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// GLSL-specific parse helper. Should have GLSL in the name, but that's
|
||||||
|
// too big of a change for comparing branches at the moment, and perhaps
|
||||||
|
// impacts downstream consumers as well.
|
||||||
|
//
|
||||||
|
class TParseContext : public TParseContextBase {
|
||||||
public:
|
public:
|
||||||
TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, int spv, int vulkan, EShLanguage, TInfoSink&,
|
TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, int spv, int vulkan, EShLanguage, TInfoSink&,
|
||||||
bool forwardCompatible = false, EShMessages messages = EShMsgDefault);
|
bool forwardCompatible = false, EShMessages messages = EShMsgDefault);
|
||||||
@ -72,7 +158,6 @@ public:
|
|||||||
void setLimits(const TBuiltInResource&);
|
void setLimits(const TBuiltInResource&);
|
||||||
bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false);
|
bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false);
|
||||||
void parserError(const char* s); // for bison's yyerror
|
void parserError(const char* s); // for bison's yyerror
|
||||||
const char* getPreamble();
|
|
||||||
|
|
||||||
void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
|
void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
const char* szExtraInfoFormat, ...);
|
const char* szExtraInfoFormat, ...);
|
||||||
@ -83,12 +168,10 @@ public:
|
|||||||
void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
|
void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
const char* szExtraInfoFormat, ...);
|
const char* szExtraInfoFormat, ...);
|
||||||
|
|
||||||
bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; }
|
|
||||||
bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; }
|
|
||||||
|
|
||||||
void reservedErrorCheck(const TSourceLoc&, const TString&);
|
void reservedErrorCheck(const TSourceLoc&, const TString&);
|
||||||
void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op);
|
void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op);
|
||||||
bool lineContinuationCheck(const TSourceLoc&, bool endOfComment);
|
bool lineContinuationCheck(const TSourceLoc&, bool endOfComment);
|
||||||
|
bool lineDirectiveShouldSetNextLine() const;
|
||||||
bool builtInName(const TString&);
|
bool builtInName(const TString&);
|
||||||
|
|
||||||
void handlePragma(const TSourceLoc&, const TVector<TString>&);
|
void handlePragma(const TSourceLoc&, const TVector<TString>&);
|
||||||
@ -210,55 +293,6 @@ public:
|
|||||||
|
|
||||||
void updateImplicitArraySize(const TSourceLoc&, TIntermNode*, int index);
|
void updateImplicitArraySize(const TSourceLoc&, TIntermNode*, int index);
|
||||||
|
|
||||||
void setScanContext(TScanContext* c) { scanContext = c; }
|
|
||||||
TScanContext* getScanContext() const { return scanContext; }
|
|
||||||
void setPpContext(TPpContext* c) { ppContext = c; }
|
|
||||||
TPpContext* getPpContext() const { return ppContext; }
|
|
||||||
void addError() { ++numErrors; }
|
|
||||||
int getNumErrors() const { return numErrors; }
|
|
||||||
const TSourceLoc& getCurrentLoc() const { return currentScanner->getSourceLoc(); }
|
|
||||||
void setCurrentLine(int line) { currentScanner->setLine(line); }
|
|
||||||
void setCurrentColumn(int col) { currentScanner->setColumn(col); }
|
|
||||||
void setCurrentSourceName(const char* name) { currentScanner->setFile(name); }
|
|
||||||
void setCurrentString(int string) { currentScanner->setString(string); }
|
|
||||||
void setScanner(TInputScanner* scanner) { currentScanner = scanner; }
|
|
||||||
TInputScanner* getScanner() const { return currentScanner; }
|
|
||||||
|
|
||||||
bool lineDirectiveShouldSetNextLine() const;
|
|
||||||
|
|
||||||
void notifyVersion(int line, int version, const char* type_string);
|
|
||||||
void notifyErrorDirective(int line, const char* error_message);
|
|
||||||
void notifyLineDirective(int curLineNo, int newLineNo, bool hasSource, int sourceNum, const char* sourceName);
|
|
||||||
void notifyExtensionDirective(int line, const char* extension, const char* behavior);
|
|
||||||
|
|
||||||
// The following are implemented in Versions.cpp to localize version/profile/stage/extensions control
|
|
||||||
void initializeExtensionBehavior();
|
|
||||||
void requireProfile(const TSourceLoc&, int queryProfiles, const char* featureDesc);
|
|
||||||
void profileRequires(const TSourceLoc&, int queryProfiles, int minVersion, int numExtensions, const char* const extensions[], const char* featureDesc);
|
|
||||||
void profileRequires(const TSourceLoc&, int queryProfiles, int minVersion, const char* const extension, const char* featureDesc);
|
|
||||||
void requireStage(const TSourceLoc&, EShLanguageMask, const char* featureDesc);
|
|
||||||
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);
|
|
||||||
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[]);
|
|
||||||
void updateExtensionBehavior(int line, const char* const extension, const char* behavior);
|
|
||||||
void fullIntegerCheck(const TSourceLoc&, const char* op);
|
|
||||||
void doubleCheck(const TSourceLoc&, const char* op);
|
|
||||||
void spvRemoved(const TSourceLoc&, const char* op);
|
|
||||||
void vulkanRemoved(const TSourceLoc&, const char* op);
|
|
||||||
void requireVulkan(const TSourceLoc&, const char* op);
|
|
||||||
void requireSpv(const TSourceLoc&, const char* op);
|
|
||||||
|
|
||||||
void setVersionCallback(const std::function<void(int, int, const char*)>& func) { versionCallback = func; }
|
|
||||||
void setPragmaCallback(const std::function<void(int, const TVector<TString>&)>& func) { pragmaCallback = func; }
|
|
||||||
void setLineCallback(const std::function<void(int, int, bool, int, const char*)>& func) { lineCallback = func; }
|
|
||||||
void setExtensionCallback(const std::function<void(int, const char*, const char*)>& func) { extensionCallback = func; }
|
|
||||||
void setErrorCallback(const std::function<void(int, const char*)>& func) { errorCallback = func; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type);
|
void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type);
|
||||||
void inheritGlobalDefaults(TQualifier& dst) const;
|
void inheritGlobalDefaults(TQualifier& dst) const;
|
||||||
@ -268,8 +302,6 @@ protected:
|
|||||||
TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
|
TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
|
||||||
TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
|
TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
|
||||||
TOperator mapTypeToConstructorOp(const TType&) const;
|
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 finalErrorCheck();
|
||||||
void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken,
|
void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
const char* szExtraInfoFormat, TPrefixType prefix,
|
const char* szExtraInfoFormat, TPrefixType prefix,
|
||||||
@ -280,18 +312,6 @@ public:
|
|||||||
// Generally, bison productions, the scanner, and the PP need read/write access to these; just give them direct access
|
// Generally, bison productions, the scanner, and the PP need read/write access to these; just give them direct access
|
||||||
//
|
//
|
||||||
|
|
||||||
TIntermediate& intermediate; // helper for making and hooking up pieces of the parse tree
|
|
||||||
TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile
|
|
||||||
TInfoSink& infoSink;
|
|
||||||
|
|
||||||
// compilation mode
|
|
||||||
EShLanguage language; // vertex or fragment language
|
|
||||||
int version; // version, updated by #version in the shader
|
|
||||||
EProfile profile; // the declared profile in the shader (core by default)
|
|
||||||
int spv; // SPIR-V version; 0 means not SPIR-V
|
|
||||||
int vulkan; // Vulkan version; 0 means not vulkan
|
|
||||||
bool forwardCompatible; // true if errors are to be given for use of deprecated features
|
|
||||||
|
|
||||||
// Current state of parsing
|
// Current state of parsing
|
||||||
struct TPragma contextPragma;
|
struct TPragma contextPragma;
|
||||||
int loopNestingLevel; // 0 if outside all loops
|
int loopNestingLevel; // 0 if outside all loops
|
||||||
@ -306,9 +326,7 @@ public:
|
|||||||
bool functionReturnsValue; // true if a non-void function has a return
|
bool functionReturnsValue; // true if a non-void function has a return
|
||||||
const TString* blockName;
|
const TString* blockName;
|
||||||
TQualifier currentBlockQualifier;
|
TQualifier currentBlockQualifier;
|
||||||
TIntermAggregate *linkage; // aggregate node of objects the linker may need, if not referenced by the rest of the AST
|
|
||||||
TPrecisionQualifier defaultPrecision[EbtNumTypes];
|
TPrecisionQualifier defaultPrecision[EbtNumTypes];
|
||||||
bool tokensBeforeEOF;
|
|
||||||
TBuiltInResource resources;
|
TBuiltInResource resources;
|
||||||
TLimits& limits;
|
TLimits& limits;
|
||||||
|
|
||||||
@ -316,13 +334,7 @@ protected:
|
|||||||
TParseContext(TParseContext&);
|
TParseContext(TParseContext&);
|
||||||
TParseContext& operator=(TParseContext&);
|
TParseContext& operator=(TParseContext&);
|
||||||
|
|
||||||
EShMessages messages; // errors/warnings/rule-sets
|
|
||||||
TScanContext* scanContext;
|
|
||||||
TPpContext* ppContext;
|
|
||||||
TInputScanner* currentScanner;
|
|
||||||
int numErrors; // number of compile-time errors encountered
|
|
||||||
bool parsingBuiltins; // true if parsing built-in symbols/functions
|
bool parsingBuiltins; // true if parsing built-in symbols/functions
|
||||||
TMap<TString, TExtensionBehavior> extensionBehavior; // for each extension string, what its current behavior is set to
|
|
||||||
static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2 * 2)); // see computeSamplerTypeIndex()
|
static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2 * 2)); // see computeSamplerTypeIndex()
|
||||||
TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex];
|
TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex];
|
||||||
bool afterEOF;
|
bool afterEOF;
|
||||||
@ -369,14 +381,6 @@ protected:
|
|||||||
// array-sizing declarations
|
// array-sizing declarations
|
||||||
//
|
//
|
||||||
TVector<TSymbol*> ioArraySymbolResizeList;
|
TVector<TSymbol*> ioArraySymbolResizeList;
|
||||||
|
|
||||||
// These, if set, will be called when a line, pragma ... is preprocessed.
|
|
||||||
// They will be called with any parameters to the original directive.
|
|
||||||
std::function<void(int, int, bool, int, const char*)> lineCallback;
|
|
||||||
std::function<void(int, const TVector<TString>&)> pragmaCallback;
|
|
||||||
std::function<void(int, int, const char*)> versionCallback;
|
|
||||||
std::function<void(int, const char*, const char*)> extensionCallback;
|
|
||||||
std::function<void(int, const char*)> errorCallback;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
@ -48,7 +48,7 @@ class TParserToken;
|
|||||||
|
|
||||||
class TScanContext {
|
class TScanContext {
|
||||||
public:
|
public:
|
||||||
explicit TScanContext(TParseContext& pc) : parseContext(pc), afterType(false), field(false) { }
|
explicit TScanContext(TParseContextBase& pc) : parseContext(pc), afterType(false), field(false) { }
|
||||||
virtual ~TScanContext() { }
|
virtual ~TScanContext() { }
|
||||||
|
|
||||||
static void fillInKeywordMap();
|
static void fillInKeywordMap();
|
||||||
@ -72,7 +72,7 @@ protected:
|
|||||||
int firstGenerationImage(bool inEs310);
|
int firstGenerationImage(bool inEs310);
|
||||||
int secondGenerationImage();
|
int secondGenerationImage();
|
||||||
|
|
||||||
TParseContext& parseContext;
|
TParseContextBase& parseContext;
|
||||||
bool afterType; // true if we've recognized a type, so can only be looking for an identifier
|
bool afterType; // true if we've recognized a type, so can only be looking for an identifier
|
||||||
bool field; // true if we're on a field, right after a '.'
|
bool field; // true if we're on a field, right after a '.'
|
||||||
TSourceLoc loc;
|
TSourceLoc loc;
|
||||||
|
@ -464,7 +464,7 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
|
|||||||
// This is the common setup and cleanup code for PreprocessDeferred and
|
// This is the common setup and cleanup code for PreprocessDeferred and
|
||||||
// CompileDeferred.
|
// CompileDeferred.
|
||||||
// It takes any callable with a signature of
|
// It takes any callable with a signature of
|
||||||
// bool (TParseContext& parseContext, TPpContext& ppContext,
|
// bool (TParseContextBase& parseContext, TPpContext& ppContext,
|
||||||
// TInputScanner& input, bool versionWillBeError,
|
// TInputScanner& input, bool versionWillBeError,
|
||||||
// TSymbolTable& , TIntermediate& ,
|
// TSymbolTable& , TIntermediate& ,
|
||||||
// EShOptimizationLevel , EShMessages );
|
// EShOptimizationLevel , EShMessages );
|
||||||
@ -717,7 +717,7 @@ private:
|
|||||||
// It places the result in the "string" argument to its constructor.
|
// It places the result in the "string" argument to its constructor.
|
||||||
struct DoPreprocessing {
|
struct DoPreprocessing {
|
||||||
explicit DoPreprocessing(std::string* string): outputString(string) {}
|
explicit DoPreprocessing(std::string* string): outputString(string) {}
|
||||||
bool operator()(TParseContext& parseContext, TPpContext& ppContext,
|
bool operator()(TParseContextBase& parseContext, TPpContext& ppContext,
|
||||||
TInputScanner& input, bool versionWillBeError,
|
TInputScanner& input, bool versionWillBeError,
|
||||||
TSymbolTable& , TIntermediate& ,
|
TSymbolTable& , TIntermediate& ,
|
||||||
EShOptimizationLevel , EShMessages )
|
EShOptimizationLevel , EShMessages )
|
||||||
@ -828,7 +828,7 @@ struct DoPreprocessing {
|
|||||||
// DoFullParse is a valid ProcessingConext template argument for fully
|
// DoFullParse is a valid ProcessingConext template argument for fully
|
||||||
// parsing the shader. It populates the "intermediate" with the AST.
|
// parsing the shader. It populates the "intermediate" with the AST.
|
||||||
struct DoFullParse{
|
struct DoFullParse{
|
||||||
bool operator()(TParseContext& parseContext, TPpContext& ppContext,
|
bool operator()(TParseContextBase& parseContext, TPpContext& ppContext,
|
||||||
TInputScanner& fullInput, bool versionWillBeError,
|
TInputScanner& fullInput, bool versionWillBeError,
|
||||||
TSymbolTable& symbolTable, TIntermediate& intermediate,
|
TSymbolTable& symbolTable, TIntermediate& intermediate,
|
||||||
EShOptimizationLevel optLevel, EShMessages messages)
|
EShOptimizationLevel optLevel, EShMessages messages)
|
||||||
@ -837,13 +837,13 @@ struct DoFullParse{
|
|||||||
// Parse the full shader.
|
// Parse the full shader.
|
||||||
if (! parseContext.parseShaderStrings(ppContext, fullInput, versionWillBeError))
|
if (! parseContext.parseShaderStrings(ppContext, fullInput, versionWillBeError))
|
||||||
success = false;
|
success = false;
|
||||||
intermediate.addSymbolLinkageNodes(parseContext.linkage, parseContext.language, symbolTable);
|
intermediate.addSymbolLinkageNodes(parseContext.getLinkage(), parseContext.getLanguage(), symbolTable);
|
||||||
|
|
||||||
if (success && intermediate.getTreeRoot()) {
|
if (success && intermediate.getTreeRoot()) {
|
||||||
if (optLevel == EShOptNoGeneration)
|
if (optLevel == EShOptNoGeneration)
|
||||||
parseContext.infoSink.info.message(EPrefixNone, "No errors. No code generation or linking was requested.");
|
parseContext.infoSink.info.message(EPrefixNone, "No errors. No code generation or linking was requested.");
|
||||||
else
|
else
|
||||||
success = intermediate.postProcess(intermediate.getTreeRoot(), parseContext.language);
|
success = intermediate.postProcess(intermediate.getTreeRoot(), parseContext.getLanguage());
|
||||||
} else if (! success) {
|
} else if (! success) {
|
||||||
parseContext.infoSink.info.prefix(EPrefixError);
|
parseContext.infoSink.info.prefix(EPrefixError);
|
||||||
parseContext.infoSink.info << parseContext.getNumErrors() << " compilation errors. No code generated.\n\n";
|
parseContext.infoSink.info << parseContext.getNumErrors() << " compilation errors. No code generated.\n\n";
|
||||||
|
@ -74,12 +74,12 @@
|
|||||||
//
|
//
|
||||||
// const char* const XXX_extension_X = "XXX_extension_X";
|
// const char* const XXX_extension_X = "XXX_extension_X";
|
||||||
//
|
//
|
||||||
// 2) Add extension initialization to TParseContext::initializeExtensionBehavior(),
|
// 2) Add extension initialization to TParseVersions::initializeExtensionBehavior(),
|
||||||
// the first function below:
|
// the first function below:
|
||||||
//
|
//
|
||||||
// extensionBehavior[XXX_extension_X] = EBhDisable;
|
// extensionBehavior[XXX_extension_X] = EBhDisable;
|
||||||
//
|
//
|
||||||
// 3) Add any preprocessor directives etc. in the next function, TParseContext::getPreamble():
|
// 3) Add any preprocessor directives etc. in the next function, TParseVersions::getPreamble():
|
||||||
//
|
//
|
||||||
// "#define XXX_extension_X 1\n"
|
// "#define XXX_extension_X 1\n"
|
||||||
//
|
//
|
||||||
@ -138,7 +138,8 @@
|
|||||||
// table. (There is a different symbol table for each version.)
|
// table. (There is a different symbol table for each version.)
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "ParseHelper.h"
|
#include "parseVersions.h"
|
||||||
|
#include "localintermediate.h"
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
@ -147,7 +148,7 @@ namespace glslang {
|
|||||||
// are incorporated into a core version, their features are supported through allowing that
|
// are incorporated into a core version, their features are supported through allowing that
|
||||||
// core version, not through a pseudo-enablement of the extension.
|
// core version, not through a pseudo-enablement of the extension.
|
||||||
//
|
//
|
||||||
void TParseContext::initializeExtensionBehavior()
|
void TParseVersions::initializeExtensionBehavior()
|
||||||
{
|
{
|
||||||
extensionBehavior[E_GL_OES_texture_3D] = EBhDisable;
|
extensionBehavior[E_GL_OES_texture_3D] = EBhDisable;
|
||||||
extensionBehavior[E_GL_OES_standard_derivatives] = EBhDisable;
|
extensionBehavior[E_GL_OES_standard_derivatives] = EBhDisable;
|
||||||
@ -213,7 +214,7 @@ void TParseContext::initializeExtensionBehavior()
|
|||||||
|
|
||||||
// Get code that is not part of a shared symbol table, is specific to this shader,
|
// Get code that is not part of a shared symbol table, is specific to this shader,
|
||||||
// or needed by the preprocessor (which does not use a shared symbol table).
|
// or needed by the preprocessor (which does not use a shared symbol table).
|
||||||
const char* TParseContext::getPreamble()
|
const char* TParseVersions::getPreamble()
|
||||||
{
|
{
|
||||||
if (profile == EEsProfile) {
|
if (profile == EEsProfile) {
|
||||||
return
|
return
|
||||||
@ -297,7 +298,7 @@ const char* TParseContext::getPreamble()
|
|||||||
// Operation: If the current profile is not one of the profileMask,
|
// Operation: If the current profile is not one of the profileMask,
|
||||||
// give an error message.
|
// give an error message.
|
||||||
//
|
//
|
||||||
void TParseContext::requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc)
|
void TParseVersions::requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc)
|
||||||
{
|
{
|
||||||
if (! (profile & profileMask))
|
if (! (profile & profileMask))
|
||||||
error(loc, "not supported with this profile:", featureDesc, ProfileName(profile));
|
error(loc, "not supported with this profile:", featureDesc, ProfileName(profile));
|
||||||
@ -336,7 +337,7 @@ const char* StageName(EShLanguage stage)
|
|||||||
//
|
//
|
||||||
|
|
||||||
// entry point that takes multiple extensions
|
// entry point that takes multiple extensions
|
||||||
void TParseContext::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions, const char* const extensions[], const char* featureDesc)
|
void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions, const char* const extensions[], const char* featureDesc)
|
||||||
{
|
{
|
||||||
if (profile & profileMask) {
|
if (profile & profileMask) {
|
||||||
bool okay = false;
|
bool okay = false;
|
||||||
@ -361,7 +362,7 @@ void TParseContext::profileRequires(const TSourceLoc& loc, int profileMask, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
// entry point for the above that takes a single extension
|
// entry point for the above that takes a single extension
|
||||||
void TParseContext::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension, const char* featureDesc)
|
void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension, const char* featureDesc)
|
||||||
{
|
{
|
||||||
profileRequires(loc, profileMask, minVersion, extension ? 1 : 0, &extension, featureDesc);
|
profileRequires(loc, profileMask, minVersion, extension ? 1 : 0, &extension, featureDesc);
|
||||||
}
|
}
|
||||||
@ -373,7 +374,7 @@ void TParseContext::profileRequires(const TSourceLoc& loc, int profileMask, int
|
|||||||
//
|
//
|
||||||
// Operation: If the current stage is not present, give an error message.
|
// Operation: If the current stage is not present, give an error message.
|
||||||
//
|
//
|
||||||
void TParseContext::requireStage(const TSourceLoc& loc, EShLanguageMask languageMask, const char* featureDesc)
|
void TParseVersions::requireStage(const TSourceLoc& loc, EShLanguageMask languageMask, const char* featureDesc)
|
||||||
{
|
{
|
||||||
if (((1 << language) & languageMask) == 0)
|
if (((1 << language) & languageMask) == 0)
|
||||||
error(loc, "not supported in this stage:", featureDesc, StageName(language));
|
error(loc, "not supported in this stage:", featureDesc, StageName(language));
|
||||||
@ -381,7 +382,7 @@ void TParseContext::requireStage(const TSourceLoc& loc, EShLanguageMask language
|
|||||||
|
|
||||||
// If only one stage supports a feature, this can be called. But, all supporting stages
|
// If only one stage supports a feature, this can be called. But, all supporting stages
|
||||||
// must be specified with one call.
|
// must be specified with one call.
|
||||||
void TParseContext::requireStage(const TSourceLoc& loc, EShLanguage stage, const char* featureDesc)
|
void TParseVersions::requireStage(const TSourceLoc& loc, EShLanguage stage, const char* featureDesc)
|
||||||
{
|
{
|
||||||
requireStage(loc, static_cast<EShLanguageMask>(1 << stage), featureDesc);
|
requireStage(loc, static_cast<EShLanguageMask>(1 << stage), featureDesc);
|
||||||
}
|
}
|
||||||
@ -390,7 +391,7 @@ void TParseContext::requireStage(const TSourceLoc& loc, EShLanguage stage, const
|
|||||||
// Within a set of profiles, see if a feature is deprecated and give an error or warning based on whether
|
// Within a set of profiles, see if a feature is deprecated and give an error or warning based on whether
|
||||||
// a future compatibility context is being use.
|
// a future compatibility context is being use.
|
||||||
//
|
//
|
||||||
void TParseContext::checkDeprecated(const TSourceLoc& loc, int profileMask, int depVersion, const char* featureDesc)
|
void TParseVersions::checkDeprecated(const TSourceLoc& loc, int profileMask, int depVersion, const char* featureDesc)
|
||||||
{
|
{
|
||||||
if (profile & profileMask) {
|
if (profile & profileMask) {
|
||||||
if (version >= depVersion) {
|
if (version >= depVersion) {
|
||||||
@ -407,7 +408,7 @@ void TParseContext::checkDeprecated(const TSourceLoc& loc, int profileMask, int
|
|||||||
// Within a set of profiles, see if a feature has now been removed and if so, give an error.
|
// Within a set of profiles, see if a feature has now been removed and if so, give an error.
|
||||||
// The version argument is the first version no longer having the feature.
|
// The version argument is the first version no longer having the feature.
|
||||||
//
|
//
|
||||||
void TParseContext::requireNotRemoved(const TSourceLoc& loc, int profileMask, int removedVersion, const char* featureDesc)
|
void TParseVersions::requireNotRemoved(const TSourceLoc& loc, int profileMask, int removedVersion, const char* featureDesc)
|
||||||
{
|
{
|
||||||
if (profile & profileMask) {
|
if (profile & profileMask) {
|
||||||
if (version >= removedVersion) {
|
if (version >= removedVersion) {
|
||||||
@ -421,7 +422,7 @@ void TParseContext::requireNotRemoved(const TSourceLoc& loc, int profileMask, in
|
|||||||
|
|
||||||
// Returns true if at least one of the extensions in the extensions parameter is requested. Otherwise, returns false.
|
// 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".
|
// 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)
|
bool TParseVersions::checkExtensionsRequested(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
|
||||||
{
|
{
|
||||||
// First, see if any of the extensions are enabled
|
// First, see if any of the extensions are enabled
|
||||||
for (int i = 0; i < numExtensions; ++i) {
|
for (int i = 0; i < numExtensions; ++i) {
|
||||||
@ -452,7 +453,7 @@ bool TParseContext::checkExtensionsRequested(const TSourceLoc& loc, int numExten
|
|||||||
// Use when there are no profile/version to check, it's just an error if one of the
|
// Use when there are no profile/version to check, it's just an error if one of the
|
||||||
// extensions is not present.
|
// extensions is not present.
|
||||||
//
|
//
|
||||||
void TParseContext::requireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
|
void TParseVersions::requireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
|
||||||
{
|
{
|
||||||
if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc)) return;
|
if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc)) return;
|
||||||
|
|
||||||
@ -470,7 +471,7 @@ void TParseContext::requireExtensions(const TSourceLoc& loc, int numExtensions,
|
|||||||
// Use by preprocessor when there are no profile/version to check, it's just an error if one of the
|
// Use by preprocessor when there are no profile/version to check, it's just an error if one of the
|
||||||
// extensions is not present.
|
// extensions is not present.
|
||||||
//
|
//
|
||||||
void TParseContext::ppRequireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
|
void TParseVersions::ppRequireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
|
||||||
{
|
{
|
||||||
if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc)) return;
|
if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc)) return;
|
||||||
|
|
||||||
@ -484,7 +485,7 @@ void TParseContext::ppRequireExtensions(const TSourceLoc& loc, int numExtensions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TExtensionBehavior TParseContext::getExtensionBehavior(const char* extension)
|
TExtensionBehavior TParseVersions::getExtensionBehavior(const char* extension)
|
||||||
{
|
{
|
||||||
auto iter = extensionBehavior.find(TString(extension));
|
auto iter = extensionBehavior.find(TString(extension));
|
||||||
if (iter == extensionBehavior.end())
|
if (iter == extensionBehavior.end())
|
||||||
@ -494,7 +495,7 @@ TExtensionBehavior TParseContext::getExtensionBehavior(const char* extension)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the given extension is set to enable, require, or warn.
|
// Returns true if the given extension is set to enable, require, or warn.
|
||||||
bool TParseContext::extensionTurnedOn(const char* const extension)
|
bool TParseVersions::extensionTurnedOn(const char* const extension)
|
||||||
{
|
{
|
||||||
switch (getExtensionBehavior(extension)) {
|
switch (getExtensionBehavior(extension)) {
|
||||||
case EBhEnable:
|
case EBhEnable:
|
||||||
@ -507,7 +508,7 @@ bool TParseContext::extensionTurnedOn(const char* const extension)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// See if any of the extensions are set to enable, require, or warn.
|
// See if any of the extensions are set to enable, require, or warn.
|
||||||
bool TParseContext::extensionsTurnedOn(int numExtensions, const char* const extensions[])
|
bool TParseVersions::extensionsTurnedOn(int numExtensions, const char* const extensions[])
|
||||||
{
|
{
|
||||||
for (int i = 0; i < numExtensions; ++i) {
|
for (int i = 0; i < numExtensions; ++i) {
|
||||||
if (extensionTurnedOn(extensions[i])) return true;
|
if (extensionTurnedOn(extensions[i])) return true;
|
||||||
@ -518,7 +519,7 @@ bool TParseContext::extensionsTurnedOn(int numExtensions, const char* const exte
|
|||||||
//
|
//
|
||||||
// Change the current state of an extension's behavior.
|
// Change the current state of an extension's behavior.
|
||||||
//
|
//
|
||||||
void TParseContext::updateExtensionBehavior(int line, const char* extension, const char* behaviorString)
|
void TParseVersions::updateExtensionBehavior(int line, const char* extension, const char* behaviorString)
|
||||||
{
|
{
|
||||||
// Translate from text string of extension's behavior to an enum.
|
// Translate from text string of extension's behavior to an enum.
|
||||||
TExtensionBehavior behavior = EBhDisable;
|
TExtensionBehavior behavior = EBhDisable;
|
||||||
@ -571,7 +572,7 @@ void TParseContext::updateExtensionBehavior(int line, const char* extension, con
|
|||||||
spv = 100;
|
spv = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TParseContext::updateExtensionBehavior(const char* extension, TExtensionBehavior behavior)
|
void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBehavior behavior)
|
||||||
{
|
{
|
||||||
// Update the current behavior
|
// Update the current behavior
|
||||||
if (strcmp(extension, "all") == 0) {
|
if (strcmp(extension, "all") == 0) {
|
||||||
@ -612,14 +613,14 @@ void TParseContext::updateExtensionBehavior(const char* extension, TExtensionBeh
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call for any operation needing full GLSL integer data-type support.
|
// Call for any operation needing full GLSL integer data-type support.
|
||||||
void TParseContext::fullIntegerCheck(const TSourceLoc& loc, const char* op)
|
void TParseVersions::fullIntegerCheck(const TSourceLoc& loc, const char* op)
|
||||||
{
|
{
|
||||||
profileRequires(loc, ENoProfile, 130, nullptr, op);
|
profileRequires(loc, ENoProfile, 130, nullptr, op);
|
||||||
profileRequires(loc, EEsProfile, 300, nullptr, op);
|
profileRequires(loc, EEsProfile, 300, nullptr, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call for any operation needing GLSL double data-type support.
|
// Call for any operation needing GLSL double data-type support.
|
||||||
void TParseContext::doubleCheck(const TSourceLoc& loc, const char* op)
|
void TParseVersions::doubleCheck(const TSourceLoc& loc, const char* op)
|
||||||
{
|
{
|
||||||
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
||||||
profileRequires(loc, ECoreProfile, 400, nullptr, op);
|
profileRequires(loc, ECoreProfile, 400, nullptr, op);
|
||||||
@ -627,28 +628,28 @@ void TParseContext::doubleCheck(const TSourceLoc& loc, const char* op)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call for any operation removed because SPIR-V is in use.
|
// Call for any operation removed because SPIR-V is in use.
|
||||||
void TParseContext::spvRemoved(const TSourceLoc& loc, const char* op)
|
void TParseVersions::spvRemoved(const TSourceLoc& loc, const char* op)
|
||||||
{
|
{
|
||||||
if (spv > 0)
|
if (spv > 0)
|
||||||
error(loc, "not allowed when generating SPIR-V", op, "");
|
error(loc, "not allowed when generating SPIR-V", op, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call for any operation removed because Vulkan SPIR-V is being generated.
|
// Call for any operation removed because Vulkan SPIR-V is being generated.
|
||||||
void TParseContext::vulkanRemoved(const TSourceLoc& loc, const char* op)
|
void TParseVersions::vulkanRemoved(const TSourceLoc& loc, const char* op)
|
||||||
{
|
{
|
||||||
if (vulkan > 0)
|
if (vulkan > 0)
|
||||||
error(loc, "not allowed when using GLSL for Vulkan", op, "");
|
error(loc, "not allowed when using GLSL for Vulkan", op, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call for any operation that requires Vulkan.
|
// Call for any operation that requires Vulkan.
|
||||||
void TParseContext::requireVulkan(const TSourceLoc& loc, const char* op)
|
void TParseVersions::requireVulkan(const TSourceLoc& loc, const char* op)
|
||||||
{
|
{
|
||||||
if (vulkan == 0)
|
if (vulkan == 0)
|
||||||
error(loc, "only allowed when using GLSL for Vulkan", op, "");
|
error(loc, "only allowed when using GLSL for Vulkan", op, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call for any operation that requires SPIR-V.
|
// Call for any operation that requires SPIR-V.
|
||||||
void TParseContext::requireSpv(const TSourceLoc& loc, const char* op)
|
void TParseVersions::requireSpv(const TSourceLoc& loc, const char* op)
|
||||||
{
|
{
|
||||||
if (spv == 0)
|
if (spv == 0)
|
||||||
error(loc, "only allowed when generating SPIR-V", op, "");
|
error(loc, "only allowed when generating SPIR-V", op, "");
|
||||||
|
134
glslang/MachineIndependent/parseVersions.h
Executable file
134
glslang/MachineIndependent/parseVersions.h
Executable file
@ -0,0 +1,134 @@
|
|||||||
|
//
|
||||||
|
//Copyright (C) 2016 Google, Inc.
|
||||||
|
//
|
||||||
|
//All rights reserved.
|
||||||
|
//
|
||||||
|
//Redistribution and use in source and binary forms, with or without
|
||||||
|
//modification, are permitted provided that the following conditions
|
||||||
|
//are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
//POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
|
||||||
|
// This is implemented in Versions.cpp
|
||||||
|
|
||||||
|
#ifndef _PARSE_VERSIONS_INCLUDED_
|
||||||
|
#define _PARSE_VERSIONS_INCLUDED_
|
||||||
|
|
||||||
|
#include "../Public/ShaderLang.h"
|
||||||
|
#include "../Include/InfoSink.h"
|
||||||
|
#include "Scan.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Base class for parse helpers.
|
||||||
|
// This just has version-related information and checking.
|
||||||
|
// This class should be sufficient for preprocessing.
|
||||||
|
//
|
||||||
|
class TParseVersions {
|
||||||
|
public:
|
||||||
|
TParseVersions(TIntermediate& interm, int version, EProfile profile,
|
||||||
|
int spv, int vulkan, EShLanguage language, TInfoSink& infoSink,
|
||||||
|
bool forwardCompatible, EShMessages messages)
|
||||||
|
: infoSink(infoSink), version(version), profile(profile), language(language),
|
||||||
|
spv(spv), vulkan(vulkan), forwardCompatible(forwardCompatible),
|
||||||
|
intermediate(interm), messages(messages), numErrors(0), currentScanner(0) { }
|
||||||
|
virtual ~TParseVersions() { }
|
||||||
|
virtual void initializeExtensionBehavior();
|
||||||
|
virtual void requireProfile(const TSourceLoc&, int queryProfiles, const char* featureDesc);
|
||||||
|
virtual void profileRequires(const TSourceLoc&, int queryProfiles, int minVersion, int numExtensions, const char* const extensions[], const char* featureDesc);
|
||||||
|
virtual void profileRequires(const TSourceLoc&, int queryProfiles, int minVersion, const char* const extension, const char* featureDesc);
|
||||||
|
virtual void requireStage(const TSourceLoc&, EShLanguageMask, const char* featureDesc);
|
||||||
|
virtual void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc);
|
||||||
|
virtual void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc);
|
||||||
|
virtual void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc);
|
||||||
|
virtual void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
|
||||||
|
virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
|
||||||
|
virtual TExtensionBehavior getExtensionBehavior(const char*);
|
||||||
|
virtual bool extensionTurnedOn(const char* const extension);
|
||||||
|
virtual bool extensionsTurnedOn(int numExtensions, const char* const extensions[]);
|
||||||
|
virtual void updateExtensionBehavior(int line, const char* const extension, const char* behavior);
|
||||||
|
virtual void fullIntegerCheck(const TSourceLoc&, const char* op);
|
||||||
|
virtual void doubleCheck(const TSourceLoc&, const char* op);
|
||||||
|
virtual void spvRemoved(const TSourceLoc&, const char* op);
|
||||||
|
virtual void vulkanRemoved(const TSourceLoc&, const char* op);
|
||||||
|
virtual void requireVulkan(const TSourceLoc&, const char* op);
|
||||||
|
virtual void requireSpv(const TSourceLoc&, const char* op);
|
||||||
|
virtual bool checkExtensionsRequested(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
|
||||||
|
virtual void updateExtensionBehavior(const char* const extension, TExtensionBehavior);
|
||||||
|
|
||||||
|
virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, ...) = 0;
|
||||||
|
virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, ...) = 0;
|
||||||
|
virtual void C_DECL ppError(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, ...) = 0;
|
||||||
|
virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, ...) = 0;
|
||||||
|
|
||||||
|
void addError() { ++numErrors; }
|
||||||
|
int getNumErrors() const { return numErrors; }
|
||||||
|
|
||||||
|
void setScanner(TInputScanner* scanner) { currentScanner = scanner; }
|
||||||
|
TInputScanner* getScanner() const { return currentScanner; }
|
||||||
|
const TSourceLoc& getCurrentLoc() const { return currentScanner->getSourceLoc(); }
|
||||||
|
void setCurrentLine(int line) { currentScanner->setLine(line); }
|
||||||
|
void setCurrentColumn(int col) { currentScanner->setColumn(col); }
|
||||||
|
void setCurrentSourceName(const char* name) { currentScanner->setFile(name); }
|
||||||
|
void setCurrentString(int string) { currentScanner->setString(string); }
|
||||||
|
|
||||||
|
const char* getPreamble();
|
||||||
|
bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; }
|
||||||
|
bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; }
|
||||||
|
|
||||||
|
TInfoSink& infoSink;
|
||||||
|
|
||||||
|
// compilation mode
|
||||||
|
int version; // version, updated by #version in the shader
|
||||||
|
EProfile profile; // the declared profile in the shader (core by default)
|
||||||
|
EShLanguage language; // really the stage
|
||||||
|
int spv; // SPIR-V version; 0 means not SPIR-V
|
||||||
|
int vulkan; // Vulkan version; 0 means not vulkan
|
||||||
|
bool forwardCompatible; // true if errors are to be given for use of deprecated features
|
||||||
|
TIntermediate& intermediate; // helper for making and hooking up pieces of the parse tree
|
||||||
|
|
||||||
|
protected:
|
||||||
|
EShMessages messages; // errors/warnings/rule-sets
|
||||||
|
int numErrors; // number of compile-time errors encountered
|
||||||
|
TInputScanner* currentScanner;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TMap<TString, TExtensionBehavior> extensionBehavior; // for each extension string, what its current behavior is set to
|
||||||
|
explicit TParseVersions(const TParseVersions&);
|
||||||
|
TParseVersions& operator=(const TParseVersions&);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace glslang
|
||||||
|
|
||||||
|
#endif // _PARSE_VERSIONS_INCLUDED_
|
@ -83,7 +83,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
TPpContext::TPpContext(TParseContext& pc, const TShader::Includer& inclr) :
|
TPpContext::TPpContext(TParseContextBase& pc, const TShader::Includer& inclr) :
|
||||||
preamble(0), strings(0), parseContext(pc), includer(inclr), inComment(false)
|
preamble(0), strings(0), parseContext(pc), includer(inclr), inComment(false)
|
||||||
{
|
{
|
||||||
InitAtomTable();
|
InitAtomTable();
|
||||||
|
@ -121,7 +121,7 @@ class TInputScanner;
|
|||||||
// Don't expect too much in terms of OO design.
|
// Don't expect too much in terms of OO design.
|
||||||
class TPpContext {
|
class TPpContext {
|
||||||
public:
|
public:
|
||||||
TPpContext(TParseContext&, const TShader::Includer&);
|
TPpContext(TParseContextBase&, const TShader::Includer&);
|
||||||
virtual ~TPpContext();
|
virtual ~TPpContext();
|
||||||
|
|
||||||
void setPreamble(const char* preamble, size_t length);
|
void setPreamble(const char* preamble, size_t length);
|
||||||
@ -213,7 +213,7 @@ protected:
|
|||||||
|
|
||||||
// Scanner data:
|
// Scanner data:
|
||||||
int previous_token;
|
int previous_token;
|
||||||
TParseContext& parseContext;
|
TParseContextBase& parseContext;
|
||||||
|
|
||||||
// Get the next token from *stack* of input sources, popping input sources
|
// Get the next token from *stack* of input sources, popping input sources
|
||||||
// that are out of tokens, down until an input sources is found that has a token.
|
// that are out of tokens, down until an input sources is found that has a token.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user