blob: cac1647c2730fafb6be86c5e63a823d059bffc96 [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),
37 structNestingLevel(0),
38 inTypeParen(false),
39 currentFunctionType(NULL),
40 functionReturnsValue(false),
41 checksPrecisionErrors(checksPrecErrors),
Alexis Hetuad6b8752015-06-09 16:15:30 -040042 defaultMatrixPacking(EmpColumnMajor),
43 defaultBlockStorage(EbsShared),
John Bauman66b8ab22014-05-06 15:57:45 -040044 diagnostics(is),
Nicolas Capens7d626792015-02-17 17:58:31 -050045 shaderVersion(100),
Nicolas Capensc6841852015-02-15 14:25:37 -050046 directiveHandler(ext, diagnostics, shaderVersion),
John Bauman66b8ab22014-05-06 15:57:45 -040047 preprocessor(&diagnostics, &directiveHandler),
Alexis Hetudd7ff7a2015-06-11 08:25:30 -040048 scanner(NULL),
49 mDeferredSingleDeclarationErrorCheck(false),
50 mUsesFragData(false),
51 mUsesFragColor(false) { }
John Bauman66b8ab22014-05-06 15:57:45 -040052 TIntermediate& intermediate; // to hold and build a parse tree
53 TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed
Nicolas Capens08ca3c62015-02-13 16:06:45 -050054 GLenum shaderType; // vertex or fragment language (future: pack or unpack)
Nicolas Capensc6841852015-02-15 14:25:37 -050055 int shaderVersion;
John Bauman66b8ab22014-05-06 15:57:45 -040056 int compileOptions;
57 const char* sourcePath; // Path of source file or NULL.
58 TIntermNode* treeRoot; // root of parse tree being created
59 bool lexAfterType; // true if we've recognized a type, so can only be looking for an identifier
60 int loopNestingLevel; // 0 if outside all loops
61 int structNestingLevel; // incremented while parsing a struct declaration
62 bool inTypeParen; // true if in parentheses, looking only for an identifier
63 const TType* currentFunctionType; // the return type of the function that's currently being parsed
64 bool functionReturnsValue; // true if a non-void function has a return
65 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 -040066 TLayoutMatrixPacking defaultMatrixPacking;
67 TLayoutBlockStorage defaultBlockStorage;
John Bauman66b8ab22014-05-06 15:57:45 -040068 TString HashErrMsg;
69 bool AfterEOF;
70 TDiagnostics diagnostics;
71 TDirectiveHandler directiveHandler;
72 pp::Preprocessor preprocessor;
73 void* scanner;
74
Nicolas Capensc6841852015-02-15 14:25:37 -050075 int getShaderVersion() const { return shaderVersion; }
John Bauman66b8ab22014-05-06 15:57:45 -040076 int numErrors() const { return diagnostics.numErrors(); }
77 TInfoSink& infoSink() { return diagnostics.infoSink(); }
78 void error(TSourceLoc loc, const char *reason, const char* token,
79 const char* extraInfo="");
80 void warning(TSourceLoc loc, const char* reason, const char* token,
81 const char* extraInfo="");
82 void trace(const char* str);
83 void recover();
84
Alexis Hetudd7ff7a2015-06-11 08:25:30 -040085 // This method is guaranteed to succeed, even if no variable with 'name' exists.
86 const TVariable *getNamedVariable(const TSourceLoc &location, const TString *name, const TSymbol *symbol);
87
John Bauman66b8ab22014-05-06 15:57:45 -040088 bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line);
Alexis Hetu00106d42015-04-23 11:45:35 -040089 bool parseMatrixFields(const TString&, int matCols, int matRows, TMatrixFields&, int line);
John Bauman66b8ab22014-05-06 15:57:45 -040090
91 bool reservedErrorCheck(int line, const TString& identifier);
92 void assignError(int line, const char* op, TString left, TString right);
93 void unaryOpError(int line, const char* op, TString operand);
94 void binaryOpError(int line, const char* op, TString left, TString right);
95 bool precisionErrorCheck(int line, TPrecision precision, TBasicType type);
96 bool lValueErrorCheck(int line, const char* op, TIntermTyped*);
97 bool constErrorCheck(TIntermTyped* node);
98 bool integerErrorCheck(TIntermTyped* node, const char* token);
99 bool globalErrorCheck(int line, bool global, const char* token);
100 bool constructorErrorCheck(int line, TIntermNode*, TFunction&, TOperator, TType*);
101 bool arraySizeErrorCheck(int line, TIntermTyped* expr, int& size);
102 bool arrayQualifierErrorCheck(int line, TPublicType type);
103 bool arrayTypeErrorCheck(int line, TPublicType type);
104 bool arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable);
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400105 bool voidErrorCheck(int, const TString&, const TBasicType&);
John Bauman66b8ab22014-05-06 15:57:45 -0400106 bool boolErrorCheck(int, const TIntermTyped*);
107 bool boolErrorCheck(int, const TPublicType&);
108 bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason);
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400109 bool locationDeclaratorListCheck(const TSourceLoc &line, const TPublicType &pType);
John Bauman66b8ab22014-05-06 15:57:45 -0400110 bool structQualifierErrorCheck(int line, const TPublicType& pType);
111 bool parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type);
112 bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type, bool array);
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400113 bool nonInitErrorCheck(int line, const TString& identifier, TPublicType& type);
John Bauman66b8ab22014-05-06 15:57:45 -0400114 bool paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
115 bool extensionErrorCheck(int line, const TString&);
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400116 bool singleDeclarationErrorCheck(const TPublicType &publicType, const TSourceLoc &identifierLocation);
Alexis Hetuad6b8752015-06-09 16:15:30 -0400117 bool layoutLocationErrorCheck(const TSourceLoc& location, const TLayoutQualifier &layoutQualifier);
118 bool functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *);
John Bauman66b8ab22014-05-06 15:57:45 -0400119
120 const TExtensionBehavior& extensionBehavior() const { return directiveHandler.extensionBehavior(); }
121 bool supportsExtension(const char* extension);
122 void handleExtensionDirective(int line, const char* extName, const char* behavior);
123
124 const TPragma& pragma() const { return directiveHandler.pragma(); }
125 void handlePragmaDirective(int line, const char* name, const char* value);
126
127 bool containsSampler(TType& type);
128 bool areAllChildConst(TIntermAggregate* aggrNode);
129 const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0);
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400130 bool executeInitializer(TSourceLoc line, const TString& identifier, const TPublicType& pType,
John Bauman66b8ab22014-05-06 15:57:45 -0400131 TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
Alexis Hetu42ff6b12015-06-03 16:03:48 -0400132
133 TPublicType addFullySpecifiedType(TQualifier qualifier, bool invariant, TLayoutQualifier layoutQualifier, const TPublicType &typeSpecifier);
John Bauman66b8ab22014-05-06 15:57:45 -0400134 bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, TSourceLoc);
135
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400136 TIntermAggregate *parseSingleDeclaration(TPublicType &publicType, const TSourceLoc &identifierOrTypeLocation, const TString &identifier);
137 TIntermAggregate *parseSingleArrayDeclaration(TPublicType &publicType, const TSourceLoc &identifierLocation, const TString &identifier,
138 const TSourceLoc &indexLocation, TIntermTyped *indexExpression);
139 TIntermAggregate *parseSingleInitDeclaration(const TPublicType &publicType, const TSourceLoc &identifierLocation, const TString &identifier,
140 const TSourceLoc &initLocation, TIntermTyped *initializer);
141
142 // Parse a declaration like "type a[n] = initializer"
143 // Note that this does not apply to declarations like "type[n] a = initializer"
144 TIntermAggregate *parseSingleArrayInitDeclaration(TPublicType &publicType, const TSourceLoc &identifierLocation, const TString &identifier,
145 const TSourceLoc &indexLocation, TIntermTyped *indexExpression,
146 const TSourceLoc &initLocation, TIntermTyped *initializer);
147
148 TIntermAggregate *parseInvariantDeclaration(const TSourceLoc &invariantLoc, const TSourceLoc &identifierLoc, const TString *identifier,
149 const TSymbol *symbol);
150
151 TIntermAggregate *parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, const TSourceLoc &identifierLocation,
152 const TString &identifier);
153 TIntermAggregate *parseArrayDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, const TSourceLoc &identifierLocation,
154 const TString &identifier, const TSourceLoc &arrayLocation, TIntermTyped *indexExpression);
155 TIntermAggregate *parseInitDeclarator(const TPublicType &publicType, TIntermAggregate *aggregateDeclaration, const TSourceLoc &identifierLocation,
156 const TString &identifier, const TSourceLoc &initLocation, TIntermTyped *initializer);
157
158 // Parse a declarator like "a[n] = initializer"
159 TIntermAggregate *parseArrayInitDeclarator(const TPublicType &publicType, TIntermAggregate *aggregateDeclaration, const TSourceLoc &identifierLocation,
160 const TString &identifier, const TSourceLoc &indexLocation, TIntermTyped *indexExpression,
161 const TSourceLoc &initLocation, TIntermTyped *initializer);
162
John Bauman66b8ab22014-05-06 15:57:45 -0400163 TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, TSourceLoc);
164 TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type);
John Bauman66b8ab22014-05-06 15:57:45 -0400165 TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc);
166 TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc);
167 TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line);
Alexis Hetuad6b8752015-06-09 16:15:30 -0400168 TIntermTyped* addConstStruct(const TString& , TIntermTyped*, TSourceLoc);
169 TIntermTyped *addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc& location, TIntermTyped *indexExpression);
170 TIntermTyped* addFieldSelectionExpression(TIntermTyped *baseExpression, const TSourceLoc &dotLocation, const TString &fieldString, const TSourceLoc &fieldLocation);
171
172 TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList);
173 TPublicType addStructure(const TSourceLoc &structLine, const TSourceLoc &nameLine, const TString *structName, TFieldList *fieldList);
John Bauman66b8ab22014-05-06 15:57:45 -0400174
Nicolas Capens7d626792015-02-17 17:58:31 -0500175 TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine);
176 TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine);
177 TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier);
Alexis Hetu55a2cbc2015-04-16 10:49:45 -0400178 TPublicType joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier, const TSourceLoc &storageLoc, TQualifier storageQualifier);
Nicolas Capens7d626792015-02-17 17:58:31 -0500179
John Bauman66b8ab22014-05-06 15:57:45 -0400180 // Performs an error check for embedded struct declarations.
181 // Returns true if an error was raised due to the declaration of
182 // this struct.
183 bool enterStructDeclaration(TSourceLoc line, const TString& identifier);
184 void exitStructDeclaration();
185
Alexis Hetuad6b8752015-06-09 16:15:30 -0400186 bool structNestingErrorCheck(const TSourceLoc &line, const TField &field);
187
188 TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
189 TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
190
191private:
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400192 bool declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type, TVariable **variable);
193
Alexis Hetuad6b8752015-06-09 16:15:30 -0400194 // The funcReturnType parameter is expected to be non-null when the operation is a built-in function.
195 // It is expected to be null for other unary operators.
196 TIntermTyped *createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc, const TType *funcReturnType);
197
198 // Return true if the checks pass
199 bool binaryOpCommonCheck(TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
Alexis Hetudd7ff7a2015-06-11 08:25:30 -0400200
201 bool mDeferredSingleDeclarationErrorCheck;
202 bool mUsesFragData; // track if we are using both gl_FragData and gl_FragColor
203 bool mUsesFragColor;
John Bauman66b8ab22014-05-06 15:57:45 -0400204};
205
206int PaParseStrings(int count, const char* const string[], const int length[],
207 TParseContext* context);
208
209#endif // _PARSER_HELPER_INCLUDED_