blob: 31d0590af2ddcf5e5abd887ead4004c47cd8c7d1 [file] [log] [blame]
Zachary Turnerf435a7e2018-07-20 17:27:48 +00001//===-- llvm-undname.cpp - Microsoft ABI name undecorator
2//------------------===//
3//
4// The LLVM Compiler Infrastructure
5//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10//
11// This utility works like the windows undname utility. It converts mangled
12// Microsoft symbol names into pretty C/C++ human-readable names.
13//
14//===----------------------------------------------------------------------===//
15
16#include "llvm/ADT/StringRef.h"
17#include "llvm/Demangle/Demangle.h"
18#include "llvm/Support/CommandLine.h"
19#include "llvm/Support/InitLLVM.h"
20#include "llvm/Support/Process.h"
21#include "llvm/Support/raw_ostream.h"
22#include <cstdio>
23#include <cstring>
24#include <iostream>
25#include <string>
26
27using namespace llvm;
28
Zachary Turner3a758e22018-08-01 18:33:04 +000029cl::opt<bool> DumpBackReferences("backrefs", cl::Optional,
30 cl::desc("dump backreferences"), cl::Hidden,
31 cl::init(false));
Zachary Turnerf435a7e2018-07-20 17:27:48 +000032cl::list<std::string> Symbols(cl::Positional, cl::desc("<input symbols>"),
33 cl::ZeroOrMore);
34
35static void demangle(const std::string &S) {
36 int Status;
Zachary Turner3a758e22018-08-01 18:33:04 +000037 MSDemangleFlags Flags = MSDF_None;
38 if (DumpBackReferences)
39 Flags = MSDemangleFlags(Flags | MSDF_DumpBackrefs);
40
41 char *ResultBuf =
42 microsoftDemangle(S.c_str(), nullptr, nullptr, &Status, Flags);
Zachary Turnerf435a7e2018-07-20 17:27:48 +000043 if (Status == llvm::demangle_success) {
44 outs() << ResultBuf << "\n";
45 outs().flush();
46 } else {
47 errs() << "Error: Invalid mangled name\n";
48 }
49 std::free(ResultBuf);
Martin Storsjo21524be2018-07-20 20:48:36 +000050}
Zachary Turnerf435a7e2018-07-20 17:27:48 +000051
52int main(int argc, char **argv) {
53 InitLLVM X(argc, argv);
54
55 cl::ParseCommandLineOptions(argc, argv, "llvm-undname\n");
56
57 if (Symbols.empty()) {
58 while (true) {
59 std::string LineStr;
60 std::getline(std::cin, LineStr);
61 if (std::cin.eof())
62 break;
63
64 StringRef Line(LineStr);
65 Line = Line.trim();
66 if (Line.empty() || Line.startswith("#") || Line.startswith(";"))
67 continue;
68
69 // If the user is manually typing in these decorated names, don't echo
70 // them to the terminal a second time. If they're coming from redirected
71 // input, however, then we should display the input line so that the
72 // mangled and demangled name can be easily correlated in the output.
Zachary Turnerc93b8702018-07-21 15:39:05 +000073 if (!sys::Process::StandardInIsUserInput()) {
Zachary Turnerf435a7e2018-07-20 17:27:48 +000074 outs() << Line << "\n";
Zachary Turnerc93b8702018-07-21 15:39:05 +000075 outs().flush();
76 }
Zachary Turnerf435a7e2018-07-20 17:27:48 +000077 demangle(Line);
78 outs() << "\n";
79 }
80 } else {
81 for (StringRef S : Symbols) {
82 outs() << S << "\n";
Zachary Turnerc93b8702018-07-21 15:39:05 +000083 outs().flush();
Zachary Turnerf435a7e2018-07-20 17:27:48 +000084 demangle(S);
85 outs() << "\n";
86 }
87 }
88
89 return 0;
Martin Storsjo21524be2018-07-20 20:48:36 +000090}