blob: 3e7b83a215669b868f8e7cca1b9fe2dd185e298e [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 Etuahofbb1c792018-01-19 16:26:59 +020049 if (mName != "")
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 }
53 ASSERT(mSymbolType == SymbolType::AngleInternal);
Olli Etuahofbb1c792018-01-19 16:26:59 +020054 int uniqueId = mUniqueId.get();
55 ImmutableStringBuilder symbolNameOut(sizeof(uniqueId) * 2u + 1u);
56 symbolNameOut << 's';
57 symbolNameOut.appendHex(mUniqueId.get());
58 return symbolNameOut;
Olli Etuahod4529f32017-12-12 13:06:40 +020059}
60
Olli Etuahofbb1c792018-01-19 16:26:59 +020061ImmutableString TSymbol::getMangledName() const
Olli Etuahod4529f32017-12-12 13:06:40 +020062{
63 ASSERT(mSymbolType != SymbolType::Empty);
Olli Etuahobed35d72017-12-20 16:36:26 +020064 return name();
Olli Etuahod4529f32017-12-12 13:06:40 +020065}
66
67TVariable::TVariable(TSymbolTable *symbolTable,
Olli Etuahofbb1c792018-01-19 16:26:59 +020068 const ImmutableString &name,
Olli Etuahob60d30f2018-01-16 12:31:06 +020069 const TType *type,
Olli Etuahod4529f32017-12-12 13:06:40 +020070 SymbolType symbolType,
71 TExtension extension)
Olli Etuahob60d30f2018-01-16 12:31:06 +020072 : TSymbol(symbolTable, name, symbolType, extension), mType(type), unionArray(nullptr)
Olli Etuahod4529f32017-12-12 13:06:40 +020073{
Olli Etuahob60d30f2018-01-16 12:31:06 +020074 ASSERT(mType);
Olli Etuahod4529f32017-12-12 13:06:40 +020075}
76
77TStructure::TStructure(TSymbolTable *symbolTable,
Olli Etuahofbb1c792018-01-19 16:26:59 +020078 const ImmutableString &name,
Olli Etuahod4529f32017-12-12 13:06:40 +020079 const TFieldList *fields,
80 SymbolType symbolType)
81 : TSymbol(symbolTable, name, symbolType), TFieldListCollection(fields)
82{
83}
84
Olli Etuahofbb1c792018-01-19 16:26:59 +020085void TStructure::createSamplerSymbols(const char *namePrefix,
Olli Etuahod4529f32017-12-12 13:06:40 +020086 const TString &apiNamePrefix,
Olli Etuahobbd9d4c2017-12-21 12:02:00 +020087 TVector<const TVariable *> *outputSymbols,
88 TMap<const TVariable *, TString> *outputSymbolsToAPINames,
Olli Etuahod4529f32017-12-12 13:06:40 +020089 TSymbolTable *symbolTable) const
90{
91 ASSERT(containsSamplers());
92 for (const auto *field : *mFields)
93 {
94 const TType *fieldType = field->type();
95 if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
96 {
Olli Etuahofbb1c792018-01-19 16:26:59 +020097 std::stringstream fieldName;
98 fieldName << namePrefix << "_" << field->name();
99 TString fieldApiName = apiNamePrefix + ".";
100 fieldApiName += field->name().data();
101 fieldType->createSamplerSymbols(ImmutableString(fieldName.str()), fieldApiName,
102 outputSymbols, outputSymbolsToAPINames, symbolTable);
Olli Etuahod4529f32017-12-12 13:06:40 +0200103 }
104 }
105}
106
Olli Etuahofbb1c792018-01-19 16:26:59 +0200107void TStructure::setName(const ImmutableString &name)
Olli Etuahod4529f32017-12-12 13:06:40 +0200108{
Olli Etuahofbb1c792018-01-19 16:26:59 +0200109 ImmutableString *mutableName = const_cast<ImmutableString *>(&mName);
Olli Etuahod4529f32017-12-12 13:06:40 +0200110 *mutableName = name;
111}
112
113TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
Olli Etuahofbb1c792018-01-19 16:26:59 +0200114 const ImmutableString &name,
Olli Etuahod4529f32017-12-12 13:06:40 +0200115 const TFieldList *fields,
116 const TLayoutQualifier &layoutQualifier,
117 SymbolType symbolType,
118 TExtension extension)
119 : TSymbol(symbolTable, name, symbolType, extension),
120 TFieldListCollection(fields),
121 mBlockStorage(layoutQualifier.blockStorage),
122 mBinding(layoutQualifier.binding)
123{
124 ASSERT(name != nullptr);
125}
126
127TFunction::TFunction(TSymbolTable *symbolTable,
Olli Etuahofbb1c792018-01-19 16:26:59 +0200128 const ImmutableString &name,
Olli Etuahod4529f32017-12-12 13:06:40 +0200129 SymbolType symbolType,
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200130 const TType *retType,
131 bool knownToNotHaveSideEffects)
132 : TSymbol(symbolTable, name, symbolType, TExtension::UNDEFINED),
133 mParametersVector(new TParamVector()),
134 mParameters(nullptr),
135 mParamCount(0u),
Olli Etuahod4529f32017-12-12 13:06:40 +0200136 returnType(retType),
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200137 mMangledName(""),
138 mOp(EOpNull),
Olli Etuahod4529f32017-12-12 13:06:40 +0200139 defined(false),
Olli Etuaho0c371002017-12-13 17:00:25 +0400140 mHasPrototypeDeclaration(false),
141 mKnownToNotHaveSideEffects(knownToNotHaveSideEffects)
Olli Etuahod4529f32017-12-12 13:06:40 +0200142{
Olli Etuaho0c371002017-12-13 17:00:25 +0400143 // Functions with an empty name are not allowed.
144 ASSERT(symbolType != SymbolType::Empty);
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200145 ASSERT(name != nullptr || symbolType == SymbolType::AngleInternal);
Olli Etuahod4529f32017-12-12 13:06:40 +0200146}
147
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200148TFunction::TFunction(TSymbolTable *symbolTable,
149 const ImmutableString &name,
150 TExtension extension,
151 TConstParameter *parameters,
152 size_t paramCount,
153 const TType *retType,
154 TOperator op,
155 bool knownToNotHaveSideEffects)
156 : TSymbol(symbolTable, name, SymbolType::BuiltIn, extension),
157 mParametersVector(nullptr),
158 mParameters(parameters),
159 mParamCount(paramCount),
160 returnType(retType),
161 mMangledName(""),
162 mOp(op),
163 defined(false),
164 mHasPrototypeDeclaration(false),
165 mKnownToNotHaveSideEffects(knownToNotHaveSideEffects)
Olli Etuahod4529f32017-12-12 13:06:40 +0200166{
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200167 ASSERT(name != nullptr);
168 ASSERT(op != EOpNull);
169 ASSERT(paramCount == 0 || parameters != nullptr);
170 mMangledName = buildMangledName();
Olli Etuahod4529f32017-12-12 13:06:40 +0200171}
172
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200173void TFunction::addParameter(const TConstParameter &p)
Olli Etuahod4529f32017-12-12 13:06:40 +0200174{
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200175 ASSERT(mParametersVector);
176 mParametersVector->push_back(p);
177 mParameters = mParametersVector->data();
178 mParamCount = mParametersVector->size();
179 mMangledName = ImmutableString("");
180}
181
182void TFunction::shareParameters(const TFunction &parametersSource)
183{
184 mParametersVector = nullptr;
185 mParameters = parametersSource.mParameters;
186 mParamCount = parametersSource.mParamCount;
187 ASSERT(parametersSource.name() == name());
188 mMangledName = parametersSource.mMangledName;
Olli Etuahod4529f32017-12-12 13:06:40 +0200189}
190
Olli Etuahofbb1c792018-01-19 16:26:59 +0200191ImmutableString TFunction::buildMangledName() const
Olli Etuahod4529f32017-12-12 13:06:40 +0200192{
Olli Etuahofbb1c792018-01-19 16:26:59 +0200193 std::string newName(name().data(), name().length());
Olli Etuahod4529f32017-12-12 13:06:40 +0200194 newName += kFunctionMangledNameSeparator;
195
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200196 for (size_t i = 0u; i < mParamCount; ++i)
Olli Etuahod4529f32017-12-12 13:06:40 +0200197 {
Olli Etuaho029e8ca2018-02-16 14:06:49 +0200198 newName += mParameters[i].type->getMangledName();
Olli Etuahod4529f32017-12-12 13:06:40 +0200199 }
Olli Etuahofbb1c792018-01-19 16:26:59 +0200200 return ImmutableString(newName);
Olli Etuahod4529f32017-12-12 13:06:40 +0200201}
202
Olli Etuaho1bb85282017-12-14 13:39:53 +0200203bool TFunction::isMain() const
204{
Olli Etuahofbb1c792018-01-19 16:26:59 +0200205 return symbolType() == SymbolType::UserDefined && name() == kMainName;
Olli Etuaho1bb85282017-12-14 13:39:53 +0200206}
207
208bool TFunction::isImageFunction() const
209{
210 return symbolType() == SymbolType::BuiltIn &&
Olli Etuahofbb1c792018-01-19 16:26:59 +0200211 (name() == kImageSizeName || name() == kImageLoadName || name() == kImageStoreName);
Olli Etuaho1bb85282017-12-14 13:39:53 +0200212}
213
Olli Etuahod4529f32017-12-12 13:06:40 +0200214} // namespace sh