Implement semantic checking for __builtin_signbit.

r242675 changed the signature for the signbit builtin but did not introduce proper semantic checking to ensure the arguments are as-expected. This patch groups the signbit builtin along with the other fp classification builtins. Fixes PR28172.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@335048 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 5530bd8..e18dd05 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -772,406 +772,409 @@
   }
 
   // Since return type of reserve_read/write_pipe built-in function is
-  // reserve_id_t, which is not defined in the builtin def file , we used int
-  // as return type and need to override the return type of these functions.
-  Call->setType(S.Context.OCLReserveIDTy);
-
-  return false;
-}
-
-// Performs a semantic analysis on {work_group_/sub_group_
-//        /_}commit_{read/write}_pipe
-// \param S Reference to the semantic analyzer.
-// \param Call The call to the builtin function to be analyzed.
-// \return True if a semantic error was found, false otherwise.
-static bool SemaBuiltinCommitRWPipe(Sema &S, CallExpr *Call) {
-  if (checkArgCount(S, Call, 2))
-    return true;
-
-  if (checkOpenCLPipeArg(S, Call))
-    return true;
-
-  // Check reserve_id_t.
-  if (!Call->getArg(1)->getType()->isReserveIDT()) {
-    S.Diag(Call->getLocStart(), diag::err_opencl_builtin_pipe_invalid_arg)
-        << Call->getDirectCallee() << S.Context.OCLReserveIDTy
-        << Call->getArg(1)->getType() << Call->getArg(1)->getSourceRange();
-    return true;
-  }
-
-  return false;
-}
-
-// Performs a semantic analysis on the call to built-in Pipe
-//        Query Functions.
-// \param S Reference to the semantic analyzer.
-// \param Call The call to the builtin function to be analyzed.
-// \return True if a semantic error was found, false otherwise.
-static bool SemaBuiltinPipePackets(Sema &S, CallExpr *Call) {
-  if (checkArgCount(S, Call, 1))
-    return true;
-
-  if (!Call->getArg(0)->getType()->isPipeType()) {
-    S.Diag(Call->getLocStart(), diag::err_opencl_builtin_pipe_first_arg)
-        << Call->getDirectCallee() << Call->getArg(0)->getSourceRange();
-    return true;
-  }
-
-  return false;
-}
-
-// OpenCL v2.0 s6.13.9 - Address space qualifier functions.
-// Performs semantic analysis for the to_global/local/private call.
-// \param S Reference to the semantic analyzer.
-// \param BuiltinID ID of the builtin function.
-// \param Call A pointer to the builtin call.
-// \return True if a semantic error has been found, false otherwise.
-static bool SemaOpenCLBuiltinToAddr(Sema &S, unsigned BuiltinID,
-                                    CallExpr *Call) {
-  if (Call->getNumArgs() != 1) {
-    S.Diag(Call->getLocStart(), diag::err_opencl_builtin_to_addr_arg_num)
-        << Call->getDirectCallee() << Call->getSourceRange();
-    return true;
-  }
-
-  auto RT = Call->getArg(0)->getType();
-  if (!RT->isPointerType() || RT->getPointeeType()
-      .getAddressSpace() == LangAS::opencl_constant) {
-    S.Diag(Call->getLocStart(), diag::err_opencl_builtin_to_addr_invalid_arg)
-        << Call->getArg(0) << Call->getDirectCallee() << Call->getSourceRange();
-    return true;
-  }
-
-  RT = RT->getPointeeType();
-  auto Qual = RT.getQualifiers();
-  switch (BuiltinID) {
-  case Builtin::BIto_global:
-    Qual.setAddressSpace(LangAS::opencl_global);
-    break;
-  case Builtin::BIto_local:
-    Qual.setAddressSpace(LangAS::opencl_local);
-    break;
-  case Builtin::BIto_private:
-    Qual.setAddressSpace(LangAS::opencl_private);
-    break;
-  default:
-    llvm_unreachable("Invalid builtin function");
-  }
-  Call->setType(S.Context.getPointerType(S.Context.getQualifiedType(
-      RT.getUnqualifiedType(), Qual)));
-
-  return false;
-}
-
-// Emit an error and return true if the current architecture is not in the list
-// of supported architectures.
-static bool
-CheckBuiltinTargetSupport(Sema &S, unsigned BuiltinID, CallExpr *TheCall,
-                          ArrayRef<llvm::Triple::ArchType> SupportedArchs) {
-  llvm::Triple::ArchType CurArch =
-      S.getASTContext().getTargetInfo().getTriple().getArch();
-  if (llvm::is_contained(SupportedArchs, CurArch))
-    return false;
-  S.Diag(TheCall->getLocStart(), diag::err_builtin_target_unsupported)
-      << TheCall->getSourceRange();
-  return true;
-}
-
-ExprResult
-Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
-                               CallExpr *TheCall) {
-  ExprResult TheCallResult(TheCall);
-
-  // Find out if any arguments are required to be integer constant expressions.
-  unsigned ICEArguments = 0;
-  ASTContext::GetBuiltinTypeError Error;
-  Context.GetBuiltinType(BuiltinID, Error, &ICEArguments);
-  if (Error != ASTContext::GE_None)
-    ICEArguments = 0;  // Don't diagnose previously diagnosed errors.
-  
-  // If any arguments are required to be ICE's, check and diagnose.
-  for (unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
-    // Skip arguments not required to be ICE's.
-    if ((ICEArguments & (1 << ArgNo)) == 0) continue;
-    
-    llvm::APSInt Result;
-    if (SemaBuiltinConstantArg(TheCall, ArgNo, Result))
-      return true;
-    ICEArguments &= ~(1 << ArgNo);
-  }
-  
-  switch (BuiltinID) {
-  case Builtin::BI__builtin___CFStringMakeConstantString:
-    assert(TheCall->getNumArgs() == 1 &&
-           "Wrong # arguments to builtin CFStringMakeConstantString");
-    if (CheckObjCString(TheCall->getArg(0)))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_ms_va_start:
-  case Builtin::BI__builtin_stdarg_start:
-  case Builtin::BI__builtin_va_start:
-    if (SemaBuiltinVAStart(BuiltinID, TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__va_start: {
-    switch (Context.getTargetInfo().getTriple().getArch()) {
-    case llvm::Triple::arm:
-    case llvm::Triple::thumb:
-      if (SemaBuiltinVAStartARMMicrosoft(TheCall))
-        return ExprError();
-      break;
-    default:
-      if (SemaBuiltinVAStart(BuiltinID, TheCall))
-        return ExprError();
-      break;
-    }
-    break;
-  }
-
-  // The acquire, release, and no fence variants are ARM and AArch64 only.
-  case Builtin::BI_interlockedbittestandset_acq:
-  case Builtin::BI_interlockedbittestandset_rel:
-  case Builtin::BI_interlockedbittestandset_nf:
-  case Builtin::BI_interlockedbittestandreset_acq:
-  case Builtin::BI_interlockedbittestandreset_rel:
-  case Builtin::BI_interlockedbittestandreset_nf:
-    if (CheckBuiltinTargetSupport(
-            *this, BuiltinID, TheCall,
-            {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
-      return ExprError();
-    break;
-
-  // The 64-bit bittest variants are x64, ARM, and AArch64 only.
-  case Builtin::BI_bittest64:
-  case Builtin::BI_bittestandcomplement64:
-  case Builtin::BI_bittestandreset64:
-  case Builtin::BI_bittestandset64:
-  case Builtin::BI_interlockedbittestandreset64:
-  case Builtin::BI_interlockedbittestandset64:
-    if (CheckBuiltinTargetSupport(*this, BuiltinID, TheCall,
-                                  {llvm::Triple::x86_64, llvm::Triple::arm,
-                                   llvm::Triple::thumb, llvm::Triple::aarch64}))
-      return ExprError();
-    break;
-
-  case Builtin::BI__builtin_isgreater:
-  case Builtin::BI__builtin_isgreaterequal:
-  case Builtin::BI__builtin_isless:
-  case Builtin::BI__builtin_islessequal:
-  case Builtin::BI__builtin_islessgreater:
-  case Builtin::BI__builtin_isunordered:
-    if (SemaBuiltinUnorderedCompare(TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_fpclassify:
-    if (SemaBuiltinFPClassification(TheCall, 6))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_isfinite:
-  case Builtin::BI__builtin_isinf:
-  case Builtin::BI__builtin_isinf_sign:
-  case Builtin::BI__builtin_isnan:
-  case Builtin::BI__builtin_isnormal:
-    if (SemaBuiltinFPClassification(TheCall, 1))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_shufflevector:
-    return SemaBuiltinShuffleVector(TheCall);
-    // TheCall will be freed by the smart pointer here, but that's fine, since
-    // SemaBuiltinShuffleVector guts it, but then doesn't release it.
-  case Builtin::BI__builtin_prefetch:
-    if (SemaBuiltinPrefetch(TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_alloca_with_align:
-    if (SemaBuiltinAllocaWithAlign(TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__assume:
-  case Builtin::BI__builtin_assume:
-    if (SemaBuiltinAssume(TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_assume_aligned:
-    if (SemaBuiltinAssumeAligned(TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_object_size:
-    if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_longjmp:
-    if (SemaBuiltinLongjmp(TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_setjmp:
-    if (SemaBuiltinSetjmp(TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI_setjmp:
-  case Builtin::BI_setjmpex:
-    if (checkArgCount(*this, TheCall, 1))
-      return true;
-    break;
-  case Builtin::BI__builtin_classify_type:
-    if (checkArgCount(*this, TheCall, 1)) return true;
-    TheCall->setType(Context.IntTy);
-    break;
-  case Builtin::BI__builtin_constant_p:
-    if (checkArgCount(*this, TheCall, 1)) return true;
-    TheCall->setType(Context.IntTy);
-    break;
-  case Builtin::BI__sync_fetch_and_add:
-  case Builtin::BI__sync_fetch_and_add_1:
-  case Builtin::BI__sync_fetch_and_add_2:
-  case Builtin::BI__sync_fetch_and_add_4:
-  case Builtin::BI__sync_fetch_and_add_8:
-  case Builtin::BI__sync_fetch_and_add_16:
-  case Builtin::BI__sync_fetch_and_sub:
-  case Builtin::BI__sync_fetch_and_sub_1:
-  case Builtin::BI__sync_fetch_and_sub_2:
-  case Builtin::BI__sync_fetch_and_sub_4:
-  case Builtin::BI__sync_fetch_and_sub_8:
-  case Builtin::BI__sync_fetch_and_sub_16:
-  case Builtin::BI__sync_fetch_and_or:
-  case Builtin::BI__sync_fetch_and_or_1:
-  case Builtin::BI__sync_fetch_and_or_2:
-  case Builtin::BI__sync_fetch_and_or_4:
-  case Builtin::BI__sync_fetch_and_or_8:
-  case Builtin::BI__sync_fetch_and_or_16:
-  case Builtin::BI__sync_fetch_and_and:
-  case Builtin::BI__sync_fetch_and_and_1:
-  case Builtin::BI__sync_fetch_and_and_2:
-  case Builtin::BI__sync_fetch_and_and_4:
-  case Builtin::BI__sync_fetch_and_and_8:
-  case Builtin::BI__sync_fetch_and_and_16:
-  case Builtin::BI__sync_fetch_and_xor:
-  case Builtin::BI__sync_fetch_and_xor_1:
-  case Builtin::BI__sync_fetch_and_xor_2:
-  case Builtin::BI__sync_fetch_and_xor_4:
-  case Builtin::BI__sync_fetch_and_xor_8:
-  case Builtin::BI__sync_fetch_and_xor_16:
-  case Builtin::BI__sync_fetch_and_nand:
-  case Builtin::BI__sync_fetch_and_nand_1:
-  case Builtin::BI__sync_fetch_and_nand_2:
-  case Builtin::BI__sync_fetch_and_nand_4:
-  case Builtin::BI__sync_fetch_and_nand_8:
-  case Builtin::BI__sync_fetch_and_nand_16:
-  case Builtin::BI__sync_add_and_fetch:
-  case Builtin::BI__sync_add_and_fetch_1:
-  case Builtin::BI__sync_add_and_fetch_2:
-  case Builtin::BI__sync_add_and_fetch_4:
-  case Builtin::BI__sync_add_and_fetch_8:
-  case Builtin::BI__sync_add_and_fetch_16:
-  case Builtin::BI__sync_sub_and_fetch:
-  case Builtin::BI__sync_sub_and_fetch_1:
-  case Builtin::BI__sync_sub_and_fetch_2:
-  case Builtin::BI__sync_sub_and_fetch_4:
-  case Builtin::BI__sync_sub_and_fetch_8:
-  case Builtin::BI__sync_sub_and_fetch_16:
-  case Builtin::BI__sync_and_and_fetch:
-  case Builtin::BI__sync_and_and_fetch_1:
-  case Builtin::BI__sync_and_and_fetch_2:
-  case Builtin::BI__sync_and_and_fetch_4:
-  case Builtin::BI__sync_and_and_fetch_8:
-  case Builtin::BI__sync_and_and_fetch_16:
-  case Builtin::BI__sync_or_and_fetch:
-  case Builtin::BI__sync_or_and_fetch_1:
-  case Builtin::BI__sync_or_and_fetch_2:
-  case Builtin::BI__sync_or_and_fetch_4:
-  case Builtin::BI__sync_or_and_fetch_8:
-  case Builtin::BI__sync_or_and_fetch_16:
-  case Builtin::BI__sync_xor_and_fetch:
-  case Builtin::BI__sync_xor_and_fetch_1:
-  case Builtin::BI__sync_xor_and_fetch_2:
-  case Builtin::BI__sync_xor_and_fetch_4:
-  case Builtin::BI__sync_xor_and_fetch_8:
-  case Builtin::BI__sync_xor_and_fetch_16:
-  case Builtin::BI__sync_nand_and_fetch:
-  case Builtin::BI__sync_nand_and_fetch_1:
-  case Builtin::BI__sync_nand_and_fetch_2:
-  case Builtin::BI__sync_nand_and_fetch_4:
-  case Builtin::BI__sync_nand_and_fetch_8:
-  case Builtin::BI__sync_nand_and_fetch_16:
-  case Builtin::BI__sync_val_compare_and_swap:
-  case Builtin::BI__sync_val_compare_and_swap_1:
-  case Builtin::BI__sync_val_compare_and_swap_2:
-  case Builtin::BI__sync_val_compare_and_swap_4:
-  case Builtin::BI__sync_val_compare_and_swap_8:
-  case Builtin::BI__sync_val_compare_and_swap_16:
-  case Builtin::BI__sync_bool_compare_and_swap:
-  case Builtin::BI__sync_bool_compare_and_swap_1:
-  case Builtin::BI__sync_bool_compare_and_swap_2:
-  case Builtin::BI__sync_bool_compare_and_swap_4:
-  case Builtin::BI__sync_bool_compare_and_swap_8:
-  case Builtin::BI__sync_bool_compare_and_swap_16:
-  case Builtin::BI__sync_lock_test_and_set:
-  case Builtin::BI__sync_lock_test_and_set_1:
-  case Builtin::BI__sync_lock_test_and_set_2:
-  case Builtin::BI__sync_lock_test_and_set_4:
-  case Builtin::BI__sync_lock_test_and_set_8:
-  case Builtin::BI__sync_lock_test_and_set_16:
-  case Builtin::BI__sync_lock_release:
-  case Builtin::BI__sync_lock_release_1:
-  case Builtin::BI__sync_lock_release_2:
-  case Builtin::BI__sync_lock_release_4:
-  case Builtin::BI__sync_lock_release_8:
-  case Builtin::BI__sync_lock_release_16:
-  case Builtin::BI__sync_swap:
-  case Builtin::BI__sync_swap_1:
-  case Builtin::BI__sync_swap_2:
-  case Builtin::BI__sync_swap_4:
-  case Builtin::BI__sync_swap_8:
-  case Builtin::BI__sync_swap_16:
-    return SemaBuiltinAtomicOverloaded(TheCallResult);
-  case Builtin::BI__builtin_nontemporal_load:
-  case Builtin::BI__builtin_nontemporal_store:
-    return SemaBuiltinNontemporalOverloaded(TheCallResult);
-#define BUILTIN(ID, TYPE, ATTRS)
-#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
-  case Builtin::BI##ID: \
-    return SemaAtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
-#include "clang/Basic/Builtins.def"
-  case Builtin::BI__annotation:
-    if (SemaBuiltinMSVCAnnotation(*this, TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_annotation:
-    if (SemaBuiltinAnnotation(*this, TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_addressof:
-    if (SemaBuiltinAddressof(*this, TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_add_overflow:
-  case Builtin::BI__builtin_sub_overflow:
-  case Builtin::BI__builtin_mul_overflow:
-    if (SemaBuiltinOverflow(*this, TheCall))
-      return ExprError();
-    break;
-  case Builtin::BI__builtin_operator_new:
-  case Builtin::BI__builtin_operator_delete: {
-    bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
-    ExprResult Res =
-        SemaBuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
-    if (Res.isInvalid())
-      CorrectDelayedTyposInExpr(TheCallResult.get());
-    return Res;
-  }
-  case Builtin::BI__builtin_dump_struct: {
-    // We first want to ensure we are called with 2 arguments
-    if (checkArgCount(*this, TheCall, 2))
-      return ExprError();
-    // Ensure that the first argument is of type 'struct XX *'
-    const Expr *PtrArg = TheCall->getArg(0)->IgnoreParenImpCasts();
-    const QualType PtrArgType = PtrArg->getType();
-    if (!PtrArgType->isPointerType() ||
-        !PtrArgType->getPointeeType()->isRecordType()) {
-      Diag(PtrArg->getLocStart(), diag::err_typecheck_convert_incompatible)
-          << PtrArgType << "structure pointer" << 1 << 0 << 3 << 1 << PtrArgType
-          << "structure pointer";
-      return ExprError();
+  // reserve_id_t, which is not defined in the builtin def file , we used int

+  // as return type and need to override the return type of these functions.

+  Call->setType(S.Context.OCLReserveIDTy);

+

+  return false;

+}

+

+// Performs a semantic analysis on {work_group_/sub_group_

+//        /_}commit_{read/write}_pipe

+// \param S Reference to the semantic analyzer.

+// \param Call The call to the builtin function to be analyzed.

+// \return True if a semantic error was found, false otherwise.

+static bool SemaBuiltinCommitRWPipe(Sema &S, CallExpr *Call) {

+  if (checkArgCount(S, Call, 2))

+    return true;

+

+  if (checkOpenCLPipeArg(S, Call))

+    return true;

+

+  // Check reserve_id_t.

+  if (!Call->getArg(1)->getType()->isReserveIDT()) {

+    S.Diag(Call->getLocStart(), diag::err_opencl_builtin_pipe_invalid_arg)

+        << Call->getDirectCallee() << S.Context.OCLReserveIDTy

+        << Call->getArg(1)->getType() << Call->getArg(1)->getSourceRange();

+    return true;

+  }

+

+  return false;

+}

+

+// Performs a semantic analysis on the call to built-in Pipe

+//        Query Functions.

+// \param S Reference to the semantic analyzer.

+// \param Call The call to the builtin function to be analyzed.

+// \return True if a semantic error was found, false otherwise.

+static bool SemaBuiltinPipePackets(Sema &S, CallExpr *Call) {

+  if (checkArgCount(S, Call, 1))

+    return true;

+

+  if (!Call->getArg(0)->getType()->isPipeType()) {

+    S.Diag(Call->getLocStart(), diag::err_opencl_builtin_pipe_first_arg)

+        << Call->getDirectCallee() << Call->getArg(0)->getSourceRange();

+    return true;

+  }

+

+  return false;

+}

+

+// OpenCL v2.0 s6.13.9 - Address space qualifier functions.

+// Performs semantic analysis for the to_global/local/private call.

+// \param S Reference to the semantic analyzer.

+// \param BuiltinID ID of the builtin function.

+// \param Call A pointer to the builtin call.

+// \return True if a semantic error has been found, false otherwise.

+static bool SemaOpenCLBuiltinToAddr(Sema &S, unsigned BuiltinID,

+                                    CallExpr *Call) {

+  if (Call->getNumArgs() != 1) {

+    S.Diag(Call->getLocStart(), diag::err_opencl_builtin_to_addr_arg_num)

+        << Call->getDirectCallee() << Call->getSourceRange();

+    return true;

+  }

+

+  auto RT = Call->getArg(0)->getType();

+  if (!RT->isPointerType() || RT->getPointeeType()

+      .getAddressSpace() == LangAS::opencl_constant) {

+    S.Diag(Call->getLocStart(), diag::err_opencl_builtin_to_addr_invalid_arg)

+        << Call->getArg(0) << Call->getDirectCallee() << Call->getSourceRange();

+    return true;

+  }

+

+  RT = RT->getPointeeType();

+  auto Qual = RT.getQualifiers();

+  switch (BuiltinID) {

+  case Builtin::BIto_global:

+    Qual.setAddressSpace(LangAS::opencl_global);

+    break;

+  case Builtin::BIto_local:

+    Qual.setAddressSpace(LangAS::opencl_local);

+    break;

+  case Builtin::BIto_private:

+    Qual.setAddressSpace(LangAS::opencl_private);

+    break;

+  default:

+    llvm_unreachable("Invalid builtin function");

+  }

+  Call->setType(S.Context.getPointerType(S.Context.getQualifiedType(

+      RT.getUnqualifiedType(), Qual)));

+

+  return false;

+}

+

+// Emit an error and return true if the current architecture is not in the list

+// of supported architectures.

+static bool

+CheckBuiltinTargetSupport(Sema &S, unsigned BuiltinID, CallExpr *TheCall,

+                          ArrayRef<llvm::Triple::ArchType> SupportedArchs) {

+  llvm::Triple::ArchType CurArch =

+      S.getASTContext().getTargetInfo().getTriple().getArch();

+  if (llvm::is_contained(SupportedArchs, CurArch))

+    return false;

+  S.Diag(TheCall->getLocStart(), diag::err_builtin_target_unsupported)

+      << TheCall->getSourceRange();

+  return true;

+}

+

+ExprResult

+Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,

+                               CallExpr *TheCall) {

+  ExprResult TheCallResult(TheCall);

+

+  // Find out if any arguments are required to be integer constant expressions.

+  unsigned ICEArguments = 0;

+  ASTContext::GetBuiltinTypeError Error;

+  Context.GetBuiltinType(BuiltinID, Error, &ICEArguments);

+  if (Error != ASTContext::GE_None)

+    ICEArguments = 0;  // Don't diagnose previously diagnosed errors.

+  

+  // If any arguments are required to be ICE's, check and diagnose.

+  for (unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {

+    // Skip arguments not required to be ICE's.

+    if ((ICEArguments & (1 << ArgNo)) == 0) continue;

+    

+    llvm::APSInt Result;

+    if (SemaBuiltinConstantArg(TheCall, ArgNo, Result))

+      return true;

+    ICEArguments &= ~(1 << ArgNo);

+  }

+  

+  switch (BuiltinID) {

+  case Builtin::BI__builtin___CFStringMakeConstantString:

+    assert(TheCall->getNumArgs() == 1 &&

+           "Wrong # arguments to builtin CFStringMakeConstantString");

+    if (CheckObjCString(TheCall->getArg(0)))

+      return ExprError();

+    break;

+  case Builtin::BI__builtin_ms_va_start:

+  case Builtin::BI__builtin_stdarg_start:

+  case Builtin::BI__builtin_va_start:

+    if (SemaBuiltinVAStart(BuiltinID, TheCall))

+      return ExprError();

+    break;

+  case Builtin::BI__va_start: {

+    switch (Context.getTargetInfo().getTriple().getArch()) {

+    case llvm::Triple::arm:

+    case llvm::Triple::thumb:

+      if (SemaBuiltinVAStartARMMicrosoft(TheCall))

+        return ExprError();

+      break;

+    default:

+      if (SemaBuiltinVAStart(BuiltinID, TheCall))

+        return ExprError();

+      break;

+    }

+    break;

+  }

+

+  // The acquire, release, and no fence variants are ARM and AArch64 only.

+  case Builtin::BI_interlockedbittestandset_acq:

+  case Builtin::BI_interlockedbittestandset_rel:

+  case Builtin::BI_interlockedbittestandset_nf:

+  case Builtin::BI_interlockedbittestandreset_acq:

+  case Builtin::BI_interlockedbittestandreset_rel:

+  case Builtin::BI_interlockedbittestandreset_nf:

+    if (CheckBuiltinTargetSupport(

+            *this, BuiltinID, TheCall,

+            {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))

+      return ExprError();

+    break;

+

+  // The 64-bit bittest variants are x64, ARM, and AArch64 only.

+  case Builtin::BI_bittest64:

+  case Builtin::BI_bittestandcomplement64:

+  case Builtin::BI_bittestandreset64:

+  case Builtin::BI_bittestandset64:

+  case Builtin::BI_interlockedbittestandreset64:

+  case Builtin::BI_interlockedbittestandset64:

+    if (CheckBuiltinTargetSupport(*this, BuiltinID, TheCall,

+                                  {llvm::Triple::x86_64, llvm::Triple::arm,

+                                   llvm::Triple::thumb, llvm::Triple::aarch64}))

+      return ExprError();

+    break;

+

+  case Builtin::BI__builtin_isgreater:

+  case Builtin::BI__builtin_isgreaterequal:

+  case Builtin::BI__builtin_isless:

+  case Builtin::BI__builtin_islessequal:

+  case Builtin::BI__builtin_islessgreater:

+  case Builtin::BI__builtin_isunordered:

+    if (SemaBuiltinUnorderedCompare(TheCall))

+      return ExprError();

+    break;

+  case Builtin::BI__builtin_fpclassify:

+    if (SemaBuiltinFPClassification(TheCall, 6))

+      return ExprError();

+    break;

+  case Builtin::BI__builtin_isfinite:

+  case Builtin::BI__builtin_isinf:

+  case Builtin::BI__builtin_isinf_sign:

+  case Builtin::BI__builtin_isnan:

+  case Builtin::BI__builtin_isnormal:

+  case Builtin::BI__builtin_signbit:

+  case Builtin::BI__builtin_signbitf:

+  case Builtin::BI__builtin_signbitl:

+    if (SemaBuiltinFPClassification(TheCall, 1))

+      return ExprError();

+    break;

+  case Builtin::BI__builtin_shufflevector:

+    return SemaBuiltinShuffleVector(TheCall);

+    // TheCall will be freed by the smart pointer here, but that's fine, since

+    // SemaBuiltinShuffleVector guts it, but then doesn't release it.

+  case Builtin::BI__builtin_prefetch:

+    if (SemaBuiltinPrefetch(TheCall))

+      return ExprError();

+    break;

+  case Builtin::BI__builtin_alloca_with_align:

+    if (SemaBuiltinAllocaWithAlign(TheCall))

+      return ExprError();

+    break;

+  case Builtin::BI__assume:

+  case Builtin::BI__builtin_assume:

+    if (SemaBuiltinAssume(TheCall))

+      return ExprError();

+    break;

+  case Builtin::BI__builtin_assume_aligned:

+    if (SemaBuiltinAssumeAligned(TheCall))

+      return ExprError();

+    break;

+  case Builtin::BI__builtin_object_size:

+    if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3))

+      return ExprError();

+    break;

+  case Builtin::BI__builtin_longjmp:

+    if (SemaBuiltinLongjmp(TheCall))

+      return ExprError();

+    break;

+  case Builtin::BI__builtin_setjmp:

+    if (SemaBuiltinSetjmp(TheCall))

+      return ExprError();

+    break;

+  case Builtin::BI_setjmp:

+  case Builtin::BI_setjmpex:

+    if (checkArgCount(*this, TheCall, 1))

+      return true;

+    break;

+  case Builtin::BI__builtin_classify_type:

+    if (checkArgCount(*this, TheCall, 1)) return true;

+    TheCall->setType(Context.IntTy);

+    break;

+  case Builtin::BI__builtin_constant_p:

+    if (checkArgCount(*this, TheCall, 1)) return true;

+    TheCall->setType(Context.IntTy);

+    break;

+  case Builtin::BI__sync_fetch_and_add:

+  case Builtin::BI__sync_fetch_and_add_1:

+  case Builtin::BI__sync_fetch_and_add_2:

+  case Builtin::BI__sync_fetch_and_add_4:

+  case Builtin::BI__sync_fetch_and_add_8:

+  case Builtin::BI__sync_fetch_and_add_16:

+  case Builtin::BI__sync_fetch_and_sub:

+  case Builtin::BI__sync_fetch_and_sub_1:

+  case Builtin::BI__sync_fetch_and_sub_2:

+  case Builtin::BI__sync_fetch_and_sub_4:

+  case Builtin::BI__sync_fetch_and_sub_8:

+  case Builtin::BI__sync_fetch_and_sub_16:

+  case Builtin::BI__sync_fetch_and_or:

+  case Builtin::BI__sync_fetch_and_or_1:

+  case Builtin::BI__sync_fetch_and_or_2:

+  case Builtin::BI__sync_fetch_and_or_4:

+  case Builtin::BI__sync_fetch_and_or_8:

+  case Builtin::BI__sync_fetch_and_or_16:

+  case Builtin::BI__sync_fetch_and_and:

+  case Builtin::BI__sync_fetch_and_and_1:

+  case Builtin::BI__sync_fetch_and_and_2:

+  case Builtin::BI__sync_fetch_and_and_4:

+  case Builtin::BI__sync_fetch_and_and_8:

+  case Builtin::BI__sync_fetch_and_and_16:

+  case Builtin::BI__sync_fetch_and_xor:

+  case Builtin::BI__sync_fetch_and_xor_1:

+  case Builtin::BI__sync_fetch_and_xor_2:

+  case Builtin::BI__sync_fetch_and_xor_4:

+  case Builtin::BI__sync_fetch_and_xor_8:

+  case Builtin::BI__sync_fetch_and_xor_16:

+  case Builtin::BI__sync_fetch_and_nand:

+  case Builtin::BI__sync_fetch_and_nand_1:

+  case Builtin::BI__sync_fetch_and_nand_2:

+  case Builtin::BI__sync_fetch_and_nand_4:

+  case Builtin::BI__sync_fetch_and_nand_8:

+  case Builtin::BI__sync_fetch_and_nand_16:

+  case Builtin::BI__sync_add_and_fetch:

+  case Builtin::BI__sync_add_and_fetch_1:

+  case Builtin::BI__sync_add_and_fetch_2:

+  case Builtin::BI__sync_add_and_fetch_4:

+  case Builtin::BI__sync_add_and_fetch_8:

+  case Builtin::BI__sync_add_and_fetch_16:

+  case Builtin::BI__sync_sub_and_fetch:

+  case Builtin::BI__sync_sub_and_fetch_1:

+  case Builtin::BI__sync_sub_and_fetch_2:

+  case Builtin::BI__sync_sub_and_fetch_4:

+  case Builtin::BI__sync_sub_and_fetch_8:

+  case Builtin::BI__sync_sub_and_fetch_16:

+  case Builtin::BI__sync_and_and_fetch:

+  case Builtin::BI__sync_and_and_fetch_1:

+  case Builtin::BI__sync_and_and_fetch_2:

+  case Builtin::BI__sync_and_and_fetch_4:

+  case Builtin::BI__sync_and_and_fetch_8:

+  case Builtin::BI__sync_and_and_fetch_16:

+  case Builtin::BI__sync_or_and_fetch:

+  case Builtin::BI__sync_or_and_fetch_1:

+  case Builtin::BI__sync_or_and_fetch_2:

+  case Builtin::BI__sync_or_and_fetch_4:

+  case Builtin::BI__sync_or_and_fetch_8:

+  case Builtin::BI__sync_or_and_fetch_16:

+  case Builtin::BI__sync_xor_and_fetch:

+  case Builtin::BI__sync_xor_and_fetch_1:

+  case Builtin::BI__sync_xor_and_fetch_2:

+  case Builtin::BI__sync_xor_and_fetch_4:

+  case Builtin::BI__sync_xor_and_fetch_8:

+  case Builtin::BI__sync_xor_and_fetch_16:

+  case Builtin::BI__sync_nand_and_fetch:

+  case Builtin::BI__sync_nand_and_fetch_1:

+  case Builtin::BI__sync_nand_and_fetch_2:

+  case Builtin::BI__sync_nand_and_fetch_4:

+  case Builtin::BI__sync_nand_and_fetch_8:

+  case Builtin::BI__sync_nand_and_fetch_16:

+  case Builtin::BI__sync_val_compare_and_swap:

+  case Builtin::BI__sync_val_compare_and_swap_1:

+  case Builtin::BI__sync_val_compare_and_swap_2:

+  case Builtin::BI__sync_val_compare_and_swap_4:

+  case Builtin::BI__sync_val_compare_and_swap_8:

+  case Builtin::BI__sync_val_compare_and_swap_16:

+  case Builtin::BI__sync_bool_compare_and_swap:

+  case Builtin::BI__sync_bool_compare_and_swap_1:

+  case Builtin::BI__sync_bool_compare_and_swap_2:

+  case Builtin::BI__sync_bool_compare_and_swap_4:

+  case Builtin::BI__sync_bool_compare_and_swap_8:

+  case Builtin::BI__sync_bool_compare_and_swap_16:

+  case Builtin::BI__sync_lock_test_and_set:

+  case Builtin::BI__sync_lock_test_and_set_1:

+  case Builtin::BI__sync_lock_test_and_set_2:

+  case Builtin::BI__sync_lock_test_and_set_4:

+  case Builtin::BI__sync_lock_test_and_set_8:

+  case Builtin::BI__sync_lock_test_and_set_16:

+  case Builtin::BI__sync_lock_release:

+  case Builtin::BI__sync_lock_release_1:

+  case Builtin::BI__sync_lock_release_2:

+  case Builtin::BI__sync_lock_release_4:

+  case Builtin::BI__sync_lock_release_8:

+  case Builtin::BI__sync_lock_release_16:

+  case Builtin::BI__sync_swap:

+  case Builtin::BI__sync_swap_1:

+  case Builtin::BI__sync_swap_2:

+  case Builtin::BI__sync_swap_4:

+  case Builtin::BI__sync_swap_8:

+  case Builtin::BI__sync_swap_16:

+    return SemaBuiltinAtomicOverloaded(TheCallResult);

+  case Builtin::BI__builtin_nontemporal_load:

+  case Builtin::BI__builtin_nontemporal_store:

+    return SemaBuiltinNontemporalOverloaded(TheCallResult);

+#define BUILTIN(ID, TYPE, ATTRS)

+#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \

+  case Builtin::BI##ID: \

+    return SemaAtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);

+#include "clang/Basic/Builtins.def"

+  case Builtin::BI__annotation:

+    if (SemaBuiltinMSVCAnnotation(*this, TheCall))

+      return ExprError();

+    break;

+  case Builtin::BI__builtin_annotation:

+    if (SemaBuiltinAnnotation(*this, TheCall))

+      return ExprError();

+    break;

+  case Builtin::BI__builtin_addressof:

+    if (SemaBuiltinAddressof(*this, TheCall))

+      return ExprError();

+    break;

+  case Builtin::BI__builtin_add_overflow:

+  case Builtin::BI__builtin_sub_overflow:

+  case Builtin::BI__builtin_mul_overflow:

+    if (SemaBuiltinOverflow(*this, TheCall))

+      return ExprError();

+    break;

+  case Builtin::BI__builtin_operator_new:

+  case Builtin::BI__builtin_operator_delete: {

+    bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;

+    ExprResult Res =

+        SemaBuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);

+    if (Res.isInvalid())

+      CorrectDelayedTyposInExpr(TheCallResult.get());

+    return Res;

+  }

+  case Builtin::BI__builtin_dump_struct: {

+    // We first want to ensure we are called with 2 arguments

+    if (checkArgCount(*this, TheCall, 2))

+      return ExprError();

+    // Ensure that the first argument is of type 'struct XX *'

+    const Expr *PtrArg = TheCall->getArg(0)->IgnoreParenImpCasts();

+    const QualType PtrArgType = PtrArg->getType();

+    if (!PtrArgType->isPointerType() ||

+        !PtrArgType->getPointeeType()->isRecordType()) {

+      Diag(PtrArg->getLocStart(), diag::err_typecheck_convert_incompatible)

+          << PtrArgType << "structure pointer" << 1 << 0 << 3 << 1 << PtrArgType

+          << "structure pointer";

+      return ExprError();

     }
 
     // Ensure that the second argument is of type 'FunctionType'
@@ -4392,415 +4395,419 @@
   return false;
 }
 
-/// Check the arguments to '__builtin_va_start' or '__builtin_ms_va_start'
-/// for validity.  Emit an error and return true on failure; return false
-/// on success.
-bool Sema::SemaBuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall) {
-  Expr *Fn = TheCall->getCallee();
-
-  if (checkVAStartABI(*this, BuiltinID, Fn))
-    return true;
-
-  if (TheCall->getNumArgs() > 2) {
-    Diag(TheCall->getArg(2)->getLocStart(),
-         diag::err_typecheck_call_too_many_args)
-      << 0 /*function call*/ << 2 << TheCall->getNumArgs()
-      << Fn->getSourceRange()
-      << SourceRange(TheCall->getArg(2)->getLocStart(),
-                     (*(TheCall->arg_end()-1))->getLocEnd());
-    return true;
-  }
-
-  if (TheCall->getNumArgs() < 2) {
-    return Diag(TheCall->getLocEnd(),
-      diag::err_typecheck_call_too_few_args_at_least)
-      << 0 /*function call*/ << 2 << TheCall->getNumArgs();
-  }
-
-  // Type-check the first argument normally.
-  if (checkBuiltinArgument(*this, TheCall, 0))
-    return true;
-
-  // Check that the current function is variadic, and get its last parameter.
-  ParmVarDecl *LastParam;
-  if (checkVAStartIsInVariadicFunction(*this, Fn, &LastParam))
-    return true;
-
-  // Verify that the second argument to the builtin is the last argument of the
-  // current function or method.
-  bool SecondArgIsLastNamedArgument = false;
-  const Expr *Arg = TheCall->getArg(1)->IgnoreParenCasts();
-
-  // These are valid if SecondArgIsLastNamedArgument is false after the next
-  // block.
-  QualType Type;
-  SourceLocation ParamLoc;
-  bool IsCRegister = false;
-
-  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
-    if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
-      SecondArgIsLastNamedArgument = PV == LastParam;
-
-      Type = PV->getType();
-      ParamLoc = PV->getLocation();
-      IsCRegister =
-          PV->getStorageClass() == SC_Register && !getLangOpts().CPlusPlus;
-    }
-  }
-
-  if (!SecondArgIsLastNamedArgument)
-    Diag(TheCall->getArg(1)->getLocStart(),
-         diag::warn_second_arg_of_va_start_not_last_named_param);
-  else if (IsCRegister || Type->isReferenceType() ||
-           Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
-             // Promotable integers are UB, but enumerations need a bit of
-             // extra checking to see what their promotable type actually is.
-             if (!Type->isPromotableIntegerType())
-               return false;
-             if (!Type->isEnumeralType())
-               return true;
-             const EnumDecl *ED = Type->getAs<EnumType>()->getDecl();
-             return !(ED &&
-                      Context.typesAreCompatible(ED->getPromotionType(), Type));
-           }()) {
-    unsigned Reason = 0;
-    if (Type->isReferenceType())  Reason = 1;
-    else if (IsCRegister)         Reason = 2;
-    Diag(Arg->getLocStart(), diag::warn_va_start_type_is_undefined) << Reason;
-    Diag(ParamLoc, diag::note_parameter_type) << Type;
-  }
-
-  TheCall->setType(Context.VoidTy);
-  return false;
-}
-
-bool Sema::SemaBuiltinVAStartARMMicrosoft(CallExpr *Call) {
-  // void __va_start(va_list *ap, const char *named_addr, size_t slot_size,
-  //                 const char *named_addr);
-
-  Expr *Func = Call->getCallee();
-
-  if (Call->getNumArgs() < 3)
-    return Diag(Call->getLocEnd(),
-                diag::err_typecheck_call_too_few_args_at_least)
-           << 0 /*function call*/ << 3 << Call->getNumArgs();
-
-  // Type-check the first argument normally.
-  if (checkBuiltinArgument(*this, Call, 0))
-    return true;
-
-  // Check that the current function is variadic.
-  if (checkVAStartIsInVariadicFunction(*this, Func))
-    return true;
-
-  // __va_start on Windows does not validate the parameter qualifiers
-
-  const Expr *Arg1 = Call->getArg(1)->IgnoreParens();
-  const Type *Arg1Ty = Arg1->getType().getCanonicalType().getTypePtr();
-
-  const Expr *Arg2 = Call->getArg(2)->IgnoreParens();
-  const Type *Arg2Ty = Arg2->getType().getCanonicalType().getTypePtr();
-
-  const QualType &ConstCharPtrTy =
-      Context.getPointerType(Context.CharTy.withConst());
-  if (!Arg1Ty->isPointerType() ||
-      Arg1Ty->getPointeeType().withoutLocalFastQualifiers() != Context.CharTy)
-    Diag(Arg1->getLocStart(), diag::err_typecheck_convert_incompatible)
-        << Arg1->getType() << ConstCharPtrTy
-        << 1 /* different class */
-        << 0 /* qualifier difference */
-        << 3 /* parameter mismatch */
-        << 2 << Arg1->getType() << ConstCharPtrTy;
-
-  const QualType SizeTy = Context.getSizeType();
-  if (Arg2Ty->getCanonicalTypeInternal().withoutLocalFastQualifiers() != SizeTy)
-    Diag(Arg2->getLocStart(), diag::err_typecheck_convert_incompatible)
-        << Arg2->getType() << SizeTy
-        << 1 /* different class */
-        << 0 /* qualifier difference */
-        << 3 /* parameter mismatch */
-        << 3 << Arg2->getType() << SizeTy;
-
-  return false;
-}
-
-/// SemaBuiltinUnorderedCompare - Handle functions like __builtin_isgreater and
-/// friends.  This is declared to take (...), so we have to check everything.
-bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) {
-  if (TheCall->getNumArgs() < 2)
-    return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args)
-      << 0 << 2 << TheCall->getNumArgs()/*function call*/;
-  if (TheCall->getNumArgs() > 2)
-    return Diag(TheCall->getArg(2)->getLocStart(),
-                diag::err_typecheck_call_too_many_args)
-      << 0 /*function call*/ << 2 << TheCall->getNumArgs()
-      << SourceRange(TheCall->getArg(2)->getLocStart(),
-                     (*(TheCall->arg_end()-1))->getLocEnd());
-
-  ExprResult OrigArg0 = TheCall->getArg(0);
-  ExprResult OrigArg1 = TheCall->getArg(1);
-
-  // Do standard promotions between the two arguments, returning their common
-  // type.
-  QualType Res = UsualArithmeticConversions(OrigArg0, OrigArg1, false);
-  if (OrigArg0.isInvalid() || OrigArg1.isInvalid())
-    return true;
-
-  // Make sure any conversions are pushed back into the call; this is
-  // type safe since unordered compare builtins are declared as "_Bool
-  // foo(...)".
-  TheCall->setArg(0, OrigArg0.get());
-  TheCall->setArg(1, OrigArg1.get());
-
-  if (OrigArg0.get()->isTypeDependent() || OrigArg1.get()->isTypeDependent())
-    return false;
-
-  // If the common type isn't a real floating type, then the arguments were
-  // invalid for this operation.
-  if (Res.isNull() || !Res->isRealFloatingType())
-    return Diag(OrigArg0.get()->getLocStart(),
-                diag::err_typecheck_call_invalid_ordered_compare)
-      << OrigArg0.get()->getType() << OrigArg1.get()->getType()
-      << SourceRange(OrigArg0.get()->getLocStart(), OrigArg1.get()->getLocEnd());
-
-  return false;
-}
-
-/// SemaBuiltinSemaBuiltinFPClassification - Handle functions like
-/// __builtin_isnan and friends.  This is declared to take (...), so we have
-/// to check everything. We expect the last argument to be a floating point
-/// value.
-bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs) {
-  if (TheCall->getNumArgs() < NumArgs)
-    return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args)
-      << 0 << NumArgs << TheCall->getNumArgs()/*function call*/;
-  if (TheCall->getNumArgs() > NumArgs)
-    return Diag(TheCall->getArg(NumArgs)->getLocStart(),
-                diag::err_typecheck_call_too_many_args)
-      << 0 /*function call*/ << NumArgs << TheCall->getNumArgs()
-      << SourceRange(TheCall->getArg(NumArgs)->getLocStart(),
-                     (*(TheCall->arg_end()-1))->getLocEnd());
-
-  Expr *OrigArg = TheCall->getArg(NumArgs-1);
-
-  if (OrigArg->isTypeDependent())
-    return false;
-
-  // This operation requires a non-_Complex floating-point number.
-  if (!OrigArg->getType()->isRealFloatingType())
-    return Diag(OrigArg->getLocStart(),
-                diag::err_typecheck_call_invalid_unary_fp)
-      << OrigArg->getType() << OrigArg->getSourceRange();
-
-  // If this is an implicit conversion from float -> float or double, remove it.
-  if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(OrigArg)) {
-    // Only remove standard FloatCasts, leaving other casts inplace
-    if (Cast->getCastKind() == CK_FloatingCast) {
-      Expr *CastArg = Cast->getSubExpr();
-      if (CastArg->getType()->isSpecificBuiltinType(BuiltinType::Float)) {
-          assert((Cast->getType()->isSpecificBuiltinType(BuiltinType::Double) ||
-                  Cast->getType()->isSpecificBuiltinType(BuiltinType::Float)) &&
-               "promotion from float to either float or double is the only expected cast here");
-        Cast->setSubExpr(nullptr);
-        TheCall->setArg(NumArgs-1, CastArg);
-      }
-    }
-  }
-  
-  return false;
-}
-
-// Customized Sema Checking for VSX builtins that have the following signature:
-// vector [...] builtinName(vector [...], vector [...], const int);
-// Which takes the same type of vectors (any legal vector type) for the first
-// two arguments and takes compile time constant for the third argument.
-// Example builtins are :
-// vector double vec_xxpermdi(vector double, vector double, int);
-// vector short vec_xxsldwi(vector short, vector short, int);
-bool Sema::SemaBuiltinVSX(CallExpr *TheCall) {
-  unsigned ExpectedNumArgs = 3;
-  if (TheCall->getNumArgs() < ExpectedNumArgs)
-    return Diag(TheCall->getLocEnd(),
-                diag::err_typecheck_call_too_few_args_at_least)
-           << 0 /*function call*/ <<  ExpectedNumArgs << TheCall->getNumArgs()
-           << TheCall->getSourceRange();
-
-  if (TheCall->getNumArgs() > ExpectedNumArgs)
-    return Diag(TheCall->getLocEnd(),
-                diag::err_typecheck_call_too_many_args_at_most)
-           << 0 /*function call*/ << ExpectedNumArgs << TheCall->getNumArgs()
-           << TheCall->getSourceRange();
-
-  // Check the third argument is a compile time constant
-  llvm::APSInt Value;
-  if(!TheCall->getArg(2)->isIntegerConstantExpr(Value, Context))
-    return Diag(TheCall->getLocStart(),
-                diag::err_vsx_builtin_nonconstant_argument)
-           << 3 /* argument index */ << TheCall->getDirectCallee()
-           << SourceRange(TheCall->getArg(2)->getLocStart(),
-                          TheCall->getArg(2)->getLocEnd());
-
-  QualType Arg1Ty = TheCall->getArg(0)->getType();
-  QualType Arg2Ty = TheCall->getArg(1)->getType();
-
-  // Check the type of argument 1 and argument 2 are vectors.
-  SourceLocation BuiltinLoc = TheCall->getLocStart();
-  if ((!Arg1Ty->isVectorType() && !Arg1Ty->isDependentType()) ||
-      (!Arg2Ty->isVectorType() && !Arg2Ty->isDependentType())) {
-    return Diag(BuiltinLoc, diag::err_vec_builtin_non_vector)
-           << TheCall->getDirectCallee()
-           << SourceRange(TheCall->getArg(0)->getLocStart(),
-                          TheCall->getArg(1)->getLocEnd());
-  }
-
-  // Check the first two arguments are the same type.
-  if (!Context.hasSameUnqualifiedType(Arg1Ty, Arg2Ty)) {
-    return Diag(BuiltinLoc, diag::err_vec_builtin_incompatible_vector)
-           << TheCall->getDirectCallee()
-           << SourceRange(TheCall->getArg(0)->getLocStart(),
-                          TheCall->getArg(1)->getLocEnd());
-  }
-
-  // When default clang type checking is turned off and the customized type
-  // checking is used, the returning type of the function must be explicitly
-  // set. Otherwise it is _Bool by default.
-  TheCall->setType(Arg1Ty);
-
-  return false;
-}
-
-/// SemaBuiltinShuffleVector - Handle __builtin_shufflevector.
-// This is declared to take (...), so we have to check everything.
-ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {
-  if (TheCall->getNumArgs() < 2)
-    return ExprError(Diag(TheCall->getLocEnd(),
-                          diag::err_typecheck_call_too_few_args_at_least)
-                     << 0 /*function call*/ << 2 << TheCall->getNumArgs()
-                     << TheCall->getSourceRange());
-
-  // Determine which of the following types of shufflevector we're checking:
-  // 1) unary, vector mask: (lhs, mask)
-  // 2) binary, scalar mask: (lhs, rhs, index, ..., index)
-  QualType resType = TheCall->getArg(0)->getType();
-  unsigned numElements = 0;
-
-  if (!TheCall->getArg(0)->isTypeDependent() &&
-      !TheCall->getArg(1)->isTypeDependent()) {
-    QualType LHSType = TheCall->getArg(0)->getType();
-    QualType RHSType = TheCall->getArg(1)->getType();
-
-    if (!LHSType->isVectorType() || !RHSType->isVectorType())
-      return ExprError(Diag(TheCall->getLocStart(),
-                            diag::err_vec_builtin_non_vector)
-                       << TheCall->getDirectCallee()
-                       << SourceRange(TheCall->getArg(0)->getLocStart(),
-                                      TheCall->getArg(1)->getLocEnd()));
-
-    numElements = LHSType->getAs<VectorType>()->getNumElements();
-    unsigned numResElements = TheCall->getNumArgs() - 2;
-
-    // Check to see if we have a call with 2 vector arguments, the unary shuffle
-    // with mask.  If so, verify that RHS is an integer vector type with the
-    // same number of elts as lhs.
-    if (TheCall->getNumArgs() == 2) {
-      if (!RHSType->hasIntegerRepresentation() ||
-          RHSType->getAs<VectorType>()->getNumElements() != numElements)
-        return ExprError(Diag(TheCall->getLocStart(),
-                              diag::err_vec_builtin_incompatible_vector)
-                         << TheCall->getDirectCallee()
-                         << SourceRange(TheCall->getArg(1)->getLocStart(),
-                                        TheCall->getArg(1)->getLocEnd()));
-    } else if (!Context.hasSameUnqualifiedType(LHSType, RHSType)) {
-      return ExprError(Diag(TheCall->getLocStart(),
-                            diag::err_vec_builtin_incompatible_vector)
-                       << TheCall->getDirectCallee()
-                       << SourceRange(TheCall->getArg(0)->getLocStart(),
-                                      TheCall->getArg(1)->getLocEnd()));
-    } else if (numElements != numResElements) {
-      QualType eltType = LHSType->getAs<VectorType>()->getElementType();
-      resType = Context.getVectorType(eltType, numResElements,
-                                      VectorType::GenericVector);
-    }
-  }
-
-  for (unsigned i = 2; i < TheCall->getNumArgs(); i++) {
-    if (TheCall->getArg(i)->isTypeDependent() ||
-        TheCall->getArg(i)->isValueDependent())
-      continue;
-
-    llvm::APSInt Result(32);
-    if (!TheCall->getArg(i)->isIntegerConstantExpr(Result, Context))
-      return ExprError(Diag(TheCall->getLocStart(),
-                            diag::err_shufflevector_nonconstant_argument)
-                       << TheCall->getArg(i)->getSourceRange());
-
-    // Allow -1 which will be translated to undef in the IR.
-    if (Result.isSigned() && Result.isAllOnesValue())
-      continue;
-
-    if (Result.getActiveBits() > 64 || Result.getZExtValue() >= numElements*2)
-      return ExprError(Diag(TheCall->getLocStart(),
-                            diag::err_shufflevector_argument_too_large)
-                       << TheCall->getArg(i)->getSourceRange());
-  }
-
-  SmallVector<Expr*, 32> exprs;
-
-  for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; i++) {
-    exprs.push_back(TheCall->getArg(i));
-    TheCall->setArg(i, nullptr);
-  }
-
-  return new (Context) ShuffleVectorExpr(Context, exprs, resType,
-                                         TheCall->getCallee()->getLocStart(),
-                                         TheCall->getRParenLoc());
-}
-
-/// SemaConvertVectorExpr - Handle __builtin_convertvector
-ExprResult Sema::SemaConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo,
-                                       SourceLocation BuiltinLoc,
-                                       SourceLocation RParenLoc) {
-  ExprValueKind VK = VK_RValue;
-  ExprObjectKind OK = OK_Ordinary;
-  QualType DstTy = TInfo->getType();
-  QualType SrcTy = E->getType();
-
-  if (!SrcTy->isVectorType() && !SrcTy->isDependentType())
-    return ExprError(Diag(BuiltinLoc,
-                          diag::err_convertvector_non_vector)
-                     << E->getSourceRange());
-  if (!DstTy->isVectorType() && !DstTy->isDependentType())
-    return ExprError(Diag(BuiltinLoc,
-                          diag::err_convertvector_non_vector_type));
-
-  if (!SrcTy->isDependentType() && !DstTy->isDependentType()) {
-    unsigned SrcElts = SrcTy->getAs<VectorType>()->getNumElements();
-    unsigned DstElts = DstTy->getAs<VectorType>()->getNumElements();
-    if (SrcElts != DstElts)
-      return ExprError(Diag(BuiltinLoc,
-                            diag::err_convertvector_incompatible_vector)
-                       << E->getSourceRange());
-  }
-
-  return new (Context)
-      ConvertVectorExpr(E, TInfo, DstTy, VK, OK, BuiltinLoc, RParenLoc);
-}
-
-/// SemaBuiltinPrefetch - Handle __builtin_prefetch.
-// This is declared to take (const void*, ...) and can take two
-// optional constant int args.
-bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) {
-  unsigned NumArgs = TheCall->getNumArgs();
-
-  if (NumArgs > 3)
-    return Diag(TheCall->getLocEnd(),
-             diag::err_typecheck_call_too_many_args_at_most)
-             << 0 /*function call*/ << 3 << NumArgs
-             << TheCall->getSourceRange();
-
-  // Argument 0 is checked for us and the remaining arguments must be
-  // constant integers.
-  for (unsigned i = 1; i != NumArgs; ++i)
+/// Check the arguments to '__builtin_va_start' or '__builtin_ms_va_start'

+/// for validity.  Emit an error and return true on failure; return false

+/// on success.

+bool Sema::SemaBuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall) {

+  Expr *Fn = TheCall->getCallee();

+

+  if (checkVAStartABI(*this, BuiltinID, Fn))

+    return true;

+

+  if (TheCall->getNumArgs() > 2) {

+    Diag(TheCall->getArg(2)->getLocStart(),

+         diag::err_typecheck_call_too_many_args)

+      << 0 /*function call*/ << 2 << TheCall->getNumArgs()

+      << Fn->getSourceRange()

+      << SourceRange(TheCall->getArg(2)->getLocStart(),

+                     (*(TheCall->arg_end()-1))->getLocEnd());

+    return true;

+  }

+

+  if (TheCall->getNumArgs() < 2) {

+    return Diag(TheCall->getLocEnd(),

+      diag::err_typecheck_call_too_few_args_at_least)

+      << 0 /*function call*/ << 2 << TheCall->getNumArgs();

+  }

+

+  // Type-check the first argument normally.

+  if (checkBuiltinArgument(*this, TheCall, 0))

+    return true;

+

+  // Check that the current function is variadic, and get its last parameter.

+  ParmVarDecl *LastParam;

+  if (checkVAStartIsInVariadicFunction(*this, Fn, &LastParam))

+    return true;

+

+  // Verify that the second argument to the builtin is the last argument of the

+  // current function or method.

+  bool SecondArgIsLastNamedArgument = false;

+  const Expr *Arg = TheCall->getArg(1)->IgnoreParenCasts();

+

+  // These are valid if SecondArgIsLastNamedArgument is false after the next

+  // block.

+  QualType Type;

+  SourceLocation ParamLoc;

+  bool IsCRegister = false;

+

+  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {

+    if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {

+      SecondArgIsLastNamedArgument = PV == LastParam;

+

+      Type = PV->getType();

+      ParamLoc = PV->getLocation();

+      IsCRegister =

+          PV->getStorageClass() == SC_Register && !getLangOpts().CPlusPlus;

+    }

+  }

+

+  if (!SecondArgIsLastNamedArgument)

+    Diag(TheCall->getArg(1)->getLocStart(),

+         diag::warn_second_arg_of_va_start_not_last_named_param);

+  else if (IsCRegister || Type->isReferenceType() ||

+           Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {

+             // Promotable integers are UB, but enumerations need a bit of

+             // extra checking to see what their promotable type actually is.

+             if (!Type->isPromotableIntegerType())

+               return false;

+             if (!Type->isEnumeralType())

+               return true;

+             const EnumDecl *ED = Type->getAs<EnumType>()->getDecl();

+             return !(ED &&

+                      Context.typesAreCompatible(ED->getPromotionType(), Type));

+           }()) {

+    unsigned Reason = 0;

+    if (Type->isReferenceType())  Reason = 1;

+    else if (IsCRegister)         Reason = 2;

+    Diag(Arg->getLocStart(), diag::warn_va_start_type_is_undefined) << Reason;

+    Diag(ParamLoc, diag::note_parameter_type) << Type;

+  }

+

+  TheCall->setType(Context.VoidTy);

+  return false;

+}

+

+bool Sema::SemaBuiltinVAStartARMMicrosoft(CallExpr *Call) {

+  // void __va_start(va_list *ap, const char *named_addr, size_t slot_size,

+  //                 const char *named_addr);

+

+  Expr *Func = Call->getCallee();

+

+  if (Call->getNumArgs() < 3)

+    return Diag(Call->getLocEnd(),

+                diag::err_typecheck_call_too_few_args_at_least)

+           << 0 /*function call*/ << 3 << Call->getNumArgs();

+

+  // Type-check the first argument normally.

+  if (checkBuiltinArgument(*this, Call, 0))

+    return true;

+

+  // Check that the current function is variadic.

+  if (checkVAStartIsInVariadicFunction(*this, Func))

+    return true;

+

+  // __va_start on Windows does not validate the parameter qualifiers

+

+  const Expr *Arg1 = Call->getArg(1)->IgnoreParens();

+  const Type *Arg1Ty = Arg1->getType().getCanonicalType().getTypePtr();

+

+  const Expr *Arg2 = Call->getArg(2)->IgnoreParens();

+  const Type *Arg2Ty = Arg2->getType().getCanonicalType().getTypePtr();

+

+  const QualType &ConstCharPtrTy =

+      Context.getPointerType(Context.CharTy.withConst());

+  if (!Arg1Ty->isPointerType() ||

+      Arg1Ty->getPointeeType().withoutLocalFastQualifiers() != Context.CharTy)

+    Diag(Arg1->getLocStart(), diag::err_typecheck_convert_incompatible)

+        << Arg1->getType() << ConstCharPtrTy

+        << 1 /* different class */

+        << 0 /* qualifier difference */

+        << 3 /* parameter mismatch */

+        << 2 << Arg1->getType() << ConstCharPtrTy;

+

+  const QualType SizeTy = Context.getSizeType();

+  if (Arg2Ty->getCanonicalTypeInternal().withoutLocalFastQualifiers() != SizeTy)

+    Diag(Arg2->getLocStart(), diag::err_typecheck_convert_incompatible)

+        << Arg2->getType() << SizeTy

+        << 1 /* different class */

+        << 0 /* qualifier difference */

+        << 3 /* parameter mismatch */

+        << 3 << Arg2->getType() << SizeTy;

+

+  return false;

+}

+

+/// SemaBuiltinUnorderedCompare - Handle functions like __builtin_isgreater and

+/// friends.  This is declared to take (...), so we have to check everything.

+bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) {

+  if (TheCall->getNumArgs() < 2)

+    return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args)

+      << 0 << 2 << TheCall->getNumArgs()/*function call*/;

+  if (TheCall->getNumArgs() > 2)

+    return Diag(TheCall->getArg(2)->getLocStart(),

+                diag::err_typecheck_call_too_many_args)

+      << 0 /*function call*/ << 2 << TheCall->getNumArgs()

+      << SourceRange(TheCall->getArg(2)->getLocStart(),

+                     (*(TheCall->arg_end()-1))->getLocEnd());

+

+  ExprResult OrigArg0 = TheCall->getArg(0);

+  ExprResult OrigArg1 = TheCall->getArg(1);

+

+  // Do standard promotions between the two arguments, returning their common

+  // type.

+  QualType Res = UsualArithmeticConversions(OrigArg0, OrigArg1, false);

+  if (OrigArg0.isInvalid() || OrigArg1.isInvalid())

+    return true;

+

+  // Make sure any conversions are pushed back into the call; this is

+  // type safe since unordered compare builtins are declared as "_Bool

+  // foo(...)".

+  TheCall->setArg(0, OrigArg0.get());

+  TheCall->setArg(1, OrigArg1.get());

+

+  if (OrigArg0.get()->isTypeDependent() || OrigArg1.get()->isTypeDependent())

+    return false;

+

+  // If the common type isn't a real floating type, then the arguments were

+  // invalid for this operation.

+  if (Res.isNull() || !Res->isRealFloatingType())

+    return Diag(OrigArg0.get()->getLocStart(),

+                diag::err_typecheck_call_invalid_ordered_compare)

+      << OrigArg0.get()->getType() << OrigArg1.get()->getType()

+      << SourceRange(OrigArg0.get()->getLocStart(), OrigArg1.get()->getLocEnd());

+

+  return false;

+}

+

+/// SemaBuiltinSemaBuiltinFPClassification - Handle functions like

+/// __builtin_isnan and friends.  This is declared to take (...), so we have

+/// to check everything. We expect the last argument to be a floating point

+/// value.

+bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs) {

+  if (TheCall->getNumArgs() < NumArgs)

+    return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args)

+      << 0 << NumArgs << TheCall->getNumArgs()/*function call*/;

+  if (TheCall->getNumArgs() > NumArgs)

+    return Diag(TheCall->getArg(NumArgs)->getLocStart(),

+                diag::err_typecheck_call_too_many_args)

+      << 0 /*function call*/ << NumArgs << TheCall->getNumArgs()

+      << SourceRange(TheCall->getArg(NumArgs)->getLocStart(),

+                     (*(TheCall->arg_end()-1))->getLocEnd());

+

+  Expr *OrigArg = TheCall->getArg(NumArgs-1);

+

+  if (OrigArg->isTypeDependent())

+    return false;

+

+  // This operation requires a non-_Complex floating-point number.

+  if (!OrigArg->getType()->isRealFloatingType())

+    return Diag(OrigArg->getLocStart(),

+                diag::err_typecheck_call_invalid_unary_fp)

+      << OrigArg->getType() << OrigArg->getSourceRange();

+

+  // If this is an implicit conversion from float -> float, double, or

+  // long double, remove it.

+  if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(OrigArg)) {

+    // Only remove standard FloatCasts, leaving other casts inplace

+    if (Cast->getCastKind() == CK_FloatingCast) {

+      Expr *CastArg = Cast->getSubExpr();

+      if (CastArg->getType()->isSpecificBuiltinType(BuiltinType::Float)) {

+        assert(

+            (Cast->getType()->isSpecificBuiltinType(BuiltinType::Double) ||

+             Cast->getType()->isSpecificBuiltinType(BuiltinType::Float) ||

+             Cast->getType()->isSpecificBuiltinType(BuiltinType::LongDouble)) &&

+            "promotion from float to either float, double, or long double is "

+            "the only expected cast here");

+        Cast->setSubExpr(nullptr);

+        TheCall->setArg(NumArgs-1, CastArg);

+      }

+    }

+  }

+  

+  return false;

+}

+

+// Customized Sema Checking for VSX builtins that have the following signature:

+// vector [...] builtinName(vector [...], vector [...], const int);

+// Which takes the same type of vectors (any legal vector type) for the first

+// two arguments and takes compile time constant for the third argument.

+// Example builtins are :

+// vector double vec_xxpermdi(vector double, vector double, int);

+// vector short vec_xxsldwi(vector short, vector short, int);

+bool Sema::SemaBuiltinVSX(CallExpr *TheCall) {

+  unsigned ExpectedNumArgs = 3;

+  if (TheCall->getNumArgs() < ExpectedNumArgs)

+    return Diag(TheCall->getLocEnd(),

+                diag::err_typecheck_call_too_few_args_at_least)

+           << 0 /*function call*/ <<  ExpectedNumArgs << TheCall->getNumArgs()

+           << TheCall->getSourceRange();

+

+  if (TheCall->getNumArgs() > ExpectedNumArgs)

+    return Diag(TheCall->getLocEnd(),

+                diag::err_typecheck_call_too_many_args_at_most)

+           << 0 /*function call*/ << ExpectedNumArgs << TheCall->getNumArgs()

+           << TheCall->getSourceRange();

+

+  // Check the third argument is a compile time constant

+  llvm::APSInt Value;

+  if(!TheCall->getArg(2)->isIntegerConstantExpr(Value, Context))

+    return Diag(TheCall->getLocStart(),

+                diag::err_vsx_builtin_nonconstant_argument)

+           << 3 /* argument index */ << TheCall->getDirectCallee()

+           << SourceRange(TheCall->getArg(2)->getLocStart(),

+                          TheCall->getArg(2)->getLocEnd());

+

+  QualType Arg1Ty = TheCall->getArg(0)->getType();

+  QualType Arg2Ty = TheCall->getArg(1)->getType();

+

+  // Check the type of argument 1 and argument 2 are vectors.

+  SourceLocation BuiltinLoc = TheCall->getLocStart();

+  if ((!Arg1Ty->isVectorType() && !Arg1Ty->isDependentType()) ||

+      (!Arg2Ty->isVectorType() && !Arg2Ty->isDependentType())) {

+    return Diag(BuiltinLoc, diag::err_vec_builtin_non_vector)

+           << TheCall->getDirectCallee()

+           << SourceRange(TheCall->getArg(0)->getLocStart(),

+                          TheCall->getArg(1)->getLocEnd());

+  }

+

+  // Check the first two arguments are the same type.

+  if (!Context.hasSameUnqualifiedType(Arg1Ty, Arg2Ty)) {

+    return Diag(BuiltinLoc, diag::err_vec_builtin_incompatible_vector)

+           << TheCall->getDirectCallee()

+           << SourceRange(TheCall->getArg(0)->getLocStart(),

+                          TheCall->getArg(1)->getLocEnd());

+  }

+

+  // When default clang type checking is turned off and the customized type

+  // checking is used, the returning type of the function must be explicitly

+  // set. Otherwise it is _Bool by default.

+  TheCall->setType(Arg1Ty);

+

+  return false;

+}

+

+/// SemaBuiltinShuffleVector - Handle __builtin_shufflevector.

+// This is declared to take (...), so we have to check everything.

+ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {

+  if (TheCall->getNumArgs() < 2)

+    return ExprError(Diag(TheCall->getLocEnd(),

+                          diag::err_typecheck_call_too_few_args_at_least)

+                     << 0 /*function call*/ << 2 << TheCall->getNumArgs()

+                     << TheCall->getSourceRange());

+

+  // Determine which of the following types of shufflevector we're checking:

+  // 1) unary, vector mask: (lhs, mask)

+  // 2) binary, scalar mask: (lhs, rhs, index, ..., index)

+  QualType resType = TheCall->getArg(0)->getType();

+  unsigned numElements = 0;

+

+  if (!TheCall->getArg(0)->isTypeDependent() &&

+      !TheCall->getArg(1)->isTypeDependent()) {

+    QualType LHSType = TheCall->getArg(0)->getType();

+    QualType RHSType = TheCall->getArg(1)->getType();

+

+    if (!LHSType->isVectorType() || !RHSType->isVectorType())

+      return ExprError(Diag(TheCall->getLocStart(),

+                            diag::err_vec_builtin_non_vector)

+                       << TheCall->getDirectCallee()

+                       << SourceRange(TheCall->getArg(0)->getLocStart(),

+                                      TheCall->getArg(1)->getLocEnd()));

+

+    numElements = LHSType->getAs<VectorType>()->getNumElements();

+    unsigned numResElements = TheCall->getNumArgs() - 2;

+

+    // Check to see if we have a call with 2 vector arguments, the unary shuffle

+    // with mask.  If so, verify that RHS is an integer vector type with the

+    // same number of elts as lhs.

+    if (TheCall->getNumArgs() == 2) {

+      if (!RHSType->hasIntegerRepresentation() ||

+          RHSType->getAs<VectorType>()->getNumElements() != numElements)

+        return ExprError(Diag(TheCall->getLocStart(),

+                              diag::err_vec_builtin_incompatible_vector)

+                         << TheCall->getDirectCallee()

+                         << SourceRange(TheCall->getArg(1)->getLocStart(),

+                                        TheCall->getArg(1)->getLocEnd()));

+    } else if (!Context.hasSameUnqualifiedType(LHSType, RHSType)) {

+      return ExprError(Diag(TheCall->getLocStart(),

+                            diag::err_vec_builtin_incompatible_vector)

+                       << TheCall->getDirectCallee()

+                       << SourceRange(TheCall->getArg(0)->getLocStart(),

+                                      TheCall->getArg(1)->getLocEnd()));

+    } else if (numElements != numResElements) {

+      QualType eltType = LHSType->getAs<VectorType>()->getElementType();

+      resType = Context.getVectorType(eltType, numResElements,

+                                      VectorType::GenericVector);

+    }

+  }

+

+  for (unsigned i = 2; i < TheCall->getNumArgs(); i++) {

+    if (TheCall->getArg(i)->isTypeDependent() ||

+        TheCall->getArg(i)->isValueDependent())

+      continue;

+

+    llvm::APSInt Result(32);

+    if (!TheCall->getArg(i)->isIntegerConstantExpr(Result, Context))

+      return ExprError(Diag(TheCall->getLocStart(),

+                            diag::err_shufflevector_nonconstant_argument)

+                       << TheCall->getArg(i)->getSourceRange());

+

+    // Allow -1 which will be translated to undef in the IR.

+    if (Result.isSigned() && Result.isAllOnesValue())

+      continue;

+

+    if (Result.getActiveBits() > 64 || Result.getZExtValue() >= numElements*2)

+      return ExprError(Diag(TheCall->getLocStart(),

+                            diag::err_shufflevector_argument_too_large)

+                       << TheCall->getArg(i)->getSourceRange());

+  }

+

+  SmallVector<Expr*, 32> exprs;

+

+  for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; i++) {

+    exprs.push_back(TheCall->getArg(i));

+    TheCall->setArg(i, nullptr);

+  }

+

+  return new (Context) ShuffleVectorExpr(Context, exprs, resType,

+                                         TheCall->getCallee()->getLocStart(),

+                                         TheCall->getRParenLoc());

+}

+

+/// SemaConvertVectorExpr - Handle __builtin_convertvector

+ExprResult Sema::SemaConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo,

+                                       SourceLocation BuiltinLoc,

+                                       SourceLocation RParenLoc) {

+  ExprValueKind VK = VK_RValue;

+  ExprObjectKind OK = OK_Ordinary;

+  QualType DstTy = TInfo->getType();

+  QualType SrcTy = E->getType();

+

+  if (!SrcTy->isVectorType() && !SrcTy->isDependentType())

+    return ExprError(Diag(BuiltinLoc,

+                          diag::err_convertvector_non_vector)

+                     << E->getSourceRange());

+  if (!DstTy->isVectorType() && !DstTy->isDependentType())

+    return ExprError(Diag(BuiltinLoc,

+                          diag::err_convertvector_non_vector_type));

+

+  if (!SrcTy->isDependentType() && !DstTy->isDependentType()) {

+    unsigned SrcElts = SrcTy->getAs<VectorType>()->getNumElements();

+    unsigned DstElts = DstTy->getAs<VectorType>()->getNumElements();

+    if (SrcElts != DstElts)

+      return ExprError(Diag(BuiltinLoc,

+                            diag::err_convertvector_incompatible_vector)

+                       << E->getSourceRange());

+  }

+

+  return new (Context)

+      ConvertVectorExpr(E, TInfo, DstTy, VK, OK, BuiltinLoc, RParenLoc);

+}

+

+/// SemaBuiltinPrefetch - Handle __builtin_prefetch.

+// This is declared to take (const void*, ...) and can take two

+// optional constant int args.

+bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) {

+  unsigned NumArgs = TheCall->getNumArgs();

+

+  if (NumArgs > 3)

+    return Diag(TheCall->getLocEnd(),

+             diag::err_typecheck_call_too_many_args_at_most)

+             << 0 /*function call*/ << 3 << NumArgs

+             << TheCall->getSourceRange();

+

+  // Argument 0 is checked for us and the remaining arguments must be

+  // constant integers.

+  for (unsigned i = 1; i != NumArgs; ++i)

     if (SemaBuiltinConstantArgRange(TheCall, i, 0, i == 1 ? 1 : 3))
       return true;
 
diff --git a/test/Sema/builtins.c b/test/Sema/builtins.c
index 7e99999..893a445 100644
--- a/test/Sema/builtins.c
+++ b/test/Sema/builtins.c
@@ -53,203 +53,226 @@
 
 // overloaded atomics should be declared only once.
 void test9_1(volatile int* ptr, int val) {
-  __sync_fetch_and_add_4(ptr, val);
-}
-void test9_2(volatile int* ptr, int val) {
-  __sync_fetch_and_add(ptr, val);
-}
-void test9_3(volatile int* ptr, int val) {
-  __sync_fetch_and_add_4(ptr, val);
-  __sync_fetch_and_add(ptr, val);
-  __sync_fetch_and_add(ptr, val);
-  __sync_fetch_and_add_4(ptr, val);
-  __sync_fetch_and_add_4(ptr, val);
-}
-
-void test9_4(volatile int* ptr, int val) {
-  // expected-warning@+1 {{the semantics of this intrinsic changed with GCC version 4.4 - the newer semantics are provided here}}
-  __sync_fetch_and_nand(ptr, val);
-}
-
-// rdar://7236819
-void test10(void) __attribute__((noreturn));
-
-void test10(void) {
-  __asm__("int3");
-  __builtin_unreachable();
-
-  // No warning about falling off the end of a noreturn function.
-}
-
-void test11(int X) {
-  switch (X) {
-  case __builtin_eh_return_data_regno(0):  // constant foldable.
-    break;
-  }
-
-  __builtin_eh_return_data_regno(X);  // expected-error {{argument to '__builtin_eh_return_data_regno' must be a constant integer}}
-}
-
-// PR5062
-void test12(void) __attribute__((__noreturn__));
-void test12(void) {
-  __builtin_trap();  // no warning because trap is noreturn.
-}
-
-void test_unknown_builtin(int a, int b) {
-  __builtin_isles(a, b); // expected-error{{use of unknown builtin}} \
-                         // expected-note{{did you mean '__builtin_isless'?}}
-}
-
-int test13() {
-  __builtin_eh_return(0, 0); // no warning, eh_return never returns.
-}
-
-// <rdar://problem/8228293>
-void test14() {
-  int old;
-  old = __sync_fetch_and_min((volatile int *)&old, 1);
-}
-
-// <rdar://problem/8336581>
-void test15(const char *s) {
-  __builtin_printf("string is %s\n", s);
-}
-
-// PR7885
-int test16() {
-  return __builtin_constant_p() + // expected-error{{too few arguments}}
-         __builtin_constant_p(1, 2); // expected-error {{too many arguments}}
-}
-
-const int test17_n = 0;
-const char test17_c[] = {1, 2, 3, 0};
-const char test17_d[] = {1, 2, 3, 4};
-typedef int __attribute__((vector_size(16))) IntVector;
-struct Aggregate { int n; char c; };
-enum Enum { EnumValue1, EnumValue2 };
-
-typedef __typeof(sizeof(int)) size_t;
-size_t strlen(const char *);
-
-void test17() {
-#define ASSERT(...) { int arr[(__VA_ARGS__) ? 1 : -1]; }
-#define T(...) ASSERT(__builtin_constant_p(__VA_ARGS__))
-#define F(...) ASSERT(!__builtin_constant_p(__VA_ARGS__))
-
-  // __builtin_constant_p returns 1 if the argument folds to:
-  //  - an arithmetic constant with value which is known at compile time
-  T(test17_n);
-  T(&test17_c[3] - test17_c);
-  T(3i + 5); // expected-warning {{imaginary constant}}
-  T(4.2 * 7.6);
-  T(EnumValue1);
-  T((enum Enum)(int)EnumValue2);
-
-  //  - the address of the first character of a string literal, losslessly cast
-  //    to any type
-  T("string literal");
-  T((double*)"string literal");
-  T("string literal" + 0);
-  T((long)"string literal");
-
-  // ... and otherwise returns 0.
-  F("string literal" + 1);
-  F(&test17_n);
-  F(test17_c);
-  F(&test17_c);
-  F(&test17_d);
-  F((struct Aggregate){0, 1});
-  F((IntVector){0, 1, 2, 3});
-
-  // Ensure that a technique used in glibc is handled correctly.
-#define OPT(...) (__builtin_constant_p(__VA_ARGS__) && strlen(__VA_ARGS__) < 4)
-  // FIXME: These are incorrectly treated as ICEs because strlen is treated as
-  // a builtin.
-  ASSERT(OPT("abc"));
-  ASSERT(!OPT("abcd"));
-  // In these cases, the strlen is non-constant, but the __builtin_constant_p
-  // is 0: the array size is not an ICE but is foldable.
-  ASSERT(!OPT(test17_c));        // expected-warning {{folded}}
-  ASSERT(!OPT(&test17_c[0]));    // expected-warning {{folded}}
-  ASSERT(!OPT((char*)test17_c)); // expected-warning {{folded}}
-  ASSERT(!OPT(test17_d));        // expected-warning {{folded}}
-  ASSERT(!OPT(&test17_d[0]));    // expected-warning {{folded}}
-  ASSERT(!OPT((char*)test17_d)); // expected-warning {{folded}}
-
-#undef OPT
-#undef T
-#undef F
-}
-
-void test18() {
-  char src[1024];
-  char dst[2048];
-  size_t result;
-  void *ptr;
-
-  ptr = __builtin___memccpy_chk(dst, src, '\037', sizeof(src), sizeof(dst));
-  result = __builtin___strlcpy_chk(dst, src, sizeof(dst), sizeof(dst));
-  result = __builtin___strlcat_chk(dst, src, sizeof(dst), sizeof(dst));
-
-  ptr = __builtin___memccpy_chk(dst, src, '\037', sizeof(src));      // expected-error {{too few arguments to function call}}
-  ptr = __builtin___strlcpy_chk(dst, src, sizeof(dst), sizeof(dst)); // expected-warning {{incompatible integer to pointer conversion}}
-  ptr = __builtin___strlcat_chk(dst, src, sizeof(dst), sizeof(dst)); // expected-warning {{incompatible integer to pointer conversion}}
-}
-
-void no_ms_builtins() {
-  __assume(1); // expected-warning {{implicit declaration}}
-  __noop(1); // expected-warning {{implicit declaration}}
-  __debugbreak(); // expected-warning {{implicit declaration}}
-}
-
-void unavailable() {
-  __builtin_operator_new(0); // expected-error {{'__builtin_operator_new' is only available in C++}}
-  __builtin_operator_delete(0); // expected-error {{'__builtin_operator_delete' is only available in C++}}
-}
-
-// rdar://18259539
-size_t strlcpy(char * restrict dst, const char * restrict src, size_t size);
-size_t strlcat(char * restrict dst, const char * restrict src, size_t size);
-
-void Test19(void)
-{
-        static char b[40];
-        static char buf[20];
-
-        strlcpy(buf, b, sizeof(b)); // expected-warning {{size argument in 'strlcpy' call appears to be size of the source; expected the size of the destination}} \\
-                                    // expected-note {{change size argument to be the size of the destination}}
-        __builtin___strlcpy_chk(buf, b, sizeof(b), __builtin_object_size(buf, 0)); // expected-warning {{size argument in '__builtin___strlcpy_chk' call appears to be size of the source; expected the size of the destination}} \
-                                    // expected-note {{change size argument to be the size of the destination}} \
-				    // expected-warning {{'__builtin___strlcpy_chk' will always overflow destination buffer}}
-
-        strlcat(buf, b, sizeof(b)); // expected-warning {{size argument in 'strlcat' call appears to be size of the source; expected the size of the destination}} \
-                                    // expected-note {{change size argument to be the size of the destination}}
-				    
-        __builtin___strlcat_chk(buf, b, sizeof(b), __builtin_object_size(buf, 0)); // expected-warning {{size argument in '__builtin___strlcat_chk' call appears to be size of the source; expected the size of the destination}} \
-                                                                                   // expected-note {{change size argument to be the size of the destination}} \
-				                                                   // expected-warning {{'__builtin___strlcat_chk' will always overflow destination buffer}}
-}
-
-// rdar://11076881
-char * Test20(char *p, const char *in, unsigned n)
-{
-    static char buf[10];
-
-    __builtin___memcpy_chk (&buf[6], in, 5, __builtin_object_size (&buf[6], 0)); // expected-warning {{'__builtin___memcpy_chk' will always overflow destination buffer}}
-
-    __builtin___memcpy_chk (p, "abcde", n, __builtin_object_size (p, 0));
-
-    __builtin___memcpy_chk (&buf[5], "abcde", 5, __builtin_object_size (&buf[5], 0));
-
-    __builtin___memcpy_chk (&buf[5], "abcde", n, __builtin_object_size (&buf[5], 0));
-
-    __builtin___memcpy_chk (&buf[6], "abcde", 5, __builtin_object_size (&buf[6], 0)); // expected-warning {{'__builtin___memcpy_chk' will always overflow destination buffer}}
-
-    return buf;
-}
-
-void test21(const int *ptr) {
-  __sync_fetch_and_add(ptr, 1); // expected-error{{address argument to atomic builtin cannot be const-qualified ('const int *' invalid)}}
-  __atomic_fetch_add(ptr, 1, 0);  // expected-error {{address argument to atomic operation must be a pointer to non-const type ('const int *' invalid)}}
-}
+  __sync_fetch_and_add_4(ptr, val);

+}

+void test9_2(volatile int* ptr, int val) {

+  __sync_fetch_and_add(ptr, val);

+}

+void test9_3(volatile int* ptr, int val) {

+  __sync_fetch_and_add_4(ptr, val);

+  __sync_fetch_and_add(ptr, val);

+  __sync_fetch_and_add(ptr, val);

+  __sync_fetch_and_add_4(ptr, val);

+  __sync_fetch_and_add_4(ptr, val);

+}

+

+void test9_4(volatile int* ptr, int val) {

+  // expected-warning@+1 {{the semantics of this intrinsic changed with GCC version 4.4 - the newer semantics are provided here}}

+  __sync_fetch_and_nand(ptr, val);

+}

+

+// rdar://7236819

+void test10(void) __attribute__((noreturn));

+

+void test10(void) {

+  __asm__("int3");

+  __builtin_unreachable();

+

+  // No warning about falling off the end of a noreturn function.

+}

+

+void test11(int X) {

+  switch (X) {

+  case __builtin_eh_return_data_regno(0):  // constant foldable.

+    break;

+  }

+

+  __builtin_eh_return_data_regno(X);  // expected-error {{argument to '__builtin_eh_return_data_regno' must be a constant integer}}

+}

+

+// PR5062

+void test12(void) __attribute__((__noreturn__));

+void test12(void) {

+  __builtin_trap();  // no warning because trap is noreturn.

+}

+

+void test_unknown_builtin(int a, int b) {

+  __builtin_isles(a, b); // expected-error{{use of unknown builtin}} \

+                         // expected-note{{did you mean '__builtin_isless'?}}

+}

+

+int test13() {

+  __builtin_eh_return(0, 0); // no warning, eh_return never returns.

+}

+

+// <rdar://problem/8228293>

+void test14() {

+  int old;

+  old = __sync_fetch_and_min((volatile int *)&old, 1);

+}

+

+// <rdar://problem/8336581>

+void test15(const char *s) {

+  __builtin_printf("string is %s\n", s);

+}

+

+// PR7885

+int test16() {

+  return __builtin_constant_p() + // expected-error{{too few arguments}}

+         __builtin_constant_p(1, 2); // expected-error {{too many arguments}}

+}

+

+const int test17_n = 0;

+const char test17_c[] = {1, 2, 3, 0};

+const char test17_d[] = {1, 2, 3, 4};

+typedef int __attribute__((vector_size(16))) IntVector;

+struct Aggregate { int n; char c; };

+enum Enum { EnumValue1, EnumValue2 };

+

+typedef __typeof(sizeof(int)) size_t;

+size_t strlen(const char *);

+

+void test17() {

+#define ASSERT(...) { int arr[(__VA_ARGS__) ? 1 : -1]; }

+#define T(...) ASSERT(__builtin_constant_p(__VA_ARGS__))

+#define F(...) ASSERT(!__builtin_constant_p(__VA_ARGS__))

+

+  // __builtin_constant_p returns 1 if the argument folds to:

+  //  - an arithmetic constant with value which is known at compile time

+  T(test17_n);

+  T(&test17_c[3] - test17_c);

+  T(3i + 5); // expected-warning {{imaginary constant}}

+  T(4.2 * 7.6);

+  T(EnumValue1);

+  T((enum Enum)(int)EnumValue2);

+

+  //  - the address of the first character of a string literal, losslessly cast

+  //    to any type

+  T("string literal");

+  T((double*)"string literal");

+  T("string literal" + 0);

+  T((long)"string literal");

+

+  // ... and otherwise returns 0.

+  F("string literal" + 1);

+  F(&test17_n);

+  F(test17_c);

+  F(&test17_c);

+  F(&test17_d);

+  F((struct Aggregate){0, 1});

+  F((IntVector){0, 1, 2, 3});

+

+  // Ensure that a technique used in glibc is handled correctly.

+#define OPT(...) (__builtin_constant_p(__VA_ARGS__) && strlen(__VA_ARGS__) < 4)

+  // FIXME: These are incorrectly treated as ICEs because strlen is treated as

+  // a builtin.

+  ASSERT(OPT("abc"));

+  ASSERT(!OPT("abcd"));

+  // In these cases, the strlen is non-constant, but the __builtin_constant_p

+  // is 0: the array size is not an ICE but is foldable.

+  ASSERT(!OPT(test17_c));        // expected-warning {{folded}}

+  ASSERT(!OPT(&test17_c[0]));    // expected-warning {{folded}}

+  ASSERT(!OPT((char*)test17_c)); // expected-warning {{folded}}

+  ASSERT(!OPT(test17_d));        // expected-warning {{folded}}

+  ASSERT(!OPT(&test17_d[0]));    // expected-warning {{folded}}

+  ASSERT(!OPT((char*)test17_d)); // expected-warning {{folded}}

+

+#undef OPT

+#undef T

+#undef F

+}

+

+void test18() {

+  char src[1024];

+  char dst[2048];

+  size_t result;

+  void *ptr;

+

+  ptr = __builtin___memccpy_chk(dst, src, '\037', sizeof(src), sizeof(dst));

+  result = __builtin___strlcpy_chk(dst, src, sizeof(dst), sizeof(dst));

+  result = __builtin___strlcat_chk(dst, src, sizeof(dst), sizeof(dst));

+

+  ptr = __builtin___memccpy_chk(dst, src, '\037', sizeof(src));      // expected-error {{too few arguments to function call}}

+  ptr = __builtin___strlcpy_chk(dst, src, sizeof(dst), sizeof(dst)); // expected-warning {{incompatible integer to pointer conversion}}

+  ptr = __builtin___strlcat_chk(dst, src, sizeof(dst), sizeof(dst)); // expected-warning {{incompatible integer to pointer conversion}}

+}

+

+void no_ms_builtins() {

+  __assume(1); // expected-warning {{implicit declaration}}

+  __noop(1); // expected-warning {{implicit declaration}}

+  __debugbreak(); // expected-warning {{implicit declaration}}

+}

+

+void unavailable() {

+  __builtin_operator_new(0); // expected-error {{'__builtin_operator_new' is only available in C++}}

+  __builtin_operator_delete(0); // expected-error {{'__builtin_operator_delete' is only available in C++}}

+}

+

+// rdar://18259539

+size_t strlcpy(char * restrict dst, const char * restrict src, size_t size);

+size_t strlcat(char * restrict dst, const char * restrict src, size_t size);

+

+void Test19(void)

+{

+        static char b[40];

+        static char buf[20];

+

+        strlcpy(buf, b, sizeof(b)); // expected-warning {{size argument in 'strlcpy' call appears to be size of the source; expected the size of the destination}} \\

+                                    // expected-note {{change size argument to be the size of the destination}}

+        __builtin___strlcpy_chk(buf, b, sizeof(b), __builtin_object_size(buf, 0)); // expected-warning {{size argument in '__builtin___strlcpy_chk' call appears to be size of the source; expected the size of the destination}} \

+                                    // expected-note {{change size argument to be the size of the destination}} \

+				    // expected-warning {{'__builtin___strlcpy_chk' will always overflow destination buffer}}

+

+        strlcat(buf, b, sizeof(b)); // expected-warning {{size argument in 'strlcat' call appears to be size of the source; expected the size of the destination}} \

+                                    // expected-note {{change size argument to be the size of the destination}}

+				    

+        __builtin___strlcat_chk(buf, b, sizeof(b), __builtin_object_size(buf, 0)); // expected-warning {{size argument in '__builtin___strlcat_chk' call appears to be size of the source; expected the size of the destination}} \

+                                                                                   // expected-note {{change size argument to be the size of the destination}} \

+				                                                   // expected-warning {{'__builtin___strlcat_chk' will always overflow destination buffer}}

+}

+

+// rdar://11076881

+char * Test20(char *p, const char *in, unsigned n)

+{

+    static char buf[10];

+

+    __builtin___memcpy_chk (&buf[6], in, 5, __builtin_object_size (&buf[6], 0)); // expected-warning {{'__builtin___memcpy_chk' will always overflow destination buffer}}

+

+    __builtin___memcpy_chk (p, "abcde", n, __builtin_object_size (p, 0));

+

+    __builtin___memcpy_chk (&buf[5], "abcde", 5, __builtin_object_size (&buf[5], 0));

+

+    __builtin___memcpy_chk (&buf[5], "abcde", n, __builtin_object_size (&buf[5], 0));

+

+    __builtin___memcpy_chk (&buf[6], "abcde", 5, __builtin_object_size (&buf[6], 0)); // expected-warning {{'__builtin___memcpy_chk' will always overflow destination buffer}}

+

+    return buf;

+}

+

+void test21(const int *ptr) {

+  __sync_fetch_and_add(ptr, 1); // expected-error{{address argument to atomic builtin cannot be const-qualified ('const int *' invalid)}}

+  __atomic_fetch_add(ptr, 1, 0);  // expected-error {{address argument to atomic operation must be a pointer to non-const type ('const int *' invalid)}}

+}

+

+void test22(void) {

+  (void)__builtin_signbit(); // expected-error{{too few arguments to function call, expected 1, have 0}}

+  (void)__builtin_signbit(1.0, 2.0, 3.0); // expected-error{{too many arguments to function call, expected 1, have 3}}

+  (void)__builtin_signbit(1); // expected-error {{floating point classification requires argument of floating point type (passed in 'int')}}

+  (void)__builtin_signbit(1.0);

+  (void)__builtin_signbit(1.0f);

+  (void)__builtin_signbit(1.0L);

+

+  (void)__builtin_signbitf(); // expected-error{{too few arguments to function call, expected 1, have 0}}

+  (void)__builtin_signbitf(1.0, 2.0, 3.0); // expected-error{{too many arguments to function call, expected 1, have 3}}

+  (void)__builtin_signbitf(1);

+  (void)__builtin_signbitf(1.0);

+  (void)__builtin_signbitf(1.0f);

+  (void)__builtin_signbitf(1.0L);

+

+  (void)__builtin_signbitl(); // expected-error{{too few arguments to function call, expected 1, have 0}}

+  (void)__builtin_signbitl(1.0, 2.0, 3.0); // expected-error{{too many arguments to function call, expected 1, have 3}}

+  (void)__builtin_signbitl(1);

+  (void)__builtin_signbitl(1.0);

+  (void)__builtin_signbitl(1.0f);

+  (void)__builtin_signbitl(1.0L);

+}