blob: 71cb76caa1fe0fdf7295774a46dddb9ef270bcfd [file] [log] [blame]
Olli Etuahob0c645e2015-05-12 14:25:36 +03001//
2// Copyright (c) 2002-2015 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
7#include "compiler/translator/ValidateGlobalInitializer.h"
8
9#include "compiler/translator/ParseContext.h"
10
11namespace
12{
13
14class ValidateGlobalInitializerTraverser : public TIntermTraverser
15{
16 public:
17 ValidateGlobalInitializerTraverser(const TParseContext *context);
18
19 void visitSymbol(TIntermSymbol *node) override;
20
21 bool isValid() const { return mIsValid; }
22 bool issueWarning() const { return mIssueWarning; }
23
24 private:
25 const TParseContext *mContext;
26 bool mIsValid;
27 bool mIssueWarning;
28};
29
30void ValidateGlobalInitializerTraverser::visitSymbol(TIntermSymbol *node)
31{
32 const TSymbol *sym = mContext->symbolTable.find(node->getSymbol(), mContext->getShaderVersion());
33 if (sym->isVariable())
34 {
35 // ESSL 1.00 section 4.3 (or ESSL 3.00 section 4.3):
36 // Global initializers must be constant expressions.
37 const TVariable *var = static_cast<const TVariable *>(sym);
38 switch (var->getType().getQualifier())
39 {
40 case EvqConst:
41 break;
42 case EvqGlobal:
43 case EvqTemporary:
44 case EvqUniform:
45 // We allow these cases to be compatible with legacy ESSL 1.00 content.
46 // Implement stricter rules for ESSL 3.00 since there's no legacy content to deal with.
47 if (mContext->getShaderVersion() >= 300)
48 {
49 mIsValid = false;
50 }
51 else
52 {
53 mIssueWarning = true;
54 }
55 break;
56 default:
57 mIsValid = false;
58 }
59 }
60}
61
62ValidateGlobalInitializerTraverser::ValidateGlobalInitializerTraverser(const TParseContext *context)
63 : TIntermTraverser(true, false, false),
64 mContext(context),
65 mIsValid(true),
66 mIssueWarning(false)
67{
68}
69
70} // namespace
71
72bool ValidateGlobalInitializer(TIntermTyped *initializer, const TParseContext *context, bool *warning)
73{
74 ValidateGlobalInitializerTraverser validate(context);
75 initializer->traverse(&validate);
76 ASSERT(warning != nullptr);
77 *warning = validate.issueWarning();
78 return validate.isValid();
79}
80