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