Line data Source code
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/translator/Compiler.h"
10 : #include "compiler/translator/Diagnostics.h"
11 : #include "compiler/translator/DirectiveHandler.h"
12 : #include "compiler/translator/Intermediate.h"
13 : #include "compiler/translator/SymbolTable.h"
14 : #include "compiler/translator/QualifierTypes.h"
15 : #include "compiler/preprocessor/Preprocessor.h"
16 :
17 : namespace sh
18 : {
19 :
20 : struct TMatrixFields
21 : {
22 : bool wholeRow;
23 : bool wholeCol;
24 : int row;
25 : int col;
26 : };
27 :
28 : //
29 : // The following are extra variables needed during parsing, grouped together so
30 : // they can be passed to the parser without needing a global.
31 : //
32 0 : class TParseContext : angle::NonCopyable
33 : {
34 : public:
35 : TParseContext(TSymbolTable &symt,
36 : TExtensionBehavior &ext,
37 : sh::GLenum type,
38 : ShShaderSpec spec,
39 : ShCompileOptions options,
40 : bool checksPrecErrors,
41 : TInfoSink &is,
42 : const ShBuiltInResources &resources);
43 :
44 : const pp::Preprocessor &getPreprocessor() const { return mPreprocessor; }
45 0 : pp::Preprocessor &getPreprocessor() { return mPreprocessor; }
46 0 : void *getScanner() const { return mScanner; }
47 0 : void setScanner(void *scanner) { mScanner = scanner; }
48 0 : int getShaderVersion() const { return mShaderVersion; }
49 0 : sh::GLenum getShaderType() const { return mShaderType; }
50 0 : ShShaderSpec getShaderSpec() const { return mShaderSpec; }
51 0 : int numErrors() const { return mDiagnostics.numErrors(); }
52 : TInfoSink &infoSink() { return mDiagnostics.infoSink(); }
53 : void error(const TSourceLoc &loc, const char *reason, const char *token,
54 : const char *extraInfo="");
55 : void warning(const TSourceLoc &loc, const char *reason, const char *token,
56 : const char *extraInfo="");
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 : const char *extraInfo = "");
64 :
65 0 : TIntermBlock *getTreeRoot() const { return mTreeRoot; }
66 0 : void setTreeRoot(TIntermBlock *treeRoot) { mTreeRoot = treeRoot; }
67 :
68 0 : bool getFragmentPrecisionHigh() const
69 : {
70 0 : return mFragmentPrecisionHighOnESSL1 || mShaderVersion >= 300;
71 : }
72 0 : void setFragmentPrecisionHighOnESSL1(bool fragmentPrecisionHigh)
73 : {
74 0 : mFragmentPrecisionHighOnESSL1 = fragmentPrecisionHigh;
75 0 : }
76 :
77 0 : void setLoopNestingLevel(int loopNestintLevel)
78 : {
79 0 : mLoopNestingLevel = loopNestintLevel;
80 0 : }
81 :
82 0 : void incrLoopNestingLevel() { ++mLoopNestingLevel; }
83 0 : void decrLoopNestingLevel() { --mLoopNestingLevel; }
84 :
85 0 : void incrSwitchNestingLevel() { ++mSwitchNestingLevel; }
86 0 : void decrSwitchNestingLevel() { --mSwitchNestingLevel; }
87 :
88 0 : bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; }
89 : sh::WorkGroupSize getComputeShaderLocalSize() const;
90 :
91 0 : void enterFunctionDeclaration() { mDeclaringFunction = true; }
92 :
93 0 : void exitFunctionDeclaration() { mDeclaringFunction = false; }
94 :
95 0 : bool declaringFunction() const { return mDeclaringFunction; }
96 :
97 : // This method is guaranteed to succeed, even if no variable with 'name' exists.
98 : const TVariable *getNamedVariable(const TSourceLoc &location, const TString *name, const TSymbol *symbol);
99 : TIntermTyped *parseVariableIdentifier(const TSourceLoc &location,
100 : const TString *name,
101 : const TSymbol *symbol);
102 :
103 : bool parseVectorFields(const TString&, int vecSize, TVectorFields&, const TSourceLoc &line);
104 :
105 : void assignError(const TSourceLoc &line, const char *op, TString left, TString right);
106 : void unaryOpError(const TSourceLoc &line, const char *op, TString operand);
107 : void binaryOpError(const TSourceLoc &line, const char *op, TString left, TString right);
108 :
109 : // Check functions - the ones that return bool return false if an error was generated.
110 :
111 : bool checkIsNotReserved(const TSourceLoc &line, const TString &identifier);
112 : void checkPrecisionSpecified(const TSourceLoc &line, TPrecision precision, TBasicType type);
113 : bool checkCanBeLValue(const TSourceLoc &line, const char *op, TIntermTyped *node);
114 : void checkIsConst(TIntermTyped *node);
115 : void checkIsScalarInteger(TIntermTyped *node, const char *token);
116 : bool checkIsAtGlobalLevel(const TSourceLoc &line, const char *token);
117 : bool checkConstructorArguments(const TSourceLoc &line,
118 : TIntermNode *argumentsNode,
119 : const TFunction &function,
120 : TOperator op,
121 : const TType &type);
122 :
123 : // Returns a sanitized array size to use (the size is at least 1).
124 : unsigned int checkIsValidArraySize(const TSourceLoc &line, TIntermTyped *expr);
125 : bool checkIsValidQualifierForArray(const TSourceLoc &line, const TPublicType &elementQualifier);
126 : bool checkIsValidTypeForArray(const TSourceLoc &line, const TPublicType &elementType);
127 : bool checkIsNonVoid(const TSourceLoc &line, const TString &identifier, const TBasicType &type);
128 : void checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type);
129 : void checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType);
130 : bool checkIsNotSampler(const TSourceLoc &line,
131 : const TTypeSpecifierNonArray &pType,
132 : const char *reason);
133 : bool checkIsNotImage(const TSourceLoc &line,
134 : const TTypeSpecifierNonArray &pType,
135 : const char *reason);
136 : void checkDeclaratorLocationIsNotSpecified(const TSourceLoc &line, const TPublicType &pType);
137 : void checkLocationIsNotSpecified(const TSourceLoc &location,
138 : const TLayoutQualifier &layoutQualifier);
139 : void checkIsParameterQualifierValid(const TSourceLoc &line,
140 : const TTypeQualifierBuilder &typeQualifierBuilder,
141 : TType *type);
142 : bool checkCanUseExtension(const TSourceLoc &line, const TString &extension);
143 : void singleDeclarationErrorCheck(const TPublicType &publicType,
144 : const TSourceLoc &identifierLocation);
145 : void checkLayoutQualifierSupported(const TSourceLoc &location,
146 : const TString &layoutQualifierName,
147 : int versionRequired);
148 : bool checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location,
149 : const TLayoutQualifier &layoutQualifier);
150 : bool checkInternalFormatIsNotSpecified(const TSourceLoc &location,
151 : TLayoutImageInternalFormat internalFormat);
152 : void functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *fnCall);
153 : void checkInvariantVariableQualifier(bool invariant,
154 : const TQualifier qualifier,
155 : const TSourceLoc &invariantLocation);
156 : void checkInputOutputTypeIsValidES3(const TQualifier qualifier,
157 : const TPublicType &type,
158 : const TSourceLoc &qualifierLocation);
159 : void checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase &qualifier);
160 0 : const TPragma &pragma() const { return mDirectiveHandler.pragma(); }
161 0 : const TExtensionBehavior &extensionBehavior() const { return mDirectiveHandler.extensionBehavior(); }
162 : bool supportsExtension(const char *extension);
163 : bool isExtensionEnabled(const char *extension) const;
164 : void handleExtensionDirective(const TSourceLoc &loc, const char *extName, const char *behavior);
165 : void handlePragmaDirective(const TSourceLoc &loc, const char *name, const char *value, bool stdgl);
166 :
167 : const TFunction* findFunction(
168 : const TSourceLoc &line, TFunction *pfnCall, int inputShaderVersion, bool *builtIn = 0);
169 : bool executeInitializer(const TSourceLoc &line,
170 : const TString &identifier,
171 : const TPublicType &pType,
172 : TIntermTyped *initializer,
173 : TIntermBinary **initNode);
174 :
175 : void addFullySpecifiedType(TPublicType *typeSpecifier);
176 : TPublicType addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
177 : const TPublicType &typeSpecifier);
178 :
179 : TIntermDeclaration *parseSingleDeclaration(TPublicType &publicType,
180 : const TSourceLoc &identifierOrTypeLocation,
181 : const TString &identifier);
182 : TIntermDeclaration *parseSingleArrayDeclaration(TPublicType &publicType,
183 : const TSourceLoc &identifierLocation,
184 : const TString &identifier,
185 : const TSourceLoc &indexLocation,
186 : TIntermTyped *indexExpression);
187 : TIntermDeclaration *parseSingleInitDeclaration(const TPublicType &publicType,
188 : const TSourceLoc &identifierLocation,
189 : const TString &identifier,
190 : const TSourceLoc &initLocation,
191 : TIntermTyped *initializer);
192 :
193 : // Parse a declaration like "type a[n] = initializer"
194 : // Note that this does not apply to declarations like "type[n] a = initializer"
195 : TIntermDeclaration *parseSingleArrayInitDeclaration(TPublicType &publicType,
196 : const TSourceLoc &identifierLocation,
197 : const TString &identifier,
198 : const TSourceLoc &indexLocation,
199 : TIntermTyped *indexExpression,
200 : const TSourceLoc &initLocation,
201 : TIntermTyped *initializer);
202 :
203 : TIntermAggregate *parseInvariantDeclaration(const TTypeQualifierBuilder &typeQualifierBuilder,
204 : const TSourceLoc &identifierLoc,
205 : const TString *identifier,
206 : const TSymbol *symbol);
207 :
208 : void parseDeclarator(TPublicType &publicType,
209 : const TSourceLoc &identifierLocation,
210 : const TString &identifier,
211 : TIntermDeclaration *declarationOut);
212 : void parseArrayDeclarator(TPublicType &publicType,
213 : const TSourceLoc &identifierLocation,
214 : const TString &identifier,
215 : const TSourceLoc &arrayLocation,
216 : TIntermTyped *indexExpression,
217 : TIntermDeclaration *declarationOut);
218 : void parseInitDeclarator(const TPublicType &publicType,
219 : const TSourceLoc &identifierLocation,
220 : const TString &identifier,
221 : const TSourceLoc &initLocation,
222 : TIntermTyped *initializer,
223 : TIntermDeclaration *declarationOut);
224 :
225 : // Parse a declarator like "a[n] = initializer"
226 : void parseArrayInitDeclarator(const TPublicType &publicType,
227 : const TSourceLoc &identifierLocation,
228 : const TString &identifier,
229 : const TSourceLoc &indexLocation,
230 : TIntermTyped *indexExpression,
231 : const TSourceLoc &initLocation,
232 : TIntermTyped *initializer,
233 : TIntermDeclaration *declarationOut);
234 :
235 : void parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder);
236 : TIntermAggregate *addFunctionPrototypeDeclaration(const TFunction &parsedFunction,
237 : const TSourceLoc &location);
238 : TIntermFunctionDefinition *addFunctionDefinition(const TFunction &function,
239 : TIntermAggregate *functionParameters,
240 : TIntermBlock *functionBody,
241 : const TSourceLoc &location);
242 : void parseFunctionDefinitionHeader(const TSourceLoc &location,
243 : TFunction **function,
244 : TIntermAggregate **aggregateOut);
245 : TFunction *parseFunctionDeclarator(const TSourceLoc &location,
246 : TFunction *function);
247 : TFunction *parseFunctionHeader(const TPublicType &type,
248 : const TString *name,
249 : const TSourceLoc &location);
250 : TFunction *addConstructorFunc(const TPublicType &publicType);
251 : TIntermTyped *addConstructor(TIntermNode *arguments,
252 : TOperator op,
253 : TFunction *fnCall,
254 : const TSourceLoc &line);
255 :
256 : TIntermTyped *addIndexExpression(TIntermTyped *baseExpression,
257 : const TSourceLoc& location,
258 : TIntermTyped *indexExpression);
259 : TIntermTyped* addFieldSelectionExpression(TIntermTyped *baseExpression,
260 : const TSourceLoc &dotLocation,
261 : const TString &fieldString,
262 : const TSourceLoc &fieldLocation);
263 :
264 : TFieldList *addStructDeclaratorListWithQualifiers(
265 : const TTypeQualifierBuilder &typeQualifierBuilder,
266 : TPublicType *typeSpecifier,
267 : TFieldList *fieldList);
268 : TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList);
269 : TTypeSpecifierNonArray addStructure(const TSourceLoc &structLine,
270 : const TSourceLoc &nameLine,
271 : const TString *structName,
272 : TFieldList *fieldList);
273 :
274 : TIntermDeclaration *addInterfaceBlock(const TTypeQualifierBuilder &typeQualifierBuilder,
275 : const TSourceLoc &nameLine,
276 : const TString &blockName,
277 : TFieldList *fieldList,
278 : const TString *instanceName,
279 : const TSourceLoc &instanceLine,
280 : TIntermTyped *arrayIndex,
281 : const TSourceLoc &arrayIndexLine);
282 :
283 : void parseLocalSize(const TString &qualifierType,
284 : const TSourceLoc &qualifierTypeLine,
285 : int intValue,
286 : const TSourceLoc &intValueLine,
287 : const std::string &intValueString,
288 : size_t index,
289 : sh::WorkGroupSize *localSize);
290 : TLayoutQualifier parseLayoutQualifier(
291 : const TString &qualifierType, const TSourceLoc &qualifierTypeLine);
292 : TLayoutQualifier parseLayoutQualifier(const TString &qualifierType,
293 : const TSourceLoc &qualifierTypeLine,
294 : int intValue,
295 : const TSourceLoc &intValueLine);
296 : TTypeQualifierBuilder *createTypeQualifierBuilder(const TSourceLoc &loc);
297 : TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier,
298 : TLayoutQualifier rightQualifier,
299 : const TSourceLoc &rightQualifierLocation);
300 :
301 : // Performs an error check for embedded struct declarations.
302 : void enterStructDeclaration(const TSourceLoc &line, const TString &identifier);
303 : void exitStructDeclaration();
304 :
305 : void checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field);
306 :
307 : TIntermSwitch *addSwitch(TIntermTyped *init,
308 : TIntermBlock *statementList,
309 : const TSourceLoc &loc);
310 : TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc);
311 : TIntermCase *addDefault(const TSourceLoc &loc);
312 :
313 : TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
314 : TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
315 : TIntermTyped *addBinaryMath(
316 : TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
317 : TIntermTyped *addBinaryMathBooleanResult(
318 : TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
319 : TIntermTyped *addAssign(
320 : TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
321 :
322 : TIntermTyped *addComma(TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
323 :
324 : TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc);
325 : TIntermBranch *addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc);
326 :
327 : void checkTextureOffsetConst(TIntermAggregate *functionCall);
328 : void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall);
329 : void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition,
330 : const TIntermAggregate *functionCall);
331 : TIntermTyped *addFunctionCallOrMethod(TFunction *fnCall,
332 : TIntermNode *paramNode,
333 : TIntermNode *thisNode,
334 : const TSourceLoc &loc,
335 : bool *fatalError);
336 :
337 : TIntermTyped *addTernarySelection(TIntermTyped *cond,
338 : TIntermTyped *trueExpression,
339 : TIntermTyped *falseExpression,
340 : const TSourceLoc &line);
341 :
342 : // TODO(jmadill): make these private
343 : TIntermediate intermediate; // to build a parse tree
344 : TSymbolTable &symbolTable; // symbol table that goes with the language currently being parsed
345 :
346 : private:
347 : // Returns a clamped index.
348 : int checkIndexOutOfRange(bool outOfRangeIndexIsError,
349 : const TSourceLoc &location,
350 : int index,
351 : int arraySize,
352 : const char *reason,
353 : const char *token);
354 :
355 : bool declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type, TVariable **variable);
356 :
357 : void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
358 : const TString &identifier,
359 : TPublicType *type);
360 :
361 : bool checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation,
362 : const TPublicType &elementType);
363 :
364 : // Assumes that multiplication op has already been set based on the types.
365 : bool isMultiplicationTypeCombinationValid(TOperator op, const TType &left, const TType &right);
366 :
367 : bool checkIsMemoryQualifierNotSpecified(const TMemoryQualifier &memoryQualifier,
368 : const TSourceLoc &location);
369 : void checkOutParameterIsNotImage(const TSourceLoc &line,
370 : TQualifier qualifier,
371 : const TType &type);
372 : void checkOutParameterIsNotOpaqueType(const TSourceLoc &line,
373 : TQualifier qualifier,
374 : const TType &type);
375 : void checkOutParameterIsNotSampler(const TSourceLoc &line,
376 : TQualifier qualifier,
377 : const TType &type);
378 :
379 : TIntermTyped *addBinaryMathInternal(
380 : TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
381 : TIntermBinary *createAssign(TOperator op,
382 : TIntermTyped *left,
383 : TIntermTyped *right,
384 : const TSourceLoc &loc);
385 : // The funcReturnType parameter is expected to be non-null when the operation is a built-in function.
386 : // It is expected to be null for other unary operators.
387 : TIntermTyped *createUnaryMath(
388 : TOperator op, TIntermTyped *child, const TSourceLoc &loc, const TType *funcReturnType);
389 :
390 : // Return true if the checks pass
391 : bool binaryOpCommonCheck(
392 : TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
393 :
394 : // Set to true when the last/current declarator list was started with an empty declaration.
395 : bool mDeferredSingleDeclarationErrorCheck;
396 :
397 : sh::GLenum mShaderType; // vertex or fragment language (future: pack or unpack)
398 : ShShaderSpec mShaderSpec; // The language specification compiler conforms to - GLES2 or WebGL.
399 : ShCompileOptions mCompileOptions; // Options passed to TCompiler
400 : int mShaderVersion;
401 : TIntermBlock *mTreeRoot; // root of parse tree being created
402 : int mLoopNestingLevel; // 0 if outside all loops
403 : int mStructNestingLevel; // incremented while parsing a struct declaration
404 : int mSwitchNestingLevel; // 0 if outside all switch statements
405 : const TType
406 : *mCurrentFunctionType; // the return type of the function that's currently being parsed
407 : bool mFunctionReturnsValue; // true if a non-void function has a return
408 : bool mChecksPrecisionErrors; // true if an error will be generated when a variable is declared
409 : // without precision, explicit or implicit.
410 : bool mFragmentPrecisionHighOnESSL1; // true if highp precision is supported when compiling
411 : // ESSL1.
412 : TLayoutMatrixPacking mDefaultMatrixPacking;
413 : TLayoutBlockStorage mDefaultBlockStorage;
414 : TString mHashErrMsg;
415 : TDiagnostics mDiagnostics;
416 : TDirectiveHandler mDirectiveHandler;
417 : pp::Preprocessor mPreprocessor;
418 : void *mScanner;
419 : bool mUsesFragData; // track if we are using both gl_FragData and gl_FragColor
420 : bool mUsesFragColor;
421 : bool mUsesSecondaryOutputs; // Track if we are using either gl_SecondaryFragData or
422 : // gl_Secondary FragColor or both.
423 : int mMinProgramTexelOffset;
424 : int mMaxProgramTexelOffset;
425 :
426 : // keep track of local group size declared in layout. It should be declared only once.
427 : bool mComputeShaderLocalSizeDeclared;
428 : sh::WorkGroupSize mComputeShaderLocalSize;
429 : // keeps track whether we are declaring / defining a function
430 : bool mDeclaringFunction;
431 : };
432 :
433 : int PaParseStrings(
434 : size_t count, const char *const string[], const int length[], TParseContext *context);
435 :
436 : } // namespace sh
437 :
438 : #endif // COMPILER_TRANSLATOR_PARSECONTEXT_H_
|