blob: 6ec6449fba6af43502dd01641aecdc0507142fa6 [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 ||
Olli Etuaho95ed1942018-02-01 14:01:19 +020038 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
Olli Etuahod4529f32017-12-12 13:06:40 +0200138TFunction::~TFunction()
139{
Olli Etuaho68981eb2018-01-23 17:46:12 +0200140 // Just here to discourage the compiler from inlining it.
Olli Etuahod4529f32017-12-12 13:06:40 +0200141}
142
143void TFunction::clearParameters()
144{
Olli Etuahod4529f32017-12-12 13:06:40 +0200145 parameters.clear();
146 mangledName = nullptr;
147}
148
149void TFunction::swapParameters(const TFunction &parametersSource)
150{
151 clearParameters();
152 for (auto parameter : parametersSource.parameters)
153 {
154 addParameter(parameter);
155 }
156}
157
158const TString *TFunction::buildMangledName() const
159{
Olli Etuahobed35d72017-12-20 16:36:26 +0200160 std::string newName = name().c_str();
Olli Etuahod4529f32017-12-12 13:06:40 +0200161 newName += kFunctionMangledNameSeparator;
162
163 for (const auto &p : parameters)
164 {
165 newName += p.type->getMangledName();
166 }
167 return NewPoolTString(newName.c_str());
168}
169
Olli Etuaho1bb85282017-12-14 13:39:53 +0200170bool TFunction::isMain() const
171{
Olli Etuahobed35d72017-12-20 16:36:26 +0200172 return symbolType() == SymbolType::UserDefined && name() == "main";
Olli Etuaho1bb85282017-12-14 13:39:53 +0200173}
174
175bool TFunction::isImageFunction() const
176{
177 return symbolType() == SymbolType::BuiltIn &&
Olli Etuahobed35d72017-12-20 16:36:26 +0200178 (name() == "imageSize" || name() == "imageLoad" || name() == "imageStore");
Olli Etuaho1bb85282017-12-14 13:39:53 +0200179}
180
Olli Etuahod4529f32017-12-12 13:06:40 +0200181} // namespace sh