clang API Documentation

Mangle.h
Go to the documentation of this file.
00001 //===--- Mangle.h - Mangle C++ Names ----------------------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // Defines the C++ name mangling interface.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_CLANG_AST_MANGLE_H
00015 #define LLVM_CLANG_AST_MANGLE_H
00016 
00017 #include "clang/AST/Type.h"
00018 #include "clang/Basic/ABI.h"
00019 #include "llvm/ADT/DenseMap.h"
00020 #include "llvm/ADT/SmallString.h"
00021 #include "llvm/ADT/StringRef.h"
00022 #include "llvm/Support/Casting.h"
00023 #include "llvm/Support/raw_ostream.h"
00024 
00025 namespace clang {
00026   class ASTContext;
00027   class BlockDecl;
00028   class CXXConstructorDecl;
00029   class CXXDestructorDecl;
00030   class CXXMethodDecl;
00031   class FunctionDecl;
00032   class NamedDecl;
00033   class ObjCMethodDecl;
00034   class StringLiteral;
00035   struct ThisAdjustment;
00036   struct ThunkInfo;
00037   class VarDecl;
00038 
00039 /// MangleContext - Context for tracking state which persists across multiple
00040 /// calls to the C++ name mangler.
00041 class MangleContext {
00042 public:
00043   enum ManglerKind {
00044     MK_Itanium,
00045     MK_Microsoft
00046   };
00047 
00048 private:
00049   virtual void anchor();
00050 
00051   ASTContext &Context;
00052   DiagnosticsEngine &Diags;
00053   const ManglerKind Kind;
00054 
00055   llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
00056   llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
00057   llvm::DenseMap<const TagDecl*, uint64_t> AnonStructIds;
00058 
00059 public:
00060   ManglerKind getKind() const { return Kind; }
00061 
00062   explicit MangleContext(ASTContext &Context,
00063                          DiagnosticsEngine &Diags,
00064                          ManglerKind Kind)
00065       : Context(Context), Diags(Diags), Kind(Kind) {}
00066 
00067   virtual ~MangleContext() { }
00068 
00069   ASTContext &getASTContext() const { return Context; }
00070 
00071   DiagnosticsEngine &getDiags() const { return Diags; }
00072 
00073   virtual void startNewFunction() { LocalBlockIds.clear(); }
00074   
00075   unsigned getBlockId(const BlockDecl *BD, bool Local) {
00076     llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
00077       = Local? LocalBlockIds : GlobalBlockIds;
00078     std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
00079       Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
00080     return Result.first->second;
00081   }
00082 
00083   uint64_t getAnonymousStructId(const TagDecl *TD) {
00084     std::pair<llvm::DenseMap<const TagDecl *, uint64_t>::iterator, bool>
00085         Result = AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
00086     return Result.first->second;
00087   }
00088 
00089   /// @name Mangler Entry Points
00090   /// @{
00091 
00092   bool shouldMangleDeclName(const NamedDecl *D);
00093   virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
00094   virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
00095 
00096   // FIXME: consider replacing raw_ostream & with something like SmallString &.
00097   void mangleName(const NamedDecl *D, raw_ostream &);
00098   virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0;
00099   virtual void mangleThunk(const CXXMethodDecl *MD,
00100                           const ThunkInfo &Thunk,
00101                           raw_ostream &) = 0;
00102   virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
00103                                   const ThisAdjustment &ThisAdjustment,
00104                                   raw_ostream &) = 0;
00105   virtual void mangleReferenceTemporary(const VarDecl *D,
00106                                         unsigned ManglingNumber,
00107                                         raw_ostream &) = 0;
00108   virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
00109   virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
00110   virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
00111                              raw_ostream &) = 0;
00112   virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
00113                              raw_ostream &) = 0;
00114   virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
00115 
00116   void mangleGlobalBlock(const BlockDecl *BD,
00117                          const NamedDecl *ID,
00118                          raw_ostream &Out);
00119   void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
00120                        const BlockDecl *BD, raw_ostream &Out);
00121   void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
00122                        const BlockDecl *BD, raw_ostream &Out);
00123   void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
00124                    raw_ostream &Out);
00125 
00126   void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &);
00127 
00128   virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
00129 
00130   virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
00131 
00132   virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
00133                                              raw_ostream &) = 0;
00134 
00135   /// Generates a unique string for an externally visible type for use with TBAA
00136   /// or type uniquing.
00137   /// TODO: Extend this to internal types by generating names that are unique
00138   /// across translation units so it can be used with LTO.
00139   virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
00140 
00141   /// @}
00142 };
00143 
00144 class ItaniumMangleContext : public MangleContext {
00145 public:
00146   explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
00147       : MangleContext(C, D, MK_Itanium) {}
00148 
00149   virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
00150   virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
00151   virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
00152                                    const CXXRecordDecl *Type,
00153                                    raw_ostream &) = 0;
00154   virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
00155                                             raw_ostream &) = 0;
00156   virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
00157                                                raw_ostream &) = 0;
00158 
00159   virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D,
00160                                    raw_ostream &) = 0;
00161   virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D,
00162                                    raw_ostream &) = 0;
00163 
00164   static bool classof(const MangleContext *C) {
00165     return C->getKind() == MK_Itanium;
00166   }
00167 
00168   static ItaniumMangleContext *create(ASTContext &Context,
00169                                       DiagnosticsEngine &Diags);
00170 };
00171 
00172 class MicrosoftMangleContext : public MangleContext {
00173 public:
00174   explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D)
00175       : MangleContext(C, D, MK_Microsoft) {}
00176 
00177   /// \brief Mangle vftable symbols.  Only a subset of the bases along the path
00178   /// to the vftable are included in the name.  It's up to the caller to pick
00179   /// them correctly.
00180   virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
00181                                 ArrayRef<const CXXRecordDecl *> BasePath,
00182                                 raw_ostream &Out) = 0;
00183 
00184   /// \brief Mangle vbtable symbols.  Only a subset of the bases along the path
00185   /// to the vbtable are included in the name.  It's up to the caller to pick
00186   /// them correctly.
00187   virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
00188                                 ArrayRef<const CXXRecordDecl *> BasePath,
00189                                 raw_ostream &Out) = 0;
00190 
00191   virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
00192                                         raw_ostream &) = 0;
00193 
00194   virtual void mangleCXXRTTIBaseClassDescriptor(
00195       const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
00196       uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
00197 
00198   virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
00199                                            raw_ostream &Out) = 0;
00200   virtual void
00201   mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
00202                                         raw_ostream &Out) = 0;
00203 
00204   virtual void
00205   mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
00206                                      ArrayRef<const CXXRecordDecl *> BasePath,
00207                                      raw_ostream &Out) = 0;
00208 
00209   static bool classof(const MangleContext *C) {
00210     return C->getKind() == MK_Microsoft;
00211   }
00212 
00213   static MicrosoftMangleContext *create(ASTContext &Context,
00214                                         DiagnosticsEngine &Diags);
00215 };
00216 }
00217 
00218 #endif