ClangASTImporter.h revision b2027ec7cc8c15dfdc7c945dc6aed4b5d684321e
1529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz//===-- ClangASTImporter.h --------------------------------------*- C++ -*-===// 2529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz// 3529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz// The LLVM Compiler Infrastructure 4529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz// 5529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz// This file is distributed under the University of Illinois Open Source 6529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz// License. See LICENSE.TXT for details. 7529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz// 8529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz//===----------------------------------------------------------------------===// 9529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz 10529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz#ifndef liblldb_ClangASTImporter_h_ 11529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz#define liblldb_ClangASTImporter_h_ 12529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz 13529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz#include <map> 14529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz 15529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz#include "lldb/lldb-types.h" 16529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz 17529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz#include "clang/AST/ASTImporter.h" 18529f86fb113529d1ecf113dc45efade7fe185f94Jakob Bornecrantz#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 bool 57 CompleteTagDecl (clang::TagDecl *decl); 58 59 bool 60 CompleteTagDeclWithOrigin (clang::TagDecl *decl, clang::TagDecl *origin); 61 62 bool 63 CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface_decl); 64 65 bool 66 ResolveDeclOrigin (const clang::Decl *decl, clang::Decl **original_decl, clang::ASTContext **original_ctx) 67 { 68 DeclOrigin origin = GetDeclOrigin(decl); 69 70 if (original_decl) 71 *original_decl = origin.decl; 72 73 if (original_ctx) 74 *original_ctx = origin.ctx; 75 76 return origin.Valid(); 77 } 78 79 // 80 // Namespace maps 81 // 82 83 typedef std::vector < std::pair<lldb::ModuleSP, ClangNamespaceDecl> > NamespaceMap; 84 typedef lldb::SharedPtr<NamespaceMap>::Type NamespaceMapSP; 85 86 void RegisterNamespaceMap (const clang::NamespaceDecl *decl, 87 NamespaceMapSP &namespace_map); 88 89 NamespaceMapSP GetNamespaceMap (const clang::NamespaceDecl *decl); 90 91 void BuildNamespaceMap (const clang::NamespaceDecl *decl); 92 93 // 94 // Objective-C interface maps 95 // 96 97 typedef std::vector <ClangASTType> ObjCInterfaceMap; 98 typedef lldb::SharedPtr<ObjCInterfaceMap>::Type ObjCInterfaceMapSP; 99 100 void BuildObjCInterfaceMap (const clang::ObjCInterfaceDecl *decl); 101 102 ObjCInterfaceMapSP GetObjCInterfaceMap (const clang::ObjCInterfaceDecl *decl); 103 104 // 105 // Completers for the namespace and Objective-C interface maps 106 // 107 108 class MapCompleter 109 { 110 public: 111 virtual ~MapCompleter (); 112 113 virtual void CompleteNamespaceMap (NamespaceMapSP &namespace_map, 114 const ConstString &name, 115 NamespaceMapSP &parent_map) const = 0; 116 117 virtual void CompleteObjCInterfaceMap (ObjCInterfaceMapSP &objc_interface_map, 118 const ConstString &name) const = 0; 119 }; 120 121 void InstallMapCompleter (clang::ASTContext *dst_ctx, MapCompleter &completer) 122 { 123 ASTContextMetadataSP context_md; 124 ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); 125 126 if (context_md_iter == m_metadata_map.end()) 127 { 128 context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx)); 129 m_metadata_map[dst_ctx] = context_md; 130 } 131 else 132 { 133 context_md = context_md_iter->second; 134 } 135 136 context_md->m_map_completer = &completer; 137 } 138 139 void ForgetDestination (clang::ASTContext *dst_ctx); 140 void ForgetSource (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx); 141private: 142 struct DeclOrigin 143 { 144 DeclOrigin () : 145 ctx(NULL), 146 decl(NULL) 147 { 148 } 149 150 DeclOrigin (clang::ASTContext *_ctx, 151 clang::Decl *_decl) : 152 ctx(_ctx), 153 decl(_decl) 154 { 155 } 156 157 DeclOrigin (const DeclOrigin &rhs) 158 { 159 ctx = rhs.ctx; 160 decl = rhs.decl; 161 } 162 163 void operator= (const DeclOrigin &rhs) 164 { 165 ctx = rhs.ctx; 166 decl = rhs.decl; 167 } 168 169 bool 170 Valid () 171 { 172 return (ctx != NULL || decl != NULL); 173 } 174 175 clang::ASTContext *ctx; 176 clang::Decl *decl; 177 }; 178 179 typedef std::map<const clang::Decl *, DeclOrigin> OriginMap; 180 181 class Minion : public clang::ASTImporter 182 { 183 public: 184 Minion (ClangASTImporter &master, 185 clang::ASTContext *target_ctx, 186 clang::ASTContext *source_ctx) : 187 clang::ASTImporter(*target_ctx, 188 master.m_file_manager, 189 *source_ctx, 190 master.m_file_manager, 191 true /*minimal*/), 192 m_master(master), 193 m_source_ctx(source_ctx) 194 { 195 } 196 197 clang::Decl *Imported (clang::Decl *from, clang::Decl *to); 198 199 ClangASTImporter &m_master; 200 clang::ASTContext *m_source_ctx; 201 }; 202 203 typedef lldb::SharedPtr<Minion>::Type MinionSP; 204 typedef std::map<clang::ASTContext *, MinionSP> MinionMap; 205 typedef std::map<const clang::NamespaceDecl *, NamespaceMapSP> NamespaceMetaMap; 206 typedef std::map<const clang::ObjCInterfaceDecl *, ObjCInterfaceMapSP> ObjCInterfaceMetaMap; 207 208 struct ASTContextMetadata 209 { 210 ASTContextMetadata(clang::ASTContext *dst_ctx) : 211 m_dst_ctx (dst_ctx), 212 m_minions (), 213 m_origins (), 214 m_namespace_maps (), 215 m_objc_interface_maps (), 216 m_map_completer (NULL) 217 { 218 } 219 220 clang::ASTContext *m_dst_ctx; 221 MinionMap m_minions; 222 OriginMap m_origins; 223 224 NamespaceMetaMap m_namespace_maps; 225 MapCompleter *m_map_completer; 226 227 ObjCInterfaceMetaMap m_objc_interface_maps; 228 }; 229 230 typedef lldb::SharedPtr<ASTContextMetadata>::Type ASTContextMetadataSP; 231 232 typedef std::map<const clang::ASTContext *, ASTContextMetadataSP> ContextMetadataMap; 233 234 ContextMetadataMap m_metadata_map; 235 236 ASTContextMetadataSP 237 GetContextMetadata (clang::ASTContext *dst_ctx) 238 { 239 ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); 240 241 if (context_md_iter == m_metadata_map.end()) 242 { 243 ASTContextMetadataSP context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx)); 244 m_metadata_map[dst_ctx] = context_md; 245 return context_md; 246 } 247 else 248 { 249 return context_md_iter->second; 250 } 251 } 252 253 ASTContextMetadataSP 254 MaybeGetContextMetadata (clang::ASTContext *dst_ctx) 255 { 256 ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); 257 258 if (context_md_iter != m_metadata_map.end()) 259 return context_md_iter->second; 260 else 261 return ASTContextMetadataSP(); 262 } 263 264 MinionSP 265 GetMinion (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx) 266 { 267 ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx); 268 269 MinionMap &minions = context_md->m_minions; 270 MinionMap::iterator minion_iter = minions.find(src_ctx); 271 272 if (minion_iter == minions.end()) 273 { 274 MinionSP minion = MinionSP(new Minion(*this, dst_ctx, src_ctx)); 275 minions[src_ctx] = minion; 276 return minion; 277 } 278 else 279 { 280 return minion_iter->second; 281 } 282 } 283 284 DeclOrigin 285 GetDeclOrigin (const clang::Decl *decl); 286 287 clang::FileManager m_file_manager; 288}; 289 290} 291 292#endif 293