1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "global_tables.h"
17 #include "mir_type.h"
18 #include "mir_symbol.h"
19
20 #if MIR_FEATURE_FULL
21 namespace maple {
CreateMirType(uint32 primTypeIdx) const22 MIRType *TypeTable::CreateMirType(uint32 primTypeIdx) const
23 {
24 MIRTypeKind defaultKind = (primTypeIdx == PTY_constStr ? kTypeConstString : kTypeScalar);
25 auto primType = static_cast<PrimType>(primTypeIdx);
26 auto *mirType = new MIRType(defaultKind, primType);
27 return mirType;
28 }
29
TypeTable()30 TypeTable::TypeTable()
31 {
32 Init();
33 }
34
Init()35 void TypeTable::Init()
36 {
37 // enter the primitve types in type_table_
38 typeTable.push_back(static_cast<MIRType *>(nullptr));
39 DEBUG_ASSERT(typeTable.size() == static_cast<size_t>(PTY_void), "use PTY_void as the first index to type table");
40 uint32 primTypeIdx;
41 for (primTypeIdx = static_cast<uint32>(PTY_begin) + 1; primTypeIdx <= static_cast<uint32>(PTY_end); ++primTypeIdx) {
42 MIRType *type = CreateMirType(primTypeIdx);
43 type->SetTypeIndex(TyIdx {primTypeIdx});
44 typeTable.push_back(type);
45 PutToHashTable(type);
46 }
47 if (voidPtrType == nullptr) {
48 voidPtrType = GetOrCreatePointerType(*GetVoid(), PTY_ptr);
49 }
50 lastDefaultTyIdx.SetIdx(primTypeIdx);
51 }
52
Reset()53 void TypeTable::Reset()
54 {
55 ReleaseTypes();
56 typeHashTable.clear();
57 ptrTypeMap.clear();
58 refTypeMap.clear();
59 typeTable.clear();
60 Init();
61 }
62
ReleaseTypes()63 void TypeTable::ReleaseTypes()
64 {
65 for (auto index = static_cast<uint32>(PTY_void); index < typeTable.size(); ++index) {
66 delete typeTable[index];
67 typeTable[index] = nullptr;
68 }
69 voidPtrType = nullptr;
70 }
71
SetTypeWithTyIdx(const TyIdx & tyIdx,MIRType & type)72 void TypeTable::SetTypeWithTyIdx(const TyIdx &tyIdx, MIRType &type)
73 {
74 CHECK_FATAL(tyIdx < typeTable.size(), "array index out of range");
75 MIRType *oldType = typeTable.at(tyIdx);
76 typeTable.at(tyIdx) = &type;
77 if (oldType != nullptr && oldType != &type) {
78 (void)typeHashTable.erase(oldType);
79 (void)typeHashTable.insert(&type);
80 delete oldType;
81 }
82 }
83
~TypeTable()84 TypeTable::~TypeTable()
85 {
86 ReleaseTypes();
87 }
88
PutToHashTable(MIRType * mirType)89 void TypeTable::PutToHashTable(MIRType *mirType)
90 {
91 (void)typeHashTable.insert(mirType);
92 }
93
UpdateMIRType(const MIRType & pType,const TyIdx tyIdx)94 void TypeTable::UpdateMIRType(const MIRType &pType, const TyIdx tyIdx)
95 {
96 MIRType *nType = pType.CopyMIRTypeNode();
97 ASSERT_NOT_NULL(nType);
98 nType->SetTypeIndex(tyIdx);
99 SetTypeWithTyIdx(tyIdx, *nType);
100 }
101
102 // used only by bin_mpl_import
CreateMirTypeNodeAt(MIRType & pType,TyIdx tyIdxUsed,MIRModule * module,bool isObject,bool isIncomplete)103 void TypeTable::CreateMirTypeNodeAt(MIRType &pType, TyIdx tyIdxUsed, MIRModule *module, bool isObject,
104 bool isIncomplete)
105 {
106 MIRType *nType = pType.CopyMIRTypeNode();
107 nType->SetTypeIndex(tyIdxUsed);
108 typeTable[tyIdxUsed] = nType;
109
110 if (pType.IsMIRPtrType()) {
111 auto &pty = static_cast<MIRPtrType &>(pType);
112 if (pty.GetTypeAttrs() == TypeAttrs()) {
113 if (pty.GetPrimType() != PTY_ref) {
114 ptrTypeMap[pty.GetPointedTyIdx()] = nType->GetTypeIndex();
115 } else {
116 refTypeMap[pty.GetPointedTyIdx()] = nType->GetTypeIndex();
117 }
118 } else {
119 (void)typeHashTable.insert(nType);
120 }
121 } else {
122 (void)typeHashTable.insert(nType);
123 }
124
125 GStrIdx stridx = pType.GetNameStrIdx();
126 if (stridx != 0u) {
127 module->GetTypeNameTab()->SetGStrIdxToTyIdx(stridx, tyIdxUsed);
128 module->PushbackTypeDefOrder(stridx);
129 if (isObject) {
130 module->AddClass(tyIdxUsed);
131 if (!isIncomplete) {
132 GlobalTables::GetTypeNameTable().SetGStrIdxToTyIdx(stridx, tyIdxUsed);
133 }
134 }
135 }
136 }
137
CreateAndUpdateMirTypeNode(MIRType & pType)138 MIRType *TypeTable::CreateAndUpdateMirTypeNode(MIRType &pType)
139 {
140 MIRType *nType = pType.CopyMIRTypeNode();
141 nType->SetTypeIndex(TyIdx(typeTable.size()));
142 typeTable.push_back(nType);
143
144 if (pType.IsMIRPtrType()) {
145 auto &pty = static_cast<MIRPtrType &>(pType);
146 if (pty.GetTypeAttrs() == TypeAttrs()) {
147 if (pty.GetPrimType() != PTY_ref) {
148 ptrTypeMap[pty.GetPointedTyIdx()] = nType->GetTypeIndex();
149 } else {
150 refTypeMap[pty.GetPointedTyIdx()] = nType->GetTypeIndex();
151 }
152 } else {
153 (void)typeHashTable.insert(nType);
154 }
155 } else {
156 (void)typeHashTable.insert(nType);
157 }
158 return nType;
159 }
160
GetOrCreateMIRTypeNode(MIRType & pType)161 MIRType *TypeTable::GetOrCreateMIRTypeNode(MIRType &pType)
162 {
163 if (pType.IsMIRPtrType()) {
164 auto &type = static_cast<MIRPtrType &>(pType);
165 if (type.GetTypeAttrs() == TypeAttrs()) {
166 auto *pMap = (type.GetPrimType() != PTY_ref ? &ptrTypeMap : &refTypeMap);
167 auto *otherPMap = (type.GetPrimType() == PTY_ref ? &ptrTypeMap : &refTypeMap);
168 {
169 std::shared_lock<std::shared_timed_mutex> lock(mtx);
170 const auto it = pMap->find(type.GetPointedTyIdx());
171 if (it != pMap->end()) {
172 return GetTypeFromTyIdx(it->second);
173 }
174 }
175 std::unique_lock<std::shared_timed_mutex> lock(mtx);
176 CHECK_FATAL(!(type.GetPointedTyIdx().GetIdx() >= kPtyDerived && type.GetPrimType() == PTY_ref &&
177 otherPMap->find(type.GetPointedTyIdx()) != otherPMap->end()),
178 "GetOrCreateMIRType: ref pointed-to type %d has previous ptr occurrence",
179 type.GetPointedTyIdx().GetIdx());
180 return CreateAndUpdateMirTypeNode(pType);
181 }
182 }
183 {
184 std::shared_lock<std::shared_timed_mutex> lock(mtx);
185 const auto it = typeHashTable.find(&pType);
186 if (it != typeHashTable.end()) {
187 return *it;
188 }
189 }
190 std::unique_lock<std::shared_timed_mutex> lock(mtx);
191 return CreateAndUpdateMirTypeNode(pType);
192 }
193
194 MIRType *TypeTable::voidPtrType = nullptr;
195 // get or create a type that pointing to pointedTyIdx
GetOrCreatePointerType(const TyIdx & pointedTyIdx,PrimType primType,const TypeAttrs & attrs)196 MIRType *TypeTable::GetOrCreatePointerType(const TyIdx &pointedTyIdx, PrimType primType, const TypeAttrs &attrs)
197 {
198 MIRPtrType type(pointedTyIdx, primType);
199 type.SetTypeAttrs(attrs);
200 TyIdx tyIdx = GetOrCreateMIRType(&type);
201 DEBUG_ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreatePointerType");
202 return typeTable.at(tyIdx);
203 }
204
GetOrCreatePointerType(const MIRType & pointTo,PrimType primType,const TypeAttrs & attrs)205 MIRType *TypeTable::GetOrCreatePointerType(const MIRType &pointTo, PrimType primType, const TypeAttrs &attrs)
206 {
207 if (pointTo.GetPrimType() == PTY_constStr) {
208 primType = PTY_ptr;
209 }
210 return GetOrCreatePointerType(pointTo.GetTypeIndex(), primType, attrs);
211 }
212
GetPointedTypeIfApplicable(MIRType & type) const213 const MIRType *TypeTable::GetPointedTypeIfApplicable(MIRType &type) const
214 {
215 if (type.GetKind() != kTypePointer) {
216 return &type;
217 }
218 auto &ptrType = static_cast<MIRPtrType &>(type);
219 return GetTypeFromTyIdx(ptrType.GetPointedTyIdx());
220 }
GetPointedTypeIfApplicable(MIRType & type)221 MIRType *TypeTable::GetPointedTypeIfApplicable(MIRType &type)
222 {
223 return const_cast<MIRType *>(const_cast<const TypeTable *>(this)->GetPointedTypeIfApplicable(type));
224 }
225
GetOrCreateArrayType(const MIRType & elem,uint8 dim,const uint64 * sizeArray,const TypeAttrs & attrs)226 MIRArrayType *TypeTable::GetOrCreateArrayType(const MIRType &elem, uint8 dim, const uint64 *sizeArray,
227 const TypeAttrs &attrs)
228 {
229 std::vector<uint64> sizeVector;
230 for (size_t i = 0; i < dim; ++i) {
231 sizeVector.push_back(sizeArray != nullptr ? sizeArray[i] : 0);
232 }
233 MIRArrayType arrayType(elem.GetTypeIndex(), sizeVector);
234 arrayType.SetTypeAttrs(attrs);
235 TyIdx tyIdx = GetOrCreateMIRType(&arrayType);
236 return static_cast<MIRArrayType *>(typeTable[tyIdx]);
237 }
238
239 // For one dimension array
GetOrCreateArrayType(const MIRType & elem,uint64 size,const TypeAttrs & attrs)240 MIRArrayType *TypeTable::GetOrCreateArrayType(const MIRType &elem, uint64 size, const TypeAttrs &attrs)
241 {
242 return GetOrCreateArrayType(elem, 1, &size, attrs);
243 }
244
GetOrCreateFarrayType(const MIRType & elem)245 MIRType *TypeTable::GetOrCreateFarrayType(const MIRType &elem)
246 {
247 MIRFarrayType type;
248 type.SetElemtTyIdx(elem.GetTypeIndex());
249 TyIdx tyIdx = GetOrCreateMIRType(&type);
250 DEBUG_ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateFarrayType");
251 return typeTable.at(tyIdx);
252 }
253
GetOrCreateJarrayType(const MIRType & elem)254 MIRType *TypeTable::GetOrCreateJarrayType(const MIRType &elem)
255 {
256 MIRJarrayType type;
257 type.SetElemtTyIdx(elem.GetTypeIndex());
258 TyIdx tyIdx = GetOrCreateMIRType(&type);
259 DEBUG_ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateJarrayType");
260 return typeTable.at(tyIdx);
261 }
262
GetOrCreateFunctionType(const TyIdx & retTyIdx,const std::vector<TyIdx> & vecType,const std::vector<TypeAttrs> & vecAttrs,bool isVarg,const TypeAttrs & retAttrs)263 MIRType *TypeTable::GetOrCreateFunctionType(const TyIdx &retTyIdx, const std::vector<TyIdx> &vecType,
264 const std::vector<TypeAttrs> &vecAttrs, bool isVarg,
265 const TypeAttrs &retAttrs)
266 {
267 MIRFuncType funcType(retTyIdx, vecType, vecAttrs, retAttrs);
268 if (isVarg) {
269 funcType.SetVarArgs();
270 }
271 TyIdx tyIdx = GetOrCreateMIRType(&funcType);
272 DEBUG_ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateFunctionType");
273 return typeTable.at(tyIdx);
274 }
275
GetOrCreateStructOrUnion(const std::string & name,const FieldVector & fields,const FieldVector & parentFields,MIRModule & module,bool forStruct,const TypeAttrs & attrs)276 MIRType *TypeTable::GetOrCreateStructOrUnion(const std::string &name, const FieldVector &fields,
277 const FieldVector &parentFields, MIRModule &module, bool forStruct,
278 const TypeAttrs &attrs)
279 {
280 GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name);
281 MIRStructType type(forStruct ? kTypeStruct : kTypeUnion, strIdx);
282 type.SetFields(fields);
283 type.SetParentFields(parentFields);
284 type.SetTypeAttrs(attrs);
285
286 TyIdx tyIdx = GetOrCreateMIRType(&type);
287 // Global?
288 module.GetTypeNameTab()->SetGStrIdxToTyIdx(strIdx, tyIdx);
289 module.PushbackTypeDefOrder(strIdx);
290 DEBUG_ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateStructOrUnion");
291 return typeTable.at(tyIdx);
292 }
293
PushIntoFieldVector(FieldVector & fields,const std::string & name,const MIRType & type)294 void TypeTable::PushIntoFieldVector(FieldVector &fields, const std::string &name, const MIRType &type)
295 {
296 GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name);
297 fields.push_back(FieldPair(strIdx, TyIdxFieldAttrPair(type.GetTypeIndex(), FieldAttrs())));
298 }
299
GetOrCreateClassOrInterface(const std::string & name,MIRModule & module,bool forClass)300 MIRType *TypeTable::GetOrCreateClassOrInterface(const std::string &name, MIRModule &module, bool forClass)
301 {
302 GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name);
303 TyIdx tyIdx = module.GetTypeNameTab()->GetTyIdxFromGStrIdx(strIdx);
304 if (!tyIdx) {
305 if (forClass) {
306 MIRClassType type(kTypeClassIncomplete, strIdx); // for class type
307 tyIdx = GetOrCreateMIRType(&type);
308 } else {
309 MIRInterfaceType type(kTypeInterfaceIncomplete, strIdx); // for interface type
310 tyIdx = GetOrCreateMIRType(&type);
311 }
312 module.PushbackTypeDefOrder(strIdx);
313 module.GetTypeNameTab()->SetGStrIdxToTyIdx(strIdx, tyIdx);
314 if (typeTable[tyIdx]->GetNameStrIdx() == 0u) {
315 typeTable[tyIdx]->SetNameStrIdx(strIdx);
316 }
317 }
318 DEBUG_ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateClassOrInterface");
319 return typeTable.at(tyIdx);
320 }
321
AddFieldToStructType(MIRStructType & structType,const std::string & fieldName,const MIRType & fieldType)322 void TypeTable::AddFieldToStructType(MIRStructType &structType, const std::string &fieldName, const MIRType &fieldType)
323 {
324 GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fieldName);
325 FieldAttrs fieldAttrs;
326 fieldAttrs.SetAttr(FLDATTR_final); // Mark compiler-generated struct fields as final to improve AliasAnalysis
327 structType.GetFields().push_back(FieldPair(strIdx, TyIdxFieldAttrPair(fieldType.GetTypeIndex(), fieldAttrs)));
328 }
329
PostInit()330 void FPConstTable::PostInit()
331 {
332 MIRType &typeFloat = *GlobalTables::GetTypeTable().GetPrimType(PTY_f32);
333 nanFloatConst = new MIRFloatConst(NAN, typeFloat);
334 infFloatConst = new MIRFloatConst(INFINITY, typeFloat);
335 minusInfFloatConst = new MIRFloatConst(-INFINITY, typeFloat);
336 minusZeroFloatConst = new MIRFloatConst(-0.0, typeFloat);
337 MIRType &typeDouble = *GlobalTables::GetTypeTable().GetPrimType(PTY_f64);
338 nanDoubleConst = new MIRDoubleConst(NAN, typeDouble);
339 infDoubleConst = new MIRDoubleConst(INFINITY, typeDouble);
340 minusInfDoubleConst = new MIRDoubleConst(-INFINITY, typeDouble);
341 minusZeroDoubleConst = new MIRDoubleConst(-0.0, typeDouble);
342 }
343
GetOrCreateIntConst(const IntVal & val,MIRType & type)344 MIRIntConst *IntConstTable::GetOrCreateIntConst(const IntVal &val, MIRType &type)
345 {
346 if (ThreadEnv::IsMeParallel()) {
347 return DoGetOrCreateIntConstTreadSafe(val.GetExtValue(), type);
348 }
349 return DoGetOrCreateIntConst(val.GetExtValue(), type);
350 }
351
GetOrCreateIntConst(uint64 val,MIRType & type)352 MIRIntConst *IntConstTable::GetOrCreateIntConst(uint64 val, MIRType &type)
353 {
354 if (ThreadEnv::IsMeParallel()) {
355 return DoGetOrCreateIntConstTreadSafe(val, type);
356 }
357 return DoGetOrCreateIntConst(val, type);
358 }
359
DoGetOrCreateIntConst(uint64 val,MIRType & type)360 MIRIntConst *IntConstTable::DoGetOrCreateIntConst(uint64 val, MIRType &type)
361 {
362 IntConstKey key(val, type.GetTypeIndex());
363 if (intConstTable.find(key) != intConstTable.end()) {
364 return intConstTable[key];
365 }
366 intConstTable[key] = new MIRIntConst(val, type);
367 return intConstTable[key];
368 }
369
DoGetOrCreateIntConstTreadSafe(uint64 val,MIRType & type)370 MIRIntConst *IntConstTable::DoGetOrCreateIntConstTreadSafe(uint64 val, MIRType &type)
371 {
372 IntConstKey key(val, type.GetTypeIndex());
373 {
374 std::shared_lock<std::shared_timed_mutex> lock(mtx);
375 if (intConstTable.find(key) != intConstTable.end()) {
376 return intConstTable[key];
377 }
378 }
379 std::unique_lock<std::shared_timed_mutex> lock(mtx);
380 intConstTable[key] = new MIRIntConst(val, type);
381 return intConstTable[key];
382 }
383
~IntConstTable()384 IntConstTable::~IntConstTable()
385 {
386 for (auto pair : intConstTable) {
387 delete pair.second;
388 }
389 }
390
GetOrCreateFloatConst(float floatVal)391 MIRFloatConst *FPConstTable::GetOrCreateFloatConst(float floatVal)
392 {
393 if (std::isnan(floatVal)) {
394 return nanFloatConst;
395 }
396 if (std::isinf(floatVal)) {
397 return (floatVal < 0) ? minusInfFloatConst : infFloatConst;
398 }
399 if (floatVal == 0.0 && std::signbit(floatVal)) {
400 return minusZeroFloatConst;
401 }
402 if (ThreadEnv::IsMeParallel()) {
403 return DoGetOrCreateFloatConstThreadSafe(floatVal);
404 }
405 return DoGetOrCreateFloatConst(floatVal);
406 }
407
DoGetOrCreateFloatConst(float floatVal)408 MIRFloatConst *FPConstTable::DoGetOrCreateFloatConst(float floatVal)
409 {
410 const auto it = floatConstTable.find(floatVal);
411 if (it != floatConstTable.cend()) {
412 return it->second;
413 }
414 // create a new one
415 auto *floatConst = new MIRFloatConst(floatVal, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx {PTY_f32}));
416 floatConstTable[floatVal] = floatConst;
417 return floatConst;
418 }
419
DoGetOrCreateFloatConstThreadSafe(float floatVal)420 MIRFloatConst *FPConstTable::DoGetOrCreateFloatConstThreadSafe(float floatVal)
421 {
422 {
423 std::shared_lock<std::shared_timed_mutex> lock(floatMtx);
424 const auto it = floatConstTable.find(floatVal);
425 if (it != floatConstTable.cend()) {
426 return it->second;
427 }
428 }
429 // create a new one
430 std::unique_lock<std::shared_timed_mutex> lock(floatMtx);
431 auto *floatConst = new MIRFloatConst(floatVal, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx {PTY_f32}));
432 floatConstTable[floatVal] = floatConst;
433 return floatConst;
434 }
435
GetOrCreateDoubleConst(double doubleVal)436 MIRDoubleConst *FPConstTable::GetOrCreateDoubleConst(double doubleVal)
437 {
438 if (std::isnan(doubleVal)) {
439 return nanDoubleConst;
440 }
441 if (std::isinf(doubleVal)) {
442 return (doubleVal < 0) ? minusInfDoubleConst : infDoubleConst;
443 }
444 if (doubleVal == 0.0 && std::signbit(doubleVal)) {
445 return minusZeroDoubleConst;
446 }
447 if (ThreadEnv::IsMeParallel()) {
448 return DoGetOrCreateDoubleConstThreadSafe(doubleVal);
449 }
450 return DoGetOrCreateDoubleConst(doubleVal);
451 }
452
DoGetOrCreateDoubleConst(double doubleVal)453 MIRDoubleConst *FPConstTable::DoGetOrCreateDoubleConst(double doubleVal)
454 {
455 const auto it = doubleConstTable.find(doubleVal);
456 if (it != doubleConstTable.cend()) {
457 return it->second;
458 }
459 // create a new one
460 auto *doubleConst =
461 new MIRDoubleConst(doubleVal, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast<TyIdx>(PTY_f64)));
462 doubleConstTable[doubleVal] = doubleConst;
463 return doubleConst;
464 }
465
DoGetOrCreateDoubleConstThreadSafe(double doubleVal)466 MIRDoubleConst *FPConstTable::DoGetOrCreateDoubleConstThreadSafe(double doubleVal)
467 {
468 {
469 std::shared_lock<std::shared_timed_mutex> lock(doubleMtx);
470 const auto it = doubleConstTable.find(doubleVal);
471 if (it != doubleConstTable.cend()) {
472 return it->second;
473 }
474 }
475 // create a new one
476 std::unique_lock<std::shared_timed_mutex> lock(doubleMtx);
477 auto *doubleConst =
478 new MIRDoubleConst(doubleVal, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast<TyIdx>(PTY_f64)));
479 doubleConstTable[doubleVal] = doubleConst;
480 return doubleConst;
481 }
482
~FPConstTable()483 FPConstTable::~FPConstTable()
484 {
485 delete nanFloatConst;
486 delete infFloatConst;
487 delete minusInfFloatConst;
488 delete minusZeroFloatConst;
489 delete nanDoubleConst;
490 delete infDoubleConst;
491 delete minusInfDoubleConst;
492 delete minusZeroDoubleConst;
493 for (const auto &floatConst : floatConstTable) {
494 delete floatConst.second;
495 }
496 for (const auto &doubleConst : doubleConstTable) {
497 delete doubleConst.second;
498 }
499 }
500
GSymbolTable()501 GSymbolTable::GSymbolTable()
502 {
503 Init();
504 }
505
Init()506 void GSymbolTable::Init()
507 {
508 symbolTable.push_back(static_cast<MIRSymbol *>(nullptr));
509 }
510
Reset()511 void GSymbolTable::Reset()
512 {
513 ReleaseSymbols();
514 symbolTable.clear();
515 strIdxToStIdxMap.clear();
516 Init();
517 }
518
ReleaseSymbols()519 void GSymbolTable::ReleaseSymbols()
520 {
521 for (MIRSymbol *symbol : symbolTable) {
522 delete symbol;
523 }
524 }
525
~GSymbolTable()526 GSymbolTable::~GSymbolTable()
527 {
528 ReleaseSymbols();
529 }
530
CreateSymbol(uint8 scopeID)531 MIRSymbol *GSymbolTable::CreateSymbol(uint8 scopeID)
532 {
533 auto *st = new MIRSymbol(symbolTable.size(), scopeID);
534 CHECK_FATAL(st != nullptr, "CreateSymbol failure");
535 symbolTable.push_back(st);
536 module->AddSymbol(st);
537 return st;
538 }
539
AddToStringSymbolMap(const MIRSymbol & st)540 bool GSymbolTable::AddToStringSymbolMap(const MIRSymbol &st)
541 {
542 GStrIdx strIdx = st.GetNameStrIdx();
543 if (strIdxToStIdxMap[strIdx].FullIdx() != 0) {
544 return false;
545 }
546 strIdxToStIdxMap[strIdx] = st.GetStIdx();
547 return true;
548 }
549
RemoveFromStringSymbolMap(const MIRSymbol & st)550 bool GSymbolTable::RemoveFromStringSymbolMap(const MIRSymbol &st)
551 {
552 const auto it = strIdxToStIdxMap.find(st.GetNameStrIdx());
553 if (it != strIdxToStIdxMap.cend()) {
554 strIdxToStIdxMap.erase(it);
555 return true;
556 }
557 return false;
558 }
559
Dump(bool isLocal,int32 indent) const560 void GSymbolTable::Dump(bool isLocal, int32 indent) const
561 {
562 for (size_t i = 1; i < symbolTable.size(); ++i) {
563 const MIRSymbol *symbol = symbolTable[i];
564 if (symbol != nullptr) {
565 symbol->Dump(isLocal, indent);
566 }
567 }
568 }
569
570 GlobalTables GlobalTables::globalTables;
GetGlobalTables()571 GlobalTables &GlobalTables::GetGlobalTables()
572 {
573 return globalTables;
574 }
575 } // namespace maple
576 #endif // MIR_FEATURE_FULL
577