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 "clang/Basic/IdentifierTable.h" 16 #include "lldb/Symbol/ClangExternalASTSourceCommon.h" 17 #include "lldb/Symbol/ClangASTImporter.h" 18 #include "lldb/Target/Target.h" 19 20 #include "llvm/ADT/SmallSet.h" 21 22 namespace 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 //---------------------------------------------------------------------- 35 class ClangASTSource : 36 public ClangExternalASTSourceCommon, 37 public ClangASTImporter::MapCompleter 38 { 39 public: 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 //------------------------------------------------------------------ ClangASTSource(const lldb::TargetSP & target)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 //------------------------------------------------------------------ GetExternalDecl(uint32_t)66 clang::Decl *GetExternalDecl (uint32_t) { return NULL; } GetExternalDeclStmt(uint64_t)67 clang::Stmt *GetExternalDeclStmt (uint64_t) { return NULL; } GetExternalSelector(uint32_t)68 clang::Selector GetExternalSelector (uint32_t) { return clang::Selector(); } GetNumExternalSelectors()69 uint32_t GetNumExternalSelectors () { return 0; } GetExternalCXXBaseSpecifiers(uint64_t Offset)70 clang::CXXBaseSpecifier *GetExternalCXXBaseSpecifiers (uint64_t Offset) 71 { return NULL; } MaterializeVisibleDecls(const clang::DeclContext * DC)72 void MaterializeVisibleDecls (const clang::DeclContext *DC) 73 { return; } 74 InstallASTContext(clang::ASTContext * ast_context)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 SetImportInProgress(bool import_in_progress)232 void SetImportInProgress (bool import_in_progress) { m_import_in_progress = import_in_progress; } GetImportInProgress()233 bool GetImportInProgress () { return m_import_in_progress; } 234 SetLookupsEnabled(bool lookups_enabled)235 void SetLookupsEnabled (bool lookups_enabled) { m_lookups_enabled = lookups_enabled; } GetLookupsEnabled()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: ClangASTSourceProxy(ClangASTSource & original)248 ClangASTSourceProxy (ClangASTSource &original) : 249 m_original(original) 250 { 251 } 252 253 bool FindExternalVisibleDeclsByName(const clang::DeclContext * DC,clang::DeclarationName Name)254 FindExternalVisibleDeclsByName (const clang::DeclContext *DC, 255 clang::DeclarationName Name) 256 { 257 return m_original.FindExternalVisibleDeclsByName(DC, Name); 258 } 259 260 clang::ExternalLoadResult FindExternalLexicalDecls(const clang::DeclContext * DC,bool (* isKindWeWant)(clang::Decl::Kind),llvm::SmallVectorImpl<clang::Decl * > & Decls)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 CompleteType(clang::TagDecl * Tag)269 CompleteType (clang::TagDecl *Tag) 270 { 271 return m_original.CompleteType(Tag); 272 } 273 274 void CompleteType(clang::ObjCInterfaceDecl * Class)275 CompleteType (clang::ObjCInterfaceDecl *Class) 276 { 277 return m_original.CompleteType(Class); 278 } 279 280 bool 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)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 StartTranslationUnit(clang::ASTConsumer * Consumer)296 void StartTranslationUnit (clang::ASTConsumer *Consumer) 297 { 298 return m_original.StartTranslationUnit(Consumer); 299 } 300 301 ClangASTMetadata * GetMetadata(const void * object)302 GetMetadata(const void * object) 303 { 304 return m_original.GetMetadata(object); 305 } 306 307 void SetMetadata(const void * object,ClangASTMetadata & metadata)308 SetMetadata(const void * object, ClangASTMetadata &metadata) 309 { 310 return m_original.SetMetadata(object, metadata); 311 } 312 313 bool HasMetadata(const void * object)314 HasMetadata(const void * object) 315 { 316 return m_original.HasMetadata(object); 317 } 318 private: 319 ClangASTSource &m_original; 320 }; 321 CreateProxy()322 clang::ExternalASTSource *CreateProxy() 323 { 324 return new ClangASTSourceProxy(*this); 325 } 326 327 protected: 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 ClangASTType 408 GuardedCopyType (const ClangASTType &src_type); 409 410 friend struct NameSearchContext; 411 412 bool m_import_in_progress; 413 bool m_lookups_enabled; 414 415 const lldb::TargetSP m_target; ///< The target to use in finding variables and types. 416 clang::ASTContext *m_ast_context; ///< The AST context requests are coming in for. 417 ClangASTImporter *m_ast_importer; ///< The target's AST importer. 418 std::set<const char *> m_active_lookups; 419 }; 420 421 //---------------------------------------------------------------------- 422 /// @class NameSearchContext ClangASTSource.h "lldb/Expression/ClangASTSource.h" 423 /// @brief Container for all objects relevant to a single name lookup 424 /// 425 /// LLDB needs to create Decls for entities it finds. This class communicates 426 /// what name is being searched for and provides helper functions to construct 427 /// Decls given appropriate type information. 428 //---------------------------------------------------------------------- 429 struct NameSearchContext { 430 ClangASTSource &m_ast_source; ///< The AST source making the request 431 llvm::SmallVectorImpl<clang::NamedDecl*> &m_decls; ///< The list of declarations already constructed 432 ClangASTImporter::NamespaceMapSP m_namespace_map; ///< The mapping of all namespaces found for this request back to their modules 433 const clang::DeclarationName &m_decl_name; ///< The name being looked for 434 const clang::DeclContext *m_decl_context; ///< The DeclContext to put declarations into 435 llvm::SmallSet <ClangASTType, 5> m_function_types; ///< All the types of functions that have been reported, so we don't report conflicts 436 437 struct { 438 bool variable : 1; 439 bool function_with_type_info : 1; 440 bool function : 1; 441 } m_found; 442 443 //------------------------------------------------------------------ 444 /// Constructor 445 /// 446 /// Initializes class variables. 447 /// 448 /// @param[in] astSource 449 /// A reference to the AST source making a request. 450 /// 451 /// @param[in] decls 452 /// A reference to a list into which new Decls will be placed. This 453 /// list is typically empty when the function is called. 454 /// 455 /// @param[in] name 456 /// The name being searched for (always an Identifier). 457 /// 458 /// @param[in] dc 459 /// The DeclContext to register Decls in. 460 //------------------------------------------------------------------ NameSearchContextNameSearchContext461 NameSearchContext (ClangASTSource &astSource, 462 llvm::SmallVectorImpl<clang::NamedDecl*> &decls, 463 clang::DeclarationName &name, 464 const clang::DeclContext *dc) : 465 m_ast_source(astSource), 466 m_decls(decls), 467 m_decl_name(name), 468 m_decl_context(dc) 469 { 470 memset(&m_found, 0, sizeof(m_found)); 471 } 472 473 //------------------------------------------------------------------ 474 /// Create a VarDecl with the name being searched for and the provided 475 /// type and register it in the right places. 476 /// 477 /// @param[in] type 478 /// The opaque QualType for the VarDecl being registered. 479 //------------------------------------------------------------------ 480 clang::NamedDecl *AddVarDecl(const ClangASTType &type); 481 482 //------------------------------------------------------------------ 483 /// Create a FunDecl with the name being searched for and the provided 484 /// type and register it in the right places. 485 /// 486 /// @param[in] type 487 /// The opaque QualType for the FunDecl being registered. 488 //------------------------------------------------------------------ 489 clang::NamedDecl *AddFunDecl(const ClangASTType &type); 490 491 //------------------------------------------------------------------ 492 /// Create a FunDecl with the name being searched for and generic 493 /// type (i.e. intptr_t NAME_GOES_HERE(...)) and register it in the 494 /// right places. 495 //------------------------------------------------------------------ 496 clang::NamedDecl *AddGenericFunDecl(); 497 498 //------------------------------------------------------------------ 499 /// Create a TypeDecl with the name being searched for and the provided 500 /// type and register it in the right places. 501 /// 502 /// @param[in] type 503 /// The opaque QualType for the TypeDecl being registered. 504 //------------------------------------------------------------------ 505 clang::NamedDecl *AddTypeDecl(const ClangASTType &clang_type); 506 507 508 //------------------------------------------------------------------ 509 /// Add Decls from the provided DeclContextLookupResult to the list 510 /// of results. 511 /// 512 /// @param[in] result 513 /// The DeclContextLookupResult, usually returned as the result 514 /// of querying a DeclContext. 515 //------------------------------------------------------------------ 516 void AddLookupResult (clang::DeclContextLookupConstResult result); 517 518 //------------------------------------------------------------------ 519 /// Add a NamedDecl to the list of results. 520 /// 521 /// @param[in] decl 522 /// The NamedDecl, usually returned as the result 523 /// of querying a DeclContext. 524 //------------------------------------------------------------------ 525 void AddNamedDecl (clang::NamedDecl *decl); 526 }; 527 528 } 529 530 #endif 531