forked from OSchip/llvm-project
Preserve the owning module information from DWARF in the synthesized AST
Types that came from a Clang module are nested in DW_TAG_module tags in DWARF. This patch recreates the Clang module hierarchy in LLDB and 1;95;0csets the owning module information accordingly. My primary motivation is to facilitate looking up per-module APINotes for individual declarations, but this likely also has other applications. This reapplies the previously reverted commit, but without support for ClassTemplateSpecializations, which I'm going to look into separately. rdar://problem/59634380 Differential Revision: https://reviews.llvm.org/D75488
This commit is contained in:
parent
680082a408
commit
143d507c9f
|
@ -242,8 +242,10 @@ public:
|
|||
/// Create a typedef to this type using "name" as the name of the typedef this
|
||||
/// type is valid and the type system supports typedefs, else return an
|
||||
/// invalid type.
|
||||
/// \param payload The typesystem-specific \p lldb::Type payload.
|
||||
CompilerType CreateTypedef(const char *name,
|
||||
const CompilerDeclContext &decl_ctx) const;
|
||||
const CompilerDeclContext &decl_ctx,
|
||||
uint32_t payload) const;
|
||||
|
||||
/// If the current object represents a typedef type, get the underlying type
|
||||
CompilerType GetTypedefedType() const;
|
||||
|
|
|
@ -259,9 +259,12 @@ public:
|
|||
|
||||
virtual CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type);
|
||||
|
||||
/// \param opaque_payload The m_payload field of Type, which may
|
||||
/// carry TypeSystem-specific extra information.
|
||||
virtual CompilerType CreateTypedef(lldb::opaque_compiler_type_t type,
|
||||
const char *name,
|
||||
const CompilerDeclContext &decl_ctx);
|
||||
const CompilerDeclContext &decl_ctx,
|
||||
uint32_t opaque_payload);
|
||||
|
||||
// Exploring the type
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
|
||||
#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
|
||||
#include "Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h"
|
||||
#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
|
||||
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
|
||||
|
||||
|
@ -1003,6 +1004,21 @@ static void MaybeCompleteReturnType(ClangASTImporter &importer,
|
|||
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));
|
||||
|
@ -1012,6 +1028,20 @@ void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
|
|||
if (m_decls_to_ignore.find(to) != m_decls_to_ignore.end())
|
||||
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)
|
||||
|
|
|
@ -993,7 +993,7 @@ void ClangExpressionDeclMap::LookupLocalVarNamespace(
|
|||
|
||||
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;
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
using namespace lldb_private;
|
||||
|
||||
char ClangExternalASTSourceCallbacks::ID;
|
||||
|
||||
void ClangExternalASTSourceCallbacks::CompleteType(clang::TagDecl *tag_decl) {
|
||||
m_ast.CompleteTagDecl(tag_decl);
|
||||
}
|
||||
|
@ -43,3 +45,29 @@ void ClangExternalASTSourceCallbacks::FindExternalLexicalDecls(
|
|||
CompleteType(tag_decl);
|
||||
}
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
|
|
|
@ -10,14 +10,19 @@
|
|||
#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXTERNALASTSOURCECALLBACKS_H
|
||||
|
||||
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
|
||||
#include "clang/AST/ExternalASTSource.h"
|
||||
#include "clang/Basic/Module.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class TypeSystemClang;
|
||||
|
||||
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(
|
||||
|
@ -37,8 +42,20 @@ public:
|
|||
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
|
||||
|
|
|
@ -76,8 +76,9 @@ static CompilerType GetLLDBNSPairType(TargetSP target_sp) {
|
|||
|
||||
if (!compiler_type) {
|
||||
compiler_type = target_ast_context->CreateRecordType(
|
||||
nullptr, lldb::eAccessPublic, g___lldb_autogen_nspair.GetCString(),
|
||||
clang::TTK_Struct, lldb::eLanguageTypeC);
|
||||
nullptr, OptionalClangModuleID(), lldb::eAccessPublic,
|
||||
g___lldb_autogen_nspair.GetCString(), clang::TTK_Struct,
|
||||
lldb::eLanguageTypeC);
|
||||
|
||||
if (compiler_type) {
|
||||
TypeSystemClang::StartTagDeclarationDefinition(compiler_type);
|
||||
|
|
|
@ -124,7 +124,8 @@ clang::QualType AppleObjCTypeEncodingParser::BuildAggregate(
|
|||
return clang::QualType(); // This is where we bail out. Sorry!
|
||||
|
||||
CompilerType union_type(ast_ctx.CreateRecordType(
|
||||
nullptr, lldb::eAccessPublic, name, kind, lldb::eLanguageTypeC));
|
||||
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, name, kind,
|
||||
lldb::eLanguageTypeC));
|
||||
if (union_type) {
|
||||
TypeSystemClang::StartTagDeclarationDefinition(union_type);
|
||||
|
||||
|
|
|
@ -212,14 +212,15 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
|
|||
TypeSP type_sp(new Type(
|
||||
die.GetID(), dwarf, pcm_type_sp->GetName(), pcm_type_sp->GetByteSize(),
|
||||
nullptr, LLDB_INVALID_UID, Type::eEncodingInvalid,
|
||||
&pcm_type_sp->GetDeclaration(), type, Type::ResolveState::Forward));
|
||||
&pcm_type_sp->GetDeclaration(), type, Type::ResolveState::Forward,
|
||||
TypePayloadClang(GetOwningClangModule(die))));
|
||||
|
||||
dwarf->GetTypeList().Insert(type_sp);
|
||||
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
|
||||
clang::TagDecl *tag_decl = TypeSystemClang::GetAsTagDecl(type);
|
||||
if (tag_decl)
|
||||
if (tag_decl) {
|
||||
LinkDeclContextToDIE(tag_decl, die);
|
||||
else {
|
||||
} else {
|
||||
clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(die);
|
||||
if (defn_decl_ctx)
|
||||
LinkDeclContextToDIE(defn_decl_ctx, die);
|
||||
|
@ -708,7 +709,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
|
|||
type_sp = std::make_shared<Type>(
|
||||
die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr,
|
||||
dwarf->GetUID(attrs.type.Reference()), encoding_data_type, &attrs.decl,
|
||||
clang_type, resolve_state);
|
||||
clang_type, resolve_state, TypePayloadClang(GetOwningClangModule(die)));
|
||||
|
||||
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
|
||||
return type_sp;
|
||||
|
@ -790,7 +791,8 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc,
|
|||
|
||||
clang_type = m_ast.CreateEnumerationType(
|
||||
attrs.name.GetCString(), GetClangDeclContextContainingDIE(die, nullptr),
|
||||
attrs.decl, enumerator_clang_type, attrs.is_scoped_enum);
|
||||
GetOwningClangModule(die), attrs.decl, enumerator_clang_type,
|
||||
attrs.is_scoped_enum);
|
||||
} else {
|
||||
enumerator_clang_type = m_ast.GetEnumerationIntegerType(clang_type);
|
||||
}
|
||||
|
@ -800,7 +802,8 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc,
|
|||
type_sp = std::make_shared<Type>(
|
||||
die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr,
|
||||
dwarf->GetUID(attrs.type.Reference()), Type::eEncodingIsUID, &attrs.decl,
|
||||
clang_type, Type::ResolveState::Forward);
|
||||
clang_type, Type::ResolveState::Forward,
|
||||
TypePayloadClang(GetOwningClangModule(die)));
|
||||
|
||||
if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) {
|
||||
if (die.HasChildren()) {
|
||||
|
@ -1184,7 +1187,8 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
|
|||
function_decl = m_ast.CreateFunctionDeclaration(
|
||||
ignore_containing_context ? m_ast.GetTranslationUnitDecl()
|
||||
: containing_decl_ctx,
|
||||
name, clang_type, attrs.storage, attrs.is_inline);
|
||||
GetOwningClangModule(die), name, clang_type, attrs.storage,
|
||||
attrs.is_inline);
|
||||
|
||||
if (has_template_params) {
|
||||
TypeSystemClang::TemplateParameterInfos template_param_infos;
|
||||
|
@ -1192,12 +1196,12 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
|
|||
template_function_decl = m_ast.CreateFunctionDeclaration(
|
||||
ignore_containing_context ? m_ast.GetTranslationUnitDecl()
|
||||
: containing_decl_ctx,
|
||||
name, clang_type, attrs.storage, attrs.is_inline);
|
||||
|
||||
GetOwningClangModule(die), attrs.name.GetCString(), clang_type,
|
||||
attrs.storage, attrs.is_inline);
|
||||
clang::FunctionTemplateDecl *func_template_decl =
|
||||
m_ast.CreateFunctionTemplateDecl(containing_decl_ctx,
|
||||
template_function_decl, name,
|
||||
template_param_infos);
|
||||
m_ast.CreateFunctionTemplateDecl(
|
||||
containing_decl_ctx, GetOwningClangModule(die),
|
||||
template_function_decl, name, template_param_infos);
|
||||
m_ast.CreateFunctionTemplateSpecializationInfo(
|
||||
template_function_decl, func_template_decl, template_param_infos);
|
||||
}
|
||||
|
@ -1594,9 +1598,9 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
|
|||
TypeSystemClang::TemplateParameterInfos template_param_infos;
|
||||
if (ParseTemplateParameterInfos(die, template_param_infos)) {
|
||||
clang::ClassTemplateDecl *class_template_decl =
|
||||
m_ast.ParseClassTemplateDecl(decl_ctx, attrs.accessibility,
|
||||
attrs.name.GetCString(), tag_decl_kind,
|
||||
template_param_infos);
|
||||
m_ast.ParseClassTemplateDecl(
|
||||
decl_ctx, GetOwningClangModule(die), attrs.accessibility,
|
||||
attrs.name.GetCString(), tag_decl_kind, template_param_infos);
|
||||
if (!class_template_decl) {
|
||||
if (log) {
|
||||
dwarf->GetObjectFile()->GetModule()->LogMessage(
|
||||
|
@ -1611,8 +1615,8 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
|
|||
|
||||
clang::ClassTemplateSpecializationDecl *class_specialization_decl =
|
||||
m_ast.CreateClassTemplateSpecializationDecl(
|
||||
decl_ctx, class_template_decl, tag_decl_kind,
|
||||
template_param_infos);
|
||||
decl_ctx, GetOwningClangModule(die), class_template_decl,
|
||||
tag_decl_kind, template_param_infos);
|
||||
clang_type = m_ast.CreateClassTemplateSpecializationType(
|
||||
class_specialization_decl);
|
||||
clang_type_was_created = true;
|
||||
|
@ -1625,8 +1629,9 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
|
|||
if (!clang_type_was_created) {
|
||||
clang_type_was_created = true;
|
||||
clang_type = m_ast.CreateRecordType(
|
||||
decl_ctx, attrs.accessibility, attrs.name.GetCString(), tag_decl_kind,
|
||||
attrs.class_language, &metadata, attrs.exports_symbols);
|
||||
decl_ctx, GetOwningClangModule(die), attrs.accessibility,
|
||||
attrs.name.GetCString(), tag_decl_kind, attrs.class_language,
|
||||
&metadata, attrs.exports_symbols);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1638,7 +1643,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
|
|||
die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr,
|
||||
LLDB_INVALID_UID, Type::eEncodingIsUID, &attrs.decl, clang_type,
|
||||
Type::ResolveState::Forward,
|
||||
TypePayloadClang(attrs.is_complete_objc_class));
|
||||
TypePayloadClang(OptionalClangModuleID(), attrs.is_complete_objc_class));
|
||||
|
||||
// Add our type to the unique type map so we don't end up creating many
|
||||
// copies of the same type over and over in the ASTContext for our
|
||||
|
@ -3082,9 +3087,9 @@ size_t DWARFASTParserClang::ParseChildParameters(
|
|||
function_param_types.push_back(type->GetForwardCompilerType());
|
||||
|
||||
clang::ParmVarDecl *param_var_decl =
|
||||
m_ast.CreateParameterDeclaration(containing_decl_ctx, name,
|
||||
type->GetForwardCompilerType(),
|
||||
storage);
|
||||
m_ast.CreateParameterDeclaration(
|
||||
containing_decl_ctx, GetOwningClangModule(die), name,
|
||||
type->GetForwardCompilerType(), storage);
|
||||
assert(param_var_decl);
|
||||
function_param_decls.push_back(param_var_decl);
|
||||
|
||||
|
@ -3282,7 +3287,7 @@ clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) {
|
|||
TypeSystemClang::DeclContextGetAsDeclContext(
|
||||
dwarf->GetDeclContextContainingUID(die.GetID()));
|
||||
decl = m_ast.CreateVariableDeclaration(
|
||||
decl_context, name,
|
||||
decl_context, GetOwningClangModule(die), name,
|
||||
ClangUtil::GetQualType(type->GetForwardCompilerType()));
|
||||
}
|
||||
break;
|
||||
|
@ -3299,8 +3304,8 @@ clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) {
|
|||
if (clang::NamedDecl *clang_imported_decl =
|
||||
llvm::dyn_cast<clang::NamedDecl>(
|
||||
(clang::Decl *)imported_decl.GetOpaqueDecl()))
|
||||
decl =
|
||||
m_ast.CreateUsingDeclaration(decl_context, clang_imported_decl);
|
||||
decl = m_ast.CreateUsingDeclaration(
|
||||
decl_context, OptionalClangModuleID(), clang_imported_decl);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -3319,7 +3324,8 @@ clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) {
|
|||
if (clang::NamespaceDecl *ns_decl =
|
||||
TypeSystemClang::DeclContextGetAsNamespaceDecl(
|
||||
imported_decl_ctx))
|
||||
decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, ns_decl);
|
||||
decl = m_ast.CreateUsingDirectiveDeclaration(
|
||||
decl_context, OptionalClangModuleID(), ns_decl);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -3377,6 +3383,32 @@ DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
OptionalClangModuleID
|
||||
DWARFASTParserClang::GetOwningClangModule(const DWARFDIE &die) {
|
||||
if (!die.IsValid())
|
||||
return {};
|
||||
|
||||
for (DWARFDIE parent = die.GetParent(); parent.IsValid();
|
||||
parent = parent.GetParent()) {
|
||||
const dw_tag_t tag = parent.Tag();
|
||||
if (tag == DW_TAG_module) {
|
||||
DWARFDIE module_die = parent;
|
||||
auto it = m_die_to_module.find(module_die.GetDIE());
|
||||
if (it != m_die_to_module.end())
|
||||
return it->second;
|
||||
const char *name = module_die.GetAttributeValueAsString(DW_AT_name, 0);
|
||||
if (!name)
|
||||
return {};
|
||||
|
||||
OptionalClangModuleID id =
|
||||
m_ast.GetOrCreateClangModule(name, GetOwningClangModule(module_die));
|
||||
m_die_to_module.insert({module_die.GetDIE(), id});
|
||||
return id;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
static bool IsSubroutine(const DWARFDIE &die) {
|
||||
switch (die.Tag()) {
|
||||
case DW_TAG_subprogram:
|
||||
|
@ -3449,7 +3481,8 @@ clang::BlockDecl *DWARFASTParserClang::ResolveBlockDIE(const DWARFDIE &die) {
|
|||
DWARFDIE decl_context_die;
|
||||
clang::DeclContext *decl_context =
|
||||
GetClangDeclContextContainingDIE(die, &decl_context_die);
|
||||
decl = m_ast.CreateBlockDeclaration(decl_context);
|
||||
decl =
|
||||
m_ast.CreateBlockDeclaration(decl_context, GetOwningClangModule(die));
|
||||
|
||||
if (decl)
|
||||
LinkDeclContextToDIE((clang::DeclContext *)decl, die);
|
||||
|
@ -3477,7 +3510,8 @@ DWARFASTParserClang::ResolveNamespaceDIE(const DWARFDIE &die) {
|
|||
die.GetAttributeValueAsUnsigned(DW_AT_export_symbols, 0) != 0;
|
||||
|
||||
namespace_decl = m_ast.GetUniqueNamespaceDeclaration(
|
||||
namespace_name, containing_decl_ctx, is_inline);
|
||||
namespace_name, containing_decl_ctx, GetOwningClangModule(die),
|
||||
is_inline);
|
||||
Log *log =
|
||||
nullptr; // (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
|
||||
if (log) {
|
||||
|
|
|
@ -78,6 +78,9 @@ protected:
|
|||
DIEToDeclContextMap;
|
||||
typedef std::multimap<const clang::DeclContext *, const DWARFDIE>
|
||||
DeclContextToDIEMap;
|
||||
typedef llvm::DenseMap<const DWARFDebugInfoEntry *,
|
||||
lldb_private::OptionalClangModuleID>
|
||||
DIEToModuleMap;
|
||||
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *>
|
||||
DIEToDeclMap;
|
||||
typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap;
|
||||
|
@ -87,6 +90,7 @@ protected:
|
|||
DeclToDIEMap m_decl_to_die;
|
||||
DIEToDeclContextMap m_die_to_decl_ctx;
|
||||
DeclContextToDIEMap m_decl_ctx_to_die;
|
||||
DIEToModuleMap m_die_to_module;
|
||||
std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_up;
|
||||
/// @}
|
||||
|
||||
|
@ -140,6 +144,7 @@ protected:
|
|||
|
||||
clang::DeclContext *GetClangDeclContextContainingDIE(const DWARFDIE &die,
|
||||
DWARFDIE *decl_ctx_die);
|
||||
lldb_private::OptionalClangModuleID GetOwningClangModule(const DWARFDIE &die);
|
||||
|
||||
bool CopyUniqueClassMethodTypes(const DWARFDIE &src_class_die,
|
||||
const DWARFDIE &dst_class_die,
|
||||
|
|
|
@ -776,8 +776,9 @@ clang::QualType PdbAstBuilder::CreateRecordType(PdbTypeSymId id,
|
|||
metadata.SetUserID(toOpaqueUid(id));
|
||||
metadata.SetIsDynamicCXXType(false);
|
||||
|
||||
CompilerType ct = m_clang.CreateRecordType(
|
||||
context, access, uname, ttk, lldb::eLanguageTypeC_plus_plus, &metadata);
|
||||
CompilerType ct =
|
||||
m_clang.CreateRecordType(context, OptionalClangModuleID(), access, uname,
|
||||
ttk, lldb::eLanguageTypeC_plus_plus, &metadata);
|
||||
|
||||
lldbassert(ct.IsValid());
|
||||
|
||||
|
@ -804,7 +805,8 @@ clang::NamespaceDecl *
|
|||
PdbAstBuilder::GetOrCreateNamespaceDecl(const char *name,
|
||||
clang::DeclContext &context) {
|
||||
return m_clang.GetUniqueNamespaceDeclaration(
|
||||
IsAnonymousNamespaceName(name) ? nullptr : name, &context);
|
||||
IsAnonymousNamespaceName(name) ? nullptr : name, &context,
|
||||
OptionalClangModuleID());
|
||||
}
|
||||
|
||||
clang::BlockDecl *
|
||||
|
@ -814,7 +816,8 @@ PdbAstBuilder::GetOrCreateBlockDecl(PdbCompilandSymId block_id) {
|
|||
|
||||
clang::DeclContext *scope = GetParentDeclContext(block_id);
|
||||
|
||||
clang::BlockDecl *block_decl = m_clang.CreateBlockDeclaration(scope);
|
||||
clang::BlockDecl *block_decl =
|
||||
m_clang.CreateBlockDeclaration(scope, OptionalClangModuleID());
|
||||
m_uid_to_decl.insert({toOpaqueUid(block_id), block_decl});
|
||||
|
||||
DeclStatus status;
|
||||
|
@ -831,7 +834,7 @@ clang::VarDecl *PdbAstBuilder::CreateVariableDecl(PdbSymUid uid, CVSymbol sym,
|
|||
clang::QualType qt = GetOrCreateType(var_info.type);
|
||||
|
||||
clang::VarDecl *var_decl = m_clang.CreateVariableDeclaration(
|
||||
&scope, var_info.name.str().c_str(), qt);
|
||||
&scope, OptionalClangModuleID(), var_info.name.str().c_str(), qt);
|
||||
|
||||
m_uid_to_decl[toOpaqueUid(uid)] = var_decl;
|
||||
DeclStatus status;
|
||||
|
@ -879,7 +882,7 @@ PdbAstBuilder::GetOrCreateTypedefDecl(PdbGlobalSymId id) {
|
|||
std::string uname = std::string(DropNameScope(udt.Name));
|
||||
|
||||
CompilerType ct = m_clang.CreateTypedefType(ToCompilerType(qt), uname.c_str(),
|
||||
ToCompilerDeclContext(*scope));
|
||||
ToCompilerDeclContext(*scope), 0);
|
||||
clang::TypedefNameDecl *tnd = m_clang.GetAsTypedefDecl(ct);
|
||||
DeclStatus status;
|
||||
status.resolved = true;
|
||||
|
@ -1012,7 +1015,8 @@ PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) {
|
|||
proc_name.consume_front("::");
|
||||
|
||||
clang::FunctionDecl *function_decl = m_clang.CreateFunctionDeclaration(
|
||||
parent, proc_name.str().c_str(), func_ct, storage, false);
|
||||
parent, OptionalClangModuleID(), proc_name.str().c_str(), func_ct,
|
||||
storage, false);
|
||||
|
||||
lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0);
|
||||
m_uid_to_decl[toOpaqueUid(func_id)] = function_decl;
|
||||
|
@ -1080,8 +1084,8 @@ void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id,
|
|||
|
||||
CompilerType param_type_ct = m_clang.GetType(qt);
|
||||
clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration(
|
||||
&function_decl, param_name.str().c_str(), param_type_ct,
|
||||
clang::SC_None, true);
|
||||
&function_decl, OptionalClangModuleID(), param_name.str().c_str(),
|
||||
param_type_ct, clang::SC_None, true);
|
||||
lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0);
|
||||
|
||||
m_uid_to_decl[toOpaqueUid(param_uid)] = param;
|
||||
|
@ -1102,8 +1106,8 @@ clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id,
|
|||
|
||||
Declaration declaration;
|
||||
CompilerType enum_ct = m_clang.CreateEnumerationType(
|
||||
uname.c_str(), decl_context, declaration, ToCompilerType(underlying_type),
|
||||
er.isScoped());
|
||||
uname.c_str(), decl_context, OptionalClangModuleID(), declaration,
|
||||
ToCompilerType(underlying_type), er.isScoped());
|
||||
|
||||
TypeSystemClang::StartTagDeclarationDefinition(enum_ct);
|
||||
TypeSystemClang::SetHasExternalStorage(enum_ct.GetOpaqueQualType(), true);
|
||||
|
|
|
@ -409,9 +409,9 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
|
|||
metadata.SetUserID(type.getSymIndexId());
|
||||
metadata.SetIsDynamicCXXType(false);
|
||||
|
||||
clang_type =
|
||||
m_ast.CreateRecordType(decl_context, access, name, tag_type_kind,
|
||||
lldb::eLanguageTypeC_plus_plus, &metadata);
|
||||
clang_type = m_ast.CreateRecordType(
|
||||
decl_context, OptionalClangModuleID(), access, name, tag_type_kind,
|
||||
lldb::eLanguageTypeC_plus_plus, &metadata);
|
||||
assert(clang_type.IsValid());
|
||||
|
||||
auto record_decl =
|
||||
|
@ -497,7 +497,8 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
|
|||
// Class). Set it false for now.
|
||||
bool isScoped = false;
|
||||
|
||||
ast_enum = m_ast.CreateEnumerationType(name.c_str(), decl_context, decl,
|
||||
ast_enum = m_ast.CreateEnumerationType(name.c_str(), decl_context,
|
||||
OptionalClangModuleID(), decl,
|
||||
builtin_type, isScoped);
|
||||
|
||||
auto enum_decl = TypeSystemClang::GetAsEnumDecl(ast_enum);
|
||||
|
@ -550,7 +551,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
|
|||
CompilerType target_ast_type = target_type->GetFullCompilerType();
|
||||
|
||||
ast_typedef = m_ast.CreateTypedefType(
|
||||
target_ast_type, name.c_str(), m_ast.CreateDeclContext(decl_ctx));
|
||||
target_ast_type, name.c_str(), m_ast.CreateDeclContext(decl_ctx), 0);
|
||||
if (!ast_typedef)
|
||||
return nullptr;
|
||||
|
||||
|
@ -901,7 +902,7 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
|
|||
return nullptr;
|
||||
|
||||
decl = m_ast.CreateVariableDeclaration(
|
||||
decl_context, name.c_str(),
|
||||
decl_context, OptionalClangModuleID(), name.c_str(),
|
||||
ClangUtil::GetQualType(type->GetLayoutCompilerType()));
|
||||
}
|
||||
|
||||
|
@ -927,8 +928,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
|
|||
: clang::StorageClass::SC_None;
|
||||
|
||||
auto decl = m_ast.CreateFunctionDeclaration(
|
||||
decl_context, name.c_str(), type->GetForwardCompilerType(), storage,
|
||||
func->hasInlineAttribute());
|
||||
decl_context, OptionalClangModuleID(), name.c_str(),
|
||||
type->GetForwardCompilerType(), storage, func->hasInlineAttribute());
|
||||
|
||||
std::vector<clang::ParmVarDecl *> params;
|
||||
if (std::unique_ptr<PDBSymbolTypeFunctionSig> sig = func->getSignature()) {
|
||||
|
@ -941,8 +942,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
|
|||
continue;
|
||||
|
||||
clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration(
|
||||
decl, nullptr, arg_type->GetForwardCompilerType(),
|
||||
clang::SC_None, true);
|
||||
decl, OptionalClangModuleID(), nullptr,
|
||||
arg_type->GetForwardCompilerType(), clang::SC_None, true);
|
||||
if (param)
|
||||
params.push_back(param);
|
||||
}
|
||||
|
@ -1056,8 +1057,8 @@ clang::DeclContext *PDBASTParser::GetDeclContextContainingSymbol(
|
|||
IsAnonymousNamespaceName(namespace_name) ? nullptr
|
||||
: namespace_name.data();
|
||||
clang::NamespaceDecl *namespace_decl =
|
||||
m_ast.GetUniqueNamespaceDeclaration(namespace_name_c_str,
|
||||
curr_context);
|
||||
m_ast.GetUniqueNamespaceDeclaration(
|
||||
namespace_name_c_str, curr_context, OptionalClangModuleID());
|
||||
|
||||
m_parent_to_namespaces[curr_context].insert(namespace_decl);
|
||||
m_namespaces.insert(namespace_decl);
|
||||
|
|
|
@ -419,8 +419,9 @@ void SystemRuntimeMacOSX::ReadLibdispatchTSDIndexes() {
|
|||
CompilerType uint16 =
|
||||
ast_ctx->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 16);
|
||||
CompilerType dispatch_tsd_indexes_s = ast_ctx->CreateRecordType(
|
||||
nullptr, lldb::eAccessPublic, "__lldb_dispatch_tsd_indexes_s",
|
||||
clang::TTK_Struct, lldb::eLanguageTypeC);
|
||||
nullptr, OptionalClangModuleID(), lldb::eAccessPublic,
|
||||
"__lldb_dispatch_tsd_indexes_s", clang::TTK_Struct,
|
||||
lldb::eLanguageTypeC);
|
||||
|
||||
TypeSystemClang::StartTagDeclarationDefinition(dispatch_tsd_indexes_s);
|
||||
TypeSystemClang::AddFieldToRecordType(dispatch_tsd_indexes_s,
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "clang/Basic/TargetOptions.h"
|
||||
#include "clang/Frontend/FrontendOptions.h"
|
||||
#include "clang/Lex/HeaderSearch.h"
|
||||
#include "clang/Lex/HeaderSearchOptions.h"
|
||||
#include "clang/Lex/ModuleMap.h"
|
||||
#include "clang/Sema/Sema.h"
|
||||
|
||||
#include "llvm/Support/Signals.h"
|
||||
|
@ -316,10 +319,33 @@ static ClangASTMap &GetASTMap() {
|
|||
return *g_map_ptr;
|
||||
}
|
||||
|
||||
TypePayloadClang::TypePayloadClang(bool is_complete_objc_class) {
|
||||
TypePayloadClang::TypePayloadClang(OptionalClangModuleID owning_module,
|
||||
bool is_complete_objc_class)
|
||||
: m_payload(owning_module.GetValue()) {
|
||||
SetIsCompleteObjCClass(is_complete_objc_class);
|
||||
}
|
||||
|
||||
void TypePayloadClang::SetOwningModule(OptionalClangModuleID id) {
|
||||
assert(id.GetValue() < ObjCClassBit);
|
||||
bool is_complete = IsCompleteObjCClass();
|
||||
m_payload = id.GetValue();
|
||||
SetIsCompleteObjCClass(is_complete);
|
||||
}
|
||||
|
||||
static void SetMemberOwningModule(clang::Decl *member,
|
||||
const clang::Decl *parent) {
|
||||
if (!member || !parent)
|
||||
return;
|
||||
|
||||
OptionalClangModuleID id(parent->getOwningModuleID());
|
||||
if (!id.HasValue())
|
||||
return;
|
||||
|
||||
member->setFromASTFile();
|
||||
member->setOwningModuleID(id.GetValue());
|
||||
member->setModuleOwnershipKind(clang::Decl::ModuleOwnershipKind::Visible);
|
||||
}
|
||||
|
||||
char TypeSystemClang::ID;
|
||||
|
||||
bool TypeSystemClang::IsOperator(llvm::StringRef name,
|
||||
|
@ -505,6 +531,10 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
|
|||
//
|
||||
// FIXME: This is affected by other options (-fno-inline).
|
||||
Opts.NoInlineDefine = !Opt;
|
||||
|
||||
// This is needed to allocate the extra space for the owning module
|
||||
// on each decl.
|
||||
Opts.ModulesLocalVisibility = 1;
|
||||
}
|
||||
|
||||
TypeSystemClang::TypeSystemClang(llvm::StringRef name,
|
||||
|
@ -1186,12 +1216,60 @@ CompilerType TypeSystemClang::GetTypeForDecl(ObjCInterfaceDecl *decl) {
|
|||
|
||||
#pragma mark Structure, Unions, Classes
|
||||
|
||||
CompilerType TypeSystemClang::CreateRecordType(DeclContext *decl_ctx,
|
||||
AccessType access_type,
|
||||
llvm::StringRef name, int kind,
|
||||
LanguageType language,
|
||||
ClangASTMetadata *metadata,
|
||||
bool exports_symbols) {
|
||||
void TypeSystemClang::SetOwningModule(clang::Decl *decl,
|
||||
OptionalClangModuleID owning_module) {
|
||||
if (!decl || !owning_module.HasValue())
|
||||
return;
|
||||
|
||||
decl->setFromASTFile();
|
||||
decl->setOwningModuleID(owning_module.GetValue());
|
||||
decl->setModuleOwnershipKind(clang::Decl::ModuleOwnershipKind::Visible);
|
||||
if (auto *decl_ctx = llvm::dyn_cast<clang::DeclContext>(decl)) {
|
||||
decl_ctx->setHasExternalVisibleStorage();
|
||||
if (auto *ns = llvm::dyn_cast<NamespaceDecl>(decl_ctx))
|
||||
ns->getPrimaryContext()->setMustBuildLookupTable();
|
||||
}
|
||||
}
|
||||
|
||||
OptionalClangModuleID
|
||||
TypeSystemClang::GetOrCreateClangModule(llvm::StringRef name,
|
||||
OptionalClangModuleID parent,
|
||||
bool is_framework, bool is_explicit) {
|
||||
// Get the external AST source which holds the modules.
|
||||
auto *ast_source = llvm::dyn_cast_or_null<ClangExternalASTSourceCallbacks>(
|
||||
getASTContext().getExternalSource());
|
||||
assert(ast_source && "external ast source was lost");
|
||||
if (!ast_source)
|
||||
return {};
|
||||
|
||||
// Lazily initialize the module map.
|
||||
if (!m_header_search_up) {
|
||||
auto HSOpts = std::make_shared<clang::HeaderSearchOptions>();
|
||||
m_header_search_up = std::make_unique<clang::HeaderSearch>(
|
||||
HSOpts, *m_source_manager_up, *m_diagnostics_engine_up,
|
||||
*m_language_options_up, m_target_info_up.get());
|
||||
m_module_map_up = std::make_unique<clang::ModuleMap>(
|
||||
*m_source_manager_up, *m_diagnostics_engine_up, *m_language_options_up,
|
||||
m_target_info_up.get(), *m_header_search_up);
|
||||
}
|
||||
|
||||
// Get or create the module context.
|
||||
bool created;
|
||||
clang::Module *module;
|
||||
auto parent_desc = ast_source->getSourceDescriptor(parent.GetValue());
|
||||
std::tie(module, created) = m_module_map_up->findOrCreateModule(
|
||||
name, parent_desc ? parent_desc->getModuleOrNull() : nullptr,
|
||||
is_framework, is_explicit);
|
||||
if (!created)
|
||||
return ast_source->GetIDForModule(module);
|
||||
|
||||
return ast_source->RegisterModule(module);
|
||||
}
|
||||
|
||||
CompilerType TypeSystemClang::CreateRecordType(
|
||||
clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
|
||||
AccessType access_type, llvm::StringRef name, int kind,
|
||||
LanguageType language, ClangASTMetadata *metadata, bool exports_symbols) {
|
||||
ASTContext &ast = getASTContext();
|
||||
|
||||
if (decl_ctx == nullptr)
|
||||
|
@ -1201,7 +1279,8 @@ CompilerType TypeSystemClang::CreateRecordType(DeclContext *decl_ctx,
|
|||
language == eLanguageTypeObjC_plus_plus) {
|
||||
bool isForwardDecl = true;
|
||||
bool isInternal = false;
|
||||
return CreateObjCClass(name, decl_ctx, isForwardDecl, isInternal, metadata);
|
||||
return CreateObjCClass(name, decl_ctx, owning_module, isForwardDecl,
|
||||
isInternal, metadata);
|
||||
}
|
||||
|
||||
// NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
|
||||
|
@ -1216,6 +1295,7 @@ CompilerType TypeSystemClang::CreateRecordType(DeclContext *decl_ctx,
|
|||
decl->setDeclContext(decl_ctx);
|
||||
if (has_name)
|
||||
decl->setDeclName(&ast.Idents.get(name));
|
||||
SetOwningModule(decl, owning_module);
|
||||
|
||||
if (!has_name) {
|
||||
// In C++ a lambda is also represented as an unnamed class. This is
|
||||
|
@ -1327,13 +1407,13 @@ static TemplateParameterList *CreateTemplateParameterList(
|
|||
}
|
||||
|
||||
clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl(
|
||||
clang::DeclContext *decl_ctx, clang::FunctionDecl *func_decl,
|
||||
const char *name, const TemplateParameterInfos &template_param_infos) {
|
||||
clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
|
||||
clang::FunctionDecl *func_decl, const char *name,
|
||||
const TemplateParameterInfos &template_param_infos) {
|
||||
// /// Create a function template node.
|
||||
ASTContext &ast = getASTContext();
|
||||
|
||||
llvm::SmallVector<NamedDecl *, 8> template_param_decls;
|
||||
|
||||
TemplateParameterList *template_param_list = CreateTemplateParameterList(
|
||||
ast, template_param_infos, template_param_decls);
|
||||
FunctionTemplateDecl *func_tmpl_decl =
|
||||
|
@ -1342,6 +1422,7 @@ clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl(
|
|||
func_tmpl_decl->setLocation(func_decl->getLocation());
|
||||
func_tmpl_decl->setDeclName(func_decl->getDeclName());
|
||||
func_tmpl_decl->init(func_decl, template_param_list);
|
||||
SetOwningModule(func_tmpl_decl, owning_module);
|
||||
|
||||
for (size_t i = 0, template_param_decl_count = template_param_decls.size();
|
||||
i < template_param_decl_count; ++i) {
|
||||
|
@ -1368,8 +1449,9 @@ void TypeSystemClang::CreateFunctionTemplateSpecializationInfo(
|
|||
}
|
||||
|
||||
ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl(
|
||||
DeclContext *decl_ctx, lldb::AccessType access_type, const char *class_name,
|
||||
int kind, const TemplateParameterInfos &template_param_infos) {
|
||||
DeclContext *decl_ctx, OptionalClangModuleID owning_module,
|
||||
lldb::AccessType access_type, const char *class_name, int kind,
|
||||
const TemplateParameterInfos &template_param_infos) {
|
||||
ASTContext &ast = getASTContext();
|
||||
|
||||
ClassTemplateDecl *class_template_decl = nullptr;
|
||||
|
@ -1397,6 +1479,7 @@ ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl(
|
|||
// What decl context do we use here? TU? The actual decl context?
|
||||
template_cxx_decl->setDeclContext(decl_ctx);
|
||||
template_cxx_decl->setDeclName(decl_name);
|
||||
SetOwningModule(template_cxx_decl, owning_module);
|
||||
|
||||
for (size_t i = 0, template_param_decl_count = template_param_decls.size();
|
||||
i < template_param_decl_count; ++i) {
|
||||
|
@ -1414,6 +1497,7 @@ ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl(
|
|||
class_template_decl->setDeclName(decl_name);
|
||||
class_template_decl->init(template_cxx_decl, template_param_list);
|
||||
template_cxx_decl->setDescribedClassTemplate(class_template_decl);
|
||||
SetOwningModule(class_template_decl, owning_module);
|
||||
|
||||
if (class_template_decl) {
|
||||
if (access_type != eAccessNone)
|
||||
|
@ -1453,7 +1537,8 @@ TypeSystemClang::CreateTemplateTemplateParmDecl(const char *template_name) {
|
|||
|
||||
ClassTemplateSpecializationDecl *
|
||||
TypeSystemClang::CreateClassTemplateSpecializationDecl(
|
||||
DeclContext *decl_ctx, ClassTemplateDecl *class_template_decl, int kind,
|
||||
DeclContext *decl_ctx, OptionalClangModuleID owning_module,
|
||||
ClassTemplateDecl *class_template_decl, int kind,
|
||||
const TemplateParameterInfos &template_param_infos) {
|
||||
ASTContext &ast = getASTContext();
|
||||
llvm::SmallVector<clang::TemplateArgument, 2> args(
|
||||
|
@ -1476,6 +1561,16 @@ TypeSystemClang::CreateClassTemplateSpecializationDecl(
|
|||
ast.getTypeDeclType(class_template_specialization_decl, nullptr);
|
||||
class_template_specialization_decl->setDeclName(
|
||||
class_template_decl->getDeclName());
|
||||
// FIXME: Turning this on breaks the libcxx data formatter tests.
|
||||
// SetOwningModule marks the Decl as external, which prevents a
|
||||
// LookupPtr from being built. Template instantiations can also not
|
||||
// be found by ExternalASTSource::FindExternalVisibleDeclsByName(),
|
||||
// nor can we lazily build a LookupPtr later, because template
|
||||
// specializations are supposed to be hidden so
|
||||
// makeDeclVisibleInContextWithFlags() is a noop, as well.
|
||||
//
|
||||
// SetOwningModule(class_template_specialization_decl, owning_module);
|
||||
decl_ctx->addDecl(class_template_specialization_decl);
|
||||
|
||||
class_template_specialization_decl->setSpecializationKind(
|
||||
TSK_ExplicitSpecialization);
|
||||
|
@ -1594,14 +1689,13 @@ bool TypeSystemClang::RecordHasFields(const RecordDecl *record_decl) {
|
|||
|
||||
#pragma mark Objective-C Classes
|
||||
|
||||
CompilerType TypeSystemClang::CreateObjCClass(llvm::StringRef name,
|
||||
DeclContext *decl_ctx,
|
||||
bool isForwardDecl,
|
||||
bool isInternal,
|
||||
ClangASTMetadata *metadata) {
|
||||
CompilerType TypeSystemClang::CreateObjCClass(
|
||||
llvm::StringRef name, clang::DeclContext *decl_ctx,
|
||||
OptionalClangModuleID owning_module, bool isForwardDecl, bool isInternal,
|
||||
ClangASTMetadata *metadata) {
|
||||
ASTContext &ast = getASTContext();
|
||||
assert(!name.empty());
|
||||
if (decl_ctx == nullptr)
|
||||
if (!decl_ctx)
|
||||
decl_ctx = ast.getTranslationUnitDecl();
|
||||
|
||||
ObjCInterfaceDecl *decl = ObjCInterfaceDecl::CreateDeserialized(ast, 0);
|
||||
|
@ -1609,6 +1703,7 @@ CompilerType TypeSystemClang::CreateObjCClass(llvm::StringRef name,
|
|||
decl->setDeclName(&ast.Idents.get(name));
|
||||
/*isForwardDecl,*/
|
||||
decl->setImplicit(isInternal);
|
||||
SetOwningModule(decl, owning_module);
|
||||
|
||||
if (decl && metadata)
|
||||
SetMetadata(decl, *metadata);
|
||||
|
@ -1646,11 +1741,12 @@ TypeSystemClang::GetNumBaseClasses(const CXXRecordDecl *cxx_record_decl,
|
|||
#pragma mark Namespace Declarations
|
||||
|
||||
NamespaceDecl *TypeSystemClang::GetUniqueNamespaceDeclaration(
|
||||
const char *name, clang::DeclContext *decl_ctx, bool is_inline) {
|
||||
const char *name, clang::DeclContext *decl_ctx,
|
||||
OptionalClangModuleID owning_module, bool is_inline) {
|
||||
NamespaceDecl *namespace_decl = nullptr;
|
||||
ASTContext &ast = getASTContext();
|
||||
TranslationUnitDecl *translation_unit_decl = ast.getTranslationUnitDecl();
|
||||
if (decl_ctx == nullptr)
|
||||
if (!decl_ctx)
|
||||
decl_ctx = translation_unit_decl;
|
||||
|
||||
if (name) {
|
||||
|
@ -1699,17 +1795,23 @@ NamespaceDecl *TypeSystemClang::GetUniqueNamespaceDeclaration(
|
|||
}
|
||||
}
|
||||
}
|
||||
// Note: namespaces can span multiple modules, so perhaps this isn't a good
|
||||
// idea.
|
||||
SetOwningModule(namespace_decl, owning_module);
|
||||
|
||||
VerifyDecl(namespace_decl);
|
||||
return namespace_decl;
|
||||
}
|
||||
|
||||
clang::BlockDecl *
|
||||
TypeSystemClang::CreateBlockDeclaration(clang::DeclContext *ctx) {
|
||||
TypeSystemClang::CreateBlockDeclaration(clang::DeclContext *ctx,
|
||||
OptionalClangModuleID owning_module) {
|
||||
if (ctx) {
|
||||
clang::BlockDecl *decl =
|
||||
clang::BlockDecl::CreateDeserialized(getASTContext(), 0);
|
||||
decl->setDeclContext(ctx);
|
||||
ctx->addDecl(decl);
|
||||
SetOwningModule(decl, owning_module);
|
||||
return decl;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -1733,7 +1835,8 @@ clang::DeclContext *FindLCABetweenDecls(clang::DeclContext *left,
|
|||
}
|
||||
|
||||
clang::UsingDirectiveDecl *TypeSystemClang::CreateUsingDirectiveDeclaration(
|
||||
clang::DeclContext *decl_ctx, clang::NamespaceDecl *ns_decl) {
|
||||
clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
|
||||
clang::NamespaceDecl *ns_decl) {
|
||||
if (decl_ctx && ns_decl) {
|
||||
auto *translation_unit = getASTContext().getTranslationUnitDecl();
|
||||
clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create(
|
||||
|
@ -1743,6 +1846,7 @@ clang::UsingDirectiveDecl *TypeSystemClang::CreateUsingDirectiveDeclaration(
|
|||
FindLCABetweenDecls(decl_ctx, ns_decl,
|
||||
translation_unit));
|
||||
decl_ctx->addDecl(using_decl);
|
||||
SetOwningModule(using_decl, owning_module);
|
||||
return using_decl;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -1750,14 +1854,17 @@ clang::UsingDirectiveDecl *TypeSystemClang::CreateUsingDirectiveDeclaration(
|
|||
|
||||
clang::UsingDecl *
|
||||
TypeSystemClang::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
|
||||
OptionalClangModuleID owning_module,
|
||||
clang::NamedDecl *target) {
|
||||
if (current_decl_ctx != nullptr && target != nullptr) {
|
||||
if (current_decl_ctx && target) {
|
||||
clang::UsingDecl *using_decl = clang::UsingDecl::Create(
|
||||
getASTContext(), current_decl_ctx, clang::SourceLocation(),
|
||||
clang::NestedNameSpecifierLoc(), clang::DeclarationNameInfo(), false);
|
||||
SetOwningModule(using_decl, owning_module);
|
||||
clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create(
|
||||
getASTContext(), current_decl_ctx, clang::SourceLocation(), using_decl,
|
||||
target);
|
||||
SetOwningModule(shadow_decl, owning_module);
|
||||
using_decl->addShadowDecl(shadow_decl);
|
||||
current_decl_ctx->addDecl(using_decl);
|
||||
return using_decl;
|
||||
|
@ -1766,7 +1873,8 @@ TypeSystemClang::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
|
|||
}
|
||||
|
||||
clang::VarDecl *TypeSystemClang::CreateVariableDeclaration(
|
||||
clang::DeclContext *decl_context, const char *name, clang::QualType type) {
|
||||
clang::DeclContext *decl_context, OptionalClangModuleID owning_module,
|
||||
const char *name, clang::QualType type) {
|
||||
if (decl_context) {
|
||||
clang::VarDecl *var_decl =
|
||||
clang::VarDecl::CreateDeserialized(getASTContext(), 0);
|
||||
|
@ -1774,6 +1882,7 @@ clang::VarDecl *TypeSystemClang::CreateVariableDeclaration(
|
|||
if (name && name[0])
|
||||
var_decl->setDeclName(&getASTContext().Idents.getOwn(name));
|
||||
var_decl->setType(type);
|
||||
SetOwningModule(var_decl, owning_module);
|
||||
var_decl->setAccess(clang::AS_public);
|
||||
decl_context->addDecl(var_decl);
|
||||
return var_decl;
|
||||
|
@ -1885,11 +1994,12 @@ TypeSystemClang::GetDeclarationName(const char *name,
|
|||
}
|
||||
|
||||
FunctionDecl *TypeSystemClang::CreateFunctionDeclaration(
|
||||
DeclContext *decl_ctx, const char *name,
|
||||
const CompilerType &function_clang_type, int storage, bool is_inline) {
|
||||
clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
|
||||
const char *name, const CompilerType &function_clang_type, int storage,
|
||||
bool is_inline) {
|
||||
FunctionDecl *func_decl = nullptr;
|
||||
ASTContext &ast = getASTContext();
|
||||
if (decl_ctx == nullptr)
|
||||
if (!decl_ctx)
|
||||
decl_ctx = ast.getTranslationUnitDecl();
|
||||
|
||||
const bool hasWrittenPrototype = true;
|
||||
|
@ -1906,6 +2016,7 @@ FunctionDecl *TypeSystemClang::CreateFunctionDeclaration(
|
|||
func_decl->setHasWrittenPrototype(hasWrittenPrototype);
|
||||
func_decl->setConstexprKind(isConstexprSpecified ? CSK_constexpr
|
||||
: CSK_unspecified);
|
||||
SetOwningModule(func_decl, owning_module);
|
||||
if (func_decl)
|
||||
decl_ctx->addDecl(func_decl);
|
||||
|
||||
|
@ -1954,8 +2065,9 @@ TypeSystemClang::CreateFunctionType(const CompilerType &result_type,
|
|||
}
|
||||
|
||||
ParmVarDecl *TypeSystemClang::CreateParameterDeclaration(
|
||||
clang::DeclContext *decl_ctx, const char *name,
|
||||
const CompilerType ¶m_type, int storage, bool add_decl) {
|
||||
clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
|
||||
const char *name, const CompilerType ¶m_type, int storage,
|
||||
bool add_decl) {
|
||||
ASTContext &ast = getASTContext();
|
||||
auto *decl = ParmVarDecl::CreateDeserialized(ast, 0);
|
||||
decl->setDeclContext(decl_ctx);
|
||||
|
@ -1963,6 +2075,7 @@ ParmVarDecl *TypeSystemClang::CreateParameterDeclaration(
|
|||
decl->setDeclName(&ast.Idents.get(name));
|
||||
decl->setType(ClangUtil::GetQualType(param_type));
|
||||
decl->setStorageClass(static_cast<clang::StorageClass>(storage));
|
||||
SetOwningModule(decl, owning_module);
|
||||
if (add_decl)
|
||||
decl_ctx->addDecl(decl);
|
||||
|
||||
|
@ -2024,8 +2137,9 @@ CompilerType TypeSystemClang::CreateStructForIdentifier(
|
|||
return type;
|
||||
}
|
||||
|
||||
type = CreateRecordType(nullptr, lldb::eAccessPublic, type_name.GetCString(),
|
||||
clang::TTK_Struct, lldb::eLanguageTypeC);
|
||||
type = CreateRecordType(nullptr, OptionalClangModuleID(), lldb::eAccessPublic,
|
||||
type_name.GetCString(), clang::TTK_Struct,
|
||||
lldb::eLanguageTypeC);
|
||||
StartTagDeclarationDefinition(type);
|
||||
for (const auto &field : type_fields)
|
||||
AddFieldToRecordType(type, field.first, field.second, lldb::eAccessPublic,
|
||||
|
@ -2050,11 +2164,10 @@ CompilerType TypeSystemClang::GetOrCreateStructForIdentifier(
|
|||
|
||||
#pragma mark Enumeration Types
|
||||
|
||||
CompilerType
|
||||
TypeSystemClang::CreateEnumerationType(const char *name, DeclContext *decl_ctx,
|
||||
const Declaration &decl,
|
||||
const CompilerType &integer_clang_type,
|
||||
bool is_scoped) {
|
||||
CompilerType TypeSystemClang::CreateEnumerationType(
|
||||
const char *name, clang::DeclContext *decl_ctx,
|
||||
OptionalClangModuleID owning_module, const Declaration &decl,
|
||||
const CompilerType &integer_clang_type, bool is_scoped) {
|
||||
// TODO: Do something intelligent with the Declaration object passed in
|
||||
// like maybe filling in the SourceLocation with it...
|
||||
ASTContext &ast = getASTContext();
|
||||
|
@ -2068,6 +2181,7 @@ TypeSystemClang::CreateEnumerationType(const char *name, DeclContext *decl_ctx,
|
|||
enum_decl->setScoped(is_scoped);
|
||||
enum_decl->setScopedUsingClassTag(is_scoped);
|
||||
enum_decl->setFixed(false);
|
||||
SetOwningModule(enum_decl, owning_module);
|
||||
if (enum_decl) {
|
||||
if (decl_ctx)
|
||||
decl_ctx->addDecl(enum_decl);
|
||||
|
@ -4254,7 +4368,7 @@ TypeSystemClang::GetNonReferenceType(lldb::opaque_compiler_type_t type) {
|
|||
|
||||
CompilerType TypeSystemClang::CreateTypedefType(
|
||||
const CompilerType &type, const char *typedef_name,
|
||||
const CompilerDeclContext &compiler_decl_ctx) {
|
||||
const CompilerDeclContext &compiler_decl_ctx, uint32_t payload) {
|
||||
if (type && typedef_name && typedef_name[0]) {
|
||||
TypeSystemClang *ast =
|
||||
llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
|
||||
|
@ -4265,7 +4379,7 @@ CompilerType TypeSystemClang::CreateTypedefType(
|
|||
|
||||
clang::DeclContext *decl_ctx =
|
||||
TypeSystemClang::DeclContextGetAsDeclContext(compiler_decl_ctx);
|
||||
if (decl_ctx == nullptr)
|
||||
if (!decl_ctx)
|
||||
decl_ctx = ast->getASTContext().getTranslationUnitDecl();
|
||||
|
||||
clang::TypedefDecl *decl =
|
||||
|
@ -4274,6 +4388,7 @@ CompilerType TypeSystemClang::CreateTypedefType(
|
|||
decl->setDeclName(&clang_ast.Idents.get(typedef_name));
|
||||
decl->setTypeSourceInfo(clang_ast.getTrivialTypeSourceInfo(qual_type));
|
||||
|
||||
SetOwningModule(decl, TypePayloadClang(payload).GetOwningModule());
|
||||
decl->setAccess(clang::AS_public); // TODO respect proper access specifier
|
||||
|
||||
decl_ctx->addDecl(decl);
|
||||
|
@ -4362,24 +4477,23 @@ TypeSystemClang::AddRestrictModifier(lldb::opaque_compiler_type_t type) {
|
|||
return CompilerType();
|
||||
}
|
||||
|
||||
CompilerType
|
||||
TypeSystemClang::CreateTypedef(lldb::opaque_compiler_type_t type,
|
||||
const char *typedef_name,
|
||||
const CompilerDeclContext &compiler_decl_ctx) {
|
||||
CompilerType TypeSystemClang::CreateTypedef(
|
||||
lldb::opaque_compiler_type_t type, const char *typedef_name,
|
||||
const CompilerDeclContext &compiler_decl_ctx, uint32_t payload) {
|
||||
if (type) {
|
||||
clang::ASTContext &clang_ast = getASTContext();
|
||||
clang::QualType qual_type(GetQualType(type));
|
||||
|
||||
clang::DeclContext *decl_ctx =
|
||||
TypeSystemClang::DeclContextGetAsDeclContext(compiler_decl_ctx);
|
||||
if (decl_ctx == nullptr)
|
||||
if (!decl_ctx)
|
||||
decl_ctx = getASTContext().getTranslationUnitDecl();
|
||||
|
||||
clang::TypedefDecl *decl =
|
||||
clang::TypedefDecl::CreateDeserialized(clang_ast, 0);
|
||||
decl->setDeclContext(decl_ctx);
|
||||
decl->setDeclName(&clang_ast.Idents.get(typedef_name));
|
||||
decl->setTypeSourceInfo(clang_ast.getTrivialTypeSourceInfo(qual_type));
|
||||
clang::TypedefDecl *decl = clang::TypedefDecl::Create(
|
||||
clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(),
|
||||
&clang_ast.Idents.get(typedef_name),
|
||||
clang_ast.getTrivialTypeSourceInfo(qual_type));
|
||||
SetOwningModule(decl, TypePayloadClang(payload).GetOwningModule());
|
||||
|
||||
clang::TagDecl *tdecl = nullptr;
|
||||
if (!qual_type.isNull()) {
|
||||
|
@ -6923,6 +7037,7 @@ clang::FieldDecl *TypeSystemClang::AddFieldToRecordType(
|
|||
field->setType(ClangUtil::GetQualType(field_clang_type));
|
||||
if (bit_width)
|
||||
field->setBitWidth(bit_width);
|
||||
SetMemberOwningModule(field, record_decl);
|
||||
|
||||
if (name.empty()) {
|
||||
// Determine whether this field corresponds to an anonymous struct or
|
||||
|
@ -6964,6 +7079,7 @@ clang::FieldDecl *TypeSystemClang::AddFieldToRecordType(
|
|||
ivar->setBitWidth(bit_width);
|
||||
ivar->setSynthesize(is_synthesized);
|
||||
field = ivar;
|
||||
SetMemberOwningModule(field, class_interface_decl);
|
||||
|
||||
if (field) {
|
||||
class_interface_decl->addDecl(field);
|
||||
|
@ -7025,6 +7141,7 @@ void TypeSystemClang::BuildIndirectFields(const CompilerType &type) {
|
|||
ast->getASTContext(), record_decl, clang::SourceLocation(),
|
||||
nested_field_decl->getIdentifier(),
|
||||
nested_field_decl->getType(), {chain, 2});
|
||||
SetMemberOwningModule(indirect_field, record_decl);
|
||||
|
||||
indirect_field->setImplicit();
|
||||
|
||||
|
@ -7055,6 +7172,7 @@ void TypeSystemClang::BuildIndirectFields(const CompilerType &type) {
|
|||
nested_indirect_field_decl->getIdentifier(),
|
||||
nested_indirect_field_decl->getType(),
|
||||
{chain, nested_chain_size + 1});
|
||||
SetMemberOwningModule(indirect_field, record_decl);
|
||||
|
||||
indirect_field->setImplicit();
|
||||
|
||||
|
@ -7121,6 +7239,7 @@ clang::VarDecl *TypeSystemClang::AddVariableToRecordType(
|
|||
var_decl->setDeclName(ident);
|
||||
var_decl->setType(ClangUtil::GetQualType(var_type));
|
||||
var_decl->setStorageClass(clang::SC_Static);
|
||||
SetMemberOwningModule(var_decl, record_decl);
|
||||
if (!var_decl)
|
||||
return nullptr;
|
||||
|
||||
|
@ -7256,6 +7375,7 @@ clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType(
|
|||
cxx_method_decl->setConstexprKind(CSK_unspecified);
|
||||
}
|
||||
}
|
||||
SetMemberOwningModule(cxx_method_decl, cxx_record_decl);
|
||||
|
||||
clang::AccessSpecifier access_specifier =
|
||||
TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access);
|
||||
|
@ -7430,6 +7550,7 @@ bool TypeSystemClang::AddObjCClassProperty(
|
|||
? ivar_decl->getType()
|
||||
: ClangUtil::GetQualType(property_clang_type),
|
||||
prop_type_source);
|
||||
SetMemberOwningModule(property_decl, class_interface_decl);
|
||||
|
||||
if (!property_decl)
|
||||
return false;
|
||||
|
@ -7521,6 +7642,7 @@ bool TypeSystemClang::AddObjCClassProperty(
|
|||
getter->setDefined(isDefined);
|
||||
getter->setDeclImplementation(impControl);
|
||||
getter->setRelatedResultType(HasRelatedResultType);
|
||||
SetMemberOwningModule(getter, class_interface_decl);
|
||||
|
||||
if (getter) {
|
||||
if (metadata)
|
||||
|
@ -7562,6 +7684,7 @@ bool TypeSystemClang::AddObjCClassProperty(
|
|||
setter->setDefined(isDefined);
|
||||
setter->setDeclImplementation(impControl);
|
||||
setter->setRelatedResultType(HasRelatedResultType);
|
||||
SetMemberOwningModule(setter, class_interface_decl);
|
||||
|
||||
if (setter) {
|
||||
if (metadata)
|
||||
|
@ -7690,6 +7813,7 @@ clang::ObjCMethodDecl *TypeSystemClang::AddMethodToObjCObjectType(
|
|||
objc_method_decl->setDefined(isDefined);
|
||||
objc_method_decl->setDeclImplementation(impControl);
|
||||
objc_method_decl->setRelatedResultType(HasRelatedResultType);
|
||||
SetMemberOwningModule(objc_method_decl, class_interface_decl);
|
||||
|
||||
if (objc_method_decl == nullptr)
|
||||
return nullptr;
|
||||
|
@ -7920,6 +8044,7 @@ clang::EnumConstantDecl *TypeSystemClang::AddEnumerationValueToEnumerationType(
|
|||
enumerator_decl->setDeclName(&getASTContext().Idents.get(name));
|
||||
enumerator_decl->setType(clang::QualType(enutype, 0));
|
||||
enumerator_decl->setInitVal(value);
|
||||
SetMemberOwningModule(enumerator_decl, enutype->getDecl());
|
||||
|
||||
if (!enumerator_decl)
|
||||
return nullptr;
|
||||
|
@ -8814,14 +8939,14 @@ void TypeSystemClang::DumpTypeName(const CompilerType &type) {
|
|||
}
|
||||
|
||||
clang::ClassTemplateDecl *TypeSystemClang::ParseClassTemplateDecl(
|
||||
clang::DeclContext *decl_ctx, lldb::AccessType access_type,
|
||||
const char *parent_name, int tag_decl_kind,
|
||||
clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
|
||||
lldb::AccessType access_type, const char *parent_name, int tag_decl_kind,
|
||||
const TypeSystemClang::TemplateParameterInfos &template_param_infos) {
|
||||
if (template_param_infos.IsValid()) {
|
||||
std::string template_basename(parent_name);
|
||||
template_basename.erase(template_basename.find('<'));
|
||||
|
||||
return CreateClassTemplateDecl(decl_ctx, access_type,
|
||||
return CreateClassTemplateDecl(decl_ctx, owning_module, access_type,
|
||||
template_basename.c_str(), tag_decl_kind,
|
||||
template_param_infos);
|
||||
}
|
||||
|
|
|
@ -53,13 +53,30 @@ class ClangASTMetadata;
|
|||
class ClangASTSource;
|
||||
class Declaration;
|
||||
|
||||
/// A Clang module ID.
|
||||
class OptionalClangModuleID {
|
||||
unsigned m_id = 0;
|
||||
|
||||
public:
|
||||
OptionalClangModuleID() = default;
|
||||
explicit OptionalClangModuleID(unsigned id) : m_id(id) {}
|
||||
bool HasValue() const { return m_id != 0; }
|
||||
unsigned GetValue() const { return m_id; }
|
||||
};
|
||||
|
||||
/// The implementation of lldb::Type's m_payload field for TypeSystemClang.
|
||||
class TypePayloadClang {
|
||||
/// Layout: bit 31 ... IsCompleteObjCClass.
|
||||
/// The Layout is as follows:
|
||||
/// \verbatim
|
||||
/// bit 0..30 ... Owning Module ID.
|
||||
/// bit 31 ...... IsCompleteObjCClass.
|
||||
/// \endverbatim
|
||||
Type::Payload m_payload = 0;
|
||||
|
||||
public:
|
||||
TypePayloadClang() = default;
|
||||
explicit TypePayloadClang(bool is_complete_objc_class);
|
||||
explicit TypePayloadClang(OptionalClangModuleID owning_module,
|
||||
bool is_complete_objc_class = false);
|
||||
explicit TypePayloadClang(uint32_t opaque_payload) : m_payload(opaque_payload) {}
|
||||
operator Type::Payload() { return m_payload; }
|
||||
|
||||
|
@ -69,6 +86,11 @@ public:
|
|||
m_payload = is_complete_objc_class ? Flags(m_payload).Set(ObjCClassBit)
|
||||
: Flags(m_payload).Clear(ObjCClassBit);
|
||||
}
|
||||
OptionalClangModuleID GetOwningModule() {
|
||||
return OptionalClangModuleID(Flags(m_payload).Clear(ObjCClassBit));
|
||||
}
|
||||
void SetOwningModule(OptionalClangModuleID id);
|
||||
/// \}
|
||||
};
|
||||
|
||||
/// A TypeSystem implementation based on Clang.
|
||||
|
@ -293,7 +315,14 @@ public:
|
|||
static uint32_t GetNumBaseClasses(const clang::CXXRecordDecl *cxx_record_decl,
|
||||
bool omit_empty_base_classes);
|
||||
|
||||
/// Synthesize a clang::Module and return its ID or a default-constructed ID.
|
||||
OptionalClangModuleID GetOrCreateClangModule(llvm::StringRef name,
|
||||
OptionalClangModuleID parent,
|
||||
bool is_framework = false,
|
||||
bool is_explicit = false);
|
||||
|
||||
CompilerType CreateRecordType(clang::DeclContext *decl_ctx,
|
||||
OptionalClangModuleID owning_module,
|
||||
lldb::AccessType access_type,
|
||||
llvm::StringRef name, int kind,
|
||||
lldb::LanguageType language,
|
||||
|
@ -319,6 +348,7 @@ public:
|
|||
|
||||
clang::FunctionTemplateDecl *
|
||||
CreateFunctionTemplateDecl(clang::DeclContext *decl_ctx,
|
||||
OptionalClangModuleID owning_module,
|
||||
clang::FunctionDecl *func_decl, const char *name,
|
||||
const TemplateParameterInfos &infos);
|
||||
|
||||
|
@ -328,6 +358,7 @@ public:
|
|||
|
||||
clang::ClassTemplateDecl *
|
||||
CreateClassTemplateDecl(clang::DeclContext *decl_ctx,
|
||||
OptionalClangModuleID owning_module,
|
||||
lldb::AccessType access_type, const char *class_name,
|
||||
int kind, const TemplateParameterInfos &infos);
|
||||
|
||||
|
@ -335,7 +366,7 @@ public:
|
|||
CreateTemplateTemplateParmDecl(const char *template_name);
|
||||
|
||||
clang::ClassTemplateSpecializationDecl *CreateClassTemplateSpecializationDecl(
|
||||
clang::DeclContext *decl_ctx,
|
||||
clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
|
||||
clang::ClassTemplateDecl *class_template_decl, int kind,
|
||||
const TemplateParameterInfos &infos);
|
||||
|
||||
|
@ -355,8 +386,9 @@ public:
|
|||
static bool RecordHasFields(const clang::RecordDecl *record_decl);
|
||||
|
||||
CompilerType CreateObjCClass(llvm::StringRef name,
|
||||
clang::DeclContext *decl_ctx, bool isForwardDecl,
|
||||
bool isInternal,
|
||||
clang::DeclContext *decl_ctx,
|
||||
OptionalClangModuleID owning_module,
|
||||
bool isForwardDecl, bool isInternal,
|
||||
ClangASTMetadata *metadata = nullptr);
|
||||
|
||||
bool SetTagTypeKind(clang::QualType type, int kind) const;
|
||||
|
@ -373,14 +405,16 @@ public:
|
|||
|
||||
clang::NamespaceDecl *
|
||||
GetUniqueNamespaceDeclaration(const char *name, clang::DeclContext *decl_ctx,
|
||||
OptionalClangModuleID owning_module,
|
||||
bool is_inline = false);
|
||||
|
||||
// Function Types
|
||||
|
||||
clang::FunctionDecl *
|
||||
CreateFunctionDeclaration(clang::DeclContext *decl_ctx, const char *name,
|
||||
const CompilerType &function_Type, int storage,
|
||||
bool is_inline);
|
||||
CreateFunctionDeclaration(clang::DeclContext *decl_ctx,
|
||||
OptionalClangModuleID owning_module,
|
||||
const char *name, const CompilerType &function_Type,
|
||||
int storage, bool is_inline);
|
||||
|
||||
CompilerType CreateFunctionType(const CompilerType &result_type,
|
||||
const CompilerType *args, unsigned num_args,
|
||||
|
@ -394,11 +428,11 @@ public:
|
|||
type_quals, clang::CC_C);
|
||||
}
|
||||
|
||||
clang::ParmVarDecl *CreateParameterDeclaration(clang::DeclContext *decl_ctx,
|
||||
const char *name,
|
||||
const CompilerType ¶m_type,
|
||||
int storage,
|
||||
bool add_decl=false);
|
||||
clang::ParmVarDecl *
|
||||
CreateParameterDeclaration(clang::DeclContext *decl_ctx,
|
||||
OptionalClangModuleID owning_module,
|
||||
const char *name, const CompilerType ¶m_type,
|
||||
int storage, bool add_decl = false);
|
||||
|
||||
void SetFunctionParameters(clang::FunctionDecl *function_decl,
|
||||
clang::ParmVarDecl **params, unsigned num_params);
|
||||
|
@ -413,6 +447,7 @@ public:
|
|||
// Enumeration Types
|
||||
CompilerType CreateEnumerationType(const char *name,
|
||||
clang::DeclContext *decl_ctx,
|
||||
OptionalClangModuleID owning_module,
|
||||
const Declaration &decl,
|
||||
const CompilerType &integer_qual_type,
|
||||
bool is_scoped);
|
||||
|
@ -479,6 +514,10 @@ public:
|
|||
/// TypeSystemClang.
|
||||
CompilerDeclContext CreateDeclContext(clang::DeclContext *ctx);
|
||||
|
||||
/// Set the owning module for \p decl.
|
||||
static void SetOwningModule(clang::Decl *decl,
|
||||
OptionalClangModuleID owning_module);
|
||||
|
||||
std::vector<CompilerDecl>
|
||||
DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name,
|
||||
const bool ignore_using_decls) override;
|
||||
|
@ -641,11 +680,13 @@ public:
|
|||
|
||||
// Creating related types
|
||||
|
||||
// Using the current type, create a new typedef to that type using
|
||||
// "typedef_name" as the name and "decl_ctx" as the decl context.
|
||||
/// Using the current type, create a new typedef to that type using
|
||||
/// "typedef_name" as the name and "decl_ctx" as the decl context.
|
||||
/// \param payload is an opaque TypePayloadClang.
|
||||
static CompilerType
|
||||
CreateTypedefType(const CompilerType &type, const char *typedef_name,
|
||||
const CompilerDeclContext &compiler_decl_ctx);
|
||||
const CompilerDeclContext &compiler_decl_ctx,
|
||||
uint32_t opaque_payload);
|
||||
|
||||
CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type,
|
||||
uint64_t *stride) override;
|
||||
|
@ -696,7 +737,8 @@ public:
|
|||
|
||||
CompilerType CreateTypedef(lldb::opaque_compiler_type_t type,
|
||||
const char *name,
|
||||
const CompilerDeclContext &decl_ctx) override;
|
||||
const CompilerDeclContext &decl_ctx,
|
||||
uint32_t opaque_payload) override;
|
||||
|
||||
// If the current object represents a typedef type, get the underlying type
|
||||
CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) override;
|
||||
|
@ -955,20 +997,24 @@ public:
|
|||
GetAsObjCInterfaceDecl(const CompilerType &type);
|
||||
|
||||
clang::ClassTemplateDecl *ParseClassTemplateDecl(
|
||||
clang::DeclContext *decl_ctx, lldb::AccessType access_type,
|
||||
const char *parent_name, int tag_decl_kind,
|
||||
clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
|
||||
lldb::AccessType access_type, const char *parent_name, int tag_decl_kind,
|
||||
const TypeSystemClang::TemplateParameterInfos &template_param_infos);
|
||||
|
||||
clang::BlockDecl *CreateBlockDeclaration(clang::DeclContext *ctx);
|
||||
clang::BlockDecl *CreateBlockDeclaration(clang::DeclContext *ctx,
|
||||
OptionalClangModuleID owning_module);
|
||||
|
||||
clang::UsingDirectiveDecl *
|
||||
CreateUsingDirectiveDeclaration(clang::DeclContext *decl_ctx,
|
||||
OptionalClangModuleID owning_module,
|
||||
clang::NamespaceDecl *ns_decl);
|
||||
|
||||
clang::UsingDecl *CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
|
||||
OptionalClangModuleID owning_module,
|
||||
clang::NamedDecl *target);
|
||||
|
||||
clang::VarDecl *CreateVariableDeclaration(clang::DeclContext *decl_context,
|
||||
OptionalClangModuleID owning_module,
|
||||
const char *name,
|
||||
clang::QualType type);
|
||||
|
||||
|
@ -991,6 +1037,13 @@ public:
|
|||
clang::DeclarationName
|
||||
GetDeclarationName(const char *name, const CompilerType &function_clang_type);
|
||||
|
||||
clang::LangOptions *GetLangOpts() const {
|
||||
return m_language_options_up.get();
|
||||
}
|
||||
clang::SourceManager *GetSourceMgr() const {
|
||||
return m_source_manager_up.get();
|
||||
}
|
||||
|
||||
private:
|
||||
const clang::ClassTemplateSpecializationDecl *
|
||||
GetAsTemplateSpecialization(lldb::opaque_compiler_type_t type);
|
||||
|
@ -1008,6 +1061,8 @@ private:
|
|||
std::unique_ptr<clang::IdentifierTable> m_identifier_table_up;
|
||||
std::unique_ptr<clang::SelectorTable> m_selector_table_up;
|
||||
std::unique_ptr<clang::Builtin::Context> m_builtins_up;
|
||||
std::unique_ptr<clang::HeaderSearch> m_header_search_up;
|
||||
std::unique_ptr<clang::ModuleMap> m_module_map_up;
|
||||
std::unique_ptr<DWARFASTParserClang> m_dwarf_ast_parser_up;
|
||||
std::unique_ptr<PDBASTParser> m_pdb_ast_parser_up;
|
||||
std::unique_ptr<clang::MangleContext> m_mangle_ctx_up;
|
||||
|
|
|
@ -439,11 +439,11 @@ CompilerType CompilerType::AddRestrictModifier() const {
|
|||
return CompilerType();
|
||||
}
|
||||
|
||||
CompilerType
|
||||
CompilerType::CreateTypedef(const char *name,
|
||||
const CompilerDeclContext &decl_ctx) const {
|
||||
CompilerType CompilerType::CreateTypedef(const char *name,
|
||||
const CompilerDeclContext &decl_ctx,
|
||||
uint32_t payload) const {
|
||||
if (IsValid())
|
||||
return m_type_system->CreateTypedef(m_type, name, decl_ctx);
|
||||
return m_type_system->CreateTypedef(m_type, name, decl_ctx, payload);
|
||||
else
|
||||
return CompilerType();
|
||||
}
|
||||
|
|
|
@ -505,7 +505,7 @@ bool Type::ResolveCompilerType(ResolveState compiler_type_resolve_state) {
|
|||
case eEncodingIsTypedefUID:
|
||||
m_compiler_type = encoding_type->GetForwardCompilerType().CreateTypedef(
|
||||
m_name.AsCString("__lldb_invalid_typedef_name"),
|
||||
GetSymbolFile()->GetDeclContextContainingUID(GetID()));
|
||||
GetSymbolFile()->GetDeclContextContainingUID(GetID()), m_payload);
|
||||
m_name.Clear();
|
||||
break;
|
||||
|
||||
|
@ -563,7 +563,7 @@ bool Type::ResolveCompilerType(ResolveState compiler_type_resolve_state) {
|
|||
case eEncodingIsTypedefUID:
|
||||
m_compiler_type = void_compiler_type.CreateTypedef(
|
||||
m_name.AsCString("__lldb_invalid_typedef_name"),
|
||||
GetSymbolFile()->GetDeclContextContainingUID(GetID()));
|
||||
GetSymbolFile()->GetDeclContextContainingUID(GetID()), m_payload);
|
||||
break;
|
||||
|
||||
case eEncodingIsPointerUID:
|
||||
|
|
|
@ -113,7 +113,8 @@ TypeSystem::AddRestrictModifier(lldb::opaque_compiler_type_t type) {
|
|||
|
||||
CompilerType TypeSystem::CreateTypedef(lldb::opaque_compiler_type_t type,
|
||||
const char *name,
|
||||
const CompilerDeclContext &decl_ctx) {
|
||||
const CompilerDeclContext &decl_ctx,
|
||||
uint32_t opaque_payload) {
|
||||
return CompilerType();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
#include "B.h" // -*- ObjC -*-
|
||||
|
||||
typedef int Typedef;
|
||||
|
||||
struct TopLevelStruct {
|
||||
int a;
|
||||
};
|
||||
|
||||
typedef struct Struct_s {
|
||||
int a;
|
||||
} Struct;
|
||||
|
||||
struct Nested {
|
||||
StructB fromb;
|
||||
};
|
||||
|
||||
typedef enum Enum_e { a = 0 } Enum;
|
||||
|
||||
@interface SomeClass {
|
||||
}
|
||||
@end
|
||||
|
||||
template <typename T> struct Template { T field; };
|
||||
extern template struct Template<int>;
|
||||
|
||||
namespace Namespace {
|
||||
template <typename T> struct InNamespace { T field; };
|
||||
extern template struct InNamespace<int>;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
typedef struct {
|
||||
int b;
|
||||
} StructB;
|
||||
|
||||
namespace Namespace {
|
||||
template <typename T> struct AlsoInNamespace { T field; };
|
||||
extern template struct AlsoInNamespace<int>;
|
||||
} // namespace Namespace
|
|
@ -0,0 +1,6 @@
|
|||
module A {
|
||||
header "A.h"
|
||||
module B {
|
||||
header "B.h"
|
||||
}
|
||||
}
|
|
@ -1 +1 @@
|
|||
config.suffixes = ['.cpp', '.m', '.s', '.test', '.ll']
|
||||
config.suffixes = ['.cpp', '.m', '.mm', '.s', '.test', '.ll']
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
// RUN: %clang --target=x86_64-apple-macosx -g -gmodules \
|
||||
// RUN: -fmodules -fmodules-cache-path=%t.cache \
|
||||
// RUN: -c -o %t.o %s -I%S/Inputs
|
||||
// RUN: lldb-test symbols -dump-clang-ast %t.o | FileCheck %s
|
||||
// Verify that the owning module information from DWARF is preserved in the AST.
|
||||
|
||||
@import A;
|
||||
|
||||
Typedef t1;
|
||||
// CHECK-DAG: TypedefDecl {{.*}} imported in A Typedef
|
||||
|
||||
TopLevelStruct s1;
|
||||
// CHECK-DAG: CXXRecordDecl {{.*}} imported in A struct TopLevelStruct
|
||||
// CHECK-DAG: -FieldDecl {{.*}} in A a 'int'
|
||||
|
||||
Struct s2;
|
||||
// CHECK-DAG: CXXRecordDecl {{.*}} imported in A struct
|
||||
|
||||
StructB s3;
|
||||
// CHECK-DAG: CXXRecordDecl {{.*}} imported in A.B struct
|
||||
// CHECK-DAG: -FieldDecl {{.*}} in A.B b 'int'
|
||||
|
||||
Nested s4;
|
||||
// CHECK-DAG: CXXRecordDecl {{.*}} imported in A struct Nested
|
||||
// CHECK-DAG: -FieldDecl {{.*}} in A fromb 'StructB'
|
||||
|
||||
Enum e1;
|
||||
// CHECK-DAG: EnumDecl {{.*}} imported in A {{.*}} Enum_e
|
||||
// FIXME: -EnumConstantDecl {{.*}} imported in A a
|
||||
|
||||
SomeClass *obj1;
|
||||
// CHECK-DAG: ObjCInterfaceDecl {{.*}} imported in A {{.*}} SomeClass
|
||||
|
||||
// Template specializations are not yet supported, so they lack the ownership info:
|
||||
Template<int> t2;
|
||||
// CHECK-DAG: ClassTemplateSpecializationDecl {{.*}} struct Template
|
||||
|
||||
Namespace::InNamespace<int> t3;
|
||||
// CHECK-DAG: ClassTemplateSpecializationDecl {{.*}} struct InNamespace
|
||||
|
||||
Namespace::AlsoInNamespace<int> t4;
|
||||
// CHECK-DAG: ClassTemplateSpecializationDecl {{.*}} struct AlsoInNamespace
|
|
@ -14,6 +14,7 @@
|
|||
#include "lldb/Host/HostInfo.h"
|
||||
#include "lldb/Symbol/Declaration.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
|
@ -257,9 +258,10 @@ TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeBasicTypes) {
|
|||
CompilerType basic_compiler_type = ast.GetBasicType(basic_type);
|
||||
EXPECT_TRUE(basic_compiler_type.IsValid());
|
||||
|
||||
CompilerType enum_type =
|
||||
ast.CreateEnumerationType("my_enum", ast.GetTranslationUnitDecl(),
|
||||
Declaration(), basic_compiler_type, scoped);
|
||||
CompilerType enum_type = ast.CreateEnumerationType(
|
||||
"my_enum", ast.GetTranslationUnitDecl(), OptionalClangModuleID(),
|
||||
Declaration(), basic_compiler_type, scoped);
|
||||
|
||||
CompilerType t = ast.GetEnumerationIntegerType(enum_type);
|
||||
// Check that the type we put in at the start is found again.
|
||||
EXPECT_EQ(basic_compiler_type.GetTypeName(), t.GetTypeName());
|
||||
|
@ -267,14 +269,39 @@ TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeBasicTypes) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST_F(TestTypeSystemClang, TestOwningModule) {
|
||||
TypeSystemClang ast("module_ast", HostInfo::GetTargetTriple());
|
||||
CompilerType basic_compiler_type = ast.GetBasicType(BasicType::eBasicTypeInt);
|
||||
CompilerType enum_type = ast.CreateEnumerationType(
|
||||
"my_enum", ast.GetTranslationUnitDecl(), OptionalClangModuleID(100),
|
||||
Declaration(), basic_compiler_type, false);
|
||||
auto *ed = TypeSystemClang::GetAsEnumDecl(enum_type);
|
||||
EXPECT_FALSE(!ed);
|
||||
EXPECT_EQ(ed->getOwningModuleID(), 100u);
|
||||
|
||||
CompilerType record_type = ast.CreateRecordType(
|
||||
nullptr, OptionalClangModuleID(200), lldb::eAccessPublic, "FooRecord",
|
||||
clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
|
||||
auto *rd = TypeSystemClang::GetAsRecordDecl(record_type);
|
||||
EXPECT_FALSE(!rd);
|
||||
EXPECT_EQ(rd->getOwningModuleID(), 200u);
|
||||
|
||||
CompilerType class_type =
|
||||
ast.CreateObjCClass("objc_class", ast.GetTranslationUnitDecl(),
|
||||
OptionalClangModuleID(300), false, false);
|
||||
auto *cd = TypeSystemClang::GetAsObjCInterfaceDecl(class_type);
|
||||
EXPECT_FALSE(!cd);
|
||||
EXPECT_EQ(cd->getOwningModuleID(), 300u);
|
||||
}
|
||||
|
||||
TEST_F(TestTypeSystemClang, TestIsClangType) {
|
||||
clang::ASTContext &context = m_ast->getASTContext();
|
||||
lldb::opaque_compiler_type_t bool_ctype =
|
||||
TypeSystemClang::GetOpaqueCompilerType(&context, lldb::eBasicTypeBool);
|
||||
CompilerType bool_type(m_ast.get(), bool_ctype);
|
||||
CompilerType record_type = m_ast->CreateRecordType(
|
||||
nullptr, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct,
|
||||
lldb::eLanguageTypeC_plus_plus, nullptr);
|
||||
nullptr, OptionalClangModuleID(100), lldb::eAccessPublic, "FooRecord",
|
||||
clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
|
||||
// Clang builtin type and record type should pass
|
||||
EXPECT_TRUE(ClangUtil::IsClangType(bool_type));
|
||||
EXPECT_TRUE(ClangUtil::IsClangType(record_type));
|
||||
|
@ -285,8 +312,8 @@ TEST_F(TestTypeSystemClang, TestIsClangType) {
|
|||
|
||||
TEST_F(TestTypeSystemClang, TestRemoveFastQualifiers) {
|
||||
CompilerType record_type = m_ast->CreateRecordType(
|
||||
nullptr, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct,
|
||||
lldb::eLanguageTypeC_plus_plus, nullptr);
|
||||
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "FooRecord",
|
||||
clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
|
||||
QualType qt;
|
||||
|
||||
qt = ClangUtil::GetQualType(record_type);
|
||||
|
@ -357,8 +384,8 @@ TEST_F(TestTypeSystemClang, TestRecordHasFields) {
|
|||
|
||||
// Test that a record with no fields returns false
|
||||
CompilerType empty_base = m_ast->CreateRecordType(
|
||||
nullptr, lldb::eAccessPublic, "EmptyBase", clang::TTK_Struct,
|
||||
lldb::eLanguageTypeC_plus_plus, nullptr);
|
||||
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyBase",
|
||||
clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
|
||||
TypeSystemClang::StartTagDeclarationDefinition(empty_base);
|
||||
TypeSystemClang::CompleteTagDeclarationDefinition(empty_base);
|
||||
|
||||
|
@ -368,8 +395,8 @@ TEST_F(TestTypeSystemClang, TestRecordHasFields) {
|
|||
|
||||
// Test that a record with direct fields returns true
|
||||
CompilerType non_empty_base = m_ast->CreateRecordType(
|
||||
nullptr, lldb::eAccessPublic, "NonEmptyBase", clang::TTK_Struct,
|
||||
lldb::eLanguageTypeC_plus_plus, nullptr);
|
||||
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "NonEmptyBase",
|
||||
clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
|
||||
TypeSystemClang::StartTagDeclarationDefinition(non_empty_base);
|
||||
FieldDecl *non_empty_base_field_decl = m_ast->AddFieldToRecordType(
|
||||
non_empty_base, "MyField", int_type, eAccessPublic, 0);
|
||||
|
@ -384,8 +411,8 @@ TEST_F(TestTypeSystemClang, TestRecordHasFields) {
|
|||
|
||||
// Test that a record with no direct fields, but fields in a base returns true
|
||||
CompilerType empty_derived = m_ast->CreateRecordType(
|
||||
nullptr, lldb::eAccessPublic, "EmptyDerived", clang::TTK_Struct,
|
||||
lldb::eLanguageTypeC_plus_plus, nullptr);
|
||||
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyDerived",
|
||||
clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
|
||||
TypeSystemClang::StartTagDeclarationDefinition(empty_derived);
|
||||
std::unique_ptr<clang::CXXBaseSpecifier> non_empty_base_spec =
|
||||
m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(),
|
||||
|
@ -407,8 +434,8 @@ TEST_F(TestTypeSystemClang, TestRecordHasFields) {
|
|||
// Test that a record with no direct fields, but fields in a virtual base
|
||||
// returns true
|
||||
CompilerType empty_derived2 = m_ast->CreateRecordType(
|
||||
nullptr, lldb::eAccessPublic, "EmptyDerived2", clang::TTK_Struct,
|
||||
lldb::eLanguageTypeC_plus_plus, nullptr);
|
||||
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyDerived2",
|
||||
clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
|
||||
TypeSystemClang::StartTagDeclarationDefinition(empty_derived2);
|
||||
std::unique_ptr<CXXBaseSpecifier> non_empty_vbase_spec =
|
||||
m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(),
|
||||
|
@ -439,13 +466,15 @@ TEST_F(TestTypeSystemClang, TemplateArguments) {
|
|||
|
||||
// template<typename T, int I> struct foo;
|
||||
ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl(
|
||||
m_ast->GetTranslationUnitDecl(), eAccessPublic, "foo", TTK_Struct, infos);
|
||||
m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic,
|
||||
"foo", TTK_Struct, infos);
|
||||
ASSERT_NE(decl, nullptr);
|
||||
|
||||
// foo<int, 47>
|
||||
ClassTemplateSpecializationDecl *spec_decl =
|
||||
m_ast->CreateClassTemplateSpecializationDecl(
|
||||
m_ast->GetTranslationUnitDecl(), decl, TTK_Struct, infos);
|
||||
m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), decl,
|
||||
TTK_Struct, infos);
|
||||
ASSERT_NE(spec_decl, nullptr);
|
||||
CompilerType type = m_ast->CreateClassTemplateSpecializationType(spec_decl);
|
||||
ASSERT_TRUE(type);
|
||||
|
@ -454,7 +483,8 @@ TEST_F(TestTypeSystemClang, TemplateArguments) {
|
|||
|
||||
// typedef foo<int, 47> foo_def;
|
||||
CompilerType typedef_type = m_ast->CreateTypedefType(
|
||||
type, "foo_def", m_ast->CreateDeclContext(m_ast->GetTranslationUnitDecl()));
|
||||
type, "foo_def",
|
||||
m_ast->CreateDeclContext(m_ast->GetTranslationUnitDecl()), 0);
|
||||
|
||||
CompilerType auto_type(
|
||||
m_ast.get(),
|
||||
|
@ -528,13 +558,14 @@ TEST_F(TestTypeSystemClang, TestFunctionTemplateConstruction) {
|
|||
// Prepare the declarations/types we need for the template.
|
||||
CompilerType clang_type =
|
||||
m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U);
|
||||
FunctionDecl *func =
|
||||
m_ast->CreateFunctionDeclaration(TU, "foo", clang_type, 0, false);
|
||||
FunctionDecl *func = m_ast->CreateFunctionDeclaration(
|
||||
TU, OptionalClangModuleID(), "foo", clang_type, 0, false);
|
||||
TypeSystemClang::TemplateParameterInfos empty_params;
|
||||
|
||||
// Create the actual function template.
|
||||
clang::FunctionTemplateDecl *func_template =
|
||||
m_ast->CreateFunctionTemplateDecl(TU, func, "foo", empty_params);
|
||||
m_ast->CreateFunctionTemplateDecl(TU, OptionalClangModuleID(), func,
|
||||
"foo", empty_params);
|
||||
|
||||
EXPECT_EQ(TU, func_template->getDeclContext());
|
||||
EXPECT_EQ("foo", func_template->getName());
|
||||
|
@ -558,13 +589,14 @@ TEST_F(TestTypeSystemClang, TestFunctionTemplateInRecordConstruction) {
|
|||
// We create the FunctionDecl for the template in the TU DeclContext because:
|
||||
// 1. FunctionDecls can't be in a Record (only CXXMethodDecls can).
|
||||
// 2. It is mirroring the behavior of DWARFASTParserClang::ParseSubroutine.
|
||||
FunctionDecl *func =
|
||||
m_ast->CreateFunctionDeclaration(TU, "foo", clang_type, 0, false);
|
||||
FunctionDecl *func = m_ast->CreateFunctionDeclaration(
|
||||
TU, OptionalClangModuleID(), "foo", clang_type, 0, false);
|
||||
TypeSystemClang::TemplateParameterInfos empty_params;
|
||||
|
||||
// Create the actual function template.
|
||||
clang::FunctionTemplateDecl *func_template =
|
||||
m_ast->CreateFunctionTemplateDecl(record, func, "foo", empty_params);
|
||||
m_ast->CreateFunctionTemplateDecl(record, OptionalClangModuleID(), func,
|
||||
"foo", empty_params);
|
||||
|
||||
EXPECT_EQ(record, func_template->getDeclContext());
|
||||
EXPECT_EQ("foo", func_template->getName());
|
||||
|
|
|
@ -28,6 +28,7 @@ inline std::unique_ptr<TypeSystemClang> createAST() {
|
|||
|
||||
inline CompilerType createRecord(TypeSystemClang &ast, llvm::StringRef name) {
|
||||
return ast.CreateRecordType(ast.getASTContext().getTranslationUnitDecl(),
|
||||
OptionalClangModuleID(),
|
||||
lldb::AccessType::eAccessPublic, name, 0,
|
||||
lldb::LanguageType::eLanguageTypeC);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue