clang API Documentation
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