ClangASTImporter.h revision 40960a7953ba723190de1be397ce9679df5b7a07
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 RequireCompleteType (clang::QualType type); 133 134 bool 135 ResolveDeclOrigin (const clang::Decl *decl, clang::Decl **original_decl, clang::ASTContext **original_ctx) 136 { 137 DeclOrigin origin = GetDeclOrigin(decl); 138 139 if (original_decl) 140 *original_decl = origin.decl; 141 142 if (original_ctx) 143 *original_ctx = origin.ctx; 144 145 return origin.Valid(); 146 } 147 148 void 149 SetDeclOrigin (const clang::Decl *decl, clang::Decl *original_decl); 150 151 ClangASTMetadata * 152 GetDeclMetadata (const clang::Decl *decl); 153 154 // 155 // Namespace maps 156 // 157 158 typedef std::vector < std::pair<lldb::ModuleSP, ClangNamespaceDecl> > NamespaceMap; 159 typedef STD_SHARED_PTR(NamespaceMap) NamespaceMapSP; 160 161 void RegisterNamespaceMap (const clang::NamespaceDecl *decl, 162 NamespaceMapSP &namespace_map); 163 164 NamespaceMapSP GetNamespaceMap (const clang::NamespaceDecl *decl); 165 166 void BuildNamespaceMap (const clang::NamespaceDecl *decl); 167 168 // 169 // Comleters for maps 170 // 171 172 class MapCompleter 173 { 174 public: 175 virtual ~MapCompleter (); 176 177 virtual void CompleteNamespaceMap (NamespaceMapSP &namespace_map, 178 const ConstString &name, 179 NamespaceMapSP &parent_map) const = 0; 180 }; 181 182 void InstallMapCompleter (clang::ASTContext *dst_ctx, MapCompleter &completer) 183 { 184 ASTContextMetadataSP context_md; 185 ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); 186 187 if (context_md_iter == m_metadata_map.end()) 188 { 189 context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx)); 190 m_metadata_map[dst_ctx] = context_md; 191 } 192 else 193 { 194 context_md = context_md_iter->second; 195 } 196 197 context_md->m_map_completer = &completer; 198 } 199 200 void ForgetDestination (clang::ASTContext *dst_ctx); 201 void ForgetSource (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx); 202private: 203 struct DeclOrigin 204 { 205 DeclOrigin () : 206 ctx(NULL), 207 decl(NULL) 208 { 209 } 210 211 DeclOrigin (clang::ASTContext *_ctx, 212 clang::Decl *_decl) : 213 ctx(_ctx), 214 decl(_decl) 215 { 216 } 217 218 DeclOrigin (const DeclOrigin &rhs) 219 { 220 ctx = rhs.ctx; 221 decl = rhs.decl; 222 } 223 224 void operator= (const DeclOrigin &rhs) 225 { 226 ctx = rhs.ctx; 227 decl = rhs.decl; 228 } 229 230 bool 231 Valid () 232 { 233 return (ctx != NULL || decl != NULL); 234 } 235 236 clang::ASTContext *ctx; 237 clang::Decl *decl; 238 }; 239 240 typedef std::map<const clang::Decl *, DeclOrigin> OriginMap; 241 242 class Minion : public clang::ASTImporter 243 { 244 public: 245 Minion (ClangASTImporter &master, 246 clang::ASTContext *target_ctx, 247 clang::ASTContext *source_ctx) : 248 clang::ASTImporter(*target_ctx, 249 master.m_file_manager, 250 *source_ctx, 251 master.m_file_manager, 252 true /*minimal*/), 253 m_master(master), 254 m_source_ctx(source_ctx) 255 { 256 } 257 258 void ImportDefinitionTo (clang::Decl *to, clang::Decl *from); 259 260 clang::Decl *Imported (clang::Decl *from, clang::Decl *to); 261 262 ClangASTImporter &m_master; 263 clang::ASTContext *m_source_ctx; 264 }; 265 266 typedef STD_SHARED_PTR(Minion) MinionSP; 267 typedef std::map<clang::ASTContext *, MinionSP> MinionMap; 268 typedef std::map<const clang::NamespaceDecl *, NamespaceMapSP> NamespaceMetaMap; 269 270 struct ASTContextMetadata 271 { 272 ASTContextMetadata(clang::ASTContext *dst_ctx) : 273 m_dst_ctx (dst_ctx), 274 m_minions (), 275 m_origins (), 276 m_namespace_maps (), 277 m_map_completer (NULL) 278 { 279 } 280 281 clang::ASTContext *m_dst_ctx; 282 MinionMap m_minions; 283 OriginMap m_origins; 284 285 NamespaceMetaMap m_namespace_maps; 286 MapCompleter *m_map_completer; 287 }; 288 289 typedef STD_SHARED_PTR(ASTContextMetadata) ASTContextMetadataSP; 290 typedef std::map<const clang::ASTContext *, ASTContextMetadataSP> ContextMetadataMap; 291 292 ContextMetadataMap m_metadata_map; 293 294 ASTContextMetadataSP 295 GetContextMetadata (clang::ASTContext *dst_ctx) 296 { 297 ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); 298 299 if (context_md_iter == m_metadata_map.end()) 300 { 301 ASTContextMetadataSP context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx)); 302 m_metadata_map[dst_ctx] = context_md; 303 return context_md; 304 } 305 else 306 { 307 return context_md_iter->second; 308 } 309 } 310 311 ASTContextMetadataSP 312 MaybeGetContextMetadata (clang::ASTContext *dst_ctx) 313 { 314 ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); 315 316 if (context_md_iter != m_metadata_map.end()) 317 return context_md_iter->second; 318 else 319 return ASTContextMetadataSP(); 320 } 321 322 MinionSP 323 GetMinion (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx) 324 { 325 ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx); 326 327 MinionMap &minions = context_md->m_minions; 328 MinionMap::iterator minion_iter = minions.find(src_ctx); 329 330 if (minion_iter == minions.end()) 331 { 332 MinionSP minion = MinionSP(new Minion(*this, dst_ctx, src_ctx)); 333 minions[src_ctx] = minion; 334 return minion; 335 } 336 else 337 { 338 return minion_iter->second; 339 } 340 } 341 342 DeclOrigin 343 GetDeclOrigin (const clang::Decl *decl); 344 345 clang::FileManager m_file_manager; 346}; 347 348} 349 350#endif 351