blob: 4301a5b466bb6b03ae91b239da70ee75170e8f78 [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 ||
38 mSymbolType == SymbolType::NotResolved || 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,
62 const TType &t,
63 SymbolType symbolType,
64 TExtension extension)
65 : TSymbol(symbolTable, name, symbolType, extension), type(t), unionArray(nullptr)
66{
67}
68
69TStructure::TStructure(TSymbolTable *symbolTable,
70 const TString *name,
71 const TFieldList *fields,
72 SymbolType symbolType)
73 : TSymbol(symbolTable, name, symbolType), TFieldListCollection(fields)
74{
75}
76
77void TStructure::createSamplerSymbols(const TString &namePrefix,
78 const TString &apiNamePrefix,
Olli Etuahobbd9d4c2017-12-21 12:02:00 +020079 TVector<const TVariable *> *outputSymbols,
80 TMap<const TVariable *, TString> *outputSymbolsToAPINames,
Olli Etuahod4529f32017-12-12 13:06:40 +020081 TSymbolTable *symbolTable) const
82{
83 ASSERT(containsSamplers());
84 for (const auto *field : *mFields)
85 {
86 const TType *fieldType = field->type();
87 if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
88 {
89 TString fieldName = namePrefix + "_" + field->name();
90 TString fieldApiName = apiNamePrefix + "." + field->name();
91 fieldType->createSamplerSymbols(fieldName, fieldApiName, outputSymbols,
92 outputSymbolsToAPINames, symbolTable);
93 }
94 }
95}
96
97void TStructure::setName(const TString &name)
98{
99 TString *mutableName = const_cast<TString *>(mName);
100 *mutableName = name;
101}
102
103TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
104 const TString *name,
105 const TFieldList *fields,
106 const TLayoutQualifier &layoutQualifier,
107 SymbolType symbolType,
108 TExtension extension)
109 : TSymbol(symbolTable, name, symbolType, extension),
110 TFieldListCollection(fields),
111 mBlockStorage(layoutQualifier.blockStorage),
112 mBinding(layoutQualifier.binding)
113{
114 ASSERT(name != nullptr);
115}
116
117TFunction::TFunction(TSymbolTable *symbolTable,
118 const TString *name,
119 const TType *retType,
120 SymbolType symbolType,
Olli Etuaho0c371002017-12-13 17:00:25 +0400121 bool knownToNotHaveSideEffects,
Olli Etuahod4529f32017-12-12 13:06:40 +0200122 TOperator tOp,
123 TExtension extension)
124 : TSymbol(symbolTable, name, symbolType, extension),
125 returnType(retType),
126 mangledName(nullptr),
127 op(tOp),
128 defined(false),
Olli Etuaho0c371002017-12-13 17:00:25 +0400129 mHasPrototypeDeclaration(false),
130 mKnownToNotHaveSideEffects(knownToNotHaveSideEffects)
Olli Etuahod4529f32017-12-12 13:06:40 +0200131{
Olli Etuaho0c371002017-12-13 17:00:25 +0400132 // Functions with an empty name are not allowed.
133 ASSERT(symbolType != SymbolType::Empty);
134 ASSERT(name != nullptr || symbolType == SymbolType::AngleInternal || tOp != EOpNull);
Olli Etuahod4529f32017-12-12 13:06:40 +0200135}
136
137//
138// Functions have buried pointers to delete.
139//
140TFunction::~TFunction()
141{
142 clearParameters();
143}
144
145void TFunction::clearParameters()
146{
147 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
148 delete (*i).type;
149 parameters.clear();
150 mangledName = nullptr;
151}
152
153void TFunction::swapParameters(const TFunction &parametersSource)
154{
155 clearParameters();
156 for (auto parameter : parametersSource.parameters)
157 {
158 addParameter(parameter);
159 }
160}
161
162const TString *TFunction::buildMangledName() const
163{
Olli Etuahobed35d72017-12-20 16:36:26 +0200164 std::string newName = name().c_str();
Olli Etuahod4529f32017-12-12 13:06:40 +0200165 newName += kFunctionMangledNameSeparator;
166
167 for (const auto &p : parameters)
168 {
169 newName += p.type->getMangledName();
170 }
171 return NewPoolTString(newName.c_str());
172}
173
174const TString &TFunction::GetMangledNameFromCall(const TString &functionName,
175 const TIntermSequence &arguments)
176{
177 std::string newName = functionName.c_str();
178 newName += kFunctionMangledNameSeparator;
179
180 for (TIntermNode *argument : arguments)
181 {
182 newName += argument->getAsTyped()->getType().getMangledName();
183 }
184 return *NewPoolTString(newName.c_str());
185}
186
Olli Etuaho1bb85282017-12-14 13:39:53 +0200187bool TFunction::isMain() const
188{
Olli Etuahobed35d72017-12-20 16:36:26 +0200189 return symbolType() == SymbolType::UserDefined && name() == "main";
Olli Etuaho1bb85282017-12-14 13:39:53 +0200190}
191
192bool TFunction::isImageFunction() const
193{
194 return symbolType() == SymbolType::BuiltIn &&
Olli Etuahobed35d72017-12-20 16:36:26 +0200195 (name() == "imageSize" || name() == "imageLoad" || name() == "imageStore");
Olli Etuaho1bb85282017-12-14 13:39:53 +0200196}
197
Olli Etuahod4529f32017-12-12 13:06:40 +0200198} // namespace sh