180814287SRaphael Isemann //===-- ClangASTSource.cpp ------------------------------------------------===//
24dbb271fSSean Callanan //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64dbb271fSSean Callanan //
74dbb271fSSean Callanan //===----------------------------------------------------------------------===//
84dbb271fSSean Callanan 
94dbb271fSSean Callanan #include "ClangASTSource.h"
104dbb271fSSean Callanan 
11cb68bd72SAlex Langford #include "ClangDeclVendor.h"
124dbb271fSSean Callanan #include "ClangModulesDeclVendor.h"
134dbb271fSSean Callanan 
144dbb271fSSean Callanan #include "lldb/Core/Module.h"
154dbb271fSSean Callanan #include "lldb/Core/ModuleList.h"
164dbb271fSSean Callanan #include "lldb/Symbol/CompilerDeclContext.h"
174dbb271fSSean Callanan #include "lldb/Symbol/Function.h"
18ae088e52SGreg Clayton #include "lldb/Symbol/SymbolFile.h"
194dbb271fSSean Callanan #include "lldb/Symbol/TaggedASTType.h"
204dbb271fSSean Callanan #include "lldb/Target/Target.h"
21c34698a8SPavel Labath #include "lldb/Utility/LLDBLog.h"
226f9e6901SZachary Turner #include "lldb/Utility/Log.h"
23d133f6acSZachary Turner #include "clang/AST/ASTContext.h"
24d133f6acSZachary Turner #include "clang/AST/RecordLayout.h"
2586565c13SReid Kleckner #include "clang/Basic/SourceManager.h"
264dbb271fSSean Callanan 
278be30215SAlex Langford #include "Plugins/ExpressionParser/Clang/ClangUtil.h"
28b5701710SAlex Langford #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
298be30215SAlex Langford #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
30b5701710SAlex Langford 
31796ac80bSJonas Devlieghere #include <memory>
324dbb271fSSean Callanan #include <vector>
334dbb271fSSean Callanan 
344dbb271fSSean Callanan using namespace clang;
354dbb271fSSean Callanan using namespace lldb_private;
364dbb271fSSean Callanan 
3705097246SAdrian Prantl // Scoped class that will remove an active lexical decl from the set when it
3805097246SAdrian Prantl // goes out of scope.
394dbb271fSSean Callanan namespace {
40b9c1b51eSKate Stone class ScopedLexicalDeclEraser {
414dbb271fSSean Callanan public:
ScopedLexicalDeclEraser(std::set<const clang::Decl * > & decls,const clang::Decl * decl)424dbb271fSSean Callanan   ScopedLexicalDeclEraser(std::set<const clang::Decl *> &decls,
434dbb271fSSean Callanan                           const clang::Decl *decl)
44b9c1b51eSKate Stone       : m_active_lexical_decls(decls), m_decl(decl) {}
454dbb271fSSean Callanan 
~ScopedLexicalDeclEraser()46b9c1b51eSKate Stone   ~ScopedLexicalDeclEraser() { m_active_lexical_decls.erase(m_decl); }
474dbb271fSSean Callanan 
484dbb271fSSean Callanan private:
494dbb271fSSean Callanan   std::set<const clang::Decl *> &m_active_lexical_decls;
504dbb271fSSean Callanan   const clang::Decl *m_decl;
514dbb271fSSean Callanan };
524dbb271fSSean Callanan }
534dbb271fSSean Callanan 
ClangASTSource(const lldb::TargetSP & target,const std::shared_ptr<ClangASTImporter> & importer)547c9ebdd3SAlex Langford ClangASTSource::ClangASTSource(
557c9ebdd3SAlex Langford     const lldb::TargetSP &target,
567c9ebdd3SAlex Langford     const std::shared_ptr<ClangASTImporter> &importer)
57502773d7SRaphael Isemann     : m_lookups_enabled(false), m_target(target), m_ast_context(nullptr),
58502773d7SRaphael Isemann       m_ast_importer_sp(importer), m_active_lexical_decls(),
59502773d7SRaphael Isemann       m_active_lookups() {
601ccc7029SRaphael Isemann   assert(m_ast_importer_sp && "No ClangASTImporter passed to ClangASTSource?");
6168e44239SSean Callanan }
6268e44239SSean Callanan 
InstallASTContext(TypeSystemClang & clang_ast_context)636e3b0cc2SRaphael Isemann void ClangASTSource::InstallASTContext(TypeSystemClang &clang_ast_context) {
64f9f49d35SRaphael Isemann   m_ast_context = &clang_ast_context.getASTContext();
65bc7f1df6SRaphael Isemann   m_clang_ast_context = &clang_ast_context;
6649b206f9SRaphael Isemann   m_file_manager = &m_ast_context->getSourceManager().getFileManager();
67bc7f1df6SRaphael Isemann   m_ast_importer_sp->InstallMapCompleter(m_ast_context, *this);
6868e44239SSean Callanan }
6968e44239SSean Callanan 
~ClangASTSource()70b9c1b51eSKate Stone ClangASTSource::~ClangASTSource() {
71a3444ffcSSean Callanan   m_ast_importer_sp->ForgetDestination(m_ast_context);
724dbb271fSSean Callanan 
734aee81c4SRaphael Isemann   if (!m_target)
744aee81c4SRaphael Isemann     return;
754dbb271fSSean Callanan 
7647e7ecddSRaphael Isemann   // Unregister the current ASTContext as a source for all scratch
7747e7ecddSRaphael Isemann   // ASTContexts in the ClangASTImporter. Without this the scratch AST might
7847e7ecddSRaphael Isemann   // query the deleted ASTContext for additional type information.
7947e7ecddSRaphael Isemann   // We unregister from *all* scratch ASTContexts in case a type got exported
8047e7ecddSRaphael Isemann   // to a scratch AST that isn't the best fitting scratch ASTContext.
8147e7ecddSRaphael Isemann   TypeSystemClang *scratch_ast = ScratchTypeSystemClang::GetForTarget(
8247e7ecddSRaphael Isemann       *m_target, ScratchTypeSystemClang::DefaultAST, false);
8347e7ecddSRaphael Isemann 
8447e7ecddSRaphael Isemann   if (!scratch_ast)
854dbb271fSSean Callanan     return;
864dbb271fSSean Callanan 
8747e7ecddSRaphael Isemann   ScratchTypeSystemClang *default_scratch_ast =
8847e7ecddSRaphael Isemann       llvm::cast<ScratchTypeSystemClang>(scratch_ast);
8947e7ecddSRaphael Isemann   // Unregister from the default scratch AST (and all sub-ASTs).
9047e7ecddSRaphael Isemann   default_scratch_ast->ForgetSource(m_ast_context, *m_ast_importer_sp);
914dbb271fSSean Callanan }
924dbb271fSSean Callanan 
StartTranslationUnit(ASTConsumer * Consumer)93b9c1b51eSKate Stone void ClangASTSource::StartTranslationUnit(ASTConsumer *Consumer) {
944dbb271fSSean Callanan   if (!m_ast_context)
954dbb271fSSean Callanan     return;
964dbb271fSSean Callanan 
974dbb271fSSean Callanan   m_ast_context->getTranslationUnitDecl()->setHasExternalVisibleStorage();
984dbb271fSSean Callanan   m_ast_context->getTranslationUnitDecl()->setHasExternalLexicalStorage();
994dbb271fSSean Callanan }
1004dbb271fSSean Callanan 
1014dbb271fSSean Callanan // The core lookup interface.
FindExternalVisibleDeclsByName(const DeclContext * decl_ctx,DeclarationName clang_decl_name)102b9c1b51eSKate Stone bool ClangASTSource::FindExternalVisibleDeclsByName(
103b9c1b51eSKate Stone     const DeclContext *decl_ctx, DeclarationName clang_decl_name) {
104b9c1b51eSKate Stone   if (!m_ast_context) {
1054dbb271fSSean Callanan     SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
1064dbb271fSSean Callanan     return false;
1074dbb271fSSean Callanan   }
1084dbb271fSSean Callanan 
1094dbb271fSSean Callanan   std::string decl_name(clang_decl_name.getAsString());
1104dbb271fSSean Callanan 
1114dbb271fSSean Callanan   switch (clang_decl_name.getNameKind()) {
1124dbb271fSSean Callanan   // Normal identifiers.
113b9c1b51eSKate Stone   case DeclarationName::Identifier: {
114b9c1b51eSKate Stone     clang::IdentifierInfo *identifier_info =
115b9c1b51eSKate Stone         clang_decl_name.getAsIdentifierInfo();
1164dbb271fSSean Callanan 
117b9c1b51eSKate Stone     if (!identifier_info || identifier_info->getBuiltinID() != 0) {
1184dbb271fSSean Callanan       SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
1194dbb271fSSean Callanan       return false;
1204dbb271fSSean Callanan     }
121b9c1b51eSKate Stone   } break;
1224dbb271fSSean Callanan 
1234dbb271fSSean Callanan   // Operator names.
1244dbb271fSSean Callanan   case DeclarationName::CXXOperatorName:
1254dbb271fSSean Callanan   case DeclarationName::CXXLiteralOperatorName:
1264dbb271fSSean Callanan     break;
1274dbb271fSSean Callanan 
1284dbb271fSSean Callanan   // Using directives found in this context.
1294dbb271fSSean Callanan   // Tell Sema we didn't find any or we'll end up getting asked a *lot*.
1304dbb271fSSean Callanan   case DeclarationName::CXXUsingDirective:
1314dbb271fSSean Callanan     SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
1324dbb271fSSean Callanan     return false;
1334dbb271fSSean Callanan 
1344dbb271fSSean Callanan   case DeclarationName::ObjCZeroArgSelector:
1354dbb271fSSean Callanan   case DeclarationName::ObjCOneArgSelector:
136b9c1b51eSKate Stone   case DeclarationName::ObjCMultiArgSelector: {
1374dbb271fSSean Callanan     llvm::SmallVector<NamedDecl *, 1> method_decls;
1384dbb271fSSean Callanan 
139defd0e24SRaphael Isemann     NameSearchContext method_search_context(*m_clang_ast_context, method_decls,
140b9c1b51eSKate Stone                                             clang_decl_name, decl_ctx);
1414dbb271fSSean Callanan 
1424dbb271fSSean Callanan     FindObjCMethodDecls(method_search_context);
1434dbb271fSSean Callanan 
1444dbb271fSSean Callanan     SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, method_decls);
1454dbb271fSSean Callanan     return (method_decls.size() > 0);
1464dbb271fSSean Callanan   }
1474dbb271fSSean Callanan   // These aren't possible in the global context.
1484dbb271fSSean Callanan   case DeclarationName::CXXConstructorName:
1494dbb271fSSean Callanan   case DeclarationName::CXXDestructorName:
1504dbb271fSSean Callanan   case DeclarationName::CXXConversionFunctionName:
1514f19fce2SPavel Labath   case DeclarationName::CXXDeductionGuideName:
1524dbb271fSSean Callanan     SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
1534dbb271fSSean Callanan     return false;
1544dbb271fSSean Callanan   }
1554dbb271fSSean Callanan 
156b9c1b51eSKate Stone   if (!GetLookupsEnabled()) {
15705097246SAdrian Prantl     // Wait until we see a '$' at the start of a name before we start doing any
15805097246SAdrian Prantl     // lookups so we can avoid lookup up all of the builtin types.
159b9c1b51eSKate Stone     if (!decl_name.empty() && decl_name[0] == '$') {
1604dbb271fSSean Callanan       SetLookupsEnabled(true);
161b9c1b51eSKate Stone     } else {
1624dbb271fSSean Callanan       SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
1634dbb271fSSean Callanan       return false;
1644dbb271fSSean Callanan     }
1654dbb271fSSean Callanan   }
1664dbb271fSSean Callanan 
1674dbb271fSSean Callanan   ConstString const_decl_name(decl_name.c_str());
1684dbb271fSSean Callanan 
1694dbb271fSSean Callanan   const char *uniqued_const_decl_name = const_decl_name.GetCString();
170b9c1b51eSKate Stone   if (m_active_lookups.find(uniqued_const_decl_name) !=
171b9c1b51eSKate Stone       m_active_lookups.end()) {
1724dbb271fSSean Callanan     // We are currently looking up this name...
1734dbb271fSSean Callanan     SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
1744dbb271fSSean Callanan     return false;
1754dbb271fSSean Callanan   }
1764dbb271fSSean Callanan   m_active_lookups.insert(uniqued_const_decl_name);
1774dbb271fSSean Callanan   llvm::SmallVector<NamedDecl *, 4> name_decls;
178defd0e24SRaphael Isemann   NameSearchContext name_search_context(*m_clang_ast_context, name_decls,
179defd0e24SRaphael Isemann                                         clang_decl_name, decl_ctx);
1804dbb271fSSean Callanan   FindExternalVisibleDecls(name_search_context);
1814dbb271fSSean Callanan   SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, name_decls);
1824dbb271fSSean Callanan   m_active_lookups.erase(uniqued_const_decl_name);
1834dbb271fSSean Callanan   return (name_decls.size() != 0);
1844dbb271fSSean Callanan }
1854dbb271fSSean Callanan 
FindCompleteType(const TagDecl * decl)1865a4d7806SPavel Labath TagDecl *ClangASTSource::FindCompleteType(const TagDecl *decl) {
187a007a6d8SPavel Labath   Log *log = GetLog(LLDBLog::Expressions);
1885a4d7806SPavel Labath 
1895a4d7806SPavel Labath   if (const NamespaceDecl *namespace_context =
1905a4d7806SPavel Labath           dyn_cast<NamespaceDecl>(decl->getDeclContext())) {
1915a4d7806SPavel Labath     ClangASTImporter::NamespaceMapSP namespace_map =
1925a4d7806SPavel Labath         m_ast_importer_sp->GetNamespaceMap(namespace_context);
1935a4d7806SPavel Labath 
1945a4d7806SPavel Labath     if (!namespace_map)
1955a4d7806SPavel Labath       return nullptr;
1965a4d7806SPavel Labath 
197*0a412b35SMichael Buch     LLDB_LOGV(log, "      CTD Inspecting namespace map{0} ({1} entries)",
198*0a412b35SMichael Buch               namespace_map.get(), namespace_map->size());
199*0a412b35SMichael Buch 
2005a4d7806SPavel Labath     for (const ClangASTImporter::NamespaceMapItem &item : *namespace_map) {
2015a4d7806SPavel Labath       LLDB_LOG(log, "      CTD Searching namespace {0} in module {1}",
2025a4d7806SPavel Labath                item.second.GetName(), item.first->GetFileSpec().GetFilename());
2035a4d7806SPavel Labath 
2045a4d7806SPavel Labath       TypeList types;
2055a4d7806SPavel Labath 
2065a4d7806SPavel Labath       ConstString name(decl->getName());
2075a4d7806SPavel Labath 
2085a4d7806SPavel Labath       item.first->FindTypesInNamespace(name, item.second, UINT32_MAX, types);
2095a4d7806SPavel Labath 
2105a4d7806SPavel Labath       for (uint32_t ti = 0, te = types.GetSize(); ti != te; ++ti) {
2115a4d7806SPavel Labath         lldb::TypeSP type = types.GetTypeAtIndex(ti);
2125a4d7806SPavel Labath 
2135a4d7806SPavel Labath         if (!type)
2145a4d7806SPavel Labath           continue;
2155a4d7806SPavel Labath 
2165a4d7806SPavel Labath         CompilerType clang_type(type->GetFullCompilerType());
2175a4d7806SPavel Labath 
2185a4d7806SPavel Labath         if (!ClangUtil::IsClangType(clang_type))
2195a4d7806SPavel Labath           continue;
2205a4d7806SPavel Labath 
2215a4d7806SPavel Labath         const TagType *tag_type =
2225a4d7806SPavel Labath             ClangUtil::GetQualType(clang_type)->getAs<TagType>();
2235a4d7806SPavel Labath 
2245a4d7806SPavel Labath         if (!tag_type)
2255a4d7806SPavel Labath           continue;
2265a4d7806SPavel Labath 
2275a4d7806SPavel Labath         TagDecl *candidate_tag_decl =
2285a4d7806SPavel Labath             const_cast<TagDecl *>(tag_type->getDecl());
2295a4d7806SPavel Labath 
2305a4d7806SPavel Labath         if (TypeSystemClang::GetCompleteDecl(
2315a4d7806SPavel Labath                 &candidate_tag_decl->getASTContext(), candidate_tag_decl))
2325a4d7806SPavel Labath           return candidate_tag_decl;
2335a4d7806SPavel Labath       }
2345a4d7806SPavel Labath     }
2355a4d7806SPavel Labath   } else {
2365a4d7806SPavel Labath     TypeList types;
2375a4d7806SPavel Labath 
2385a4d7806SPavel Labath     ConstString name(decl->getName());
2395a4d7806SPavel Labath 
2405a4d7806SPavel Labath     const ModuleList &module_list = m_target->GetImages();
2415a4d7806SPavel Labath 
2425a4d7806SPavel Labath     bool exact_match = false;
2435a4d7806SPavel Labath     llvm::DenseSet<SymbolFile *> searched_symbol_files;
2445a4d7806SPavel Labath     module_list.FindTypes(nullptr, name, exact_match, UINT32_MAX,
2455a4d7806SPavel Labath                           searched_symbol_files, types);
2465a4d7806SPavel Labath 
2475a4d7806SPavel Labath     for (uint32_t ti = 0, te = types.GetSize(); ti != te; ++ti) {
2485a4d7806SPavel Labath       lldb::TypeSP type = types.GetTypeAtIndex(ti);
2495a4d7806SPavel Labath 
2505a4d7806SPavel Labath       if (!type)
2515a4d7806SPavel Labath         continue;
2525a4d7806SPavel Labath 
2535a4d7806SPavel Labath       CompilerType clang_type(type->GetFullCompilerType());
2545a4d7806SPavel Labath 
2555a4d7806SPavel Labath       if (!ClangUtil::IsClangType(clang_type))
2565a4d7806SPavel Labath         continue;
2575a4d7806SPavel Labath 
2585a4d7806SPavel Labath       const TagType *tag_type =
2595a4d7806SPavel Labath           ClangUtil::GetQualType(clang_type)->getAs<TagType>();
2605a4d7806SPavel Labath 
2615a4d7806SPavel Labath       if (!tag_type)
2625a4d7806SPavel Labath         continue;
2635a4d7806SPavel Labath 
2645a4d7806SPavel Labath       TagDecl *candidate_tag_decl = const_cast<TagDecl *>(tag_type->getDecl());
2655a4d7806SPavel Labath 
2665a4d7806SPavel Labath       // We have found a type by basename and we need to make sure the decl
2675a4d7806SPavel Labath       // contexts are the same before we can try to complete this type with
2685a4d7806SPavel Labath       // another
2695a4d7806SPavel Labath       if (!TypeSystemClang::DeclsAreEquivalent(const_cast<TagDecl *>(decl),
2705a4d7806SPavel Labath                                                candidate_tag_decl))
2715a4d7806SPavel Labath         continue;
2725a4d7806SPavel Labath 
2735a4d7806SPavel Labath       if (TypeSystemClang::GetCompleteDecl(&candidate_tag_decl->getASTContext(),
2745a4d7806SPavel Labath                                            candidate_tag_decl))
2755a4d7806SPavel Labath         return candidate_tag_decl;
2765a4d7806SPavel Labath     }
2775a4d7806SPavel Labath   }
2785a4d7806SPavel Labath   return nullptr;
2795a4d7806SPavel Labath }
2805a4d7806SPavel Labath 
CompleteType(TagDecl * tag_decl)281b9c1b51eSKate Stone void ClangASTSource::CompleteType(TagDecl *tag_decl) {
282a007a6d8SPavel Labath   Log *log = GetLog(LLDBLog::Expressions);
2834dbb271fSSean Callanan 
284b9c1b51eSKate Stone   if (log) {
2851f7b95d0SRaphael Isemann     LLDB_LOG(log,
286e98ef0afSRaphael Isemann              "    CompleteTagDecl on (ASTContext*){0} Completing "
287e98ef0afSRaphael Isemann              "(TagDecl*){1} named {2}",
288e657a1ebSRaphael Isemann              m_clang_ast_context->getDisplayName(), tag_decl,
289c9a39a89SRaphael Isemann              tag_decl->getName());
2904dbb271fSSean Callanan 
291e657a1ebSRaphael Isemann     LLDB_LOG(log, "      CTD Before:\n{0}", ClangUtil::DumpDecl(tag_decl));
2924dbb271fSSean Callanan   }
2934dbb271fSSean Callanan 
2944dbb271fSSean Callanan   auto iter = m_active_lexical_decls.find(tag_decl);
2954dbb271fSSean Callanan   if (iter != m_active_lexical_decls.end())
2964dbb271fSSean Callanan     return;
2974dbb271fSSean Callanan   m_active_lexical_decls.insert(tag_decl);
2984dbb271fSSean Callanan   ScopedLexicalDeclEraser eraser(m_active_lexical_decls, tag_decl);
2994dbb271fSSean Callanan 
300b9c1b51eSKate Stone   if (!m_ast_importer_sp->CompleteTagDecl(tag_decl)) {
30105097246SAdrian Prantl     // We couldn't complete the type.  Maybe there's a definition somewhere
30205097246SAdrian Prantl     // else that can be completed.
3035a4d7806SPavel Labath     if (TagDecl *alternate = FindCompleteType(tag_decl))
3045a4d7806SPavel Labath       m_ast_importer_sp->CompleteTagDeclWithOrigin(tag_decl, alternate);
3054dbb271fSSean Callanan   }
3064dbb271fSSean Callanan 
3077a6588abSRaphael Isemann   LLDB_LOG(log, "      [CTD] After:\n{0}", ClangUtil::DumpDecl(tag_decl));
3084dbb271fSSean Callanan }
3094dbb271fSSean Callanan 
CompleteType(clang::ObjCInterfaceDecl * interface_decl)310b9c1b51eSKate Stone void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) {
311a007a6d8SPavel Labath   Log *log = GetLog(LLDBLog::Expressions);
3124dbb271fSSean Callanan 
3131f7b95d0SRaphael Isemann   LLDB_LOG(log,
314c9a39a89SRaphael Isemann            "    [CompleteObjCInterfaceDecl] on (ASTContext*){0} '{1}' "
315c9a39a89SRaphael Isemann            "Completing an ObjCInterfaceDecl named {1}",
316c9a39a89SRaphael Isemann            m_ast_context, m_clang_ast_context->getDisplayName(),
317c9a39a89SRaphael Isemann            interface_decl->getName());
3187a6588abSRaphael Isemann   LLDB_LOG(log, "      [COID] Before:\n{0}",
3197a6588abSRaphael Isemann            ClangUtil::DumpDecl(interface_decl));
3204dbb271fSSean Callanan 
32164678ef9SRaphael Isemann   ClangASTImporter::DeclOrigin original = m_ast_importer_sp->GetDeclOrigin(interface_decl);
3224dbb271fSSean Callanan 
32364678ef9SRaphael Isemann   if (original.Valid()) {
324b9c1b51eSKate Stone     if (ObjCInterfaceDecl *original_iface_decl =
32564678ef9SRaphael Isemann             dyn_cast<ObjCInterfaceDecl>(original.decl)) {
326b9c1b51eSKate Stone       ObjCInterfaceDecl *complete_iface_decl =
327b9c1b51eSKate Stone           GetCompleteObjCInterface(original_iface_decl);
3284dbb271fSSean Callanan 
329b9c1b51eSKate Stone       if (complete_iface_decl && (complete_iface_decl != original_iface_decl)) {
33040d067cdSSean Callanan         m_ast_importer_sp->SetDeclOrigin(interface_decl, complete_iface_decl);
3314dbb271fSSean Callanan       }
3324dbb271fSSean Callanan     }
3334dbb271fSSean Callanan   }
3344dbb271fSSean Callanan 
335a3444ffcSSean Callanan   m_ast_importer_sp->CompleteObjCInterfaceDecl(interface_decl);
3364dbb271fSSean Callanan 
3374dbb271fSSean Callanan   if (interface_decl->getSuperClass() &&
3384dbb271fSSean Callanan       interface_decl->getSuperClass() != interface_decl)
3394dbb271fSSean Callanan     CompleteType(interface_decl->getSuperClass());
3404dbb271fSSean Callanan 
3411f7b95d0SRaphael Isemann   LLDB_LOG(log, "      [COID] After:");
3427a6588abSRaphael Isemann   LLDB_LOG(log, "      [COID] {0}", ClangUtil::DumpDecl(interface_decl));
3434dbb271fSSean Callanan }
3444dbb271fSSean Callanan 
GetCompleteObjCInterface(const clang::ObjCInterfaceDecl * interface_decl)345b9c1b51eSKate Stone clang::ObjCInterfaceDecl *ClangASTSource::GetCompleteObjCInterface(
34668e44239SSean Callanan     const clang::ObjCInterfaceDecl *interface_decl) {
3474dbb271fSSean Callanan   lldb::ProcessSP process(m_target->GetProcessSP());
3484dbb271fSSean Callanan 
3494dbb271fSSean Callanan   if (!process)
350248a1305SKonrad Kleine     return nullptr;
3514dbb271fSSean Callanan 
352e823bbe8SAlex Langford   ObjCLanguageRuntime *language_runtime(ObjCLanguageRuntime::Get(*process));
3534dbb271fSSean Callanan 
3544dbb271fSSean Callanan   if (!language_runtime)
355248a1305SKonrad Kleine     return nullptr;
3564dbb271fSSean Callanan 
3574dbb271fSSean Callanan   ConstString class_name(interface_decl->getNameAsString().c_str());
3584dbb271fSSean Callanan 
359b9c1b51eSKate Stone   lldb::TypeSP complete_type_sp(
360b9c1b51eSKate Stone       language_runtime->LookupInCompleteClassCache(class_name));
3614dbb271fSSean Callanan 
3624dbb271fSSean Callanan   if (!complete_type_sp)
363248a1305SKonrad Kleine     return nullptr;
3644dbb271fSSean Callanan 
365b9c1b51eSKate Stone   TypeFromUser complete_type =
366b9c1b51eSKate Stone       TypeFromUser(complete_type_sp->GetFullCompilerType());
367b9c1b51eSKate Stone   lldb::opaque_compiler_type_t complete_opaque_type =
368b9c1b51eSKate Stone       complete_type.GetOpaqueQualType();
3694dbb271fSSean Callanan 
3704dbb271fSSean Callanan   if (!complete_opaque_type)
371248a1305SKonrad Kleine     return nullptr;
3724dbb271fSSean Callanan 
373b9c1b51eSKate Stone   const clang::Type *complete_clang_type =
374b9c1b51eSKate Stone       QualType::getFromOpaquePtr(complete_opaque_type).getTypePtr();
375b9c1b51eSKate Stone   const ObjCInterfaceType *complete_interface_type =
376b9c1b51eSKate Stone       dyn_cast<ObjCInterfaceType>(complete_clang_type);
3774dbb271fSSean Callanan 
3784dbb271fSSean Callanan   if (!complete_interface_type)
379248a1305SKonrad Kleine     return nullptr;
3804dbb271fSSean Callanan 
3814dbb271fSSean Callanan   ObjCInterfaceDecl *complete_iface_decl(complete_interface_type->getDecl());
3824dbb271fSSean Callanan 
3834dbb271fSSean Callanan   return complete_iface_decl;
3844dbb271fSSean Callanan }
3854dbb271fSSean Callanan 
FindExternalLexicalDecls(const DeclContext * decl_context,llvm::function_ref<bool (Decl::Kind)> predicate,llvm::SmallVectorImpl<Decl * > & decls)386b9c1b51eSKate Stone void ClangASTSource::FindExternalLexicalDecls(
387b9c1b51eSKate Stone     const DeclContext *decl_context,
3884dbb271fSSean Callanan     llvm::function_ref<bool(Decl::Kind)> predicate,
389b9c1b51eSKate Stone     llvm::SmallVectorImpl<Decl *> &decls) {
39068e44239SSean Callanan 
391a007a6d8SPavel Labath   Log *log = GetLog(LLDBLog::Expressions);
3924dbb271fSSean Callanan 
3934dbb271fSSean Callanan   const Decl *context_decl = dyn_cast<Decl>(decl_context);
3944dbb271fSSean Callanan 
3954dbb271fSSean Callanan   if (!context_decl)
3964dbb271fSSean Callanan     return;
3974dbb271fSSean Callanan 
3984dbb271fSSean Callanan   auto iter = m_active_lexical_decls.find(context_decl);
3994dbb271fSSean Callanan   if (iter != m_active_lexical_decls.end())
4004dbb271fSSean Callanan     return;
4014dbb271fSSean Callanan   m_active_lexical_decls.insert(context_decl);
4024dbb271fSSean Callanan   ScopedLexicalDeclEraser eraser(m_active_lexical_decls, context_decl);
4034dbb271fSSean Callanan 
404b9c1b51eSKate Stone   if (log) {
4054dbb271fSSean Callanan     if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
4061f7b95d0SRaphael Isemann       LLDB_LOG(log,
407d0e8abc4SRaphael Isemann                "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in "
408d0e8abc4SRaphael Isemann                "'{2}' (%sDecl*){3}",
409e657a1ebSRaphael Isemann                m_ast_context, m_clang_ast_context->getDisplayName(),
4104dbb271fSSean Callanan                context_named_decl->getNameAsString().c_str(),
4114dbb271fSSean Callanan                context_decl->getDeclKindName(),
4124dbb271fSSean Callanan                static_cast<const void *>(context_decl));
4134dbb271fSSean Callanan     else if (context_decl)
414c9a39a89SRaphael Isemann       LLDB_LOG(log,
415d0e8abc4SRaphael Isemann                "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in "
416d0e8abc4SRaphael Isemann                "({2}Decl*){3}",
417e657a1ebSRaphael Isemann                m_ast_context, m_clang_ast_context->getDisplayName(),
4184dbb271fSSean Callanan                context_decl->getDeclKindName(),
4194dbb271fSSean Callanan                static_cast<const void *>(context_decl));
4204dbb271fSSean Callanan     else
421c9a39a89SRaphael Isemann       LLDB_LOG(log,
422d0e8abc4SRaphael Isemann                "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in a "
423c9a39a89SRaphael Isemann                "NULL context",
424e657a1ebSRaphael Isemann                m_ast_context, m_clang_ast_context->getDisplayName());
4254dbb271fSSean Callanan   }
4264dbb271fSSean Callanan 
42764678ef9SRaphael Isemann   ClangASTImporter::DeclOrigin original = m_ast_importer_sp->GetDeclOrigin(context_decl);
4284dbb271fSSean Callanan 
42964678ef9SRaphael Isemann   if (!original.Valid())
4304dbb271fSSean Callanan     return;
4314dbb271fSSean Callanan 
432d0e8abc4SRaphael Isemann   LLDB_LOG(log, "  FELD Original decl {0} (Decl*){1:x}:\n{2}",
433c9a39a89SRaphael Isemann            static_cast<void *>(original.ctx),
434c9a39a89SRaphael Isemann            static_cast<void *>(original.decl),
435c9a39a89SRaphael Isemann            ClangUtil::DumpDecl(original.decl));
4364dbb271fSSean Callanan 
437b9c1b51eSKate Stone   if (ObjCInterfaceDecl *original_iface_decl =
43864678ef9SRaphael Isemann           dyn_cast<ObjCInterfaceDecl>(original.decl)) {
439b9c1b51eSKate Stone     ObjCInterfaceDecl *complete_iface_decl =
440b9c1b51eSKate Stone         GetCompleteObjCInterface(original_iface_decl);
4414dbb271fSSean Callanan 
442b9c1b51eSKate Stone     if (complete_iface_decl && (complete_iface_decl != original_iface_decl)) {
44364678ef9SRaphael Isemann       original.decl = complete_iface_decl;
44464678ef9SRaphael Isemann       original.ctx = &complete_iface_decl->getASTContext();
4454dbb271fSSean Callanan 
44640d067cdSSean Callanan       m_ast_importer_sp->SetDeclOrigin(context_decl, complete_iface_decl);
4474dbb271fSSean Callanan     }
4484dbb271fSSean Callanan   }
4494dbb271fSSean Callanan 
45064678ef9SRaphael Isemann   if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original.decl)) {
45164678ef9SRaphael Isemann     ExternalASTSource *external_source = original.ctx->getExternalSource();
4524dbb271fSSean Callanan 
4534dbb271fSSean Callanan     if (external_source)
4544dbb271fSSean Callanan       external_source->CompleteType(original_tag_decl);
4554dbb271fSSean Callanan   }
4564dbb271fSSean Callanan 
457b9c1b51eSKate Stone   const DeclContext *original_decl_context =
45864678ef9SRaphael Isemann       dyn_cast<DeclContext>(original.decl);
4594dbb271fSSean Callanan 
4604dbb271fSSean Callanan   if (!original_decl_context)
4614dbb271fSSean Callanan     return;
4624dbb271fSSean Callanan 
463aefcf510SGabor Marton   // Indicates whether we skipped any Decls of the original DeclContext.
464aefcf510SGabor Marton   bool SkippedDecls = false;
46570b8f958SRaphael Isemann   for (Decl *decl : original_decl_context->decls()) {
466aefcf510SGabor Marton     // The predicate function returns true if the passed declaration kind is
467aefcf510SGabor Marton     // the one we are looking for.
468aefcf510SGabor Marton     // See clang::ExternalASTSource::FindExternalLexicalDecls()
469b9c1b51eSKate Stone     if (predicate(decl->getKind())) {
470b9c1b51eSKate Stone       if (log) {
4717a6588abSRaphael Isemann         std::string ast_dump = ClangUtil::DumpDecl(decl);
472b9c1b51eSKate Stone         if (const NamedDecl *context_named_decl =
473b9c1b51eSKate Stone                 dyn_cast<NamedDecl>(context_decl))
4744ab2ea9fSRaphael Isemann           LLDB_LOG(log, "  FELD Adding [to {0}Decl {1}] lexical {2}Decl {3}",
475e657a1ebSRaphael Isemann                    context_named_decl->getDeclKindName(),
476e657a1ebSRaphael Isemann                    context_named_decl->getName(), decl->getDeclKindName(),
477e657a1ebSRaphael Isemann                    ast_dump);
4784dbb271fSSean Callanan         else
479e98ef0afSRaphael Isemann           LLDB_LOG(log, "  FELD Adding lexical {0}Decl {1}",
4801f7b95d0SRaphael Isemann                    decl->getDeclKindName(), ast_dump);
4814dbb271fSSean Callanan       }
4824dbb271fSSean Callanan 
483360d901bSJordan Rupprecht       Decl *copied_decl = CopyDecl(decl);
484360d901bSJordan Rupprecht 
485360d901bSJordan Rupprecht       if (!copied_decl)
486360d901bSJordan Rupprecht         continue;
4874dbb271fSSean Callanan 
488b7a09de1SRaphael Isemann       // FIXME: We should add the copied decl to the 'decls' list. This would
489b7a09de1SRaphael Isemann       // add the copied Decl into the DeclContext and make sure that we
490b7a09de1SRaphael Isemann       // correctly propagate that we added some Decls back to Clang.
491b7a09de1SRaphael Isemann       // By leaving 'decls' empty we incorrectly return false from
492b7a09de1SRaphael Isemann       // DeclContext::LoadLexicalDeclsFromExternalStorage which might cause
493b7a09de1SRaphael Isemann       // lookup issues later on.
494b7a09de1SRaphael Isemann       // We can't just add them for now as the ASTImporter already added the
495b7a09de1SRaphael Isemann       // decl into the DeclContext and this would add it twice.
496360d901bSJordan Rupprecht 
497360d901bSJordan Rupprecht       if (FieldDecl *copied_field = dyn_cast<FieldDecl>(copied_decl)) {
498360d901bSJordan Rupprecht         QualType copied_field_type = copied_field->getType();
499360d901bSJordan Rupprecht 
500360d901bSJordan Rupprecht         m_ast_importer_sp->RequireCompleteType(copied_field_type);
501360d901bSJordan Rupprecht       }
502aefcf510SGabor Marton     } else {
503aefcf510SGabor Marton       SkippedDecls = true;
504aefcf510SGabor Marton     }
5054dbb271fSSean Callanan   }
5064dbb271fSSean Callanan 
507aefcf510SGabor Marton   // CopyDecl may build a lookup table which may set up ExternalLexicalStorage
508aefcf510SGabor Marton   // to false.  However, since we skipped some of the external Decls we must
509aefcf510SGabor Marton   // set it back!
510aefcf510SGabor Marton   if (SkippedDecls) {
511aefcf510SGabor Marton     decl_context->setHasExternalLexicalStorage(true);
512aefcf510SGabor Marton     // This sets HasLazyExternalLexicalLookups to true.  By setting this bit we
513aefcf510SGabor Marton     // ensure that the lookup table is rebuilt, which means the external source
514aefcf510SGabor Marton     // is consulted again when a clang::DeclContext::lookup is called.
515aefcf510SGabor Marton     const_cast<DeclContext *>(decl_context)->setMustBuildLookupTable();
5164dbb271fSSean Callanan   }
5174dbb271fSSean Callanan }
5184dbb271fSSean Callanan 
FindExternalVisibleDecls(NameSearchContext & context)519b9c1b51eSKate Stone void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
5204dbb271fSSean Callanan   assert(m_ast_context);
5214dbb271fSSean Callanan 
5224dbb271fSSean Callanan   const ConstString name(context.m_decl_name.getAsString().c_str());
5234dbb271fSSean Callanan 
524a007a6d8SPavel Labath   Log *log = GetLog(LLDBLog::Expressions);
5254dbb271fSSean Callanan 
526b9c1b51eSKate Stone   if (log) {
5274dbb271fSSean Callanan     if (!context.m_decl_context)
5281f7b95d0SRaphael Isemann       LLDB_LOG(log,
529e657a1ebSRaphael Isemann                "ClangASTSource::FindExternalVisibleDecls on "
530e98ef0afSRaphael Isemann                "(ASTContext*){0} '{1}' for '{2}' in a NULL DeclContext",
531e657a1ebSRaphael Isemann                m_ast_context, m_clang_ast_context->getDisplayName(), name);
532b9c1b51eSKate Stone     else if (const NamedDecl *context_named_decl =
533b9c1b51eSKate Stone                  dyn_cast<NamedDecl>(context.m_decl_context))
5341f7b95d0SRaphael Isemann       LLDB_LOG(log,
535e657a1ebSRaphael Isemann                "ClangASTSource::FindExternalVisibleDecls on "
536e98ef0afSRaphael Isemann                "(ASTContext*){0} '{1}' for '{2}' in '{3}'",
537e657a1ebSRaphael Isemann                m_ast_context, m_clang_ast_context->getDisplayName(), name,
538e657a1ebSRaphael Isemann                context_named_decl->getName());
5394dbb271fSSean Callanan     else
5401f7b95d0SRaphael Isemann       LLDB_LOG(log,
541e657a1ebSRaphael Isemann                "ClangASTSource::FindExternalVisibleDecls on "
542e98ef0afSRaphael Isemann                "(ASTContext*){0} '{1}' for '{2}' in a '{3}'",
543e657a1ebSRaphael Isemann                m_ast_context, m_clang_ast_context->getDisplayName(), name,
544e657a1ebSRaphael Isemann                context.m_decl_context->getDeclKindName());
5454dbb271fSSean Callanan   }
5464dbb271fSSean Callanan 
54705d174d3SRaphael Isemann   if (isa<NamespaceDecl>(context.m_decl_context)) {
54805d174d3SRaphael Isemann     LookupInNamespace(context);
549ff0102b3SRaphael Isemann   } else if (isa<ObjCInterfaceDecl>(context.m_decl_context)) {
5504dbb271fSSean Callanan     FindObjCPropertyAndIvarDecls(context);
551b9c1b51eSKate Stone   } else if (!isa<TranslationUnitDecl>(context.m_decl_context)) {
5524dbb271fSSean Callanan     // we shouldn't be getting FindExternalVisibleDecls calls for these
5534dbb271fSSean Callanan     return;
554b9c1b51eSKate Stone   } else {
5554dbb271fSSean Callanan     CompilerDeclContext namespace_decl;
5564dbb271fSSean Callanan 
557e657a1ebSRaphael Isemann     LLDB_LOG(log, "  CAS::FEVD Searching the root namespace");
5584dbb271fSSean Callanan 
559e657a1ebSRaphael Isemann     FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl);
5604dbb271fSSean Callanan   }
5614dbb271fSSean Callanan 
562b9c1b51eSKate Stone   if (!context.m_namespace_map->empty()) {
5634dbb271fSSean Callanan     if (log && log->GetVerbose())
564d0e8abc4SRaphael Isemann       LLDB_LOG(log, "  CAS::FEVD Registering namespace map {0} ({1} entries)",
565e657a1ebSRaphael Isemann                context.m_namespace_map.get(), context.m_namespace_map->size());
5664dbb271fSSean Callanan 
567b9c1b51eSKate Stone     NamespaceDecl *clang_namespace_decl =
568b9c1b51eSKate Stone         AddNamespace(context, context.m_namespace_map);
5694dbb271fSSean Callanan 
5704dbb271fSSean Callanan     if (clang_namespace_decl)
5714dbb271fSSean Callanan       clang_namespace_decl->setHasExternalVisibleStorage();
5724dbb271fSSean Callanan   }
5734dbb271fSSean Callanan }
5744dbb271fSSean Callanan 
getSema()575f74a4c1fSRaphael Isemann clang::Sema *ClangASTSource::getSema() {
576bc7f1df6SRaphael Isemann   return m_clang_ast_context->getSema();
577f74a4c1fSRaphael Isemann }
578f74a4c1fSRaphael Isemann 
IgnoreName(const ConstString name,bool ignore_all_dollar_names)5791b3c43b6SSean Callanan bool ClangASTSource::IgnoreName(const ConstString name,
5801b3c43b6SSean Callanan                                 bool ignore_all_dollar_names) {
5811b3c43b6SSean Callanan   static const ConstString id_name("id");
5821b3c43b6SSean Callanan   static const ConstString Class_name("Class");
5831b3c43b6SSean Callanan 
584f3351889SAleksandr Urakov   if (m_ast_context->getLangOpts().ObjC)
5851b3c43b6SSean Callanan     if (name == id_name || name == Class_name)
5861b3c43b6SSean Callanan       return true;
5871b3c43b6SSean Callanan 
5881b3c43b6SSean Callanan   StringRef name_string_ref = name.GetStringRef();
5891b3c43b6SSean Callanan 
5901b3c43b6SSean Callanan   // The ClangASTSource is not responsible for finding $-names.
591a6682a41SJonas Devlieghere   return name_string_ref.empty() ||
5921b3c43b6SSean Callanan          (ignore_all_dollar_names && name_string_ref.startswith("$")) ||
593a6682a41SJonas Devlieghere          name_string_ref.startswith("_$");
5941b3c43b6SSean Callanan }
5951b3c43b6SSean Callanan 
FindExternalVisibleDecls(NameSearchContext & context,lldb::ModuleSP module_sp,CompilerDeclContext & namespace_decl)596b9c1b51eSKate Stone void ClangASTSource::FindExternalVisibleDecls(
597b9c1b51eSKate Stone     NameSearchContext &context, lldb::ModuleSP module_sp,
598e657a1ebSRaphael Isemann     CompilerDeclContext &namespace_decl) {
5994dbb271fSSean Callanan   assert(m_ast_context);
6004dbb271fSSean Callanan 
601a007a6d8SPavel Labath   Log *log = GetLog(LLDBLog::Expressions);
6024dbb271fSSean Callanan 
6034dbb271fSSean Callanan   SymbolContextList sc_list;
6044dbb271fSSean Callanan 
6054dbb271fSSean Callanan   const ConstString name(context.m_decl_name.getAsString().c_str());
6061b3c43b6SSean Callanan   if (IgnoreName(name, true))
6074dbb271fSSean Callanan     return;
6084dbb271fSSean Callanan 
6094aee81c4SRaphael Isemann   if (!m_target)
6104aee81c4SRaphael Isemann     return;
6114aee81c4SRaphael Isemann 
612bdb24faaSRaphael Isemann   FillNamespaceMap(context, module_sp, namespace_decl);
6134dbb271fSSean Callanan 
6142ad7b6fbSRaphael Isemann   if (context.m_found_type)
615bb61021aSRaphael Isemann     return;
6168ba1654dSSean Callanan 
6174dbb271fSSean Callanan   TypeList types;
618c485f056SGreg Clayton   const bool exact_match = true;
619ae088e52SGreg Clayton   llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
6204dbb271fSSean Callanan   if (module_sp && namespace_decl)
621f9568a95SRaphael Isemann     module_sp->FindTypesInNamespace(name, namespace_decl, 1, types);
622c485f056SGreg Clayton   else {
623576495e6SZachary Turner     m_target->GetImages().FindTypes(module_sp.get(), name, exact_match, 1,
624b9c1b51eSKate Stone                                     searched_symbol_files, types);
625c485f056SGreg Clayton   }
6264dbb271fSSean Callanan 
627b9c1b51eSKate Stone   if (size_t num_types = types.GetSize()) {
628b9c1b51eSKate Stone     for (size_t ti = 0; ti < num_types; ++ti) {
6294dbb271fSSean Callanan       lldb::TypeSP type_sp = types.GetTypeAtIndex(ti);
6304dbb271fSSean Callanan 
631b9c1b51eSKate Stone       if (log) {
6324dbb271fSSean Callanan         const char *name_string = type_sp->GetName().GetCString();
6334dbb271fSSean Callanan 
634e98ef0afSRaphael Isemann         LLDB_LOG(log, "  CAS::FEVD Matching type found for \"{0}\": {1}", name,
6354dbb271fSSean Callanan                  (name_string ? name_string : "<anonymous>"));
6364dbb271fSSean Callanan       }
6374dbb271fSSean Callanan 
6384dbb271fSSean Callanan       CompilerType full_type = type_sp->GetFullCompilerType();
6394dbb271fSSean Callanan 
6404dbb271fSSean Callanan       CompilerType copied_clang_type(GuardedCopyType(full_type));
6414dbb271fSSean Callanan 
642b9c1b51eSKate Stone       if (!copied_clang_type) {
643e657a1ebSRaphael Isemann         LLDB_LOG(log, "  CAS::FEVD - Couldn't export a type");
6444dbb271fSSean Callanan 
6454dbb271fSSean Callanan         continue;
6464dbb271fSSean Callanan       }
6474dbb271fSSean Callanan 
6484dbb271fSSean Callanan       context.AddTypeDecl(copied_clang_type);
6494dbb271fSSean Callanan 
6502ad7b6fbSRaphael Isemann       context.m_found_type = true;
6514dbb271fSSean Callanan       break;
6524dbb271fSSean Callanan     }
6534dbb271fSSean Callanan   }
6544dbb271fSSean Callanan 
6552ad7b6fbSRaphael Isemann   if (!context.m_found_type) {
6564dbb271fSSean Callanan     // Try the modules next.
657e657a1ebSRaphael Isemann     FindDeclInModules(context, name);
6584dbb271fSSean Callanan   }
6594dbb271fSSean Callanan 
6602ad7b6fbSRaphael Isemann   if (!context.m_found_type) {
661e657a1ebSRaphael Isemann     FindDeclInObjCRuntime(context, name);
6624dbb271fSSean Callanan   }
6634dbb271fSSean Callanan }
6644dbb271fSSean Callanan 
FillNamespaceMap(NameSearchContext & context,lldb::ModuleSP module_sp,const CompilerDeclContext & namespace_decl)665bdb24faaSRaphael Isemann void ClangASTSource::FillNamespaceMap(
666bdb24faaSRaphael Isemann     NameSearchContext &context, lldb::ModuleSP module_sp,
667bdb24faaSRaphael Isemann     const CompilerDeclContext &namespace_decl) {
668bdb24faaSRaphael Isemann   const ConstString name(context.m_decl_name.getAsString().c_str());
669bdb24faaSRaphael Isemann   if (IgnoreName(name, true))
670bdb24faaSRaphael Isemann     return;
671bdb24faaSRaphael Isemann 
672a007a6d8SPavel Labath   Log *log = GetLog(LLDBLog::Expressions);
673bdb24faaSRaphael Isemann 
674bdb24faaSRaphael Isemann   if (module_sp && namespace_decl) {
675bdb24faaSRaphael Isemann     CompilerDeclContext found_namespace_decl;
676bdb24faaSRaphael Isemann 
677bdb24faaSRaphael Isemann     if (SymbolFile *symbol_file = module_sp->GetSymbolFile()) {
678bdb24faaSRaphael Isemann       found_namespace_decl = symbol_file->FindNamespace(name, namespace_decl);
679bdb24faaSRaphael Isemann 
680bdb24faaSRaphael Isemann       if (found_namespace_decl) {
681bdb24faaSRaphael Isemann         context.m_namespace_map->push_back(
682bdb24faaSRaphael Isemann             std::pair<lldb::ModuleSP, CompilerDeclContext>(
683bdb24faaSRaphael Isemann                 module_sp, found_namespace_decl));
684bdb24faaSRaphael Isemann 
685e98ef0afSRaphael Isemann         LLDB_LOG(log, "  CAS::FEVD Found namespace {0} in module {1}", name,
686bdb24faaSRaphael Isemann                  module_sp->GetFileSpec().GetFilename());
687bdb24faaSRaphael Isemann       }
688bdb24faaSRaphael Isemann     }
689bdb24faaSRaphael Isemann     return;
690bdb24faaSRaphael Isemann   }
691bdb24faaSRaphael Isemann 
692f2e05855SJonas Devlieghere   for (lldb::ModuleSP image : m_target->GetImages().Modules()) {
693bdb24faaSRaphael Isemann     if (!image)
694bdb24faaSRaphael Isemann       continue;
695bdb24faaSRaphael Isemann 
696bdb24faaSRaphael Isemann     CompilerDeclContext found_namespace_decl;
697bdb24faaSRaphael Isemann 
698bdb24faaSRaphael Isemann     SymbolFile *symbol_file = image->GetSymbolFile();
699bdb24faaSRaphael Isemann 
700bdb24faaSRaphael Isemann     if (!symbol_file)
701bdb24faaSRaphael Isemann       continue;
702bdb24faaSRaphael Isemann 
703bdb24faaSRaphael Isemann     found_namespace_decl = symbol_file->FindNamespace(name, namespace_decl);
704bdb24faaSRaphael Isemann 
705bdb24faaSRaphael Isemann     if (found_namespace_decl) {
706bdb24faaSRaphael Isemann       context.m_namespace_map->push_back(
707bdb24faaSRaphael Isemann           std::pair<lldb::ModuleSP, CompilerDeclContext>(image,
708bdb24faaSRaphael Isemann                                                          found_namespace_decl));
709bdb24faaSRaphael Isemann 
710e98ef0afSRaphael Isemann       LLDB_LOG(log, "  CAS::FEVD Found namespace {0} in module {1}", name,
711bdb24faaSRaphael Isemann                image->GetFileSpec().GetFilename());
712bdb24faaSRaphael Isemann     }
713bdb24faaSRaphael Isemann   }
714bdb24faaSRaphael Isemann }
715bdb24faaSRaphael Isemann 
7164dbb271fSSean Callanan template <class D> class TaggedASTDecl {
7174dbb271fSSean Callanan public:
TaggedASTDecl()718248a1305SKonrad Kleine   TaggedASTDecl() : decl(nullptr) {}
TaggedASTDecl(D * _decl)7194dbb271fSSean Callanan   TaggedASTDecl(D *_decl) : decl(_decl) {}
IsValid() const720248a1305SKonrad Kleine   bool IsValid() const { return (decl != nullptr); }
IsInvalid() const7214dbb271fSSean Callanan   bool IsInvalid() const { return !IsValid(); }
operator ->() const7224dbb271fSSean Callanan   D *operator->() const { return decl; }
7234dbb271fSSean Callanan   D *decl;
7244dbb271fSSean Callanan };
7254dbb271fSSean Callanan 
7264dbb271fSSean Callanan template <class D2, template <class D> class TD, class D1>
DynCast(TD<D1> source)727b9c1b51eSKate Stone TD<D2> DynCast(TD<D1> source) {
7284dbb271fSSean Callanan   return TD<D2>(dyn_cast<D2>(source.decl));
7294dbb271fSSean Callanan }
7304dbb271fSSean Callanan 
7314dbb271fSSean Callanan template <class D = Decl> class DeclFromParser;
7324dbb271fSSean Callanan template <class D = Decl> class DeclFromUser;
7334dbb271fSSean Callanan 
7344dbb271fSSean Callanan template <class D> class DeclFromParser : public TaggedASTDecl<D> {
7354dbb271fSSean Callanan public:
DeclFromParser()7364dbb271fSSean Callanan   DeclFromParser() : TaggedASTDecl<D>() {}
DeclFromParser(D * _decl)7374dbb271fSSean Callanan   DeclFromParser(D *_decl) : TaggedASTDecl<D>(_decl) {}
7384dbb271fSSean Callanan 
73968e44239SSean Callanan   DeclFromUser<D> GetOrigin(ClangASTSource &source);
7404dbb271fSSean Callanan };
7414dbb271fSSean Callanan 
7424dbb271fSSean Callanan template <class D> class DeclFromUser : public TaggedASTDecl<D> {
7434dbb271fSSean Callanan public:
DeclFromUser()7444dbb271fSSean Callanan   DeclFromUser() : TaggedASTDecl<D>() {}
DeclFromUser(D * _decl)7454dbb271fSSean Callanan   DeclFromUser(D *_decl) : TaggedASTDecl<D>(_decl) {}
7464dbb271fSSean Callanan 
74768e44239SSean Callanan   DeclFromParser<D> Import(ClangASTSource &source);
7484dbb271fSSean Callanan };
7494dbb271fSSean Callanan 
7504dbb271fSSean Callanan template <class D>
GetOrigin(ClangASTSource & source)75168e44239SSean Callanan DeclFromUser<D> DeclFromParser<D>::GetOrigin(ClangASTSource &source) {
75264678ef9SRaphael Isemann   ClangASTImporter::DeclOrigin origin = source.GetDeclOrigin(this->decl);
75364678ef9SRaphael Isemann   if (!origin.Valid())
7544dbb271fSSean Callanan     return DeclFromUser<D>();
75564678ef9SRaphael Isemann   return DeclFromUser<D>(dyn_cast<D>(origin.decl));
7564dbb271fSSean Callanan }
7574dbb271fSSean Callanan 
7584dbb271fSSean Callanan template <class D>
Import(ClangASTSource & source)75968e44239SSean Callanan DeclFromParser<D> DeclFromUser<D>::Import(ClangASTSource &source) {
76068e44239SSean Callanan   DeclFromParser<> parser_generic_decl(source.CopyDecl(this->decl));
7614dbb271fSSean Callanan   if (parser_generic_decl.IsInvalid())
7624dbb271fSSean Callanan     return DeclFromParser<D>();
7634dbb271fSSean Callanan   return DeclFromParser<D>(dyn_cast<D>(parser_generic_decl.decl));
7644dbb271fSSean Callanan }
7654dbb271fSSean Callanan 
FindObjCMethodDeclsWithOrigin(NameSearchContext & context,ObjCInterfaceDecl * original_interface_decl,const char * log_info)76668e44239SSean Callanan bool ClangASTSource::FindObjCMethodDeclsWithOrigin(
767e657a1ebSRaphael Isemann     NameSearchContext &context, ObjCInterfaceDecl *original_interface_decl,
768e657a1ebSRaphael Isemann     const char *log_info) {
7694dbb271fSSean Callanan   const DeclarationName &decl_name(context.m_decl_name);
7704dbb271fSSean Callanan   clang::ASTContext *original_ctx = &original_interface_decl->getASTContext();
7714dbb271fSSean Callanan 
7724dbb271fSSean Callanan   Selector original_selector;
7734dbb271fSSean Callanan 
774b9c1b51eSKate Stone   if (decl_name.isObjCZeroArgSelector()) {
7754dbb271fSSean Callanan     IdentifierInfo *ident = &original_ctx->Idents.get(decl_name.getAsString());
7764dbb271fSSean Callanan     original_selector = original_ctx->Selectors.getSelector(0, &ident);
777b9c1b51eSKate Stone   } else if (decl_name.isObjCOneArgSelector()) {
7784dbb271fSSean Callanan     const std::string &decl_name_string = decl_name.getAsString();
779b9c1b51eSKate Stone     std::string decl_name_string_without_colon(decl_name_string.c_str(),
780b9c1b51eSKate Stone                                                decl_name_string.length() - 1);
781b9c1b51eSKate Stone     IdentifierInfo *ident =
782771ef6d4SMalcolm Parsons         &original_ctx->Idents.get(decl_name_string_without_colon);
7834dbb271fSSean Callanan     original_selector = original_ctx->Selectors.getSelector(1, &ident);
784b9c1b51eSKate Stone   } else {
7854dbb271fSSean Callanan     SmallVector<IdentifierInfo *, 4> idents;
7864dbb271fSSean Callanan 
7874dbb271fSSean Callanan     clang::Selector sel = decl_name.getObjCSelector();
7884dbb271fSSean Callanan 
7894dbb271fSSean Callanan     unsigned num_args = sel.getNumArgs();
7904dbb271fSSean Callanan 
791b9c1b51eSKate Stone     for (unsigned i = 0; i != num_args; ++i) {
7924dbb271fSSean Callanan       idents.push_back(&original_ctx->Idents.get(sel.getNameForSlot(i)));
7934dbb271fSSean Callanan     }
7944dbb271fSSean Callanan 
795b9c1b51eSKate Stone     original_selector =
796b9c1b51eSKate Stone         original_ctx->Selectors.getSelector(num_args, idents.data());
7974dbb271fSSean Callanan   }
7984dbb271fSSean Callanan 
7994dbb271fSSean Callanan   DeclarationName original_decl_name(original_selector);
8004dbb271fSSean Callanan 
8014dbb271fSSean Callanan   llvm::SmallVector<NamedDecl *, 1> methods;
8024dbb271fSSean Callanan 
8036e3b0cc2SRaphael Isemann   TypeSystemClang::GetCompleteDecl(original_ctx, original_interface_decl);
8044dbb271fSSean Callanan 
805b9c1b51eSKate Stone   if (ObjCMethodDecl *instance_method_decl =
806b9c1b51eSKate Stone           original_interface_decl->lookupInstanceMethod(original_selector)) {
8074dbb271fSSean Callanan     methods.push_back(instance_method_decl);
808b9c1b51eSKate Stone   } else if (ObjCMethodDecl *class_method_decl =
809b9c1b51eSKate Stone                  original_interface_decl->lookupClassMethod(
810b9c1b51eSKate Stone                      original_selector)) {
8114dbb271fSSean Callanan     methods.push_back(class_method_decl);
8124dbb271fSSean Callanan   }
8134dbb271fSSean Callanan 
814b9c1b51eSKate Stone   if (methods.empty()) {
8154dbb271fSSean Callanan     return false;
8164dbb271fSSean Callanan   }
8174dbb271fSSean Callanan 
818b9c1b51eSKate Stone   for (NamedDecl *named_decl : methods) {
8194dbb271fSSean Callanan     if (!named_decl)
8204dbb271fSSean Callanan       continue;
8214dbb271fSSean Callanan 
8224dbb271fSSean Callanan     ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(named_decl);
8234dbb271fSSean Callanan 
8244dbb271fSSean Callanan     if (!result_method)
8254dbb271fSSean Callanan       continue;
8264dbb271fSSean Callanan 
82768e44239SSean Callanan     Decl *copied_decl = CopyDecl(result_method);
8284dbb271fSSean Callanan 
8294dbb271fSSean Callanan     if (!copied_decl)
8304dbb271fSSean Callanan       continue;
8314dbb271fSSean Callanan 
8324dbb271fSSean Callanan     ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
8334dbb271fSSean Callanan 
8344dbb271fSSean Callanan     if (!copied_method_decl)
8354dbb271fSSean Callanan       continue;
8364dbb271fSSean Callanan 
837a007a6d8SPavel Labath     Log *log = GetLog(LLDBLog::Expressions);
8384dbb271fSSean Callanan 
839e98ef0afSRaphael Isemann     LLDB_LOG(log, "  CAS::FOMD found ({0}) {1}", log_info,
8407a6588abSRaphael Isemann              ClangUtil::DumpDecl(copied_method_decl));
8414dbb271fSSean Callanan 
8424dbb271fSSean Callanan     context.AddNamedDecl(copied_method_decl);
8434dbb271fSSean Callanan   }
8444dbb271fSSean Callanan 
8454dbb271fSSean Callanan   return true;
8464dbb271fSSean Callanan }
8474dbb271fSSean Callanan 
FindDeclInModules(NameSearchContext & context,ConstString name)8480e5ed1b2SRaphael Isemann void ClangASTSource::FindDeclInModules(NameSearchContext &context,
849e657a1ebSRaphael Isemann                                        ConstString name) {
850a007a6d8SPavel Labath   Log *log = GetLog(LLDBLog::Expressions);
8510e5ed1b2SRaphael Isemann 
8524c0b0de9SAlex Langford   std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor =
8534c0b0de9SAlex Langford       GetClangModulesDeclVendor();
8540e5ed1b2SRaphael Isemann   if (!modules_decl_vendor)
8550e5ed1b2SRaphael Isemann     return;
8560e5ed1b2SRaphael Isemann 
8570e5ed1b2SRaphael Isemann   bool append = false;
8580e5ed1b2SRaphael Isemann   uint32_t max_matches = 1;
8590e5ed1b2SRaphael Isemann   std::vector<clang::NamedDecl *> decls;
8600e5ed1b2SRaphael Isemann 
8610e5ed1b2SRaphael Isemann   if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls))
8620e5ed1b2SRaphael Isemann     return;
8630e5ed1b2SRaphael Isemann 
864e98ef0afSRaphael Isemann   LLDB_LOG(log, "  CAS::FEVD Matching entity found for \"{0}\" in the modules",
865e657a1ebSRaphael Isemann            name);
8660e5ed1b2SRaphael Isemann 
8670e5ed1b2SRaphael Isemann   clang::NamedDecl *const decl_from_modules = decls[0];
8680e5ed1b2SRaphael Isemann 
8690e5ed1b2SRaphael Isemann   if (llvm::isa<clang::TypeDecl>(decl_from_modules) ||
8700e5ed1b2SRaphael Isemann       llvm::isa<clang::ObjCContainerDecl>(decl_from_modules) ||
8710e5ed1b2SRaphael Isemann       llvm::isa<clang::EnumConstantDecl>(decl_from_modules)) {
8720e5ed1b2SRaphael Isemann     clang::Decl *copied_decl = CopyDecl(decl_from_modules);
8730e5ed1b2SRaphael Isemann     clang::NamedDecl *copied_named_decl =
8740e5ed1b2SRaphael Isemann         copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
8750e5ed1b2SRaphael Isemann 
8760e5ed1b2SRaphael Isemann     if (!copied_named_decl) {
877e657a1ebSRaphael Isemann       LLDB_LOG(log, "  CAS::FEVD - Couldn't export a type from the modules");
8780e5ed1b2SRaphael Isemann 
8790e5ed1b2SRaphael Isemann       return;
8800e5ed1b2SRaphael Isemann     }
8810e5ed1b2SRaphael Isemann 
8820e5ed1b2SRaphael Isemann     context.AddNamedDecl(copied_named_decl);
8830e5ed1b2SRaphael Isemann 
8842ad7b6fbSRaphael Isemann     context.m_found_type = true;
8850e5ed1b2SRaphael Isemann   }
8860e5ed1b2SRaphael Isemann }
8870e5ed1b2SRaphael Isemann 
FindDeclInObjCRuntime(NameSearchContext & context,ConstString name)8880e5ed1b2SRaphael Isemann void ClangASTSource::FindDeclInObjCRuntime(NameSearchContext &context,
889e657a1ebSRaphael Isemann                                            ConstString name) {
890a007a6d8SPavel Labath   Log *log = GetLog(LLDBLog::Expressions);
8910e5ed1b2SRaphael Isemann 
8920e5ed1b2SRaphael Isemann   lldb::ProcessSP process(m_target->GetProcessSP());
8930e5ed1b2SRaphael Isemann 
8940e5ed1b2SRaphael Isemann   if (!process)
8950e5ed1b2SRaphael Isemann     return;
8960e5ed1b2SRaphael Isemann 
8970e5ed1b2SRaphael Isemann   ObjCLanguageRuntime *language_runtime(ObjCLanguageRuntime::Get(*process));
8980e5ed1b2SRaphael Isemann 
8990e5ed1b2SRaphael Isemann   if (!language_runtime)
9000e5ed1b2SRaphael Isemann     return;
9010e5ed1b2SRaphael Isemann 
9020e5ed1b2SRaphael Isemann   DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
9030e5ed1b2SRaphael Isemann 
9040e5ed1b2SRaphael Isemann   if (!decl_vendor)
9050e5ed1b2SRaphael Isemann     return;
9060e5ed1b2SRaphael Isemann 
9070e5ed1b2SRaphael Isemann   bool append = false;
9080e5ed1b2SRaphael Isemann   uint32_t max_matches = 1;
9090e5ed1b2SRaphael Isemann   std::vector<clang::NamedDecl *> decls;
9100e5ed1b2SRaphael Isemann 
9110e5ed1b2SRaphael Isemann   auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor);
9120e5ed1b2SRaphael Isemann   if (!clang_decl_vendor->FindDecls(name, append, max_matches, decls))
9130e5ed1b2SRaphael Isemann     return;
9140e5ed1b2SRaphael Isemann 
915e657a1ebSRaphael Isemann   LLDB_LOG(log, "  CAS::FEVD Matching type found for \"{0}\" in the runtime",
916e657a1ebSRaphael Isemann            name);
9170e5ed1b2SRaphael Isemann 
9180e5ed1b2SRaphael Isemann   clang::Decl *copied_decl = CopyDecl(decls[0]);
9190e5ed1b2SRaphael Isemann   clang::NamedDecl *copied_named_decl =
9200e5ed1b2SRaphael Isemann       copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
9210e5ed1b2SRaphael Isemann 
9220e5ed1b2SRaphael Isemann   if (!copied_named_decl) {
923e657a1ebSRaphael Isemann     LLDB_LOG(log, "  CAS::FEVD - Couldn't export a type from the runtime");
9240e5ed1b2SRaphael Isemann 
9250e5ed1b2SRaphael Isemann     return;
9260e5ed1b2SRaphael Isemann   }
9270e5ed1b2SRaphael Isemann 
9280e5ed1b2SRaphael Isemann   context.AddNamedDecl(copied_named_decl);
9290e5ed1b2SRaphael Isemann }
9300e5ed1b2SRaphael Isemann 
FindObjCMethodDecls(NameSearchContext & context)931b9c1b51eSKate Stone void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
932a007a6d8SPavel Labath   Log *log = GetLog(LLDBLog::Expressions);
9334dbb271fSSean Callanan 
9344dbb271fSSean Callanan   const DeclarationName &decl_name(context.m_decl_name);
9354dbb271fSSean Callanan   const DeclContext *decl_ctx(context.m_decl_context);
9364dbb271fSSean Callanan 
937b9c1b51eSKate Stone   const ObjCInterfaceDecl *interface_decl =
938b9c1b51eSKate Stone       dyn_cast<ObjCInterfaceDecl>(decl_ctx);
9394dbb271fSSean Callanan 
9404dbb271fSSean Callanan   if (!interface_decl)
9414dbb271fSSean Callanan     return;
9424dbb271fSSean Callanan 
943b9c1b51eSKate Stone   do {
94464678ef9SRaphael Isemann     ClangASTImporter::DeclOrigin original = m_ast_importer_sp->GetDeclOrigin(interface_decl);
9454dbb271fSSean Callanan 
94664678ef9SRaphael Isemann     if (!original.Valid())
9474dbb271fSSean Callanan       break;
9484dbb271fSSean Callanan 
949b9c1b51eSKate Stone     ObjCInterfaceDecl *original_interface_decl =
95064678ef9SRaphael Isemann         dyn_cast<ObjCInterfaceDecl>(original.decl);
9514dbb271fSSean Callanan 
952e657a1ebSRaphael Isemann     if (FindObjCMethodDeclsWithOrigin(context, original_interface_decl,
953e657a1ebSRaphael Isemann                                       "at origin"))
9544dbb271fSSean Callanan       return; // found it, no need to look any further
95509ad8c8fSJonas Devlieghere   } while (false);
9564dbb271fSSean Callanan 
9574dbb271fSSean Callanan   StreamString ss;
9584dbb271fSSean Callanan 
959b9c1b51eSKate Stone   if (decl_name.isObjCZeroArgSelector()) {
9604dbb271fSSean Callanan     ss.Printf("%s", decl_name.getAsString().c_str());
961b9c1b51eSKate Stone   } else if (decl_name.isObjCOneArgSelector()) {
9624dbb271fSSean Callanan     ss.Printf("%s", decl_name.getAsString().c_str());
963b9c1b51eSKate Stone   } else {
9644dbb271fSSean Callanan     clang::Selector sel = decl_name.getObjCSelector();
9654dbb271fSSean Callanan 
966b9c1b51eSKate Stone     for (unsigned i = 0, e = sel.getNumArgs(); i != e; ++i) {
9674dbb271fSSean Callanan       llvm::StringRef r = sel.getNameForSlot(i);
9684dbb271fSSean Callanan       ss.Printf("%s:", r.str().c_str());
9694dbb271fSSean Callanan     }
9704dbb271fSSean Callanan   }
9714dbb271fSSean Callanan   ss.Flush();
9724dbb271fSSean Callanan 
973c156427dSZachary Turner   if (ss.GetString().contains("$__lldb"))
9744dbb271fSSean Callanan     return; // we don't need any results
9754dbb271fSSean Callanan 
976c156427dSZachary Turner   ConstString selector_name(ss.GetString());
9774dbb271fSSean Callanan 
9781f7b95d0SRaphael Isemann   LLDB_LOG(log,
979e98ef0afSRaphael Isemann            "ClangASTSource::FindObjCMethodDecls on (ASTContext*){0} '{1}' "
980e98ef0afSRaphael Isemann            "for selector [{2} {3}]",
981e657a1ebSRaphael Isemann            m_ast_context, m_clang_ast_context->getDisplayName(),
982c9a39a89SRaphael Isemann            interface_decl->getName(), selector_name);
9834dbb271fSSean Callanan   SymbolContextList sc_list;
9844dbb271fSSean Callanan 
985c020be17SJonas Devlieghere   ModuleFunctionSearchOptions function_options;
986c020be17SJonas Devlieghere   function_options.include_symbols = false;
987c020be17SJonas Devlieghere   function_options.include_inlines = false;
9884dbb271fSSean Callanan 
9894dbb271fSSean Callanan   std::string interface_name = interface_decl->getNameAsString();
9904dbb271fSSean Callanan 
991b9c1b51eSKate Stone   do {
9924dbb271fSSean Callanan     StreamString ms;
9934dbb271fSSean Callanan     ms.Printf("-[%s %s]", interface_name.c_str(), selector_name.AsCString());
9944dbb271fSSean Callanan     ms.Flush();
995c156427dSZachary Turner     ConstString instance_method_name(ms.GetString());
9964dbb271fSSean Callanan 
9971ad655e2SAdrian Prantl     sc_list.Clear();
998c020be17SJonas Devlieghere     m_target->GetImages().FindFunctions(instance_method_name,
999c020be17SJonas Devlieghere                                         lldb::eFunctionNameTypeFull,
1000c020be17SJonas Devlieghere                                         function_options, sc_list);
10014dbb271fSSean Callanan 
10024dbb271fSSean Callanan     if (sc_list.GetSize())
10034dbb271fSSean Callanan       break;
10044dbb271fSSean Callanan 
10054dbb271fSSean Callanan     ms.Clear();
10064dbb271fSSean Callanan     ms.Printf("+[%s %s]", interface_name.c_str(), selector_name.AsCString());
10074dbb271fSSean Callanan     ms.Flush();
1008c156427dSZachary Turner     ConstString class_method_name(ms.GetString());
10094dbb271fSSean Callanan 
10101ad655e2SAdrian Prantl     sc_list.Clear();
1011c020be17SJonas Devlieghere     m_target->GetImages().FindFunctions(class_method_name,
1012c020be17SJonas Devlieghere                                         lldb::eFunctionNameTypeFull,
1013c020be17SJonas Devlieghere                                         function_options, sc_list);
10144dbb271fSSean Callanan 
10154dbb271fSSean Callanan     if (sc_list.GetSize())
10164dbb271fSSean Callanan       break;
10174dbb271fSSean Callanan 
1018b9c1b51eSKate Stone     // Fall back and check for methods in categories.  If we find methods this
101905097246SAdrian Prantl     // way, we need to check that they're actually in categories on the desired
102005097246SAdrian Prantl     // class.
10214dbb271fSSean Callanan 
10224dbb271fSSean Callanan     SymbolContextList candidate_sc_list;
10234dbb271fSSean Callanan 
1024c020be17SJonas Devlieghere     m_target->GetImages().FindFunctions(selector_name,
1025c020be17SJonas Devlieghere                                         lldb::eFunctionNameTypeSelector,
1026c020be17SJonas Devlieghere                                         function_options, candidate_sc_list);
10274dbb271fSSean Callanan 
1028b9c1b51eSKate Stone     for (uint32_t ci = 0, ce = candidate_sc_list.GetSize(); ci != ce; ++ci) {
10294dbb271fSSean Callanan       SymbolContext candidate_sc;
10304dbb271fSSean Callanan 
10314dbb271fSSean Callanan       if (!candidate_sc_list.GetContextAtIndex(ci, candidate_sc))
10324dbb271fSSean Callanan         continue;
10334dbb271fSSean Callanan 
10344dbb271fSSean Callanan       if (!candidate_sc.function)
10354dbb271fSSean Callanan         continue;
10364dbb271fSSean Callanan 
10374dbb271fSSean Callanan       const char *candidate_name = candidate_sc.function->GetName().AsCString();
10384dbb271fSSean Callanan 
10394dbb271fSSean Callanan       const char *cursor = candidate_name;
10404dbb271fSSean Callanan 
10414dbb271fSSean Callanan       if (*cursor != '+' && *cursor != '-')
10424dbb271fSSean Callanan         continue;
10434dbb271fSSean Callanan 
10444dbb271fSSean Callanan       ++cursor;
10454dbb271fSSean Callanan 
10464dbb271fSSean Callanan       if (*cursor != '[')
10474dbb271fSSean Callanan         continue;
10484dbb271fSSean Callanan 
10494dbb271fSSean Callanan       ++cursor;
10504dbb271fSSean Callanan 
10514dbb271fSSean Callanan       size_t interface_len = interface_name.length();
10524dbb271fSSean Callanan 
10534dbb271fSSean Callanan       if (strncmp(cursor, interface_name.c_str(), interface_len))
10544dbb271fSSean Callanan         continue;
10554dbb271fSSean Callanan 
10564dbb271fSSean Callanan       cursor += interface_len;
10574dbb271fSSean Callanan 
10584dbb271fSSean Callanan       if (*cursor == ' ' || *cursor == '(')
10594dbb271fSSean Callanan         sc_list.Append(candidate_sc);
10604dbb271fSSean Callanan     }
106109ad8c8fSJonas Devlieghere   } while (false);
10624dbb271fSSean Callanan 
1063b9c1b51eSKate Stone   if (sc_list.GetSize()) {
10644dbb271fSSean Callanan     // We found a good function symbol.  Use that.
10654dbb271fSSean Callanan 
1066b9c1b51eSKate Stone     for (uint32_t i = 0, e = sc_list.GetSize(); i != e; ++i) {
10674dbb271fSSean Callanan       SymbolContext sc;
10684dbb271fSSean Callanan 
10694dbb271fSSean Callanan       if (!sc_list.GetContextAtIndex(i, sc))
10704dbb271fSSean Callanan         continue;
10714dbb271fSSean Callanan 
10724dbb271fSSean Callanan       if (!sc.function)
10734dbb271fSSean Callanan         continue;
10744dbb271fSSean Callanan 
10754dbb271fSSean Callanan       CompilerDeclContext function_decl_ctx = sc.function->GetDeclContext();
10764dbb271fSSean Callanan       if (!function_decl_ctx)
10774dbb271fSSean Callanan         continue;
10784dbb271fSSean Callanan 
1079b9c1b51eSKate Stone       ObjCMethodDecl *method_decl =
10806e3b0cc2SRaphael Isemann           TypeSystemClang::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
10814dbb271fSSean Callanan 
10824dbb271fSSean Callanan       if (!method_decl)
10834dbb271fSSean Callanan         continue;
10844dbb271fSSean Callanan 
1085b9c1b51eSKate Stone       ObjCInterfaceDecl *found_interface_decl =
1086b9c1b51eSKate Stone           method_decl->getClassInterface();
10874dbb271fSSean Callanan 
10884dbb271fSSean Callanan       if (!found_interface_decl)
10894dbb271fSSean Callanan         continue;
10904dbb271fSSean Callanan 
1091b9c1b51eSKate Stone       if (found_interface_decl->getName() == interface_decl->getName()) {
109268e44239SSean Callanan         Decl *copied_decl = CopyDecl(method_decl);
10934dbb271fSSean Callanan 
10944dbb271fSSean Callanan         if (!copied_decl)
10954dbb271fSSean Callanan           continue;
10964dbb271fSSean Callanan 
1097b9c1b51eSKate Stone         ObjCMethodDecl *copied_method_decl =
1098b9c1b51eSKate Stone             dyn_cast<ObjCMethodDecl>(copied_decl);
10994dbb271fSSean Callanan 
11004dbb271fSSean Callanan         if (!copied_method_decl)
11014dbb271fSSean Callanan           continue;
11024dbb271fSSean Callanan 
1103e98ef0afSRaphael Isemann         LLDB_LOG(log, "  CAS::FOMD found (in symbols)\n{0}",
11047a6588abSRaphael Isemann                  ClangUtil::DumpDecl(copied_method_decl));
11054dbb271fSSean Callanan 
11064dbb271fSSean Callanan         context.AddNamedDecl(copied_method_decl);
11074dbb271fSSean Callanan       }
11084dbb271fSSean Callanan     }
11094dbb271fSSean Callanan 
11104dbb271fSSean Callanan     return;
11114dbb271fSSean Callanan   }
11124dbb271fSSean Callanan 
11134dbb271fSSean Callanan   // Try the debug information.
11144dbb271fSSean Callanan 
1115b9c1b51eSKate Stone   do {
1116b9c1b51eSKate Stone     ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(
1117b9c1b51eSKate Stone         const_cast<ObjCInterfaceDecl *>(interface_decl));
11184dbb271fSSean Callanan 
11194dbb271fSSean Callanan     if (!complete_interface_decl)
11204dbb271fSSean Callanan       break;
11214dbb271fSSean Callanan 
1122b9c1b51eSKate Stone     // We found the complete interface.  The runtime never needs to be queried
1123b9c1b51eSKate Stone     // in this scenario.
11244dbb271fSSean Callanan 
1125b9c1b51eSKate Stone     DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(
1126b9c1b51eSKate Stone         complete_interface_decl);
11274dbb271fSSean Callanan 
11284dbb271fSSean Callanan     if (complete_interface_decl == interface_decl)
11294dbb271fSSean Callanan       break; // already checked this one
11304dbb271fSSean Callanan 
11311f7b95d0SRaphael Isemann     LLDB_LOG(log,
1132e657a1ebSRaphael Isemann              "CAS::FOPD trying origin "
1133e98ef0afSRaphael Isemann              "(ObjCInterfaceDecl*){0}/(ASTContext*){1}...",
1134e657a1ebSRaphael Isemann              complete_interface_decl, &complete_iface_decl->getASTContext());
11354dbb271fSSean Callanan 
1136e657a1ebSRaphael Isemann     FindObjCMethodDeclsWithOrigin(context, complete_interface_decl,
11374dbb271fSSean Callanan                                   "in debug info");
11384dbb271fSSean Callanan 
11394dbb271fSSean Callanan     return;
114009ad8c8fSJonas Devlieghere   } while (false);
11414dbb271fSSean Callanan 
1142b9c1b51eSKate Stone   do {
1143b9c1b51eSKate Stone     // Check the modules only if the debug information didn't have a complete
1144b9c1b51eSKate Stone     // interface.
11454dbb271fSSean Callanan 
11464c0b0de9SAlex Langford     if (std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor =
11474c0b0de9SAlex Langford             GetClangModulesDeclVendor()) {
11484dbb271fSSean Callanan       ConstString interface_name(interface_decl->getNameAsString().c_str());
11494dbb271fSSean Callanan       bool append = false;
11504dbb271fSSean Callanan       uint32_t max_matches = 1;
11514dbb271fSSean Callanan       std::vector<clang::NamedDecl *> decls;
11524dbb271fSSean Callanan 
1153b9c1b51eSKate Stone       if (!modules_decl_vendor->FindDecls(interface_name, append, max_matches,
11544dbb271fSSean Callanan                                           decls))
11554dbb271fSSean Callanan         break;
11564dbb271fSSean Callanan 
1157b9c1b51eSKate Stone       ObjCInterfaceDecl *interface_decl_from_modules =
1158b9c1b51eSKate Stone           dyn_cast<ObjCInterfaceDecl>(decls[0]);
11594dbb271fSSean Callanan 
11604dbb271fSSean Callanan       if (!interface_decl_from_modules)
11614dbb271fSSean Callanan         break;
11624dbb271fSSean Callanan 
1163e657a1ebSRaphael Isemann       if (FindObjCMethodDeclsWithOrigin(context, interface_decl_from_modules,
1164e657a1ebSRaphael Isemann                                         "in modules"))
11654dbb271fSSean Callanan         return;
11664dbb271fSSean Callanan     }
116709ad8c8fSJonas Devlieghere   } while (false);
11684dbb271fSSean Callanan 
1169b9c1b51eSKate Stone   do {
1170b9c1b51eSKate Stone     // Check the runtime only if the debug information didn't have a complete
1171b9c1b51eSKate Stone     // interface and the modules don't get us anywhere.
11724dbb271fSSean Callanan 
11734dbb271fSSean Callanan     lldb::ProcessSP process(m_target->GetProcessSP());
11744dbb271fSSean Callanan 
11754dbb271fSSean Callanan     if (!process)
11764dbb271fSSean Callanan       break;
11774dbb271fSSean Callanan 
1178e823bbe8SAlex Langford     ObjCLanguageRuntime *language_runtime(ObjCLanguageRuntime::Get(*process));
11794dbb271fSSean Callanan 
11804dbb271fSSean Callanan     if (!language_runtime)
11814dbb271fSSean Callanan       break;
11824dbb271fSSean Callanan 
11834dbb271fSSean Callanan     DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
11844dbb271fSSean Callanan 
11854dbb271fSSean Callanan     if (!decl_vendor)
11864dbb271fSSean Callanan       break;
11874dbb271fSSean Callanan 
11884dbb271fSSean Callanan     ConstString interface_name(interface_decl->getNameAsString().c_str());
11894dbb271fSSean Callanan     bool append = false;
11904dbb271fSSean Callanan     uint32_t max_matches = 1;
11914dbb271fSSean Callanan     std::vector<clang::NamedDecl *> decls;
11924dbb271fSSean Callanan 
1193cb68bd72SAlex Langford     auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor);
1194cb68bd72SAlex Langford     if (!clang_decl_vendor->FindDecls(interface_name, append, max_matches,
1195cb68bd72SAlex Langford                                       decls))
11964dbb271fSSean Callanan       break;
11974dbb271fSSean Callanan 
1198b9c1b51eSKate Stone     ObjCInterfaceDecl *runtime_interface_decl =
1199b9c1b51eSKate Stone         dyn_cast<ObjCInterfaceDecl>(decls[0]);
12004dbb271fSSean Callanan 
12014dbb271fSSean Callanan     if (!runtime_interface_decl)
12024dbb271fSSean Callanan       break;
12034dbb271fSSean Callanan 
1204e657a1ebSRaphael Isemann     FindObjCMethodDeclsWithOrigin(context, runtime_interface_decl,
12054dbb271fSSean Callanan                                   "in runtime");
120609ad8c8fSJonas Devlieghere   } while (false);
12074dbb271fSSean Callanan }
12084dbb271fSSean Callanan 
FindObjCPropertyAndIvarDeclsWithOrigin(NameSearchContext & context,ClangASTSource & source,DeclFromUser<const ObjCInterfaceDecl> & origin_iface_decl)1209b9c1b51eSKate Stone static bool FindObjCPropertyAndIvarDeclsWithOrigin(
1210e657a1ebSRaphael Isemann     NameSearchContext &context, ClangASTSource &source,
1211b9c1b51eSKate Stone     DeclFromUser<const ObjCInterfaceDecl> &origin_iface_decl) {
1212a007a6d8SPavel Labath   Log *log = GetLog(LLDBLog::Expressions);
12134dbb271fSSean Callanan 
12144dbb271fSSean Callanan   if (origin_iface_decl.IsInvalid())
12154dbb271fSSean Callanan     return false;
12164dbb271fSSean Callanan 
12174dbb271fSSean Callanan   std::string name_str = context.m_decl_name.getAsString();
1218771ef6d4SMalcolm Parsons   StringRef name(name_str);
1219b9c1b51eSKate Stone   IdentifierInfo &name_identifier(
1220b9c1b51eSKate Stone       origin_iface_decl->getASTContext().Idents.get(name));
12214dbb271fSSean Callanan 
1222b9c1b51eSKate Stone   DeclFromUser<ObjCPropertyDecl> origin_property_decl(
1223b9c1b51eSKate Stone       origin_iface_decl->FindPropertyDeclaration(
1224b9c1b51eSKate Stone           &name_identifier, ObjCPropertyQueryKind::OBJC_PR_query_instance));
12254dbb271fSSean Callanan 
12264dbb271fSSean Callanan   bool found = false;
12274dbb271fSSean Callanan 
1228b9c1b51eSKate Stone   if (origin_property_decl.IsValid()) {
1229b9c1b51eSKate Stone     DeclFromParser<ObjCPropertyDecl> parser_property_decl(
123068e44239SSean Callanan         origin_property_decl.Import(source));
1231b9c1b51eSKate Stone     if (parser_property_decl.IsValid()) {
1232e98ef0afSRaphael Isemann       LLDB_LOG(log, "  CAS::FOPD found\n{0}",
12337a6588abSRaphael Isemann                ClangUtil::DumpDecl(parser_property_decl.decl));
12344dbb271fSSean Callanan 
12354dbb271fSSean Callanan       context.AddNamedDecl(parser_property_decl.decl);
12364dbb271fSSean Callanan       found = true;
12374dbb271fSSean Callanan     }
12384dbb271fSSean Callanan   }
12394dbb271fSSean Callanan 
1240b9c1b51eSKate Stone   DeclFromUser<ObjCIvarDecl> origin_ivar_decl(
1241b9c1b51eSKate Stone       origin_iface_decl->getIvarDecl(&name_identifier));
12424dbb271fSSean Callanan 
1243b9c1b51eSKate Stone   if (origin_ivar_decl.IsValid()) {
1244b9c1b51eSKate Stone     DeclFromParser<ObjCIvarDecl> parser_ivar_decl(
124568e44239SSean Callanan         origin_ivar_decl.Import(source));
1246b9c1b51eSKate Stone     if (parser_ivar_decl.IsValid()) {
1247e98ef0afSRaphael Isemann       LLDB_LOG(log, "  CAS::FOPD found\n{0}",
12487a6588abSRaphael Isemann                ClangUtil::DumpDecl(parser_ivar_decl.decl));
12494dbb271fSSean Callanan 
12504dbb271fSSean Callanan       context.AddNamedDecl(parser_ivar_decl.decl);
12514dbb271fSSean Callanan       found = true;
12524dbb271fSSean Callanan     }
12534dbb271fSSean Callanan   }
12544dbb271fSSean Callanan 
12554dbb271fSSean Callanan   return found;
12564dbb271fSSean Callanan }
12574dbb271fSSean Callanan 
FindObjCPropertyAndIvarDecls(NameSearchContext & context)1258b9c1b51eSKate Stone void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
1259a007a6d8SPavel Labath   Log *log = GetLog(LLDBLog::Expressions);
12604dbb271fSSean Callanan 
1261b9c1b51eSKate Stone   DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl(
1262b9c1b51eSKate Stone       cast<ObjCInterfaceDecl>(context.m_decl_context));
1263b9c1b51eSKate Stone   DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl(
126468e44239SSean Callanan       parser_iface_decl.GetOrigin(*this));
12654dbb271fSSean Callanan 
12664dbb271fSSean Callanan   ConstString class_name(parser_iface_decl->getNameAsString().c_str());
12674dbb271fSSean Callanan 
12681f7b95d0SRaphael Isemann   LLDB_LOG(log,
1269e657a1ebSRaphael Isemann            "ClangASTSource::FindObjCPropertyAndIvarDecls on "
1270e98ef0afSRaphael Isemann            "(ASTContext*){0} '{1}' for '{2}.{3}'",
1271e657a1ebSRaphael Isemann            m_ast_context, m_clang_ast_context->getDisplayName(),
1272c9a39a89SRaphael Isemann            parser_iface_decl->getName(), context.m_decl_name.getAsString());
12734dbb271fSSean Callanan 
1274e657a1ebSRaphael Isemann   if (FindObjCPropertyAndIvarDeclsWithOrigin(context, *this, origin_iface_decl))
12754dbb271fSSean Callanan     return;
12764dbb271fSSean Callanan 
12771f7b95d0SRaphael Isemann   LLDB_LOG(log,
1278e657a1ebSRaphael Isemann            "CAS::FOPD couldn't find the property on origin "
1279e98ef0afSRaphael Isemann            "(ObjCInterfaceDecl*){0}/(ASTContext*){1}, searching "
1280b9c1b51eSKate Stone            "elsewhere...",
1281e657a1ebSRaphael Isemann            origin_iface_decl.decl, &origin_iface_decl->getASTContext());
12824dbb271fSSean Callanan 
12834dbb271fSSean Callanan   SymbolContext null_sc;
12844dbb271fSSean Callanan   TypeList type_list;
12854dbb271fSSean Callanan 
1286b9c1b51eSKate Stone   do {
1287b9c1b51eSKate Stone     ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(
1288b9c1b51eSKate Stone         const_cast<ObjCInterfaceDecl *>(parser_iface_decl.decl));
12894dbb271fSSean Callanan 
12904dbb271fSSean Callanan     if (!complete_interface_decl)
12914dbb271fSSean Callanan       break;
12924dbb271fSSean Callanan 
1293b9c1b51eSKate Stone     // We found the complete interface.  The runtime never needs to be queried
1294b9c1b51eSKate Stone     // in this scenario.
12954dbb271fSSean Callanan 
1296b9c1b51eSKate Stone     DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(
1297b9c1b51eSKate Stone         complete_interface_decl);
12984dbb271fSSean Callanan 
12994dbb271fSSean Callanan     if (complete_iface_decl.decl == origin_iface_decl.decl)
13004dbb271fSSean Callanan       break; // already checked this one
13014dbb271fSSean Callanan 
13021f7b95d0SRaphael Isemann     LLDB_LOG(log,
1303e657a1ebSRaphael Isemann              "CAS::FOPD trying origin "
1304e98ef0afSRaphael Isemann              "(ObjCInterfaceDecl*){0}/(ASTContext*){1}...",
1305e657a1ebSRaphael Isemann              complete_iface_decl.decl, &complete_iface_decl->getASTContext());
13064dbb271fSSean Callanan 
1307e657a1ebSRaphael Isemann     FindObjCPropertyAndIvarDeclsWithOrigin(context, *this, complete_iface_decl);
13084dbb271fSSean Callanan 
13094dbb271fSSean Callanan     return;
131009ad8c8fSJonas Devlieghere   } while (false);
13114dbb271fSSean Callanan 
1312b9c1b51eSKate Stone   do {
1313b9c1b51eSKate Stone     // Check the modules only if the debug information didn't have a complete
1314b9c1b51eSKate Stone     // interface.
13154dbb271fSSean Callanan 
13164c0b0de9SAlex Langford     std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor =
13174c0b0de9SAlex Langford         GetClangModulesDeclVendor();
13184dbb271fSSean Callanan 
13194dbb271fSSean Callanan     if (!modules_decl_vendor)
13204dbb271fSSean Callanan       break;
13214dbb271fSSean Callanan 
13224dbb271fSSean Callanan     bool append = false;
13234dbb271fSSean Callanan     uint32_t max_matches = 1;
13244dbb271fSSean Callanan     std::vector<clang::NamedDecl *> decls;
13254dbb271fSSean Callanan 
1326b9c1b51eSKate Stone     if (!modules_decl_vendor->FindDecls(class_name, append, max_matches, decls))
13274dbb271fSSean Callanan       break;
13284dbb271fSSean Callanan 
1329b9c1b51eSKate Stone     DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_modules(
1330b9c1b51eSKate Stone         dyn_cast<ObjCInterfaceDecl>(decls[0]));
13314dbb271fSSean Callanan 
13324dbb271fSSean Callanan     if (!interface_decl_from_modules.IsValid())
13334dbb271fSSean Callanan       break;
13344dbb271fSSean Callanan 
13351f7b95d0SRaphael Isemann     LLDB_LOG(log,
13361f7b95d0SRaphael Isemann              "CAS::FOPD[{0}] trying module "
1337e98ef0afSRaphael Isemann              "(ObjCInterfaceDecl*){0}/(ASTContext*){1}...",
1338e657a1ebSRaphael Isemann              interface_decl_from_modules.decl,
13391f7b95d0SRaphael Isemann              &interface_decl_from_modules->getASTContext());
13404dbb271fSSean Callanan 
1341e657a1ebSRaphael Isemann     if (FindObjCPropertyAndIvarDeclsWithOrigin(context, *this,
13424dbb271fSSean Callanan                                                interface_decl_from_modules))
13434dbb271fSSean Callanan       return;
134409ad8c8fSJonas Devlieghere   } while (false);
13454dbb271fSSean Callanan 
1346b9c1b51eSKate Stone   do {
1347b9c1b51eSKate Stone     // Check the runtime only if the debug information didn't have a complete
134805097246SAdrian Prantl     // interface and nothing was in the modules.
13494dbb271fSSean Callanan 
13504dbb271fSSean Callanan     lldb::ProcessSP process(m_target->GetProcessSP());
13514dbb271fSSean Callanan 
13524dbb271fSSean Callanan     if (!process)
13534dbb271fSSean Callanan       return;
13544dbb271fSSean Callanan 
1355e823bbe8SAlex Langford     ObjCLanguageRuntime *language_runtime(ObjCLanguageRuntime::Get(*process));
13564dbb271fSSean Callanan 
13574dbb271fSSean Callanan     if (!language_runtime)
13584dbb271fSSean Callanan       return;
13594dbb271fSSean Callanan 
13604dbb271fSSean Callanan     DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
13614dbb271fSSean Callanan 
13624dbb271fSSean Callanan     if (!decl_vendor)
13634dbb271fSSean Callanan       break;
13644dbb271fSSean Callanan 
13654dbb271fSSean Callanan     bool append = false;
13664dbb271fSSean Callanan     uint32_t max_matches = 1;
13674dbb271fSSean Callanan     std::vector<clang::NamedDecl *> decls;
13684dbb271fSSean Callanan 
1369cb68bd72SAlex Langford     auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor);
1370cb68bd72SAlex Langford     if (!clang_decl_vendor->FindDecls(class_name, append, max_matches, decls))
13714dbb271fSSean Callanan       break;
13724dbb271fSSean Callanan 
1373b9c1b51eSKate Stone     DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_runtime(
1374b9c1b51eSKate Stone         dyn_cast<ObjCInterfaceDecl>(decls[0]));
13754dbb271fSSean Callanan 
13764dbb271fSSean Callanan     if (!interface_decl_from_runtime.IsValid())
13774dbb271fSSean Callanan       break;
13784dbb271fSSean Callanan 
13791f7b95d0SRaphael Isemann     LLDB_LOG(log,
13801f7b95d0SRaphael Isemann              "CAS::FOPD[{0}] trying runtime "
1381e98ef0afSRaphael Isemann              "(ObjCInterfaceDecl*){0}/(ASTContext*){1}...",
1382e657a1ebSRaphael Isemann              interface_decl_from_runtime.decl,
13831f7b95d0SRaphael Isemann              &interface_decl_from_runtime->getASTContext());
13844dbb271fSSean Callanan 
1385e657a1ebSRaphael Isemann     if (FindObjCPropertyAndIvarDeclsWithOrigin(context, *this,
1386e657a1ebSRaphael Isemann                                                interface_decl_from_runtime))
13874dbb271fSSean Callanan       return;
138809ad8c8fSJonas Devlieghere   } while (false);
13894dbb271fSSean Callanan }
13904dbb271fSSean Callanan 
LookupInNamespace(NameSearchContext & context)139105d174d3SRaphael Isemann void ClangASTSource::LookupInNamespace(NameSearchContext &context) {
139205d174d3SRaphael Isemann   const NamespaceDecl *namespace_context =
139305d174d3SRaphael Isemann       dyn_cast<NamespaceDecl>(context.m_decl_context);
139405d174d3SRaphael Isemann 
1395a007a6d8SPavel Labath   Log *log = GetLog(LLDBLog::Expressions);
139605d174d3SRaphael Isemann 
139705d174d3SRaphael Isemann   ClangASTImporter::NamespaceMapSP namespace_map =
139805d174d3SRaphael Isemann       m_ast_importer_sp->GetNamespaceMap(namespace_context);
139905d174d3SRaphael Isemann 
1400e98ef0afSRaphael Isemann   LLDB_LOGV(log, "  CAS::FEVD Inspecting namespace map {0} ({1} entries)",
140105d174d3SRaphael Isemann             namespace_map.get(), namespace_map->size());
140205d174d3SRaphael Isemann 
140305d174d3SRaphael Isemann   if (!namespace_map)
140405d174d3SRaphael Isemann     return;
140505d174d3SRaphael Isemann 
140605d174d3SRaphael Isemann   for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
140705d174d3SRaphael Isemann                                                 e = namespace_map->end();
140805d174d3SRaphael Isemann        i != e; ++i) {
1409e98ef0afSRaphael Isemann     LLDB_LOG(log, "  CAS::FEVD Searching namespace {0} in module {1}",
141005d174d3SRaphael Isemann              i->second.GetName(), i->first->GetFileSpec().GetFilename());
141105d174d3SRaphael Isemann 
141205d174d3SRaphael Isemann     FindExternalVisibleDecls(context, i->first, i->second);
141305d174d3SRaphael Isemann   }
141405d174d3SRaphael Isemann }
141505d174d3SRaphael Isemann 
14164dbb271fSSean Callanan typedef llvm::DenseMap<const FieldDecl *, uint64_t> FieldOffsetMap;
14174dbb271fSSean Callanan typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetMap;
14184dbb271fSSean Callanan 
14194dbb271fSSean Callanan template <class D, class O>
ImportOffsetMap(llvm::DenseMap<const D *,O> & destination_map,llvm::DenseMap<const D *,O> & source_map,ClangASTSource & source)1420b9c1b51eSKate Stone static bool ImportOffsetMap(llvm::DenseMap<const D *, O> &destination_map,
1421b9c1b51eSKate Stone                             llvm::DenseMap<const D *, O> &source_map,
142268e44239SSean Callanan                             ClangASTSource &source) {
14234dbb271fSSean Callanan   // When importing fields into a new record, clang has a hard requirement that
1424b9c1b51eSKate Stone   // fields be imported in field offset order.  Since they are stored in a
142505097246SAdrian Prantl   // DenseMap with a pointer as the key type, this means we cannot simply
142605097246SAdrian Prantl   // iterate over the map, as the order will be non-deterministic.  Instead we
142705097246SAdrian Prantl   // have to sort by the offset and then insert in sorted order.
14284dbb271fSSean Callanan   typedef llvm::DenseMap<const D *, O> MapType;
14294dbb271fSSean Callanan   typedef typename MapType::value_type PairType;
14304dbb271fSSean Callanan   std::vector<PairType> sorted_items;
14314dbb271fSSean Callanan   sorted_items.reserve(source_map.size());
14324dbb271fSSean Callanan   sorted_items.assign(source_map.begin(), source_map.end());
1433acf648b5SKazu Hirata   llvm::sort(sorted_items, llvm::less_second());
14344dbb271fSSean Callanan 
1435b9c1b51eSKate Stone   for (const auto &item : sorted_items) {
14364dbb271fSSean Callanan     DeclFromUser<D> user_decl(const_cast<D *>(item.first));
143768e44239SSean Callanan     DeclFromParser<D> parser_decl(user_decl.Import(source));
14384dbb271fSSean Callanan     if (parser_decl.IsInvalid())
14394dbb271fSSean Callanan       return false;
1440b9c1b51eSKate Stone     destination_map.insert(
1441b9c1b51eSKate Stone         std::pair<const D *, O>(parser_decl.decl, item.second));
14424dbb271fSSean Callanan   }
14434dbb271fSSean Callanan 
14444dbb271fSSean Callanan   return true;
14454dbb271fSSean Callanan }
14464dbb271fSSean Callanan 
14474dbb271fSSean Callanan template <bool IsVirtual>
ExtractBaseOffsets(const ASTRecordLayout & record_layout,DeclFromUser<const CXXRecordDecl> & record,BaseOffsetMap & base_offsets)1448b9c1b51eSKate Stone bool ExtractBaseOffsets(const ASTRecordLayout &record_layout,
1449b9c1b51eSKate Stone                         DeclFromUser<const CXXRecordDecl> &record,
1450b9c1b51eSKate Stone                         BaseOffsetMap &base_offsets) {
1451b9c1b51eSKate Stone   for (CXXRecordDecl::base_class_const_iterator
1452b9c1b51eSKate Stone            bi = (IsVirtual ? record->vbases_begin() : record->bases_begin()),
14534dbb271fSSean Callanan            be = (IsVirtual ? record->vbases_end() : record->bases_end());
1454b9c1b51eSKate Stone        bi != be; ++bi) {
14554dbb271fSSean Callanan     if (!IsVirtual && bi->isVirtual())
14564dbb271fSSean Callanan       continue;
14574dbb271fSSean Callanan 
14584dbb271fSSean Callanan     const clang::Type *origin_base_type = bi->getType().getTypePtr();
1459b9c1b51eSKate Stone     const clang::RecordType *origin_base_record_type =
1460b9c1b51eSKate Stone         origin_base_type->getAs<RecordType>();
14614dbb271fSSean Callanan 
14624dbb271fSSean Callanan     if (!origin_base_record_type)
14634dbb271fSSean Callanan       return false;
14644dbb271fSSean Callanan 
1465b9c1b51eSKate Stone     DeclFromUser<RecordDecl> origin_base_record(
1466b9c1b51eSKate Stone         origin_base_record_type->getDecl());
14674dbb271fSSean Callanan 
14684dbb271fSSean Callanan     if (origin_base_record.IsInvalid())
14694dbb271fSSean Callanan       return false;
14704dbb271fSSean Callanan 
1471b9c1b51eSKate Stone     DeclFromUser<CXXRecordDecl> origin_base_cxx_record(
1472b9c1b51eSKate Stone         DynCast<CXXRecordDecl>(origin_base_record));
14734dbb271fSSean Callanan 
14744dbb271fSSean Callanan     if (origin_base_cxx_record.IsInvalid())
14754dbb271fSSean Callanan       return false;
14764dbb271fSSean Callanan 
14774dbb271fSSean Callanan     CharUnits base_offset;
14784dbb271fSSean Callanan 
14794dbb271fSSean Callanan     if (IsVirtual)
1480b9c1b51eSKate Stone       base_offset =
1481b9c1b51eSKate Stone           record_layout.getVBaseClassOffset(origin_base_cxx_record.decl);
14824dbb271fSSean Callanan     else
1483b9c1b51eSKate Stone       base_offset =
1484b9c1b51eSKate Stone           record_layout.getBaseClassOffset(origin_base_cxx_record.decl);
14854dbb271fSSean Callanan 
1486b9c1b51eSKate Stone     base_offsets.insert(std::pair<const CXXRecordDecl *, CharUnits>(
1487b9c1b51eSKate Stone         origin_base_cxx_record.decl, base_offset));
14884dbb271fSSean Callanan   }
14894dbb271fSSean Callanan 
14904dbb271fSSean Callanan   return true;
14914dbb271fSSean Callanan }
14924dbb271fSSean Callanan 
layoutRecordType(const RecordDecl * record,uint64_t & size,uint64_t & alignment,FieldOffsetMap & field_offsets,BaseOffsetMap & base_offsets,BaseOffsetMap & virtual_base_offsets)1493b9c1b51eSKate Stone bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
1494b9c1b51eSKate Stone                                       uint64_t &alignment,
1495b9c1b51eSKate Stone                                       FieldOffsetMap &field_offsets,
1496b9c1b51eSKate Stone                                       BaseOffsetMap &base_offsets,
1497b9c1b51eSKate Stone                                       BaseOffsetMap &virtual_base_offsets) {
14984dbb271fSSean Callanan 
1499a007a6d8SPavel Labath   Log *log = GetLog(LLDBLog::Expressions);
15004dbb271fSSean Callanan 
15011f7b95d0SRaphael Isemann   LLDB_LOG(log,
1502e98ef0afSRaphael Isemann            "LayoutRecordType on (ASTContext*){0} '{1}' for (RecordDecl*)"
15030479afb3SShafik Yaghmour            "{2} [name = '{3}']",
1504e657a1ebSRaphael Isemann            m_ast_context, m_clang_ast_context->getDisplayName(), record,
1505e657a1ebSRaphael Isemann            record->getName());
15064dbb271fSSean Callanan 
15074dbb271fSSean Callanan   DeclFromParser<const RecordDecl> parser_record(record);
1508b9c1b51eSKate Stone   DeclFromUser<const RecordDecl> origin_record(
150968e44239SSean Callanan       parser_record.GetOrigin(*this));
15104dbb271fSSean Callanan 
15114dbb271fSSean Callanan   if (origin_record.IsInvalid())
15124dbb271fSSean Callanan     return false;
15134dbb271fSSean Callanan 
15144dbb271fSSean Callanan   FieldOffsetMap origin_field_offsets;
15154dbb271fSSean Callanan   BaseOffsetMap origin_base_offsets;
15164dbb271fSSean Callanan   BaseOffsetMap origin_virtual_base_offsets;
15174dbb271fSSean Callanan 
15186e3b0cc2SRaphael Isemann   TypeSystemClang::GetCompleteDecl(
1519b9c1b51eSKate Stone       &origin_record->getASTContext(),
1520b9c1b51eSKate Stone       const_cast<RecordDecl *>(origin_record.decl));
15214dbb271fSSean Callanan 
15224dbb271fSSean Callanan   clang::RecordDecl *definition = origin_record.decl->getDefinition();
15234dbb271fSSean Callanan   if (!definition || !definition->isCompleteDefinition())
15244dbb271fSSean Callanan     return false;
15254dbb271fSSean Callanan 
1526b9c1b51eSKate Stone   const ASTRecordLayout &record_layout(
1527b9c1b51eSKate Stone       origin_record->getASTContext().getASTRecordLayout(origin_record.decl));
15284dbb271fSSean Callanan 
15294dbb271fSSean Callanan   int field_idx = 0, field_count = record_layout.getFieldCount();
15304dbb271fSSean Callanan 
1531b9c1b51eSKate Stone   for (RecordDecl::field_iterator fi = origin_record->field_begin(),
1532b9c1b51eSKate Stone                                   fe = origin_record->field_end();
1533b9c1b51eSKate Stone        fi != fe; ++fi) {
15344dbb271fSSean Callanan     if (field_idx >= field_count)
15354dbb271fSSean Callanan       return false; // Layout didn't go well.  Bail out.
15364dbb271fSSean Callanan 
15374dbb271fSSean Callanan     uint64_t field_offset = record_layout.getFieldOffset(field_idx);
15384dbb271fSSean Callanan 
1539b9c1b51eSKate Stone     origin_field_offsets.insert(
1540b9c1b51eSKate Stone         std::pair<const FieldDecl *, uint64_t>(*fi, field_offset));
15414dbb271fSSean Callanan 
15424dbb271fSSean Callanan     field_idx++;
15434dbb271fSSean Callanan   }
15444dbb271fSSean Callanan 
154568e44239SSean Callanan   lldbassert(&record->getASTContext() == m_ast_context);
15464dbb271fSSean Callanan 
1547b9c1b51eSKate Stone   DeclFromUser<const CXXRecordDecl> origin_cxx_record(
1548b9c1b51eSKate Stone       DynCast<const CXXRecordDecl>(origin_record));
15494dbb271fSSean Callanan 
1550b9c1b51eSKate Stone   if (origin_cxx_record.IsValid()) {
1551b9c1b51eSKate Stone     if (!ExtractBaseOffsets<false>(record_layout, origin_cxx_record,
1552b9c1b51eSKate Stone                                    origin_base_offsets) ||
1553b9c1b51eSKate Stone         !ExtractBaseOffsets<true>(record_layout, origin_cxx_record,
1554b9c1b51eSKate Stone                                   origin_virtual_base_offsets))
15554dbb271fSSean Callanan       return false;
15564dbb271fSSean Callanan   }
15574dbb271fSSean Callanan 
155868e44239SSean Callanan   if (!ImportOffsetMap(field_offsets, origin_field_offsets, *this) ||
155968e44239SSean Callanan       !ImportOffsetMap(base_offsets, origin_base_offsets, *this) ||
1560b9c1b51eSKate Stone       !ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets,
156168e44239SSean Callanan                        *this))
15624dbb271fSSean Callanan     return false;
15634dbb271fSSean Callanan 
15644dbb271fSSean Callanan   size = record_layout.getSize().getQuantity() * m_ast_context->getCharWidth();
1565b9c1b51eSKate Stone   alignment = record_layout.getAlignment().getQuantity() *
1566b9c1b51eSKate Stone               m_ast_context->getCharWidth();
15674dbb271fSSean Callanan 
1568b9c1b51eSKate Stone   if (log) {
1569e657a1ebSRaphael Isemann     LLDB_LOG(log, "LRT returned:");
15709f175998SShafik Yaghmour     LLDB_LOG(log, "LRT   Original = (RecordDecl*){0}",
15714dbb271fSSean Callanan              static_cast<const void *>(origin_record.decl));
15729f175998SShafik Yaghmour     LLDB_LOG(log, "LRT   Size = {0}", size);
15739f175998SShafik Yaghmour     LLDB_LOG(log, "LRT   Alignment = {0}", alignment);
1574e657a1ebSRaphael Isemann     LLDB_LOG(log, "LRT   Fields:");
1575b9c1b51eSKate Stone     for (RecordDecl::field_iterator fi = record->field_begin(),
1576b9c1b51eSKate Stone                                     fe = record->field_end();
1577b9c1b51eSKate Stone          fi != fe; ++fi) {
15781f7b95d0SRaphael Isemann       LLDB_LOG(log,
15792a4a498aSShafik Yaghmour                "LRT     (FieldDecl*){0}, Name = '{1}', Type = '{2}', Offset = "
15802a4a498aSShafik Yaghmour                "{3} bits",
15812a4a498aSShafik Yaghmour                *fi, fi->getName(), fi->getType().getAsString(),
15822a4a498aSShafik Yaghmour                field_offsets[*fi]);
15834dbb271fSSean Callanan     }
1584b9c1b51eSKate Stone     DeclFromParser<const CXXRecordDecl> parser_cxx_record =
1585b9c1b51eSKate Stone         DynCast<const CXXRecordDecl>(parser_record);
1586b9c1b51eSKate Stone     if (parser_cxx_record.IsValid()) {
1587e657a1ebSRaphael Isemann       LLDB_LOG(log, "LRT   Bases:");
1588b9c1b51eSKate Stone       for (CXXRecordDecl::base_class_const_iterator
1589b9c1b51eSKate Stone                bi = parser_cxx_record->bases_begin(),
1590b9c1b51eSKate Stone                be = parser_cxx_record->bases_end();
1591b9c1b51eSKate Stone            bi != be; ++bi) {
15924dbb271fSSean Callanan         bool is_virtual = bi->isVirtual();
15934dbb271fSSean Callanan 
15944dbb271fSSean Callanan         QualType base_type = bi->getType();
15954dbb271fSSean Callanan         const RecordType *base_record_type = base_type->getAs<RecordType>();
15964dbb271fSSean Callanan         DeclFromParser<RecordDecl> base_record(base_record_type->getDecl());
1597b9c1b51eSKate Stone         DeclFromParser<CXXRecordDecl> base_cxx_record =
1598b9c1b51eSKate Stone             DynCast<CXXRecordDecl>(base_record);
15994dbb271fSSean Callanan 
16001f7b95d0SRaphael Isemann         LLDB_LOG(log,
1601e98ef0afSRaphael Isemann                  "LRT     {0}(CXXRecordDecl*){1}, Name = '{2}', Offset = "
1602e98ef0afSRaphael Isemann                  "{3} chars",
1603e657a1ebSRaphael Isemann                  (is_virtual ? "Virtual " : ""), base_cxx_record.decl,
1604e657a1ebSRaphael Isemann                  base_cxx_record.decl->getName(),
1605b9c1b51eSKate Stone                  (is_virtual
1606b9c1b51eSKate Stone                       ? virtual_base_offsets[base_cxx_record.decl].getQuantity()
16074dbb271fSSean Callanan                       : base_offsets[base_cxx_record.decl].getQuantity()));
16084dbb271fSSean Callanan       }
1609b9c1b51eSKate Stone     } else {
1610e657a1ebSRaphael Isemann       LLDB_LOG(log, "LRD   Not a CXXRecord, so no bases");
16114dbb271fSSean Callanan     }
16124dbb271fSSean Callanan   }
16134dbb271fSSean Callanan 
16144dbb271fSSean Callanan   return true;
16154dbb271fSSean Callanan }
16164dbb271fSSean Callanan 
CompleteNamespaceMap(ClangASTImporter::NamespaceMapSP & namespace_map,ConstString name,ClangASTImporter::NamespaceMapSP & parent_map) const1617b9c1b51eSKate Stone void ClangASTSource::CompleteNamespaceMap(
16180e4c4821SAdrian Prantl     ClangASTImporter::NamespaceMapSP &namespace_map, ConstString name,
1619b9c1b51eSKate Stone     ClangASTImporter::NamespaceMapSP &parent_map) const {
16204dbb271fSSean Callanan 
1621a007a6d8SPavel Labath   Log *log = GetLog(LLDBLog::Expressions);
16224dbb271fSSean Callanan 
1623b9c1b51eSKate Stone   if (log) {
16244dbb271fSSean Callanan     if (parent_map && parent_map->size())
16251f7b95d0SRaphael Isemann       LLDB_LOG(log,
1626e98ef0afSRaphael Isemann                "CompleteNamespaceMap on (ASTContext*){0} '{1}' Searching "
1627e98ef0afSRaphael Isemann                "for namespace {2} in namespace {3}",
1628e657a1ebSRaphael Isemann                m_ast_context, m_clang_ast_context->getDisplayName(), name,
1629e657a1ebSRaphael Isemann                parent_map->begin()->second.GetName());
16304dbb271fSSean Callanan     else
16311f7b95d0SRaphael Isemann       LLDB_LOG(log,
1632e98ef0afSRaphael Isemann                "CompleteNamespaceMap on (ASTContext*){0} '{1}' Searching "
1633e98ef0afSRaphael Isemann                "for namespace {2}",
1634e657a1ebSRaphael Isemann                m_ast_context, m_clang_ast_context->getDisplayName(), name);
16354dbb271fSSean Callanan   }
16364dbb271fSSean Callanan 
1637b9c1b51eSKate Stone   if (parent_map) {
1638b9c1b51eSKate Stone     for (ClangASTImporter::NamespaceMap::iterator i = parent_map->begin(),
1639b9c1b51eSKate Stone                                                   e = parent_map->end();
1640b9c1b51eSKate Stone          i != e; ++i) {
16414dbb271fSSean Callanan       CompilerDeclContext found_namespace_decl;
16424dbb271fSSean Callanan 
16434dbb271fSSean Callanan       lldb::ModuleSP module_sp = i->first;
16444dbb271fSSean Callanan       CompilerDeclContext module_parent_namespace_decl = i->second;
16454dbb271fSSean Callanan 
1646465eae36SPavel Labath       SymbolFile *symbol_file = module_sp->GetSymbolFile();
16474dbb271fSSean Callanan 
1648465eae36SPavel Labath       if (!symbol_file)
16494dbb271fSSean Callanan         continue;
16504dbb271fSSean Callanan 
1651c0a246afSZachary Turner       found_namespace_decl =
1652f9568a95SRaphael Isemann           symbol_file->FindNamespace(name, module_parent_namespace_decl);
16534dbb271fSSean Callanan 
16544dbb271fSSean Callanan       if (!found_namespace_decl)
16554dbb271fSSean Callanan         continue;
16564dbb271fSSean Callanan 
1657b9c1b51eSKate Stone       namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(
1658b9c1b51eSKate Stone           module_sp, found_namespace_decl));
16594dbb271fSSean Callanan 
1660e98ef0afSRaphael Isemann       LLDB_LOG(log, "  CMN Found namespace {0} in module {1}", name,
1661e657a1ebSRaphael Isemann                module_sp->GetFileSpec().GetFilename());
16624dbb271fSSean Callanan     }
1663b9c1b51eSKate Stone   } else {
16644dbb271fSSean Callanan     CompilerDeclContext null_namespace_decl;
1665f2e05855SJonas Devlieghere     for (lldb::ModuleSP image : m_target->GetImages().Modules()) {
16664dbb271fSSean Callanan       if (!image)
16674dbb271fSSean Callanan         continue;
16684dbb271fSSean Callanan 
16694dbb271fSSean Callanan       CompilerDeclContext found_namespace_decl;
16704dbb271fSSean Callanan 
1671465eae36SPavel Labath       SymbolFile *symbol_file = image->GetSymbolFile();
16724dbb271fSSean Callanan 
1673465eae36SPavel Labath       if (!symbol_file)
16744dbb271fSSean Callanan         continue;
16754dbb271fSSean Callanan 
1676b9c1b51eSKate Stone       found_namespace_decl =
1677f9568a95SRaphael Isemann           symbol_file->FindNamespace(name, null_namespace_decl);
16784dbb271fSSean Callanan 
16794dbb271fSSean Callanan       if (!found_namespace_decl)
16804dbb271fSSean Callanan         continue;
16814dbb271fSSean Callanan 
1682b9c1b51eSKate Stone       namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(
1683b9c1b51eSKate Stone           image, found_namespace_decl));
16844dbb271fSSean Callanan 
1685e98ef0afSRaphael Isemann       LLDB_LOG(log, "  CMN[{0}] Found namespace {0} in module {1}", name,
1686e657a1ebSRaphael Isemann                image->GetFileSpec().GetFilename());
16874dbb271fSSean Callanan     }
16884dbb271fSSean Callanan   }
16894dbb271fSSean Callanan }
16904dbb271fSSean Callanan 
AddNamespace(NameSearchContext & context,ClangASTImporter::NamespaceMapSP & namespace_decls)1691b9c1b51eSKate Stone NamespaceDecl *ClangASTSource::AddNamespace(
1692b9c1b51eSKate Stone     NameSearchContext &context,
1693b9c1b51eSKate Stone     ClangASTImporter::NamespaceMapSP &namespace_decls) {
16944dbb271fSSean Callanan   if (!namespace_decls)
16954dbb271fSSean Callanan     return nullptr;
16964dbb271fSSean Callanan 
16974dbb271fSSean Callanan   const CompilerDeclContext &namespace_decl = namespace_decls->begin()->second;
16984dbb271fSSean Callanan 
1699b9c1b51eSKate Stone   clang::ASTContext *src_ast =
17006e3b0cc2SRaphael Isemann       TypeSystemClang::DeclContextGetTypeSystemClang(namespace_decl);
17014dbb271fSSean Callanan   if (!src_ast)
17024dbb271fSSean Callanan     return nullptr;
1703b9c1b51eSKate Stone   clang::NamespaceDecl *src_namespace_decl =
17046e3b0cc2SRaphael Isemann       TypeSystemClang::DeclContextGetAsNamespaceDecl(namespace_decl);
17054dbb271fSSean Callanan 
17064dbb271fSSean Callanan   if (!src_namespace_decl)
17074dbb271fSSean Callanan     return nullptr;
17084dbb271fSSean Callanan 
170968e44239SSean Callanan   Decl *copied_decl = CopyDecl(src_namespace_decl);
17104dbb271fSSean Callanan 
17114dbb271fSSean Callanan   if (!copied_decl)
17124dbb271fSSean Callanan     return nullptr;
17134dbb271fSSean Callanan 
17144dbb271fSSean Callanan   NamespaceDecl *copied_namespace_decl = dyn_cast<NamespaceDecl>(copied_decl);
17154dbb271fSSean Callanan 
17164dbb271fSSean Callanan   if (!copied_namespace_decl)
17174dbb271fSSean Callanan     return nullptr;
17184dbb271fSSean Callanan 
17194dbb271fSSean Callanan   context.m_decls.push_back(copied_namespace_decl);
17204dbb271fSSean Callanan 
1721b9c1b51eSKate Stone   m_ast_importer_sp->RegisterNamespaceMap(copied_namespace_decl,
1722b9c1b51eSKate Stone                                           namespace_decls);
17234dbb271fSSean Callanan 
17244dbb271fSSean Callanan   return dyn_cast<NamespaceDecl>(copied_decl);
17254dbb271fSSean Callanan }
17264dbb271fSSean Callanan 
CopyDecl(Decl * src_decl)172768e44239SSean Callanan clang::Decl *ClangASTSource::CopyDecl(Decl *src_decl) {
17286be76f49SRaphael Isemann   return m_ast_importer_sp->CopyDecl(m_ast_context, src_decl);
172968e44239SSean Callanan }
173068e44239SSean Callanan 
GetDeclOrigin(const clang::Decl * decl)173164678ef9SRaphael Isemann ClangASTImporter::DeclOrigin ClangASTSource::GetDeclOrigin(const clang::Decl *decl) {
173264678ef9SRaphael Isemann   return m_ast_importer_sp->GetDeclOrigin(decl);
173368e44239SSean Callanan }
173468e44239SSean Callanan 
GuardedCopyType(const CompilerType & src_type)1735b9c1b51eSKate Stone CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) {
17366e3b0cc2SRaphael Isemann   TypeSystemClang *src_ast =
17376e3b0cc2SRaphael Isemann       llvm::dyn_cast_or_null<TypeSystemClang>(src_type.GetTypeSystem());
17384dbb271fSSean Callanan   if (src_ast == nullptr)
17394dbb271fSSean Callanan     return CompilerType();
17404dbb271fSSean Callanan 
17411ccc7029SRaphael Isemann   QualType copied_qual_type = ClangUtil::GetQualType(
174275e8a91cSRaphael Isemann       m_ast_importer_sp->CopyType(*m_clang_ast_context, src_type));
17434dbb271fSSean Callanan 
1744b9c1b51eSKate Stone   if (copied_qual_type.getAsOpaquePtr() &&
1745b9c1b51eSKate Stone       copied_qual_type->getCanonicalTypeInternal().isNull())
174605097246SAdrian Prantl     // this shouldn't happen, but we're hardening because the AST importer
174705097246SAdrian Prantl     // seems to be generating bad types on occasion.
17484dbb271fSSean Callanan     return CompilerType();
17494dbb271fSSean Callanan 
1750fe8e25a4SRaphael Isemann   return m_clang_ast_context->GetType(copied_qual_type);
17514dbb271fSSean Callanan }
17524c0b0de9SAlex Langford 
17534c0b0de9SAlex Langford std::shared_ptr<ClangModulesDeclVendor>
GetClangModulesDeclVendor()17544c0b0de9SAlex Langford ClangASTSource::GetClangModulesDeclVendor() {
17554c0b0de9SAlex Langford   auto persistent_vars = llvm::cast<ClangPersistentVariables>(
17564c0b0de9SAlex Langford       m_target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC));
17574c0b0de9SAlex Langford   return persistent_vars->GetClangModulesDeclVendor();
17584c0b0de9SAlex Langford }
1759