r221558 - Introduce a SanitizerKind enum to LangOptions.

Alexey Samsonov vonosmas at gmail.com
Fri Nov 7 14:29:38 PST 2014


Author: samsonov
Date: Fri Nov  7 16:29:38 2014
New Revision: 221558

URL: http://llvm.org/viewvc/llvm-project?rev=221558&view=rev
Log:
Introduce a SanitizerKind enum to LangOptions.

Use the bitmask to store the set of enabled sanitizers instead of a
bitfield. On the negative side, it makes syntax for querying the
set of enabled sanitizers a bit more clunky. On the positive side, we
will be able to use SanitizerKind to eventually implement the
new semantics for -fsanitize-recover= flag, that would allow us
to make some sanitizers recoverable, and some non-recoverable.

No functionality change.

Modified:
    cfe/trunk/include/clang/Basic/LangOptions.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/Basic/LangOptions.cpp
    cfe/trunk/lib/Basic/Targets.cpp
    cfe/trunk/lib/CodeGen/BackendUtil.cpp
    cfe/trunk/lib/CodeGen/CGBuiltin.cpp
    cfe/trunk/lib/CodeGen/CGCall.cpp
    cfe/trunk/lib/CodeGen/CGClass.cpp
    cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
    cfe/trunk/lib/CodeGen/SanitizerMetadata.cpp
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
    cfe/trunk/lib/Lex/PPMacroExpansion.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp

Modified: cfe/trunk/include/clang/Basic/LangOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.h?rev=221558&r1=221557&r2=221558&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/LangOptions.h (original)
+++ cfe/trunk/include/clang/Basic/LangOptions.h Fri Nov  7 16:29:38 2014
@@ -23,9 +23,23 @@
 
 namespace clang {
 
-struct SanitizerOptions {
-#define SANITIZER(NAME, ID) unsigned ID : 1;
+enum class SanitizerKind {
+#define SANITIZER(NAME, ID) ID,
 #include "clang/Basic/Sanitizers.def"
+  Unknown
+};
+
+class SanitizerOptions {
+  /// \brief Bitmask of enabled sanitizers.
+  unsigned Kind;
+public:
+  SanitizerOptions();
+
+  /// \brief Check if a certain sanitizer is enabled.
+  bool has(SanitizerKind K) const;
+  /// \brief Enable or disable a certain sanitizer.
+  void set(SanitizerKind K, bool Value);
+
   /// \brief Controls how agressive is asan field padding (0: none, 1: least
   /// aggressive, 2: more aggressive).
   unsigned SanitizeAddressFieldPadding : 2;
@@ -34,8 +48,6 @@ struct SanitizerOptions {
   /// (files, functions, variables) should not be instrumented.
   std::string BlacklistFile;
 
-  SanitizerOptions();
-
   /// \brief Disable all sanitizers.
   void clear();
 };

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=221558&r1=221557&r2=221558&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Fri Nov  7 16:29:38 2014
@@ -3627,7 +3627,7 @@ void RecordDecl::LoadFieldsFromExternalS
 
 bool RecordDecl::mayInsertExtraPadding(bool EmitRemark) const {
   ASTContext &Context = getASTContext();
-  if (!Context.getLangOpts().Sanitize.Address ||
+  if (!Context.getLangOpts().Sanitize.has(SanitizerKind::Address) ||
       !Context.getLangOpts().Sanitize.SanitizeAddressFieldPadding)
     return false;
   const auto &Blacklist = Context.getSanitizerBlacklist();

Modified: cfe/trunk/lib/Basic/LangOptions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/LangOptions.cpp?rev=221558&r1=221557&r2=221558&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/LangOptions.cpp (original)
+++ cfe/trunk/lib/Basic/LangOptions.cpp Fri Nov  7 16:29:38 2014
@@ -14,10 +14,17 @@
 
 using namespace clang;
 
-SanitizerOptions::SanitizerOptions() {
-#define SANITIZER(NAME, ID) ID = 0;
-#include "clang/Basic/Sanitizers.def"
-  SanitizeAddressFieldPadding = 0;
+SanitizerOptions::SanitizerOptions()
+    : Kind(0), SanitizeAddressFieldPadding(0) {}
+
+bool SanitizerOptions::has(SanitizerKind K) const {
+  unsigned Bit = static_cast<unsigned>(K);
+  return Kind & (1 << Bit);
+}
+
+void SanitizerOptions::set(SanitizerKind K, bool Value) {
+  unsigned Bit = static_cast<unsigned>(K);
+  Kind = Value ? (Kind | (1 << Bit)) : (Kind & ~(1 << Bit));
 }
 
 void SanitizerOptions::clear() {

Modified: cfe/trunk/lib/Basic/Targets.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=221558&r1=221557&r2=221558&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/Targets.cpp (original)
+++ cfe/trunk/lib/Basic/Targets.cpp Fri Nov  7 16:29:38 2014
@@ -94,7 +94,8 @@ static void getDarwinDefines(MacroBuilde
   Builder.defineMacro("OBJC_NEW_PROPERTIES");
   // AddressSanitizer doesn't play well with source fortification, which is on
   // by default on Darwin.
-  if (Opts.Sanitize.Address) Builder.defineMacro("_FORTIFY_SOURCE", "0");
+  if (Opts.Sanitize.has(SanitizerKind::Address))
+    Builder.defineMacro("_FORTIFY_SOURCE", "0");
 
   if (!Opts.ObjCAutoRefCount) {
     // __weak is always defined, for use in blocks and with objc pointers.

Modified: cfe/trunk/lib/CodeGen/BackendUtil.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/BackendUtil.cpp?rev=221558&r1=221557&r2=221558&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/BackendUtil.cpp (original)
+++ cfe/trunk/lib/CodeGen/BackendUtil.cpp Fri Nov  7 16:29:38 2014
@@ -267,35 +267,35 @@ void EmitAssemblyHelper::CreatePasses()
                            addObjCARCOptPass);
   }
 
-  if (LangOpts.Sanitize.LocalBounds) {
+  if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) {
     PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
                            addBoundsCheckingPass);
     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                            addBoundsCheckingPass);
   }
 
-  if (LangOpts.Sanitize.Address) {
+  if (LangOpts.Sanitize.has(SanitizerKind::Address)) {
     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                            addAddressSanitizerPasses);
     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                            addAddressSanitizerPasses);
   }
 
-  if (LangOpts.Sanitize.Memory) {
+  if (LangOpts.Sanitize.has(SanitizerKind::Memory)) {
     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                            addMemorySanitizerPass);
     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                            addMemorySanitizerPass);
   }
 
-  if (LangOpts.Sanitize.Thread) {
+  if (LangOpts.Sanitize.has(SanitizerKind::Thread)) {
     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                            addThreadSanitizerPass);
     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                            addThreadSanitizerPass);
   }
 
-  if (LangOpts.Sanitize.DataFlow) {
+  if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) {
     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                            addDataFlowSanitizerPass);
     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,

Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=221558&r1=221557&r2=221558&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Fri Nov  7 16:29:38 2014
@@ -473,7 +473,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(
     return RValue::get(Builder.CreateCall(F));
   }
   case Builtin::BI__builtin_unreachable: {
-    if (SanOpts.Unreachable) {
+    if (SanOpts.has(SanitizerKind::Unreachable)) {
       SanitizerScope SanScope(this);
       EmitCheck(Builder.getFalse(), "builtin_unreachable",
                 EmitCheckSourceLocation(E->getExprLoc()),

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=221558&r1=221557&r2=221558&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Fri Nov  7 16:29:38 2014
@@ -2291,7 +2291,7 @@ void CodeGenFunction::EmitFunctionEpilog
 
   llvm::Instruction *Ret;
   if (RV) {
-    if (SanOpts.ReturnsNonnullAttribute) {
+    if (SanOpts.has(SanitizerKind::ReturnsNonnullAttribute)) {
       if (auto RetNNAttr = CurGD.getDecl()->getAttr<ReturnsNonNullAttr>()) {
         SanitizerScope SanScope(this);
         llvm::Value *Cond = Builder.CreateICmpNE(
@@ -2618,7 +2618,7 @@ void CallArgList::freeArgumentMemory(Cod
 static void emitNonNullArgCheck(CodeGenFunction &CGF, RValue RV,
                                 QualType ArgType, SourceLocation ArgLoc,
                                 const FunctionDecl *FD, unsigned ParmNum) {
-  if (!CGF.SanOpts.NonnullAttribute || !FD)
+  if (!CGF.SanOpts.has(SanitizerKind::NonnullAttribute) || !FD)
     return;
   auto PVD = ParmNum < FD->getNumParams() ? FD->getParamDecl(ParmNum) : nullptr;
   unsigned ArgNo = PVD ? PVD->getFunctionScopeIndex() : ParmNum;

Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=221558&r1=221557&r2=221558&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Fri Nov  7 16:29:38 2014
@@ -834,8 +834,8 @@ namespace {
   public:
     explicit CopyingValueRepresentation(CodeGenFunction &CGF)
         : CGF(CGF), OldSanOpts(CGF.SanOpts) {
-      CGF.SanOpts.Bool = false;
-      CGF.SanOpts.Enum = false;
+      CGF.SanOpts.set(SanitizerKind::Bool, false);
+      CGF.SanOpts.set(SanitizerKind::Enum, false);
     }
     ~CopyingValueRepresentation() {
       CGF.SanOpts = OldSanOpts;

Modified: cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=221558&r1=221557&r2=221558&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Fri Nov  7 16:29:38 2014
@@ -237,11 +237,11 @@ llvm::Function *CodeGenModule::CreateGlo
     Fn->setDoesNotThrow();
 
   if (!isInSanitizerBlacklist(Fn, Loc)) {
-    if (getLangOpts().Sanitize.Address)
+    if (getLangOpts().Sanitize.has(SanitizerKind::Address))
       Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
-    if (getLangOpts().Sanitize.Thread)
+    if (getLangOpts().Sanitize.has(SanitizerKind::Thread))
       Fn->addFnAttr(llvm::Attribute::SanitizeThread);
-    if (getLangOpts().Sanitize.Memory)
+    if (getLangOpts().Sanitize.has(SanitizerKind::Memory))
       Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
   }
 

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=221558&r1=221557&r2=221558&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Fri Nov  7 16:29:38 2014
@@ -457,8 +457,10 @@ static llvm::Value *emitHash16Bytes(CGBu
 }
 
 bool CodeGenFunction::sanitizePerformTypeCheck() const {
-  return SanOpts.Null | SanOpts.Alignment | SanOpts.ObjectSize |
-         SanOpts.Vptr;
+  return SanOpts.has(SanitizerKind::Null) |
+         SanOpts.has(SanitizerKind::Alignment) |
+         SanOpts.has(SanitizerKind::ObjectSize) |
+         SanOpts.has(SanitizerKind::Vptr);
 }
 
 void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
@@ -480,7 +482,8 @@ void CodeGenFunction::EmitTypeCheck(Type
 
   bool AllowNullPointers = TCK == TCK_DowncastPointer || TCK == TCK_Upcast ||
                            TCK == TCK_UpcastToVirtualBase;
-  if ((SanOpts.Null || AllowNullPointers) && !SkipNullCheck) {
+  if ((SanOpts.has(SanitizerKind::Null) || AllowNullPointers) &&
+      !SkipNullCheck) {
     // The glvalue must not be an empty glvalue.
     Cond = Builder.CreateICmpNE(
         Address, llvm::Constant::getNullValue(Address->getType()));
@@ -496,7 +499,7 @@ void CodeGenFunction::EmitTypeCheck(Type
     }
   }
 
-  if (SanOpts.ObjectSize && !Ty->isIncompleteType()) {
+  if (SanOpts.has(SanitizerKind::ObjectSize) && !Ty->isIncompleteType()) {
     uint64_t Size = getContext().getTypeSizeInChars(Ty).getQuantity();
 
     // The glvalue must refer to a large enough storage region.
@@ -515,7 +518,7 @@ void CodeGenFunction::EmitTypeCheck(Type
 
   uint64_t AlignVal = 0;
 
-  if (SanOpts.Alignment) {
+  if (SanOpts.has(SanitizerKind::Alignment)) {
     AlignVal = Alignment.getQuantity();
     if (!Ty->isIncompleteType() && !AlignVal)
       AlignVal = getContext().getTypeAlignInChars(Ty).getQuantity();
@@ -550,7 +553,7 @@ void CodeGenFunction::EmitTypeCheck(Type
   //    -- the [pointer or glvalue] is used to access a non-static data member
   //       or call a non-static member function
   CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
-  if (SanOpts.Vptr &&
+  if (SanOpts.has(SanitizerKind::Vptr) &&
       (TCK == TCK_MemberAccess || TCK == TCK_MemberCall ||
        TCK == TCK_DowncastPointer || TCK == TCK_DowncastReference ||
        TCK == TCK_UpcastToVirtualBase) &&
@@ -673,7 +676,7 @@ static llvm::Value *getArrayIndexingBoun
 void CodeGenFunction::EmitBoundsCheck(const Expr *E, const Expr *Base,
                                       llvm::Value *Index, QualType IndexType,
                                       bool Accessed) {
-  assert(SanOpts.ArrayBounds &&
+  assert(SanOpts.has(SanitizerKind::ArrayBounds) &&
          "should not be called unless adding bounds checks");
   SanitizerScope SanScope(this);
 
@@ -775,7 +778,7 @@ LValue CodeGenFunction::EmitUnsupportedL
 
 LValue CodeGenFunction::EmitCheckedLValue(const Expr *E, TypeCheckKind TCK) {
   LValue LV;
-  if (SanOpts.ArrayBounds && isa<ArraySubscriptExpr>(E))
+  if (SanOpts.has(SanitizerKind::ArrayBounds) && isa<ArraySubscriptExpr>(E))
     LV = EmitArraySubscriptExpr(cast<ArraySubscriptExpr>(E), /*Accessed*/true);
   else
     LV = EmitLValue(E);
@@ -1148,8 +1151,8 @@ llvm::Value *CodeGenFunction::EmitLoadOf
       CGM.DecorateInstruction(Load, TBAAPath, false/*ConvertTypeToTag*/);
   }
 
-  if ((SanOpts.Bool && hasBooleanRepresentation(Ty)) ||
-      (SanOpts.Enum && Ty->getAs<EnumType>())) {
+  if ((SanOpts.has(SanitizerKind::Bool) && hasBooleanRepresentation(Ty)) ||
+      (SanOpts.has(SanitizerKind::Enum) && Ty->getAs<EnumType>())) {
     SanitizerScope SanScope(this);
     llvm::APInt Min, End;
     if (getRangeForType(*this, Ty, Min, End, true)) {
@@ -2291,7 +2294,7 @@ LValue CodeGenFunction::EmitArraySubscri
   QualType IdxTy  = E->getIdx()->getType();
   bool IdxSigned = IdxTy->isSignedIntegerOrEnumerationType();
 
-  if (SanOpts.ArrayBounds)
+  if (SanOpts.has(SanitizerKind::ArrayBounds))
     EmitBoundsCheck(E, E->getBase(), Idx, IdxTy, Accessed);
 
   // If the base is a vector type, then we are forming a vector element lvalue
@@ -3222,7 +3225,7 @@ RValue CodeGenFunction::EmitCall(QualTyp
   if (const FunctionDecl* FD = dyn_cast_or_null<const FunctionDecl>(TargetDecl))
     ForceColumnInfo = FD->isInlineSpecified();
 
-  if (getLangOpts().CPlusPlus && SanOpts.Function &&
+  if (getLangOpts().CPlusPlus && SanOpts.has(SanitizerKind::Function) &&
       (!TargetDecl || !isa<FunctionDecl>(TargetDecl))) {
     if (llvm::Constant *PrefixSig =
             CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) {

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=221558&r1=221557&r2=221558&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Fri Nov  7 16:29:38 2014
@@ -452,7 +452,7 @@ public:
       case LangOptions::SOB_Defined:
         return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
       case LangOptions::SOB_Undefined:
-        if (!CGF.SanOpts.SignedIntegerOverflow)
+        if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
           return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
         // Fall through.
       case LangOptions::SOB_Trapping:
@@ -460,7 +460,8 @@ public:
       }
     }
 
-    if (Ops.Ty->isUnsignedIntegerType() && CGF.SanOpts.UnsignedIntegerOverflow)
+    if (Ops.Ty->isUnsignedIntegerType() &&
+        CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow))
       return EmitOverflowCheckedBinOp(Ops);
 
     if (Ops.LHS->getType()->isFPOrFPVectorTy())
@@ -810,7 +811,7 @@ Value *ScalarExprEmitter::EmitScalarConv
 
   // An overflowing conversion has undefined behavior if either the source type
   // or the destination type is a floating-point type.
-  if (CGF.SanOpts.FloatCastOverflow &&
+  if (CGF.SanOpts.has(SanitizerKind::FloatCastOverflow) &&
       (OrigSrcType->isFloatingType() || DstType->isFloatingType()))
     EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType,
                              DstTy);
@@ -1120,7 +1121,7 @@ Value *ScalarExprEmitter::VisitArraySubs
   Value *Idx  = Visit(E->getIdx());
   QualType IdxTy = E->getIdx()->getType();
 
-  if (CGF.SanOpts.ArrayBounds)
+  if (CGF.SanOpts.has(SanitizerKind::ArrayBounds))
     CGF.EmitBoundsCheck(E, E->getBase(), Idx, IdxTy, /*Accessed*/true);
 
   return Builder.CreateExtractElement(Base, Idx, "vecext");
@@ -1572,7 +1573,7 @@ EmitAddConsiderOverflowBehavior(const Un
   case LangOptions::SOB_Defined:
     return Builder.CreateAdd(InVal, NextVal, IsInc ? "inc" : "dec");
   case LangOptions::SOB_Undefined:
-    if (!CGF.SanOpts.SignedIntegerOverflow)
+    if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
       return Builder.CreateNSWAdd(InVal, NextVal, IsInc ? "inc" : "dec");
     // Fall through.
   case LangOptions::SOB_Trapping:
@@ -1620,9 +1621,9 @@ ScalarExprEmitter::EmitScalarPrePostIncD
     // checking, and fall into the slow path with the atomic cmpxchg loop.
     if (!type->isBooleanType() && type->isIntegerType() &&
         !(type->isUnsignedIntegerType() &&
-         CGF.SanOpts.UnsignedIntegerOverflow) &&
+          CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) &&
         CGF.getLangOpts().getSignedOverflowBehavior() !=
-         LangOptions::SOB_Trapping) {
+            LangOptions::SOB_Trapping) {
       llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
         llvm::AtomicRMWInst::Sub;
       llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
@@ -1671,7 +1672,7 @@ ScalarExprEmitter::EmitScalarPrePostIncD
     if (CanOverflow && type->isSignedIntegerOrEnumerationType()) {
       value = EmitAddConsiderOverflowBehavior(E, value, amt, isInc);
     } else if (CanOverflow && type->isUnsignedIntegerType() &&
-               CGF.SanOpts.UnsignedIntegerOverflow) {
+               CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) {
       BinOpInfo BinOp;
       BinOp.LHS = value;
       BinOp.RHS = llvm::ConstantInt::get(value->getType(), 1, false);
@@ -2065,10 +2066,10 @@ LValue ScalarExprEmitter::EmitCompoundAs
   if (const AtomicType *atomicTy = LHSTy->getAs<AtomicType>()) {
     QualType type = atomicTy->getValueType();
     if (!type->isBooleanType() && type->isIntegerType() &&
-         !(type->isUnsignedIntegerType() &&
-          CGF.SanOpts.UnsignedIntegerOverflow) &&
-         CGF.getLangOpts().getSignedOverflowBehavior() !=
-          LangOptions::SOB_Trapping) {
+        !(type->isUnsignedIntegerType() &&
+          CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) &&
+        CGF.getLangOpts().getSignedOverflowBehavior() !=
+            LangOptions::SOB_Trapping) {
       llvm::AtomicRMWInst::BinOp aop = llvm::AtomicRMWInst::BAD_BINOP;
       switch (OpInfo.Opcode) {
         // We don't have atomicrmw operands for *, %, /, <<, >>
@@ -2179,10 +2180,10 @@ void ScalarExprEmitter::EmitUndefinedBeh
     const BinOpInfo &Ops, llvm::Value *Zero, bool isDiv) {
   llvm::Value *Cond = nullptr;
 
-  if (CGF.SanOpts.IntegerDivideByZero)
+  if (CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero))
     Cond = Builder.CreateICmpNE(Ops.RHS, Zero);
 
-  if (CGF.SanOpts.SignedIntegerOverflow &&
+  if (CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow) &&
       Ops.Ty->hasSignedIntegerRepresentation()) {
     llvm::IntegerType *Ty = cast<llvm::IntegerType>(Zero->getType());
 
@@ -2203,12 +2204,12 @@ void ScalarExprEmitter::EmitUndefinedBeh
 Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
   {
     CodeGenFunction::SanitizerScope SanScope(&CGF);
-    if ((CGF.SanOpts.IntegerDivideByZero ||
-         CGF.SanOpts.SignedIntegerOverflow) &&
+    if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) ||
+         CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
         Ops.Ty->isIntegerType()) {
       llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
       EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, true);
-    } else if (CGF.SanOpts.FloatDivideByZero &&
+    } else if (CGF.SanOpts.has(SanitizerKind::FloatDivideByZero) &&
                Ops.Ty->isRealFloatingType()) {
       llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
       EmitBinOpCheck(Builder.CreateFCmpUNE(Ops.RHS, Zero), Ops);
@@ -2235,7 +2236,7 @@ Value *ScalarExprEmitter::EmitDiv(const
 
 Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) {
   // Rem in C can't be a floating point type: C99 6.5.5p2.
-  if (CGF.SanOpts.IntegerDivideByZero) {
+  if (CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero)) {
     CodeGenFunction::SanitizerScope SanScope(&CGF);
     llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
 
@@ -2294,7 +2295,7 @@ Value *ScalarExprEmitter::EmitOverflowCh
   if (handlerName->empty()) {
     // If the signed-integer-overflow sanitizer is enabled, emit a call to its
     // runtime. Otherwise, this is a -ftrapv check, so just emit a trap.
-    if (!isSigned || CGF.SanOpts.SignedIntegerOverflow) {
+    if (!isSigned || CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) {
       CodeGenFunction::SanitizerScope SanScope(&CGF);
       EmitBinOpCheck(Builder.CreateNot(overflow), Ops);
     } else
@@ -2382,7 +2383,7 @@ static Value *emitPointerArithmetic(Code
   if (isSubtraction)
     index = CGF.Builder.CreateNeg(index, "idx.neg");
 
-  if (CGF.SanOpts.ArrayBounds)
+  if (CGF.SanOpts.has(SanitizerKind::ArrayBounds))
     CGF.EmitBoundsCheck(op.E, pointerOperand, index, indexOperand->getType(),
                         /*Accessed*/ false);
 
@@ -2522,7 +2523,7 @@ Value *ScalarExprEmitter::EmitAdd(const
     case LangOptions::SOB_Defined:
       return Builder.CreateAdd(op.LHS, op.RHS, "add");
     case LangOptions::SOB_Undefined:
-      if (!CGF.SanOpts.SignedIntegerOverflow)
+      if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
         return Builder.CreateNSWAdd(op.LHS, op.RHS, "add");
       // Fall through.
     case LangOptions::SOB_Trapping:
@@ -2530,7 +2531,8 @@ Value *ScalarExprEmitter::EmitAdd(const
     }
   }
 
-  if (op.Ty->isUnsignedIntegerType() && CGF.SanOpts.UnsignedIntegerOverflow)
+  if (op.Ty->isUnsignedIntegerType() &&
+      CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow))
     return EmitOverflowCheckedBinOp(op);
 
   if (op.LHS->getType()->isFPOrFPVectorTy()) {
@@ -2552,7 +2554,7 @@ Value *ScalarExprEmitter::EmitSub(const
       case LangOptions::SOB_Defined:
         return Builder.CreateSub(op.LHS, op.RHS, "sub");
       case LangOptions::SOB_Undefined:
-        if (!CGF.SanOpts.SignedIntegerOverflow)
+        if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
           return Builder.CreateNSWSub(op.LHS, op.RHS, "sub");
         // Fall through.
       case LangOptions::SOB_Trapping:
@@ -2560,7 +2562,8 @@ Value *ScalarExprEmitter::EmitSub(const
       }
     }
 
-    if (op.Ty->isUnsignedIntegerType() && CGF.SanOpts.UnsignedIntegerOverflow)
+    if (op.Ty->isUnsignedIntegerType() &&
+        CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow))
       return EmitOverflowCheckedBinOp(op);
 
     if (op.LHS->getType()->isFPOrFPVectorTy()) {
@@ -2647,7 +2650,7 @@ Value *ScalarExprEmitter::EmitShl(const
   if (Ops.LHS->getType() != RHS->getType())
     RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
 
-  if (CGF.SanOpts.Shift && !CGF.getLangOpts().OpenCL &&
+  if (CGF.SanOpts.has(SanitizerKind::Shift) && !CGF.getLangOpts().OpenCL &&
       isa<llvm::IntegerType>(Ops.LHS->getType())) {
     CodeGenFunction::SanitizerScope SanScope(&CGF);
     llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, RHS);
@@ -2700,7 +2703,7 @@ Value *ScalarExprEmitter::EmitShr(const
   if (Ops.LHS->getType() != RHS->getType())
     RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
 
-  if (CGF.SanOpts.Shift && !CGF.getLangOpts().OpenCL &&
+  if (CGF.SanOpts.has(SanitizerKind::Shift) && !CGF.getLangOpts().OpenCL &&
       isa<llvm::IntegerType>(Ops.LHS->getType())) {
     CodeGenFunction::SanitizerScope SanScope(&CGF);
     EmitBinOpCheck(Builder.CreateICmpULE(RHS, GetWidthMinusOneValue(Ops.LHS, RHS)), Ops);

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=221558&r1=221557&r2=221558&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Fri Nov  7 16:29:38 2014
@@ -604,7 +604,7 @@ void CodeGenFunction::StartFunction(Glob
 
   // If we are checking function types, emit a function type signature as
   // prefix data.
-  if (getLangOpts().CPlusPlus && SanOpts.Function) {
+  if (getLangOpts().CPlusPlus && SanOpts.has(SanitizerKind::Function)) {
     if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
       if (llvm::Constant *PrefixSig =
               CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) {
@@ -897,7 +897,7 @@ void CodeGenFunction::GenerateCode(Globa
   //   function call is used by the caller, the behavior is undefined.
   if (getLangOpts().CPlusPlus && !FD->hasImplicitReturnZero() && !SawAsmBlock &&
       !FD->getReturnType()->isVoidType() && Builder.GetInsertBlock()) {
-    if (SanOpts.Return) {
+    if (SanOpts.has(SanitizerKind::Return)) {
       SanitizerScope SanScope(this);
       EmitCheck(Builder.getFalse(), "missing_return",
                 EmitCheckSourceLocation(FD->getLocation()),
@@ -1552,7 +1552,7 @@ void CodeGenFunction::EmitVariablyModifi
           //   If the size is an expression that is not an integer constant
           //   expression [...] each time it is evaluated it shall have a value
           //   greater than zero.
-          if (SanOpts.VLABound &&
+          if (SanOpts.has(SanitizerKind::VLABound) &&
               size->getType()->isSignedIntegerType()) {
             SanitizerScope SanScope(this);
             llvm::Value *Zero = llvm::Constant::getNullValue(Size->getType());

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=221558&r1=221557&r2=221558&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Nov  7 16:29:38 2014
@@ -120,7 +120,7 @@ CodeGenModule::CodeGenModule(ASTContext
     createCUDARuntime();
 
   // Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0.
-  if (LangOpts.Sanitize.Thread ||
+  if (LangOpts.Sanitize.has(SanitizerKind::Thread) ||
       (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0))
     TBAA = new CodeGenTBAA(Context, VMContext, CodeGenOpts, getLangOpts(),
                            getCXXABI().getMangleContext());
@@ -743,13 +743,16 @@ void CodeGenModule::SetLLVMFunctionAttri
   if (!isInSanitizerBlacklist(F, D->getLocation())) {
     // When AddressSanitizer is enabled, set SanitizeAddress attribute
     // unless __attribute__((no_sanitize_address)) is used.
-    if (LangOpts.Sanitize.Address && !D->hasAttr<NoSanitizeAddressAttr>())
+    if (LangOpts.Sanitize.has(SanitizerKind::Address) &&
+        !D->hasAttr<NoSanitizeAddressAttr>())
       B.addAttribute(llvm::Attribute::SanitizeAddress);
     // Same for ThreadSanitizer and __attribute__((no_sanitize_thread))
-    if (LangOpts.Sanitize.Thread && !D->hasAttr<NoSanitizeThreadAttr>())
+    if (LangOpts.Sanitize.has(SanitizerKind::Thread) &&
+        !D->hasAttr<NoSanitizeThreadAttr>())
       B.addAttribute(llvm::Attribute::SanitizeThread);
     // Same for MemorySanitizer and __attribute__((no_sanitize_memory))
-    if (LangOpts.Sanitize.Memory && !D->hasAttr<NoSanitizeMemoryAttr>())
+    if (LangOpts.Sanitize.has(SanitizerKind::Memory) &&
+        !D->hasAttr<NoSanitizeMemoryAttr>())
       B.addAttribute(llvm::Attribute::SanitizeMemory);
   }
 
@@ -1190,7 +1193,7 @@ bool CodeGenModule::isInSanitizerBlackli
                                            SourceLocation Loc, QualType Ty,
                                            StringRef Category) const {
   // For now globals can be blacklisted only in ASan.
-  if (!LangOpts.Sanitize.Address)
+  if (!LangOpts.Sanitize.has(SanitizerKind::Address))
     return false;
   const auto &SanitizerBL = getContext().getSanitizerBlacklist();
   if (SanitizerBL.isBlacklistedGlobal(GV->getName(), Category))
@@ -2819,7 +2822,8 @@ CodeGenModule::GetAddrOfConstantStringFr
   // Mangle the string literal if the ABI allows for it.  However, we cannot
   // do this if  we are compiling with ASan or -fwritable-strings because they
   // rely on strings having normal linkage.
-  if (!LangOpts.WritableStrings && !LangOpts.Sanitize.Address &&
+  if (!LangOpts.WritableStrings &&
+      !LangOpts.Sanitize.has(SanitizerKind::Address) &&
       getCXXABI().getMangleContext().shouldMangleStringLiteral(S)) {
     llvm::raw_svector_ostream Out(MangledNameBuffer);
     getCXXABI().getMangleContext().mangleStringLiteral(S, Out);

Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=221558&r1=221557&r2=221558&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Fri Nov  7 16:29:38 2014
@@ -1493,7 +1493,7 @@ llvm::Value *ItaniumCXXABI::InitializeAr
   llvm::Value *NumElementsPtr =
       CGF.Builder.CreateBitCast(CookiePtr, NumElementsTy);
   llvm::Instruction *SI = CGF.Builder.CreateStore(NumElements, NumElementsPtr);
-  if (CGM.getLangOpts().Sanitize.Address && AS == 0 &&
+  if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
       expr->getOperatorNew()->isReplaceableGlobalAllocationFunction()) {
     // The store to the CookiePtr does not need to be instrumented.
     CGM.getSanitizerMetadata()->disableSanitizerForInstruction(SI);
@@ -1525,7 +1525,7 @@ llvm::Value *ItaniumCXXABI::readArrayCoo
   unsigned AS = allocPtr->getType()->getPointerAddressSpace();
   numElementsPtr = 
     CGF.Builder.CreateBitCast(numElementsPtr, CGF.SizeTy->getPointerTo(AS));
-  if (!CGM.getLangOpts().Sanitize.Address || AS != 0)
+  if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
     return CGF.Builder.CreateLoad(numElementsPtr);
   // In asan mode emit a function call instead of a regular load and let the
   // run-time deal with it: if the shadow is properly poisoned return the

Modified: cfe/trunk/lib/CodeGen/SanitizerMetadata.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/SanitizerMetadata.cpp?rev=221558&r1=221557&r2=221558&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/SanitizerMetadata.cpp (original)
+++ cfe/trunk/lib/CodeGen/SanitizerMetadata.cpp Fri Nov  7 16:29:38 2014
@@ -25,7 +25,7 @@ void SanitizerMetadata::reportGlobalToAS
                                            SourceLocation Loc, StringRef Name,
                                            QualType Ty, bool IsDynInit,
                                            bool IsBlacklisted) {
-  if (!CGM.getLangOpts().Sanitize.Address)
+  if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address))
     return;
   IsDynInit &= !CGM.isInSanitizerBlacklist(GV, Loc, Ty, "init");
   IsBlacklisted |= CGM.isInSanitizerBlacklist(GV, Loc, Ty);
@@ -54,7 +54,7 @@ void SanitizerMetadata::reportGlobalToAS
 
 void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
                                            const VarDecl &D, bool IsDynInit) {
-  if (!CGM.getLangOpts().Sanitize.Address)
+  if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address))
     return;
   std::string QualName;
   llvm::raw_string_ostream OS(QualName);
@@ -65,7 +65,7 @@ void SanitizerMetadata::reportGlobalToAS
 void SanitizerMetadata::disableSanitizerForGlobal(llvm::GlobalVariable *GV) {
   // For now, just make sure the global is not modified by the ASan
   // instrumentation.
-  if (CGM.getLangOpts().Sanitize.Address)
+  if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address))
     reportGlobalToASan(GV, SourceLocation(), "", QualType(), false, true);
 }
 

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=221558&r1=221557&r2=221558&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Fri Nov  7 16:29:38 2014
@@ -1610,33 +1610,16 @@ static void ParseLangArgs(LangOptions &O
 
   // Parse -fsanitize= arguments.
   std::vector<std::string> Sanitizers = Args.getAllArgValues(OPT_fsanitize_EQ);
-  for (unsigned I = 0, N = Sanitizers.size(); I != N; ++I) {
-    // Since the Opts.Sanitize* values are bitfields, it's a little tricky to
-    // efficiently map string values to them. Perform the mapping indirectly:
-    // convert strings to enumerated values, then switch over the enum to set
-    // the right bitfield value.
-    enum Sanitizer {
-#define SANITIZER(NAME, ID) \
-      ID,
+  for (const auto &Sanitizer : Sanitizers) {
+    SanitizerKind K = llvm::StringSwitch<SanitizerKind>(Sanitizer)
+#define SANITIZER(NAME, ID) .Case(NAME, SanitizerKind::ID)
 #include "clang/Basic/Sanitizers.def"
-      Unknown
-    };
-    switch (llvm::StringSwitch<unsigned>(Sanitizers[I])
-#define SANITIZER(NAME, ID) \
-              .Case(NAME, ID)
-#include "clang/Basic/Sanitizers.def"
-              .Default(Unknown)) {
-#define SANITIZER(NAME, ID) \
-    case ID: \
-      Opts.Sanitize.ID = true; \
-      break;
-#include "clang/Basic/Sanitizers.def"
-
-    case Unknown:
+        .Default(SanitizerKind::Unknown);
+    if (K == SanitizerKind::Unknown)
       Diags.Report(diag::err_drv_invalid_value)
-        << "-fsanitize=" << Sanitizers[I];
-      break;
-    }
+        << "-fsanitize=" << Sanitizer;
+    else
+      Opts.Sanitize.set(K, true);
   }
   // -fsanitize-address-field-padding=N has to be a LangOpt, parse it here.
   Opts.Sanitize.SanitizeAddressFieldPadding =

Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=221558&r1=221557&r2=221558&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Fri Nov  7 16:29:38 2014
@@ -860,144 +860,145 @@ static bool HasFeature(const Preprocesso
     Feature = Feature.substr(2, Feature.size() - 4);
 
   return llvm::StringSwitch<bool>(Feature)
-           .Case("address_sanitizer", LangOpts.Sanitize.Address)
-           .Case("attribute_analyzer_noreturn", true)
-           .Case("attribute_availability", true)
-           .Case("attribute_availability_with_message", true)
-           .Case("attribute_cf_returns_not_retained", true)
-           .Case("attribute_cf_returns_retained", true)
-           .Case("attribute_deprecated_with_message", true)
-           .Case("attribute_ext_vector_type", true)
-           .Case("attribute_ns_returns_not_retained", true)
-           .Case("attribute_ns_returns_retained", true)
-           .Case("attribute_ns_consumes_self", true)
-           .Case("attribute_ns_consumed", true)
-           .Case("attribute_cf_consumed", true)
-           .Case("attribute_objc_ivar_unused", true)
-           .Case("attribute_objc_method_family", true)
-           .Case("attribute_overloadable", true)
-           .Case("attribute_unavailable_with_message", true)
-           .Case("attribute_unused_on_fields", true)
-           .Case("blocks", LangOpts.Blocks)
-           .Case("c_thread_safety_attributes", true)
-           .Case("cxx_exceptions", LangOpts.CXXExceptions)
-           .Case("cxx_rtti", LangOpts.RTTI)
-           .Case("enumerator_attributes", true)
-           .Case("memory_sanitizer", LangOpts.Sanitize.Memory)
-           .Case("thread_sanitizer", LangOpts.Sanitize.Thread)
-           .Case("dataflow_sanitizer", LangOpts.Sanitize.DataFlow)
-           // Objective-C features
-           .Case("objc_arr", LangOpts.ObjCAutoRefCount) // FIXME: REMOVE?
-           .Case("objc_arc", LangOpts.ObjCAutoRefCount)
-           .Case("objc_arc_weak", LangOpts.ObjCARCWeak)
-           .Case("objc_default_synthesize_properties", LangOpts.ObjC2)
-           .Case("objc_fixed_enum", LangOpts.ObjC2)
-           .Case("objc_instancetype", LangOpts.ObjC2)
-           .Case("objc_modules", LangOpts.ObjC2 && LangOpts.Modules)
-           .Case("objc_nonfragile_abi", LangOpts.ObjCRuntime.isNonFragile())
-           .Case("objc_property_explicit_atomic", true) // Does clang support explicit "atomic" keyword?
-           .Case("objc_protocol_qualifier_mangling", true)
-           .Case("objc_weak_class", LangOpts.ObjCRuntime.hasWeakClassImport())
-           .Case("ownership_holds", true)
-           .Case("ownership_returns", true)
-           .Case("ownership_takes", true)
-           .Case("objc_bool", true)
-           .Case("objc_subscripting", LangOpts.ObjCRuntime.isNonFragile())
-           .Case("objc_array_literals", LangOpts.ObjC2)
-           .Case("objc_dictionary_literals", LangOpts.ObjC2)
-           .Case("objc_boxed_expressions", LangOpts.ObjC2)
-           .Case("arc_cf_code_audited", true)
-           // C11 features
-           .Case("c_alignas", LangOpts.C11)
-           .Case("c_atomic", LangOpts.C11)
-           .Case("c_generic_selections", LangOpts.C11)
-           .Case("c_static_assert", LangOpts.C11)
-           .Case("c_thread_local",
-                 LangOpts.C11 && PP.getTargetInfo().isTLSSupported())
-           // C++11 features
-           .Case("cxx_access_control_sfinae", LangOpts.CPlusPlus11)
-           .Case("cxx_alias_templates", LangOpts.CPlusPlus11)
-           .Case("cxx_alignas", LangOpts.CPlusPlus11)
-           .Case("cxx_atomic", LangOpts.CPlusPlus11)
-           .Case("cxx_attributes", LangOpts.CPlusPlus11)
-           .Case("cxx_auto_type", LangOpts.CPlusPlus11)
-           .Case("cxx_constexpr", LangOpts.CPlusPlus11)
-           .Case("cxx_decltype", LangOpts.CPlusPlus11)
-           .Case("cxx_decltype_incomplete_return_types", LangOpts.CPlusPlus11)
-           .Case("cxx_default_function_template_args", LangOpts.CPlusPlus11)
-           .Case("cxx_defaulted_functions", LangOpts.CPlusPlus11)
-           .Case("cxx_delegating_constructors", LangOpts.CPlusPlus11)
-           .Case("cxx_deleted_functions", LangOpts.CPlusPlus11)
-           .Case("cxx_explicit_conversions", LangOpts.CPlusPlus11)
-           .Case("cxx_generalized_initializers", LangOpts.CPlusPlus11)
-           .Case("cxx_implicit_moves", LangOpts.CPlusPlus11)
-           .Case("cxx_inheriting_constructors", LangOpts.CPlusPlus11)
-           .Case("cxx_inline_namespaces", LangOpts.CPlusPlus11)
-           .Case("cxx_lambdas", LangOpts.CPlusPlus11)
-           .Case("cxx_local_type_template_args", LangOpts.CPlusPlus11)
-           .Case("cxx_nonstatic_member_init", LangOpts.CPlusPlus11)
-           .Case("cxx_noexcept", LangOpts.CPlusPlus11)
-           .Case("cxx_nullptr", LangOpts.CPlusPlus11)
-           .Case("cxx_override_control", LangOpts.CPlusPlus11)
-           .Case("cxx_range_for", LangOpts.CPlusPlus11)
-           .Case("cxx_raw_string_literals", LangOpts.CPlusPlus11)
-           .Case("cxx_reference_qualified_functions", LangOpts.CPlusPlus11)
-           .Case("cxx_rvalue_references", LangOpts.CPlusPlus11)
-           .Case("cxx_strong_enums", LangOpts.CPlusPlus11)
-           .Case("cxx_static_assert", LangOpts.CPlusPlus11)
-           .Case("cxx_thread_local",
-                 LangOpts.CPlusPlus11 && PP.getTargetInfo().isTLSSupported())
-           .Case("cxx_trailing_return", LangOpts.CPlusPlus11)
-           .Case("cxx_unicode_literals", LangOpts.CPlusPlus11)
-           .Case("cxx_unrestricted_unions", LangOpts.CPlusPlus11)
-           .Case("cxx_user_literals", LangOpts.CPlusPlus11)
-           .Case("cxx_variadic_templates", LangOpts.CPlusPlus11)
-           // C++1y features
-           .Case("cxx_aggregate_nsdmi", LangOpts.CPlusPlus14)
-           .Case("cxx_binary_literals", LangOpts.CPlusPlus14)
-           .Case("cxx_contextual_conversions", LangOpts.CPlusPlus14)
-           .Case("cxx_decltype_auto", LangOpts.CPlusPlus14)
-           .Case("cxx_generic_lambdas", LangOpts.CPlusPlus14)
-           .Case("cxx_init_captures", LangOpts.CPlusPlus14)
-           .Case("cxx_relaxed_constexpr", LangOpts.CPlusPlus14)
-           .Case("cxx_return_type_deduction", LangOpts.CPlusPlus14)
-           .Case("cxx_variable_templates", LangOpts.CPlusPlus14)
-           // C++ TSes
-           //.Case("cxx_runtime_arrays", LangOpts.CPlusPlusTSArrays)
-           //.Case("cxx_concepts", LangOpts.CPlusPlusTSConcepts)
-           // FIXME: Should this be __has_feature or __has_extension?
-           //.Case("raw_invocation_type", LangOpts.CPlusPlus)
-           // Type traits
-           .Case("has_nothrow_assign", LangOpts.CPlusPlus)
-           .Case("has_nothrow_copy", LangOpts.CPlusPlus)
-           .Case("has_nothrow_constructor", LangOpts.CPlusPlus)
-           .Case("has_trivial_assign", LangOpts.CPlusPlus)
-           .Case("has_trivial_copy", LangOpts.CPlusPlus)
-           .Case("has_trivial_constructor", LangOpts.CPlusPlus)
-           .Case("has_trivial_destructor", LangOpts.CPlusPlus)
-           .Case("has_virtual_destructor", LangOpts.CPlusPlus)
-           .Case("is_abstract", LangOpts.CPlusPlus)
-           .Case("is_base_of", LangOpts.CPlusPlus)
-           .Case("is_class", LangOpts.CPlusPlus)
-           .Case("is_constructible", LangOpts.CPlusPlus)
-           .Case("is_convertible_to", LangOpts.CPlusPlus)
-           .Case("is_empty", LangOpts.CPlusPlus)
-           .Case("is_enum", LangOpts.CPlusPlus)
-           .Case("is_final", LangOpts.CPlusPlus)
-           .Case("is_literal", LangOpts.CPlusPlus)
-           .Case("is_standard_layout", LangOpts.CPlusPlus)
-           .Case("is_pod", LangOpts.CPlusPlus)
-           .Case("is_polymorphic", LangOpts.CPlusPlus)
-           .Case("is_sealed", LangOpts.MicrosoftExt)
-           .Case("is_trivial", LangOpts.CPlusPlus)
-           .Case("is_trivially_assignable", LangOpts.CPlusPlus)
-           .Case("is_trivially_constructible", LangOpts.CPlusPlus)
-           .Case("is_trivially_copyable", LangOpts.CPlusPlus)
-           .Case("is_union", LangOpts.CPlusPlus)
-           .Case("modules", LangOpts.Modules)
-           .Case("tls", PP.getTargetInfo().isTLSSupported())
-           .Case("underlying_type", LangOpts.CPlusPlus)
-           .Default(false);
+      .Case("address_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Address))
+      .Case("attribute_analyzer_noreturn", true)
+      .Case("attribute_availability", true)
+      .Case("attribute_availability_with_message", true)
+      .Case("attribute_cf_returns_not_retained", true)
+      .Case("attribute_cf_returns_retained", true)
+      .Case("attribute_deprecated_with_message", true)
+      .Case("attribute_ext_vector_type", true)
+      .Case("attribute_ns_returns_not_retained", true)
+      .Case("attribute_ns_returns_retained", true)
+      .Case("attribute_ns_consumes_self", true)
+      .Case("attribute_ns_consumed", true)
+      .Case("attribute_cf_consumed", true)
+      .Case("attribute_objc_ivar_unused", true)
+      .Case("attribute_objc_method_family", true)
+      .Case("attribute_overloadable", true)
+      .Case("attribute_unavailable_with_message", true)
+      .Case("attribute_unused_on_fields", true)
+      .Case("blocks", LangOpts.Blocks)
+      .Case("c_thread_safety_attributes", true)
+      .Case("cxx_exceptions", LangOpts.CXXExceptions)
+      .Case("cxx_rtti", LangOpts.RTTI)
+      .Case("enumerator_attributes", true)
+      .Case("memory_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Memory))
+      .Case("thread_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Thread))
+      .Case("dataflow_sanitizer", LangOpts.Sanitize.has(SanitizerKind::DataFlow))
+      // Objective-C features
+      .Case("objc_arr", LangOpts.ObjCAutoRefCount) // FIXME: REMOVE?
+      .Case("objc_arc", LangOpts.ObjCAutoRefCount)
+      .Case("objc_arc_weak", LangOpts.ObjCARCWeak)
+      .Case("objc_default_synthesize_properties", LangOpts.ObjC2)
+      .Case("objc_fixed_enum", LangOpts.ObjC2)
+      .Case("objc_instancetype", LangOpts.ObjC2)
+      .Case("objc_modules", LangOpts.ObjC2 && LangOpts.Modules)
+      .Case("objc_nonfragile_abi", LangOpts.ObjCRuntime.isNonFragile())
+      .Case("objc_property_explicit_atomic",
+            true) // Does clang support explicit "atomic" keyword?
+      .Case("objc_protocol_qualifier_mangling", true)
+      .Case("objc_weak_class", LangOpts.ObjCRuntime.hasWeakClassImport())
+      .Case("ownership_holds", true)
+      .Case("ownership_returns", true)
+      .Case("ownership_takes", true)
+      .Case("objc_bool", true)
+      .Case("objc_subscripting", LangOpts.ObjCRuntime.isNonFragile())
+      .Case("objc_array_literals", LangOpts.ObjC2)
+      .Case("objc_dictionary_literals", LangOpts.ObjC2)
+      .Case("objc_boxed_expressions", LangOpts.ObjC2)
+      .Case("arc_cf_code_audited", true)
+      // C11 features
+      .Case("c_alignas", LangOpts.C11)
+      .Case("c_atomic", LangOpts.C11)
+      .Case("c_generic_selections", LangOpts.C11)
+      .Case("c_static_assert", LangOpts.C11)
+      .Case("c_thread_local",
+            LangOpts.C11 && PP.getTargetInfo().isTLSSupported())
+      // C++11 features
+      .Case("cxx_access_control_sfinae", LangOpts.CPlusPlus11)
+      .Case("cxx_alias_templates", LangOpts.CPlusPlus11)
+      .Case("cxx_alignas", LangOpts.CPlusPlus11)
+      .Case("cxx_atomic", LangOpts.CPlusPlus11)
+      .Case("cxx_attributes", LangOpts.CPlusPlus11)
+      .Case("cxx_auto_type", LangOpts.CPlusPlus11)
+      .Case("cxx_constexpr", LangOpts.CPlusPlus11)
+      .Case("cxx_decltype", LangOpts.CPlusPlus11)
+      .Case("cxx_decltype_incomplete_return_types", LangOpts.CPlusPlus11)
+      .Case("cxx_default_function_template_args", LangOpts.CPlusPlus11)
+      .Case("cxx_defaulted_functions", LangOpts.CPlusPlus11)
+      .Case("cxx_delegating_constructors", LangOpts.CPlusPlus11)
+      .Case("cxx_deleted_functions", LangOpts.CPlusPlus11)
+      .Case("cxx_explicit_conversions", LangOpts.CPlusPlus11)
+      .Case("cxx_generalized_initializers", LangOpts.CPlusPlus11)
+      .Case("cxx_implicit_moves", LangOpts.CPlusPlus11)
+      .Case("cxx_inheriting_constructors", LangOpts.CPlusPlus11)
+      .Case("cxx_inline_namespaces", LangOpts.CPlusPlus11)
+      .Case("cxx_lambdas", LangOpts.CPlusPlus11)
+      .Case("cxx_local_type_template_args", LangOpts.CPlusPlus11)
+      .Case("cxx_nonstatic_member_init", LangOpts.CPlusPlus11)
+      .Case("cxx_noexcept", LangOpts.CPlusPlus11)
+      .Case("cxx_nullptr", LangOpts.CPlusPlus11)
+      .Case("cxx_override_control", LangOpts.CPlusPlus11)
+      .Case("cxx_range_for", LangOpts.CPlusPlus11)
+      .Case("cxx_raw_string_literals", LangOpts.CPlusPlus11)
+      .Case("cxx_reference_qualified_functions", LangOpts.CPlusPlus11)
+      .Case("cxx_rvalue_references", LangOpts.CPlusPlus11)
+      .Case("cxx_strong_enums", LangOpts.CPlusPlus11)
+      .Case("cxx_static_assert", LangOpts.CPlusPlus11)
+      .Case("cxx_thread_local",
+            LangOpts.CPlusPlus11 && PP.getTargetInfo().isTLSSupported())
+      .Case("cxx_trailing_return", LangOpts.CPlusPlus11)
+      .Case("cxx_unicode_literals", LangOpts.CPlusPlus11)
+      .Case("cxx_unrestricted_unions", LangOpts.CPlusPlus11)
+      .Case("cxx_user_literals", LangOpts.CPlusPlus11)
+      .Case("cxx_variadic_templates", LangOpts.CPlusPlus11)
+      // C++1y features
+      .Case("cxx_aggregate_nsdmi", LangOpts.CPlusPlus14)
+      .Case("cxx_binary_literals", LangOpts.CPlusPlus14)
+      .Case("cxx_contextual_conversions", LangOpts.CPlusPlus14)
+      .Case("cxx_decltype_auto", LangOpts.CPlusPlus14)
+      .Case("cxx_generic_lambdas", LangOpts.CPlusPlus14)
+      .Case("cxx_init_captures", LangOpts.CPlusPlus14)
+      .Case("cxx_relaxed_constexpr", LangOpts.CPlusPlus14)
+      .Case("cxx_return_type_deduction", LangOpts.CPlusPlus14)
+      .Case("cxx_variable_templates", LangOpts.CPlusPlus14)
+      // C++ TSes
+      //.Case("cxx_runtime_arrays", LangOpts.CPlusPlusTSArrays)
+      //.Case("cxx_concepts", LangOpts.CPlusPlusTSConcepts)
+      // FIXME: Should this be __has_feature or __has_extension?
+      //.Case("raw_invocation_type", LangOpts.CPlusPlus)
+      // Type traits
+      .Case("has_nothrow_assign", LangOpts.CPlusPlus)
+      .Case("has_nothrow_copy", LangOpts.CPlusPlus)
+      .Case("has_nothrow_constructor", LangOpts.CPlusPlus)
+      .Case("has_trivial_assign", LangOpts.CPlusPlus)
+      .Case("has_trivial_copy", LangOpts.CPlusPlus)
+      .Case("has_trivial_constructor", LangOpts.CPlusPlus)
+      .Case("has_trivial_destructor", LangOpts.CPlusPlus)
+      .Case("has_virtual_destructor", LangOpts.CPlusPlus)
+      .Case("is_abstract", LangOpts.CPlusPlus)
+      .Case("is_base_of", LangOpts.CPlusPlus)
+      .Case("is_class", LangOpts.CPlusPlus)
+      .Case("is_constructible", LangOpts.CPlusPlus)
+      .Case("is_convertible_to", LangOpts.CPlusPlus)
+      .Case("is_empty", LangOpts.CPlusPlus)
+      .Case("is_enum", LangOpts.CPlusPlus)
+      .Case("is_final", LangOpts.CPlusPlus)
+      .Case("is_literal", LangOpts.CPlusPlus)
+      .Case("is_standard_layout", LangOpts.CPlusPlus)
+      .Case("is_pod", LangOpts.CPlusPlus)
+      .Case("is_polymorphic", LangOpts.CPlusPlus)
+      .Case("is_sealed", LangOpts.MicrosoftExt)
+      .Case("is_trivial", LangOpts.CPlusPlus)
+      .Case("is_trivially_assignable", LangOpts.CPlusPlus)
+      .Case("is_trivially_constructible", LangOpts.CPlusPlus)
+      .Case("is_trivially_copyable", LangOpts.CPlusPlus)
+      .Case("is_union", LangOpts.CPlusPlus)
+      .Case("modules", LangOpts.Modules)
+      .Case("tls", PP.getTargetInfo().isTLSSupported())
+      .Case("underlying_type", LangOpts.CPlusPlus)
+      .Default(false);
 }
 
 /// HasExtension - Return true if we recognize and implement the feature

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=221558&r1=221557&r2=221558&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Nov  7 16:29:38 2014
@@ -4648,7 +4648,8 @@ bool ASTReader::ParseLanguageOptions(con
 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
   LangOpts.set##Name(static_cast<LangOptions::Type>(Record[Idx++]));
 #include "clang/Basic/LangOptions.def"
-#define SANITIZER(NAME, ID) LangOpts.Sanitize.ID = Record[Idx++];
+#define SANITIZER(NAME, ID)                                                    \
+  LangOpts.Sanitize.set(SanitizerKind::ID, Record[Idx++]);
 #include "clang/Basic/Sanitizers.def"
 
   ObjCRuntime::Kind runtimeKind = (ObjCRuntime::Kind) Record[Idx++];

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=221558&r1=221557&r2=221558&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Fri Nov  7 16:29:38 2014
@@ -1203,8 +1203,9 @@ void ASTWriter::WriteControlBlock(Prepro
   Record.push_back(LangOpts.Name);
 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
   Record.push_back(static_cast<unsigned>(LangOpts.get##Name()));
-#include "clang/Basic/LangOptions.def"  
-#define SANITIZER(NAME, ID) Record.push_back(LangOpts.Sanitize.ID);
+#include "clang/Basic/LangOptions.def"
+#define SANITIZER(NAME, ID)                                                    \
+  Record.push_back(LangOpts.Sanitize.has(SanitizerKind::ID));
 #include "clang/Basic/Sanitizers.def"
 
   Record.push_back((unsigned) LangOpts.ObjCRuntime.getKind());





More information about the cfe-commits mailing list