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 sets 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. rdar://problem/59634380 Differential Revision: https://reviews.llvm.org/D75488
This commit is contained in:
parent
f4754ea0ed
commit
4354dfbdf5
|
@ -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,20 @@ 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 +1027,19 @@ 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,27 @@ 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);
|
||||
|
|
|
@ -123,8 +123,9 @@ clang::QualType AppleObjCTypeEncodingParser::BuildAggregate(
|
|||
if (is_templated)
|
||||
return clang::QualType(); // This is where we bail out. Sorry!
|
||||
|
||||
CompilerType union_type(ast_ctx.CreateRecordType(
|
||||
nullptr, lldb::eAccessPublic, name, kind, lldb::eLanguageTypeC));
|
||||
CompilerType union_type(ast_ctx.CreateRecordType(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,13 @@ 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 +1599,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 +1616,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 +1630,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 +1644,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 +3088,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);
|
||||
|
||||
|
@ -3153,8 +3159,8 @@ DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die,
|
|||
Status error;
|
||||
lldb::VariableSP var_sp;
|
||||
auto valobj_sp = frame->GetValueForVariableExpressionPath(
|
||||
var_die.GetName(), eNoDynamicValues, 0, var_sp,
|
||||
error);
|
||||
var_die.GetName(), eNoDynamicValues, 0,
|
||||
var_sp, error);
|
||||
if (valobj_sp) {
|
||||
num_elements = valobj_sp->GetValueAsUnsigned(0);
|
||||
break;
|
||||
|
@ -3282,7 +3288,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 +3305,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 +3325,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 +3384,31 @@ 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,7 @@ 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 +3509,7 @@ 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, OptionalClangModuleID(), is_inline);
|
||||
Log *log =
|
||||
nullptr; // (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
|
||||
if (log) {
|
||||
|
|
|
@ -78,6 +78,8 @@ 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 +89,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 +143,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,7 @@ 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 +815,7 @@ 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 +832,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 +880,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 +1013,7 @@ 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,7 +1081,7 @@ 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,
|
||||
&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);
|
||||
|
||||
|
@ -1102,8 +1103,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,8 +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,
|
||||
builtin_type, isScoped);
|
||||
ast_enum = m_ast.CreateEnumerationType(
|
||||
name.c_str(), decl_context, OptionalClangModuleID(), decl, builtin_type, isScoped);
|
||||
|
||||
auto enum_decl = TypeSystemClang::GetAsEnumDecl(ast_enum);
|
||||
assert(enum_decl);
|
||||
|
@ -550,7 +550,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 +901,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 +927,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,7 +941,7 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
|
|||
continue;
|
||||
|
||||
clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration(
|
||||
decl, nullptr, arg_type->GetForwardCompilerType(),
|
||||
decl, OptionalClangModuleID(), nullptr, arg_type->GetForwardCompilerType(),
|
||||
clang::SC_None, true);
|
||||
if (param)
|
||||
params.push_back(param);
|
||||
|
@ -1057,7 +1057,7 @@ clang::DeclContext *PDBASTParser::GetDeclContextContainingSymbol(
|
|||
: namespace_name.data();
|
||||
clang::NamespaceDecl *namespace_decl =
|
||||
m_ast.GetUniqueNamespaceDeclaration(namespace_name_c_str,
|
||||
curr_context);
|
||||
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,7 +1216,53 @@ CompilerType TypeSystemClang::GetTypeForDecl(ObjCInterfaceDecl *decl) {
|
|||
|
||||
#pragma mark Structure, Unions, Classes
|
||||
|
||||
CompilerType TypeSystemClang::CreateRecordType(DeclContext *decl_ctx,
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -1201,7 +1277,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 +1293,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 +1405,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 +1420,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 +1447,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 +1477,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 +1495,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 +1535,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 +1559,7 @@ TypeSystemClang::CreateClassTemplateSpecializationDecl(
|
|||
ast.getTypeDeclType(class_template_specialization_decl, nullptr);
|
||||
class_template_specialization_decl->setDeclName(
|
||||
class_template_decl->getDeclName());
|
||||
SetOwningModule(class_template_specialization_decl, owning_module);
|
||||
|
||||
class_template_specialization_decl->setSpecializationKind(
|
||||
TSK_ExplicitSpecialization);
|
||||
|
@ -1595,13 +1679,14 @@ bool TypeSystemClang::RecordHasFields(const RecordDecl *record_decl) {
|
|||
#pragma mark Objective-C Classes
|
||||
|
||||
CompilerType TypeSystemClang::CreateObjCClass(llvm::StringRef name,
|
||||
DeclContext *decl_ctx,
|
||||
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 +1694,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,17 +1732,19 @@ 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) {
|
||||
IdentifierInfo &identifier_info = ast.Idents.get(name);
|
||||
DeclarationName decl_name(&identifier_info);
|
||||
clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
|
||||
clang::DeclContext::lookup_result result =
|
||||
decl_ctx->lookup(decl_name);
|
||||
for (NamedDecl *decl : result) {
|
||||
namespace_decl = dyn_cast<clang::NamespaceDecl>(decl);
|
||||
if (namespace_decl)
|
||||
|
@ -1699,17 +1787,22 @@ 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 +1826,7 @@ 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 +1836,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 +1844,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 +1863,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 +1872,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 +1984,11 @@ TypeSystemClang::GetDeclarationName(const char *name,
|
|||
}
|
||||
|
||||
FunctionDecl *TypeSystemClang::CreateFunctionDeclaration(
|
||||
DeclContext *decl_ctx, const char *name,
|
||||
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 +2005,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,7 +2054,7 @@ TypeSystemClang::CreateFunctionType(const CompilerType &result_type,
|
|||
}
|
||||
|
||||
ParmVarDecl *TypeSystemClang::CreateParameterDeclaration(
|
||||
clang::DeclContext *decl_ctx, const char *name,
|
||||
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);
|
||||
|
@ -1963,6 +2063,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 +2125,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 +2152,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 +2169,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 +4356,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 +4367,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 +4376,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 +4465,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()) {
|
||||
|
@ -6922,6 +7024,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
|
||||
|
@ -6963,6 +7066,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);
|
||||
|
@ -7024,6 +7128,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();
|
||||
|
||||
|
@ -7054,7 +7159,8 @@ 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();
|
||||
|
||||
indirect_field->setAccess(TypeSystemClang::UnifyAccessSpecifiers(
|
||||
|
@ -7120,6 +7226,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;
|
||||
|
||||
|
@ -7255,6 +7362,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);
|
||||
|
@ -7429,6 +7537,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;
|
||||
|
@ -7520,6 +7629,7 @@ bool TypeSystemClang::AddObjCClassProperty(
|
|||
getter->setDefined(isDefined);
|
||||
getter->setDeclImplementation(impControl);
|
||||
getter->setRelatedResultType(HasRelatedResultType);
|
||||
SetMemberOwningModule(getter, class_interface_decl);
|
||||
|
||||
if (getter) {
|
||||
if (metadata)
|
||||
|
@ -7561,6 +7671,7 @@ bool TypeSystemClang::AddObjCClassProperty(
|
|||
setter->setDefined(isDefined);
|
||||
setter->setDeclImplementation(impControl);
|
||||
setter->setRelatedResultType(HasRelatedResultType);
|
||||
SetMemberOwningModule(setter, class_interface_decl);
|
||||
|
||||
if (setter) {
|
||||
if (metadata)
|
||||
|
@ -7689,6 +7800,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;
|
||||
|
@ -7919,6 +8031,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;
|
||||
|
@ -8813,14 +8926,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,13 @@ 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 +347,7 @@ public:
|
|||
|
||||
clang::FunctionTemplateDecl *
|
||||
CreateFunctionTemplateDecl(clang::DeclContext *decl_ctx,
|
||||
OptionalClangModuleID owning_module,
|
||||
clang::FunctionDecl *func_decl, const char *name,
|
||||
const TemplateParameterInfos &infos);
|
||||
|
||||
|
@ -327,7 +356,7 @@ public:
|
|||
const TemplateParameterInfos &infos);
|
||||
|
||||
clang::ClassTemplateDecl *
|
||||
CreateClassTemplateDecl(clang::DeclContext *decl_ctx,
|
||||
CreateClassTemplateDecl(clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
|
||||
lldb::AccessType access_type, const char *class_name,
|
||||
int kind, const TemplateParameterInfos &infos);
|
||||
|
||||
|
@ -335,7 +364,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,7 +384,8 @@ public:
|
|||
static bool RecordHasFields(const clang::RecordDecl *record_decl);
|
||||
|
||||
CompilerType CreateObjCClass(llvm::StringRef name,
|
||||
clang::DeclContext *decl_ctx, bool isForwardDecl,
|
||||
clang::DeclContext *decl_ctx,
|
||||
OptionalClangModuleID owning_module, bool isForwardDecl,
|
||||
bool isInternal,
|
||||
ClangASTMetadata *metadata = nullptr);
|
||||
|
||||
|
@ -373,14 +403,13 @@ public:
|
|||
|
||||
clang::NamespaceDecl *
|
||||
GetUniqueNamespaceDeclaration(const char *name, clang::DeclContext *decl_ctx,
|
||||
bool is_inline = false);
|
||||
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);
|
||||
clang::FunctionDecl *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,
|
||||
|
@ -395,6 +424,7 @@ public:
|
|||
}
|
||||
|
||||
clang::ParmVarDecl *CreateParameterDeclaration(clang::DeclContext *decl_ctx,
|
||||
OptionalClangModuleID owning_module,
|
||||
const char *name,
|
||||
const CompilerType ¶m_type,
|
||||
int storage,
|
||||
|
@ -413,6 +443,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 +510,9 @@ 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 +675,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 +732,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 +992,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 +1032,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 +1056,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,30 @@
|
|||
#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>;
|
||||
}
|
|
@ -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,41 @@
|
|||
// 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<int> t2;
|
||||
// CHECK-DAG: ClassTemplateSpecializationDecl {{.*}} imported in A struct Template
|
||||
|
||||
Namespace::InNamespace<int> t3;
|
||||
// CHECK-DAG: ClassTemplateSpecializationDecl {{.*}} imported in A struct InNamespace
|
||||
|
||||
Namespace::AlsoInNamespace<int> t4;
|
||||
// CHECK-DAG: ClassTemplateSpecializationDecl {{.*}} imported in A.B 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,38 @@ 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,7 +311,7 @@ TEST_F(TestTypeSystemClang, TestIsClangType) {
|
|||
|
||||
TEST_F(TestTypeSystemClang, TestRemoveFastQualifiers) {
|
||||
CompilerType record_type = m_ast->CreateRecordType(
|
||||
nullptr, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct,
|
||||
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "FooRecord", clang::TTK_Struct,
|
||||
lldb::eLanguageTypeC_plus_plus, nullptr);
|
||||
QualType qt;
|
||||
|
||||
|
@ -357,7 +383,7 @@ 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,
|
||||
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyBase", clang::TTK_Struct,
|
||||
lldb::eLanguageTypeC_plus_plus, nullptr);
|
||||
TypeSystemClang::StartTagDeclarationDefinition(empty_base);
|
||||
TypeSystemClang::CompleteTagDeclarationDefinition(empty_base);
|
||||
|
@ -368,8 +394,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 +410,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 +433,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 +465,14 @@ 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 +481,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 +556,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 +587,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,8 +28,8 @@ inline std::unique_ptr<TypeSystemClang> createAST() {
|
|||
|
||||
inline CompilerType createRecord(TypeSystemClang &ast, llvm::StringRef name) {
|
||||
return ast.CreateRecordType(ast.getASTContext().getTranslationUnitDecl(),
|
||||
lldb::AccessType::eAccessPublic, name, 0,
|
||||
lldb::LanguageType::eLanguageTypeC);
|
||||
OptionalClangModuleID(), lldb::AccessType::eAccessPublic, name,
|
||||
0, lldb::LanguageType::eLanguageTypeC);
|
||||
}
|
||||
|
||||
/// Create a record with the given name and a field with the given type
|
||||
|
|
Loading…
Reference in New Issue