• 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