2 // Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
3 // Copyright (C) 2012-2013 LunarG, Inc.
4 // Copyright (C) 2015-2018 Google, Inc.
6 // All rights reserved.
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions
12 // Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
15 // Redistributions in binary form must reproduce the above
16 // copyright notice, this list of conditions and the following
17 // disclaimer in the documentation and/or other materials provided
18 // with the distribution.
20 // Neither the name of 3Dlabs Inc. Ltd. nor the names of its
21 // contributors may be used to endorse or promote products derived
22 // from this software without specific prior written permission.
24 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 // POSSIBILITY OF SUCH DAMAGE.
39 // This header defines a two-level parse-helper hierarchy, derived from
41 // - TParseContextBase: sharable across multiple parsers
42 // - TParseContext: GLSL specific helper
45 #ifndef _PARSER_HELPER_INCLUDED_
46 #define _PARSER_HELPER_INCLUDED_
51 #include "parseVersions.h"
52 #include "../Include/ShHandle.h"
53 #include "SymbolTable.h"
54 #include "localintermediate.h"
56 #include "attribute.h"
61 TPragma(bool o, bool d) : optimize(o), debug(d) { }
64 TPragmaTable pragmaTable;
70 typedef std::set<long long> TIdSetType;
71 typedef std::map<const TTypeList*, std::map<size_t, const TTypeList*>> TStructRecord;
74 // Sharable code (as well as what's in TParseVersions) across
77 class TParseContextBase : public TParseVersions {
79 TParseContextBase(TSymbolTable& symbolTable, TIntermediate& interm, bool parsingBuiltins, int version,
80 EProfile profile, const SpvVersion& spvVersion, EShLanguage language,
81 TInfoSink& infoSink, bool forwardCompatible, EShMessages messages,
82 const TString* entryPoint = nullptr)
83 : TParseVersions(interm, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
85 symbolTable(symbolTable),
86 statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), blockNestingLevel(0), controlFlowNestingLevel(0),
87 currentFunctionType(nullptr),
88 postEntryPointReturn(false),
89 contextPragma(true, false),
90 beginInvocationInterlockCount(0), endInvocationInterlockCount(0),
91 parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr),
92 limits(resources.limits),
93 globalUniformBlock(nullptr),
94 globalUniformBinding(TQualifier::layoutBindingEnd),
95 globalUniformSet(TQualifier::layoutSetEnd),
96 atomicCounterBlockSet(TQualifier::layoutSetEnd)
98 if (entryPoint != nullptr)
99 sourceEntryPointName = *entryPoint;
101 virtual ~TParseContextBase() { }
103 #if !defined(GLSLANG_WEB) || defined(GLSLANG_WEB_DEVEL)
104 virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
105 const char* szExtraInfoFormat, ...);
106 virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken,
107 const char* szExtraInfoFormat, ...);
108 virtual void C_DECL ppError(const TSourceLoc&, const char* szReason, const char* szToken,
109 const char* szExtraInfoFormat, ...);
110 virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
111 const char* szExtraInfoFormat, ...);
114 virtual void setLimits(const TBuiltInResource&) = 0;
116 void checkIndex(const TSourceLoc&, const TType&, int& index);
118 EShLanguage getLanguage() const { return language; }
119 void setScanContext(TScanContext* c) { scanContext = c; }
120 TScanContext* getScanContext() const { return scanContext; }
121 void setPpContext(TPpContext* c) { ppContext = c; }
122 TPpContext* getPpContext() const { return ppContext; }
124 virtual void setLineCallback(const std::function<void(int, int, bool, int, const char*)>& func) { lineCallback = func; }
125 virtual void setExtensionCallback(const std::function<void(int, const char*, const char*)>& func) { extensionCallback = func; }
126 virtual void setVersionCallback(const std::function<void(int, int, const char*)>& func) { versionCallback = func; }
127 virtual void setPragmaCallback(const std::function<void(int, const TVector<TString>&)>& func) { pragmaCallback = func; }
128 virtual void setErrorCallback(const std::function<void(int, const char*)>& func) { errorCallback = func; }
130 virtual void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op) = 0;
131 virtual bool lineContinuationCheck(const TSourceLoc&, bool endOfComment) = 0;
132 virtual bool lineDirectiveShouldSetNextLine() const = 0;
133 virtual void handlePragma(const TSourceLoc&, const TVector<TString>&) = 0;
135 virtual bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) = 0;
137 virtual void notifyVersion(int line, int version, const char* type_string)
140 versionCallback(line, version, type_string);
142 virtual void notifyErrorDirective(int line, const char* error_message)
145 errorCallback(line, error_message);
147 virtual void notifyLineDirective(int curLineNo, int newLineNo, bool hasSource, int sourceNum, const char* sourceName)
150 lineCallback(curLineNo, newLineNo, hasSource, sourceNum, sourceName);
152 virtual void notifyExtensionDirective(int line, const char* extension, const char* behavior)
154 if (extensionCallback)
155 extensionCallback(line, extension, behavior);
158 // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
159 virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr);
161 // Manage global buffer (used for backing atomic counters in GLSL when using relaxed Vulkan semantics)
162 virtual void growAtomicCounterBlock(int binding, const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr);
164 // Potentially rename shader entry point function
165 void renameShaderFunction(TString*& name) const
167 // Replace the entry point name given in the shader with the real entry point name,
168 // if there is a substitution.
169 if (name != nullptr && *name == sourceEntryPointName && intermediate.getEntryPointName().size() > 0)
170 name = NewPoolTString(intermediate.getEntryPointName().c_str());
173 virtual bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
174 virtual void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
176 const char* const scopeMangler;
178 // Basic parsing state, easily accessible to the grammar
180 TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile
181 int statementNestingLevel; // 0 if outside all flow control or compound statements
182 int loopNestingLevel; // 0 if outside all loops
183 int structNestingLevel; // 0 if outside structures
184 int blockNestingLevel; // 0 if outside blocks
185 int controlFlowNestingLevel; // 0 if outside all flow control
186 const TType* currentFunctionType; // the return type of the function that's currently being parsed
187 bool functionReturnsValue; // true if a non-void function has a return
188 // if inside a function, true if the function is the entry point and this is after a return statement
189 bool postEntryPointReturn;
190 // case, node, case, case, node, ...; ensure only one node between cases; stack of them for nesting
191 TList<TIntermSequence*> switchSequenceStack;
192 // the statementNestingLevel the current switch statement is at, which must match the level of its case statements
193 TList<int> switchLevel;
194 struct TPragma contextPragma;
195 int beginInvocationInterlockCount;
196 int endInvocationInterlockCount;
199 TParseContextBase(TParseContextBase&);
200 TParseContextBase& operator=(TParseContextBase&);
202 const bool parsingBuiltins; // true if parsing built-in symbols/functions
203 TVector<TSymbol*> linkageSymbols; // will be transferred to 'linkage', after all editing is done, order preserving
204 TScanContext* scanContext;
205 TPpContext* ppContext;
206 TBuiltInResource resources;
208 TString sourceEntryPointName;
210 // These, if set, will be called when a line, pragma ... is preprocessed.
211 // They will be called with any parameters to the original directive.
212 std::function<void(int, int, bool, int, const char*)> lineCallback;
213 std::function<void(int, const TVector<TString>&)> pragmaCallback;
214 std::function<void(int, int, const char*)> versionCallback;
215 std::function<void(int, const char*, const char*)> extensionCallback;
216 std::function<void(int, const char*)> errorCallback;
218 // see implementation for detail
219 const TFunction* selectFunction(const TVector<const TFunction*>, const TFunction&,
220 std::function<bool(const TType&, const TType&, TOperator, int arg)>,
221 std::function<bool(const TType&, const TType&, const TType&)>,
222 /* output */ bool& tie);
224 virtual void parseSwizzleSelector(const TSourceLoc&, const TString&, int size,
225 TSwizzleSelectors<TVectorSelector>&);
227 // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
228 TVariable* globalUniformBlock; // the actual block, inserted into the symbol table
229 unsigned int globalUniformBinding; // the block's binding number
230 unsigned int globalUniformSet; // the block's set number
231 int firstNewMember; // the index of the first member not yet inserted into the symbol table
232 // override this to set the language-specific name
233 virtual const char* getGlobalUniformBlockName() const { return ""; }
234 virtual void setUniformBlockDefaults(TType&) const { }
235 virtual void finalizeGlobalUniformBlockLayout(TVariable&) {}
237 // Manage the atomic counter block (used for atomic_uints with Vulkan-Relaxed)
238 TMap<int, TVariable*> atomicCounterBuffers;
239 unsigned int atomicCounterBlockSet;
240 TMap<int, int> atomicCounterBlockFirstNewMember;
241 // override this to set the language-specific name
242 virtual const char* getAtomicCounterBlockName() const { return ""; }
243 virtual void setAtomicCounterBlockDefaults(TType&) const {}
244 virtual void setInvariant(const TSourceLoc&, const char*) {}
245 virtual void finalizeAtomicCounterBlockLayout(TVariable&) {}
246 bool isAtomicCounterBlock(const TSymbol& symbol) {
247 const TVariable* var = symbol.getAsVariable();
250 const auto& at = atomicCounterBuffers.find(var->getType().getQualifier().layoutBinding);
251 return (at != atomicCounterBuffers.end() && (*at).second->getType() == var->getType());
254 virtual void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken,
255 const char* szExtraInfoFormat, TPrefixType prefix,
257 virtual void trackLinkage(TSymbol& symbol);
258 virtual void makeEditable(TSymbol*&);
259 virtual TVariable* getEditableVariable(const char* name);
260 virtual void finish();
264 // Manage the state for when to respect precision qualifiers and when to warn about
265 // the defaults being different than might be expected.
267 class TPrecisionManager {
269 TPrecisionManager() : obey(false), warn(false), explicitIntDefault(false), explicitFloatDefault(false){ }
270 virtual ~TPrecisionManager() {}
272 void respectPrecisionQualifiers() { obey = true; }
273 bool respectingPrecisionQualifiers() const { return obey; }
274 bool shouldWarnAboutDefaults() const { return warn; }
275 void defaultWarningGiven() { warn = false; }
276 void warnAboutDefaults() { warn = true; }
277 void explicitIntDefaultSeen()
279 explicitIntDefault = true;
280 if (explicitFloatDefault)
283 void explicitFloatDefaultSeen()
285 explicitFloatDefault = true;
286 if (explicitIntDefault)
291 bool obey; // respect precision qualifiers
292 bool warn; // need to give a warning about the defaults
293 bool explicitIntDefault; // user set the default for int/uint
294 bool explicitFloatDefault; // user set the default for float
298 // GLSL-specific parse helper. Should have GLSL in the name, but that's
299 // too big of a change for comparing branches at the moment, and perhaps
300 // impacts downstream consumers as well.
302 class TParseContext : public TParseContextBase {
304 TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, const SpvVersion& spvVersion, EShLanguage, TInfoSink&,
305 bool forwardCompatible = false, EShMessages messages = EShMsgDefault,
306 const TString* entryPoint = nullptr);
307 virtual ~TParseContext();
309 bool obeyPrecisionQualifiers() const { return precisionManager.respectingPrecisionQualifiers(); }
310 void setPrecisionDefaults();
312 void setLimits(const TBuiltInResource&) override;
313 bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) override;
314 void parserError(const char* s); // for bison's yyerror
316 virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr) override;
317 virtual void growAtomicCounterBlock(int binding, const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr) override;
319 void reservedErrorCheck(const TSourceLoc&, const TString&);
320 void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op) override;
321 bool lineContinuationCheck(const TSourceLoc&, bool endOfComment) override;
322 bool lineDirectiveShouldSetNextLine() const override;
323 bool builtInName(const TString&);
325 void handlePragma(const TSourceLoc&, const TVector<TString>&) override;
326 TIntermTyped* handleVariable(const TSourceLoc&, TSymbol* symbol, const TString* string);
327 TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
328 void handleIndexLimits(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
331 void makeEditable(TSymbol*&) override;
332 void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier);
334 bool isIoResizeArray(const TType&) const;
335 void fixIoArraySize(const TSourceLoc&, TType&);
336 void handleIoResizeArrayAccess(const TSourceLoc&, TIntermTyped* base);
337 void checkIoArraysConsistency(const TSourceLoc&, bool tailOnly = false);
338 int getIoArrayImplicitSize(const TQualifier&, TString* featureString = nullptr) const;
339 void checkIoArrayConsistency(const TSourceLoc&, int requiredSize, const char* feature, TType&, const TString&);
341 TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);
342 TIntermTyped* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode);
343 TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field);
344 TIntermTyped* handleDotSwizzle(const TSourceLoc&, TIntermTyped* base, const TString& field);
345 void blockMemberExtensionCheck(const TSourceLoc&, const TIntermTyped* base, int member, const TString& memberName);
346 TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
347 TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
348 TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
349 TIntermTyped* handleBuiltInFunctionCall(TSourceLoc, TIntermNode* arguments, const TFunction& function);
350 void computeBuiltinPrecisions(TIntermTyped&, const TFunction&);
351 TIntermNode* handleReturnValue(const TSourceLoc&, TIntermTyped*);
352 void checkLocation(const TSourceLoc&, TOperator);
353 TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*);
354 void addInputArgumentConversions(const TFunction&, TIntermNode*&) const;
355 TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const;
356 TIntermTyped* addAssign(const TSourceLoc&, TOperator op, TIntermTyped* left, TIntermTyped* right);
357 void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
358 void nonOpBuiltInCheck(const TSourceLoc&, const TFunction&, TIntermAggregate&);
359 void userFunctionCallCheck(const TSourceLoc&, TIntermAggregate&);
360 void samplerConstructorLocationCheck(const TSourceLoc&, const char* token, TIntermNode*);
361 TFunction* handleConstructorCall(const TSourceLoc&, const TPublicType&);
362 void handlePrecisionQualifier(const TSourceLoc&, TQualifier&, TPrecisionQualifier);
363 void checkPrecisionQualifier(const TSourceLoc&, TPrecisionQualifier);
364 void memorySemanticsCheck(const TSourceLoc&, const TFunction&, const TIntermOperator& callNode);
366 TIntermTyped* vkRelaxedRemapFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
367 // returns true if the variable was remapped to something else
368 bool vkRelaxedRemapUniformVariable(const TSourceLoc&, TString&, const TPublicType&, TArraySizes*, TIntermTyped*, TType&);
370 void assignError(const TSourceLoc&, const char* op, TString left, TString right);
371 void unaryOpError(const TSourceLoc&, const char* op, TString operand);
372 void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right);
373 void variableCheck(TIntermTyped*& nodePtr);
374 bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*) override;
375 void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*) override;
376 void constantValueCheck(TIntermTyped* node, const char* token);
377 void integerCheck(const TIntermTyped* node, const char* token);
378 void globalCheck(const TSourceLoc&, const char* token);
379 bool constructorError(const TSourceLoc&, TIntermNode*, TFunction&, TOperator, TType&);
380 bool constructorTextureSamplerError(const TSourceLoc&, const TFunction&);
381 void arraySizeCheck(const TSourceLoc&, TIntermTyped* expr, TArraySize&, const char *sizeType);
382 bool arrayQualifierError(const TSourceLoc&, const TQualifier&);
383 bool arrayError(const TSourceLoc&, const TType&);
384 void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&);
385 void structArrayCheck(const TSourceLoc&, const TType& structure);
386 void arraySizesCheck(const TSourceLoc&, const TQualifier&, TArraySizes*, const TIntermTyped* initializer, bool lastMember);
387 void arrayOfArrayVersionCheck(const TSourceLoc&, const TArraySizes*);
388 bool voidErrorCheck(const TSourceLoc&, const TString&, TBasicType);
389 void boolCheck(const TSourceLoc&, const TIntermTyped*);
390 void boolCheck(const TSourceLoc&, const TPublicType&);
391 void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer);
392 void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier);
393 void accStructCheck(const TSourceLoc & loc, const TType & type, const TString & identifier);
394 void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier);
395 void memberQualifierCheck(glslang::TPublicType&);
396 void globalQualifierFixCheck(const TSourceLoc&, TQualifier&, bool isMemberCheck = false);
397 void globalQualifierTypeCheck(const TSourceLoc&, const TQualifier&, const TPublicType&);
398 bool structQualifierErrorCheck(const TSourceLoc&, const TPublicType& pType);
399 void mergeQualifiers(const TSourceLoc&, TQualifier& dst, const TQualifier& src, bool force);
400 void setDefaultPrecision(const TSourceLoc&, TPublicType&, TPrecisionQualifier);
401 int computeSamplerTypeIndex(TSampler&);
402 TPrecisionQualifier getDefaultPrecision(TPublicType&);
403 void precisionQualifierCheck(const TSourceLoc&, TBasicType, TQualifier&);
404 void parameterTypeCheck(const TSourceLoc&, TStorageQualifier qualifier, const TType& type);
405 bool containsFieldWithBasicType(const TType& type ,TBasicType basicType);
406 TSymbol* redeclareBuiltinVariable(const TSourceLoc&, const TString&, const TQualifier&, const TShaderQualifiers&);
407 void redeclareBuiltinBlock(const TSourceLoc&, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes);
408 void paramCheckFixStorage(const TSourceLoc&, const TStorageQualifier&, TType& type);
409 void paramCheckFix(const TSourceLoc&, const TQualifier&, TType& type);
410 void nestedBlockCheck(const TSourceLoc&);
411 void nestedStructCheck(const TSourceLoc&);
412 void arrayObjectCheck(const TSourceLoc&, const TType&, const char* op);
413 void opaqueCheck(const TSourceLoc&, const TType&, const char* op);
414 void referenceCheck(const TSourceLoc&, const TType&, const char* op);
415 void storage16BitAssignmentCheck(const TSourceLoc&, const TType&, const char* op);
416 void specializationCheck(const TSourceLoc&, const TType&, const char* op);
417 void structTypeCheck(const TSourceLoc&, TPublicType&);
418 void inductiveLoopCheck(const TSourceLoc&, TIntermNode* init, TIntermLoop* loop);
419 void arrayLimitCheck(const TSourceLoc&, const TString&, int size);
420 void limitCheck(const TSourceLoc&, int value, const char* limit, const char* feature);
422 void inductiveLoopBodyCheck(TIntermNode*, long long loopIndexId, TSymbolTable&);
423 void constantIndexExpressionCheck(TIntermNode*);
425 void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&);
426 void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&, const TIntermTyped*);
427 void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly);
428 void layoutObjectCheck(const TSourceLoc&, const TSymbol&);
429 void layoutMemberLocationArrayCheck(const TSourceLoc&, bool memberWithLocation, TArraySizes* arraySizes);
430 void layoutTypeCheck(const TSourceLoc&, const TType&);
431 void layoutQualifierCheck(const TSourceLoc&, const TQualifier&);
432 void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);
433 void fixOffset(const TSourceLoc&, TSymbol&);
435 const TFunction* findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
436 const TFunction* findFunctionExact(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
437 const TFunction* findFunction120(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
438 const TFunction* findFunction400(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
439 const TFunction* findFunctionExplicitTypes(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
440 void declareTypeDefaults(const TSourceLoc&, const TPublicType&);
441 TIntermNode* declareVariable(const TSourceLoc&, TString& identifier, const TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0);
442 TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&);
443 TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
444 TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
445 void inheritMemoryQualifiers(const TQualifier& from, TQualifier& to);
446 void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
447 void blockStorageRemap(const TSourceLoc&, const TString*, TQualifier&);
448 void blockStageIoCheck(const TSourceLoc&, const TQualifier&);
449 void blockQualifierCheck(const TSourceLoc&, const TQualifier&, bool instanceName);
450 void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
451 void fixXfbOffsets(TQualifier&, TTypeList&);
452 void fixBlockUniformOffsets(TQualifier&, TTypeList&);
453 void fixBlockUniformLayoutMatrix(TQualifier&, TTypeList*, TTypeList*);
454 void fixBlockUniformLayoutPacking(TQualifier&, TTypeList*, TTypeList*);
455 void addQualifierToExisting(const TSourceLoc&, TQualifier, const TString& identifier);
456 void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&);
457 void invariantCheck(const TSourceLoc&, const TQualifier&);
458 void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&);
459 void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
460 TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body);
461 const TTypeList* recordStructCopy(TStructRecord&, const TType*, const TType*);
464 TAttributeType attributeFromName(const TString& name) const;
465 TAttributes* makeAttributes(const TString& identifier) const;
466 TAttributes* makeAttributes(const TString& identifier, TIntermNode* node) const;
467 TAttributes* mergeAttributes(TAttributes*, TAttributes*) const;
469 // Determine selection control from attributes
470 void handleSelectionAttributes(const TAttributes& attributes, TIntermNode*);
471 void handleSwitchAttributes(const TAttributes& attributes, TIntermNode*);
472 // Determine loop control from attributes
473 void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
474 // Function attributes
475 void handleFunctionAttributes(const TSourceLoc&, const TAttributes&);
477 // GL_EXT_spirv_intrinsics
478 TSpirvRequirement* makeSpirvRequirement(const TSourceLoc& loc, const TString& name,
479 const TIntermAggregate* extensions, const TIntermAggregate* capabilities);
480 TSpirvRequirement* mergeSpirvRequirements(const TSourceLoc& loc, TSpirvRequirement* spirvReq1,
481 TSpirvRequirement* spirvReq2);
482 TSpirvTypeParameters* makeSpirvTypeParameters(const TSourceLoc& loc, const TIntermConstantUnion* constant);
483 TSpirvTypeParameters* makeSpirvTypeParameters(const TPublicType& type);
484 TSpirvTypeParameters* mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1,
485 TSpirvTypeParameters* spirvTypeParams2);
486 TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, const TString& value);
487 TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, int value);
488 TSpirvInstruction* mergeSpirvInstruction(const TSourceLoc& loc, TSpirvInstruction* spirvInst1,
489 TSpirvInstruction* spirvInst2);
492 void checkAndResizeMeshViewDim(const TSourceLoc&, TType&, bool isBlockMember);
495 void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type);
496 void inheritGlobalDefaults(TQualifier& dst) const;
497 TVariable* makeInternalVariable(const char* name, const TType&) const;
498 TVariable* declareNonArray(const TSourceLoc&, const TString& identifier, const TType&);
499 void declareArray(const TSourceLoc&, const TString& identifier, const TType&, TSymbol*&);
500 void checkRuntimeSizable(const TSourceLoc&, const TIntermTyped&);
501 bool isRuntimeLength(const TIntermTyped&) const;
502 TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
503 TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
505 void finish() override;
508 virtual const char* getGlobalUniformBlockName() const override;
509 virtual void finalizeGlobalUniformBlockLayout(TVariable&) override;
510 virtual void setUniformBlockDefaults(TType& block) const override;
512 virtual const char* getAtomicCounterBlockName() const override;
513 virtual void finalizeAtomicCounterBlockLayout(TVariable&) override;
514 virtual void setAtomicCounterBlockDefaults(TType& block) const override;
515 virtual void setInvariant(const TSourceLoc& loc, const char* builtin) override;
519 // Generally, bison productions, the scanner, and the PP need read/write access to these; just give them direct access
522 // Current state of parsing
523 bool inMain; // if inside a function, true if the function is main
524 const TString* blockName;
525 TQualifier currentBlockQualifier;
526 TPrecisionQualifier defaultPrecision[EbtNumTypes];
527 TBuiltInResource resources;
531 TParseContext(TParseContext&);
532 TParseContext& operator=(TParseContext&);
534 static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2 * 2 * 2 * 2)); // see computeSamplerTypeIndex()
535 TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex];
536 TPrecisionManager precisionManager;
537 TQualifier globalBufferDefaults;
538 TQualifier globalUniformDefaults;
539 TQualifier globalInputDefaults;
540 TQualifier globalOutputDefaults;
541 TQualifier globalSharedDefaults;
542 TString currentCaller; // name of last function body entered (not valid when at global scope)
544 int* atomicUintOffsets; // to become an array of the right size to hold an offset per binding point
546 TIdSetType inductiveLoopIds;
547 TVector<TIntermTyped*> needsIndexLimitationChecking;
548 TStructRecord matrixFixRecord;
549 TStructRecord packingFixRecord;
552 // Geometry shader input arrays:
553 // - array sizing is based on input primitive and/or explicit size
555 // Tessellation control output arrays:
556 // - array sizing is based on output layout(vertices=...) and/or explicit size
559 // - array sizing is retroactive
560 // - built-in block redeclarations interact with this
563 // - use a per-context "resize-list", a list of symbols whose array sizes
566 // - the resize-list starts empty at beginning of user-shader compilation, it does
567 // not have built-ins in it
569 // - on built-in array use: copyUp() symbol and add it to the resize-list
571 // - on user array declaration: add it to the resize-list
573 // - on block redeclaration: copyUp() symbol and add it to the resize-list
574 // * note, that appropriately gives an error if redeclaring a block that
575 // was already used and hence already copied-up
577 // - on seeing a layout declaration that sizes the array, fix everything in the
578 // resize-list, giving errors for mismatch
580 // - on seeing an array size declaration, give errors on mismatch between it and previous
581 // array-sizing declarations
583 TVector<TSymbol*> ioArraySymbolResizeList;
587 } // end namespace glslang
589 #endif // _PARSER_HELPER_INCLUDED_