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