Add support for the OpenCL vec_step operator, by generalising and
extending the existing support for sizeof and alignof.  Original
patch by Guy Benyei.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127475 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp b/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp
index ffcfce3..abf53fd 100644
--- a/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp
@@ -26,7 +26,7 @@
 
 public:
   WalkAST(BugReporter &br) : BR(br) {}
-  void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
+  void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
   void VisitStmt(Stmt *S) { VisitChildren(S); }
   void VisitChildren(Stmt *S);
 };
@@ -39,8 +39,8 @@
 }
 
 // CWE-467: Use of sizeof() on a Pointer Type
-void WalkAST::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
-  if (!E->isSizeOf())
+void WalkAST::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
+  if (E->getKind() != UETT_SizeOf)
     return;
 
   // If an explicit type is used in the code, usually the coder knows what he is
diff --git a/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp b/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
index bc9a29d..495c594 100644
--- a/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
@@ -641,9 +641,10 @@
     return false;
 
   // Cases requiring custom logic
-  case Stmt::SizeOfAlignOfExprClass: {
-    const SizeOfAlignOfExpr *SE = cast<const SizeOfAlignOfExpr>(Ex);
-    if (!SE->isSizeOf())
+  case Stmt::UnaryExprOrTypeTraitExprClass: {
+    const UnaryExprOrTypeTraitExpr *SE = 
+                       cast<const UnaryExprOrTypeTraitExpr>(Ex);
+    if (SE->getKind() != UETT_SizeOf)
       return false;
     return SE->getTypeOfArgument()->isVariableArrayType();
   }
diff --git a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
index 905a99e..b540bce 100644
--- a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
@@ -204,7 +204,7 @@
   // Run each of the checks on the conditions
   if (containsMacro(cond) || containsEnum(cond)
       || containsStaticLocal(cond) || containsBuiltinOffsetOf(cond)
-      || containsStmt<SizeOfAlignOfExpr>(cond))
+      || containsStmt<UnaryExprOrTypeTraitExpr>(cond))
     return true;
 
   return false;
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 95d339f..9178a61 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -690,8 +690,9 @@
       VisitOffsetOfExpr(cast<OffsetOfExpr>(S), Pred, Dst);
       break;
 
-    case Stmt::SizeOfAlignOfExprClass:
-      VisitSizeOfAlignOfExpr(cast<SizeOfAlignOfExpr>(S), Pred, Dst);
+    case Stmt::UnaryExprOrTypeTraitExprClass:
+      VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S),
+                                    Pred, Dst);
       break;
 
     case Stmt::StmtExprClass: {
@@ -2410,19 +2411,15 @@
   assert(0 && "unprocessed InitListExpr type");
 }
 
-/// VisitSizeOfAlignOfExpr - Transfer function for sizeof(type).
-void ExprEngine::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr* Ex,
+/// VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof(type).
+void ExprEngine::VisitUnaryExprOrTypeTraitExpr(
+                                          const UnaryExprOrTypeTraitExpr* Ex,
                                           ExplodedNode* Pred,
                                           ExplodedNodeSet& Dst) {
   QualType T = Ex->getTypeOfArgument();
-  CharUnits amt;
 
-  if (Ex->isSizeOf()) {
-    if (T == getContext().VoidTy) {
-      // sizeof(void) == 1 byte.
-      amt = CharUnits::One();
-    }
-    else if (!T->isConstantSizeType()) {
+  if (Ex->getKind() == UETT_SizeOf) {
+    if (!T->isIncompleteType() && !T->isConstantSizeType()) {
       assert(T->isVariableArrayType() && "Unknown non-constant-sized type.");
 
       // FIXME: Add support for VLA type arguments, not just VLA expressions.
@@ -2463,13 +2460,11 @@
       Dst.Add(Pred);
       return;
     }
-    else {
-      // All other cases.
-      amt = getContext().getTypeSizeInChars(T);
-    }
   }
-  else  // Get alignment of the type.
-    amt = getContext().getTypeAlignInChars(T);
+
+  Expr::EvalResult Result;
+  Ex->Evaluate(Result, getContext());
+  CharUnits amt = CharUnits::fromQuantity(Result.Val.getInt().getZExtValue());
 
   MakeNode(Dst, Ex, Pred,
            GetState(Pred)->BindExpr(Ex,