@@ -31,30 +31,27 @@ using namespace swift;
3131
3232static StringRef toStringRef (const SanitizerKind kind) {
3333 switch (kind) {
34- case SanitizerKind::Address:
35- return " address" ;
36- case SanitizerKind::Thread:
37- return " thread" ;
38- case SanitizerKind::Fuzzer:
39- return " fuzzer" ;
40- case SanitizerKind::Undefined:
41- return " undefined" ;
34+ #define SANITIZER (_, kind, name, file ) \
35+ case SanitizerKind::kind: return #name;
36+ #include " swift/Basic/Sanitizers.def"
4237 }
43- llvm_unreachable (" Unsupported sanitizer" );
38+ llvm_unreachable (" Unknown sanitizer" );
4439}
4540
46- static const char * toFileName (const SanitizerKind kind) {
41+ static StringRef toFileName (const SanitizerKind kind) {
4742 switch (kind) {
48- case SanitizerKind::Address:
49- return " asan" ;
50- case SanitizerKind::Thread:
51- return " tsan" ;
52- case SanitizerKind::Fuzzer:
53- return " fuzzer" ;
54- case SanitizerKind::Undefined:
55- return " ubsan" ;
43+ #define SANITIZER (_, kind, name, file ) \
44+ case SanitizerKind::kind: return #file;
45+ #include " swift/Basic/Sanitizers.def"
5646 }
57- llvm_unreachable (" Unsupported sanitizer" );
47+ llvm_unreachable (" Unknown sanitizer" );
48+ }
49+
50+ static Optional<SanitizerKind> parse (const char * arg) {
51+ return llvm::StringSwitch<Optional<SanitizerKind>>(arg)
52+ #define SANITIZER (_, kind, name, file ) .Case(#name, SanitizerKind::kind)
53+ #include " swift/Basic/Sanitizers.def"
54+ .Default (None);
5855}
5956
6057llvm::SanitizerCoverageOptions swift::parseSanitizerCoverageArgValue (
@@ -133,35 +130,34 @@ OptionSet<SanitizerKind> swift::parseSanitizerArgValues(
133130 OptionSet<SanitizerKind> sanitizerSet;
134131
135132 // Find the sanitizer kind.
136- for (int i = 0 , n = A->getNumValues (); i != n; ++i) {
137- auto kind = llvm::StringSwitch<Optional<SanitizerKind>>(A->getValue (i))
138- .Case (" address" , SanitizerKind::Address)
139- .Case (" thread" , SanitizerKind::Thread)
140- .Case (" fuzzer" , SanitizerKind::Fuzzer)
141- .Case (" undefined" , SanitizerKind::Undefined)
142- .Default (None);
143- bool isShared = kind && *kind != SanitizerKind::Fuzzer;
144- if (!kind) {
133+ for (const char *arg : A->getValues ()) {
134+ Optional<SanitizerKind> optKind = parse (arg);
135+
136+ // Unrecognized sanitizer option
137+ if (!optKind.hasValue ()) {
145138 Diags.diagnose (SourceLoc (), diag::error_unsupported_option_argument,
146- A->getOption ().getPrefixedName (), A->getValue (i));
139+ A->getOption ().getPrefixedName (), arg);
140+ continue ;
141+ }
142+ SanitizerKind kind = optKind.getValue ();
143+
144+ // Support is determined by existance of the sanitizer library.
145+ auto fileName = toFileName (kind);
146+ bool isShared = (kind != SanitizerKind::Fuzzer);
147+ bool sanitizerSupported = sanitizerRuntimeLibExists (fileName, isShared);
148+
149+ // TSan is explicitly not supported for 32 bits.
150+ if (kind == SanitizerKind::Thread && !Triple.isArch64Bit ())
151+ sanitizerSupported = false ;
152+
153+ if (!sanitizerSupported) {
154+ SmallString<128 > b;
155+ Diags.diagnose (SourceLoc (), diag::error_unsupported_opt_for_target,
156+ (A->getOption ().getPrefixedName () + toStringRef (kind))
157+ .toStringRef (b),
158+ Triple.getTriple ());
147159 } else {
148- // Support is determined by existance of the sanitizer library.
149- bool sanitizerSupported =
150- sanitizerRuntimeLibExists (toFileName (*kind), isShared);
151-
152- // TSan is explicitly not supported for 32 bits.
153- if (*kind == SanitizerKind::Thread && !Triple.isArch64Bit ())
154- sanitizerSupported = false ;
155-
156- if (!sanitizerSupported) {
157- SmallString<128 > b;
158- Diags.diagnose (SourceLoc (), diag::error_unsupported_opt_for_target,
159- (A->getOption ().getPrefixedName () + toStringRef (*kind))
160- .toStringRef (b),
161- Triple.getTriple ());
162- } else {
163- sanitizerSet |= *kind;
164- }
160+ sanitizerSet |= kind;
165161 }
166162 }
167163
@@ -191,10 +187,12 @@ OptionSet<SanitizerKind> swift::parseSanitizerArgValues(
191187
192188std::string swift::getSanitizerList (const OptionSet<SanitizerKind> &Set) {
193189 std::string list;
194- if (Set & SanitizerKind::Address) list += " address," ;
195- if (Set & SanitizerKind::Thread) list += " thread," ;
196- if (Set & SanitizerKind::Fuzzer) list += " fuzzer," ;
197- if (Set & SanitizerKind::Undefined) list += " undefined," ;
198- if (!list.empty ()) list.pop_back (); // Remove last comma
190+ #define SANITIZER (_, kind, name, file ) \
191+ if (Set & SanitizerKind::kind) list += #name " ," ;
192+ #include " swift/Basic/Sanitizers.def"
193+
194+ if (!list.empty ())
195+ list.pop_back (); // Remove last comma
196+
199197 return list;
200198}
0 commit comments