1 //===--- ArgumentsAdjusters.cpp - Command line arguments adjuster ---------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains definitions of classes which implement ArgumentsAdjuster
11 // interface.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "clang/Tooling/ArgumentsAdjusters.h"
16 
17 namespace clang {
18 namespace tooling {
19 
20 /// Add -fsyntax-only option to the command line arguments.
21 ArgumentsAdjuster getClangSyntaxOnlyAdjuster() {
22   return [](const CommandLineArguments &Args, StringRef /*unused*/) {
23     CommandLineArguments AdjustedArgs;
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     }
31     AdjustedArgs.push_back("-fsyntax-only");
32     return AdjustedArgs;
33   };
34 }
35 
36 ArgumentsAdjuster getClangStripOutputAdjuster() {
37   return [](const CommandLineArguments &Args, StringRef /*unused*/) {
38     CommandLineArguments AdjustedArgs;
39     for (size_t i = 0, e = Args.size(); i < e; ++i) {
40       StringRef Arg = Args[i];
41       if (!Arg.startswith("-o"))
42         AdjustedArgs.push_back(Args[i]);
43 
44       if (Arg == "-o") {
45         // Output is specified as -o foo. Skip the next argument too.
46         ++i;
47       }
48       // Else, the output is specified as -ofoo. Just do nothing.
49     }
50     return AdjustedArgs;
51   };
52 }
53 
54 ArgumentsAdjuster getClangStripDependencyFileAdjuster() {
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       // All dependency-file options begin with -M. These include -MM,
60       // -MF, -MG, -MP, -MT, -MQ, -MD, and -MMD.
61       if (!Arg.startswith("-M")) {
62         AdjustedArgs.push_back(Args[i]);
63         continue;
64       }
65 
66       if (Arg == "-MF" || Arg == "-MT" || Arg == "-MQ")
67         // These flags take an argument: -MX foo. Skip the next argument also.
68         ++i;
69     }
70     return AdjustedArgs;
71   };
72 }
73 
74 ArgumentsAdjuster getInsertArgumentAdjuster(const CommandLineArguments &Extra,
75                                             ArgumentInsertPosition Pos) {
76   return [Extra, Pos](const CommandLineArguments &Args, StringRef /*unused*/) {
77     CommandLineArguments Return(Args);
78 
79     CommandLineArguments::iterator I;
80     if (Pos == ArgumentInsertPosition::END) {
81       I = Return.end();
82     } else {
83       I = Return.begin();
84       ++I; // To leave the program name in place
85     }
86 
87     Return.insert(I, Extra.begin(), Extra.end());
88     return Return;
89   };
90 }
91 
92 ArgumentsAdjuster getInsertArgumentAdjuster(const char *Extra,
93                                             ArgumentInsertPosition Pos) {
94   return getInsertArgumentAdjuster(CommandLineArguments(1, Extra), Pos);
95 }
96 
97 ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First,
98                                    ArgumentsAdjuster Second) {
99   if (!First)
100     return Second;
101   if (!Second)
102     return First;
103   return [First, Second](const CommandLineArguments &Args, StringRef File) {
104     return Second(First(Args, File), File);
105   };
106 }
107 
108 } // end namespace tooling
109 } // end namespace clang
110