blob: 145d3f79539d8a349384dc0aaaab26dfc8bd6705 [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 *);
John Bauman66b8ab22014-05-06 15:57:45 -0400136
Alexis Hetu0a655842015-06-22 16:52:11 -0400137 const TExtensionBehavior& extensionBehavior() const { return mDirectiveHandler.extensionBehavior(); }
John Bauman66b8ab22014-05-06 15:57:45 -0400138 bool supportsExtension(const char* extension);
Alexis Hetufe1269e2015-06-16 12:43:32 -0400139 void handleExtensionDirective(const TSourceLoc &line, const char* extName, const char* behavior);
John Bauman66b8ab22014-05-06 15:57:45 -0400140
Alexis Hetu0a655842015-06-22 16:52:11 -0400141 const TPragma& pragma() const { return mDirectiveHandler.pragma(); }
Alexis Hetufe1269e2015-06-16 12:43:32 -0400142 void handlePragmaDirective(const TSourceLoc &line, const char* name, const char* value);
John Bauman66b8ab22014-05-06 15:57:45 -0400143
144 bool containsSampler(TType& type);
145 bool areAllChildConst(TIntermAggregate* aggrNode);
Alexis Hetufe1269e2015-06-16 12:43:32 -0400146 const TFunction* findFunction(const TSourceLoc &line, TFunction* pfnCall, bool *builtIn = 0);
Alexis Hetue5246692015-06-18 12:34:52 -0400147 bool executeInitializer(const TSourceLoc &line, const TString &identifier, const TPublicType &pType,
148 TIntermTyped *initializer, TIntermNode **intermNode);
Alexis Hetu42ff6b12015-06-03 16:03:48 -0400149
150 TPublicType addFullySpecifiedType(TQualifier qualifier, bool invariant, TLayoutQualifier layoutQualifier, const TPublicType &typeSpecifier);
Alexis Hetufe1269e2015-06-16 12:43:32 -0400151 bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, const TSourceLoc&);
John Bauman66b8ab22014-05-06 15:57:45 -0400152
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400153 TIntermAggregate *parseSingleDeclaration(TPublicType &publicType, const TSourceLoc &identifierOrTypeLocation, const TString &identifier);
154 TIntermAggregate *parseSingleArrayDeclaration(TPublicType &publicType, const TSourceLoc &identifierLocation, const TString &identifier,
155 const TSourceLoc &indexLocation, TIntermTyped *indexExpression);
156 TIntermAggregate *parseSingleInitDeclaration(const TPublicType &publicType, const TSourceLoc &identifierLocation, const TString &identifier,
157 const TSourceLoc &initLocation, TIntermTyped *initializer);
158
159 // Parse a declaration like "type a[n] = initializer"
160 // Note that this does not apply to declarations like "type[n] a = initializer"
161 TIntermAggregate *parseSingleArrayInitDeclaration(TPublicType &publicType, const TSourceLoc &identifierLocation, const TString &identifier,
162 const TSourceLoc &indexLocation, TIntermTyped *indexExpression,
163 const TSourceLoc &initLocation, TIntermTyped *initializer);
164
165 TIntermAggregate *parseInvariantDeclaration(const TSourceLoc &invariantLoc, const TSourceLoc &identifierLoc, const TString *identifier,
166 const TSymbol *symbol);
167
168 TIntermAggregate *parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, const TSourceLoc &identifierLocation,
169 const TString &identifier);
170 TIntermAggregate *parseArrayDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, const TSourceLoc &identifierLocation,
171 const TString &identifier, const TSourceLoc &arrayLocation, TIntermTyped *indexExpression);
172 TIntermAggregate *parseInitDeclarator(const TPublicType &publicType, TIntermAggregate *aggregateDeclaration, const TSourceLoc &identifierLocation,
173 const TString &identifier, const TSourceLoc &initLocation, TIntermTyped *initializer);
174
175 // Parse a declarator like "a[n] = initializer"
176 TIntermAggregate *parseArrayInitDeclarator(const TPublicType &publicType, TIntermAggregate *aggregateDeclaration, const TSourceLoc &identifierLocation,
177 const TString &identifier, const TSourceLoc &indexLocation, TIntermTyped *indexExpression,
178 const TSourceLoc &initLocation, TIntermTyped *initializer);
179
Alexis Hetua35d8232015-06-11 17:11:06 -0400180 void parseGlobalLayoutQualifier(const TPublicType &typeQualifier);
Alexis Hetue5246692015-06-18 12:34:52 -0400181 TFunction *addConstructorFunc(const TPublicType &publicType);
Alexis Hetufe1269e2015-06-16 12:43:32 -0400182 TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, const TSourceLoc&);
John Bauman66b8ab22014-05-06 15:57:45 -0400183 TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type);
Alexis Hetufe1269e2015-06-16 12:43:32 -0400184 TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, const TSourceLoc&);
185 TIntermTyped* addConstMatrixNode(int, TIntermTyped*, const TSourceLoc&);
186 TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc &line);
187 TIntermTyped* addConstStruct(const TString&, TIntermTyped*, const TSourceLoc&);
Alexis Hetuad6b8752015-06-09 16:15:30 -0400188 TIntermTyped *addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc& location, TIntermTyped *indexExpression);
189 TIntermTyped* addFieldSelectionExpression(TIntermTyped *baseExpression, const TSourceLoc &dotLocation, const TString &fieldString, const TSourceLoc &fieldLocation);
190
191 TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList);
192 TPublicType addStructure(const TSourceLoc &structLine, const TSourceLoc &nameLine, const TString *structName, TFieldList *fieldList);
John Bauman66b8ab22014-05-06 15:57:45 -0400193
Alexis Hetua35d8232015-06-11 17:11:06 -0400194 TIntermAggregate* addInterfaceBlock(const TPublicType& typeQualifier, const TSourceLoc& nameLine, const TString& blockName, TFieldList* fieldList,
195 const TString* instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine);
196
Nicolas Capens7d626792015-02-17 17:58:31 -0500197 TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine);
198 TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine);
199 TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier);
Alexis Hetu55a2cbc2015-04-16 10:49:45 -0400200 TPublicType joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier, const TSourceLoc &storageLoc, TQualifier storageQualifier);
Nicolas Capens7d626792015-02-17 17:58:31 -0500201
John Bauman66b8ab22014-05-06 15:57:45 -0400202 // Performs an error check for embedded struct declarations.
203 // Returns true if an error was raised due to the declaration of
204 // this struct.
Alexis Hetufe1269e2015-06-16 12:43:32 -0400205 bool enterStructDeclaration(const TSourceLoc &line, const TString& identifier);
John Bauman66b8ab22014-05-06 15:57:45 -0400206 void exitStructDeclaration();
207
Alexis Hetuad6b8752015-06-09 16:15:30 -0400208 bool structNestingErrorCheck(const TSourceLoc &line, const TField &field);
209
Alexis Hetu76a343a2015-06-04 17:21:22 -0400210 TIntermSwitch *addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &loc);
211 TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc);
212 TIntermCase *addDefault(const TSourceLoc &loc);
213
Alexis Hetuad6b8752015-06-09 16:15:30 -0400214 TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
215 TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
Alexis Hetub4769582015-06-16 12:19:50 -0400216 TIntermTyped *addBinaryMath(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
217 TIntermTyped *addBinaryMathBooleanResult(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
Alexis Hetuad6b8752015-06-09 16:15:30 -0400218
Alexis Hetue5246692015-06-18 12:34:52 -0400219 TIntermTyped *addAssign(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
220
Alexis Hetu76a343a2015-06-04 17:21:22 -0400221 TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc);
222 TIntermBranch *addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc);
223
Alexis Hetub3ff42c2015-07-03 18:19:57 -0400224 TIntermTyped *addFunctionCallOrMethod(TFunction *fnCall, TIntermNode *paramNode, TIntermNode *thisNode, const TSourceLoc &loc, bool *fatalError);
225
Alexis Hetuad6b8752015-06-09 16:15:30 -0400226private:
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400227 bool declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type, TVariable **variable);
228
Alexis Hetub4769582015-06-16 12:19:50 -0400229 TIntermTyped *addBinaryMathInternal(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
Alexis Hetue5246692015-06-18 12:34:52 -0400230 TIntermTyped *createAssign(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
Alexis Hetub4769582015-06-16 12:19:50 -0400231
Alexis Hetuad6b8752015-06-09 16:15:30 -0400232 // The funcReturnType parameter is expected to be non-null when the operation is a built-in function.
233 // It is expected to be null for other unary operators.
234 TIntermTyped *createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc, const TType *funcReturnType);
235
236 // Return true if the checks pass
237 bool binaryOpCommonCheck(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400238
Alexis Hetu0a655842015-06-22 16:52:11 -0400239 // Set to true when the last/current declarator list was started with an empty declaration.
240 bool mDeferredSingleDeclarationErrorCheck;
241
242 GLenum mShaderType; // vertex or fragment language (future: pack or unpack)
243 int mShaderVersion;
244 TIntermNode *mTreeRoot; // root of parse tree being created
245 int mLoopNestingLevel; // 0 if outside all loops
246 int mSwitchNestingLevel; // 0 if outside all switch statements
247 int mStructNestingLevel; // incremented while parsing a struct declaration
248 const TType *mCurrentFunctionType; // the return type of the function that's currently being parsed
249 bool mFunctionReturnsValue; // true if a non-void function has a return
250 bool mChecksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit.
251
252 TLayoutMatrixPacking mDefaultMatrixPacking;
253 TLayoutBlockStorage mDefaultBlockStorage;
254 TDiagnostics mDiagnostics;
255 TDirectiveHandler mDirectiveHandler;
256 pp::Preprocessor mPreprocessor;
257 void *mScanner;
258 bool mUsesFragData; // track if we are using both gl_FragData and gl_FragColor
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400259 bool mUsesFragColor;
John Bauman66b8ab22014-05-06 15:57:45 -0400260};
261
262int PaParseStrings(int count, const char* const string[], const int length[],
263 TParseContext* context);
264
265#endif // _PARSER_HELPER_INCLUDED_