xref: /llvm-project/llvm/include/llvm/TextAPI/Symbol.h (revision 97d72839301e6fd005fb258322b96bd46086daa1)
10116d04dSCyndy Ishida //===- llvm/TextAPI/Symbol.h - TAPI Symbol ----------------------*- C++ -*-===//
20116d04dSCyndy Ishida //
30116d04dSCyndy Ishida // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40116d04dSCyndy Ishida // See https://llvm.org/LICENSE.txt for license information.
50116d04dSCyndy Ishida // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60116d04dSCyndy Ishida //
70116d04dSCyndy Ishida //===----------------------------------------------------------------------===//
80116d04dSCyndy Ishida 
9eec96db1SKazu Hirata #ifndef LLVM_TEXTAPI_SYMBOL_H
10eec96db1SKazu Hirata #define LLVM_TEXTAPI_SYMBOL_H
110116d04dSCyndy Ishida 
120116d04dSCyndy Ishida #include "llvm/ADT/BitmaskEnum.h"
130116d04dSCyndy Ishida #include "llvm/ADT/StringRef.h"
140116d04dSCyndy Ishida #include "llvm/Support/raw_ostream.h"
150116d04dSCyndy Ishida #include "llvm/TextAPI/ArchitectureSet.h"
160116d04dSCyndy Ishida #include "llvm/TextAPI/Target.h"
170116d04dSCyndy Ishida 
180116d04dSCyndy Ishida namespace llvm {
190116d04dSCyndy Ishida namespace MachO {
200116d04dSCyndy Ishida 
210116d04dSCyndy Ishida // clang-format off
220116d04dSCyndy Ishida 
230116d04dSCyndy Ishida /// Symbol flags.
240116d04dSCyndy Ishida enum class SymbolFlags : uint8_t {
250116d04dSCyndy Ishida   /// No flags
260116d04dSCyndy Ishida   None             = 0,
270116d04dSCyndy Ishida 
280116d04dSCyndy Ishida   /// Thread-local value symbol
290116d04dSCyndy Ishida   ThreadLocalValue = 1U << 0,
300116d04dSCyndy Ishida 
310116d04dSCyndy Ishida   /// Weak defined symbol
320116d04dSCyndy Ishida   WeakDefined      = 1U << 1,
330116d04dSCyndy Ishida 
340116d04dSCyndy Ishida   /// Weak referenced symbol
350116d04dSCyndy Ishida   WeakReferenced   = 1U << 2,
360116d04dSCyndy Ishida 
370116d04dSCyndy Ishida   /// Undefined
380116d04dSCyndy Ishida   Undefined        = 1U << 3,
390116d04dSCyndy Ishida 
400116d04dSCyndy Ishida   /// Rexported
410116d04dSCyndy Ishida   Rexported        = 1U << 4,
420116d04dSCyndy Ishida 
43b70d87bcSCyndy Ishida   /// Data Segment
44b70d87bcSCyndy Ishida   Data             = 1U << 5,
45b70d87bcSCyndy Ishida 
46b70d87bcSCyndy Ishida   /// Text Segment
47b70d87bcSCyndy Ishida   Text             = 1U << 6,
48b70d87bcSCyndy Ishida 
49b70d87bcSCyndy Ishida   LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Text),
500116d04dSCyndy Ishida };
510116d04dSCyndy Ishida 
520116d04dSCyndy Ishida // clang-format on
530116d04dSCyndy Ishida 
54d9a9872eSCyndy Ishida /// Mapping of entry types in TextStubs.
55d9a9872eSCyndy Ishida enum class EncodeKind : uint8_t {
560116d04dSCyndy Ishida   GlobalSymbol,
570116d04dSCyndy Ishida   ObjectiveCClass,
580116d04dSCyndy Ishida   ObjectiveCClassEHType,
590116d04dSCyndy Ishida   ObjectiveCInstanceVariable,
600116d04dSCyndy Ishida };
610116d04dSCyndy Ishida 
6256709b86SCyndy Ishida constexpr StringLiteral ObjC1ClassNamePrefix = ".objc_class_name_";
6356709b86SCyndy Ishida constexpr StringLiteral ObjC2ClassNamePrefix = "_OBJC_CLASS_$_";
6456709b86SCyndy Ishida constexpr StringLiteral ObjC2MetaClassNamePrefix = "_OBJC_METACLASS_$_";
6556709b86SCyndy Ishida constexpr StringLiteral ObjC2EHTypePrefix = "_OBJC_EHTYPE_$_";
6656709b86SCyndy Ishida constexpr StringLiteral ObjC2IVarPrefix = "_OBJC_IVAR_$_";
6756709b86SCyndy Ishida 
684460fa88SCyndy Ishida /// ObjC Interface symbol mappings.
694460fa88SCyndy Ishida enum class ObjCIFSymbolKind : uint8_t {
704460fa88SCyndy Ishida   None = 0,
714460fa88SCyndy Ishida   /// Is OBJC_CLASS* symbol.
724460fa88SCyndy Ishida   Class = 1U << 0,
734460fa88SCyndy Ishida   /// Is OBJC_METACLASS* symbol.
744460fa88SCyndy Ishida   MetaClass = 1U << 1,
754460fa88SCyndy Ishida   /// Is OBJC_EHTYPE* symbol.
764460fa88SCyndy Ishida   EHType = 1U << 2,
774460fa88SCyndy Ishida 
784460fa88SCyndy Ishida   LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/EHType),
794460fa88SCyndy Ishida };
804460fa88SCyndy Ishida 
810116d04dSCyndy Ishida using TargetList = SmallVector<Target, 5>;
820882c70dSCyndy Ishida 
830882c70dSCyndy Ishida // Keep containers that hold Targets in sorted order and uniqued.
840882c70dSCyndy Ishida template <typename C>
addEntry(C & Container,const Target & Targ)850882c70dSCyndy Ishida typename C::iterator addEntry(C &Container, const Target &Targ) {
860882c70dSCyndy Ishida   auto Iter =
870882c70dSCyndy Ishida       lower_bound(Container, Targ, [](const Target &LHS, const Target &RHS) {
880882c70dSCyndy Ishida         return LHS < RHS;
890882c70dSCyndy Ishida       });
900882c70dSCyndy Ishida   if ((Iter != std::end(Container)) && !(Targ < *Iter))
910882c70dSCyndy Ishida     return Iter;
920882c70dSCyndy Ishida 
930882c70dSCyndy Ishida   return Container.insert(Iter, Targ);
940882c70dSCyndy Ishida }
950882c70dSCyndy Ishida 
960116d04dSCyndy Ishida class Symbol {
970116d04dSCyndy Ishida public:
Symbol(EncodeKind Kind,StringRef Name,TargetList Targets,SymbolFlags Flags)98d9a9872eSCyndy Ishida   Symbol(EncodeKind Kind, StringRef Name, TargetList Targets, SymbolFlags Flags)
990116d04dSCyndy Ishida       : Name(Name), Targets(std::move(Targets)), Kind(Kind), Flags(Flags) {}
1000116d04dSCyndy Ishida 
addTarget(Target InputTarget)1010882c70dSCyndy Ishida   void addTarget(Target InputTarget) { addEntry(Targets, InputTarget); }
getKind()102d9a9872eSCyndy Ishida   EncodeKind getKind() const { return Kind; }
getName()1030116d04dSCyndy Ishida   StringRef getName() const { return Name; }
getArchitectures()1040116d04dSCyndy Ishida   ArchitectureSet getArchitectures() const {
1050116d04dSCyndy Ishida     return mapToArchitectureSet(Targets);
1060116d04dSCyndy Ishida   }
getFlags()1070116d04dSCyndy Ishida   SymbolFlags getFlags() const { return Flags; }
1080116d04dSCyndy Ishida 
isWeakDefined()1090116d04dSCyndy Ishida   bool isWeakDefined() const {
1100116d04dSCyndy Ishida     return (Flags & SymbolFlags::WeakDefined) == SymbolFlags::WeakDefined;
1110116d04dSCyndy Ishida   }
1120116d04dSCyndy Ishida 
isWeakReferenced()1130116d04dSCyndy Ishida   bool isWeakReferenced() const {
1140116d04dSCyndy Ishida     return (Flags & SymbolFlags::WeakReferenced) == SymbolFlags::WeakReferenced;
1150116d04dSCyndy Ishida   }
1160116d04dSCyndy Ishida 
isThreadLocalValue()1170116d04dSCyndy Ishida   bool isThreadLocalValue() const {
1180116d04dSCyndy Ishida     return (Flags & SymbolFlags::ThreadLocalValue) ==
1190116d04dSCyndy Ishida            SymbolFlags::ThreadLocalValue;
1200116d04dSCyndy Ishida   }
1210116d04dSCyndy Ishida 
isUndefined()1220116d04dSCyndy Ishida   bool isUndefined() const {
1230116d04dSCyndy Ishida     return (Flags & SymbolFlags::Undefined) == SymbolFlags::Undefined;
1240116d04dSCyndy Ishida   }
1250116d04dSCyndy Ishida 
isReexported()1260116d04dSCyndy Ishida   bool isReexported() const {
1270116d04dSCyndy Ishida     return (Flags & SymbolFlags::Rexported) == SymbolFlags::Rexported;
1280116d04dSCyndy Ishida   }
1290116d04dSCyndy Ishida 
isData()130b70d87bcSCyndy Ishida   bool isData() const {
131b70d87bcSCyndy Ishida     return (Flags & SymbolFlags::Data) == SymbolFlags::Data;
132b70d87bcSCyndy Ishida   }
133b70d87bcSCyndy Ishida 
isText()134b70d87bcSCyndy Ishida   bool isText() const {
135b70d87bcSCyndy Ishida     return (Flags & SymbolFlags::Text) == SymbolFlags::Text;
136b70d87bcSCyndy Ishida   }
137b70d87bcSCyndy Ishida 
hasArchitecture(Architecture Arch)13816c1f436SCyndy Ishida   bool hasArchitecture(Architecture Arch) const {
13916c1f436SCyndy Ishida     return mapToArchitectureSet(Targets).contains(Arch);
14016c1f436SCyndy Ishida   }
14116c1f436SCyndy Ishida 
hasTarget(const Target & Targ)14227459a3aSCyndy Ishida   bool hasTarget(const Target &Targ) const {
14327459a3aSCyndy Ishida     return llvm::is_contained(Targets, Targ);
14427459a3aSCyndy Ishida   }
14527459a3aSCyndy Ishida 
1460116d04dSCyndy Ishida   using const_target_iterator = TargetList::const_iterator;
1470116d04dSCyndy Ishida   using const_target_range = llvm::iterator_range<const_target_iterator>;
targets()1480116d04dSCyndy Ishida   const_target_range targets() const { return {Targets}; }
1490116d04dSCyndy Ishida 
1500116d04dSCyndy Ishida   using const_filtered_target_iterator =
1510116d04dSCyndy Ishida       llvm::filter_iterator<const_target_iterator,
1520116d04dSCyndy Ishida                             std::function<bool(const Target &)>>;
1530116d04dSCyndy Ishida   using const_filtered_target_range =
1540116d04dSCyndy Ishida       llvm::iterator_range<const_filtered_target_iterator>;
1550116d04dSCyndy Ishida   const_filtered_target_range targets(ArchitectureSet architectures) const;
1560116d04dSCyndy Ishida 
1570116d04dSCyndy Ishida #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1580116d04dSCyndy Ishida   void dump(raw_ostream &OS) const;
dump()1590116d04dSCyndy Ishida   void dump() const { dump(llvm::errs()); }
1600116d04dSCyndy Ishida #endif
1610116d04dSCyndy Ishida 
162bc85cf16SCyndy Ishida   bool operator==(const Symbol &O) const;
1630116d04dSCyndy Ishida 
1640116d04dSCyndy Ishida   bool operator!=(const Symbol &O) const { return !(*this == O); }
1650116d04dSCyndy Ishida 
1665b5ab80eSSam Powell   bool operator<(const Symbol &O) const {
16727459a3aSCyndy Ishida     return std::tie(Kind, Name) < std::tie(O.Kind, O.Name);
1685b5ab80eSSam Powell   }
1695b5ab80eSSam Powell 
1700116d04dSCyndy Ishida private:
1710116d04dSCyndy Ishida   StringRef Name;
1720116d04dSCyndy Ishida   TargetList Targets;
173d9a9872eSCyndy Ishida   EncodeKind Kind;
1740116d04dSCyndy Ishida   SymbolFlags Flags;
1750116d04dSCyndy Ishida };
1760116d04dSCyndy Ishida 
177b04b8975SCyndy Ishida /// Lightweight struct for passing around symbol information.
178b04b8975SCyndy Ishida struct SimpleSymbol {
179b04b8975SCyndy Ishida   StringRef Name;
180d9a9872eSCyndy Ishida   EncodeKind Kind;
1814460fa88SCyndy Ishida   ObjCIFSymbolKind ObjCInterfaceType;
182b04b8975SCyndy Ishida 
183b04b8975SCyndy Ishida   bool operator<(const SimpleSymbol &O) const {
1844460fa88SCyndy Ishida     return std::tie(Name, Kind, ObjCInterfaceType) <
1854460fa88SCyndy Ishida            std::tie(O.Name, O.Kind, O.ObjCInterfaceType);
186b04b8975SCyndy Ishida   }
187b04b8975SCyndy Ishida };
188b04b8975SCyndy Ishida 
1894460fa88SCyndy Ishida /// Get symbol classification by parsing the name of a symbol.
190b04b8975SCyndy Ishida ///
191*97d72839SCyndy Ishida /// \param SymName The name of symbol.
1924460fa88SCyndy Ishida SimpleSymbol parseSymbol(StringRef SymName);
193b04b8975SCyndy Ishida 
1940116d04dSCyndy Ishida } // end namespace MachO.
1950116d04dSCyndy Ishida } // end namespace llvm.
1960116d04dSCyndy Ishida 
197eec96db1SKazu Hirata #endif // LLVM_TEXTAPI_SYMBOL_H
198