Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1991,7 +1991,7 @@ void ClangExpressionDeclMap::AddContextClassType(NameSearchContext &context,
const bool is_artificial = false;

CXXMethodDecl *method_decl = m_clang_ast_context->AddMethodToCXXRecordType(
copied_clang_type.GetOpaqueQualType(), "$__lldb_expr", nullptr,
copied_clang_type.GetOpaqueQualType(), "$__lldb_expr", /*asm_label=*/{},
method_type, lldb::eAccessPublic, is_virtual, is_static, is_inline,
is_explicit, is_attr_used, is_artificial);

Expand Down
28 changes: 11 additions & 17 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,14 @@ static unsigned GetCXXMethodCVQuals(const DWARFDIE &subprogram,
return cv_quals;
}

static std::string MakeLLDBFuncAsmLabel(const DWARFDIE &die) {
char const *name = die.GetMangledName(/*substitute_name_allowed*/ false);
if (!name)
return {};

return name;
}

TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
const DWARFDIE &die,
Log *log) {
Expand Down Expand Up @@ -1231,7 +1239,7 @@ std::pair<bool, TypeSP> DWARFASTParserClang::ParseCXXMethod(

clang::CXXMethodDecl *cxx_method_decl = m_ast.AddMethodToCXXRecordType(
class_opaque_type.GetOpaqueQualType(), attrs.name.GetCString(),
attrs.mangled_name, clang_type, accessibility, attrs.is_virtual,
MakeLLDBFuncAsmLabel(die), clang_type, accessibility, attrs.is_virtual,
is_static, attrs.is_inline, attrs.is_explicit, is_attr_used,
attrs.is_artificial);

Expand Down Expand Up @@ -1384,7 +1392,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
ignore_containing_context ? m_ast.GetTranslationUnitDecl()
: containing_decl_ctx,
GetOwningClangModule(die), name, clang_type, attrs.storage,
attrs.is_inline);
attrs.is_inline, MakeLLDBFuncAsmLabel(die));
std::free(name_buf);

if (has_template_params) {
Expand All @@ -1394,7 +1402,7 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
ignore_containing_context ? m_ast.GetTranslationUnitDecl()
: containing_decl_ctx,
GetOwningClangModule(die), attrs.name.GetStringRef(), clang_type,
attrs.storage, attrs.is_inline);
attrs.storage, attrs.is_inline, /*asm_label=*/{});
clang::FunctionTemplateDecl *func_template_decl =
m_ast.CreateFunctionTemplateDecl(
containing_decl_ctx, GetOwningClangModule(die),
Expand All @@ -1406,20 +1414,6 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
lldbassert(function_decl);

if (function_decl) {
// Attach an asm(<mangled_name>) label to the FunctionDecl.
// This ensures that clang::CodeGen emits function calls
// using symbols that are mangled according to the DW_AT_linkage_name.
// If we didn't do this, the external symbols wouldn't exactly
// match the mangled name LLDB knows about and the IRExecutionUnit
// would have to fall back to searching object files for
// approximately matching function names. The motivating
// example is generating calls to ABI-tagged template functions.
// This is done separately for member functions in
// AddMethodToCXXRecordType.
if (attrs.mangled_name)
function_decl->addAttr(clang::AsmLabelAttr::CreateImplicit(
m_ast.getASTContext(), attrs.mangled_name, /*literal=*/false));

LinkDeclContextToDIE(function_decl, die);

const clang::FunctionProtoType *function_prototype(
Expand Down
6 changes: 3 additions & 3 deletions lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ struct CreateMethodDecl : public TypeVisitorCallbacks {
MethodOptions::CompilerGenerated;
function_decl = m_clang.AddMethodToCXXRecordType(
parent_ty, proc_name,
/*mangled_name=*/nullptr, func_ct, /*access=*/access_type,
/*asm_label=*/{}, func_ct, /*access=*/access_type,
/*is_virtual=*/is_virtual, /*is_static=*/is_static,
/*is_inline=*/false, /*is_explicit=*/false,
/*is_attr_used=*/false, /*is_artificial=*/is_artificial);
Expand Down Expand Up @@ -903,7 +903,7 @@ PdbAstBuilder::CreateFunctionDecl(PdbCompilandSymId func_id,
if (!function_decl) {
function_decl = m_clang.AddMethodToCXXRecordType(
parent_opaque_ty, func_name,
/*mangled_name=*/nullptr, func_ct,
/*asm_label=*/{}, func_ct,
/*access=*/lldb::AccessType::eAccessPublic,
/*is_virtual=*/false, /*is_static=*/false,
/*is_inline=*/false, /*is_explicit=*/false,
Expand All @@ -913,7 +913,7 @@ PdbAstBuilder::CreateFunctionDecl(PdbCompilandSymId func_id,
} else {
function_decl = m_clang.CreateFunctionDeclaration(
parent, OptionalClangModuleID(), func_name, func_ct, func_storage,
is_inline);
is_inline, /*asm_label=*/{});
CreateFunctionParameters(func_id, *function_decl, param_count);
}
return function_decl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,8 @@ void UdtRecordCompleter::AddMethod(llvm::StringRef name, TypeIndex type_idx,
bool is_artificial = (options & MethodOptions::CompilerGenerated) ==
MethodOptions::CompilerGenerated;
m_ast_builder.clang().AddMethodToCXXRecordType(
derived_opaque_ty, name.data(), nullptr, method_ct,
access_type, attrs.isVirtual(), attrs.isStatic(), false, false, false,
is_artificial);
derived_opaque_ty, name.data(), /*asm_label=*/{}, method_ct, access_type,
attrs.isVirtual(), attrs.isStatic(), false, false, false, is_artificial);

m_cxx_record_map[derived_opaque_ty].insert({name, method_ct});
}
Expand Down
5 changes: 3 additions & 2 deletions lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -954,7 +954,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {

auto decl = m_ast.CreateFunctionDeclaration(
decl_context, OptionalClangModuleID(), name,
type->GetForwardCompilerType(), storage, func->hasInlineAttribute());
type->GetForwardCompilerType(), storage, func->hasInlineAttribute(),
/*asm_label=*/{});

std::vector<clang::ParmVarDecl *> params;
if (std::unique_ptr<PDBSymbolTypeFunctionSig> sig = func->getSignature()) {
Expand Down Expand Up @@ -1446,7 +1447,7 @@ PDBASTParser::AddRecordMethod(lldb_private::SymbolFile &symbol_file,
// TODO: get mangled name for the method.
return m_ast.AddMethodToCXXRecordType(
record_type.GetOpaqueQualType(), name.c_str(),
/*mangled_name*/ nullptr, method_comp_type, access, method.isVirtual(),
/*asm_label=*/{}, method_comp_type, access, method.isVirtual(),
method.isStatic(), method.hasInlineAttribute(),
/*is_explicit*/ false, // FIXME: Need this field in CodeView.
/*is_attr_used*/ false,
Expand Down
24 changes: 19 additions & 5 deletions lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2137,7 +2137,7 @@ std::string TypeSystemClang::GetTypeNameForDecl(const NamedDecl *named_decl,
FunctionDecl *TypeSystemClang::CreateFunctionDeclaration(
clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
llvm::StringRef name, const CompilerType &function_clang_type,
clang::StorageClass storage, bool is_inline) {
clang::StorageClass storage, bool is_inline, llvm::StringRef asm_label) {
FunctionDecl *func_decl = nullptr;
ASTContext &ast = getASTContext();
if (!decl_ctx)
Expand All @@ -2158,6 +2158,21 @@ FunctionDecl *TypeSystemClang::CreateFunctionDeclaration(
func_decl->setConstexprKind(isConstexprSpecified
? ConstexprSpecKind::Constexpr
: ConstexprSpecKind::Unspecified);

// Attach an asm(<mangled_name>) label to the FunctionDecl.
// This ensures that clang::CodeGen emits function calls
// using symbols that are mangled according to the DW_AT_linkage_name.
// If we didn't do this, the external symbols wouldn't exactly
// match the mangled name LLDB knows about and the IRExecutionUnit
// would have to fall back to searching object files for
// approximately matching function names. The motivating
// example is generating calls to ABI-tagged template functions.
// This is done separately for member functions in
// AddMethodToCXXRecordType.
if (!asm_label.empty())
func_decl->addAttr(clang::AsmLabelAttr::CreateImplicit(ast, asm_label,
/*literal=*/true));

SetOwningModule(func_decl, owning_module);
decl_ctx->addDecl(func_decl);

Expand Down Expand Up @@ -7651,7 +7666,7 @@ TypeSystemClang::CreateParameterDeclarations(

clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType(
lldb::opaque_compiler_type_t type, llvm::StringRef name,
const char *mangled_name, const CompilerType &method_clang_type,
llvm::StringRef asm_label, const CompilerType &method_clang_type,
lldb::AccessType access, bool is_virtual, bool is_static, bool is_inline,
bool is_explicit, bool is_attr_used, bool is_artificial) {
if (!type || !method_clang_type.IsValid() || name.empty())
Expand Down Expand Up @@ -7784,10 +7799,9 @@ clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType(
if (is_attr_used)
cxx_method_decl->addAttr(clang::UsedAttr::CreateImplicit(getASTContext()));

if (mangled_name != nullptr) {
if (!asm_label.empty())
cxx_method_decl->addAttr(clang::AsmLabelAttr::CreateImplicit(
getASTContext(), mangled_name, /*literal=*/false));
}
getASTContext(), asm_label, /*literal=*/true));

// Parameters on member function declarations in DWARF generally don't
// have names, so we omit them when creating the ParmVarDecls.
Expand Down
4 changes: 2 additions & 2 deletions lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ class TypeSystemClang : public TypeSystem {
clang::FunctionDecl *CreateFunctionDeclaration(
clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
llvm::StringRef name, const CompilerType &function_Type,
clang::StorageClass storage, bool is_inline);
clang::StorageClass storage, bool is_inline, llvm::StringRef asm_label);

CompilerType
CreateFunctionType(const CompilerType &result_type,
Expand Down Expand Up @@ -1001,7 +1001,7 @@ class TypeSystemClang : public TypeSystem {

clang::CXXMethodDecl *AddMethodToCXXRecordType(
lldb::opaque_compiler_type_t type, llvm::StringRef name,
const char *mangled_name, const CompilerType &method_type,
llvm::StringRef asm_label, const CompilerType &method_type,
lldb::AccessType access, bool is_virtual, bool is_static, bool is_inline,
bool is_explicit, bool is_attr_used, bool is_artificial);

Expand Down
12 changes: 6 additions & 6 deletions lldb/unittests/Symbol/TestTypeSystemClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,7 @@ TEST_F(TestTypeSystemClang, TestFunctionTemplateConstruction) {
CompilerType clang_type = m_ast->CreateFunctionType(int_type, {}, false, 0U);
FunctionDecl *func = m_ast->CreateFunctionDeclaration(
TU, OptionalClangModuleID(), "foo", clang_type, StorageClass::SC_None,
false);
false, /*asm_label=*/{});
TypeSystemClang::TemplateParameterInfos empty_params;

// Create the actual function template.
Expand Down Expand Up @@ -900,7 +900,7 @@ TEST_F(TestTypeSystemClang, TestFunctionTemplateInRecordConstruction) {
// 2. It is mirroring the behavior of DWARFASTParserClang::ParseSubroutine.
FunctionDecl *func = m_ast->CreateFunctionDeclaration(
TU, OptionalClangModuleID(), "foo", clang_type, StorageClass::SC_None,
false);
false, /*asm_label=*/{});
TypeSystemClang::TemplateParameterInfos empty_params;

// Create the actual function template.
Expand Down Expand Up @@ -938,7 +938,7 @@ TEST_F(TestTypeSystemClang, TestDeletingImplicitCopyCstrDueToMoveCStr) {
bool is_attr_used = false;
bool is_artificial = false;
m_ast->AddMethodToCXXRecordType(
t.GetOpaqueQualType(), class_name, nullptr, function_type,
t.GetOpaqueQualType(), class_name, /*asm_label=*/{}, function_type,
lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,
is_explicit, is_attr_used, is_artificial);

Expand Down Expand Up @@ -975,7 +975,7 @@ TEST_F(TestTypeSystemClang, TestNotDeletingUserCopyCstrDueToMoveCStr) {
CompilerType function_type = m_ast->CreateFunctionType(
return_type, args, /*variadic=*/false, /*quals*/ 0U);
m_ast->AddMethodToCXXRecordType(
t.GetOpaqueQualType(), class_name, nullptr, function_type,
t.GetOpaqueQualType(), class_name, /*asm_label=*/{}, function_type,
lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,
is_explicit, is_attr_used, is_artificial);
}
Expand All @@ -987,7 +987,7 @@ TEST_F(TestTypeSystemClang, TestNotDeletingUserCopyCstrDueToMoveCStr) {
m_ast->CreateFunctionType(return_type, args,
/*variadic=*/false, /*quals*/ 0U);
m_ast->AddMethodToCXXRecordType(
t.GetOpaqueQualType(), class_name, nullptr, function_type,
t.GetOpaqueQualType(), class_name, /*asm_label=*/{}, function_type,
lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,
is_explicit, is_attr_used, is_artificial);
}
Expand Down Expand Up @@ -1098,7 +1098,7 @@ TEST_F(TestTypeSystemClang, AddMethodToCXXRecordType_ParmVarDecls) {
m_ast->CreateFunctionType(return_type, param_types,
/*variadic=*/false, /*quals*/ 0U);
m_ast->AddMethodToCXXRecordType(
t.GetOpaqueQualType(), "myFunc", nullptr, function_type,
t.GetOpaqueQualType(), "myFunc", /*asm_label=*/{}, function_type,
lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,
is_explicit, is_attr_used, is_artificial);

Expand Down
Loading