summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/ExpressionParser
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/ExpressionParser')
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp50
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h15
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp2
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h7
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp2
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h9
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp1212
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h328
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.cpp35
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.h110
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp1154
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h166
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp7
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h12
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h6
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp400
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h115
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h13
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp357
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h18
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp142
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h38
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp2
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h19
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp88
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h66
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp8
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h7
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp10
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangHost.h4
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp65
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h7
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp26
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h28
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp155
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h12
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.cpp87
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.h50
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp16
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h7
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp2
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h6
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp289
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.h65
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp8
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.h6
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp47
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h11
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h4
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp179
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.h124
51 files changed, 3969 insertions, 1627 deletions
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
index 77bb9544ea40..39ba5f4e9e4f 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
@@ -1,4 +1,4 @@
-//===-- ASTResultSynthesizer.cpp --------------------------------*- C++ -*-===//
+//===-- ASTResultSynthesizer.cpp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,10 +8,10 @@
#include "ASTResultSynthesizer.h"
+#include "ClangASTImporter.h"
#include "ClangPersistentVariables.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangASTImporter.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
@@ -248,48 +248,37 @@ bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body,
// For Lvalues
//
// - In AST result synthesis (here!) the expression E is transformed into an
- // initialization
- // T *$__lldb_expr_result_ptr = &E.
+ // initialization T *$__lldb_expr_result_ptr = &E.
//
// - In structure allocation, a pointer-sized slot is allocated in the
- // struct that is to be
- // passed into the expression.
+ // struct that is to be passed into the expression.
//
// - In IR transformations, reads and writes to $__lldb_expr_result_ptr are
- // redirected at
- // an entry in the struct ($__lldb_arg) passed into the expression.
- // (Other persistent
- // variables are treated similarly, having been materialized as
- // references, but in those
- // cases the value of the reference itself is never modified.)
+ // redirected at an entry in the struct ($__lldb_arg) passed into the
+ // expression. (Other persistent variables are treated similarly, having
+ // been materialized as references, but in those cases the value of the
+ // reference itself is never modified.)
//
// - During materialization, $0 (the result persistent variable) is ignored.
//
// - During dematerialization, $0 is marked up as a load address with value
- // equal to the
- // contents of the structure entry.
+ // equal to the contents of the structure entry.
//
// For Rvalues
//
// - In AST result synthesis the expression E is transformed into an
- // initialization
- // static T $__lldb_expr_result = E.
+ // initialization static T $__lldb_expr_result = E.
//
// - In structure allocation, a pointer-sized slot is allocated in the
- // struct that is to be
- // passed into the expression.
+ // struct that is to be passed into the expression.
//
// - In IR transformations, an instruction is inserted at the beginning of
- // the function to
- // dereference the pointer resident in the slot. Reads and writes to
- // $__lldb_expr_result
- // are redirected at that dereferenced version. Guard variables for the
- // static variable
- // are excised.
+ // the function to dereference the pointer resident in the slot. Reads and
+ // writes to $__lldb_expr_result are redirected at that dereferenced
+ // version. Guard variables for the static variable are excised.
//
// - During materialization, $0 (the result persistent variable) is
- // populated with the location
- // of a newly-allocated area of memory.
+ // populated with the location of a newly-allocated area of memory.
//
// - During dematerialization, $0 is ignored.
@@ -325,7 +314,8 @@ bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body,
else
result_ptr_id = &Ctx.Idents.get("$__lldb_expr_result_ptr");
- m_sema->RequireCompleteType(SourceLocation(), expr_qual_type,
+ m_sema->RequireCompleteType(last_expr->getSourceRange().getBegin(),
+ expr_qual_type,
clang::diag::err_incomplete_type);
QualType ptr_qual_type;
@@ -453,13 +443,13 @@ void ASTResultSynthesizer::CommitPersistentDecls() {
return;
auto *persistent_vars = llvm::cast<ClangPersistentVariables>(state);
- ClangASTContext *scratch_ctx = ClangASTContext::GetScratch(m_target);
+ TypeSystemClang *scratch_ctx = TypeSystemClang::GetScratch(m_target);
for (clang::NamedDecl *decl : m_decls) {
StringRef name = decl->getName();
ConstString name_cs(name.str().c_str());
- Decl *D_scratch = m_target.GetClangASTImporter()->DeportDecl(
+ Decl *D_scratch = persistent_vars->GetClangASTImporter()->DeportDecl(
&scratch_ctx->getASTContext(), decl);
if (!D_scratch) {
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h
index 0b0f3b97705d..9de823bc75a7 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.h
@@ -6,13 +6,20 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ASTResultSynthesizer_h_
-#define liblldb_ASTResultSynthesizer_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTRESULTSYNTHESIZER_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTRESULTSYNTHESIZER_H
-#include "lldb/Core/ClangForward.h"
#include "lldb/Target/Target.h"
#include "clang/Sema/SemaConsumer.h"
+namespace clang {
+class CompoundStmt;
+class DeclContext;
+class NamedDecl;
+class ObjCMethodDecl;
+class TypeDecl;
+} // namespace clang
+
namespace lldb_private {
/// \class ASTResultSynthesizer ASTResultSynthesizer.h
@@ -163,4 +170,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_ASTResultSynthesizer_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTRESULTSYNTHESIZER_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp
index a164d48ae3e0..40f0de40da52 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp
@@ -1,4 +1,4 @@
-//===-- ASTStructExtractor.cpp ----------------------------------*- C++ -*-===//
+//===-- ASTStructExtractor.cpp --------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h b/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h
index 078cf095975f..c285f6408895 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.h
@@ -6,13 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ASTStructExtractor_h_
-#define liblldb_ASTStructExtractor_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTSTRUCTEXTRACTOR_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTSTRUCTEXTRACTOR_H
#include "ClangExpressionVariable.h"
#include "ClangFunctionCaller.h"
-#include "lldb/Core/ClangForward.h"
#include "clang/Sema/SemaConsumer.h"
namespace lldb_private {
@@ -129,4 +128,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_ASTStructExtractor_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTSTRUCTEXTRACTOR_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp
index bbdf4e31c5a4..1e438ed9d73e 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp
@@ -1,4 +1,4 @@
-//===-- ASTUtils.cpp --------------------------------------------*- C++ -*-===//
+//===-- ASTUtils.cpp ------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h
index d429e8c3855f..3787c572d45b 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h
@@ -6,9 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ASTUtils_h_
-#define liblldb_ASTUtils_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTUTILS_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTUTILS_H
+#include "clang/Basic/Module.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/MultiplexExternalSemaSource.h"
#include "clang/Sema/Sema.h"
@@ -71,7 +72,7 @@ public:
return m_Source->getModule(ID);
}
- llvm::Optional<ASTSourceDescriptor>
+ llvm::Optional<clang::ASTSourceDescriptor>
getSourceDescriptor(unsigned ID) override {
return m_Source->getSourceDescriptor(ID);
}
@@ -576,4 +577,4 @@ public:
};
} // namespace lldb_private
-#endif // liblldb_ASTUtils_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTUTILS_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
new file mode 100644
index 000000000000..ac16738933ac
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
@@ -0,0 +1,1212 @@
+//===-- ClangASTImporter.cpp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Core/Module.h"
+#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/Log.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Sema.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
+#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
+#include "Plugins/ExpressionParser/Clang/ClangASTSource.h"
+#include "Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+
+#include <memory>
+
+using namespace lldb_private;
+using namespace clang;
+
+CompilerType ClangASTImporter::CopyType(TypeSystemClang &dst_ast,
+ const CompilerType &src_type) {
+ clang::ASTContext &dst_clang_ast = dst_ast.getASTContext();
+
+ TypeSystemClang *src_ast =
+ llvm::dyn_cast_or_null<TypeSystemClang>(src_type.GetTypeSystem());
+ if (!src_ast)
+ return CompilerType();
+
+ clang::ASTContext &src_clang_ast = src_ast->getASTContext();
+
+ clang::QualType src_qual_type = ClangUtil::GetQualType(src_type);
+
+ ImporterDelegateSP delegate_sp(GetDelegate(&dst_clang_ast, &src_clang_ast));
+ if (!delegate_sp)
+ return CompilerType();
+
+ ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, &dst_clang_ast);
+
+ llvm::Expected<QualType> ret_or_error = delegate_sp->Import(src_qual_type);
+ if (!ret_or_error) {
+ Log *log =
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+ LLDB_LOG_ERROR(log, ret_or_error.takeError(),
+ "Couldn't import type: {0}");
+ return CompilerType();
+ }
+
+ lldb::opaque_compiler_type_t dst_clang_type = ret_or_error->getAsOpaquePtr();
+
+ if (dst_clang_type)
+ return CompilerType(&dst_ast, dst_clang_type);
+ return CompilerType();
+}
+
+clang::Decl *ClangASTImporter::CopyDecl(clang::ASTContext *dst_ast,
+ clang::Decl *decl) {
+ ImporterDelegateSP delegate_sp;
+
+ clang::ASTContext *src_ast = &decl->getASTContext();
+ delegate_sp = GetDelegate(dst_ast, src_ast);
+
+ ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, dst_ast);
+
+ if (!delegate_sp)
+ return nullptr;
+
+ llvm::Expected<clang::Decl *> result = delegate_sp->Import(decl);
+ if (!result) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+ LLDB_LOG_ERROR(log, result.takeError(), "Couldn't import decl: {0}");
+ if (log) {
+ lldb::user_id_t user_id = LLDB_INVALID_UID;
+ ClangASTMetadata *metadata = GetDeclMetadata(decl);
+ if (metadata)
+ user_id = metadata->GetUserID();
+
+ if (NamedDecl *named_decl = dyn_cast<NamedDecl>(decl))
+ LLDB_LOG(log,
+ " [ClangASTImporter] WARNING: Failed to import a {0} "
+ "'{1}', metadata {2}",
+ decl->getDeclKindName(), named_decl->getNameAsString(),
+ user_id);
+ else
+ LLDB_LOG(log,
+ " [ClangASTImporter] WARNING: Failed to import a {0}, "
+ "metadata {1}",
+ decl->getDeclKindName(), user_id);
+ }
+ return nullptr;
+ }
+
+ return *result;
+}
+
+class DeclContextOverride {
+private:
+ struct Backup {
+ clang::DeclContext *decl_context;
+ clang::DeclContext *lexical_decl_context;
+ };
+
+ llvm::DenseMap<clang::Decl *, Backup> m_backups;
+
+ void OverrideOne(clang::Decl *decl) {
+ if (m_backups.find(decl) != m_backups.end()) {
+ return;
+ }
+
+ m_backups[decl] = {decl->getDeclContext(), decl->getLexicalDeclContext()};
+
+ decl->setDeclContext(decl->getASTContext().getTranslationUnitDecl());
+ decl->setLexicalDeclContext(decl->getASTContext().getTranslationUnitDecl());
+ }
+
+ bool ChainPassesThrough(
+ clang::Decl *decl, clang::DeclContext *base,
+ clang::DeclContext *(clang::Decl::*contextFromDecl)(),
+ clang::DeclContext *(clang::DeclContext::*contextFromContext)()) {
+ for (DeclContext *decl_ctx = (decl->*contextFromDecl)(); decl_ctx;
+ decl_ctx = (decl_ctx->*contextFromContext)()) {
+ if (decl_ctx == base) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ clang::Decl *GetEscapedChild(clang::Decl *decl,
+ clang::DeclContext *base = nullptr) {
+ if (base) {
+ // decl's DeclContext chains must pass through base.
+
+ if (!ChainPassesThrough(decl, base, &clang::Decl::getDeclContext,
+ &clang::DeclContext::getParent) ||
+ !ChainPassesThrough(decl, base, &clang::Decl::getLexicalDeclContext,
+ &clang::DeclContext::getLexicalParent)) {
+ return decl;
+ }
+ } else {
+ base = clang::dyn_cast<clang::DeclContext>(decl);
+
+ if (!base) {
+ return nullptr;
+ }
+ }
+
+ if (clang::DeclContext *context =
+ clang::dyn_cast<clang::DeclContext>(decl)) {
+ for (clang::Decl *decl : context->decls()) {
+ if (clang::Decl *escaped_child = GetEscapedChild(decl)) {
+ return escaped_child;
+ }
+ }
+ }
+
+ return nullptr;
+ }
+
+ void Override(clang::Decl *decl) {
+ if (clang::Decl *escaped_child = GetEscapedChild(decl)) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ LLDB_LOG(log,
+ " [ClangASTImporter] DeclContextOverride couldn't "
+ "override ({0}Decl*){1} - its child ({2}Decl*){3} escapes",
+ decl->getDeclKindName(), decl, escaped_child->getDeclKindName(),
+ escaped_child);
+ lldbassert(0 && "Couldn't override!");
+ }
+
+ OverrideOne(decl);
+ }
+
+public:
+ DeclContextOverride() {}
+
+ void OverrideAllDeclsFromContainingFunction(clang::Decl *decl) {
+ for (DeclContext *decl_context = decl->getLexicalDeclContext();
+ decl_context; decl_context = decl_context->getLexicalParent()) {
+ DeclContext *redecl_context = decl_context->getRedeclContext();
+
+ if (llvm::isa<FunctionDecl>(redecl_context) &&
+ llvm::isa<TranslationUnitDecl>(redecl_context->getLexicalParent())) {
+ for (clang::Decl *child_decl : decl_context->decls()) {
+ Override(child_decl);
+ }
+ }
+ }
+ }
+
+ ~DeclContextOverride() {
+ for (const std::pair<clang::Decl *, Backup> &backup : m_backups) {
+ backup.first->setDeclContext(backup.second.decl_context);
+ backup.first->setLexicalDeclContext(backup.second.lexical_decl_context);
+ }
+ }
+};
+
+namespace {
+/// Completes all imported TagDecls at the end of the scope.
+///
+/// While in a CompleteTagDeclsScope, every decl that could be completed will
+/// be completed at the end of the scope (including all Decls that are
+/// imported while completing the original Decls).
+class CompleteTagDeclsScope : public ClangASTImporter::NewDeclListener {
+ ClangASTImporter::ImporterDelegateSP m_delegate;
+ llvm::SmallVector<NamedDecl *, 32> m_decls_to_complete;
+ llvm::SmallPtrSet<NamedDecl *, 32> m_decls_already_completed;
+ clang::ASTContext *m_dst_ctx;
+ clang::ASTContext *m_src_ctx;
+ ClangASTImporter &importer;
+
+public:
+ /// Constructs a CompleteTagDeclsScope.
+ /// \param importer The ClangASTImporter that we should observe.
+ /// \param dst_ctx The ASTContext to which Decls are imported.
+ /// \param src_ctx The ASTContext from which Decls are imported.
+ explicit CompleteTagDeclsScope(ClangASTImporter &importer,
+ clang::ASTContext *dst_ctx,
+ clang::ASTContext *src_ctx)
+ : m_delegate(importer.GetDelegate(dst_ctx, src_ctx)), m_dst_ctx(dst_ctx),
+ m_src_ctx(src_ctx), importer(importer) {
+ m_delegate->SetImportListener(this);
+ }
+
+ virtual ~CompleteTagDeclsScope() {
+ ClangASTImporter::ASTContextMetadataSP to_context_md =
+ importer.GetContextMetadata(m_dst_ctx);
+
+ // Complete all decls we collected until now.
+ while (!m_decls_to_complete.empty()) {
+ NamedDecl *decl = m_decls_to_complete.pop_back_val();
+ m_decls_already_completed.insert(decl);
+
+ // We should only complete decls coming from the source context.
+ assert(to_context_md->m_origins[decl].ctx == m_src_ctx);
+
+ Decl *original_decl = to_context_md->m_origins[decl].decl;
+
+ // Complete the decl now.
+ TypeSystemClang::GetCompleteDecl(m_src_ctx, original_decl);
+ if (auto *tag_decl = dyn_cast<TagDecl>(decl)) {
+ if (auto *original_tag_decl = dyn_cast<TagDecl>(original_decl)) {
+ if (original_tag_decl->isCompleteDefinition()) {
+ m_delegate->ImportDefinitionTo(tag_decl, original_tag_decl);
+ tag_decl->setCompleteDefinition(true);
+ }
+ }
+
+ tag_decl->setHasExternalLexicalStorage(false);
+ tag_decl->setHasExternalVisibleStorage(false);
+ } else if (auto *container_decl = dyn_cast<ObjCContainerDecl>(decl)) {
+ container_decl->setHasExternalLexicalStorage(false);
+ container_decl->setHasExternalVisibleStorage(false);
+ }
+
+ to_context_md->m_origins.erase(decl);
+ }
+
+ // Stop listening to imported decls. We do this after clearing the
+ // Decls we needed to import to catch all Decls they might have pulled in.
+ m_delegate->RemoveImportListener();
+ }
+
+ void NewDeclImported(clang::Decl *from, clang::Decl *to) override {
+ // Filter out decls that we can't complete later.
+ if (!isa<TagDecl>(to) && !isa<ObjCInterfaceDecl>(to))
+ return;
+ RecordDecl *from_record_decl = dyn_cast<RecordDecl>(from);
+ // We don't need to complete injected class name decls.
+ if (from_record_decl && from_record_decl->isInjectedClassName())
+ return;
+
+ NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to);
+ // Check if we already completed this type.
+ if (m_decls_already_completed.count(to_named_decl) != 0)
+ return;
+ m_decls_to_complete.push_back(to_named_decl);
+ }
+};
+} // namespace
+
+CompilerType ClangASTImporter::DeportType(TypeSystemClang &dst,
+ const CompilerType &src_type) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ TypeSystemClang *src_ctxt =
+ llvm::cast<TypeSystemClang>(src_type.GetTypeSystem());
+
+ LLDB_LOG(log,
+ " [ClangASTImporter] DeportType called on ({0}Type*){1} "
+ "from (ASTContext*){2} to (ASTContext*){3}",
+ src_type.GetTypeName(), src_type.GetOpaqueQualType(),
+ &src_ctxt->getASTContext(), &dst.getASTContext());
+
+ DeclContextOverride decl_context_override;
+
+ if (auto *t = ClangUtil::GetQualType(src_type)->getAs<TagType>())
+ decl_context_override.OverrideAllDeclsFromContainingFunction(t->getDecl());
+
+ CompleteTagDeclsScope complete_scope(*this, &dst.getASTContext(),
+ &src_ctxt->getASTContext());
+ return CopyType(dst, src_type);
+}
+
+clang::Decl *ClangASTImporter::DeportDecl(clang::ASTContext *dst_ctx,
+ clang::Decl *decl) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ clang::ASTContext *src_ctx = &decl->getASTContext();
+ LLDB_LOG(log,
+ " [ClangASTImporter] DeportDecl called on ({0}Decl*){1} from "
+ "(ASTContext*){2} to (ASTContext*){3}",
+ decl->getDeclKindName(), decl, src_ctx, dst_ctx);
+
+ DeclContextOverride decl_context_override;
+
+ decl_context_override.OverrideAllDeclsFromContainingFunction(decl);
+
+ clang::Decl *result;
+ {
+ CompleteTagDeclsScope complete_scope(*this, dst_ctx, src_ctx);
+ result = CopyDecl(dst_ctx, decl);
+ }
+
+ if (!result)
+ return nullptr;
+
+ LLDB_LOG(log,
+ " [ClangASTImporter] DeportDecl deported ({0}Decl*){1} to "
+ "({2}Decl*){3}",
+ decl->getDeclKindName(), decl, result->getDeclKindName(), result);
+
+ return result;
+}
+
+bool ClangASTImporter::CanImport(const CompilerType &type) {
+ if (!ClangUtil::IsClangType(type))
+ return false;
+
+ // TODO: remove external completion BOOL
+ // CompleteAndFetchChildren should get the Decl out and check for the
+
+ clang::QualType qual_type(
+ ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record: {
+ const clang::CXXRecordDecl *cxx_record_decl =
+ qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl) {
+ if (GetDeclOrigin(cxx_record_decl).Valid())
+ return true;
+ }
+ } break;
+
+ case clang::Type::Enum: {
+ clang::EnumDecl *enum_decl =
+ llvm::cast<clang::EnumType>(qual_type)->getDecl();
+ if (enum_decl) {
+ if (GetDeclOrigin(enum_decl).Valid())
+ return true;
+ }
+ } break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface: {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+ // We currently can't complete objective C types through the newly added
+ // ASTContext because it only supports TagDecl objects right now...
+ if (class_interface_decl) {
+ if (GetDeclOrigin(class_interface_decl).Valid())
+ return true;
+ }
+ }
+ } break;
+
+ case clang::Type::Typedef:
+ return CanImport(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr()));
+
+ case clang::Type::Auto:
+ return CanImport(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr()));
+
+ case clang::Type::Elaborated:
+ return CanImport(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr()));
+
+ case clang::Type::Paren:
+ return CanImport(CompilerType(
+ type.GetTypeSystem(),
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool ClangASTImporter::Import(const CompilerType &type) {
+ if (!ClangUtil::IsClangType(type))
+ return false;
+ // TODO: remove external completion BOOL
+ // CompleteAndFetchChildren should get the Decl out and check for the
+
+ clang::QualType qual_type(
+ ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record: {
+ const clang::CXXRecordDecl *cxx_record_decl =
+ qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl) {
+ if (GetDeclOrigin(cxx_record_decl).Valid())
+ return CompleteAndFetchChildren(qual_type);
+ }
+ } break;
+
+ case clang::Type::Enum: {
+ clang::EnumDecl *enum_decl =
+ llvm::cast<clang::EnumType>(qual_type)->getDecl();
+ if (enum_decl) {
+ if (GetDeclOrigin(enum_decl).Valid())
+ return CompleteAndFetchChildren(qual_type);
+ }
+ } break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface: {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+ // We currently can't complete objective C types through the newly added
+ // ASTContext because it only supports TagDecl objects right now...
+ if (class_interface_decl) {
+ if (GetDeclOrigin(class_interface_decl).Valid())
+ return CompleteAndFetchChildren(qual_type);
+ }
+ }
+ } break;
+
+ case clang::Type::Typedef:
+ return Import(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr()));
+
+ case clang::Type::Auto:
+ return Import(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr()));
+
+ case clang::Type::Elaborated:
+ return Import(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr()));
+
+ case clang::Type::Paren:
+ return Import(CompilerType(
+ type.GetTypeSystem(),
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
+
+ default:
+ break;
+ }
+ return false;
+}
+
+bool ClangASTImporter::CompleteType(const CompilerType &compiler_type) {
+ if (!CanImport(compiler_type))
+ return false;
+
+ if (Import(compiler_type)) {
+ TypeSystemClang::CompleteTagDeclarationDefinition(compiler_type);
+ return true;
+ }
+
+ TypeSystemClang::SetHasExternalStorage(compiler_type.GetOpaqueQualType(),
+ false);
+ return false;
+}
+
+bool ClangASTImporter::LayoutRecordType(
+ const clang::RecordDecl *record_decl, uint64_t &bit_size,
+ uint64_t &alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &base_offsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &vbase_offsets) {
+ RecordDeclToLayoutMap::iterator pos =
+ m_record_decl_to_layout_map.find(record_decl);
+ bool success = false;
+ base_offsets.clear();
+ vbase_offsets.clear();
+ if (pos != m_record_decl_to_layout_map.end()) {
+ bit_size = pos->second.bit_size;
+ alignment = pos->second.alignment;
+ field_offsets.swap(pos->second.field_offsets);
+ base_offsets.swap(pos->second.base_offsets);
+ vbase_offsets.swap(pos->second.vbase_offsets);
+ m_record_decl_to_layout_map.erase(pos);
+ success = true;
+ } else {
+ bit_size = 0;
+ alignment = 0;
+ field_offsets.clear();
+ }
+ return success;
+}
+
+void ClangASTImporter::SetRecordLayout(clang::RecordDecl *decl,
+ const LayoutInfo &layout) {
+ m_record_decl_to_layout_map.insert(std::make_pair(decl, layout));
+}
+
+bool ClangASTImporter::CompleteTagDecl(clang::TagDecl *decl) {
+ DeclOrigin decl_origin = GetDeclOrigin(decl);
+
+ if (!decl_origin.Valid())
+ return false;
+
+ if (!TypeSystemClang::GetCompleteDecl(decl_origin.ctx, decl_origin.decl))
+ return false;
+
+ ImporterDelegateSP delegate_sp(
+ GetDelegate(&decl->getASTContext(), decl_origin.ctx));
+
+ ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp,
+ &decl->getASTContext());
+ if (delegate_sp)
+ delegate_sp->ImportDefinitionTo(decl, decl_origin.decl);
+
+ return true;
+}
+
+bool ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl,
+ clang::TagDecl *origin_decl) {
+ clang::ASTContext *origin_ast_ctx = &origin_decl->getASTContext();
+
+ if (!TypeSystemClang::GetCompleteDecl(origin_ast_ctx, origin_decl))
+ return false;
+
+ ImporterDelegateSP delegate_sp(
+ GetDelegate(&decl->getASTContext(), origin_ast_ctx));
+
+ if (delegate_sp)
+ delegate_sp->ImportDefinitionTo(decl, origin_decl);
+
+ ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
+
+ OriginMap &origins = context_md->m_origins;
+
+ origins[decl] = DeclOrigin(origin_ast_ctx, origin_decl);
+
+ return true;
+}
+
+bool ClangASTImporter::CompleteObjCInterfaceDecl(
+ clang::ObjCInterfaceDecl *interface_decl) {
+ DeclOrigin decl_origin = GetDeclOrigin(interface_decl);
+
+ if (!decl_origin.Valid())
+ return false;
+
+ if (!TypeSystemClang::GetCompleteDecl(decl_origin.ctx, decl_origin.decl))
+ return false;
+
+ ImporterDelegateSP delegate_sp(
+ GetDelegate(&interface_decl->getASTContext(), decl_origin.ctx));
+
+ if (delegate_sp)
+ delegate_sp->ImportDefinitionTo(interface_decl, decl_origin.decl);
+
+ if (ObjCInterfaceDecl *super_class = interface_decl->getSuperClass())
+ RequireCompleteType(clang::QualType(super_class->getTypeForDecl(), 0));
+
+ return true;
+}
+
+bool ClangASTImporter::CompleteAndFetchChildren(clang::QualType type) {
+ if (!RequireCompleteType(type))
+ return false;
+
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+
+ if (const TagType *tag_type = type->getAs<TagType>()) {
+ TagDecl *tag_decl = tag_type->getDecl();
+
+ DeclOrigin decl_origin = GetDeclOrigin(tag_decl);
+
+ if (!decl_origin.Valid())
+ return false;
+
+ ImporterDelegateSP delegate_sp(
+ GetDelegate(&tag_decl->getASTContext(), decl_origin.ctx));
+
+ ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp,
+ &tag_decl->getASTContext());
+
+ TagDecl *origin_tag_decl = llvm::dyn_cast<TagDecl>(decl_origin.decl);
+
+ for (Decl *origin_child_decl : origin_tag_decl->decls()) {
+ llvm::Expected<Decl *> imported_or_err =
+ delegate_sp->Import(origin_child_decl);
+ if (!imported_or_err) {
+ LLDB_LOG_ERROR(log, imported_or_err.takeError(),
+ "Couldn't import decl: {0}");
+ return false;
+ }
+ }
+
+ if (RecordDecl *record_decl = dyn_cast<RecordDecl>(origin_tag_decl))
+ record_decl->setHasLoadedFieldsFromExternalStorage(true);
+
+ return true;
+ }
+
+ if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) {
+ if (ObjCInterfaceDecl *objc_interface_decl =
+ objc_object_type->getInterface()) {
+ DeclOrigin decl_origin = GetDeclOrigin(objc_interface_decl);
+
+ if (!decl_origin.Valid())
+ return false;
+
+ ImporterDelegateSP delegate_sp(
+ GetDelegate(&objc_interface_decl->getASTContext(), decl_origin.ctx));
+
+ ObjCInterfaceDecl *origin_interface_decl =
+ llvm::dyn_cast<ObjCInterfaceDecl>(decl_origin.decl);
+
+ for (Decl *origin_child_decl : origin_interface_decl->decls()) {
+ llvm::Expected<Decl *> imported_or_err =
+ delegate_sp->Import(origin_child_decl);
+ if (!imported_or_err) {
+ LLDB_LOG_ERROR(log, imported_or_err.takeError(),
+ "Couldn't import decl: {0}");
+ return false;
+ }
+ }
+
+ return true;
+ }
+ return false;
+ }
+
+ return true;
+}
+
+bool ClangASTImporter::RequireCompleteType(clang::QualType type) {
+ if (type.isNull())
+ return false;
+
+ if (const TagType *tag_type = type->getAs<TagType>()) {
+ TagDecl *tag_decl = tag_type->getDecl();
+
+ if (tag_decl->getDefinition() || tag_decl->isBeingDefined())
+ return true;
+
+ return CompleteTagDecl(tag_decl);
+ }
+ if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) {
+ if (ObjCInterfaceDecl *objc_interface_decl =
+ objc_object_type->getInterface())
+ return CompleteObjCInterfaceDecl(objc_interface_decl);
+ return false;
+ }
+ if (const ArrayType *array_type = type->getAsArrayTypeUnsafe())
+ return RequireCompleteType(array_type->getElementType());
+ if (const AtomicType *atomic_type = type->getAs<AtomicType>())
+ return RequireCompleteType(atomic_type->getPointeeType());
+
+ return true;
+}
+
+ClangASTMetadata *ClangASTImporter::GetDeclMetadata(const clang::Decl *decl) {
+ DeclOrigin decl_origin = GetDeclOrigin(decl);
+
+ if (decl_origin.Valid()) {
+ TypeSystemClang *ast = TypeSystemClang::GetASTContext(decl_origin.ctx);
+ return ast->GetMetadata(decl_origin.decl);
+ }
+ TypeSystemClang *ast = TypeSystemClang::GetASTContext(&decl->getASTContext());
+ return ast->GetMetadata(decl);
+}
+
+ClangASTImporter::DeclOrigin
+ClangASTImporter::GetDeclOrigin(const clang::Decl *decl) {
+ ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
+
+ OriginMap &origins = context_md->m_origins;
+
+ OriginMap::iterator iter = origins.find(decl);
+
+ if (iter != origins.end())
+ return iter->second;
+ return DeclOrigin();
+}
+
+void ClangASTImporter::SetDeclOrigin(const clang::Decl *decl,
+ clang::Decl *original_decl) {
+ ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
+
+ OriginMap &origins = context_md->m_origins;
+
+ OriginMap::iterator iter = origins.find(decl);
+
+ if (iter != origins.end()) {
+ iter->second.decl = original_decl;
+ iter->second.ctx = &original_decl->getASTContext();
+ return;
+ }
+ origins[decl] = DeclOrigin(&original_decl->getASTContext(), original_decl);
+}
+
+void ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl,
+ NamespaceMapSP &namespace_map) {
+ ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
+
+ context_md->m_namespace_maps[decl] = namespace_map;
+}
+
+ClangASTImporter::NamespaceMapSP
+ClangASTImporter::GetNamespaceMap(const clang::NamespaceDecl *decl) {
+ ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
+
+ NamespaceMetaMap &namespace_maps = context_md->m_namespace_maps;
+
+ NamespaceMetaMap::iterator iter = namespace_maps.find(decl);
+
+ if (iter != namespace_maps.end())
+ return iter->second;
+ return NamespaceMapSP();
+}
+
+void ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl) {
+ assert(decl);
+ ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
+
+ const DeclContext *parent_context = decl->getDeclContext();
+ const NamespaceDecl *parent_namespace =
+ dyn_cast<NamespaceDecl>(parent_context);
+ NamespaceMapSP parent_map;
+
+ if (parent_namespace)
+ parent_map = GetNamespaceMap(parent_namespace);
+
+ NamespaceMapSP new_map;
+
+ new_map = std::make_shared<NamespaceMap>();
+
+ if (context_md->m_map_completer) {
+ std::string namespace_string = decl->getDeclName().getAsString();
+
+ context_md->m_map_completer->CompleteNamespaceMap(
+ new_map, ConstString(namespace_string.c_str()), parent_map);
+ }
+
+ context_md->m_namespace_maps[decl] = new_map;
+}
+
+void ClangASTImporter::ForgetDestination(clang::ASTContext *dst_ast) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ LLDB_LOG(log,
+ " [ClangASTImporter] Forgetting destination (ASTContext*){0}",
+ dst_ast);
+
+ m_metadata_map.erase(dst_ast);
+}
+
+void ClangASTImporter::ForgetSource(clang::ASTContext *dst_ast,
+ clang::ASTContext *src_ast) {
+ ASTContextMetadataSP md = MaybeGetContextMetadata(dst_ast);
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ LLDB_LOG(log,
+ " [ClangASTImporter] Forgetting source->dest "
+ "(ASTContext*){0}->(ASTContext*){1}",
+ src_ast, dst_ast);
+
+ if (!md)
+ return;
+
+ md->m_delegates.erase(src_ast);
+
+ for (OriginMap::iterator iter = md->m_origins.begin();
+ iter != md->m_origins.end();) {
+ if (iter->second.ctx == src_ast)
+ md->m_origins.erase(iter++);
+ else
+ ++iter;
+ }
+}
+
+ClangASTImporter::MapCompleter::~MapCompleter() { return; }
+
+llvm::Expected<Decl *>
+ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) {
+ if (m_std_handler) {
+ llvm::Optional<Decl *> D = m_std_handler->Import(From);
+ if (D) {
+ // Make sure we don't use this decl later to map it back to it's original
+ // decl. The decl the CxxModuleHandler created has nothing to do with
+ // the one from debug info, and linking those two would just cause the
+ // ASTImporter to try 'updating' the module decl with the minimal one from
+ // the debug info.
+ m_decls_to_ignore.insert(*D);
+ return *D;
+ }
+ }
+
+ // Check which ASTContext this declaration originally came from.
+ DeclOrigin origin = m_master.GetDeclOrigin(From);
+ // If it originally came from the target ASTContext then we can just
+ // pretend that the original is the one we imported. This can happen for
+ // example when inspecting a persistent declaration from the scratch
+ // ASTContext (which will provide the declaration when parsing the
+ // expression and then we later try to copy the declaration back to the
+ // scratch ASTContext to store the result).
+ // Without this check we would ask the ASTImporter to import a declaration
+ // into the same ASTContext where it came from (which doesn't make a lot of
+ // sense).
+ if (origin.Valid() && origin.ctx == &getToContext()) {
+ RegisterImportedDecl(From, origin.decl);
+ return origin.decl;
+ }
+
+ // This declaration came originally from another ASTContext. Instead of
+ // copying our potentially incomplete 'From' Decl we instead go to the
+ // original ASTContext and copy the original to the target. This is not
+ // only faster than first completing our current decl and then copying it
+ // to the target, but it also prevents that indirectly copying the same
+ // declaration to the same target requires the ASTImporter to merge all
+ // the different decls that appear to come from different ASTContexts (even
+ // though all these different source ASTContexts just got a copy from
+ // one source AST).
+ if (origin.Valid()) {
+ auto R = m_master.CopyDecl(&getToContext(), origin.decl);
+ if (R) {
+ RegisterImportedDecl(From, R);
+ return R;
+ }
+ }
+
+ // If we have a forcefully completed type, try to find an actual definition
+ // for it in other modules.
+ const ClangASTMetadata *md = m_master.GetDeclMetadata(From);
+ auto *td = dyn_cast<TagDecl>(From);
+ if (td && md && md->IsForcefullyCompleted()) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+ LLDB_LOG(log,
+ "[ClangASTImporter] Searching for a complete definition of {0} in "
+ "other modules",
+ td->getName());
+ Expected<DeclContext *> dc_or_err = ImportContext(td->getDeclContext());
+ if (!dc_or_err)
+ return dc_or_err.takeError();
+ Expected<DeclarationName> dn_or_err = Import(td->getDeclName());
+ if (!dn_or_err)
+ return dn_or_err.takeError();
+ DeclContext *dc = *dc_or_err;
+ DeclContext::lookup_result lr = dc->lookup(*dn_or_err);
+ if (lr.size()) {
+ clang::Decl *lookup_found = lr.front();
+ RegisterImportedDecl(From, lookup_found);
+ m_decls_to_ignore.insert(lookup_found);
+ return lookup_found;
+ } else
+ LLDB_LOG(log, "[ClangASTImporter] Complete definition not found");
+ }
+
+ return ASTImporter::ImportImpl(From);
+}
+
+void ClangASTImporter::ASTImporterDelegate::ImportDefinitionTo(
+ clang::Decl *to, clang::Decl *from) {
+ // We might have a forward declaration from a shared library that we
+ // gave external lexical storage so that Clang asks us about the full
+ // definition when it needs it. In this case the ASTImporter isn't aware
+ // that the forward decl from the shared library is the actual import
+ // target but would create a second declaration that would then be defined.
+ // We want that 'to' is actually complete after this function so let's
+ // tell the ASTImporter that 'to' was imported from 'from'.
+ MapImported(from, to);
+ ASTImporter::Imported(from, to);
+
+ /*
+ if (to_objc_interface)
+ to_objc_interface->startDefinition();
+
+ CXXRecordDecl *to_cxx_record = dyn_cast<CXXRecordDecl>(to);
+
+ if (to_cxx_record)
+ to_cxx_record->startDefinition();
+ */
+
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+
+ if (llvm::Error err = ImportDefinition(from)) {
+ LLDB_LOG_ERROR(log, std::move(err),
+ "[ClangASTImporter] Error during importing definition: {0}");
+ return;
+ }
+
+ if (clang::TagDecl *to_tag = dyn_cast<clang::TagDecl>(to)) {
+ if (clang::TagDecl *from_tag = dyn_cast<clang::TagDecl>(from)) {
+ to_tag->setCompleteDefinition(from_tag->isCompleteDefinition());
+
+ if (Log *log_ast =
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST)) {
+ std::string name_string;
+ if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from)) {
+ llvm::raw_string_ostream name_stream(name_string);
+ from_named_decl->printName(name_stream);
+ name_stream.flush();
+ }
+ LLDB_LOG(log_ast, "==== [ClangASTImporter][TUDecl: {0}] Imported "
+ "({1}Decl*){2}, named {3} (from "
+ "(Decl*){4})",
+ static_cast<void *>(to->getTranslationUnitDecl()),
+ from->getDeclKindName(), static_cast<void *>(to), name_string,
+ static_cast<void *>(from));
+
+ // Log the AST of the TU.
+ std::string ast_string;
+ llvm::raw_string_ostream ast_stream(ast_string);
+ to->getTranslationUnitDecl()->dump(ast_stream);
+ LLDB_LOG(log_ast, "{0}", ast_string);
+ }
+ }
+ }
+
+ // If we're dealing with an Objective-C class, ensure that the inheritance
+ // has been set up correctly. The ASTImporter may not do this correctly if
+ // the class was originally sourced from symbols.
+
+ if (ObjCInterfaceDecl *to_objc_interface = dyn_cast<ObjCInterfaceDecl>(to)) {
+ do {
+ ObjCInterfaceDecl *to_superclass = to_objc_interface->getSuperClass();
+
+ if (to_superclass)
+ break; // we're not going to override it if it's set
+
+ ObjCInterfaceDecl *from_objc_interface =
+ dyn_cast<ObjCInterfaceDecl>(from);
+
+ if (!from_objc_interface)
+ break;
+
+ ObjCInterfaceDecl *from_superclass = from_objc_interface->getSuperClass();
+
+ if (!from_superclass)
+ break;
+
+ llvm::Expected<Decl *> imported_from_superclass_decl =
+ Import(from_superclass);
+
+ if (!imported_from_superclass_decl) {
+ LLDB_LOG_ERROR(log, imported_from_superclass_decl.takeError(),
+ "Couldn't import decl: {0}");
+ break;
+ }
+
+ ObjCInterfaceDecl *imported_from_superclass =
+ dyn_cast<ObjCInterfaceDecl>(*imported_from_superclass_decl);
+
+ if (!imported_from_superclass)
+ break;
+
+ if (!to_objc_interface->hasDefinition())
+ to_objc_interface->startDefinition();
+
+ to_objc_interface->setSuperClass(m_source_ctx->getTrivialTypeSourceInfo(
+ m_source_ctx->getObjCInterfaceType(imported_from_superclass)));
+ } while (false);
+ }
+}
+
+/// Takes a CXXMethodDecl and completes the return type if necessary. This
+/// is currently only necessary for virtual functions with covariant return
+/// types where Clang's CodeGen expects that the underlying records are already
+/// completed.
+static void MaybeCompleteReturnType(ClangASTImporter &importer,
+ CXXMethodDecl *to_method) {
+ if (!to_method->isVirtual())
+ return;
+ QualType return_type = to_method->getReturnType();
+ if (!return_type->isPointerType() && !return_type->isReferenceType())
+ return;
+
+ clang::RecordDecl *rd = return_type->getPointeeType()->getAsRecordDecl();
+ if (!rd)
+ return;
+ if (rd->getDefinition())
+ return;
+
+ importer.CompleteTagDecl(rd);
+}
+
+/// Recreate a module with its parents in \p to_source and return its id.
+static OptionalClangModuleID
+RemapModule(OptionalClangModuleID from_id,
+ ClangExternalASTSourceCallbacks &from_source,
+ ClangExternalASTSourceCallbacks &to_source) {
+ if (!from_id.HasValue())
+ return {};
+ clang::Module *module = from_source.getModule(from_id.GetValue());
+ OptionalClangModuleID parent = RemapModule(
+ from_source.GetIDForModule(module->Parent), from_source, to_source);
+ TypeSystemClang &to_ts = to_source.GetTypeSystem();
+ return to_ts.GetOrCreateClangModule(module->Name, parent, module->IsFramework,
+ module->IsExplicit);
+}
+
+void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
+ clang::Decl *to) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ // Some decls shouldn't be tracked here because they were not created by
+ // copying 'from' to 'to'. Just exit early for those.
+ if (m_decls_to_ignore.count(to))
+ return clang::ASTImporter::Imported(from, to);
+
+ // Transfer module ownership information.
+ auto *from_source = llvm::dyn_cast_or_null<ClangExternalASTSourceCallbacks>(
+ getFromContext().getExternalSource());
+ // Can also be a ClangASTSourceProxy.
+ auto *to_source = llvm::dyn_cast_or_null<ClangExternalASTSourceCallbacks>(
+ getToContext().getExternalSource());
+ if (from_source && to_source) {
+ OptionalClangModuleID from_id(from->getOwningModuleID());
+ OptionalClangModuleID to_id =
+ RemapModule(from_id, *from_source, *to_source);
+ TypeSystemClang &to_ts = to_source->GetTypeSystem();
+ to_ts.SetOwningModule(to, to_id);
+ }
+
+ lldb::user_id_t user_id = LLDB_INVALID_UID;
+ ClangASTMetadata *metadata = m_master.GetDeclMetadata(from);
+ if (metadata)
+ user_id = metadata->GetUserID();
+
+ if (log) {
+ if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from)) {
+ std::string name_string;
+ llvm::raw_string_ostream name_stream(name_string);
+ from_named_decl->printName(name_stream);
+ name_stream.flush();
+
+ LLDB_LOG(log,
+ " [ClangASTImporter] Imported ({0}Decl*){1}, named {2} (from "
+ "(Decl*){3}), metadata {4}",
+ from->getDeclKindName(), to, name_string, from, user_id);
+ } else {
+ LLDB_LOG(log,
+ " [ClangASTImporter] Imported ({0}Decl*){1} (from "
+ "(Decl*){2}), metadata {3}",
+ from->getDeclKindName(), to, from, user_id);
+ }
+ }
+
+ ASTContextMetadataSP to_context_md =
+ m_master.GetContextMetadata(&to->getASTContext());
+ ASTContextMetadataSP from_context_md =
+ m_master.MaybeGetContextMetadata(m_source_ctx);
+
+ if (from_context_md) {
+ OriginMap &origins = from_context_md->m_origins;
+
+ OriginMap::iterator origin_iter = origins.find(from);
+
+ if (origin_iter != origins.end()) {
+ if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() ||
+ user_id != LLDB_INVALID_UID) {
+ if (origin_iter->second.ctx != &to->getASTContext())
+ to_context_md->m_origins[to] = origin_iter->second;
+ }
+
+ ImporterDelegateSP direct_completer =
+ m_master.GetDelegate(&to->getASTContext(), origin_iter->second.ctx);
+
+ if (direct_completer.get() != this)
+ direct_completer->ASTImporter::Imported(origin_iter->second.decl, to);
+
+ LLDB_LOG(log,
+ " [ClangASTImporter] Propagated origin "
+ "(Decl*){0}/(ASTContext*){1} from (ASTContext*){2} to "
+ "(ASTContext*){3}",
+ origin_iter->second.decl, origin_iter->second.ctx,
+ &from->getASTContext(), &to->getASTContext());
+ } else {
+ if (m_new_decl_listener)
+ m_new_decl_listener->NewDeclImported(from, to);
+
+ if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() ||
+ user_id != LLDB_INVALID_UID) {
+ to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from);
+ }
+
+ LLDB_LOG(log,
+ " [ClangASTImporter] Decl has no origin information in "
+ "(ASTContext*){0}",
+ &from->getASTContext());
+ }
+
+ if (auto *to_namespace = dyn_cast<clang::NamespaceDecl>(to)) {
+ auto *from_namespace = cast<clang::NamespaceDecl>(from);
+
+ NamespaceMetaMap &namespace_maps = from_context_md->m_namespace_maps;
+
+ NamespaceMetaMap::iterator namespace_map_iter =
+ namespace_maps.find(from_namespace);
+
+ if (namespace_map_iter != namespace_maps.end())
+ to_context_md->m_namespace_maps[to_namespace] =
+ namespace_map_iter->second;
+ }
+ } else {
+ to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from);
+
+ LLDB_LOG(log,
+ " [ClangASTImporter] Sourced origin "
+ "(Decl*){0}/(ASTContext*){1} into (ASTContext*){2}",
+ from, m_source_ctx, &to->getASTContext());
+ }
+
+ if (auto *to_tag_decl = dyn_cast<TagDecl>(to)) {
+ to_tag_decl->setHasExternalLexicalStorage();
+ to_tag_decl->getPrimaryContext()->setMustBuildLookupTable();
+ auto from_tag_decl = cast<TagDecl>(from);
+
+ LLDB_LOG(
+ log,
+ " [ClangASTImporter] To is a TagDecl - attributes {0}{1} [{2}->{3}]",
+ (to_tag_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
+ (to_tag_decl->hasExternalVisibleStorage() ? " Visible" : ""),
+ (from_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"),
+ (to_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"));
+ }
+
+ if (auto *to_namespace_decl = dyn_cast<NamespaceDecl>(to)) {
+ m_master.BuildNamespaceMap(to_namespace_decl);
+ to_namespace_decl->setHasExternalVisibleStorage();
+ }
+
+ if (auto *to_container_decl = dyn_cast<ObjCContainerDecl>(to)) {
+ to_container_decl->setHasExternalLexicalStorage();
+ to_container_decl->setHasExternalVisibleStorage();
+
+ if (log) {
+ if (ObjCInterfaceDecl *to_interface_decl =
+ llvm::dyn_cast<ObjCInterfaceDecl>(to_container_decl)) {
+ LLDB_LOG(
+ log,
+ " [ClangASTImporter] To is an ObjCInterfaceDecl - attributes "
+ "{0}{1}{2}",
+ (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
+ (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""),
+ (to_interface_decl->hasDefinition() ? " HasDefinition" : ""));
+ } else {
+ LLDB_LOG(
+ log, " [ClangASTImporter] To is an {0}Decl - attributes {1}{2}",
+ ((Decl *)to_container_decl)->getDeclKindName(),
+ (to_container_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
+ (to_container_decl->hasExternalVisibleStorage() ? " Visible" : ""));
+ }
+ }
+ }
+
+ if (clang::CXXMethodDecl *to_method = dyn_cast<CXXMethodDecl>(to))
+ MaybeCompleteReturnType(m_master, to_method);
+}
+
+clang::Decl *
+ClangASTImporter::ASTImporterDelegate::GetOriginalDecl(clang::Decl *To) {
+ return m_master.GetDeclOrigin(To).decl;
+}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h
new file mode 100644
index 000000000000..6ceec774914b
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h
@@ -0,0 +1,328 @@
+//===-- ClangASTImporter.h --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTIMPORTER_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTIMPORTER_H
+
+#include <map>
+#include <memory>
+#include <set>
+#include <vector>
+
+#include "clang/AST/ASTImporter.h"
+#include "clang/AST/CharUnits.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/FileSystemOptions.h"
+
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Symbol/CompilerDeclContext.h"
+#include "lldb/lldb-types.h"
+
+#include "Plugins/ExpressionParser/Clang/CxxModuleHandler.h"
+
+#include "llvm/ADT/DenseMap.h"
+
+namespace lldb_private {
+
+class ClangASTMetadata;
+class TypeSystemClang;
+
+class ClangASTImporter {
+public:
+ struct LayoutInfo {
+ LayoutInfo() = default;
+ typedef llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ OffsetMap;
+
+ uint64_t bit_size = 0;
+ uint64_t alignment = 0;
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> field_offsets;
+ OffsetMap base_offsets;
+ OffsetMap vbase_offsets;
+ };
+
+ ClangASTImporter()
+ : m_file_manager(clang::FileSystemOptions(),
+ FileSystem::Instance().GetVirtualFileSystem()) {}
+
+ CompilerType CopyType(TypeSystemClang &dst, const CompilerType &src_type);
+
+ clang::Decl *CopyDecl(clang::ASTContext *dst_ctx, clang::Decl *decl);
+
+ CompilerType DeportType(TypeSystemClang &dst, const CompilerType &src_type);
+
+ clang::Decl *DeportDecl(clang::ASTContext *dst_ctx, clang::Decl *decl);
+
+ /// Sets the layout for the given RecordDecl. The layout will later be
+ /// used by Clang's during code generation. Not calling this function for
+ /// a RecordDecl will cause that Clang's codegen tries to layout the
+ /// record by itself.
+ ///
+ /// \param decl The RecordDecl to set the layout for.
+ /// \param layout The layout for the record.
+ void SetRecordLayout(clang::RecordDecl *decl, const LayoutInfo &layout);
+
+ bool LayoutRecordType(
+ const clang::RecordDecl *record_decl, uint64_t &bit_size,
+ uint64_t &alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &base_offsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &vbase_offsets);
+
+ bool CanImport(const CompilerType &type);
+
+ bool Import(const CompilerType &type);
+
+ bool CompleteType(const CompilerType &compiler_type);
+
+ bool CompleteTagDecl(clang::TagDecl *decl);
+
+ bool CompleteTagDeclWithOrigin(clang::TagDecl *decl, clang::TagDecl *origin);
+
+ bool CompleteObjCInterfaceDecl(clang::ObjCInterfaceDecl *interface_decl);
+
+ bool CompleteAndFetchChildren(clang::QualType type);
+
+ bool RequireCompleteType(clang::QualType type);
+
+ void SetDeclOrigin(const clang::Decl *decl, clang::Decl *original_decl);
+
+ ClangASTMetadata *GetDeclMetadata(const clang::Decl *decl);
+
+ //
+ // Namespace maps
+ //
+
+ typedef std::pair<lldb::ModuleSP, CompilerDeclContext> NamespaceMapItem;
+ typedef std::vector<NamespaceMapItem> NamespaceMap;
+ typedef std::shared_ptr<NamespaceMap> NamespaceMapSP;
+
+ void RegisterNamespaceMap(const clang::NamespaceDecl *decl,
+ NamespaceMapSP &namespace_map);
+
+ NamespaceMapSP GetNamespaceMap(const clang::NamespaceDecl *decl);
+
+ void BuildNamespaceMap(const clang::NamespaceDecl *decl);
+
+ //
+ // Completers for maps
+ //
+
+ class MapCompleter {
+ public:
+ virtual ~MapCompleter();
+
+ virtual void CompleteNamespaceMap(NamespaceMapSP &namespace_map,
+ ConstString name,
+ NamespaceMapSP &parent_map) const = 0;
+ };
+
+ void InstallMapCompleter(clang::ASTContext *dst_ctx,
+ MapCompleter &completer) {
+ ASTContextMetadataSP context_md;
+ ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
+
+ if (context_md_iter == m_metadata_map.end()) {
+ context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
+ m_metadata_map[dst_ctx] = context_md;
+ } else {
+ context_md = context_md_iter->second;
+ }
+
+ context_md->m_map_completer = &completer;
+ }
+
+ void ForgetDestination(clang::ASTContext *dst_ctx);
+ void ForgetSource(clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx);
+
+ struct DeclOrigin {
+ DeclOrigin() : ctx(nullptr), decl(nullptr) {}
+
+ DeclOrigin(clang::ASTContext *_ctx, clang::Decl *_decl)
+ : ctx(_ctx), decl(_decl) {}
+
+ DeclOrigin(const DeclOrigin &rhs) {
+ ctx = rhs.ctx;
+ decl = rhs.decl;
+ }
+
+ void operator=(const DeclOrigin &rhs) {
+ ctx = rhs.ctx;
+ decl = rhs.decl;
+ }
+
+ bool Valid() { return (ctx != nullptr || decl != nullptr); }
+
+ clang::ASTContext *ctx;
+ clang::Decl *decl;
+ };
+
+ typedef llvm::DenseMap<const clang::Decl *, DeclOrigin> OriginMap;
+
+ /// Listener interface used by the ASTImporterDelegate to inform other code
+ /// about decls that have been imported the first time.
+ struct NewDeclListener {
+ virtual ~NewDeclListener() = default;
+ /// A decl has been imported for the first time.
+ virtual void NewDeclImported(clang::Decl *from, clang::Decl *to) = 0;
+ };
+
+ /// ASTImporter that intercepts and records the import process of the
+ /// underlying ASTImporter.
+ ///
+ /// This class updates the map from declarations to their original
+ /// declarations and can record declarations that have been imported in a
+ /// certain interval.
+ ///
+ /// When intercepting a declaration import, the ASTImporterDelegate uses the
+ /// CxxModuleHandler to replace any missing or malformed declarations with
+ /// their counterpart from a C++ module.
+ struct ASTImporterDelegate : public clang::ASTImporter {
+ ASTImporterDelegate(ClangASTImporter &master, clang::ASTContext *target_ctx,
+ clang::ASTContext *source_ctx)
+ : clang::ASTImporter(*target_ctx, master.m_file_manager, *source_ctx,
+ master.m_file_manager, true /*minimal*/),
+ m_master(master), m_source_ctx(source_ctx) {
+ setODRHandling(clang::ASTImporter::ODRHandlingType::Liberal);
+ }
+
+ /// Scope guard that attaches a CxxModuleHandler to an ASTImporterDelegate
+ /// and deattaches it at the end of the scope. Supports being used multiple
+ /// times on the same ASTImporterDelegate instance in nested scopes.
+ class CxxModuleScope {
+ /// The handler we attach to the ASTImporterDelegate.
+ CxxModuleHandler m_handler;
+ /// The ASTImporterDelegate we are supposed to attach the handler to.
+ ASTImporterDelegate &m_delegate;
+ /// True iff we attached the handler to the ASTImporterDelegate.
+ bool m_valid = false;
+
+ public:
+ CxxModuleScope(ASTImporterDelegate &delegate, clang::ASTContext *dst_ctx)
+ : m_delegate(delegate) {
+ // If the delegate doesn't have a CxxModuleHandler yet, create one
+ // and attach it.
+ if (!delegate.m_std_handler) {
+ m_handler = CxxModuleHandler(delegate, dst_ctx);
+ m_valid = true;
+ delegate.m_std_handler = &m_handler;
+ }
+ }
+ ~CxxModuleScope() {
+ if (m_valid) {
+ // Make sure no one messed with the handler we placed.
+ assert(m_delegate.m_std_handler == &m_handler);
+ m_delegate.m_std_handler = nullptr;
+ }
+ }
+ };
+
+ void ImportDefinitionTo(clang::Decl *to, clang::Decl *from);
+
+ void Imported(clang::Decl *from, clang::Decl *to) override;
+
+ clang::Decl *GetOriginalDecl(clang::Decl *To) override;
+
+ void SetImportListener(NewDeclListener *listener) {
+ assert(m_new_decl_listener == nullptr && "Already attached a listener?");
+ m_new_decl_listener = listener;
+ }
+ void RemoveImportListener() { m_new_decl_listener = nullptr; }
+
+ protected:
+ llvm::Expected<clang::Decl *> ImportImpl(clang::Decl *From) override;
+
+ private:
+ /// Decls we should ignore when mapping decls back to their original
+ /// ASTContext. Used by the CxxModuleHandler to mark declarations that
+ /// were created from the 'std' C++ module to prevent that the Importer
+ /// tries to sync them with the broken equivalent in the debug info AST.
+ llvm::SmallPtrSet<clang::Decl *, 16> m_decls_to_ignore;
+ ClangASTImporter &m_master;
+ clang::ASTContext *m_source_ctx;
+ CxxModuleHandler *m_std_handler = nullptr;
+ /// The currently attached listener.
+ NewDeclListener *m_new_decl_listener = nullptr;
+ };
+
+ typedef std::shared_ptr<ASTImporterDelegate> ImporterDelegateSP;
+ typedef llvm::DenseMap<clang::ASTContext *, ImporterDelegateSP> DelegateMap;
+ typedef llvm::DenseMap<const clang::NamespaceDecl *, NamespaceMapSP>
+ NamespaceMetaMap;
+
+ struct ASTContextMetadata {
+ ASTContextMetadata(clang::ASTContext *dst_ctx)
+ : m_dst_ctx(dst_ctx), m_delegates(), m_origins(), m_namespace_maps(),
+ m_map_completer(nullptr) {}
+
+ clang::ASTContext *m_dst_ctx;
+ DelegateMap m_delegates;
+ OriginMap m_origins;
+
+ NamespaceMetaMap m_namespace_maps;
+ MapCompleter *m_map_completer;
+ };
+
+ typedef std::shared_ptr<ASTContextMetadata> ASTContextMetadataSP;
+ typedef llvm::DenseMap<const clang::ASTContext *, ASTContextMetadataSP>
+ ContextMetadataMap;
+
+ ContextMetadataMap m_metadata_map;
+
+ ASTContextMetadataSP GetContextMetadata(clang::ASTContext *dst_ctx) {
+ ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
+
+ if (context_md_iter == m_metadata_map.end()) {
+ ASTContextMetadataSP context_md =
+ ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
+ m_metadata_map[dst_ctx] = context_md;
+ return context_md;
+ }
+ return context_md_iter->second;
+ }
+
+ ASTContextMetadataSP MaybeGetContextMetadata(clang::ASTContext *dst_ctx) {
+ ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
+
+ if (context_md_iter != m_metadata_map.end())
+ return context_md_iter->second;
+ return ASTContextMetadataSP();
+ }
+
+ ImporterDelegateSP GetDelegate(clang::ASTContext *dst_ctx,
+ clang::ASTContext *src_ctx) {
+ ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx);
+
+ DelegateMap &delegates = context_md->m_delegates;
+ DelegateMap::iterator delegate_iter = delegates.find(src_ctx);
+
+ if (delegate_iter == delegates.end()) {
+ ImporterDelegateSP delegate =
+ ImporterDelegateSP(new ASTImporterDelegate(*this, dst_ctx, src_ctx));
+ delegates[src_ctx] = delegate;
+ return delegate;
+ }
+ return delegate_iter->second;
+ }
+
+ DeclOrigin GetDeclOrigin(const clang::Decl *decl);
+
+ clang::FileManager m_file_manager;
+ typedef llvm::DenseMap<const clang::RecordDecl *, LayoutInfo>
+ RecordDeclToLayoutMap;
+
+ RecordDeclToLayoutMap m_record_decl_to_layout_map;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTIMPORTER_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.cpp
new file mode 100644
index 000000000000..42933c78b027
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.cpp
@@ -0,0 +1,35 @@
+//===-- ClangASTMetadata.cpp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
+#include "lldb/Utility/Stream.h"
+
+using namespace lldb_private;
+
+void ClangASTMetadata::Dump(Stream *s) {
+ lldb::user_id_t uid = GetUserID();
+
+ if (uid != LLDB_INVALID_UID) {
+ s->Printf("uid=0x%" PRIx64, uid);
+ }
+
+ uint64_t isa_ptr = GetISAPtr();
+ if (isa_ptr != 0) {
+ s->Printf("isa_ptr=0x%" PRIx64, isa_ptr);
+ }
+
+ const char *obj_ptr_name = GetObjectPtrName();
+ if (obj_ptr_name) {
+ s->Printf("obj_ptr_name=\"%s\" ", obj_ptr_name);
+ }
+
+ if (m_is_dynamic_cxx) {
+ s->Printf("is_dynamic_cxx=%i ", m_is_dynamic_cxx);
+ }
+ s->EOL();
+}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.h
new file mode 100644
index 000000000000..d3bcde2ced79
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.h
@@ -0,0 +1,110 @@
+//===-- ClangASTMetadata.h --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTMETADATA_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTMETADATA_H
+
+#include "lldb/Core/dwarf.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+
+namespace lldb_private {
+
+class ClangASTMetadata {
+public:
+ ClangASTMetadata()
+ : m_user_id(0), m_union_is_user_id(false), m_union_is_isa_ptr(false),
+ m_has_object_ptr(false), m_is_self(false), m_is_dynamic_cxx(true),
+ m_is_forcefully_completed(false) {}
+
+ bool GetIsDynamicCXXType() const { return m_is_dynamic_cxx; }
+
+ void SetIsDynamicCXXType(bool b) { m_is_dynamic_cxx = b; }
+
+ void SetUserID(lldb::user_id_t user_id) {
+ m_user_id = user_id;
+ m_union_is_user_id = true;
+ m_union_is_isa_ptr = false;
+ }
+
+ lldb::user_id_t GetUserID() const {
+ if (m_union_is_user_id)
+ return m_user_id;
+ else
+ return LLDB_INVALID_UID;
+ }
+
+ void SetISAPtr(uint64_t isa_ptr) {
+ m_isa_ptr = isa_ptr;
+ m_union_is_user_id = false;
+ m_union_is_isa_ptr = true;
+ }
+
+ uint64_t GetISAPtr() const {
+ if (m_union_is_isa_ptr)
+ return m_isa_ptr;
+ else
+ return 0;
+ }
+
+ void SetObjectPtrName(const char *name) {
+ m_has_object_ptr = true;
+ if (strcmp(name, "self") == 0)
+ m_is_self = true;
+ else if (strcmp(name, "this") == 0)
+ m_is_self = false;
+ else
+ m_has_object_ptr = false;
+ }
+
+ lldb::LanguageType GetObjectPtrLanguage() const {
+ if (m_has_object_ptr) {
+ if (m_is_self)
+ return lldb::eLanguageTypeObjC;
+ else
+ return lldb::eLanguageTypeC_plus_plus;
+ }
+ return lldb::eLanguageTypeUnknown;
+ }
+
+ const char *GetObjectPtrName() const {
+ if (m_has_object_ptr) {
+ if (m_is_self)
+ return "self";
+ else
+ return "this";
+ } else
+ return nullptr;
+ }
+
+ bool HasObjectPtr() const { return m_has_object_ptr; }
+
+ /// A type is "forcefully completed" if it was declared complete to satisfy an
+ /// AST invariant (e.g. base classes must be complete types), but in fact we
+ /// were not able to find a actual definition for it.
+ bool IsForcefullyCompleted() const { return m_is_forcefully_completed; }
+
+ void SetIsForcefullyCompleted(bool value = true) {
+ m_is_forcefully_completed = true;
+ }
+
+ void Dump(Stream *s);
+
+private:
+ union {
+ lldb::user_id_t m_user_id;
+ uint64_t m_isa_ptr;
+ };
+
+ bool m_union_is_user_id : 1, m_union_is_isa_ptr : 1, m_has_object_ptr : 1,
+ m_is_self : 1, m_is_dynamic_cxx : 1, m_is_forcefully_completed : 1;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTMETADATA_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
index 42927ab6cc8a..6fe85a1298fc 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
@@ -1,4 +1,4 @@
-//===-- ClangASTSource.cpp ---------------------------------------*- C++-*-===//
+//===-- ClangASTSource.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -13,8 +13,6 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/CompilerDeclContext.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/SymbolFile.h"
@@ -23,8 +21,11 @@
#include "lldb/Utility/Log.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecordLayout.h"
+#include "clang/Basic/SourceManager.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include <memory>
#include <vector>
@@ -49,14 +50,16 @@ private:
};
}
-ClangASTSource::ClangASTSource(const lldb::TargetSP &target,
- const lldb::ClangASTImporterSP &importer)
- : m_import_in_progress(false), m_lookups_enabled(false), m_target(target),
- m_ast_context(nullptr), m_active_lexical_decls(), m_active_lookups() {
- m_ast_importer_sp = importer;
+ClangASTSource::ClangASTSource(
+ const lldb::TargetSP &target,
+ const std::shared_ptr<ClangASTImporter> &importer)
+ : m_lookups_enabled(false), m_target(target), m_ast_context(nullptr),
+ m_ast_importer_sp(importer), m_active_lexical_decls(),
+ m_active_lookups() {
+ assert(m_ast_importer_sp && "No ClangASTImporter passed to ClangASTSource?");
}
-void ClangASTSource::InstallASTContext(ClangASTContext &clang_ast_context) {
+void ClangASTSource::InstallASTContext(TypeSystemClang &clang_ast_context) {
m_ast_context = &clang_ast_context.getASTContext();
m_clang_ast_context = &clang_ast_context;
m_file_manager = &m_ast_context->getSourceManager().getFileManager();
@@ -64,18 +67,15 @@ void ClangASTSource::InstallASTContext(ClangASTContext &clang_ast_context) {
}
ClangASTSource::~ClangASTSource() {
- if (!m_ast_importer_sp)
- return;
-
m_ast_importer_sp->ForgetDestination(m_ast_context);
if (!m_target)
return;
// We are in the process of destruction, don't create clang ast context on
// demand by passing false to
- // Target::GetScratchClangASTContext(create_on_demand).
- ClangASTContext *scratch_clang_ast_context =
- ClangASTContext::GetScratch(*m_target, false);
+ // Target::GetScratchTypeSystemClang(create_on_demand).
+ TypeSystemClang *scratch_clang_ast_context =
+ TypeSystemClang::GetScratch(*m_target, false);
if (!scratch_clang_ast_context)
return;
@@ -103,16 +103,8 @@ bool ClangASTSource::FindExternalVisibleDeclsByName(
return false;
}
- if (GetImportInProgress()) {
- SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
- return false;
- }
-
std::string decl_name(clang_decl_name.getAsString());
- // if (m_decl_map.DoingASTImport ())
- // return DeclContext::lookup_result();
- //
switch (clang_decl_name.getNameKind()) {
// Normal identifiers.
case DeclarationName::Identifier: {
@@ -141,7 +133,7 @@ bool ClangASTSource::FindExternalVisibleDeclsByName(
case DeclarationName::ObjCMultiArgSelector: {
llvm::SmallVector<NamedDecl *, 1> method_decls;
- NameSearchContext method_search_context(*this, method_decls,
+ NameSearchContext method_search_context(*m_clang_ast_context, method_decls,
clang_decl_name, decl_ctx);
FindObjCMethodDecls(method_search_context);
@@ -179,154 +171,134 @@ bool ClangASTSource::FindExternalVisibleDeclsByName(
return false;
}
m_active_lookups.insert(uniqued_const_decl_name);
- // static uint32_t g_depth = 0;
- // ++g_depth;
- // printf("[%5u] FindExternalVisibleDeclsByName() \"%s\"\n", g_depth,
- // uniqued_const_decl_name);
llvm::SmallVector<NamedDecl *, 4> name_decls;
- NameSearchContext name_search_context(*this, name_decls, clang_decl_name,
- decl_ctx);
+ NameSearchContext name_search_context(*m_clang_ast_context, name_decls,
+ clang_decl_name, decl_ctx);
FindExternalVisibleDecls(name_search_context);
SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, name_decls);
- // --g_depth;
m_active_lookups.erase(uniqued_const_decl_name);
return (name_decls.size() != 0);
}
-void ClangASTSource::CompleteType(TagDecl *tag_decl) {
+TagDecl *ClangASTSource::FindCompleteType(const TagDecl *decl) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
-
- if (log) {
- LLDB_LOGF(log,
- " CompleteTagDecl[%u] on (ASTContext*)%p Completing "
- "(TagDecl*)%p named %s",
- current_id, static_cast<void *>(m_ast_context),
- static_cast<void *>(tag_decl), tag_decl->getName().str().c_str());
-
- LLDB_LOG(log, " CTD[%u] Before:\n{0}", current_id,
- ClangUtil::DumpDecl(tag_decl));
- }
-
- auto iter = m_active_lexical_decls.find(tag_decl);
- if (iter != m_active_lexical_decls.end())
- return;
- m_active_lexical_decls.insert(tag_decl);
- ScopedLexicalDeclEraser eraser(m_active_lexical_decls, tag_decl);
+ if (const NamespaceDecl *namespace_context =
+ dyn_cast<NamespaceDecl>(decl->getDeclContext())) {
+ ClangASTImporter::NamespaceMapSP namespace_map =
+ m_ast_importer_sp->GetNamespaceMap(namespace_context);
- if (!m_ast_importer_sp) {
- return;
- }
+ LLDB_LOGV(log, " CTD Inspecting namespace map{0} ({1} entries)",
+ namespace_map.get(), namespace_map->size());
- if (!m_ast_importer_sp->CompleteTagDecl(tag_decl)) {
- // We couldn't complete the type. Maybe there's a definition somewhere
- // else that can be completed.
-
- LLDB_LOGF(log,
- " CTD[%u] Type could not be completed in the module in "
- "which it was first found.",
- current_id);
+ if (!namespace_map)
+ return nullptr;
- bool found = false;
+ for (const ClangASTImporter::NamespaceMapItem &item : *namespace_map) {
+ LLDB_LOG(log, " CTD Searching namespace {0} in module {1}",
+ item.second.GetName(), item.first->GetFileSpec().GetFilename());
- DeclContext *decl_ctx = tag_decl->getDeclContext();
+ TypeList types;
- if (const NamespaceDecl *namespace_context =
- dyn_cast<NamespaceDecl>(decl_ctx)) {
- ClangASTImporter::NamespaceMapSP namespace_map =
- m_ast_importer_sp->GetNamespaceMap(namespace_context);
+ ConstString name(decl->getName());
- if (log && log->GetVerbose())
- LLDB_LOGF(log, " CTD[%u] Inspecting namespace map %p (%d entries)",
- current_id, static_cast<void *>(namespace_map.get()),
- static_cast<int>(namespace_map->size()));
+ item.first->FindTypesInNamespace(name, item.second, UINT32_MAX, types);
- if (!namespace_map)
- return;
+ for (uint32_t ti = 0, te = types.GetSize(); ti != te; ++ti) {
+ lldb::TypeSP type = types.GetTypeAtIndex(ti);
- for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
- e = namespace_map->end();
- i != e && !found; ++i) {
- LLDB_LOGF(log, " CTD[%u] Searching namespace %s in module %s",
- current_id, i->second.GetName().AsCString(),
- i->first->GetFileSpec().GetFilename().GetCString());
+ if (!type)
+ continue;
- TypeList types;
+ CompilerType clang_type(type->GetFullCompilerType());
- ConstString name(tag_decl->getName().str().c_str());
+ if (!ClangUtil::IsClangType(clang_type))
+ continue;
- i->first->FindTypesInNamespace(name, &i->second, UINT32_MAX, types);
+ const TagType *tag_type =
+ ClangUtil::GetQualType(clang_type)->getAs<TagType>();
- for (uint32_t ti = 0, te = types.GetSize(); ti != te && !found; ++ti) {
- lldb::TypeSP type = types.GetTypeAtIndex(ti);
+ if (!tag_type)
+ continue;
- if (!type)
- continue;
+ TagDecl *candidate_tag_decl =
+ const_cast<TagDecl *>(tag_type->getDecl());
- CompilerType clang_type(type->GetFullCompilerType());
+ if (TypeSystemClang::GetCompleteDecl(
+ &candidate_tag_decl->getASTContext(), candidate_tag_decl))
+ return candidate_tag_decl;
+ }
+ }
+ } else {
+ TypeList types;
- if (!ClangUtil::IsClangType(clang_type))
- continue;
+ ConstString name(decl->getName());
- const TagType *tag_type =
- ClangUtil::GetQualType(clang_type)->getAs<TagType>();
+ const ModuleList &module_list = m_target->GetImages();
- if (!tag_type)
- continue;
+ bool exact_match = false;
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
+ module_list.FindTypes(nullptr, name, exact_match, UINT32_MAX,
+ searched_symbol_files, types);
- TagDecl *candidate_tag_decl =
- const_cast<TagDecl *>(tag_type->getDecl());
+ for (uint32_t ti = 0, te = types.GetSize(); ti != te; ++ti) {
+ lldb::TypeSP type = types.GetTypeAtIndex(ti);
- if (m_ast_importer_sp->CompleteTagDeclWithOrigin(tag_decl,
- candidate_tag_decl))
- found = true;
- }
- }
- } else {
- TypeList types;
+ if (!type)
+ continue;
- ConstString name(tag_decl->getName().str().c_str());
+ CompilerType clang_type(type->GetFullCompilerType());
- const ModuleList &module_list = m_target->GetImages();
+ if (!ClangUtil::IsClangType(clang_type))
+ continue;
- bool exact_match = false;
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- module_list.FindTypes(nullptr, name, exact_match, UINT32_MAX,
- searched_symbol_files, types);
+ const TagType *tag_type =
+ ClangUtil::GetQualType(clang_type)->getAs<TagType>();
- for (uint32_t ti = 0, te = types.GetSize(); ti != te && !found; ++ti) {
- lldb::TypeSP type = types.GetTypeAtIndex(ti);
+ if (!tag_type)
+ continue;
- if (!type)
- continue;
+ TagDecl *candidate_tag_decl = const_cast<TagDecl *>(tag_type->getDecl());
- CompilerType clang_type(type->GetFullCompilerType());
+ // We have found a type by basename and we need to make sure the decl
+ // contexts are the same before we can try to complete this type with
+ // another
+ if (!TypeSystemClang::DeclsAreEquivalent(const_cast<TagDecl *>(decl),
+ candidate_tag_decl))
+ continue;
- if (!ClangUtil::IsClangType(clang_type))
- continue;
+ if (TypeSystemClang::GetCompleteDecl(&candidate_tag_decl->getASTContext(),
+ candidate_tag_decl))
+ return candidate_tag_decl;
+ }
+ }
+ return nullptr;
+}
- const TagType *tag_type =
- ClangUtil::GetQualType(clang_type)->getAs<TagType>();
+void ClangASTSource::CompleteType(TagDecl *tag_decl) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (!tag_type)
- continue;
+ if (log) {
+ LLDB_LOG(log,
+ " CompleteTagDecl on (ASTContext*){0} Completing "
+ "(TagDecl*){1} named {2}",
+ m_clang_ast_context->getDisplayName(), tag_decl,
+ tag_decl->getName());
- TagDecl *candidate_tag_decl =
- const_cast<TagDecl *>(tag_type->getDecl());
+ LLDB_LOG(log, " CTD Before:\n{0}", ClangUtil::DumpDecl(tag_decl));
+ }
- // We have found a type by basename and we need to make sure the decl
- // contexts are the same before we can try to complete this type with
- // another
- if (!ClangASTContext::DeclsAreEquivalent(tag_decl, candidate_tag_decl))
- continue;
+ auto iter = m_active_lexical_decls.find(tag_decl);
+ if (iter != m_active_lexical_decls.end())
+ return;
+ m_active_lexical_decls.insert(tag_decl);
+ ScopedLexicalDeclEraser eraser(m_active_lexical_decls, tag_decl);
- if (m_ast_importer_sp->CompleteTagDeclWithOrigin(tag_decl,
- candidate_tag_decl))
- found = true;
- }
- }
+ if (!m_ast_importer_sp->CompleteTagDecl(tag_decl)) {
+ // We couldn't complete the type. Maybe there's a definition somewhere
+ // else that can be completed.
+ if (TagDecl *alternate = FindCompleteType(tag_decl))
+ m_ast_importer_sp->CompleteTagDeclWithOrigin(tag_decl, alternate);
}
LLDB_LOG(log, " [CTD] After:\n{0}", ClangUtil::DumpDecl(tag_decl));
@@ -335,19 +307,14 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) {
void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- LLDB_LOGF(log,
- " [CompleteObjCInterfaceDecl] on (ASTContext*)%p Completing "
- "an ObjCInterfaceDecl named %s",
- static_cast<void *>(m_ast_context),
- interface_decl->getName().str().c_str());
+ LLDB_LOG(log,
+ " [CompleteObjCInterfaceDecl] on (ASTContext*){0} '{1}' "
+ "Completing an ObjCInterfaceDecl named {1}",
+ m_ast_context, m_clang_ast_context->getDisplayName(),
+ interface_decl->getName());
LLDB_LOG(log, " [COID] Before:\n{0}",
ClangUtil::DumpDecl(interface_decl));
- if (!m_ast_importer_sp) {
- lldbassert(0 && "No mechanism for completing a type!");
- return;
- }
-
ClangASTImporter::DeclOrigin original = m_ast_importer_sp->GetDeclOrigin(interface_decl);
if (original.Valid()) {
@@ -368,10 +335,8 @@ void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) {
interface_decl->getSuperClass() != interface_decl)
CompleteType(interface_decl->getSuperClass());
- if (log) {
- LLDB_LOGF(log, " [COID] After:");
- LLDB_LOG(log, " [COID] {0}", ClangUtil::DumpDecl(interface_decl));
- }
+ LLDB_LOG(log, " [COID] After:");
+ LLDB_LOG(log, " [COID] {0}", ClangUtil::DumpDecl(interface_decl));
}
clang::ObjCInterfaceDecl *ClangASTSource::GetCompleteObjCInterface(
@@ -420,9 +385,6 @@ void ClangASTSource::FindExternalLexicalDecls(
llvm::function_ref<bool(Decl::Kind)> predicate,
llvm::SmallVectorImpl<Decl *> &decls) {
- if (!m_ast_importer_sp)
- return;
-
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
const Decl *context_decl = dyn_cast<Decl>(decl_context);
@@ -436,29 +398,27 @@ void ClangASTSource::FindExternalLexicalDecls(
m_active_lexical_decls.insert(context_decl);
ScopedLexicalDeclEraser eraser(m_active_lexical_decls, context_decl);
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
-
if (log) {
if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
- LLDB_LOGF(
- log,
- "FindExternalLexicalDecls[%u] on (ASTContext*)%p in '%s' (%sDecl*)%p",
- current_id, static_cast<void *>(m_ast_context),
- context_named_decl->getNameAsString().c_str(),
- context_decl->getDeclKindName(),
- static_cast<const void *>(context_decl));
+ LLDB_LOG(log,
+ "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in "
+ "'{2}' (%sDecl*){3}",
+ m_ast_context, m_clang_ast_context->getDisplayName(),
+ context_named_decl->getNameAsString().c_str(),
+ context_decl->getDeclKindName(),
+ static_cast<const void *>(context_decl));
else if (context_decl)
- LLDB_LOGF(
- log, "FindExternalLexicalDecls[%u] on (ASTContext*)%p in (%sDecl*)%p",
- current_id, static_cast<void *>(m_ast_context),
- context_decl->getDeclKindName(),
- static_cast<const void *>(context_decl));
+ LLDB_LOG(log,
+ "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in "
+ "({2}Decl*){3}",
+ m_ast_context, m_clang_ast_context->getDisplayName(),
+ context_decl->getDeclKindName(),
+ static_cast<const void *>(context_decl));
else
- LLDB_LOGF(
- log,
- "FindExternalLexicalDecls[%u] on (ASTContext*)%p in a NULL context",
- current_id, static_cast<const void *>(m_ast_context));
+ LLDB_LOG(log,
+ "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in a "
+ "NULL context",
+ m_ast_context, m_clang_ast_context->getDisplayName());
}
ClangASTImporter::DeclOrigin original = m_ast_importer_sp->GetDeclOrigin(context_decl);
@@ -466,10 +426,10 @@ void ClangASTSource::FindExternalLexicalDecls(
if (!original.Valid())
return;
- LLDB_LOG(
- log, " FELD[{0}] Original decl (ASTContext*){1:x} (Decl*){2:x}:\n{3}",
- current_id, static_cast<void *>(original.ctx),
- static_cast<void *>(original.decl), ClangUtil::DumpDecl(original.decl));
+ LLDB_LOG(log, " FELD Original decl {0} (Decl*){1:x}:\n{2}",
+ static_cast<void *>(original.ctx),
+ static_cast<void *>(original.decl),
+ ClangUtil::DumpDecl(original.decl));
if (ObjCInterfaceDecl *original_iface_decl =
dyn_cast<ObjCInterfaceDecl>(original.decl)) {
@@ -499,10 +459,7 @@ void ClangASTSource::FindExternalLexicalDecls(
// Indicates whether we skipped any Decls of the original DeclContext.
bool SkippedDecls = false;
- for (TagDecl::decl_iterator iter = original_decl_context->decls_begin();
- iter != original_decl_context->decls_end(); ++iter) {
- Decl *decl = *iter;
-
+ for (Decl *decl : original_decl_context->decls()) {
// The predicate function returns true if the passed declaration kind is
// the one we are looking for.
// See clang::ExternalASTSource::FindExternalLexicalDecls()
@@ -511,13 +468,13 @@ void ClangASTSource::FindExternalLexicalDecls(
std::string ast_dump = ClangUtil::DumpDecl(decl);
if (const NamedDecl *context_named_decl =
dyn_cast<NamedDecl>(context_decl))
- LLDB_LOGF(log, " FELD[%d] Adding [to %sDecl %s] lexical %sDecl %s",
- current_id, context_named_decl->getDeclKindName(),
- context_named_decl->getNameAsString().c_str(),
- decl->getDeclKindName(), ast_dump.c_str());
+ LLDB_LOG(log, " FELD Adding [to {0}Decl {1}] lexical {2}Decl {3}",
+ context_named_decl->getDeclKindName(),
+ context_named_decl->getName(), decl->getDeclKindName(),
+ ast_dump);
else
- LLDB_LOGF(log, " FELD[%d] Adding lexical %sDecl %s", current_id,
- decl->getDeclKindName(), ast_dump.c_str());
+ LLDB_LOG(log, " FELD Adding lexical {0}Decl {1}",
+ decl->getDeclKindName(), ast_dump);
}
Decl *copied_decl = CopyDecl(decl);
@@ -556,56 +513,29 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
-
if (log) {
if (!context.m_decl_context)
- LLDB_LOGF(log,
- "ClangASTSource::FindExternalVisibleDecls[%u] on "
- "(ASTContext*)%p for '%s' in a NULL DeclContext",
- current_id, static_cast<void *>(m_ast_context),
- name.GetCString());
+ LLDB_LOG(log,
+ "ClangASTSource::FindExternalVisibleDecls on "
+ "(ASTContext*){0} '{1}' for '{2}' in a NULL DeclContext",
+ m_ast_context, m_clang_ast_context->getDisplayName(), name);
else if (const NamedDecl *context_named_decl =
dyn_cast<NamedDecl>(context.m_decl_context))
- LLDB_LOGF(log,
- "ClangASTSource::FindExternalVisibleDecls[%u] on "
- "(ASTContext*)%p for '%s' in '%s'",
- current_id, static_cast<void *>(m_ast_context),
- name.GetCString(),
- context_named_decl->getNameAsString().c_str());
+ LLDB_LOG(log,
+ "ClangASTSource::FindExternalVisibleDecls on "
+ "(ASTContext*){0} '{1}' for '{2}' in '{3}'",
+ m_ast_context, m_clang_ast_context->getDisplayName(), name,
+ context_named_decl->getName());
else
- LLDB_LOGF(log,
- "ClangASTSource::FindExternalVisibleDecls[%u] on "
- "(ASTContext*)%p for '%s' in a '%s'",
- current_id, static_cast<void *>(m_ast_context),
- name.GetCString(), context.m_decl_context->getDeclKindName());
+ LLDB_LOG(log,
+ "ClangASTSource::FindExternalVisibleDecls on "
+ "(ASTContext*){0} '{1}' for '{2}' in a '{3}'",
+ m_ast_context, m_clang_ast_context->getDisplayName(), name,
+ context.m_decl_context->getDeclKindName());
}
- context.m_namespace_map = std::make_shared<ClangASTImporter::NamespaceMap>();
-
- if (const NamespaceDecl *namespace_context =
- dyn_cast<NamespaceDecl>(context.m_decl_context)) {
- ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer_sp ?
- m_ast_importer_sp->GetNamespaceMap(namespace_context) : nullptr;
-
- if (log && log->GetVerbose())
- LLDB_LOGF(log, " CAS::FEVD[%u] Inspecting namespace map %p (%d entries)",
- current_id, static_cast<void *>(namespace_map.get()),
- static_cast<int>(namespace_map->size()));
-
- if (!namespace_map)
- return;
-
- for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
- e = namespace_map->end();
- i != e; ++i) {
- LLDB_LOGF(log, " CAS::FEVD[%u] Searching namespace %s in module %s",
- current_id, i->second.GetName().AsCString(),
- i->first->GetFileSpec().GetFilename().GetCString());
-
- FindExternalVisibleDecls(context, i->first, i->second, current_id);
- }
+ if (isa<NamespaceDecl>(context.m_decl_context)) {
+ LookupInNamespace(context);
} else if (isa<ObjCInterfaceDecl>(context.m_decl_context)) {
FindObjCPropertyAndIvarDecls(context);
} else if (!isa<TranslationUnitDecl>(context.m_decl_context)) {
@@ -614,18 +544,15 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
} else {
CompilerDeclContext namespace_decl;
- LLDB_LOGF(log, " CAS::FEVD[%u] Searching the root namespace", current_id);
+ LLDB_LOG(log, " CAS::FEVD Searching the root namespace");
- FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl,
- current_id);
+ FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl);
}
if (!context.m_namespace_map->empty()) {
if (log && log->GetVerbose())
- LLDB_LOGF(log,
- " CAS::FEVD[%u] Registering namespace map %p (%d entries)",
- current_id, static_cast<void *>(context.m_namespace_map.get()),
- static_cast<int>(context.m_namespace_map->size()));
+ LLDB_LOG(log, " CAS::FEVD Registering namespace map {0} ({1} entries)",
+ context.m_namespace_map.get(), context.m_namespace_map->size());
NamespaceDecl *clang_namespace_decl =
AddNamespace(context, context.m_namespace_map);
@@ -658,7 +585,7 @@ bool ClangASTSource::IgnoreName(const ConstString name,
void ClangASTSource::FindExternalVisibleDecls(
NameSearchContext &context, lldb::ModuleSP module_sp,
- CompilerDeclContext &namespace_decl, unsigned int current_id) {
+ CompilerDeclContext &namespace_decl) {
assert(m_ast_context);
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -672,196 +599,113 @@ void ClangASTSource::FindExternalVisibleDecls(
if (!m_target)
return;
- if (module_sp && namespace_decl) {
- CompilerDeclContext found_namespace_decl;
-
- if (SymbolFile *symbol_file = module_sp->GetSymbolFile()) {
- found_namespace_decl = symbol_file->FindNamespace(name, &namespace_decl);
+ FillNamespaceMap(context, module_sp, namespace_decl);
- if (found_namespace_decl) {
- context.m_namespace_map->push_back(
- std::pair<lldb::ModuleSP, CompilerDeclContext>(
- module_sp, found_namespace_decl));
-
- LLDB_LOGF(log, " CAS::FEVD[%u] Found namespace %s in module %s",
- current_id, name.GetCString(),
- module_sp->GetFileSpec().GetFilename().GetCString());
- }
- }
- } else {
- const ModuleList &target_images = m_target->GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
+ if (context.m_found_type)
+ return;
- for (size_t i = 0, e = target_images.GetSize(); i < e; ++i) {
- lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
+ TypeList types;
+ const bool exact_match = true;
+ llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
+ if (module_sp && namespace_decl)
+ module_sp->FindTypesInNamespace(name, namespace_decl, 1, types);
+ else {
+ m_target->GetImages().FindTypes(module_sp.get(), name, exact_match, 1,
+ searched_symbol_files, types);
+ }
- if (!image)
- continue;
+ if (size_t num_types = types.GetSize()) {
+ for (size_t ti = 0; ti < num_types; ++ti) {
+ lldb::TypeSP type_sp = types.GetTypeAtIndex(ti);
- CompilerDeclContext found_namespace_decl;
+ if (log) {
+ const char *name_string = type_sp->GetName().GetCString();
- SymbolFile *symbol_file = image->GetSymbolFile();
+ LLDB_LOG(log, " CAS::FEVD Matching type found for \"{0}\": {1}", name,
+ (name_string ? name_string : "<anonymous>"));
+ }
- if (!symbol_file)
- continue;
+ CompilerType full_type = type_sp->GetFullCompilerType();
- found_namespace_decl = symbol_file->FindNamespace(name, &namespace_decl);
+ CompilerType copied_clang_type(GuardedCopyType(full_type));
- if (found_namespace_decl) {
- context.m_namespace_map->push_back(
- std::pair<lldb::ModuleSP, CompilerDeclContext>(
- image, found_namespace_decl));
+ if (!copied_clang_type) {
+ LLDB_LOG(log, " CAS::FEVD - Couldn't export a type");
- LLDB_LOGF(log, " CAS::FEVD[%u] Found namespace %s in module %s",
- current_id, name.GetCString(),
- image->GetFileSpec().GetFilename().GetCString());
+ continue;
}
- }
- }
- do {
- if (context.m_found.type)
- break;
+ context.AddTypeDecl(copied_clang_type);
- TypeList types;
- const bool exact_match = true;
- llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
- if (module_sp && namespace_decl)
- module_sp->FindTypesInNamespace(name, &namespace_decl, 1, types);
- else {
- m_target->GetImages().FindTypes(module_sp.get(), name, exact_match, 1,
- searched_symbol_files, types);
+ context.m_found_type = true;
+ break;
}
+ }
- if (size_t num_types = types.GetSize()) {
- for (size_t ti = 0; ti < num_types; ++ti) {
- lldb::TypeSP type_sp = types.GetTypeAtIndex(ti);
-
- if (log) {
- const char *name_string = type_sp->GetName().GetCString();
+ if (!context.m_found_type) {
+ // Try the modules next.
+ FindDeclInModules(context, name);
+ }
- LLDB_LOGF(log, " CAS::FEVD[%u] Matching type found for \"%s\": %s",
- current_id, name.GetCString(),
- (name_string ? name_string : "<anonymous>"));
- }
+ if (!context.m_found_type) {
+ FindDeclInObjCRuntime(context, name);
+ }
+}
- CompilerType full_type = type_sp->GetFullCompilerType();
+void ClangASTSource::FillNamespaceMap(
+ NameSearchContext &context, lldb::ModuleSP module_sp,
+ const CompilerDeclContext &namespace_decl) {
+ const ConstString name(context.m_decl_name.getAsString().c_str());
+ if (IgnoreName(name, true))
+ return;
- CompilerType copied_clang_type(GuardedCopyType(full_type));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (!copied_clang_type) {
- LLDB_LOGF(log, " CAS::FEVD[%u] - Couldn't export a type",
- current_id);
+ if (module_sp && namespace_decl) {
+ CompilerDeclContext found_namespace_decl;
- continue;
- }
+ if (SymbolFile *symbol_file = module_sp->GetSymbolFile()) {
+ found_namespace_decl = symbol_file->FindNamespace(name, namespace_decl);
- context.AddTypeDecl(copied_clang_type);
+ if (found_namespace_decl) {
+ context.m_namespace_map->push_back(
+ std::pair<lldb::ModuleSP, CompilerDeclContext>(
+ module_sp, found_namespace_decl));
- context.m_found.type = true;
- break;
+ LLDB_LOG(log, " CAS::FEVD Found namespace {0} in module {1}", name,
+ module_sp->GetFileSpec().GetFilename());
}
}
+ return;
+ }
- if (!context.m_found.type) {
- // Try the modules next.
-
- do {
- if (ClangModulesDeclVendor *modules_decl_vendor =
- m_target->GetClangModulesDeclVendor()) {
- bool append = false;
- uint32_t max_matches = 1;
- std::vector<clang::NamedDecl *> decls;
-
- if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls))
- break;
-
- if (log) {
- LLDB_LOGF(log,
- " CAS::FEVD[%u] Matching entity found for \"%s\" in "
- "the modules",
- current_id, name.GetCString());
- }
-
- clang::NamedDecl *const decl_from_modules = decls[0];
-
- if (llvm::isa<clang::TypeDecl>(decl_from_modules) ||
- llvm::isa<clang::ObjCContainerDecl>(decl_from_modules) ||
- llvm::isa<clang::EnumConstantDecl>(decl_from_modules)) {
- clang::Decl *copied_decl = CopyDecl(decl_from_modules);
- clang::NamedDecl *copied_named_decl =
- copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
-
- if (!copied_named_decl) {
- LLDB_LOGF(
- log,
- " CAS::FEVD[%u] - Couldn't export a type from the modules",
- current_id);
-
- break;
- }
-
- context.AddNamedDecl(copied_named_decl);
-
- context.m_found.type = true;
- }
- }
- } while (false);
- }
-
- if (!context.m_found.type) {
- do {
- // Couldn't find any types elsewhere. Try the Objective-C runtime if
- // one exists.
-
- lldb::ProcessSP process(m_target->GetProcessSP());
-
- if (!process)
- break;
-
- ObjCLanguageRuntime *language_runtime(
- ObjCLanguageRuntime::Get(*process));
-
- if (!language_runtime)
- break;
-
- DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
+ const ModuleList &target_images = m_target->GetImages();
+ std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
- if (!decl_vendor)
- break;
+ for (size_t i = 0, e = target_images.GetSize(); i < e; ++i) {
+ lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
- bool append = false;
- uint32_t max_matches = 1;
- std::vector<clang::NamedDecl *> decls;
+ if (!image)
+ continue;
- auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor);
- if (!clang_decl_vendor->FindDecls(name, append, max_matches, decls))
- break;
+ CompilerDeclContext found_namespace_decl;
- if (log) {
- LLDB_LOGF(
- log,
- " CAS::FEVD[%u] Matching type found for \"%s\" in the runtime",
- current_id, name.GetCString());
- }
+ SymbolFile *symbol_file = image->GetSymbolFile();
- clang::Decl *copied_decl = CopyDecl(decls[0]);
- clang::NamedDecl *copied_named_decl =
- copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
+ if (!symbol_file)
+ continue;
- if (!copied_named_decl) {
- LLDB_LOGF(log,
- " CAS::FEVD[%u] - Couldn't export a type from the runtime",
- current_id);
+ found_namespace_decl = symbol_file->FindNamespace(name, namespace_decl);
- break;
- }
+ if (found_namespace_decl) {
+ context.m_namespace_map->push_back(
+ std::pair<lldb::ModuleSP, CompilerDeclContext>(image,
+ found_namespace_decl));
- context.AddNamedDecl(copied_named_decl);
- } while (false);
+ LLDB_LOG(log, " CAS::FEVD Found namespace {0} in module {1}", name,
+ image->GetFileSpec().GetFilename());
}
-
- } while (false);
+ }
}
template <class D> class TaggedASTDecl {
@@ -915,8 +759,8 @@ DeclFromParser<D> DeclFromUser<D>::Import(ClangASTSource &source) {
}
bool ClangASTSource::FindObjCMethodDeclsWithOrigin(
- unsigned int current_id, NameSearchContext &context,
- ObjCInterfaceDecl *original_interface_decl, const char *log_info) {
+ NameSearchContext &context, ObjCInterfaceDecl *original_interface_decl,
+ const char *log_info) {
const DeclarationName &decl_name(context.m_decl_name);
clang::ASTContext *original_ctx = &original_interface_decl->getASTContext();
@@ -951,7 +795,7 @@ bool ClangASTSource::FindObjCMethodDeclsWithOrigin(
llvm::SmallVector<NamedDecl *, 1> methods;
- ClangASTContext::GetCompleteDecl(original_ctx, original_interface_decl);
+ TypeSystemClang::GetCompleteDecl(original_ctx, original_interface_decl);
if (ObjCMethodDecl *instance_method_decl =
original_interface_decl->lookupInstanceMethod(original_selector)) {
@@ -987,7 +831,7 @@ bool ClangASTSource::FindObjCMethodDeclsWithOrigin(
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- LLDB_LOG(log, " CAS::FOMD[{0}] found ({1}) {2}", current_id, log_info,
+ LLDB_LOG(log, " CAS::FOMD found ({0}) {1}", log_info,
ClangUtil::DumpDecl(copied_method_decl));
context.AddNamedDecl(copied_method_decl);
@@ -996,11 +840,91 @@ bool ClangASTSource::FindObjCMethodDeclsWithOrigin(
return true;
}
-void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
+void ClangASTSource::FindDeclInModules(NameSearchContext &context,
+ ConstString name) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
+ ClangModulesDeclVendor *modules_decl_vendor =
+ m_target->GetClangModulesDeclVendor();
+ if (!modules_decl_vendor)
+ return;
+
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector<clang::NamedDecl *> decls;
+
+ if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls))
+ return;
+
+ LLDB_LOG(log, " CAS::FEVD Matching entity found for \"{0}\" in the modules",
+ name);
+
+ clang::NamedDecl *const decl_from_modules = decls[0];
+
+ if (llvm::isa<clang::TypeDecl>(decl_from_modules) ||
+ llvm::isa<clang::ObjCContainerDecl>(decl_from_modules) ||
+ llvm::isa<clang::EnumConstantDecl>(decl_from_modules)) {
+ clang::Decl *copied_decl = CopyDecl(decl_from_modules);
+ clang::NamedDecl *copied_named_decl =
+ copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
+
+ if (!copied_named_decl) {
+ LLDB_LOG(log, " CAS::FEVD - Couldn't export a type from the modules");
+
+ return;
+ }
+
+ context.AddNamedDecl(copied_named_decl);
+
+ context.m_found_type = true;
+ }
+}
+
+void ClangASTSource::FindDeclInObjCRuntime(NameSearchContext &context,
+ ConstString name) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ lldb::ProcessSP process(m_target->GetProcessSP());
+
+ if (!process)
+ return;
+
+ ObjCLanguageRuntime *language_runtime(ObjCLanguageRuntime::Get(*process));
+
+ if (!language_runtime)
+ return;
+
+ DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
+
+ if (!decl_vendor)
+ return;
+
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector<clang::NamedDecl *> decls;
+
+ auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor);
+ if (!clang_decl_vendor->FindDecls(name, append, max_matches, decls))
+ return;
+
+ LLDB_LOG(log, " CAS::FEVD Matching type found for \"{0}\" in the runtime",
+ name);
+
+ clang::Decl *copied_decl = CopyDecl(decls[0]);
+ clang::NamedDecl *copied_named_decl =
+ copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
+
+ if (!copied_named_decl) {
+ LLDB_LOG(log, " CAS::FEVD - Couldn't export a type from the runtime");
+
+ return;
+ }
+
+ context.AddNamedDecl(copied_named_decl);
+}
+
+void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
const DeclarationName &decl_name(context.m_decl_name);
const DeclContext *decl_ctx(context.m_decl_context);
@@ -1020,8 +944,8 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
ObjCInterfaceDecl *original_interface_decl =
dyn_cast<ObjCInterfaceDecl>(original.decl);
- if (FindObjCMethodDeclsWithOrigin(current_id, context,
- original_interface_decl, "at origin"))
+ if (FindObjCMethodDeclsWithOrigin(context, original_interface_decl,
+ "at origin"))
return; // found it, no need to look any further
} while (false);
@@ -1046,12 +970,11 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
ConstString selector_name(ss.GetString());
- LLDB_LOGF(log,
- "ClangASTSource::FindObjCMethodDecls[%d] on (ASTContext*)%p "
- "for selector [%s %s]",
- current_id, static_cast<void *>(m_ast_context),
- interface_decl->getNameAsString().c_str(),
- selector_name.AsCString());
+ LLDB_LOG(log,
+ "ClangASTSource::FindObjCMethodDecls on (ASTContext*){0} '{1}' "
+ "for selector [{2} {3}]",
+ m_ast_context, m_clang_ast_context->getDisplayName(),
+ interface_decl->getName(), selector_name);
SymbolContextList sc_list;
const bool include_symbols = false;
@@ -1148,7 +1071,7 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
continue;
ObjCMethodDecl *method_decl =
- ClangASTContext::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
+ TypeSystemClang::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
if (!method_decl)
continue;
@@ -1171,7 +1094,7 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
if (!copied_method_decl)
continue;
- LLDB_LOG(log, " CAS::FOMD[{0}] found (in symbols)\n{1}", current_id,
+ LLDB_LOG(log, " CAS::FOMD found (in symbols)\n{0}",
ClangUtil::DumpDecl(copied_method_decl));
context.AddNamedDecl(copied_method_decl);
@@ -1199,13 +1122,12 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
if (complete_interface_decl == interface_decl)
break; // already checked this one
- LLDB_LOGF(log,
- "CAS::FOPD[%d] trying origin "
- "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id, static_cast<void *>(complete_interface_decl),
- static_cast<void *>(&complete_iface_decl->getASTContext()));
+ LLDB_LOG(log,
+ "CAS::FOPD trying origin "
+ "(ObjCInterfaceDecl*){0}/(ASTContext*){1}...",
+ complete_interface_decl, &complete_iface_decl->getASTContext());
- FindObjCMethodDeclsWithOrigin(current_id, context, complete_interface_decl,
+ FindObjCMethodDeclsWithOrigin(context, complete_interface_decl,
"in debug info");
return;
@@ -1232,8 +1154,8 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
if (!interface_decl_from_modules)
break;
- if (FindObjCMethodDeclsWithOrigin(
- current_id, context, interface_decl_from_modules, "in modules"))
+ if (FindObjCMethodDeclsWithOrigin(context, interface_decl_from_modules,
+ "in modules"))
return;
}
} while (false);
@@ -1273,13 +1195,13 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
if (!runtime_interface_decl)
break;
- FindObjCMethodDeclsWithOrigin(current_id, context, runtime_interface_decl,
+ FindObjCMethodDeclsWithOrigin(context, runtime_interface_decl,
"in runtime");
} while (false);
}
static bool FindObjCPropertyAndIvarDeclsWithOrigin(
- unsigned int current_id, NameSearchContext &context, ClangASTSource &source,
+ NameSearchContext &context, ClangASTSource &source,
DeclFromUser<const ObjCInterfaceDecl> &origin_iface_decl) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -1301,7 +1223,7 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin(
DeclFromParser<ObjCPropertyDecl> parser_property_decl(
origin_property_decl.Import(source));
if (parser_property_decl.IsValid()) {
- LLDB_LOG(log, " CAS::FOPD[{0}] found\n{1}", current_id,
+ LLDB_LOG(log, " CAS::FOPD found\n{0}",
ClangUtil::DumpDecl(parser_property_decl.decl));
context.AddNamedDecl(parser_property_decl.decl);
@@ -1316,10 +1238,8 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin(
DeclFromParser<ObjCIvarDecl> parser_ivar_decl(
origin_ivar_decl.Import(source));
if (parser_ivar_decl.IsValid()) {
- if (log) {
- LLDB_LOG(log, " CAS::FOPD[{0}] found\n{1}", current_id,
- ClangUtil::DumpDecl(parser_ivar_decl.decl));
- }
+ LLDB_LOG(log, " CAS::FOPD found\n{0}",
+ ClangUtil::DumpDecl(parser_ivar_decl.decl));
context.AddNamedDecl(parser_ivar_decl.decl);
found = true;
@@ -1332,9 +1252,6 @@ static bool FindObjCPropertyAndIvarDeclsWithOrigin(
void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
-
DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl(
cast<ObjCInterfaceDecl>(context.m_decl_context));
DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl(
@@ -1342,23 +1259,20 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
ConstString class_name(parser_iface_decl->getNameAsString().c_str());
- LLDB_LOGF(log,
- "ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on "
- "(ASTContext*)%p for '%s.%s'",
- current_id, static_cast<void *>(m_ast_context),
- parser_iface_decl->getNameAsString().c_str(),
- context.m_decl_name.getAsString().c_str());
+ LLDB_LOG(log,
+ "ClangASTSource::FindObjCPropertyAndIvarDecls on "
+ "(ASTContext*){0} '{1}' for '{2}.{3}'",
+ m_ast_context, m_clang_ast_context->getDisplayName(),
+ parser_iface_decl->getName(), context.m_decl_name.getAsString());
- if (FindObjCPropertyAndIvarDeclsWithOrigin(
- current_id, context, *this, origin_iface_decl))
+ if (FindObjCPropertyAndIvarDeclsWithOrigin(context, *this, origin_iface_decl))
return;
- LLDB_LOGF(log,
- "CAS::FOPD[%d] couldn't find the property on origin "
- "(ObjCInterfaceDecl*)%p/(ASTContext*)%p, searching "
- "elsewhere...",
- current_id, static_cast<const void *>(origin_iface_decl.decl),
- static_cast<void *>(&origin_iface_decl->getASTContext()));
+ LLDB_LOG(log,
+ "CAS::FOPD couldn't find the property on origin "
+ "(ObjCInterfaceDecl*){0}/(ASTContext*){1}, searching "
+ "elsewhere...",
+ origin_iface_decl.decl, &origin_iface_decl->getASTContext());
SymbolContext null_sc;
TypeList type_list;
@@ -1379,14 +1293,12 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
if (complete_iface_decl.decl == origin_iface_decl.decl)
break; // already checked this one
- LLDB_LOGF(log,
- "CAS::FOPD[%d] trying origin "
- "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id, static_cast<const void *>(complete_iface_decl.decl),
- static_cast<void *>(&complete_iface_decl->getASTContext()));
+ LLDB_LOG(log,
+ "CAS::FOPD trying origin "
+ "(ObjCInterfaceDecl*){0}/(ASTContext*){1}...",
+ complete_iface_decl.decl, &complete_iface_decl->getASTContext());
- FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *this,
- complete_iface_decl);
+ FindObjCPropertyAndIvarDeclsWithOrigin(context, *this, complete_iface_decl);
return;
} while (false);
@@ -1414,14 +1326,13 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
if (!interface_decl_from_modules.IsValid())
break;
- LLDB_LOGF(
- log,
- "CAS::FOPD[%d] trying module "
- "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id, static_cast<const void *>(interface_decl_from_modules.decl),
- static_cast<void *>(&interface_decl_from_modules->getASTContext()));
+ LLDB_LOG(log,
+ "CAS::FOPD[{0}] trying module "
+ "(ObjCInterfaceDecl*){0}/(ASTContext*){1}...",
+ interface_decl_from_modules.decl,
+ &interface_decl_from_modules->getASTContext());
- if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *this,
+ if (FindObjCPropertyAndIvarDeclsWithOrigin(context, *this,
interface_decl_from_modules))
return;
} while (false);
@@ -1459,19 +1370,43 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
if (!interface_decl_from_runtime.IsValid())
break;
- LLDB_LOGF(
- log,
- "CAS::FOPD[%d] trying runtime "
- "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id, static_cast<const void *>(interface_decl_from_runtime.decl),
- static_cast<void *>(&interface_decl_from_runtime->getASTContext()));
+ LLDB_LOG(log,
+ "CAS::FOPD[{0}] trying runtime "
+ "(ObjCInterfaceDecl*){0}/(ASTContext*){1}...",
+ interface_decl_from_runtime.decl,
+ &interface_decl_from_runtime->getASTContext());
- if (FindObjCPropertyAndIvarDeclsWithOrigin(
- current_id, context, *this, interface_decl_from_runtime))
+ if (FindObjCPropertyAndIvarDeclsWithOrigin(context, *this,
+ interface_decl_from_runtime))
return;
} while (false);
}
+void ClangASTSource::LookupInNamespace(NameSearchContext &context) {
+ const NamespaceDecl *namespace_context =
+ dyn_cast<NamespaceDecl>(context.m_decl_context);
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ ClangASTImporter::NamespaceMapSP namespace_map =
+ m_ast_importer_sp->GetNamespaceMap(namespace_context);
+
+ LLDB_LOGV(log, " CAS::FEVD Inspecting namespace map {0} ({1} entries)",
+ namespace_map.get(), namespace_map->size());
+
+ if (!namespace_map)
+ return;
+
+ for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
+ e = namespace_map->end();
+ i != e; ++i) {
+ LLDB_LOG(log, " CAS::FEVD Searching namespace {0} in module {1}",
+ i->second.GetName(), i->first->GetFileSpec().GetFilename());
+
+ FindExternalVisibleDecls(context, i->first, i->second);
+ }
+}
+
typedef llvm::DenseMap<const FieldDecl *, uint64_t> FieldOffsetMap;
typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetMap;
@@ -1557,17 +1492,14 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
FieldOffsetMap &field_offsets,
BaseOffsetMap &base_offsets,
BaseOffsetMap &virtual_base_offsets) {
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- LLDB_LOGF(log,
- "LayoutRecordType[%u] on (ASTContext*)%p for (RecordDecl*)%p "
- "[name = '%s']",
- current_id, static_cast<void *>(m_ast_context),
- static_cast<const void *>(record),
- record->getNameAsString().c_str());
+ LLDB_LOG(log,
+ "LayoutRecordType on (ASTContext*){0} '{1}' for (RecordDecl*)"
+ "{3} [name = '{4}']",
+ m_ast_context, m_clang_ast_context->getDisplayName(), record,
+ record->getName());
DeclFromParser<const RecordDecl> parser_record(record);
DeclFromUser<const RecordDecl> origin_record(
@@ -1580,7 +1512,7 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
BaseOffsetMap origin_base_offsets;
BaseOffsetMap origin_virtual_base_offsets;
- ClangASTContext::GetCompleteDecl(
+ TypeSystemClang::GetCompleteDecl(
&origin_record->getASTContext(),
const_cast<RecordDecl *>(origin_record.decl));
@@ -1631,25 +1563,23 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
m_ast_context->getCharWidth();
if (log) {
- LLDB_LOGF(log, "LRT[%u] returned:", current_id);
- LLDB_LOGF(log, "LRT[%u] Original = (RecordDecl*)%p", current_id,
- static_cast<const void *>(origin_record.decl));
- LLDB_LOGF(log, "LRT[%u] Size = %" PRId64, current_id, size);
- LLDB_LOGF(log, "LRT[%u] Alignment = %" PRId64, current_id, alignment);
- LLDB_LOGF(log, "LRT[%u] Fields:", current_id);
+ LLDB_LOG(log, "LRT returned:");
+ LLDB_LOG(log, "LRT Original = (RecordDecl*)%p",
+ static_cast<const void *>(origin_record.decl));
+ LLDB_LOG(log, "LRT Size = %" PRId64, size);
+ LLDB_LOG(log, "LRT Alignment = %" PRId64, alignment);
+ LLDB_LOG(log, "LRT Fields:");
for (RecordDecl::field_iterator fi = record->field_begin(),
fe = record->field_end();
fi != fe; ++fi) {
- LLDB_LOGF(log,
- "LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %" PRId64
- " bits",
- current_id, static_cast<void *>(*fi),
- fi->getNameAsString().c_str(), field_offsets[*fi]);
+ LLDB_LOG(log,
+ "LRT (FieldDecl*){0}, Name = '{1}', Offset = {2} bits",
+ *fi, fi->getName(), field_offsets[*fi]);
}
DeclFromParser<const CXXRecordDecl> parser_cxx_record =
DynCast<const CXXRecordDecl>(parser_record);
if (parser_cxx_record.IsValid()) {
- LLDB_LOGF(log, "LRT[%u] Bases:", current_id);
+ LLDB_LOG(log, "LRT Bases:");
for (CXXRecordDecl::base_class_const_iterator
bi = parser_cxx_record->bases_begin(),
be = parser_cxx_record->bases_end();
@@ -1662,19 +1592,17 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
DeclFromParser<CXXRecordDecl> base_cxx_record =
DynCast<CXXRecordDecl>(base_record);
- LLDB_LOGF(
- log,
- "LRT[%u] %s(CXXRecordDecl*)%p, Name = '%s', Offset = %" PRId64
- " chars",
- current_id, (is_virtual ? "Virtual " : ""),
- static_cast<void *>(base_cxx_record.decl),
- base_cxx_record.decl->getNameAsString().c_str(),
- (is_virtual
- ? virtual_base_offsets[base_cxx_record.decl].getQuantity()
- : base_offsets[base_cxx_record.decl].getQuantity()));
+ LLDB_LOG(log,
+ "LRT {0}(CXXRecordDecl*){1}, Name = '{2}', Offset = "
+ "{3} chars",
+ (is_virtual ? "Virtual " : ""), base_cxx_record.decl,
+ base_cxx_record.decl->getName(),
+ (is_virtual
+ ? virtual_base_offsets[base_cxx_record.decl].getQuantity()
+ : base_offsets[base_cxx_record.decl].getQuantity()));
}
} else {
- LLDB_LOGF(log, "LRD[%u] Not a CXXRecord, so no bases", current_id);
+ LLDB_LOG(log, "LRD Not a CXXRecord, so no bases");
}
}
@@ -1684,25 +1612,21 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
void ClangASTSource::CompleteNamespaceMap(
ClangASTImporter::NamespaceMapSP &namespace_map, ConstString name,
ClangASTImporter::NamespaceMapSP &parent_map) const {
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
if (log) {
if (parent_map && parent_map->size())
- LLDB_LOGF(log,
- "CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for "
- "namespace %s in namespace %s",
- current_id, static_cast<void *>(m_ast_context),
- name.GetCString(),
- parent_map->begin()->second.GetName().AsCString());
+ LLDB_LOG(log,
+ "CompleteNamespaceMap on (ASTContext*){0} '{1}' Searching "
+ "for namespace {2} in namespace {3}",
+ m_ast_context, m_clang_ast_context->getDisplayName(), name,
+ parent_map->begin()->second.GetName());
else
- LLDB_LOGF(log,
- "CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for "
- "namespace %s",
- current_id, static_cast<void *>(m_ast_context),
- name.GetCString());
+ LLDB_LOG(log,
+ "CompleteNamespaceMap on (ASTContext*){0} '{1}' Searching "
+ "for namespace {2}",
+ m_ast_context, m_clang_ast_context->getDisplayName(), name);
}
if (parent_map) {
@@ -1720,7 +1644,7 @@ void ClangASTSource::CompleteNamespaceMap(
continue;
found_namespace_decl =
- symbol_file->FindNamespace(name, &module_parent_namespace_decl);
+ symbol_file->FindNamespace(name, module_parent_namespace_decl);
if (!found_namespace_decl)
continue;
@@ -1728,9 +1652,8 @@ void ClangASTSource::CompleteNamespaceMap(
namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(
module_sp, found_namespace_decl));
- LLDB_LOGF(log, " CMN[%u] Found namespace %s in module %s", current_id,
- name.GetCString(),
- module_sp->GetFileSpec().GetFilename().GetCString());
+ LLDB_LOG(log, " CMN Found namespace {0} in module {1}", name,
+ module_sp->GetFileSpec().GetFilename());
}
} else {
const ModuleList &target_images = m_target->GetImages();
@@ -1752,7 +1675,7 @@ void ClangASTSource::CompleteNamespaceMap(
continue;
found_namespace_decl =
- symbol_file->FindNamespace(name, &null_namespace_decl);
+ symbol_file->FindNamespace(name, null_namespace_decl);
if (!found_namespace_decl)
continue;
@@ -1760,9 +1683,8 @@ void ClangASTSource::CompleteNamespaceMap(
namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(
image, found_namespace_decl));
- LLDB_LOGF(log, " CMN[%u] Found namespace %s in module %s", current_id,
- name.GetCString(),
- image->GetFileSpec().GetFilename().GetCString());
+ LLDB_LOG(log, " CMN[{0}] Found namespace {0} in module {1}", name,
+ image->GetFileSpec().GetFilename());
}
}
}
@@ -1776,11 +1698,11 @@ NamespaceDecl *ClangASTSource::AddNamespace(
const CompilerDeclContext &namespace_decl = namespace_decls->begin()->second;
clang::ASTContext *src_ast =
- ClangASTContext::DeclContextGetClangASTContext(namespace_decl);
+ TypeSystemClang::DeclContextGetTypeSystemClang(namespace_decl);
if (!src_ast)
return nullptr;
clang::NamespaceDecl *src_namespace_decl =
- ClangASTContext::DeclContextGetAsNamespaceDecl(namespace_decl);
+ TypeSystemClang::DeclContextGetAsNamespaceDecl(namespace_decl);
if (!src_namespace_decl)
return nullptr;
@@ -1804,42 +1726,21 @@ NamespaceDecl *ClangASTSource::AddNamespace(
}
clang::Decl *ClangASTSource::CopyDecl(Decl *src_decl) {
- if (m_ast_importer_sp) {
- return m_ast_importer_sp->CopyDecl(m_ast_context, src_decl);
- } else {
- lldbassert(0 && "No mechanism for copying a decl!");
- return nullptr;
- }
+ return m_ast_importer_sp->CopyDecl(m_ast_context, src_decl);
}
ClangASTImporter::DeclOrigin ClangASTSource::GetDeclOrigin(const clang::Decl *decl) {
- if (m_ast_importer_sp) {
- return m_ast_importer_sp->GetDeclOrigin(decl);
- } else {
- // this can happen early enough that no ExternalASTSource is installed.
- return ClangASTImporter::DeclOrigin();
- }
+ return m_ast_importer_sp->GetDeclOrigin(decl);
}
CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) {
- ClangASTContext *src_ast =
- llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem());
+ TypeSystemClang *src_ast =
+ llvm::dyn_cast_or_null<TypeSystemClang>(src_type.GetTypeSystem());
if (src_ast == nullptr)
return CompilerType();
- SetImportInProgress(true);
-
- QualType copied_qual_type;
-
- if (m_ast_importer_sp) {
- copied_qual_type = ClangUtil::GetQualType(
- m_ast_importer_sp->CopyType(*m_clang_ast_context, src_type));
- } else {
- lldbassert(0 && "No mechanism for copying a type!");
- return CompilerType();
- }
-
- SetImportInProgress(false);
+ QualType copied_qual_type = ClangUtil::GetQualType(
+ m_ast_importer_sp->CopyType(*m_clang_ast_context, src_type));
if (copied_qual_type.getAsOpaquePtr() &&
copied_qual_type->getCanonicalTypeInternal().isNull())
@@ -1849,170 +1750,3 @@ CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) {
return m_clang_ast_context->GetType(copied_qual_type);
}
-
-clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) {
- assert(type && "Type for variable must be valid!");
-
- if (!type.IsValid())
- return nullptr;
-
- ClangASTContext *lldb_ast =
- llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
- if (!lldb_ast)
- return nullptr;
-
- IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();
-
- clang::ASTContext &ast = lldb_ast->getASTContext();
-
- clang::NamedDecl *Decl = VarDecl::Create(
- ast, const_cast<DeclContext *>(m_decl_context), SourceLocation(),
- SourceLocation(), ii, ClangUtil::GetQualType(type), nullptr, SC_Static);
- m_decls.push_back(Decl);
-
- return Decl;
-}
-
-clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type,
- bool extern_c) {
- assert(type && "Type for variable must be valid!");
-
- if (!type.IsValid())
- return nullptr;
-
- if (m_function_types.count(type))
- return nullptr;
-
- ClangASTContext *lldb_ast =
- llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
- if (!lldb_ast)
- return nullptr;
-
- m_function_types.insert(type);
-
- QualType qual_type(ClangUtil::GetQualType(type));
-
- clang::ASTContext &ast = lldb_ast->getASTContext();
-
- const bool isInlineSpecified = false;
- const bool hasWrittenPrototype = true;
- const bool isConstexprSpecified = false;
-
- clang::DeclContext *context = const_cast<DeclContext *>(m_decl_context);
-
- if (extern_c) {
- context = LinkageSpecDecl::Create(
- ast, context, SourceLocation(), SourceLocation(),
- clang::LinkageSpecDecl::LanguageIDs::lang_c, false);
- }
-
- // Pass the identifier info for functions the decl_name is needed for
- // operators
- clang::DeclarationName decl_name =
- m_decl_name.getNameKind() == DeclarationName::Identifier
- ? m_decl_name.getAsIdentifierInfo()
- : m_decl_name;
-
- clang::FunctionDecl *func_decl = FunctionDecl::Create(
- ast, context, SourceLocation(), SourceLocation(), decl_name, qual_type,
- nullptr, SC_Extern, isInlineSpecified, hasWrittenPrototype,
- isConstexprSpecified ? CSK_constexpr : CSK_unspecified);
-
- // We have to do more than just synthesize the FunctionDecl. We have to
- // synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do
- // this, we raid the function's FunctionProtoType for types.
-
- const FunctionProtoType *func_proto_type =
- qual_type.getTypePtr()->getAs<FunctionProtoType>();
-
- if (func_proto_type) {
- unsigned NumArgs = func_proto_type->getNumParams();
- unsigned ArgIndex;
-
- SmallVector<ParmVarDecl *, 5> parm_var_decls;
-
- for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex) {
- QualType arg_qual_type(func_proto_type->getParamType(ArgIndex));
-
- parm_var_decls.push_back(
- ParmVarDecl::Create(ast, const_cast<DeclContext *>(context),
- SourceLocation(), SourceLocation(), nullptr,
- arg_qual_type, nullptr, SC_Static, nullptr));
- }
-
- func_decl->setParams(ArrayRef<ParmVarDecl *>(parm_var_decls));
- } else {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
-
- LLDB_LOGF(log, "Function type wasn't a FunctionProtoType");
- }
-
- // If this is an operator (e.g. operator new or operator==), only insert the
- // declaration we inferred from the symbol if we can provide the correct
- // number of arguments. We shouldn't really inject random decl(s) for
- // functions that are analyzed semantically in a special way, otherwise we
- // will crash in clang.
- clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
- if (func_proto_type &&
- ClangASTContext::IsOperator(decl_name.getAsString().c_str(), op_kind)) {
- if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount(
- false, op_kind, func_proto_type->getNumParams()))
- return nullptr;
- }
- m_decls.push_back(func_decl);
-
- return func_decl;
-}
-
-clang::NamedDecl *NameSearchContext::AddGenericFunDecl() {
- FunctionProtoType::ExtProtoInfo proto_info;
-
- proto_info.Variadic = true;
-
- QualType generic_function_type(m_ast_source.m_ast_context->getFunctionType(
- m_ast_source.m_ast_context->UnknownAnyTy, // result
- ArrayRef<QualType>(), // argument types
- proto_info));
-
- return AddFunDecl(
- m_ast_source.m_clang_ast_context->GetType(generic_function_type), true);
-}
-
-clang::NamedDecl *
-NameSearchContext::AddTypeDecl(const CompilerType &clang_type) {
- if (ClangUtil::IsClangType(clang_type)) {
- QualType qual_type = ClangUtil::GetQualType(clang_type);
-
- if (const TypedefType *typedef_type =
- llvm::dyn_cast<TypedefType>(qual_type)) {
- TypedefNameDecl *typedef_name_decl = typedef_type->getDecl();
-
- m_decls.push_back(typedef_name_decl);
-
- return (NamedDecl *)typedef_name_decl;
- } else if (const TagType *tag_type = qual_type->getAs<TagType>()) {
- TagDecl *tag_decl = tag_type->getDecl();
-
- m_decls.push_back(tag_decl);
-
- return tag_decl;
- } else if (const ObjCObjectType *objc_object_type =
- qual_type->getAs<ObjCObjectType>()) {
- ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface();
-
- m_decls.push_back((NamedDecl *)interface_decl);
-
- return (NamedDecl *)interface_decl;
- }
- }
- return nullptr;
-}
-
-void NameSearchContext::AddLookupResult(clang::DeclContextLookupResult result) {
- for (clang::NamedDecl *decl : result)
- m_decls.push_back(decl);
-}
-
-void NameSearchContext::AddNamedDecl(clang::NamedDecl *decl) {
- m_decls.push_back(decl);
-}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
index 3149b4266b2f..14761fbeb26b 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
@@ -6,12 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangASTSource_h_
-#define liblldb_ClangASTSource_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H
#include <set>
-#include "lldb/Symbol/ClangASTImporter.h"
+#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
+#include "Plugins/ExpressionParser/Clang/NameSearchContext.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Target/Target.h"
#include "clang/AST/ExternalASTSource.h"
@@ -42,7 +43,7 @@ public:
/// \param[in] importer
/// The ClangASTImporter to use.
ClangASTSource(const lldb::TargetSP &target,
- const lldb::ClangASTImporterSP &importer);
+ const std::shared_ptr<ClangASTImporter> &importer);
/// Destructor
~ClangASTSource() override;
@@ -60,7 +61,7 @@ public:
}
void MaterializeVisibleDecls(const clang::DeclContext *DC) { return; }
- void InstallASTContext(ClangASTContext &ast_context);
+ void InstallASTContext(TypeSystemClang &ast_context);
//
// APIs for ExternalASTSource
@@ -196,11 +197,6 @@ public:
clang::Sema *getSema();
- void SetImportInProgress(bool import_in_progress) {
- m_import_in_progress = import_in_progress;
- }
- bool GetImportInProgress() { return m_import_in_progress; }
-
void SetLookupsEnabled(bool lookups_enabled) {
m_lookups_enabled = lookups_enabled;
}
@@ -282,14 +278,9 @@ protected:
///
/// \param[in] namespace_decl
/// If valid and module is non-NULL, the parent namespace.
- ///
- /// \param[in] current_id
- /// The ID for the current FindExternalVisibleDecls invocation,
- /// for logging purposes.
void FindExternalVisibleDecls(NameSearchContext &context,
lldb::ModuleSP module,
- CompilerDeclContext &namespace_decl,
- unsigned int current_id);
+ CompilerDeclContext &namespace_decl);
/// Find all Objective-C methods matching a given selector.
///
@@ -307,7 +298,13 @@ protected:
/// is the containing object.
void FindObjCPropertyAndIvarDecls(NameSearchContext &context);
- /// A wrapper for ClangASTContext::CopyType that sets a flag that
+ /// Performs lookup into a namespace.
+ ///
+ /// \param context
+ /// The NameSearchContext for a lookup inside a namespace.
+ void LookupInNamespace(NameSearchContext &context);
+
+ /// A wrapper for TypeSystemClang::CopyType that sets a flag that
/// indicates that we should not respond to queries during import.
///
/// \param[in] src_type
@@ -331,7 +328,6 @@ public:
/// global lookup for performance reasons.
bool IgnoreName(const ConstString name, bool ignore_all_dollar_names);
-public:
/// Copies a single Decl into the parser's AST context.
///
/// \param[in] src_decl
@@ -346,139 +342,51 @@ public:
/// \param[in] decl
/// The Decl whose origin is to be found.
///
- /// \param[out] original_decl
- /// A pointer whose target is filled in with the original Decl.
- ///
- /// \param[in] original_ctx
- /// A pointer whose target is filled in with the original's ASTContext.
- ///
/// \return
/// True if lookup succeeded; false otherwise.
ClangASTImporter::DeclOrigin GetDeclOrigin(const clang::Decl *decl);
+ /// Returns the TypeSystem that uses this ClangASTSource instance as it's
+ /// ExternalASTSource.
+ TypeSystemClang *GetTypeSystem() const { return m_clang_ast_context; }
+
protected:
bool FindObjCMethodDeclsWithOrigin(
- unsigned int current_id, NameSearchContext &context,
+ NameSearchContext &context,
clang::ObjCInterfaceDecl *original_interface_decl, const char *log_info);
+ void FindDeclInModules(NameSearchContext &context, ConstString name);
+ void FindDeclInObjCRuntime(NameSearchContext &context, ConstString name);
+
+ /// Fills the namespace map of the given NameSearchContext.
+ ///
+ /// \param context The NameSearchContext with the namespace map to fill.
+ /// \param module_sp The module to search for namespaces or a nullptr if
+ /// the current target should be searched.
+ /// \param namespace_decl The DeclContext in which to search for namespaces.
+ void FillNamespaceMap(NameSearchContext &context, lldb::ModuleSP module_sp,
+ const CompilerDeclContext &namespace_decl);
+
+ clang::TagDecl *FindCompleteType(const clang::TagDecl *decl);
+
friend struct NameSearchContext;
- bool m_import_in_progress;
bool m_lookups_enabled;
/// The target to use in finding variables and types.
const lldb::TargetSP m_target;
/// The AST context requests are coming in for.
clang::ASTContext *m_ast_context;
- /// The ClangASTContext for m_ast_context.
- ClangASTContext *m_clang_ast_context;
+ /// The TypeSystemClang for m_ast_context.
+ TypeSystemClang *m_clang_ast_context;
/// The file manager paired with the AST context.
clang::FileManager *m_file_manager;
/// The target's AST importer.
- lldb::ClangASTImporterSP m_ast_importer_sp;
+ std::shared_ptr<ClangASTImporter> m_ast_importer_sp;
std::set<const clang::Decl *> m_active_lexical_decls;
std::set<const char *> m_active_lookups;
};
-/// \class NameSearchContext ClangASTSource.h
-/// "lldb/Expression/ClangASTSource.h" Container for all objects relevant to a
-/// single name lookup
-///
-/// LLDB needs to create Decls for entities it finds. This class communicates
-/// what name is being searched for and provides helper functions to construct
-/// Decls given appropriate type information.
-struct NameSearchContext {
- /// The AST source making the request.
- ClangASTSource &m_ast_source;
- /// The list of declarations already constructed.
- llvm::SmallVectorImpl<clang::NamedDecl *> &m_decls;
- /// The mapping of all namespaces found for this request back to their
- /// modules.
- ClangASTImporter::NamespaceMapSP m_namespace_map;
- /// The name being looked for.
- const clang::DeclarationName &m_decl_name;
- /// The DeclContext to put declarations into.
- const clang::DeclContext *m_decl_context;
- /// All the types of functions that have been reported, so we don't
- /// report conflicts.
- llvm::SmallSet<CompilerType, 5> m_function_types;
-
- struct {
- bool variable : 1;
- bool function_with_type_info : 1;
- bool function : 1;
- bool local_vars_nsp : 1;
- bool type : 1;
- } m_found;
-
- /// Constructor
- ///
- /// Initializes class variables.
- ///
- /// \param[in] astSource
- /// A reference to the AST source making a request.
- ///
- /// \param[in] decls
- /// A reference to a list into which new Decls will be placed. This
- /// list is typically empty when the function is called.
- ///
- /// \param[in] name
- /// The name being searched for (always an Identifier).
- ///
- /// \param[in] dc
- /// The DeclContext to register Decls in.
- NameSearchContext(ClangASTSource &astSource,
- llvm::SmallVectorImpl<clang::NamedDecl *> &decls,
- clang::DeclarationName &name, const clang::DeclContext *dc)
- : m_ast_source(astSource), m_decls(decls), m_decl_name(name),
- m_decl_context(dc) {
- memset(&m_found, 0, sizeof(m_found));
- }
-
- /// Create a VarDecl with the name being searched for and the provided type
- /// and register it in the right places.
- ///
- /// \param[in] type
- /// The opaque QualType for the VarDecl being registered.
- clang::NamedDecl *AddVarDecl(const CompilerType &type);
-
- /// Create a FunDecl with the name being searched for and the provided type
- /// and register it in the right places.
- ///
- /// \param[in] type
- /// The opaque QualType for the FunDecl being registered.
- ///
- /// \param[in] extern_c
- /// If true, build an extern "C" linkage specification for this.
- clang::NamedDecl *AddFunDecl(const CompilerType &type, bool extern_c = false);
-
- /// Create a FunDecl with the name being searched for and generic type (i.e.
- /// intptr_t NAME_GOES_HERE(...)) and register it in the right places.
- clang::NamedDecl *AddGenericFunDecl();
-
- /// Create a TypeDecl with the name being searched for and the provided type
- /// and register it in the right places.
- ///
- /// \param[in] compiler_type
- /// The opaque QualType for the TypeDecl being registered.
- clang::NamedDecl *AddTypeDecl(const CompilerType &compiler_type);
-
- /// Add Decls from the provided DeclContextLookupResult to the list of
- /// results.
- ///
- /// \param[in] result
- /// The DeclContextLookupResult, usually returned as the result
- /// of querying a DeclContext.
- void AddLookupResult(clang::DeclContextLookupResult result);
-
- /// Add a NamedDecl to the list of results.
- ///
- /// \param[in] decl
- /// The NamedDecl, usually returned as the result
- /// of querying a DeclContext.
- void AddNamedDecl(clang::NamedDecl *decl);
-};
-
} // namespace lldb_private
-#endif // liblldb_ClangASTSource_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp
index c87507a25855..867d4ff0a907 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.cpp
@@ -1,4 +1,4 @@
-//===-- ClangDeclVendor.cpp -------------------------------------*- C++ -*-===//
+//===-- ClangDeclVendor.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -7,8 +7,9 @@
//===----------------------------------------------------------------------===//
#include "Plugins/ExpressionParser/Clang/ClangDeclVendor.h"
+#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Utility/ConstString.h"
using namespace lldb_private;
@@ -22,7 +23,7 @@ uint32_t ClangDeclVendor::FindDecls(ConstString name, bool append,
std::vector<CompilerDecl> compiler_decls;
uint32_t ret = FindDecls(name, /*append*/ false, max_matches, compiler_decls);
for (CompilerDecl compiler_decl : compiler_decls) {
- clang::Decl *d = static_cast<clang::Decl *>(compiler_decl.GetOpaqueDecl());
+ clang::Decl *d = ClangUtil::GetDecl(compiler_decl);
clang::NamedDecl *nd = llvm::cast<clang::NamedDecl>(d);
decls.push_back(nd);
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h
index 0c888de08841..bf52bec4b1fa 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h
@@ -6,12 +6,15 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangDeclVendor_h_
-#define liblldb_ClangDeclVendor_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGDECLVENDOR_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGDECLVENDOR_H
-#include "lldb/Core/ClangForward.h"
#include "lldb/Symbol/DeclVendor.h"
+namespace clang {
+class NamedDecl;
+}
+
namespace lldb_private {
// A clang specialized extension to DeclVendor.
@@ -32,7 +35,8 @@ public:
}
private:
- DISALLOW_COPY_AND_ASSIGN(ClangDeclVendor);
+ ClangDeclVendor(const ClangDeclVendor &) = delete;
+ const ClangDeclVendor &operator=(const ClangDeclVendor &) = delete;
};
} // namespace lldb_private
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
index 48cd1c4b99fa..7459b715dbe2 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_ClangDiagnostic_h
-#define lldb_ClangDiagnostic_h
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGDIAGNOSTIC_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGDIAGNOSTIC_H
#include <vector>
@@ -47,4 +47,4 @@ private:
};
} // namespace lldb_private
-#endif /* lldb_ClangDiagnostic_h */
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGDIAGNOSTIC_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index bf3023be5f60..8c49898e1d6c 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -1,4 +1,4 @@
-//===-- ClangExpressionDeclMap.cpp -----------------------------*- C++ -*-===//
+//===-- ClangExpressionDeclMap.cpp ----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -11,15 +11,15 @@
#include "ClangASTSource.h"
#include "ClangModulesDeclVendor.h"
#include "ClangPersistentVariables.h"
+#include "ClangUtil.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Expression/Materializer.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/CompilerDecl.h"
#include "lldb/Symbol/CompilerDeclContext.h"
@@ -65,8 +65,8 @@ const char *g_lldb_local_vars_namespace_cstr = "$__lldb_local_vars";
ClangExpressionDeclMap::ClangExpressionDeclMap(
bool keep_result_in_memory,
Materializer::PersistentVariableDelegate *result_delegate,
- const lldb::TargetSP &target, const lldb::ClangASTImporterSP &importer,
- ValueObject *ctx_obj)
+ const lldb::TargetSP &target,
+ const std::shared_ptr<ClangASTImporter> &importer, ValueObject *ctx_obj)
: ClangASTSource(target, importer), m_found_entities(), m_struct_members(),
m_keep_result_in_memory(keep_result_in_memory),
m_result_delegate(result_delegate), m_ctx_obj(ctx_obj), m_parser_vars(),
@@ -109,7 +109,7 @@ bool ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx,
m_parser_vars->m_persistent_vars = llvm::cast<ClangPersistentVariables>(
target->GetPersistentExpressionStateForLanguage(eLanguageTypeC));
- if (!ClangASTContext::GetScratch(*target))
+ if (!TypeSystemClang::GetScratch(*target))
return false;
}
@@ -174,19 +174,14 @@ ClangExpressionDeclMap::TargetInfo ClangExpressionDeclMap::GetTargetInfo() {
return ret;
}
-TypeFromUser ClangExpressionDeclMap::DeportType(ClangASTContext &target,
- ClangASTContext &source,
+TypeFromUser ClangExpressionDeclMap::DeportType(TypeSystemClang &target,
+ TypeSystemClang &source,
TypeFromParser parser_type) {
- assert(&target == ClangASTContext::GetScratch(*m_target));
+ assert(&target == TypeSystemClang::GetScratch(*m_target));
assert((TypeSystem *)&source == parser_type.GetTypeSystem());
assert(&source.getASTContext() == m_ast_context);
- if (m_ast_importer_sp) {
- return TypeFromUser(m_ast_importer_sp->DeportType(target, parser_type));
- } else {
- lldbassert(0 && "No mechanism for deporting a type!");
- return TypeFromUser();
- }
+ return TypeFromUser(m_ast_importer_sp->DeportType(target, parser_type));
}
bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
@@ -196,8 +191,8 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
bool is_lvalue) {
assert(m_parser_vars.get());
- ClangASTContext *ast =
- llvm::dyn_cast_or_null<ClangASTContext>(parser_type.GetTypeSystem());
+ TypeSystemClang *ast =
+ llvm::dyn_cast_or_null<TypeSystemClang>(parser_type.GetTypeSystem());
if (ast == nullptr)
return false;
@@ -209,7 +204,7 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
if (target == nullptr)
return false;
- auto *clang_ast_context = ClangASTContext::GetScratch(*target);
+ auto *clang_ast_context = TypeSystemClang::GetScratch(*target);
if (!clang_ast_context)
return false;
@@ -231,7 +226,6 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
var->GetParserVars(GetParserID());
parser_vars->m_named_decl = decl;
- parser_vars->m_parser_type = parser_type;
var->EnableJITVars(GetParserID());
@@ -248,14 +242,14 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
if (target == nullptr)
return false;
- ClangASTContext *context = ClangASTContext::GetScratch(*target);
+ TypeSystemClang *context = TypeSystemClang::GetScratch(*target);
if (!context)
return false;
TypeFromUser user_type = DeportType(*context, *ast, parser_type);
if (!user_type.GetOpaqueQualType()) {
- LLDB_LOGF(log, "Persistent variable's type wasn't copied successfully");
+ LLDB_LOG(log, "Persistent variable's type wasn't copied successfully");
return false;
}
@@ -297,7 +291,7 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
var->m_flags |= ClangExpressionVariable::EVKeepInTarget;
}
- LLDB_LOGF(log, "Created persistent variable with flags 0x%hx", var->m_flags);
+ LLDB_LOG(log, "Created persistent variable with flags {0:x}", var->m_flags);
var->EnableParserVars(GetParserID());
@@ -305,7 +299,6 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
var->GetParserVars(GetParserID());
parser_vars->m_named_decl = decl;
- parser_vars->m_parser_type = parser_type;
return true;
}
@@ -339,9 +332,8 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl,
if (!var)
return false;
- LLDB_LOGF(log, "Adding value for (NamedDecl*)%p [%s - %s] to the structure",
- static_cast<const void *>(decl), name.GetCString(),
- var->GetName().GetCString());
+ LLDB_LOG(log, "Adding value for (NamedDecl*)%p [%s - %s] to the structure",
+ decl, name, var->GetName());
// We know entity->m_parser_vars is valid because we used a parser variable
// to find it
@@ -355,8 +347,7 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl,
llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID())) {
// We already laid this out; do not touch
- LLDB_LOGF(log, "Already placed at 0x%llx",
- (unsigned long long)jit_vars->m_offset);
+ LLDB_LOG(log, "Already placed at {0:x}", jit_vars->m_offset);
}
llvm::cast<ClangExpressionVariable>(var)->EnableJITVars(GetParserID());
@@ -391,7 +382,7 @@ bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl,
if (!err.Success())
return false;
- LLDB_LOGF(log, "Placed at 0x%llx", (unsigned long long)offset);
+ LLDB_LOG(log, "Placed at {0:x}", offset);
jit_vars->m_offset =
offset; // TODO DoStructLayout() should not change this.
@@ -600,7 +591,7 @@ addr_t ClangExpressionDeclMap::GetSymbolAddress(ConstString name,
lldb::VariableSP ClangExpressionDeclMap::FindGlobalVariable(
Target &target, ModuleSP &module, ConstString name,
- CompilerDeclContext *namespace_decl) {
+ const CompilerDeclContext &namespace_decl) {
VariableList vars;
if (module && namespace_decl)
@@ -613,7 +604,7 @@ lldb::VariableSP ClangExpressionDeclMap::FindGlobalVariable(
return vars.GetVariableAtIndex(0);
}
-ClangASTContext *ClangExpressionDeclMap::GetClangASTContext() {
+TypeSystemClang *ClangExpressionDeclMap::GetTypeSystemClang() {
StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
if (frame == nullptr)
return nullptr;
@@ -627,7 +618,7 @@ ClangASTContext *ClangExpressionDeclMap::GetClangASTContext() {
if (!frame_decl_context)
return nullptr;
- return llvm::dyn_cast_or_null<ClangASTContext>(
+ return llvm::dyn_cast_or_null<TypeSystemClang>(
frame_decl_context.GetTypeSystem());
}
@@ -641,34 +632,23 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (GetImportInProgress()) {
- if (log && log->GetVerbose())
- LLDB_LOGF(log, "Ignoring a query during an import");
- return;
- }
-
- static unsigned int invocation_id = 0;
- unsigned int current_id = invocation_id++;
-
if (log) {
if (!context.m_decl_context)
- LLDB_LOGF(log,
- "ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
- "'%s' in a NULL DeclContext",
- current_id, name.GetCString());
+ LLDB_LOG(log,
+ "ClangExpressionDeclMap::FindExternalVisibleDecls for "
+ "'{0}' in a NULL DeclContext",
+ name);
else if (const NamedDecl *context_named_decl =
dyn_cast<NamedDecl>(context.m_decl_context))
- LLDB_LOGF(log,
- "ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
- "'%s' in '%s'",
- current_id, name.GetCString(),
- context_named_decl->getNameAsString().c_str());
+ LLDB_LOG(log,
+ "ClangExpressionDeclMap::FindExternalVisibleDecls for "
+ "'{0}' in '{1}'",
+ name, context_named_decl->getNameAsString());
else
- LLDB_LOGF(log,
- "ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
- "'%s' in a '%s'",
- current_id, name.GetCString(),
- context.m_decl_context->getDeclKindName());
+ LLDB_LOG(log,
+ "ClangExpressionDeclMap::FindExternalVisibleDecls for "
+ "'{0}' in a '{1}'",
+ name, context.m_decl_context->getDeclKindName());
}
if (const NamespaceDecl *namespace_context =
@@ -678,42 +658,31 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
CompilerDeclContext compiler_decl_ctx =
m_clang_ast_context->CreateDeclContext(
const_cast<clang::DeclContext *>(context.m_decl_context));
- FindExternalVisibleDecls(context, lldb::ModuleSP(), compiler_decl_ctx,
- current_id);
+ FindExternalVisibleDecls(context, lldb::ModuleSP(), compiler_decl_ctx);
return;
}
ClangASTImporter::NamespaceMapSP namespace_map =
- m_ast_importer_sp
- ? m_ast_importer_sp->GetNamespaceMap(namespace_context)
- : ClangASTImporter::NamespaceMapSP();
+ m_ast_importer_sp->GetNamespaceMap(namespace_context);
if (!namespace_map)
return;
- if (log && log->GetVerbose())
- log->Printf(" CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)",
- current_id, static_cast<void *>(namespace_map.get()),
- (int)namespace_map->size());
+ LLDB_LOGV(log, " CEDM::FEVD Inspecting (NamespaceMap*){0:x} ({1} entries)",
+ namespace_map.get(), namespace_map->size());
- for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
- e = namespace_map->end();
- i != e; ++i) {
- if (log)
- log->Printf(" CEDM::FEVD[%u] Searching namespace %s in module %s",
- current_id, i->second.GetName().AsCString(),
- i->first->GetFileSpec().GetFilename().GetCString());
+ for (ClangASTImporter::NamespaceMapItem &n : *namespace_map) {
+ LLDB_LOG(log, " CEDM::FEVD Searching namespace {0} in module {1}",
+ n.second.GetName(), n.first->GetFileSpec().GetFilename());
- FindExternalVisibleDecls(context, i->first, i->second, current_id);
+ FindExternalVisibleDecls(context, n.first, n.second);
}
} else if (isa<TranslationUnitDecl>(context.m_decl_context)) {
CompilerDeclContext namespace_decl;
- if (log)
- log->Printf(" CEDM::FEVD[%u] Searching the root namespace", current_id);
+ LLDB_LOG(log, " CEDM::FEVD Searching the root namespace");
- FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl,
- current_id);
+ FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl);
}
ClangASTSource::FindExternalVisibleDecls(context);
@@ -734,7 +703,7 @@ clang::NamedDecl *ClangExpressionDeclMap::GetPersistentDecl(ConstString name) {
if (!target)
return nullptr;
- ClangASTContext::GetScratch(*target);
+ TypeSystemClang::GetScratch(*target);
if (!m_parser_vars->m_persistent_vars)
return nullptr;
@@ -742,8 +711,7 @@ clang::NamedDecl *ClangExpressionDeclMap::GetPersistentDecl(ConstString name) {
}
void ClangExpressionDeclMap::SearchPersistenDecls(NameSearchContext &context,
- const ConstString name,
- unsigned int current_id) {
+ const ConstString name) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
NamedDecl *persistent_decl = GetPersistentDecl(name);
@@ -766,14 +734,12 @@ void ClangExpressionDeclMap::SearchPersistenDecls(NameSearchContext &context,
MaybeRegisterFunctionBody(parser_function_decl);
}
- LLDB_LOGF(log, " CEDM::FEVD[%u] Found persistent decl %s", current_id,
- name.GetCString());
+ LLDB_LOG(log, " CEDM::FEVD Found persistent decl %s", name);
context.AddNamedDecl(parser_named_decl);
}
-void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context,
- unsigned int current_id) {
+void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
@@ -788,8 +754,7 @@ void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context,
if (!ctx_obj_ptr || status.Fail())
return;
- AddThisType(context, TypeFromUser(m_ctx_obj->GetCompilerType()),
- current_id);
+ AddContextClassType(context, TypeFromUser(m_ctx_obj->GetCompilerType()));
m_struct_vars->m_object_pointer_type =
TypeFromUser(ctx_obj_ptr->GetCompilerType());
@@ -814,7 +779,7 @@ void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context,
return;
clang::CXXMethodDecl *method_decl =
- ClangASTContext::DeclContextGetAsCXXMethodDecl(function_decl_ctx);
+ TypeSystemClang::DeclContextGetAsCXXMethodDecl(function_decl_ctx);
if (method_decl) {
clang::CXXRecordDecl *class_decl = method_decl->getParent();
@@ -824,10 +789,10 @@ void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context,
TypeFromUser class_user_type(class_qual_type.getAsOpaquePtr(),
function_decl_ctx.GetTypeSystem());
- LLDB_LOG(log, " CEDM::FEVD[{0}] Adding type for $__lldb_class: {1}",
- current_id, class_qual_type.getAsString());
+ LLDB_LOG(log, " CEDM::FEVD Adding type for $__lldb_class: {1}",
+ class_qual_type.getAsString());
- AddThisType(context, class_user_type, current_id);
+ AddContextClassType(context, class_user_type);
if (method_decl->isInstance()) {
// self is a pointer to the object
@@ -866,17 +831,16 @@ void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context,
TypeFromUser pointee_type =
this_type->GetForwardCompilerType().GetPointeeType();
- LLDB_LOG(log, " FEVD[{0}] Adding type for $__lldb_class: {1}", current_id,
+ LLDB_LOG(log, " FEVD Adding type for $__lldb_class: {1}",
ClangUtil::GetQualType(pointee_type).getAsString());
- AddThisType(context, pointee_type, current_id);
+ AddContextClassType(context, pointee_type);
TypeFromUser this_user_type(this_type->GetFullCompilerType());
m_struct_vars->m_object_pointer_type = this_user_type;
}
}
-void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context,
- unsigned int current_id) {
+void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
@@ -887,7 +851,7 @@ void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context,
if (!ctx_obj_ptr || status.Fail())
return;
- AddOneType(context, TypeFromUser(m_ctx_obj->GetCompilerType()), current_id);
+ AddOneType(context, TypeFromUser(m_ctx_obj->GetCompilerType()));
m_struct_vars->m_object_pointer_type =
TypeFromUser(ctx_obj_ptr->GetCompilerType());
@@ -915,7 +879,7 @@ void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context,
return;
clang::ObjCMethodDecl *method_decl =
- ClangASTContext::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
+ TypeSystemClang::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
if (method_decl) {
ObjCInterfaceDecl *self_interface = method_decl->getClassInterface();
@@ -933,9 +897,9 @@ void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context,
function_decl_ctx.GetTypeSystem());
LLDB_LOG(log, " FEVD[{0}] Adding type for $__lldb_objc_class: {1}",
- current_id, ClangUtil::ToString(interface_type));
+ ClangUtil::ToString(interface_type));
- AddOneType(context, class_user_type, current_id);
+ AddOneType(context, class_user_type);
if (method_decl->isInstanceMethod()) {
// self is a pointer to the object
@@ -984,10 +948,10 @@ void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context,
CompilerType self_clang_type = self_type->GetFullCompilerType();
- if (ClangASTContext::IsObjCClassType(self_clang_type)) {
+ if (TypeSystemClang::IsObjCClassType(self_clang_type)) {
return;
}
- if (!ClangASTContext::IsObjCObjectPointerType(self_clang_type))
+ if (!TypeSystemClang::IsObjCObjectPointerType(self_clang_type))
return;
self_clang_type = self_clang_type.GetPointeeType();
@@ -995,11 +959,11 @@ void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context,
return;
LLDB_LOG(log, " FEVD[{0}] Adding type for $__lldb_objc_class: {1}",
- current_id, ClangUtil::ToString(self_type->GetFullCompilerType()));
+ ClangUtil::ToString(self_type->GetFullCompilerType()));
TypeFromUser class_user_type(self_clang_type);
- AddOneType(context, class_user_type, current_id);
+ AddOneType(context, class_user_type);
TypeFromUser self_user_type(self_type->GetFullCompilerType());
@@ -1015,25 +979,25 @@ void ClangExpressionDeclMap::LookupLocalVarNamespace(
if (!frame_decl_context)
return;
- ClangASTContext *frame_ast = llvm::dyn_cast_or_null<ClangASTContext>(
+ TypeSystemClang *frame_ast = llvm::dyn_cast_or_null<TypeSystemClang>(
frame_decl_context.GetTypeSystem());
if (!frame_ast)
return;
clang::NamespaceDecl *namespace_decl =
m_clang_ast_context->GetUniqueNamespaceDeclaration(
- g_lldb_local_vars_namespace_cstr, nullptr);
+ g_lldb_local_vars_namespace_cstr, nullptr, OptionalClangModuleID());
if (!namespace_decl)
return;
name_context.AddNamedDecl(namespace_decl);
clang::DeclContext *ctxt = clang::Decl::castToDeclContext(namespace_decl);
ctxt->setHasExternalVisibleStorage(true);
- name_context.m_found.local_vars_nsp = true;
+ name_context.m_found_local_vars_nsp = true;
}
void ClangExpressionDeclMap::LookupInModulesDeclVendor(
- NameSearchContext &context, ConstString name, unsigned current_id) {
+ NameSearchContext &context, ConstString name) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
if (!m_target)
@@ -1054,16 +1018,14 @@ void ClangExpressionDeclMap::LookupInModulesDeclVendor(
clang::NamedDecl *const decl_from_modules = decls[0];
LLDB_LOG(log,
- " CAS::FEVD[{0}] Matching decl found for "
+ " CAS::FEVD Matching decl found for "
"\"{1}\" in the modules",
- current_id, name);
+ name);
clang::Decl *copied_decl = CopyDecl(decl_from_modules);
if (!copied_decl) {
- LLDB_LOG(log,
- " CAS::FEVD[{0}] - Couldn't export a "
- "declaration from the modules",
- current_id);
+ LLDB_LOG(log, " CAS::FEVD - Couldn't export a "
+ "declaration from the modules");
return;
}
@@ -1072,17 +1034,17 @@ void ClangExpressionDeclMap::LookupInModulesDeclVendor(
context.AddNamedDecl(copied_function);
- context.m_found.function_with_type_info = true;
- context.m_found.function = true;
+ context.m_found_function_with_type_info = true;
+ context.m_found_function = true;
} else if (auto copied_var = dyn_cast<clang::VarDecl>(copied_decl)) {
context.AddNamedDecl(copied_var);
- context.m_found.variable = true;
+ context.m_found_variable = true;
}
}
bool ClangExpressionDeclMap::LookupLocalVariable(
- NameSearchContext &context, ConstString name, unsigned current_id,
- SymbolContext &sym_ctx, CompilerDeclContext &namespace_decl) {
+ NameSearchContext &context, ConstString name, SymbolContext &sym_ctx,
+ const CompilerDeclContext &namespace_decl) {
if (sym_ctx.block == nullptr)
return false;
@@ -1117,8 +1079,8 @@ bool ClangExpressionDeclMap::LookupLocalVariable(
if (var && !variable_found) {
variable_found = true;
ValueObjectSP valobj = ValueObjectVariable::Create(frame, var);
- AddOneVariable(context, var, valobj, current_id);
- context.m_found.variable = true;
+ AddOneVariable(context, var, valobj);
+ context.m_found_variable = true;
}
}
return variable_found;
@@ -1148,7 +1110,7 @@ SymbolContextList ClangExpressionDeclMap::SearchFunctionsInSymbolContexts(
decl_infos.reserve(num_indices);
clang::DeclContext *frame_decl_ctx =
(clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext();
- ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(
+ TypeSystemClang *ast = llvm::dyn_cast_or_null<TypeSystemClang>(
frame_decl_context.GetTypeSystem());
for (uint32_t index = 0; index < num_indices; ++index) {
@@ -1222,11 +1184,9 @@ SymbolContextList ClangExpressionDeclMap::SearchFunctionsInSymbolContexts(
return sc_func_list;
}
-void ClangExpressionDeclMap::LookupFunction(NameSearchContext &context,
- lldb::ModuleSP module_sp,
- ConstString name,
- CompilerDeclContext &namespace_decl,
- unsigned current_id) {
+void ClangExpressionDeclMap::LookupFunction(
+ NameSearchContext &context, lldb::ModuleSP module_sp, ConstString name,
+ const CompilerDeclContext &namespace_decl) {
if (!m_parser_vars)
return;
@@ -1246,7 +1206,7 @@ void ClangExpressionDeclMap::LookupFunction(NameSearchContext &context,
if (namespace_decl && module_sp) {
const bool include_symbols = false;
- module_sp->FindFunctions(name, &namespace_decl, eFunctionNameTypeBase,
+ module_sp->FindFunctions(name, namespace_decl, eFunctionNameTypeBase,
include_symbols, include_inlines, sc_list);
} else if (target && !namespace_decl) {
const bool include_symbols = true;
@@ -1304,9 +1264,9 @@ void ClangExpressionDeclMap::LookupFunction(NameSearchContext &context,
if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr))
continue;
- AddOneFunction(context, sym_ctx.function, nullptr, current_id);
- context.m_found.function_with_type_info = true;
- context.m_found.function = true;
+ AddOneFunction(context, sym_ctx.function, nullptr);
+ context.m_found_function_with_type_info = true;
+ context.m_found_function = true;
} else if (sym_ctx.symbol) {
if (sym_ctx.symbol->GetType() == eSymbolTypeReExported && target) {
sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target);
@@ -1321,26 +1281,26 @@ void ClangExpressionDeclMap::LookupFunction(NameSearchContext &context,
}
}
- if (!context.m_found.function_with_type_info) {
+ if (!context.m_found_function_with_type_info) {
for (clang::NamedDecl *decl : decls_from_modules) {
if (llvm::isa<clang::FunctionDecl>(decl)) {
clang::NamedDecl *copied_decl =
llvm::cast_or_null<FunctionDecl>(CopyDecl(decl));
if (copied_decl) {
context.AddNamedDecl(copied_decl);
- context.m_found.function_with_type_info = true;
+ context.m_found_function_with_type_info = true;
}
}
}
}
- if (!context.m_found.function_with_type_info) {
+ if (!context.m_found_function_with_type_info) {
if (extern_symbol) {
- AddOneFunction(context, nullptr, extern_symbol, current_id);
- context.m_found.function = true;
+ AddOneFunction(context, nullptr, extern_symbol);
+ context.m_found_function = true;
} else if (non_extern_symbol) {
- AddOneFunction(context, nullptr, non_extern_symbol, current_id);
- context.m_found.function = true;
+ AddOneFunction(context, nullptr, non_extern_symbol);
+ context.m_found_function = true;
}
}
}
@@ -1348,7 +1308,7 @@ void ClangExpressionDeclMap::LookupFunction(NameSearchContext &context,
void ClangExpressionDeclMap::FindExternalVisibleDecls(
NameSearchContext &context, lldb::ModuleSP module_sp,
- CompilerDeclContext &namespace_decl, unsigned int current_id) {
+ const CompilerDeclContext &namespace_decl) {
assert(m_ast_context);
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -1373,16 +1333,16 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
// Try the persistent decls, which take precedence over all else.
if (!namespace_decl)
- SearchPersistenDecls(context, name, current_id);
+ SearchPersistenDecls(context, name);
if (name.GetStringRef().startswith("$") && !namespace_decl) {
if (name == "$__lldb_class") {
- LookUpLldbClass(context, current_id);
+ LookUpLldbClass(context);
return;
}
if (name == "$__lldb_objc_class") {
- LookUpLldbObjCClass(context, current_id);
+ LookUpLldbObjCClass(context);
return;
}
if (name == g_lldb_local_vars_namespace_cstr) {
@@ -1402,7 +1362,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
m_parser_vars->m_persistent_vars->GetVariable(name));
if (pvar_sp) {
- AddOneVariable(context, pvar_sp, current_id);
+ AddOneVariable(context, pvar_sp);
return;
}
@@ -1415,10 +1375,9 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
reg_name));
if (reg_info) {
- LLDB_LOGF(log, " CEDM::FEVD[%u] Found register %s", current_id,
- reg_info->name);
+ LLDB_LOG(log, " CEDM::FEVD Found register {0}", reg_info->name);
- AddOneRegister(context, reg_info, current_id);
+ AddOneRegister(context, reg_info);
}
}
return;
@@ -1427,29 +1386,29 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
bool local_var_lookup = !namespace_decl || (namespace_decl.GetName() ==
g_lldb_local_vars_namespace_cstr);
if (frame && local_var_lookup)
- if (LookupLocalVariable(context, name, current_id, sym_ctx, namespace_decl))
+ if (LookupLocalVariable(context, name, sym_ctx, namespace_decl))
return;
if (target) {
ValueObjectSP valobj;
VariableSP var;
- var = FindGlobalVariable(*target, module_sp, name, &namespace_decl);
+ var = FindGlobalVariable(*target, module_sp, name, namespace_decl);
if (var) {
valobj = ValueObjectVariable::Create(target, var);
- AddOneVariable(context, var, valobj, current_id);
- context.m_found.variable = true;
+ AddOneVariable(context, var, valobj);
+ context.m_found_variable = true;
return;
}
}
- LookupFunction(context, module_sp, name, namespace_decl, current_id);
+ LookupFunction(context, module_sp, name, namespace_decl);
// Try the modules next.
- if (!context.m_found.function_with_type_info)
- LookupInModulesDeclVendor(context, name, current_id);
+ if (!context.m_found_function_with_type_info)
+ LookupInModulesDeclVendor(context, name);
- if (target && !context.m_found.variable && !namespace_decl) {
+ if (target && !context.m_found_variable && !namespace_decl) {
// We couldn't find a non-symbol variable for this. Now we'll hunt for a
// generic data symbol, and -- if it is found -- treat it as a variable.
Status error;
@@ -1471,8 +1430,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
m_ast_context->getDiagnostics().getCustomDiagID(
clang::DiagnosticsEngine::Level::Warning, "%0");
m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str();
- AddOneGenericVariable(context, *data_symbol, current_id);
- context.m_found.variable = true;
+ AddOneGenericVariable(context, *data_symbol);
+ context.m_found_variable = true;
}
}
}
@@ -1486,25 +1445,22 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
Type *var_type = var->GetType();
if (!var_type) {
- if (log)
- log->PutCString("Skipped a definition because it has no type");
+ LLDB_LOG(log, "Skipped a definition because it has no type");
return false;
}
CompilerType var_clang_type = var_type->GetFullCompilerType();
if (!var_clang_type) {
- if (log)
- log->PutCString("Skipped a definition because it has no Clang type");
+ LLDB_LOG(log, "Skipped a definition because it has no Clang type");
return false;
}
- ClangASTContext *clang_ast = llvm::dyn_cast_or_null<ClangASTContext>(
+ TypeSystemClang *clang_ast = llvm::dyn_cast_or_null<TypeSystemClang>(
var_type->GetForwardCompilerType().GetTypeSystem());
if (!clang_ast) {
- if (log)
- log->PutCString("Skipped a definition because it has no Clang AST");
+ LLDB_LOG(log, "Skipped a definition because it has no Clang AST");
return false;
}
@@ -1521,7 +1477,7 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
const_value_extractor.GetByteSize());
var_location.SetValueType(Value::eValueTypeHostAddress);
} else {
- LLDB_LOGF(log, "Error evaluating constant variable: %s", err.AsCString());
+ LLDB_LOG(log, "Error evaluating constant variable: {0}", err.AsCString());
return false;
}
}
@@ -1529,8 +1485,8 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
CompilerType type_to_use = GuardedCopyType(var_clang_type);
if (!type_to_use) {
- LLDB_LOGF(log,
- "Couldn't copy a variable's type into the parser's AST context");
+ LLDB_LOG(log,
+ "Couldn't copy a variable's type into the parser's AST context");
return false;
}
@@ -1567,8 +1523,7 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
VariableSP var,
- ValueObjectSP valobj,
- unsigned int current_id) {
+ ValueObjectSP valobj) {
assert(m_parser_vars.get());
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -1611,7 +1566,6 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
entity->EnableParserVars(GetParserID());
ClangExpressionVariable::ParserVars *parser_vars =
entity->GetParserVars(GetParserID());
- parser_vars->m_parser_type = pt;
parser_vars->m_named_decl = var_decl;
parser_vars->m_llvm_value = nullptr;
parser_vars->m_lldb_value = var_location;
@@ -1620,15 +1574,12 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
if (is_reference)
entity->m_flags |= ClangExpressionVariable::EVTypeIsReference;
- LLDB_LOG(log,
- " CEDM::FEVD[{0}] Found variable {1}, returned\n{2} (original {3})",
- current_id, decl_name, ClangUtil::DumpDecl(var_decl),
- ClangUtil::ToString(ut));
+ LLDB_LOG(log, " CEDM::FEVD Found variable {1}, returned\n{2} (original {3})",
+ decl_name, ClangUtil::DumpDecl(var_decl), ClangUtil::ToString(ut));
}
void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
- ExpressionVariableSP &pvar_sp,
- unsigned int current_id) {
+ ExpressionVariableSP &pvar_sp) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
TypeFromUser user_type(
@@ -1637,8 +1588,8 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
TypeFromParser parser_type(GuardedCopyType(user_type));
if (!parser_type.GetOpaqueQualType()) {
- LLDB_LOGF(log, " CEDM::FEVD[%u] Couldn't import type for pvar %s",
- current_id, pvar_sp->GetName().GetCString());
+ LLDB_LOG(log, " CEDM::FEVD Couldn't import type for pvar {0}",
+ pvar_sp->GetName());
return;
}
@@ -1650,18 +1601,16 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
ClangExpressionVariable::ParserVars *parser_vars =
llvm::cast<ClangExpressionVariable>(pvar_sp.get())
->GetParserVars(GetParserID());
- parser_vars->m_parser_type = parser_type;
parser_vars->m_named_decl = var_decl;
parser_vars->m_llvm_value = nullptr;
parser_vars->m_lldb_value.Clear();
- LLDB_LOG(log, " CEDM::FEVD[{0}] Added pvar {1}, returned\n{2}", current_id,
+ LLDB_LOG(log, " CEDM::FEVD Added pvar {1}, returned\n{2}",
pvar_sp->GetName(), ClangUtil::DumpDecl(var_decl));
}
void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
- const Symbol &symbol,
- unsigned int current_id) {
+ const Symbol &symbol) {
assert(m_parser_vars.get());
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -1671,7 +1620,7 @@ void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
if (target == nullptr)
return;
- ClangASTContext *scratch_ast_context = ClangASTContext::GetScratch(*target);
+ TypeSystemClang *scratch_ast_context = TypeSystemClang::GetScratch(*target);
if (!scratch_ast_context)
return;
@@ -1704,18 +1653,16 @@ void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
parser_vars->m_lldb_value.GetScalar() = symbol_load_addr;
parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
- parser_vars->m_parser_type = parser_type;
parser_vars->m_named_decl = var_decl;
parser_vars->m_llvm_value = nullptr;
parser_vars->m_lldb_sym = &symbol;
- LLDB_LOG(log, " CEDM::FEVD[{0}] Found variable {1}, returned\n{2}",
- current_id, decl_name, ClangUtil::DumpDecl(var_decl));
+ LLDB_LOG(log, " CEDM::FEVD Found variable {1}, returned\n{2}", decl_name,
+ ClangUtil::DumpDecl(var_decl));
}
void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,
- const RegisterInfo *reg_info,
- unsigned int current_id) {
+ const RegisterInfo *reg_info) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
CompilerType clang_type =
@@ -1723,8 +1670,8 @@ void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,
reg_info->encoding, reg_info->byte_size * 8);
if (!clang_type) {
- LLDB_LOGF(log, " Tried to add a type for %s, but couldn't get one",
- context.m_decl_name.getAsString().c_str());
+ LLDB_LOG(log, " Tried to add a type for {0}, but couldn't get one",
+ context.m_decl_name.getAsString());
return;
}
@@ -1744,20 +1691,18 @@ void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,
entity->EnableParserVars(GetParserID());
ClangExpressionVariable::ParserVars *parser_vars =
entity->GetParserVars(GetParserID());
- parser_vars->m_parser_type = parser_clang_type;
parser_vars->m_named_decl = var_decl;
parser_vars->m_llvm_value = nullptr;
parser_vars->m_lldb_value.Clear();
entity->m_flags |= ClangExpressionVariable::EVBareRegister;
- LLDB_LOG(log, " CEDM::FEVD[{0}] Added register {1}, returned\n{2}",
- current_id, context.m_decl_name.getAsString(),
- ClangUtil::DumpDecl(var_decl));
+ LLDB_LOG(log, " CEDM::FEVD Added register {1}, returned\n{2}",
+ context.m_decl_name.getAsString(), ClangUtil::DumpDecl(var_decl));
}
void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
- Function *function, Symbol *symbol,
- unsigned int current_id) {
+ Function *function,
+ Symbol *symbol) {
assert(m_parser_vars.get());
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -1780,7 +1725,7 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
if (!extern_c) {
TypeSystem *type_system = function->GetDeclContext().GetTypeSystem();
- if (llvm::isa<ClangASTContext>(type_system)) {
+ if (llvm::isa<TypeSystemClang>(type_system)) {
clang::DeclContext *src_decl_context =
(clang::DeclContext *)function->GetDeclContext()
.GetOpaqueDeclContext();
@@ -1800,9 +1745,9 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
function->DumpSymbolContext(&ss);
LLDB_LOG(log,
- " CEDM::FEVD[{0}] Imported decl for function template"
+ " CEDM::FEVD Imported decl for function template"
" {1} (description {2}), returned\n{3}",
- current_id, copied_function_template->getNameAsString(),
+ copied_function_template->getNameAsString(),
ss.GetData(),
ClangUtil::DumpDecl(copied_function_template));
}
@@ -1819,35 +1764,31 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
function->DumpSymbolContext(&ss);
LLDB_LOG(log,
- " CEDM::FEVD[{0}]] Imported decl for function {1} "
+ " CEDM::FEVD Imported decl for function {1} "
"(description {2}), returned\n{3}",
- current_id, copied_function_decl->getNameAsString(),
- ss.GetData(), ClangUtil::DumpDecl(copied_function_decl));
+ copied_function_decl->getNameAsString(), ss.GetData(),
+ ClangUtil::DumpDecl(copied_function_decl));
}
context.AddNamedDecl(copied_function_decl);
return;
} else {
- if (log) {
- LLDB_LOGF(log, " Failed to import the function decl for '%s'",
- src_function_decl->getName().str().c_str());
- }
+ LLDB_LOG(log, " Failed to import the function decl for '{0}'",
+ src_function_decl->getName());
}
}
}
}
if (!function_type) {
- if (log)
- log->PutCString(" Skipped a function because it has no type");
+ LLDB_LOG(log, " Skipped a function because it has no type");
return;
}
function_clang_type = function_type->GetFullCompilerType();
if (!function_clang_type) {
- if (log)
- log->PutCString(" Skipped a function because it has no Clang type");
+ LLDB_LOG(log, " Skipped a function because it has no Clang type");
return;
}
@@ -1858,24 +1799,17 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
function_decl = context.AddFunDecl(copied_function_type, extern_c);
if (!function_decl) {
- if (log) {
- LLDB_LOGF(
- log,
- " Failed to create a function decl for '%s' {0x%8.8" PRIx64 "}",
- function_type->GetName().GetCString(), function_type->GetID());
- }
+ LLDB_LOG(log, " Failed to create a function decl for '{0}' ({1:x})",
+ function_type->GetName(), function_type->GetID());
return;
}
} else {
// We failed to copy the type we found
- if (log) {
- LLDB_LOGF(log,
- " Failed to import the function type '%s' {0x%8.8" PRIx64
- "} into the expression parser AST contenxt",
- function_type->GetName().GetCString(),
- function_type->GetID());
- }
+ LLDB_LOG(log,
+ " Failed to import the function type '{0}' ({1:x})"
+ " into the expression parser AST contenxt",
+ function_type->GetName(), function_type->GetID());
return;
}
@@ -1884,8 +1818,7 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
function_decl = context.AddGenericFunDecl();
is_indirect_function = symbol->IsIndirect();
} else {
- if (log)
- log->PutCString(" AddOneFunction called with no function and no symbol");
+ LLDB_LOG(log, " AddOneFunction called with no function and no symbol");
return;
}
@@ -1931,25 +1864,22 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
Address::DumpStyleResolvedDescription);
LLDB_LOG(log,
- " CEDM::FEVD[{0}] Found {1} function {2} (description {3}), "
+ " CEDM::FEVD Found {1} function {2} (description {3}), "
"returned\n{4}",
- current_id, (function ? "specific" : "generic"), decl_name,
- ss.GetData(), ClangUtil::DumpDecl(function_decl));
+ (function ? "specific" : "generic"), decl_name, ss.GetData(),
+ ClangUtil::DumpDecl(function_decl));
}
}
-void ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
- const TypeFromUser &ut,
- unsigned int current_id) {
+void ClangExpressionDeclMap::AddContextClassType(NameSearchContext &context,
+ const TypeFromUser &ut) {
CompilerType copied_clang_type = GuardedCopyType(ut);
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
if (!copied_clang_type) {
- if (log)
- LLDB_LOGF(
- log,
- "ClangExpressionDeclMap::AddThisType - Couldn't import the type");
+ LLDB_LOG(log,
+ "ClangExpressionDeclMap::AddThisType - Couldn't import the type");
return;
}
@@ -2009,16 +1939,14 @@ void ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
}
void ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
- const TypeFromUser &ut,
- unsigned int current_id) {
+ const TypeFromUser &ut) {
CompilerType copied_clang_type = GuardedCopyType(ut);
if (!copied_clang_type) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
- if (log)
- LLDB_LOGF(
- log, "ClangExpressionDeclMap::AddOneType - Couldn't import the type");
+ LLDB_LOG(log,
+ "ClangExpressionDeclMap::AddOneType - Couldn't import the type");
return;
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
index 722f5e15a2aa..6974535a8993 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangExpressionDeclMap_h_
-#define liblldb_ClangExpressionDeclMap_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONDECLMAP_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONDECLMAP_H
#include <signal.h>
#include <stdint.h>
@@ -17,7 +17,6 @@
#include "ClangASTSource.h"
#include "ClangExpressionVariable.h"
-#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Value.h"
#include "lldb/Expression/Materializer.h"
#include "lldb/Symbol/SymbolContext.h"
@@ -29,6 +28,8 @@
namespace lldb_private {
+class ClangPersistentVariables;
+
/// \class ClangExpressionDeclMap ClangExpressionDeclMap.h
/// "lldb/Expression/ClangExpressionDeclMap.h" Manages named entities that are
/// defined in LLDB's debug information.
@@ -79,8 +80,8 @@ public:
ClangExpressionDeclMap(
bool keep_result_in_memory,
Materializer::PersistentVariableDelegate *result_delegate,
- const lldb::TargetSP &target, const lldb::ClangASTImporterSP &importer,
- ValueObject *ctx_obj);
+ const lldb::TargetSP &target,
+ const std::shared_ptr<ClangASTImporter> &importer, ValueObject *ctx_obj);
/// Destructor
~ClangExpressionDeclMap() override;
@@ -274,14 +275,9 @@ public:
///
/// \param[in] namespace_decl
/// If valid and module is non-NULL, the parent namespace.
- ///
- /// \param[in] current_id
- /// The ID for the current FindExternalVisibleDecls invocation,
- /// for logging purposes.
void FindExternalVisibleDecls(NameSearchContext &context,
lldb::ModuleSP module,
- CompilerDeclContext &namespace_decl,
- unsigned int current_id);
+ const CompilerDeclContext &namespace_decl);
protected:
/// Retrieves the declaration with the given name from the storage of
@@ -335,7 +331,8 @@ private:
///that receives new top-level
///functions.
private:
- DISALLOW_COPY_AND_ASSIGN(ParserVars);
+ ParserVars(const ParserVars &) = delete;
+ const ParserVars &operator=(const ParserVars &) = delete;
};
std::unique_ptr<ParserVars> m_parser_vars;
@@ -394,32 +391,19 @@ private:
///
/// \param[in] name
/// The name of the entities that need to be found.
- ///
- /// \param[in] current_id
- /// The ID for the current FindExternalVisibleDecls invocation,
- /// for logging purposes.
- void SearchPersistenDecls(NameSearchContext &context, const ConstString name,
- unsigned int current_id);
+ void SearchPersistenDecls(NameSearchContext &context, const ConstString name);
/// Handles looking up $__lldb_class which requires special treatment.
///
/// \param[in] context
/// The NameSearchContext that can construct Decls for this name.
- ///
- /// \param[in] current_id
- /// The ID for the current FindExternalVisibleDecls invocation,
- /// for logging purposes.
- void LookUpLldbClass(NameSearchContext &context, unsigned int current_id);
+ void LookUpLldbClass(NameSearchContext &context);
/// Handles looking up $__lldb_objc_class which requires special treatment.
///
/// \param[in] context
/// The NameSearchContext that can construct Decls for this name.
- ///
- /// \param[in] current_id
- /// The ID for the current FindExternalVisibleDecls invocation,
- /// for logging purposes.
- void LookUpLldbObjCClass(NameSearchContext &context, unsigned int current_id);
+ void LookUpLldbObjCClass(NameSearchContext &context);
/// Handles looking up the synthetic namespace that contains our local
/// variables for the current frame.
@@ -438,12 +422,7 @@ private:
///
/// \param[in] name
/// The name of the entities that need to be found.
- ///
- /// \param[in] current_id
- /// The ID for the current FindExternalVisibleDecls invocation,
- /// for logging purposes.
- void LookupInModulesDeclVendor(NameSearchContext &context, ConstString name,
- unsigned current_id);
+ void LookupInModulesDeclVendor(NameSearchContext &context, ConstString name);
/// Looks up a local variable.
///
@@ -453,10 +432,6 @@ private:
/// \param[in] name
/// The name of the entities that need to be found.
///
- /// \param[in] current_id
- /// The ID for the current FindExternalVisibleDecls invocation,
- /// for logging purposes.
- ///
/// \param[in] sym_ctx
/// The current SymbolContext of this frame.
///
@@ -466,8 +441,8 @@ private:
/// \return
/// True iff a local variable was found.
bool LookupLocalVariable(NameSearchContext &context, ConstString name,
- unsigned current_id, SymbolContext &sym_ctx,
- CompilerDeclContext &namespace_decl);
+ SymbolContext &sym_ctx,
+ const CompilerDeclContext &namespace_decl);
/// Searches for functions in the given SymbolContextList.
///
@@ -499,13 +474,9 @@ private:
///
/// \param[in] namespace_decl
/// If valid and module is non-NULL, the parent namespace.
- ///
- /// \param[in] current_id
- /// The ID for the current FindExternalVisibleDecls invocation,
- /// for logging purposes.
void LookupFunction(NameSearchContext &context, lldb::ModuleSP module_sp,
- ConstString name, CompilerDeclContext &namespace_decl,
- unsigned current_id);
+ ConstString name,
+ const CompilerDeclContext &namespace_decl);
/// Given a target, find a variable that matches the given name and type.
///
@@ -523,9 +494,9 @@ private:
///
/// \return
/// The LLDB Variable found, or NULL if none was found.
- lldb::VariableSP FindGlobalVariable(Target &target, lldb::ModuleSP &module,
- ConstString name,
- CompilerDeclContext *namespace_decl);
+ lldb::VariableSP
+ FindGlobalVariable(Target &target, lldb::ModuleSP &module, ConstString name,
+ const CompilerDeclContext &namespace_decl);
/// Get the value of a variable in a given execution context and return the
/// associated Types if needed.
@@ -565,7 +536,7 @@ private:
/// \param[in] valobj
/// The LLDB ValueObject for that variable.
void AddOneVariable(NameSearchContext &context, lldb::VariableSP var,
- lldb::ValueObjectSP valobj, unsigned int current_id);
+ lldb::ValueObjectSP valobj);
/// Use the NameSearchContext to generate a Decl for the given persistent
/// variable, and put it in the list of found entities.
@@ -575,18 +546,12 @@ private:
///
/// \param[in] pvar_sp
/// The persistent variable that needs a Decl.
- ///
- /// \param[in] current_id
- /// The ID of the current invocation of FindExternalVisibleDecls
- /// for logging purposes.
void AddOneVariable(NameSearchContext &context,
- lldb::ExpressionVariableSP &pvar_sp,
- unsigned int current_id);
+ lldb::ExpressionVariableSP &pvar_sp);
/// Use the NameSearchContext to generate a Decl for the given LLDB symbol
/// (treated as a variable), and put it in the list of found entities.
- void AddOneGenericVariable(NameSearchContext &context, const Symbol &symbol,
- unsigned int current_id);
+ void AddOneGenericVariable(NameSearchContext &context, const Symbol &symbol);
/// Use the NameSearchContext to generate a Decl for the given function.
/// (Functions are not placed in the Tuple list.) Can handle both fully
@@ -602,8 +567,7 @@ private:
/// \param[in] sym
/// The Symbol that corresponds to a function that needs to be
/// created with generic type (unitptr_t foo(...)).
- void AddOneFunction(NameSearchContext &context, Function *fun, Symbol *sym,
- unsigned int current_id);
+ void AddOneFunction(NameSearchContext &context, Function *fun, Symbol *sym);
/// Use the NameSearchContext to generate a Decl for the given register.
///
@@ -612,8 +576,7 @@ private:
///
/// \param[in] reg_info
/// The information corresponding to that register.
- void AddOneRegister(NameSearchContext &context, const RegisterInfo *reg_info,
- unsigned int current_id);
+ void AddOneRegister(NameSearchContext &context, const RegisterInfo *reg_info);
/// Use the NameSearchContext to generate a Decl for the given type. (Types
/// are not placed in the Tuple list.)
@@ -623,38 +586,40 @@ private:
///
/// \param[in] type
/// The type that needs to be created.
- void AddOneType(NameSearchContext &context, const TypeFromUser &type,
- unsigned int current_id);
+ void AddOneType(NameSearchContext &context, const TypeFromUser &type);
- /// Generate a Decl for "*this" and add a member function declaration to it
- /// for the expression, then report it.
+ /// Adds the class in which the expression is evaluated to the lookup and
+ /// prepares the class to be used as a context for expression evaluation (for
+ /// example, it creates a fake member function that will contain the
+ /// expression LLDB is trying to evaluate).
///
/// \param[in] context
- /// The NameSearchContext to use when constructing the Decl.
+ /// The NameSearchContext to which the class should be added as a lookup
+ /// result.
///
/// \param[in] type
- /// The type for *this.
- void AddThisType(NameSearchContext &context, const TypeFromUser &type,
- unsigned int current_id);
+ /// The type of the class that serves as the evaluation context.
+ void AddContextClassType(NameSearchContext &context,
+ const TypeFromUser &type);
/// Move a type out of the current ASTContext into another, but make sure to
/// export all components of the type also.
///
/// \param[in] target
- /// The ClangASTContext to move to.
+ /// The TypeSystemClang to move to.
/// \param[in] source
- /// The ClangASTContext to move from. This is assumed to be going away.
+ /// The TypeSystemClang to move from. This is assumed to be going away.
/// \param[in] parser_type
/// The type as it appears in the source context.
///
/// \return
/// Returns the moved type, or an empty type if there was a problem.
- TypeFromUser DeportType(ClangASTContext &target, ClangASTContext &source,
+ TypeFromUser DeportType(TypeSystemClang &target, TypeSystemClang &source,
TypeFromParser parser_type);
- ClangASTContext *GetClangASTContext();
+ TypeSystemClang *GetTypeSystemClang();
};
} // namespace lldb_private
-#endif // liblldb_ClangExpressionDeclMap_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONDECLMAP_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
index 48da5abb9126..e33e5df22236 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
@@ -6,21 +6,24 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangExpression_h_
-#define liblldb_ClangExpression_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONHELPER_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONHELPER_H
#include <map>
#include <string>
#include <vector>
-
-#include "lldb/Core/ClangForward.h"
#include "lldb/Expression/ExpressionTypeSystemHelper.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"
+namespace clang {
+class ASTConsumer;
+}
+
namespace lldb_private {
+class ClangExpressionDeclMap;
class RecordingMemoryManager;
// ClangExpressionHelper
@@ -57,4 +60,4 @@ protected:
} // namespace lldb_private
-#endif // liblldb_ClangExpression_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONHELPER_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 8abd14942885..6ff028cf6980 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -1,4 +1,4 @@
-//===-- ClangExpressionParser.cpp -------------------------------*- C++ -*-===//
+//===-- ClangExpressionParser.cpp -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -67,6 +67,7 @@
#include "IRForTarget.h"
#include "ModuleDependencyCollector.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Module.h"
@@ -75,7 +76,6 @@
#include "lldb/Expression/IRInterpreter.h"
#include "lldb/Host/File.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Language.h"
@@ -91,6 +91,7 @@
#include "lldb/Utility/StringList.h"
#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
+#include "Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h"
#include <cctype>
#include <memory>
@@ -146,21 +147,40 @@ public:
llvm::StringRef getErrorString() { return m_error_stream.GetString(); }
};
+static void AddAllFixIts(ClangDiagnostic *diag, const clang::Diagnostic &Info) {
+ for (auto &fix_it : Info.getFixItHints()) {
+ if (fix_it.isNull())
+ continue;
+ diag->AddFixitHint(fix_it);
+ }
+}
+
class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer {
public:
ClangDiagnosticManagerAdapter(DiagnosticOptions &opts) {
- DiagnosticOptions *m_options = new DiagnosticOptions(opts);
- m_options->ShowPresumedLoc = true;
- m_options->ShowLevel = false;
- m_os.reset(new llvm::raw_string_ostream(m_output));
- m_passthrough.reset(
- new clang::TextDiagnosticPrinter(*m_os, m_options, false));
+ DiagnosticOptions *options = new DiagnosticOptions(opts);
+ options->ShowPresumedLoc = true;
+ options->ShowLevel = false;
+ m_os = std::make_shared<llvm::raw_string_ostream>(m_output);
+ m_passthrough =
+ std::make_shared<clang::TextDiagnosticPrinter>(*m_os, options);
}
void ResetManager(DiagnosticManager *manager = nullptr) {
m_manager = manager;
}
+ /// Returns the last ClangDiagnostic message that the DiagnosticManager
+ /// received or a nullptr if the DiagnosticMangager hasn't seen any
+ /// Clang diagnostics yet.
+ ClangDiagnostic *MaybeGetLastClangDiag() const {
+ if (m_manager->Diagnostics().empty())
+ return nullptr;
+ lldb_private::Diagnostic *diag = m_manager->Diagnostics().back().get();
+ ClangDiagnostic *clang_diag = dyn_cast<ClangDiagnostic>(diag);
+ return clang_diag;
+ }
+
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
const clang::Diagnostic &Info) override {
if (!m_manager) {
@@ -180,6 +200,9 @@ public:
return;
}
+ // Update error/warning counters.
+ DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info);
+
// Render diagnostic message to m_output.
m_output.clear();
m_passthrough->HandleDiagnostic(DiagLevel, Info);
@@ -203,11 +226,29 @@ public:
case DiagnosticsEngine::Level::Note:
m_manager->AppendMessageToDiagnostic(m_output);
make_new_diagnostic = false;
+
+ // 'note:' diagnostics for errors and warnings can also contain Fix-Its.
+ // We add these Fix-Its to the last error diagnostic to make sure
+ // that we later have all Fix-Its related to an 'error' diagnostic when
+ // we apply them to the user expression.
+ auto *clang_diag = MaybeGetLastClangDiag();
+ // If we don't have a previous diagnostic there is nothing to do.
+ // If the previous diagnostic already has its own Fix-Its, assume that
+ // the 'note:' Fix-It is just an alternative way to solve the issue and
+ // ignore these Fix-Its.
+ if (!clang_diag || clang_diag->HasFixIts())
+ break;
+ // Ignore all Fix-Its that are not associated with an error.
+ if (clang_diag->GetSeverity() != eDiagnosticSeverityError)
+ break;
+ AddAllFixIts(clang_diag, Info);
+ break;
}
if (make_new_diagnostic) {
// ClangDiagnostic messages are expected to have no whitespace/newlines
// around them.
- std::string stripped_output = llvm::StringRef(m_output).trim();
+ std::string stripped_output =
+ std::string(llvm::StringRef(m_output).trim());
auto new_diagnostic = std::make_unique<ClangDiagnostic>(
stripped_output, severity, Info.getID());
@@ -216,20 +257,18 @@ public:
// enough context in an expression for the warning to be useful.
// FIXME: Should we try to filter out FixIts that apply to our generated
// code, and not the user's expression?
- if (severity == eDiagnosticSeverityError) {
- size_t num_fixit_hints = Info.getNumFixItHints();
- for (size_t i = 0; i < num_fixit_hints; i++) {
- const clang::FixItHint &fixit = Info.getFixItHint(i);
- if (!fixit.isNull())
- new_diagnostic->AddFixitHint(fixit);
- }
- }
+ if (severity == eDiagnosticSeverityError)
+ AddAllFixIts(new_diagnostic.get(), Info);
m_manager->AddDiagnostic(std::move(new_diagnostic));
}
}
- clang::TextDiagnosticPrinter *GetPassthrough() { return m_passthrough.get(); }
+ void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) override {
+ m_passthrough->BeginSourceFile(LO, PP);
+ }
+
+ void EndSourceFile() override { m_passthrough->EndSourceFile(); }
private:
DiagnosticManager *m_manager = nullptr;
@@ -253,9 +292,9 @@ static void SetupModuleHeaderPaths(CompilerInstance *compiler,
}
llvm::SmallString<128> module_cache;
- auto props = ModuleList::GetGlobalModuleListProperties();
+ const auto &props = ModuleList::GetGlobalModuleListProperties();
props.GetClangModulesCachePath().GetPath(module_cache);
- search_opts.ModuleCachePath = module_cache.str();
+ search_opts.ModuleCachePath = std::string(module_cache.str());
LLDB_LOG(log, "Using module cache path: {0}", module_cache.c_str());
search_opts.ResourceDir = GetClangResourceDir().GetPath();
@@ -279,28 +318,27 @@ ClangExpressionParser::ClangExpressionParser(
// We can't compile expressions without a target. So if the exe_scope is
// null or doesn't have a target, then we just need to get out of here. I'll
- // lldb_assert and not make any of the compiler objects since
+ // lldbassert and not make any of the compiler objects since
// I can't return errors directly from the constructor. Further calls will
// check if the compiler was made and
// bag out if it wasn't.
if (!exe_scope) {
- lldb_assert(exe_scope, "Can't make an expression parser with a null scope.",
- __FUNCTION__, __FILE__, __LINE__);
+ lldbassert(exe_scope &&
+ "Can't make an expression parser with a null scope.");
return;
}
lldb::TargetSP target_sp;
target_sp = exe_scope->CalculateTarget();
if (!target_sp) {
- lldb_assert(target_sp.get(),
- "Can't make an expression parser with a null target.",
- __FUNCTION__, __FILE__, __LINE__);
+ lldbassert(target_sp.get() &&
+ "Can't make an expression parser with a null target.");
return;
}
// 1. Create a new compiler instance.
- m_compiler.reset(new CompilerInstance());
+ m_compiler = std::make_unique<CompilerInstance>();
// When capturing a reproducer, hook up the file collector with clang to
// collector modules and headers.
@@ -391,9 +429,13 @@ ClangExpressionParser::ClangExpressionParser(
// target. In this case, a specialized language runtime is available and we
// can query it for extra options. For 99% of use cases, this will not be
// needed and should be provided when basic platform detection is not enough.
- if (lang_rt)
+ // FIXME: Generalize this. Only RenderScriptRuntime currently supports this
+ // currently. Hardcoding this isn't ideal but it's better than LanguageRuntime
+ // having knowledge of clang::TargetOpts.
+ if (auto *renderscript_rt =
+ llvm::dyn_cast_or_null<RenderScriptRuntime>(lang_rt))
overridden_target_opts =
- lang_rt->GetOverrideExprOptions(m_compiler->getTargetOpts());
+ renderscript_rt->GetOverrideExprOptions(m_compiler->getTargetOpts());
if (overridden_target_opts)
if (log && log->GetVerbose()) {
@@ -606,11 +648,12 @@ ClangExpressionParser::ClangExpressionParser(
m_compiler->createASTContext();
clang::ASTContext &ast_context = m_compiler->getASTContext();
- m_ast_context.reset(new ClangASTContext(ast_context));
+ m_ast_context = std::make_unique<TypeSystemClang>(
+ "Expression ASTContext for '" + m_filename + "'", ast_context);
std::string module_name("$__lldb_module");
- m_llvm_context.reset(new LLVMContext());
+ m_llvm_context = std::make_unique<LLVMContext>();
m_code_generator.reset(CreateLLVMCodeGen(
m_compiler->getDiagnostics(), module_name,
m_compiler->getHeaderSearchOpts(), m_compiler->getPreprocessorOpts(),
@@ -631,11 +674,33 @@ class CodeComplete : public CodeCompleteConsumer {
std::string m_expr;
unsigned m_position = 0;
- CompletionRequest &m_request;
/// The printing policy we use when printing declarations for our completion
/// descriptions.
clang::PrintingPolicy m_desc_policy;
+ struct CompletionWithPriority {
+ CompletionResult::Completion completion;
+ /// See CodeCompletionResult::Priority;
+ unsigned Priority;
+
+ /// Establishes a deterministic order in a list of CompletionWithPriority.
+ /// The order returned here is the order in which the completions are
+ /// displayed to the user.
+ bool operator<(const CompletionWithPriority &o) const {
+ // High priority results should come first.
+ if (Priority != o.Priority)
+ return Priority > o.Priority;
+
+ // Identical priority, so just make sure it's a deterministic order.
+ return completion.GetUniqueKey() < o.completion.GetUniqueKey();
+ }
+ };
+
+ /// The stored completions.
+ /// Warning: These are in a non-deterministic order until they are sorted
+ /// and returned back to the caller.
+ std::vector<CompletionWithPriority> m_completions;
+
/// Returns true if the given character can be used in an identifier.
/// This also returns true for numbers because for completion we usually
/// just iterate backwards over iterators.
@@ -652,7 +717,7 @@ class CodeComplete : public CodeCompleteConsumer {
/// Drops all tokens in front of the expression that are unrelated for
/// the completion of the cmd line. 'unrelated' means here that the token
/// is not interested for the lldb completion API result.
- StringRef dropUnrelatedFrontTokens(StringRef cmd) {
+ StringRef dropUnrelatedFrontTokens(StringRef cmd) const {
if (cmd.empty())
return cmd;
@@ -673,18 +738,18 @@ class CodeComplete : public CodeCompleteConsumer {
}
/// Removes the last identifier token from the given cmd line.
- StringRef removeLastToken(StringRef cmd) {
+ StringRef removeLastToken(StringRef cmd) const {
while (!cmd.empty() && IsIdChar(cmd.back())) {
cmd = cmd.drop_back();
}
return cmd;
}
- /// Attemps to merge the given completion from the given position into the
+ /// Attempts to merge the given completion from the given position into the
/// existing command. Returns the completion string that can be returned to
/// the lldb completion API.
std::string mergeCompletion(StringRef existing, unsigned pos,
- StringRef completion) {
+ StringRef completion) const {
StringRef existing_command = existing.substr(0, pos);
// We rewrite the last token with the completion, so let's drop that
// token from the command.
@@ -706,11 +771,10 @@ public:
/// \param[out] position
/// The character position of the user cursor in the `expr` parameter.
///
- CodeComplete(CompletionRequest &request, clang::LangOptions ops,
- std::string expr, unsigned position)
+ CodeComplete(clang::LangOptions ops, std::string expr, unsigned position)
: CodeCompleteConsumer(CodeCompleteOptions()),
m_info(std::make_shared<GlobalCodeCompletionAllocator>()), m_expr(expr),
- m_position(position), m_request(request), m_desc_policy(ops) {
+ m_position(position), m_desc_policy(ops) {
// Ensure that the printing policy is producing a description that is as
// short as possible.
@@ -723,9 +787,6 @@ public:
m_desc_policy.Bool = true;
}
- /// Deregisters and destroys this code-completion consumer.
- ~CodeComplete() override {}
-
/// \name Code-completion filtering
/// Check if the result should be filtered out.
bool isResultFilteredOut(StringRef Filter,
@@ -753,6 +814,85 @@ public:
return true;
}
+private:
+ /// Generate the completion strings for the given CodeCompletionResult.
+ /// Note that this function has to process results that could come in
+ /// non-deterministic order, so this function should have no side effects.
+ /// To make this easier to enforce, this function and all its parameters
+ /// should always be const-qualified.
+ /// \return Returns llvm::None if no completion should be provided for the
+ /// given CodeCompletionResult.
+ llvm::Optional<CompletionWithPriority>
+ getCompletionForResult(const CodeCompletionResult &R) const {
+ std::string ToInsert;
+ std::string Description;
+ // Handle the different completion kinds that come from the Sema.
+ switch (R.Kind) {
+ case CodeCompletionResult::RK_Declaration: {
+ const NamedDecl *D = R.Declaration;
+ ToInsert = R.Declaration->getNameAsString();
+ // If we have a function decl that has no arguments we want to
+ // complete the empty parantheses for the user. If the function has
+ // arguments, we at least complete the opening bracket.
+ if (const FunctionDecl *F = dyn_cast<FunctionDecl>(D)) {
+ if (F->getNumParams() == 0)
+ ToInsert += "()";
+ else
+ ToInsert += "(";
+ raw_string_ostream OS(Description);
+ F->print(OS, m_desc_policy, false);
+ OS.flush();
+ } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
+ Description = V->getType().getAsString(m_desc_policy);
+ } else if (const FieldDecl *F = dyn_cast<FieldDecl>(D)) {
+ Description = F->getType().getAsString(m_desc_policy);
+ } else if (const NamespaceDecl *N = dyn_cast<NamespaceDecl>(D)) {
+ // If we try to complete a namespace, then we can directly append
+ // the '::'.
+ if (!N->isAnonymousNamespace())
+ ToInsert += "::";
+ }
+ break;
+ }
+ case CodeCompletionResult::RK_Keyword:
+ ToInsert = R.Keyword;
+ break;
+ case CodeCompletionResult::RK_Macro:
+ ToInsert = R.Macro->getName().str();
+ break;
+ case CodeCompletionResult::RK_Pattern:
+ ToInsert = R.Pattern->getTypedText();
+ break;
+ }
+ // We also filter some internal lldb identifiers here. The user
+ // shouldn't see these.
+ if (llvm::StringRef(ToInsert).startswith("$__lldb_"))
+ return llvm::None;
+ if (ToInsert.empty())
+ return llvm::None;
+ // Merge the suggested Token into the existing command line to comply
+ // with the kind of result the lldb API expects.
+ std::string CompletionSuggestion =
+ mergeCompletion(m_expr, m_position, ToInsert);
+
+ CompletionResult::Completion completion(CompletionSuggestion, Description,
+ CompletionMode::Normal);
+ return {{completion, R.Priority}};
+ }
+
+public:
+ /// Adds the completions to the given CompletionRequest.
+ void GetCompletions(CompletionRequest &request) {
+ // Bring m_completions into a deterministic order and pass it on to the
+ // CompletionRequest.
+ llvm::sort(m_completions);
+
+ for (const CompletionWithPriority &C : m_completions)
+ request.AddCompletion(C.completion.GetCompletion(),
+ C.completion.GetDescription(),
+ C.completion.GetMode());
+ }
+
/// \name Code-completion callbacks
/// Process the finalized code-completion results.
void ProcessCodeCompleteResults(Sema &SemaRef, CodeCompletionContext Context,
@@ -771,59 +911,11 @@ public:
continue;
CodeCompletionResult &R = Results[I];
- std::string ToInsert;
- std::string Description;
- // Handle the different completion kinds that come from the Sema.
- switch (R.Kind) {
- case CodeCompletionResult::RK_Declaration: {
- const NamedDecl *D = R.Declaration;
- ToInsert = R.Declaration->getNameAsString();
- // If we have a function decl that has no arguments we want to
- // complete the empty parantheses for the user. If the function has
- // arguments, we at least complete the opening bracket.
- if (const FunctionDecl *F = dyn_cast<FunctionDecl>(D)) {
- if (F->getNumParams() == 0)
- ToInsert += "()";
- else
- ToInsert += "(";
- raw_string_ostream OS(Description);
- F->print(OS, m_desc_policy, false);
- OS.flush();
- } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
- Description = V->getType().getAsString(m_desc_policy);
- } else if (const FieldDecl *F = dyn_cast<FieldDecl>(D)) {
- Description = F->getType().getAsString(m_desc_policy);
- } else if (const NamespaceDecl *N = dyn_cast<NamespaceDecl>(D)) {
- // If we try to complete a namespace, then we can directly append
- // the '::'.
- if (!N->isAnonymousNamespace())
- ToInsert += "::";
- }
- break;
- }
- case CodeCompletionResult::RK_Keyword:
- ToInsert = R.Keyword;
- break;
- case CodeCompletionResult::RK_Macro:
- ToInsert = R.Macro->getName().str();
- break;
- case CodeCompletionResult::RK_Pattern:
- ToInsert = R.Pattern->getTypedText();
- break;
- }
- // At this point all information is in the ToInsert string.
-
- // We also filter some internal lldb identifiers here. The user
- // shouldn't see these.
- if (StringRef(ToInsert).startswith("$__lldb_"))
+ llvm::Optional<CompletionWithPriority> CompletionAndPriority =
+ getCompletionForResult(R);
+ if (!CompletionAndPriority)
continue;
- if (!ToInsert.empty()) {
- // Merge the suggested Token into the existing command line to comply
- // with the kind of result the lldb API expects.
- std::string CompletionSuggestion =
- mergeCompletion(m_expr, m_position, ToInsert);
- m_request.AddCompletion(CompletionSuggestion, Description);
- }
+ m_completions.push_back(*CompletionAndPriority);
}
}
@@ -860,12 +952,13 @@ bool ClangExpressionParser::Complete(CompletionRequest &request, unsigned line,
// the LLVMUserExpression which exposes the right API. This should never fail
// as we always have a ClangUserExpression whenever we call this.
ClangUserExpression *llvm_expr = cast<ClangUserExpression>(&m_expr);
- CodeComplete CC(request, m_compiler->getLangOpts(), llvm_expr->GetUserText(),
+ CodeComplete CC(m_compiler->getLangOpts(), llvm_expr->GetUserText(),
typed_pos);
// We don't need a code generator for parsing.
m_code_generator.reset();
// Start parsing the expression with our custom code completion consumer.
ParseInternal(mgr, &CC, line, pos);
+ CC.GetCompletions(request);
return true;
}
@@ -881,7 +974,6 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager,
ClangDiagnosticManagerAdapter *adapter =
static_cast<ClangDiagnosticManagerAdapter *>(
m_compiler->getDiagnostics().getClient());
- auto diag_buf = adapter->GetPassthrough();
adapter->ResetManager(&diagnostic_manager);
@@ -936,8 +1028,8 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager,
source_mgr.setMainFileID(source_mgr.createFileID(std::move(memory_buffer)));
}
- diag_buf->BeginSourceFile(m_compiler->getLangOpts(),
- &m_compiler->getPreprocessor());
+ adapter->BeginSourceFile(m_compiler->getLangOpts(),
+ &m_compiler->getPreprocessor());
ClangExpressionHelper *type_system_helper =
dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
@@ -961,11 +1053,11 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager,
std::unique_ptr<clang::ASTConsumer> Consumer;
if (ast_transformer) {
- Consumer.reset(new ASTConsumerForwarder(ast_transformer));
+ Consumer = std::make_unique<ASTConsumerForwarder>(ast_transformer);
} else if (m_code_generator) {
- Consumer.reset(new ASTConsumerForwarder(m_code_generator.get()));
+ Consumer = std::make_unique<ASTConsumerForwarder>(m_code_generator.get());
} else {
- Consumer.reset(new ASTConsumer());
+ Consumer = std::make_unique<ASTConsumer>();
}
clang::ASTContext &ast_context = m_compiler->getASTContext();
@@ -1022,9 +1114,9 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager,
// original behavior of ParseAST (which also destroys the Sema after parsing).
m_compiler->setSema(nullptr);
- diag_buf->EndSourceFile();
+ adapter->EndSourceFile();
- unsigned num_errors = diag_buf->getNumErrors();
+ unsigned num_errors = adapter->getNumErrors();
if (m_pp_callbacks && m_pp_callbacks->hasErrors()) {
num_errors++;
@@ -1065,6 +1157,28 @@ ClangExpressionParser::GetClangTargetABI(const ArchSpec &target_arch) {
return abi;
}
+/// Applies the given Fix-It hint to the given commit.
+static void ApplyFixIt(const FixItHint &fixit, clang::edit::Commit &commit) {
+ // This is cobbed from clang::Rewrite::FixItRewriter.
+ if (fixit.CodeToInsert.empty()) {
+ if (fixit.InsertFromRange.isValid()) {
+ commit.insertFromRange(fixit.RemoveRange.getBegin(),
+ fixit.InsertFromRange, /*afterToken=*/false,
+ fixit.BeforePreviousInsertions);
+ return;
+ }
+ commit.remove(fixit.RemoveRange);
+ return;
+ }
+ if (fixit.RemoveRange.isTokenRange() ||
+ fixit.RemoveRange.getBegin() != fixit.RemoveRange.getEnd()) {
+ commit.replace(fixit.RemoveRange, fixit.CodeToInsert);
+ return;
+ }
+ commit.insert(fixit.RemoveRange.getBegin(), fixit.CodeToInsert,
+ /*afterToken=*/false, fixit.BeforePreviousInsertions);
+}
+
bool ClangExpressionParser::RewriteExpression(
DiagnosticManager &diagnostic_manager) {
clang::SourceManager &source_manager = m_compiler->getSourceManager();
@@ -1096,26 +1210,12 @@ bool ClangExpressionParser::RewriteExpression(
for (const auto &diag : diagnostic_manager.Diagnostics()) {
const auto *diagnostic = llvm::dyn_cast<ClangDiagnostic>(diag.get());
- if (diagnostic && diagnostic->HasFixIts()) {
- for (const FixItHint &fixit : diagnostic->FixIts()) {
- // This is cobbed from clang::Rewrite::FixItRewriter.
- if (fixit.CodeToInsert.empty()) {
- if (fixit.InsertFromRange.isValid()) {
- commit.insertFromRange(fixit.RemoveRange.getBegin(),
- fixit.InsertFromRange, /*afterToken=*/false,
- fixit.BeforePreviousInsertions);
- } else
- commit.remove(fixit.RemoveRange);
- } else {
- if (fixit.RemoveRange.isTokenRange() ||
- fixit.RemoveRange.getBegin() != fixit.RemoveRange.getEnd())
- commit.replace(fixit.RemoveRange, fixit.CodeToInsert);
- else
- commit.insert(fixit.RemoveRange.getBegin(), fixit.CodeToInsert,
- /*afterToken=*/false, fixit.BeforePreviousInsertions);
- }
- }
- }
+ if (!diagnostic)
+ continue;
+ if (!diagnostic->HasFixIts())
+ continue;
+ for (const FixItHint &fixit : diagnostic->FixIts())
+ ApplyFixIt(fixit, commit);
}
// FIXME - do we want to try to propagate specific errors here?
@@ -1230,18 +1330,13 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution(
type_system_helper->DeclMap(); // result can be NULL
if (decl_map) {
- Target *target = exe_ctx.GetTargetPtr();
- auto &error_stream = target->GetDebugger().GetErrorStream();
+ StreamString error_stream;
IRForTarget ir_for_target(decl_map, m_expr.NeedsVariableResolution(),
*execution_unit_sp, error_stream,
function_name.AsCString());
- bool ir_can_run =
- ir_for_target.runOnModule(*execution_unit_sp->GetModule());
-
- if (!ir_can_run) {
- err.SetErrorString(
- "The expression could not be prepared to run in the target");
+ if (!ir_for_target.runOnModule(*execution_unit_sp->GetModule())) {
+ err.SetErrorString(error_stream.GetString());
return err;
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
index 4a410cecb94a..6afee22da8d1 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
@@ -6,10 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangExpressionParser_h_
-#define liblldb_ClangExpressionParser_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONPARSER_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONPARSER_H
-#include "lldb/Core/ClangForward.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/ExpressionParser.h"
#include "lldb/Utility/ArchSpec.h"
@@ -19,13 +18,20 @@
#include <string>
#include <vector>
+namespace llvm {
+class LLVMContext;
+}
+
namespace clang {
+class CodeGenerator;
class CodeCompleteConsumer;
-}
+class CompilerInstance;
+} // namespace clang
namespace lldb_private {
class IRExecutionUnit;
+class TypeSystemClang;
/// \class ClangExpressionParser ClangExpressionParser.h
/// "lldb/Expression/ClangExpressionParser.h" Encapsulates an instance of
@@ -171,7 +177,7 @@ private:
class LLDBPreprocessorCallbacks;
LLDBPreprocessorCallbacks *m_pp_callbacks; ///< Called when the preprocessor
///encounters module imports
- std::unique_ptr<ClangASTContext> m_ast_context;
+ std::unique_ptr<TypeSystemClang> m_ast_context;
std::vector<std::string> m_include_directories;
/// File name used for the user expression.
@@ -179,4 +185,4 @@ private:
};
}
-#endif // liblldb_ClangExpressionParser_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONPARSER_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
index 7ebb5fee1ec6..a429963277d1 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
@@ -1,4 +1,4 @@
-//===-- ClangExpressionSourceCode.cpp ---------------------------*- C++ -*-===//
+//===-- ClangExpressionSourceCode.cpp -------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -9,6 +9,7 @@
#include "ClangExpressionSourceCode.h"
#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/StringRef.h"
@@ -173,8 +174,8 @@ static void AddMacros(const DebugMacros *dm, CompileUnit *comp_unit,
lldb_private::ClangExpressionSourceCode::ClangExpressionSourceCode(
llvm::StringRef filename, llvm::StringRef name, llvm::StringRef prefix,
- llvm::StringRef body, Wrapping wrap)
- : ExpressionSourceCode(name, prefix, body, wrap) {
+ llvm::StringRef body, Wrapping wrap, WrapKind wrap_kind)
+ : ExpressionSourceCode(name, prefix, body, wrap), m_wrap_kind(wrap_kind) {
// Use #line markers to pretend that we have a single-line source file
// containing only the user expression. This will hide our wrapper code
// from the user when we render diagnostics with Clang.
@@ -260,10 +261,9 @@ TokenVerifier::TokenVerifier(std::string body) {
}
}
-static void AddLocalVariableDecls(const lldb::VariableListSP &var_list_sp,
- StreamString &stream,
- const std::string &expr,
- lldb::LanguageType wrapping_language) {
+void ClangExpressionSourceCode::AddLocalVariableDecls(
+ const lldb::VariableListSP &var_list_sp, StreamString &stream,
+ const std::string &expr) const {
TokenVerifier tokens(expr);
for (size_t i = 0; i < var_list_sp->GetSize(); i++) {
@@ -280,13 +280,12 @@ static void AddLocalVariableDecls(const lldb::VariableListSP &var_list_sp,
if (!expr.empty() && !tokens.hasToken(var_name.GetStringRef()))
continue;
- if ((var_name == "self" || var_name == "_cmd") &&
- (wrapping_language == lldb::eLanguageTypeObjC ||
- wrapping_language == lldb::eLanguageTypeObjC_plus_plus))
+ const bool is_objc = m_wrap_kind == WrapKind::ObjCInstanceMethod ||
+ m_wrap_kind == WrapKind::ObjCStaticMethod;
+ if ((var_name == "self" || var_name == "_cmd") && is_objc)
continue;
- if (var_name == "this" &&
- wrapping_language == lldb::eLanguageTypeC_plus_plus)
+ if (var_name == "this" && m_wrap_kind == WrapKind::CppMemberFunction)
continue;
stream.Printf("using $__lldb_local_vars::%s;\n", var_name.AsCString());
@@ -294,9 +293,8 @@ static void AddLocalVariableDecls(const lldb::VariableListSP &var_list_sp,
}
bool ClangExpressionSourceCode::GetText(
- std::string &text, lldb::LanguageType wrapping_language, bool static_method,
- ExecutionContext &exe_ctx, bool add_locals, bool force_add_all_locals,
- llvm::ArrayRef<std::string> modules) const {
+ std::string &text, ExecutionContext &exe_ctx, bool add_locals,
+ bool force_add_all_locals, llvm::ArrayRef<std::string> modules) const {
const char *target_specific_defines = "typedef signed char BOOL;\n";
std::string module_macros;
@@ -373,21 +371,11 @@ bool ClangExpressionSourceCode::GetText(
lldb::VariableListSP var_list_sp =
frame->GetInScopeVariableList(false, true);
AddLocalVariableDecls(var_list_sp, lldb_local_var_decls,
- force_add_all_locals ? "" : m_body,
- wrapping_language);
+ force_add_all_locals ? "" : m_body);
}
}
if (m_wrap) {
- switch (wrapping_language) {
- default:
- return false;
- case lldb::eLanguageTypeC:
- case lldb::eLanguageTypeC_plus_plus:
- case lldb::eLanguageTypeObjC:
- break;
- }
-
// Generate a list of @import statements that will import the specified
// module into our expression.
std::string module_imports;
@@ -406,22 +394,12 @@ bool ClangExpressionSourceCode::GetText(
// First construct a tagged form of the user expression so we can find it
// later:
std::string tagged_body;
- switch (wrapping_language) {
- default:
- tagged_body = m_body;
- break;
- case lldb::eLanguageTypeC:
- case lldb::eLanguageTypeC_plus_plus:
- case lldb::eLanguageTypeObjC:
- tagged_body.append(m_start_marker);
- tagged_body.append(m_body);
- tagged_body.append(m_end_marker);
- break;
- }
- switch (wrapping_language) {
- default:
- break;
- case lldb::eLanguageTypeC:
+ tagged_body.append(m_start_marker);
+ tagged_body.append(m_body);
+ tagged_body.append(m_end_marker);
+
+ switch (m_wrap_kind) {
+ case WrapKind::Function:
wrap_stream.Printf("%s"
"void \n"
"%s(void *$__lldb_arg) \n"
@@ -432,7 +410,7 @@ bool ClangExpressionSourceCode::GetText(
module_imports.c_str(), m_name.c_str(),
lldb_local_var_decls.GetData(), tagged_body.c_str());
break;
- case lldb::eLanguageTypeC_plus_plus:
+ case WrapKind::CppMemberFunction:
wrap_stream.Printf("%s"
"void \n"
"$__lldb_class::%s(void *$__lldb_arg) \n"
@@ -443,42 +421,42 @@ bool ClangExpressionSourceCode::GetText(
module_imports.c_str(), m_name.c_str(),
lldb_local_var_decls.GetData(), tagged_body.c_str());
break;
- case lldb::eLanguageTypeObjC:
- if (static_method) {
- wrap_stream.Printf(
- "%s"
- "@interface $__lldb_objc_class ($__lldb_category) \n"
- "+(void)%s:(void *)$__lldb_arg; \n"
- "@end \n"
- "@implementation $__lldb_objc_class ($__lldb_category) \n"
- "+(void)%s:(void *)$__lldb_arg \n"
- "{ \n"
- " %s; \n"
- "%s"
- "} \n"
- "@end \n",
- module_imports.c_str(), m_name.c_str(), m_name.c_str(),
- lldb_local_var_decls.GetData(), tagged_body.c_str());
- } else {
- wrap_stream.Printf(
- "%s"
- "@interface $__lldb_objc_class ($__lldb_category) \n"
- "-(void)%s:(void *)$__lldb_arg; \n"
- "@end \n"
- "@implementation $__lldb_objc_class ($__lldb_category) \n"
- "-(void)%s:(void *)$__lldb_arg \n"
- "{ \n"
- " %s; \n"
- "%s"
- "} \n"
- "@end \n",
- module_imports.c_str(), m_name.c_str(), m_name.c_str(),
- lldb_local_var_decls.GetData(), tagged_body.c_str());
- }
+ case WrapKind::ObjCInstanceMethod:
+ wrap_stream.Printf(
+ "%s"
+ "@interface $__lldb_objc_class ($__lldb_category) \n"
+ "-(void)%s:(void *)$__lldb_arg; \n"
+ "@end \n"
+ "@implementation $__lldb_objc_class ($__lldb_category) \n"
+ "-(void)%s:(void *)$__lldb_arg \n"
+ "{ \n"
+ " %s; \n"
+ "%s"
+ "} \n"
+ "@end \n",
+ module_imports.c_str(), m_name.c_str(), m_name.c_str(),
+ lldb_local_var_decls.GetData(), tagged_body.c_str());
+ break;
+
+ case WrapKind::ObjCStaticMethod:
+ wrap_stream.Printf(
+ "%s"
+ "@interface $__lldb_objc_class ($__lldb_category) \n"
+ "+(void)%s:(void *)$__lldb_arg; \n"
+ "@end \n"
+ "@implementation $__lldb_objc_class ($__lldb_category) \n"
+ "+(void)%s:(void *)$__lldb_arg \n"
+ "{ \n"
+ " %s; \n"
+ "%s"
+ "} \n"
+ "@end \n",
+ module_imports.c_str(), m_name.c_str(), m_name.c_str(),
+ lldb_local_var_decls.GetData(), tagged_body.c_str());
break;
}
- text = wrap_stream.GetString();
+ text = std::string(wrap_stream.GetString());
} else {
text.append(m_body);
}
@@ -487,17 +465,7 @@ bool ClangExpressionSourceCode::GetText(
}
bool ClangExpressionSourceCode::GetOriginalBodyBounds(
- std::string transformed_text, lldb::LanguageType wrapping_language,
- size_t &start_loc, size_t &end_loc) {
- switch (wrapping_language) {
- default:
- return false;
- case lldb::eLanguageTypeC:
- case lldb::eLanguageTypeC_plus_plus:
- case lldb::eLanguageTypeObjC:
- break;
- }
-
+ std::string transformed_text, size_t &start_loc, size_t &end_loc) {
start_loc = transformed_text.find(m_start_marker);
if (start_loc == std::string::npos)
return false;
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
index 1d159670b962..9a54f0e3ad8d 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangExpressionSourceCode_h
-#define liblldb_ClangExpressionSourceCode_h
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONSOURCECODE_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONSOURCECODE_H
#include "lldb/Expression/Expression.h"
#include "lldb/Expression/ExpressionSourceCode.h"
@@ -28,20 +28,30 @@ public:
static const llvm::StringRef g_prefix_file_name;
static const char *g_expression_prefix;
+ /// The possible ways an expression can be wrapped.
+ enum class WrapKind {
+ /// Wrapped in a non-static member function of a C++ class.
+ CppMemberFunction,
+ /// Wrapped in an instance Objective-C method.
+ ObjCInstanceMethod,
+ /// Wrapped in a static Objective-C method.
+ ObjCStaticMethod,
+ /// Wrapped in a non-member function.
+ /// Note that this is also used for static member functions of a C++ class.
+ Function
+ };
+
static ClangExpressionSourceCode *CreateWrapped(llvm::StringRef filename,
llvm::StringRef prefix,
- llvm::StringRef body) {
+ llvm::StringRef body,
+ WrapKind wrap_kind) {
return new ClangExpressionSourceCode(filename, "$__lldb_expr", prefix, body,
- Wrap);
+ Wrap, wrap_kind);
}
/// Generates the source code that will evaluate the expression.
///
/// \param text output parameter containing the source code string.
- /// \param wrapping_language If the expression is supossed to be wrapped,
- /// then this is the language that should be used for that.
- /// \param static_method True iff the expression is valuated inside a static
- /// Objective-C method.
/// \param exe_ctx The execution context in which the expression will be
/// evaluated.
/// \param add_locals True iff local variables should be injected into the
@@ -51,8 +61,7 @@ public:
/// \param modules A list of (C++) modules that the expression should import.
///
/// \return true iff the source code was successfully generated.
- bool GetText(std::string &text, lldb::LanguageType wrapping_language,
- bool static_method, ExecutionContext &exe_ctx, bool add_locals,
+ bool GetText(std::string &text, ExecutionContext &exe_ctx, bool add_locals,
bool force_add_all_locals,
llvm::ArrayRef<std::string> modules) const;
@@ -60,19 +69,24 @@ public:
// passed to CreateWrapped. Return true if the bounds could be found. This
// will also work on text with FixItHints applied.
bool GetOriginalBodyBounds(std::string transformed_text,
- lldb::LanguageType wrapping_language,
size_t &start_loc, size_t &end_loc);
protected:
ClangExpressionSourceCode(llvm::StringRef filename, llvm::StringRef name,
llvm::StringRef prefix, llvm::StringRef body,
- Wrapping wrap);
+ Wrapping wrap, WrapKind wrap_kind);
private:
+ void AddLocalVariableDecls(const lldb::VariableListSP &var_list_sp,
+ StreamString &stream,
+ const std::string &expr) const;
+
/// String marking the start of the user expression.
std::string m_start_marker;
/// String marking the end of the user expression.
std::string m_end_marker;
+ /// How the expression has been wrapped.
+ const WrapKind m_wrap_kind;
};
} // namespace lldb_private
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp
index b5a2c80b5349..9af92e194da9 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp
@@ -1,4 +1,4 @@
-//===-- ClangExpressionVariable.cpp -----------------------------*- C++ -*-===//
+//===-- ClangExpressionVariable.cpp ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
index 0e6de28ee4df..58d589962abe 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangExpressionVariable_h_
-#define liblldb_ClangExpressionVariable_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H
#include <signal.h>
#include <stdint.h>
@@ -19,7 +19,6 @@
#include "llvm/Support/Casting.h"
-#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Value.h"
#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Symbol/TaggedASTType.h"
@@ -30,6 +29,10 @@ namespace llvm {
class Value;
}
+namespace clang {
+class NamedDecl;
+}
+
namespace lldb_private {
class ValueObjectConstResult;
@@ -114,11 +117,9 @@ public:
class ParserVars {
public:
ParserVars()
- : m_parser_type(), m_named_decl(nullptr), m_llvm_value(nullptr),
+ : m_named_decl(nullptr), m_llvm_value(nullptr),
m_lldb_value(), m_lldb_var(), m_lldb_sym(nullptr) {}
- TypeFromParser
- m_parser_type; ///< The type of the variable according to the parser
const clang::NamedDecl
*m_named_decl; ///< The Decl corresponding to this variable
llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable;
@@ -196,9 +197,11 @@ public:
}
/// Members
- DISALLOW_COPY_AND_ASSIGN(ClangExpressionVariable);
+ ClangExpressionVariable(const ClangExpressionVariable &) = delete;
+ const ClangExpressionVariable &
+ operator=(const ClangExpressionVariable &) = delete;
};
} // namespace lldb_private
-#endif // liblldb_ClangExpressionVariable_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp
new file mode 100644
index 000000000000..390afb458b5a
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp
@@ -0,0 +1,88 @@
+//===-- ClangExternalASTSourceCallbacks.cpp -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+
+using namespace lldb_private;
+
+char ClangExternalASTSourceCallbacks::ID;
+
+void ClangExternalASTSourceCallbacks::CompleteType(clang::TagDecl *tag_decl) {
+ m_ast.CompleteTagDecl(tag_decl);
+}
+
+void ClangExternalASTSourceCallbacks::CompleteType(
+ clang::ObjCInterfaceDecl *objc_decl) {
+ m_ast.CompleteObjCInterfaceDecl(objc_decl);
+}
+
+bool ClangExternalASTSourceCallbacks::layoutRecordType(
+ const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &VirtualBaseOffsets) {
+ return m_ast.LayoutRecordType(Record, Size, Alignment, FieldOffsets,
+ BaseOffsets, VirtualBaseOffsets);
+}
+
+void ClangExternalASTSourceCallbacks::FindExternalLexicalDecls(
+ const clang::DeclContext *decl_ctx,
+ llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
+ llvm::SmallVectorImpl<clang::Decl *> &decls) {
+ if (decl_ctx) {
+ clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(
+ const_cast<clang::DeclContext *>(decl_ctx));
+ if (tag_decl)
+ CompleteType(tag_decl);
+ }
+}
+
+bool ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(
+ const clang::DeclContext *DC, clang::DeclarationName Name) {
+ llvm::SmallVector<clang::NamedDecl *, 4> decls;
+ // Objective-C methods are not added into the LookupPtr when they originate
+ // from an external source. SetExternalVisibleDeclsForName() adds them.
+ if (auto *oid = llvm::dyn_cast<clang::ObjCInterfaceDecl>(DC)) {
+ clang::ObjCContainerDecl::method_range noload_methods(oid->noload_decls());
+ for (auto *omd : noload_methods)
+ if (omd->getDeclName() == Name)
+ decls.push_back(omd);
+ }
+ return !SetExternalVisibleDeclsForName(DC, Name, decls).empty();
+}
+
+OptionalClangModuleID
+ClangExternalASTSourceCallbacks::RegisterModule(clang::Module *module) {
+ m_modules.push_back(module);
+ unsigned id = m_modules.size();
+ m_ids.insert({module, id});
+ return OptionalClangModuleID(id);
+}
+
+llvm::Optional<clang::ASTSourceDescriptor>
+ClangExternalASTSourceCallbacks::getSourceDescriptor(unsigned id) {
+ if (clang::Module *module = getModule(id))
+ return {*module};
+ return {};
+}
+
+clang::Module *ClangExternalASTSourceCallbacks::getModule(unsigned id) {
+ if (id && id <= m_modules.size())
+ return m_modules[id - 1];
+ return nullptr;
+}
+
+OptionalClangModuleID
+ClangExternalASTSourceCallbacks::GetIDForModule(clang::Module *module) {
+ return OptionalClangModuleID(m_ids[module]);
+}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h
new file mode 100644
index 000000000000..69088d9c82a5
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h
@@ -0,0 +1,66 @@
+//===-- ClangExternalASTSourceCallbacks.h -----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXTERNALASTSOURCECALLBACKS_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXTERNALASTSOURCECALLBACKS_H
+
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+#include "clang/Basic/Module.h"
+
+namespace lldb_private {
+
+class ClangExternalASTSourceCallbacks : public clang::ExternalASTSource {
+ /// LLVM RTTI support.
+ static char ID;
+
+public:
+ /// LLVM RTTI support.
+ bool isA(const void *ClassID) const override { return ClassID == &ID; }
+ static bool classof(const clang::ExternalASTSource *s) { return s->isA(&ID); }
+
+ ClangExternalASTSourceCallbacks(TypeSystemClang &ast) : m_ast(ast) {}
+
+ void FindExternalLexicalDecls(
+ const clang::DeclContext *DC,
+ llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
+ llvm::SmallVectorImpl<clang::Decl *> &Result) override;
+
+ bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
+ clang::DeclarationName Name) override;
+
+ void CompleteType(clang::TagDecl *tag_decl) override;
+
+ void CompleteType(clang::ObjCInterfaceDecl *objc_decl) override;
+
+ bool layoutRecordType(
+ const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &BaseOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &VirtualBaseOffsets) override;
+
+ TypeSystemClang &GetTypeSystem() const { return m_ast; }
+
+ /// Module-related methods.
+ /// \{
+ llvm::Optional<clang::ASTSourceDescriptor>
+ getSourceDescriptor(unsigned ID) override;
+ clang::Module *getModule(unsigned ID) override;
+ OptionalClangModuleID RegisterModule(clang::Module *module);
+ OptionalClangModuleID GetIDForModule(clang::Module *module);
+ /// \}
+private:
+ TypeSystemClang &m_ast;
+ std::vector<clang::Module *> m_modules;
+ llvm::DenseMap<clang::Module *, unsigned> m_ids;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXTERNALASTSOURCECALLBACKS_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
index 7f7c0a97f538..0c9ad2021035 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
@@ -1,4 +1,4 @@
-//===-- ClangFunctionCaller.cpp ---------------------------------*- C++ -*-===//
+//===-- ClangFunctionCaller.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -21,12 +21,12 @@
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/IR/Module.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Target/ExecutionContext.h"
@@ -209,8 +209,8 @@ ClangFunctionCaller::CompileFunction(lldb::ThreadSP thread_to_use_sp,
clang::ASTConsumer *
ClangFunctionCaller::ClangFunctionCallerHelper::ASTTransformer(
clang::ASTConsumer *passthrough) {
- m_struct_extractor.reset(new ASTStructExtractor(
- passthrough, m_owner.GetWrapperStructName(), m_owner));
+ m_struct_extractor = std::make_unique<ASTStructExtractor>(
+ passthrough, m_owner.GetWrapperStructName(), m_owner);
return m_struct_extractor.get();
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
index 150a913152d0..8060b8c0aedc 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
@@ -6,13 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangFunctionCaller_h_
-#define liblldb_ClangFunctionCaller_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGFUNCTIONCALLER_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGFUNCTIONCALLER_H
#include "ClangExpressionHelper.h"
#include "lldb/Core/Address.h"
-#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Expression/FunctionCaller.h"
@@ -150,4 +149,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_ClangFunctionCaller_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGFUNCTIONCALLER_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
index 42d3f22014dd..8abb7e420575 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
@@ -1,4 +1,4 @@
-//===-- ClangHost.cpp -------------------------------------------*- C++ -*-===//
+//===-- ClangHost.cpp -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -67,10 +67,10 @@ static bool DefaultComputeClangResourceDirectory(FileSpec &lldb_shlib_spec,
llvm::sys::path::native(relative_path);
llvm::sys::path::append(clang_dir, relative_path);
if (!verify || VerifyClangPath(clang_dir)) {
- LLDB_LOGF(log,
- "DefaultComputeClangResourceDir: Setting ClangResourceDir "
- "to \"%s\", verify = %s",
- clang_dir.str().str().c_str(), verify ? "true" : "false");
+ LLDB_LOG(log,
+ "DefaultComputeClangResourceDir: Setting ClangResourceDir "
+ "to \"{0}\", verify = {1}",
+ clang_dir.str(), verify ? "true" : "false");
file_spec.GetDirectory().SetString(clang_dir);
FileSystem::Instance().Resolve(file_spec);
return true;
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.h
index 9d49188178cd..d6809909a625 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGHOST_H
-#define LLDB_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGHOST_H
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGHOST_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGHOST_H
namespace lldb_private {
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
index 0696c669f2e2..95acb883774d 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
@@ -1,4 +1,4 @@
-//===-- ClangModulesDeclVendor.cpp ------------------------------*- C++ -*-===//
+//===-- ClangModulesDeclVendor.cpp ----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,11 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#include <mutex>
-
#include "clang/Basic/TargetInfo.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Parse/Parser.h"
@@ -24,10 +23,10 @@
#include "ClangModulesDeclVendor.h"
#include "ModuleDependencyCollector.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/SourceModule.h"
#include "lldb/Target/Target.h"
@@ -37,6 +36,9 @@
#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/StreamString.h"
+#include <memory>
+#include <mutex>
+
using namespace lldb_private;
namespace {
@@ -54,10 +56,21 @@ public:
void DumpDiagnostics(Stream &error_stream);
+ void BeginSourceFile(const clang::LangOptions &LangOpts,
+ const clang::Preprocessor *PP = nullptr) override;
+ void EndSourceFile() override;
+
private:
typedef std::pair<clang::DiagnosticsEngine::Level, std::string>
IDAndDiagnostic;
std::vector<IDAndDiagnostic> m_diagnostics;
+ /// The DiagnosticPrinter used for creating the full diagnostic messages
+ /// that are stored in m_diagnostics.
+ std::shared_ptr<clang::TextDiagnosticPrinter> m_diag_printer;
+ /// Output stream of m_diag_printer.
+ std::shared_ptr<llvm::raw_string_ostream> m_os;
+ /// Output string filled by m_os. Will be reused for different diagnostics.
+ std::string m_output;
Log *m_log;
};
@@ -108,25 +121,30 @@ private:
typedef std::set<ModuleID> ImportedModuleSet;
ImportedModuleMap m_imported_modules;
ImportedModuleSet m_user_imported_modules;
- // We assume that every ASTContext has an ClangASTContext, so we also store
- // a custom ClangASTContext for our internal ASTContext.
- std::unique_ptr<ClangASTContext> m_ast_context;
+ // We assume that every ASTContext has an TypeSystemClang, so we also store
+ // a custom TypeSystemClang for our internal ASTContext.
+ std::unique_ptr<TypeSystemClang> m_ast_context;
};
} // anonymous namespace
StoringDiagnosticConsumer::StoringDiagnosticConsumer() {
m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+
+ clang::DiagnosticOptions *m_options = new clang::DiagnosticOptions();
+ m_os = std::make_shared<llvm::raw_string_ostream>(m_output);
+ m_diag_printer =
+ std::make_shared<clang::TextDiagnosticPrinter>(*m_os, m_options);
}
void StoringDiagnosticConsumer::HandleDiagnostic(
clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &info) {
- llvm::SmallVector<char, 256> diagnostic_string;
+ // Print the diagnostic to m_output.
+ m_output.clear();
+ m_diag_printer->HandleDiagnostic(DiagLevel, info);
+ m_os->flush();
- info.FormatDiagnostic(diagnostic_string);
-
- m_diagnostics.push_back(
- IDAndDiagnostic(DiagLevel, std::string(diagnostic_string.data(),
- diagnostic_string.size())));
+ // Store the diagnostic for later.
+ m_diagnostics.push_back(IDAndDiagnostic(DiagLevel, m_output));
}
void StoringDiagnosticConsumer::ClearDiagnostics() { m_diagnostics.clear(); }
@@ -144,6 +162,15 @@ void StoringDiagnosticConsumer::DumpDiagnostics(Stream &error_stream) {
}
}
+void StoringDiagnosticConsumer::BeginSourceFile(
+ const clang::LangOptions &LangOpts, const clang::Preprocessor *PP) {
+ m_diag_printer->BeginSourceFile(LangOpts, PP);
+}
+
+void StoringDiagnosticConsumer::EndSourceFile() {
+ m_diag_printer->EndSourceFile();
+}
+
ClangModulesDeclVendor::ClangModulesDeclVendor()
: ClangDeclVendor(eClangModuleDeclVendor) {}
@@ -159,8 +186,10 @@ ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl(
m_compiler_instance(std::move(compiler_instance)),
m_parser(std::move(parser)) {
- // Initialize our ClangASTContext.
- m_ast_context.reset(new ClangASTContext(m_compiler_instance->getASTContext()));
+ // Initialize our TypeSystemClang.
+ m_ast_context =
+ std::make_unique<TypeSystemClang>("ClangModulesDeclVendor ASTContext",
+ m_compiler_instance->getASTContext());
}
void ClangModulesDeclVendorImpl::ReportModuleExportsHelper(
@@ -382,7 +411,7 @@ ClangModulesDeclVendorImpl::FindDecls(ConstString name, bool append,
if (num_matches >= max_matches)
return num_matches;
- decls.push_back(CompilerDecl(m_ast_context.get(), named_decl));
+ decls.push_back(m_ast_context->GetCompilerDecl(named_decl));
++num_matches;
}
@@ -601,10 +630,10 @@ ClangModulesDeclVendor::Create(Target &target) {
{
llvm::SmallString<128> path;
- auto props = ModuleList::GetGlobalModuleListProperties();
+ const auto &props = ModuleList::GetGlobalModuleListProperties();
props.GetClangModulesCachePath().GetPath(path);
std::string module_cache_argument("-fmodules-cache-path=");
- module_cache_argument.append(path.str());
+ module_cache_argument.append(std::string(path.str()));
compiler_invocation_arguments.push_back(module_cache_argument);
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
index e099b59041d8..f04d1b07f03d 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
@@ -6,10 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangModulesDeclVendor_h
-#define liblldb_ClangModulesDeclVendor_h
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGMODULESDECLVENDOR_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGMODULESDECLVENDOR_H
-#include "lldb/Core/ClangForward.h"
#include "lldb/Symbol/SourceModule.h"
#include "lldb/Target/Platform.h"
@@ -113,4 +112,4 @@ public:
} // namespace lldb_private
-#endif // liblldb_ClangModulesDeclVendor_h
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGMODULESDECLVENDOR_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
index 41d62a462ab4..42afac9edb0d 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
@@ -1,4 +1,4 @@
-//===-- ClangPersistentVariables.cpp ----------------------------*- C++ -*-===//
+//===-- ClangPersistentVariables.cpp --------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -7,9 +7,10 @@
//===----------------------------------------------------------------------===//
#include "ClangPersistentVariables.h"
+#include "ClangASTImporter.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Value.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
@@ -82,7 +83,7 @@ ClangPersistentVariables::GetCompilerTypeFromPersistentDecl(
void ClangPersistentVariables::RegisterPersistentDecl(ConstString name,
clang::NamedDecl *decl,
- ClangASTContext *ctx) {
+ TypeSystemClang *ctx) {
PersistentDecl p = {decl, ctx};
m_persistent_decls.insert(std::make_pair(name.GetCString(), p));
@@ -99,3 +100,22 @@ clang::NamedDecl *
ClangPersistentVariables::GetPersistentDecl(ConstString name) {
return m_persistent_decls.lookup(name.GetCString()).m_decl;
}
+
+std::shared_ptr<ClangASTImporter>
+ClangPersistentVariables::GetClangASTImporter() {
+ if (!m_ast_importer_sp) {
+ m_ast_importer_sp = std::make_shared<ClangASTImporter>();
+ }
+ return m_ast_importer_sp;
+}
+
+ConstString
+ClangPersistentVariables::GetNextPersistentVariableName(bool is_error) {
+ llvm::SmallString<64> name;
+ {
+ llvm::raw_svector_ostream os(name);
+ os << GetPersistentVariablePrefix(is_error)
+ << m_next_persistent_variable_id++;
+ }
+ return ConstString(name);
+}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
index 434196b35fd5..f888b2d56e68 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangPersistentVariables_h_
-#define liblldb_ClangPersistentVariables_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGPERSISTENTVARIABLES_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGPERSISTENTVARIABLES_H
#include "llvm/ADT/DenseMap.h"
@@ -18,6 +18,9 @@
namespace lldb_private {
+class ClangASTImporter;
+class TypeSystemClang;
+
/// \class ClangPersistentVariables ClangPersistentVariables.h
/// "lldb/Expression/ClangPersistentVariables.h" Manages persistent values
/// that need to be preserved between expression invocations.
@@ -36,6 +39,8 @@ public:
return pv->getKind() == PersistentExpressionState::eKindClang;
}
+ std::shared_ptr<ClangASTImporter> GetClangASTImporter();
+
lldb::ExpressionVariableSP
CreatePersistentVariable(const lldb::ValueObjectSP &valobj_sp) override;
@@ -46,9 +51,7 @@ public:
void RemovePersistentVariable(lldb::ExpressionVariableSP variable) override;
- llvm::StringRef GetPersistentVariablePrefix(bool is_error) const override {
- return "$";
- }
+ ConstString GetNextPersistentVariableName(bool is_error = false) override;
/// Returns the next file name that should be used for user expressions.
std::string GetNextExprFileName() {
@@ -63,7 +66,7 @@ public:
GetCompilerTypeFromPersistentDecl(ConstString type_name) override;
void RegisterPersistentDecl(ConstString name, clang::NamedDecl *decl,
- ClangASTContext *ctx);
+ TypeSystemClang *ctx);
clang::NamedDecl *GetPersistentDecl(ConstString name);
@@ -75,6 +78,12 @@ public:
return m_hand_loaded_clang_modules;
}
+protected:
+ llvm::StringRef
+ GetPersistentVariablePrefix(bool is_error = false) const override {
+ return "$";
+ }
+
private:
/// The counter used by GetNextExprFileName.
uint32_t m_next_user_file_id = 0;
@@ -84,8 +93,8 @@ private:
struct PersistentDecl {
/// The persistent decl.
clang::NamedDecl *m_decl = nullptr;
- /// The ClangASTContext for the ASTContext of m_decl.
- ClangASTContext *m_context = nullptr;
+ /// The TypeSystemClang for the ASTContext of m_decl.
+ TypeSystemClang *m_context = nullptr;
};
typedef llvm::DenseMap<const char *, PersistentDecl> PersistentDeclMap;
@@ -96,8 +105,9 @@ private:
m_hand_loaded_clang_modules; ///< These are Clang modules we hand-loaded;
///these are the highest-
///< priority source for macros.
+ std::shared_ptr<ClangASTImporter> m_ast_importer_sp;
};
} // namespace lldb_private
-#endif // liblldb_ClangPersistentVariables_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGPERSISTENTVARIABLES_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index 6698797617a3..a28b4a7fb42c 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -1,4 +1,4 @@
-//===-- ClangUserExpression.cpp ---------------------------------*- C++ -*-===//
+//===-- ClangUserExpression.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -20,6 +20,7 @@
#include "ClangUserExpression.h"
#include "ASTResultSynthesizer.h"
+#include "ClangASTMetadata.h"
#include "ClangDiagnostic.h"
#include "ClangExpressionDeclMap.h"
#include "ClangExpressionParser.h"
@@ -27,6 +28,7 @@
#include "ClangPersistentVariables.h"
#include "CppModuleConfiguration.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
@@ -37,8 +39,6 @@
#include "lldb/Expression/Materializer.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/Block.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangASTMetadata.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -154,7 +154,7 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
}
m_needs_object_ptr = true;
} else if (clang::CXXMethodDecl *method_decl =
- ClangASTContext::DeclContextGetAsCXXMethodDecl(decl_context)) {
+ TypeSystemClang::DeclContextGetAsCXXMethodDecl(decl_context)) {
if (m_allow_cxx && method_decl->isInstance()) {
if (m_enforce_valid_object) {
lldb::VariableListSP variable_list_sp(
@@ -183,7 +183,7 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
m_needs_object_ptr = true;
}
} else if (clang::ObjCMethodDecl *method_decl =
- ClangASTContext::DeclContextGetAsObjCMethodDecl(
+ TypeSystemClang::DeclContextGetAsObjCMethodDecl(
decl_context)) {
if (m_allow_objc) {
if (m_enforce_valid_object) {
@@ -216,7 +216,7 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
m_in_static_method = true;
}
} else if (clang::FunctionDecl *function_decl =
- ClangASTContext::DeclContextGetAsFunctionDecl(decl_context)) {
+ TypeSystemClang::DeclContextGetAsFunctionDecl(decl_context)) {
// We might also have a function that said in the debug information that it
// captured an object pointer. The best way to deal with getting to the
// ivars at present is by pretending that this is a method of a class in
@@ -224,7 +224,7 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
// that here.
ClangASTMetadata *metadata =
- ClangASTContext::DeclContextGetMetaData(decl_context, function_decl);
+ TypeSystemClang::DeclContextGetMetaData(decl_context, function_decl);
if (metadata && metadata->HasObjectPtr()) {
lldb::LanguageType language = metadata->GetObjectPtrLanguage();
if (language == lldb::eLanguageTypeC_plus_plus) {
@@ -292,9 +292,9 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
return;
}
- if (ClangASTContext::IsObjCClassType(self_clang_type)) {
+ if (TypeSystemClang::IsObjCClassType(self_clang_type)) {
return;
- } else if (ClangASTContext::IsObjCObjectPointerType(
+ } else if (TypeSystemClang::IsObjCObjectPointerType(
self_clang_type)) {
m_in_objectivec_method = true;
m_needs_object_ptr = true;
@@ -347,50 +347,70 @@ bool ClangUserExpression::SetupPersistentState(DiagnosticManager &diagnostic_man
return true;
}
-static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target) {
- if (ClangModulesDeclVendor *decl_vendor =
- target->GetClangModulesDeclVendor()) {
- auto *persistent_state = llvm::cast<ClangPersistentVariables>(
- target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC));
- if (!persistent_state)
- return;
- const ClangModulesDeclVendor::ModuleVector &hand_imported_modules =
- persistent_state->GetHandLoadedClangModules();
- ClangModulesDeclVendor::ModuleVector modules_for_macros;
+static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target,
+ DiagnosticManager &diagnostic_manager) {
+ ClangModulesDeclVendor *decl_vendor = target->GetClangModulesDeclVendor();
+ if (!decl_vendor)
+ return;
- for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules) {
- modules_for_macros.push_back(module);
- }
+ if (!target->GetEnableAutoImportClangModules())
+ return;
- if (target->GetEnableAutoImportClangModules()) {
- if (StackFrame *frame = exe_ctx.GetFramePtr()) {
- if (Block *block = frame->GetFrameBlock()) {
- SymbolContext sc;
+ auto *persistent_state = llvm::cast<ClangPersistentVariables>(
+ target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC));
+ if (!persistent_state)
+ return;
- block->CalculateSymbolContext(&sc);
+ StackFrame *frame = exe_ctx.GetFramePtr();
+ if (!frame)
+ return;
- if (sc.comp_unit) {
- StreamString error_stream;
+ Block *block = frame->GetFrameBlock();
+ if (!block)
+ return;
+ SymbolContext sc;
- decl_vendor->AddModulesForCompileUnit(
- *sc.comp_unit, modules_for_macros, error_stream);
- }
- }
- }
- }
+ block->CalculateSymbolContext(&sc);
+
+ if (!sc.comp_unit)
+ return;
+ StreamString error_stream;
+
+ ClangModulesDeclVendor::ModuleVector modules_for_macros =
+ persistent_state->GetHandLoadedClangModules();
+ if (decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros,
+ error_stream))
+ return;
+
+ // Failed to load some modules, so emit the error stream as a diagnostic.
+ if (!error_stream.Empty()) {
+ // The error stream already contains several Clang diagnostics that might
+ // be either errors or warnings, so just print them all as one remark
+ // diagnostic to prevent that the message starts with "error: error:".
+ diagnostic_manager.PutString(eDiagnosticSeverityRemark,
+ error_stream.GetString());
+ return;
}
+
+ diagnostic_manager.PutString(eDiagnosticSeverityError,
+ "Unknown error while loading modules needed for "
+ "current compilation unit.");
}
-void ClangUserExpression::UpdateLanguageForExpr() {
- m_expr_lang = lldb::LanguageType::eLanguageTypeUnknown;
- if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
- return;
+ClangExpressionSourceCode::WrapKind ClangUserExpression::GetWrapKind() const {
+ assert(m_options.GetExecutionPolicy() != eExecutionPolicyTopLevel &&
+ "Top level expressions aren't wrapped.");
+ using Kind = ClangExpressionSourceCode::WrapKind;
if (m_in_cplusplus_method)
- m_expr_lang = lldb::eLanguageTypeC_plus_plus;
- else if (m_in_objectivec_method)
- m_expr_lang = lldb::eLanguageTypeObjC;
- else
- m_expr_lang = lldb::eLanguageTypeC;
+ return Kind::CppMemberFunction;
+ else if (m_in_objectivec_method) {
+ if (m_in_static_method)
+ return Kind::ObjCStaticMethod;
+ return Kind::ObjCInstanceMethod;
+ }
+ // Not in any kind of 'special' function, so just wrap it in a normal C
+ // function.
+ return Kind::Function;
}
void ClangUserExpression::CreateSourceCode(
@@ -404,10 +424,9 @@ void ClangUserExpression::CreateSourceCode(
m_transformed_text = m_expr_text;
} else {
m_source_code.reset(ClangExpressionSourceCode::CreateWrapped(
- m_filename, prefix.c_str(), m_expr_text.c_str()));
+ m_filename, prefix, m_expr_text, GetWrapKind()));
- if (!m_source_code->GetText(m_transformed_text, m_expr_lang,
- m_in_static_method, exe_ctx, !m_ctx_obj,
+ if (!m_source_code->GetText(m_transformed_text, exe_ctx, !m_ctx_obj,
for_completion, modules_to_import)) {
diagnostic_manager.PutString(eDiagnosticSeverityError,
"couldn't construct expression body");
@@ -419,7 +438,7 @@ void ClangUserExpression::CreateSourceCode(
std::size_t original_start;
std::size_t original_end;
bool found_bounds = m_source_code->GetOriginalBodyBounds(
- m_transformed_text, m_expr_lang, original_start, original_end);
+ m_transformed_text, original_start, original_end);
if (found_bounds)
m_user_expression_start_pos = original_start;
}
@@ -530,7 +549,7 @@ bool ClangUserExpression::PrepareForParsing(
ApplyObjcCastHack(m_expr_text);
- SetupDeclVendor(exe_ctx, m_target);
+ SetupDeclVendor(exe_ctx, m_target, diagnostic_manager);
CppModuleConfiguration module_config = GetModuleConfig(m_language, exe_ctx);
llvm::ArrayRef<std::string> imported_modules =
@@ -544,7 +563,6 @@ bool ClangUserExpression::PrepareForParsing(
llvm::make_range(m_include_directories.begin(),
m_include_directories.end()));
- UpdateLanguageForExpr();
CreateSourceCode(diagnostic_manager, exe_ctx, imported_modules,
for_completion);
return true;
@@ -577,7 +595,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
// Parse the expression
//
- m_materializer_up.reset(new Materializer());
+ m_materializer_up = std::make_unique<Materializer>();
ResetDeclMap(exe_ctx, m_result_delegate, keep_result_in_memory);
@@ -616,15 +634,13 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
if (parser.RewriteExpression(diagnostic_manager)) {
size_t fixed_start;
size_t fixed_end;
- const std::string &fixed_expression =
- diagnostic_manager.GetFixedExpression();
+ m_fixed_text = diagnostic_manager.GetFixedExpression();
// Retrieve the original expression in case we don't have a top level
// expression (which has no surrounding source code).
- if (m_source_code &&
- m_source_code->GetOriginalBodyBounds(fixed_expression, m_expr_lang,
- fixed_start, fixed_end))
+ if (m_source_code && m_source_code->GetOriginalBodyBounds(
+ m_fixed_text, fixed_start, fixed_end))
m_fixed_text =
- fixed_expression.substr(fixed_start, fixed_end - fixed_start);
+ m_fixed_text.substr(fixed_start, fixed_end - fixed_start);
}
}
return false;
@@ -659,7 +675,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
const char *error_cstr = static_init_error.AsCString();
if (error_cstr && error_cstr[0])
diagnostic_manager.Printf(eDiagnosticSeverityError,
- "couldn't run static initializers: %s\n",
+ "%s\n",
error_cstr);
else
diagnostic_manager.PutString(eDiagnosticSeverityError,
@@ -767,7 +783,7 @@ bool ClangUserExpression::Complete(ExecutionContext &exe_ctx,
// Parse the expression
//
- m_materializer_up.reset(new Materializer());
+ m_materializer_up = std::make_unique<Materializer>();
ResetDeclMap(exe_ctx, m_result_delegate, /*keep result in memory*/ true);
@@ -896,16 +912,23 @@ void ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(
Materializer::PersistentVariableDelegate &delegate,
bool keep_result_in_memory,
ValueObject *ctx_obj) {
- m_expr_decl_map_up.reset(new ClangExpressionDeclMap(
- keep_result_in_memory, &delegate, exe_ctx.GetTargetSP(),
- exe_ctx.GetTargetRef().GetClangASTImporter(), ctx_obj));
+ std::shared_ptr<ClangASTImporter> ast_importer;
+ auto *state = exe_ctx.GetTargetSP()->GetPersistentExpressionStateForLanguage(
+ lldb::eLanguageTypeC);
+ if (state) {
+ auto *persistent_vars = llvm::cast<ClangPersistentVariables>(state);
+ ast_importer = persistent_vars->GetClangASTImporter();
+ }
+ m_expr_decl_map_up = std::make_unique<ClangExpressionDeclMap>(
+ keep_result_in_memory, &delegate, exe_ctx.GetTargetSP(), ast_importer,
+ ctx_obj);
}
clang::ASTConsumer *
ClangUserExpression::ClangUserExpressionHelper::ASTTransformer(
clang::ASTConsumer *passthrough) {
- m_result_synthesizer_up.reset(
- new ASTResultSynthesizer(passthrough, m_top_level, m_target));
+ m_result_synthesizer_up = std::make_unique<ASTResultSynthesizer>(
+ passthrough, m_top_level, m_target);
return m_result_synthesizer_up.get();
}
@@ -917,9 +940,7 @@ void ClangUserExpression::ClangUserExpressionHelper::CommitPersistentDecls() {
}
ConstString ClangUserExpression::ResultDelegate::GetName() {
- auto prefix = m_persistent_state->GetPersistentVariablePrefix();
- return m_persistent_state->GetNextPersistentVariableName(*m_target_sp,
- prefix);
+ return m_persistent_state->GetNextPersistentVariableName(false);
}
void ClangUserExpression::ResultDelegate::DidDematerialize(
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
index 00cbffa7fd6f..f734069655ef 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangUserExpression_h_
-#define liblldb_ClangUserExpression_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUSEREXPRESSION_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUSEREXPRESSION_H
#include <vector>
@@ -20,7 +20,6 @@
#include "IRForTarget.h"
#include "lldb/Core/Address.h"
-#include "lldb/Core/ClangForward.h"
#include "lldb/Expression/LLVMUserExpression.h"
#include "lldb/Expression/Materializer.h"
#include "lldb/Target/ExecutionContext.h"
@@ -186,7 +185,8 @@ private:
ExecutionContext &exe_ctx,
std::vector<std::string> modules_to_import,
bool for_completion);
- void UpdateLanguageForExpr();
+ /// Defines how the current expression should be wrapped.
+ ClangExpressionSourceCode::WrapKind GetWrapKind() const;
bool SetupPersistentState(DiagnosticManager &diagnostic_manager,
ExecutionContext &exe_ctx);
bool PrepareForParsing(DiagnosticManager &diagnostic_manager,
@@ -209,8 +209,6 @@ private:
lldb::TargetSP m_target_sp;
};
- /// The language type of the current expression.
- lldb::LanguageType m_expr_lang = lldb::eLanguageTypeUnknown;
/// The include directories that should be used when parsing the expression.
std::vector<std::string> m_include_directories;
@@ -251,4 +249,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_ClangUserExpression_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUSEREXPRESSION_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.cpp
new file mode 100644
index 000000000000..a7f5dce8558f
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.cpp
@@ -0,0 +1,87 @@
+//===-- ClangUtil.cpp -----------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// A collection of helper methods and data structures for manipulating clang
+// types and decls.
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+
+using namespace clang;
+using namespace lldb_private;
+
+bool ClangUtil::IsClangType(const CompilerType &ct) {
+ // Invalid types are never Clang types.
+ if (!ct)
+ return false;
+
+ if (llvm::dyn_cast_or_null<TypeSystemClang>(ct.GetTypeSystem()) == nullptr)
+ return false;
+
+ if (!ct.GetOpaqueQualType())
+ return false;
+
+ return true;
+}
+
+clang::Decl *ClangUtil::GetDecl(const CompilerDecl &decl) {
+ assert(llvm::isa<TypeSystemClang>(decl.GetTypeSystem()));
+ return static_cast<clang::Decl *>(decl.GetOpaqueDecl());
+}
+
+QualType ClangUtil::GetQualType(const CompilerType &ct) {
+ // Make sure we have a clang type before making a clang::QualType
+ if (!IsClangType(ct))
+ return QualType();
+
+ return QualType::getFromOpaquePtr(ct.GetOpaqueQualType());
+}
+
+QualType ClangUtil::GetCanonicalQualType(const CompilerType &ct) {
+ if (!IsClangType(ct))
+ return QualType();
+
+ return GetQualType(ct).getCanonicalType();
+}
+
+CompilerType ClangUtil::RemoveFastQualifiers(const CompilerType &ct) {
+ if (!IsClangType(ct))
+ return ct;
+
+ QualType qual_type(GetQualType(ct));
+ qual_type.removeLocalFastQualifiers();
+ return CompilerType(ct.GetTypeSystem(), qual_type.getAsOpaquePtr());
+}
+
+clang::TagDecl *ClangUtil::GetAsTagDecl(const CompilerType &type) {
+ clang::QualType qual_type = ClangUtil::GetCanonicalQualType(type);
+ if (qual_type.isNull())
+ return nullptr;
+
+ return qual_type->getAsTagDecl();
+}
+
+std::string ClangUtil::DumpDecl(const clang::Decl *d) {
+ if (!d)
+ return "nullptr";
+
+ std::string result;
+ llvm::raw_string_ostream stream(result);
+ bool deserialize = false;
+ d->dump(stream, deserialize);
+
+ stream.flush();
+ return result;
+}
+
+std::string ClangUtil::ToString(const clang::Type *t) {
+ return clang::QualType(t, 0).getAsString();
+}
+
+std::string ClangUtil::ToString(const CompilerType &c) {
+ return ClangUtil::GetQualType(c).getAsString();
+}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.h
new file mode 100644
index 000000000000..50cae42bc7c2
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.h
@@ -0,0 +1,50 @@
+//===-- ClangUtil.h ---------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// A collection of helper methods and data structures for manipulating clang
+// types and decls.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUTIL_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUTIL_H
+
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/Type.h"
+
+#include "lldb/Symbol/CompilerType.h"
+
+namespace clang {
+class TagDecl;
+}
+
+namespace lldb_private {
+struct ClangUtil {
+ static bool IsClangType(const CompilerType &ct);
+
+ /// Returns the clang::Decl of the given CompilerDecl.
+ /// CompilerDecl has to be valid and represent a clang::Decl.
+ static clang::Decl *GetDecl(const CompilerDecl &decl);
+
+ static clang::QualType GetQualType(const CompilerType &ct);
+
+ static clang::QualType GetCanonicalQualType(const CompilerType &ct);
+
+ static CompilerType RemoveFastQualifiers(const CompilerType &ct);
+
+ static clang::TagDecl *GetAsTagDecl(const CompilerType &type);
+
+ /// Returns a textual representation of the given Decl's AST. Does not
+ /// deserialize any child nodes.
+ static std::string DumpDecl(const clang::Decl *d);
+ /// Returns a textual representation of the given type.
+ static std::string ToString(const clang::Type *t);
+ /// Returns a textual representation of the given CompilerType (assuming
+ /// its underlying type is a Clang type).
+ static std::string ToString(const CompilerType &c);
+};
+}
+
+#endif
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
index 199e4898e118..25ec982220a0 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
@@ -1,4 +1,4 @@
-//===-- ClangUtilityFunction.cpp ---------------------------------*- C++-*-===//
+//===-- ClangUtilityFunction.cpp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -12,6 +12,7 @@
#include "ClangExpressionDeclMap.h"
#include "ClangExpressionParser.h"
#include "ClangExpressionSourceCode.h"
+#include "ClangPersistentVariables.h"
#include <stdio.h>
#if HAVE_SYS_TYPES_H
@@ -159,7 +160,14 @@ bool ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager,
void ClangUtilityFunction::ClangUtilityFunctionHelper::ResetDeclMap(
ExecutionContext &exe_ctx, bool keep_result_in_memory) {
- m_expr_decl_map_up.reset(new ClangExpressionDeclMap(
- keep_result_in_memory, nullptr, exe_ctx.GetTargetSP(),
- exe_ctx.GetTargetRef().GetClangASTImporter(), nullptr));
+ std::shared_ptr<ClangASTImporter> ast_importer;
+ auto *state = exe_ctx.GetTargetSP()->GetPersistentExpressionStateForLanguage(
+ lldb::eLanguageTypeC);
+ if (state) {
+ auto *persistent_vars = llvm::cast<ClangPersistentVariables>(state);
+ ast_importer = persistent_vars->GetClangASTImporter();
+ }
+ m_expr_decl_map_up = std::make_unique<ClangExpressionDeclMap>(
+ keep_result_in_memory, nullptr, exe_ctx.GetTargetSP(), ast_importer,
+ nullptr);
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
index 9efaa0254c3e..1f2dd5fdbecc 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangUtilityFunction_h_
-#define liblldb_ClangUtilityFunction_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUTILITYFUNCTION_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUTILITYFUNCTION_H
#include <map>
#include <string>
@@ -15,7 +15,6 @@
#include "ClangExpressionHelper.h"
-#include "lldb/Core/ClangForward.h"
#include "lldb/Expression/UtilityFunction.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"
@@ -107,4 +106,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_ClangUtilityFunction_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUTILITYFUNCTION_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
index 51ae73285b53..f1272c67d20f 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
@@ -73,7 +73,7 @@ CppModuleConfiguration::CppModuleConfiguration(
llvm::SmallString<256> resource_dir;
llvm::sys::path::append(resource_dir, GetClangResourceDir().GetPath(),
"include");
- m_resource_inc = resource_dir.str();
+ m_resource_inc = std::string(resource_dir.str());
// This order matches the way Clang orders these directories.
m_include_dirs = {m_std_inc.Get(), m_resource_inc, m_c_inc.Get()};
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
index 8e892e37d0de..235ac2bd090c 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_CppModuleConfiguration_h_
-#define liblldb_CppModuleConfiguration_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CPPMODULECONFIGURATION_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CPPMODULECONFIGURATION_H
#include <lldb/Core/FileSpecList.h>
#include <llvm/Support/Regex.h>
@@ -56,7 +56,7 @@ class CppModuleConfiguration {
bool analyzeFile(const FileSpec &f);
public:
- /// Creates a configuraiton by analyzing the given list of used source files.
+ /// Creates a configuration by analyzing the given list of used source files.
///
/// Currently only looks at the used paths and doesn't actually access the
/// files on the disk.
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp b/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp
new file mode 100644
index 000000000000..2f8cf1846ee7
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp
@@ -0,0 +1,289 @@
+//===-- CxxModuleHandler.cpp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/ExpressionParser/Clang/CxxModuleHandler.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+
+#include "lldb/Utility/Log.h"
+#include "clang/Sema/Lookup.h"
+#include "llvm/Support/Error.h"
+
+using namespace lldb_private;
+using namespace clang;
+
+CxxModuleHandler::CxxModuleHandler(ASTImporter &importer, ASTContext *target)
+ : m_importer(&importer),
+ m_sema(TypeSystemClang::GetASTContext(target)->getSema()) {
+
+ std::initializer_list<const char *> supported_names = {
+ // containers
+ "deque",
+ "forward_list",
+ "list",
+ "queue",
+ "stack",
+ "vector",
+ // pointers
+ "shared_ptr",
+ "unique_ptr",
+ "weak_ptr",
+ // utility
+ "allocator",
+ };
+ m_supported_templates.insert(supported_names.begin(), supported_names.end());
+}
+
+/// Builds a list of scopes that point into the given context.
+///
+/// \param sema The sema that will be using the scopes.
+/// \param ctxt The context that the scope should look into.
+/// \param result A list of scopes. The scopes need to be freed by the caller
+/// (except the TUScope which is owned by the sema).
+static void makeScopes(Sema &sema, DeclContext *ctxt,
+ std::vector<Scope *> &result) {
+ // FIXME: The result should be a list of unique_ptrs, but the TUScope makes
+ // this currently impossible as it's owned by the Sema.
+
+ if (auto parent = ctxt->getParent()) {
+ makeScopes(sema, parent, result);
+
+ Scope *scope =
+ new Scope(result.back(), Scope::DeclScope, sema.getDiagnostics());
+ scope->setEntity(ctxt);
+ result.push_back(scope);
+ } else
+ result.push_back(sema.TUScope);
+}
+
+/// Uses the Sema to look up the given name in the given DeclContext.
+static std::unique_ptr<LookupResult>
+emulateLookupInCtxt(Sema &sema, llvm::StringRef name, DeclContext *ctxt) {
+ IdentifierInfo &ident = sema.getASTContext().Idents.get(name);
+
+ std::unique_ptr<LookupResult> lookup_result;
+ lookup_result = std::make_unique<LookupResult>(sema, DeclarationName(&ident),
+ SourceLocation(),
+ Sema::LookupOrdinaryName);
+
+ // Usually during parsing we already encountered the scopes we would use. But
+ // here don't have these scopes so we have to emulate the behavior of the
+ // Sema during parsing.
+ std::vector<Scope *> scopes;
+ makeScopes(sema, ctxt, scopes);
+
+ // Now actually perform the lookup with the sema.
+ sema.LookupName(*lookup_result, scopes.back());
+
+ // Delete all the allocated scopes beside the translation unit scope (which
+ // has depth 0).
+ for (Scope *s : scopes)
+ if (s->getDepth() != 0)
+ delete s;
+
+ return lookup_result;
+}
+
+/// Error class for handling problems when finding a certain DeclContext.
+struct MissingDeclContext : public llvm::ErrorInfo<MissingDeclContext> {
+
+ static char ID;
+
+ MissingDeclContext(DeclContext *context, std::string error)
+ : m_context(context), m_error(error) {}
+
+ DeclContext *m_context;
+ std::string m_error;
+
+ void log(llvm::raw_ostream &OS) const override {
+ OS << llvm::formatv("error when reconstructing context of kind {0}:{1}",
+ m_context->getDeclKindName(), m_error);
+ }
+
+ std::error_code convertToErrorCode() const override {
+ return llvm::inconvertibleErrorCode();
+ }
+};
+
+char MissingDeclContext::ID = 0;
+
+/// Given a foreign decl context, this function finds the equivalent local
+/// decl context in the ASTContext of the given Sema. Potentially deserializes
+/// decls from the 'std' module if necessary.
+static llvm::Expected<DeclContext *>
+getEqualLocalDeclContext(Sema &sema, DeclContext *foreign_ctxt) {
+
+ // Inline namespaces don't matter for lookups, so let's skip them.
+ while (foreign_ctxt && foreign_ctxt->isInlineNamespace())
+ foreign_ctxt = foreign_ctxt->getParent();
+
+ // If the foreign context is the TU, we just return the local TU.
+ if (foreign_ctxt->isTranslationUnit())
+ return sema.getASTContext().getTranslationUnitDecl();
+
+ // Recursively find/build the parent DeclContext.
+ llvm::Expected<DeclContext *> parent =
+ getEqualLocalDeclContext(sema, foreign_ctxt->getParent());
+ if (!parent)
+ return parent;
+
+ // We currently only support building namespaces.
+ if (foreign_ctxt->isNamespace()) {
+ NamedDecl *ns = llvm::dyn_cast<NamedDecl>(foreign_ctxt);
+ llvm::StringRef ns_name = ns->getName();
+
+ auto lookup_result = emulateLookupInCtxt(sema, ns_name, *parent);
+ for (NamedDecl *named_decl : *lookup_result) {
+ if (DeclContext *DC = llvm::dyn_cast<DeclContext>(named_decl))
+ return DC->getPrimaryContext();
+ }
+ return llvm::make_error<MissingDeclContext>(
+ foreign_ctxt,
+ "Couldn't find namespace " + ns->getQualifiedNameAsString());
+ }
+
+ return llvm::make_error<MissingDeclContext>(foreign_ctxt, "Unknown context ");
+}
+
+/// Returns true iff tryInstantiateStdTemplate supports instantiating a template
+/// with the given template arguments.
+static bool templateArgsAreSupported(ArrayRef<TemplateArgument> a) {
+ for (const TemplateArgument &arg : a) {
+ switch (arg.getKind()) {
+ case TemplateArgument::Type:
+ case TemplateArgument::Integral:
+ break;
+ default:
+ // TemplateArgument kind hasn't been handled yet.
+ return false;
+ }
+ }
+ return true;
+}
+
+/// Constructor function for Clang declarations. Ensures that the created
+/// declaration is registered with the ASTImporter.
+template <typename T, typename... Args>
+T *createDecl(ASTImporter &importer, Decl *from_d, Args &&... args) {
+ T *to_d = T::Create(std::forward<Args>(args)...);
+ importer.RegisterImportedDecl(from_d, to_d);
+ return to_d;
+}
+
+llvm::Optional<Decl *> CxxModuleHandler::tryInstantiateStdTemplate(Decl *d) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+
+ // If we don't have a template to instiantiate, then there is nothing to do.
+ auto td = dyn_cast<ClassTemplateSpecializationDecl>(d);
+ if (!td)
+ return {};
+
+ // We only care about templates in the std namespace.
+ if (!td->getDeclContext()->isStdNamespace())
+ return {};
+
+ // We have a list of supported template names.
+ if (m_supported_templates.find(td->getName()) == m_supported_templates.end())
+ return {};
+
+ // Early check if we even support instantiating this template. We do this
+ // before we import anything into the target AST.
+ auto &foreign_args = td->getTemplateInstantiationArgs();
+ if (!templateArgsAreSupported(foreign_args.asArray()))
+ return {};
+
+ // Find the local DeclContext that corresponds to the DeclContext of our
+ // decl we want to import.
+ llvm::Expected<DeclContext *> to_context =
+ getEqualLocalDeclContext(*m_sema, td->getDeclContext());
+ if (!to_context) {
+ LLDB_LOG_ERROR(log, to_context.takeError(),
+ "Got error while searching equal local DeclContext for decl "
+ "'{1}':\n{0}",
+ td->getName());
+ return {};
+ }
+
+ // Look up the template in our local context.
+ std::unique_ptr<LookupResult> lookup =
+ emulateLookupInCtxt(*m_sema, td->getName(), *to_context);
+
+ ClassTemplateDecl *new_class_template = nullptr;
+ for (auto LD : *lookup) {
+ if ((new_class_template = dyn_cast<ClassTemplateDecl>(LD)))
+ break;
+ }
+ if (!new_class_template)
+ return {};
+
+ // Import the foreign template arguments.
+ llvm::SmallVector<TemplateArgument, 4> imported_args;
+
+ // If this logic is changed, also update templateArgsAreSupported.
+ for (const TemplateArgument &arg : foreign_args.asArray()) {
+ switch (arg.getKind()) {
+ case TemplateArgument::Type: {
+ llvm::Expected<QualType> type = m_importer->Import(arg.getAsType());
+ if (!type) {
+ LLDB_LOG_ERROR(log, type.takeError(), "Couldn't import type: {0}");
+ return {};
+ }
+ imported_args.push_back(TemplateArgument(*type));
+ break;
+ }
+ case TemplateArgument::Integral: {
+ llvm::APSInt integral = arg.getAsIntegral();
+ llvm::Expected<QualType> type =
+ m_importer->Import(arg.getIntegralType());
+ if (!type) {
+ LLDB_LOG_ERROR(log, type.takeError(), "Couldn't import type: {0}");
+ return {};
+ }
+ imported_args.push_back(
+ TemplateArgument(d->getASTContext(), integral, *type));
+ break;
+ }
+ default:
+ assert(false && "templateArgsAreSupported not updated?");
+ }
+ }
+
+ // Find the class template specialization declaration that
+ // corresponds to these arguments.
+ void *InsertPos = nullptr;
+ ClassTemplateSpecializationDecl *result =
+ new_class_template->findSpecialization(imported_args, InsertPos);
+
+ if (result) {
+ // We found an existing specialization in the module that fits our arguments
+ // so we can treat it as the result and register it with the ASTImporter.
+ m_importer->RegisterImportedDecl(d, result);
+ return result;
+ }
+
+ // Instantiate the template.
+ result = createDecl<ClassTemplateSpecializationDecl>(
+ *m_importer, d, m_sema->getASTContext(),
+ new_class_template->getTemplatedDecl()->getTagKind(),
+ new_class_template->getDeclContext(),
+ new_class_template->getTemplatedDecl()->getLocation(),
+ new_class_template->getLocation(), new_class_template, imported_args,
+ nullptr);
+
+ new_class_template->AddSpecialization(result, InsertPos);
+ if (new_class_template->isOutOfLine())
+ result->setLexicalDeclContext(
+ new_class_template->getLexicalDeclContext());
+ return result;
+}
+
+llvm::Optional<Decl *> CxxModuleHandler::Import(Decl *d) {
+ if (!isValid())
+ return {};
+
+ return tryInstantiateStdTemplate(d);
+}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.h b/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.h
new file mode 100644
index 000000000000..6490af7f8978
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.h
@@ -0,0 +1,65 @@
+//===-- CxxModuleHandler.h --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CXXMODULEHANDLER_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CXXMODULEHANDLER_H
+
+#include "clang/AST/ASTImporter.h"
+#include "clang/Sema/Sema.h"
+#include "llvm/ADT/StringSet.h"
+
+namespace lldb_private {
+
+/// Handles importing decls into an ASTContext with an attached C++ module.
+///
+/// This class searches a C++ module (which must be attached to the target
+/// ASTContext) for an equivalent decl to the one that should be imported.
+/// If the decl that is found in the module is a suitable replacement
+/// for the decl that should be imported, the module decl will be treated as
+/// the result of the import process.
+///
+/// If the Decl that should be imported is a template specialization
+/// that doesn't exist yet in the target ASTContext (e.g. `std::vector<int>`),
+/// then this class tries to create the template specialization in the target
+/// ASTContext. This is only possible if the CxxModuleHandler can determine
+/// that instantiating this template is safe to do, e.g. because the target
+/// decl is a container class from the STL.
+class CxxModuleHandler {
+ /// The ASTImporter that should be used to import any Decls which aren't
+ /// directly handled by this class itself.
+ clang::ASTImporter *m_importer = nullptr;
+
+ /// The Sema instance of the target ASTContext.
+ clang::Sema *m_sema = nullptr;
+
+ /// List of template names this class currently supports. These are the
+ /// template names inside the 'std' namespace such as 'vector' or 'list'.
+ llvm::StringSet<> m_supported_templates;
+
+ /// Tries to manually instantiate the given foreign template in the target
+ /// context (designated by m_sema).
+ llvm::Optional<clang::Decl *> tryInstantiateStdTemplate(clang::Decl *d);
+
+public:
+ CxxModuleHandler() = default;
+ CxxModuleHandler(clang::ASTImporter &importer, clang::ASTContext *target);
+
+ /// Attempts to import the given decl into the target ASTContext by
+ /// deserializing it from the 'std' module. This function returns a Decl if a
+ /// Decl has been deserialized from the 'std' module. Otherwise this function
+ /// returns nothing.
+ llvm::Optional<clang::Decl *> Import(clang::Decl *d);
+
+ /// Returns true iff this instance is capable of importing any declarations
+ /// in the target ASTContext.
+ bool isValid() const { return m_sema != nullptr; }
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CXXMODULEHANDLER_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp b/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
index d5ffb9529f36..b92f00ec2b63 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
@@ -1,4 +1,4 @@
-//===-- IRDynamicChecks.cpp -------------------------------------*- C++ -*-===//
+//===-- IRDynamicChecks.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -181,8 +181,8 @@ protected:
///
/// \param[in] inst
/// The instruction to be instrumented.
- void RegisterInstruction(llvm::Instruction &i) {
- m_to_instrument.push_back(&i);
+ void RegisterInstruction(llvm::Instruction &inst) {
+ m_to_instrument.push_back(&inst);
}
/// Determine whether a single instruction is interesting to instrument,
@@ -465,7 +465,7 @@ protected:
}
static llvm::Function *GetCalledFunction(llvm::CallInst *inst) {
- return GetFunction(inst->getCalledValue());
+ return GetFunction(inst->getCalledOperand());
}
bool InspectInstruction(llvm::Instruction &i) override {
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.h b/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.h
index 5b9c8007ab76..a4de527e4512 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_IRDynamicChecks_h_
-#define liblldb_IRDynamicChecks_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_IRDYNAMICCHECKS_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_IRDYNAMICCHECKS_H
#include "lldb/Expression/DynamicCheckerFunctions.h"
#include "lldb/lldb-types.h"
@@ -124,4 +124,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_IRDynamicChecks_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_IRDYNAMICCHECKS_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
index 103a7ee46f35..8511e554509a 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
@@ -1,4 +1,4 @@
-//===-- IRForTarget.cpp -----------------------------------------*- C++ -*-===//
+//===-- IRForTarget.cpp ---------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -9,7 +9,9 @@
#include "IRForTarget.h"
#include "ClangExpressionDeclMap.h"
+#include "ClangUtil.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InstrTypes.h"
@@ -27,8 +29,6 @@
#include "lldb/Core/dwarf.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRInterpreter.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/DataBufferHeap.h"
@@ -283,17 +283,13 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
clang::QualType element_qual_type = pointer_pointertype->getPointeeType();
m_result_type = lldb_private::TypeFromParser(
- element_qual_type.getAsOpaquePtr(),
- lldb_private::ClangASTContext::GetASTContext(
- &result_decl->getASTContext()));
+ m_decl_map->GetTypeSystem()->GetType(element_qual_type));
} else if (pointer_objcobjpointertype) {
clang::QualType element_qual_type =
clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);
m_result_type = lldb_private::TypeFromParser(
- element_qual_type.getAsOpaquePtr(),
- lldb_private::ClangASTContext::GetASTContext(
- &result_decl->getASTContext()));
+ m_decl_map->GetTypeSystem()->GetType(element_qual_type));
} else {
LLDB_LOG(log, "Expected result to have pointer type, but it did not");
@@ -305,9 +301,7 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
}
} else {
m_result_type = lldb_private::TypeFromParser(
- result_var->getType().getAsOpaquePtr(),
- lldb_private::ClangASTContext::GetASTContext(
- &result_decl->getASTContext()));
+ m_decl_map->GetTypeSystem()->GetType(result_var->getType()));
}
lldb::TargetSP target_sp(m_execution_unit.GetTarget());
@@ -433,7 +427,7 @@ bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
m_execution_unit.FindSymbol(g_CFStringCreateWithBytes_str,
missing_weak);
if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS || missing_weak) {
- log->PutCString("Couldn't find CFStringCreateWithBytes in the target");
+ LLDB_LOG(log, "Couldn't find CFStringCreateWithBytes in the target");
m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C "
"constant string requires "
@@ -823,7 +817,8 @@ bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {
if (!omvn_initializer_array->isString())
return false;
- std::string omvn_initializer_string = omvn_initializer_array->getAsString();
+ std::string omvn_initializer_string =
+ std::string(omvn_initializer_array->getAsString());
LLDB_LOG(log, "Found Objective-C selector reference \"{0}\"",
omvn_initializer_string);
@@ -981,7 +976,8 @@ bool IRForTarget::RewriteObjCClassReference(Instruction *class_load) {
if (!ocn_initializer_array->isString())
return false;
- std::string ocn_initializer_string = ocn_initializer_array->getAsString();
+ std::string ocn_initializer_string =
+ std::string(ocn_initializer_array->getAsString());
LLDB_LOG(log, "Found Objective-C class reference \"{0}\"",
ocn_initializer_string);
@@ -1092,8 +1088,7 @@ bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) {
clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);
lldb_private::TypeFromParser result_decl_type(
- decl->getType().getAsOpaquePtr(),
- lldb_private::ClangASTContext::GetASTContext(&decl->getASTContext()));
+ m_decl_map->GetTypeSystem()->GetType(decl->getType()));
StringRef decl_name(decl->getName());
lldb_private::ConstString persistent_variable_name(decl_name.data(),
@@ -1125,7 +1120,9 @@ bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) {
// Now, since the variable is a pointer variable, we will drop in a load of
// that pointer variable.
- LoadInst *persistent_load = new LoadInst(persistent_global, "", alloc);
+ LoadInst *persistent_load =
+ new LoadInst(persistent_global->getType()->getPointerElementType(),
+ persistent_global, "", alloc);
LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(alloc),
PrintValue(persistent_load));
@@ -1223,10 +1220,8 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
if (value_decl == nullptr)
return false;
- lldb_private::CompilerType compiler_type(
- lldb_private::ClangASTContext::GetASTContext(
- &value_decl->getASTContext()),
- value_decl->getType().getAsOpaquePtr());
+ lldb_private::CompilerType compiler_type =
+ m_decl_map->GetTypeSystem()->GetType(value_decl->getType());
const Type *value_type = nullptr;
@@ -1400,7 +1395,7 @@ bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) {
if (func && func->getName() == "__cxa_atexit")
remove = true;
- llvm::Value *val = call->getCalledValue();
+ llvm::Value *val = call->getCalledOperand();
if (val && val->getName() == "__cxa_atexit")
remove = true;
@@ -1799,7 +1794,9 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) {
get_element_ptr, value->getType()->getPointerTo(), "",
entry_instruction);
- LoadInst *load = new LoadInst(bit_cast, "", entry_instruction);
+ LoadInst *load =
+ new LoadInst(bit_cast->getType()->getPointerElementType(),
+ bit_cast, "", entry_instruction);
return load;
} else {
@@ -1845,7 +1842,7 @@ bool IRForTarget::runOnModule(Module &llvm_module) {
lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
m_module = &llvm_module;
- m_target_data.reset(new DataLayout(m_module));
+ m_target_data = std::make_unique<DataLayout>(m_module);
m_intptr_ty = llvm::Type::getIntNTy(m_module->getContext(),
m_target_data->getPointerSizeInBits());
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h
index 262e8ee0c06c..ebfc0cae626c 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h
@@ -7,10 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_IRForTarget_h_
-#define liblldb_IRForTarget_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_IRFORTARGET_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_IRFORTARGET_H
-#include "lldb/Core/ClangForward.h"
#include "lldb/Symbol/TaggedASTType.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Status.h"
@@ -38,6 +37,10 @@ class DataLayout;
class Value;
}
+namespace clang {
+class NamedDecl;
+}
+
namespace lldb_private {
class ClangExpressionDeclMap;
class IRExecutionUnit;
@@ -506,4 +509,4 @@ private:
bool CompleteDataAllocation();
};
-#endif // liblldb_IRForTarget_h_
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_IRFORTARGET_H
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h b/lldb/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h
index 7553860f2492..b7b6640c4810 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ModuleDependencyCollector_h_
-#define liblldb_ModuleDependencyCollector_h_
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_MODULEDEPENDENCYCOLLECTOR_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_MODULEDEPENDENCYCOLLECTOR_H
#include "clang/Frontend/Utils.h"
#include "llvm/ADT/StringRef.h"
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp b/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp
new file mode 100644
index 000000000000..c1f88889f1dc
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp
@@ -0,0 +1,179 @@
+//===-- NameSearchContext.cpp ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "NameSearchContext.h"
+#include "ClangUtil.h"
+
+using namespace clang;
+using namespace lldb_private;
+
+clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) {
+ assert(type && "Type for variable must be valid!");
+
+ if (!type.IsValid())
+ return nullptr;
+
+ TypeSystemClang *lldb_ast =
+ llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+ if (!lldb_ast)
+ return nullptr;
+
+ IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();
+
+ clang::ASTContext &ast = lldb_ast->getASTContext();
+
+ clang::NamedDecl *Decl = VarDecl::Create(
+ ast, const_cast<DeclContext *>(m_decl_context), SourceLocation(),
+ SourceLocation(), ii, ClangUtil::GetQualType(type), nullptr, SC_Static);
+ m_decls.push_back(Decl);
+
+ return Decl;
+}
+
+clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type,
+ bool extern_c) {
+ assert(type && "Type for variable must be valid!");
+
+ if (!type.IsValid())
+ return nullptr;
+
+ if (m_function_types.count(type))
+ return nullptr;
+
+ TypeSystemClang *lldb_ast =
+ llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+ if (!lldb_ast)
+ return nullptr;
+
+ m_function_types.insert(type);
+
+ QualType qual_type(ClangUtil::GetQualType(type));
+
+ clang::ASTContext &ast = lldb_ast->getASTContext();
+
+ const bool isInlineSpecified = false;
+ const bool hasWrittenPrototype = true;
+ const bool isConstexprSpecified = false;
+
+ clang::DeclContext *context = const_cast<DeclContext *>(m_decl_context);
+
+ if (extern_c) {
+ context = LinkageSpecDecl::Create(
+ ast, context, SourceLocation(), SourceLocation(),
+ clang::LinkageSpecDecl::LanguageIDs::lang_c, false);
+ }
+
+ // Pass the identifier info for functions the decl_name is needed for
+ // operators
+ clang::DeclarationName decl_name =
+ m_decl_name.getNameKind() == DeclarationName::Identifier
+ ? m_decl_name.getAsIdentifierInfo()
+ : m_decl_name;
+
+ clang::FunctionDecl *func_decl = FunctionDecl::Create(
+ ast, context, SourceLocation(), SourceLocation(), decl_name, qual_type,
+ nullptr, SC_Extern, isInlineSpecified, hasWrittenPrototype,
+ isConstexprSpecified ? CSK_constexpr : CSK_unspecified);
+
+ // We have to do more than just synthesize the FunctionDecl. We have to
+ // synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do
+ // this, we raid the function's FunctionProtoType for types.
+
+ const FunctionProtoType *func_proto_type =
+ qual_type.getTypePtr()->getAs<FunctionProtoType>();
+
+ if (func_proto_type) {
+ unsigned NumArgs = func_proto_type->getNumParams();
+ unsigned ArgIndex;
+
+ SmallVector<ParmVarDecl *, 5> parm_var_decls;
+
+ for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex) {
+ QualType arg_qual_type(func_proto_type->getParamType(ArgIndex));
+
+ parm_var_decls.push_back(
+ ParmVarDecl::Create(ast, const_cast<DeclContext *>(context),
+ SourceLocation(), SourceLocation(), nullptr,
+ arg_qual_type, nullptr, SC_Static, nullptr));
+ }
+
+ func_decl->setParams(ArrayRef<ParmVarDecl *>(parm_var_decls));
+ } else {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ LLDB_LOG(log, "Function type wasn't a FunctionProtoType");
+ }
+
+ // If this is an operator (e.g. operator new or operator==), only insert the
+ // declaration we inferred from the symbol if we can provide the correct
+ // number of arguments. We shouldn't really inject random decl(s) for
+ // functions that are analyzed semantically in a special way, otherwise we
+ // will crash in clang.
+ clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
+ if (func_proto_type &&
+ TypeSystemClang::IsOperator(decl_name.getAsString().c_str(), op_kind)) {
+ if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount(
+ false, op_kind, func_proto_type->getNumParams()))
+ return nullptr;
+ }
+ m_decls.push_back(func_decl);
+
+ return func_decl;
+}
+
+clang::NamedDecl *NameSearchContext::AddGenericFunDecl() {
+ FunctionProtoType::ExtProtoInfo proto_info;
+
+ proto_info.Variadic = true;
+
+ QualType generic_function_type(
+ GetASTContext().getFunctionType(GetASTContext().UnknownAnyTy, // result
+ ArrayRef<QualType>(), // argument types
+ proto_info));
+
+ return AddFunDecl(m_clang_ts.GetType(generic_function_type), true);
+}
+
+clang::NamedDecl *
+NameSearchContext::AddTypeDecl(const CompilerType &clang_type) {
+ if (ClangUtil::IsClangType(clang_type)) {
+ QualType qual_type = ClangUtil::GetQualType(clang_type);
+
+ if (const TypedefType *typedef_type =
+ llvm::dyn_cast<TypedefType>(qual_type)) {
+ TypedefNameDecl *typedef_name_decl = typedef_type->getDecl();
+
+ m_decls.push_back(typedef_name_decl);
+
+ return (NamedDecl *)typedef_name_decl;
+ } else if (const TagType *tag_type = qual_type->getAs<TagType>()) {
+ TagDecl *tag_decl = tag_type->getDecl();
+
+ m_decls.push_back(tag_decl);
+
+ return tag_decl;
+ } else if (const ObjCObjectType *objc_object_type =
+ qual_type->getAs<ObjCObjectType>()) {
+ ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface();
+
+ m_decls.push_back((NamedDecl *)interface_decl);
+
+ return (NamedDecl *)interface_decl;
+ }
+ }
+ return nullptr;
+}
+
+void NameSearchContext::AddLookupResult(clang::DeclContextLookupResult result) {
+ for (clang::NamedDecl *decl : result)
+ m_decls.push_back(decl);
+}
+
+void NameSearchContext::AddNamedDecl(clang::NamedDecl *decl) {
+ m_decls.push_back(decl);
+}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.h b/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.h
new file mode 100644
index 000000000000..dc8621dd6aba
--- /dev/null
+++ b/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.h
@@ -0,0 +1,124 @@
+//===-- NameSearchContext.h -------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_NAME_SEARCH_CONTEXT_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_NAME_SEARCH_CONTEXT_H
+
+#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "llvm/ADT/SmallSet.h"
+
+namespace lldb_private {
+
+/// \class NameSearchContext ClangASTSource.h
+/// "lldb/Expression/ClangASTSource.h" Container for all objects relevant to a
+/// single name lookup
+///
+/// LLDB needs to create Decls for entities it finds. This class communicates
+/// what name is being searched for and provides helper functions to construct
+/// Decls given appropriate type information.
+struct NameSearchContext {
+ /// The type system of the AST from which the lookup originated.
+ TypeSystemClang &m_clang_ts;
+ /// The list of declarations already constructed.
+ llvm::SmallVectorImpl<clang::NamedDecl *> &m_decls;
+ /// The mapping of all namespaces found for this request back to their
+ /// modules.
+ ClangASTImporter::NamespaceMapSP m_namespace_map;
+ /// The name being looked for.
+ const clang::DeclarationName m_decl_name;
+ /// The DeclContext to put declarations into.
+ const clang::DeclContext *m_decl_context;
+ /// All the types of functions that have been reported, so we don't
+ /// report conflicts.
+ llvm::SmallSet<CompilerType, 5> m_function_types;
+
+ bool m_found_variable = false;
+ bool m_found_function_with_type_info = false;
+ bool m_found_function = false;
+ bool m_found_local_vars_nsp = false;
+ bool m_found_type = false;
+
+ /// Constructor
+ ///
+ /// Initializes class variables.
+ ///
+ /// \param[in] clang_ts
+ /// The TypeSystemClang from which the request originates.
+ ///
+ /// \param[in] decls
+ /// A reference to a list into which new Decls will be placed. This
+ /// list is typically empty when the function is called.
+ ///
+ /// \param[in] name
+ /// The name being searched for (always an Identifier).
+ ///
+ /// \param[in] dc
+ /// The DeclContext to register Decls in.
+ NameSearchContext(TypeSystemClang &clang_ts,
+ llvm::SmallVectorImpl<clang::NamedDecl *> &decls,
+ clang::DeclarationName name, const clang::DeclContext *dc)
+ : m_clang_ts(clang_ts), m_decls(decls),
+ m_namespace_map(std::make_shared<ClangASTImporter::NamespaceMap>()),
+ m_decl_name(name), m_decl_context(dc) {
+ ;
+ }
+
+ /// Create a VarDecl with the name being searched for and the provided type
+ /// and register it in the right places.
+ ///
+ /// \param[in] type
+ /// The opaque QualType for the VarDecl being registered.
+ clang::NamedDecl *AddVarDecl(const CompilerType &type);
+
+ /// Create a FunDecl with the name being searched for and the provided type
+ /// and register it in the right places.
+ ///
+ /// \param[in] type
+ /// The opaque QualType for the FunDecl being registered.
+ ///
+ /// \param[in] extern_c
+ /// If true, build an extern "C" linkage specification for this.
+ clang::NamedDecl *AddFunDecl(const CompilerType &type, bool extern_c = false);
+
+ /// Create a FunDecl with the name being searched for and generic type (i.e.
+ /// intptr_t NAME_GOES_HERE(...)) and register it in the right places.
+ clang::NamedDecl *AddGenericFunDecl();
+
+ /// Create a TypeDecl with the name being searched for and the provided type
+ /// and register it in the right places.
+ ///
+ /// \param[in] compiler_type
+ /// The opaque QualType for the TypeDecl being registered.
+ clang::NamedDecl *AddTypeDecl(const CompilerType &compiler_type);
+
+ /// Add Decls from the provided DeclContextLookupResult to the list of
+ /// results.
+ ///
+ /// \param[in] result
+ /// The DeclContextLookupResult, usually returned as the result
+ /// of querying a DeclContext.
+ void AddLookupResult(clang::DeclContextLookupResult result);
+
+ /// Add a NamedDecl to the list of results.
+ ///
+ /// \param[in] decl
+ /// The NamedDecl, usually returned as the result
+ /// of querying a DeclContext.
+ void AddNamedDecl(clang::NamedDecl *decl);
+
+private:
+ clang::ASTContext &GetASTContext() const {
+ return m_clang_ts.getASTContext();
+ }
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_NAME_SEARCH_CONTEXT_H