Home | History | Annotate | Download | only in AST
      1 //===--- Mangle.h - Mangle C++ Names ----------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // Defines the C++ name mangling interface.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_CLANG_AST_MANGLE_H
     15 #define LLVM_CLANG_AST_MANGLE_H
     16 
     17 #include "clang/AST/Type.h"
     18 #include "clang/Basic/ABI.h"
     19 #include "llvm/ADT/DenseMap.h"
     20 #include "llvm/Support/Casting.h"
     21 
     22 namespace llvm {
     23   class raw_ostream;
     24 }
     25 
     26 namespace clang {
     27   class ASTContext;
     28   class BlockDecl;
     29   class CXXConstructorDecl;
     30   class CXXDestructorDecl;
     31   class CXXMethodDecl;
     32   class FunctionDecl;
     33   class NamedDecl;
     34   class ObjCMethodDecl;
     35   class StringLiteral;
     36   struct ThisAdjustment;
     37   struct ThunkInfo;
     38   class VarDecl;
     39 
     40 /// MangleContext - Context for tracking state which persists across multiple
     41 /// calls to the C++ name mangler.
     42 class MangleContext {
     43 public:
     44   enum ManglerKind {
     45     MK_Itanium,
     46     MK_Microsoft
     47   };
     48 
     49 private:
     50   virtual void anchor();
     51 
     52   ASTContext &Context;
     53   DiagnosticsEngine &Diags;
     54   const ManglerKind Kind;
     55 
     56   llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
     57   llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
     58   llvm::DenseMap<const TagDecl*, uint64_t> AnonStructIds;
     59 
     60 public:
     61   ManglerKind getKind() const { return Kind; }
     62 
     63   explicit MangleContext(ASTContext &Context,
     64                          DiagnosticsEngine &Diags,
     65                          ManglerKind Kind)
     66       : Context(Context), Diags(Diags), Kind(Kind) {}
     67 
     68   virtual ~MangleContext() { }
     69 
     70   ASTContext &getASTContext() const { return Context; }
     71 
     72   DiagnosticsEngine &getDiags() const { return Diags; }
     73 
     74   virtual void startNewFunction() { LocalBlockIds.clear(); }
     75 
     76   unsigned getBlockId(const BlockDecl *BD, bool Local) {
     77     llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
     78       = Local? LocalBlockIds : GlobalBlockIds;
     79     std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
     80       Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
     81     return Result.first->second;
     82   }
     83 
     84   uint64_t getAnonymousStructId(const TagDecl *TD) {
     85     std::pair<llvm::DenseMap<const TagDecl *, uint64_t>::iterator, bool>
     86         Result = AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
     87     return Result.first->second;
     88   }
     89 
     90   /// @name Mangler Entry Points
     91   /// @{
     92 
     93   bool shouldMangleDeclName(const NamedDecl *D);
     94   virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
     95   virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
     96 
     97   // FIXME: consider replacing raw_ostream & with something like SmallString &.
     98   void mangleName(const NamedDecl *D, raw_ostream &);
     99   virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0;
    100   virtual void mangleThunk(const CXXMethodDecl *MD,
    101                           const ThunkInfo &Thunk,
    102                           raw_ostream &) = 0;
    103   virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
    104                                   const ThisAdjustment &ThisAdjustment,
    105                                   raw_ostream &) = 0;
    106   virtual void mangleReferenceTemporary(const VarDecl *D,
    107                                         unsigned ManglingNumber,
    108                                         raw_ostream &) = 0;
    109   virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
    110   virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
    111   virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
    112                              raw_ostream &) = 0;
    113   virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
    114                              raw_ostream &) = 0;
    115   virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
    116 
    117   void mangleGlobalBlock(const BlockDecl *BD,
    118                          const NamedDecl *ID,
    119                          raw_ostream &Out);
    120   void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
    121                        const BlockDecl *BD, raw_ostream &Out);
    122   void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
    123                        const BlockDecl *BD, raw_ostream &Out);
    124   void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
    125                    raw_ostream &Out);
    126 
    127   void mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD, raw_ostream &);
    128   void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &);
    129 
    130   virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
    131 
    132   virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
    133 
    134   virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
    135                                              raw_ostream &) = 0;
    136 
    137   virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl,
    138                                          raw_ostream &Out) = 0;
    139 
    140   virtual void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl,
    141                                      raw_ostream &Out) = 0;
    142 
    143   /// Generates a unique string for an externally visible type for use with TBAA
    144   /// or type uniquing.
    145   /// TODO: Extend this to internal types by generating names that are unique
    146   /// across translation units so it can be used with LTO.
    147   virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
    148 
    149   /// @}
    150 };
    151 
    152 class ItaniumMangleContext : public MangleContext {
    153 public:
    154   explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
    155       : MangleContext(C, D, MK_Itanium) {}
    156 
    157   virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
    158   virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
    159   virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
    160                                    const CXXRecordDecl *Type,
    161                                    raw_ostream &) = 0;
    162   virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
    163                                             raw_ostream &) = 0;
    164   virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
    165                                                raw_ostream &) = 0;
    166 
    167   virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D,
    168                                    raw_ostream &) = 0;
    169   virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D,
    170                                    raw_ostream &) = 0;
    171 
    172   static bool classof(const MangleContext *C) {
    173     return C->getKind() == MK_Itanium;
    174   }
    175 
    176   static ItaniumMangleContext *create(ASTContext &Context,
    177                                       DiagnosticsEngine &Diags);
    178 };
    179 
    180 class MicrosoftMangleContext : public MangleContext {
    181 public:
    182   explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D)
    183       : MangleContext(C, D, MK_Microsoft) {}
    184 
    185   /// \brief Mangle vftable symbols.  Only a subset of the bases along the path
    186   /// to the vftable are included in the name.  It's up to the caller to pick
    187   /// them correctly.
    188   virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
    189                                 ArrayRef<const CXXRecordDecl *> BasePath,
    190                                 raw_ostream &Out) = 0;
    191 
    192   /// \brief Mangle vbtable symbols.  Only a subset of the bases along the path
    193   /// to the vbtable are included in the name.  It's up to the caller to pick
    194   /// them correctly.
    195   virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
    196                                 ArrayRef<const CXXRecordDecl *> BasePath,
    197                                 raw_ostream &Out) = 0;
    198 
    199   virtual void mangleThreadSafeStaticGuardVariable(const VarDecl *VD,
    200                                                    unsigned GuardNum,
    201                                                    raw_ostream &Out) = 0;
    202 
    203   virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
    204                                         raw_ostream &) = 0;
    205 
    206   virtual void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD,
    207                                                const CXXRecordDecl *DstRD,
    208                                                raw_ostream &Out) = 0;
    209 
    210   virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,
    211                                   bool IsUnaligned, uint32_t NumEntries,
    212                                   raw_ostream &Out) = 0;
    213 
    214   virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
    215                                            raw_ostream &Out) = 0;
    216 
    217   virtual void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD,
    218                                       CXXCtorType CT, uint32_t Size,
    219                                       uint32_t NVOffset, int32_t VBPtrOffset,
    220                                       uint32_t VBIndex, raw_ostream &Out) = 0;
    221 
    222   virtual void mangleCXXRTTIBaseClassDescriptor(
    223       const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
    224       uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
    225 
    226   virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
    227                                            raw_ostream &Out) = 0;
    228   virtual void
    229   mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
    230                                         raw_ostream &Out) = 0;
    231 
    232   virtual void
    233   mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
    234                                      ArrayRef<const CXXRecordDecl *> BasePath,
    235                                      raw_ostream &Out) = 0;
    236 
    237   static bool classof(const MangleContext *C) {
    238     return C->getKind() == MK_Microsoft;
    239   }
    240 
    241   static MicrosoftMangleContext *create(ASTContext &Context,
    242                                         DiagnosticsEngine &Diags);
    243 };
    244 }
    245 
    246 #endif
    247