xref: /trueos/contrib/llvm/tools/lldb/source/Expression/ClangASTSource.cpp (revision fa88ea9f26d1e5430901a9ca6c47daebcc5af5de)
1 //===-- 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 
10 
11 #include "clang/AST/ASTContext.h"
12 #include "clang/AST/RecordLayout.h"
13 #include "lldb/Core/Log.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/ModuleList.h"
16 #include "lldb/Expression/ASTDumper.h"
17 #include "lldb/Expression/ClangASTSource.h"
18 #include "lldb/Expression/ClangExpression.h"
19 #include "lldb/Symbol/ClangNamespaceDecl.h"
20 #include "lldb/Symbol/Function.h"
21 #include "lldb/Symbol/SymbolVendor.h"
22 #include "lldb/Target/ObjCLanguageRuntime.h"
23 #include "lldb/Target/Target.h"
24 
25 using namespace clang;
26 using namespace lldb_private;
27 
~ClangASTSource()28 ClangASTSource::~ClangASTSource()
29 {
30     m_ast_importer->ForgetDestination(m_ast_context);
31 
32     // We are in the process of destruction, don't create clang ast context on demand
33     // by passing false to Target::GetScratchClangASTContext(create_on_demand).
34     ClangASTContext *scratch_clang_ast_context = m_target->GetScratchClangASTContext(false);
35 
36     if (!scratch_clang_ast_context)
37         return;
38 
39     clang::ASTContext *scratch_ast_context = scratch_clang_ast_context->getASTContext();
40 
41     if (!scratch_ast_context)
42         return;
43 
44     if (m_ast_context != scratch_ast_context)
45         m_ast_importer->ForgetSource(scratch_ast_context, m_ast_context);
46 }
47 
48 void
StartTranslationUnit(ASTConsumer * Consumer)49 ClangASTSource::StartTranslationUnit(ASTConsumer *Consumer)
50 {
51     if (!m_ast_context)
52         return;
53 
54     m_ast_context->getTranslationUnitDecl()->setHasExternalVisibleStorage();
55     m_ast_context->getTranslationUnitDecl()->setHasExternalLexicalStorage();
56 }
57 
58 // The core lookup interface.
59 bool
FindExternalVisibleDeclsByName(const DeclContext * decl_ctx,DeclarationName clang_decl_name)60 ClangASTSource::FindExternalVisibleDeclsByName
61 (
62     const DeclContext *decl_ctx,
63     DeclarationName clang_decl_name
64 )
65 {
66     if (!m_ast_context)
67     {
68         SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
69         return false;
70     }
71 
72     if (GetImportInProgress())
73     {
74         SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
75         return false;
76     }
77 
78     std::string decl_name (clang_decl_name.getAsString());
79 
80 //    if (m_decl_map.DoingASTImport ())
81 //      return DeclContext::lookup_result();
82 //
83     switch (clang_decl_name.getNameKind()) {
84     // Normal identifiers.
85     case DeclarationName::Identifier:
86         {
87             clang::IdentifierInfo *identifier_info = clang_decl_name.getAsIdentifierInfo();
88 
89             if (!identifier_info ||
90                 identifier_info->getBuiltinID() != 0)
91             {
92                 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
93                 return false;
94             }
95         }
96         break;
97 
98     // Operator names.  Not important for now.
99     case DeclarationName::CXXOperatorName:
100     case DeclarationName::CXXLiteralOperatorName:
101       SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
102       return false;
103 
104     // Using directives found in this context.
105     // Tell Sema we didn't find any or we'll end up getting asked a *lot*.
106     case DeclarationName::CXXUsingDirective:
107       SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
108       return false;
109 
110     case DeclarationName::ObjCZeroArgSelector:
111     case DeclarationName::ObjCOneArgSelector:
112     case DeclarationName::ObjCMultiArgSelector:
113     {
114       llvm::SmallVector<NamedDecl*, 1> method_decls;
115 
116       NameSearchContext method_search_context (*this, method_decls, clang_decl_name, decl_ctx);
117 
118       FindObjCMethodDecls(method_search_context);
119 
120       SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, method_decls);
121       return (method_decls.size() > 0);
122     }
123     // These aren't possible in the global context.
124     case DeclarationName::CXXConstructorName:
125     case DeclarationName::CXXDestructorName:
126     case DeclarationName::CXXConversionFunctionName:
127       SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
128       return false;
129     }
130 
131 
132     if (!GetLookupsEnabled())
133     {
134         // Wait until we see a '$' at the start of a name before we start doing
135         // any lookups so we can avoid lookup up all of the builtin types.
136         if (!decl_name.empty() && decl_name[0] == '$')
137         {
138             SetLookupsEnabled (true);
139         }
140         else
141         {
142             SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
143             return false;
144         }
145     }
146 
147     ConstString const_decl_name(decl_name.c_str());
148 
149     const char *uniqued_const_decl_name = const_decl_name.GetCString();
150     if (m_active_lookups.find (uniqued_const_decl_name) != m_active_lookups.end())
151     {
152         // We are currently looking up this name...
153         SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
154         return false;
155     }
156     m_active_lookups.insert(uniqued_const_decl_name);
157 //  static uint32_t g_depth = 0;
158 //  ++g_depth;
159 //  printf("[%5u] FindExternalVisibleDeclsByName() \"%s\"\n", g_depth, uniqued_const_decl_name);
160     llvm::SmallVector<NamedDecl*, 4> name_decls;
161     NameSearchContext name_search_context(*this, name_decls, clang_decl_name, decl_ctx);
162     FindExternalVisibleDecls(name_search_context);
163     SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, name_decls);
164 //  --g_depth;
165     m_active_lookups.erase (uniqued_const_decl_name);
166     return (name_decls.size() != 0);
167 }
168 
169 void
CompleteType(TagDecl * tag_decl)170 ClangASTSource::CompleteType (TagDecl *tag_decl)
171 {
172     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
173 
174     static unsigned int invocation_id = 0;
175     unsigned int current_id = invocation_id++;
176 
177     if (log)
178     {
179         log->Printf("    CompleteTagDecl[%u] on (ASTContext*)%p Completing (TagDecl*)%p named %s",
180                     current_id,
181                     m_ast_context,
182                     tag_decl,
183                     tag_decl->getName().str().c_str());
184 
185         log->Printf("      CTD[%u] Before:", current_id);
186         ASTDumper dumper((Decl*)tag_decl);
187         dumper.ToLog(log, "      [CTD] ");
188     }
189 
190     if (!m_ast_importer->CompleteTagDecl (tag_decl))
191     {
192         // We couldn't complete the type.  Maybe there's a definition
193         // somewhere else that can be completed.
194 
195         if (log)
196             log->Printf("      CTD[%u] Type could not be completed in the module in which it was first found.", current_id);
197 
198         bool found = false;
199 
200         DeclContext *decl_ctx = tag_decl->getDeclContext();
201 
202         if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(decl_ctx))
203         {
204             ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer->GetNamespaceMap(namespace_context);
205 
206             if (log && log->GetVerbose())
207                 log->Printf("      CTD[%u] Inspecting namespace map %p (%d entries)",
208                             current_id,
209                             namespace_map.get(),
210                             (int)namespace_map->size());
211 
212             if (!namespace_map)
213                 return;
214 
215             for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end();
216                  i != e && !found;
217                  ++i)
218             {
219                 if (log)
220                     log->Printf("      CTD[%u] Searching namespace %s in module %s",
221                                 current_id,
222                                 i->second.GetNamespaceDecl()->getNameAsString().c_str(),
223                                 i->first->GetFileSpec().GetFilename().GetCString());
224 
225                 TypeList types;
226 
227                 SymbolContext null_sc;
228                 ConstString name(tag_decl->getName().str().c_str());
229 
230                 i->first->FindTypesInNamespace(null_sc, name, &i->second, UINT32_MAX, types);
231 
232                 for (uint32_t ti = 0, te = types.GetSize();
233                      ti != te && !found;
234                      ++ti)
235                 {
236                     lldb::TypeSP type = types.GetTypeAtIndex(ti);
237 
238                     if (!type)
239                         continue;
240 
241                     ClangASTType clang_type (type->GetClangFullType());
242 
243                     if (!clang_type)
244                         continue;
245 
246                     const TagType *tag_type = clang_type.GetQualType()->getAs<TagType>();
247 
248                     if (!tag_type)
249                         continue;
250 
251                     TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl());
252 
253                     if (m_ast_importer->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl))
254                         found = true;
255                 }
256             }
257         }
258         else
259         {
260             TypeList types;
261 
262             SymbolContext null_sc;
263             ConstString name(tag_decl->getName().str().c_str());
264             ClangNamespaceDecl namespace_decl;
265 
266             const ModuleList &module_list = m_target->GetImages();
267 
268             bool exact_match = false;
269             module_list.FindTypes (null_sc, name, exact_match, UINT32_MAX, types);
270 
271             for (uint32_t ti = 0, te = types.GetSize();
272                  ti != te && !found;
273                  ++ti)
274             {
275                 lldb::TypeSP type = types.GetTypeAtIndex(ti);
276 
277                 if (!type)
278                     continue;
279 
280                 ClangASTType clang_type (type->GetClangFullType());
281 
282                 if (!clang_type)
283                     continue;
284 
285                 const TagType *tag_type = clang_type.GetQualType()->getAs<TagType>();
286 
287                 if (!tag_type)
288                     continue;
289 
290                 TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl());
291 
292                 if (m_ast_importer->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl))
293                     found = true;
294             }
295         }
296     }
297 
298     if (log)
299     {
300         log->Printf("      [CTD] After:");
301         ASTDumper dumper((Decl*)tag_decl);
302         dumper.ToLog(log, "      [CTD] ");
303     }
304 }
305 
306 void
CompleteType(clang::ObjCInterfaceDecl * interface_decl)307 ClangASTSource::CompleteType (clang::ObjCInterfaceDecl *interface_decl)
308 {
309     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
310 
311     if (log)
312     {
313         log->Printf("    [CompleteObjCInterfaceDecl] on (ASTContext*)%p Completing an ObjCInterfaceDecl named %s", m_ast_context, interface_decl->getName().str().c_str());
314         log->Printf("      [COID] Before:");
315         ASTDumper dumper((Decl*)interface_decl);
316         dumper.ToLog(log, "      [COID] ");
317     }
318 
319     m_ast_importer->CompleteObjCInterfaceDecl (interface_decl);
320 
321     if (interface_decl->getSuperClass() &&
322         interface_decl->getSuperClass() != interface_decl)
323         CompleteType(interface_decl->getSuperClass());
324 
325     if (log)
326     {
327         log->Printf("      [COID] After:");
328         ASTDumper dumper((Decl*)interface_decl);
329         dumper.ToLog(log, "      [COID] ");
330     }
331 }
332 
333 clang::ObjCInterfaceDecl *
GetCompleteObjCInterface(clang::ObjCInterfaceDecl * interface_decl)334 ClangASTSource::GetCompleteObjCInterface (clang::ObjCInterfaceDecl *interface_decl)
335 {
336     lldb::ProcessSP process(m_target->GetProcessSP());
337 
338     if (!process)
339         return NULL;
340 
341     ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
342 
343     if (!language_runtime)
344         return NULL;
345 
346     ConstString class_name(interface_decl->getNameAsString().c_str());
347 
348     lldb::TypeSP complete_type_sp(language_runtime->LookupInCompleteClassCache(class_name));
349 
350     if (!complete_type_sp)
351         return NULL;
352 
353     TypeFromUser complete_type = TypeFromUser(complete_type_sp->GetClangFullType());
354     lldb::clang_type_t complete_opaque_type = complete_type.GetOpaqueQualType();
355 
356     if (!complete_opaque_type)
357         return NULL;
358 
359     const clang::Type *complete_clang_type = QualType::getFromOpaquePtr(complete_opaque_type).getTypePtr();
360     const ObjCInterfaceType *complete_interface_type = dyn_cast<ObjCInterfaceType>(complete_clang_type);
361 
362     if (!complete_interface_type)
363         return NULL;
364 
365     ObjCInterfaceDecl *complete_iface_decl(complete_interface_type->getDecl());
366 
367     return complete_iface_decl;
368 }
369 
370 clang::ExternalLoadResult
FindExternalLexicalDecls(const DeclContext * decl_context,bool (* predicate)(Decl::Kind),llvm::SmallVectorImpl<Decl * > & decls)371 ClangASTSource::FindExternalLexicalDecls (const DeclContext *decl_context,
372                                           bool (*predicate)(Decl::Kind),
373                                           llvm::SmallVectorImpl<Decl*> &decls)
374 {
375     ClangASTMetrics::RegisterLexicalQuery();
376 
377     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
378 
379     const Decl *context_decl = dyn_cast<Decl>(decl_context);
380 
381     if (!context_decl)
382         return ELR_Failure;
383 
384     static unsigned int invocation_id = 0;
385     unsigned int current_id = invocation_id++;
386 
387     if (log)
388     {
389         if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
390             log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in '%s' (%sDecl*)%p with %s predicate",
391                         current_id,
392                         m_ast_context,
393                         context_named_decl->getNameAsString().c_str(),
394                         context_decl->getDeclKindName(),
395                         context_decl,
396                         (predicate ? "non-null" : "null"));
397         else if(context_decl)
398             log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in (%sDecl*)%p with %s predicate",
399                         current_id,
400                         m_ast_context,
401                         context_decl->getDeclKindName(),
402                         context_decl,
403                         (predicate ? "non-null" : "null"));
404         else
405             log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in a NULL context with %s predicate",
406                         current_id,
407                         m_ast_context,
408                         (predicate ? "non-null" : "null"));
409     }
410 
411     Decl *original_decl = NULL;
412     ASTContext *original_ctx = NULL;
413 
414     if (!m_ast_importer->ResolveDeclOrigin(context_decl, &original_decl, &original_ctx))
415         return ELR_Failure;
416 
417     if (log)
418     {
419         log->Printf("  FELD[%u] Original decl (ASTContext*)%p (Decl*)%p:", current_id, original_ctx, original_decl);
420         ASTDumper(original_decl).ToLog(log, "    ");
421     }
422 
423     if (ObjCInterfaceDecl *original_iface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl))
424     {
425         ObjCInterfaceDecl *complete_iface_decl = GetCompleteObjCInterface(original_iface_decl);
426 
427         if (complete_iface_decl && (complete_iface_decl != original_iface_decl))
428         {
429             original_decl = complete_iface_decl;
430             original_ctx = &complete_iface_decl->getASTContext();
431 
432             m_ast_importer->SetDeclOrigin(context_decl, original_iface_decl);
433         }
434     }
435 
436     if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl))
437     {
438         ExternalASTSource *external_source = original_ctx->getExternalSource();
439 
440         if (external_source)
441             external_source->CompleteType (original_tag_decl);
442     }
443 
444     const DeclContext *original_decl_context = dyn_cast<DeclContext>(original_decl);
445 
446     if (!original_decl_context)
447         return ELR_Failure;
448 
449     for (TagDecl::decl_iterator iter = original_decl_context->decls_begin();
450          iter != original_decl_context->decls_end();
451          ++iter)
452     {
453         Decl *decl = *iter;
454 
455         if (!predicate || predicate(decl->getKind()))
456         {
457             if (log)
458             {
459                 ASTDumper ast_dumper(decl);
460                 if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
461                     log->Printf("  FELD[%d] Adding [to %sDecl %s] lexical %sDecl %s", current_id, context_named_decl->getDeclKindName(), context_named_decl->getNameAsString().c_str(), decl->getDeclKindName(), ast_dumper.GetCString());
462                 else
463                     log->Printf("  FELD[%d] Adding lexical %sDecl %s", current_id, decl->getDeclKindName(), ast_dumper.GetCString());
464             }
465 
466             Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, original_ctx, decl);
467 
468             if (!copied_decl)
469                 continue;
470 
471             if (FieldDecl *copied_field = dyn_cast<FieldDecl>(copied_decl))
472             {
473                 QualType copied_field_type = copied_field->getType();
474 
475                 m_ast_importer->RequireCompleteType(copied_field_type);
476             }
477 
478             decls.push_back(copied_decl);
479 
480             DeclContext *decl_context_non_const = const_cast<DeclContext *>(decl_context);
481 
482             if (copied_decl->getDeclContext() != decl_context)
483             {
484                 if (copied_decl->getDeclContext()->containsDecl(copied_decl))
485                     copied_decl->getDeclContext()->removeDecl(copied_decl);
486                 copied_decl->setDeclContext(decl_context_non_const);
487             }
488 
489             if (!decl_context_non_const->containsDecl(copied_decl))
490                 decl_context_non_const->addDeclInternal(copied_decl);
491         }
492     }
493 
494     return ELR_AlreadyLoaded;
495 }
496 
497 void
FindExternalVisibleDecls(NameSearchContext & context)498 ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context)
499 {
500     assert (m_ast_context);
501 
502     ClangASTMetrics::RegisterVisibleQuery();
503 
504     const ConstString name(context.m_decl_name.getAsString().c_str());
505 
506     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
507 
508     static unsigned int invocation_id = 0;
509     unsigned int current_id = invocation_id++;
510 
511     if (log)
512     {
513         if (!context.m_decl_context)
514             log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in a NULL DeclContext", current_id, m_ast_context, name.GetCString());
515         else if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context.m_decl_context))
516             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());
517         else
518             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());
519     }
520 
521     context.m_namespace_map.reset(new ClangASTImporter::NamespaceMap);
522 
523     if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(context.m_decl_context))
524     {
525         ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer->GetNamespaceMap(namespace_context);
526 
527         if (log && log->GetVerbose())
528             log->Printf("  CAS::FEVD[%u] Inspecting namespace map %p (%d entries)",
529                         current_id,
530                         namespace_map.get(),
531                         (int)namespace_map->size());
532 
533         if (!namespace_map)
534             return;
535 
536         for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end();
537              i != e;
538              ++i)
539         {
540             if (log)
541                 log->Printf("  CAS::FEVD[%u] Searching namespace %s in module %s",
542                             current_id,
543                             i->second.GetNamespaceDecl()->getNameAsString().c_str(),
544                             i->first->GetFileSpec().GetFilename().GetCString());
545 
546             FindExternalVisibleDecls(context,
547                                      i->first,
548                                      i->second,
549                                      current_id);
550         }
551     }
552     else if (isa<ObjCInterfaceDecl>(context.m_decl_context))
553     {
554         FindObjCPropertyAndIvarDecls(context);
555     }
556     else if (!isa<TranslationUnitDecl>(context.m_decl_context))
557     {
558         // we shouldn't be getting FindExternalVisibleDecls calls for these
559         return;
560     }
561     else
562     {
563         ClangNamespaceDecl namespace_decl;
564 
565         if (log)
566             log->Printf("  CAS::FEVD[%u] Searching the root namespace", current_id);
567 
568         FindExternalVisibleDecls(context,
569                                  lldb::ModuleSP(),
570                                  namespace_decl,
571                                  current_id);
572     }
573 
574     if (!context.m_namespace_map->empty())
575     {
576         if (log && log->GetVerbose())
577             log->Printf("  CAS::FEVD[%u] Registering namespace map %p (%d entries)",
578                         current_id,
579                         context.m_namespace_map.get(),
580                         (int)context.m_namespace_map->size());
581 
582         NamespaceDecl *clang_namespace_decl = AddNamespace(context, context.m_namespace_map);
583 
584         if (clang_namespace_decl)
585             clang_namespace_decl->setHasExternalVisibleStorage();
586     }
587 }
588 
589 void
FindExternalVisibleDecls(NameSearchContext & context,lldb::ModuleSP module_sp,ClangNamespaceDecl & namespace_decl,unsigned int current_id)590 ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
591                                           lldb::ModuleSP module_sp,
592                                           ClangNamespaceDecl &namespace_decl,
593                                           unsigned int current_id)
594 {
595     assert (m_ast_context);
596 
597     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
598 
599     SymbolContextList sc_list;
600 
601     const ConstString name(context.m_decl_name.getAsString().c_str());
602 
603     const char *name_unique_cstr = name.GetCString();
604 
605     static ConstString id_name("id");
606     static ConstString Class_name("Class");
607 
608     if (name == id_name || name == Class_name)
609         return;
610 
611     if (name_unique_cstr == NULL)
612         return;
613 
614     // The ClangASTSource is not responsible for finding $-names.
615     if (name_unique_cstr[0] == '$')
616         return;
617 
618     if (module_sp && namespace_decl)
619     {
620         ClangNamespaceDecl found_namespace_decl;
621 
622         SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
623 
624         if (symbol_vendor)
625         {
626             SymbolContext null_sc;
627 
628             found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &namespace_decl);
629 
630             if (found_namespace_decl)
631             {
632                 context.m_namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(module_sp, found_namespace_decl));
633 
634                 if (log)
635                     log->Printf("  CAS::FEVD[%u] Found namespace %s in module %s",
636                                 current_id,
637                                 name.GetCString(),
638                                 module_sp->GetFileSpec().GetFilename().GetCString());
639             }
640         }
641     }
642     else
643     {
644         const ModuleList &target_images = m_target->GetImages();
645         Mutex::Locker modules_locker (target_images.GetMutex());
646 
647         for (size_t i = 0, e = target_images.GetSize(); i < e; ++i)
648         {
649             lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
650 
651             if (!image)
652                 continue;
653 
654             ClangNamespaceDecl found_namespace_decl;
655 
656             SymbolVendor *symbol_vendor = image->GetSymbolVendor();
657 
658             if (!symbol_vendor)
659                 continue;
660 
661             SymbolContext null_sc;
662 
663             found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &namespace_decl);
664 
665             if (found_namespace_decl)
666             {
667                 context.m_namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(image, found_namespace_decl));
668 
669                 if (log)
670                     log->Printf("  CAS::FEVD[%u] Found namespace %s in module %s",
671                                 current_id,
672                                 name.GetCString(),
673                                 image->GetFileSpec().GetFilename().GetCString());
674             }
675         }
676     }
677 
678     do
679     {
680         TypeList types;
681         SymbolContext null_sc;
682         const bool exact_match = false;
683 
684         if (module_sp && namespace_decl)
685             module_sp->FindTypesInNamespace(null_sc, name, &namespace_decl, 1, types);
686         else
687             m_target->GetImages().FindTypes(null_sc, name, exact_match, 1, types);
688 
689         if (types.GetSize())
690         {
691             lldb::TypeSP type_sp = types.GetTypeAtIndex(0);
692 
693             if (log)
694             {
695                 const char *name_string = type_sp->GetName().GetCString();
696 
697                 log->Printf("  CAS::FEVD[%u] Matching type found for \"%s\": %s",
698                             current_id,
699                             name.GetCString(),
700                             (name_string ? name_string : "<anonymous>"));
701             }
702 
703             ClangASTType full_type = type_sp->GetClangFullType();
704 
705             ClangASTType copied_clang_type (GuardedCopyType(full_type));
706 
707             if (!copied_clang_type)
708             {
709                 if (log)
710                     log->Printf("  CAS::FEVD[%u] - Couldn't export a type",
711                                 current_id);
712 
713                 break;
714             }
715 
716             context.AddTypeDecl(copied_clang_type);
717         }
718         else
719         {
720             do
721             {
722                 // Couldn't find any types elsewhere.  Try the Objective-C runtime if one exists.
723 
724                 lldb::ProcessSP process(m_target->GetProcessSP());
725 
726                 if (!process)
727                     break;
728 
729                 ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
730 
731                 if (!language_runtime)
732                     break;
733 
734                 TypeVendor *type_vendor = language_runtime->GetTypeVendor();
735 
736                 if (!type_vendor)
737                     break;
738 
739                 bool append = false;
740                 uint32_t max_matches = 1;
741                 std::vector <ClangASTType> types;
742 
743                 if (!type_vendor->FindTypes(name,
744                                             append,
745                                             max_matches,
746                                             types))
747                     break;
748 
749                 if (log)
750                 {
751                     log->Printf("  CAS::FEVD[%u] Matching type found for \"%s\" in the runtime",
752                                 current_id,
753                                 name.GetCString());
754                 }
755 
756                 ClangASTType copied_clang_type (GuardedCopyType(types[0]));
757 
758                 if (!copied_clang_type)
759                 {
760                     if (log)
761                         log->Printf("  CAS::FEVD[%u] - Couldn't export a type from the runtime",
762                                     current_id);
763 
764                     break;
765                 }
766 
767                 context.AddTypeDecl(copied_clang_type);
768             }
769             while(0);
770         }
771 
772     } while(0);
773 }
774 
775 template <class D> class TaggedASTDecl {
776 public:
TaggedASTDecl()777     TaggedASTDecl() : decl(NULL) { }
TaggedASTDecl(D * _decl)778     TaggedASTDecl(D *_decl) : decl(_decl) { }
IsValid() const779     bool IsValid() const { return (decl != NULL); }
IsInvalid() const780     bool IsInvalid() const { return !IsValid(); }
operator ->() const781     D *operator->() const { return decl; }
782     D *decl;
783 };
784 
785 template <class D2, template <class D> class TD, class D1>
786 TD<D2>
DynCast(TD<D1> source)787 DynCast(TD<D1> source)
788 {
789     return TD<D2> (dyn_cast<D2>(source.decl));
790 }
791 
792 template <class D = Decl> class DeclFromParser;
793 template <class D = Decl> class DeclFromUser;
794 
795 template <class D> class DeclFromParser : public TaggedASTDecl<D> {
796 public:
DeclFromParser()797     DeclFromParser() : TaggedASTDecl<D>() { }
DeclFromParser(D * _decl)798     DeclFromParser(D *_decl) : TaggedASTDecl<D>(_decl) { }
799 
800     DeclFromUser<D> GetOrigin(ClangASTImporter *importer);
801 };
802 
803 template <class D> class DeclFromUser : public TaggedASTDecl<D> {
804 public:
DeclFromUser()805     DeclFromUser() : TaggedASTDecl<D>() { }
DeclFromUser(D * _decl)806     DeclFromUser(D *_decl) : TaggedASTDecl<D>(_decl) { }
807 
808     DeclFromParser<D> Import(ClangASTImporter *importer, ASTContext &dest_ctx);
809 };
810 
811 template <class D>
812 DeclFromUser<D>
GetOrigin(ClangASTImporter * importer)813 DeclFromParser<D>::GetOrigin(ClangASTImporter *importer)
814 {
815     DeclFromUser <> origin_decl;
816     importer->ResolveDeclOrigin(this->decl, &origin_decl.decl, NULL);
817     if (origin_decl.IsInvalid())
818         return DeclFromUser<D>();
819     return DeclFromUser<D>(dyn_cast<D>(origin_decl.decl));
820 }
821 
822 template <class D>
823 DeclFromParser<D>
Import(ClangASTImporter * importer,ASTContext & dest_ctx)824 DeclFromUser<D>::Import(ClangASTImporter *importer, ASTContext &dest_ctx)
825 {
826     DeclFromParser <> parser_generic_decl(importer->CopyDecl(&dest_ctx, &this->decl->getASTContext(), this->decl));
827     if (parser_generic_decl.IsInvalid())
828         return DeclFromParser<D>();
829     return DeclFromParser<D>(dyn_cast<D>(parser_generic_decl.decl));
830 }
831 
832 static bool
FindObjCMethodDeclsWithOrigin(unsigned int current_id,NameSearchContext & context,ObjCInterfaceDecl * original_interface_decl,clang::ASTContext * ast_context,ClangASTImporter * ast_importer,const char * log_info)833 FindObjCMethodDeclsWithOrigin (unsigned int current_id,
834                                NameSearchContext &context,
835                                ObjCInterfaceDecl *original_interface_decl,
836                                clang::ASTContext *ast_context,
837                                ClangASTImporter *ast_importer,
838                                const char *log_info)
839 {
840     const DeclarationName &decl_name(context.m_decl_name);
841     clang::ASTContext *original_ctx = &original_interface_decl->getASTContext();
842 
843     Selector original_selector;
844 
845     if (decl_name.isObjCZeroArgSelector())
846     {
847         IdentifierInfo *ident = &original_ctx->Idents.get(decl_name.getAsString());
848         original_selector = original_ctx->Selectors.getSelector(0, &ident);
849     }
850     else if (decl_name.isObjCOneArgSelector())
851     {
852         const std::string &decl_name_string = decl_name.getAsString();
853         std::string decl_name_string_without_colon(decl_name_string.c_str(), decl_name_string.length() - 1);
854         IdentifierInfo *ident = &original_ctx->Idents.get(decl_name_string_without_colon.c_str());
855         original_selector = original_ctx->Selectors.getSelector(1, &ident);
856     }
857     else
858     {
859         SmallVector<IdentifierInfo *, 4> idents;
860 
861         clang::Selector sel = decl_name.getObjCSelector();
862 
863         unsigned num_args = sel.getNumArgs();
864 
865         for (unsigned i = 0;
866              i != num_args;
867              ++i)
868         {
869             idents.push_back(&original_ctx->Idents.get(sel.getNameForSlot(i)));
870         }
871 
872         original_selector = original_ctx->Selectors.getSelector(num_args, idents.data());
873     }
874 
875     DeclarationName original_decl_name(original_selector);
876 
877     ObjCInterfaceDecl::lookup_result result = original_interface_decl->lookup(original_decl_name);
878 
879     if (result.empty())
880         return false;
881 
882     if (!result[0])
883         return false;
884 
885     for (NamedDecl *named_decl : result)
886     {
887         ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(named_decl);
888 
889         if (!result_method)
890             return false;
891 
892         Decl *copied_decl = ast_importer->CopyDecl(ast_context, &result_method->getASTContext(), result_method);
893 
894         if (!copied_decl)
895             return false;
896 
897         ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
898 
899         if (!copied_method_decl)
900             return false;
901 
902         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
903 
904         if (log)
905         {
906             ASTDumper dumper((Decl*)copied_method_decl);
907             log->Printf("  CAS::FOMD[%d] found (%s) %s", current_id, log_info, dumper.GetCString());
908         }
909 
910         context.AddNamedDecl(copied_method_decl);
911     }
912 
913     return true;
914 }
915 
916 void
FindObjCMethodDecls(NameSearchContext & context)917 ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
918 {
919     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
920 
921     static unsigned int invocation_id = 0;
922     unsigned int current_id = invocation_id++;
923 
924     const DeclarationName &decl_name(context.m_decl_name);
925     const DeclContext *decl_ctx(context.m_decl_context);
926 
927     const ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl_ctx);
928 
929     if (!interface_decl)
930         return;
931 
932     do
933     {
934         Decl *original_decl = NULL;
935         ASTContext *original_ctx = NULL;
936 
937         m_ast_importer->ResolveDeclOrigin(interface_decl, &original_decl, &original_ctx);
938 
939         if (!original_decl)
940             break;
941 
942         ObjCInterfaceDecl *original_interface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl);
943 
944         if (FindObjCMethodDeclsWithOrigin(current_id,
945                                           context,
946                                           original_interface_decl,
947                                           m_ast_context,
948                                           m_ast_importer,
949                                           "at origin"))
950             return; // found it, no need to look any further
951     } while (0);
952 
953     StreamString ss;
954 
955     if (decl_name.isObjCZeroArgSelector())
956     {
957         ss.Printf("%s", decl_name.getAsString().c_str());
958     }
959     else if (decl_name.isObjCOneArgSelector())
960     {
961         ss.Printf("%s", decl_name.getAsString().c_str());
962     }
963     else
964     {
965         clang::Selector sel = decl_name.getObjCSelector();
966 
967         for (unsigned i = 0, e = sel.getNumArgs();
968              i != e;
969              ++i)
970         {
971             llvm::StringRef r = sel.getNameForSlot(i);
972             ss.Printf("%s:", r.str().c_str());
973         }
974     }
975     ss.Flush();
976 
977     if (strstr(ss.GetData(), "$__lldb"))
978         return; // we don't need any results
979 
980     ConstString selector_name(ss.GetData());
981 
982     if (log)
983         log->Printf("ClangASTSource::FindObjCMethodDecls[%d] on (ASTContext*)%p for selector [%s %s]",
984                     current_id,
985                     m_ast_context,
986                     interface_decl->getNameAsString().c_str(),
987                     selector_name.AsCString());
988     SymbolContextList sc_list;
989 
990     const bool include_symbols = false;
991     const bool include_inlines = false;
992     const bool append = false;
993 
994     std::string interface_name = interface_decl->getNameAsString();
995 
996     do
997     {
998         StreamString ms;
999         ms.Printf("-[%s %s]", interface_name.c_str(), selector_name.AsCString());
1000         ms.Flush();
1001         ConstString instance_method_name(ms.GetData());
1002 
1003         m_target->GetImages().FindFunctions(instance_method_name, lldb::eFunctionNameTypeFull, include_symbols, include_inlines, append, sc_list);
1004 
1005         if (sc_list.GetSize())
1006             break;
1007 
1008         ms.Clear();
1009         ms.Printf("+[%s %s]", interface_name.c_str(), selector_name.AsCString());
1010         ms.Flush();
1011         ConstString class_method_name(ms.GetData());
1012 
1013         m_target->GetImages().FindFunctions(class_method_name, lldb::eFunctionNameTypeFull, include_symbols, include_inlines, append, sc_list);
1014 
1015         if (sc_list.GetSize())
1016             break;
1017 
1018         // Fall back and check for methods in categories.  If we find methods this way, we need to check that they're actually in
1019         // categories on the desired class.
1020 
1021         SymbolContextList candidate_sc_list;
1022 
1023         m_target->GetImages().FindFunctions(selector_name, lldb::eFunctionNameTypeSelector, include_symbols, include_inlines, append, candidate_sc_list);
1024 
1025         for (uint32_t ci = 0, ce = candidate_sc_list.GetSize();
1026              ci != ce;
1027              ++ci)
1028         {
1029             SymbolContext candidate_sc;
1030 
1031             if (!candidate_sc_list.GetContextAtIndex(ci, candidate_sc))
1032                 continue;
1033 
1034             if (!candidate_sc.function)
1035                 continue;
1036 
1037             const char *candidate_name = candidate_sc.function->GetName().AsCString();
1038 
1039             const char *cursor = candidate_name;
1040 
1041             if (*cursor != '+' && *cursor != '-')
1042                 continue;
1043 
1044             ++cursor;
1045 
1046             if (*cursor != '[')
1047                 continue;
1048 
1049             ++cursor;
1050 
1051             size_t interface_len = interface_name.length();
1052 
1053             if (strncmp(cursor, interface_name.c_str(), interface_len))
1054                 continue;
1055 
1056             cursor += interface_len;
1057 
1058             if (*cursor == ' ' || *cursor == '(')
1059                 sc_list.Append(candidate_sc);
1060         }
1061     }
1062     while (0);
1063 
1064     if (sc_list.GetSize())
1065     {
1066         // We found a good function symbol.  Use that.
1067 
1068         for (uint32_t i = 0, e = sc_list.GetSize();
1069              i != e;
1070              ++i)
1071         {
1072             SymbolContext sc;
1073 
1074             if (!sc_list.GetContextAtIndex(i, sc))
1075                 continue;
1076 
1077             if (!sc.function)
1078                 continue;
1079 
1080             DeclContext *function_ctx = sc.function->GetClangDeclContext();
1081 
1082             if (!function_ctx)
1083                 continue;
1084 
1085             ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(function_ctx);
1086 
1087             if (!method_decl)
1088                 continue;
1089 
1090             ObjCInterfaceDecl *found_interface_decl = method_decl->getClassInterface();
1091 
1092             if (!found_interface_decl)
1093                 continue;
1094 
1095             if (found_interface_decl->getName() == interface_decl->getName())
1096             {
1097                 Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &method_decl->getASTContext(), method_decl);
1098 
1099                 if (!copied_decl)
1100                     continue;
1101 
1102                 ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
1103 
1104                 if (!copied_method_decl)
1105                     continue;
1106 
1107                 if (log)
1108                 {
1109                     ASTDumper dumper((Decl*)copied_method_decl);
1110                     log->Printf("  CAS::FOMD[%d] found (in symbols) %s", current_id, dumper.GetCString());
1111                 }
1112 
1113                 context.AddNamedDecl(copied_method_decl);
1114             }
1115         }
1116 
1117         return;
1118     }
1119 
1120     // Try the debug information.
1121 
1122     do
1123     {
1124         ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(const_cast<ObjCInterfaceDecl*>(interface_decl));
1125 
1126         if (!complete_interface_decl)
1127             break;
1128 
1129         // We found the complete interface.  The runtime never needs to be queried in this scenario.
1130 
1131         DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_decl);
1132 
1133         if (complete_interface_decl == interface_decl)
1134             break; // already checked this one
1135 
1136         if (log)
1137             log->Printf("CAS::FOPD[%d] trying origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
1138                         current_id,
1139                         complete_interface_decl,
1140                         &complete_iface_decl->getASTContext());
1141 
1142         FindObjCMethodDeclsWithOrigin(current_id,
1143                                       context,
1144                                       complete_interface_decl,
1145                                       m_ast_context,
1146                                       m_ast_importer,
1147                                       "in debug info");
1148 
1149         return;
1150     }
1151     while (0);
1152 
1153     do
1154     {
1155         // Check the runtime only if the debug information didn't have a complete interface.
1156 
1157         lldb::ProcessSP process(m_target->GetProcessSP());
1158 
1159         if (!process)
1160             break;
1161 
1162         ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
1163 
1164         if (!language_runtime)
1165             break;
1166 
1167         TypeVendor *type_vendor = language_runtime->GetTypeVendor();
1168 
1169         if (!type_vendor)
1170             break;
1171 
1172         ConstString interface_name(interface_decl->getNameAsString().c_str());
1173         bool append = false;
1174         uint32_t max_matches = 1;
1175         std::vector <ClangASTType> types;
1176 
1177         if (!type_vendor->FindTypes(interface_name,
1178                                     append,
1179                                     max_matches,
1180                                     types))
1181             break;
1182 
1183         const clang::Type *runtime_clang_type = QualType::getFromOpaquePtr(types[0].GetOpaqueQualType()).getTypePtr();
1184 
1185         const ObjCInterfaceType *runtime_interface_type = dyn_cast<ObjCInterfaceType>(runtime_clang_type);
1186 
1187         if (!runtime_interface_type)
1188             break;
1189 
1190         ObjCInterfaceDecl *runtime_interface_decl = runtime_interface_type->getDecl();
1191 
1192         FindObjCMethodDeclsWithOrigin(current_id,
1193                                       context,
1194                                       runtime_interface_decl,
1195                                       m_ast_context,
1196                                       m_ast_importer,
1197                                       "in runtime");
1198     }
1199     while(0);
1200 }
1201 
1202 static bool
FindObjCPropertyAndIvarDeclsWithOrigin(unsigned int current_id,NameSearchContext & context,clang::ASTContext & ast_context,ClangASTImporter * ast_importer,DeclFromUser<const ObjCInterfaceDecl> & origin_iface_decl)1203 FindObjCPropertyAndIvarDeclsWithOrigin (unsigned int current_id,
1204                                         NameSearchContext &context,
1205                                         clang::ASTContext &ast_context,
1206                                         ClangASTImporter *ast_importer,
1207                                         DeclFromUser<const ObjCInterfaceDecl> &origin_iface_decl)
1208 {
1209     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1210 
1211     if (origin_iface_decl.IsInvalid())
1212         return false;
1213 
1214     std::string name_str = context.m_decl_name.getAsString();
1215     StringRef name(name_str.c_str());
1216     IdentifierInfo &name_identifier(origin_iface_decl->getASTContext().Idents.get(name));
1217 
1218     DeclFromUser<ObjCPropertyDecl> origin_property_decl(origin_iface_decl->FindPropertyDeclaration(&name_identifier));
1219 
1220     bool found = false;
1221 
1222     if (origin_property_decl.IsValid())
1223     {
1224         DeclFromParser<ObjCPropertyDecl> parser_property_decl(origin_property_decl.Import(ast_importer, ast_context));
1225         if (parser_property_decl.IsValid())
1226         {
1227             if (log)
1228             {
1229                 ASTDumper dumper((Decl*)parser_property_decl.decl);
1230                 log->Printf("  CAS::FOPD[%d] found %s", current_id, dumper.GetCString());
1231             }
1232 
1233             context.AddNamedDecl(parser_property_decl.decl);
1234             found = true;
1235         }
1236     }
1237 
1238     DeclFromUser<ObjCIvarDecl> origin_ivar_decl(origin_iface_decl->getIvarDecl(&name_identifier));
1239 
1240     if (origin_ivar_decl.IsValid())
1241     {
1242         DeclFromParser<ObjCIvarDecl> parser_ivar_decl(origin_ivar_decl.Import(ast_importer, ast_context));
1243         if (parser_ivar_decl.IsValid())
1244         {
1245             if (log)
1246             {
1247                 ASTDumper dumper((Decl*)parser_ivar_decl.decl);
1248                 log->Printf("  CAS::FOPD[%d] found %s", current_id, dumper.GetCString());
1249             }
1250 
1251             context.AddNamedDecl(parser_ivar_decl.decl);
1252             found = true;
1253         }
1254     }
1255 
1256     return found;
1257 }
1258 
1259 void
FindObjCPropertyAndIvarDecls(NameSearchContext & context)1260 ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context)
1261 {
1262     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1263 
1264     static unsigned int invocation_id = 0;
1265     unsigned int current_id = invocation_id++;
1266 
1267     DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl(cast<ObjCInterfaceDecl>(context.m_decl_context));
1268     DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl(parser_iface_decl.GetOrigin(m_ast_importer));
1269 
1270     ConstString class_name(parser_iface_decl->getNameAsString().c_str());
1271 
1272     if (log)
1273         log->Printf("ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on (ASTContext*)%p for '%s.%s'",
1274                     current_id,
1275                     m_ast_context,
1276                     parser_iface_decl->getNameAsString().c_str(),
1277                     context.m_decl_name.getAsString().c_str());
1278 
1279     if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
1280                                                context,
1281                                                *m_ast_context,
1282                                                m_ast_importer,
1283                                                origin_iface_decl))
1284         return;
1285 
1286     if (log)
1287         log->Printf("CAS::FOPD[%d] couldn't find the property on origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p, searching elsewhere...",
1288                     current_id,
1289                     origin_iface_decl.decl,
1290                     &origin_iface_decl->getASTContext());
1291 
1292     SymbolContext null_sc;
1293     TypeList type_list;
1294 
1295     do
1296     {
1297         ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(const_cast<ObjCInterfaceDecl*>(parser_iface_decl.decl));
1298 
1299         if (!complete_interface_decl)
1300             break;
1301 
1302         // We found the complete interface.  The runtime never needs to be queried in this scenario.
1303 
1304         DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_decl);
1305 
1306         if (complete_iface_decl.decl == origin_iface_decl.decl)
1307             break; // already checked this one
1308 
1309         if (log)
1310             log->Printf("CAS::FOPD[%d] trying origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
1311                         current_id,
1312                         complete_iface_decl.decl,
1313                         &complete_iface_decl->getASTContext());
1314 
1315         FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
1316                                                context,
1317                                                *m_ast_context,
1318                                                m_ast_importer,
1319                                                complete_iface_decl);
1320 
1321         return;
1322     }
1323     while(0);
1324 
1325     do
1326     {
1327         // Check the runtime only if the debug information didn't have a complete interface.
1328 
1329         lldb::ProcessSP process(m_target->GetProcessSP());
1330 
1331         if (!process)
1332             return;
1333 
1334         ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
1335 
1336         if (!language_runtime)
1337             return;
1338 
1339         TypeVendor *type_vendor = language_runtime->GetTypeVendor();
1340 
1341         if (!type_vendor)
1342             break;
1343 
1344         bool append = false;
1345         uint32_t max_matches = 1;
1346         std::vector <ClangASTType> types;
1347 
1348         if (!type_vendor->FindTypes(class_name,
1349                                     append,
1350                                     max_matches,
1351                                     types))
1352             break;
1353 
1354         const clang::Type *runtime_clang_type = QualType::getFromOpaquePtr(types[0].GetOpaqueQualType()).getTypePtr();
1355 
1356         const ObjCInterfaceType *runtime_interface_type = dyn_cast<ObjCInterfaceType>(runtime_clang_type);
1357 
1358         if (!runtime_interface_type)
1359             break;
1360 
1361         DeclFromUser<const ObjCInterfaceDecl> runtime_iface_decl(runtime_interface_type->getDecl());
1362 
1363         if (log)
1364             log->Printf("CAS::FOPD[%d] trying runtime (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
1365                         current_id,
1366                         runtime_iface_decl.decl,
1367                         &runtime_iface_decl->getASTContext());
1368 
1369         if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
1370                                                    context,
1371                                                    *m_ast_context,
1372                                                    m_ast_importer,
1373                                                    runtime_iface_decl))
1374             return;
1375     }
1376     while(0);
1377 }
1378 
1379 typedef llvm::DenseMap <const FieldDecl *, uint64_t> FieldOffsetMap;
1380 typedef llvm::DenseMap <const CXXRecordDecl *, CharUnits> BaseOffsetMap;
1381 
1382 template <class D, class O>
1383 static bool
ImportOffsetMap(llvm::DenseMap<const D *,O> & destination_map,llvm::DenseMap<const D *,O> & source_map,ClangASTImporter * importer,ASTContext & dest_ctx)1384 ImportOffsetMap (llvm::DenseMap <const D*, O> &destination_map,
1385                  llvm::DenseMap <const D*, O> &source_map,
1386                  ClangASTImporter *importer,
1387                  ASTContext &dest_ctx)
1388 {
1389     typedef llvm::DenseMap <const D*, O> MapType;
1390 
1391     for (typename MapType::iterator fi = source_map.begin(), fe = source_map.end();
1392          fi != fe;
1393          ++fi)
1394     {
1395         DeclFromUser <D> user_decl(const_cast<D*>(fi->first));
1396         DeclFromParser <D> parser_decl(user_decl.Import(importer, dest_ctx));
1397         if (parser_decl.IsInvalid())
1398             return false;
1399         destination_map.insert(std::pair<const D *, O>(parser_decl.decl, fi->second));
1400     }
1401 
1402     return true;
1403 }
1404 
ExtractBaseOffsets(const ASTRecordLayout & record_layout,DeclFromUser<const CXXRecordDecl> & record,BaseOffsetMap & base_offsets)1405 template <bool IsVirtual> bool ExtractBaseOffsets (const ASTRecordLayout &record_layout,
1406                                                    DeclFromUser<const CXXRecordDecl> &record,
1407                                                    BaseOffsetMap &base_offsets)
1408 {
1409     for (CXXRecordDecl::base_class_const_iterator
1410             bi = (IsVirtual ? record->vbases_begin() : record->bases_begin()),
1411             be = (IsVirtual ? record->vbases_end() : record->bases_end());
1412          bi != be;
1413          ++bi)
1414     {
1415         if (!IsVirtual && bi->isVirtual())
1416             continue;
1417 
1418         const clang::Type *origin_base_type = bi->getType().getTypePtr();
1419         const clang::RecordType *origin_base_record_type = origin_base_type->getAs<RecordType>();
1420 
1421         if (!origin_base_record_type)
1422             return false;
1423 
1424         DeclFromUser <RecordDecl> origin_base_record(origin_base_record_type->getDecl());
1425 
1426         if (origin_base_record.IsInvalid())
1427             return false;
1428 
1429         DeclFromUser <CXXRecordDecl> origin_base_cxx_record(DynCast<CXXRecordDecl>(origin_base_record));
1430 
1431         if (origin_base_cxx_record.IsInvalid())
1432             return false;
1433 
1434         CharUnits base_offset;
1435 
1436         if (IsVirtual)
1437             base_offset = record_layout.getVBaseClassOffset(origin_base_cxx_record.decl);
1438         else
1439             base_offset = record_layout.getBaseClassOffset(origin_base_cxx_record.decl);
1440 
1441         base_offsets.insert(std::pair<const CXXRecordDecl *, CharUnits>(origin_base_cxx_record.decl, base_offset));
1442     }
1443 
1444     return true;
1445 }
1446 
1447 bool
layoutRecordType(const RecordDecl * record,uint64_t & size,uint64_t & alignment,FieldOffsetMap & field_offsets,BaseOffsetMap & base_offsets,BaseOffsetMap & virtual_base_offsets)1448 ClangASTSource::layoutRecordType(const RecordDecl *record,
1449                                  uint64_t &size,
1450                                  uint64_t &alignment,
1451                                  FieldOffsetMap &field_offsets,
1452                                  BaseOffsetMap &base_offsets,
1453                                  BaseOffsetMap &virtual_base_offsets)
1454 {
1455     ClangASTMetrics::RegisterRecordLayout();
1456 
1457     static unsigned int invocation_id = 0;
1458     unsigned int current_id = invocation_id++;
1459 
1460     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1461 
1462     if (log)
1463     {
1464         log->Printf("LayoutRecordType[%u] on (ASTContext*)%p for (RecordDecl*)%p [name = '%s']",
1465                     current_id,
1466                     m_ast_context,
1467                     record,
1468                     record->getNameAsString().c_str());
1469     }
1470 
1471 
1472     DeclFromParser <const RecordDecl> parser_record(record);
1473     DeclFromUser <const RecordDecl> origin_record(parser_record.GetOrigin(m_ast_importer));
1474 
1475     if (origin_record.IsInvalid())
1476         return false;
1477 
1478     FieldOffsetMap origin_field_offsets;
1479     BaseOffsetMap origin_base_offsets;
1480     BaseOffsetMap origin_virtual_base_offsets;
1481 
1482     ClangASTContext::GetCompleteDecl(&origin_record->getASTContext(), const_cast<RecordDecl*>(origin_record.decl));
1483 
1484     if (!origin_record.decl->getDefinition())
1485         return false;
1486 
1487     const ASTRecordLayout &record_layout(origin_record->getASTContext().getASTRecordLayout(origin_record.decl));
1488 
1489     int field_idx = 0, field_count = record_layout.getFieldCount();
1490 
1491     for (RecordDecl::field_iterator fi = origin_record->field_begin(), fe = origin_record->field_end();
1492          fi != fe;
1493          ++fi)
1494     {
1495         if (field_idx >= field_count)
1496             return false; // Layout didn't go well.  Bail out.
1497 
1498         uint64_t field_offset = record_layout.getFieldOffset(field_idx);
1499 
1500         origin_field_offsets.insert(std::pair<const FieldDecl *, uint64_t>(*fi, field_offset));
1501 
1502         field_idx++;
1503     }
1504 
1505     ASTContext &parser_ast_context(record->getASTContext());
1506 
1507     DeclFromUser <const CXXRecordDecl> origin_cxx_record(DynCast<const CXXRecordDecl>(origin_record));
1508 
1509     if (origin_cxx_record.IsValid())
1510     {
1511         if (!ExtractBaseOffsets<false>(record_layout, origin_cxx_record, origin_base_offsets) ||
1512             !ExtractBaseOffsets<true>(record_layout, origin_cxx_record, origin_virtual_base_offsets))
1513             return false;
1514     }
1515 
1516     if (!ImportOffsetMap(field_offsets, origin_field_offsets, m_ast_importer, parser_ast_context) ||
1517         !ImportOffsetMap(base_offsets, origin_base_offsets, m_ast_importer, parser_ast_context) ||
1518         !ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets, m_ast_importer, parser_ast_context))
1519         return false;
1520 
1521     size = record_layout.getSize().getQuantity() * m_ast_context->getCharWidth();
1522     alignment = record_layout.getAlignment().getQuantity() * m_ast_context->getCharWidth();
1523 
1524     if (log)
1525     {
1526         log->Printf("LRT[%u] returned:", current_id);
1527         log->Printf("LRT[%u]   Original = (RecordDecl*)%p", current_id, origin_record.decl);
1528         log->Printf("LRT[%u]   Size = %" PRId64, current_id, size);
1529         log->Printf("LRT[%u]   Alignment = %" PRId64, current_id, alignment);
1530         log->Printf("LRT[%u]   Fields:", current_id);
1531         for (RecordDecl::field_iterator fi = record->field_begin(), fe = record->field_end();
1532              fi != fe;
1533              ++fi)
1534         {
1535             log->Printf("LRT[%u]     (FieldDecl*)%p, Name = '%s', Offset = %" PRId64 " bits",
1536                         current_id,
1537                         *fi,
1538                         fi->getNameAsString().c_str(),
1539                         field_offsets[*fi]);
1540         }
1541         DeclFromParser <const CXXRecordDecl> parser_cxx_record = DynCast<const CXXRecordDecl>(parser_record);
1542         if (parser_cxx_record.IsValid())
1543         {
1544             log->Printf("LRT[%u]   Bases:", current_id);
1545             for (CXXRecordDecl::base_class_const_iterator bi = parser_cxx_record->bases_begin(), be = parser_cxx_record->bases_end();
1546                  bi != be;
1547                  ++bi)
1548             {
1549                 bool is_virtual = bi->isVirtual();
1550 
1551                 QualType base_type = bi->getType();
1552                 const RecordType *base_record_type = base_type->getAs<RecordType>();
1553                 DeclFromParser <RecordDecl> base_record(base_record_type->getDecl());
1554                 DeclFromParser <CXXRecordDecl> base_cxx_record = DynCast<CXXRecordDecl>(base_record);
1555 
1556                 log->Printf("LRT[%u]     %s(CXXRecordDecl*)%p, Name = '%s', Offset = %" PRId64 " chars",
1557                             current_id,
1558                             (is_virtual ? "Virtual " : ""),
1559                             base_cxx_record.decl,
1560                             base_cxx_record.decl->getNameAsString().c_str(),
1561                             (is_virtual ? virtual_base_offsets[base_cxx_record.decl].getQuantity() :
1562                                           base_offsets[base_cxx_record.decl].getQuantity()));
1563             }
1564         }
1565         else
1566         {
1567             log->Printf("LRD[%u]   Not a CXXRecord, so no bases", current_id);
1568         }
1569     }
1570 
1571     return true;
1572 }
1573 
1574 void
CompleteNamespaceMap(ClangASTImporter::NamespaceMapSP & namespace_map,const ConstString & name,ClangASTImporter::NamespaceMapSP & parent_map) const1575 ClangASTSource::CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespace_map,
1576                                       const ConstString &name,
1577                                       ClangASTImporter::NamespaceMapSP &parent_map) const
1578 {
1579     static unsigned int invocation_id = 0;
1580     unsigned int current_id = invocation_id++;
1581 
1582     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1583 
1584     if (log)
1585     {
1586         if (parent_map && parent_map->size())
1587             log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for namespace %s in namespace %s",
1588                         current_id,
1589                         m_ast_context,
1590                         name.GetCString(),
1591                         parent_map->begin()->second.GetNamespaceDecl()->getDeclName().getAsString().c_str());
1592         else
1593             log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for namespace %s",
1594                         current_id,
1595                         m_ast_context,
1596                         name.GetCString());
1597     }
1598 
1599 
1600     if (parent_map)
1601     {
1602         for (ClangASTImporter::NamespaceMap::iterator i = parent_map->begin(), e = parent_map->end();
1603              i != e;
1604              ++i)
1605         {
1606             ClangNamespaceDecl found_namespace_decl;
1607 
1608             lldb::ModuleSP module_sp = i->first;
1609             ClangNamespaceDecl module_parent_namespace_decl = i->second;
1610 
1611             SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
1612 
1613             if (!symbol_vendor)
1614                 continue;
1615 
1616             SymbolContext null_sc;
1617 
1618             found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &module_parent_namespace_decl);
1619 
1620             if (!found_namespace_decl)
1621                 continue;
1622 
1623             namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(module_sp, found_namespace_decl));
1624 
1625             if (log)
1626                 log->Printf("  CMN[%u] Found namespace %s in module %s",
1627                             current_id,
1628                             name.GetCString(),
1629                             module_sp->GetFileSpec().GetFilename().GetCString());
1630         }
1631     }
1632     else
1633     {
1634         const ModuleList &target_images = m_target->GetImages();
1635         Mutex::Locker modules_locker(target_images.GetMutex());
1636 
1637         ClangNamespaceDecl null_namespace_decl;
1638 
1639         for (size_t i = 0, e = target_images.GetSize(); i < e; ++i)
1640         {
1641             lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
1642 
1643             if (!image)
1644                 continue;
1645 
1646             ClangNamespaceDecl found_namespace_decl;
1647 
1648             SymbolVendor *symbol_vendor = image->GetSymbolVendor();
1649 
1650             if (!symbol_vendor)
1651                 continue;
1652 
1653             SymbolContext null_sc;
1654 
1655             found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &null_namespace_decl);
1656 
1657             if (!found_namespace_decl)
1658                 continue;
1659 
1660             namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(image, found_namespace_decl));
1661 
1662             if (log)
1663                 log->Printf("  CMN[%u] Found namespace %s in module %s",
1664                             current_id,
1665                             name.GetCString(),
1666                             image->GetFileSpec().GetFilename().GetCString());
1667         }
1668     }
1669 }
1670 
1671 NamespaceDecl *
AddNamespace(NameSearchContext & context,ClangASTImporter::NamespaceMapSP & namespace_decls)1672 ClangASTSource::AddNamespace (NameSearchContext &context, ClangASTImporter::NamespaceMapSP &namespace_decls)
1673 {
1674     if (!namespace_decls)
1675         return NULL;
1676 
1677     const ClangNamespaceDecl &namespace_decl = namespace_decls->begin()->second;
1678 
1679     Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, namespace_decl.GetASTContext(), namespace_decl.GetNamespaceDecl());
1680 
1681     if (!copied_decl)
1682         return NULL;
1683 
1684     NamespaceDecl *copied_namespace_decl = dyn_cast<NamespaceDecl>(copied_decl);
1685 
1686     if (!copied_namespace_decl)
1687         return NULL;
1688 
1689     context.m_decls.push_back(copied_namespace_decl);
1690 
1691     m_ast_importer->RegisterNamespaceMap(copied_namespace_decl, namespace_decls);
1692 
1693     return dyn_cast<NamespaceDecl>(copied_decl);
1694 }
1695 
1696 ClangASTType
GuardedCopyType(const ClangASTType & src_type)1697 ClangASTSource::GuardedCopyType (const ClangASTType &src_type)
1698 {
1699     ClangASTMetrics::RegisterLLDBImport();
1700 
1701     SetImportInProgress(true);
1702 
1703     QualType copied_qual_type = m_ast_importer->CopyType (m_ast_context, src_type.GetASTContext(), src_type.GetQualType());
1704 
1705     SetImportInProgress(false);
1706 
1707     if (copied_qual_type.getAsOpaquePtr() && copied_qual_type->getCanonicalTypeInternal().isNull())
1708         // this shouldn't happen, but we're hardening because the AST importer seems to be generating bad types
1709         // on occasion.
1710         return ClangASTType();
1711 
1712     return ClangASTType(m_ast_context, copied_qual_type);
1713 }
1714 
1715 clang::NamedDecl *
AddVarDecl(const ClangASTType & type)1716 NameSearchContext::AddVarDecl(const ClangASTType &type)
1717 {
1718     assert (type && "Type for variable must be valid!");
1719 
1720     if (!type.IsValid())
1721         return NULL;
1722 
1723     IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();
1724 
1725     clang::ASTContext *ast = type.GetASTContext();
1726 
1727     clang::NamedDecl *Decl = VarDecl::Create(*ast,
1728                                              const_cast<DeclContext*>(m_decl_context),
1729                                              SourceLocation(),
1730                                              SourceLocation(),
1731                                              ii,
1732                                              type.GetQualType(),
1733                                              0,
1734                                              SC_Static);
1735     m_decls.push_back(Decl);
1736 
1737     return Decl;
1738 }
1739 
1740 clang::NamedDecl *
AddFunDecl(const ClangASTType & type)1741 NameSearchContext::AddFunDecl (const ClangASTType &type)
1742 {
1743     assert (type && "Type for variable must be valid!");
1744 
1745     if (!type.IsValid())
1746         return NULL;
1747 
1748     if (m_function_types.count(type))
1749         return NULL;
1750 
1751     m_function_types.insert(type);
1752 
1753     QualType qual_type (type.GetQualType());
1754 
1755     clang::ASTContext *ast = type.GetASTContext();
1756 
1757     const bool isInlineSpecified = false;
1758     const bool hasWrittenPrototype = true;
1759     const bool isConstexprSpecified = false;
1760 
1761     clang::FunctionDecl *func_decl = FunctionDecl::Create (*ast,
1762                                                            const_cast<DeclContext*>(m_decl_context),
1763                                                            SourceLocation(),
1764                                                            SourceLocation(),
1765                                                            m_decl_name.getAsIdentifierInfo(),
1766                                                            qual_type,
1767                                                            NULL,
1768                                                            SC_Static,
1769                                                            isInlineSpecified,
1770                                                            hasWrittenPrototype,
1771                                                            isConstexprSpecified);
1772 
1773     // We have to do more than just synthesize the FunctionDecl.  We have to
1774     // synthesize ParmVarDecls for all of the FunctionDecl's arguments.  To do
1775     // this, we raid the function's FunctionProtoType for types.
1776 
1777     const FunctionProtoType *func_proto_type = qual_type.getTypePtr()->getAs<FunctionProtoType>();
1778 
1779     if (func_proto_type)
1780     {
1781         unsigned NumArgs = func_proto_type->getNumArgs();
1782         unsigned ArgIndex;
1783 
1784         SmallVector<ParmVarDecl *, 5> parm_var_decls;
1785 
1786         for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex)
1787         {
1788             QualType arg_qual_type (func_proto_type->getArgType(ArgIndex));
1789 
1790             parm_var_decls.push_back(ParmVarDecl::Create (*ast,
1791                                                           const_cast<DeclContext*>(m_decl_context),
1792                                                           SourceLocation(),
1793                                                           SourceLocation(),
1794                                                           NULL,
1795                                                           arg_qual_type,
1796                                                           NULL,
1797                                                           SC_Static,
1798                                                           NULL));
1799         }
1800 
1801         func_decl->setParams(ArrayRef<ParmVarDecl*>(parm_var_decls));
1802     }
1803     else
1804     {
1805         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1806 
1807         if (log)
1808             log->Printf("Function type wasn't a FunctionProtoType");
1809     }
1810 
1811     m_decls.push_back(func_decl);
1812 
1813     return func_decl;
1814 }
1815 
1816 clang::NamedDecl *
AddGenericFunDecl()1817 NameSearchContext::AddGenericFunDecl()
1818 {
1819     FunctionProtoType::ExtProtoInfo proto_info;
1820 
1821     proto_info.Variadic = true;
1822 
1823     QualType generic_function_type(m_ast_source.m_ast_context->getFunctionType (m_ast_source.m_ast_context->UnknownAnyTy,    // result
1824                                                                                 ArrayRef<QualType>(),                                        // argument types
1825                                                                                 proto_info));
1826 
1827     return AddFunDecl(ClangASTType (m_ast_source.m_ast_context, generic_function_type));
1828 }
1829 
1830 clang::NamedDecl *
AddTypeDecl(const ClangASTType & clang_type)1831 NameSearchContext::AddTypeDecl(const ClangASTType &clang_type)
1832 {
1833     if (clang_type)
1834     {
1835         QualType qual_type = clang_type.GetQualType();
1836 
1837         if (const TypedefType *typedef_type = llvm::dyn_cast<TypedefType>(qual_type))
1838         {
1839             TypedefNameDecl *typedef_name_decl = typedef_type->getDecl();
1840 
1841             m_decls.push_back(typedef_name_decl);
1842 
1843             return (NamedDecl*)typedef_name_decl;
1844         }
1845         else if (const TagType *tag_type = qual_type->getAs<TagType>())
1846         {
1847             TagDecl *tag_decl = tag_type->getDecl();
1848 
1849             m_decls.push_back(tag_decl);
1850 
1851             return tag_decl;
1852         }
1853         else if (const ObjCObjectType *objc_object_type = qual_type->getAs<ObjCObjectType>())
1854         {
1855             ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface();
1856 
1857             m_decls.push_back((NamedDecl*)interface_decl);
1858 
1859             return (NamedDecl*)interface_decl;
1860         }
1861     }
1862     return NULL;
1863 }
1864 
1865 void
AddLookupResult(clang::DeclContextLookupConstResult result)1866 NameSearchContext::AddLookupResult (clang::DeclContextLookupConstResult result)
1867 {
1868     for (clang::NamedDecl *decl : result)
1869         m_decls.push_back (decl);
1870 }
1871 
1872 void
AddNamedDecl(clang::NamedDecl * decl)1873 NameSearchContext::AddNamedDecl (clang::NamedDecl *decl)
1874 {
1875     m_decls.push_back (decl);
1876 }
1877