1 #!/usr/bin/perl -w /* -*- indent-tabs-mode: nil -*- */
4 # This file is part of the LibreOffice project.
6 # This Source Code Form is subject to the terms of the Mozilla Public
7 # License, v. 2.0. If a copy of the MPL was not distributed with this
8 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 # Change MSVC mangled C++ names from 32-bit form to the corresponding
12 # 64-bit form. Each line of input can contain at most one mangled
15 # Based on experimentation with MSVC2008 and the following web pages:
17 # http://www.geoffchappell.com/viewer.htm?doc=studies/msvc/language/decoration/index.htm
18 # Thorough but incomplete. Still, describes details the below sources
21 # http://cvs.winehq.com/cvsweb/wine/dlls/msvcrt/undname.c
22 # Wine's __unDname function, presumably the most complete, although
23 # not really written to act as "documentation"
25 # http://mearie.org/documents/mscmangle/
26 # Relatively complete but a bit badly structured and terse.
28 # http://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B_Name_Mangling
29 # seems to be mostly a ripoff on the mearie.org page
31 # Example transformation:
32 # ??0ORealDynamicLoader@salhelper@@IAE@PAPAV01@ABVOUString@rtl@@1PAX2@Z =>
33 # ??0ORealDynamicLoader@salhelper@@IEAA@PEAPEAV01@AEBVOUString@rtl@@1PEAX2@Z
35 # It should be relatively easy to remove the modification parts of the
36 # below code and use the regex for some other task on MSVC mangled
39 # The regular expression below accepts also nonsensical mangled names,
40 # so it should not be used to verify correctness of mangled names.
50 return $num + 1 if ($num eq '0' || ($num ge '1' && $num le '9'));
52 $num =~ tr/ABCDEFGHIJKLMNOP@/0123456789ABCDEF /;
60 return $num - 1 if ($num <= 10);
62 $num = sprintf("%X", $num);
63 $num =~ tr/0123456789ABCDEF/ABCDEFGHIJKLMNOP/;
69 my ($number, $position) = @_;
71 my $bytes = parse_number
($number);
73 push(@opstack, 'r '.($position - length($number)).' '.length($number).' '.format_number
($bytes));
79 # Named subpattern definitions. I use names of the form
80 # __CamelCase__ for the named subpatters so that they are easier
89 (?
<__CallingConvention__
>
94 (?
{ push(@opstack, 'r '.(pos()-1).' 1 A cdecl'); })
97 (?
<__StringLiteralText__
>
107 [_a
-zA
-Z\
$][_a
-zA
-Z0
-9\
$]*@
109 (?
<__ArgsZTerminated__
>
110 (?
&__DataTypeInArgs__
)+ @? Z
112 (?
<__ArgsNonZTerminated__
>
113 (?
&__DataTypeInArgs__
)+ @?
116 (?
&__Identifier__
) (?
&__ArgsNonZTerminated__
)
122 \?\
$ (?
&__TemplateName__
)
127 (?
<__DataTypeCommon__
>
129 # extended types like _int64, bool and wchar_t
135 # class, struct, union, cointerface
140 (?
{ push(@opstack, 'i '.pos().' E reference'); })
145 (?
{ push(@opstack, 'i '.pos().' E pointer'); })
151 6 (?
&__CallingConvention__
) (?
&__DataTypeNotInArgs__
) (?
&__ArgsZTerminated__
)
154 (?
{ push(@opstack, 'i '.pos().' E pointer'); })
169 \
$ [ABCD
] (?
&__DataTypeNotInArgs__
)
176 # multidimensional array
179 (?
&__DataTypeNotInArgs__
)
181 (?
<__DataTypeInArgs__
>
183 (?
&__DataTypeCommon__
)
189 (?
<__DataTypeNotInArgs__
>
191 (?
&__DataTypeCommon__
)
193 \? (?
&__ModifiedType__
)
198 # All mangled names start with a question mark
201 # Ctors, dtors, operators etc have separate a priori defined
202 # special mangled names like the very simple ?0 for constructor
203 # and ?_R16789 for "RTTI Base Class Descriptor at (6,7,8,9)"
204 # whatever that might mean.
210 # C is for string literals, see below
211 # R is RTTI, see immediately below
214 R0
(?
&__DataTypeNotInArgs__
)
229 # Static members and normal variables
231 (?
&__DataTypeNotInArgs__
)
234 # Compiler-generated static
243 # Non-static Methods, implicit 'this'
246 (?
{ push(@opstack, 'i '.(pos()-1).' E this'); })
247 (?
&__CallingConvention__
)
251 (?
&__DataTypeNotInArgs__
)
253 (?
&__ArgsZTerminated__
)
257 (?
&__CallingConvention__
)
261 (?
&__DataTypeNotInArgs__
)
263 (?
&__ArgsZTerminated__
)
268 (?
{ double_thunk
($^N
, pos()); })
270 (?
{ push(@opstack, 'i '.(pos()-1).' E this'); })
271 (?
&__CallingConvention__
)
275 (?
&__DataTypeNotInArgs__
)
277 (?
&__ArgsZTerminated__
)
281 (?
&__CallingConvention__
)
285 (?
&__DataTypeNotInArgs__
)
287 (?
&__ArgsZTerminated__
)
290 \
$ (?
&__Identifier__
) (?
&__ArgsNonZTerminated__
)
293 # pooled string literals
294 \?_C\
@_[01](?
&__Number__
)(?
&__32BitChecksum__
)(?
&__StringLiteralText__
)@
298 while (my $op = pop(@opstack))
300 # print STDERR "op=$op\n";
301 my @a = split (' ', $op);
303 substr($_,$a[1],0) = $a[2];
304 } elsif ($a[0] eq 'r') {
305 substr($_,$a[1],$a[2]) = $a[3];