blob: 1fddbda581c7d3deb84b830953ded5d999cfea66 [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//
27struct TParseContext {
Nicolas Capens08ca3c62015-02-13 16:06:45 -050028 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 -040029 intermediate(interm),
30 symbolTable(symt),
31 shaderType(type),
John Bauman66b8ab22014-05-06 15:57:45 -040032 compileOptions(options),
33 sourcePath(sourcePath),
34 treeRoot(0),
35 lexAfterType(false),
36 loopNestingLevel(0),
Alexis Hetu76a343a2015-06-04 17:21:22 -040037 switchNestingLevel(0),
John Bauman66b8ab22014-05-06 15:57:45 -040038 structNestingLevel(0),
39 inTypeParen(false),
40 currentFunctionType(NULL),
41 functionReturnsValue(false),
42 checksPrecisionErrors(checksPrecErrors),
Alexis Hetuad6b8752015-06-09 16:15:30 -040043 defaultMatrixPacking(EmpColumnMajor),
44 defaultBlockStorage(EbsShared),
John Bauman66b8ab22014-05-06 15:57:45 -040045 diagnostics(is),
Nicolas Capens7d626792015-02-17 17:58:31 -050046 shaderVersion(100),
Nicolas Capensc6841852015-02-15 14:25:37 -050047 directiveHandler(ext, diagnostics, shaderVersion),
John Bauman66b8ab22014-05-06 15:57:45 -040048 preprocessor(&diagnostics, &directiveHandler),
Alexis Hetudd7ff7a2015-06-11 08:25:30 -040049 scanner(NULL),
50 mDeferredSingleDeclarationErrorCheck(false),
51 mUsesFragData(false),
52 mUsesFragColor(false) { }
John Bauman66b8ab22014-05-06 15:57:45 -040053 TIntermediate& intermediate; // to hold and build a parse tree
54 TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed
Nicolas Capens08ca3c62015-02-13 16:06:45 -050055 GLenum shaderType; // vertex or fragment language (future: pack or unpack)
Nicolas Capensc6841852015-02-15 14:25:37 -050056 int shaderVersion;
John Bauman66b8ab22014-05-06 15:57:45 -040057 int compileOptions;
58 const char* sourcePath; // Path of source file or NULL.
59 TIntermNode* treeRoot; // root of parse tree being created
60 bool lexAfterType; // true if we've recognized a type, so can only be looking for an identifier
61 int loopNestingLevel; // 0 if outside all loops
Alexis Hetu76a343a2015-06-04 17:21:22 -040062 int switchNestingLevel; // 0 if outside all switch statements
John Bauman66b8ab22014-05-06 15:57:45 -040063 int structNestingLevel; // incremented while parsing a struct declaration
64 bool inTypeParen; // true if in parentheses, looking only for an identifier
65 const TType* currentFunctionType; // the return type of the function that's currently being parsed
66 bool functionReturnsValue; // true if a non-void function has a return
67 bool checksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit.
Alexis Hetuad6b8752015-06-09 16:15:30 -040068 TLayoutMatrixPacking defaultMatrixPacking;
69 TLayoutBlockStorage defaultBlockStorage;
John Bauman66b8ab22014-05-06 15:57:45 -040070 TString HashErrMsg;
71 bool AfterEOF;
72 TDiagnostics diagnostics;
73 TDirectiveHandler directiveHandler;
74 pp::Preprocessor preprocessor;
75 void* scanner;
76
Nicolas Capensc6841852015-02-15 14:25:37 -050077 int getShaderVersion() const { return shaderVersion; }
John Bauman66b8ab22014-05-06 15:57:45 -040078 int numErrors() const { return diagnostics.numErrors(); }
79 TInfoSink& infoSink() { return diagnostics.infoSink(); }
Alexis Hetufe1269e2015-06-16 12:43:32 -040080 void error(const TSourceLoc &loc, const char *reason, const char* token,
John Bauman66b8ab22014-05-06 15:57:45 -040081 const char* extraInfo="");
Alexis Hetufe1269e2015-06-16 12:43:32 -040082 void warning(const TSourceLoc &loc, const char* reason, const char* token,
John Bauman66b8ab22014-05-06 15:57:45 -040083 const char* extraInfo="");
84 void trace(const char* str);
85 void recover();
86
Alexis Hetu76a343a2015-06-04 17:21:22 -040087 void incrSwitchNestingLevel() { ++switchNestingLevel; }
88 void decrSwitchNestingLevel() { --switchNestingLevel; }
89
Alexis Hetudd7ff7a2015-06-11 08:25:30 -040090 // This method is guaranteed to succeed, even if no variable with 'name' exists.
91 const TVariable *getNamedVariable(const TSourceLoc &location, const TString *name, const TSymbol *symbol);
92
Alexis Hetufe1269e2015-06-16 12:43:32 -040093 bool parseVectorFields(const TString&, int vecSize, TVectorFields&, const TSourceLoc &line);
94 bool parseMatrixFields(const TString&, int matCols, int matRows, TMatrixFields&, const TSourceLoc &line);
John Bauman66b8ab22014-05-06 15:57:45 -040095
Alexis Hetufe1269e2015-06-16 12:43:32 -040096 bool reservedErrorCheck(const TSourceLoc &line, const TString& identifier);
97 void assignError(const TSourceLoc &line, const char* op, TString left, TString right);
98 void unaryOpError(const TSourceLoc &line, const char* op, TString operand);
99 void binaryOpError(const TSourceLoc &line, const char* op, TString left, TString right);
100 bool precisionErrorCheck(const TSourceLoc &line, TPrecision precision, TBasicType type);
101 bool lValueErrorCheck(const TSourceLoc &line, const char* op, TIntermTyped*);
John Bauman66b8ab22014-05-06 15:57:45 -0400102 bool constErrorCheck(TIntermTyped* node);
103 bool integerErrorCheck(TIntermTyped* node, const char* token);
Alexis Hetufe1269e2015-06-16 12:43:32 -0400104 bool globalErrorCheck(const TSourceLoc &line, bool global, const char* token);
105 bool constructorErrorCheck(const TSourceLoc &line, TIntermNode*, TFunction&, TOperator, TType*);
106 bool arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped* expr, int& size);
107 bool arrayQualifierErrorCheck(const TSourceLoc &line, TPublicType type);
108 bool arrayTypeErrorCheck(const TSourceLoc &line, TPublicType type);
109 bool arrayErrorCheck(const TSourceLoc &line, TString& identifier, TPublicType type, TVariable*& variable);
110 bool voidErrorCheck(const TSourceLoc&, const TString&, const TBasicType&);
111 bool boolErrorCheck(const TSourceLoc&, const TIntermTyped*);
112 bool boolErrorCheck(const TSourceLoc&, const TPublicType&);
113 bool samplerErrorCheck(const TSourceLoc &line, const TPublicType& pType, const char* reason);
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400114 bool locationDeclaratorListCheck(const TSourceLoc &line, const TPublicType &pType);
Alexis Hetufe1269e2015-06-16 12:43:32 -0400115 bool structQualifierErrorCheck(const TSourceLoc &line, const TPublicType& pType);
116 bool parameterSamplerErrorCheck(const TSourceLoc &line, TQualifier qualifier, const TType& type);
117 bool nonInitConstErrorCheck(const TSourceLoc &line, TString& identifier, TPublicType& type, bool array);
118 bool nonInitErrorCheck(const TSourceLoc &line, const TString& identifier, TPublicType& type);
119 bool paramErrorCheck(const TSourceLoc &line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
120 bool extensionErrorCheck(const TSourceLoc &line, const TString&);
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400121 bool singleDeclarationErrorCheck(const TPublicType &publicType, const TSourceLoc &identifierLocation);
Alexis Hetuad6b8752015-06-09 16:15:30 -0400122 bool layoutLocationErrorCheck(const TSourceLoc& location, const TLayoutQualifier &layoutQualifier);
123 bool functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *);
John Bauman66b8ab22014-05-06 15:57:45 -0400124
125 const TExtensionBehavior& extensionBehavior() const { return directiveHandler.extensionBehavior(); }
126 bool supportsExtension(const char* extension);
Alexis Hetufe1269e2015-06-16 12:43:32 -0400127 void handleExtensionDirective(const TSourceLoc &line, const char* extName, const char* behavior);
John Bauman66b8ab22014-05-06 15:57:45 -0400128
129 const TPragma& pragma() const { return directiveHandler.pragma(); }
Alexis Hetufe1269e2015-06-16 12:43:32 -0400130 void handlePragmaDirective(const TSourceLoc &line, const char* name, const char* value);
John Bauman66b8ab22014-05-06 15:57:45 -0400131
132 bool containsSampler(TType& type);
133 bool areAllChildConst(TIntermAggregate* aggrNode);
Alexis Hetufe1269e2015-06-16 12:43:32 -0400134 const TFunction* findFunction(const TSourceLoc &line, TFunction* pfnCall, bool *builtIn = 0);
135 bool executeInitializer(const TSourceLoc &line, const TString& identifier, const TPublicType& pType,
John Bauman66b8ab22014-05-06 15:57:45 -0400136 TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
Alexis Hetu42ff6b12015-06-03 16:03:48 -0400137
138 TPublicType addFullySpecifiedType(TQualifier qualifier, bool invariant, TLayoutQualifier layoutQualifier, const TPublicType &typeSpecifier);
Alexis Hetufe1269e2015-06-16 12:43:32 -0400139 bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, const TSourceLoc&);
John Bauman66b8ab22014-05-06 15:57:45 -0400140
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400141 TIntermAggregate *parseSingleDeclaration(TPublicType &publicType, const TSourceLoc &identifierOrTypeLocation, const TString &identifier);
142 TIntermAggregate *parseSingleArrayDeclaration(TPublicType &publicType, const TSourceLoc &identifierLocation, const TString &identifier,
143 const TSourceLoc &indexLocation, TIntermTyped *indexExpression);
144 TIntermAggregate *parseSingleInitDeclaration(const TPublicType &publicType, const TSourceLoc &identifierLocation, const TString &identifier,
145 const TSourceLoc &initLocation, TIntermTyped *initializer);
146
147 // Parse a declaration like "type a[n] = initializer"
148 // Note that this does not apply to declarations like "type[n] a = initializer"
149 TIntermAggregate *parseSingleArrayInitDeclaration(TPublicType &publicType, const TSourceLoc &identifierLocation, const TString &identifier,
150 const TSourceLoc &indexLocation, TIntermTyped *indexExpression,
151 const TSourceLoc &initLocation, TIntermTyped *initializer);
152
153 TIntermAggregate *parseInvariantDeclaration(const TSourceLoc &invariantLoc, const TSourceLoc &identifierLoc, const TString *identifier,
154 const TSymbol *symbol);
155
156 TIntermAggregate *parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, const TSourceLoc &identifierLocation,
157 const TString &identifier);
158 TIntermAggregate *parseArrayDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, const TSourceLoc &identifierLocation,
159 const TString &identifier, const TSourceLoc &arrayLocation, TIntermTyped *indexExpression);
160 TIntermAggregate *parseInitDeclarator(const TPublicType &publicType, TIntermAggregate *aggregateDeclaration, const TSourceLoc &identifierLocation,
161 const TString &identifier, const TSourceLoc &initLocation, TIntermTyped *initializer);
162
163 // Parse a declarator like "a[n] = initializer"
164 TIntermAggregate *parseArrayInitDeclarator(const TPublicType &publicType, TIntermAggregate *aggregateDeclaration, const TSourceLoc &identifierLocation,
165 const TString &identifier, const TSourceLoc &indexLocation, TIntermTyped *indexExpression,
166 const TSourceLoc &initLocation, TIntermTyped *initializer);
167
Alexis Hetua35d8232015-06-11 17:11:06 -0400168 void parseGlobalLayoutQualifier(const TPublicType &typeQualifier);
Alexis Hetufe1269e2015-06-16 12:43:32 -0400169 TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, const TSourceLoc&);
John Bauman66b8ab22014-05-06 15:57:45 -0400170 TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type);
Alexis Hetufe1269e2015-06-16 12:43:32 -0400171 TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, const TSourceLoc&);
172 TIntermTyped* addConstMatrixNode(int, TIntermTyped*, const TSourceLoc&);
173 TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc &line);
174 TIntermTyped* addConstStruct(const TString&, TIntermTyped*, const TSourceLoc&);
Alexis Hetuad6b8752015-06-09 16:15:30 -0400175 TIntermTyped *addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc& location, TIntermTyped *indexExpression);
176 TIntermTyped* addFieldSelectionExpression(TIntermTyped *baseExpression, const TSourceLoc &dotLocation, const TString &fieldString, const TSourceLoc &fieldLocation);
177
178 TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList);
179 TPublicType addStructure(const TSourceLoc &structLine, const TSourceLoc &nameLine, const TString *structName, TFieldList *fieldList);
John Bauman66b8ab22014-05-06 15:57:45 -0400180
Alexis Hetua35d8232015-06-11 17:11:06 -0400181 TIntermAggregate* addInterfaceBlock(const TPublicType& typeQualifier, const TSourceLoc& nameLine, const TString& blockName, TFieldList* fieldList,
182 const TString* instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine);
183
Nicolas Capens7d626792015-02-17 17:58:31 -0500184 TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine);
185 TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine);
186 TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier);
Alexis Hetu55a2cbc2015-04-16 10:49:45 -0400187 TPublicType joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier, const TSourceLoc &storageLoc, TQualifier storageQualifier);
Nicolas Capens7d626792015-02-17 17:58:31 -0500188
John Bauman66b8ab22014-05-06 15:57:45 -0400189 // Performs an error check for embedded struct declarations.
190 // Returns true if an error was raised due to the declaration of
191 // this struct.
Alexis Hetufe1269e2015-06-16 12:43:32 -0400192 bool enterStructDeclaration(const TSourceLoc &line, const TString& identifier);
John Bauman66b8ab22014-05-06 15:57:45 -0400193 void exitStructDeclaration();
194
Alexis Hetuad6b8752015-06-09 16:15:30 -0400195 bool structNestingErrorCheck(const TSourceLoc &line, const TField &field);
196
Alexis Hetu76a343a2015-06-04 17:21:22 -0400197 TIntermSwitch *addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &loc);
198 TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc);
199 TIntermCase *addDefault(const TSourceLoc &loc);
200
Alexis Hetuad6b8752015-06-09 16:15:30 -0400201 TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
202 TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
203
Alexis Hetu76a343a2015-06-04 17:21:22 -0400204 TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc);
205 TIntermBranch *addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc);
206
Alexis Hetuad6b8752015-06-09 16:15:30 -0400207private:
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400208 bool declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type, TVariable **variable);
209
Alexis Hetuad6b8752015-06-09 16:15:30 -0400210 // The funcReturnType parameter is expected to be non-null when the operation is a built-in function.
211 // It is expected to be null for other unary operators.
212 TIntermTyped *createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc, const TType *funcReturnType);
213
214 // Return true if the checks pass
215 bool binaryOpCommonCheck(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400216
217 bool mDeferredSingleDeclarationErrorCheck;
218 bool mUsesFragData; // track if we are using both gl_FragData and gl_FragColor
219 bool mUsesFragColor;
John Bauman66b8ab22014-05-06 15:57:45 -0400220};
221
222int PaParseStrings(int count, const char* const string[], const int length[],
223 TParseContext* context);
224
225#endif // _PARSER_HELPER_INCLUDED_