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