blob: c1be7c99b15cf09014a440c5671bbdf19b413161 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
Nicolas Capens16004fc2014-06-11 11:29:11 -04002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
Geoff Lang0a73dd82014-11-19 16:18:08 -05006#ifndef COMPILER_TRANSLATOR_PARSECONTEXT_H_
7#define COMPILER_TRANSLATOR_PARSECONTEXT_H_
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00008
Jamie Madilld4a3a312014-06-25 16:04:56 -04009#include "compiler/translator/Compiler.h"
Geoff Lang17732822013-08-29 13:46:49 -040010#include "compiler/translator/Diagnostics.h"
11#include "compiler/translator/DirectiveHandler.h"
Jamie Madillb1a85f42014-08-19 15:23:24 -040012#include "compiler/translator/Intermediate.h"
Geoff Lang17732822013-08-29 13:46:49 -040013#include "compiler/translator/SymbolTable.h"
daniel@transgaming.comb401a922012-10-26 18:58:24 +000014#include "compiler/preprocessor/Preprocessor.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000015
Jamie Madill06145232015-05-13 13:10:01 -040016struct TMatrixFields
17{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000018 bool wholeRow;
19 bool wholeCol;
20 int row;
21 int col;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000022};
23
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000024//
25// The following are extra variables needed during parsing, grouped together so
26// they can be passed to the parser without needing a global.
27//
Jamie Madill06145232015-05-13 13:10:01 -040028struct TParseContext : angle::NonCopyable
29{
30 TParseContext(TSymbolTable &symt,
31 TExtensionBehavior &ext,
32 TIntermediate &interm,
33 sh::GLenum type,
34 ShShaderSpec spec,
35 int options,
36 bool checksPrecErrors,
37 TInfoSink &is,
38 bool debugShaderPrecisionSupported)
39 : intermediate(interm),
40 symbolTable(symt),
41 shaderType(type),
42 shaderSpec(spec),
43 compileOptions(options),
44 treeRoot(nullptr),
45 mLoopNestingLevel(0),
46 structNestingLevel(0),
47 mSwitchNestingLevel(0),
48 currentFunctionType(nullptr),
49 mFunctionReturnsValue(false),
50 checksPrecisionErrors(checksPrecErrors),
51 fragmentPrecisionHigh(false),
52 defaultMatrixPacking(EmpColumnMajor),
53 defaultBlockStorage(EbsShared),
54 diagnostics(is),
55 shaderVersion(100),
56 directiveHandler(ext, diagnostics, shaderVersion, debugShaderPrecisionSupported),
57 preprocessor(&diagnostics, &directiveHandler),
58 scanner(nullptr),
59 mDeferredSingleDeclarationErrorCheck(false)
Olli Etuahofa33d582015-04-09 14:33:12 +030060 {
61 }
Jamie Madill06145232015-05-13 13:10:01 -040062
63 TIntermediate &intermediate; // to hold and build a parse tree
64 TSymbolTable &symbolTable; // symbol table that goes with the language currently being parsed
Jamie Madill183bde52014-07-02 15:31:19 -040065 sh::GLenum shaderType; // vertex or fragment language (future: pack or unpack)
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000066 ShShaderSpec shaderSpec; // The language specification compiler conforms to - GLES2 or WebGL.
shannon.woods%transgaming.com@gtempaccount.com5524db02013-04-13 03:38:16 +000067 int shaderVersion;
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +000068 int compileOptions;
Jamie Madill06145232015-05-13 13:10:01 -040069 TIntermNode *treeRoot; // root of parse tree being created
Olli Etuaho49300862015-02-20 14:54:49 +020070 int mLoopNestingLevel; // 0 if outside all loops
kbr@chromium.org476541f2011-10-27 21:14:51 +000071 int structNestingLevel; // incremented while parsing a struct declaration
Olli Etuaho53f076f2015-02-20 10:55:14 +020072 int mSwitchNestingLevel; // 0 if outside all switch statements
Jamie Madill06145232015-05-13 13:10:01 -040073 const TType *currentFunctionType; // the return type of the function that's currently being parsed
Olli Etuaho49300862015-02-20 14:54:49 +020074 bool mFunctionReturnsValue; // true if a non-void function has a return
zmo@google.comdc4b4f82011-06-17 00:42:53 +000075 bool checksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit.
shannon.woods%transgaming.com@gtempaccount.comcbb6b6a2013-04-13 03:27:47 +000076 bool fragmentPrecisionHigh; // true if highp precision is supported in the fragment language.
Jamie Madill099c0f32013-06-20 11:55:52 -040077 TLayoutMatrixPacking defaultMatrixPacking;
Jamie Madill1566ef72013-06-20 11:55:54 -040078 TLayoutBlockStorage defaultBlockStorage;
alokp@chromium.org75fe6b72011-08-14 05:31:22 +000079 TString HashErrMsg;
alokp@chromium.org73bc2982012-06-19 18:48:05 +000080 TDiagnostics diagnostics;
81 TDirectiveHandler directiveHandler;
82 pp::Preprocessor preprocessor;
Jamie Madill06145232015-05-13 13:10:01 -040083 void *scanner;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000084
shannon.woods%transgaming.com@gtempaccount.com5524db02013-04-13 03:38:16 +000085 int getShaderVersion() const { return shaderVersion; }
alokp@chromium.org6b495712012-06-29 00:06:58 +000086 int numErrors() const { return diagnostics.numErrors(); }
Jamie Madill06145232015-05-13 13:10:01 -040087 TInfoSink &infoSink() { return diagnostics.infoSink(); }
88 void error(const TSourceLoc &loc, const char *reason, const char *token,
89 const char *extraInfo="");
90 void warning(const TSourceLoc &loc, const char *reason, const char *token,
91 const char *extraInfo="");
daniel@transgaming.com0578f812010-05-17 09:58:39 +000092 void recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000093
Jamie Madill5c097022014-08-20 16:38:32 -040094 // This method is guaranteed to succeed, even if no variable with 'name' exists.
95 const TVariable *getNamedVariable(const TSourceLoc &location, const TString *name, const TSymbol *symbol);
96
Jamie Madill06145232015-05-13 13:10:01 -040097 bool parseVectorFields(const TString&, int vecSize, TVectorFields&, const TSourceLoc &line);
98 bool parseMatrixFields(const TString&, int matCols, int matRows, TMatrixFields&, const TSourceLoc &line);
alokp@chromium.org75fe6b72011-08-14 05:31:22 +000099
Jamie Madill06145232015-05-13 13:10:01 -0400100 bool reservedErrorCheck(const TSourceLoc &line, const TString &identifier);
101 void assignError(const TSourceLoc &line, const char *op, TString left, TString right);
102 void unaryOpError(const TSourceLoc &line, const char *op, TString operand);
103 void binaryOpError(const TSourceLoc &line, const char *op, TString left, TString right);
104 bool precisionErrorCheck(const TSourceLoc &line, TPrecision precision, TBasicType type);
105 bool lValueErrorCheck(const TSourceLoc &line, const char *op, TIntermTyped*);
106 bool constErrorCheck(TIntermTyped *node);
107 bool integerErrorCheck(TIntermTyped *node, const char *token);
108 bool globalErrorCheck(const TSourceLoc &line, bool global, const char *token);
109 bool constructorErrorCheck(const TSourceLoc &line, TIntermNode*, TFunction&, TOperator, TType*);
110 bool arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped *expr, int &size);
Olli Etuaho3739d232015-04-08 12:23:44 +0300111 bool arrayQualifierErrorCheck(const TSourceLoc &line, const TPublicType &type);
Jamie Madill06145232015-05-13 13:10:01 -0400112 bool arrayTypeErrorCheck(const TSourceLoc &line, const TPublicType &type);
Olli Etuaho6ed7bbe2015-04-07 18:08:46 +0300113 bool voidErrorCheck(const TSourceLoc &line, const TString &identifier, const TBasicType &type);
Jamie Madill075edd82013-07-08 13:30:19 -0400114 bool boolErrorCheck(const TSourceLoc&, const TIntermTyped*);
115 bool boolErrorCheck(const TSourceLoc&, const TPublicType&);
Jamie Madill06145232015-05-13 13:10:01 -0400116 bool samplerErrorCheck(const TSourceLoc &line, const TPublicType &pType, const char *reason);
117 bool locationDeclaratorListCheck(const TSourceLoc &line, const TPublicType &pType);
118 bool parameterSamplerErrorCheck(const TSourceLoc &line, TQualifier qualifier, const TType &type);
119 bool paramErrorCheck(const TSourceLoc &line, TQualifier qualifier, TQualifier paramQualifier, TType *type);
120 bool extensionErrorCheck(const TSourceLoc &line, const TString&);
121 bool singleDeclarationErrorCheck(const TPublicType &publicType, const TSourceLoc &identifierLocation);
122 bool layoutLocationErrorCheck(const TSourceLoc &location, const TLayoutQualifier &layoutQualifier);
Olli Etuahob6e07a62015-02-16 12:22:10 +0200123 bool functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *);
Olli Etuaho37ad4742015-04-27 13:18:50 +0300124 void es3InvariantErrorCheck(const TQualifier qualifier, const TSourceLoc &invariantLocation);
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000125
Jamie Madill06145232015-05-13 13:10:01 -0400126 const TPragma &pragma() const { return directiveHandler.pragma(); }
127 const TExtensionBehavior &extensionBehavior() const { return directiveHandler.extensionBehavior(); }
128 bool supportsExtension(const char *extension);
129 bool isExtensionEnabled(const char *extension) const;
130 void handleExtensionDirective(const TSourceLoc &loc, const char *extName, const char *behavior);
131 void handlePragmaDirective(const TSourceLoc &loc, const char *name, const char *value, bool stdgl);
alokp@chromium.org75fe6b72011-08-14 05:31:22 +0000132
Jamie Madill06145232015-05-13 13:10:01 -0400133 bool containsSampler(const TType &type);
134 bool areAllChildConst(TIntermAggregate *aggrNode);
135 const TFunction* findFunction(
136 const TSourceLoc &line, TFunction *pfnCall, int inputShaderVersion, bool *builtIn = 0);
137 bool executeInitializer(const TSourceLoc &line,
138 const TString &identifier,
139 const TPublicType &pType,
140 TIntermTyped *initializer,
141 TIntermNode **intermNode);
alokp@chromium.org75fe6b72011-08-14 05:31:22 +0000142
Jamie Madill06145232015-05-13 13:10:01 -0400143 TPublicType addFullySpecifiedType(TQualifier qualifier,
144 bool invariant,
145 TLayoutQualifier layoutQualifier,
146 const TPublicType &typeSpecifier);
Olli Etuahoe7847b02015-03-16 11:56:12 +0200147
Olli Etuahofa33d582015-04-09 14:33:12 +0300148 TIntermAggregate *parseSingleDeclaration(TPublicType &publicType,
Jamie Madill06145232015-05-13 13:10:01 -0400149 const TSourceLoc &identifierOrTypeLocation,
150 const TString &identifier);
Olli Etuahoe7847b02015-03-16 11:56:12 +0200151 TIntermAggregate *parseSingleArrayDeclaration(TPublicType &publicType,
Jamie Madill06145232015-05-13 13:10:01 -0400152 const TSourceLoc &identifierLocation,
153 const TString &identifier,
154 const TSourceLoc &indexLocation,
155 TIntermTyped *indexExpression);
156 TIntermAggregate *parseSingleInitDeclaration(const TPublicType &publicType,
157 const TSourceLoc &identifierLocation,
158 const TString &identifier,
159 const TSourceLoc &initLocation,
160 TIntermTyped *initializer);
Jamie Madill47e3ec02014-08-20 16:38:33 -0400161
Olli Etuaho3875ffd2015-04-10 16:45:14 +0300162 // Parse a declaration like "type a[n] = initializer"
163 // Note that this does not apply to declarations like "type[n] a = initializer"
164 TIntermAggregate *parseSingleArrayInitDeclaration(TPublicType &publicType,
Jamie Madill06145232015-05-13 13:10:01 -0400165 const TSourceLoc &identifierLocation,
166 const TString &identifier,
167 const TSourceLoc &indexLocation,
168 TIntermTyped *indexExpression,
169 const TSourceLoc &initLocation,
170 TIntermTyped *initializer);
Olli Etuaho3875ffd2015-04-10 16:45:14 +0300171
Jamie Madill06145232015-05-13 13:10:01 -0400172 TIntermAggregate *parseInvariantDeclaration(const TSourceLoc &invariantLoc,
173 const TSourceLoc &identifierLoc,
174 const TString *identifier,
175 const TSymbol *symbol);
Olli Etuahoe7847b02015-03-16 11:56:12 +0200176
Jamie Madill06145232015-05-13 13:10:01 -0400177 TIntermAggregate *parseDeclarator(TPublicType &publicType,
178 TIntermAggregate *aggregateDeclaration,
179 const TSourceLoc &identifierLocation,
180 const TString &identifier);
181 TIntermAggregate *parseArrayDeclarator(TPublicType &publicType,
182 TIntermAggregate *aggregateDeclaration,
183 const TSourceLoc &identifierLocation,
184 const TString &identifier,
185 const TSourceLoc &arrayLocation,
186 TIntermTyped *indexExpression);
187 TIntermAggregate *parseInitDeclarator(const TPublicType &publicType,
188 TIntermAggregate *aggregateDeclaration,
189 const TSourceLoc &identifierLocation,
190 const TString &identifier,
191 const TSourceLoc &initLocation,
192 TIntermTyped *initializer);
Olli Etuahoe7847b02015-03-16 11:56:12 +0200193
Olli Etuaho3875ffd2015-04-10 16:45:14 +0300194 // Parse a declarator like "a[n] = initializer"
Jamie Madill06145232015-05-13 13:10:01 -0400195 TIntermAggregate *parseArrayInitDeclarator(const TPublicType &publicType,
196 TIntermAggregate *aggregateDeclaration,
197 const TSourceLoc &identifierLocation,
198 const TString &identifier,
199 const TSourceLoc &indexLocation,
200 TIntermTyped *indexExpression,
201 const TSourceLoc &initLocation,
202 TIntermTyped *initializer);
Olli Etuaho3875ffd2015-04-10 16:45:14 +0300203
Jamie Madilla295edf2013-06-06 11:56:48 -0400204 void parseGlobalLayoutQualifier(const TPublicType &typeQualifier);
Jamie Madill06145232015-05-13 13:10:01 -0400205 TFunction *addConstructorFunc(const TPublicType &publicType);
206 TIntermTyped *addConstructor(TIntermNode *arguments,
207 TType *type,
208 TOperator op,
209 TFunction *fnCall,
210 const TSourceLoc &line);
211 TIntermTyped *foldConstConstructor(TIntermAggregate *aggrNode, const TType &type);
212 TIntermTyped *addConstVectorNode(TVectorFields&, TIntermTyped*, const TSourceLoc&);
213 TIntermTyped *addConstMatrixNode(int, TIntermTyped*, const TSourceLoc&);
214 TIntermTyped *addConstArrayNode(int index, TIntermTyped *node, const TSourceLoc &line);
215 TIntermTyped *addConstStruct(
216 const TString &identifier, TIntermTyped *node, const TSourceLoc& line);
217 TIntermTyped *addIndexExpression(TIntermTyped *baseExpression,
218 const TSourceLoc& location,
219 TIntermTyped *indexExpression);
220 TIntermTyped* addFieldSelectionExpression(TIntermTyped *baseExpression,
221 const TSourceLoc &dotLocation,
222 const TString &fieldString,
223 const TSourceLoc &fieldLocation);
shannonwoods@chromium.orga9100882013-05-30 00:11:39 +0000224
Jamie Madill06145232015-05-13 13:10:01 -0400225 TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList);
226 TPublicType addStructure(const TSourceLoc &structLine,
227 const TSourceLoc &nameLine,
228 const TString *structName,
229 TFieldList *fieldList);
kbr@chromium.org476541f2011-10-27 21:14:51 +0000230
Jamie Madill06145232015-05-13 13:10:01 -0400231 TIntermAggregate* addInterfaceBlock(const TPublicType &typeQualifier,
232 const TSourceLoc &nameLine,
233 const TString &blockName,
234 TFieldList *fieldList,
235 const TString *instanceName,
236 const TSourceLoc &instanceLine,
237 TIntermTyped *arrayIndex,
238 const TSourceLoc& arrayIndexLine);
shannonwoods@chromium.org5668c5d2013-05-30 00:11:48 +0000239
Jamie Madill06145232015-05-13 13:10:01 -0400240 TLayoutQualifier parseLayoutQualifier(
241 const TString &qualifierType, const TSourceLoc &qualifierTypeLine);
242 TLayoutQualifier parseLayoutQualifier(const TString &qualifierType,
243 const TSourceLoc &qualifierTypeLine,
244 const TString &intValueString,
245 int intValue,
246 const TSourceLoc &intValueLine);
Jamie Madilla5efff92013-06-06 11:56:47 -0400247 TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier);
Jamie Madillf2e0f9b2013-08-26 16:39:42 -0400248 TPublicType joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier,
249 const TSourceLoc &storageLoc, TQualifier storageQualifier);
shannonwoods@chromium.org302adfe2013-05-30 00:21:06 +0000250
kbr@chromium.org476541f2011-10-27 21:14:51 +0000251 // Performs an error check for embedded struct declarations.
252 // Returns true if an error was raised due to the declaration of
253 // this struct.
Jamie Madill06145232015-05-13 13:10:01 -0400254 bool enterStructDeclaration(const TSourceLoc &line, const TString &identifier);
kbr@chromium.org476541f2011-10-27 21:14:51 +0000255 void exitStructDeclaration();
256
Jamie Madill06145232015-05-13 13:10:01 -0400257 bool structNestingErrorCheck(const TSourceLoc &line, const TField &field);
Olli Etuaho09b22472015-02-11 11:47:26 +0200258
Olli Etuahoa3a36662015-02-17 13:46:51 +0200259 TIntermSwitch *addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &loc);
260 TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc);
261 TIntermCase *addDefault(const TSourceLoc &loc);
262
Jamie Madill06145232015-05-13 13:10:01 -0400263 TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
264 TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
265 TIntermTyped *addBinaryMath(
266 TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
267 TIntermTyped *addBinaryMathBooleanResult(
268 TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
269 TIntermTyped *addAssign(
270 TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
Olli Etuaho49300862015-02-20 14:54:49 +0200271
272 TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc);
273 TIntermBranch *addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc);
Olli Etuahoc4ba3be2015-03-02 14:42:24 +0200274
Jamie Madill06145232015-05-13 13:10:01 -0400275 TIntermTyped *addFunctionCallOrMethod(TFunction *fnCall,
276 TIntermNode *paramNode,
277 TIntermNode *thisNode,
278 const TSourceLoc &loc,
279 bool *fatalError);
Olli Etuahofc1806e2015-03-17 13:03:11 +0200280
Jamie Madill06145232015-05-13 13:10:01 -0400281 TIntermTyped *addTernarySelection(
282 TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &line);
Olli Etuaho52901742015-04-15 13:42:45 +0300283
Olli Etuahofc1806e2015-03-17 13:03:11 +0200284 private:
Olli Etuaho2935c582015-04-08 14:32:06 +0300285 bool declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type, TVariable **variable);
286
Olli Etuaho376f1b52015-04-13 13:23:41 +0300287 bool nonInitErrorCheck(const TSourceLoc &line, const TString &identifier, TPublicType *type);
288
Jamie Madill06145232015-05-13 13:10:01 -0400289 TIntermTyped *addBinaryMathInternal(
290 TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
291 TIntermTyped *createAssign(
292 TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
Olli Etuahof6c694b2015-03-26 14:50:53 +0200293 // The funcReturnType parameter is expected to be non-null when the operation is a built-in function.
294 // It is expected to be null for other unary operators.
Jamie Madill06145232015-05-13 13:10:01 -0400295 TIntermTyped *createUnaryMath(
296 TOperator op, TIntermTyped *child, const TSourceLoc &loc, const TType *funcReturnType);
Olli Etuahod6b14282015-03-17 14:31:35 +0200297
Olli Etuaho47fd36a2015-03-19 14:22:24 +0200298 // Return true if the checks pass
Jamie Madill06145232015-05-13 13:10:01 -0400299 bool binaryOpCommonCheck(
300 TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
Olli Etuahofa33d582015-04-09 14:33:12 +0300301
302 // Set to true when the last/current declarator list was started with an empty declaration.
303 bool mDeferredSingleDeclarationErrorCheck;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000304};
305
Jamie Madill06145232015-05-13 13:10:01 -0400306int PaParseStrings(
307 size_t count, const char *const string[], const int length[], TParseContext *context);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000308
Geoff Lang0a73dd82014-11-19 16:18:08 -0500309#endif // COMPILER_TRANSLATOR_PARSECONTEXT_H_