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