Skip to content

Conversation

@Nerixyz
Copy link
Contributor

@Nerixyz Nerixyz commented Aug 27, 2025

When there's a deep inheritance hierarchy of multiple C++ classes (see below), then the mangled name of a VFTable can include multiple key nodes in the target name.
For example, in the following code, MSVC will generate mangled names for the VFTables that have up to three key classes in the context.

Code
class Base1 {
  virtual void a() {};
};
class Base2 {
  virtual void b() {}
};

class Ind1 : public Base1 {};
class Ind2 : public Base1 {};

class A : public Ind1, public Ind2 {};

class Ind3 : public A {};
class Ind4 : public A {};

class B : public Ind3, public Ind4 {};

class Ind5 : public B {};
class Ind6 : public B {};

class C : public Ind5, public Ind6 {};

int main() { auto i = new C; }

This will include ??_7C@@6BInd1@@Ind4@@Ind5@@@ (and every other combination). Microsoft's undname will demangle this to "const C::`vftable'{for `Ind1's `Ind4's `Ind5'}". Previously, LLVM would demangle this to "const C::`vftable'{for `Ind1'}".

With this PR, the output of LLVM's undname will be identical to Microsoft's version. This changes SpecialTableSymbolNode::TargetName to a node array which contains each key from the name. Unlike namespaces, these keys are not in reverse order - they are in the same order as in the mangled name.

@Nerixyz Nerixyz requested a review from zmodem September 18, 2025 09:58
@Nerixyz
Copy link
Contributor Author

Nerixyz commented Nov 4, 2025

Ping

Copy link
Collaborator

@zmodem zmodem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I must have missed this before. Thanks for fixing this.

if (!consumeFront(MangledName, '@'))
STSN->TargetName = demangleFullyQualifiedTypeName(MangledName);

NodeList *TargetCurrent = nullptr;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of building a linked list here, could we just put these into a SmallVector and create the NodeArray from that directly?

Copy link
Collaborator

@zmodem zmodem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I think that's much easier to read.

Copy link
Collaborator

@zmodem zmodem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@Nerixyz Nerixyz merged commit 3641e26 into llvm:main Nov 5, 2025
10 checks passed
#include "llvm/Demangle/MicrosoftDemangle.h"

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot build LLVM with gcc+gnu ld after this patch. It introduces cyclic dependencies (LLVMSupport <-> LLVMDemangle).

FAILED: lib/libLLVMDemangle.so.22.0git 
: && /usr/bin/c++ -fPIC -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-uninitialized -Wno-nonnull -Wno-class-memaccess -Wno-dangling-reference -Wno-redundant-move -Wno-pessimizing-move -Wno-array-bounds -Wno-stringop-overread -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O2 -g -DNDEBUG  -Wl,-z,defs -Wl,-z,nodelete   -Wl,-rpath-link,/data/zyw/dev/llvm-build/./lib  -Wl,--gc-sections -shared -Wl,-soname,libLLVMDemangle.so.22.0git -o lib/libLLVMDemangle.so.22.0git lib/Demangle/CMakeFiles/LLVMDemangle.dir/Demangle.cpp.o lib/Demangle/CMakeFiles/LLVMDemangle.dir/ItaniumDemangle.cpp.o lib/Demangle/CMakeFiles/LLVMDemangle.dir/MicrosoftDemangle.cpp.o lib/Demangle/CMakeFiles/LLVMDemangle.dir/MicrosoftDemangleNodes.cpp.o lib/Demangle/CMakeFiles/LLVMDemangle.dir/RustDemangle.cpp.o lib/Demangle/CMakeFiles/LLVMDemangle.dir/DLangDemangle.cpp.o  -Wl,-rpath,"\$ORIGIN/../lib:" && :
/usr/bin/ld: lib/Demangle/CMakeFiles/LLVMDemangle.dir/MicrosoftDemangle.cpp.o: in function `llvm::SmallVectorTemplateCommon<llvm::ms_demangle::Node*, void>::grow_pod(unsigned long, unsigned long)':
/data/zyw/dev/llvm-project/llvm/include/llvm/ADT/SmallVector.h:140:(.text._ZN4llvm11ms_demangle9Demangler30demangleSpecialTableSymbolNodeERSt17basic_string_viewIcSt11char_traitsIcEENS0_20SpecialIntrinsicKindE+0x28c): undefined reference to `llvm::SmallVectorBase<unsigned int>::grow_pod(void*, unsigned long, unsigned long)'
collect2: error: ld returned 1 exit status

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, opened #166586 to fix this.

@jplehr
Copy link
Contributor

jplehr commented Nov 5, 2025

I believe this one broke a few of our buildbots, e.g., https://lab.llvm.org/buildbot/#/builders/203/builds/28219

From the log

[694/8173] Linking CXX shared library lib/libLLVMDemangle.so.22.0git
FAILED: lib/libLLVMDemangle.so.22.0git 
: && /usr/bin/c++ -fPIC -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-uninitialized -Wno-nonnull -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-array-bounds -Wno-stringop-overread -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG  -Wl,-z,defs -Wl,-z,nodelete   -Wl,-rpath-link,/home/botworker/bbot/amdgpu-offload-ubuntu-22-cmake-build-only/build/./lib  -Wl,--gc-sections -shared -Wl,-soname,libLLVMDemangle.so.22.0git -o lib/libLLVMDemangle.so.22.0git lib/Demangle/CMakeFiles/LLVMDemangle.dir/Demangle.cpp.o lib/Demangle/CMakeFiles/LLVMDemangle.dir/ItaniumDemangle.cpp.o lib/Demangle/CMakeFiles/LLVMDemangle.dir/MicrosoftDemangle.cpp.o lib/Demangle/CMakeFiles/LLVMDemangle.dir/MicrosoftDemangleNodes.cpp.o lib/Demangle/CMakeFiles/LLVMDemangle.dir/RustDemangle.cpp.o lib/Demangle/CMakeFiles/LLVMDemangle.dir/DLangDemangle.cpp.o  -Wl,-rpath,"\$ORIGIN/../lib:" && :
/usr/bin/ld: lib/Demangle/CMakeFiles/LLVMDemangle.dir/MicrosoftDemangle.cpp.o: in function `llvm::ms_demangle::Demangler::demangleSpecialTableSymbolNode(std::basic_string_view<char, std::char_traits<char> >&, llvm::ms_demangle::SpecialIntrinsicKind) [clone .localalias]':
MicrosoftDemangle.cpp:(.text._ZN4llvm11ms_demangle9Demangler30demangleSpecialTableSymbolNodeERSt17basic_string_viewIcSt11char_traitsIcEENS0_20SpecialIntrinsicKindE+0x36c): undefined reference to `llvm::SmallVectorBase<unsigned int>::grow_pod(void*, unsigned long, unsigned long)'
collect2: error: ld returned 1 exit status

Nerixyz added a commit that referenced this pull request Nov 5, 2025
Using `SmallVector` would introduce a dependency cycle (see
#155630 (comment)),
so this uses a NodeList.
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Nov 5, 2025
…s (#166586)

Using `SmallVector` would introduce a dependency cycle (see
llvm/llvm-project#155630 (comment)),
so this uses a NodeList.
@Nerixyz Nerixyz deleted the fix/llvm-ms-demangle-nested-vtable branch November 7, 2025 14:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants