diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-04-04 19:47:41 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-04-09 18:53:22 +0000 |
commit | 0fde097e31e908b18db68f05e2122c5280d36304 (patch) | |
tree | fef45d90f164983dd49130a2d14e86055f84f1da /src/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h | |
parent | 8c10e6cb759f8d4acdcf54a25b70530d4c936bf6 (diff) |
Import the Qt Shader Tools module
...from https://git.qt.io/laagocs/qtshadertools/
Change-Id: I3aa655da81978e13016f8150634e278448015709
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Diffstat (limited to 'src/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h')
-rw-r--r-- | src/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h | 510 |
1 files changed, 510 insertions, 0 deletions
diff --git a/src/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h b/src/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h new file mode 100644 index 0000000..a1ffe64 --- /dev/null +++ b/src/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h @@ -0,0 +1,510 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2012-2013 LunarG, Inc. +// Copyright (C) 2015-2018 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 header defines a two-level parse-helper hierarchy, derived from +// TParseVersions: +// - TParseContextBase: sharable across multiple parsers +// - TParseContext: GLSL specific helper +// + +#ifndef _PARSER_HELPER_INCLUDED_ +#define _PARSER_HELPER_INCLUDED_ + +#include <cstdarg> +#include <functional> + +#include "parseVersions.h" +#include "../Include/ShHandle.h" +#include "SymbolTable.h" +#include "localintermediate.h" +#include "Scan.h" +#include "attribute.h" + +namespace glslang { + +struct TPragma { + TPragma(bool o, bool d) : optimize(o), debug(d) { } + bool optimize; + bool debug; + TPragmaTable pragmaTable; +}; + +class TScanContext; +class TPpContext; + +typedef std::set<int> TIdSetType; + +// +// Sharable code (as well as what's in TParseVersions) across +// parse helpers. +// +class TParseContextBase : public TParseVersions { +public: + TParseContextBase(TSymbolTable& symbolTable, TIntermediate& interm, bool parsingBuiltins, int version, + EProfile profile, const SpvVersion& spvVersion, EShLanguage language, + TInfoSink& infoSink, bool forwardCompatible, EShMessages messages, + const TString* entryPoint = nullptr) + : TParseVersions(interm, version, profile, spvVersion, language, infoSink, forwardCompatible, messages), + scopeMangler("::"), + symbolTable(symbolTable), + statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0), + postEntryPointReturn(false), + contextPragma(true, false), + parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr), + limits(resources.limits), + globalUniformBlock(nullptr), + globalUniformBinding(TQualifier::layoutBindingEnd), + globalUniformSet(TQualifier::layoutSetEnd) + { + if (entryPoint != nullptr) + sourceEntryPointName = *entryPoint; + } + virtual ~TParseContextBase() { } + + virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...); + virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...); + virtual void C_DECL ppError(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...); + virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...); + + virtual void setLimits(const TBuiltInResource&) = 0; + + void checkIndex(const TSourceLoc&, const TType&, int& index); + + EShLanguage getLanguage() const { return language; } + 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); + } + + // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL) + virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr); + + // Potentially rename shader entry point function + void renameShaderFunction(TString*& name) const + { + // Replace the entry point name given in the shader with the real entry point name, + // if there is a substitution. + if (name != nullptr && *name == sourceEntryPointName && intermediate.getEntryPointName().size() > 0) + name = NewPoolTString(intermediate.getEntryPointName().c_str()); + } + + virtual bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*); + virtual void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*); + + const char* const scopeMangler; + + // Basic parsing state, easily accessible to the grammar + + TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile + int statementNestingLevel; // 0 if outside all flow control or compound statements + int loopNestingLevel; // 0 if outside all loops + int structNestingLevel; // 0 if outside blocks and structures + int controlFlowNestingLevel; // 0 if outside all flow control + const TType* currentFunctionType; // the return type of the function that's currently being parsed + bool functionReturnsValue; // true if a non-void function has a return + // if inside a function, true if the function is the entry point and this is after a return statement + bool postEntryPointReturn; + // case, node, case, case, node, ...; ensure only one node between cases; stack of them for nesting + TList<TIntermSequence*> switchSequenceStack; + // the statementNestingLevel the current switch statement is at, which must match the level of its case statements + TList<int> switchLevel; + struct TPragma contextPragma; + +protected: + TParseContextBase(TParseContextBase&); + TParseContextBase& operator=(TParseContextBase&); + + const bool parsingBuiltins; // true if parsing built-in symbols/functions + TVector<TSymbol*> linkageSymbols; // will be transferred to 'linkage', after all editing is done, order preserving + TScanContext* scanContext; + TPpContext* ppContext; + TBuiltInResource resources; + TLimits& limits; + TString sourceEntryPointName; + + // 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; + + // see implementation for detail + const TFunction* selectFunction(const TVector<const TFunction*>, const TFunction&, + std::function<bool(const TType&, const TType&, TOperator, int arg)>, + std::function<bool(const TType&, const TType&, const TType&)>, + /* output */ bool& tie); + + virtual void parseSwizzleSelector(const TSourceLoc&, const TString&, int size, + TSwizzleSelectors<TVectorSelector>&); + + // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL) + TVariable* globalUniformBlock; // the actual block, inserted into the symbol table + unsigned int globalUniformBinding; // the block's binding number + unsigned int globalUniformSet; // the block's set number + int firstNewMember; // the index of the first member not yet inserted into the symbol table + // override this to set the language-specific name + virtual const char* getGlobalUniformBlockName() const { return ""; } + virtual void setUniformBlockDefaults(TType&) const { } + virtual void finalizeGlobalUniformBlockLayout(TVariable&) { } + virtual void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, TPrefixType prefix, + va_list args); + virtual void trackLinkage(TSymbol& symbol); + virtual void makeEditable(TSymbol*&); + virtual TVariable* getEditableVariable(const char* name); + virtual void finish(); +}; + +// +// Manage the state for when to respect precision qualifiers and when to warn about +// the defaults being different than might be expected. +// +class TPrecisionManager { +public: + TPrecisionManager() : obey(false), warn(false), explicitIntDefault(false), explicitFloatDefault(false){ } + virtual ~TPrecisionManager() {} + + void respectPrecisionQualifiers() { obey = true; } + bool respectingPrecisionQualifiers() const { return obey; } + bool shouldWarnAboutDefaults() const { return warn; } + void defaultWarningGiven() { warn = false; } + void warnAboutDefaults() { warn = true; } + void explicitIntDefaultSeen() + { + explicitIntDefault = true; + if (explicitFloatDefault) + warn = false; + } + void explicitFloatDefaultSeen() + { + explicitFloatDefault = true; + if (explicitIntDefault) + warn = false; + } + +protected: + bool obey; // respect precision qualifiers + bool warn; // need to give a warning about the defaults + bool explicitIntDefault; // user set the default for int/uint + bool explicitFloatDefault; // user set the default for float +}; + +// +// 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: + TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, const SpvVersion& spvVersion, EShLanguage, TInfoSink&, + bool forwardCompatible = false, EShMessages messages = EShMsgDefault, + const TString* entryPoint = nullptr); + virtual ~TParseContext(); + + bool obeyPrecisionQualifiers() const { return precisionManager.respectingPrecisionQualifiers(); }; + void setPrecisionDefaults(); + + void setLimits(const TBuiltInResource&) override; + bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) override; + void parserError(const char* s); // for bison's yyerror + + void reservedErrorCheck(const TSourceLoc&, const TString&); + void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op) override; + bool lineContinuationCheck(const TSourceLoc&, bool endOfComment) override; + bool lineDirectiveShouldSetNextLine() const override; + bool builtInName(const TString&); + + void handlePragma(const TSourceLoc&, const TVector<TString>&) override; + TIntermTyped* handleVariable(const TSourceLoc&, TSymbol* symbol, const TString* string); + TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index); + void handleIndexLimits(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index); + + void makeEditable(TSymbol*&) override; + bool isIoResizeArray(const TType&) const; + void fixIoArraySize(const TSourceLoc&, TType&); + void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier); + void handleIoResizeArrayAccess(const TSourceLoc&, TIntermTyped* base); + void checkIoArraysConsistency(const TSourceLoc&, bool tailOnly = false); + int getIoArrayImplicitSize(const TQualifier&, TString* featureString = nullptr) const; + void checkIoArrayConsistency(const TSourceLoc&, int requiredSize, const char* feature, TType&, const TString&); + + TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right); + TIntermTyped* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode); + TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field); + void blockMemberExtensionCheck(const TSourceLoc&, const TIntermTyped* base, int member, const TString& memberName); + TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype); + TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&); + TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*); + TIntermTyped* handleBuiltInFunctionCall(TSourceLoc, TIntermNode* arguments, const TFunction& function); + void computeBuiltinPrecisions(TIntermTyped&, const TFunction&); + TIntermNode* handleReturnValue(const TSourceLoc&, TIntermTyped*); + void checkLocation(const TSourceLoc&, TOperator); + TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*); + void addInputArgumentConversions(const TFunction&, TIntermNode*&) const; + TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const; + void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&); + void nonOpBuiltInCheck(const TSourceLoc&, const TFunction&, TIntermAggregate&); + void userFunctionCallCheck(const TSourceLoc&, TIntermAggregate&); + void samplerConstructorLocationCheck(const TSourceLoc&, const char* token, TIntermNode*); + TFunction* handleConstructorCall(const TSourceLoc&, const TPublicType&); + void handlePrecisionQualifier(const TSourceLoc&, TQualifier&, TPrecisionQualifier); + void checkPrecisionQualifier(const TSourceLoc&, TPrecisionQualifier); + void memorySemanticsCheck(const TSourceLoc&, const TFunction&, const TIntermOperator& callNode); + + void assignError(const TSourceLoc&, const char* op, TString left, TString right); + void unaryOpError(const TSourceLoc&, const char* op, TString operand); + void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right); + void variableCheck(TIntermTyped*& nodePtr); + bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*) override; + void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*) override; + void constantValueCheck(TIntermTyped* node, const char* token); + void integerCheck(const TIntermTyped* node, const char* token); + void globalCheck(const TSourceLoc&, const char* token); + bool constructorError(const TSourceLoc&, TIntermNode*, TFunction&, TOperator, TType&); + bool constructorTextureSamplerError(const TSourceLoc&, const TFunction&); + void arraySizeCheck(const TSourceLoc&, TIntermTyped* expr, TArraySize&, const char *sizeType); + bool arrayQualifierError(const TSourceLoc&, const TQualifier&); + bool arrayError(const TSourceLoc&, const TType&); + void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&); + void structArrayCheck(const TSourceLoc&, const TType& structure); + void arraySizesCheck(const TSourceLoc&, const TQualifier&, TArraySizes*, const TIntermTyped* initializer, bool lastMember); + void arrayOfArrayVersionCheck(const TSourceLoc&, const TArraySizes*); + bool voidErrorCheck(const TSourceLoc&, const TString&, TBasicType); + void boolCheck(const TSourceLoc&, const TIntermTyped*); + void boolCheck(const TSourceLoc&, const TPublicType&); + void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer); + void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier); + void accStructNVCheck(const TSourceLoc & loc, const TType & type, const TString & identifier); + void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier); + void memberQualifierCheck(glslang::TPublicType&); + void globalQualifierFixCheck(const TSourceLoc&, TQualifier&); + void globalQualifierTypeCheck(const TSourceLoc&, const TQualifier&, const TPublicType&); + bool structQualifierErrorCheck(const TSourceLoc&, const TPublicType& pType); + void mergeQualifiers(const TSourceLoc&, TQualifier& dst, const TQualifier& src, bool force); + void setDefaultPrecision(const TSourceLoc&, TPublicType&, TPrecisionQualifier); + int computeSamplerTypeIndex(TSampler&); + TPrecisionQualifier getDefaultPrecision(TPublicType&); + void precisionQualifierCheck(const TSourceLoc&, TBasicType, TQualifier&); + void parameterTypeCheck(const TSourceLoc&, TStorageQualifier qualifier, const TType& type); + bool containsFieldWithBasicType(const TType& type ,TBasicType basicType); + TSymbol* redeclareBuiltinVariable(const TSourceLoc&, const TString&, const TQualifier&, const TShaderQualifiers&); + void redeclareBuiltinBlock(const TSourceLoc&, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes); + void paramCheckFixStorage(const TSourceLoc&, const TStorageQualifier&, TType& type); + void paramCheckFix(const TSourceLoc&, const TQualifier&, TType& type); + void nestedBlockCheck(const TSourceLoc&); + void nestedStructCheck(const TSourceLoc&); + void arrayObjectCheck(const TSourceLoc&, const TType&, const char* op); + void opaqueCheck(const TSourceLoc&, const TType&, const char* op); + void referenceCheck(const TSourceLoc&, const TType&, const char* op); + void storage16BitAssignmentCheck(const TSourceLoc&, const TType&, const char* op); + void specializationCheck(const TSourceLoc&, const TType&, const char* op); + void structTypeCheck(const TSourceLoc&, TPublicType&); + void inductiveLoopCheck(const TSourceLoc&, TIntermNode* init, TIntermLoop* loop); + void arrayLimitCheck(const TSourceLoc&, const TString&, int size); + void limitCheck(const TSourceLoc&, int value, const char* limit, const char* feature); + + void inductiveLoopBodyCheck(TIntermNode*, int loopIndexId, TSymbolTable&); + void constantIndexExpressionCheck(TIntermNode*); + + void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&); + void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&, const TIntermTyped*); + void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly); + void layoutObjectCheck(const TSourceLoc&, const TSymbol&); + void layoutMemberLocationArrayCheck(const TSourceLoc&, bool memberWithLocation, TArraySizes* arraySizes); + void layoutTypeCheck(const TSourceLoc&, const TType&); + void layoutQualifierCheck(const TSourceLoc&, const TQualifier&); + void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&); + void fixOffset(const TSourceLoc&, TSymbol&); + + const TFunction* findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn); + const TFunction* findFunctionExact(const TSourceLoc& loc, const TFunction& call, bool& builtIn); + const TFunction* findFunction120(const TSourceLoc& loc, const TFunction& call, bool& builtIn); + const TFunction* findFunction400(const TSourceLoc& loc, const TFunction& call, bool& builtIn); + const TFunction* findFunctionExplicitTypes(const TSourceLoc& loc, const TFunction& call, bool& builtIn); + void declareTypeDefaults(const TSourceLoc&, const TPublicType&); + TIntermNode* declareVariable(const TSourceLoc&, TString& identifier, const TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0); + TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&); + TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&); + TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset); + void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0); + void blockStageIoCheck(const TSourceLoc&, const TQualifier&); + void blockQualifierCheck(const TSourceLoc&, const TQualifier&, bool instanceName); + void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation); + void fixXfbOffsets(TQualifier&, TTypeList&); + void fixBlockUniformOffsets(TQualifier&, TTypeList&); + void addQualifierToExisting(const TSourceLoc&, TQualifier, const TString& identifier); + void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&); + void invariantCheck(const TSourceLoc&, const TQualifier&); + void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&); + void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode); + TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body); + + TAttributeType attributeFromName(const TString& name) const; + TAttributes* makeAttributes(const TString& identifier) const; + TAttributes* makeAttributes(const TString& identifier, TIntermNode* node) const; + TAttributes* mergeAttributes(TAttributes*, TAttributes*) const; + + // Determine selection control from attributes + void handleSelectionAttributes(const TAttributes& attributes, TIntermNode*); + void handleSwitchAttributes(const TAttributes& attributes, TIntermNode*); + + // Determine loop control from attributes + void handleLoopAttributes(const TAttributes& attributes, TIntermNode*); + + void resizeMeshViewDimension(const TSourceLoc&, TType&); + +protected: + void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type); + void inheritGlobalDefaults(TQualifier& dst) const; + TVariable* makeInternalVariable(const char* name, const TType&) const; + TVariable* declareNonArray(const TSourceLoc&, const TString& identifier, const TType&); + void declareArray(const TSourceLoc&, const TString& identifier, const TType&, TSymbol*&); + void checkRuntimeSizable(const TSourceLoc&, const TIntermTyped&); + bool isRuntimeLength(const TIntermTyped&) const; + TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable); + TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer); + void finish() override; + +public: + // + // Generally, bison productions, the scanner, and the PP need read/write access to these; just give them direct access + // + + // Current state of parsing + bool inMain; // if inside a function, true if the function is main + const TString* blockName; + TQualifier currentBlockQualifier; + TPrecisionQualifier defaultPrecision[EbtNumTypes]; + TBuiltInResource resources; + TLimits& limits; + +protected: + TParseContext(TParseContext&); + TParseContext& operator=(TParseContext&); + + static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2 * 2 * 2 * 2)); // see computeSamplerTypeIndex() + TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex]; + TPrecisionManager precisionManager; + TQualifier globalBufferDefaults; + TQualifier globalUniformDefaults; + TQualifier globalInputDefaults; + TQualifier globalOutputDefaults; + int* atomicUintOffsets; // to become an array of the right size to hold an offset per binding point + TString currentCaller; // name of last function body entered (not valid when at global scope) + TIdSetType inductiveLoopIds; + bool anyIndexLimits; + TVector<TIntermTyped*> needsIndexLimitationChecking; + + // + // Geometry shader input arrays: + // - array sizing is based on input primitive and/or explicit size + // + // Tessellation control output arrays: + // - array sizing is based on output layout(vertices=...) and/or explicit size + // + // Both: + // - array sizing is retroactive + // - built-in block redeclarations interact with this + // + // Design: + // - use a per-context "resize-list", a list of symbols whose array sizes + // can be fixed + // + // - the resize-list starts empty at beginning of user-shader compilation, it does + // not have built-ins in it + // + // - on built-in array use: copyUp() symbol and add it to the resize-list + // + // - on user array declaration: add it to the resize-list + // + // - on block redeclaration: copyUp() symbol and add it to the resize-list + // * note, that appropriately gives an error if redeclaring a block that + // was already used and hence already copied-up + // + // - on seeing a layout declaration that sizes the array, fix everything in the + // resize-list, giving errors for mismatch + // + // - on seeing an array size declaration, give errors on mismatch between it and previous + // array-sizing declarations + // + TVector<TSymbol*> ioArraySymbolResizeList; +}; + +} // end namespace glslang + +#endif // _PARSER_HELPER_INCLUDED_ |