blob: 605747adb56a1aae7e9c33d98cae3a673c7cdfb8 [file] [log] [blame]
Greg Clayton1e591ce2010-07-16 18:28:27 +00001//===-- ClangASTSource.cpp ---------------------------------------*- 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
Chris Lattner24943d22010-06-08 16:52:24 +000010
Chris Lattner24943d22010-06-08 16:52:24 +000011#include "clang/AST/ASTContext.h"
Sean Callanan8f2e3922012-02-04 08:49:35 +000012#include "clang/AST/RecordLayout.h"
Greg Claytonf4c7ae02010-10-15 03:36:13 +000013#include "lldb/Core/Log.h"
Greg Clayton6e0101c2011-09-17 06:21:20 +000014#include "lldb/Core/Module.h"
Sean Callanan73b520f2011-10-29 01:58:46 +000015#include "lldb/Core/ModuleList.h"
Sean Callananbb715f92011-10-29 02:28:18 +000016#include "lldb/Expression/ASTDumper.h"
Chris Lattner24943d22010-06-08 16:52:24 +000017#include "lldb/Expression/ClangASTSource.h"
18#include "lldb/Expression/ClangExpression.h"
Sean Callanan73b520f2011-10-29 01:58:46 +000019#include "lldb/Symbol/ClangNamespaceDecl.h"
20#include "lldb/Symbol/SymbolVendor.h"
Sean Callanan673f3db2011-11-30 22:11:59 +000021#include "lldb/Target/ObjCLanguageRuntime.h"
Sean Callanan73b520f2011-10-29 01:58:46 +000022#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023
24using namespace clang;
25using namespace lldb_private;
26
Greg Claytonb01000f2011-01-17 03:46:26 +000027ClangASTSource::~ClangASTSource()
28{
Sean Callanana3d04472011-11-29 00:42:02 +000029 m_ast_importer->ForgetDestination(m_ast_context);
30
Johnny Chenfa21ffd2011-11-30 23:18:53 +000031 // We are in the process of destruction, don't create clang ast context on demand
32 // by passing false to Target::GetScratchClangASTContext(create_on_demand).
33 ClangASTContext *scratch_clang_ast_context = m_target->GetScratchClangASTContext(false);
Sean Callanana3d04472011-11-29 00:42:02 +000034
35 if (!scratch_clang_ast_context)
36 return;
37
38 clang::ASTContext *scratch_ast_context = scratch_clang_ast_context->getASTContext();
39
40 if (!scratch_ast_context)
41 return;
42
43 if (m_ast_context != scratch_ast_context)
44 m_ast_importer->ForgetSource(scratch_ast_context, m_ast_context);
Greg Claytonb01000f2011-01-17 03:46:26 +000045}
Chris Lattner24943d22010-06-08 16:52:24 +000046
Greg Claytonb01000f2011-01-17 03:46:26 +000047void
48ClangASTSource::StartTranslationUnit(ASTConsumer *Consumer)
49{
Sean Callananf76afff2011-10-28 23:38:38 +000050 if (!m_ast_context)
51 return;
52
53 m_ast_context->getTranslationUnitDecl()->setHasExternalVisibleStorage();
54 m_ast_context->getTranslationUnitDecl()->setHasExternalLexicalStorage();
Chris Lattner24943d22010-06-08 16:52:24 +000055}
56
Chris Lattner24943d22010-06-08 16:52:24 +000057// The core lookup interface.
Greg Claytonb01000f2011-01-17 03:46:26 +000058DeclContext::lookup_result
59ClangASTSource::FindExternalVisibleDeclsByName
Greg Claytonf4c7ae02010-10-15 03:36:13 +000060(
61 const DeclContext *decl_ctx,
Greg Clayton8de27c72010-10-15 22:48:33 +000062 DeclarationName clang_decl_name
Greg Claytonf4c7ae02010-10-15 03:36:13 +000063)
64{
Sean Callananf76afff2011-10-28 23:38:38 +000065 if (!m_ast_context)
66 return SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
67
68 if (GetImportInProgress())
Greg Claytonb01000f2011-01-17 03:46:26 +000069 return SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
70
71 std::string decl_name (clang_decl_name.getAsString());
72
73// if (m_decl_map.DoingASTImport ())
74// return DeclContext::lookup_result();
75//
Greg Clayton8de27c72010-10-15 22:48:33 +000076 switch (clang_decl_name.getNameKind()) {
Chris Lattner24943d22010-06-08 16:52:24 +000077 // Normal identifiers.
78 case DeclarationName::Identifier:
Sean Callanan0ffff1e2012-04-25 17:46:01 +000079 {
80 clang::IdentifierInfo *identifier_info = clang_decl_name.getAsIdentifierInfo();
81
82 if (!identifier_info ||
83 identifier_info->getBuiltinID() != 0)
84 {
85 return SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
86 }
87 }
Greg Clayton8de27c72010-10-15 22:48:33 +000088 break;
Chris Lattner24943d22010-06-08 16:52:24 +000089
90 // Operator names. Not important for now.
91 case DeclarationName::CXXOperatorName:
92 case DeclarationName::CXXLiteralOperatorName:
93 return DeclContext::lookup_result();
94
95 // Using directives found in this context.
96 // Tell Sema we didn't find any or we'll end up getting asked a *lot*.
97 case DeclarationName::CXXUsingDirective:
Greg Clayton8de27c72010-10-15 22:48:33 +000098 return SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
Chris Lattner24943d22010-06-08 16:52:24 +000099
Chris Lattner24943d22010-06-08 16:52:24 +0000100 case DeclarationName::ObjCZeroArgSelector:
101 case DeclarationName::ObjCOneArgSelector:
102 case DeclarationName::ObjCMultiArgSelector:
Sean Callanan9b714842011-11-09 19:33:21 +0000103 {
104 llvm::SmallVector<NamedDecl*, 1> method_decls;
Chris Lattner24943d22010-06-08 16:52:24 +0000105
Sean Callanan9b714842011-11-09 19:33:21 +0000106 NameSearchContext method_search_context (*this, method_decls, clang_decl_name, decl_ctx);
107
108 FindObjCMethodDecls(method_search_context);
109
110 return SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, method_decls);
111 }
Chris Lattner24943d22010-06-08 16:52:24 +0000112 // These aren't possible in the global context.
113 case DeclarationName::CXXConstructorName:
114 case DeclarationName::CXXDestructorName:
115 case DeclarationName::CXXConversionFunctionName:
116 return DeclContext::lookup_result();
117 }
Greg Claytonf4c7ae02010-10-15 03:36:13 +0000118
Greg Claytonf4c7ae02010-10-15 03:36:13 +0000119
Sean Callananf76afff2011-10-28 23:38:38 +0000120 if (!GetLookupsEnabled())
Greg Clayton8de27c72010-10-15 22:48:33 +0000121 {
122 // Wait until we see a '$' at the start of a name before we start doing
123 // any lookups so we can avoid lookup up all of the builtin types.
124 if (!decl_name.empty() && decl_name[0] == '$')
125 {
Sean Callananf76afff2011-10-28 23:38:38 +0000126 SetLookupsEnabled (true);
Greg Clayton8de27c72010-10-15 22:48:33 +0000127 }
128 else
129 {
130 return SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
131 }
Greg Claytonf4c7ae02010-10-15 03:36:13 +0000132 }
Greg Clayton8de27c72010-10-15 22:48:33 +0000133
Greg Clayton8de27c72010-10-15 22:48:33 +0000134 ConstString const_decl_name(decl_name.c_str());
Greg Clayton9ceed1e2010-11-13 04:18:24 +0000135
136 const char *uniqued_const_decl_name = const_decl_name.GetCString();
137 if (m_active_lookups.find (uniqued_const_decl_name) != m_active_lookups.end())
138 {
139 // We are currently looking up this name...
140 return DeclContext::lookup_result();
141 }
142 m_active_lookups.insert(uniqued_const_decl_name);
Greg Claytona8b278a2010-11-15 01:34:18 +0000143// static uint32_t g_depth = 0;
144// ++g_depth;
145// printf("[%5u] FindExternalVisibleDeclsByName() \"%s\"\n", g_depth, uniqued_const_decl_name);
Greg Clayton9ceed1e2010-11-13 04:18:24 +0000146 llvm::SmallVector<NamedDecl*, 4> name_decls;
147 NameSearchContext name_search_context(*this, name_decls, clang_decl_name, decl_ctx);
Sean Callananf76afff2011-10-28 23:38:38 +0000148 FindExternalVisibleDecls(name_search_context);
Greg Clayton9ceed1e2010-11-13 04:18:24 +0000149 DeclContext::lookup_result result (SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, name_decls));
Greg Claytona8b278a2010-11-15 01:34:18 +0000150// --g_depth;
Greg Clayton9ceed1e2010-11-13 04:18:24 +0000151 m_active_lookups.erase (uniqued_const_decl_name);
152 return result;
Chris Lattner24943d22010-06-08 16:52:24 +0000153}
154
Greg Claytonb01000f2011-01-17 03:46:26 +0000155void
156ClangASTSource::CompleteType (TagDecl *tag_decl)
Sean Callananbb715f92011-10-29 02:28:18 +0000157{
158 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
159
Sean Callananb2027ec2011-12-08 23:45:45 +0000160 static unsigned int invocation_id = 0;
161 unsigned int current_id = invocation_id++;
162
Sean Callananbb715f92011-10-29 02:28:18 +0000163 if (log)
164 {
Sean Callanan6e22e8b2012-01-13 22:05:55 +0000165 log->Printf(" CompleteTagDecl[%u] on (ASTContext*)%p Completing (TagDecl*)%p named %s",
166 current_id,
Sean Callananb2027ec2011-12-08 23:45:45 +0000167 m_ast_context,
Sean Callanan6e22e8b2012-01-13 22:05:55 +0000168 tag_decl,
Sean Callananb2027ec2011-12-08 23:45:45 +0000169 tag_decl->getName().str().c_str());
170
171 log->Printf(" CTD[%u] Before:", current_id);
Sean Callananbb715f92011-10-29 02:28:18 +0000172 ASTDumper dumper((Decl*)tag_decl);
173 dumper.ToLog(log, " [CTD] ");
174 }
175
Sean Callananb2027ec2011-12-08 23:45:45 +0000176 if (!m_ast_importer->CompleteTagDecl (tag_decl))
177 {
178 // We couldn't complete the type. Maybe there's a definition
179 // somewhere else that can be completed.
180
181 if (log)
182 log->Printf(" CTD[%u] Type could not be completed in the module in which it was first found.", current_id);
183
184 bool found = false;
185
186 DeclContext *decl_ctx = tag_decl->getDeclContext();
187
188 if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(decl_ctx))
189 {
190 ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer->GetNamespaceMap(namespace_context);
191
192 if (log && log->GetVerbose())
193 log->Printf(" CTD[%u] Inspecting namespace map %p (%d entries)",
194 current_id,
195 namespace_map.get(),
196 (int)namespace_map->size());
197
198 if (!namespace_map)
199 return;
200
201 for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end();
202 i != e && !found;
203 ++i)
204 {
205 if (log)
206 log->Printf(" CTD[%u] Searching namespace %s in module %s",
207 current_id,
208 i->second.GetNamespaceDecl()->getNameAsString().c_str(),
209 i->first->GetFileSpec().GetFilename().GetCString());
210
211 TypeList types;
212
213 SymbolContext null_sc;
214 ConstString name(tag_decl->getName().str().c_str());
215
Greg Claytondc0a38c2012-03-26 23:03:23 +0000216 i->first->FindTypesInNamespace(null_sc, name, &i->second, UINT32_MAX, types);
Sean Callananb2027ec2011-12-08 23:45:45 +0000217
218 for (uint32_t ti = 0, te = types.GetSize();
219 ti != te && !found;
220 ++ti)
221 {
222 lldb::TypeSP type = types.GetTypeAtIndex(ti);
223
224 if (!type)
225 continue;
226
227 lldb::clang_type_t opaque_type = type->GetClangFullType();
228
229 if (!opaque_type)
230 continue;
231
Sean Callanan21f2e192011-12-14 01:13:04 +0000232 const TagType *tag_type = QualType::getFromOpaquePtr(opaque_type)->getAs<TagType>();
Sean Callananb2027ec2011-12-08 23:45:45 +0000233
234 if (!tag_type)
235 continue;
236
237 TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl());
238
239 if (m_ast_importer->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl))
240 found = true;
241 }
242 }
243 }
244 else
245 {
246 TypeList types;
247
248 SymbolContext null_sc;
249 ConstString name(tag_decl->getName().str().c_str());
250 ClangNamespaceDecl namespace_decl;
251
252 ModuleList &module_list = m_target->GetImages();
253
Greg Claytondc0a38c2012-03-26 23:03:23 +0000254 bool exact_match = false;
Greg Clayton9f95fb62012-04-06 17:41:13 +0000255 module_list.FindTypes (null_sc, name, exact_match, UINT32_MAX, types);
Sean Callananb2027ec2011-12-08 23:45:45 +0000256
257 for (uint32_t ti = 0, te = types.GetSize();
258 ti != te && !found;
259 ++ti)
260 {
261 lldb::TypeSP type = types.GetTypeAtIndex(ti);
262
263 if (!type)
264 continue;
265
266 lldb::clang_type_t opaque_type = type->GetClangFullType();
267
268 if (!opaque_type)
269 continue;
270
Sean Callanan21f2e192011-12-14 01:13:04 +0000271 const TagType *tag_type = QualType::getFromOpaquePtr(opaque_type)->getAs<TagType>();
Sean Callananb2027ec2011-12-08 23:45:45 +0000272
273 if (!tag_type)
274 continue;
275
276 TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl());
277
278 if (m_ast_importer->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl))
279 found = true;
280 }
281 }
282 }
Sean Callananbb715f92011-10-29 02:28:18 +0000283
284 if (log)
285 {
286 log->Printf(" [CTD] After:");
287 ASTDumper dumper((Decl*)tag_decl);
288 dumper.ToLog(log, " [CTD] ");
289 }
Greg Claytonb01000f2011-01-17 03:46:26 +0000290}
291
292void
Sean Callananbb715f92011-10-29 02:28:18 +0000293ClangASTSource::CompleteType (clang::ObjCInterfaceDecl *interface_decl)
294{
295 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
296
297 if (log)
298 {
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000299 log->Printf(" [CompleteObjCInterfaceDecl] on (ASTContext*)%p Completing an ObjCInterfaceDecl named %s", m_ast_context, interface_decl->getName().str().c_str());
Sean Callananbb715f92011-10-29 02:28:18 +0000300 log->Printf(" [COID] Before:");
301 ASTDumper dumper((Decl*)interface_decl);
302 dumper.ToLog(log, " [COID] ");
303 }
304
305 m_ast_importer->CompleteObjCInterfaceDecl (interface_decl);
306
307 if (log)
308 {
309 log->Printf(" [COID] After:");
310 ASTDumper dumper((Decl*)interface_decl);
311 dumper.ToLog(log, " [COID] ");
312 }
Greg Claytonb01000f2011-01-17 03:46:26 +0000313}
314
Sean Callanan9b6898f2011-07-30 02:42:06 +0000315clang::ExternalLoadResult
Sean Callananbb715f92011-10-29 02:28:18 +0000316ClangASTSource::FindExternalLexicalDecls (const DeclContext *decl_context,
317 bool (*predicate)(Decl::Kind),
318 llvm::SmallVectorImpl<Decl*> &decls)
319{
320 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
321
322 const Decl *context_decl = dyn_cast<Decl>(decl_context);
323
324 if (!context_decl)
325 return ELR_Failure;
326
327 static unsigned int invocation_id = 0;
328 unsigned int current_id = invocation_id++;
329
330 if (log)
331 {
332 if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000333 log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in '%s' (%sDecl*)%p with %s predicate",
Sean Callananbb715f92011-10-29 02:28:18 +0000334 current_id,
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000335 m_ast_context,
Sean Callananbb715f92011-10-29 02:28:18 +0000336 context_named_decl->getNameAsString().c_str(),
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000337 context_decl->getDeclKindName(),
338 context_decl,
Sean Callananbb715f92011-10-29 02:28:18 +0000339 (predicate ? "non-null" : "null"));
340 else if(context_decl)
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000341 log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in (%sDecl*)%p with %s predicate",
Sean Callananbb715f92011-10-29 02:28:18 +0000342 current_id,
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000343 m_ast_context,
Sean Callananbb715f92011-10-29 02:28:18 +0000344 context_decl->getDeclKindName(),
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000345 context_decl,
Sean Callananbb715f92011-10-29 02:28:18 +0000346 (predicate ? "non-null" : "null"));
347 else
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000348 log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in a NULL context with %s predicate",
Sean Callananbb715f92011-10-29 02:28:18 +0000349 current_id,
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000350 m_ast_context,
Sean Callananbb715f92011-10-29 02:28:18 +0000351 (predicate ? "non-null" : "null"));
352 }
353
354 Decl *original_decl = NULL;
355 ASTContext *original_ctx = NULL;
356
357 if (!m_ast_importer->ResolveDeclOrigin(context_decl, &original_decl, &original_ctx))
358 return ELR_Failure;
359
360 if (log)
361 {
Sean Callanan6e22e8b2012-01-13 22:05:55 +0000362 log->Printf(" FELD[%u] Original decl (Decl*)%p:", current_id, original_decl);
Sean Callananbb715f92011-10-29 02:28:18 +0000363 ASTDumper(original_decl).ToLog(log, " ");
364 }
365
366 if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl))
367 {
368 ExternalASTSource *external_source = original_ctx->getExternalSource();
369
370 if (external_source)
371 external_source->CompleteType (original_tag_decl);
372 }
373
Sean Callananb2027ec2011-12-08 23:45:45 +0000374 const DeclContext *original_decl_context = dyn_cast<DeclContext>(original_decl);
Sean Callananbb715f92011-10-29 02:28:18 +0000375
376 if (!original_decl_context)
377 return ELR_Failure;
378
379 for (TagDecl::decl_iterator iter = original_decl_context->decls_begin();
380 iter != original_decl_context->decls_end();
381 ++iter)
382 {
383 Decl *decl = *iter;
384
385 if (!predicate || predicate(decl->getKind()))
386 {
387 if (log)
388 {
389 ASTDumper ast_dumper(decl);
390 if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
391 log->Printf(" FELD[%d] Adding [to %s] lexical decl %s", current_id, context_named_decl->getNameAsString().c_str(), ast_dumper.GetCString());
392 else
393 log->Printf(" FELD[%d] Adding lexical decl %s", current_id, ast_dumper.GetCString());
394 }
395
Sean Callanan4938bd62011-11-16 18:20:47 +0000396 Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, original_ctx, decl);
Sean Callananbb715f92011-10-29 02:28:18 +0000397
Sean Callananddb59332012-03-20 21:11:12 +0000398 if (!copied_decl)
399 continue;
400
Sean Callanane9478392012-03-15 01:53:17 +0000401 if (FieldDecl *copied_field = dyn_cast<FieldDecl>(copied_decl))
402 {
403 QualType copied_field_type = copied_field->getType();
404
405 if (const TagType *copied_field_tag_type = copied_field_type->getAs<TagType>())
406 m_ast_importer->CompleteTagDecl(copied_field_tag_type->getDecl());
407 if (const ObjCObjectType *copied_field_object_type = copied_field_type->getAs<ObjCObjectType>())
408 if (ObjCInterfaceDecl *copied_field_objc_interface_decl = copied_field_object_type->getInterface())
409 m_ast_importer->CompleteObjCInterfaceDecl(copied_field_objc_interface_decl);
410 }
411
Sean Callananbb715f92011-10-29 02:28:18 +0000412 decls.push_back(copied_decl);
413 }
414 }
415
416 return ELR_AlreadyLoaded;
Chris Lattner24943d22010-06-08 16:52:24 +0000417}
418
Sean Callanan9394b5a2011-10-29 19:50:43 +0000419void
420ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context)
421{
422 assert (m_ast_context);
423
424 const ConstString name(context.m_decl_name.getAsString().c_str());
425
426 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
427
428 static unsigned int invocation_id = 0;
429 unsigned int current_id = invocation_id++;
430
431 if (log)
432 {
433 if (!context.m_decl_context)
Sean Callanan6e22e8b2012-01-13 22:05:55 +0000434 log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in a NULL DeclContext", current_id, m_ast_context, name.GetCString());
Sean Callanan9394b5a2011-10-29 19:50:43 +0000435 else if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context.m_decl_context))
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000436 log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in '%s'", current_id, m_ast_context, name.GetCString(), context_named_decl->getNameAsString().c_str());
Sean Callanan9394b5a2011-10-29 19:50:43 +0000437 else
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000438 log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in a '%s'", current_id, m_ast_context, name.GetCString(), context.m_decl_context->getDeclKindName());
Sean Callanan9394b5a2011-10-29 19:50:43 +0000439 }
440
441 context.m_namespace_map.reset(new ClangASTImporter::NamespaceMap);
442
443 if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(context.m_decl_context))
444 {
445 ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer->GetNamespaceMap(namespace_context);
446
447 if (log && log->GetVerbose())
448 log->Printf(" CAS::FEVD[%u] Inspecting namespace map %p (%d entries)",
449 current_id,
450 namespace_map.get(),
451 (int)namespace_map->size());
452
453 if (!namespace_map)
454 return;
455
456 for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end();
457 i != e;
458 ++i)
459 {
460 if (log)
461 log->Printf(" CAS::FEVD[%u] Searching namespace %s in module %s",
462 current_id,
463 i->second.GetNamespaceDecl()->getNameAsString().c_str(),
464 i->first->GetFileSpec().GetFilename().GetCString());
465
466 FindExternalVisibleDecls(context,
467 i->first,
468 i->second,
469 current_id);
470 }
471 }
Sean Callanand3812fa2011-11-15 21:50:18 +0000472 else if (isa<ObjCInterfaceDecl>(context.m_decl_context))
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000473 {
Sean Callanan8f2e3922012-02-04 08:49:35 +0000474 FindObjCPropertyAndIvarDecls(context);
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000475 }
Sean Callanan9394b5a2011-10-29 19:50:43 +0000476 else if (!isa<TranslationUnitDecl>(context.m_decl_context))
477 {
478 // we shouldn't be getting FindExternalVisibleDecls calls for these
479 return;
480 }
481 else
482 {
483 ClangNamespaceDecl namespace_decl;
484
485 if (log)
486 log->Printf(" CAS::FEVD[%u] Searching the root namespace", current_id);
487
488 FindExternalVisibleDecls(context,
489 lldb::ModuleSP(),
490 namespace_decl,
491 current_id);
492 }
493
494 if (!context.m_namespace_map->empty())
495 {
496 if (log && log->GetVerbose())
497 log->Printf(" CAS::FEVD[%u] Registering namespace map %p (%d entries)",
498 current_id,
499 context.m_namespace_map.get(),
500 (int)context.m_namespace_map->size());
501
502 NamespaceDecl *clang_namespace_decl = AddNamespace(context, context.m_namespace_map);
503
504 if (clang_namespace_decl)
505 clang_namespace_decl->setHasExternalVisibleStorage();
506 }
507}
508
509void
510ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
511 lldb::ModuleSP module_sp,
512 ClangNamespaceDecl &namespace_decl,
513 unsigned int current_id)
514{
515 assert (m_ast_context);
516
517 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
518
519 SymbolContextList sc_list;
520
521 const ConstString name(context.m_decl_name.getAsString().c_str());
522
523 const char *name_unique_cstr = name.GetCString();
524
Sean Callanan8f2e3922012-02-04 08:49:35 +0000525 static ConstString id_name("id");
526 static ConstString Class_name("Class");
527
528 if (name == id_name || name == Class_name)
529 return;
530
Sean Callanan9394b5a2011-10-29 19:50:43 +0000531 if (name_unique_cstr == NULL)
532 return;
533
534 // The ClangASTSource is not responsible for finding $-names.
535 if (name_unique_cstr[0] == '$')
536 return;
537
538 if (module_sp && namespace_decl)
539 {
540 ClangNamespaceDecl found_namespace_decl;
541
542 SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
543
544 if (symbol_vendor)
545 {
546 SymbolContext null_sc;
547
548 found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &namespace_decl);
549
550 if (found_namespace_decl)
551 {
552 context.m_namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(module_sp, found_namespace_decl));
553
554 if (log)
555 log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s",
556 current_id,
557 name.GetCString(),
558 module_sp->GetFileSpec().GetFilename().GetCString());
559 }
560 }
561 }
562 else
563 {
Jim Ingham93367902012-05-30 02:19:25 +0000564 ModuleList &target_images = m_target->GetImages();
565 Mutex::Locker modules_locker (target_images.GetMutex());
Sean Callanan9394b5a2011-10-29 19:50:43 +0000566
Jim Ingham93367902012-05-30 02:19:25 +0000567 for (uint32_t i = 0, e = target_images.GetSize();
Sean Callanan9394b5a2011-10-29 19:50:43 +0000568 i != e;
569 ++i)
570 {
Jim Ingham93367902012-05-30 02:19:25 +0000571 lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
Sean Callanan9394b5a2011-10-29 19:50:43 +0000572
573 if (!image)
574 continue;
575
576 ClangNamespaceDecl found_namespace_decl;
577
578 SymbolVendor *symbol_vendor = image->GetSymbolVendor();
579
580 if (!symbol_vendor)
581 continue;
582
583 SymbolContext null_sc;
584
585 found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &namespace_decl);
586
587 if (found_namespace_decl)
588 {
589 context.m_namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(image, found_namespace_decl));
590
591 if (log)
592 log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s",
593 current_id,
594 name.GetCString(),
595 image->GetFileSpec().GetFilename().GetCString());
596 }
597 }
598 }
599
Sean Callanan9394b5a2011-10-29 19:50:43 +0000600 do
601 {
602 TypeList types;
603 SymbolContext null_sc;
Greg Claytondc0a38c2012-03-26 23:03:23 +0000604 const bool exact_match = false;
Sean Callanan0f71d192011-12-19 19:38:39 +0000605
Sean Callanan9394b5a2011-10-29 19:50:43 +0000606 if (module_sp && namespace_decl)
Greg Claytondc0a38c2012-03-26 23:03:23 +0000607 module_sp->FindTypesInNamespace(null_sc, name, &namespace_decl, 1, types);
Sean Callanan0f71d192011-12-19 19:38:39 +0000608 else
Greg Clayton9f95fb62012-04-06 17:41:13 +0000609 m_target->GetImages().FindTypes(null_sc, name, exact_match, 1, types);
Sean Callanan9394b5a2011-10-29 19:50:43 +0000610
611 if (types.GetSize())
612 {
613 lldb::TypeSP type_sp = types.GetTypeAtIndex(0);
614
615 if (log)
616 {
617 const char *name_string = type_sp->GetName().GetCString();
618
619 log->Printf(" CAS::FEVD[%u] Matching type found for \"%s\": %s",
620 current_id,
621 name.GetCString(),
622 (name_string ? name_string : "<anonymous>"));
623 }
624
Sean Callanane1301a62011-12-06 03:41:14 +0000625
Sean Callanan9394b5a2011-10-29 19:50:43 +0000626 void *copied_type = GuardedCopyType(m_ast_context, type_sp->GetClangAST(), type_sp->GetClangFullType());
Sean Callanane1301a62011-12-06 03:41:14 +0000627
Sean Callanandc5fce12011-12-01 21:04:37 +0000628 if (!copied_type)
629 {
630 if (log)
Sean Callanane1301a62011-12-06 03:41:14 +0000631 log->Printf(" CAS::FEVD[%u] - Couldn't export the type for a constant integer result",
632 current_id);
633
Sean Callanandc5fce12011-12-01 21:04:37 +0000634 break;
635 }
636
Sean Callanan9394b5a2011-10-29 19:50:43 +0000637 context.AddTypeDecl(copied_type);
638 }
Sean Callanan673f3db2011-11-30 22:11:59 +0000639
Sean Callanan9394b5a2011-10-29 19:50:43 +0000640 } while(0);
641}
642
Sean Callanan9b714842011-11-09 19:33:21 +0000643void
644ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
645{
646 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
647
Sean Callananf2a0a5c2011-11-11 20:37:26 +0000648 static unsigned int invocation_id = 0;
649 unsigned int current_id = invocation_id++;
650
Sean Callanan9b714842011-11-09 19:33:21 +0000651 const DeclarationName &decl_name(context.m_decl_name);
652 const DeclContext *decl_ctx(context.m_decl_context);
653
654 const ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl_ctx);
655
656 if (!interface_decl)
657 return;
658
Sean Callanan8d611562012-04-05 00:12:52 +0000659 do
660 {
661 Decl *original_decl = NULL;
662 ASTContext *original_ctx = NULL;
663
664 m_ast_importer->ResolveDeclOrigin(interface_decl, &original_decl, &original_ctx);
665
666 if (!original_decl)
667 break;
668
669 ObjCInterfaceDecl *original_interface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl);
670
671 Selector original_selector;
672
673 if (decl_name.isObjCZeroArgSelector())
674 {
675 IdentifierInfo *ident = &original_ctx->Idents.get(decl_name.getAsString());
676 original_selector = original_ctx->Selectors.getSelector(0, &ident);
677 }
678 else if (decl_name.isObjCOneArgSelector())
679 {
680 const std::string &decl_name_string = decl_name.getAsString();
681 std::string decl_name_string_without_colon(decl_name_string.c_str(), decl_name_string.length() - 1);
682 IdentifierInfo *ident = &original_ctx->Idents.get(decl_name_string_without_colon.c_str());
683 original_selector = original_ctx->Selectors.getSelector(1, &ident);
684 }
685 else
686 {
687 SmallVector<IdentifierInfo *, 4> idents;
688
689 clang::Selector sel = decl_name.getObjCSelector();
690
691 int num_args = sel.getNumArgs();
692
693 for (unsigned i = 0;
694 i != num_args;
695 ++i)
696 {
697 idents.push_back(&original_ctx->Idents.get(sel.getNameForSlot(i)));
698 }
699
700 original_selector = original_ctx->Selectors.getSelector(num_args, idents.data());
701 }
702
703 DeclarationName original_decl_name(original_selector);
704
705 ObjCInterfaceDecl::lookup_result result = original_interface_decl->lookup(original_decl_name);
706
707 if (result.first == result.second)
708 break;
709
710 if (!*result.first)
711 break;
712
713 ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(*result.first);
714
715 if (!result_method)
716 break;
717
718 Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &result_method->getASTContext(), result_method);
719
720 if (!copied_decl)
721 continue;
722
723 ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
724
725 if (!copied_method_decl)
726 continue;
727
728 if (log)
729 {
730 ASTDumper dumper((Decl*)copied_method_decl);
731 log->Printf(" CAS::FOMD[%d] found (in debug info) %s", current_id, dumper.GetCString());
732 }
733
734 context.AddNamedDecl(copied_method_decl);
735
736 return;
737 } while (0);
738
Sean Callanan9b714842011-11-09 19:33:21 +0000739 StreamString ss;
Sean Callanane1301a62011-12-06 03:41:14 +0000740
Sean Callanan9b714842011-11-09 19:33:21 +0000741 if (decl_name.isObjCZeroArgSelector())
742 {
743 ss.Printf("%s", decl_name.getAsString().c_str());
744 }
745 else if (decl_name.isObjCOneArgSelector())
746 {
Sean Callanan1d9ffe22011-11-14 18:29:46 +0000747 ss.Printf("%s", decl_name.getAsString().c_str());
Sean Callanan9b714842011-11-09 19:33:21 +0000748 }
749 else
750 {
751 clang::Selector sel = decl_name.getObjCSelector();
752
753 for (unsigned i = 0, e = sel.getNumArgs();
754 i != e;
755 ++i)
756 {
757 llvm::StringRef r = sel.getNameForSlot(i);
758 ss.Printf("%s:", r.str().c_str());
759 }
760 }
761 ss.Flush();
762
Sean Callananf2a0a5c2011-11-11 20:37:26 +0000763 ConstString selector_name(ss.GetData());
764
Sean Callanan9b714842011-11-09 19:33:21 +0000765 if (log)
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000766 log->Printf("ClangASTSource::FindObjCMethodDecls[%d] on (ASTContext*)%p for selector [%s %s]",
767 current_id,
768 m_ast_context,
Sean Callananf2a0a5c2011-11-11 20:37:26 +0000769 interface_decl->getNameAsString().c_str(),
770 selector_name.AsCString());
Sean Callananf2a0a5c2011-11-11 20:37:26 +0000771 SymbolContextList sc_list;
772
773 const bool include_symbols = false;
Sean Callanan302d78c2012-02-10 22:52:19 +0000774 const bool include_inlines = false;
Sean Callananf2a0a5c2011-11-11 20:37:26 +0000775 const bool append = false;
776
Sean Callanane0028b82012-01-19 02:17:40 +0000777 std::string interface_name = interface_decl->getNameAsString();
778
779 do
780 {
781 StreamString ms;
782 ms.Printf("-[%s %s]", interface_name.c_str(), selector_name.AsCString());
783 ms.Flush();
784 ConstString instance_method_name(ms.GetData());
785
Sean Callanan302d78c2012-02-10 22:52:19 +0000786 m_target->GetImages().FindFunctions(instance_method_name, lldb::eFunctionNameTypeFull, include_symbols, include_inlines, append, sc_list);
Sean Callanane0028b82012-01-19 02:17:40 +0000787
788 if (sc_list.GetSize())
789 break;
790
791 ms.Clear();
792 ms.Printf("+[%s %s]", interface_name.c_str(), selector_name.AsCString());
793 ms.Flush();
794 ConstString class_method_name(ms.GetData());
795
Sean Callanan302d78c2012-02-10 22:52:19 +0000796 m_target->GetImages().FindFunctions(class_method_name, lldb::eFunctionNameTypeFull, include_symbols, include_inlines, append, sc_list);
Sean Callanane0028b82012-01-19 02:17:40 +0000797
798 if (sc_list.GetSize())
799 break;
800
801 // Fall back and check for methods in categories. If we find methods this way, we need to check that they're actually in
802 // categories on the desired class.
803
804 SymbolContextList candidate_sc_list;
805
Sean Callanan302d78c2012-02-10 22:52:19 +0000806 m_target->GetImages().FindFunctions(selector_name, lldb::eFunctionNameTypeSelector, include_symbols, include_inlines, append, candidate_sc_list);
Sean Callanane0028b82012-01-19 02:17:40 +0000807
808 for (uint32_t ci = 0, ce = candidate_sc_list.GetSize();
809 ci != ce;
810 ++ci)
811 {
812 SymbolContext candidate_sc;
813
814 if (!candidate_sc_list.GetContextAtIndex(ci, candidate_sc))
815 continue;
816
817 if (!candidate_sc.function)
818 continue;
819
820 const char *candidate_name = candidate_sc.function->GetName().AsCString();
821
822 const char *cursor = candidate_name;
823
824 if (*cursor != '+' && *cursor != '-')
825 continue;
826
827 ++cursor;
828
829 if (*cursor != '[')
830 continue;
831
832 ++cursor;
833
834 size_t interface_len = interface_name.length();
835
836 if (strncmp(cursor, interface_name.c_str(), interface_len))
837 continue;
838
839 cursor += interface_len;
840
841 if (*cursor == ' ' || *cursor == '(')
842 sc_list.Append(candidate_sc);
843 }
844 }
845 while (0);
Sean Callananf2a0a5c2011-11-11 20:37:26 +0000846
847 for (uint32_t i = 0, e = sc_list.GetSize();
848 i != e;
849 ++i)
850 {
851 SymbolContext sc;
852
853 if (!sc_list.GetContextAtIndex(i, sc))
854 continue;
855
856 if (!sc.function)
857 continue;
858
859 DeclContext *function_ctx = sc.function->GetClangDeclContext();
860
861 if (!function_ctx)
862 continue;
863
864 ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(function_ctx);
865
866 if (!method_decl)
867 continue;
868
869 ObjCInterfaceDecl *found_interface_decl = method_decl->getClassInterface();
870
871 if (!found_interface_decl)
872 continue;
873
874 if (found_interface_decl->getName() == interface_decl->getName())
875 {
Sean Callanan4938bd62011-11-16 18:20:47 +0000876 Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &method_decl->getASTContext(), method_decl);
Sean Callananf2a0a5c2011-11-11 20:37:26 +0000877
878 if (!copied_decl)
879 continue;
880
881 ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
882
883 if (!copied_method_decl)
884 continue;
885
886 if (log)
887 {
888 ASTDumper dumper((Decl*)copied_method_decl);
Sean Callanane1301a62011-12-06 03:41:14 +0000889 log->Printf(" CAS::FOMD[%d] found (in debug info) %s", current_id, dumper.GetCString());
Sean Callananf2a0a5c2011-11-11 20:37:26 +0000890 }
Sean Callanane0028b82012-01-19 02:17:40 +0000891
Sean Callananf2a0a5c2011-11-11 20:37:26 +0000892 context.AddNamedDecl(copied_method_decl);
893 }
894 }
Sean Callanan9b714842011-11-09 19:33:21 +0000895}
896
Sean Callanan8f2e3922012-02-04 08:49:35 +0000897template <class D> class TaggedASTDecl {
898public:
899 TaggedASTDecl() : decl(NULL) { }
900 TaggedASTDecl(D *_decl) : decl(_decl) { }
901 bool IsValid() const { return (decl != NULL); }
902 bool IsInvalid() const { return !IsValid(); }
903 D *operator->() const { return decl; }
904 D *decl;
905};
906
907template <class D2, template <class D> class TD, class D1>
908TD<D2>
909DynCast(TD<D1> source)
910{
911 return TD<D2> (dyn_cast<D2>(source.decl));
912}
913
914template <class D = Decl> class DeclFromParser;
915template <class D = Decl> class DeclFromUser;
916
917template <class D> class DeclFromParser : public TaggedASTDecl<D> {
918public:
919 DeclFromParser() : TaggedASTDecl<D>() { }
920 DeclFromParser(D *_decl) : TaggedASTDecl<D>(_decl) { }
921
922 DeclFromUser<D> GetOrigin(ClangASTImporter *importer);
923};
924
925template <class D> class DeclFromUser : public TaggedASTDecl<D> {
926public:
927 DeclFromUser() : TaggedASTDecl<D>() { }
928 DeclFromUser(D *_decl) : TaggedASTDecl<D>(_decl) { }
929
930 DeclFromParser<D> Import(ClangASTImporter *importer, ASTContext &dest_ctx);
931};
932
933template <class D>
934DeclFromUser<D>
935DeclFromParser<D>::GetOrigin(ClangASTImporter *importer)
936{
937 DeclFromUser <> origin_decl;
938 importer->ResolveDeclOrigin(this->decl, &origin_decl.decl, NULL);
939 if (origin_decl.IsInvalid())
940 return DeclFromUser<D>();
941 return DeclFromUser<D>(dyn_cast<D>(origin_decl.decl));
942}
943
944template <class D>
945DeclFromParser<D>
946DeclFromUser<D>::Import(ClangASTImporter *importer, ASTContext &dest_ctx)
947{
948 DeclFromParser <> parser_generic_decl(importer->CopyDecl(&dest_ctx, &this->decl->getASTContext(), this->decl));
949 if (parser_generic_decl.IsInvalid())
950 return DeclFromParser<D>();
951 return DeclFromParser<D>(dyn_cast<D>(parser_generic_decl.decl));
952}
953
Sean Callanan931acec2012-02-22 23:57:45 +0000954static bool
955FindObjCPropertyAndIvarDeclsWithOrigin (unsigned int current_id,
956 NameSearchContext &context,
957 clang::ASTContext &ast_context,
958 ClangASTImporter *ast_importer,
959 DeclFromUser<const ObjCInterfaceDecl> &origin_iface_decl)
960{
961 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
962
963 if (origin_iface_decl.IsInvalid())
964 return false;
965
966 std::string name_str = context.m_decl_name.getAsString();
967 StringRef name(name_str.c_str());
968 IdentifierInfo &name_identifier(origin_iface_decl->getASTContext().Idents.get(name));
969
970 DeclFromUser<ObjCPropertyDecl> origin_property_decl(origin_iface_decl->FindPropertyDeclaration(&name_identifier));
971
972 bool found = false;
973
974 if (origin_property_decl.IsValid())
975 {
976 DeclFromParser<ObjCPropertyDecl> parser_property_decl(origin_property_decl.Import(ast_importer, ast_context));
977 if (parser_property_decl.IsValid())
978 {
979 if (log)
980 {
981 ASTDumper dumper((Decl*)parser_property_decl.decl);
982 log->Printf(" CAS::FOPD[%d] found %s", current_id, dumper.GetCString());
983 }
984
985 context.AddNamedDecl(parser_property_decl.decl);
986 found = true;
987 }
988 }
989
990 DeclFromUser<ObjCIvarDecl> origin_ivar_decl(origin_iface_decl->getIvarDecl(&name_identifier));
991
992 if (origin_ivar_decl.IsValid())
993 {
994 DeclFromParser<ObjCIvarDecl> parser_ivar_decl(origin_ivar_decl.Import(ast_importer, ast_context));
995 if (parser_ivar_decl.IsValid())
996 {
997 if (log)
998 {
999 ASTDumper dumper((Decl*)parser_ivar_decl.decl);
1000 log->Printf(" CAS::FOPD[%d] found %s", current_id, dumper.GetCString());
1001 }
1002
1003 context.AddNamedDecl(parser_ivar_decl.decl);
1004 found = true;
1005 }
1006 }
1007
1008 return found;
1009}
1010
Sean Callanane6ea5fe2011-11-15 02:11:17 +00001011void
Sean Callanan8f2e3922012-02-04 08:49:35 +00001012ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context)
Sean Callanane6ea5fe2011-11-15 02:11:17 +00001013{
1014 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1015
1016 static unsigned int invocation_id = 0;
1017 unsigned int current_id = invocation_id++;
1018
Sean Callanan8f2e3922012-02-04 08:49:35 +00001019 DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl(cast<ObjCInterfaceDecl>(context.m_decl_context));
1020 DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl(parser_iface_decl.GetOrigin(m_ast_importer));
Sean Callanan931acec2012-02-22 23:57:45 +00001021
1022 ConstString class_name(parser_iface_decl->getNameAsString().c_str());
Sean Callanane6ea5fe2011-11-15 02:11:17 +00001023
1024 if (log)
Sean Callanan8f2e3922012-02-04 08:49:35 +00001025 log->Printf("ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on (ASTContext*)%p for '%s.%s'",
Sean Callanane6ea5fe2011-11-15 02:11:17 +00001026 current_id,
Sean Callanan5a55c7a2011-11-18 03:28:09 +00001027 m_ast_context,
Sean Callanan8f2e3922012-02-04 08:49:35 +00001028 parser_iface_decl->getNameAsString().c_str(),
Sean Callanan931acec2012-02-22 23:57:45 +00001029 context.m_decl_name.getAsString().c_str());
Sean Callanane6ea5fe2011-11-15 02:11:17 +00001030
Sean Callanan931acec2012-02-22 23:57:45 +00001031 if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
1032 context,
1033 *m_ast_context,
1034 m_ast_importer,
1035 origin_iface_decl))
1036 return;
Sean Callanane6ea5fe2011-11-15 02:11:17 +00001037
Sean Callanan931acec2012-02-22 23:57:45 +00001038 if (log)
1039 log->Printf("CAS::FOPD[%d] couldn't find the property on origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p, searching elsewhere...",
1040 current_id,
1041 origin_iface_decl.decl,
1042 &origin_iface_decl->getASTContext());
Sean Callanane6ea5fe2011-11-15 02:11:17 +00001043
Sean Callanan931acec2012-02-22 23:57:45 +00001044 SymbolContext null_sc;
1045 TypeList type_list;
Sean Callanane6ea5fe2011-11-15 02:11:17 +00001046
Sean Callanan931acec2012-02-22 23:57:45 +00001047 lldb::ProcessSP process(m_target->GetProcessSP());
1048
1049 if (!process)
1050 return;
1051
1052 ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
1053
1054 if (!language_runtime)
1055 return;
1056
1057 lldb::TypeSP complete_type_sp(language_runtime->LookupInCompleteClassCache(class_name));
1058
1059 if (!complete_type_sp)
1060 return;
1061
1062 TypeFromUser complete_type = TypeFromUser(complete_type_sp->GetClangFullType(), complete_type_sp->GetClangAST());
1063 lldb::clang_type_t complete_opaque_type = complete_type.GetOpaqueQualType();
1064
1065 if (!complete_opaque_type)
1066 return;
1067
1068 const clang::Type *complete_clang_type = QualType::getFromOpaquePtr(complete_opaque_type).getTypePtr();
1069 const ObjCInterfaceType *complete_interface_type = dyn_cast<ObjCInterfaceType>(complete_clang_type);
1070
1071 if (!complete_interface_type)
1072 return;
1073
1074 DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_type->getDecl());
1075
1076 if (complete_iface_decl.decl == origin_iface_decl.decl)
1077 return; // already checked this one
1078
1079 if (log)
1080 log->Printf("CAS::FOPD[%d] trying origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
1081 current_id,
1082 complete_iface_decl.decl,
1083 &complete_iface_decl->getASTContext());
1084
1085
1086 if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
1087 context,
1088 *m_ast_context,
1089 m_ast_importer,
1090 complete_iface_decl))
1091 return;
Sean Callanan8f2e3922012-02-04 08:49:35 +00001092}
1093
1094typedef llvm::DenseMap <const FieldDecl *, uint64_t> FieldOffsetMap;
1095typedef llvm::DenseMap <const CXXRecordDecl *, CharUnits> BaseOffsetMap;
1096
1097template <class D, class O>
1098static bool
1099ImportOffsetMap (llvm::DenseMap <const D*, O> &destination_map,
1100 llvm::DenseMap <const D*, O> &source_map,
1101 ClangASTImporter *importer,
1102 ASTContext &dest_ctx)
1103{
1104 typedef llvm::DenseMap <const D*, O> MapType;
Sean Callanane6ea5fe2011-11-15 02:11:17 +00001105
Sean Callanan8f2e3922012-02-04 08:49:35 +00001106 for (typename MapType::iterator fi = source_map.begin(), fe = source_map.end();
1107 fi != fe;
1108 ++fi)
1109 {
1110 DeclFromUser <D> user_decl(const_cast<D*>(fi->first));
1111 DeclFromParser <D> parser_decl(user_decl.Import(importer, dest_ctx));
1112 if (parser_decl.IsInvalid())
1113 return false;
1114 destination_map.insert(std::pair<const D *, O>(parser_decl.decl, fi->second));
1115 }
1116
1117 return true;
1118}
1119
1120template <bool IsVirtual> bool ExtractBaseOffsets (const ASTRecordLayout &record_layout,
1121 DeclFromUser<const CXXRecordDecl> &record,
1122 BaseOffsetMap &base_offsets)
1123{
1124 for (CXXRecordDecl::base_class_const_iterator
1125 bi = (IsVirtual ? record->vbases_begin() : record->bases_begin()),
1126 be = (IsVirtual ? record->vbases_end() : record->bases_end());
1127 bi != be;
1128 ++bi)
1129 {
1130 if (!IsVirtual && bi->isVirtual())
1131 continue;
1132
1133 const clang::Type *origin_base_type = bi->getType().getTypePtr();
1134 const clang::RecordType *origin_base_record_type = origin_base_type->getAs<RecordType>();
1135
1136 if (!origin_base_record_type)
1137 return false;
1138
1139 DeclFromUser <RecordDecl> origin_base_record(origin_base_record_type->getDecl());
1140
1141 if (origin_base_record.IsInvalid())
1142 return false;
1143
1144 DeclFromUser <CXXRecordDecl> origin_base_cxx_record(DynCast<CXXRecordDecl>(origin_base_record));
1145
1146 if (origin_base_cxx_record.IsInvalid())
1147 return false;
1148
1149 CharUnits base_offset;
1150
1151 if (IsVirtual)
1152 base_offset = record_layout.getVBaseClassOffset(origin_base_cxx_record.decl);
1153 else
1154 base_offset = record_layout.getBaseClassOffset(origin_base_cxx_record.decl);
1155
1156 base_offsets.insert(std::pair<const CXXRecordDecl *, CharUnits>(origin_base_cxx_record.decl, base_offset));
1157 }
1158
1159 return true;
1160}
1161
1162bool
1163ClangASTSource::layoutRecordType(const RecordDecl *record,
1164 uint64_t &size,
1165 uint64_t &alignment,
1166 FieldOffsetMap &field_offsets,
1167 BaseOffsetMap &base_offsets,
1168 BaseOffsetMap &virtual_base_offsets)
1169{
1170 static unsigned int invocation_id = 0;
1171 unsigned int current_id = invocation_id++;
1172
1173 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1174
Sean Callanane6ea5fe2011-11-15 02:11:17 +00001175 if (log)
1176 {
Sean Callanan8f2e3922012-02-04 08:49:35 +00001177 log->Printf("LayoutRecordType[%u] on (RecordDecl*)%p [name = '%s']",
1178 current_id,
1179 m_ast_context,
1180 record->getNameAsString().c_str());
Sean Callanane6ea5fe2011-11-15 02:11:17 +00001181 }
Sean Callanan8f2e3922012-02-04 08:49:35 +00001182
1183
1184 DeclFromParser <const RecordDecl> parser_record(record);
1185 DeclFromUser <const RecordDecl> origin_record(parser_record.GetOrigin(m_ast_importer));
1186
1187 if (origin_record.IsInvalid())
1188 return false;
1189
1190 FieldOffsetMap origin_field_offsets;
1191 BaseOffsetMap origin_base_offsets;
1192 BaseOffsetMap origin_virtual_base_offsets;
1193
Sean Callanan33bff9a2012-04-07 00:06:00 +00001194 ClangASTContext::GetCompleteDecl(&origin_record->getASTContext(), const_cast<RecordDecl*>(origin_record.decl));
1195
1196 if (!origin_record.decl->getDefinition())
1197 return false;
1198
Sean Callanan8f2e3922012-02-04 08:49:35 +00001199 const ASTRecordLayout &record_layout(origin_record->getASTContext().getASTRecordLayout(origin_record.decl));
1200
1201 int field_idx = 0;
1202
1203 for (RecordDecl::field_iterator fi = origin_record->field_begin(), fe = origin_record->field_end();
1204 fi != fe;
1205 ++fi)
1206 {
1207 uint64_t field_offset = record_layout.getFieldOffset(field_idx);
1208
1209 origin_field_offsets.insert(std::pair<const FieldDecl *, uint64_t>(*fi, field_offset));
1210
1211 field_idx++;
1212 }
1213
1214 ASTContext &parser_ast_context(record->getASTContext());
1215
1216 DeclFromUser <const CXXRecordDecl> origin_cxx_record(DynCast<const CXXRecordDecl>(origin_record));
1217
1218 if (origin_cxx_record.IsValid())
1219 {
1220 if (!ExtractBaseOffsets<false>(record_layout, origin_cxx_record, origin_base_offsets) ||
1221 !ExtractBaseOffsets<true>(record_layout, origin_cxx_record, origin_virtual_base_offsets))
1222 return false;
1223 }
1224
1225 if (!ImportOffsetMap(field_offsets, origin_field_offsets, m_ast_importer, parser_ast_context) ||
1226 !ImportOffsetMap(base_offsets, origin_base_offsets, m_ast_importer, parser_ast_context) ||
1227 !ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets, m_ast_importer, parser_ast_context))
1228 return false;
1229
1230 size = record_layout.getSize().getQuantity() * m_ast_context->getCharWidth();
1231 alignment = record_layout.getAlignment().getQuantity() * m_ast_context->getCharWidth();
1232
1233 if (log)
1234 {
1235 log->Printf("LRT[%u] returned:", current_id);
1236 log->Printf("LRT[%u] Original = (RecordDecl*)%p", current_id, origin_record.decl);
1237 log->Printf("LRT[%u] Size = %lld", current_id, size);
1238 log->Printf("LRT[%u] Alignment = %lld", current_id, alignment);
1239 log->Printf("LRT[%u] Fields:", current_id);
1240 for (RecordDecl::field_iterator fi = record->field_begin(), fe = record->field_end();
1241 fi != fe;
1242 ++fi)
1243 {
1244 log->Printf("LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %lld bits",
1245 current_id,
1246 *fi,
1247 fi->getNameAsString().c_str(),
1248 field_offsets[*fi]);
1249 }
1250 DeclFromParser <const CXXRecordDecl> parser_cxx_record = DynCast<const CXXRecordDecl>(parser_record);
1251 if (parser_cxx_record.IsValid())
1252 {
1253 log->Printf("LRT[%u] Bases:", current_id);
1254 for (CXXRecordDecl::base_class_const_iterator bi = parser_cxx_record->bases_begin(), be = parser_cxx_record->bases_end();
1255 bi != be;
1256 ++bi)
1257 {
1258 bool is_virtual = bi->isVirtual();
1259
1260 QualType base_type = bi->getType();
1261 const RecordType *base_record_type = base_type->getAs<RecordType>();
1262 DeclFromParser <RecordDecl> base_record(base_record_type->getDecl());
1263 DeclFromParser <CXXRecordDecl> base_cxx_record = DynCast<CXXRecordDecl>(base_record);
1264
1265 log->Printf("LRT[%u] %s(CXXRecordDecl*)%p, Name = '%s', Offset = %lld chars",
1266 current_id,
1267 (is_virtual ? "Virtual " : ""),
1268 base_cxx_record.decl,
1269 base_cxx_record.decl->getNameAsString().c_str(),
1270 (is_virtual ? virtual_base_offsets[base_cxx_record.decl].getQuantity() :
1271 base_offsets[base_cxx_record.decl].getQuantity()));
1272 }
1273 }
1274 else
1275 {
1276 log->Printf("LRD[%u] Not a CXXRecord, so no bases", current_id);
1277 }
1278 }
1279
1280 return true;
Sean Callanane6ea5fe2011-11-15 02:11:17 +00001281}
1282
Sean Callanan73b520f2011-10-29 01:58:46 +00001283void
1284ClangASTSource::CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespace_map,
1285 const ConstString &name,
1286 ClangASTImporter::NamespaceMapSP &parent_map) const
1287{
1288 static unsigned int invocation_id = 0;
1289 unsigned int current_id = invocation_id++;
1290
1291 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1292
1293 if (log)
1294 {
1295 if (parent_map && parent_map->size())
Sean Callanan5a55c7a2011-11-18 03:28:09 +00001296 log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for namespace %s in namespace %s",
Sean Callanan73b520f2011-10-29 01:58:46 +00001297 current_id,
Sean Callanan5a55c7a2011-11-18 03:28:09 +00001298 m_ast_context,
Sean Callanan73b520f2011-10-29 01:58:46 +00001299 name.GetCString(),
1300 parent_map->begin()->second.GetNamespaceDecl()->getDeclName().getAsString().c_str());
1301 else
Sean Callanan5a55c7a2011-11-18 03:28:09 +00001302 log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for namespace %s",
Sean Callanan73b520f2011-10-29 01:58:46 +00001303 current_id,
Sean Callanan5a55c7a2011-11-18 03:28:09 +00001304 m_ast_context,
Sean Callanan73b520f2011-10-29 01:58:46 +00001305 name.GetCString());
1306 }
1307
1308
1309 if (parent_map)
1310 {
1311 for (ClangASTImporter::NamespaceMap::iterator i = parent_map->begin(), e = parent_map->end();
1312 i != e;
1313 ++i)
1314 {
1315 ClangNamespaceDecl found_namespace_decl;
1316
1317 lldb::ModuleSP module_sp = i->first;
1318 ClangNamespaceDecl module_parent_namespace_decl = i->second;
1319
1320 SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
1321
1322 if (!symbol_vendor)
1323 continue;
1324
1325 SymbolContext null_sc;
1326
1327 found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &module_parent_namespace_decl);
1328
1329 if (!found_namespace_decl)
1330 continue;
1331
1332 namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(module_sp, found_namespace_decl));
1333
1334 if (log)
1335 log->Printf(" CMN[%u] Found namespace %s in module %s",
1336 current_id,
1337 name.GetCString(),
1338 module_sp->GetFileSpec().GetFilename().GetCString());
1339 }
1340 }
1341 else
1342 {
Jim Ingham93367902012-05-30 02:19:25 +00001343 ModuleList &target_images = m_target->GetImages();
1344 Mutex::Locker modules_locker(target_images.GetMutex());
1345
Sean Callanan73b520f2011-10-29 01:58:46 +00001346 ClangNamespaceDecl null_namespace_decl;
1347
Jim Ingham93367902012-05-30 02:19:25 +00001348 for (uint32_t i = 0, e = target_images.GetSize();
Sean Callanan73b520f2011-10-29 01:58:46 +00001349 i != e;
1350 ++i)
1351 {
Jim Ingham93367902012-05-30 02:19:25 +00001352 lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
Sean Callanan73b520f2011-10-29 01:58:46 +00001353
1354 if (!image)
1355 continue;
1356
1357 ClangNamespaceDecl found_namespace_decl;
1358
1359 SymbolVendor *symbol_vendor = image->GetSymbolVendor();
1360
1361 if (!symbol_vendor)
1362 continue;
1363
1364 SymbolContext null_sc;
1365
1366 found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &null_namespace_decl);
1367
1368 if (!found_namespace_decl)
1369 continue;
1370
1371 namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(image, found_namespace_decl));
1372
1373 if (log)
1374 log->Printf(" CMN[%u] Found namespace %s in module %s",
1375 current_id,
1376 name.GetCString(),
1377 image->GetFileSpec().GetFilename().GetCString());
1378 }
1379 }
1380}
1381
Sean Callananbb715f92011-10-29 02:28:18 +00001382NamespaceDecl *
1383ClangASTSource::AddNamespace (NameSearchContext &context, ClangASTImporter::NamespaceMapSP &namespace_decls)
1384{
Greg Clayton13d24fb2012-01-29 20:56:30 +00001385 if (!namespace_decls)
Sean Callananbb715f92011-10-29 02:28:18 +00001386 return NULL;
1387
1388 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1389
1390 const ClangNamespaceDecl &namespace_decl = namespace_decls->begin()->second;
1391
Sean Callanan4938bd62011-11-16 18:20:47 +00001392 Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, namespace_decl.GetASTContext(), namespace_decl.GetNamespaceDecl());
Sean Callananbb715f92011-10-29 02:28:18 +00001393
Sean Callananddb59332012-03-20 21:11:12 +00001394 if (!copied_decl)
1395 return NULL;
1396
Sean Callananbb715f92011-10-29 02:28:18 +00001397 NamespaceDecl *copied_namespace_decl = dyn_cast<NamespaceDecl>(copied_decl);
1398
1399 m_ast_importer->RegisterNamespaceMap(copied_namespace_decl, namespace_decls);
1400
1401 return dyn_cast<NamespaceDecl>(copied_decl);
1402}
1403
Sean Callanan9394b5a2011-10-29 19:50:43 +00001404void *
1405ClangASTSource::GuardedCopyType (ASTContext *dest_context,
1406 ASTContext *source_context,
1407 void *clang_type)
1408{
1409 SetImportInProgress(true);
1410
Sean Callanan4938bd62011-11-16 18:20:47 +00001411 QualType ret_qual_type = m_ast_importer->CopyType (m_ast_context, source_context, QualType::getFromOpaquePtr(clang_type));
Sean Callanan9394b5a2011-10-29 19:50:43 +00001412
1413 void *ret = ret_qual_type.getAsOpaquePtr();
1414
1415 SetImportInProgress(false);
1416
Sean Callananddb59332012-03-20 21:11:12 +00001417 if (ret && ret_qual_type->getCanonicalTypeInternal().isNull())
Sean Callananaa11af82012-02-27 19:22:39 +00001418 // this shouldn't happen, but we're hardening because the AST importer seems to be generating bad types
1419 // on occasion.
1420 return NULL;
1421
Sean Callanan9394b5a2011-10-29 19:50:43 +00001422 return ret;
1423}
1424
Greg Claytonb01000f2011-01-17 03:46:26 +00001425clang::NamedDecl *
1426NameSearchContext::AddVarDecl(void *type)
1427{
Greg Clayton8de27c72010-10-15 22:48:33 +00001428 IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();
Sean Callanan1ddd9fe2010-11-30 00:27:43 +00001429
1430 assert (type && "Type for variable must be non-NULL!");
Sean Callanancc074622010-09-14 21:59:34 +00001431
Sean Callananf76afff2011-10-28 23:38:38 +00001432 clang::NamedDecl *Decl = VarDecl::Create(*m_ast_source.m_ast_context,
Greg Clayton8de27c72010-10-15 22:48:33 +00001433 const_cast<DeclContext*>(m_decl_context),
Chris Lattner24943d22010-06-08 16:52:24 +00001434 SourceLocation(),
Sean Callanan279584c2011-03-15 00:17:19 +00001435 SourceLocation(),
Sean Callanancc074622010-09-14 21:59:34 +00001436 ii,
Chris Lattner24943d22010-06-08 16:52:24 +00001437 QualType::getFromOpaquePtr(type),
1438 0,
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001439 SC_Static,
1440 SC_Static);
Greg Clayton8de27c72010-10-15 22:48:33 +00001441 m_decls.push_back(Decl);
Chris Lattner24943d22010-06-08 16:52:24 +00001442
1443 return Decl;
1444}
Sean Callanan8f0dc342010-06-22 23:46:24 +00001445
Greg Claytonb01000f2011-01-17 03:46:26 +00001446clang::NamedDecl *
1447NameSearchContext::AddFunDecl (void *type)
1448{
Sean Callanan30a5dd52012-03-21 17:13:20 +00001449 assert (type && "Type for variable must be non-NULL!");
1450
Sean Callananf76afff2011-10-28 23:38:38 +00001451 clang::FunctionDecl *func_decl = FunctionDecl::Create (*m_ast_source.m_ast_context,
Greg Clayton8de27c72010-10-15 22:48:33 +00001452 const_cast<DeclContext*>(m_decl_context),
1453 SourceLocation(),
Sean Callanan279584c2011-03-15 00:17:19 +00001454 SourceLocation(),
Greg Clayton8de27c72010-10-15 22:48:33 +00001455 m_decl_name.getAsIdentifierInfo(),
1456 QualType::getFromOpaquePtr(type),
1457 NULL,
1458 SC_Static,
1459 SC_Static,
1460 false,
1461 true);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001462
Sean Callananb291abe2010-08-12 23:45:38 +00001463 // We have to do more than just synthesize the FunctionDecl. We have to
1464 // synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do
1465 // this, we raid the function's FunctionProtoType for types.
1466
Greg Clayton8de27c72010-10-15 22:48:33 +00001467 QualType qual_type (QualType::getFromOpaquePtr(type));
Sean Callanan21f2e192011-12-14 01:13:04 +00001468 const FunctionProtoType *func_proto_type = qual_type.getTypePtr()->getAs<FunctionProtoType>();
Sean Callanan8f0dc342010-06-22 23:46:24 +00001469
Greg Clayton8de27c72010-10-15 22:48:33 +00001470 if (func_proto_type)
Sean Callanan3c821cc2010-06-23 18:58:10 +00001471 {
Greg Clayton8de27c72010-10-15 22:48:33 +00001472 unsigned NumArgs = func_proto_type->getNumArgs();
Sean Callanan8f0dc342010-06-22 23:46:24 +00001473 unsigned ArgIndex;
1474
Sean Callananc1535182011-10-07 23:18:13 +00001475 SmallVector<ParmVarDecl *, 5> parm_var_decls;
1476
Sean Callanan8f0dc342010-06-22 23:46:24 +00001477 for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex)
1478 {
Greg Clayton8de27c72010-10-15 22:48:33 +00001479 QualType arg_qual_type (func_proto_type->getArgType(ArgIndex));
Sean Callanan8f0dc342010-06-22 23:46:24 +00001480
Sean Callananf76afff2011-10-28 23:38:38 +00001481 parm_var_decls.push_back(ParmVarDecl::Create (*m_ast_source.m_ast_context,
Sean Callananc1535182011-10-07 23:18:13 +00001482 const_cast<DeclContext*>(m_decl_context),
1483 SourceLocation(),
1484 SourceLocation(),
1485 NULL,
1486 arg_qual_type,
1487 NULL,
1488 SC_Static,
1489 SC_Static,
1490 NULL));
Sean Callanan8f0dc342010-06-22 23:46:24 +00001491 }
1492
Sean Callananc1535182011-10-07 23:18:13 +00001493 func_decl->setParams(ArrayRef<ParmVarDecl*>(parm_var_decls));
Sean Callanan8f0dc342010-06-22 23:46:24 +00001494 }
Sean Callanandc5fce12011-12-01 21:04:37 +00001495 else
1496 {
1497 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1498
1499 log->Printf("Function type wasn't a FunctionProtoType");
1500 }
Sean Callanan8f0dc342010-06-22 23:46:24 +00001501
Greg Clayton8de27c72010-10-15 22:48:33 +00001502 m_decls.push_back(func_decl);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001503
Greg Clayton8de27c72010-10-15 22:48:33 +00001504 return func_decl;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001505}
Sean Callanan0fc73582010-07-27 00:55:47 +00001506
Greg Claytonb01000f2011-01-17 03:46:26 +00001507clang::NamedDecl *
1508NameSearchContext::AddGenericFunDecl()
Sean Callanan0fc73582010-07-27 00:55:47 +00001509{
Sean Callananad293092011-01-18 23:32:05 +00001510 FunctionProtoType::ExtProtoInfo proto_info;
1511
1512 proto_info.Variadic = true;
1513
Sean Callananf76afff2011-10-28 23:38:38 +00001514 QualType generic_function_type(m_ast_source.m_ast_context->getFunctionType (m_ast_source.m_ast_context->UnknownAnyTy, // result
1515 NULL, // argument types
1516 0, // number of arguments
1517 proto_info));
Greg Clayton8de27c72010-10-15 22:48:33 +00001518
Sean Callanan0fc73582010-07-27 00:55:47 +00001519 return AddFunDecl(generic_function_type.getAsOpaquePtr());
1520}
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001521
Greg Claytonb01000f2011-01-17 03:46:26 +00001522clang::NamedDecl *
1523NameSearchContext::AddTypeDecl(void *type)
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001524{
Greg Claytona1aaaff2011-01-23 00:34:52 +00001525 if (type)
1526 {
1527 QualType qual_type = QualType::getFromOpaquePtr(type);
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001528
Sean Callanan21f2e192011-12-14 01:13:04 +00001529 if (const TagType *tag_type = qual_type->getAs<TagType>())
Greg Claytona1aaaff2011-01-23 00:34:52 +00001530 {
1531 TagDecl *tag_decl = tag_type->getDecl();
1532
1533 m_decls.push_back(tag_decl);
1534
1535 return tag_decl;
1536 }
Sean Callanan21f2e192011-12-14 01:13:04 +00001537 else if (const ObjCObjectType *objc_object_type = qual_type->getAs<ObjCObjectType>())
Greg Claytona1aaaff2011-01-23 00:34:52 +00001538 {
1539 ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface();
1540
1541 m_decls.push_back((NamedDecl*)interface_decl);
1542
1543 return (NamedDecl*)interface_decl;
1544 }
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001545 }
Greg Claytona1aaaff2011-01-23 00:34:52 +00001546 return NULL;
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001547}
Greg Claytone6d72ca2011-06-25 00:44:06 +00001548
1549void
1550NameSearchContext::AddLookupResult (clang::DeclContextLookupConstResult result)
1551{
1552 for (clang::NamedDecl * const *decl_iterator = result.first;
1553 decl_iterator != result.second;
1554 ++decl_iterator)
1555 m_decls.push_back (*decl_iterator);
1556}
1557
1558void
1559NameSearchContext::AddNamedDecl (clang::NamedDecl *decl)
1560{
1561 m_decls.push_back (decl);
1562}