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/StringRef.h"
00021 #include "llvm/ADT/SmallString.h"
00022 #include "llvm/Support/raw_ostream.h"
00023 
00024 namespace clang {
00025   class ASTContext;
00026   class BlockDecl;
00027   class CXXConstructorDecl;
00028   class CXXDestructorDecl;
00029   class CXXMethodDecl;
00030   class FunctionDecl;
00031   class NamedDecl;
00032   class ObjCMethodDecl;
00033   class VarDecl;
00034   struct ThisAdjustment;
00035   struct ThunkInfo;
00036 
00037 /// MangleBuffer - a convenient class for storing a name which is
00038 /// either the result of a mangling or is a constant string with
00039 /// external memory ownership.
00040 class MangleBuffer {
00041 public:
00042   void setString(StringRef Ref) {
00043     String = Ref;
00044   }
00045 
00046   SmallVectorImpl<char> &getBuffer() {
00047     return Buffer;
00048   }
00049 
00050   StringRef getString() const {
00051     if (!String.empty()) return String;
00052     return Buffer.str();
00053   }
00054 
00055   operator StringRef() const {
00056     return getString();
00057   }
00058 
00059 private:
00060   StringRef String;
00061   SmallString<256> Buffer;
00062 };
00063 
00064 /// MangleContext - Context for tracking state which persists across multiple
00065 /// calls to the C++ name mangler.
00066 class MangleContext {
00067   virtual void anchor();
00068 
00069   ASTContext &Context;
00070   DiagnosticsEngine &Diags;
00071 
00072   llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
00073   llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
00074   
00075 public:
00076   explicit MangleContext(ASTContext &Context,
00077                          DiagnosticsEngine &Diags)
00078     : Context(Context), Diags(Diags) { }
00079 
00080   virtual ~MangleContext() { }
00081 
00082   ASTContext &getASTContext() const { return Context; }
00083 
00084   DiagnosticsEngine &getDiags() const { return Diags; }
00085 
00086   virtual void startNewFunction() { LocalBlockIds.clear(); }
00087   
00088   unsigned getBlockId(const BlockDecl *BD, bool Local) {
00089     llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
00090       = Local? LocalBlockIds : GlobalBlockIds;
00091     std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
00092       Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
00093     return Result.first->second;
00094   }
00095   
00096   /// @name Mangler Entry Points
00097   /// @{
00098 
00099   virtual bool shouldMangleDeclName(const NamedDecl *D) = 0;
00100   virtual void mangleName(const NamedDecl *D, raw_ostream &)=0;
00101   virtual void mangleThunk(const CXXMethodDecl *MD,
00102                           const ThunkInfo &Thunk,
00103                           raw_ostream &) = 0;
00104   virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
00105                                   const ThisAdjustment &ThisAdjustment,
00106                                   raw_ostream &) = 0;
00107   virtual void mangleReferenceTemporary(const VarDecl *D,
00108                                         raw_ostream &) = 0;
00109   virtual void mangleCXXVTable(const CXXRecordDecl *RD,
00110                                raw_ostream &) = 0;
00111   virtual void mangleCXXVTT(const CXXRecordDecl *RD,
00112                             raw_ostream &) = 0;
00113   virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
00114                                    const CXXRecordDecl *Type,
00115                                    raw_ostream &) = 0;
00116   virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
00117   virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
00118   virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
00119                              raw_ostream &) = 0;
00120   virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
00121                              raw_ostream &) = 0;
00122 
00123   void mangleGlobalBlock(const BlockDecl *BD,
00124                          raw_ostream &Out);
00125   void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
00126                        const BlockDecl *BD, raw_ostream &Out);
00127   void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
00128                        const BlockDecl *BD, raw_ostream &Out);
00129   void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
00130                    raw_ostream &Out);
00131   // Do the right thing.
00132   void mangleBlock(const BlockDecl *BD, raw_ostream &Out);
00133 
00134   void mangleObjCMethodName(const ObjCMethodDecl *MD,
00135                             raw_ostream &);
00136 
00137   // This is pretty lame.
00138   virtual void mangleItaniumGuardVariable(const VarDecl *D,
00139                                           raw_ostream &) {
00140     llvm_unreachable("Target does not support mangling guard variables");
00141   }
00142   /// @}
00143 };
00144 
00145 MangleContext *createItaniumMangleContext(ASTContext &Context,
00146                                           DiagnosticsEngine &Diags);
00147 MangleContext *createMicrosoftMangleContext(ASTContext &Context,
00148                                             DiagnosticsEngine &Diags);
00149 
00150 }
00151 
00152 #endif