Mercurial > hg > CbC > CbC_llvm
comparison clang/lib/Tooling/Tooling.cpp @ 207:2e18cbf3894f
LLVM12
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 08 Jun 2021 06:07:14 +0900 |
parents | 0572611fdcc8 |
children | c4bab56944e8 |
comparison
equal
deleted
inserted
replaced
173:0572611fdcc8 | 207:2e18cbf3894f |
---|---|
76 static driver::Driver * | 76 static driver::Driver * |
77 newDriver(DiagnosticsEngine *Diagnostics, const char *BinaryName, | 77 newDriver(DiagnosticsEngine *Diagnostics, const char *BinaryName, |
78 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) { | 78 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) { |
79 driver::Driver *CompilerDriver = | 79 driver::Driver *CompilerDriver = |
80 new driver::Driver(BinaryName, llvm::sys::getDefaultTargetTriple(), | 80 new driver::Driver(BinaryName, llvm::sys::getDefaultTargetTriple(), |
81 *Diagnostics, std::move(VFS)); | 81 *Diagnostics, "clang LLVM compiler", std::move(VFS)); |
82 CompilerDriver->setTitle("clang_based_tool"); | 82 CompilerDriver->setTitle("clang_based_tool"); |
83 return CompilerDriver; | 83 return CompilerDriver; |
84 } | 84 } |
85 | 85 |
86 /// Retrieves the clang CC1 specific flags out of the compilation's jobs. | 86 /// Retrieves the clang CC1 specific flags out of the compilation's jobs. |
139 | 139 |
140 namespace clang { | 140 namespace clang { |
141 namespace tooling { | 141 namespace tooling { |
142 | 142 |
143 /// Returns a clang build invocation initialized from the CC1 flags. | 143 /// Returns a clang build invocation initialized from the CC1 flags. |
144 CompilerInvocation *newInvocation( | 144 CompilerInvocation *newInvocation(DiagnosticsEngine *Diagnostics, |
145 DiagnosticsEngine *Diagnostics, const llvm::opt::ArgStringList &CC1Args) { | 145 const llvm::opt::ArgStringList &CC1Args, |
146 const char *const BinaryName) { | |
146 assert(!CC1Args.empty() && "Must at least contain the program name!"); | 147 assert(!CC1Args.empty() && "Must at least contain the program name!"); |
147 CompilerInvocation *Invocation = new CompilerInvocation; | 148 CompilerInvocation *Invocation = new CompilerInvocation; |
148 CompilerInvocation::CreateFromArgs(*Invocation, CC1Args, *Diagnostics); | 149 CompilerInvocation::CreateFromArgs(*Invocation, CC1Args, *Diagnostics, |
150 BinaryName); | |
149 Invocation->getFrontendOpts().DisableFree = false; | 151 Invocation->getFrontendOpts().DisableFree = false; |
150 Invocation->getCodeGenOpts().DisableFree = false; | 152 Invocation->getCodeGenOpts().DisableFree = false; |
151 return Invocation; | 153 return Invocation; |
152 } | 154 } |
153 | 155 |
241 return llvm::cantFail(getAbsolutePath(*llvm::vfs::getRealFileSystem(), File)); | 243 return llvm::cantFail(getAbsolutePath(*llvm::vfs::getRealFileSystem(), File)); |
242 } | 244 } |
243 | 245 |
244 void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine, | 246 void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine, |
245 StringRef InvokedAs) { | 247 StringRef InvokedAs) { |
246 if (!CommandLine.empty() && !InvokedAs.empty()) { | 248 if (CommandLine.empty() || InvokedAs.empty()) |
247 bool AlreadyHasTarget = false; | 249 return; |
248 bool AlreadyHasMode = false; | 250 const auto &Table = driver::getDriverOptTable(); |
249 // Skip CommandLine[0]. | 251 // --target=X |
250 for (auto Token = ++CommandLine.begin(); Token != CommandLine.end(); | 252 const std::string TargetOPT = |
251 ++Token) { | 253 Table.getOption(driver::options::OPT_target).getPrefixedName(); |
252 StringRef TokenRef(*Token); | 254 // -target X |
253 AlreadyHasTarget |= | 255 const std::string TargetOPTLegacy = |
254 (TokenRef == "-target" || TokenRef.startswith("-target=")); | 256 Table.getOption(driver::options::OPT_target_legacy_spelling) |
255 AlreadyHasMode |= (TokenRef == "--driver-mode" || | 257 .getPrefixedName(); |
256 TokenRef.startswith("--driver-mode=")); | 258 // --driver-mode=X |
257 } | 259 const std::string DriverModeOPT = |
258 auto TargetMode = | 260 Table.getOption(driver::options::OPT_driver_mode).getPrefixedName(); |
259 driver::ToolChain::getTargetAndModeFromProgramName(InvokedAs); | 261 auto TargetMode = |
260 if (!AlreadyHasMode && TargetMode.DriverMode) { | 262 driver::ToolChain::getTargetAndModeFromProgramName(InvokedAs); |
261 CommandLine.insert(++CommandLine.begin(), TargetMode.DriverMode); | 263 // No need to search for target args if we don't have a target/mode to insert. |
262 } | 264 bool ShouldAddTarget = TargetMode.TargetIsValid; |
263 if (!AlreadyHasTarget && TargetMode.TargetIsValid) { | 265 bool ShouldAddMode = TargetMode.DriverMode != nullptr; |
264 CommandLine.insert(++CommandLine.begin(), {"-target", | 266 // Skip CommandLine[0]. |
265 TargetMode.TargetPrefix}); | 267 for (auto Token = ++CommandLine.begin(); Token != CommandLine.end(); |
266 } | 268 ++Token) { |
269 StringRef TokenRef(*Token); | |
270 ShouldAddTarget = ShouldAddTarget && !TokenRef.startswith(TargetOPT) && | |
271 !TokenRef.equals(TargetOPTLegacy); | |
272 ShouldAddMode = ShouldAddMode && !TokenRef.startswith(DriverModeOPT); | |
273 } | |
274 if (ShouldAddMode) { | |
275 CommandLine.insert(++CommandLine.begin(), TargetMode.DriverMode); | |
276 } | |
277 if (ShouldAddTarget) { | |
278 CommandLine.insert(++CommandLine.begin(), | |
279 TargetOPT + TargetMode.TargetPrefix); | |
267 } | 280 } |
268 } | 281 } |
269 | 282 |
270 } // namespace tooling | 283 } // namespace tooling |
271 } // namespace clang | 284 } // namespace clang |
302 PCHContainerOps(std::move(PCHContainerOps)) {} | 315 PCHContainerOps(std::move(PCHContainerOps)) {} |
303 | 316 |
304 ToolInvocation::~ToolInvocation() { | 317 ToolInvocation::~ToolInvocation() { |
305 if (OwnsAction) | 318 if (OwnsAction) |
306 delete Action; | 319 delete Action; |
307 } | |
308 | |
309 void ToolInvocation::mapVirtualFile(StringRef FilePath, StringRef Content) { | |
310 SmallString<1024> PathStorage; | |
311 llvm::sys::path::native(FilePath, PathStorage); | |
312 MappedFileContents[PathStorage] = Content; | |
313 } | 320 } |
314 | 321 |
315 bool ToolInvocation::run() { | 322 bool ToolInvocation::run() { |
316 std::vector<const char*> Argv; | 323 std::vector<const char*> Argv; |
317 for (const std::string &Str : CommandLine) | 324 for (const std::string &Str : CommandLine) |
325 TextDiagnosticPrinter DiagnosticPrinter( | 332 TextDiagnosticPrinter DiagnosticPrinter( |
326 llvm::errs(), &*DiagOpts); | 333 llvm::errs(), &*DiagOpts); |
327 DiagnosticsEngine Diagnostics( | 334 DiagnosticsEngine Diagnostics( |
328 IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts, | 335 IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts, |
329 DiagConsumer ? DiagConsumer : &DiagnosticPrinter, false); | 336 DiagConsumer ? DiagConsumer : &DiagnosticPrinter, false); |
337 // Although `Diagnostics` are used only for command-line parsing, the custom | |
338 // `DiagConsumer` might expect a `SourceManager` to be present. | |
339 SourceManager SrcMgr(Diagnostics, *Files); | |
340 Diagnostics.setSourceManager(&SrcMgr); | |
330 | 341 |
331 const std::unique_ptr<driver::Driver> Driver( | 342 const std::unique_ptr<driver::Driver> Driver( |
332 newDriver(&Diagnostics, BinaryName, &Files->getVirtualFileSystem())); | 343 newDriver(&Diagnostics, BinaryName, &Files->getVirtualFileSystem())); |
333 // The "input file not found" diagnostics from the driver are useful. | 344 // The "input file not found" diagnostics from the driver are useful. |
334 // The driver is only aware of the VFS working directory, but some clients | 345 // The driver is only aware of the VFS working directory, but some clients |
343 const llvm::opt::ArgStringList *const CC1Args = getCC1Arguments( | 354 const llvm::opt::ArgStringList *const CC1Args = getCC1Arguments( |
344 &Diagnostics, Compilation.get()); | 355 &Diagnostics, Compilation.get()); |
345 if (!CC1Args) | 356 if (!CC1Args) |
346 return false; | 357 return false; |
347 std::unique_ptr<CompilerInvocation> Invocation( | 358 std::unique_ptr<CompilerInvocation> Invocation( |
348 newInvocation(&Diagnostics, *CC1Args)); | 359 newInvocation(&Diagnostics, *CC1Args, BinaryName)); |
349 // FIXME: remove this when all users have migrated! | |
350 for (const auto &It : MappedFileContents) { | |
351 // Inject the code as the given file name into the preprocessor options. | |
352 std::unique_ptr<llvm::MemoryBuffer> Input = | |
353 llvm::MemoryBuffer::getMemBuffer(It.getValue()); | |
354 Invocation->getPreprocessorOpts().addRemappedFile(It.getKey(), | |
355 Input.release()); | |
356 } | |
357 return runInvocation(BinaryName, Compilation.get(), std::move(Invocation), | 360 return runInvocation(BinaryName, Compilation.get(), std::move(Invocation), |
358 std::move(PCHContainerOps)); | 361 std::move(PCHContainerOps)); |
359 } | 362 } |
360 | 363 |
361 bool ToolInvocation::runInvocation( | 364 bool ToolInvocation::runInvocation( |
439 for (StringRef Arg : Args) | 442 for (StringRef Arg : Args) |
440 if (Arg.startswith("-resource-dir")) | 443 if (Arg.startswith("-resource-dir")) |
441 return; | 444 return; |
442 | 445 |
443 // If there's no override in place add our resource dir. | 446 // If there's no override in place add our resource dir. |
444 Args.push_back("-resource-dir=" + | 447 Args = getInsertArgumentAdjuster( |
445 CompilerInvocation::GetResourcesPath(Argv0, MainAddr)); | 448 ("-resource-dir=" + CompilerInvocation::GetResourcesPath(Argv0, MainAddr)) |
449 .c_str())(Args, ""); | |
446 } | 450 } |
447 | 451 |
448 int ClangTool::run(ToolAction *Action) { | 452 int ClangTool::run(ToolAction *Action) { |
449 // Exists solely for the purpose of lookup of the resource path. | 453 // Exists solely for the purpose of lookup of the resource path. |
450 // This just needs to be some symbol in the binary. | 454 // This just needs to be some symbol in the binary. |
644 llvm::MemoryBuffer::getMemBuffer(FilenameWithContent.second)); | 648 llvm::MemoryBuffer::getMemBuffer(FilenameWithContent.second)); |
645 } | 649 } |
646 | 650 |
647 if (!Invocation.run()) | 651 if (!Invocation.run()) |
648 return nullptr; | 652 return nullptr; |
649 | 653 |
650 assert(ASTs.size() == 1); | 654 assert(ASTs.size() == 1); |
651 return std::move(ASTs[0]); | 655 return std::move(ASTs[0]); |
652 } | 656 } |
653 | 657 |
654 } // namespace tooling | 658 } // namespace tooling |