• 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 #ifndef MAPLE_IR_INCLUDE_MIR_SYMBOL_H
17 #define MAPLE_IR_INCLUDE_MIR_SYMBOL_H
18 #include <sstream>
19 #include "mir_const.h"
20 #include "mir_preg.h"
21 #include "src_position.h"
22 
23 constexpr int kScopeLocal = 2;   // the default scope level for function variables
24 constexpr int kScopeGlobal = 1;  // the scope level for global variables
25 
26 namespace maple {
27 enum MIRSymKind { kStInvalid, kStVar, kStFunc, kStConst, kStJavaClass, kStJavaInterface, kStPreg };
28 
29 enum MIRStorageClass : uint8 {
30     kScInvalid,
31     kScAuto,
32     kScAliased,
33     kScFormal,
34     kScExtern,
35     kScGlobal,
36     kScPstatic,  // PU-static
37     kScFstatic,  // file-static
38     kScText,
39     kScTypeInfo,      // used for eh type st
40     kScTypeInfoName,  // used for eh type st name
41     kScTypeCxxAbi,    // used for eh inherited from c++ __cxxabiv1
42     kScEHRegionSupp,  // used for tables that control C++ exception handling
43     kScUnused
44 };
45 
46 // to represent a single symbol
47 class MIRSymbol {
48 public:
49     union SymbolType {  // a symbol can either be a const or a function or a preg which currently used for formal
50         MIRConst *konst;
51         MIRFunction *mirFunc;
52         MIRPreg *preg;  // the MIRSymKind must be kStPreg
53     };
54 
55     MIRSymbol() = default;
MIRSymbol(uint32 idx,uint8 scp)56     MIRSymbol(uint32 idx, uint8 scp) : stIdx(scp, idx) {}
57     ~MIRSymbol() = default;
58 
SetIsTmp(bool temp)59     void SetIsTmp(bool temp)
60     {
61         isTmp = temp;
62     }
63 
GetIsTmp()64     bool GetIsTmp() const
65     {
66         return isTmp;
67     }
68 
SetNeedForwDecl()69     void SetNeedForwDecl()
70     {
71         needForwDecl = true;
72     }
73 
IsNeedForwDecl()74     bool IsNeedForwDecl() const
75     {
76         return needForwDecl;
77     }
78 
SetInstrumented()79     void SetInstrumented()
80     {
81         instrumented = true;
82     }
83 
IsInstrumented()84     bool IsInstrumented() const
85     {
86         return instrumented;
87     }
88 
SetIsImported(bool imported)89     void SetIsImported(bool imported)
90     {
91         isImported = imported;
92     }
93 
GetIsImported()94     bool GetIsImported() const
95     {
96         return isImported;
97     }
98 
SetWPOFakeParm()99     void SetWPOFakeParm()
100     {
101         wpoFakeParam = true;
102     }
103 
IsWpoFakeParm()104     bool IsWpoFakeParm() const
105     {
106         return wpoFakeParam;
107     }
108 
IsWpoFakeRet()109     bool IsWpoFakeRet() const
110     {
111         return wpoFakeRet;
112     }
113 
SetWPOFakeRet()114     void SetWPOFakeRet()
115     {
116         wpoFakeRet = true;
117     }
118 
SetIsTmpUnused(bool unused)119     void SetIsTmpUnused(bool unused)
120     {
121         isTmpUnused = unused;
122     }
123 
SetIsImportedDecl(bool imported)124     void SetIsImportedDecl(bool imported)
125     {
126         isImportedDecl = imported;
127     }
128 
GetIsImportedDecl()129     bool GetIsImportedDecl() const
130     {
131         return isImportedDecl;
132     }
133 
IsTmpUnused()134     bool IsTmpUnused() const
135     {
136         return isTmpUnused;
137     }
138 
SetAppearsInCode(bool appears)139     void SetAppearsInCode(bool appears)
140     {
141         appearsInCode = appears;
142     }
143 
GetAppearsInCode()144     bool GetAppearsInCode() const
145     {
146         return appearsInCode;
147     }
148 
SetTyIdx(TyIdx tyIdx)149     void SetTyIdx(TyIdx tyIdx)
150     {
151         this->tyIdx = tyIdx;
152     }
153 
GetTyIdx()154     TyIdx GetTyIdx() const
155     {
156         return tyIdx;
157     }
158 
SetInferredTyIdx(TyIdx inferredTyIdx)159     void SetInferredTyIdx(TyIdx inferredTyIdx)
160     {
161         this->inferredTyIdx = inferredTyIdx;
162     }
163 
GetInferredTyIdx()164     TyIdx GetInferredTyIdx() const
165     {
166         return inferredTyIdx;
167     }
168 
SetStIdx(StIdx stIdx)169     void SetStIdx(StIdx stIdx)
170     {
171         this->stIdx = stIdx;
172     }
173 
GetStIdx()174     StIdx GetStIdx() const
175     {
176         return stIdx;
177     }
178 
SetSKind(MIRSymKind m)179     void SetSKind(MIRSymKind m)
180     {
181         sKind = m;
182     }
183 
GetSKind()184     MIRSymKind GetSKind() const
185     {
186         return sKind;
187     }
188 
GetScopeIdx()189     uint32 GetScopeIdx() const
190     {
191         return stIdx.Scope();
192     }
193 
GetStIndex()194     uint32 GetStIndex() const
195     {
196         return stIdx.Idx();
197     }
198 
IsLocal()199     bool IsLocal() const
200     {
201         return stIdx.Islocal();
202     }
203 
IsGlobal()204     bool IsGlobal() const
205     {
206         return stIdx.IsGlobal();
207     }
208 
GetAttrs()209     const TypeAttrs &GetAttrs() const
210     {
211         return typeAttrs;
212     }
213 
GetAttrs()214     TypeAttrs &GetAttrs()
215     {
216         return typeAttrs;
217     }
218 
SetAttrs(TypeAttrs attr)219     void SetAttrs(TypeAttrs attr)
220     {
221         typeAttrs = attr;
222     }
223 
224     // AddAttrs adds more attributes instead of overrides the current one
AddAttrs(TypeAttrs attr)225     void AddAttrs(TypeAttrs attr)
226     {
227         typeAttrs.SetAttrFlag(typeAttrs.GetAttrFlag() | attr.GetAttrFlag());
228         typeAttrs.AddAttrBoundary(attr.GetAttrBoundary());
229     }
230 
GetAttr(AttrKind attrKind)231     bool GetAttr(AttrKind attrKind) const
232     {
233         return typeAttrs.GetAttr(attrKind);
234     }
235 
SetAttr(AttrKind attrKind)236     void SetAttr(AttrKind attrKind)
237     {
238         typeAttrs.SetAttr(attrKind);
239     }
240 
ResetAttr(AttrKind attrKind)241     void ResetAttr(AttrKind attrKind)
242     {
243         typeAttrs.ResetAttr(attrKind);
244     }
245 
IsVolatile()246     bool IsVolatile() const
247     {
248         return typeAttrs.GetAttr(ATTR_volatile);
249     }
250 
251     bool IsTypeVolatile(int fieldID) const;
252 
253     bool NeedPIC() const;
254 
IsThreadLocal()255     bool IsThreadLocal() const
256     {
257         return typeAttrs.GetAttr(ATTR_tls_static) || typeAttrs.GetAttr(ATTR_tls_dynamic);
258     }
259 
IsStatic()260     bool IsStatic() const
261     {
262         return typeAttrs.GetAttr(ATTR_static);
263     }
264 
IsPUStatic()265     bool IsPUStatic() const
266     {
267         return GetStorageClass() == kScPstatic;
268     }
269 
IsFinal()270     bool IsFinal() const
271     {
272         return ((typeAttrs.GetAttr(ATTR_final) || typeAttrs.GetAttr(ATTR_readonly)) &&
273                 staticFinalBlackList.find(GetName()) == staticFinalBlackList.end()) ||
274                IsLiteral() || IsLiteralPtr();
275     }
276 
IsWeak()277     bool IsWeak() const
278     {
279         return typeAttrs.GetAttr(ATTR_weak);
280     }
281 
IsPrivate()282     bool IsPrivate() const
283     {
284         return typeAttrs.GetAttr(ATTR_private);
285     }
286 
IsRefType()287     bool IsRefType() const
288     {
289         return typeAttrs.GetAttr(ATTR_localrefvar);
290     }
291 
SetNameStrIdx(GStrIdx strIdx)292     void SetNameStrIdx(GStrIdx strIdx)
293     {
294         nameStrIdx = strIdx;
295     }
296 
297     void SetNameStrIdx(const std::string &name);
298 
GetNameStrIdx()299     GStrIdx GetNameStrIdx() const
300     {
301         return nameStrIdx;
302     }
303 
GetStorageClass()304     MIRStorageClass GetStorageClass() const
305     {
306         return storageClass;
307     }
308 
SetStorageClass(MIRStorageClass cl)309     void SetStorageClass(MIRStorageClass cl)
310     {
311         storageClass = cl;
312     }
313 
IsReadOnly()314     bool IsReadOnly() const
315     {
316         return kScFstatic == storageClass && kStConst == sKind;
317     }
318 
IsConst()319     bool IsConst() const
320     {
321         return sKind == kStConst || (sKind == kStVar && value.konst != nullptr);
322     }
323 
324     MIRType *GetType() const;
325 
GetName()326     const std::string &GetName() const
327     {
328         return GlobalTables::GetStrTable().GetStringFromStrIdx(nameStrIdx);
329     }
330 
GetKonst()331     MIRConst *GetKonst() const
332     {
333         DEBUG_ASSERT((sKind == kStConst || sKind == kStVar), "must be const symbol");
334         return value.konst;
335     }
336 
SetKonst(MIRConst * mirconst)337     void SetKonst(MIRConst *mirconst)
338     {
339         DEBUG_ASSERT((sKind == kStConst || sKind == kStVar), "must be const symbol");
340         value.konst = mirconst;
341     }
342 
SetIsDeleted()343     void SetIsDeleted()
344     {
345         isDeleted = true;
346     }
347 
ResetIsDeleted()348     void ResetIsDeleted()
349     {
350         isDeleted = false;
351     }
352 
IsDeleted()353     bool IsDeleted() const
354     {
355         return isDeleted;
356     }
357 
IsVar()358     bool IsVar() const
359     {
360         return sKind == kStVar;
361     }
362 
IsPreg()363     bool IsPreg() const
364     {
365         return sKind == kStPreg;
366     }
367 
IsJavaClassInterface()368     bool IsJavaClassInterface() const
369     {
370         return sKind == kStJavaClass || sKind == kStJavaInterface;
371     }
372 
GetValue()373     SymbolType GetValue() const
374     {
375         return value;
376     }
377 
SetValue(SymbolType value)378     void SetValue(SymbolType value)
379     {
380         this->value = value;
381     }
382 
GetSrcPosition()383     SrcPosition &GetSrcPosition()
384     {
385         return srcPosition;
386     }
387 
GetSrcPosition()388     const SrcPosition &GetSrcPosition() const
389     {
390         return srcPosition;
391     }
392 
SetSrcPosition(const SrcPosition & position)393     void SetSrcPosition(const SrcPosition &position)
394     {
395         srcPosition = position;
396     }
397 
GetPreg()398     MIRPreg *GetPreg()
399     {
400         DEBUG_ASSERT(IsPreg(), "must be Preg");
401         return value.preg;
402     }
403 
GetPreg()404     const MIRPreg *GetPreg() const
405     {
406         CHECK_FATAL(IsPreg(), "must be Preg");
407         return value.preg;
408     }
409 
SetPreg(MIRPreg * preg)410     void SetPreg(MIRPreg *preg)
411     {
412         CHECK_FATAL(IsPreg(), "must be Preg");
413         value.preg = preg;
414     }
415 
CanBeIgnored()416     bool CanBeIgnored() const
417     {
418         return isDeleted;
419     }
420 
SetLocalRefVar()421     void SetLocalRefVar()
422     {
423         SetAttr(ATTR_localrefvar);
424     }
425 
ResetLocalRefVar()426     void ResetLocalRefVar()
427     {
428         ResetAttr(ATTR_localrefvar);
429     }
430 
GetFunction()431     MIRFunction *GetFunction() const
432     {
433         DEBUG_ASSERT(sKind == kStFunc, "must be function symbol");
434         return value.mirFunc;
435     }
436 
SetFunction(MIRFunction * func)437     void SetFunction(MIRFunction *func)
438     {
439         DEBUG_ASSERT(sKind == kStFunc, "must be function symbol");
440         value.mirFunc = func;
441     }
442 
IsEhIndex()443     bool IsEhIndex() const
444     {
445         return GetName() == "__eh_index__";
446     }
447 
448     bool HasAddrOfValues() const;
449     bool IsLiteral() const;
450     bool IsLiteralPtr() const;
451     bool PointsToConstString() const;
452     bool IsConstString() const;
453     bool IsClassInitBridge() const;
454     bool IsReflectionStrTab() const;
455     bool IsReflectionHashTabBucket() const;
456     bool IsReflectionInfo() const;
457     bool IsReflectionFieldsInfo() const;
458     bool IsReflectionFieldsInfoCompact() const;
459     bool IsReflectionSuperclassInfo() const;
460     bool IsReflectionFieldOffsetData() const;
461     bool IsReflectionMethodAddrData() const;
462     bool IsReflectionMethodSignature() const;
463     bool IsReflectionClassInfo() const;
464     bool IsReflectionArrayClassInfo() const;
465     bool IsReflectionClassInfoPtr() const;
466     bool IsReflectionClassInfoRO() const;
467     bool IsITabConflictInfo() const;
468     bool IsVTabInfo() const;
469     bool IsITabInfo() const;
470     bool IsReflectionPrimitiveClassInfo() const;
471     bool IsReflectionMethodsInfo() const;
472     bool IsReflectionMethodsInfoCompact() const;
473     bool IsRegJNITab() const;
474     bool IsRegJNIFuncTab() const;
475     bool IsMuidTab() const;
476     bool IsMuidRoTab() const;
477     bool IsCodeLayoutInfo() const;
478     std::string GetMuidTabName() const;
479     bool IsMuidFuncDefTab() const;
480     bool IsMuidFuncDefOrigTab() const;
481     bool IsMuidFuncInfTab() const;
482     bool IsMuidFuncUndefTab() const;
483     bool IsMuidDataDefTab() const;
484     bool IsMuidDataDefOrigTab() const;
485     bool IsMuidDataUndefTab() const;
486     bool IsMuidFuncDefMuidTab() const;
487     bool IsMuidFuncUndefMuidTab() const;
488     bool IsMuidDataDefMuidTab() const;
489     bool IsMuidDataUndefMuidTab() const;
490     bool IsMuidFuncMuidIdxMuidTab() const;
491     bool IsMuidRangeTab() const;
492     bool IsArrayClassCache() const;
493     bool IsArrayClassCacheName() const;
494     bool IsForcedGlobalFunc() const;
495     bool IsForcedGlobalClassinfo() const;
496     bool IsGctibSym() const;
497     bool IsPrimordialObject() const;
498     bool IgnoreRC() const;
499     void Dump(bool isLocal, int32 indent, bool suppressInit = false, const MIRSymbolTable *localsymtab = nullptr) const;
500     void DumpAsLiteralVar() const;
501     bool operator==(const MIRSymbol &msym) const
502     {
503         return nameStrIdx == msym.nameStrIdx;
504     }
505 
506     bool operator!=(const MIRSymbol &msym) const
507     {
508         return nameStrIdx != msym.nameStrIdx;
509     }
510 
511     bool operator<(const MIRSymbol &msym) const
512     {
513         return nameStrIdx < msym.nameStrIdx;
514     }
515 
LastPrintedLineNumRef()516     static uint32 &LastPrintedLineNumRef()
517     {
518         return lastPrintedLineNum;
519     }
520 
LastPrintedColumnNumRef()521     static uint16 &LastPrintedColumnNumRef()
522     {
523         return lastPrintedColumnNum;
524     }
525 
HasPotentialAssignment()526     bool HasPotentialAssignment() const
527     {
528         return hasPotentialAssignment;
529     }
530 
SetHasPotentialAssignment()531     void SetHasPotentialAssignment()
532     {
533         hasPotentialAssignment = true;
534     }
535 
SetAsmAttr(const UStrIdx & idx)536     void SetAsmAttr(const UStrIdx &idx)
537     {
538         asmAttr = idx;
539     }
540 
GetAsmAttr()541     const UStrIdx &GetAsmAttr() const
542     {
543         return asmAttr;
544     }
545 
SetWeakrefAttr(const std::pair<bool,UStrIdx> & idx)546     void SetWeakrefAttr(const std::pair<bool, UStrIdx> &idx)
547     {
548         weakrefAttr = idx;
549     }
550 
GetWeakrefAttr()551     const std::pair<bool, UStrIdx> &GetWeakrefAttr() const
552     {
553         return weakrefAttr;
554     }
555 
IsFormal()556     bool IsFormal() const
557     {
558         return storageClass == kScFormal;
559     }
560 
LMBCAllocateOffSpecialReg()561     bool LMBCAllocateOffSpecialReg() const
562     {
563         if (isDeleted) {
564             return false;
565         }
566         switch (storageClass) {
567             case kScAuto:
568                 return true;
569             case kScPstatic:
570             case kScFstatic:
571                 return value.konst == nullptr && !hasPotentialAssignment;
572             default:
573                 return false;
574         }
575     }
576 
577     // Please keep order of the fields, avoid paddings.
578 private:
579     TyIdx tyIdx {0};
580     TyIdx inferredTyIdx {kInitTyIdx};
581     MIRStorageClass storageClass {kScInvalid};
582     MIRSymKind sKind {kStInvalid};
583     bool isTmp = false;
584     bool needForwDecl = false;  // addrof of this symbol used in initialization, NOT serialized
585     bool wpoFakeParam = false;  // fake symbol introduced in wpo phase for a parameter, NOT serialized
586     bool wpoFakeRet = false;    // fake symbol introduced in wpo phase for return value, NOT serialized
587     bool isDeleted = false;     // tell if it is deleted, NOT serialized
588     bool instrumented = false;  // a local ref pointer instrumented by RC opt, NOT serialized
589     bool isImported = false;
590     bool isImportedDecl = false;
591     bool isTmpUnused = false;             // when parse the mplt_inline file, mark all the new symbol as tmpunused
592     bool appearsInCode = false;           // only used for kStFunc
593     bool hasPotentialAssignment = false;  // for global static vars, init as false and will be set true
594                                           // if assigned by stmt or the address of itself is taken
595     StIdx stIdx {0, 0};
596     TypeAttrs typeAttrs;
597     GStrIdx nameStrIdx {0};
598     std::pair<bool, UStrIdx> weakrefAttr {false, 0};
599 
600 public:
601     UStrIdx asmAttr {0};      // if not 0, the string for the name in C's asm attribute
602     UStrIdx sectionAttr {0};  // if not 0, the string for the name in C's section attribute
603 private:
604     SymbolType value = {nullptr};
605     SrcPosition srcPosition;  // where the symbol is defined
606     // following cannot be assumed final even though they are declared final
607     static const std::set<std::string> staticFinalBlackList;
608     static GStrIdx reflectClassNameIdx;
609     static GStrIdx reflectMethodNameIdx;
610     static GStrIdx reflectFieldNameIdx;
611     static uint32 lastPrintedLineNum;  // used during printing ascii output
612     static uint16 lastPrintedColumnNum;
613 };
614 
615 class MIRSymbolTable {
616 public:
MIRSymbolTable(const MapleAllocator & allocator)617     explicit MIRSymbolTable(const MapleAllocator &allocator)
618         : mAllocator(allocator), strIdxToStIdxMap(mAllocator.Adapter()), symbolTable({nullptr}, mAllocator.Adapter())
619     {
620     }
621 
622     ~MIRSymbolTable() = default;
623 
IsValidIdx(uint32 idx)624     bool IsValidIdx(uint32 idx) const
625     {
626         return idx < symbolTable.size();
627     }
628 
629     MIRSymbol *GetSymbolFromStIdx(uint32 idx, bool checkFirst = false) const
630     {
631         if (checkFirst && idx >= symbolTable.size()) {
632             return nullptr;
633         }
634         CHECK_FATAL(IsValidIdx(idx), "symbol table index out of range");
635         return symbolTable[idx];
636     }
637 
CreateSymbol(uint8 scopeID)638     MIRSymbol *CreateSymbol(uint8 scopeID)
639     {
640         auto *st = mAllocator.GetMemPool()->New<MIRSymbol>(symbolTable.size(), scopeID);
641         symbolTable.push_back(st);
642         return st;
643     }
644 
PushNullSymbol()645     void PushNullSymbol()
646     {
647         symbolTable.push_back(nullptr);
648     }
649 
650     // add sym from other symbol table, happens in inline
AddStOutside(MIRSymbol * sym)651     bool AddStOutside(MIRSymbol *sym)
652     {
653         if (sym == nullptr) {
654             return false;
655         }
656         sym->SetStIdx(StIdx(sym->GetScopeIdx(), symbolTable.size()));
657         symbolTable.push_back(sym);
658         return AddToStringSymbolMap(*sym);
659     }
660 
AddToStringSymbolMap(const MIRSymbol & st)661     bool AddToStringSymbolMap(const MIRSymbol &st)
662     {
663         GStrIdx strIdx = st.GetNameStrIdx();
664         if (strIdxToStIdxMap[strIdx].FullIdx() != 0) {
665             return false;
666         }
667         strIdxToStIdxMap[strIdx] = st.GetStIdx();
668         return true;
669     }
670 
GetStIdxFromStrIdx(GStrIdx idx)671     StIdx GetStIdxFromStrIdx(GStrIdx idx) const
672     {
673         auto it = strIdxToStIdxMap.find(idx);
674         return (it == strIdxToStIdxMap.end()) ? StIdx() : it->second;
675     }
676 
677     MIRSymbol *GetSymbolFromStrIdx(GStrIdx idx, bool checkFirst = false)
678     {
679         return GetSymbolFromStIdx(GetStIdxFromStrIdx(idx).Idx(), checkFirst);
680     }
681 
682     void Dump(bool isLocal, int32 indent = 0, bool printDeleted = false, MIRFlavor flavor = kFlavorUnknown) const;
683 
GetSymbolTableSize()684     size_t GetSymbolTableSize() const
685     {
686         return symbolTable.size();
687     }
688 
GetTable()689     MapleVector<MIRSymbol *> &GetTable()
690     {
691         return symbolTable;
692     }
693 
GetTable()694     const MapleVector<MIRSymbol *> &GetTable() const
695     {
696         return symbolTable;
697     }
698 
GetSymbolAt(uint32 idx)699     const MIRSymbol *GetSymbolAt(uint32 idx) const
700     {
701         DEBUG_ASSERT(idx < symbolTable.size(), "symbol id out of table range");
702         return symbolTable[idx];
703     }
704 
GetSymbolAt(uint32 idx)705     MIRSymbol *GetSymbolAt(uint32 idx)
706     {
707         return const_cast<MIRSymbol *>(const_cast<const MIRSymbolTable *>(this)->GetSymbolAt(idx));
708     }
709 
Clear()710     void Clear()
711     {
712         symbolTable.clear();
713         strIdxToStIdxMap.clear();
714     }
715 
CloneLocalSymbol(const MIRSymbol & oldSym)716     MIRSymbol *CloneLocalSymbol(const MIRSymbol &oldSym) const
717     {
718         auto *memPool = mAllocator.GetMemPool();
719         auto *newSym = memPool->New<MIRSymbol>(oldSym);
720         if (oldSym.GetSKind() == kStConst) {
721             newSym->SetKonst(oldSym.GetKonst()->Clone(*memPool));
722         } else if (oldSym.GetSKind() == kStPreg) {
723             newSym->SetPreg(memPool->New<MIRPreg>(*oldSym.GetPreg()));
724         } else if (oldSym.GetSKind() == kStFunc) {
725             CHECK_FATAL(false, "%s has unexpected local func symbol", oldSym.GetName().c_str());
726         }
727         return newSym;
728     }
729 
730 private:
731     MapleAllocator mAllocator;
732     // hash table mapping string index to st index
733     MapleMap<GStrIdx, StIdx> strIdxToStIdxMap;
734     // map symbol idx to symbol node
735     MapleVector<MIRSymbol *> symbolTable;
736 };
737 
738 class MIRLabelTable {
739 public:
MIRLabelTable(MapleAllocator & allocator)740     explicit MIRLabelTable(MapleAllocator &allocator)
741         : addrTakenLabels(allocator.Adapter()),
742           caseLabelSet(allocator.Adapter()),
743           mAllocator(allocator),
744           strIdxToLabIdxMap(std::less<GStrIdx>(), mAllocator.Adapter()),
745           labelTable(mAllocator.Adapter())
746     {
747         labelTable.push_back(GStrIdx(kDummyLabel));  // push dummy label index 0
748     }
749 
750     ~MIRLabelTable() = default;
751 
CreateLabel()752     LabelIdx CreateLabel()
753     {
754         LabelIdx labelIdx = labelTable.size();
755         GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(std::to_string(labelIdx));
756         labelTable.push_back(strIdx);
757         return labelIdx;
758     }
759 
760     LabelIdx CreateLabelWithPrefix(char c);
761 
AddLabel(GStrIdx nameIdx)762     LabelIdx AddLabel(GStrIdx nameIdx)
763     {
764         LabelIdx labelIdx = labelTable.size();
765         labelTable.push_back(nameIdx);
766         strIdxToLabIdxMap[nameIdx] = labelIdx;
767         return labelIdx;
768     }
769 
GetLabelIdxFromStrIdx(GStrIdx idx)770     LabelIdx GetLabelIdxFromStrIdx(GStrIdx idx) const
771     {
772         auto it = strIdxToLabIdxMap.find(idx);
773         if (it == strIdxToLabIdxMap.end()) {
774             return LabelIdx();
775         }
776         return it->second;
777     }
778 
779     void AddToStringLabelMap(LabelIdx labelIdx);
GetLabelTableSize()780     size_t GetLabelTableSize() const
781     {
782         return labelTable.size();
783     }
784 
785     const std::string &GetName(LabelIdx labelIdx) const;
786 
Size()787     size_t Size() const
788     {
789         return labelTable.size();
790     }
791 
GetDummyLabel()792     static uint32 GetDummyLabel()
793     {
794         return kDummyLabel;
795     }
796 
GetSymbolFromStIdx(LabelIdx idx)797     GStrIdx GetSymbolFromStIdx(LabelIdx idx) const
798     {
799         CHECK_FATAL(idx < labelTable.size(), "label table index out of range");
800         return labelTable[idx];
801     }
802 
SetSymbolFromStIdx(LabelIdx idx,GStrIdx strIdx)803     void SetSymbolFromStIdx(LabelIdx idx, GStrIdx strIdx)
804     {
805         CHECK_FATAL(idx < labelTable.size(), "label table index out of range");
806         labelTable[idx] = strIdx;
807     }
808 
GetLabelTable()809     MapleVector<GStrIdx> GetLabelTable()
810     {
811         return labelTable;
812     }
813 
GetAddrTakenLabels()814     const MapleUnorderedSet<LabelIdx> &GetAddrTakenLabels() const
815     {
816         return addrTakenLabels;
817     }
818 
GetAddrTakenLabels()819     MapleUnorderedSet<LabelIdx> &GetAddrTakenLabels()
820     {
821         return addrTakenLabels;
822     }
823 
GetStrIdxToLabelIdxMap()824     const MapleMap<GStrIdx, LabelIdx> &GetStrIdxToLabelIdxMap() const
825     {
826         return strIdxToLabIdxMap;
827     }
EraseStrIdxToLabelIdxElem(GStrIdx idx)828     void EraseStrIdxToLabelIdxElem(GStrIdx idx)
829     {
830         strIdxToLabIdxMap.erase(idx);
831     }
832 
833     MapleUnorderedSet<LabelIdx> addrTakenLabels;  // those appeared in addroflabel or MIRLblConst
834     MapleUnorderedSet<LabelIdx> caseLabelSet;     // labels marking starts of switch cases
835 
836 private:
837     static constexpr uint32 kDummyLabel = 0;
838     MapleAllocator mAllocator;
839     MapleMap<GStrIdx, LabelIdx> strIdxToLabIdxMap;
840     MapleVector<GStrIdx> labelTable;  // map label idx to label name
841 };
842 }  // namespace maple
843 #endif  // MAPLE_IR_INCLUDE_MIR_SYMBOL_H
844