ClangASTImporter.h revision 598df88bd6fc33c6fb330bc859bdc277795501f3
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 lldb::clang_type_t 52 DeportType (clang::ASTContext *dst_ctx, 53 clang::ASTContext *src_ctx, 54 lldb::clang_type_t type); 55 56 clang::Decl * 57 DeportDecl (clang::ASTContext *dst_ctx, 58 clang::ASTContext *src_ctx, 59 clang::Decl *decl); 60 61 void 62 CompleteDecl (clang::Decl *decl); 63 64 bool 65 CompleteTagDecl (clang::TagDecl *decl); 66 67 bool 68 CompleteTagDeclWithOrigin (clang::TagDecl *decl, clang::TagDecl *origin); 69 70 bool 71 CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface_decl); 72 73 bool 74 ResolveDeclOrigin (const clang::Decl *decl, clang::Decl **original_decl, clang::ASTContext **original_ctx) 75 { 76 DeclOrigin origin = GetDeclOrigin(decl); 77 78 if (original_decl) 79 *original_decl = origin.decl; 80 81 if (original_ctx) 82 *original_ctx = origin.ctx; 83 84 return origin.Valid(); 85 } 86 87 // 88 // Namespace maps 89 // 90 91 typedef std::vector < std::pair<lldb::ModuleSP, ClangNamespaceDecl> > NamespaceMap; 92 typedef STD_SHARED_PTR(NamespaceMap) NamespaceMapSP; 93 94 void RegisterNamespaceMap (const clang::NamespaceDecl *decl, 95 NamespaceMapSP &namespace_map); 96 97 NamespaceMapSP GetNamespaceMap (const clang::NamespaceDecl *decl); 98 99 void BuildNamespaceMap (const clang::NamespaceDecl *decl); 100 101 // 102 // Comleters for 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 115 void InstallMapCompleter (clang::ASTContext *dst_ctx, MapCompleter &completer) 116 { 117 ASTContextMetadataSP context_md; 118 ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); 119 120 if (context_md_iter == m_metadata_map.end()) 121 { 122 context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx)); 123 m_metadata_map[dst_ctx] = context_md; 124 } 125 else 126 { 127 context_md = context_md_iter->second; 128 } 129 130 context_md->m_map_completer = &completer; 131 } 132 133 void ForgetDestination (clang::ASTContext *dst_ctx); 134 void ForgetSource (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx); 135private: 136 struct DeclOrigin 137 { 138 DeclOrigin () : 139 ctx(NULL), 140 decl(NULL) 141 { 142 } 143 144 DeclOrigin (clang::ASTContext *_ctx, 145 clang::Decl *_decl) : 146 ctx(_ctx), 147 decl(_decl) 148 { 149 } 150 151 DeclOrigin (const DeclOrigin &rhs) 152 { 153 ctx = rhs.ctx; 154 decl = rhs.decl; 155 } 156 157 void operator= (const DeclOrigin &rhs) 158 { 159 ctx = rhs.ctx; 160 decl = rhs.decl; 161 } 162 163 bool 164 Valid () 165 { 166 return (ctx != NULL || decl != NULL); 167 } 168 169 clang::ASTContext *ctx; 170 clang::Decl *decl; 171 }; 172 173 typedef std::map<const clang::Decl *, DeclOrigin> OriginMap; 174 175 class Minion : public clang::ASTImporter 176 { 177 public: 178 Minion (ClangASTImporter &master, 179 clang::ASTContext *target_ctx, 180 clang::ASTContext *source_ctx) : 181 clang::ASTImporter(*target_ctx, 182 master.m_file_manager, 183 *source_ctx, 184 master.m_file_manager, 185 true /*minimal*/), 186 m_master(master), 187 m_source_ctx(source_ctx) 188 { 189 } 190 191 void ImportDefinitionTo (clang::Decl *to, clang::Decl *from); 192 193 clang::Decl *Imported (clang::Decl *from, clang::Decl *to); 194 195 ClangASTImporter &m_master; 196 clang::ASTContext *m_source_ctx; 197 }; 198 199 typedef STD_SHARED_PTR(Minion) MinionSP; 200 typedef std::map<clang::ASTContext *, MinionSP> MinionMap; 201 typedef std::map<const clang::NamespaceDecl *, NamespaceMapSP> NamespaceMetaMap; 202 203 struct ASTContextMetadata 204 { 205 ASTContextMetadata(clang::ASTContext *dst_ctx) : 206 m_dst_ctx (dst_ctx), 207 m_minions (), 208 m_origins (), 209 m_namespace_maps (), 210 m_map_completer (NULL) 211 { 212 } 213 214 clang::ASTContext *m_dst_ctx; 215 MinionMap m_minions; 216 OriginMap m_origins; 217 218 NamespaceMetaMap m_namespace_maps; 219 MapCompleter *m_map_completer; 220 }; 221 222 typedef STD_SHARED_PTR(ASTContextMetadata) ASTContextMetadataSP; 223 typedef std::map<const clang::ASTContext *, ASTContextMetadataSP> ContextMetadataMap; 224 225 ContextMetadataMap m_metadata_map; 226 227 ASTContextMetadataSP 228 GetContextMetadata (clang::ASTContext *dst_ctx) 229 { 230 ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); 231 232 if (context_md_iter == m_metadata_map.end()) 233 { 234 ASTContextMetadataSP context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx)); 235 m_metadata_map[dst_ctx] = context_md; 236 return context_md; 237 } 238 else 239 { 240 return context_md_iter->second; 241 } 242 } 243 244 ASTContextMetadataSP 245 MaybeGetContextMetadata (clang::ASTContext *dst_ctx) 246 { 247 ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); 248 249 if (context_md_iter != m_metadata_map.end()) 250 return context_md_iter->second; 251 else 252 return ASTContextMetadataSP(); 253 } 254 255 MinionSP 256 GetMinion (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx) 257 { 258 ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx); 259 260 MinionMap &minions = context_md->m_minions; 261 MinionMap::iterator minion_iter = minions.find(src_ctx); 262 263 if (minion_iter == minions.end()) 264 { 265 MinionSP minion = MinionSP(new Minion(*this, dst_ctx, src_ctx)); 266 minions[src_ctx] = minion; 267 return minion; 268 } 269 else 270 { 271 return minion_iter->second; 272 } 273 } 274 275 DeclOrigin 276 GetDeclOrigin (const clang::Decl *decl); 277 278 clang::FileManager m_file_manager; 279}; 280 281} 282 283#endif 284