blob: fc9f1029e06299a48b8dde4a1ce65a5d81c3f709 [file] [log] [blame]
John Bauman66b8ab22014-05-06 15:57:45 -04001//
2// Copyright (c) 2002-2012 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 _PARSER_HELPER_INCLUDED_
7#define _PARSER_HELPER_INCLUDED_
8
Nicolas Capenscc863da2015-01-21 15:50:55 -05009#include "Diagnostics.h"
10#include "DirectiveHandler.h"
11#include "localintermediate.h"
12#include "preprocessor/Preprocessor.h"
Nicolas Capensd8cbf392015-02-10 15:35:11 -050013#include "Compiler.h"
Nicolas Capenscc863da2015-01-21 15:50:55 -050014#include "SymbolTable.h"
John Bauman66b8ab22014-05-06 15:57:45 -040015
16struct TMatrixFields {
17 bool wholeRow;
18 bool wholeCol;
19 int row;
20 int col;
21};
22
23//
24// The following are extra variables needed during parsing, grouped together so
25// they can be passed to the parser without needing a global.
26//
Alexis Hetu0a655842015-06-22 16:52:11 -040027class TParseContext {
28public:
Nicolas Capens08ca3c62015-02-13 16:06:45 -050029 TParseContext(TSymbolTable& symt, TExtensionBehavior& ext, TIntermediate& interm, GLenum type, int options, bool checksPrecErrors, const char* sourcePath, TInfoSink& is) :
John Bauman66b8ab22014-05-06 15:57:45 -040030 intermediate(interm),
31 symbolTable(symt),
John Bauman66b8ab22014-05-06 15:57:45 -040032 compileOptions(options),
33 sourcePath(sourcePath),
John Bauman66b8ab22014-05-06 15:57:45 -040034 lexAfterType(false),
John Bauman66b8ab22014-05-06 15:57:45 -040035 inTypeParen(false),
Alexis Hetu0a655842015-06-22 16:52:11 -040036 AfterEOF(false),
37 mDeferredSingleDeclarationErrorCheck(false),
38 mShaderType(type),
39 mShaderVersion(100),
40 mTreeRoot(0),
41 mLoopNestingLevel(0),
42 mSwitchNestingLevel(0),
43 mStructNestingLevel(0),
44 mCurrentFunctionType(NULL),
45 mFunctionReturnsValue(false),
46 mChecksPrecisionErrors(checksPrecErrors),
47 mDefaultMatrixPacking(EmpColumnMajor),
48 mDefaultBlockStorage(EbsShared),
49 mDiagnostics(is),
50 mDirectiveHandler(ext, mDiagnostics, mShaderVersion),
51 mPreprocessor(&mDiagnostics, &mDirectiveHandler),
52 mScanner(NULL),
Alexis Hetudd7ff7a2015-06-11 08:25:30 -040053 mUsesFragData(false),
54 mUsesFragColor(false) { }
John Bauman66b8ab22014-05-06 15:57:45 -040055 TIntermediate& intermediate; // to hold and build a parse tree
56 TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed
John Bauman66b8ab22014-05-06 15:57:45 -040057 int compileOptions;
58 const char* sourcePath; // Path of source file or NULL.
John Bauman66b8ab22014-05-06 15:57:45 -040059 bool lexAfterType; // true if we've recognized a type, so can only be looking for an identifier
John Bauman66b8ab22014-05-06 15:57:45 -040060 bool inTypeParen; // true if in parentheses, looking only for an identifier
John Bauman66b8ab22014-05-06 15:57:45 -040061 bool AfterEOF;
John Bauman66b8ab22014-05-06 15:57:45 -040062
Alexis Hetu0a655842015-06-22 16:52:11 -040063 const pp::Preprocessor &getPreprocessor() const { return mPreprocessor; }
64 pp::Preprocessor &getPreprocessor() { return mPreprocessor; }
65 void *getScanner() const { return mScanner; }
66 void setScanner(void *scanner) { mScanner = scanner; }
67 int getShaderVersion() const { return mShaderVersion; }
68 GLenum getShaderType() const { return mShaderType; }
69 int numErrors() const { return mDiagnostics.numErrors(); }
70 TInfoSink &infoSink() { return mDiagnostics.infoSink(); }
Alexis Hetufe1269e2015-06-16 12:43:32 -040071 void error(const TSourceLoc &loc, const char *reason, const char* token,
John Bauman66b8ab22014-05-06 15:57:45 -040072 const char* extraInfo="");
Alexis Hetufe1269e2015-06-16 12:43:32 -040073 void warning(const TSourceLoc &loc, const char* reason, const char* token,
John Bauman66b8ab22014-05-06 15:57:45 -040074 const char* extraInfo="");
75 void trace(const char* str);
76 void recover();
Alexis Hetu0a655842015-06-22 16:52:11 -040077 TIntermNode *getTreeRoot() const { return mTreeRoot; }
78 void setTreeRoot(TIntermNode *treeRoot) { mTreeRoot = treeRoot; }
79
80 bool getFunctionReturnsValue() const { return mFunctionReturnsValue; }
81 void setFunctionReturnsValue(bool functionReturnsValue)
82 {
83 mFunctionReturnsValue = functionReturnsValue;
84 }
85
86 void setLoopNestingLevel(int loopNestintLevel)
87 {
88 mLoopNestingLevel = loopNestintLevel;
89 }
90
91 const TType *getCurrentFunctionType() const { return mCurrentFunctionType; }
92 void setCurrentFunctionType(const TType *currentFunctionType)
93 {
94 mCurrentFunctionType = currentFunctionType;
95 }
96
97 void incrLoopNestingLevel() { ++mLoopNestingLevel; }
98 void decrLoopNestingLevel() { --mLoopNestingLevel; }
99
100 void incrSwitchNestingLevel() { ++mSwitchNestingLevel; }
101 void decrSwitchNestingLevel() { --mSwitchNestingLevel; }
Alexis Hetu76a343a2015-06-04 17:21:22 -0400102
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400103 // This method is guaranteed to succeed, even if no variable with 'name' exists.
104 const TVariable *getNamedVariable(const TSourceLoc &location, const TString *name, const TSymbol *symbol);
105
Alexis Hetufe1269e2015-06-16 12:43:32 -0400106 bool parseVectorFields(const TString&, int vecSize, TVectorFields&, const TSourceLoc &line);
107 bool parseMatrixFields(const TString&, int matCols, int matRows, TMatrixFields&, const TSourceLoc &line);
John Bauman66b8ab22014-05-06 15:57:45 -0400108
Alexis Hetufe1269e2015-06-16 12:43:32 -0400109 bool reservedErrorCheck(const TSourceLoc &line, const TString& identifier);
110 void assignError(const TSourceLoc &line, const char* op, TString left, TString right);
111 void unaryOpError(const TSourceLoc &line, const char* op, TString operand);
112 void binaryOpError(const TSourceLoc &line, const char* op, TString left, TString right);
113 bool precisionErrorCheck(const TSourceLoc &line, TPrecision precision, TBasicType type);
114 bool lValueErrorCheck(const TSourceLoc &line, const char* op, TIntermTyped*);
John Bauman66b8ab22014-05-06 15:57:45 -0400115 bool constErrorCheck(TIntermTyped* node);
116 bool integerErrorCheck(TIntermTyped* node, const char* token);
Alexis Hetufe1269e2015-06-16 12:43:32 -0400117 bool globalErrorCheck(const TSourceLoc &line, bool global, const char* token);
118 bool constructorErrorCheck(const TSourceLoc &line, TIntermNode*, TFunction&, TOperator, TType*);
119 bool arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped* expr, int& size);
120 bool arrayQualifierErrorCheck(const TSourceLoc &line, TPublicType type);
121 bool arrayTypeErrorCheck(const TSourceLoc &line, TPublicType type);
Alexis Hetufe1269e2015-06-16 12:43:32 -0400122 bool voidErrorCheck(const TSourceLoc&, const TString&, const TBasicType&);
123 bool boolErrorCheck(const TSourceLoc&, const TIntermTyped*);
124 bool boolErrorCheck(const TSourceLoc&, const TPublicType&);
125 bool samplerErrorCheck(const TSourceLoc &line, const TPublicType& pType, const char* reason);
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400126 bool locationDeclaratorListCheck(const TSourceLoc &line, const TPublicType &pType);
Alexis Hetufe1269e2015-06-16 12:43:32 -0400127 bool structQualifierErrorCheck(const TSourceLoc &line, const TPublicType& pType);
128 bool parameterSamplerErrorCheck(const TSourceLoc &line, TQualifier qualifier, const TType& type);
129 bool nonInitConstErrorCheck(const TSourceLoc &line, TString& identifier, TPublicType& type, bool array);
130 bool nonInitErrorCheck(const TSourceLoc &line, const TString& identifier, TPublicType& type);
131 bool paramErrorCheck(const TSourceLoc &line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
132 bool extensionErrorCheck(const TSourceLoc &line, const TString&);
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400133 bool singleDeclarationErrorCheck(const TPublicType &publicType, const TSourceLoc &identifierLocation);
Alexis Hetuad6b8752015-06-09 16:15:30 -0400134 bool layoutLocationErrorCheck(const TSourceLoc& location, const TLayoutQualifier &layoutQualifier);
135 bool functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *);
Alexis Hetuad527752015-07-07 13:31:44 -0400136 void es3InvariantErrorCheck(const TQualifier qualifier, const TSourceLoc &invariantLocation);
John Bauman66b8ab22014-05-06 15:57:45 -0400137
Alexis Hetu0a655842015-06-22 16:52:11 -0400138 const TExtensionBehavior& extensionBehavior() const { return mDirectiveHandler.extensionBehavior(); }
John Bauman66b8ab22014-05-06 15:57:45 -0400139 bool supportsExtension(const char* extension);
Alexis Hetufe1269e2015-06-16 12:43:32 -0400140 void handleExtensionDirective(const TSourceLoc &line, const char* extName, const char* behavior);
John Bauman66b8ab22014-05-06 15:57:45 -0400141
Alexis Hetu0a655842015-06-22 16:52:11 -0400142 const TPragma& pragma() const { return mDirectiveHandler.pragma(); }
Alexis Hetufe1269e2015-06-16 12:43:32 -0400143 void handlePragmaDirective(const TSourceLoc &line, const char* name, const char* value);
John Bauman66b8ab22014-05-06 15:57:45 -0400144
145 bool containsSampler(TType& type);
146 bool areAllChildConst(TIntermAggregate* aggrNode);
Alexis Hetufe1269e2015-06-16 12:43:32 -0400147 const TFunction* findFunction(const TSourceLoc &line, TFunction* pfnCall, bool *builtIn = 0);
Alexis Hetue5246692015-06-18 12:34:52 -0400148 bool executeInitializer(const TSourceLoc &line, const TString &identifier, const TPublicType &pType,
149 TIntermTyped *initializer, TIntermNode **intermNode);
Alexis Hetu42ff6b12015-06-03 16:03:48 -0400150
151 TPublicType addFullySpecifiedType(TQualifier qualifier, bool invariant, TLayoutQualifier layoutQualifier, const TPublicType &typeSpecifier);
Alexis Hetufe1269e2015-06-16 12:43:32 -0400152 bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, const TSourceLoc&);
John Bauman66b8ab22014-05-06 15:57:45 -0400153
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400154 TIntermAggregate *parseSingleDeclaration(TPublicType &publicType, const TSourceLoc &identifierOrTypeLocation, const TString &identifier);
155 TIntermAggregate *parseSingleArrayDeclaration(TPublicType &publicType, const TSourceLoc &identifierLocation, const TString &identifier,
156 const TSourceLoc &indexLocation, TIntermTyped *indexExpression);
157 TIntermAggregate *parseSingleInitDeclaration(const TPublicType &publicType, const TSourceLoc &identifierLocation, const TString &identifier,
158 const TSourceLoc &initLocation, TIntermTyped *initializer);
159
160 // Parse a declaration like "type a[n] = initializer"
161 // Note that this does not apply to declarations like "type[n] a = initializer"
162 TIntermAggregate *parseSingleArrayInitDeclaration(TPublicType &publicType, const TSourceLoc &identifierLocation, const TString &identifier,
163 const TSourceLoc &indexLocation, TIntermTyped *indexExpression,
164 const TSourceLoc &initLocation, TIntermTyped *initializer);
165
166 TIntermAggregate *parseInvariantDeclaration(const TSourceLoc &invariantLoc, const TSourceLoc &identifierLoc, const TString *identifier,
167 const TSymbol *symbol);
168
169 TIntermAggregate *parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, const TSourceLoc &identifierLocation,
170 const TString &identifier);
171 TIntermAggregate *parseArrayDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, const TSourceLoc &identifierLocation,
172 const TString &identifier, const TSourceLoc &arrayLocation, TIntermTyped *indexExpression);
173 TIntermAggregate *parseInitDeclarator(const TPublicType &publicType, TIntermAggregate *aggregateDeclaration, const TSourceLoc &identifierLocation,
174 const TString &identifier, const TSourceLoc &initLocation, TIntermTyped *initializer);
175
176 // Parse a declarator like "a[n] = initializer"
177 TIntermAggregate *parseArrayInitDeclarator(const TPublicType &publicType, TIntermAggregate *aggregateDeclaration, const TSourceLoc &identifierLocation,
178 const TString &identifier, const TSourceLoc &indexLocation, TIntermTyped *indexExpression,
179 const TSourceLoc &initLocation, TIntermTyped *initializer);
180
Alexis Hetua35d8232015-06-11 17:11:06 -0400181 void parseGlobalLayoutQualifier(const TPublicType &typeQualifier);
Alexis Hetue5246692015-06-18 12:34:52 -0400182 TFunction *addConstructorFunc(const TPublicType &publicType);
Alexis Hetufe1269e2015-06-16 12:43:32 -0400183 TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, const TSourceLoc&);
John Bauman66b8ab22014-05-06 15:57:45 -0400184 TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type);
Alexis Hetufe1269e2015-06-16 12:43:32 -0400185 TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, const TSourceLoc&);
186 TIntermTyped* addConstMatrixNode(int, TIntermTyped*, const TSourceLoc&);
187 TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc &line);
188 TIntermTyped* addConstStruct(const TString&, TIntermTyped*, const TSourceLoc&);
Alexis Hetuad6b8752015-06-09 16:15:30 -0400189 TIntermTyped *addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc& location, TIntermTyped *indexExpression);
190 TIntermTyped* addFieldSelectionExpression(TIntermTyped *baseExpression, const TSourceLoc &dotLocation, const TString &fieldString, const TSourceLoc &fieldLocation);
191
192 TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList);
193 TPublicType addStructure(const TSourceLoc &structLine, const TSourceLoc &nameLine, const TString *structName, TFieldList *fieldList);
John Bauman66b8ab22014-05-06 15:57:45 -0400194
Alexis Hetua35d8232015-06-11 17:11:06 -0400195 TIntermAggregate* addInterfaceBlock(const TPublicType& typeQualifier, const TSourceLoc& nameLine, const TString& blockName, TFieldList* fieldList,
196 const TString* instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine);
197
Nicolas Capens7d626792015-02-17 17:58:31 -0500198 TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine);
199 TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine);
200 TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier);
Alexis Hetu55a2cbc2015-04-16 10:49:45 -0400201 TPublicType joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier, const TSourceLoc &storageLoc, TQualifier storageQualifier);
Nicolas Capens7d626792015-02-17 17:58:31 -0500202
John Bauman66b8ab22014-05-06 15:57:45 -0400203 // Performs an error check for embedded struct declarations.
204 // Returns true if an error was raised due to the declaration of
205 // this struct.
Alexis Hetufe1269e2015-06-16 12:43:32 -0400206 bool enterStructDeclaration(const TSourceLoc &line, const TString& identifier);
John Bauman66b8ab22014-05-06 15:57:45 -0400207 void exitStructDeclaration();
208
Alexis Hetuad6b8752015-06-09 16:15:30 -0400209 bool structNestingErrorCheck(const TSourceLoc &line, const TField &field);
210
Alexis Hetu76a343a2015-06-04 17:21:22 -0400211 TIntermSwitch *addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &loc);
212 TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc);
213 TIntermCase *addDefault(const TSourceLoc &loc);
214
Alexis Hetuad6b8752015-06-09 16:15:30 -0400215 TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
216 TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
Alexis Hetub4769582015-06-16 12:19:50 -0400217 TIntermTyped *addBinaryMath(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
218 TIntermTyped *addBinaryMathBooleanResult(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
Alexis Hetuad6b8752015-06-09 16:15:30 -0400219
Alexis Hetue5246692015-06-18 12:34:52 -0400220 TIntermTyped *addAssign(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
221
Alexis Hetu76a343a2015-06-04 17:21:22 -0400222 TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc);
223 TIntermBranch *addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc);
224
Alexis Hetub3ff42c2015-07-03 18:19:57 -0400225 TIntermTyped *addFunctionCallOrMethod(TFunction *fnCall, TIntermNode *paramNode, TIntermNode *thisNode, const TSourceLoc &loc, bool *fatalError);
226
Alexis Hetueee212e2015-07-07 17:13:30 -0400227 TIntermTyped *addTernarySelection(TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &line);
228
Alexis Hetuad6b8752015-06-09 16:15:30 -0400229private:
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400230 bool declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type, TVariable **variable);
231
Alexis Hetub4769582015-06-16 12:19:50 -0400232 TIntermTyped *addBinaryMathInternal(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
Alexis Hetue5246692015-06-18 12:34:52 -0400233 TIntermTyped *createAssign(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
Alexis Hetub4769582015-06-16 12:19:50 -0400234
Alexis Hetuad6b8752015-06-09 16:15:30 -0400235 // The funcReturnType parameter is expected to be non-null when the operation is a built-in function.
236 // It is expected to be null for other unary operators.
237 TIntermTyped *createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc, const TType *funcReturnType);
238
239 // Return true if the checks pass
240 bool binaryOpCommonCheck(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400241
Alexis Hetu0a655842015-06-22 16:52:11 -0400242 // Set to true when the last/current declarator list was started with an empty declaration.
243 bool mDeferredSingleDeclarationErrorCheck;
244
245 GLenum mShaderType; // vertex or fragment language (future: pack or unpack)
246 int mShaderVersion;
247 TIntermNode *mTreeRoot; // root of parse tree being created
248 int mLoopNestingLevel; // 0 if outside all loops
249 int mSwitchNestingLevel; // 0 if outside all switch statements
250 int mStructNestingLevel; // incremented while parsing a struct declaration
251 const TType *mCurrentFunctionType; // the return type of the function that's currently being parsed
252 bool mFunctionReturnsValue; // true if a non-void function has a return
253 bool mChecksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit.
254
255 TLayoutMatrixPacking mDefaultMatrixPacking;
256 TLayoutBlockStorage mDefaultBlockStorage;
257 TDiagnostics mDiagnostics;
258 TDirectiveHandler mDirectiveHandler;
259 pp::Preprocessor mPreprocessor;
260 void *mScanner;
261 bool mUsesFragData; // track if we are using both gl_FragData and gl_FragColor
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400262 bool mUsesFragColor;
John Bauman66b8ab22014-05-06 15:57:45 -0400263};
264
265int PaParseStrings(int count, const char* const string[], const int length[],
266 TParseContext* context);
267
268#endif // _PARSER_HELPER_INCLUDED_