ClangASTSource.h revision 79e7ad84e2b31baf22e05ab24aaa11b5e0f566a5
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===-- ClangASTSource.h ----------------------------------------*- C++ -*-===// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef liblldb_ClangASTSource_h_ 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define liblldb_ClangASTSource_h_ 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/Basic/IdentifierTable.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lldb/Symbol/ClangExternalASTSourceCommon.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lldb/Symbol/ClangASTImporter.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "lldb/Target/Target.h" 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/ADT/SmallSet.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22namespace lldb_private { 23 24//---------------------------------------------------------------------- 25/// @class ClangASTSource ClangASTSource.h "lldb/Expression/ClangASTSource.h" 26/// @brief Provider for named objects defined in the debug info for Clang 27/// 28/// As Clang parses an expression, it may encounter names that are not 29/// defined inside the expression, including variables, functions, and 30/// types. Clang knows the name it is looking for, but nothing else. 31/// The ExternalSemaSource class provides Decls (VarDecl, FunDecl, TypeDecl) 32/// to Clang for these names, consulting the ClangExpressionDeclMap to do 33/// the actual lookups. 34//---------------------------------------------------------------------- 35class ClangASTSource : 36 public ClangExternalASTSourceCommon, 37 public ClangASTImporter::MapCompleter 38{ 39public: 40 //------------------------------------------------------------------ 41 /// Constructor 42 /// 43 /// Initializes class variables. 44 /// 45 /// @param[in] declMap 46 /// A reference to the LLDB object that handles entity lookup. 47 //------------------------------------------------------------------ 48 ClangASTSource (const lldb::TargetSP &target) : 49 m_import_in_progress (false), 50 m_lookups_enabled (false), 51 m_target (target), 52 m_ast_context (NULL), 53 m_active_lookups () 54 { 55 m_ast_importer = m_target->GetClangASTImporter(); 56 } 57 58 //------------------------------------------------------------------ 59 /// Destructor 60 //------------------------------------------------------------------ 61 ~ClangASTSource(); 62 63 //------------------------------------------------------------------ 64 /// Interface stubs. 65 //------------------------------------------------------------------ 66 clang::Decl *GetExternalDecl (uint32_t) { return NULL; } 67 clang::Stmt *GetExternalDeclStmt (uint64_t) { return NULL; } 68 clang::Selector GetExternalSelector (uint32_t) { return clang::Selector(); } 69 uint32_t GetNumExternalSelectors () { return 0; } 70 clang::CXXBaseSpecifier *GetExternalCXXBaseSpecifiers (uint64_t Offset) 71 { return NULL; } 72 void MaterializeVisibleDecls (const clang::DeclContext *DC) 73 { return; } 74 75 void InstallASTContext (clang::ASTContext *ast_context) 76 { 77 m_ast_context = ast_context; 78 m_ast_importer->InstallMapCompleter(ast_context, *this); 79 } 80 81 // 82 // APIs for ExternalASTSource 83 // 84 85 //------------------------------------------------------------------ 86 /// Look up all Decls that match a particular name. Only handles 87 /// Identifiers and DeclContexts that are either NamespaceDecls or 88 /// TranslationUnitDecls. Calls SetExternalVisibleDeclsForName with 89 /// the result. 90 /// 91 /// The work for this function is done by 92 /// void FindExternalVisibleDecls (NameSearchContext &); 93 /// 94 /// @param[in] DC 95 /// The DeclContext to register the found Decls in. 96 /// 97 /// @param[in] Name 98 /// The name to find entries for. 99 /// 100 /// @return 101 /// Whatever SetExternalVisibleDeclsForName returns. 102 //------------------------------------------------------------------ 103 bool 104 FindExternalVisibleDeclsByName (const clang::DeclContext *DC, 105 clang::DeclarationName Name); 106 107 //------------------------------------------------------------------ 108 /// Enumerate all Decls in a given lexical context. 109 /// 110 /// @param[in] DC 111 /// The DeclContext being searched. 112 /// 113 /// @param[in] isKindWeWant 114 /// If non-NULL, a callback function that returns true given the 115 /// DeclKinds of desired Decls, and false otherwise. 116 /// 117 /// @param[in] Decls 118 /// A vector that is filled in with matching Decls. 119 //------------------------------------------------------------------ 120 clang::ExternalLoadResult 121 FindExternalLexicalDecls (const clang::DeclContext *DC, 122 bool (*isKindWeWant)(clang::Decl::Kind), 123 llvm::SmallVectorImpl<clang::Decl*> &Decls); 124 125 //------------------------------------------------------------------ 126 /// Specify the layout of the contents of a RecordDecl. 127 /// 128 /// @param[in] Record 129 /// The record (in the parser's AST context) that needs to be 130 /// laid out. 131 /// 132 /// @param[out] Size 133 /// The total size of the record in bits. 134 /// 135 /// @param[out] Alignment 136 /// The alignment of the record in bits. 137 /// 138 /// @param[in] FieldOffsets 139 /// A map that must be populated with pairs of the record's 140 /// fields (in the parser's AST context) and their offsets 141 /// (measured in bits). 142 /// 143 /// @param[in] BaseOffsets 144 /// A map that must be populated with pairs of the record's 145 /// C++ concrete base classes (in the parser's AST context, 146 /// and only if the record is a CXXRecordDecl and has base 147 /// classes) and their offsets (measured in bytes). 148 /// 149 /// @param[in] VirtualBaseOffsets 150 /// A map that must be populated with pairs of the record's 151 /// C++ virtual base classes (in the parser's AST context, 152 /// and only if the record is a CXXRecordDecl and has base 153 /// classes) and their offsets (measured in bytes). 154 /// 155 /// @return 156 /// True <=> the layout is valid. 157 //----------------------------------------------------------------- 158 bool 159 layoutRecordType(const clang::RecordDecl *Record, 160 uint64_t &Size, 161 uint64_t &Alignment, 162 llvm::DenseMap <const clang::FieldDecl *, uint64_t> &FieldOffsets, 163 llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets, 164 llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets); 165 166 //------------------------------------------------------------------ 167 /// Complete a TagDecl. 168 /// 169 /// @param[in] Tag 170 /// The Decl to be completed in place. 171 //------------------------------------------------------------------ 172 virtual void 173 CompleteType (clang::TagDecl *Tag); 174 175 //------------------------------------------------------------------ 176 /// Complete an ObjCInterfaceDecl. 177 /// 178 /// @param[in] Class 179 /// The Decl to be completed in place. 180 //------------------------------------------------------------------ 181 virtual void 182 CompleteType (clang::ObjCInterfaceDecl *Class); 183 184 //------------------------------------------------------------------ 185 /// Called on entering a translation unit. Tells Clang by calling 186 /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage() 187 /// that this object has something to say about undefined names. 188 /// 189 /// @param[in] ASTConsumer 190 /// Unused. 191 //------------------------------------------------------------------ 192 void StartTranslationUnit (clang::ASTConsumer *Consumer); 193 194 // 195 // APIs for NamespaceMapCompleter 196 // 197 198 //------------------------------------------------------------------ 199 /// Look up the modules containing a given namespace and put the 200 /// appropriate entries in the namespace map. 201 /// 202 /// @param[in] namespace_map 203 /// The map to be completed. 204 /// 205 /// @param[in] name 206 /// The name of the namespace to be found. 207 /// 208 /// @param[in] parent_map 209 /// The map for the namespace's parent namespace, if there is 210 /// one. 211 //------------------------------------------------------------------ 212 void CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespace_map, 213 const ConstString &name, 214 ClangASTImporter::NamespaceMapSP &parent_map) const; 215 216 // 217 // Helper APIs 218 // 219 220 clang::NamespaceDecl * 221 AddNamespace (NameSearchContext &context, 222 ClangASTImporter::NamespaceMapSP &namespace_decls); 223 224 //------------------------------------------------------------------ 225 /// The worker function for FindExternalVisibleDeclsByName. 226 /// 227 /// @param[in] context 228 /// The NameSearchContext to use when filing results. 229 //------------------------------------------------------------------ 230 virtual void FindExternalVisibleDecls (NameSearchContext &context); 231 232 void SetImportInProgress (bool import_in_progress) { m_import_in_progress = import_in_progress; } 233 bool GetImportInProgress () { return m_import_in_progress; } 234 235 void SetLookupsEnabled (bool lookups_enabled) { m_lookups_enabled = lookups_enabled; } 236 bool GetLookupsEnabled () { return m_lookups_enabled; } 237 238 //---------------------------------------------------------------------- 239 /// @class ClangASTSourceProxy ClangASTSource.h "lldb/Expression/ClangASTSource.h" 240 /// @brief Proxy for ClangASTSource 241 /// 242 /// Clang AST contexts like to own their AST sources, so this is a 243 /// state-free proxy object. 244 //---------------------------------------------------------------------- 245 class ClangASTSourceProxy : public ClangExternalASTSourceCommon 246 { 247 public: 248 ClangASTSourceProxy (ClangASTSource &original) : 249 m_original(original) 250 { 251 } 252 253 bool 254 FindExternalVisibleDeclsByName (const clang::DeclContext *DC, 255 clang::DeclarationName Name) 256 { 257 return m_original.FindExternalVisibleDeclsByName(DC, Name); 258 } 259 260 clang::ExternalLoadResult 261 FindExternalLexicalDecls (const clang::DeclContext *DC, 262 bool (*isKindWeWant)(clang::Decl::Kind), 263 llvm::SmallVectorImpl<clang::Decl*> &Decls) 264 { 265 return m_original.FindExternalLexicalDecls(DC, isKindWeWant, Decls); 266 } 267 268 void 269 CompleteType (clang::TagDecl *Tag) 270 { 271 return m_original.CompleteType(Tag); 272 } 273 274 void 275 CompleteType (clang::ObjCInterfaceDecl *Class) 276 { 277 return m_original.CompleteType(Class); 278 } 279 280 bool 281 layoutRecordType(const clang::RecordDecl *Record, 282 uint64_t &Size, 283 uint64_t &Alignment, 284 llvm::DenseMap <const clang::FieldDecl *, uint64_t> &FieldOffsets, 285 llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets, 286 llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets) 287 { 288 return m_original.layoutRecordType(Record, 289 Size, 290 Alignment, 291 FieldOffsets, 292 BaseOffsets, 293 VirtualBaseOffsets); 294 } 295 296 void StartTranslationUnit (clang::ASTConsumer *Consumer) 297 { 298 return m_original.StartTranslationUnit(Consumer); 299 } 300 301 ClangASTMetadata * 302 GetMetadata(const void * object) 303 { 304 return m_original.GetMetadata(object); 305 } 306 307 void 308 SetMetadata(const void * object, ClangASTMetadata &metadata) 309 { 310 return m_original.SetMetadata(object, metadata); 311 } 312 313 bool 314 HasMetadata(const void * object) 315 { 316 return m_original.HasMetadata(object); 317 } 318 private: 319 ClangASTSource &m_original; 320 }; 321 322 clang::ExternalASTSource *CreateProxy() 323 { 324 return new ClangASTSourceProxy(*this); 325 } 326 327protected: 328 //------------------------------------------------------------------ 329 /// Look for the complete version of an Objective-C interface, and 330 /// return it if found. 331 /// 332 /// @param[in] interface_decl 333 /// An ObjCInterfaceDecl that may not be the complete one. 334 /// 335 /// @return 336 /// NULL if the complete interface couldn't be found; 337 /// the complete interface otherwise. 338 //------------------------------------------------------------------ 339 clang::ObjCInterfaceDecl * 340 GetCompleteObjCInterface (clang::ObjCInterfaceDecl *interface_decl); 341 342 //------------------------------------------------------------------ 343 /// Find all entities matching a given name in a given module, 344 /// using a NameSearchContext to make Decls for them. 345 /// 346 /// @param[in] context 347 /// The NameSearchContext that can construct Decls for this name. 348 /// 349 /// @param[in] module 350 /// If non-NULL, the module to query. 351 /// 352 /// @param[in] namespace_decl 353 /// If valid and module is non-NULL, the parent namespace. 354 /// 355 /// @param[in] current_id 356 /// The ID for the current FindExternalVisibleDecls invocation, 357 /// for logging purposes. 358 /// 359 /// @return 360 /// True on success; false otherwise. 361 //------------------------------------------------------------------ 362 void 363 FindExternalVisibleDecls (NameSearchContext &context, 364 lldb::ModuleSP module, 365 ClangNamespaceDecl &namespace_decl, 366 unsigned int current_id); 367 368 //------------------------------------------------------------------ 369 /// Find all Objective-C methods matching a given selector. 370 /// 371 /// @param[in] context 372 /// The NameSearchContext that can construct Decls for this name. 373 /// Its m_decl_name contains the selector and its m_decl_context 374 /// is the containing object. 375 //------------------------------------------------------------------ 376 void 377 FindObjCMethodDecls (NameSearchContext &context); 378 379 //------------------------------------------------------------------ 380 /// Find all Objective-C properties and ivars with a given name. 381 /// 382 /// @param[in] context 383 /// The NameSearchContext that can construct Decls for this name. 384 /// Its m_decl_name contains the name and its m_decl_context 385 /// is the containing object. 386 //------------------------------------------------------------------ 387 void 388 FindObjCPropertyAndIvarDecls (NameSearchContext &context); 389 390 //------------------------------------------------------------------ 391 /// A wrapper for ClangASTContext::CopyType that sets a flag that 392 /// indicates that we should not respond to queries during import. 393 /// 394 /// @param[in] dest_context 395 /// The target AST context, typically the parser's AST context. 396 /// 397 /// @param[in] source_context 398 /// The source AST context, typically the AST context of whatever 399 /// symbol file the type was found in. 400 /// 401 /// @param[in] clang_type 402 /// The source type. 403 /// 404 /// @return 405 /// The imported type. 406 //------------------------------------------------------------------ 407 void * 408 GuardedCopyType (clang::ASTContext *dest_context, 409 clang::ASTContext *source_context, 410 void *clang_type); 411 412 friend struct NameSearchContext; 413 414 bool m_import_in_progress; 415 bool m_lookups_enabled; 416 417 const lldb::TargetSP m_target; ///< The target to use in finding variables and types. 418 clang::ASTContext *m_ast_context; ///< The AST context requests are coming in for. 419 ClangASTImporter *m_ast_importer; ///< The target's AST importer. 420 std::set<const char *> m_active_lookups; 421}; 422 423//---------------------------------------------------------------------- 424/// @class NameSearchContext ClangASTSource.h "lldb/Expression/ClangASTSource.h" 425/// @brief Container for all objects relevant to a single name lookup 426/// 427/// LLDB needs to create Decls for entities it finds. This class communicates 428/// what name is being searched for and provides helper functions to construct 429/// Decls given appropriate type information. 430//---------------------------------------------------------------------- 431struct NameSearchContext { 432 ClangASTSource &m_ast_source; ///< The AST source making the request 433 llvm::SmallVectorImpl<clang::NamedDecl*> &m_decls; ///< The list of declarations already constructed 434 ClangASTImporter::NamespaceMapSP m_namespace_map; ///< The mapping of all namespaces found for this request back to their modules 435 const clang::DeclarationName &m_decl_name; ///< The name being looked for 436 const clang::DeclContext *m_decl_context; ///< The DeclContext to put declarations into 437 llvm::SmallSet <lldb::clang_type_t, 5> m_function_types; ///< All the types of functions that have been reported, so we don't report conflicts 438 439 struct { 440 bool variable : 1; 441 bool function_with_type_info : 1; 442 bool function : 1; 443 } m_found; 444 445 //------------------------------------------------------------------ 446 /// Constructor 447 /// 448 /// Initializes class variables. 449 /// 450 /// @param[in] astSource 451 /// A reference to the AST source making a request. 452 /// 453 /// @param[in] decls 454 /// A reference to a list into which new Decls will be placed. This 455 /// list is typically empty when the function is called. 456 /// 457 /// @param[in] name 458 /// The name being searched for (always an Identifier). 459 /// 460 /// @param[in] dc 461 /// The DeclContext to register Decls in. 462 //------------------------------------------------------------------ 463 NameSearchContext (ClangASTSource &astSource, 464 llvm::SmallVectorImpl<clang::NamedDecl*> &decls, 465 clang::DeclarationName &name, 466 const clang::DeclContext *dc) : 467 m_ast_source(astSource), 468 m_decls(decls), 469 m_decl_name(name), 470 m_decl_context(dc) 471 { 472 memset(&m_found, 0, sizeof(m_found)); 473 } 474 475 //------------------------------------------------------------------ 476 /// Create a VarDecl with the name being searched for and the provided 477 /// type and register it in the right places. 478 /// 479 /// @param[in] type 480 /// The opaque QualType for the VarDecl being registered. 481 //------------------------------------------------------------------ 482 clang::NamedDecl *AddVarDecl(void *type); 483 484 //------------------------------------------------------------------ 485 /// Create a FunDecl with the name being searched for and the provided 486 /// type and register it in the right places. 487 /// 488 /// @param[in] type 489 /// The opaque QualType for the FunDecl being registered. 490 //------------------------------------------------------------------ 491 clang::NamedDecl *AddFunDecl(void *type); 492 493 //------------------------------------------------------------------ 494 /// Create a FunDecl with the name being searched for and generic 495 /// type (i.e. intptr_t NAME_GOES_HERE(...)) and register it in the 496 /// right places. 497 //------------------------------------------------------------------ 498 clang::NamedDecl *AddGenericFunDecl(); 499 500 //------------------------------------------------------------------ 501 /// Create a TypeDecl with the name being searched for and the provided 502 /// type and register it in the right places. 503 /// 504 /// @param[in] type 505 /// The opaque QualType for the TypeDecl being registered. 506 //------------------------------------------------------------------ 507 clang::NamedDecl *AddTypeDecl(void *type); 508 509 510 //------------------------------------------------------------------ 511 /// Add Decls from the provided DeclContextLookupResult to the list 512 /// of results. 513 /// 514 /// @param[in] result 515 /// The DeclContextLookupResult, usually returned as the result 516 /// of querying a DeclContext. 517 //------------------------------------------------------------------ 518 void AddLookupResult (clang::DeclContextLookupConstResult result); 519 520 //------------------------------------------------------------------ 521 /// Add a NamedDecl to the list of results. 522 /// 523 /// @param[in] decl 524 /// The NamedDecl, usually returned as the result 525 /// of querying a DeclContext. 526 //------------------------------------------------------------------ 527 void AddNamedDecl (clang::NamedDecl *decl); 528}; 529 530} 531 532#endif 533