ClangASTImporter.h revision 6741173bf58eaeab4964226ba5a42b2a9bbc21b1
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#include "lldb/Symbol/ClangNamespaceDecl.h" 21 22namespace lldb_private { 23 24class ClangASTMetrics 25{ 26public: 27 static void DumpCounters (lldb::LogSP log); 28 static void ClearLocalCounters () 29 { 30 local_counters = { 0, 0, 0, 0, 0, 0 }; 31 } 32 33 static void RegisterVisibleQuery () 34 { 35 ++global_counters.m_visible_query_count; 36 ++local_counters.m_visible_query_count; 37 } 38 39 static void RegisterLexicalQuery () 40 { 41 ++global_counters.m_lexical_query_count; 42 ++local_counters.m_lexical_query_count; 43 } 44 45 static void RegisterLLDBImport () 46 { 47 ++global_counters.m_lldb_import_count; 48 ++local_counters.m_lldb_import_count; 49 } 50 51 static void RegisterClangImport () 52 { 53 ++global_counters.m_clang_import_count; 54 ++local_counters.m_clang_import_count; 55 } 56 57 static void RegisterDeclCompletion () 58 { 59 ++global_counters.m_decls_completed_count; 60 ++local_counters.m_decls_completed_count; 61 } 62 63 static void RegisterRecordLayout () 64 { 65 ++global_counters.m_record_layout_count; 66 ++local_counters.m_record_layout_count; 67 } 68 69private: 70 struct Counters 71 { 72 uint64_t m_visible_query_count; 73 uint64_t m_lexical_query_count; 74 uint64_t m_lldb_import_count; 75 uint64_t m_clang_import_count; 76 uint64_t m_decls_completed_count; 77 uint64_t m_record_layout_count; 78 }; 79 80 static Counters global_counters; 81 static Counters local_counters; 82 83 static void DumpCounters (lldb::LogSP log, Counters &counters); 84}; 85 86class ClangASTImporter 87{ 88public: 89 ClangASTImporter () : 90 m_file_manager(clang::FileSystemOptions()) 91 { 92 } 93 94 clang::QualType 95 CopyType (clang::ASTContext *dst_ctx, 96 clang::ASTContext *src_ctx, 97 clang::QualType type); 98 99 lldb::clang_type_t 100 CopyType (clang::ASTContext *dst_ctx, 101 clang::ASTContext *src_ctx, 102 lldb::clang_type_t type); 103 104 clang::Decl * 105 CopyDecl (clang::ASTContext *dst_ctx, 106 clang::ASTContext *src_ctx, 107 clang::Decl *decl); 108 109 lldb::clang_type_t 110 DeportType (clang::ASTContext *dst_ctx, 111 clang::ASTContext *src_ctx, 112 lldb::clang_type_t type); 113 114 clang::Decl * 115 DeportDecl (clang::ASTContext *dst_ctx, 116 clang::ASTContext *src_ctx, 117 clang::Decl *decl); 118 119 void 120 CompleteDecl (clang::Decl *decl); 121 122 bool 123 CompleteTagDecl (clang::TagDecl *decl); 124 125 bool 126 CompleteTagDeclWithOrigin (clang::TagDecl *decl, clang::TagDecl *origin); 127 128 bool 129 CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface_decl); 130 131 bool 132 ResolveDeclOrigin (const clang::Decl *decl, clang::Decl **original_decl, clang::ASTContext **original_ctx) 133 { 134 DeclOrigin origin = GetDeclOrigin(decl); 135 136 if (original_decl) 137 *original_decl = origin.decl; 138 139 if (original_ctx) 140 *original_ctx = origin.ctx; 141 142 return origin.Valid(); 143 } 144 145 void 146 SetDeclOrigin (const clang::Decl *decl, clang::Decl *original_decl); 147 148 ClangASTMetadata * 149 GetDeclMetadata (const clang::Decl *decl); 150 151 // 152 // Namespace maps 153 // 154 155 typedef std::vector < std::pair<lldb::ModuleSP, ClangNamespaceDecl> > NamespaceMap; 156 typedef STD_SHARED_PTR(NamespaceMap) NamespaceMapSP; 157 158 void RegisterNamespaceMap (const clang::NamespaceDecl *decl, 159 NamespaceMapSP &namespace_map); 160 161 NamespaceMapSP GetNamespaceMap (const clang::NamespaceDecl *decl); 162 163 void BuildNamespaceMap (const clang::NamespaceDecl *decl); 164 165 // 166 // Comleters for maps 167 // 168 169 class MapCompleter 170 { 171 public: 172 virtual ~MapCompleter (); 173 174 virtual void CompleteNamespaceMap (NamespaceMapSP &namespace_map, 175 const ConstString &name, 176 NamespaceMapSP &parent_map) const = 0; 177 }; 178 179 void InstallMapCompleter (clang::ASTContext *dst_ctx, MapCompleter &completer) 180 { 181 ASTContextMetadataSP context_md; 182 ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); 183 184 if (context_md_iter == m_metadata_map.end()) 185 { 186 context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx)); 187 m_metadata_map[dst_ctx] = context_md; 188 } 189 else 190 { 191 context_md = context_md_iter->second; 192 } 193 194 context_md->m_map_completer = &completer; 195 } 196 197 void ForgetDestination (clang::ASTContext *dst_ctx); 198 void ForgetSource (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx); 199private: 200 struct DeclOrigin 201 { 202 DeclOrigin () : 203 ctx(NULL), 204 decl(NULL) 205 { 206 } 207 208 DeclOrigin (clang::ASTContext *_ctx, 209 clang::Decl *_decl) : 210 ctx(_ctx), 211 decl(_decl) 212 { 213 } 214 215 DeclOrigin (const DeclOrigin &rhs) 216 { 217 ctx = rhs.ctx; 218 decl = rhs.decl; 219 } 220 221 void operator= (const DeclOrigin &rhs) 222 { 223 ctx = rhs.ctx; 224 decl = rhs.decl; 225 } 226 227 bool 228 Valid () 229 { 230 return (ctx != NULL || decl != NULL); 231 } 232 233 clang::ASTContext *ctx; 234 clang::Decl *decl; 235 }; 236 237 typedef std::map<const clang::Decl *, DeclOrigin> OriginMap; 238 239 class Minion : public clang::ASTImporter 240 { 241 public: 242 Minion (ClangASTImporter &master, 243 clang::ASTContext *target_ctx, 244 clang::ASTContext *source_ctx) : 245 clang::ASTImporter(*target_ctx, 246 master.m_file_manager, 247 *source_ctx, 248 master.m_file_manager, 249 true /*minimal*/), 250 m_master(master), 251 m_source_ctx(source_ctx) 252 { 253 } 254 255 void ImportDefinitionTo (clang::Decl *to, clang::Decl *from); 256 257 clang::Decl *Imported (clang::Decl *from, clang::Decl *to); 258 259 ClangASTImporter &m_master; 260 clang::ASTContext *m_source_ctx; 261 }; 262 263 typedef STD_SHARED_PTR(Minion) MinionSP; 264 typedef std::map<clang::ASTContext *, MinionSP> MinionMap; 265 typedef std::map<const clang::NamespaceDecl *, NamespaceMapSP> NamespaceMetaMap; 266 267 struct ASTContextMetadata 268 { 269 ASTContextMetadata(clang::ASTContext *dst_ctx) : 270 m_dst_ctx (dst_ctx), 271 m_minions (), 272 m_origins (), 273 m_namespace_maps (), 274 m_map_completer (NULL) 275 { 276 } 277 278 clang::ASTContext *m_dst_ctx; 279 MinionMap m_minions; 280 OriginMap m_origins; 281 282 NamespaceMetaMap m_namespace_maps; 283 MapCompleter *m_map_completer; 284 }; 285 286 typedef STD_SHARED_PTR(ASTContextMetadata) ASTContextMetadataSP; 287 typedef std::map<const clang::ASTContext *, ASTContextMetadataSP> ContextMetadataMap; 288 289 ContextMetadataMap m_metadata_map; 290 291 ASTContextMetadataSP 292 GetContextMetadata (clang::ASTContext *dst_ctx) 293 { 294 ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); 295 296 if (context_md_iter == m_metadata_map.end()) 297 { 298 ASTContextMetadataSP context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx)); 299 m_metadata_map[dst_ctx] = context_md; 300 return context_md; 301 } 302 else 303 { 304 return context_md_iter->second; 305 } 306 } 307 308 ASTContextMetadataSP 309 MaybeGetContextMetadata (clang::ASTContext *dst_ctx) 310 { 311 ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); 312 313 if (context_md_iter != m_metadata_map.end()) 314 return context_md_iter->second; 315 else 316 return ASTContextMetadataSP(); 317 } 318 319 MinionSP 320 GetMinion (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx) 321 { 322 ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx); 323 324 MinionMap &minions = context_md->m_minions; 325 MinionMap::iterator minion_iter = minions.find(src_ctx); 326 327 if (minion_iter == minions.end()) 328 { 329 MinionSP minion = MinionSP(new Minion(*this, dst_ctx, src_ctx)); 330 minions[src_ctx] = minion; 331 return minion; 332 } 333 else 334 { 335 return minion_iter->second; 336 } 337 } 338 339 DeclOrigin 340 GetDeclOrigin (const clang::Decl *decl); 341 342 clang::FileManager m_file_manager; 343}; 344 345} 346 347#endif 348