diff options
| author | Aaron Ballman <aaron@aaronballman.com> | 2018-06-19 14:53:20 +0000 | 
|---|---|---|
| committer | Aaron Ballman <aaron@aaronballman.com> | 2018-06-19 14:53:20 +0000 | 
| commit | 68d5064beb0993fe3898f111fa6e7ff358bbe082 (patch) | |
| tree | 9d83c5e0a2e0e3d3ed1b1feff32fc2734811c5b0 /clang/lib/Sema | |
| parent | 9360cb0745b3488e5123bda56557a5b1ce11bf7f (diff) | |
| download | bcm5719-llvm-68d5064beb0993fe3898f111fa6e7ff358bbe082.tar.gz bcm5719-llvm-68d5064beb0993fe3898f111fa6e7ff358bbe082.zip | |
Reverting due to line ending changes; will reapply after addressing that.
llvm-svn: 335049
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 1625 | 
1 files changed, 809 insertions, 816 deletions
| diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index e18dd056e90..5530bd8fe76 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -772,409 +772,406 @@ static bool SemaBuiltinReserveRWPipe(Sema &S, CallExpr *Call) {    }    // 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:
 -  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();
 +  // 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();      }      // Ensure that the second argument is of type 'FunctionType' @@ -4395,419 +4392,415 @@ static bool checkVAStartIsInVariadicFunction(Sema &S, Expr *Fn,    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, 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)
 +/// 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)      if (SemaBuiltinConstantArgRange(TheCall, i, 0, i == 1 ? 1 : 3))        return true; | 

