1 //===-- llvm-c++filt.cpp --------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ADT/StringExtras.h"
10 #include "llvm/Demangle/Demangle.h"
11 #include "llvm/Support/CommandLine.h"
12 #include "llvm/Support/InitLLVM.h"
13 #include "llvm/Support/raw_ostream.h"
20 Auto
, ///< auto-detect mangling
22 Lucid
, ///< Lucid compiler (lcc)
24 HP
, ///< HP compiler (xCC)
25 EDG
, ///< EDG compiler
26 GNUv3
, ///< GNU C++ v3 ABI
28 GNAT
///< ADA compiler (gnat)
31 Format("format", cl::desc("decoration style"),
32 cl::values(clEnumValN(Auto
, "auto", "auto-detect style"),
33 clEnumValN(GNU
, "gnu", "GNU (itanium) style")),
35 static cl::alias
FormatShort("s", cl::desc("alias for --format"),
36 cl::aliasopt(Format
));
38 static cl::opt
<bool> StripUnderscore("strip-underscore",
39 cl::desc("strip the leading underscore"),
41 static cl::alias
StripUnderscoreShort("_",
42 cl::desc("alias for --strip-underscore"),
43 cl::aliasopt(StripUnderscore
));
47 cl::desc("attempt to demangle types as well as function names"),
49 static cl::alias
TypesShort("t", cl::desc("alias for --types"),
52 static cl::list
<std::string
>
53 Decorated(cl::Positional
, cl::desc("<mangled>"), cl::ZeroOrMore
);
56 HelpResponse("\nPass @FILE as argument to read options from FILE.\n");
58 static std::string
demangle(llvm::raw_ostream
&OS
, const std::string
&Mangled
) {
61 const char *DecoratedStr
= Mangled
.c_str();
63 if (DecoratedStr
[0] == '_')
65 size_t DecoratedLength
= strlen(DecoratedStr
);
67 char *Undecorated
= nullptr;
70 ((DecoratedLength
>= 2 && strncmp(DecoratedStr
, "_Z", 2) == 0) ||
71 (DecoratedLength
>= 4 && strncmp(DecoratedStr
, "___Z", 4) == 0)))
72 Undecorated
= itaniumDemangle(DecoratedStr
, nullptr, nullptr, &Status
);
75 (DecoratedLength
> 6 && strncmp(DecoratedStr
, "__imp_", 6) == 0)) {
76 OS
<< "import thunk for ";
77 Undecorated
= itaniumDemangle(DecoratedStr
+ 6, nullptr, nullptr, &Status
);
80 std::string
Result(Undecorated
? Undecorated
: Mangled
);
85 // Split 'Source' on any character that fails to pass 'IsLegalChar'. The
86 // returned vector consists of pairs where 'first' is the delimited word, and
87 // 'second' are the delimiters following that word.
88 static void SplitStringDelims(
90 SmallVectorImpl
<std::pair
<StringRef
, StringRef
>> &OutFragments
,
91 function_ref
<bool(char)> IsLegalChar
) {
92 // The beginning of the input string.
93 const auto Head
= Source
.begin();
95 // Obtain any leading delimiters.
96 auto Start
= std::find_if(Head
, Source
.end(), IsLegalChar
);
98 OutFragments
.push_back({"", Source
.slice(0, Start
- Head
)});
100 // Capture each word and the delimiters following that word.
101 while (Start
!= Source
.end()) {
102 Start
= std::find_if(Start
, Source
.end(), IsLegalChar
);
103 auto End
= std::find_if_not(Start
, Source
.end(), IsLegalChar
);
104 auto DEnd
= std::find_if(End
, Source
.end(), IsLegalChar
);
105 OutFragments
.push_back({Source
.slice(Start
- Head
, End
- Head
),
106 Source
.slice(End
- Head
, DEnd
- Head
)});
111 // This returns true if 'C' is a character that can show up in an
112 // Itanium-mangled string.
113 static bool IsLegalItaniumChar(char C
) {
114 // Itanium CXX ABI [External Names]p5.1.1:
115 // '$' and '.' in mangled names are reserved for private implementations.
116 return isalnum(C
) || C
== '.' || C
== '$' || C
== '_';
119 // If 'Split' is true, then 'Mangled' is broken into individual words and each
120 // word is demangled. Otherwise, the entire string is treated as a single
121 // mangled item. The result is output to 'OS'.
122 static void demangleLine(llvm::raw_ostream
&OS
, StringRef Mangled
, bool Split
) {
125 SmallVector
<std::pair
<StringRef
, StringRef
>, 16> Words
;
126 SplitStringDelims(Mangled
, Words
, IsLegalItaniumChar
);
127 for (const auto &Word
: Words
)
128 Result
+= demangle(OS
, Word
.first
) + Word
.second
.str();
130 Result
= demangle(OS
, Mangled
);
131 OS
<< Result
<< '\n';
135 int main(int argc
, char **argv
) {
136 InitLLVM
X(argc
, argv
);
138 cl::ParseCommandLineOptions(argc
, argv
, "llvm symbol undecoration tool\n");
140 if (Decorated
.empty())
141 for (std::string Mangled
; std::getline(std::cin
, Mangled
);)
142 demangleLine(llvm::outs(), Mangled
, true);
144 for (const auto &Symbol
: Decorated
)
145 demangleLine(llvm::outs(), Symbol
, false);