ClangASTSource.h revision 8f2e392e8937aaf66f91201dc5f4190d61902c67
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 /// Find all entities matching a given name in a given module, 325 /// using a NameSearchContext to make Decls for them. 326 /// 327 /// @param[in] context 328 /// The NameSearchContext that can construct Decls for this name. 329 /// 330 /// @param[in] module 331 /// If non-NULL, the module to query. 332 /// 333 /// @param[in] namespace_decl 334 /// If valid and module is non-NULL, the parent namespace. 335 /// 336 /// @param[in] current_id 337 /// The ID for the current FindExternalVisibleDecls invocation, 338 /// for logging purposes. 339 /// 340 /// @return 341 /// True on success; false otherwise. 342 //------------------------------------------------------------------ 343 void 344 FindExternalVisibleDecls (NameSearchContext &context, 345 lldb::ModuleSP module, 346 ClangNamespaceDecl &namespace_decl, 347 unsigned int current_id); 348 349 //------------------------------------------------------------------ 350 /// Find all Objective-C methods matching a given selector. 351 /// 352 /// @param[in] context 353 /// The NameSearchContext that can construct Decls for this name. 354 /// Its m_decl_name contains the selector and its m_decl_context 355 /// is the containing object. 356 //------------------------------------------------------------------ 357 void 358 FindObjCMethodDecls (NameSearchContext &context); 359 360 //------------------------------------------------------------------ 361 /// Find all Objective-C properties and ivars with a given name. 362 /// 363 /// @param[in] context 364 /// The NameSearchContext that can construct Decls for this name. 365 /// Its m_decl_name contains the name and its m_decl_context 366 /// is the containing object. 367 //------------------------------------------------------------------ 368 void 369 FindObjCPropertyAndIvarDecls (NameSearchContext &context); 370 371 //------------------------------------------------------------------ 372 /// A wrapper for ClangASTContext::CopyType that sets a flag that 373 /// indicates that we should not respond to queries during import. 374 /// 375 /// @param[in] dest_context 376 /// The target AST context, typically the parser's AST context. 377 /// 378 /// @param[in] source_context 379 /// The source AST context, typically the AST context of whatever 380 /// symbol file the type was found in. 381 /// 382 /// @param[in] clang_type 383 /// The source type. 384 /// 385 /// @return 386 /// The imported type. 387 //------------------------------------------------------------------ 388 void * 389 GuardedCopyType (clang::ASTContext *dest_context, 390 clang::ASTContext *source_context, 391 void *clang_type); 392 393 friend struct NameSearchContext; 394 395 bool m_import_in_progress; 396 bool m_lookups_enabled; 397 398 const lldb::TargetSP m_target; ///< The target to use in finding variables and types. 399 clang::ASTContext *m_ast_context; ///< The AST context requests are coming in for. 400 ClangASTImporter *m_ast_importer; ///< The target's AST importer. 401 std::set<const char *> m_active_lookups; 402}; 403 404//---------------------------------------------------------------------- 405/// @class NameSearchContext ClangASTSource.h "lldb/Expression/ClangASTSource.h" 406/// @brief Container for all objects relevant to a single name lookup 407/// 408/// LLDB needs to create Decls for entities it finds. This class communicates 409/// what name is being searched for and provides helper functions to construct 410/// Decls given appropriate type information. 411//---------------------------------------------------------------------- 412struct NameSearchContext { 413 ClangASTSource &m_ast_source; ///< The AST source making the request 414 llvm::SmallVectorImpl<clang::NamedDecl*> &m_decls; ///< The list of declarations already constructed 415 ClangASTImporter::NamespaceMapSP m_namespace_map; ///< The mapping of all namespaces found for this request back to their modules 416 const clang::DeclarationName &m_decl_name; ///< The name being looked for 417 const clang::DeclContext *m_decl_context; ///< The DeclContext to put declarations into 418 419 struct { 420 bool variable : 1; 421 bool function_with_type_info : 1; 422 bool function : 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, 446 const clang::DeclContext *dc) : 447 m_ast_source(astSource), 448 m_decls(decls), 449 m_decl_name(name), 450 m_decl_context(dc) 451 { 452 memset(&m_found, 0, sizeof(m_found)); 453 } 454 455 //------------------------------------------------------------------ 456 /// Create a VarDecl with the name being searched for and the provided 457 /// type and register it in the right places. 458 /// 459 /// @param[in] type 460 /// The opaque QualType for the VarDecl being registered. 461 //------------------------------------------------------------------ 462 clang::NamedDecl *AddVarDecl(void *type); 463 464 //------------------------------------------------------------------ 465 /// Create a FunDecl with the name being searched for and the provided 466 /// type and register it in the right places. 467 /// 468 /// @param[in] type 469 /// The opaque QualType for the FunDecl being registered. 470 //------------------------------------------------------------------ 471 clang::NamedDecl *AddFunDecl(void *type); 472 473 //------------------------------------------------------------------ 474 /// Create a FunDecl with the name being searched for and generic 475 /// type (i.e. intptr_t NAME_GOES_HERE(...)) and register it in the 476 /// right places. 477 //------------------------------------------------------------------ 478 clang::NamedDecl *AddGenericFunDecl(); 479 480 //------------------------------------------------------------------ 481 /// Create a TypeDecl with the name being searched for and the provided 482 /// type and register it in the right places. 483 /// 484 /// @param[in] type 485 /// The opaque QualType for the TypeDecl being registered. 486 //------------------------------------------------------------------ 487 clang::NamedDecl *AddTypeDecl(void *type); 488 489 490 //------------------------------------------------------------------ 491 /// Add Decls from the provided DeclContextLookupResult to the list 492 /// of results. 493 /// 494 /// @param[in] result 495 /// The DeclContextLookupResult, usually returned as the result 496 /// of querying a DeclContext. 497 //------------------------------------------------------------------ 498 void AddLookupResult (clang::DeclContextLookupConstResult result); 499 500 //------------------------------------------------------------------ 501 /// Add a NamedDecl to the list of results. 502 /// 503 /// @param[in] decl 504 /// The NamedDecl, usually returned as the result 505 /// of querying a DeclContext. 506 //------------------------------------------------------------------ 507 void AddNamedDecl (clang::NamedDecl *decl); 508}; 509 510} 511 512#endif 513