blob: 12d0ef3c2cb1543d13e4019aa0d7699f9b6e8961 [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
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");
28
Olli Etuahod4529f32017-12-12 13:06:40 +020029static const char kFunctionMangledNameSeparator = '(';
30
31} // anonymous namespace
32
33TSymbol::TSymbol(TSymbolTable *symbolTable,
Olli Etuahofbb1c792018-01-19 16:26:59 +020034 const ImmutableString &name,
Olli Etuahod4529f32017-12-12 13:06:40 +020035 SymbolType symbolType,
Olli Etuaho8073a952018-05-09 16:41:39 +030036 SymbolClass symbolClass,
Olli Etuahod4529f32017-12-12 13:06:40 +020037 TExtension extension)
38 : mName(name),
39 mUniqueId(symbolTable->nextUniqueId()),
40 mSymbolType(symbolType),
Olli Etuaho8073a952018-05-09 16:41:39 +030041 mExtension(extension),
42 mSymbolClass(symbolClass)
Olli Etuahod4529f32017-12-12 13:06:40 +020043{
44 ASSERT(mSymbolType == SymbolType::BuiltIn || mExtension == TExtension::UNDEFINED);
Olli Etuahofbb1c792018-01-19 16:26:59 +020045 ASSERT(mName != "" || mSymbolType == SymbolType::AngleInternal ||
Olli Etuaho95ed1942018-02-01 14:01:19 +020046 mSymbolType == SymbolType::Empty);
Olli Etuahod4529f32017-12-12 13:06:40 +020047}
48
Olli Etuahofbb1c792018-01-19 16:26:59 +020049ImmutableString TSymbol::name() const
Olli Etuahod4529f32017-12-12 13:06:40 +020050{
Olli Etuaho40b1c772018-03-19 10:29:37 +020051 if (!mName.empty())
Olli Etuahod4529f32017-12-12 13:06:40 +020052 {
Olli Etuahofbb1c792018-01-19 16:26:59 +020053 return mName;
Olli Etuahod4529f32017-12-12 13:06:40 +020054 }
Olli Etuaho40b1c772018-03-19 10:29:37 +020055 // This can be called for nameless function parameters in HLSL.
56 ASSERT(mSymbolType == SymbolType::AngleInternal ||
57 (mSymbolType == SymbolType::Empty && isVariable()));
Olli Etuahofbb1c792018-01-19 16:26:59 +020058 int uniqueId = mUniqueId.get();
59 ImmutableStringBuilder symbolNameOut(sizeof(uniqueId) * 2u + 1u);
60 symbolNameOut << 's';
61 symbolNameOut.appendHex(mUniqueId.get());
62 return symbolNameOut;
Olli Etuahod4529f32017-12-12 13:06:40 +020063}
64
Olli Etuahofbb1c792018-01-19 16:26:59 +020065ImmutableString TSymbol::getMangledName() const
Olli Etuahod4529f32017-12-12 13:06:40 +020066{
Olli Etuaho8073a952018-05-09 16:41:39 +030067 if (mSymbolClass == SymbolClass::Function)
68 {
69 // We do this instead of using proper virtual functions so that we can better support
70 // constexpr symbols.
71 return static_cast<const TFunction *>(this)->getFunctionMangledName();
72 }
Olli Etuahod4529f32017-12-12 13:06:40 +020073 ASSERT(mSymbolType != SymbolType::Empty);
Olli Etuahobed35d72017-12-20 16:36:26 +020074 return name();
Olli Etuahod4529f32017-12-12 13:06:40 +020075}
76
77TVariable::TVariable(TSymbolTable *symbolTable,
Olli Etuahofbb1c792018-01-19 16:26:59 +020078 const ImmutableString &name,
Olli Etuahob60d30f2018-01-16 12:31:06 +020079 const TType *type,
Olli Etuahod4529f32017-12-12 13:06:40 +020080 SymbolType symbolType,
81 TExtension extension)
Olli Etuaho8073a952018-05-09 16:41:39 +030082 : TSymbol(symbolTable, name, symbolType, SymbolClass::Variable, extension),
83 mType(type),
84 unionArray(nullptr)
Olli Etuahod4529f32017-12-12 13:06:40 +020085{
Olli Etuahob60d30f2018-01-16 12:31:06 +020086 ASSERT(mType);
Jamie Madille0339992018-06-20 11:46:40 -040087 ASSERT(name.empty() || symbolType != SymbolType::Empty);
Olli Etuahod4529f32017-12-12 13:06:40 +020088}
89
90TStructure::TStructure(TSymbolTable *symbolTable,
Olli Etuahofbb1c792018-01-19 16:26:59 +020091 const ImmutableString &name,
Olli Etuahod4529f32017-12-12 13:06:40 +020092 const TFieldList *fields,
93 SymbolType symbolType)
Olli Etuaho8073a952018-05-09 16:41:39 +030094 : TSymbol(symbolTable, name, symbolType, SymbolClass::Struct), TFieldListCollection(fields)
Olli Etuahod4529f32017-12-12 13:06:40 +020095{
96}
97
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)
Olli Etuaho391bda22018-02-23 11:43:14 +0200104{
105}
106
Olli Etuahofbb1c792018-01-19 16:26:59 +0200107void TStructure::createSamplerSymbols(const char *namePrefix,
Olli Etuahod4529f32017-12-12 13:06:40 +0200108 const TString &apiNamePrefix,
Olli Etuahobbd9d4c2017-12-21 12:02:00 +0200109 TVector<const TVariable *> *outputSymbols,
110 TMap<const TVariable *, TString> *outputSymbolsToAPINames,
Olli Etuahod4529f32017-12-12 13:06:40 +0200111 TSymbolTable *symbolTable) const
112{
113 ASSERT(containsSamplers());
114 for (const auto *field : *mFields)
115 {
116 const TType *fieldType = field->type();
117 if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
118 {
Olli Etuahofbb1c792018-01-19 16:26:59 +0200119 std::stringstream fieldName;
120 fieldName << namePrefix << "_" << field->name();
121 TString fieldApiName = apiNamePrefix + ".";
122 fieldApiName += field->name().data();
123 fieldType->createSamplerSymbols(ImmutableString(fieldName.str()), fieldApiName,
124 outputSymbols, outputSymbolsToAPINames, symbolTable);
Olli Etuahod4529f32017-12-12 13:06:40 +0200125 }
126 }
127}
128
Olli Etuahofbb1c792018-01-19 16:26:59 +0200129void TStructure::setName(const ImmutableString &name)
Olli Etuahod4529f32017-12-12 13:06:40 +0200130{
Olli Etuahofbb1c792018-01-19 16:26:59 +0200131 ImmutableString *mutableName = const_cast<ImmutableString *>(&mName);
Olli Etuahod4529f32017-12-12 13:06:40 +0200132 *mutableName = name;
133}
134
135TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
Olli Etuahofbb1c792018-01-19 16:26:59 +0200136 const ImmutableString &name,
Olli Etuahod4529f32017-12-12 13:06:40 +0200137 const TFieldList *fields,
138 const TLayoutQualifier &layoutQualifier,
139 SymbolType symbolType,
140 TExtension extension)
Olli Etuaho8073a952018-05-09 16:41:39 +0300141 : TSymbol(symbolTable, name, symbolType, SymbolClass::InterfaceBlock, extension),
Olli Etuahod4529f32017-12-12 13:06:40 +0200142 TFieldListCollection(fields),
143 mBlockStorage(layoutQualifier.blockStorage),
144 mBinding(layoutQualifier.binding)
145{
146 ASSERT(name != nullptr);
147}
148
Olli Etuaho391bda22018-02-23 11:43:14 +0200149TInterfaceBlock::TInterfaceBlock(const TSymbolUniqueId &id,
150 const ImmutableString &name,
151 TExtension extension,
152 const TFieldList *fields)
Olli Etuaho8073a952018-05-09 16:41:39 +0300153 : TSymbol(id, name, SymbolType::BuiltIn, extension, SymbolClass::InterfaceBlock),
Olli Etuaho391bda22018-02-23 11:43:14 +0200154 TFieldListCollection(fields),
155 mBlockStorage(EbsUnspecified),
156 mBinding(0)
157{
158}
159
Olli Etuahod4529f32017-12-12 13:06:40 +0200160TFunction::TFunction(TSymbolTable *symbolTable,
Olli Etuahofbb1c792018-01-19 16:26:59 +0200161 const ImmutableString &name,
Olli Etuahod4529f32017-12-12 13:06:40 +0200162 SymbolType symbolType,
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200163 const TType *retType,
164 bool knownToNotHaveSideEffects)
Olli Etuaho8073a952018-05-09 16:41:39 +0300165 : TSymbol(symbolTable, name, symbolType, SymbolClass::Function, TExtension::UNDEFINED),
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200166 mParametersVector(new TParamVector()),
167 mParameters(nullptr),
168 mParamCount(0u),
Olli Etuahod4529f32017-12-12 13:06:40 +0200169 returnType(retType),
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200170 mMangledName(""),
171 mOp(EOpNull),
Olli Etuahod4529f32017-12-12 13:06:40 +0200172 defined(false),
Olli Etuaho0c371002017-12-13 17:00:25 +0400173 mHasPrototypeDeclaration(false),
174 mKnownToNotHaveSideEffects(knownToNotHaveSideEffects)
Olli Etuahod4529f32017-12-12 13:06:40 +0200175{
Olli Etuaho0c371002017-12-13 17:00:25 +0400176 // Functions with an empty name are not allowed.
177 ASSERT(symbolType != SymbolType::Empty);
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200178 ASSERT(name != nullptr || symbolType == SymbolType::AngleInternal);
Olli Etuahod4529f32017-12-12 13:06:40 +0200179}
180
Olli Etuahod4bd9632018-03-08 16:32:44 +0200181void TFunction::addParameter(const TVariable *p)
Olli Etuahod4529f32017-12-12 13:06:40 +0200182{
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200183 ASSERT(mParametersVector);
184 mParametersVector->push_back(p);
185 mParameters = mParametersVector->data();
186 mParamCount = mParametersVector->size();
187 mMangledName = ImmutableString("");
188}
189
190void TFunction::shareParameters(const TFunction &parametersSource)
191{
192 mParametersVector = nullptr;
193 mParameters = parametersSource.mParameters;
194 mParamCount = parametersSource.mParamCount;
195 ASSERT(parametersSource.name() == name());
196 mMangledName = parametersSource.mMangledName;
Olli Etuahod4529f32017-12-12 13:06:40 +0200197}
198
Olli Etuahofbb1c792018-01-19 16:26:59 +0200199ImmutableString TFunction::buildMangledName() const
Olli Etuahod4529f32017-12-12 13:06:40 +0200200{
Olli Etuahofbb1c792018-01-19 16:26:59 +0200201 std::string newName(name().data(), name().length());
Olli Etuahod4529f32017-12-12 13:06:40 +0200202 newName += kFunctionMangledNameSeparator;
203
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200204 for (size_t i = 0u; i < mParamCount; ++i)
Olli Etuahod4529f32017-12-12 13:06:40 +0200205 {
Olli Etuahod4bd9632018-03-08 16:32:44 +0200206 newName += mParameters[i]->getType().getMangledName();
Olli Etuahod4529f32017-12-12 13:06:40 +0200207 }
Olli Etuahofbb1c792018-01-19 16:26:59 +0200208 return ImmutableString(newName);
Olli Etuahod4529f32017-12-12 13:06:40 +0200209}
210
Olli Etuaho1bb85282017-12-14 13:39:53 +0200211bool TFunction::isMain() const
212{
Olli Etuahofbb1c792018-01-19 16:26:59 +0200213 return symbolType() == SymbolType::UserDefined && name() == kMainName;
Olli Etuaho1bb85282017-12-14 13:39:53 +0200214}
215
216bool TFunction::isImageFunction() const
217{
218 return symbolType() == SymbolType::BuiltIn &&
Olli Etuahofbb1c792018-01-19 16:26:59 +0200219 (name() == kImageSizeName || name() == kImageLoadName || name() == kImageStoreName);
Olli Etuaho1bb85282017-12-14 13:39:53 +0200220}
221
Olli Etuahod4529f32017-12-12 13:06:40 +0200222} // namespace sh