28
28
#include " llvm/ADT/ArrayRef.h"
29
29
#include " llvm/ADT/SmallString.h"
30
30
#include " llvm/ADT/SmallVector.h"
31
+ #include " llvm/ADT/StringSet.h"
31
32
#include " llvm/Option/ArgList.h"
32
33
#include " llvm/Option/OptTable.h"
33
34
#include " llvm/Option/Option.h"
41
42
#include " llvm/Support/PrettyStackTrace.h"
42
43
#include " llvm/Support/Process.h"
43
44
#include " llvm/Support/Program.h"
44
- #include " llvm/Support/Regex.h"
45
45
#include " llvm/Support/Signals.h"
46
46
#include " llvm/Support/StringSaver.h"
47
47
#include " llvm/Support/TargetSelect.h"
@@ -73,136 +73,8 @@ std::string GetExecutablePath(const char *Argv0, bool CanonicalPrefixes) {
73
73
return llvm::sys::fs::getMainExecutable (Argv0, P);
74
74
}
75
75
76
- static const char *GetStableCStr (std::set<std::string> &SavedStrings,
77
- StringRef S) {
78
- return SavedStrings.insert (std::string (S)).first ->c_str ();
79
- }
80
-
81
- // / ApplyOneQAOverride - Apply a list of edits to the input argument lists.
82
- // /
83
- // / The input string is a space separated list of edits to perform,
84
- // / they are applied in order to the input argument lists. Edits
85
- // / should be one of the following forms:
86
- // /
87
- // / '#': Silence information about the changes to the command line arguments.
88
- // /
89
- // / '^': Add FOO as a new argument at the beginning of the command line.
90
- // /
91
- // / '+': Add FOO as a new argument at the end of the command line.
92
- // /
93
- // / 's/XXX/YYY/': Substitute the regular expression XXX with YYY in the command
94
- // / line.
95
- // /
96
- // / 'xOPTION': Removes all instances of the literal argument OPTION.
97
- // /
98
- // / 'XOPTION': Removes all instances of the literal argument OPTION,
99
- // / and the following argument.
100
- // /
101
- // / 'Ox': Removes all flags matching 'O' or 'O[sz0-9]' and adds 'Ox'
102
- // / at the end of the command line.
103
- // /
104
- // / \param OS - The stream to write edit information to.
105
- // / \param Args - The vector of command line arguments.
106
- // / \param Edit - The override command to perform.
107
- // / \param SavedStrings - Set to use for storing string representations.
108
- static void ApplyOneQAOverride (raw_ostream &OS,
109
- SmallVectorImpl<const char *> &Args,
110
- StringRef Edit,
111
- std::set<std::string> &SavedStrings) {
112
- // This does not need to be efficient.
113
-
114
- if (Edit[0 ] == ' ^' ) {
115
- const char *Str =
116
- GetStableCStr (SavedStrings, Edit.substr (1 ));
117
- OS << " ### Adding argument " << Str << " at beginning\n " ;
118
- Args.insert (Args.begin () + 1 , Str);
119
- } else if (Edit[0 ] == ' +' ) {
120
- const char *Str =
121
- GetStableCStr (SavedStrings, Edit.substr (1 ));
122
- OS << " ### Adding argument " << Str << " at end\n " ;
123
- Args.push_back (Str);
124
- } else if (Edit[0 ] == ' s' && Edit[1 ] == ' /' && Edit.ends_with (" /" ) &&
125
- Edit.slice (2 , Edit.size () - 1 ).contains (' /' )) {
126
- StringRef MatchPattern = Edit.substr (2 ).split (' /' ).first ;
127
- StringRef ReplPattern = Edit.substr (2 ).split (' /' ).second ;
128
- ReplPattern = ReplPattern.slice (0 , ReplPattern.size ()-1 );
129
-
130
- for (unsigned i = 1 , e = Args.size (); i != e; ++i) {
131
- // Ignore end-of-line response file markers
132
- if (Args[i] == nullptr )
133
- continue ;
134
- std::string Repl = llvm::Regex (MatchPattern).sub (ReplPattern, Args[i]);
135
-
136
- if (Repl != Args[i]) {
137
- OS << " ### Replacing '" << Args[i] << " ' with '" << Repl << " '\n " ;
138
- Args[i] = GetStableCStr (SavedStrings, Repl);
139
- }
140
- }
141
- } else if (Edit[0 ] == ' x' || Edit[0 ] == ' X' ) {
142
- auto Option = Edit.substr (1 );
143
- for (unsigned i = 1 ; i < Args.size ();) {
144
- if (Option == Args[i]) {
145
- OS << " ### Deleting argument " << Args[i] << ' \n ' ;
146
- Args.erase (Args.begin () + i);
147
- if (Edit[0 ] == ' X' ) {
148
- if (i < Args.size ()) {
149
- OS << " ### Deleting argument " << Args[i] << ' \n ' ;
150
- Args.erase (Args.begin () + i);
151
- } else
152
- OS << " ### Invalid X edit, end of command line!\n " ;
153
- }
154
- } else
155
- ++i;
156
- }
157
- } else if (Edit[0 ] == ' O' ) {
158
- for (unsigned i = 1 ; i < Args.size ();) {
159
- const char *A = Args[i];
160
- // Ignore end-of-line response file markers
161
- if (A == nullptr )
162
- continue ;
163
- if (A[0 ] == ' -' && A[1 ] == ' O' &&
164
- (A[2 ] == ' \0 ' ||
165
- (A[3 ] == ' \0 ' && (A[2 ] == ' s' || A[2 ] == ' z' ||
166
- (' 0' <= A[2 ] && A[2 ] <= ' 9' ))))) {
167
- OS << " ### Deleting argument " << Args[i] << ' \n ' ;
168
- Args.erase (Args.begin () + i);
169
- } else
170
- ++i;
171
- }
172
- OS << " ### Adding argument " << Edit << " at end\n " ;
173
- Args.push_back (GetStableCStr (SavedStrings, ' -' + Edit.str ()));
174
- } else {
175
- OS << " ### Unrecognized edit: " << Edit << " \n " ;
176
- }
177
- }
178
-
179
- // / ApplyQAOverride - Apply a space separated list of edits to the
180
- // / input argument lists. See ApplyOneQAOverride.
181
- static void ApplyQAOverride (SmallVectorImpl<const char *> &Args,
182
- const char *OverrideStr,
183
- std::set<std::string> &SavedStrings) {
184
- raw_ostream *OS = &llvm::errs ();
185
-
186
- if (OverrideStr[0 ] == ' #' ) {
187
- ++OverrideStr;
188
- OS = &llvm::nulls ();
189
- }
190
-
191
- *OS << " ### CCC_OVERRIDE_OPTIONS: " << OverrideStr << " \n " ;
192
-
193
- // This does not need to be efficient.
194
-
195
- const char *S = OverrideStr;
196
- while (*S) {
197
- const char *End = ::strchr (S, ' ' );
198
- if (!End)
199
- End = S + strlen (S);
200
- if (End != S)
201
- ApplyOneQAOverride (*OS, Args, std::string (S, End), SavedStrings);
202
- S = End;
203
- if (*S != ' \0 ' )
204
- ++S;
205
- }
76
+ static const char *GetStableCStr (llvm::StringSet<> &SavedStrings, StringRef S) {
77
+ return SavedStrings.insert (S).first ->getKeyData ();
206
78
}
207
79
208
80
extern int cc1_main (ArrayRef<const char *> Argv, const char *Argv0,
@@ -215,7 +87,7 @@ extern int cc1gen_reproducer_main(ArrayRef<const char *> Argv,
215
87
216
88
static void insertTargetAndModeArgs (const ParsedClangName &NameParts,
217
89
SmallVectorImpl<const char *> &ArgVector,
218
- std::set<std::string > &SavedStrings) {
90
+ llvm::StringSet< > &SavedStrings) {
219
91
// Put target and mode arguments at the start of argument list so that
220
92
// arguments specified in command line could override them. Avoid putting
221
93
// them at index 0, as an option like '-cc1' must remain the first.
@@ -419,12 +291,13 @@ int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) {
419
291
}
420
292
}
421
293
422
- std::set<std::string > SavedStrings;
294
+ llvm::StringSet< > SavedStrings;
423
295
// Handle CCC_OVERRIDE_OPTIONS, used for editing a command line behind the
424
296
// scenes.
425
297
if (const char *OverrideStr = ::getenv (" CCC_OVERRIDE_OPTIONS" )) {
426
298
// FIXME: Driver shouldn't take extra initial argument.
427
- ApplyQAOverride (Args, OverrideStr, SavedStrings);
299
+ driver::applyOverrideOptions (Args, OverrideStr, SavedStrings,
300
+ &llvm::errs ());
428
301
}
429
302
430
303
std::string Path = GetExecutablePath (ToolContext.Path , CanonicalPrefixes);
0 commit comments