diff options
author | Chris Lattner <sabre@nondot.org> | 2009-09-23 06:06:36 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-09-23 06:06:36 +0000 |
commit | 21fb98ee003e992b0c4e204d98a19e0ef544cae3 (patch) | |
tree | fb74b2013454c3630bc397c5a8ba0c8f9b654b42 /lib | |
parent | 6a3bc6df36848188e9d0c1d978170c2b0918c6a3 (diff) |
implement support for __builtin_eh_return_data_regno on x86-32 and x86-64.
This implements PR5034 and rdar://6836445.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82614 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ExprConstant.cpp | 6 | ||||
-rw-r--r-- | lib/Basic/Targets.cpp | 12 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 1 | ||||
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 22 |
4 files changed, 38 insertions, 3 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 9c34547db1..5123aaa7ca 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -870,6 +870,12 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { // __builtin_constant_p always has one operand: it returns true if that // operand can be folded, false otherwise. return Success(E->getArg(0)->isEvaluatable(Info.Ctx), E); + + case Builtin::BI__builtin_eh_return_data_regno: { + int Operand = E->getArg(0)->EvaluateAsInt(Info.Ctx).getZExtValue(); + Operand = Info.Ctx.Target.getEHDataRegisterNumber(Operand); + return Success(Operand, E); + } } } diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index f620581cb4..8c31dcb7c6 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -900,6 +900,12 @@ public: virtual const char *getVAListDeclaration() const { return "typedef char* __builtin_va_list;"; } + + int getEHDataRegisterNumber(unsigned RegNo) const { + if (RegNo == 0) return 0; + if (RegNo == 1) return 2; + return -1; + } }; } // end anonymous namespace @@ -990,6 +996,12 @@ public: "} __va_list_tag;" "typedef __va_list_tag __builtin_va_list[1];"; } + + int getEHDataRegisterNumber(unsigned RegNo) const { + if (RegNo == 0) return 0; + if (RegNo == 1) return 1; + return -1; + } }; } // end anonymous namespace diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 193d992881..875da1a1d9 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -3700,6 +3700,7 @@ private: bool SemaBuiltinObjectSize(CallExpr *TheCall); bool SemaBuiltinLongjmp(CallExpr *TheCall); bool SemaBuiltinAtomicOverloaded(CallExpr *TheCall); + bool SemaBuiltinEHReturnDataRegNo(CallExpr *TheCall); bool SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall, bool HasVAListArg, unsigned format_idx, unsigned firstDataArg); diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 1e26c3507b..18a997998a 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -138,6 +138,10 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { if (SemaBuiltinStackAddress(TheCall)) return ExprError(); break; + case Builtin::BI__builtin_eh_return_data_regno: + if (SemaBuiltinEHReturnDataRegNo(TheCall)) + 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 @@ -698,7 +702,7 @@ bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) { llvm::APSInt Result; if (!BT || BT->getKind() != BuiltinType::Int) return Diag(TheCall->getLocStart(), diag::err_prefetch_invalid_argument) - << SourceRange(Arg->getLocStart(), Arg->getLocEnd()); + << Arg->getSourceRange(); if (Arg->isValueDependent()) continue; @@ -713,17 +717,29 @@ bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) { if (i == 1) { if (Result.getSExtValue() < 0 || Result.getSExtValue() > 1) return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range) - << "0" << "1" << SourceRange(Arg->getLocStart(), Arg->getLocEnd()); + << "0" << "1" << Arg->getSourceRange(); } else { if (Result.getSExtValue() < 0 || Result.getSExtValue() > 3) return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range) - << "0" << "3" << SourceRange(Arg->getLocStart(), Arg->getLocEnd()); + << "0" << "3" << Arg->getSourceRange(); } } return false; } +/// SemaBuiltinEHReturnDataRegNo - Handle __builtin_eh_return_data_regno, the +/// operand must be an integer constant. +bool Sema::SemaBuiltinEHReturnDataRegNo(CallExpr *TheCall) { + llvm::APSInt Result; + if (!TheCall->getArg(0)->isIntegerConstantExpr(Result, Context)) + return Diag(TheCall->getLocStart(), diag::err_expr_not_ice) + << TheCall->getArg(0)->getSourceRange(); + + return false; +} + + /// SemaBuiltinObjectSize - Handle __builtin_object_size(void *ptr, /// int type). This simply type checks that type is one of the defined /// constants (0-3). |