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