|
45 | 45 | #include "clang/AST/Type.h" |
46 | 46 | #include "llvm/ADT/StringExtras.h" |
47 | 47 | #include "llvm/Demangle/Demangle.h" |
| 48 | +#include "llvm/Support/FormatVariadic.h" |
48 | 49 |
|
49 | 50 | #include <map> |
50 | 51 | #include <memory> |
@@ -1040,6 +1041,62 @@ bool DWARFASTParserClang::ParseObjCMethod( |
1040 | 1041 | return true; |
1041 | 1042 | } |
1042 | 1043 |
|
| 1044 | +static bool IsStructorDIE(DWARFDIE const &die, DWARFDIE const &parent_die) { |
| 1045 | + llvm::StringRef name = die.GetName(); |
| 1046 | + llvm::StringRef parent_name = parent_die.GetName(); |
| 1047 | + |
| 1048 | + name.consume_front("~"); |
| 1049 | + parent_name = parent_name.substr(0, parent_name.find('<')); |
| 1050 | + |
| 1051 | + return name == parent_name; |
| 1052 | +} |
| 1053 | + |
| 1054 | +/// Given a DIE with an external definition (and thus no linkage name) |
| 1055 | +/// find the definitions by lookup into the DWARF name index. |
| 1056 | +/// We check the DW_AT_specification for each DIE in the index with |
| 1057 | +/// the same name as the specified 'die' until we find one that references |
| 1058 | +/// 'die'. Then return that linkage name. If no such DIE is found in the index, |
| 1059 | +/// returns nullptr. |
| 1060 | +static std::vector<std::string> FindStructorNames(DWARFDIE die) { |
| 1061 | + auto *dwarf = die.GetDWARF(); |
| 1062 | + assert(dwarf); |
| 1063 | + |
| 1064 | + ConstString func_name(die.GetName()); |
| 1065 | + assert(func_name); |
| 1066 | + |
| 1067 | + SymbolContextList sc_list; |
| 1068 | + Module::LookupInfo lookup_info(func_name, |
| 1069 | + FunctionNameType::eFunctionNameTypeMethod | |
| 1070 | + FunctionNameType::eFunctionNameTypeFull, |
| 1071 | + LanguageType::eLanguageTypeUnknown); |
| 1072 | + dwarf->FindFunctions(lookup_info, {}, true, sc_list); |
| 1073 | + |
| 1074 | + std::vector<std::string> structor_names; |
| 1075 | + for (auto const &sc : sc_list.SymbolContexts()) { |
| 1076 | + if (auto *func = sc.function) { |
| 1077 | + auto func_die = dwarf->GetDIE(func->GetID()); |
| 1078 | + if (!func_die.IsValid()) |
| 1079 | + continue; |
| 1080 | + |
| 1081 | + auto spec_die = |
| 1082 | + func_die.GetAttributeValueAsReferenceDIE(DW_AT_specification); |
| 1083 | + if (spec_die.IsValid() && spec_die == die) { |
| 1084 | + llvm::ItaniumPartialDemangler D; |
| 1085 | + const bool success = !D.partialDemangle(func_die.GetMangledName()); |
| 1086 | + assert(success); |
| 1087 | + const auto maybe_structor_kind = D.getCtorDtorVariant(); |
| 1088 | + assert(maybe_structor_kind); |
| 1089 | + |
| 1090 | + structor_names.push_back( |
| 1091 | + llvm::formatv("{0}:$__lldb_func_{1}:{2}", *maybe_structor_kind, |
| 1092 | + func_die.GetModule().get(), die.GetID())); |
| 1093 | + } |
| 1094 | + } |
| 1095 | + } |
| 1096 | + |
| 1097 | + return structor_names; |
| 1098 | +} |
| 1099 | + |
1043 | 1100 | std::pair<bool, TypeSP> DWARFASTParserClang::ParseCXXMethod( |
1044 | 1101 | const DWARFDIE &die, CompilerType clang_type, |
1045 | 1102 | const ParsedDWARFTypeAttributes &attrs, const DWARFDIE &decl_ctx_die, |
@@ -1140,11 +1197,15 @@ std::pair<bool, TypeSP> DWARFASTParserClang::ParseCXXMethod( |
1140 | 1197 | const auto accessibility = |
1141 | 1198 | attrs.accessibility == eAccessNone ? eAccessPublic : attrs.accessibility; |
1142 | 1199 |
|
| 1200 | + std::vector<std::string> structor_names; |
| 1201 | + if (IsStructorDIE(die, decl_ctx_die)) |
| 1202 | + structor_names = FindStructorNames(die); |
| 1203 | + |
1143 | 1204 | clang::CXXMethodDecl *cxx_method_decl = m_ast.AddMethodToCXXRecordType( |
1144 | 1205 | class_opaque_type.GetOpaqueQualType(), attrs.name.GetCString(), |
1145 | 1206 | attrs.mangled_name, clang_type, accessibility, attrs.is_virtual, |
1146 | 1207 | is_static, attrs.is_inline, attrs.is_explicit, is_attr_used, |
1147 | | - attrs.is_artificial); |
| 1208 | + attrs.is_artificial, structor_names); |
1148 | 1209 |
|
1149 | 1210 | if (cxx_method_decl) { |
1150 | 1211 | LinkDeclContextToDIE(cxx_method_decl, die); |
@@ -1330,19 +1391,10 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, |
1330 | 1391 | lldbassert(function_decl); |
1331 | 1392 |
|
1332 | 1393 | if (function_decl) { |
1333 | | - // Attach an asm(<mangled_name>) label to the FunctionDecl. |
1334 | | - // This ensures that clang::CodeGen emits function calls |
1335 | | - // using symbols that are mangled according to the DW_AT_linkage_name. |
1336 | | - // If we didn't do this, the external symbols wouldn't exactly |
1337 | | - // match the mangled name LLDB knows about and the IRExecutionUnit |
1338 | | - // would have to fall back to searching object files for |
1339 | | - // approximately matching function names. The motivating |
1340 | | - // example is generating calls to ABI-tagged template functions. |
1341 | | - // This is done separately for member functions in |
1342 | | - // AddMethodToCXXRecordType. |
1343 | | - if (attrs.mangled_name) |
1344 | | - function_decl->addAttr(clang::AsmLabelAttr::CreateImplicit( |
1345 | | - m_ast.getASTContext(), attrs.mangled_name, /*literal=*/false)); |
| 1394 | + auto ident = llvm::formatv("$__lldb_func_{0}:{1}", |
| 1395 | + die.GetModule().get(), die.GetID()); |
| 1396 | + function_decl->addAttr(clang::AsmLabelAttr::CreateImplicit( |
| 1397 | + m_ast.getASTContext(), ident.str(), /*literal=*/false)); |
1346 | 1398 |
|
1347 | 1399 | LinkDeclContextToDIE(function_decl, die); |
1348 | 1400 |
|
|
0 commit comments