blob: cb3331c01e54f79edb2b34d54f3a5e5461beaab1 [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,
36 TExtension extension)
37 : mName(name),
38 mUniqueId(symbolTable->nextUniqueId()),
39 mSymbolType(symbolType),
40 mExtension(extension)
41{
42 ASSERT(mSymbolType == SymbolType::BuiltIn || mExtension == TExtension::UNDEFINED);
Olli Etuahofbb1c792018-01-19 16:26:59 +020043 ASSERT(mName != "" || mSymbolType == SymbolType::AngleInternal ||
Olli Etuaho95ed1942018-02-01 14:01:19 +020044 mSymbolType == SymbolType::Empty);
Olli Etuahod4529f32017-12-12 13:06:40 +020045}
46
Olli Etuahofbb1c792018-01-19 16:26:59 +020047ImmutableString TSymbol::name() const
Olli Etuahod4529f32017-12-12 13:06:40 +020048{
Olli Etuaho40b1c772018-03-19 10:29:37 +020049 if (!mName.empty())
Olli Etuahod4529f32017-12-12 13:06:40 +020050 {
Olli Etuahofbb1c792018-01-19 16:26:59 +020051 return mName;
Olli Etuahod4529f32017-12-12 13:06:40 +020052 }
Olli Etuaho40b1c772018-03-19 10:29:37 +020053 // This can be called for nameless function parameters in HLSL.
54 ASSERT(mSymbolType == SymbolType::AngleInternal ||
55 (mSymbolType == SymbolType::Empty && isVariable()));
Olli Etuahofbb1c792018-01-19 16:26:59 +020056 int uniqueId = mUniqueId.get();
57 ImmutableStringBuilder symbolNameOut(sizeof(uniqueId) * 2u + 1u);
58 symbolNameOut << 's';
59 symbolNameOut.appendHex(mUniqueId.get());
60 return symbolNameOut;
Olli Etuahod4529f32017-12-12 13:06:40 +020061}
62
Olli Etuahofbb1c792018-01-19 16:26:59 +020063ImmutableString TSymbol::getMangledName() const
Olli Etuahod4529f32017-12-12 13:06:40 +020064{
65 ASSERT(mSymbolType != SymbolType::Empty);
Olli Etuahobed35d72017-12-20 16:36:26 +020066 return name();
Olli Etuahod4529f32017-12-12 13:06:40 +020067}
68
69TVariable::TVariable(TSymbolTable *symbolTable,
Olli Etuahofbb1c792018-01-19 16:26:59 +020070 const ImmutableString &name,
Olli Etuahob60d30f2018-01-16 12:31:06 +020071 const TType *type,
Olli Etuahod4529f32017-12-12 13:06:40 +020072 SymbolType symbolType,
73 TExtension extension)
Olli Etuahob60d30f2018-01-16 12:31:06 +020074 : TSymbol(symbolTable, name, symbolType, extension), mType(type), unionArray(nullptr)
Olli Etuahod4529f32017-12-12 13:06:40 +020075{
Olli Etuahob60d30f2018-01-16 12:31:06 +020076 ASSERT(mType);
Olli Etuahod4529f32017-12-12 13:06:40 +020077}
78
79TStructure::TStructure(TSymbolTable *symbolTable,
Olli Etuahofbb1c792018-01-19 16:26:59 +020080 const ImmutableString &name,
Olli Etuahod4529f32017-12-12 13:06:40 +020081 const TFieldList *fields,
82 SymbolType symbolType)
83 : TSymbol(symbolTable, name, symbolType), TFieldListCollection(fields)
84{
85}
86
Olli Etuaho391bda22018-02-23 11:43:14 +020087TStructure::TStructure(const TSymbolUniqueId &id,
88 const ImmutableString &name,
89 TExtension extension,
90 const TFieldList *fields)
91 : TSymbol(id, name, SymbolType::BuiltIn, extension), TFieldListCollection(fields)
92{
93}
94
Olli Etuahofbb1c792018-01-19 16:26:59 +020095void TStructure::createSamplerSymbols(const char *namePrefix,
Olli Etuahod4529f32017-12-12 13:06:40 +020096 const TString &apiNamePrefix,
Olli Etuahobbd9d4c2017-12-21 12:02:00 +020097 TVector<const TVariable *> *outputSymbols,
98 TMap<const TVariable *, TString> *outputSymbolsToAPINames,
Olli Etuahod4529f32017-12-12 13:06:40 +020099 TSymbolTable *symbolTable) const
100{
101 ASSERT(containsSamplers());
102 for (const auto *field : *mFields)
103 {
104 const TType *fieldType = field->type();
105 if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
106 {
Olli Etuahofbb1c792018-01-19 16:26:59 +0200107 std::stringstream fieldName;
108 fieldName << namePrefix << "_" << field->name();
109 TString fieldApiName = apiNamePrefix + ".";
110 fieldApiName += field->name().data();
111 fieldType->createSamplerSymbols(ImmutableString(fieldName.str()), fieldApiName,
112 outputSymbols, outputSymbolsToAPINames, symbolTable);
Olli Etuahod4529f32017-12-12 13:06:40 +0200113 }
114 }
115}
116
Olli Etuahofbb1c792018-01-19 16:26:59 +0200117void TStructure::setName(const ImmutableString &name)
Olli Etuahod4529f32017-12-12 13:06:40 +0200118{
Olli Etuahofbb1c792018-01-19 16:26:59 +0200119 ImmutableString *mutableName = const_cast<ImmutableString *>(&mName);
Olli Etuahod4529f32017-12-12 13:06:40 +0200120 *mutableName = name;
121}
122
123TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
Olli Etuahofbb1c792018-01-19 16:26:59 +0200124 const ImmutableString &name,
Olli Etuahod4529f32017-12-12 13:06:40 +0200125 const TFieldList *fields,
126 const TLayoutQualifier &layoutQualifier,
127 SymbolType symbolType,
128 TExtension extension)
129 : TSymbol(symbolTable, name, symbolType, extension),
130 TFieldListCollection(fields),
131 mBlockStorage(layoutQualifier.blockStorage),
132 mBinding(layoutQualifier.binding)
133{
134 ASSERT(name != nullptr);
135}
136
Olli Etuaho391bda22018-02-23 11:43:14 +0200137TInterfaceBlock::TInterfaceBlock(const TSymbolUniqueId &id,
138 const ImmutableString &name,
139 TExtension extension,
140 const TFieldList *fields)
141 : TSymbol(id, name, SymbolType::BuiltIn, extension),
142 TFieldListCollection(fields),
143 mBlockStorage(EbsUnspecified),
144 mBinding(0)
145{
146}
147
Olli Etuahod4529f32017-12-12 13:06:40 +0200148TFunction::TFunction(TSymbolTable *symbolTable,
Olli Etuahofbb1c792018-01-19 16:26:59 +0200149 const ImmutableString &name,
Olli Etuahod4529f32017-12-12 13:06:40 +0200150 SymbolType symbolType,
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200151 const TType *retType,
152 bool knownToNotHaveSideEffects)
153 : TSymbol(symbolTable, name, symbolType, TExtension::UNDEFINED),
154 mParametersVector(new TParamVector()),
155 mParameters(nullptr),
156 mParamCount(0u),
Olli Etuahod4529f32017-12-12 13:06:40 +0200157 returnType(retType),
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200158 mMangledName(""),
159 mOp(EOpNull),
Olli Etuahod4529f32017-12-12 13:06:40 +0200160 defined(false),
Olli Etuaho0c371002017-12-13 17:00:25 +0400161 mHasPrototypeDeclaration(false),
162 mKnownToNotHaveSideEffects(knownToNotHaveSideEffects)
Olli Etuahod4529f32017-12-12 13:06:40 +0200163{
Olli Etuaho0c371002017-12-13 17:00:25 +0400164 // Functions with an empty name are not allowed.
165 ASSERT(symbolType != SymbolType::Empty);
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200166 ASSERT(name != nullptr || symbolType == SymbolType::AngleInternal);
Olli Etuahod4529f32017-12-12 13:06:40 +0200167}
168
Olli Etuahod4bd9632018-03-08 16:32:44 +0200169void TFunction::addParameter(const TVariable *p)
Olli Etuahod4529f32017-12-12 13:06:40 +0200170{
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200171 ASSERT(mParametersVector);
172 mParametersVector->push_back(p);
173 mParameters = mParametersVector->data();
174 mParamCount = mParametersVector->size();
175 mMangledName = ImmutableString("");
176}
177
178void TFunction::shareParameters(const TFunction &parametersSource)
179{
180 mParametersVector = nullptr;
181 mParameters = parametersSource.mParameters;
182 mParamCount = parametersSource.mParamCount;
183 ASSERT(parametersSource.name() == name());
184 mMangledName = parametersSource.mMangledName;
Olli Etuahod4529f32017-12-12 13:06:40 +0200185}
186
Olli Etuahofbb1c792018-01-19 16:26:59 +0200187ImmutableString TFunction::buildMangledName() const
Olli Etuahod4529f32017-12-12 13:06:40 +0200188{
Olli Etuahofbb1c792018-01-19 16:26:59 +0200189 std::string newName(name().data(), name().length());
Olli Etuahod4529f32017-12-12 13:06:40 +0200190 newName += kFunctionMangledNameSeparator;
191
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200192 for (size_t i = 0u; i < mParamCount; ++i)
Olli Etuahod4529f32017-12-12 13:06:40 +0200193 {
Olli Etuahod4bd9632018-03-08 16:32:44 +0200194 newName += mParameters[i]->getType().getMangledName();
Olli Etuahod4529f32017-12-12 13:06:40 +0200195 }
Olli Etuahofbb1c792018-01-19 16:26:59 +0200196 return ImmutableString(newName);
Olli Etuahod4529f32017-12-12 13:06:40 +0200197}
198
Olli Etuaho1bb85282017-12-14 13:39:53 +0200199bool TFunction::isMain() const
200{
Olli Etuahofbb1c792018-01-19 16:26:59 +0200201 return symbolType() == SymbolType::UserDefined && name() == kMainName;
Olli Etuaho1bb85282017-12-14 13:39:53 +0200202}
203
204bool TFunction::isImageFunction() const
205{
206 return symbolType() == SymbolType::BuiltIn &&
Olli Etuahofbb1c792018-01-19 16:26:59 +0200207 (name() == kImageSizeName || name() == kImageLoadName || name() == kImageStoreName);
Olli Etuaho1bb85282017-12-14 13:39:53 +0200208}
209
Olli Etuahod4529f32017-12-12 13:06:40 +0200210} // namespace sh