blob: a16ffcdd85d27489a84bc71ed2d0370344227b2f [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);
Olli Etuaho8b5e8fd2017-12-15 14:59:15 +020039 ASSERT(mName == nullptr || *mName != "");
Olli Etuahod4529f32017-12-12 13:06:40 +020040}
41
Olli Etuahobed35d72017-12-20 16:36:26 +020042const TString &TSymbol::name() const
Olli Etuahod4529f32017-12-12 13:06:40 +020043{
Olli Etuahobed35d72017-12-20 16:36:26 +020044 if (mName != nullptr)
Olli Etuahod4529f32017-12-12 13:06:40 +020045 {
Olli Etuahobed35d72017-12-20 16:36:26 +020046 return *mName;
Olli Etuahod4529f32017-12-12 13:06:40 +020047 }
48 ASSERT(mSymbolType == SymbolType::AngleInternal);
49 TInfoSinkBase symbolNameOut;
50 symbolNameOut << "s" << mUniqueId.get();
Olli Etuahobed35d72017-12-20 16:36:26 +020051 return *NewPoolTString(symbolNameOut.c_str());
Olli Etuahod4529f32017-12-12 13:06:40 +020052}
53
54const TString &TSymbol::getMangledName() const
55{
56 ASSERT(mSymbolType != SymbolType::Empty);
Olli Etuahobed35d72017-12-20 16:36:26 +020057 return name();
Olli Etuahod4529f32017-12-12 13:06:40 +020058}
59
60TVariable::TVariable(TSymbolTable *symbolTable,
61 const TString *name,
Olli Etuahob60d30f2018-01-16 12:31:06 +020062 const TType *type,
Olli Etuahod4529f32017-12-12 13:06:40 +020063 SymbolType symbolType,
64 TExtension extension)
Olli Etuahob60d30f2018-01-16 12:31:06 +020065 : TSymbol(symbolTable, name, symbolType, extension), mType(type), unionArray(nullptr)
Olli Etuahod4529f32017-12-12 13:06:40 +020066{
Olli Etuahob60d30f2018-01-16 12:31:06 +020067 ASSERT(mType);
Olli Etuahod4529f32017-12-12 13:06:40 +020068}
69
70TStructure::TStructure(TSymbolTable *symbolTable,
71 const TString *name,
72 const TFieldList *fields,
73 SymbolType symbolType)
74 : TSymbol(symbolTable, name, symbolType), TFieldListCollection(fields)
75{
76}
77
78void TStructure::createSamplerSymbols(const TString &namePrefix,
79 const TString &apiNamePrefix,
Olli Etuahobbd9d4c2017-12-21 12:02:00 +020080 TVector<const TVariable *> *outputSymbols,
81 TMap<const TVariable *, TString> *outputSymbolsToAPINames,
Olli Etuahod4529f32017-12-12 13:06:40 +020082 TSymbolTable *symbolTable) const
83{
84 ASSERT(containsSamplers());
85 for (const auto *field : *mFields)
86 {
87 const TType *fieldType = field->type();
88 if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
89 {
90 TString fieldName = namePrefix + "_" + field->name();
91 TString fieldApiName = apiNamePrefix + "." + field->name();
92 fieldType->createSamplerSymbols(fieldName, fieldApiName, outputSymbols,
93 outputSymbolsToAPINames, symbolTable);
94 }
95 }
96}
97
98void TStructure::setName(const TString &name)
99{
100 TString *mutableName = const_cast<TString *>(mName);
101 *mutableName = name;
102}
103
104TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
105 const TString *name,
106 const TFieldList *fields,
107 const TLayoutQualifier &layoutQualifier,
108 SymbolType symbolType,
109 TExtension extension)
110 : TSymbol(symbolTable, name, symbolType, extension),
111 TFieldListCollection(fields),
112 mBlockStorage(layoutQualifier.blockStorage),
113 mBinding(layoutQualifier.binding)
114{
115 ASSERT(name != nullptr);
116}
117
118TFunction::TFunction(TSymbolTable *symbolTable,
119 const TString *name,
120 const TType *retType,
121 SymbolType symbolType,
Olli Etuaho0c371002017-12-13 17:00:25 +0400122 bool knownToNotHaveSideEffects,
Olli Etuahod4529f32017-12-12 13:06:40 +0200123 TOperator tOp,
124 TExtension extension)
125 : TSymbol(symbolTable, name, symbolType, extension),
126 returnType(retType),
127 mangledName(nullptr),
128 op(tOp),
129 defined(false),
Olli Etuaho0c371002017-12-13 17:00:25 +0400130 mHasPrototypeDeclaration(false),
131 mKnownToNotHaveSideEffects(knownToNotHaveSideEffects)
Olli Etuahod4529f32017-12-12 13:06:40 +0200132{
Olli Etuaho0c371002017-12-13 17:00:25 +0400133 // Functions with an empty name are not allowed.
134 ASSERT(symbolType != SymbolType::Empty);
135 ASSERT(name != nullptr || symbolType == SymbolType::AngleInternal || tOp != EOpNull);
Olli Etuahod4529f32017-12-12 13:06:40 +0200136}
137
138//
139// Functions have buried pointers to delete.
140//
141TFunction::~TFunction()
142{
143 clearParameters();
144}
145
146void TFunction::clearParameters()
147{
148 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
149 delete (*i).type;
150 parameters.clear();
151 mangledName = nullptr;
152}
153
154void TFunction::swapParameters(const TFunction &parametersSource)
155{
156 clearParameters();
157 for (auto parameter : parametersSource.parameters)
158 {
159 addParameter(parameter);
160 }
161}
162
163const TString *TFunction::buildMangledName() const
164{
Olli Etuahobed35d72017-12-20 16:36:26 +0200165 std::string newName = name().c_str();
Olli Etuahod4529f32017-12-12 13:06:40 +0200166 newName += kFunctionMangledNameSeparator;
167
168 for (const auto &p : parameters)
169 {
170 newName += p.type->getMangledName();
171 }
172 return NewPoolTString(newName.c_str());
173}
174
175const TString &TFunction::GetMangledNameFromCall(const TString &functionName,
176 const TIntermSequence &arguments)
177{
178 std::string newName = functionName.c_str();
179 newName += kFunctionMangledNameSeparator;
180
181 for (TIntermNode *argument : arguments)
182 {
183 newName += argument->getAsTyped()->getType().getMangledName();
184 }
185 return *NewPoolTString(newName.c_str());
186}
187
Olli Etuaho1bb85282017-12-14 13:39:53 +0200188bool TFunction::isMain() const
189{
Olli Etuahobed35d72017-12-20 16:36:26 +0200190 return symbolType() == SymbolType::UserDefined && name() == "main";
Olli Etuaho1bb85282017-12-14 13:39:53 +0200191}
192
193bool TFunction::isImageFunction() const
194{
195 return symbolType() == SymbolType::BuiltIn &&
Olli Etuahobed35d72017-12-20 16:36:26 +0200196 (name() == "imageSize" || name() == "imageLoad" || name() == "imageStore");
Olli Etuaho1bb85282017-12-14 13:39:53 +0200197}
198
Olli Etuahod4529f32017-12-12 13:06:40 +0200199} // namespace sh