ArgumentsAdjusters.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. //===- ArgumentsAdjusters.cpp - Command line arguments adjuster -----------===//
  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. // This file contains definitions of classes which implement ArgumentsAdjuster
  10. // interface.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "clang/Tooling/ArgumentsAdjusters.h"
  14. #include "clang/Basic/LLVM.h"
  15. #include "llvm/ADT/StringRef.h"
  16. #include <cstddef>
  17. namespace clang {
  18. namespace tooling {
  19. /// Add -fsyntax-only option to the command line arguments.
  20. ArgumentsAdjuster getClangSyntaxOnlyAdjuster() {
  21. return [](const CommandLineArguments &Args, StringRef /*unused*/) {
  22. CommandLineArguments AdjustedArgs;
  23. bool HasSyntaxOnly = false;
  24. for (size_t i = 0, e = Args.size(); i < e; ++i) {
  25. StringRef Arg = Args[i];
  26. // FIXME: Remove options that generate output.
  27. if (!Arg.startswith("-fcolor-diagnostics") &&
  28. !Arg.startswith("-fdiagnostics-color"))
  29. AdjustedArgs.push_back(Args[i]);
  30. if (Arg == "-fsyntax-only")
  31. HasSyntaxOnly = true;
  32. }
  33. if (!HasSyntaxOnly)
  34. AdjustedArgs.push_back("-fsyntax-only");
  35. return AdjustedArgs;
  36. };
  37. }
  38. ArgumentsAdjuster getClangStripOutputAdjuster() {
  39. return [](const CommandLineArguments &Args, StringRef /*unused*/) {
  40. CommandLineArguments AdjustedArgs;
  41. for (size_t i = 0, e = Args.size(); i < e; ++i) {
  42. StringRef Arg = Args[i];
  43. if (!Arg.startswith("-o"))
  44. AdjustedArgs.push_back(Args[i]);
  45. if (Arg == "-o") {
  46. // Output is specified as -o foo. Skip the next argument too.
  47. ++i;
  48. }
  49. // Else, the output is specified as -ofoo. Just do nothing.
  50. }
  51. return AdjustedArgs;
  52. };
  53. }
  54. ArgumentsAdjuster getClangStripSerializeDiagnosticAdjuster() {
  55. return [](const CommandLineArguments &Args, StringRef /*unused*/) {
  56. CommandLineArguments AdjustedArgs;
  57. for (size_t i = 0, e = Args.size(); i < e; ++i) {
  58. StringRef Arg = Args[i];
  59. if (Arg == "--serialize-diagnostics") {
  60. // Skip the diagnostic output argument.
  61. ++i;
  62. continue;
  63. }
  64. AdjustedArgs.push_back(Args[i]);
  65. }
  66. return AdjustedArgs;
  67. };
  68. }
  69. ArgumentsAdjuster getClangStripDependencyFileAdjuster() {
  70. return [](const CommandLineArguments &Args, StringRef /*unused*/) {
  71. CommandLineArguments AdjustedArgs;
  72. for (size_t i = 0, e = Args.size(); i < e; ++i) {
  73. StringRef Arg = Args[i];
  74. // All dependency-file options begin with -M. These include -MM,
  75. // -MF, -MG, -MP, -MT, -MQ, -MD, and -MMD.
  76. if (!Arg.startswith("-M")) {
  77. AdjustedArgs.push_back(Args[i]);
  78. continue;
  79. }
  80. if (Arg == "-MF" || Arg == "-MT" || Arg == "-MQ")
  81. // These flags take an argument: -MX foo. Skip the next argument also.
  82. ++i;
  83. }
  84. return AdjustedArgs;
  85. };
  86. }
  87. ArgumentsAdjuster getInsertArgumentAdjuster(const CommandLineArguments &Extra,
  88. ArgumentInsertPosition Pos) {
  89. return [Extra, Pos](const CommandLineArguments &Args, StringRef /*unused*/) {
  90. CommandLineArguments Return(Args);
  91. CommandLineArguments::iterator I;
  92. if (Pos == ArgumentInsertPosition::END) {
  93. I = Return.end();
  94. } else {
  95. I = Return.begin();
  96. ++I; // To leave the program name in place
  97. }
  98. Return.insert(I, Extra.begin(), Extra.end());
  99. return Return;
  100. };
  101. }
  102. ArgumentsAdjuster getInsertArgumentAdjuster(const char *Extra,
  103. ArgumentInsertPosition Pos) {
  104. return getInsertArgumentAdjuster(CommandLineArguments(1, Extra), Pos);
  105. }
  106. ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First,
  107. ArgumentsAdjuster Second) {
  108. if (!First)
  109. return Second;
  110. if (!Second)
  111. return First;
  112. return [First, Second](const CommandLineArguments &Args, StringRef File) {
  113. return Second(First(Args, File), File);
  114. };
  115. }
  116. ArgumentsAdjuster getStripPluginsAdjuster() {
  117. return [](const CommandLineArguments &Args, StringRef /*unused*/) {
  118. CommandLineArguments AdjustedArgs;
  119. for (size_t I = 0, E = Args.size(); I != E; I++) {
  120. // According to https://clang.llvm.org/docs/ClangPlugins.html
  121. // plugin arguments are in the form:
  122. // -Xclang {-load, -plugin, -plugin-arg-<plugin-name>, -add-plugin}
  123. // -Xclang <arbitrary-argument>
  124. if (I + 4 < E && Args[I] == "-Xclang" &&
  125. (Args[I + 1] == "-load" || Args[I + 1] == "-plugin" ||
  126. llvm::StringRef(Args[I + 1]).startswith("-plugin-arg-") ||
  127. Args[I + 1] == "-add-plugin") &&
  128. Args[I + 2] == "-Xclang") {
  129. I += 3;
  130. continue;
  131. }
  132. AdjustedArgs.push_back(Args[I]);
  133. }
  134. return AdjustedArgs;
  135. };
  136. }
  137. } // end namespace tooling
  138. } // end namespace clang