aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-09-23 06:06:36 +0000
committerChris Lattner <sabre@nondot.org>2009-09-23 06:06:36 +0000
commit21fb98ee003e992b0c4e204d98a19e0ef544cae3 (patch)
treefb74b2013454c3630bc397c5a8ba0c8f9b654b42 /lib
parent6a3bc6df36848188e9d0c1d978170c2b0918c6a3 (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.cpp6
-rw-r--r--lib/Basic/Targets.cpp12
-rw-r--r--lib/Sema/Sema.h1
-rw-r--r--lib/Sema/SemaChecking.cpp22
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).