Previously if you had something like this:
template<typename T>
struct Foo {
template<typename U>
Foo(U);
};
Foo F(3.7);
this would mangle as ??$?0N@?$Foo@H@@QEAA@N@Z
and this would be demangled as:
undname: __cdecl Foo<int>::Foo<int><double>(double)
llvm-undname: __cdecl Foo<int>::Foo<int>(double)
Note the lack of the constructor template parameter in our
demangling.
This patch makes it so we print the constructor argument list.
llvm-svn: 340356
I found these by running llvm-undname over a couple hundred
megabytes of object files generated as part of building chromium.
The issues fixed in this patch are:
1) decltype-auto return types.
2) Indirect vtables (e.g. const A::`vftable'{for `B'})
3) Pointers, references, and rvalue-references to member pointers.
I have exactly one remaining symbol out of a few hundred MB of object
files that produces a name we can't demangle, and it's related to
back-referencing.
llvm-svn: 340341
This is encoded as __E and should print something like
"dynamic initializer for 'Foo'(void)"
This also adds support for dynamic atexit destructor, which is
basically identical but encoded as __F with slightly different
description.
llvm-svn: 340239
Summary:
This transforms the Itanium demangler into a generic reusable library that can
be used to build, traverse, and transform Itanium mangled name trees.
This is in preparation for adding a canonicalizing demangler, which
cannot live in the Demangle library for layering reasons. In order to
keep the diffs simpler, this patch moves more code to the new header
than is strictly necessary: in particular, all of the printLeft /
printRight implementations can be moved to the implementation file.
(And indeed we could make them non-virtual now if we wished, and remove
the vptr from Node.)
All nodes are now included in the Kind enumeration, rather than omitting
some of the Expr nodes, and the three different floating-point literal
node types now have distinct Kind values.
As a proof of concept for the visitation / matching mechanism, this
patch implements a Node dumping facility on top of it, replacing the
prior mechanism that produced the pretty-printed output rather than a
tree dump. Sample dump output:
FunctionEncoding(
NameType("int"),
NameWithTemplateArgs(
NestedName(
NameWithTemplateArgs(
NameType("A"),
TemplateArgs(
{NameType("B")})),
NameType("f")),
TemplateArgs(
{NameType("int")})),
{},
<null>,
QualConst, FunctionRefQual::FrefQualLValue)
As a next step, it would make sense to move the LLVM high-level interface to
the demangler (the itaniumDemangler function and ItaniumPartialDemangler class)
into the Support library, and implement them in terms of the Demangle library.
This would allow the libc++abi demangler implementation to be an identical copy
of the llvm Demangle library, and would allow the LLVM implementation to reuse
LLVM components such as llvm::BumpPtrAllocator, but we'll need to decide how to
coordinate that with the MS ABI demangler, so I'm not doing that in this patch.
No functionality change intended other than the behavior of dump().
Reviewers: erik.pilkington, zturner, chandlerc, dlj
Subscribers: aheejin, llvm-commits
Differential Revision: https://reviews.llvm.org/D50930
llvm-svn: 340203
A while back I submitted a patch to resolve backreferences
lazily, thinking this that it was not always possible to know
in advance what type you were looking at until you had completed
a full pass over the input, and therefore it would be impossible
to resolve backreferences eagerly.
This was mistaken though, and turned out to be an unrelated
problem. In fact, the reverse is true. You *must* resolve
backreferences eagerly. This is because certain types of nested
mangled symbols do not share a backreference context with their
parent symbol, and as such, if you try to resolve them lazily
their backreference context will have been lost by the time you
finish demangling the entire input. On the other hand, resolving
them eagerly appears to always work, and enables us to port
many more tests over.
llvm-svn: 340126
We were only printing the vtordisp thunk before as the previous
patch was more aimed at getting special operators working, one
of which was a thunk. This patch gets all thunk types to print
properly, and adds a test for each one.
llvm-svn: 340088
Previously, some of the code for actually parsing mangled
operator names was more like formatting code in nature,
and was interspersed with the demangling code which builds
the AST. This means that by the time we got to the printing
code, we had lost all information about what type of operator
we had, and all we were left with was a string that we just
had to print. However, not all operators are actually even
operators. it's basically just a catch-all mangling for
"special names", and for some of the other types it helps
to know when we're actually doing the printing what it is.
This patch changes the way things work by introducing an
OperatorInfo structure and corresponding enumeration. When
we demangle we store the enumeration value and demangled
components separately. This gives more flexibility during
printing.
In doing so, some demanglings of special names which we didn't
previously support come out of this for free, so we now demangle
those.
A few are more complex and are better left for a followup patch
though.
An exhaustive test of every possible operator code is included,
with the ones that don't yet work commented out.
llvm-svn: 340046
When demangling string literals, Microsoft's undname
simply prints 'string'. This patch implements string
literal demangling while doing a bit better than this
by decoding as much of the string as possible and
trying to faithfully reproduce the original string
literal definition.
This is a bit tricky because the different character
types char, char16_t, and char32_t are not uniquely
identified by the mangling, so we have to use a
heuristic to try to guess the character type. But
it works pretty well, and many tests are added to
illustrate the behavior.
Differential Revision: https://reviews.llvm.org/D50806
llvm-svn: 339892
When we have an MD5 mangled name, we shouldn't choke and say
that it's an invalid name. Even though it's impossible to demangle,
we should just output the original name.
llvm-svn: 339891
1) We print __restrict twice on member pointers. This is fixed
and relevant tests are re-enabled.
2) Several tests were disabled because of printing slightly
different output than undname. These were confirmed to be
bugs in undname, so we just re-enable the tests.
3) The test for printing reference temporaries is re-enabled. This
is a clang mangling extension, so we have some flexibility with
how we demangle it. The output currently looks fine, so we just
re-enable the test with no fixes.
llvm-svn: 339708
This function calls a callback whenever a <type> is parsed.
This is necessary to implement FindAlternateFunctionManglings in LLDB, which
uses a similar hack in FastDemangle. Once that function has been updated to use
this version, FastDemangle can finally be removed.
Differential revision: https://reviews.llvm.org/D50586
llvm-svn: 339580
There are two cases we need to support with extern "C"
functions. The first is the case of a '9' indicating that
the function has no prototype. This occurs when we mangle
a symbol inside of an extern "C" function, but not the
function itself.
The second case is when we have an overloaded extern "C"
functions. In this case we emit $$J0 to indicate this.
This patch adds support for both of these cases.
llvm-svn: 339471
Before we wouldn't properly demangle something like
Foo<const int>. Template args have a special escape sequence
'$$C' that is optional, but if it is present contains
qualifiers. So we need to check for this and only if it
present, demangle qualifiers before demangling the type.
With this fix, we re-enable some tests that were previously
marked FIXME.
llvm-svn: 339465
These were uncovered when porting the mangling tests in
ms-templates.cpp from clang/CodeGenCXX over to demangling
tests. The main issues fixed here are surrounding integer
literal signed and unsignedness, empty array dimensions,
and pointer and reference non-type template parameters.
Differential Revision: https://reviews.llvm.org/D50512
llvm-svn: 339434
Template manglings use a fresh back-referencing context, so we
need to do the same. This fixes several existing tests which are
marked as FIXME, so those are now actually run.
llvm-svn: 339275
Function template names are not stored in the backref table,
but non-template function names are. The general pattern seems
to be that when you are demangling a symbol name, if the name
starts with '?' it does not go into the backreference table,
otherwise it does. Note that this even handles the general case
of operator names (template or otherwise) not going into the
back-reference table, anonymous namespaces not going into the
backreference table, etc.
It's important that we apply this check *only* for the
unqualified portion of a name, and only for symbol names.
For example, this does not apply to type names (such as class
templates) and we need to make sure that these still do go
into the backref table.
Differential Revision: https://reviews.llvm.org/D50394
llvm-svn: 339211
We need to both record and resolve back-references lazily due to
not being able to know until a demangling is complete whether or
not a name should go into the back-reference table.. This patch
implements lazy resolution of back-references, but we still have
eager recording of back-references. This will be fixed in a
subsequent patch.
llvm-svn: 338736
It seems like perhaps because cstdio isn't directly included, the
compiler is accidentally picking up wprintf from somewhere else
and trying to call that. Hopefully this fixes it.
llvm-svn: 338614
This is useful for understanding how our demangler processes
back references and for investigating issues related to
back references. But it's a feature only useful for debugging
the demangling process itself, so I'm marking it hidden.
llvm-svn: 338609
After we detected the presence of a template via ?$ we would proceed by
only demangling a simple unqualified name. This means we would fail on
templated operators (and perhaps other yet-to-be-determined things)
This was discovered while doing some refactoring to store richer
semantic information about the demangled types to pave the way for
overhauling the way we handle backreferences. (Specifically, we need to
defer recording or resolving back-references until a symbol has been
completely demangled, because we need to use information that only
occurs later in the mangled string to decide whether a back-reference
should be recorded.)
Differential Revision: https://reviews.llvm.org/D50145
llvm-svn: 338608
This patch fixes demangling of template aliases as template-template
arguments, and also fixes function pointers and references as
not type template parameters. All of these can be properly
demangled now, so I've ported over the test
clang/test/CodeGenCXX/ms-template-callbacks.cpp. All of these
tests pass
llvm-svn: 338340
This patch adds support for demangling r-value references, new
operators such as the ""_foo operator, lambdas, alias types,
nullptr_t, and various other C++11'isms.
There is 1 failing test remaining in this file, which appears to
be related to back-referencing. This type of problem has the
potential to get ugly so I'd rather fix it in a separate patch.
Differential Revision: https://reviews.llvm.org/D50013
llvm-svn: 338324
There are a couple of issues you run into when you start getting into
more complex names, especially with regards to function local statics.
When you've got something like:
int x() {
static int n = 0;
return n;
}
Then this needs to demangle to something like
int `int __cdecl x()'::`1'::n
The nested mangled symbols (e.g. `int __cdecl x()` in the above
example) also share state with regards to back-referencing, so
we need to be able to re-use the demangler in the middle of
demangling a symbol while sharing back-ref state.
To make matters more complicated, there are a lot of ambiguities
when demangling a symbol's qualified name, because a function local
scope pattern (usually something like `?1??name?`) looks suspiciously
like many other possible things that can occur, such as `?1` meaning
the second back-ref and disambiguating these cases is rather
interesting. The `?1?` in a local scope pattern is actually a special
case of the more general pattern of `? + <encoded number> + ?`, where
"encoded number" can itself have embedded `@` symbols, which is a
common delimeter in mangled names. So we have to take care during the
disambiguation, which is the reason for the overly complicated
`isLocalScopePattern` function in this patch.
I've added some pretty obnoxious tests to exercise all of this, which
exposed several other problems related to back-referencing, so those
are fixed here as well. Finally, I've uncommented some tests that were
previously marked as `FIXME`, since now these work.
Differential Revision: https://reviews.llvm.org/D49965
llvm-svn: 338226
We need to be able to initiate a nested demangling from inside
of an "outer" demangling. These need to be able to share some
state, such as back-references. As a result, we can't store
things like the output stream or the mangled name in the Demangler
class, since each demangling will have different values. So
remove this state and pass it through the necessary methods.
llvm-svn: 338219
There are some very subtle differences between how one should
parse symbol names and type names. They differ with respect
to back-referencing, the set of legal values that can appear
as the unqualified portion, and various other aspects.
By separating the parsing code into separate paths, we can
remove a lot of ambiguity during the demangling process, which
is necessary for demangling more complicated things like
function local statics, nested classes, and lambdas.
llvm-svn: 338207
Stack overflow on invalid. While collapsing references, we were skipping over a
cycle check in ForwardTemplateReference leading to a stack overflow. This commit
fixes the problem by duplicating the cycle check in ReferenceType.
llvm-svn: 338190
Properly demangle function parameter back-references.
Previously we treated lists of function parameters and template
parameters the same. There are some important differences with regards
to back-references, and some less important differences regarding which
characters can appear before or after the name.
The important differences are that with a given type T, all instances of
a function parameter list share the same global back-ref table.
Specifically, if X and Y are function pointers, then there are 3
entities in the declaration X func(Y) which all affect and are affected
by the master parameter back-ref table:
1) The parameter list of X's function type
2) the parameter list of func itself
3) The parameter list of Y's function type.
The previous code would create a back-reference table that was local to
a single parameter list, so it would not be shared across parameter
lists.
This was discovered when porting ms-back-references.test from clang's
mangling tests. All of these tests should now pass with the new changes.
In doing so, I split the function for parsing template and function
parameters into two separate functions. This makes the template
parameter list parsing code in particular very small and easy to
understand now.
Differential Revision: https://reviews.llvm.org/D49875
llvm-svn: 338075
For function pointers, we would print something like
int __cdecl (*)(int)
We need to move the calling convention inside, and print
int (__cdecl *)(int)
This patch implements this change for regular function pointers as
well as member function pointers.
llvm-svn: 338068
This converts the arg qualifier mangling tests from
clang/CodeGenCXX/mangle-ms-arg-qualifiers.cpp to demangling tests.
Most tests already pass, so this patch doesn't come with any
functional change, just the addition of new tests. The few tests
that don't pass are left in with a FIXME label so that they don't
run but serve as documentation about what still doesn't work.
llvm-svn: 338067
After this patch, we can now properly demangle pointers to member
functions. The calling convention is located in the wrong place,
but this will be fixed in a followup since it also affects non
member function pointers.
Differential Revision: https://reviews.llvm.org/D49639
llvm-svn: 338065