Home | History | Annotate | Download | only in MachineIndependent
      1 //
      2 // Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
      3 // Copyright (C) 2012-2013 LunarG, Inc.
      4 //
      5 // All rights reserved.
      6 //
      7 // Redistribution and use in source and binary forms, with or without
      8 // modification, are permitted provided that the following conditions
      9 // are met:
     10 //
     11 //    Redistributions of source code must retain the above copyright
     12 //    notice, this list of conditions and the following disclaimer.
     13 //
     14 //    Redistributions in binary form must reproduce the above
     15 //    copyright notice, this list of conditions and the following
     16 //    disclaimer in the documentation and/or other materials provided
     17 //    with the distribution.
     18 //
     19 //    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
     20 //    contributors may be used to endorse or promote products derived
     21 //    from this software without specific prior written permission.
     22 //
     23 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     24 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     25 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     26 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     27 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     28 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     29 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     30 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     31 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     32 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     33 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     34 // POSSIBILITY OF SUCH DAMAGE.
     35 //
     36 
     37 //
     38 // This header defines a two-level parse-helper hierarchy, derived from
     39 // TParseVersions:
     40 //  - TParseContextBase:  sharable across multiple parsers
     41 //  - TParseContext:      GLSL specific helper
     42 //
     43 
     44 #ifndef _PARSER_HELPER_INCLUDED_
     45 #define _PARSER_HELPER_INCLUDED_
     46 
     47 #include "parseVersions.h"
     48 #include "../Include/ShHandle.h"
     49 #include "SymbolTable.h"
     50 #include "localintermediate.h"
     51 #include "Scan.h"
     52 #include <cstdarg>
     53 #include <functional>
     54 
     55 namespace glslang {
     56 
     57 struct TPragma {
     58     TPragma(bool o, bool d) : optimize(o), debug(d) { }
     59     bool optimize;
     60     bool debug;
     61     TPragmaTable pragmaTable;
     62 };
     63 
     64 class TScanContext;
     65 class TPpContext;
     66 
     67 typedef std::set<int> TIdSetType;
     68 
     69 //
     70 // Sharable code (as well as what's in TParseVersions) across
     71 // parse helpers.
     72 //
     73 class TParseContextBase : public TParseVersions {
     74 public:
     75     TParseContextBase(TSymbolTable& symbolTable, TIntermediate& interm, bool parsingBuiltins, int version,
     76                       EProfile profile, const SpvVersion& spvVersion, EShLanguage language,
     77                       TInfoSink& infoSink, bool forwardCompatible, EShMessages messages)
     78           : TParseVersions(interm, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
     79             scopeMangler("::"),
     80             symbolTable(symbolTable),
     81             statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0),
     82             postEntryPointReturn(false),
     83             contextPragma(true, false),
     84             parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr),
     85             limits(resources.limits),
     86             globalUniformBlock(nullptr)
     87     { }
     88     virtual ~TParseContextBase() { }
     89 
     90     virtual void C_DECL   error(const TSourceLoc&, const char* szReason, const char* szToken,
     91                                 const char* szExtraInfoFormat, ...);
     92     virtual void C_DECL    warn(const TSourceLoc&, const char* szReason, const char* szToken,
     93                                 const char* szExtraInfoFormat, ...);
     94     virtual void C_DECL ppError(const TSourceLoc&, const char* szReason, const char* szToken,
     95                                 const char* szExtraInfoFormat, ...);
     96     virtual void C_DECL  ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
     97                                 const char* szExtraInfoFormat, ...);
     98 
     99     virtual void setLimits(const TBuiltInResource&) = 0;
    100 
    101     EShLanguage getLanguage() const { return language; }
    102     void setScanContext(TScanContext* c) { scanContext = c; }
    103     TScanContext* getScanContext() const { return scanContext; }
    104     void setPpContext(TPpContext* c) { ppContext = c; }
    105     TPpContext* getPpContext() const { return ppContext; }
    106 
    107     virtual void setLineCallback(const std::function<void(int, int, bool, int, const char*)>& func) { lineCallback = func; }
    108     virtual void setExtensionCallback(const std::function<void(int, const char*, const char*)>& func) { extensionCallback = func; }
    109     virtual void setVersionCallback(const std::function<void(int, int, const char*)>& func) { versionCallback = func; }
    110     virtual void setPragmaCallback(const std::function<void(int, const TVector<TString>&)>& func) { pragmaCallback = func; }
    111     virtual void setErrorCallback(const std::function<void(int, const char*)>& func) { errorCallback = func; }
    112 
    113     virtual void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op) = 0;
    114     virtual bool lineContinuationCheck(const TSourceLoc&, bool endOfComment) = 0;
    115     virtual bool lineDirectiveShouldSetNextLine() const = 0;
    116     virtual void handlePragma(const TSourceLoc&, const TVector<TString>&) = 0;
    117 
    118     virtual bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) = 0;
    119 
    120     virtual void notifyVersion(int line, int version, const char* type_string)
    121     {
    122         if (versionCallback)
    123             versionCallback(line, version, type_string);
    124     }
    125     virtual void notifyErrorDirective(int line, const char* error_message)
    126     {
    127         if (errorCallback)
    128             errorCallback(line, error_message);
    129     }
    130     virtual void notifyLineDirective(int curLineNo, int newLineNo, bool hasSource, int sourceNum, const char* sourceName)
    131     {
    132         if (lineCallback)
    133             lineCallback(curLineNo, newLineNo, hasSource, sourceNum, sourceName);
    134     }
    135     virtual void notifyExtensionDirective(int line, const char* extension, const char* behavior)
    136     {
    137         if (extensionCallback)
    138             extensionCallback(line, extension, behavior);
    139     }
    140 
    141     // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
    142     virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr);
    143 
    144     virtual bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
    145     virtual void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
    146 
    147     const char* const scopeMangler;
    148 
    149     // Basic parsing state, easily accessible to the grammar
    150 
    151     TSymbolTable& symbolTable;        // symbol table that goes with the current language, version, and profile
    152     int statementNestingLevel;        // 0 if outside all flow control or compound statements
    153     int loopNestingLevel;             // 0 if outside all loops
    154     int structNestingLevel;           // 0 if outside blocks and structures
    155     int controlFlowNestingLevel;      // 0 if outside all flow control
    156     const TType* currentFunctionType; // the return type of the function that's currently being parsed
    157     bool functionReturnsValue;        // true if a non-void function has a return
    158     // if inside a function, true if the function is the entry point and this is after a return statement
    159     bool postEntryPointReturn;
    160     // case, node, case, case, node, ...; ensure only one node between cases;   stack of them for nesting
    161     TList<TIntermSequence*> switchSequenceStack;
    162     // the statementNestingLevel the current switch statement is at, which must match the level of its case statements
    163     TList<int> switchLevel;
    164     struct TPragma contextPragma;
    165 
    166 protected:
    167     TParseContextBase(TParseContextBase&);
    168     TParseContextBase& operator=(TParseContextBase&);
    169 
    170     const bool parsingBuiltins;       // true if parsing built-in symbols/functions
    171     TVector<TSymbol*> linkageSymbols; // these need to be transferred to 'linkage', after all editing is done
    172     TScanContext* scanContext;
    173     TPpContext* ppContext;
    174     TBuiltInResource resources;
    175     TLimits& limits;
    176 
    177     // These, if set, will be called when a line, pragma ... is preprocessed.
    178     // They will be called with any parameters to the original directive.
    179     std::function<void(int, int, bool, int, const char*)> lineCallback;
    180     std::function<void(int, const TVector<TString>&)> pragmaCallback;
    181     std::function<void(int, int, const char*)> versionCallback;
    182     std::function<void(int, const char*, const char*)> extensionCallback;
    183     std::function<void(int, const char*)> errorCallback;
    184 
    185     // see implementation for detail
    186     const TFunction* selectFunction(const TVector<const TFunction*>, const TFunction&,
    187         std::function<bool(const TType&, const TType&, TOperator, int arg)>,
    188         std::function<bool(const TType&, const TType&, const TType&)>,
    189         /* output */ bool& tie);
    190 
    191     virtual void parseSwizzleSelector(const TSourceLoc&, const TString&, int size,
    192                                       TSwizzleSelectors<TVectorSelector>&);
    193 
    194     // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
    195     TVariable* globalUniformBlock;   // the actual block, inserted into the symbol table
    196     int firstNewMember;              // the index of the first member not yet inserted into the symbol table
    197     // override this to set the language-specific name
    198     virtual const char* getGlobalUniformBlockName() const { return ""; }
    199     virtual void setUniformBlockDefaults(TType&) const { }
    200     virtual void finalizeGlobalUniformBlockLayout(TVariable&) { }
    201     virtual void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken,
    202                                const char* szExtraInfoFormat, TPrefixType prefix,
    203                                va_list args);
    204     virtual void trackLinkage(TSymbol& symbol);
    205     virtual void makeEditable(TSymbol*&);
    206     virtual TVariable* getEditableVariable(const char* name);
    207     virtual void finish();
    208 };
    209 
    210 //
    211 // Manage the state for when to respect precision qualifiers and when to warn about
    212 // the defaults being different than might be expected.
    213 //
    214 class TPrecisionManager {
    215 public:
    216     TPrecisionManager() : obey(false), warn(false), explicitIntDefault(false), explicitFloatDefault(false){ }
    217     virtual ~TPrecisionManager() {}
    218 
    219     void respectPrecisionQualifiers() { obey = true; }
    220     bool respectingPrecisionQualifiers() const { return obey; }
    221     bool shouldWarnAboutDefaults() const { return warn; }
    222     void defaultWarningGiven() { warn = false; }
    223     void warnAboutDefaults() { warn = true; }
    224     void explicitIntDefaultSeen()
    225     {
    226         explicitIntDefault = true;
    227         if (explicitFloatDefault)
    228             warn = false;
    229     }
    230     void explicitFloatDefaultSeen()
    231     {
    232         explicitFloatDefault = true;
    233         if (explicitIntDefault)
    234             warn = false;
    235     }
    236 
    237 protected:
    238     bool obey;                  // respect precision qualifiers
    239     bool warn;                  // need to give a warning about the defaults
    240     bool explicitIntDefault;    // user set the default for int/uint
    241     bool explicitFloatDefault;  // user set the default for float
    242 };
    243 
    244 //
    245 // GLSL-specific parse helper.  Should have GLSL in the name, but that's
    246 // too big of a change for comparing branches at the moment, and perhaps
    247 // impacts downstream consumers as well.
    248 //
    249 class TParseContext : public TParseContextBase {
    250 public:
    251     TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, const SpvVersion& spvVersion, EShLanguage, TInfoSink&,
    252                   bool forwardCompatible = false, EShMessages messages = EShMsgDefault);
    253     virtual ~TParseContext();
    254 
    255     bool obeyPrecisionQualifiers() const { return precisionManager.respectingPrecisionQualifiers(); };
    256     void setPrecisionDefaults();
    257 
    258     void setLimits(const TBuiltInResource&) override;
    259     bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) override;
    260     void parserError(const char* s);     // for bison's yyerror
    261 
    262     void reservedErrorCheck(const TSourceLoc&, const TString&);
    263     void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op) override;
    264     bool lineContinuationCheck(const TSourceLoc&, bool endOfComment) override;
    265     bool lineDirectiveShouldSetNextLine() const override;
    266     bool builtInName(const TString&);
    267 
    268     void handlePragma(const TSourceLoc&, const TVector<TString>&) override;
    269     TIntermTyped* handleVariable(const TSourceLoc&, TSymbol* symbol, const TString* string);
    270     TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
    271     void checkIndex(const TSourceLoc&, const TType&, int& index);
    272     void handleIndexLimits(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
    273 
    274     void makeEditable(TSymbol*&) override;
    275     bool isIoResizeArray(const TType&) const;
    276     void fixIoArraySize(const TSourceLoc&, TType&);
    277     void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier);
    278     void handleIoResizeArrayAccess(const TSourceLoc&, TIntermTyped* base);
    279     void checkIoArraysConsistency(const TSourceLoc&, bool tailOnly = false);
    280     int getIoArrayImplicitSize() const;
    281     void checkIoArrayConsistency(const TSourceLoc&, int requiredSize, const char* feature, TType&, const TString&);
    282 
    283     TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);
    284     TIntermTyped* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode);
    285     TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field);
    286     void blockMemberExtensionCheck(const TSourceLoc&, const TIntermTyped* base, const TString& field);
    287     TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
    288     TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
    289     TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
    290     TIntermTyped* handleBuiltInFunctionCall(TSourceLoc, TIntermNode& arguments, const TFunction& function);
    291     void computeBuiltinPrecisions(TIntermTyped&, const TFunction&);
    292     TIntermNode* handleReturnValue(const TSourceLoc&, TIntermTyped*);
    293     void checkLocation(const TSourceLoc&, TOperator);
    294     TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*);
    295     void addInputArgumentConversions(const TFunction&, TIntermNode*&) const;
    296     TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const;
    297     void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
    298     void nonOpBuiltInCheck(const TSourceLoc&, const TFunction&, TIntermAggregate&);
    299     void userFunctionCallCheck(const TSourceLoc&, TIntermAggregate&);
    300     void samplerConstructorLocationCheck(const TSourceLoc&, const char* token, TIntermNode*);
    301     TFunction* handleConstructorCall(const TSourceLoc&, const TPublicType&);
    302     void handlePrecisionQualifier(const TSourceLoc&, TQualifier&, TPrecisionQualifier);
    303     void checkPrecisionQualifier(const TSourceLoc&, TPrecisionQualifier);
    304 
    305     void assignError(const TSourceLoc&, const char* op, TString left, TString right);
    306     void unaryOpError(const TSourceLoc&, const char* op, TString operand);
    307     void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right);
    308     void variableCheck(TIntermTyped*& nodePtr);
    309     bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*) override;
    310     void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*) override;
    311     void constantValueCheck(TIntermTyped* node, const char* token);
    312     void integerCheck(const TIntermTyped* node, const char* token);
    313     void globalCheck(const TSourceLoc&, const char* token);
    314     bool constructorError(const TSourceLoc&, TIntermNode*, TFunction&, TOperator, TType&);
    315     bool constructorTextureSamplerError(const TSourceLoc&, const TFunction&);
    316     void arraySizeCheck(const TSourceLoc&, TIntermTyped* expr, TArraySize&);
    317     bool arrayQualifierError(const TSourceLoc&, const TQualifier&);
    318     bool arrayError(const TSourceLoc&, const TType&);
    319     void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&);
    320     void structArrayCheck(const TSourceLoc&, const TType& structure);
    321     void arraySizesCheck(const TSourceLoc&, const TQualifier&, const TArraySizes*, bool initializer, bool lastMember);
    322     void arrayOfArrayVersionCheck(const TSourceLoc&);
    323     void arrayDimCheck(const TSourceLoc&, const TArraySizes* sizes1, const TArraySizes* sizes2);
    324     void arrayDimCheck(const TSourceLoc&, const TType*, const TArraySizes*);
    325     void arrayDimMerge(TType& type, const TArraySizes* sizes);
    326     bool voidErrorCheck(const TSourceLoc&, const TString&, TBasicType);
    327     void boolCheck(const TSourceLoc&, const TIntermTyped*);
    328     void boolCheck(const TSourceLoc&, const TPublicType&);
    329     void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer);
    330     void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier);
    331     void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier);
    332     void globalQualifierFixCheck(const TSourceLoc&, TQualifier&);
    333     void globalQualifierTypeCheck(const TSourceLoc&, const TQualifier&, const TPublicType&);
    334     bool structQualifierErrorCheck(const TSourceLoc&, const TPublicType& pType);
    335     void mergeQualifiers(const TSourceLoc&, TQualifier& dst, const TQualifier& src, bool force);
    336     void setDefaultPrecision(const TSourceLoc&, TPublicType&, TPrecisionQualifier);
    337     int computeSamplerTypeIndex(TSampler&);
    338     TPrecisionQualifier getDefaultPrecision(TPublicType&);
    339     void precisionQualifierCheck(const TSourceLoc&, TBasicType, TQualifier&);
    340     void parameterTypeCheck(const TSourceLoc&, TStorageQualifier qualifier, const TType& type);
    341     bool containsFieldWithBasicType(const TType& type ,TBasicType basicType);
    342     TSymbol* redeclareBuiltinVariable(const TSourceLoc&, const TString&, const TQualifier&, const TShaderQualifiers&);
    343     void redeclareBuiltinBlock(const TSourceLoc&, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes);
    344     void paramCheckFix(const TSourceLoc&, const TStorageQualifier&, TType& type);
    345     void paramCheckFix(const TSourceLoc&, const TQualifier&, TType& type);
    346     void nestedBlockCheck(const TSourceLoc&);
    347     void nestedStructCheck(const TSourceLoc&);
    348     void arrayObjectCheck(const TSourceLoc&, const TType&, const char* op);
    349     void opaqueCheck(const TSourceLoc&, const TType&, const char* op);
    350     void specializationCheck(const TSourceLoc&, const TType&, const char* op);
    351     void structTypeCheck(const TSourceLoc&, TPublicType&);
    352     void inductiveLoopCheck(const TSourceLoc&, TIntermNode* init, TIntermLoop* loop);
    353     void arrayLimitCheck(const TSourceLoc&, const TString&, int size);
    354     void limitCheck(const TSourceLoc&, int value, const char* limit, const char* feature);
    355 
    356     void inductiveLoopBodyCheck(TIntermNode*, int loopIndexId, TSymbolTable&);
    357     void constantIndexExpressionCheck(TIntermNode*);
    358 
    359     void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&);
    360     void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&, const TIntermTyped*);
    361     void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly);
    362     void layoutObjectCheck(const TSourceLoc&, const TSymbol&);
    363     void layoutMemberLocationArrayCheck(const TSourceLoc&, bool memberWithLocation, TArraySizes* arraySizes);
    364     void layoutTypeCheck(const TSourceLoc&, const TType&);
    365     void layoutQualifierCheck(const TSourceLoc&, const TQualifier&);
    366     void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);
    367     void fixOffset(const TSourceLoc&, TSymbol&);
    368 
    369     const TFunction* findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
    370     const TFunction* findFunctionExact(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
    371     const TFunction* findFunction120(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
    372     const TFunction* findFunction400(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
    373     void declareTypeDefaults(const TSourceLoc&, const TPublicType&);
    374     TIntermNode* declareVariable(const TSourceLoc&, TString& identifier, const TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0);
    375     TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&);
    376     TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
    377     TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
    378     void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
    379     void blockStageIoCheck(const TSourceLoc&, const TQualifier&);
    380     void blockQualifierCheck(const TSourceLoc&, const TQualifier&, bool instanceName);
    381     void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
    382     void fixBlockXfbOffsets(TQualifier&, TTypeList&);
    383     void fixBlockUniformOffsets(TQualifier&, TTypeList&);
    384     void addQualifierToExisting(const TSourceLoc&, TQualifier, const TString& identifier);
    385     void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&);
    386     void invariantCheck(const TSourceLoc&, const TQualifier&);
    387     void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&);
    388     void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
    389     TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body);
    390 
    391     void updateImplicitArraySize(const TSourceLoc&, TIntermNode*, int index);
    392 
    393 protected:
    394     void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type);
    395     void inheritGlobalDefaults(TQualifier& dst) const;
    396     TVariable* makeInternalVariable(const char* name, const TType&) const;
    397     TVariable* declareNonArray(const TSourceLoc&, const TString& identifier, const TType&);
    398     void declareArray(const TSourceLoc&, const TString& identifier, const TType&, TSymbol*&);
    399     TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
    400     TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
    401     void finish() override;
    402 
    403 public:
    404     //
    405     // Generally, bison productions, the scanner, and the PP need read/write access to these; just give them direct access
    406     //
    407 
    408     // Current state of parsing
    409     bool inMain;                 // if inside a function, true if the function is main
    410     const TString* blockName;
    411     TQualifier currentBlockQualifier;
    412     TPrecisionQualifier defaultPrecision[EbtNumTypes];
    413     TBuiltInResource resources;
    414     TLimits& limits;
    415 
    416 protected:
    417     TParseContext(TParseContext&);
    418     TParseContext& operator=(TParseContext&);
    419 
    420     static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2 * 2 * 2 * 2)); // see computeSamplerTypeIndex()
    421     TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex];
    422     TPrecisionManager precisionManager;
    423     TQualifier globalBufferDefaults;
    424     TQualifier globalUniformDefaults;
    425     TQualifier globalInputDefaults;
    426     TQualifier globalOutputDefaults;
    427     int* atomicUintOffsets;       // to become an array of the right size to hold an offset per binding point
    428     TString currentCaller;        // name of last function body entered (not valid when at global scope)
    429     TIdSetType inductiveLoopIds;
    430     bool anyIndexLimits;
    431     TVector<TIntermTyped*> needsIndexLimitationChecking;
    432 
    433     //
    434     // Geometry shader input arrays:
    435     //  - array sizing is based on input primitive and/or explicit size
    436     //
    437     // Tessellation control output arrays:
    438     //  - array sizing is based on output layout(vertices=...) and/or explicit size
    439     //
    440     // Both:
    441     //  - array sizing is retroactive
    442     //  - built-in block redeclarations interact with this
    443     //
    444     // Design:
    445     //  - use a per-context "resize-list", a list of symbols whose array sizes
    446     //    can be fixed
    447     //
    448     //  - the resize-list starts empty at beginning of user-shader compilation, it does
    449     //    not have built-ins in it
    450     //
    451     //  - on built-in array use: copyUp() symbol and add it to the resize-list
    452     //
    453     //  - on user array declaration: add it to the resize-list
    454     //
    455     //  - on block redeclaration: copyUp() symbol and add it to the resize-list
    456     //     * note, that appropriately gives an error if redeclaring a block that
    457     //       was already used and hence already copied-up
    458     //
    459     //  - on seeing a layout declaration that sizes the array, fix everything in the
    460     //    resize-list, giving errors for mismatch
    461     //
    462     //  - on seeing an array size declaration, give errors on mismatch between it and previous
    463     //    array-sizing declarations
    464     //
    465     TVector<TSymbol*> ioArraySymbolResizeList;
    466 };
    467 
    468 } // end namespace glslang
    469 
    470 #endif // _PARSER_HELPER_INCLUDED_
    471