1 //===- MCSymbolXCOFF.h -  ----------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 #ifndef LLVM_MC_MCSYMBOLXCOFF_H
9 #define LLVM_MC_MCSYMBOLXCOFF_H
10 
11 #include "llvm/ADT/StringRef.h"
12 #include "llvm/BinaryFormat/XCOFF.h"
13 #include "llvm/MC/MCSymbol.h"
14 
15 namespace llvm {
16 
17 class MCSectionXCOFF;
18 
19 class MCSymbolXCOFF : public MCSymbol {
20 
21   enum XCOFFSymbolFlags : uint16_t { SF_EHInfo = 0x0001 };
22 
23 public:
MCSymbolXCOFF(const StringMapEntry<bool> * Name,bool isTemporary)24   MCSymbolXCOFF(const StringMapEntry<bool> *Name, bool isTemporary)
25       : MCSymbol(SymbolKindXCOFF, Name, isTemporary) {}
26 
classof(const MCSymbol * S)27   static bool classof(const MCSymbol *S) { return S->isXCOFF(); }
28 
29   enum CodeModel : uint8_t { CM_Small, CM_Large };
30 
getUnqualifiedName(StringRef Name)31   static StringRef getUnqualifiedName(StringRef Name) {
32     if (Name.back() == ']') {
33       StringRef Lhs, Rhs;
34       std::tie(Lhs, Rhs) = Name.rsplit('[');
35       assert(!Rhs.empty() && "Invalid SMC format in XCOFF symbol.");
36       return Lhs;
37     }
38     return Name;
39   }
40 
setStorageClass(XCOFF::StorageClass SC)41   void setStorageClass(XCOFF::StorageClass SC) {
42     StorageClass = SC;
43   };
44 
getStorageClass()45   XCOFF::StorageClass getStorageClass() const {
46     assert(StorageClass && "StorageClass not set on XCOFF MCSymbol.");
47     return *StorageClass;
48   }
49 
getUnqualifiedName()50   StringRef getUnqualifiedName() const { return getUnqualifiedName(getName()); }
51 
52   MCSectionXCOFF *getRepresentedCsect() const;
53 
54   void setRepresentedCsect(MCSectionXCOFF *C);
55 
setVisibilityType(XCOFF::VisibilityType SVT)56   void setVisibilityType(XCOFF::VisibilityType SVT) { VisibilityType = SVT; };
57 
getVisibilityType()58   XCOFF::VisibilityType getVisibilityType() const { return VisibilityType; }
59 
hasRename()60   bool hasRename() const { return HasRename; }
61 
setSymbolTableName(StringRef STN)62   void setSymbolTableName(StringRef STN) {
63     SymbolTableName = STN;
64     HasRename = true;
65   }
66 
getSymbolTableName()67   StringRef getSymbolTableName() const {
68     if (hasRename())
69       return SymbolTableName;
70     return getUnqualifiedName();
71   }
72 
isEHInfo()73   bool isEHInfo() const { return getFlags() & SF_EHInfo; }
74 
setEHInfo()75   void setEHInfo() const { modifyFlags(SF_EHInfo, SF_EHInfo); }
76 
hasPerSymbolCodeModel()77   bool hasPerSymbolCodeModel() const { return PerSymbolCodeModel.has_value(); }
78 
getPerSymbolCodeModel()79   CodeModel getPerSymbolCodeModel() const {
80     assert(hasPerSymbolCodeModel() &&
81            "Requested code model for symbol without one");
82     return *PerSymbolCodeModel;
83   }
84 
setPerSymbolCodeModel(MCSymbolXCOFF::CodeModel Model)85   void setPerSymbolCodeModel(MCSymbolXCOFF::CodeModel Model) {
86     PerSymbolCodeModel = Model;
87   }
88 
89 private:
90   std::optional<XCOFF::StorageClass> StorageClass;
91   std::optional<CodeModel> PerSymbolCodeModel;
92 
93   MCSectionXCOFF *RepresentedCsect = nullptr;
94   XCOFF::VisibilityType VisibilityType = XCOFF::SYM_V_UNSPECIFIED;
95   StringRef SymbolTableName;
96   bool HasRename = false;
97 };
98 
99 } // end namespace llvm
100 
101 #endif // LLVM_MC_MCSYMBOLXCOFF_H
102