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