diff options
author | John McCall <rjmccall@apple.com> | 2011-02-26 05:39:39 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-02-26 05:39:39 +0000 |
commit | bebede4d336a709d237fdbf20ddd5f2eac51101b (patch) | |
tree | d20ed07fc2171f3e4e27be25147c398a59ec71b5 /clang/lib/Sema/SemaChecking.cpp | |
parent | 31ca7efa041d3f97906cfc943325cd9e92e583e5 (diff) | |
download | bcm5719-llvm-bebede4d336a709d237fdbf20ddd5f2eac51101b.tar.gz bcm5719-llvm-bebede4d336a709d237fdbf20ddd5f2eac51101b.zip |
Provide a bit saying that a builtin undergoes custom type-checking, then
don't let calls to such functions go down the normal type-checking path.
Test this out with __builtin_classify_type and __builtin_constant_p.
llvm-svn: 126539
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 97cc44e7372..d83809d7089 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -66,6 +66,26 @@ bool Sema::CheckablePrintfAttr(const FormatAttr *Format, CallExpr *TheCall) { return false; } +/// Checks that a call expression's argument count is the desired number. +/// This is useful when doing custom type-checking. Returns true on error. +static bool checkArgCount(Sema &S, CallExpr *call, unsigned desiredArgCount) { + unsigned argCount = call->getNumArgs(); + if (argCount == desiredArgCount) return false; + + if (argCount < desiredArgCount) + return S.Diag(call->getLocEnd(), diag::err_typecheck_call_too_few_args) + << 0 /*function call*/ << desiredArgCount << argCount + << call->getSourceRange(); + + // Highlight all the excess arguments. + SourceRange range(call->getArg(desiredArgCount)->getLocStart(), + call->getArg(argCount - 1)->getLocEnd()); + + return S.Diag(range.getBegin(), diag::err_typecheck_call_too_many_args) + << 0 /*function call*/ << desiredArgCount << argCount + << call->getArg(1)->getSourceRange(); +} + ExprResult Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { ExprResult TheCallResult(Owned(TheCall)); @@ -137,15 +157,14 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { if (SemaBuiltinLongjmp(TheCall)) return ExprError(); 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 (TheCall->getNumArgs() == 0) - return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args) - << 0 /*function call*/ << 1 << 0 << TheCall->getSourceRange(); - if (TheCall->getNumArgs() > 1) - return Diag(TheCall->getArg(1)->getLocStart(), - diag::err_typecheck_call_too_many_args) - << 0 /*function call*/ << 1 << TheCall->getNumArgs() - << TheCall->getArg(1)->getSourceRange(); + 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_sub: |