================
@@ -2482,6 +2485,134 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE
&orig_die,
return false;
}
+static int ClangToItaniumCtorKind(clang::CXXCtorType kind) {
+ switch (kind) {
+ case clang::CXXCtorType::Ctor_Complete:
+ return 1;
+ case clang::CXXCtorType::Ctor_Base:
+ return 2;
+ case clang::CXXCtorType::Ctor_CopyingClosure:
+ case clang::CXXCtorType::Ctor_DefaultClosure:
+ case clang::CXXCtorType::Ctor_Comdat:
+ llvm_unreachable("Unexpected constructor kind.");
+ }
+}
+
+static int ClangToItaniumDtorKind(clang::CXXDtorType kind) {
+ switch (kind) {
+ case clang::CXXDtorType::Dtor_Deleting:
+ return 0;
+ case clang::CXXDtorType::Dtor_Complete:
+ return 1;
+ case clang::CXXDtorType::Dtor_Base:
+ return 2;
+ case clang::CXXDtorType::Dtor_Comdat:
+ llvm_unreachable("Unexpected destructor kind.");
+ }
+}
+
+static std::optional<int>
+GetItaniumCtorDtorVariant(llvm::StringRef discriminator) {
+ const bool is_ctor = discriminator.consume_front("C");
+ if (!is_ctor && !discriminator.consume_front("D"))
+ return std::nullopt;
+
+ uint64_t structor_kind;
+ if (!llvm::to_integer(discriminator, structor_kind))
+ return std::nullopt;
+
+ if (is_ctor) {
+ if (structor_kind > clang::CXXCtorType::Ctor_DefaultClosure)
+ return std::nullopt;
+
+ return ClangToItaniumCtorKind(
+ static_cast<clang::CXXCtorType>(structor_kind));
+ }
+
+ if (structor_kind > clang::CXXDtorType::Dtor_Comdat)
+ return std::nullopt;
+
+ return
ClangToItaniumDtorKind(static_cast<clang::CXXDtorType>(structor_kind));
+}
+
+DWARFDIE SymbolFileDWARF::FindFunctionDefinition(const FunctionCallLabel
&label,
+ const DWARFDIE &declaration) {
+ DWARFDIE definition;
+ llvm::DenseMap<int, DWARFDIE> structor_variant_to_die;
+
+ // eFunctionNameTypeFull for mangled name lookup.
+ // eFunctionNameTypeMethod is required for structor lookups (since we look
+ // those up by DW_AT_name).
+ Module::LookupInfo info(ConstString(label.lookup_name),
+ lldb::eFunctionNameTypeFull |
+ lldb::eFunctionNameTypeMethod,
+ lldb::eLanguageTypeUnknown);
+
+ m_index->GetFunctions(info, *this, {}, [&](DWARFDIE entry) {
+ if (entry.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_declaration, 0))
+ return IterationAction::Continue;
+
+ auto spec = entry.GetAttributeValueAsReferenceDIE(DW_AT_specification);
+ if (!spec)
+ return IterationAction::Continue;
+
+ if (spec != declaration)
----------------
labath wrote:
Okay, I guess this is why. I don't think this will work, for the reasons
outlined in the other comment. This needs to be a structural match between the
two DIEs, maybe facilitated by
`DWARFASTParserClang::CopyUniqueClassMethodTypes`.
I admit this is more complicated that I originally expected. I didn't realise
just how load-bearing the mangling is for constructors. As clang does not emit
DW_AT_linkage_name for constructors (for better or worse, gcc does, using the
funny `C4` variant), the way we were looking up the right constructor versions
was by making sure the mangler roundtrips the exact same mangled name.
I still think this is better than relying on the mangling roundtrip, though it
brings up an interesting point. Given then ABI tags are meant to allow
different versions of the same class to coexist, then *if* you want to support
these different versions coexisting, then the DWARF sort of has to contain the
ABI tag information as it relies on structural matches to connect DIEs from
different compilation units. Maybe this is irrelevant as you don't want to
support this "coexistence" (I believe you just want to "deal with" the presence
of ABI tags), but I think this might make a reasonable case for encoding the
ABI tag information (in one way or another) in DWARF.
https://github.com/llvm/llvm-project/pull/149827
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits