blob: babda8c172daa5cb958049a9bcfa60f96d836963 [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)
Jamie Madillb980c562018-11-27 11:34:27 -050010# pragma warning(disable : 4718)
Olli Etuahod4529f32017-12-12 13:06:40 +020011#endif
12
13#include "compiler/translator/Symbol.h"
14
Olli Etuahofbb1c792018-01-19 16:26:59 +020015#include "compiler/translator/ImmutableStringBuilder.h"
Olli Etuahod4529f32017-12-12 13:06:40 +020016#include "compiler/translator/SymbolTable.h"
17
18namespace sh
19{
20
21namespace
22{
23
Olli Etuahofbb1c792018-01-19 16:26:59 +020024constexpr const ImmutableString kMainName("main");
25constexpr const ImmutableString kImageLoadName("imageLoad");
26constexpr const ImmutableString kImageStoreName("imageStore");
27constexpr const ImmutableString kImageSizeName("imageSize");
Brandon Jones4a22f4b2018-10-23 14:36:47 -070028constexpr const ImmutableString kAtomicCounterName("atomicCounter");
Olli Etuahofbb1c792018-01-19 16:26:59 +020029
Olli Etuahod4529f32017-12-12 13:06:40 +020030static const char kFunctionMangledNameSeparator = '(';
31
32} // anonymous namespace
33
34TSymbol::TSymbol(TSymbolTable *symbolTable,
Olli Etuahofbb1c792018-01-19 16:26:59 +020035 const ImmutableString &name,
Olli Etuahod4529f32017-12-12 13:06:40 +020036 SymbolType symbolType,
Olli Etuaho8073a952018-05-09 16:41:39 +030037 SymbolClass symbolClass,
Olli Etuahod4529f32017-12-12 13:06:40 +020038 TExtension extension)
39 : mName(name),
40 mUniqueId(symbolTable->nextUniqueId()),
41 mSymbolType(symbolType),
Olli Etuaho8073a952018-05-09 16:41:39 +030042 mExtension(extension),
43 mSymbolClass(symbolClass)
Olli Etuahod4529f32017-12-12 13:06:40 +020044{
45 ASSERT(mSymbolType == SymbolType::BuiltIn || mExtension == TExtension::UNDEFINED);
Olli Etuahofbb1c792018-01-19 16:26:59 +020046 ASSERT(mName != "" || mSymbolType == SymbolType::AngleInternal ||
Olli Etuaho95ed1942018-02-01 14:01:19 +020047 mSymbolType == SymbolType::Empty);
Olli Etuahod4529f32017-12-12 13:06:40 +020048}
49
Olli Etuahofbb1c792018-01-19 16:26:59 +020050ImmutableString TSymbol::name() const
Olli Etuahod4529f32017-12-12 13:06:40 +020051{
Olli Etuaho40b1c772018-03-19 10:29:37 +020052 if (!mName.empty())
Olli Etuahod4529f32017-12-12 13:06:40 +020053 {
Olli Etuahofbb1c792018-01-19 16:26:59 +020054 return mName;
Olli Etuahod4529f32017-12-12 13:06:40 +020055 }
Olli Etuaho40b1c772018-03-19 10:29:37 +020056 // This can be called for nameless function parameters in HLSL.
57 ASSERT(mSymbolType == SymbolType::AngleInternal ||
58 (mSymbolType == SymbolType::Empty && isVariable()));
Olli Etuahofbb1c792018-01-19 16:26:59 +020059 int uniqueId = mUniqueId.get();
60 ImmutableStringBuilder symbolNameOut(sizeof(uniqueId) * 2u + 1u);
61 symbolNameOut << 's';
62 symbolNameOut.appendHex(mUniqueId.get());
63 return symbolNameOut;
Olli Etuahod4529f32017-12-12 13:06:40 +020064}
65
Olli Etuahofbb1c792018-01-19 16:26:59 +020066ImmutableString TSymbol::getMangledName() const
Olli Etuahod4529f32017-12-12 13:06:40 +020067{
Olli Etuaho8073a952018-05-09 16:41:39 +030068 if (mSymbolClass == SymbolClass::Function)
69 {
70 // We do this instead of using proper virtual functions so that we can better support
71 // constexpr symbols.
72 return static_cast<const TFunction *>(this)->getFunctionMangledName();
73 }
Olli Etuahod4529f32017-12-12 13:06:40 +020074 ASSERT(mSymbolType != SymbolType::Empty);
Olli Etuahobed35d72017-12-20 16:36:26 +020075 return name();
Olli Etuahod4529f32017-12-12 13:06:40 +020076}
77
78TVariable::TVariable(TSymbolTable *symbolTable,
Olli Etuahofbb1c792018-01-19 16:26:59 +020079 const ImmutableString &name,
Olli Etuahob60d30f2018-01-16 12:31:06 +020080 const TType *type,
Olli Etuahod4529f32017-12-12 13:06:40 +020081 SymbolType symbolType,
82 TExtension extension)
Olli Etuaho8073a952018-05-09 16:41:39 +030083 : TSymbol(symbolTable, name, symbolType, SymbolClass::Variable, extension),
84 mType(type),
85 unionArray(nullptr)
Olli Etuahod4529f32017-12-12 13:06:40 +020086{
Olli Etuahob60d30f2018-01-16 12:31:06 +020087 ASSERT(mType);
Jamie Madille0339992018-06-20 11:46:40 -040088 ASSERT(name.empty() || symbolType != SymbolType::Empty);
Olli Etuahod4529f32017-12-12 13:06:40 +020089}
90
91TStructure::TStructure(TSymbolTable *symbolTable,
Olli Etuahofbb1c792018-01-19 16:26:59 +020092 const ImmutableString &name,
Olli Etuahod4529f32017-12-12 13:06:40 +020093 const TFieldList *fields,
94 SymbolType symbolType)
Olli Etuaho8073a952018-05-09 16:41:39 +030095 : TSymbol(symbolTable, name, symbolType, SymbolClass::Struct), TFieldListCollection(fields)
Jamie Madillb980c562018-11-27 11:34:27 -050096{}
Olli Etuahod4529f32017-12-12 13:06:40 +020097
Olli Etuaho391bda22018-02-23 11:43:14 +020098TStructure::TStructure(const TSymbolUniqueId &id,
99 const ImmutableString &name,
100 TExtension extension,
101 const TFieldList *fields)
Olli Etuaho8073a952018-05-09 16:41:39 +0300102 : TSymbol(id, name, SymbolType::BuiltIn, extension, SymbolClass::Struct),
103 TFieldListCollection(fields)
Jamie Madillb980c562018-11-27 11:34:27 -0500104{}
Olli Etuaho391bda22018-02-23 11:43:14 +0200105
Olli Etuahofbb1c792018-01-19 16:26:59 +0200106void TStructure::createSamplerSymbols(const char *namePrefix,
Olli Etuahod4529f32017-12-12 13:06:40 +0200107 const TString &apiNamePrefix,
Olli Etuahobbd9d4c2017-12-21 12:02:00 +0200108 TVector<const TVariable *> *outputSymbols,
109 TMap<const TVariable *, TString> *outputSymbolsToAPINames,
Olli Etuahod4529f32017-12-12 13:06:40 +0200110 TSymbolTable *symbolTable) const
111{
112 ASSERT(containsSamplers());
113 for (const auto *field : *mFields)
114 {
115 const TType *fieldType = field->type();
116 if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
117 {
Jonah Ryan-Davis1d35d512019-02-15 15:39:27 +0000118 std::stringstream fieldName;
Olli Etuahofbb1c792018-01-19 16:26:59 +0200119 fieldName << namePrefix << "_" << field->name();
120 TString fieldApiName = apiNamePrefix + ".";
121 fieldApiName += field->name().data();
122 fieldType->createSamplerSymbols(ImmutableString(fieldName.str()), fieldApiName,
123 outputSymbols, outputSymbolsToAPINames, symbolTable);
Olli Etuahod4529f32017-12-12 13:06:40 +0200124 }
125 }
126}
127
Olli Etuahofbb1c792018-01-19 16:26:59 +0200128void TStructure::setName(const ImmutableString &name)
Olli Etuahod4529f32017-12-12 13:06:40 +0200129{
Olli Etuahofbb1c792018-01-19 16:26:59 +0200130 ImmutableString *mutableName = const_cast<ImmutableString *>(&mName);
Jamie Madillb980c562018-11-27 11:34:27 -0500131 *mutableName = name;
Olli Etuahod4529f32017-12-12 13:06:40 +0200132}
133
134TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
Olli Etuahofbb1c792018-01-19 16:26:59 +0200135 const ImmutableString &name,
Olli Etuahod4529f32017-12-12 13:06:40 +0200136 const TFieldList *fields,
137 const TLayoutQualifier &layoutQualifier,
138 SymbolType symbolType,
139 TExtension extension)
Olli Etuaho8073a952018-05-09 16:41:39 +0300140 : TSymbol(symbolTable, name, symbolType, SymbolClass::InterfaceBlock, extension),
Olli Etuahod4529f32017-12-12 13:06:40 +0200141 TFieldListCollection(fields),
142 mBlockStorage(layoutQualifier.blockStorage),
143 mBinding(layoutQualifier.binding)
144{
145 ASSERT(name != nullptr);
146}
147
Olli Etuaho391bda22018-02-23 11:43:14 +0200148TInterfaceBlock::TInterfaceBlock(const TSymbolUniqueId &id,
149 const ImmutableString &name,
150 TExtension extension,
151 const TFieldList *fields)
Olli Etuaho8073a952018-05-09 16:41:39 +0300152 : TSymbol(id, name, SymbolType::BuiltIn, extension, SymbolClass::InterfaceBlock),
Olli Etuaho391bda22018-02-23 11:43:14 +0200153 TFieldListCollection(fields),
154 mBlockStorage(EbsUnspecified),
155 mBinding(0)
Jamie Madillb980c562018-11-27 11:34:27 -0500156{}
Olli Etuaho391bda22018-02-23 11:43:14 +0200157
Olli Etuahod4529f32017-12-12 13:06:40 +0200158TFunction::TFunction(TSymbolTable *symbolTable,
Olli Etuahofbb1c792018-01-19 16:26:59 +0200159 const ImmutableString &name,
Olli Etuahod4529f32017-12-12 13:06:40 +0200160 SymbolType symbolType,
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200161 const TType *retType,
162 bool knownToNotHaveSideEffects)
Olli Etuaho8073a952018-05-09 16:41:39 +0300163 : TSymbol(symbolTable, name, symbolType, SymbolClass::Function, TExtension::UNDEFINED),
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200164 mParametersVector(new TParamVector()),
165 mParameters(nullptr),
166 mParamCount(0u),
Olli Etuahod4529f32017-12-12 13:06:40 +0200167 returnType(retType),
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200168 mMangledName(""),
169 mOp(EOpNull),
Olli Etuahod4529f32017-12-12 13:06:40 +0200170 defined(false),
Olli Etuaho0c371002017-12-13 17:00:25 +0400171 mHasPrototypeDeclaration(false),
172 mKnownToNotHaveSideEffects(knownToNotHaveSideEffects)
Olli Etuahod4529f32017-12-12 13:06:40 +0200173{
Olli Etuaho0c371002017-12-13 17:00:25 +0400174 // Functions with an empty name are not allowed.
175 ASSERT(symbolType != SymbolType::Empty);
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200176 ASSERT(name != nullptr || symbolType == SymbolType::AngleInternal);
Olli Etuahod4529f32017-12-12 13:06:40 +0200177}
178
Olli Etuahod4bd9632018-03-08 16:32:44 +0200179void TFunction::addParameter(const TVariable *p)
Olli Etuahod4529f32017-12-12 13:06:40 +0200180{
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200181 ASSERT(mParametersVector);
182 mParametersVector->push_back(p);
183 mParameters = mParametersVector->data();
184 mParamCount = mParametersVector->size();
Jamie Madillb779b122018-06-20 11:46:43 -0400185 mMangledName = kEmptyImmutableString;
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200186}
187
188void TFunction::shareParameters(const TFunction &parametersSource)
189{
190 mParametersVector = nullptr;
191 mParameters = parametersSource.mParameters;
192 mParamCount = parametersSource.mParamCount;
193 ASSERT(parametersSource.name() == name());
194 mMangledName = parametersSource.mMangledName;
Olli Etuahod4529f32017-12-12 13:06:40 +0200195}
196
Olli Etuahofbb1c792018-01-19 16:26:59 +0200197ImmutableString TFunction::buildMangledName() const
Olli Etuahod4529f32017-12-12 13:06:40 +0200198{
Olli Etuahofbb1c792018-01-19 16:26:59 +0200199 std::string newName(name().data(), name().length());
Olli Etuahod4529f32017-12-12 13:06:40 +0200200 newName += kFunctionMangledNameSeparator;
201
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200202 for (size_t i = 0u; i < mParamCount; ++i)
Olli Etuahod4529f32017-12-12 13:06:40 +0200203 {
Olli Etuahod4bd9632018-03-08 16:32:44 +0200204 newName += mParameters[i]->getType().getMangledName();
Olli Etuahod4529f32017-12-12 13:06:40 +0200205 }
Olli Etuahofbb1c792018-01-19 16:26:59 +0200206 return ImmutableString(newName);
Olli Etuahod4529f32017-12-12 13:06:40 +0200207}
208
Olli Etuaho1bb85282017-12-14 13:39:53 +0200209bool TFunction::isMain() const
210{
Olli Etuahofbb1c792018-01-19 16:26:59 +0200211 return symbolType() == SymbolType::UserDefined && name() == kMainName;
Olli Etuaho1bb85282017-12-14 13:39:53 +0200212}
213
214bool TFunction::isImageFunction() const
215{
216 return symbolType() == SymbolType::BuiltIn &&
Olli Etuahofbb1c792018-01-19 16:26:59 +0200217 (name() == kImageSizeName || name() == kImageLoadName || name() == kImageStoreName);
Olli Etuaho1bb85282017-12-14 13:39:53 +0200218}
219
Brandon Jones4a22f4b2018-10-23 14:36:47 -0700220bool TFunction::isAtomicCounterFunction() const
221{
222 return SymbolType() == SymbolType::BuiltIn && name().beginsWith(kAtomicCounterName);
223}
224
Jamie Madill84c11c52018-07-11 10:12:39 -0400225bool TFunction::hasSamplerInStructParams() const
226{
227 for (size_t paramIndex = 0; paramIndex < mParamCount; ++paramIndex)
228 {
229 const TVariable *param = getParam(paramIndex);
230 if (param->getType().isStructureContainingSamplers())
231 {
232 return true;
233 }
234 }
235
236 return false;
237}
Olli Etuahod4529f32017-12-12 13:06:40 +0200238} // namespace sh