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