blob: f6a782bfbb84a2f2b305347e161cb9dd88a2a283 [file] [log] [blame]
Olli Etuahod4529f32017-12-12 13:06:40 +02001//
2// Copyright (c) 2017 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// Symbol.cpp: Symbols representing variables, functions, structures and interface blocks.
7//
8
9#if defined(_MSC_VER)
10#pragma warning(disable : 4718)
11#endif
12
13#include "compiler/translator/Symbol.h"
14
15#include "compiler/translator/SymbolTable.h"
16
17namespace sh
18{
19
20namespace
21{
22
23static const char kFunctionMangledNameSeparator = '(';
24
25} // anonymous namespace
26
27TSymbol::TSymbol(TSymbolTable *symbolTable,
28 const TString *name,
29 SymbolType symbolType,
30 TExtension extension)
31 : mName(name),
32 mUniqueId(symbolTable->nextUniqueId()),
33 mSymbolType(symbolType),
34 mExtension(extension)
35{
36 ASSERT(mSymbolType == SymbolType::BuiltIn || mExtension == TExtension::UNDEFINED);
37 ASSERT(mName != nullptr || mSymbolType == SymbolType::AngleInternal ||
38 mSymbolType == SymbolType::NotResolved || mSymbolType == SymbolType::Empty);
39}
40
41const TString *TSymbol::name() const
42{
43 if (mName != nullptr || mSymbolType == SymbolType::Empty)
44 {
45 return mName;
46 }
47 ASSERT(mSymbolType == SymbolType::AngleInternal);
48 TInfoSinkBase symbolNameOut;
49 symbolNameOut << "s" << mUniqueId.get();
50 return NewPoolTString(symbolNameOut.c_str());
51}
52
53const TString &TSymbol::getMangledName() const
54{
55 ASSERT(mSymbolType != SymbolType::Empty);
56 return *name();
57}
58
59TVariable::TVariable(TSymbolTable *symbolTable,
60 const TString *name,
61 const TType &t,
62 SymbolType symbolType,
63 TExtension extension)
64 : TSymbol(symbolTable, name, symbolType, extension), type(t), unionArray(nullptr)
65{
66}
67
68TStructure::TStructure(TSymbolTable *symbolTable,
69 const TString *name,
70 const TFieldList *fields,
71 SymbolType symbolType)
72 : TSymbol(symbolTable, name, symbolType), TFieldListCollection(fields)
73{
74}
75
76void TStructure::createSamplerSymbols(const TString &namePrefix,
77 const TString &apiNamePrefix,
78 TVector<TIntermSymbol *> *outputSymbols,
79 TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames,
80 TSymbolTable *symbolTable) const
81{
82 ASSERT(containsSamplers());
83 for (const auto *field : *mFields)
84 {
85 const TType *fieldType = field->type();
86 if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
87 {
88 TString fieldName = namePrefix + "_" + field->name();
89 TString fieldApiName = apiNamePrefix + "." + field->name();
90 fieldType->createSamplerSymbols(fieldName, fieldApiName, outputSymbols,
91 outputSymbolsToAPINames, symbolTable);
92 }
93 }
94}
95
96void TStructure::setName(const TString &name)
97{
98 TString *mutableName = const_cast<TString *>(mName);
99 *mutableName = name;
100}
101
102TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
103 const TString *name,
104 const TFieldList *fields,
105 const TLayoutQualifier &layoutQualifier,
106 SymbolType symbolType,
107 TExtension extension)
108 : TSymbol(symbolTable, name, symbolType, extension),
109 TFieldListCollection(fields),
110 mBlockStorage(layoutQualifier.blockStorage),
111 mBinding(layoutQualifier.binding)
112{
113 ASSERT(name != nullptr);
114}
115
116TFunction::TFunction(TSymbolTable *symbolTable,
117 const TString *name,
118 const TType *retType,
119 SymbolType symbolType,
Olli Etuaho0c371002017-12-13 17:00:25 +0400120 bool knownToNotHaveSideEffects,
Olli Etuahod4529f32017-12-12 13:06:40 +0200121 TOperator tOp,
122 TExtension extension)
123 : TSymbol(symbolTable, name, symbolType, extension),
124 returnType(retType),
125 mangledName(nullptr),
126 op(tOp),
127 defined(false),
Olli Etuaho0c371002017-12-13 17:00:25 +0400128 mHasPrototypeDeclaration(false),
129 mKnownToNotHaveSideEffects(knownToNotHaveSideEffects)
Olli Etuahod4529f32017-12-12 13:06:40 +0200130{
Olli Etuaho0c371002017-12-13 17:00:25 +0400131 // Functions with an empty name are not allowed.
132 ASSERT(symbolType != SymbolType::Empty);
133 ASSERT(name != nullptr || symbolType == SymbolType::AngleInternal || tOp != EOpNull);
Olli Etuahod4529f32017-12-12 13:06:40 +0200134}
135
136//
137// Functions have buried pointers to delete.
138//
139TFunction::~TFunction()
140{
141 clearParameters();
142}
143
144void TFunction::clearParameters()
145{
146 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
147 delete (*i).type;
148 parameters.clear();
149 mangledName = nullptr;
150}
151
152void TFunction::swapParameters(const TFunction &parametersSource)
153{
154 clearParameters();
155 for (auto parameter : parametersSource.parameters)
156 {
157 addParameter(parameter);
158 }
159}
160
161const TString *TFunction::buildMangledName() const
162{
163 std::string newName = name()->c_str();
164 newName += kFunctionMangledNameSeparator;
165
166 for (const auto &p : parameters)
167 {
168 newName += p.type->getMangledName();
169 }
170 return NewPoolTString(newName.c_str());
171}
172
173const TString &TFunction::GetMangledNameFromCall(const TString &functionName,
174 const TIntermSequence &arguments)
175{
176 std::string newName = functionName.c_str();
177 newName += kFunctionMangledNameSeparator;
178
179 for (TIntermNode *argument : arguments)
180 {
181 newName += argument->getAsTyped()->getType().getMangledName();
182 }
183 return *NewPoolTString(newName.c_str());
184}
185
186} // namespace sh