Mercurial > hg > CbC > CbC_llvm
comparison tools/llvm-cxxmap/llvm-cxxmap.cpp @ 148:63bd29f05246
merged
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 19:46:37 +0900 |
parents | c2174574ed3a |
children |
comparison
equal
deleted
inserted
replaced
146:3fc4d5c3e21e | 148:63bd29f05246 |
---|---|
1 //===- llvm-cxxmap.cpp ----------------------------------------------------===// | |
2 // | |
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 | |
6 // | |
7 //===----------------------------------------------------------------------===// | |
8 // | |
9 // llvm-cxxmap computes a correspondence between old symbol names and new | |
10 // symbol names based on a symbol equivalence file. | |
11 // | |
12 //===----------------------------------------------------------------------===// | |
13 | |
14 #include "llvm/ADT/DenseSet.h" | |
15 #include "llvm/ADT/DenseMap.h" | |
16 #include "llvm/ADT/StringRef.h" | |
17 #include "llvm/Support/CommandLine.h" | |
18 #include "llvm/Support/InitLLVM.h" | |
19 #include "llvm/Support/LineIterator.h" | |
20 #include "llvm/Support/MemoryBuffer.h" | |
21 #include "llvm/Support/SymbolRemappingReader.h" | |
22 #include "llvm/Support/WithColor.h" | |
23 #include "llvm/Support/raw_ostream.h" | |
24 | |
25 using namespace llvm; | |
26 | |
27 cl::opt<std::string> OldSymbolFile(cl::Positional, cl::Required, | |
28 cl::desc("<symbol-file>")); | |
29 cl::opt<std::string> NewSymbolFile(cl::Positional, cl::Required, | |
30 cl::desc("<symbol-file>")); | |
31 cl::opt<std::string> RemappingFile("remapping-file", cl::Required, | |
32 cl::desc("Remapping file")); | |
33 cl::alias RemappingFileA("r", cl::aliasopt(RemappingFile)); | |
34 cl::opt<std::string> OutputFilename("output", cl::value_desc("output"), | |
35 cl::init("-"), cl::desc("Output file")); | |
36 cl::alias OutputFilenameA("o", cl::aliasopt(OutputFilename)); | |
37 | |
38 cl::opt<bool> WarnAmbiguous( | |
39 "Wambiguous", | |
40 cl::desc("Warn on equivalent symbols in the output symbol list")); | |
41 cl::opt<bool> WarnIncomplete( | |
42 "Wincomplete", | |
43 cl::desc("Warn on input symbols missing from output symbol list")); | |
44 | |
45 static void warn(Twine Message, Twine Whence = "", | |
46 std::string Hint = "") { | |
47 WithColor::warning(); | |
48 std::string WhenceStr = Whence.str(); | |
49 if (!WhenceStr.empty()) | |
50 errs() << WhenceStr << ": "; | |
51 errs() << Message << "\n"; | |
52 if (!Hint.empty()) | |
53 WithColor::note() << Hint << "\n"; | |
54 } | |
55 | |
56 static void exitWithError(Twine Message, Twine Whence = "", | |
57 std::string Hint = "") { | |
58 WithColor::error(); | |
59 std::string WhenceStr = Whence.str(); | |
60 if (!WhenceStr.empty()) | |
61 errs() << WhenceStr << ": "; | |
62 errs() << Message << "\n"; | |
63 if (!Hint.empty()) | |
64 WithColor::note() << Hint << "\n"; | |
65 ::exit(1); | |
66 } | |
67 | |
68 static void exitWithError(Error E, StringRef Whence = "") { | |
69 exitWithError(toString(std::move(E)), Whence); | |
70 } | |
71 | |
72 static void exitWithErrorCode(std::error_code EC, StringRef Whence = "") { | |
73 exitWithError(EC.message(), Whence); | |
74 } | |
75 | |
76 static void remapSymbols(MemoryBuffer &OldSymbolFile, | |
77 MemoryBuffer &NewSymbolFile, | |
78 MemoryBuffer &RemappingFile, | |
79 raw_ostream &Out) { | |
80 // Load the remapping file and prepare to canonicalize symbols. | |
81 SymbolRemappingReader Reader; | |
82 if (Error E = Reader.read(RemappingFile)) | |
83 exitWithError(std::move(E)); | |
84 | |
85 // Canonicalize the new symbols. | |
86 DenseMap<SymbolRemappingReader::Key, StringRef> MappedNames; | |
87 DenseSet<StringRef> UnparseableSymbols; | |
88 for (line_iterator LineIt(NewSymbolFile, /*SkipBlanks=*/true, '#'); | |
89 !LineIt.is_at_eof(); ++LineIt) { | |
90 StringRef Symbol = *LineIt; | |
91 | |
92 auto K = Reader.insert(Symbol); | |
93 if (!K) { | |
94 UnparseableSymbols.insert(Symbol); | |
95 continue; | |
96 } | |
97 | |
98 auto ItAndIsNew = MappedNames.insert({K, Symbol}); | |
99 if (WarnAmbiguous && !ItAndIsNew.second && | |
100 ItAndIsNew.first->second != Symbol) { | |
101 warn("symbol " + Symbol + " is equivalent to earlier symbol " + | |
102 ItAndIsNew.first->second, | |
103 NewSymbolFile.getBufferIdentifier() + ":" + | |
104 Twine(LineIt.line_number()), | |
105 "later symbol will not be the target of any remappings"); | |
106 } | |
107 } | |
108 | |
109 // Figure out which new symbol each old symbol is equivalent to. | |
110 for (line_iterator LineIt(OldSymbolFile, /*SkipBlanks=*/true, '#'); | |
111 !LineIt.is_at_eof(); ++LineIt) { | |
112 StringRef Symbol = *LineIt; | |
113 | |
114 auto K = Reader.lookup(Symbol); | |
115 StringRef NewSymbol = MappedNames.lookup(K); | |
116 | |
117 if (NewSymbol.empty()) { | |
118 if (WarnIncomplete && !UnparseableSymbols.count(Symbol)) { | |
119 warn("no new symbol matches old symbol " + Symbol, | |
120 OldSymbolFile.getBufferIdentifier() + ":" + | |
121 Twine(LineIt.line_number())); | |
122 } | |
123 continue; | |
124 } | |
125 | |
126 Out << Symbol << " " << NewSymbol << "\n"; | |
127 } | |
128 } | |
129 | |
130 int main(int argc, const char *argv[]) { | |
131 InitLLVM X(argc, argv); | |
132 | |
133 cl::ParseCommandLineOptions(argc, argv, "LLVM C++ mangled name remapper\n"); | |
134 | |
135 auto OldSymbolBufOrError = MemoryBuffer::getFileOrSTDIN(OldSymbolFile); | |
136 if (!OldSymbolBufOrError) | |
137 exitWithErrorCode(OldSymbolBufOrError.getError(), OldSymbolFile); | |
138 | |
139 auto NewSymbolBufOrError = MemoryBuffer::getFileOrSTDIN(NewSymbolFile); | |
140 if (!NewSymbolBufOrError) | |
141 exitWithErrorCode(NewSymbolBufOrError.getError(), NewSymbolFile); | |
142 | |
143 auto RemappingBufOrError = MemoryBuffer::getFileOrSTDIN(RemappingFile); | |
144 if (!RemappingBufOrError) | |
145 exitWithErrorCode(RemappingBufOrError.getError(), RemappingFile); | |
146 | |
147 std::error_code EC; | |
148 raw_fd_ostream OS(OutputFilename.data(), EC, sys::fs::OF_Text); | |
149 if (EC) | |
150 exitWithErrorCode(EC, OutputFilename); | |
151 | |
152 remapSymbols(*OldSymbolBufOrError.get(), *NewSymbolBufOrError.get(), | |
153 *RemappingBufOrError.get(), OS); | |
154 } |