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