ClangASTSource.h revision 73b520f4f60dca58e58e446c9504d45384ee677b
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 "clang/AST/ExternalASTSource.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 clang::ExternalASTSource, 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_ast_context (NULL), 48 m_active_lookups (), 49 m_import_in_progress (false), 50 m_lookups_enabled (false), 51 m_target (target) 52 { 53 } 54 55 //------------------------------------------------------------------ 56 /// Destructor 57 //------------------------------------------------------------------ 58 ~ClangASTSource(); 59 60 //------------------------------------------------------------------ 61 /// Interface stubs. 62 //------------------------------------------------------------------ 63 clang::Decl *GetExternalDecl (uint32_t) { return NULL; } 64 clang::Stmt *GetExternalDeclStmt (uint64_t) { return NULL; } 65 clang::Selector GetExternalSelector (uint32_t) { return clang::Selector(); } 66 uint32_t GetNumExternalSelectors () { return 0; } 67 clang::CXXBaseSpecifier *GetExternalCXXBaseSpecifiers (uint64_t Offset) 68 { return NULL; } 69 void MaterializeVisibleDecls (const clang::DeclContext *DC) 70 { return; } 71 72 void InstallASTContext (clang::ASTContext *ast_context) 73 { 74 if (!m_ast_importer.get() || 75 m_ast_importer->TargetASTContext() != ast_context) 76 { 77 m_ast_importer.reset(new ClangASTImporter(ast_context)); 78 m_ast_importer->InstallMapCompleter(*this); 79 } 80 81 m_ast_context = ast_context; 82 } 83 84 // 85 // APIs for ExternalASTSource 86 // 87 88 //------------------------------------------------------------------ 89 /// Look up all Decls that match a particular name. Only handles 90 /// Identifiers and DeclContexts that are either NamespaceDecls or 91 /// TranslationUnitDecls. Calls SetExternalVisibleDeclsForName with 92 /// the result. 93 /// 94 /// The work for this function is done by 95 /// void FindExternalVisibleDecls (NameSearchContext &); 96 /// 97 /// @param[in] DC 98 /// The DeclContext to register the found Decls in. 99 /// 100 /// @param[in] Name 101 /// The name to find entries for. 102 /// 103 /// @return 104 /// Whatever SetExternalVisibleDeclsForName returns. 105 //------------------------------------------------------------------ 106 clang::DeclContextLookupResult 107 FindExternalVisibleDeclsByName (const clang::DeclContext *DC, 108 clang::DeclarationName Name); 109 110 //------------------------------------------------------------------ 111 /// Enumerate all Decls in a given lexical context. 112 /// 113 /// @param[in] DC 114 /// The DeclContext being searched. 115 /// 116 /// @param[in] isKindWeWant 117 /// If non-NULL, a callback function that returns true given the 118 /// DeclKinds of desired Decls, and false otherwise. 119 /// 120 /// @param[in] Decls 121 /// A vector that is filled in with matching Decls. 122 //------------------------------------------------------------------ 123 virtual clang::ExternalLoadResult 124 FindExternalLexicalDecls (const clang::DeclContext *DC, 125 bool (*isKindWeWant)(clang::Decl::Kind), 126 llvm::SmallVectorImpl<clang::Decl*> &Decls); 127 128 //------------------------------------------------------------------ 129 /// Complete a TagDecl. 130 /// 131 /// @param[in] Tag 132 /// The Decl to be completed in place. 133 //------------------------------------------------------------------ 134 virtual void 135 CompleteType (clang::TagDecl *Tag); 136 137 //------------------------------------------------------------------ 138 /// Complete an ObjCInterfaceDecl. 139 /// 140 /// @param[in] Class 141 /// The Decl to be completed in place. 142 //------------------------------------------------------------------ 143 virtual void 144 CompleteType (clang::ObjCInterfaceDecl *Class); 145 146 //------------------------------------------------------------------ 147 /// Called on entering a translation unit. Tells Clang by calling 148 /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage() 149 /// that this object has something to say about undefined names. 150 /// 151 /// @param[in] ASTConsumer 152 /// Unused. 153 //------------------------------------------------------------------ 154 void StartTranslationUnit (clang::ASTConsumer *Consumer); 155 156 // 157 // APIs for NamespaceMapCompleter 158 // 159 160 161 //------------------------------------------------------------------ 162 /// Look up the modules containing a given namespace and put the 163 /// appropriate entries in the namespace map. 164 /// 165 /// @param[in] namespace_map 166 /// The map to be completed. 167 /// 168 /// @param[in] name 169 /// The name of the namespace to be found. 170 /// 171 /// @param[in] parent_map 172 /// The map for the namespace's parent namespace, if there is 173 /// one. 174 //------------------------------------------------------------------ 175 void CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespace_map, 176 const ConstString &name, 177 ClangASTImporter::NamespaceMapSP &parent_map) const; 178 179 // 180 // Helper APIs 181 // 182 183 //------------------------------------------------------------------ 184 /// The worker function for FindExternalVisibleDeclsByName. 185 /// 186 /// @param[in] context 187 /// The NameSearchContext to use when filing results. 188 //------------------------------------------------------------------ 189 virtual void FindExternalVisibleDecls (NameSearchContext &context); 190 191 void SetImportInProgress (bool import_in_progress) { m_import_in_progress = import_in_progress; } 192 bool GetImportInProgress () { return m_import_in_progress; } 193 194 void SetLookupsEnabled (bool lookups_enabled) { m_lookups_enabled = lookups_enabled; } 195 bool GetLookupsEnabled () { return m_lookups_enabled; } 196 197 //---------------------------------------------------------------------- 198 /// @class ClangASTSourceProxy ClangASTSource.h "lldb/Expression/ClangASTSource.h" 199 /// @brief Proxy for ClangASTSource 200 /// 201 /// Clang AST contexts like to own their AST sources, so this is a 202 /// state-free proxy object. 203 //---------------------------------------------------------------------- 204 class ClangASTSourceProxy : public clang::ExternalASTSource 205 { 206 public: 207 ClangASTSourceProxy (ClangASTSource &original) : 208 m_original(original) 209 { 210 } 211 212 clang::DeclContextLookupResult 213 FindExternalVisibleDeclsByName (const clang::DeclContext *DC, 214 clang::DeclarationName Name) 215 { 216 return m_original.FindExternalVisibleDeclsByName(DC, Name); 217 } 218 219 virtual clang::ExternalLoadResult 220 FindExternalLexicalDecls (const clang::DeclContext *DC, 221 bool (*isKindWeWant)(clang::Decl::Kind), 222 llvm::SmallVectorImpl<clang::Decl*> &Decls) 223 { 224 return m_original.FindExternalLexicalDecls(DC, isKindWeWant, Decls); 225 } 226 227 virtual void 228 CompleteType (clang::TagDecl *Tag) 229 { 230 return m_original.CompleteType(Tag); 231 } 232 233 virtual void 234 CompleteType (clang::ObjCInterfaceDecl *Class) 235 { 236 return m_original.CompleteType(Class); 237 } 238 239 void StartTranslationUnit (clang::ASTConsumer *Consumer) 240 { 241 return m_original.StartTranslationUnit(Consumer); 242 } 243 private: 244 ClangASTSource &m_original; 245 }; 246 247 clang::ExternalASTSource *CreateProxy() 248 { 249 return new ClangASTSourceProxy(*this); 250 } 251 252protected: 253 friend struct NameSearchContext; 254 255 bool m_import_in_progress; 256 bool m_lookups_enabled; 257 258 const lldb::TargetSP m_target; ///< The target to use in finding variables and types. 259 clang::ASTContext *m_ast_context; ///< The parser's AST context, for copying types into 260 std::auto_ptr<ClangASTImporter> m_ast_importer; 261 std::set<const char *> m_active_lookups; 262}; 263 264//---------------------------------------------------------------------- 265/// @class NameSearchContext ClangASTSource.h "lldb/Expression/ClangASTSource.h" 266/// @brief Container for all objects relevant to a single name lookup 267/// 268/// LLDB needs to create Decls for entities it finds. This class communicates 269/// what name is being searched for and provides helper functions to construct 270/// Decls given appropriate type information. 271//---------------------------------------------------------------------- 272struct NameSearchContext { 273 ClangASTSource &m_ast_source; ///< The AST source making the request 274 llvm::SmallVectorImpl<clang::NamedDecl*> &m_decls; ///< The list of declarations already constructed 275 ClangASTImporter::NamespaceMapSP m_namespace_map; ///< The mapping of all namespaces found for this request back to their modules 276 const clang::DeclarationName &m_decl_name; ///< The name being looked for 277 const clang::DeclContext *m_decl_context; ///< The DeclContext to put declarations into 278 279 struct { 280 bool variable : 1; 281 bool function_with_type_info : 1; 282 bool function : 1; 283 } m_found; 284 285 //------------------------------------------------------------------ 286 /// Constructor 287 /// 288 /// Initializes class variables. 289 /// 290 /// @param[in] astSource 291 /// A reference to the AST source making a request. 292 /// 293 /// @param[in] decls 294 /// A reference to a list into which new Decls will be placed. This 295 /// list is typically empty when the function is called. 296 /// 297 /// @param[in] name 298 /// The name being searched for (always an Identifier). 299 /// 300 /// @param[in] dc 301 /// The DeclContext to register Decls in. 302 //------------------------------------------------------------------ 303 NameSearchContext (ClangASTSource &astSource, 304 llvm::SmallVectorImpl<clang::NamedDecl*> &decls, 305 clang::DeclarationName &name, 306 const clang::DeclContext *dc) : 307 m_ast_source(astSource), 308 m_decls(decls), 309 m_decl_name(name), 310 m_decl_context(dc) {} 311 312 //------------------------------------------------------------------ 313 /// Create a VarDecl with the name being searched for and the provided 314 /// type and register it in the right places. 315 /// 316 /// @param[in] type 317 /// The opaque QualType for the VarDecl being registered. 318 //------------------------------------------------------------------ 319 clang::NamedDecl *AddVarDecl(void *type); 320 321 //------------------------------------------------------------------ 322 /// Create a FunDecl with the name being searched for and the provided 323 /// type and register it in the right places. 324 /// 325 /// @param[in] type 326 /// The opaque QualType for the FunDecl being registered. 327 //------------------------------------------------------------------ 328 clang::NamedDecl *AddFunDecl(void *type); 329 330 //------------------------------------------------------------------ 331 /// Create a FunDecl with the name being searched for and generic 332 /// type (i.e. intptr_t NAME_GOES_HERE(...)) and register it in the 333 /// right places. 334 //------------------------------------------------------------------ 335 clang::NamedDecl *AddGenericFunDecl(); 336 337 //------------------------------------------------------------------ 338 /// Create a TypeDecl with the name being searched for and the provided 339 /// type and register it in the right places. 340 /// 341 /// @param[in] type 342 /// The opaque QualType for the TypeDecl being registered. 343 //------------------------------------------------------------------ 344 clang::NamedDecl *AddTypeDecl(void *type); 345 346 347 //------------------------------------------------------------------ 348 /// Add Decls from the provided DeclContextLookupResult to the list 349 /// of results. 350 /// 351 /// @param[in] result 352 /// The DeclContextLookupResult, usually returned as the result 353 /// of querying a DeclContext. 354 //------------------------------------------------------------------ 355 void AddLookupResult (clang::DeclContextLookupConstResult result); 356 357 //------------------------------------------------------------------ 358 /// Add a NamedDecl to the list of results. 359 /// 360 /// @param[in] decl 361 /// The NamedDecl, usually returned as the result 362 /// of querying a DeclContext. 363 //------------------------------------------------------------------ 364 void AddNamedDecl (clang::NamedDecl *decl); 365}; 366 367} 368 369#endif 370