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