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