1d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
3d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// Licensed under the Apache License, Version 2.0 (the "License");
4d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// you may not use this file except in compliance with the License.
5d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// You may obtain a copy of the License at
6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
7d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens//    http://www.apache.org/licenses/LICENSE-2.0
8d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens//
9d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// Unless required by applicable law or agreed to in writing, software
10d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// distributed under the License is distributed on an "AS IS" BASIS,
11d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// See the License for the specific language governing permissions and
13d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// limitations under the License.
14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
156407fe82e29ab16920742bd47b93e14bc5f0e119Nicolas Capens#include "Compiler.h"
16cc863da574ed5079b055574127fe5788a9a0fc33Nicolas Capens#include "intermediate.h"
17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass TInfoSinkBase;
19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstruct TLoopInfo {
21d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	struct TIndex {
22d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		int id;  // symbol id.
23d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	} index;
24d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	TIntermLoop* loop;
25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantypedef TVector<TLoopInfo> TLoopStack;
27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Traverses intermediate tree to ensure that the shader does not exceed the
29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// minimum functionality mandated in GLSL 1.0 spec, Appendix A.
30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass ValidateLimitations : public TIntermTraverser {
31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
32d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	ValidateLimitations(GLenum shaderType, TInfoSinkBase& sink);
33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
34d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	int numErrors() const { return mNumErrors; }
35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
36d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	virtual bool visitBinary(Visit, TIntermBinary*);
37d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	virtual bool visitUnary(Visit, TIntermUnary*);
38d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	virtual bool visitAggregate(Visit, TIntermAggregate*);
39d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	virtual bool visitLoop(Visit, TIntermLoop*);
40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanprivate:
42d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	void error(TSourceLoc loc, const char *reason, const char* token);
43d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
44d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	bool withinLoopBody() const;
45d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	bool isLoopIndex(const TIntermSymbol* symbol) const;
46d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	bool validateLoopType(TIntermLoop* node);
47d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	bool validateForLoopHeader(TIntermLoop* node, TLoopInfo* info);
48d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	bool validateForLoopInit(TIntermLoop* node, TLoopInfo* info);
49d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	bool validateForLoopCond(TIntermLoop* node, TLoopInfo* info);
50d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	bool validateForLoopExpr(TIntermLoop* node, TLoopInfo* info);
51d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	// Returns true if none of the loop indices is used as the argument to
52d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	// the given function out or inout parameter.
53d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	bool validateFunctionCall(TIntermAggregate* node);
54d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	bool validateOperation(TIntermOperator* node, TIntermNode* operand);
55d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
56d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	// Returns true if indexing does not exceed the minimum functionality
57d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	// mandated in GLSL 1.0 spec, Appendix A, Section 5.
58d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	bool isConstExpr(TIntermNode* node);
59d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	bool isConstIndexExpr(TIntermNode* node);
60d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	bool validateIndexing(TIntermBinary* node);
61d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
62d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	GLenum mShaderType;
63d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	TInfoSinkBase& mSink;
64d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	int mNumErrors;
65d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	TLoopStack mLoopStack;
66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
68