1 | // |
2 | // Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. |
3 | // Use of this source code is governed by a BSD-style license that can be |
4 | // found in the LICENSE file. |
5 | // |
6 | #ifndef COMPILER_TRANSLATOR_PARSECONTEXT_H_ |
7 | #define COMPILER_TRANSLATOR_PARSECONTEXT_H_ |
8 | |
9 | #include "compiler/preprocessor/Preprocessor.h" |
10 | #include "compiler/translator/Compiler.h" |
11 | #include "compiler/translator/Declarator.h" |
12 | #include "compiler/translator/Diagnostics.h" |
13 | #include "compiler/translator/DirectiveHandler.h" |
14 | #include "compiler/translator/FunctionLookup.h" |
15 | #include "compiler/translator/QualifierTypes.h" |
16 | #include "compiler/translator/SymbolTable.h" |
17 | |
18 | namespace sh |
19 | { |
20 | |
21 | struct TMatrixFields |
22 | { |
23 | bool wholeRow; |
24 | bool wholeCol; |
25 | int row; |
26 | int col; |
27 | }; |
28 | |
29 | // |
30 | // The following are extra variables needed during parsing, grouped together so |
31 | // they can be passed to the parser without needing a global. |
32 | // |
33 | class TParseContext : angle::NonCopyable |
34 | { |
35 | public: |
36 | TParseContext(TSymbolTable &symt, |
37 | TExtensionBehavior &ext, |
38 | sh::GLenum type, |
39 | ShShaderSpec spec, |
40 | ShCompileOptions options, |
41 | bool checksPrecErrors, |
42 | TDiagnostics *diagnostics, |
43 | const ShBuiltInResources &resources); |
44 | ~TParseContext(); |
45 | |
46 | const angle::pp::Preprocessor &getPreprocessor() const { return mPreprocessor; } |
47 | angle::pp::Preprocessor &getPreprocessor() { return mPreprocessor; } |
48 | void *getScanner() const { return mScanner; } |
49 | void setScanner(void *scanner) { mScanner = scanner; } |
50 | int getShaderVersion() const { return mShaderVersion; } |
51 | sh::GLenum getShaderType() const { return mShaderType; } |
52 | ShShaderSpec getShaderSpec() const { return mShaderSpec; } |
53 | int numErrors() const { return mDiagnostics->numErrors(); } |
54 | void error(const TSourceLoc &loc, const char *reason, const char *token); |
55 | void error(const TSourceLoc &loc, const char *reason, const ImmutableString &token); |
56 | void warning(const TSourceLoc &loc, const char *reason, const char *token); |
57 | |
58 | // If isError is false, a warning will be reported instead. |
59 | void outOfRangeError(bool isError, |
60 | const TSourceLoc &loc, |
61 | const char *reason, |
62 | const char *token); |
63 | |
64 | TIntermBlock *getTreeRoot() const { return mTreeRoot; } |
65 | void setTreeRoot(TIntermBlock *treeRoot) { mTreeRoot = treeRoot; } |
66 | |
67 | bool getFragmentPrecisionHigh() const |
68 | { |
69 | return mFragmentPrecisionHighOnESSL1 || mShaderVersion >= 300; |
70 | } |
71 | void setFragmentPrecisionHighOnESSL1(bool fragmentPrecisionHigh) |
72 | { |
73 | mFragmentPrecisionHighOnESSL1 = fragmentPrecisionHigh; |
74 | } |
75 | |
76 | void setLoopNestingLevel(int loopNestintLevel) { mLoopNestingLevel = loopNestintLevel; } |
77 | |
78 | void incrLoopNestingLevel() { ++mLoopNestingLevel; } |
79 | void decrLoopNestingLevel() { --mLoopNestingLevel; } |
80 | |
81 | void incrSwitchNestingLevel() { ++mSwitchNestingLevel; } |
82 | void decrSwitchNestingLevel() { --mSwitchNestingLevel; } |
83 | |
84 | bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; } |
85 | sh::WorkGroupSize getComputeShaderLocalSize() const; |
86 | |
87 | int getNumViews() const { return mNumViews; } |
88 | |
89 | void enterFunctionDeclaration() { mDeclaringFunction = true; } |
90 | |
91 | void exitFunctionDeclaration() { mDeclaringFunction = false; } |
92 | |
93 | bool declaringFunction() const { return mDeclaringFunction; } |
94 | |
95 | TIntermConstantUnion *addScalarLiteral(const TConstantUnion *constantUnion, |
96 | const TSourceLoc &line); |
97 | |
98 | // This method is guaranteed to succeed, even if no variable with 'name' exists. |
99 | const TVariable *getNamedVariable(const TSourceLoc &location, |
100 | const ImmutableString &name, |
101 | const TSymbol *symbol); |
102 | TIntermTyped *parseVariableIdentifier(const TSourceLoc &location, |
103 | const ImmutableString &name, |
104 | const TSymbol *symbol); |
105 | |
106 | // Look at a '.' field selector string and change it into offsets for a vector. |
107 | bool parseVectorFields(const TSourceLoc &line, |
108 | const ImmutableString &compString, |
109 | int vecSize, |
110 | TVector<int> *fieldOffsets); |
111 | |
112 | void assignError(const TSourceLoc &line, const char *op, const TType &left, const TType &right); |
113 | void unaryOpError(const TSourceLoc &line, const char *op, const TType &operand); |
114 | void binaryOpError(const TSourceLoc &line, |
115 | const char *op, |
116 | const TType &left, |
117 | const TType &right); |
118 | |
119 | // Check functions - the ones that return bool return false if an error was generated. |
120 | |
121 | bool checkIsNotReserved(const TSourceLoc &line, const ImmutableString &identifier); |
122 | void checkPrecisionSpecified(const TSourceLoc &line, TPrecision precision, TBasicType type); |
123 | bool checkCanBeLValue(const TSourceLoc &line, const char *op, TIntermTyped *node); |
124 | void checkIsConst(TIntermTyped *node); |
125 | void checkIsScalarInteger(TIntermTyped *node, const char *token); |
126 | bool checkIsAtGlobalLevel(const TSourceLoc &line, const char *token); |
127 | bool checkConstructorArguments(const TSourceLoc &line, |
128 | const TIntermSequence &arguments, |
129 | const TType &type); |
130 | |
131 | // Returns a sanitized array size to use (the size is at least 1). |
132 | unsigned int checkIsValidArraySize(const TSourceLoc &line, TIntermTyped *expr); |
133 | bool checkIsValidQualifierForArray(const TSourceLoc &line, const TPublicType &elementQualifier); |
134 | bool checkArrayElementIsNotArray(const TSourceLoc &line, const TPublicType &elementType); |
135 | bool checkIsNonVoid(const TSourceLoc &line, |
136 | const ImmutableString &identifier, |
137 | const TBasicType &type); |
138 | bool checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type); |
139 | void checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType); |
140 | bool checkIsNotOpaqueType(const TSourceLoc &line, |
141 | const TTypeSpecifierNonArray &pType, |
142 | const char *reason); |
143 | void checkDeclaratorLocationIsNotSpecified(const TSourceLoc &line, const TPublicType &pType); |
144 | void checkLocationIsNotSpecified(const TSourceLoc &location, |
145 | const TLayoutQualifier &layoutQualifier); |
146 | void checkStd430IsForShaderStorageBlock(const TSourceLoc &location, |
147 | const TLayoutBlockStorage &blockStorage, |
148 | const TQualifier &qualifier); |
149 | void checkIsParameterQualifierValid(const TSourceLoc &line, |
150 | const TTypeQualifierBuilder &typeQualifierBuilder, |
151 | TType *type); |
152 | |
153 | // Check if at least one of the specified extensions can be used, and generate error/warning as |
154 | // appropriate according to the spec. |
155 | // This function is only needed for a few different small constant sizes of extension array, and |
156 | // we want to avoid unnecessary dynamic allocations. That's why checkCanUseOneOfExtensions is a |
157 | // template function rather than one taking a vector. |
158 | template <size_t size> |
159 | bool checkCanUseOneOfExtensions(const TSourceLoc &line, |
160 | const std::array<TExtension, size> &extensions); |
161 | bool checkCanUseExtension(const TSourceLoc &line, TExtension extension); |
162 | |
163 | // Done for all declarations, whether empty or not. |
164 | void declarationQualifierErrorCheck(const sh::TQualifier qualifier, |
165 | const sh::TLayoutQualifier &layoutQualifier, |
166 | const TSourceLoc &location); |
167 | // Done for the first non-empty declarator in a declaration. |
168 | void nonEmptyDeclarationErrorCheck(const TPublicType &publicType, |
169 | const TSourceLoc &identifierLocation); |
170 | // Done only for empty declarations. |
171 | void emptyDeclarationErrorCheck(const TType &type, const TSourceLoc &location); |
172 | |
173 | void checkLayoutQualifierSupported(const TSourceLoc &location, |
174 | const ImmutableString &layoutQualifierName, |
175 | int versionRequired); |
176 | bool checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location, |
177 | const TLayoutQualifier &layoutQualifier); |
178 | void functionCallRValueLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *fnCall); |
179 | void checkInvariantVariableQualifier(bool invariant, |
180 | const TQualifier qualifier, |
181 | const TSourceLoc &invariantLocation); |
182 | void checkInputOutputTypeIsValidES3(const TQualifier qualifier, |
183 | const TPublicType &type, |
184 | const TSourceLoc &qualifierLocation); |
185 | void checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase &qualifier); |
186 | const TPragma &pragma() const { return mDirectiveHandler.pragma(); } |
187 | const TExtensionBehavior &extensionBehavior() const |
188 | { |
189 | return mDirectiveHandler.extensionBehavior(); |
190 | } |
191 | |
192 | bool isExtensionEnabled(TExtension extension) const; |
193 | void handleExtensionDirective(const TSourceLoc &loc, const char *extName, const char *behavior); |
194 | void handlePragmaDirective(const TSourceLoc &loc, |
195 | const char *name, |
196 | const char *value, |
197 | bool stdgl); |
198 | |
199 | // Returns true on success. *initNode may still be nullptr on success in case the initialization |
200 | // is not needed in the AST. |
201 | bool executeInitializer(const TSourceLoc &line, |
202 | const ImmutableString &identifier, |
203 | TType *type, |
204 | TIntermTyped *initializer, |
205 | TIntermBinary **initNode); |
206 | TIntermNode *addConditionInitializer(const TPublicType &pType, |
207 | const ImmutableString &identifier, |
208 | TIntermTyped *initializer, |
209 | const TSourceLoc &loc); |
210 | TIntermNode *addLoop(TLoopType type, |
211 | TIntermNode *init, |
212 | TIntermNode *cond, |
213 | TIntermTyped *expr, |
214 | TIntermNode *body, |
215 | const TSourceLoc &loc); |
216 | |
217 | // For "if" test nodes. There are three children: a condition, a true path, and a false path. |
218 | // The two paths are in TIntermNodePair code. |
219 | TIntermNode *addIfElse(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &loc); |
220 | |
221 | void addFullySpecifiedType(TPublicType *typeSpecifier); |
222 | TPublicType addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder, |
223 | const TPublicType &typeSpecifier); |
224 | |
225 | TIntermDeclaration *parseSingleDeclaration(TPublicType &publicType, |
226 | const TSourceLoc &identifierOrTypeLocation, |
227 | const ImmutableString &identifier); |
228 | TIntermDeclaration *parseSingleArrayDeclaration(TPublicType &elementType, |
229 | const TSourceLoc &identifierLocation, |
230 | const ImmutableString &identifier, |
231 | const TSourceLoc &indexLocation, |
232 | const TVector<unsigned int> &arraySizes); |
233 | TIntermDeclaration *parseSingleInitDeclaration(const TPublicType &publicType, |
234 | const TSourceLoc &identifierLocation, |
235 | const ImmutableString &identifier, |
236 | const TSourceLoc &initLocation, |
237 | TIntermTyped *initializer); |
238 | |
239 | // Parse a declaration like "type a[n] = initializer" |
240 | // Note that this does not apply to declarations like "type[n] a = initializer" |
241 | TIntermDeclaration *parseSingleArrayInitDeclaration(TPublicType &elementType, |
242 | const TSourceLoc &identifierLocation, |
243 | const ImmutableString &identifier, |
244 | const TSourceLoc &indexLocation, |
245 | const TVector<unsigned int> &arraySizes, |
246 | const TSourceLoc &initLocation, |
247 | TIntermTyped *initializer); |
248 | |
249 | TIntermInvariantDeclaration *parseInvariantDeclaration( |
250 | const TTypeQualifierBuilder &typeQualifierBuilder, |
251 | const TSourceLoc &identifierLoc, |
252 | const ImmutableString &identifier, |
253 | const TSymbol *symbol); |
254 | |
255 | void parseDeclarator(TPublicType &publicType, |
256 | const TSourceLoc &identifierLocation, |
257 | const ImmutableString &identifier, |
258 | TIntermDeclaration *declarationOut); |
259 | void parseArrayDeclarator(TPublicType &elementType, |
260 | const TSourceLoc &identifierLocation, |
261 | const ImmutableString &identifier, |
262 | const TSourceLoc &arrayLocation, |
263 | const TVector<unsigned int> &arraySizes, |
264 | TIntermDeclaration *declarationOut); |
265 | void parseInitDeclarator(const TPublicType &publicType, |
266 | const TSourceLoc &identifierLocation, |
267 | const ImmutableString &identifier, |
268 | const TSourceLoc &initLocation, |
269 | TIntermTyped *initializer, |
270 | TIntermDeclaration *declarationOut); |
271 | |
272 | // Parse a declarator like "a[n] = initializer" |
273 | void parseArrayInitDeclarator(const TPublicType &elementType, |
274 | const TSourceLoc &identifierLocation, |
275 | const ImmutableString &identifier, |
276 | const TSourceLoc &indexLocation, |
277 | const TVector<unsigned int> &arraySizes, |
278 | const TSourceLoc &initLocation, |
279 | TIntermTyped *initializer, |
280 | TIntermDeclaration *declarationOut); |
281 | |
282 | TIntermNode *addEmptyStatement(const TSourceLoc &location); |
283 | |
284 | void parseDefaultPrecisionQualifier(const TPrecision precision, |
285 | const TPublicType &type, |
286 | const TSourceLoc &loc); |
287 | void parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder); |
288 | |
289 | TIntermFunctionPrototype *addFunctionPrototypeDeclaration(const TFunction &parsedFunction, |
290 | const TSourceLoc &location); |
291 | TIntermFunctionDefinition *addFunctionDefinition(TIntermFunctionPrototype *functionPrototype, |
292 | TIntermBlock *functionBody, |
293 | const TSourceLoc &location); |
294 | void (const TSourceLoc &location, |
295 | const TFunction *function, |
296 | TIntermFunctionPrototype **prototypeOut); |
297 | TFunction *parseFunctionDeclarator(const TSourceLoc &location, TFunction *function); |
298 | TFunction *(const TPublicType &type, |
299 | const ImmutableString &name, |
300 | const TSourceLoc &location); |
301 | |
302 | TFunctionLookup *addNonConstructorFunc(const ImmutableString &name, const TSymbol *symbol); |
303 | TFunctionLookup *addConstructorFunc(const TPublicType &publicType); |
304 | |
305 | TParameter parseParameterDeclarator(const TPublicType &publicType, |
306 | const ImmutableString &name, |
307 | const TSourceLoc &nameLoc); |
308 | |
309 | TParameter parseParameterArrayDeclarator(const ImmutableString &name, |
310 | const TSourceLoc &nameLoc, |
311 | const TVector<unsigned int> &arraySizes, |
312 | const TSourceLoc &arrayLoc, |
313 | TPublicType *elementType); |
314 | |
315 | TIntermTyped *addIndexExpression(TIntermTyped *baseExpression, |
316 | const TSourceLoc &location, |
317 | TIntermTyped *indexExpression); |
318 | TIntermTyped *addFieldSelectionExpression(TIntermTyped *baseExpression, |
319 | const TSourceLoc &dotLocation, |
320 | const ImmutableString &fieldString, |
321 | const TSourceLoc &fieldLocation); |
322 | |
323 | // Parse declarator for a single field |
324 | TDeclarator *parseStructDeclarator(const ImmutableString &identifier, const TSourceLoc &loc); |
325 | TDeclarator *parseStructArrayDeclarator(const ImmutableString &identifier, |
326 | const TSourceLoc &loc, |
327 | const TVector<unsigned int> *arraySizes); |
328 | |
329 | void checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin, |
330 | const TFieldList::const_iterator end, |
331 | const ImmutableString &name, |
332 | const TSourceLoc &location); |
333 | TFieldList *addStructFieldList(TFieldList *fields, const TSourceLoc &location); |
334 | TFieldList *combineStructFieldLists(TFieldList *processedFields, |
335 | const TFieldList *newlyAddedFields, |
336 | const TSourceLoc &location); |
337 | TFieldList *addStructDeclaratorListWithQualifiers( |
338 | const TTypeQualifierBuilder &typeQualifierBuilder, |
339 | TPublicType *typeSpecifier, |
340 | const TDeclaratorList *declaratorList); |
341 | TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier, |
342 | const TDeclaratorList *declaratorList); |
343 | TTypeSpecifierNonArray addStructure(const TSourceLoc &structLine, |
344 | const TSourceLoc &nameLine, |
345 | const ImmutableString &structName, |
346 | TFieldList *fieldList); |
347 | |
348 | TIntermDeclaration *addInterfaceBlock(const TTypeQualifierBuilder &typeQualifierBuilder, |
349 | const TSourceLoc &nameLine, |
350 | const ImmutableString &blockName, |
351 | TFieldList *fieldList, |
352 | const ImmutableString &instanceName, |
353 | const TSourceLoc &instanceLine, |
354 | TIntermTyped *arrayIndex, |
355 | const TSourceLoc &arrayIndexLine); |
356 | |
357 | void parseLocalSize(const ImmutableString &qualifierType, |
358 | const TSourceLoc &qualifierTypeLine, |
359 | int intValue, |
360 | const TSourceLoc &intValueLine, |
361 | const std::string &intValueString, |
362 | size_t index, |
363 | sh::WorkGroupSize *localSize); |
364 | void parseNumViews(int intValue, |
365 | const TSourceLoc &intValueLine, |
366 | const std::string &intValueString, |
367 | int *numViews); |
368 | void parseInvocations(int intValue, |
369 | const TSourceLoc &intValueLine, |
370 | const std::string &intValueString, |
371 | int *numInvocations); |
372 | void parseMaxVertices(int intValue, |
373 | const TSourceLoc &intValueLine, |
374 | const std::string &intValueString, |
375 | int *numMaxVertices); |
376 | void parseIndexLayoutQualifier(int intValue, |
377 | const TSourceLoc &intValueLine, |
378 | const std::string &intValueString, |
379 | int *index); |
380 | TLayoutQualifier parseLayoutQualifier(const ImmutableString &qualifierType, |
381 | const TSourceLoc &qualifierTypeLine); |
382 | TLayoutQualifier parseLayoutQualifier(const ImmutableString &qualifierType, |
383 | const TSourceLoc &qualifierTypeLine, |
384 | int intValue, |
385 | const TSourceLoc &intValueLine); |
386 | TTypeQualifierBuilder *createTypeQualifierBuilder(const TSourceLoc &loc); |
387 | TStorageQualifierWrapper *parseGlobalStorageQualifier(TQualifier qualifier, |
388 | const TSourceLoc &loc); |
389 | TStorageQualifierWrapper *parseVaryingQualifier(const TSourceLoc &loc); |
390 | TStorageQualifierWrapper *parseInQualifier(const TSourceLoc &loc); |
391 | TStorageQualifierWrapper *parseOutQualifier(const TSourceLoc &loc); |
392 | TStorageQualifierWrapper *parseInOutQualifier(const TSourceLoc &loc); |
393 | TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier, |
394 | TLayoutQualifier rightQualifier, |
395 | const TSourceLoc &rightQualifierLocation); |
396 | |
397 | // Performs an error check for embedded struct declarations. |
398 | void enterStructDeclaration(const TSourceLoc &line, const ImmutableString &identifier); |
399 | void exitStructDeclaration(); |
400 | |
401 | void checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field); |
402 | |
403 | TIntermSwitch *addSwitch(TIntermTyped *init, |
404 | TIntermBlock *statementList, |
405 | const TSourceLoc &loc); |
406 | TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc); |
407 | TIntermCase *addDefault(const TSourceLoc &loc); |
408 | |
409 | TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc); |
410 | TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc); |
411 | TIntermTyped *addBinaryMath(TOperator op, |
412 | TIntermTyped *left, |
413 | TIntermTyped *right, |
414 | const TSourceLoc &loc); |
415 | TIntermTyped *addBinaryMathBooleanResult(TOperator op, |
416 | TIntermTyped *left, |
417 | TIntermTyped *right, |
418 | const TSourceLoc &loc); |
419 | TIntermTyped *addAssign(TOperator op, |
420 | TIntermTyped *left, |
421 | TIntermTyped *right, |
422 | const TSourceLoc &loc); |
423 | |
424 | TIntermTyped *addComma(TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc); |
425 | |
426 | TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc); |
427 | TIntermBranch *addBranch(TOperator op, TIntermTyped *expression, const TSourceLoc &loc); |
428 | |
429 | void appendStatement(TIntermBlock *block, TIntermNode *statement); |
430 | |
431 | void checkTextureGather(TIntermAggregate *functionCall); |
432 | void checkTextureOffsetConst(TIntermAggregate *functionCall); |
433 | void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall); |
434 | void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition, |
435 | const TIntermAggregate *functionCall); |
436 | void checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall); |
437 | |
438 | // fnCall is only storing the built-in op, and function name or constructor type. arguments |
439 | // has the arguments. |
440 | TIntermTyped *addFunctionCallOrMethod(TFunctionLookup *fnCall, const TSourceLoc &loc); |
441 | |
442 | TIntermTyped *addTernarySelection(TIntermTyped *cond, |
443 | TIntermTyped *trueExpression, |
444 | TIntermTyped *falseExpression, |
445 | const TSourceLoc &line); |
446 | |
447 | int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; } |
448 | int getGeometryShaderInvocations() const |
449 | { |
450 | return (mGeometryShaderInvocations > 0) ? mGeometryShaderInvocations : 1; |
451 | } |
452 | TLayoutPrimitiveType getGeometryShaderInputPrimitiveType() const |
453 | { |
454 | return mGeometryShaderInputPrimitiveType; |
455 | } |
456 | TLayoutPrimitiveType getGeometryShaderOutputPrimitiveType() const |
457 | { |
458 | return mGeometryShaderOutputPrimitiveType; |
459 | } |
460 | |
461 | // TODO(jmadill): make this private |
462 | TSymbolTable &symbolTable; // symbol table that goes with the language currently being parsed |
463 | |
464 | private: |
465 | class AtomicCounterBindingState; |
466 | constexpr static size_t kAtomicCounterSize = 4; |
467 | // UNIFORM_ARRAY_STRIDE for atomic counter arrays is an implementation-dependent value which |
468 | // can be queried after a program is linked according to ES 3.10 section 7.7.1. This is |
469 | // controversial with the offset inheritance as described in ESSL 3.10 section 4.4.6. Currently |
470 | // we treat it as always 4 in favour of the original interpretation in |
471 | // "ARB_shader_atomic_counters". |
472 | // TODO([email protected]): Double check this once the spec vagueness is resolved. |
473 | // Note that there may be tests in AtomicCounter_test that will need to be updated as well. |
474 | constexpr static size_t kAtomicCounterArrayStride = 4; |
475 | |
476 | void markStaticReadIfSymbol(TIntermNode *node); |
477 | |
478 | // Returns a clamped index. If it prints out an error message, the token is "[]". |
479 | int checkIndexLessThan(bool outOfRangeIndexIsError, |
480 | const TSourceLoc &location, |
481 | int index, |
482 | int arraySize, |
483 | const char *reason); |
484 | |
485 | bool declareVariable(const TSourceLoc &line, |
486 | const ImmutableString &identifier, |
487 | const TType *type, |
488 | TVariable **variable); |
489 | |
490 | void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line, |
491 | const ImmutableString &identifier, |
492 | TType *type); |
493 | |
494 | TParameter parseParameterDeclarator(TType *type, |
495 | const ImmutableString &name, |
496 | const TSourceLoc &nameLoc); |
497 | |
498 | bool checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation, |
499 | const TPublicType &elementType); |
500 | // Done for all atomic counter declarations, whether empty or not. |
501 | void atomicCounterQualifierErrorCheck(const TPublicType &publicType, |
502 | const TSourceLoc &location); |
503 | |
504 | // Assumes that multiplication op has already been set based on the types. |
505 | bool isMultiplicationTypeCombinationValid(TOperator op, const TType &left, const TType &right); |
506 | |
507 | void checkOutParameterIsNotOpaqueType(const TSourceLoc &line, |
508 | TQualifier qualifier, |
509 | const TType &type); |
510 | |
511 | void checkInternalFormatIsNotSpecified(const TSourceLoc &location, |
512 | TLayoutImageInternalFormat internalFormat); |
513 | void checkMemoryQualifierIsNotSpecified(const TMemoryQualifier &memoryQualifier, |
514 | const TSourceLoc &location); |
515 | void checkAtomicCounterOffsetDoesNotOverlap(bool forceAppend, |
516 | const TSourceLoc &loc, |
517 | TType *type); |
518 | void checkAtomicCounterOffsetAlignment(const TSourceLoc &location, const TType &type); |
519 | |
520 | void checkIndexIsNotSpecified(const TSourceLoc &location, int index); |
521 | void checkBindingIsValid(const TSourceLoc &identifierLocation, const TType &type); |
522 | void checkBindingIsNotSpecified(const TSourceLoc &location, int binding); |
523 | void checkOffsetIsNotSpecified(const TSourceLoc &location, int offset); |
524 | void checkImageBindingIsValid(const TSourceLoc &location, |
525 | int binding, |
526 | int arrayTotalElementCount); |
527 | void checkSamplerBindingIsValid(const TSourceLoc &location, |
528 | int binding, |
529 | int arrayTotalElementCount); |
530 | void checkBlockBindingIsValid(const TSourceLoc &location, |
531 | const TQualifier &qualifier, |
532 | int binding, |
533 | int arraySize); |
534 | void checkAtomicCounterBindingIsValid(const TSourceLoc &location, int binding); |
535 | |
536 | void checkUniformLocationInRange(const TSourceLoc &location, |
537 | int objectLocationCount, |
538 | const TLayoutQualifier &layoutQualifier); |
539 | |
540 | void checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv); |
541 | |
542 | bool checkUnsizedArrayConstructorArgumentDimensionality(const TIntermSequence &arguments, |
543 | TType type, |
544 | const TSourceLoc &line); |
545 | |
546 | // Will set the size of the outermost array according to geometry shader input layout. |
547 | void checkGeometryShaderInputAndSetArraySize(const TSourceLoc &location, |
548 | const ImmutableString &token, |
549 | TType *type); |
550 | |
551 | // Will size any unsized array type so unsized arrays won't need to be taken into account |
552 | // further along the line in parsing. |
553 | void checkIsNotUnsizedArray(const TSourceLoc &line, |
554 | const char *errorMessage, |
555 | const ImmutableString &token, |
556 | TType *arrayType); |
557 | |
558 | TIntermTyped *addBinaryMathInternal(TOperator op, |
559 | TIntermTyped *left, |
560 | TIntermTyped *right, |
561 | const TSourceLoc &loc); |
562 | TIntermTyped *createUnaryMath(TOperator op, |
563 | TIntermTyped *child, |
564 | const TSourceLoc &loc, |
565 | const TFunction *func); |
566 | |
567 | TIntermTyped *addMethod(TFunctionLookup *fnCall, const TSourceLoc &loc); |
568 | TIntermTyped *addConstructor(TFunctionLookup *fnCall, const TSourceLoc &line); |
569 | TIntermTyped *addNonConstructorFunctionCall(TFunctionLookup *fnCall, const TSourceLoc &loc); |
570 | |
571 | // Return either the original expression or the folded version of the expression in case the |
572 | // folded node will validate the same way during subsequent parsing. |
573 | TIntermTyped *expressionOrFoldedResult(TIntermTyped *expression); |
574 | |
575 | // Return true if the checks pass |
576 | bool binaryOpCommonCheck(TOperator op, |
577 | TIntermTyped *left, |
578 | TIntermTyped *right, |
579 | const TSourceLoc &loc); |
580 | |
581 | TIntermFunctionPrototype *createPrototypeNodeFromFunction(const TFunction &function, |
582 | const TSourceLoc &location, |
583 | bool insertParametersToSymbolTable); |
584 | |
585 | void setAtomicCounterBindingDefaultOffset(const TPublicType &declaration, |
586 | const TSourceLoc &location); |
587 | |
588 | bool checkPrimitiveTypeMatchesTypeQualifier(const TTypeQualifier &typeQualifier); |
589 | bool parseGeometryShaderInputLayoutQualifier(const TTypeQualifier &typeQualifier); |
590 | bool parseGeometryShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier); |
591 | void setGeometryShaderInputArraySize(unsigned int inputArraySize, const TSourceLoc &line); |
592 | |
593 | // Set to true when the last/current declarator list was started with an empty declaration. The |
594 | // non-empty declaration error check will need to be performed if the empty declaration is |
595 | // followed by a declarator. |
596 | bool mDeferredNonEmptyDeclarationErrorCheck; |
597 | |
598 | sh::GLenum mShaderType; // vertex or fragment language (future: pack or unpack) |
599 | ShShaderSpec mShaderSpec; // The language specification compiler conforms to - GLES2 or WebGL. |
600 | ShCompileOptions mCompileOptions; // Options passed to TCompiler |
601 | int mShaderVersion; |
602 | TIntermBlock *mTreeRoot; // root of parse tree being created |
603 | int mLoopNestingLevel; // 0 if outside all loops |
604 | int mStructNestingLevel; // incremented while parsing a struct declaration |
605 | int mSwitchNestingLevel; // 0 if outside all switch statements |
606 | const TType |
607 | *mCurrentFunctionType; // the return type of the function that's currently being parsed |
608 | bool mFunctionReturnsValue; // true if a non-void function has a return |
609 | bool mChecksPrecisionErrors; // true if an error will be generated when a variable is declared |
610 | // without precision, explicit or implicit. |
611 | bool mFragmentPrecisionHighOnESSL1; // true if highp precision is supported when compiling |
612 | // ESSL1. |
613 | TLayoutMatrixPacking mDefaultUniformMatrixPacking; |
614 | TLayoutBlockStorage mDefaultUniformBlockStorage; |
615 | TLayoutMatrixPacking mDefaultBufferMatrixPacking; |
616 | TLayoutBlockStorage mDefaultBufferBlockStorage; |
617 | TString mHashErrMsg; |
618 | TDiagnostics *mDiagnostics; |
619 | TDirectiveHandler mDirectiveHandler; |
620 | angle::pp::Preprocessor mPreprocessor; |
621 | void *mScanner; |
622 | int mMinProgramTexelOffset; |
623 | int mMaxProgramTexelOffset; |
624 | |
625 | int mMinProgramTextureGatherOffset; |
626 | int mMaxProgramTextureGatherOffset; |
627 | |
628 | // keep track of local group size declared in layout. It should be declared only once. |
629 | bool mComputeShaderLocalSizeDeclared; |
630 | sh::WorkGroupSize mComputeShaderLocalSize; |
631 | // keep track of number of views declared in layout. |
632 | int mNumViews; |
633 | int mMaxNumViews; |
634 | int mMaxImageUnits; |
635 | int mMaxCombinedTextureImageUnits; |
636 | int mMaxUniformLocations; |
637 | int mMaxUniformBufferBindings; |
638 | int mMaxAtomicCounterBindings; |
639 | int mMaxShaderStorageBufferBindings; |
640 | |
641 | // keeps track whether we are declaring / defining a function |
642 | bool mDeclaringFunction; |
643 | |
644 | // Track the state of each atomic counter binding. |
645 | std::map<int, AtomicCounterBindingState> mAtomicCounterBindingStates; |
646 | |
647 | // Track the geometry shader global parameters declared in layout. |
648 | TLayoutPrimitiveType mGeometryShaderInputPrimitiveType; |
649 | TLayoutPrimitiveType mGeometryShaderOutputPrimitiveType; |
650 | int mGeometryShaderInvocations; |
651 | int mGeometryShaderMaxVertices; |
652 | int mMaxGeometryShaderInvocations; |
653 | int mMaxGeometryShaderMaxVertices; |
654 | }; |
655 | |
656 | int PaParseStrings(size_t count, |
657 | const char *const string[], |
658 | const int length[], |
659 | TParseContext *context); |
660 | |
661 | } // namespace sh |
662 | |
663 | #endif // COMPILER_TRANSLATOR_PARSECONTEXT_H_ |
664 | |