]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.h
MFC r244628:
[FreeBSD/stable/9.git] / contrib / llvm / tools / clang / lib / Driver / SanitizerArgs.h
1 //===--- SanitizerArgs.h - Arguments for sanitizer tools  -------*- C++ -*-===//
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 #ifndef CLANG_LIB_DRIVER_SANITIZERARGS_H_
10 #define CLANG_LIB_DRIVER_SANITIZERARGS_H_
11
12 #include "clang/Driver/ArgList.h"
13
14 namespace clang {
15 namespace driver {
16
17 class SanitizerArgs {
18   /// Assign ordinals to sanitizer flags. We'll use the ordinal values as
19   /// bit positions within \c Kind.
20   enum SanitizeOrdinal {
21 #define SANITIZER(NAME, ID) SO_##ID,
22 #include "clang/Basic/Sanitizers.def"
23     SO_Count
24   };
25
26   /// Bugs to catch at runtime.
27   enum SanitizeKind {
28 #define SANITIZER(NAME, ID) ID = 1 << SO_##ID,
29 #define SANITIZER_GROUP(NAME, ID, ALIAS) ID = ALIAS,
30 #include "clang/Basic/Sanitizers.def"
31     NeedsAsanRt = Address,
32     NeedsTsanRt = Thread,
33     NeedsUbsanRt = Undefined
34   };
35   unsigned Kind;
36
37  public:
38   SanitizerArgs() : Kind(0) {}
39   /// Parses the sanitizer arguments from an argument list.
40   SanitizerArgs(const Driver &D, const ArgList &Args);
41
42   bool needsAsanRt() const { return Kind & NeedsAsanRt; }
43   bool needsTsanRt() const { return Kind & NeedsTsanRt; }
44   bool needsUbsanRt() const { return Kind & NeedsUbsanRt; }
45
46   bool sanitizesVptr() const { return Kind & Vptr; }
47   
48   void addArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
49     if (!Kind)
50       return;
51     llvm::SmallString<256> SanitizeOpt("-fsanitize=");
52 #define SANITIZER(NAME, ID) \
53     if (Kind & ID) \
54       SanitizeOpt += NAME ",";
55 #include "clang/Basic/Sanitizers.def"
56     SanitizeOpt.pop_back();
57     CmdArgs.push_back(Args.MakeArgString(SanitizeOpt));
58   }
59
60  private:
61   /// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
62   /// Returns a member of the \c SanitizeKind enumeration, or \c 0 if \p Value
63   /// is not known.
64   static unsigned parse(const char *Value) {
65     return llvm::StringSwitch<SanitizeKind>(Value)
66 #define SANITIZER(NAME, ID) .Case(NAME, ID)
67 #define SANITIZER_GROUP(NAME, ID, ALIAS) .Case(NAME, ID)
68 #include "clang/Basic/Sanitizers.def"
69       .Default(SanitizeKind());
70   }
71
72   /// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
73   /// invalid components.
74   static unsigned parse(const Driver &D, const Arg *A) {
75     unsigned Kind = 0;
76     for (unsigned I = 0, N = A->getNumValues(); I != N; ++I) {
77       if (unsigned K = parse(A->getValue(I)))
78         Kind |= K;
79       else
80         D.Diag(diag::err_drv_unsupported_option_argument)
81           << A->getOption().getName() << A->getValue(I);
82     }
83     return Kind;
84   }
85
86   /// Produce an argument string from argument \p A, which shows how it provides
87   /// a value in \p Mask. For instance, the argument
88   /// "-fsanitize=address,alignment" with mask \c NeedsUbsanRt would produce
89   /// "-fsanitize=alignment".
90   static std::string describeSanitizeArg(const ArgList &Args, const Arg *A,
91                                          unsigned Mask) {
92     if (!A->getOption().matches(options::OPT_fsanitize_EQ))
93       return A->getAsString(Args);
94
95     for (unsigned I = 0, N = A->getNumValues(); I != N; ++I)
96       if (parse(A->getValue(I)) & Mask)
97         return std::string("-fsanitize=") + A->getValue(I);
98
99     llvm_unreachable("arg didn't provide expected value");
100   }
101 };
102
103 }  // namespace driver
104 }  // namespace clang
105
106 #endif // CLANG_LIB_DRIVER_SANITIZERARGS_H_