2011-06-25 08:44:06 +08:00
|
|
|
//===-- ClangASTImporter.cpp ------------------------------------*- C++ -*-===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// 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
|
2011-06-25 08:44:06 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2016-03-29 06:53:41 +08:00
|
|
|
#include "lldb/Symbol/ClangASTImporter.h"
|
2011-10-22 07:04:20 +08:00
|
|
|
#include "lldb/Core/Module.h"
|
2011-06-25 08:44:06 +08:00
|
|
|
#include "lldb/Symbol/ClangASTContext.h"
|
2012-04-13 08:10:03 +08:00
|
|
|
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
|
2016-03-29 06:53:41 +08:00
|
|
|
#include "lldb/Symbol/ClangUtil.h"
|
2015-07-09 02:03:41 +08:00
|
|
|
#include "lldb/Utility/LLDBAssert.h"
|
2017-03-04 04:56:28 +08:00
|
|
|
#include "lldb/Utility/Log.h"
|
2016-03-29 06:53:41 +08:00
|
|
|
#include "clang/AST/Decl.h"
|
|
|
|
#include "clang/AST/DeclCXX.h"
|
|
|
|
#include "clang/AST/DeclObjC.h"
|
Instantiate 'std' templates explicitly in the expression evaluator
Summary:
This patch is a follow-up for D58125. It implements the manual instantiation and merging of 'std' templates like
`std::vector` and `std::shared_ptr` with information from the debug info AST. This (finally) allows using these classes
in the expression evaluator like every other class (i.e. things like `vec.size()` and shared_ptr debugging now works, yay!).
The main logic is the `CxxModuleHandler` which intercept the ASTImporter import process and replaces any `std` decls
by decls from the C++ module. The decls from the C++ module are "imported" by just deserializing them directly in
the expression evaluation context. This is mostly because we don't want to rely on the ASTImporter to correctly import
these declarations, but in the future we should also move to the ASTImporter for that.
This patch doesn't contain the automatic desugaring for result variables. This means that if you call for example
`size` of `std::vector` you maybe get some very verbose typedef'd type as the variable type, e.g.
`std::vector<int, std::allocator<int>>::value_type`.
This is not only unreadable, it also means that our ASTImporter has to import all these types and associated
decls into the persisent variable context. This currently usually leads to some assertion getting triggered
in Clang when the ASTImporter either makes a mistake during importing or our debug info AST is inconsitent.
The current workaround I use in the tests is to just cast the result to it's actual type (e.g. `size_t` or `int`) to prevent
the ASTImporter from having to handle all these complicated decls.
The automatic desugaring will be a future patch because I'm not happy yet with the current code for that and because
I anticipate that this will be a controversial patch.
Reviewers: aprantl, shafik, jingham, martong, serge-sans-paille
Reviewed By: martong
Subscribers: balazske, rnkovacs, mgorny, mgrang, abidh, jdoerfert, lldb-commits
Tags: #c_modules_in_lldb, #lldb
Differential Revision: https://reviews.llvm.org/D59537
llvm-svn: 359538
2019-04-30 16:41:35 +08:00
|
|
|
#include "clang/Sema/Lookup.h"
|
|
|
|
#include "clang/Sema/Sema.h"
|
2016-03-29 06:53:41 +08:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2011-06-25 08:44:06 +08:00
|
|
|
|
2019-02-12 07:13:08 +08:00
|
|
|
#include <memory>
|
|
|
|
|
2011-06-25 08:44:06 +08:00
|
|
|
using namespace lldb_private;
|
|
|
|
using namespace clang;
|
|
|
|
|
2013-03-09 04:04:57 +08:00
|
|
|
ClangASTMetrics::Counters ClangASTMetrics::global_counters = {0, 0, 0, 0, 0, 0};
|
|
|
|
ClangASTMetrics::Counters ClangASTMetrics::local_counters = {0, 0, 0, 0, 0, 0};
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2013-03-28 07:08:40 +08:00
|
|
|
void ClangASTMetrics::DumpCounters(Log *log,
|
|
|
|
ClangASTMetrics::Counters &counters) {
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log, " Number of visible Decl queries by name : %" PRIu64,
|
|
|
|
counters.m_visible_query_count);
|
|
|
|
LLDB_LOGF(log, " Number of lexical Decl queries : %" PRIu64,
|
|
|
|
counters.m_lexical_query_count);
|
|
|
|
LLDB_LOGF(log, " Number of imports initiated by LLDB : %" PRIu64,
|
|
|
|
counters.m_lldb_import_count);
|
|
|
|
LLDB_LOGF(log, " Number of imports conducted by Clang : %" PRIu64,
|
|
|
|
counters.m_clang_import_count);
|
|
|
|
LLDB_LOGF(log, " Number of Decls completed : %" PRIu64,
|
|
|
|
counters.m_decls_completed_count);
|
|
|
|
LLDB_LOGF(log, " Number of records laid out : %" PRIu64,
|
|
|
|
counters.m_record_layout_count);
|
2013-03-09 04:04:57 +08:00
|
|
|
}
|
|
|
|
|
2013-03-28 07:08:40 +08:00
|
|
|
void ClangASTMetrics::DumpCounters(Log *log) {
|
2013-03-09 04:04:57 +08:00
|
|
|
if (!log)
|
|
|
|
return;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log, "== ClangASTMetrics output ==");
|
|
|
|
LLDB_LOGF(log, "-- Global metrics --");
|
2013-03-09 04:04:57 +08:00
|
|
|
DumpCounters(log, global_counters);
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log, "-- Local metrics --");
|
2013-03-09 04:04:57 +08:00
|
|
|
DumpCounters(log, local_counters);
|
|
|
|
}
|
|
|
|
|
2011-11-17 02:20:47 +08:00
|
|
|
clang::QualType ClangASTImporter::CopyType(clang::ASTContext *dst_ast,
|
|
|
|
clang::ASTContext *src_ast,
|
2011-06-25 08:44:06 +08:00
|
|
|
clang::QualType type) {
|
2019-05-02 18:58:33 +08:00
|
|
|
ImporterDelegateSP delegate_sp(GetDelegate(dst_ast, src_ast));
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2019-05-02 18:58:33 +08:00
|
|
|
ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, dst_ast);
|
Instantiate 'std' templates explicitly in the expression evaluator
Summary:
This patch is a follow-up for D58125. It implements the manual instantiation and merging of 'std' templates like
`std::vector` and `std::shared_ptr` with information from the debug info AST. This (finally) allows using these classes
in the expression evaluator like every other class (i.e. things like `vec.size()` and shared_ptr debugging now works, yay!).
The main logic is the `CxxModuleHandler` which intercept the ASTImporter import process and replaces any `std` decls
by decls from the C++ module. The decls from the C++ module are "imported" by just deserializing them directly in
the expression evaluation context. This is mostly because we don't want to rely on the ASTImporter to correctly import
these declarations, but in the future we should also move to the ASTImporter for that.
This patch doesn't contain the automatic desugaring for result variables. This means that if you call for example
`size` of `std::vector` you maybe get some very verbose typedef'd type as the variable type, e.g.
`std::vector<int, std::allocator<int>>::value_type`.
This is not only unreadable, it also means that our ASTImporter has to import all these types and associated
decls into the persisent variable context. This currently usually leads to some assertion getting triggered
in Clang when the ASTImporter either makes a mistake during importing or our debug info AST is inconsitent.
The current workaround I use in the tests is to just cast the result to it's actual type (e.g. `size_t` or `int`) to prevent
the ASTImporter from having to handle all these complicated decls.
The automatic desugaring will be a future patch because I'm not happy yet with the current code for that and because
I anticipate that this will be a controversial patch.
Reviewers: aprantl, shafik, jingham, martong, serge-sans-paille
Reviewed By: martong
Subscribers: balazske, rnkovacs, mgorny, mgrang, abidh, jdoerfert, lldb-commits
Tags: #c_modules_in_lldb, #lldb
Differential Revision: https://reviews.llvm.org/D59537
llvm-svn: 359538
2019-04-30 16:41:35 +08:00
|
|
|
|
[ASTImporter] Use llvm::Expected and Error in the importer API
Summary:
This is the final phase of the refactoring towards using llvm::Expected
and llvm::Error in the ASTImporter API.
This involves the following:
- remove old Import functions which returned with a pointer,
- use the Import_New functions (which return with Err or Expected) everywhere
and handle their return value
- rename Import_New functions to Import
This affects both Clang and LLDB.
Reviewers: shafik, teemperor, aprantl, a_sidorin, balazske, a.sidorin
Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits, lldb-commits
Tags: #clang, #lldb
Differential Revision: https://reviews.llvm.org/D61438
llvm-svn: 360760
2019-05-15 18:29:48 +08:00
|
|
|
if (!delegate_sp)
|
|
|
|
return QualType();
|
|
|
|
|
|
|
|
llvm::Expected<QualType> ret_or_error = delegate_sp->Import(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 QualType();
|
|
|
|
}
|
|
|
|
return *ret_or_error;
|
2011-06-25 08:44:06 +08:00
|
|
|
}
|
|
|
|
|
2015-09-23 01:04:24 +08:00
|
|
|
lldb::opaque_compiler_type_t
|
2011-11-17 03:07:39 +08:00
|
|
|
ClangASTImporter::CopyType(clang::ASTContext *dst_ast,
|
|
|
|
clang::ASTContext *src_ast,
|
2015-09-23 01:04:24 +08:00
|
|
|
lldb::opaque_compiler_type_t type) {
|
2011-11-17 03:07:39 +08:00
|
|
|
return CopyType(dst_ast, src_ast, QualType::getFromOpaquePtr(type))
|
|
|
|
.getAsOpaquePtr();
|
|
|
|
}
|
|
|
|
|
2015-12-08 09:02:08 +08:00
|
|
|
CompilerType ClangASTImporter::CopyType(ClangASTContext &dst_ast,
|
|
|
|
const CompilerType &src_type) {
|
|
|
|
clang::ASTContext *dst_clang_ast = dst_ast.getASTContext();
|
|
|
|
if (dst_clang_ast) {
|
|
|
|
ClangASTContext *src_ast =
|
|
|
|
llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem());
|
|
|
|
if (src_ast) {
|
|
|
|
clang::ASTContext *src_clang_ast = src_ast->getASTContext();
|
|
|
|
if (src_clang_ast) {
|
|
|
|
lldb::opaque_compiler_type_t dst_clang_type = CopyType(
|
|
|
|
dst_clang_ast, src_clang_ast, src_type.GetOpaqueQualType());
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-12-08 09:02:08 +08:00
|
|
|
if (dst_clang_type)
|
|
|
|
return CompilerType(&dst_ast, dst_clang_type);
|
|
|
|
}
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2015-12-08 09:02:08 +08:00
|
|
|
return CompilerType();
|
|
|
|
}
|
|
|
|
|
2011-11-17 02:20:47 +08:00
|
|
|
clang::Decl *ClangASTImporter::CopyDecl(clang::ASTContext *dst_ast,
|
|
|
|
clang::ASTContext *src_ast,
|
2011-06-25 08:44:06 +08:00
|
|
|
clang::Decl *decl) {
|
2019-05-02 18:58:33 +08:00
|
|
|
ImporterDelegateSP delegate_sp;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2019-05-02 18:58:33 +08:00
|
|
|
delegate_sp = GetDelegate(dst_ast, src_ast);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2019-05-02 18:58:33 +08:00
|
|
|
ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, dst_ast);
|
Instantiate 'std' templates explicitly in the expression evaluator
Summary:
This patch is a follow-up for D58125. It implements the manual instantiation and merging of 'std' templates like
`std::vector` and `std::shared_ptr` with information from the debug info AST. This (finally) allows using these classes
in the expression evaluator like every other class (i.e. things like `vec.size()` and shared_ptr debugging now works, yay!).
The main logic is the `CxxModuleHandler` which intercept the ASTImporter import process and replaces any `std` decls
by decls from the C++ module. The decls from the C++ module are "imported" by just deserializing them directly in
the expression evaluation context. This is mostly because we don't want to rely on the ASTImporter to correctly import
these declarations, but in the future we should also move to the ASTImporter for that.
This patch doesn't contain the automatic desugaring for result variables. This means that if you call for example
`size` of `std::vector` you maybe get some very verbose typedef'd type as the variable type, e.g.
`std::vector<int, std::allocator<int>>::value_type`.
This is not only unreadable, it also means that our ASTImporter has to import all these types and associated
decls into the persisent variable context. This currently usually leads to some assertion getting triggered
in Clang when the ASTImporter either makes a mistake during importing or our debug info AST is inconsitent.
The current workaround I use in the tests is to just cast the result to it's actual type (e.g. `size_t` or `int`) to prevent
the ASTImporter from having to handle all these complicated decls.
The automatic desugaring will be a future patch because I'm not happy yet with the current code for that and because
I anticipate that this will be a controversial patch.
Reviewers: aprantl, shafik, jingham, martong, serge-sans-paille
Reviewed By: martong
Subscribers: balazske, rnkovacs, mgorny, mgrang, abidh, jdoerfert, lldb-commits
Tags: #c_modules_in_lldb, #lldb
Differential Revision: https://reviews.llvm.org/D59537
llvm-svn: 359538
2019-04-30 16:41:35 +08:00
|
|
|
|
[ASTImporter] Use llvm::Expected and Error in the importer API
Summary:
This is the final phase of the refactoring towards using llvm::Expected
and llvm::Error in the ASTImporter API.
This involves the following:
- remove old Import functions which returned with a pointer,
- use the Import_New functions (which return with Err or Expected) everywhere
and handle their return value
- rename Import_New functions to Import
This affects both Clang and LLDB.
Reviewers: shafik, teemperor, aprantl, a_sidorin, balazske, a.sidorin
Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits, lldb-commits
Tags: #clang, #lldb
Differential Revision: https://reviews.llvm.org/D61438
llvm-svn: 360760
2019-05-15 18:29:48 +08:00
|
|
|
if (!delegate_sp)
|
|
|
|
return nullptr;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
[ASTImporter] Use llvm::Expected and Error in the importer API
Summary:
This is the final phase of the refactoring towards using llvm::Expected
and llvm::Error in the ASTImporter API.
This involves the following:
- remove old Import functions which returned with a pointer,
- use the Import_New functions (which return with Err or Expected) everywhere
and handle their return value
- rename Import_New functions to Import
This affects both Clang and LLDB.
Reviewers: shafik, teemperor, aprantl, a_sidorin, balazske, a.sidorin
Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits, lldb-commits
Tags: #clang, #lldb
Differential Revision: https://reviews.llvm.org/D61438
llvm-svn: 360760
2019-05-15 18:29:48 +08:00
|
|
|
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))
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log,
|
|
|
|
" [ClangASTImporter] WARNING: Failed to import a %s "
|
|
|
|
"'%s', metadata 0x%" PRIx64,
|
|
|
|
decl->getDeclKindName(),
|
|
|
|
named_decl->getNameAsString().c_str(), user_id);
|
[ASTImporter] Use llvm::Expected and Error in the importer API
Summary:
This is the final phase of the refactoring towards using llvm::Expected
and llvm::Error in the ASTImporter API.
This involves the following:
- remove old Import functions which returned with a pointer,
- use the Import_New functions (which return with Err or Expected) everywhere
and handle their return value
- rename Import_New functions to Import
This affects both Clang and LLDB.
Reviewers: shafik, teemperor, aprantl, a_sidorin, balazske, a.sidorin
Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits, lldb-commits
Tags: #clang, #lldb
Differential Revision: https://reviews.llvm.org/D61438
llvm-svn: 360760
2019-05-15 18:29:48 +08:00
|
|
|
else
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log,
|
|
|
|
" [ClangASTImporter] WARNING: Failed to import a %s, "
|
|
|
|
"metadata 0x%" PRIx64,
|
|
|
|
decl->getDeclKindName(), user_id);
|
2011-11-05 06:46:46 +08:00
|
|
|
}
|
[ASTImporter] Use llvm::Expected and Error in the importer API
Summary:
This is the final phase of the refactoring towards using llvm::Expected
and llvm::Error in the ASTImporter API.
This involves the following:
- remove old Import functions which returned with a pointer,
- use the Import_New functions (which return with Err or Expected) everywhere
and handle their return value
- rename Import_New functions to Import
This affects both Clang and LLDB.
Reviewers: shafik, teemperor, aprantl, a_sidorin, balazske, a.sidorin
Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits, lldb-commits
Tags: #clang, #lldb
Differential Revision: https://reviews.llvm.org/D61438
llvm-svn: 360760
2019-05-15 18:29:48 +08:00
|
|
|
return nullptr;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
[ASTImporter] Use llvm::Expected and Error in the importer API
Summary:
This is the final phase of the refactoring towards using llvm::Expected
and llvm::Error in the ASTImporter API.
This involves the following:
- remove old Import functions which returned with a pointer,
- use the Import_New functions (which return with Err or Expected) everywhere
and handle their return value
- rename Import_New functions to Import
This affects both Clang and LLDB.
Reviewers: shafik, teemperor, aprantl, a_sidorin, balazske, a.sidorin
Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits, lldb-commits
Tags: #clang, #lldb
Differential Revision: https://reviews.llvm.org/D61438
llvm-svn: 360760
2019-05-15 18:29:48 +08:00
|
|
|
return *result;
|
2011-06-25 08:44:06 +08:00
|
|
|
}
|
|
|
|
|
2015-07-09 02:03:41 +08:00
|
|
|
class DeclContextOverride {
|
|
|
|
private:
|
|
|
|
struct Backup {
|
|
|
|
clang::DeclContext *decl_context;
|
|
|
|
clang::DeclContext *lexical_decl_context;
|
|
|
|
};
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-07-09 02:03:41 +08:00
|
|
|
std::map<clang::Decl *, Backup> m_backups;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-07-09 02:03:41 +08:00
|
|
|
void OverrideOne(clang::Decl *decl) {
|
|
|
|
if (m_backups.find(decl) != m_backups.end()) {
|
|
|
|
return;
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-07-09 02:03:41 +08:00
|
|
|
m_backups[decl] = {decl->getDeclContext(), decl->getLexicalDeclContext()};
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-07-09 02:03:41 +08:00
|
|
|
decl->setDeclContext(decl->getASTContext().getTranslationUnitDecl());
|
|
|
|
decl->setLexicalDeclContext(decl->getASTContext().getTranslationUnitDecl());
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2015-07-09 02:03:41 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-07-09 02:03:41 +08:00
|
|
|
return false;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2015-07-09 02:03:41 +08:00
|
|
|
clang::Decl *GetEscapedChild(clang::Decl *decl,
|
|
|
|
clang::DeclContext *base = nullptr) {
|
|
|
|
if (base) {
|
|
|
|
// decl's DeclContext chains must pass through base.
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-07-09 02:03:41 +08:00
|
|
|
if (!ChainPassesThrough(decl, base, &clang::Decl::getDeclContext,
|
|
|
|
&clang::DeclContext::getParent) ||
|
|
|
|
!ChainPassesThrough(decl, base, &clang::Decl::getLexicalDeclContext,
|
|
|
|
&clang::DeclContext::getLexicalParent)) {
|
|
|
|
return decl;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
} else {
|
2015-07-09 02:03:41 +08:00
|
|
|
base = clang::dyn_cast<clang::DeclContext>(decl);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-07-09 02:03:41 +08:00
|
|
|
if (!base) {
|
|
|
|
return nullptr;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2015-07-09 02:03:41 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-12-09 07:45:45 +08:00
|
|
|
if (clang::DeclContext *context =
|
2015-07-09 02:03:41 +08:00
|
|
|
clang::dyn_cast<clang::DeclContext>(decl)) {
|
|
|
|
for (clang::Decl *decl : context->decls()) {
|
|
|
|
if (clang::Decl *escaped_child = GetEscapedChild(decl)) {
|
|
|
|
return escaped_child;
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2015-07-09 02:03:41 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-07-09 02:03:41 +08:00
|
|
|
return nullptr;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2015-07-09 02:03:41 +08:00
|
|
|
void Override(clang::Decl *decl) {
|
|
|
|
if (clang::Decl *escaped_child = GetEscapedChild(decl)) {
|
|
|
|
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log,
|
|
|
|
" [ClangASTImporter] DeclContextOverride couldn't "
|
|
|
|
"override (%sDecl*)%p - its child (%sDecl*)%p escapes",
|
|
|
|
decl->getDeclKindName(), static_cast<void *>(decl),
|
|
|
|
escaped_child->getDeclKindName(),
|
|
|
|
static_cast<void *>(escaped_child));
|
2015-07-09 02:03:41 +08:00
|
|
|
lldbassert(0 && "Couldn't override!");
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-07-09 02:03:41 +08:00
|
|
|
OverrideOne(decl);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2015-07-09 02:03:41 +08:00
|
|
|
DeclContextOverride() {}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-07-09 02:03:41 +08:00
|
|
|
void OverrideAllDeclsFromContainingFunction(clang::Decl *decl) {
|
|
|
|
for (DeclContext *decl_context = decl->getLexicalDeclContext();
|
|
|
|
decl_context; decl_context = decl_context->getLexicalParent()) {
|
|
|
|
DeclContext *redecl_context = decl_context->getRedeclContext();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-07-09 02:03:41 +08:00
|
|
|
if (llvm::isa<FunctionDecl>(redecl_context) &&
|
|
|
|
llvm::isa<TranslationUnitDecl>(redecl_context->getLexicalParent())) {
|
|
|
|
for (clang::Decl *child_decl : decl_context->decls()) {
|
|
|
|
Override(child_decl);
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2015-07-09 02:03:41 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2015-07-09 02:03:41 +08:00
|
|
|
~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);
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2015-07-09 02:03:41 +08:00
|
|
|
};
|
|
|
|
|
2019-09-20 20:52:55 +08:00
|
|
|
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;
|
|
|
|
// FIXME: Investigate how many decls we usually have in these sets and
|
|
|
|
// see if we can use SmallPtrSet instead here.
|
|
|
|
std::set<NamedDecl *> m_decls_to_complete;
|
|
|
|
std::set<NamedDecl *> 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.begin();
|
|
|
|
|
|
|
|
m_decls_already_completed.insert(decl);
|
|
|
|
m_decls_to_complete.erase(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.
|
|
|
|
ClangASTContext::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.insert(to_named_decl);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} // namespace
|
|
|
|
|
2015-09-23 01:04:24 +08:00
|
|
|
lldb::opaque_compiler_type_t
|
2011-12-17 05:06:35 +08:00
|
|
|
ClangASTImporter::DeportType(clang::ASTContext *dst_ctx,
|
2015-09-03 00:39:23 +08:00
|
|
|
clang::ASTContext *src_ctx,
|
2015-09-23 01:04:24 +08:00
|
|
|
lldb::opaque_compiler_type_t type) {
|
2013-03-30 10:31:21 +08:00
|
|
|
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
|
|
|
|
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log,
|
|
|
|
" [ClangASTImporter] DeportType called on (%sType*)0x%llx "
|
|
|
|
"from (ASTContext*)%p to (ASTContext*)%p",
|
|
|
|
QualType::getFromOpaquePtr(type)->getTypeClassName(),
|
|
|
|
(unsigned long long)type, static_cast<void *>(src_ctx),
|
|
|
|
static_cast<void *>(dst_ctx));
|
2014-04-04 12:06:10 +08:00
|
|
|
|
2015-07-09 02:03:41 +08:00
|
|
|
DeclContextOverride decl_context_override;
|
2014-04-04 12:06:10 +08:00
|
|
|
|
2019-09-20 20:52:55 +08:00
|
|
|
if (auto *t = QualType::getFromOpaquePtr(type)->getAs<TagType>())
|
|
|
|
decl_context_override.OverrideAllDeclsFromContainingFunction(t->getDecl());
|
2014-04-04 12:06:10 +08:00
|
|
|
|
2019-09-20 20:52:55 +08:00
|
|
|
lldb::opaque_compiler_type_t result;
|
|
|
|
{
|
|
|
|
CompleteTagDeclsScope complete_scope(*this, dst_ctx, src_ctx);
|
|
|
|
result = CopyType(dst_ctx, src_ctx, type);
|
|
|
|
}
|
2014-04-04 12:06:10 +08:00
|
|
|
|
|
|
|
if (!result)
|
|
|
|
return nullptr;
|
|
|
|
|
2011-12-06 11:41:14 +08:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2016-03-29 06:53:41 +08:00
|
|
|
clang::Decl *ClangASTImporter::DeportDecl(clang::ASTContext *dst_ctx,
|
|
|
|
clang::ASTContext *src_ctx,
|
|
|
|
clang::Decl *decl) {
|
|
|
|
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
|
|
|
|
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log,
|
|
|
|
" [ClangASTImporter] DeportDecl called on (%sDecl*)%p from "
|
|
|
|
"(ASTContext*)%p to (ASTContext*)%p",
|
|
|
|
decl->getDeclKindName(), static_cast<void *>(decl),
|
|
|
|
static_cast<void *>(src_ctx), static_cast<void *>(dst_ctx));
|
2016-03-29 06:53:41 +08:00
|
|
|
|
|
|
|
DeclContextOverride decl_context_override;
|
|
|
|
|
|
|
|
decl_context_override.OverrideAllDeclsFromContainingFunction(decl);
|
|
|
|
|
2019-09-20 20:52:55 +08:00
|
|
|
clang::Decl *result;
|
|
|
|
{
|
|
|
|
CompleteTagDeclsScope complete_scope(*this, dst_ctx, src_ctx);
|
|
|
|
result = CopyDecl(dst_ctx, src_ctx, decl);
|
|
|
|
}
|
2016-03-29 06:53:41 +08:00
|
|
|
|
|
|
|
if (!result)
|
|
|
|
return nullptr;
|
|
|
|
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(
|
|
|
|
log,
|
|
|
|
" [ClangASTImporter] DeportDecl deported (%sDecl*)%p to (%sDecl*)%p",
|
|
|
|
decl->getDeclKindName(), static_cast<void *>(decl),
|
|
|
|
result->getDeclKindName(), static_cast<void *>(result));
|
2016-03-29 06:53:41 +08:00
|
|
|
|
|
|
|
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) {
|
[lldb] NFC modernize codebase with modernize-use-nullptr
Summary:
NFC = [[ https://llvm.org/docs/Lexicon.html#nfc | Non functional change ]]
This commit is the result of modernizing the LLDB codebase by using
`nullptr` instread of `0` or `NULL`. See
https://clang.llvm.org/extra/clang-tidy/checks/modernize-use-nullptr.html
for more information.
This is the command I ran and I to fix and format the code base:
```
run-clang-tidy.py \
-header-filter='.*' \
-checks='-*,modernize-use-nullptr' \
-fix ~/dev/llvm-project/lldb/.* \
-format \
-style LLVM \
-p ~/llvm-builds/debug-ninja-gcc
```
NOTE: There were also changes to `llvm/utils/unittest` but I did not
include them because I felt that maybe this library shall be updated in
isolation somehow.
NOTE: I know this is a rather large commit but it is a nobrainer in most
parts.
Reviewers: martong, espindola, shafik, #lldb, JDevlieghere
Reviewed By: JDevlieghere
Subscribers: arsenm, jvesely, nhaehnle, hiraditya, JDevlieghere, teemperor, rnkovacs, emaste, kubamracek, nemanjai, ki.stfu, javed.absar, arichardson, kbarton, jrtc27, MaskRay, atanasyan, dexonsmith, arphaman, jfb, jsji, jdoerfert, lldb-commits, llvm-commits
Tags: #lldb, #llvm
Differential Revision: https://reviews.llvm.org/D61847
llvm-svn: 361484
2019-05-23 19:14:47 +08:00
|
|
|
if (ResolveDeclOrigin(cxx_record_decl, nullptr, nullptr))
|
2016-03-29 06:53:41 +08:00
|
|
|
return true;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
} break;
|
2016-03-29 06:53:41 +08:00
|
|
|
|
|
|
|
case clang::Type::Enum: {
|
|
|
|
clang::EnumDecl *enum_decl =
|
|
|
|
llvm::cast<clang::EnumType>(qual_type)->getDecl();
|
|
|
|
if (enum_decl) {
|
[lldb] NFC modernize codebase with modernize-use-nullptr
Summary:
NFC = [[ https://llvm.org/docs/Lexicon.html#nfc | Non functional change ]]
This commit is the result of modernizing the LLDB codebase by using
`nullptr` instread of `0` or `NULL`. See
https://clang.llvm.org/extra/clang-tidy/checks/modernize-use-nullptr.html
for more information.
This is the command I ran and I to fix and format the code base:
```
run-clang-tidy.py \
-header-filter='.*' \
-checks='-*,modernize-use-nullptr' \
-fix ~/dev/llvm-project/lldb/.* \
-format \
-style LLVM \
-p ~/llvm-builds/debug-ninja-gcc
```
NOTE: There were also changes to `llvm/utils/unittest` but I did not
include them because I felt that maybe this library shall be updated in
isolation somehow.
NOTE: I know this is a rather large commit but it is a nobrainer in most
parts.
Reviewers: martong, espindola, shafik, #lldb, JDevlieghere
Reviewed By: JDevlieghere
Subscribers: arsenm, jvesely, nhaehnle, hiraditya, JDevlieghere, teemperor, rnkovacs, emaste, kubamracek, nemanjai, ki.stfu, javed.absar, arichardson, kbarton, jrtc27, MaskRay, atanasyan, dexonsmith, arphaman, jfb, jsji, jdoerfert, lldb-commits, llvm-commits
Tags: #lldb, #llvm
Differential Revision: https://reviews.llvm.org/D61847
llvm-svn: 361484
2019-05-23 19:14:47 +08:00
|
|
|
if (ResolveDeclOrigin(enum_decl, nullptr, nullptr))
|
2016-03-29 06:53:41 +08:00
|
|
|
return true;
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
} break;
|
|
|
|
|
2016-03-29 06:53:41 +08:00
|
|
|
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
|
2018-05-01 00:49:04 +08:00
|
|
|
// ASTContext because it only supports TagDecl objects right now...
|
2016-03-29 06:53:41 +08:00
|
|
|
if (class_interface_decl) {
|
[lldb] NFC modernize codebase with modernize-use-nullptr
Summary:
NFC = [[ https://llvm.org/docs/Lexicon.html#nfc | Non functional change ]]
This commit is the result of modernizing the LLDB codebase by using
`nullptr` instread of `0` or `NULL`. See
https://clang.llvm.org/extra/clang-tidy/checks/modernize-use-nullptr.html
for more information.
This is the command I ran and I to fix and format the code base:
```
run-clang-tidy.py \
-header-filter='.*' \
-checks='-*,modernize-use-nullptr' \
-fix ~/dev/llvm-project/lldb/.* \
-format \
-style LLVM \
-p ~/llvm-builds/debug-ninja-gcc
```
NOTE: There were also changes to `llvm/utils/unittest` but I did not
include them because I felt that maybe this library shall be updated in
isolation somehow.
NOTE: I know this is a rather large commit but it is a nobrainer in most
parts.
Reviewers: martong, espindola, shafik, #lldb, JDevlieghere
Reviewed By: JDevlieghere
Subscribers: arsenm, jvesely, nhaehnle, hiraditya, JDevlieghere, teemperor, rnkovacs, emaste, kubamracek, nemanjai, ki.stfu, javed.absar, arichardson, kbarton, jrtc27, MaskRay, atanasyan, dexonsmith, arphaman, jfb, jsji, jdoerfert, lldb-commits, llvm-commits
Tags: #lldb, #llvm
Differential Revision: https://reviews.llvm.org/D61847
llvm-svn: 361484
2019-05-23 19:14:47 +08:00
|
|
|
if (ResolveDeclOrigin(class_interface_decl, nullptr, nullptr))
|
2016-03-29 06:53:41 +08:00
|
|
|
return true;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
2016-03-29 06:53:41 +08:00
|
|
|
case clang::Type::Typedef:
|
|
|
|
return CanImport(CompilerType(type.GetTypeSystem(),
|
|
|
|
llvm::cast<clang::TypedefType>(qual_type)
|
2015-07-09 02:03:41 +08:00
|
|
|
->getDecl()
|
2016-03-29 06:53:41 +08:00
|
|
|
->getUnderlyingType()
|
|
|
|
.getAsOpaquePtr()));
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-03-29 06:53:41 +08:00
|
|
|
case clang::Type::Auto:
|
|
|
|
return CanImport(CompilerType(type.GetTypeSystem(),
|
|
|
|
llvm::cast<clang::AutoType>(qual_type)
|
|
|
|
->getDeducedType()
|
|
|
|
.getAsOpaquePtr()));
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-03-29 06:53:41 +08:00
|
|
|
case clang::Type::Elaborated:
|
|
|
|
return CanImport(CompilerType(type.GetTypeSystem(),
|
|
|
|
llvm::cast<clang::ElaboratedType>(qual_type)
|
|
|
|
->getNamedType()
|
|
|
|
.getAsOpaquePtr()));
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-03-29 06:53:41 +08:00
|
|
|
case clang::Type::Paren:
|
|
|
|
return CanImport(CompilerType(
|
|
|
|
type.GetTypeSystem(),
|
|
|
|
llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
|
2016-09-07 04:57:50 +08:00
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-03-29 06:53:41 +08:00
|
|
|
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
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-03-29 06:53:41 +08:00
|
|
|
clang::QualType qual_type(
|
|
|
|
ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-03-29 06:53:41 +08:00
|
|
|
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) {
|
[lldb] NFC modernize codebase with modernize-use-nullptr
Summary:
NFC = [[ https://llvm.org/docs/Lexicon.html#nfc | Non functional change ]]
This commit is the result of modernizing the LLDB codebase by using
`nullptr` instread of `0` or `NULL`. See
https://clang.llvm.org/extra/clang-tidy/checks/modernize-use-nullptr.html
for more information.
This is the command I ran and I to fix and format the code base:
```
run-clang-tidy.py \
-header-filter='.*' \
-checks='-*,modernize-use-nullptr' \
-fix ~/dev/llvm-project/lldb/.* \
-format \
-style LLVM \
-p ~/llvm-builds/debug-ninja-gcc
```
NOTE: There were also changes to `llvm/utils/unittest` but I did not
include them because I felt that maybe this library shall be updated in
isolation somehow.
NOTE: I know this is a rather large commit but it is a nobrainer in most
parts.
Reviewers: martong, espindola, shafik, #lldb, JDevlieghere
Reviewed By: JDevlieghere
Subscribers: arsenm, jvesely, nhaehnle, hiraditya, JDevlieghere, teemperor, rnkovacs, emaste, kubamracek, nemanjai, ki.stfu, javed.absar, arichardson, kbarton, jrtc27, MaskRay, atanasyan, dexonsmith, arphaman, jfb, jsji, jdoerfert, lldb-commits, llvm-commits
Tags: #lldb, #llvm
Differential Revision: https://reviews.llvm.org/D61847
llvm-svn: 361484
2019-05-23 19:14:47 +08:00
|
|
|
if (ResolveDeclOrigin(cxx_record_decl, nullptr, nullptr))
|
2016-03-29 06:53:41 +08:00
|
|
|
return CompleteAndFetchChildren(qual_type);
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
} break;
|
|
|
|
|
2016-03-29 06:53:41 +08:00
|
|
|
case clang::Type::Enum: {
|
|
|
|
clang::EnumDecl *enum_decl =
|
|
|
|
llvm::cast<clang::EnumType>(qual_type)->getDecl();
|
|
|
|
if (enum_decl) {
|
[lldb] NFC modernize codebase with modernize-use-nullptr
Summary:
NFC = [[ https://llvm.org/docs/Lexicon.html#nfc | Non functional change ]]
This commit is the result of modernizing the LLDB codebase by using
`nullptr` instread of `0` or `NULL`. See
https://clang.llvm.org/extra/clang-tidy/checks/modernize-use-nullptr.html
for more information.
This is the command I ran and I to fix and format the code base:
```
run-clang-tidy.py \
-header-filter='.*' \
-checks='-*,modernize-use-nullptr' \
-fix ~/dev/llvm-project/lldb/.* \
-format \
-style LLVM \
-p ~/llvm-builds/debug-ninja-gcc
```
NOTE: There were also changes to `llvm/utils/unittest` but I did not
include them because I felt that maybe this library shall be updated in
isolation somehow.
NOTE: I know this is a rather large commit but it is a nobrainer in most
parts.
Reviewers: martong, espindola, shafik, #lldb, JDevlieghere
Reviewed By: JDevlieghere
Subscribers: arsenm, jvesely, nhaehnle, hiraditya, JDevlieghere, teemperor, rnkovacs, emaste, kubamracek, nemanjai, ki.stfu, javed.absar, arichardson, kbarton, jrtc27, MaskRay, atanasyan, dexonsmith, arphaman, jfb, jsji, jdoerfert, lldb-commits, llvm-commits
Tags: #lldb, #llvm
Differential Revision: https://reviews.llvm.org/D61847
llvm-svn: 361484
2019-05-23 19:14:47 +08:00
|
|
|
if (ResolveDeclOrigin(enum_decl, nullptr, nullptr))
|
2016-03-29 06:53:41 +08:00
|
|
|
return CompleteAndFetchChildren(qual_type);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
2016-03-29 06:53:41 +08:00
|
|
|
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
|
2018-05-01 00:49:04 +08:00
|
|
|
// ASTContext because it only supports TagDecl objects right now...
|
2016-03-29 06:53:41 +08:00
|
|
|
if (class_interface_decl) {
|
[lldb] NFC modernize codebase with modernize-use-nullptr
Summary:
NFC = [[ https://llvm.org/docs/Lexicon.html#nfc | Non functional change ]]
This commit is the result of modernizing the LLDB codebase by using
`nullptr` instread of `0` or `NULL`. See
https://clang.llvm.org/extra/clang-tidy/checks/modernize-use-nullptr.html
for more information.
This is the command I ran and I to fix and format the code base:
```
run-clang-tidy.py \
-header-filter='.*' \
-checks='-*,modernize-use-nullptr' \
-fix ~/dev/llvm-project/lldb/.* \
-format \
-style LLVM \
-p ~/llvm-builds/debug-ninja-gcc
```
NOTE: There were also changes to `llvm/utils/unittest` but I did not
include them because I felt that maybe this library shall be updated in
isolation somehow.
NOTE: I know this is a rather large commit but it is a nobrainer in most
parts.
Reviewers: martong, espindola, shafik, #lldb, JDevlieghere
Reviewed By: JDevlieghere
Subscribers: arsenm, jvesely, nhaehnle, hiraditya, JDevlieghere, teemperor, rnkovacs, emaste, kubamracek, nemanjai, ki.stfu, javed.absar, arichardson, kbarton, jrtc27, MaskRay, atanasyan, dexonsmith, arphaman, jfb, jsji, jdoerfert, lldb-commits, llvm-commits
Tags: #lldb, #llvm
Differential Revision: https://reviews.llvm.org/D61847
llvm-svn: 361484
2019-05-23 19:14:47 +08:00
|
|
|
if (ResolveDeclOrigin(class_interface_decl, nullptr, nullptr))
|
2016-03-29 06:53:41 +08:00
|
|
|
return CompleteAndFetchChildren(qual_type);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
2016-03-29 06:53:41 +08:00
|
|
|
case clang::Type::Typedef:
|
|
|
|
return Import(CompilerType(type.GetTypeSystem(),
|
|
|
|
llvm::cast<clang::TypedefType>(qual_type)
|
2012-02-04 16:49:35 +08:00
|
|
|
->getDecl()
|
2016-03-29 06:53:41 +08:00
|
|
|
->getUnderlyingType()
|
|
|
|
.getAsOpaquePtr()));
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-03-29 06:53:41 +08:00
|
|
|
case clang::Type::Auto:
|
|
|
|
return Import(CompilerType(type.GetTypeSystem(),
|
|
|
|
llvm::cast<clang::AutoType>(qual_type)
|
|
|
|
->getDeducedType()
|
|
|
|
.getAsOpaquePtr()));
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-03-29 06:53:41 +08:00
|
|
|
case clang::Type::Elaborated:
|
|
|
|
return Import(CompilerType(type.GetTypeSystem(),
|
|
|
|
llvm::cast<clang::ElaboratedType>(qual_type)
|
|
|
|
->getNamedType()
|
|
|
|
.getAsOpaquePtr()));
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-03-29 06:53:41 +08:00
|
|
|
case clang::Type::Paren:
|
|
|
|
return Import(CompilerType(
|
|
|
|
type.GetTypeSystem(),
|
|
|
|
llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
|
2016-09-07 04:57:50 +08:00
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2016-03-29 06:53:41 +08:00
|
|
|
return false;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2016-03-29 06:53:41 +08:00
|
|
|
|
|
|
|
bool ClangASTImporter::CompleteType(const CompilerType &compiler_type) {
|
|
|
|
if (!CanImport(compiler_type))
|
|
|
|
return false;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-03-29 06:53:41 +08:00
|
|
|
if (Import(compiler_type)) {
|
2011-12-09 07:45:45 +08:00
|
|
|
ClangASTContext::CompleteTagDeclarationDefinition(compiler_type);
|
2016-03-29 06:53:41 +08:00
|
|
|
return true;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2016-03-29 06:53:41 +08:00
|
|
|
ClangASTContext::SetHasExternalStorage(compiler_type.GetOpaqueQualType(),
|
2016-09-07 04:57:50 +08:00
|
|
|
false);
|
2016-03-29 06:53:41 +08:00
|
|
|
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::InsertRecordDecl(clang::RecordDecl *decl,
|
|
|
|
const LayoutInfo &layout) {
|
|
|
|
m_record_decl_to_layout_map.insert(std::make_pair(decl, layout));
|
|
|
|
}
|
|
|
|
|
2012-02-04 16:49:35 +08:00
|
|
|
void ClangASTImporter::CompleteDecl(clang::Decl *decl) {
|
2013-03-28 07:08:40 +08:00
|
|
|
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
|
2012-02-04 16:49:35 +08:00
|
|
|
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log, " [ClangASTImporter] CompleteDecl called on (%sDecl*)%p",
|
|
|
|
decl->getDeclKindName(), static_cast<void *>(decl));
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2012-02-04 16:49:35 +08:00
|
|
|
if (ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl)) {
|
|
|
|
if (!interface_decl->getDefinition()) {
|
|
|
|
interface_decl->startDefinition();
|
|
|
|
CompleteObjCInterfaceDecl(interface_decl);
|
|
|
|
}
|
2012-03-30 08:51:13 +08:00
|
|
|
} else if (ObjCProtocolDecl *protocol_decl =
|
|
|
|
dyn_cast<ObjCProtocolDecl>(decl)) {
|
2012-02-04 16:49:35 +08:00
|
|
|
if (!protocol_decl->getDefinition())
|
|
|
|
protocol_decl->startDefinition();
|
|
|
|
} else if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl)) {
|
|
|
|
if (!tag_decl->getDefinition() && !tag_decl->isBeingDefined()) {
|
|
|
|
tag_decl->startDefinition();
|
|
|
|
CompleteTagDecl(tag_decl);
|
|
|
|
tag_decl->setCompleteDefinition(true);
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
} else {
|
2012-02-04 16:49:35 +08:00
|
|
|
assert(0 && "CompleteDecl called on a Decl that can't be completed");
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2012-02-04 16:49:35 +08:00
|
|
|
}
|
|
|
|
|
2011-07-30 10:42:06 +08:00
|
|
|
bool ClangASTImporter::CompleteTagDecl(clang::TagDecl *decl) {
|
|
|
|
ClangASTMetrics::RegisterDeclCompletion();
|
2011-12-09 07:45:45 +08:00
|
|
|
|
|
|
|
DeclOrigin decl_origin = GetDeclOrigin(decl);
|
2013-03-09 04:04:57 +08:00
|
|
|
|
2011-12-09 07:45:45 +08:00
|
|
|
if (!decl_origin.Valid())
|
|
|
|
return false;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-12-09 07:45:45 +08:00
|
|
|
if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl))
|
|
|
|
return false;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2019-05-02 18:58:33 +08:00
|
|
|
ImporterDelegateSP delegate_sp(
|
|
|
|
GetDelegate(&decl->getASTContext(), decl_origin.ctx));
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2019-05-02 18:58:33 +08:00
|
|
|
ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp,
|
|
|
|
&decl->getASTContext());
|
|
|
|
if (delegate_sp)
|
|
|
|
delegate_sp->ImportDefinitionTo(decl, decl_origin.decl);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-12-09 07:45:45 +08:00
|
|
|
return true;
|
2011-07-30 10:42:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl,
|
|
|
|
clang::TagDecl *origin_decl) {
|
|
|
|
ClangASTMetrics::RegisterDeclCompletion();
|
2015-04-14 02:32:54 +08:00
|
|
|
|
|
|
|
clang::ASTContext *origin_ast_ctx = &origin_decl->getASTContext();
|
|
|
|
|
2013-03-30 10:31:21 +08:00
|
|
|
if (!ClangASTContext::GetCompleteDecl(origin_ast_ctx, origin_decl))
|
2011-12-09 07:45:45 +08:00
|
|
|
return false;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2019-05-02 18:58:33 +08:00
|
|
|
ImporterDelegateSP delegate_sp(
|
|
|
|
GetDelegate(&decl->getASTContext(), origin_ast_ctx));
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2019-05-02 18:58:33 +08:00
|
|
|
if (delegate_sp)
|
|
|
|
delegate_sp->ImportDefinitionTo(decl, origin_decl);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-12-09 07:45:45 +08:00
|
|
|
ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-12-09 07:45:45 +08:00
|
|
|
OriginMap &origins = context_md->m_origins;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-12-09 07:45:45 +08:00
|
|
|
origins[decl] = DeclOrigin(origin_ast_ctx, origin_decl);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-12-09 07:45:45 +08:00
|
|
|
return true;
|
2011-06-25 08:44:06 +08:00
|
|
|
}
|
2011-07-30 10:42:06 +08:00
|
|
|
|
2015-12-08 09:02:08 +08:00
|
|
|
bool ClangASTImporter::CompleteObjCInterfaceDecl(
|
|
|
|
clang::ObjCInterfaceDecl *interface_decl) {
|
|
|
|
ClangASTMetrics::RegisterDeclCompletion();
|
|
|
|
|
|
|
|
DeclOrigin decl_origin = GetDeclOrigin(interface_decl);
|
|
|
|
|
|
|
|
if (!decl_origin.Valid())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl))
|
|
|
|
return false;
|
|
|
|
|
2019-05-02 18:58:33 +08:00
|
|
|
ImporterDelegateSP delegate_sp(
|
|
|
|
GetDelegate(&interface_decl->getASTContext(), decl_origin.ctx));
|
2015-12-08 09:02:08 +08:00
|
|
|
|
2019-05-02 18:58:33 +08:00
|
|
|
if (delegate_sp)
|
|
|
|
delegate_sp->ImportDefinitionTo(interface_decl, decl_origin.decl);
|
2015-12-08 09:02:08 +08:00
|
|
|
|
|
|
|
if (ObjCInterfaceDecl *super_class = interface_decl->getSuperClass())
|
|
|
|
RequireCompleteType(clang::QualType(super_class->getTypeForDecl(), 0));
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ClangASTImporter::CompleteAndFetchChildren(clang::QualType type) {
|
2013-03-22 06:15:41 +08:00
|
|
|
if (!RequireCompleteType(type))
|
2015-12-08 09:02:08 +08:00
|
|
|
return false;
|
|
|
|
|
[ASTImporter] Use llvm::Expected and Error in the importer API
Summary:
This is the final phase of the refactoring towards using llvm::Expected
and llvm::Error in the ASTImporter API.
This involves the following:
- remove old Import functions which returned with a pointer,
- use the Import_New functions (which return with Err or Expected) everywhere
and handle their return value
- rename Import_New functions to Import
This affects both Clang and LLDB.
Reviewers: shafik, teemperor, aprantl, a_sidorin, balazske, a.sidorin
Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits, lldb-commits
Tags: #clang, #lldb
Differential Revision: https://reviews.llvm.org/D61438
llvm-svn: 360760
2019-05-15 18:29:48 +08:00
|
|
|
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
|
|
|
|
|
2015-12-08 09:02:08 +08:00
|
|
|
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;
|
|
|
|
|
2019-05-02 18:58:33 +08:00
|
|
|
ImporterDelegateSP delegate_sp(
|
|
|
|
GetDelegate(&tag_decl->getASTContext(), decl_origin.ctx));
|
2015-12-08 09:02:08 +08:00
|
|
|
|
2019-05-02 18:58:33 +08:00
|
|
|
ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp,
|
|
|
|
&tag_decl->getASTContext());
|
Instantiate 'std' templates explicitly in the expression evaluator
Summary:
This patch is a follow-up for D58125. It implements the manual instantiation and merging of 'std' templates like
`std::vector` and `std::shared_ptr` with information from the debug info AST. This (finally) allows using these classes
in the expression evaluator like every other class (i.e. things like `vec.size()` and shared_ptr debugging now works, yay!).
The main logic is the `CxxModuleHandler` which intercept the ASTImporter import process and replaces any `std` decls
by decls from the C++ module. The decls from the C++ module are "imported" by just deserializing them directly in
the expression evaluation context. This is mostly because we don't want to rely on the ASTImporter to correctly import
these declarations, but in the future we should also move to the ASTImporter for that.
This patch doesn't contain the automatic desugaring for result variables. This means that if you call for example
`size` of `std::vector` you maybe get some very verbose typedef'd type as the variable type, e.g.
`std::vector<int, std::allocator<int>>::value_type`.
This is not only unreadable, it also means that our ASTImporter has to import all these types and associated
decls into the persisent variable context. This currently usually leads to some assertion getting triggered
in Clang when the ASTImporter either makes a mistake during importing or our debug info AST is inconsitent.
The current workaround I use in the tests is to just cast the result to it's actual type (e.g. `size_t` or `int`) to prevent
the ASTImporter from having to handle all these complicated decls.
The automatic desugaring will be a future patch because I'm not happy yet with the current code for that and because
I anticipate that this will be a controversial patch.
Reviewers: aprantl, shafik, jingham, martong, serge-sans-paille
Reviewed By: martong
Subscribers: balazske, rnkovacs, mgorny, mgrang, abidh, jdoerfert, lldb-commits
Tags: #c_modules_in_lldb, #lldb
Differential Revision: https://reviews.llvm.org/D59537
llvm-svn: 359538
2019-04-30 16:41:35 +08:00
|
|
|
|
2015-12-08 09:02:08 +08:00
|
|
|
TagDecl *origin_tag_decl = llvm::dyn_cast<TagDecl>(decl_origin.decl);
|
|
|
|
|
|
|
|
for (Decl *origin_child_decl : origin_tag_decl->decls()) {
|
[ASTImporter] Use llvm::Expected and Error in the importer API
Summary:
This is the final phase of the refactoring towards using llvm::Expected
and llvm::Error in the ASTImporter API.
This involves the following:
- remove old Import functions which returned with a pointer,
- use the Import_New functions (which return with Err or Expected) everywhere
and handle their return value
- rename Import_New functions to Import
This affects both Clang and LLDB.
Reviewers: shafik, teemperor, aprantl, a_sidorin, balazske, a.sidorin
Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits, lldb-commits
Tags: #clang, #lldb
Differential Revision: https://reviews.llvm.org/D61438
llvm-svn: 360760
2019-05-15 18:29:48 +08:00
|
|
|
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;
|
|
|
|
}
|
2015-12-08 09:02:08 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-12-08 09:02:08 +08:00
|
|
|
if (RecordDecl *record_decl = dyn_cast<RecordDecl>(origin_tag_decl)) {
|
|
|
|
record_decl->setHasLoadedFieldsFromExternalStorage(true);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2015-12-08 09:02:08 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-03-22 06:15:41 +08:00
|
|
|
if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) {
|
|
|
|
if (ObjCInterfaceDecl *objc_interface_decl =
|
|
|
|
objc_object_type->getInterface()) {
|
2015-12-08 09:02:08 +08:00
|
|
|
DeclOrigin decl_origin = GetDeclOrigin(objc_interface_decl);
|
|
|
|
|
2013-03-22 06:15:41 +08:00
|
|
|
if (!decl_origin.Valid())
|
|
|
|
return false;
|
2015-04-09 05:52:45 +08:00
|
|
|
|
2019-05-02 18:58:33 +08:00
|
|
|
ImporterDelegateSP delegate_sp(
|
|
|
|
GetDelegate(&objc_interface_decl->getASTContext(), decl_origin.ctx));
|
2015-04-09 05:52:45 +08:00
|
|
|
|
2013-03-22 06:15:41 +08:00
|
|
|
ObjCInterfaceDecl *origin_interface_decl =
|
|
|
|
llvm::dyn_cast<ObjCInterfaceDecl>(decl_origin.decl);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2013-03-22 06:15:41 +08:00
|
|
|
for (Decl *origin_child_decl : origin_interface_decl->decls()) {
|
[ASTImporter] Use llvm::Expected and Error in the importer API
Summary:
This is the final phase of the refactoring towards using llvm::Expected
and llvm::Error in the ASTImporter API.
This involves the following:
- remove old Import functions which returned with a pointer,
- use the Import_New functions (which return with Err or Expected) everywhere
and handle their return value
- rename Import_New functions to Import
This affects both Clang and LLDB.
Reviewers: shafik, teemperor, aprantl, a_sidorin, balazske, a.sidorin
Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits, lldb-commits
Tags: #clang, #lldb
Differential Revision: https://reviews.llvm.org/D61438
llvm-svn: 360760
2019-05-15 18:29:48 +08:00
|
|
|
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;
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2013-03-22 06:15:41 +08:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-27 09:48:02 +08:00
|
|
|
return true;
|
2012-04-13 08:10:03 +08:00
|
|
|
}
|
|
|
|
|
2011-11-17 05:40:57 +08:00
|
|
|
bool ClangASTImporter::RequireCompleteType(clang::QualType type) {
|
2013-03-22 06:15:41 +08:00
|
|
|
if (type.isNull())
|
2015-12-08 09:02:08 +08:00
|
|
|
return false;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-11-17 05:40:57 +08:00
|
|
|
if (const TagType *tag_type = type->getAs<TagType>()) {
|
|
|
|
TagDecl *tag_decl = tag_type->getDecl();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-11-17 05:40:57 +08:00
|
|
|
if (tag_decl->getDefinition() || tag_decl->isBeingDefined())
|
2015-12-08 09:02:08 +08:00
|
|
|
return true;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-11-17 05:40:57 +08:00
|
|
|
return CompleteTagDecl(tag_decl);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2011-11-17 05:40:57 +08:00
|
|
|
if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) {
|
|
|
|
if (ObjCInterfaceDecl *objc_interface_decl =
|
|
|
|
objc_object_type->getInterface())
|
|
|
|
return CompleteObjCInterfaceDecl(objc_interface_decl);
|
|
|
|
else
|
2015-12-08 09:02:08 +08:00
|
|
|
return false;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2013-03-22 06:15:41 +08:00
|
|
|
if (const ArrayType *array_type = type->getAsArrayTypeUnsafe()) {
|
|
|
|
return RequireCompleteType(array_type->getElementType());
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2013-03-22 06:15:41 +08:00
|
|
|
if (const AtomicType *atomic_type = type->getAs<AtomicType>()) {
|
2011-11-17 05:40:57 +08:00
|
|
|
return RequireCompleteType(atomic_type->getPointeeType());
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2015-12-08 09:02:08 +08:00
|
|
|
return true;
|
2011-11-17 05:40:57 +08:00
|
|
|
}
|
|
|
|
|
2012-09-21 07:21:16 +08:00
|
|
|
ClangASTMetadata *ClangASTImporter::GetDeclMetadata(const clang::Decl *decl) {
|
|
|
|
DeclOrigin decl_origin = GetDeclOrigin(decl);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2012-09-21 07:21:16 +08:00
|
|
|
if (decl_origin.Valid())
|
|
|
|
return ClangASTContext::GetMetadata(decl_origin.ctx, decl_origin.decl);
|
2016-09-07 04:57:50 +08:00
|
|
|
else
|
2012-09-21 07:21:16 +08:00
|
|
|
return ClangASTContext::GetMetadata(&decl->getASTContext(), decl);
|
|
|
|
}
|
|
|
|
|
2011-10-12 08:12:34 +08:00
|
|
|
ClangASTImporter::DeclOrigin
|
|
|
|
ClangASTImporter::GetDeclOrigin(const clang::Decl *decl) {
|
2011-11-17 05:40:57 +08:00
|
|
|
ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-11-17 05:40:57 +08:00
|
|
|
OriginMap &origins = context_md->m_origins;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-11-17 05:40:57 +08:00
|
|
|
OriginMap::iterator iter = origins.find(decl);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-11-17 06:23:28 +08:00
|
|
|
if (iter != origins.end())
|
2011-10-12 08:12:34 +08:00
|
|
|
return iter->second;
|
2016-09-07 04:57:50 +08:00
|
|
|
else
|
2015-12-08 09:02:08 +08:00
|
|
|
return DeclOrigin();
|
2011-10-12 08:12:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ClangASTImporter::SetDeclOrigin(const clang::Decl *decl,
|
|
|
|
clang::Decl *original_decl) {
|
2011-11-17 05:40:57 +08:00
|
|
|
ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-11-17 05:40:57 +08:00
|
|
|
OriginMap &origins = context_md->m_origins;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-11-17 05:40:57 +08:00
|
|
|
OriginMap::iterator iter = origins.find(decl);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-11-17 05:40:57 +08:00
|
|
|
if (iter != origins.end()) {
|
2011-10-12 08:12:34 +08:00
|
|
|
iter->second.decl = original_decl;
|
|
|
|
iter->second.ctx = &original_decl->getASTContext();
|
|
|
|
} else {
|
|
|
|
origins[decl] = DeclOrigin(&original_decl->getASTContext(), original_decl);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2011-10-12 08:12:34 +08:00
|
|
|
}
|
|
|
|
|
2011-10-22 06:18:07 +08:00
|
|
|
void ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl,
|
|
|
|
NamespaceMapSP &namespace_map) {
|
2011-11-17 05:40:57 +08:00
|
|
|
ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-12-06 11:41:14 +08:00
|
|
|
context_md->m_namespace_maps[decl] = namespace_map;
|
2011-10-22 06:18:07 +08:00
|
|
|
}
|
|
|
|
|
2011-11-29 08:42:02 +08:00
|
|
|
ClangASTImporter::NamespaceMapSP
|
|
|
|
ClangASTImporter::GetNamespaceMap(const clang::NamespaceDecl *decl) {
|
2013-03-28 07:08:40 +08:00
|
|
|
ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
|
2014-04-04 12:06:10 +08:00
|
|
|
|
|
|
|
NamespaceMetaMap &namespace_maps = context_md->m_namespace_maps;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2014-04-04 12:06:10 +08:00
|
|
|
NamespaceMetaMap::iterator iter = namespace_maps.find(decl);
|
2012-01-14 06:55:55 +08:00
|
|
|
|
2011-11-17 05:40:57 +08:00
|
|
|
if (iter != namespace_maps.end())
|
|
|
|
return iter->second;
|
2016-09-07 04:57:50 +08:00
|
|
|
else
|
2011-11-17 05:40:57 +08:00
|
|
|
return NamespaceMapSP();
|
2011-11-17 02:20:47 +08:00
|
|
|
}
|
|
|
|
|
2011-11-29 08:42:02 +08:00
|
|
|
void ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl) {
|
|
|
|
assert(decl);
|
|
|
|
ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
|
2014-04-04 12:06:10 +08:00
|
|
|
|
2013-03-28 07:08:40 +08:00
|
|
|
const DeclContext *parent_context = decl->getDeclContext();
|
|
|
|
const NamespaceDecl *parent_namespace =
|
|
|
|
dyn_cast<NamespaceDecl>(parent_context);
|
2011-10-22 06:18:07 +08:00
|
|
|
NamespaceMapSP parent_map;
|
2014-04-04 12:06:10 +08:00
|
|
|
|
2012-01-14 06:55:55 +08:00
|
|
|
if (parent_namespace)
|
2014-04-04 12:06:10 +08:00
|
|
|
parent_map = GetNamespaceMap(parent_namespace);
|
|
|
|
|
2011-11-29 08:42:02 +08:00
|
|
|
NamespaceMapSP new_map;
|
2014-04-04 12:06:10 +08:00
|
|
|
|
2019-02-12 07:13:08 +08:00
|
|
|
new_map = std::make_shared<NamespaceMap>();
|
2014-04-04 12:06:10 +08:00
|
|
|
|
2011-11-29 08:42:02 +08:00
|
|
|
if (context_md->m_map_completer) {
|
|
|
|
std::string namespace_string = decl->getDeclName().getAsString();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-11-29 08:42:02 +08:00
|
|
|
context_md->m_map_completer->CompleteNamespaceMap(
|
|
|
|
new_map, ConstString(namespace_string.c_str()), parent_map);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2011-11-29 08:42:02 +08:00
|
|
|
context_md->m_namespace_maps[decl] = new_map;
|
|
|
|
}
|
|
|
|
|
2011-12-06 11:41:14 +08:00
|
|
|
void ClangASTImporter::ForgetDestination(clang::ASTContext *dst_ast) {
|
2013-03-28 07:08:40 +08:00
|
|
|
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log,
|
|
|
|
" [ClangASTImporter] Forgetting destination (ASTContext*)%p",
|
|
|
|
static_cast<void *>(dst_ast));
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-12-06 11:41:14 +08:00
|
|
|
m_metadata_map.erase(dst_ast);
|
2011-10-22 06:18:07 +08:00
|
|
|
}
|
|
|
|
|
2013-03-30 10:31:21 +08:00
|
|
|
void ClangASTImporter::ForgetSource(clang::ASTContext *dst_ast,
|
|
|
|
clang::ASTContext *src_ast) {
|
|
|
|
ASTContextMetadataSP md = MaybeGetContextMetadata(dst_ast);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2013-03-30 10:31:21 +08:00
|
|
|
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log,
|
|
|
|
" [ClangASTImporter] Forgetting source->dest "
|
|
|
|
"(ASTContext*)%p->(ASTContext*)%p",
|
|
|
|
static_cast<void *>(src_ast), static_cast<void *>(dst_ast));
|
2016-09-07 04:57:50 +08:00
|
|
|
|
|
|
|
if (!md)
|
2013-03-30 10:31:21 +08:00
|
|
|
return;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2019-05-02 18:58:33 +08:00
|
|
|
md->m_delegates.erase(src_ast);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2013-03-30 10:31:21 +08:00
|
|
|
for (OriginMap::iterator iter = md->m_origins.begin();
|
2013-10-10 06:33:34 +08:00
|
|
|
iter != md->m_origins.end();) {
|
2013-03-30 10:31:21 +08:00
|
|
|
if (iter->second.ctx == src_ast)
|
2011-11-29 08:42:02 +08:00
|
|
|
md->m_origins.erase(iter++);
|
2013-03-30 10:31:21 +08:00
|
|
|
else
|
2016-09-07 04:57:50 +08:00
|
|
|
++iter;
|
|
|
|
}
|
2013-03-30 10:31:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
ClangASTImporter::MapCompleter::~MapCompleter() { return; }
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2019-05-02 18:58:33 +08:00
|
|
|
llvm::Expected<Decl *>
|
|
|
|
ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) {
|
Instantiate 'std' templates explicitly in the expression evaluator
Summary:
This patch is a follow-up for D58125. It implements the manual instantiation and merging of 'std' templates like
`std::vector` and `std::shared_ptr` with information from the debug info AST. This (finally) allows using these classes
in the expression evaluator like every other class (i.e. things like `vec.size()` and shared_ptr debugging now works, yay!).
The main logic is the `CxxModuleHandler` which intercept the ASTImporter import process and replaces any `std` decls
by decls from the C++ module. The decls from the C++ module are "imported" by just deserializing them directly in
the expression evaluation context. This is mostly because we don't want to rely on the ASTImporter to correctly import
these declarations, but in the future we should also move to the ASTImporter for that.
This patch doesn't contain the automatic desugaring for result variables. This means that if you call for example
`size` of `std::vector` you maybe get some very verbose typedef'd type as the variable type, e.g.
`std::vector<int, std::allocator<int>>::value_type`.
This is not only unreadable, it also means that our ASTImporter has to import all these types and associated
decls into the persisent variable context. This currently usually leads to some assertion getting triggered
in Clang when the ASTImporter either makes a mistake during importing or our debug info AST is inconsitent.
The current workaround I use in the tests is to just cast the result to it's actual type (e.g. `size_t` or `int`) to prevent
the ASTImporter from having to handle all these complicated decls.
The automatic desugaring will be a future patch because I'm not happy yet with the current code for that and because
I anticipate that this will be a controversial patch.
Reviewers: aprantl, shafik, jingham, martong, serge-sans-paille
Reviewed By: martong
Subscribers: balazske, rnkovacs, mgorny, mgrang, abidh, jdoerfert, lldb-commits
Tags: #c_modules_in_lldb, #lldb
Differential Revision: https://reviews.llvm.org/D59537
llvm-svn: 359538
2019-04-30 16:41:35 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ASTImporter::ImportImpl(From);
|
|
|
|
}
|
|
|
|
|
2019-05-02 18:58:33 +08:00
|
|
|
void ClangASTImporter::ASTImporterDelegate::ImportDefinitionTo(
|
|
|
|
clang::Decl *to, clang::Decl *from) {
|
2013-03-09 04:04:57 +08:00
|
|
|
ASTImporter::Imported(from, to);
|
2014-04-04 12:06:10 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
/*
|
2013-03-28 07:08:40 +08:00
|
|
|
if (to_objc_interface)
|
|
|
|
to_objc_interface->startDefinition();
|
2014-04-04 12:06:10 +08:00
|
|
|
|
2011-11-18 11:28:09 +08:00
|
|
|
CXXRecordDecl *to_cxx_record = dyn_cast<CXXRecordDecl>(to);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-11-18 11:28:09 +08:00
|
|
|
if (to_cxx_record)
|
2012-05-26 02:12:26 +08:00
|
|
|
to_cxx_record->startDefinition();
|
2016-09-07 04:57:50 +08:00
|
|
|
*/
|
|
|
|
|
[ASTImporter] Use llvm::Expected and Error in the importer API
Summary:
This is the final phase of the refactoring towards using llvm::Expected
and llvm::Error in the ASTImporter API.
This involves the following:
- remove old Import functions which returned with a pointer,
- use the Import_New functions (which return with Err or Expected) everywhere
and handle their return value
- rename Import_New functions to Import
This affects both Clang and LLDB.
Reviewers: shafik, teemperor, aprantl, a_sidorin, balazske, a.sidorin
Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits, lldb-commits
Tags: #clang, #lldb
Differential Revision: https://reviews.llvm.org/D61438
llvm-svn: 360760
2019-05-15 18:29:48 +08:00
|
|
|
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;
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2012-11-30 05:49:15 +08:00
|
|
|
if (clang::TagDecl *to_tag = dyn_cast<clang::TagDecl>(to)) {
|
|
|
|
if (clang::TagDecl *from_tag = dyn_cast<clang::TagDecl>(from)) {
|
2014-04-04 12:06:10 +08:00
|
|
|
to_tag->setCompleteDefinition(from_tag->isCompleteDefinition());
|
2019-05-22 17:10:19 +08:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2011-11-18 11:28:09 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2011-11-18 11:28:09 +08:00
|
|
|
|
2018-05-01 00:49:04 +08:00
|
|
|
// 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.
|
2014-04-04 12:06:10 +08:00
|
|
|
|
2011-11-17 06:23:28 +08:00
|
|
|
if (ObjCInterfaceDecl *to_objc_interface = dyn_cast<ObjCInterfaceDecl>(to)) {
|
|
|
|
do {
|
|
|
|
ObjCInterfaceDecl *to_superclass = to_objc_interface->getSuperClass();
|
2014-04-04 12:06:10 +08:00
|
|
|
|
2012-01-20 02:23:06 +08:00
|
|
|
if (to_superclass)
|
2011-11-17 06:23:28 +08:00
|
|
|
break; // we're not going to override it if it's set
|
2014-04-04 12:06:10 +08:00
|
|
|
|
2011-11-17 06:23:28 +08:00
|
|
|
ObjCInterfaceDecl *from_objc_interface =
|
|
|
|
dyn_cast<ObjCInterfaceDecl>(from);
|
2014-04-04 12:06:10 +08:00
|
|
|
|
2012-01-20 02:23:06 +08:00
|
|
|
if (!from_objc_interface)
|
2016-09-07 04:57:50 +08:00
|
|
|
break;
|
|
|
|
|
2011-11-17 06:23:28 +08:00
|
|
|
ObjCInterfaceDecl *from_superclass = from_objc_interface->getSuperClass();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2012-01-20 02:23:06 +08:00
|
|
|
if (!from_superclass)
|
2016-09-07 04:57:50 +08:00
|
|
|
break;
|
|
|
|
|
[ASTImporter] Use llvm::Expected and Error in the importer API
Summary:
This is the final phase of the refactoring towards using llvm::Expected
and llvm::Error in the ASTImporter API.
This involves the following:
- remove old Import functions which returned with a pointer,
- use the Import_New functions (which return with Err or Expected) everywhere
and handle their return value
- rename Import_New functions to Import
This affects both Clang and LLDB.
Reviewers: shafik, teemperor, aprantl, a_sidorin, balazske, a.sidorin
Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits, lldb-commits
Tags: #clang, #lldb
Differential Revision: https://reviews.llvm.org/D61438
llvm-svn: 360760
2019-05-15 18:29:48 +08:00
|
|
|
llvm::Expected<Decl *> imported_from_superclass_decl =
|
|
|
|
Import(from_superclass);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
[ASTImporter] Use llvm::Expected and Error in the importer API
Summary:
This is the final phase of the refactoring towards using llvm::Expected
and llvm::Error in the ASTImporter API.
This involves the following:
- remove old Import functions which returned with a pointer,
- use the Import_New functions (which return with Err or Expected) everywhere
and handle their return value
- rename Import_New functions to Import
This affects both Clang and LLDB.
Reviewers: shafik, teemperor, aprantl, a_sidorin, balazske, a.sidorin
Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits, lldb-commits
Tags: #clang, #lldb
Differential Revision: https://reviews.llvm.org/D61438
llvm-svn: 360760
2019-05-15 18:29:48 +08:00
|
|
|
if (!imported_from_superclass_decl) {
|
|
|
|
LLDB_LOG_ERROR(log, imported_from_superclass_decl.takeError(),
|
|
|
|
"Couldn't import decl: {0}");
|
2016-09-07 04:57:50 +08:00
|
|
|
break;
|
[ASTImporter] Use llvm::Expected and Error in the importer API
Summary:
This is the final phase of the refactoring towards using llvm::Expected
and llvm::Error in the ASTImporter API.
This involves the following:
- remove old Import functions which returned with a pointer,
- use the Import_New functions (which return with Err or Expected) everywhere
and handle their return value
- rename Import_New functions to Import
This affects both Clang and LLDB.
Reviewers: shafik, teemperor, aprantl, a_sidorin, balazske, a.sidorin
Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits, lldb-commits
Tags: #clang, #lldb
Differential Revision: https://reviews.llvm.org/D61438
llvm-svn: 360760
2019-05-15 18:29:48 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2012-01-20 02:23:06 +08:00
|
|
|
ObjCInterfaceDecl *imported_from_superclass =
|
[ASTImporter] Use llvm::Expected and Error in the importer API
Summary:
This is the final phase of the refactoring towards using llvm::Expected
and llvm::Error in the ASTImporter API.
This involves the following:
- remove old Import functions which returned with a pointer,
- use the Import_New functions (which return with Err or Expected) everywhere
and handle their return value
- rename Import_New functions to Import
This affects both Clang and LLDB.
Reviewers: shafik, teemperor, aprantl, a_sidorin, balazske, a.sidorin
Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits, lldb-commits
Tags: #clang, #lldb
Differential Revision: https://reviews.llvm.org/D61438
llvm-svn: 360760
2019-05-15 18:29:48 +08:00
|
|
|
dyn_cast<ObjCInterfaceDecl>(*imported_from_superclass_decl);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2012-01-20 02:23:06 +08:00
|
|
|
if (!imported_from_superclass)
|
2016-09-07 04:57:50 +08:00
|
|
|
break;
|
|
|
|
|
2011-11-17 06:23:28 +08:00
|
|
|
if (!to_objc_interface->hasDefinition())
|
|
|
|
to_objc_interface->startDefinition();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-11-17 06:23:28 +08:00
|
|
|
to_objc_interface->setSuperClass(m_source_ctx->getTrivialTypeSourceInfo(
|
|
|
|
m_source_ctx->getObjCInterfaceType(imported_from_superclass)));
|
2019-05-24 08:44:33 +08:00
|
|
|
} while (false);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-02 18:58:33 +08:00
|
|
|
void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
|
|
|
|
clang::Decl *to) {
|
2013-03-09 04:04:57 +08:00
|
|
|
ClangASTMetrics::RegisterClangImport();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-11-17 06:23:28 +08:00
|
|
|
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
|
2016-09-07 04:57:50 +08:00
|
|
|
|
Instantiate 'std' templates explicitly in the expression evaluator
Summary:
This patch is a follow-up for D58125. It implements the manual instantiation and merging of 'std' templates like
`std::vector` and `std::shared_ptr` with information from the debug info AST. This (finally) allows using these classes
in the expression evaluator like every other class (i.e. things like `vec.size()` and shared_ptr debugging now works, yay!).
The main logic is the `CxxModuleHandler` which intercept the ASTImporter import process and replaces any `std` decls
by decls from the C++ module. The decls from the C++ module are "imported" by just deserializing them directly in
the expression evaluation context. This is mostly because we don't want to rely on the ASTImporter to correctly import
these declarations, but in the future we should also move to the ASTImporter for that.
This patch doesn't contain the automatic desugaring for result variables. This means that if you call for example
`size` of `std::vector` you maybe get some very verbose typedef'd type as the variable type, e.g.
`std::vector<int, std::allocator<int>>::value_type`.
This is not only unreadable, it also means that our ASTImporter has to import all these types and associated
decls into the persisent variable context. This currently usually leads to some assertion getting triggered
in Clang when the ASTImporter either makes a mistake during importing or our debug info AST is inconsitent.
The current workaround I use in the tests is to just cast the result to it's actual type (e.g. `size_t` or `int`) to prevent
the ASTImporter from having to handle all these complicated decls.
The automatic desugaring will be a future patch because I'm not happy yet with the current code for that and because
I anticipate that this will be a controversial patch.
Reviewers: aprantl, shafik, jingham, martong, serge-sans-paille
Reviewed By: martong
Subscribers: balazske, rnkovacs, mgorny, mgrang, abidh, jdoerfert, lldb-commits
Tags: #c_modules_in_lldb, #lldb
Differential Revision: https://reviews.llvm.org/D59537
llvm-svn: 359538
2019-04-30 16:41:35 +08:00
|
|
|
// 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.find(to) != m_decls_to_ignore.end())
|
|
|
|
return clang::ASTImporter::Imported(from, to);
|
|
|
|
|
2011-11-17 06:23:28 +08:00
|
|
|
lldb::user_id_t user_id = LLDB_INVALID_UID;
|
|
|
|
ClangASTMetadata *metadata = m_master.GetDeclMetadata(from);
|
2014-08-02 06:42:38 +08:00
|
|
|
if (metadata)
|
|
|
|
user_id = metadata->GetUserID();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
|
|
|
if (log) {
|
2011-11-17 06:23:28 +08:00
|
|
|
if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from)) {
|
2012-05-26 02:12:26 +08:00
|
|
|
std::string name_string;
|
|
|
|
llvm::raw_string_ostream name_stream(name_string);
|
2011-11-17 06:23:28 +08:00
|
|
|
from_named_decl->printName(name_stream);
|
2012-05-26 02:12:26 +08:00
|
|
|
name_stream.flush();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log,
|
|
|
|
" [ClangASTImporter] Imported (%sDecl*)%p, named %s (from "
|
|
|
|
"(Decl*)%p), metadata 0x%" PRIx64,
|
|
|
|
from->getDeclKindName(), static_cast<void *>(to),
|
|
|
|
name_string.c_str(), static_cast<void *>(from), user_id);
|
2011-11-17 06:23:28 +08:00
|
|
|
} else {
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log,
|
|
|
|
" [ClangASTImporter] Imported (%sDecl*)%p (from "
|
|
|
|
"(Decl*)%p), metadata 0x%" PRIx64,
|
|
|
|
from->getDeclKindName(), static_cast<void *>(to),
|
|
|
|
static_cast<void *>(from), user_id);
|
2011-11-17 06:23:28 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2013-03-30 10:31:21 +08:00
|
|
|
ASTContextMetadataSP to_context_md =
|
2011-11-17 06:23:28 +08:00
|
|
|
m_master.GetContextMetadata(&to->getASTContext());
|
|
|
|
ASTContextMetadataSP from_context_md =
|
|
|
|
m_master.MaybeGetContextMetadata(m_source_ctx);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-11-17 06:23:28 +08:00
|
|
|
if (from_context_md) {
|
|
|
|
OriginMap &origins = from_context_md->m_origins;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-11-17 06:23:28 +08:00
|
|
|
OriginMap::iterator origin_iter = origins.find(from);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-11-17 06:23:28 +08:00
|
|
|
if (origin_iter != origins.end()) {
|
2014-08-02 06:42:38 +08:00
|
|
|
if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() ||
|
|
|
|
user_id != LLDB_INVALID_UID) {
|
2015-07-21 00:55:19 +08:00
|
|
|
if (origin_iter->second.ctx != &to->getASTContext())
|
|
|
|
to_context_md->m_origins[to] = origin_iter->second;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2019-05-02 18:58:33 +08:00
|
|
|
ImporterDelegateSP direct_completer =
|
|
|
|
m_master.GetDelegate(&to->getASTContext(), origin_iter->second.ctx);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
Fixed a bug in the ASTImporter that affects
types that have been imported multiple times.
The discussion below uses this diagram:
ASTContext A B C
Decl Da Db Dc
ASTImporter \-Iab-/\-Iac-/
\-----Iac----/
When a Decl D is imported from ASTContext A to
ASTContext B, the ASTImporter Iab records the
pair <Da, Db> in a DenseMap. That way, if Iab
ever encounters Da again (for example, as the
DeclContext for another Decl), it can use the
imported version. This is not an optimization,
it is critical: if I import the field "st_dev"
as part of importing "struct stat," the field
must have DeclContext equal to the parent
structure or we end up with multiple different
Decls containing different parts of "struct
stat." "struct stat" is imported once and
recorded in the DenseMap; then the ASTImporter
finds that same version when looking for the
DeclContext of "st_dev."
The bug arises when Db is imported into another
ASTContext C and ASTContext B goes away. This
often occurs when LLDB produces result variables
for expressions. Ibc is aware of the transport
of Db to Dc, but a brand new ASTImporter, Iac,
is responsible for completing Dc from its source
upon request. That ASTImporter has no mappings,
so it will produce a clone of Dc when attempting
to import its children. That means that type
completion operations on Dc will fail.
The solution is to create Iac as soon as Ibc
imports D from B to C, and inform Iac of the
mapping between Da and Dc. This allows type
completion to happen correctly.
llvm-svn: 147016
2011-12-21 07:55:47 +08:00
|
|
|
if (direct_completer.get() != this)
|
|
|
|
direct_completer->ASTImporter::Imported(origin_iter->second.decl, to);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log,
|
|
|
|
" [ClangASTImporter] Propagated origin "
|
|
|
|
"(Decl*)%p/(ASTContext*)%p from (ASTContext*)%p to "
|
|
|
|
"(ASTContext*)%p",
|
|
|
|
static_cast<void *>(origin_iter->second.decl),
|
|
|
|
static_cast<void *>(origin_iter->second.ctx),
|
|
|
|
static_cast<void *>(&from->getASTContext()),
|
|
|
|
static_cast<void *>(&to->getASTContext()));
|
2011-11-17 06:23:28 +08:00
|
|
|
} else {
|
2019-09-20 20:52:55 +08:00
|
|
|
if (m_new_decl_listener)
|
|
|
|
m_new_decl_listener->NewDeclImported(from, to);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2014-08-02 06:42:38 +08:00
|
|
|
if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() ||
|
|
|
|
user_id != LLDB_INVALID_UID) {
|
2011-11-17 06:23:28 +08:00
|
|
|
to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log,
|
|
|
|
" [ClangASTImporter] Decl has no origin information in "
|
|
|
|
"(ASTContext*)%p",
|
|
|
|
static_cast<void *>(&from->getASTContext()));
|
2011-11-17 06:23:28 +08:00
|
|
|
}
|
2014-04-04 12:06:10 +08:00
|
|
|
|
2011-07-30 10:42:06 +08:00
|
|
|
if (clang::NamespaceDecl *to_namespace =
|
|
|
|
dyn_cast<clang::NamespaceDecl>(to)) {
|
|
|
|
clang::NamespaceDecl *from_namespace =
|
|
|
|
dyn_cast<clang::NamespaceDecl>(from);
|
2014-04-04 12:06:10 +08:00
|
|
|
|
2011-07-30 10:42:06 +08:00
|
|
|
NamespaceMetaMap &namespace_maps = from_context_md->m_namespace_maps;
|
2014-04-04 12:06:10 +08:00
|
|
|
|
2011-11-18 11:28:09 +08:00
|
|
|
NamespaceMetaMap::iterator namespace_map_iter =
|
|
|
|
namespace_maps.find(from_namespace);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-07-30 10:42:06 +08:00
|
|
|
if (namespace_map_iter != namespace_maps.end())
|
2011-11-10 03:33:21 +08:00
|
|
|
to_context_md->m_namespace_maps[to_namespace] =
|
|
|
|
namespace_map_iter->second;
|
2011-07-30 10:42:06 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
} else {
|
2014-08-02 06:42:38 +08:00
|
|
|
to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from);
|
2014-04-04 12:06:10 +08:00
|
|
|
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log,
|
|
|
|
" [ClangASTImporter] Sourced origin "
|
|
|
|
"(Decl*)%p/(ASTContext*)%p into (ASTContext*)%p",
|
|
|
|
static_cast<void *>(from), static_cast<void *>(m_source_ctx),
|
|
|
|
static_cast<void *>(&to->getASTContext()));
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2014-04-04 12:06:10 +08:00
|
|
|
|
2011-10-22 06:18:07 +08:00
|
|
|
if (TagDecl *from_tag_decl = dyn_cast<TagDecl>(from)) {
|
|
|
|
TagDecl *to_tag_decl = dyn_cast<TagDecl>(to);
|
2014-04-04 12:06:10 +08:00
|
|
|
|
2011-10-22 06:18:07 +08:00
|
|
|
to_tag_decl->setHasExternalLexicalStorage();
|
2018-11-27 01:09:50 +08:00
|
|
|
to_tag_decl->getPrimaryContext()->setMustBuildLookupTable();
|
2014-04-04 12:06:10 +08:00
|
|
|
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(
|
|
|
|
log,
|
|
|
|
" [ClangASTImporter] To is a TagDecl - attributes %s%s [%s->%s]",
|
|
|
|
(to_tag_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
|
|
|
|
(to_tag_decl->hasExternalVisibleStorage() ? " Visible" : ""),
|
|
|
|
(from_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"),
|
|
|
|
(to_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"));
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2016-02-11 06:00:32 +08:00
|
|
|
if (isa<NamespaceDecl>(from)) {
|
2011-10-22 06:18:07 +08:00
|
|
|
NamespaceDecl *to_namespace_decl = dyn_cast<NamespaceDecl>(to);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-10-22 06:18:07 +08:00
|
|
|
m_master.BuildNamespaceMap(to_namespace_decl);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2013-03-30 10:31:21 +08:00
|
|
|
to_namespace_decl->setHasExternalVisibleStorage();
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2011-07-30 10:42:06 +08:00
|
|
|
if (isa<ObjCContainerDecl>(from)) {
|
2016-02-11 06:00:32 +08:00
|
|
|
ObjCContainerDecl *to_container_decl = dyn_cast<ObjCContainerDecl>(to);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-02-11 06:00:32 +08:00
|
|
|
to_container_decl->setHasExternalLexicalStorage();
|
|
|
|
to_container_decl->setHasExternalVisibleStorage();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2012-02-04 16:49:35 +08:00
|
|
|
/*to_interface_decl->setExternallyCompleted();*/
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2011-11-15 10:11:17 +08:00
|
|
|
if (log) {
|
2016-02-11 06:00:32 +08:00
|
|
|
if (ObjCInterfaceDecl *to_interface_decl =
|
|
|
|
llvm::dyn_cast<ObjCInterfaceDecl>(to_container_decl)) {
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(
|
|
|
|
log,
|
2016-02-11 06:00:32 +08:00
|
|
|
" [ClangASTImporter] To is an ObjCInterfaceDecl - attributes "
|
|
|
|
"%s%s%s",
|
|
|
|
(to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
|
|
|
|
(to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""),
|
|
|
|
(to_interface_decl->hasDefinition() ? " HasDefinition" : ""));
|
|
|
|
} else {
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(
|
|
|
|
log, " [ClangASTImporter] To is an %sDecl - attributes %s%s",
|
2016-02-11 06:00:32 +08:00
|
|
|
((Decl *)to_container_decl)->getDeclKindName(),
|
|
|
|
(to_container_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
|
|
|
|
(to_container_decl->hasExternalVisibleStorage() ? " Visible" : ""));
|
|
|
|
}
|
2011-07-30 10:42:06 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2011-08-10 10:10:13 +08:00
|
|
|
}
|
2013-10-10 06:33:34 +08:00
|
|
|
|
2019-05-02 18:58:33 +08:00
|
|
|
clang::Decl *
|
|
|
|
ClangASTImporter::ASTImporterDelegate::GetOriginalDecl(clang::Decl *To) {
|
2013-10-10 06:33:34 +08:00
|
|
|
ASTContextMetadataSP to_context_md =
|
|
|
|
m_master.GetContextMetadata(&To->getASTContext());
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2013-10-10 06:33:34 +08:00
|
|
|
if (!to_context_md)
|
2014-04-20 21:17:36 +08:00
|
|
|
return nullptr;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2013-10-10 06:33:34 +08:00
|
|
|
OriginMap::iterator iter = to_context_md->m_origins.find(To);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2013-10-10 06:33:34 +08:00
|
|
|
if (iter == to_context_md->m_origins.end())
|
2014-04-20 21:17:36 +08:00
|
|
|
return nullptr;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2013-10-10 06:33:34 +08:00
|
|
|
return const_cast<clang::Decl *>(iter->second.decl);
|
|
|
|
}
|