ClangASTSource.h revision e0028b827759c5ad2cbc45947371c362193a63bc
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 /// Complete a TagDecl. 125 /// 126 /// @param[in] Tag 127 /// The Decl to be completed in place. 128 //------------------------------------------------------------------ 129 virtual void 130 CompleteType (clang::TagDecl *Tag); 131 132 //------------------------------------------------------------------ 133 /// Complete an ObjCInterfaceDecl. 134 /// 135 /// @param[in] Class 136 /// The Decl to be completed in place. 137 //------------------------------------------------------------------ 138 virtual void 139 CompleteType (clang::ObjCInterfaceDecl *Class); 140 141 //------------------------------------------------------------------ 142 /// Called on entering a translation unit. Tells Clang by calling 143 /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage() 144 /// that this object has something to say about undefined names. 145 /// 146 /// @param[in] ASTConsumer 147 /// Unused. 148 //------------------------------------------------------------------ 149 void StartTranslationUnit (clang::ASTConsumer *Consumer); 150 151 // 152 // APIs for NamespaceMapCompleter 153 // 154 155 //------------------------------------------------------------------ 156 /// Look up the modules containing a given namespace and put the 157 /// appropriate entries in the namespace map. 158 /// 159 /// @param[in] namespace_map 160 /// The map to be completed. 161 /// 162 /// @param[in] name 163 /// The name of the namespace to be found. 164 /// 165 /// @param[in] parent_map 166 /// The map for the namespace's parent namespace, if there is 167 /// one. 168 //------------------------------------------------------------------ 169 void CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespace_map, 170 const ConstString &name, 171 ClangASTImporter::NamespaceMapSP &parent_map) const; 172 173 // 174 // Helper APIs 175 // 176 177 clang::NamespaceDecl * 178 AddNamespace (NameSearchContext &context, 179 ClangASTImporter::NamespaceMapSP &namespace_decls); 180 181 //------------------------------------------------------------------ 182 /// The worker function for FindExternalVisibleDeclsByName. 183 /// 184 /// @param[in] context 185 /// The NameSearchContext to use when filing results. 186 //------------------------------------------------------------------ 187 virtual void FindExternalVisibleDecls (NameSearchContext &context); 188 189 void SetImportInProgress (bool import_in_progress) { m_import_in_progress = import_in_progress; } 190 bool GetImportInProgress () { return m_import_in_progress; } 191 192 void SetLookupsEnabled (bool lookups_enabled) { m_lookups_enabled = lookups_enabled; } 193 bool GetLookupsEnabled () { return m_lookups_enabled; } 194 195 //---------------------------------------------------------------------- 196 /// @class ClangASTSourceProxy ClangASTSource.h "lldb/Expression/ClangASTSource.h" 197 /// @brief Proxy for ClangASTSource 198 /// 199 /// Clang AST contexts like to own their AST sources, so this is a 200 /// state-free proxy object. 201 //---------------------------------------------------------------------- 202 class ClangASTSourceProxy : public ClangExternalASTSourceCommon 203 { 204 public: 205 ClangASTSourceProxy (ClangASTSource &original) : 206 m_original(original) 207 { 208 } 209 210 clang::DeclContextLookupResult 211 FindExternalVisibleDeclsByName (const clang::DeclContext *DC, 212 clang::DeclarationName Name) 213 { 214 return m_original.FindExternalVisibleDeclsByName(DC, Name); 215 } 216 217 clang::ExternalLoadResult 218 FindExternalLexicalDecls (const clang::DeclContext *DC, 219 bool (*isKindWeWant)(clang::Decl::Kind), 220 llvm::SmallVectorImpl<clang::Decl*> &Decls) 221 { 222 return m_original.FindExternalLexicalDecls(DC, isKindWeWant, Decls); 223 } 224 225 void 226 CompleteType (clang::TagDecl *Tag) 227 { 228 return m_original.CompleteType(Tag); 229 } 230 231 void 232 CompleteType (clang::ObjCInterfaceDecl *Class) 233 { 234 return m_original.CompleteType(Class); 235 } 236 237 void StartTranslationUnit (clang::ASTConsumer *Consumer) 238 { 239 return m_original.StartTranslationUnit(Consumer); 240 } 241 242 uint64_t GetMetadata(uintptr_t object) 243 { 244 return m_original.GetMetadata(object); 245 } 246 247 void SetMetadata(uintptr_t object, uint64_t metadata) 248 { 249 return m_original.SetMetadata(object, metadata); 250 } 251 252 bool HasMetadata(uintptr_t object) 253 { 254 return m_original.HasMetadata(object); 255 } 256 private: 257 ClangASTSource &m_original; 258 }; 259 260 clang::ExternalASTSource *CreateProxy() 261 { 262 return new ClangASTSourceProxy(*this); 263 } 264 265protected: 266 //------------------------------------------------------------------ 267 /// Find all entities matching a given name in a given module, 268 /// using a NameSearchContext to make Decls for them. 269 /// 270 /// @param[in] context 271 /// The NameSearchContext that can construct Decls for this name. 272 /// 273 /// @param[in] module 274 /// If non-NULL, the module to query. 275 /// 276 /// @param[in] namespace_decl 277 /// If valid and module is non-NULL, the parent namespace. 278 /// 279 /// @param[in] current_id 280 /// The ID for the current FindExternalVisibleDecls invocation, 281 /// for logging purposes. 282 /// 283 /// @return 284 /// True on success; false otherwise. 285 //------------------------------------------------------------------ 286 void 287 FindExternalVisibleDecls (NameSearchContext &context, 288 lldb::ModuleSP module, 289 ClangNamespaceDecl &namespace_decl, 290 unsigned int current_id); 291 292 //------------------------------------------------------------------ 293 /// Find all Objective-C methods matching a given selector. 294 /// 295 /// @param[in] context 296 /// The NameSearchContext that can construct Decls for this name. 297 /// Its m_decl_name contains the selector and its m_decl_context 298 /// is the containing object. 299 //------------------------------------------------------------------ 300 void 301 FindObjCMethodDecls (NameSearchContext &context); 302 303 //------------------------------------------------------------------ 304 /// Find all Objective-C properties with a given name. 305 /// 306 /// @param[in] context 307 /// The NameSearchContext that can construct Decls for this name. 308 /// Its m_decl_name contains the name and its m_decl_context 309 /// is the containing object. 310 //------------------------------------------------------------------ 311 void 312 FindObjCPropertyDecls (NameSearchContext &context); 313 314 //------------------------------------------------------------------ 315 /// A wrapper for ClangASTContext::CopyType that sets a flag that 316 /// indicates that we should not respond to queries during import. 317 /// 318 /// @param[in] dest_context 319 /// The target AST context, typically the parser's AST context. 320 /// 321 /// @param[in] source_context 322 /// The source AST context, typically the AST context of whatever 323 /// symbol file the type was found in. 324 /// 325 /// @param[in] clang_type 326 /// The source type. 327 /// 328 /// @return 329 /// The imported type. 330 //------------------------------------------------------------------ 331 void * 332 GuardedCopyType (clang::ASTContext *dest_context, 333 clang::ASTContext *source_context, 334 void *clang_type); 335 336 friend struct NameSearchContext; 337 338 bool m_import_in_progress; 339 bool m_lookups_enabled; 340 341 const lldb::TargetSP m_target; ///< The target to use in finding variables and types. 342 clang::ASTContext *m_ast_context; ///< The AST context requests are coming in for. 343 ClangASTImporter *m_ast_importer; ///< The target's AST importer. 344 std::set<const char *> m_active_lookups; 345}; 346 347//---------------------------------------------------------------------- 348/// @class NameSearchContext ClangASTSource.h "lldb/Expression/ClangASTSource.h" 349/// @brief Container for all objects relevant to a single name lookup 350/// 351/// LLDB needs to create Decls for entities it finds. This class communicates 352/// what name is being searched for and provides helper functions to construct 353/// Decls given appropriate type information. 354//---------------------------------------------------------------------- 355struct NameSearchContext { 356 ClangASTSource &m_ast_source; ///< The AST source making the request 357 llvm::SmallVectorImpl<clang::NamedDecl*> &m_decls; ///< The list of declarations already constructed 358 ClangASTImporter::NamespaceMapSP m_namespace_map; ///< The mapping of all namespaces found for this request back to their modules 359 const clang::DeclarationName &m_decl_name; ///< The name being looked for 360 const clang::DeclContext *m_decl_context; ///< The DeclContext to put declarations into 361 362 struct { 363 bool variable : 1; 364 bool function_with_type_info : 1; 365 bool function : 1; 366 } m_found; 367 368 //------------------------------------------------------------------ 369 /// Constructor 370 /// 371 /// Initializes class variables. 372 /// 373 /// @param[in] astSource 374 /// A reference to the AST source making a request. 375 /// 376 /// @param[in] decls 377 /// A reference to a list into which new Decls will be placed. This 378 /// list is typically empty when the function is called. 379 /// 380 /// @param[in] name 381 /// The name being searched for (always an Identifier). 382 /// 383 /// @param[in] dc 384 /// The DeclContext to register Decls in. 385 //------------------------------------------------------------------ 386 NameSearchContext (ClangASTSource &astSource, 387 llvm::SmallVectorImpl<clang::NamedDecl*> &decls, 388 clang::DeclarationName &name, 389 const clang::DeclContext *dc) : 390 m_ast_source(astSource), 391 m_decls(decls), 392 m_decl_name(name), 393 m_decl_context(dc) 394 { 395 memset(&m_found, 0, sizeof(m_found)); 396 } 397 398 //------------------------------------------------------------------ 399 /// Create a VarDecl with the name being searched for and the provided 400 /// type and register it in the right places. 401 /// 402 /// @param[in] type 403 /// The opaque QualType for the VarDecl being registered. 404 //------------------------------------------------------------------ 405 clang::NamedDecl *AddVarDecl(void *type); 406 407 //------------------------------------------------------------------ 408 /// Create a FunDecl with the name being searched for and the provided 409 /// type and register it in the right places. 410 /// 411 /// @param[in] type 412 /// The opaque QualType for the FunDecl being registered. 413 //------------------------------------------------------------------ 414 clang::NamedDecl *AddFunDecl(void *type); 415 416 //------------------------------------------------------------------ 417 /// Create a FunDecl with the name being searched for and generic 418 /// type (i.e. intptr_t NAME_GOES_HERE(...)) and register it in the 419 /// right places. 420 //------------------------------------------------------------------ 421 clang::NamedDecl *AddGenericFunDecl(); 422 423 //------------------------------------------------------------------ 424 /// Create a TypeDecl with the name being searched for and the provided 425 /// type and register it in the right places. 426 /// 427 /// @param[in] type 428 /// The opaque QualType for the TypeDecl being registered. 429 //------------------------------------------------------------------ 430 clang::NamedDecl *AddTypeDecl(void *type); 431 432 433 //------------------------------------------------------------------ 434 /// Add Decls from the provided DeclContextLookupResult to the list 435 /// of results. 436 /// 437 /// @param[in] result 438 /// The DeclContextLookupResult, usually returned as the result 439 /// of querying a DeclContext. 440 //------------------------------------------------------------------ 441 void AddLookupResult (clang::DeclContextLookupConstResult result); 442 443 //------------------------------------------------------------------ 444 /// Add a NamedDecl to the list of results. 445 /// 446 /// @param[in] decl 447 /// The NamedDecl, usually returned as the result 448 /// of querying a DeclContext. 449 //------------------------------------------------------------------ 450 void AddNamedDecl (clang::NamedDecl *decl); 451}; 452 453} 454 455#endif 456