]> granicus.if.org Git - clang/commitdiff
Add fixit hint to bitwise precedence warning.
authorSebastian Redl <sebastian.redl@getdesigned.at>
Mon, 26 Oct 2009 17:01:32 +0000 (17:01 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Mon, 26 Oct 2009 17:01:32 +0000 (17:01 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85129 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/PartialDiagnostic.h
lib/Sema/SemaExpr.cpp

index e8cc564c8a204f8c6f0344a790200b673effa76a..9960d5beb5c1a105336201bbe921738d601476b0 100644 (file)
@@ -109,7 +109,7 @@ public:
     // Add all arguments.
     for (unsigned i = 0, e = DiagStorage->NumDiagArgs; i != e; ++i) {
       DB.AddTaggedVal(DiagStorage->DiagArgumentsVal[i],
-                      (Diagnostic::ArgumentKind)DiagStorage->DiagArgumentsKind[i]);
+                   (Diagnostic::ArgumentKind)DiagStorage->DiagArgumentsKind[i]);
     }
     
     // Add all ranges.
@@ -129,13 +129,25 @@ public:
     PD.AddTaggedVal(I, Diagnostic::ak_uint);
     return PD;
   }
-  
+
+  friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                             int I) {
+    PD.AddTaggedVal(I, Diagnostic::ak_sint);
+    return PD;
+  }
+
+  friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                                    const char *S) {
+    PD.AddTaggedVal(reinterpret_cast<intptr_t>(S), Diagnostic::ak_c_string);
+    return PD;
+  }
+
   friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
                                                     const SourceRange &R) {
     PD.AddSourceRange(R);
     return PD;
   }
-  
+
   friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
                                              DeclarationName N);
 };
index 84a430ab5235f4e4dd18c90afe0c7e8f769cb1d2..6f7ad609a03475dc03bde08fd6f8745fd8267995 100644 (file)
@@ -5419,6 +5419,23 @@ static inline bool IsEqOrRel(int Opc) {
   return Opc >= BinaryOperator::LT && Opc <= BinaryOperator::NE;
 }
 
+static void SuggestParentheses(Sema &Self, SourceLocation Loc,
+                               const PartialDiagnostic &PD,
+                               SourceRange ParenRange)
+{
+  SourceLocation EndLoc = Self.PP.getLocForEndOfToken(ParenRange.getEnd());
+  if (!ParenRange.getEnd().isFileID() || EndLoc.isInvalid()) {
+    // We can't display the parentheses, so just dig the
+    // warning/error and return.
+    Self.Diag(Loc, PD);
+    return;
+  }
+
+  Self.Diag(Loc, PD)
+    << CodeModificationHint::CreateInsertion(ParenRange.getBegin(), "(")
+    << CodeModificationHint::CreateInsertion(EndLoc, ")");
+}
+
 static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperator::Opcode Opc,
                                       SourceLocation OpLoc,Expr *lhs,Expr *rhs){
   typedef BinaryOperator::Opcode Opcode;
@@ -5439,15 +5456,21 @@ static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperator::Opcode Opc,
     return;
 
   if (IsEqOrRel(lhsopc))
-    Self.Diag(OpLoc, diag::warn_precedence_bitwise_rel)
-      << SourceRange(lhs->getLocStart(), OpLoc)
-      << BinaryOperator::getOpcodeStr(Opc)
-      << BinaryOperator::getOpcodeStr(static_cast<Opcode>(lhsopc));
+    SuggestParentheses(Self, OpLoc,
+      PDiag(diag::warn_precedence_bitwise_rel)
+        << SourceRange(lhs->getLocStart(), OpLoc)
+        << BinaryOperator::getOpcodeStr(Opc)
+        << BinaryOperator::getOpcodeStr(static_cast<Opcode>(lhsopc)),
+      SourceRange(cast<BinaryOperator>(lhs)->getRHS()->getLocStart(),
+                  rhs->getLocEnd()));
   else if (IsEqOrRel(rhsopc))
-    Self.Diag(OpLoc, diag::warn_precedence_bitwise_rel)
-      << SourceRange(OpLoc, rhs->getLocEnd())
-      << BinaryOperator::getOpcodeStr(Opc)
-      << BinaryOperator::getOpcodeStr(static_cast<Opcode>(rhsopc));
+    SuggestParentheses(Self, OpLoc,
+      PDiag(diag::warn_precedence_bitwise_rel)
+        << SourceRange(OpLoc, rhs->getLocEnd())
+        << BinaryOperator::getOpcodeStr(Opc)
+        << BinaryOperator::getOpcodeStr(static_cast<Opcode>(rhsopc)),
+      SourceRange(lhs->getLocEnd(),
+                  cast<BinaryOperator>(rhs)->getLHS()->getLocStart()));
 }
 
 /// DiagnoseBinOpPrecedence - Emit warnings for expressions with tricky