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