ClangASTImporter.h revision e1301a62783cf0d5457350b90830917841cbf6fc
1//===-- ClangASTImporter.h --------------------------------------*- 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#ifndef liblldb_ClangASTImporter_h_ 11#define liblldb_ClangASTImporter_h_ 12 13#include <map> 14 15#include "lldb/lldb-types.h" 16 17#include "clang/AST/ASTImporter.h" 18#include "clang/Basic/FileManager.h" 19#include "clang/Basic/FileSystemOptions.h" 20#if defined(__GNUC__) && !defined(__clang__) 21// Gcc complains about ClangNamespaceDecl being an incomplete type 22// without this. 23#include "lldb/Symbol/ClangNamespaceDecl.h" 24#endif 25 26namespace lldb_private { 27 28class ClangASTImporter 29{ 30public: 31 ClangASTImporter () : 32 m_file_manager(clang::FileSystemOptions()) 33 { 34 } 35 36 clang::QualType 37 CopyType (clang::ASTContext *dst_ctx, 38 clang::ASTContext *src_ctx, 39 clang::QualType type); 40 41 lldb::clang_type_t 42 CopyType (clang::ASTContext *dst_ctx, 43 clang::ASTContext *src_ctx, 44 lldb::clang_type_t type); 45 46 clang::Decl * 47 CopyDecl (clang::ASTContext *dst_ctx, 48 clang::ASTContext *src_ctx, 49 clang::Decl *decl); 50 51 clang::Decl * 52 DeportDecl (clang::ASTContext *dst_ctx, 53 clang::ASTContext *src_ctx, 54 clang::Decl *decl); 55 56 void 57 CompleteTagDecl (clang::TagDecl *decl); 58 59 void 60 CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface_decl); 61 62 bool 63 ResolveDeclOrigin (const clang::Decl *decl, clang::Decl **original_decl, clang::ASTContext **original_ctx) 64 { 65 DeclOrigin origin = GetDeclOrigin(decl); 66 67 if (original_decl) 68 *original_decl = origin.decl; 69 70 if (original_ctx) 71 *original_ctx = origin.ctx; 72 73 return origin.Valid(); 74 } 75 76 // 77 // Namespace maps 78 // 79 80 typedef std::vector < std::pair<lldb::ModuleSP, ClangNamespaceDecl> > NamespaceMap; 81 typedef lldb::SharedPtr<NamespaceMap>::Type NamespaceMapSP; 82 83 void RegisterNamespaceMap (const clang::NamespaceDecl *decl, 84 NamespaceMapSP &namespace_map); 85 86 NamespaceMapSP GetNamespaceMap (const clang::NamespaceDecl *decl); 87 88 void BuildNamespaceMap (const clang::NamespaceDecl *decl); 89 90 // 91 // Objective-C interface maps 92 // 93 94 typedef std::vector <ClangASTType> ObjCInterfaceMap; 95 typedef lldb::SharedPtr<ObjCInterfaceMap>::Type ObjCInterfaceMapSP; 96 97 void BuildObjCInterfaceMap (const clang::ObjCInterfaceDecl *decl); 98 99 ObjCInterfaceMapSP GetObjCInterfaceMap (const clang::ObjCInterfaceDecl *decl); 100 101 // 102 // Completers for the namespace and Objective-C interface maps 103 // 104 105 class MapCompleter 106 { 107 public: 108 virtual ~MapCompleter (); 109 110 virtual void CompleteNamespaceMap (NamespaceMapSP &namespace_map, 111 const ConstString &name, 112 NamespaceMapSP &parent_map) const = 0; 113 114 virtual void CompleteObjCInterfaceMap (ObjCInterfaceMapSP &objc_interface_map, 115 const ConstString &name) const = 0; 116 }; 117 118 void InstallMapCompleter (clang::ASTContext *dst_ctx, MapCompleter &completer) 119 { 120 ASTContextMetadataSP context_md; 121 ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); 122 123 if (context_md_iter == m_metadata_map.end()) 124 { 125 context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx)); 126 m_metadata_map[dst_ctx] = context_md; 127 } 128 else 129 { 130 context_md = context_md_iter->second; 131 } 132 133 context_md->m_map_completer = &completer; 134 } 135 136 void ForgetDestination (clang::ASTContext *dst_ctx); 137 void ForgetSource (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx); 138private: 139 struct DeclOrigin 140 { 141 DeclOrigin () : 142 ctx(NULL), 143 decl(NULL) 144 { 145 } 146 147 DeclOrigin (clang::ASTContext *_ctx, 148 clang::Decl *_decl) : 149 ctx(_ctx), 150 decl(_decl) 151 { 152 } 153 154 DeclOrigin (const DeclOrigin &rhs) 155 { 156 ctx = rhs.ctx; 157 decl = rhs.decl; 158 } 159 160 void operator= (const DeclOrigin &rhs) 161 { 162 ctx = rhs.ctx; 163 decl = rhs.decl; 164 } 165 166 bool 167 Valid () 168 { 169 return (ctx != NULL || decl != NULL); 170 } 171 172 clang::ASTContext *ctx; 173 clang::Decl *decl; 174 }; 175 176 typedef std::map<const clang::Decl *, DeclOrigin> OriginMap; 177 178 class Minion : public clang::ASTImporter 179 { 180 public: 181 Minion (ClangASTImporter &master, 182 clang::ASTContext *target_ctx, 183 clang::ASTContext *source_ctx) : 184 clang::ASTImporter(*target_ctx, 185 master.m_file_manager, 186 *source_ctx, 187 master.m_file_manager, 188 true /*minimal*/), 189 m_master(master), 190 m_source_ctx(source_ctx) 191 { 192 } 193 194 clang::Decl *Imported (clang::Decl *from, clang::Decl *to); 195 196 ClangASTImporter &m_master; 197 clang::ASTContext *m_source_ctx; 198 }; 199 200 typedef lldb::SharedPtr<Minion>::Type MinionSP; 201 typedef std::map<clang::ASTContext *, MinionSP> MinionMap; 202 typedef std::map<const clang::NamespaceDecl *, NamespaceMapSP> NamespaceMetaMap; 203 typedef std::map<const clang::ObjCInterfaceDecl *, ObjCInterfaceMapSP> ObjCInterfaceMetaMap; 204 205 struct ASTContextMetadata 206 { 207 ASTContextMetadata(clang::ASTContext *dst_ctx) : 208 m_dst_ctx (dst_ctx), 209 m_minions (), 210 m_origins (), 211 m_namespace_maps (), 212 m_objc_interface_maps (), 213 m_map_completer (NULL) 214 { 215 } 216 217 clang::ASTContext *m_dst_ctx; 218 MinionMap m_minions; 219 OriginMap m_origins; 220 221 NamespaceMetaMap m_namespace_maps; 222 MapCompleter *m_map_completer; 223 224 ObjCInterfaceMetaMap m_objc_interface_maps; 225 }; 226 227 typedef lldb::SharedPtr<ASTContextMetadata>::Type ASTContextMetadataSP; 228 229 typedef std::map<const clang::ASTContext *, ASTContextMetadataSP> ContextMetadataMap; 230 231 ContextMetadataMap m_metadata_map; 232 233 ASTContextMetadataSP 234 GetContextMetadata (clang::ASTContext *dst_ctx) 235 { 236 ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); 237 238 if (context_md_iter == m_metadata_map.end()) 239 { 240 ASTContextMetadataSP context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx)); 241 m_metadata_map[dst_ctx] = context_md; 242 return context_md; 243 } 244 else 245 { 246 return context_md_iter->second; 247 } 248 } 249 250 ASTContextMetadataSP 251 MaybeGetContextMetadata (clang::ASTContext *dst_ctx) 252 { 253 ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); 254 255 if (context_md_iter != m_metadata_map.end()) 256 return context_md_iter->second; 257 else 258 return ASTContextMetadataSP(); 259 } 260 261 MinionSP 262 GetMinion (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx) 263 { 264 ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx); 265 266 MinionMap &minions = context_md->m_minions; 267 MinionMap::iterator minion_iter = minions.find(src_ctx); 268 269 if (minion_iter == minions.end()) 270 { 271 MinionSP minion = MinionSP(new Minion(*this, dst_ctx, src_ctx)); 272 minions[src_ctx] = minion; 273 return minion; 274 } 275 else 276 { 277 return minion_iter->second; 278 } 279 } 280 281 DeclOrigin 282 GetDeclOrigin (const clang::Decl *decl); 283 284 clang::FileManager m_file_manager; 285}; 286 287} 288 289#endif 290