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/raw_ostream.h"
     23 
     24 namespace clang {
     25   class ASTContext;
     26   class BlockDecl;
     27   class CXXConstructorDecl;
     28   class CXXDestructorDecl;
     29   class CXXMethodDecl;
     30   class FunctionDecl;
     31   class NamedDecl;
     32   class ObjCMethodDecl;
     33   class VarDecl;
     34   struct ThisAdjustment;
     35   struct ThunkInfo;
     36 
     37 /// MangleBuffer - a convenient class for storing a name which is
     38 /// either the result of a mangling or is a constant string with
     39 /// external memory ownership.
     40 class MangleBuffer {
     41 public:
     42   void setString(StringRef Ref) {
     43     String = Ref;
     44   }
     45 
     46   SmallVectorImpl<char> &getBuffer() {
     47     return Buffer;
     48   }
     49 
     50   StringRef getString() const {
     51     if (!String.empty()) return String;
     52     return Buffer.str();
     53   }
     54 
     55   operator StringRef() const {
     56     return getString();
     57   }
     58 
     59 private:
     60   StringRef String;
     61   SmallString<256> Buffer;
     62 };
     63 
     64 /// MangleContext - Context for tracking state which persists across multiple
     65 /// calls to the C++ name mangler.
     66 class MangleContext {
     67   virtual void anchor();
     68 
     69   ASTContext &Context;
     70   DiagnosticsEngine &Diags;
     71 
     72   llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
     73   llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
     74 
     75 public:
     76   explicit MangleContext(ASTContext &Context,
     77                          DiagnosticsEngine &Diags)
     78     : Context(Context), Diags(Diags) { }
     79 
     80   virtual ~MangleContext() { }
     81 
     82   ASTContext &getASTContext() const { return Context; }
     83 
     84   DiagnosticsEngine &getDiags() const { return Diags; }
     85 
     86   virtual void startNewFunction() { LocalBlockIds.clear(); }
     87 
     88   unsigned getBlockId(const BlockDecl *BD, bool Local) {
     89     llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
     90       = Local? LocalBlockIds : GlobalBlockIds;
     91     std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
     92       Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
     93     return Result.first->second;
     94   }
     95 
     96   /// @name Mangler Entry Points
     97   /// @{
     98 
     99   virtual bool shouldMangleDeclName(const NamedDecl *D) = 0;
    100   virtual void mangleName(const NamedDecl *D, raw_ostream &)=0;
    101   virtual void mangleThunk(const CXXMethodDecl *MD,
    102                           const ThunkInfo &Thunk,
    103                           raw_ostream &) = 0;
    104   virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
    105                                   const ThisAdjustment &ThisAdjustment,
    106                                   raw_ostream &) = 0;
    107   virtual void mangleReferenceTemporary(const VarDecl *D,
    108                                         raw_ostream &) = 0;
    109   virtual void mangleCXXVTable(const CXXRecordDecl *RD,
    110                                raw_ostream &) = 0;
    111   virtual void mangleCXXVTT(const CXXRecordDecl *RD,
    112                             raw_ostream &) = 0;
    113   /// \brief Mangle vbtable symbols.  Only a subset of the bases along the path
    114   /// to the vbtable are included in the name.  It's up to the caller to pick
    115   /// them correctly.
    116   virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
    117                                 ArrayRef<const CXXRecordDecl *> BasePath,
    118                                 raw_ostream &Out) = 0;
    119   virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
    120                                    const CXXRecordDecl *Type,
    121                                    raw_ostream &) = 0;
    122   virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
    123   virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
    124   virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
    125                              raw_ostream &) = 0;
    126   virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
    127                              raw_ostream &) = 0;
    128 
    129   void mangleGlobalBlock(const BlockDecl *BD,
    130                          const NamedDecl *ID,
    131                          raw_ostream &Out);
    132   void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
    133                        const BlockDecl *BD, raw_ostream &Out);
    134   void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
    135                        const BlockDecl *BD, raw_ostream &Out);
    136   void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
    137                    raw_ostream &Out);
    138 
    139   void mangleObjCMethodName(const ObjCMethodDecl *MD,
    140                             raw_ostream &);
    141 
    142   // This is pretty lame.
    143   virtual void mangleItaniumGuardVariable(const VarDecl *D,
    144                                           raw_ostream &) {
    145     llvm_unreachable("Target does not support mangling guard variables");
    146   }
    147   // FIXME: Revisit this once we know what we need to do for MSVC compatibility.
    148   virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
    149                                             raw_ostream &) {
    150     llvm_unreachable("Target does not support mangling thread_local variables");
    151   }
    152   virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
    153                                                raw_ostream &) {
    154     llvm_unreachable("Target does not support mangling thread_local variables");
    155   }
    156 
    157   /// @}
    158 };
    159 
    160 MangleContext *createItaniumMangleContext(ASTContext &Context,
    161                                           DiagnosticsEngine &Diags);
    162 MangleContext *createMicrosoftMangleContext(ASTContext &Context,
    163                                             DiagnosticsEngine &Diags);
    164 
    165 }
    166 
    167 #endif
    168