glslang: Fix over 100 warnings from MSVC warning level 4.
[platform/upstream/glslang.git] / glslang / MachineIndependent / ParseHelper.h
1 //
2 //Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
3 //Copyright (C) 2012-2013 LunarG, Inc.
4 //
5 //All rights reserved.
6 //
7 //Redistribution and use in source and binary forms, with or without
8 //modification, are permitted provided that the following conditions
9 //are met:
10 //
11 //    Redistributions of source code must retain the above copyright
12 //    notice, this list of conditions and the following disclaimer.
13 //
14 //    Redistributions in binary form must reproduce the above
15 //    copyright notice, this list of conditions and the following
16 //    disclaimer in the documentation and/or other materials provided
17 //    with the distribution.
18 //
19 //    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
20 //    contributors may be used to endorse or promote products derived
21 //    from this software without specific prior written permission.
22 //
23 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 //"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 //FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 //COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 //INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 //CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 //LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 //ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 //POSSIBILITY OF SUCH DAMAGE.
35 //
36 #ifndef _PARSER_HELPER_INCLUDED_
37 #define _PARSER_HELPER_INCLUDED_
38
39 #include "Versions.h"
40 #include "../Include/ShHandle.h"
41 #include "SymbolTable.h"
42 #include "localintermediate.h"
43 #include "Scan.h"
44
45 namespace glslang {
46
47 struct TPragma {
48         TPragma(bool o, bool d) : optimize(o), debug(d) { }
49         bool optimize;
50         bool debug;
51         TPragmaTable pragmaTable;
52 };
53
54 class TScanContext;
55 class TPpContext;
56
57 typedef std::set<int> TIdSetType;
58
59 //
60 // The following are extra variables needed during parsing, grouped together so
61 // they can be passed to the parser without needing a global.
62 //
63 class TParseContext {
64 public:
65     TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, EShLanguage, TInfoSink&,
66                   bool forwardCompatible = false, EShMessages messages = EShMsgDefault);
67     virtual ~TParseContext();
68
69     void setLimits(const TBuiltInResource&);
70     bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false);
71     void parserError(const char* s);     // for bison's yyerror
72     const char* getPreamble();
73
74     void C_DECL error(TSourceLoc, const char* szReason, const char* szToken,
75                       const char* szExtraInfoFormat, ...);
76     void C_DECL  warn(TSourceLoc, const char* szReason, const char* szToken,
77                       const char* szExtraInfoFormat, ...);
78     void reservedErrorCheck(TSourceLoc, const TString&);
79     void reservedPpErrorCheck(TSourceLoc, const char* name, const char* op);
80     bool lineContinuationCheck(TSourceLoc, bool endOfComment);
81     bool builtInName(const TString&);
82
83     void handlePragma(TSourceLoc, const TVector<TString>&);
84     TIntermTyped* handleVariable(TSourceLoc, TSymbol* symbol, TString* string);
85     TIntermTyped* handleBracketDereference(TSourceLoc, TIntermTyped* base, TIntermTyped* index);
86     void checkIndex(TSourceLoc, const TType&, int& index);
87     void handleIndexLimits(TSourceLoc, TIntermTyped* base, TIntermTyped* index);
88
89     void makeEditable(TSymbol*&);
90     bool isIoResizeArray(const TType&) const;
91     void fixIoArraySize(TSourceLoc, TType&);
92     void ioArrayCheck(TSourceLoc, const TType&, const TString& identifier);
93     void handleIoResizeArrayAccess(TSourceLoc, TIntermTyped* base);
94     void checkIoArraysConsistency(TSourceLoc, bool tailOnly = false);
95     int getIoArrayImplicitSize() const;
96     void checkIoArrayConsistency(TSourceLoc, int requiredSize, const char* feature, TType&, const TString&);
97
98     TIntermTyped* handleBinaryMath(TSourceLoc, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);
99     TIntermTyped* handleUnaryMath(TSourceLoc, const char* str, TOperator op, TIntermTyped* childNode);
100     TIntermTyped* handleDotDereference(TSourceLoc, TIntermTyped* base, TString& field);
101     TFunction* handleFunctionDeclarator(TSourceLoc loc, TFunction& function, bool prototype);
102     TIntermAggregate* handleFunctionDefinition(TSourceLoc, TFunction&);
103     TIntermTyped* handleFunctionCall(TSourceLoc, TFunction*, TIntermNode*);
104     void checkLocation(TSourceLoc, TOperator);
105     TIntermTyped* handleLengthMethod(TSourceLoc, TFunction*, TIntermNode*);
106     void addInputArgumentConversions(const TFunction&, TIntermNode*&) const;
107     TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const;
108     void nonOpBuiltInCheck(TSourceLoc, const TFunction&, TIntermAggregate&);
109     TFunction* handleConstructorCall(TSourceLoc, const TPublicType&);
110
111     bool parseVectorFields(TSourceLoc, const TString&, int vecSize, TVectorFields&);
112     void assignError(TSourceLoc, const char* op, TString left, TString right);
113     void unaryOpError(TSourceLoc, const char* op, TString operand);
114     void binaryOpError(TSourceLoc, const char* op, TString left, TString right);
115     void variableCheck(TIntermTyped*& nodePtr);
116     bool lValueErrorCheck(TSourceLoc, const char* op, TIntermTyped*);
117     void rValueErrorCheck(TSourceLoc, const char* op, TIntermTyped*);
118     void constantValueCheck(TIntermTyped* node, const char* token);
119     void integerCheck(const TIntermTyped* node, const char* token);
120     void globalCheck(TSourceLoc, const char* token);
121     bool constructorError(TSourceLoc, TIntermNode*, TFunction&, TOperator, TType&);
122     void arraySizeCheck(TSourceLoc, TIntermTyped* expr, int& size);
123     bool arrayQualifierError(TSourceLoc, const TQualifier&);
124     bool arrayError(TSourceLoc, const TType&);
125     void arraySizeRequiredCheck(TSourceLoc, int size);
126     void structArrayCheck(TSourceLoc, TType* structure);
127     void arrayDimError(TSourceLoc);
128     void arrayDimCheck(TSourceLoc, TArraySizes* sizes1, TArraySizes* sizes2);
129     void arrayDimCheck(TSourceLoc, const TType*, TArraySizes*);
130     bool voidErrorCheck(TSourceLoc, const TString&, TBasicType);
131     void boolCheck(TSourceLoc, const TIntermTyped*);
132     void boolCheck(TSourceLoc, const TPublicType&);
133     void samplerCheck(TSourceLoc, const TType&, const TString& identifier);
134     void atomicUintCheck(TSourceLoc, const TType&, const TString& identifier);
135     void globalQualifierFixCheck(TSourceLoc, TQualifier&);
136     void globalQualifierTypeCheck(TSourceLoc, const TQualifier&, const TPublicType&);
137     bool structQualifierErrorCheck(TSourceLoc, const TPublicType& pType);
138     void mergeQualifiers(TSourceLoc, TQualifier& dst, const TQualifier& src, bool force);
139     void setDefaultPrecision(TSourceLoc, TPublicType&, TPrecisionQualifier);
140     int computeSamplerTypeIndex(TSampler&);
141     TPrecisionQualifier getDefaultPrecision(TPublicType&);
142     void precisionQualifierCheck(TSourceLoc, TBasicType, TQualifier&);
143     void parameterTypeCheck(TSourceLoc, TStorageQualifier qualifier, const TType& type);
144     bool containsFieldWithBasicType(const TType& type ,TBasicType basicType);
145     TSymbol* redeclareBuiltinVariable(TSourceLoc, const TString&, const TQualifier&, const TShaderQualifiers&, bool& newDeclaration);
146     void redeclareBuiltinBlock(TSourceLoc, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes);
147     void paramCheckFix(TSourceLoc, const TStorageQualifier&, TType& type);
148     void paramCheckFix(TSourceLoc, const TQualifier&, TType& type);
149     void nestedBlockCheck(TSourceLoc);
150     void nestedStructCheck(TSourceLoc);
151     void arrayObjectCheck(TSourceLoc, const TType&, const char* op);
152     void opaqueCheck(TSourceLoc, const TType&, const char* op);
153     void structTypeCheck(TSourceLoc, TPublicType&);
154     void inductiveLoopCheck(TSourceLoc, TIntermNode* init, TIntermLoop* loop);
155     void arrayLimitCheck(TSourceLoc, const TString&, int size);
156     void limitCheck(TSourceLoc, int value, const char* limit, const char* feature);
157
158     void inductiveLoopBodyCheck(TIntermNode*, int loopIndexId, TSymbolTable&);
159     void constantIndexExpressionCheck(TIntermNode*);
160
161     void setLayoutQualifier(TSourceLoc, TPublicType&, TString&);
162     void setLayoutQualifier(TSourceLoc, TPublicType&, TString&, const TIntermTyped*);
163     void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly);
164     void layoutObjectCheck(TSourceLoc, const TSymbol&);
165     void layoutTypeCheck(TSourceLoc, const TType&);
166     void layoutQualifierCheck(TSourceLoc, const TQualifier&);
167     void checkNoShaderLayouts(TSourceLoc, const TShaderQualifiers&);
168     void fixOffset(TSourceLoc, TSymbol&);
169
170     const TFunction* findFunction(TSourceLoc loc, const TFunction& call, bool& builtIn);
171     const TFunction* findFunctionExact(TSourceLoc loc, const TFunction& call, bool& builtIn);
172     const TFunction* findFunction120(TSourceLoc loc, const TFunction& call, bool& builtIn);
173     const TFunction* findFunction400(TSourceLoc loc, const TFunction& call, bool& builtIn);
174     void declareTypeDefaults(TSourceLoc, const TPublicType&);
175     TIntermNode* declareVariable(TSourceLoc, TString& identifier, const TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0);
176     TIntermTyped* addConstructor(TSourceLoc, TIntermNode*, const TType&, TOperator);
177     TIntermTyped* constructStruct(TIntermNode*, const TType&, int, TSourceLoc);
178     TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, TSourceLoc, bool subset);
179     void declareBlock(TSourceLoc, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
180     void fixBlockLocations(TSourceLoc, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
181     void fixBlockXfbOffsets(TQualifier&, TTypeList&);
182     void fixBlockUniformOffsets(TQualifier&, TTypeList&);
183     void addQualifierToExisting(TSourceLoc, TQualifier, const TString& identifier);
184     void addQualifierToExisting(TSourceLoc, TQualifier, TIdentifierList&);
185     void invariantCheck(TSourceLoc, const TQualifier&);
186     void updateStandaloneQualifierDefaults(TSourceLoc, const TPublicType&);
187     void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
188     TIntermNode* addSwitch(TSourceLoc, TIntermTyped* expression, TIntermAggregate* body);
189
190     void updateImplicitArraySize(TSourceLoc, TIntermNode*, int index);
191
192     void setScanContext(TScanContext* c) { scanContext = c; }
193     TScanContext* getScanContext() const { return scanContext; }
194     void setPpContext(TPpContext* c) { ppContext = c; }
195     TPpContext* getPpContext() const { return ppContext; }
196     void addError() { ++numErrors; }
197     int getNumErrors() const { return numErrors; }
198     const TSourceLoc& getCurrentLoc() const { return currentScanner->getSourceLoc(); }
199     void setCurrentLine(int line) { currentScanner->setLine(line); }
200     void setCurrentString(int string) { currentScanner->setString(string); }
201
202     // The following are implemented in Versions.cpp to localize version/profile/stage/extensions control
203     void initializeExtensionBehavior();
204     void requireProfile(TSourceLoc, int queryProfiles, const char* featureDesc);
205     void profileRequires(TSourceLoc, int queryProfiles, int minVersion, int numExtensions, const char* const extensions[], const char* featureDesc);
206     void profileRequires(TSourceLoc, int queryProfiles, int minVersion, const char* const extension, const char* featureDesc);
207     void requireStage(TSourceLoc, EShLanguageMask, const char* featureDesc);
208     void requireStage(TSourceLoc, EShLanguage, const char* featureDesc);
209     void checkDeprecated(TSourceLoc, int queryProfiles, int depVersion, const char* featureDesc);
210     void requireNotRemoved(TSourceLoc, int queryProfiles, int removedVersion, const char* featureDesc);
211     void requireExtensions(TSourceLoc, int numExtensions, const char* const extensions[], const char* featureDesc);
212     TExtensionBehavior getExtensionBehavior(const char*);
213     bool extensionsTurnedOn(int numExtensions, const char* const extensions[]);
214     void updateExtensionBehavior(const char* const extension, const char* behavior);
215     void fullIntegerCheck(TSourceLoc, const char* op);
216     void doubleCheck(TSourceLoc, const char* op);
217
218 protected:
219     void nonInitConstCheck(TSourceLoc, TString& identifier, TType& type);
220         void inheritGlobalDefaults(TQualifier& dst) const;
221     TVariable* makeInternalVariable(const char* name, const TType&) const;
222     TVariable* declareNonArray(TSourceLoc, TString& identifier, TType&, bool& newDeclaration);
223     void declareArray(TSourceLoc, TString& identifier, const TType&, TSymbol*&, bool& newDeclaration);
224     TIntermNode* executeInitializer(TSourceLoc, TIntermTyped* initializer, TVariable* variable);
225     TIntermTyped* convertInitializerList(TSourceLoc, const TType&, TIntermTyped* initializer);
226     TOperator mapTypeToConstructorOp(const TType&) const;
227     void finalErrorCheck();
228
229 public:
230     //
231     // Generally, bison productions, the scanner, and the PP need read/write access to these; just give them direct access
232     //
233
234     TIntermediate& intermediate; // helper for making and hooking up pieces of the parse tree
235     TSymbolTable& symbolTable;   // symbol table that goes with the current language, version, and profile
236     TInfoSink& infoSink;
237
238     // compilation mode
239     EShLanguage language;        // vertex or fragment language
240     int version;                 // version, updated by #version in the shader
241     EProfile profile;            // the declared profile in the shader (core by default)
242     bool forwardCompatible;      // true if errors are to be given for use of deprecated features
243     EShMessages messages;        // errors/warnings
244
245     // Current state of parsing
246     struct TPragma contextPragma;
247     int loopNestingLevel;        // 0 if outside all loops
248     int structNestingLevel;      // 0 if outside blocks and structures
249     int controlFlowNestingLevel; // 0 if outside all flow control
250     int statementNestingLevel;   // 0 if outside all flow control or compound statements
251     TList<TIntermSequence*> switchSequenceStack;  // case, node, case, case, node, ...; ensure only one node between cases;   stack of them for nesting
252     TList<int> switchLevel;      // the statementNestingLevel the current switch statement is at, which must match the level of its case statements
253     bool inMain;                 // if inside a function, true if the function is main
254     bool postMainReturn;         // if inside a function, true if the function is main and this is after a return statement
255     const TType* currentFunctionType;  // the return type of the function that's currently being parsed
256     bool functionReturnsValue;   // true if a non-void function has a return
257     const TString* blockName;
258     TQualifier currentBlockQualifier;
259     TIntermAggregate *linkage;   // aggregate node of objects the linker may need, if not referenced by the rest of the AST
260     TPrecisionQualifier defaultPrecision[EbtNumTypes];
261     bool tokensBeforeEOF;
262     TBuiltInResource resources;
263     TLimits& limits;
264
265 protected:
266     TParseContext(TParseContext&);
267     TParseContext& operator=(TParseContext&);
268
269     TScanContext* scanContext;
270     TPpContext* ppContext;
271     TInputScanner* currentScanner;
272     int numErrors;               // number of compile-time errors encountered
273     bool parsingBuiltins;        // true if parsing built-in symbols/functions
274     TMap<TString, TExtensionBehavior> extensionBehavior;    // for each extension string, what its current behavior is set to
275     static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2 * 2)); // see computeSamplerTypeIndex()
276     TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex];
277     bool afterEOF;
278     TQualifier globalBufferDefaults;
279     TQualifier globalUniformDefaults;
280     TQualifier globalInputDefaults;
281     TQualifier globalOutputDefaults;
282     int* atomicUintOffsets;       // to become an array of the right size to hold an offset per binding point
283     TString currentCaller;
284     TIdSetType inductiveLoopIds;
285     bool anyIndexLimits;
286     TVector<TIntermTyped*> needsIndexLimitationChecking;
287
288     //
289     // Geometry shader input arrays:
290     //  - array sizing is based on input primitive and/or explicit size
291     //
292     // Tessellation control output arrays:
293     //  - array sizing is based on output layout(vertices=...) and/or explicit size
294     //
295     // Both:
296     //  - array sizing is retroactive
297     //  - built-in block redeclarations interact with this
298     //
299     // Design:
300     //  - use a per-context "resize-list", a list of symbols whose array sizes
301     //    can be fixed
302     //
303     //  - the resize-list starts empty at beginning of user-shader compilation, it does
304     //    not have built-ins in it
305     //
306     //  - on built-in array use: copyUp() symbol and add it to the resize-list
307     //
308     //  - on user array declaration: add it to the resize-list
309     //
310     //  - on block redeclaration: copyUp() symbol and add it to the resize-list
311     //     * note, that appropriately gives an error if redeclaring a block that
312     //       was already used and hence already copied-up
313     //
314     //  - on seeing a layout declaration that sizes the array, fix everything in the 
315     //    resize-list, giving errors for mismatch
316     //
317     //  - on seeing an array size declaration, give errors on mismatch between it and previous
318     //    array-sizing declarations
319     //
320     TVector<TSymbol*> ioArraySymbolResizeList;
321 };
322
323 } // end namespace glslang
324
325 #endif // _PARSER_HELPER_INCLUDED_