1 //
2 // Copyright 2020 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 #ifndef COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_ASTHELPERS_H_
8 #define COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_ASTHELPERS_H_
9 
10 #include <cstring>
11 #include <unordered_map>
12 #include <unordered_set>
13 
14 #include "compiler/translator/TranslatorMetalDirect/IdGen.h"
15 #include "compiler/translator/TranslatorMetalDirect/Name.h"
16 #include "compiler/translator/TranslatorMetalDirect/SymbolEnv.h"
17 
18 namespace sh
19 {
20 
21 // A convenience view of a TIntermDeclaration node's children.
22 struct Declaration
23 {
24     TIntermSymbol &symbol;
25     TIntermTyped *initExpr;  // Non-null iff declaration is initialized.
26 };
27 
28 // Returns a `Declaration` view of the given node.
29 Declaration ViewDeclaration(TIntermDeclaration &declNode);
30 
31 // Creates a variable for a struct type.
32 const TVariable &CreateStructTypeVariable(TSymbolTable &symbolTable, const TStructure &structure);
33 
34 // Creates a variable for a struct instance.
35 const TVariable &CreateInstanceVariable(TSymbolTable &symbolTable,
36                                         const TStructure &structure,
37                                         const Name &name,
38                                         TQualifier qualifier = TQualifier::EvqTemporary,
39                                         const TSpan<const unsigned int> *arraySizes = nullptr);
40 
41 // The input sequence should be discarded from AST after this is called.
42 TIntermSequence &CloneSequenceAndPrepend(const TIntermSequence &seq, TIntermNode &node);
43 
44 // Appends parameters from `src` function to `dest` function.
45 void AddParametersFrom(TFunction &dest, const TFunction &src);
46 
47 // Clones a function.
48 const TFunction &CloneFunction(TSymbolTable &symbolTable, IdGen &idGen, const TFunction &oldFunc);
49 
50 // Clones a function and prepends the provided extr parameter.
51 // If `idGen` is null, the original function must be discarded from the AST.
52 const TFunction &CloneFunctionAndPrependParam(TSymbolTable &symbolTable,
53                                               IdGen *idGen,
54                                               const TFunction &oldFunc,
55                                               const TVariable &newParam);
56 
57 // Clones a function and appends the provided extra parameters.
58 // If `idGen` is null, the original function must be discarded from the AST.
59 const TFunction &CloneFunctionAndAppendParams(TSymbolTable &symbolTable,
60                                               IdGen *idGen,
61                                               const TFunction &oldFunc,
62                                               const std::vector<const TVariable *> &newParam);
63 
64 // Clones a function and changes its return type.
65 // If `idGen` is null, the original function must be discarded from the AST.
66 const TFunction &CloneFunctionAndChangeReturnType(TSymbolTable &symbolTable,
67                                                   IdGen *idGen,
68                                                   const TFunction &oldFunc,
69                                                   const TStructure &newReturn);
70 
71 // Gets the argument of a function call at the given index.
72 TIntermTyped &GetArg(const TIntermAggregate &call, size_t index);
73 
74 // Sets the argument of a function call at the given index.
75 void SetArg(TIntermAggregate &call, size_t index, TIntermTyped &arg);
76 
77 // Returns the field index within the given struct for the given field name.
78 // Returns -1 if the struct has no field with the given name.
79 int GetFieldIndex(const TStructure &structure, const ImmutableString &fieldName);
80 
81 // Accesses a field for the given variable with the given field name.
82 // The variable must be a struct instance.
83 TIntermBinary &AccessField(const TVariable &structInstanceVar, const ImmutableString &fieldName);
84 
85 // Accesses a field for the given node with the given field name.
86 // The node must be a struct instance.
87 TIntermBinary &AccessField(TIntermTyped &object, const ImmutableString &fieldName);
88 
89 // Accesses a field for the given node by its field index.
90 // The node must be a struct instance.
91 TIntermBinary &AccessFieldByIndex(TIntermTyped &object, int index);
92 
93 // Accesses an element by index for the given node.
94 // The node must be an array, vector, or matrix.
95 TIntermBinary &AccessIndex(TIntermTyped &indexableNode, int index);
96 
97 // Accesses an element by index for the given node if `index` is non-null.
98 // Returns the original node if `index` is null.
99 // The node must be an array, vector, or matrix if `index` is non-null.
100 TIntermTyped &AccessIndex(TIntermTyped &node, const int *index);
101 
102 // Returns a subvector based on the input slice range.
103 // This returns the original node if the slice is an identity for the node.
104 TIntermTyped &SubVector(TIntermTyped &vectorNode, int begin, int end);
105 
106 // Matches scalar bool, int, uint, float, double.
107 bool IsScalarBasicType(const TType &type);
108 
109 // Matches vector bool, int, uint, float, double.
110 bool IsVectorBasicType(const TType &type);
111 
112 // Matches bool, int, uint, float, double.
113 // Type does not need to be a scalar.
114 bool HasScalarBasicType(const TType &type);
115 
116 // Matches bool, int, uint, float, double.
117 bool HasScalarBasicType(TBasicType type);
118 
119 // Clones a type.
120 TType &CloneType(const TType &type);
121 
122 // Clones a type and drops all array dimensions.
123 TType &InnermostType(const TType &type);
124 
125 // Creates a vector type by dropping the columns off of a matrix type.
126 TType &DropColumns(const TType &matrixType);
127 
128 // Creates a type by dropping the outer dimension off of an array type.
129 TType &DropOuterDimension(const TType &arrayType);
130 
131 // Creates a scalar or vector type by changing the dimensions of a vector type.
132 TType &SetVectorDim(const TType &type, int newDim);
133 
134 // Creates a matrix type by changing the row dimensions of a matrix type.
135 TType &SetMatrixRowDim(const TType &matrixType, int newDim);
136 
137 // Returns true iff the structure directly contains a field with matrix type.
138 bool HasMatrixField(const TStructure &structure);
139 
140 // Returns true iff the structure directly contains a field with array type.
141 bool HasArrayField(const TStructure &structure);
142 
143 // Coerces `fromNode` to `toType` by a constructor call of `toType` if their types differ.
144 // Vector and matrix dimensions are retained.
145 // Array types are not allowed.
146 TIntermTyped &CoerceSimple(TBasicType toType, TIntermTyped &fromNode);
147 
148 // Coerces `fromNode` to `toType` by a constructor call of `toType` if their types differ.
149 // Vector and matrix dimensions must coincide between to and from.
150 // Array types are not allowed.
151 TIntermTyped &CoerceSimple(const TType &toType, TIntermTyped &fromNode);
152 
153 TIntermTyped &AsType(SymbolEnv &symbolEnv, const TType &toType, TIntermTyped &fromNode);
154 
155 }  // namespace sh
156 
157 #endif  // COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_ASTHELPERS_H_
158