зеркало из https://github.com/microsoft/clang-1.git
Add Builtins.def attribute for "can be a constant expression".
- Enabled for builtins which are always constant expressions (__builtin_huge_val*, __builtin_inf*, __builtin_constant_p, __builtin_classify_type, __builtin___CFStringMakeConstantString). Added Builtin::Context::isConstantExpr. - Currently overly simply interface which only works for builtins whose constantexprness does not depend on their arguments. CallExpr::isBuiltinConstantExpr now takes an ASTContext argument. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@56983 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
de45428f92
Коммит
ae3f4919e4
|
@ -52,15 +52,16 @@
|
|||
// n -> nothrow
|
||||
// c -> const
|
||||
// F -> this is a libc/libm function with a '__builtin_' prefix added.
|
||||
// C -> this builtin can be used as a "constant expression"
|
||||
// FIXME: gcc has nonnull
|
||||
|
||||
// Standard libc/libm functions:
|
||||
BUILTIN(__builtin_huge_val, "d", "nc")
|
||||
BUILTIN(__builtin_huge_valf, "f", "nc")
|
||||
BUILTIN(__builtin_huge_vall, "Ld", "nc")
|
||||
BUILTIN(__builtin_inf , "d" , "nc")
|
||||
BUILTIN(__builtin_inff , "f" , "nc")
|
||||
BUILTIN(__builtin_infl , "Ld" , "nc")
|
||||
BUILTIN(__builtin_huge_val, "d", "ncC")
|
||||
BUILTIN(__builtin_huge_valf, "f", "ncC")
|
||||
BUILTIN(__builtin_huge_vall, "Ld", "ncC")
|
||||
BUILTIN(__builtin_inf , "d" , "ncC")
|
||||
BUILTIN(__builtin_inff , "f" , "ncC")
|
||||
BUILTIN(__builtin_infl , "Ld" , "ncC")
|
||||
BUILTIN(__builtin_nan, "dcC*" , "ncF")
|
||||
BUILTIN(__builtin_nanf, "fcC*" , "ncF")
|
||||
BUILTIN(__builtin_nanl, "LdcC*", "ncF")
|
||||
|
@ -111,9 +112,9 @@ BUILTIN(__builtin_bswap32, "UiUi", "nc")
|
|||
BUILTIN(__builtin_bswap64, "ULLiULLi", "nc")
|
||||
|
||||
// Random GCC builtins
|
||||
BUILTIN(__builtin_constant_p, "UsUs", "nc")
|
||||
BUILTIN(__builtin_classify_type, "i.", "nc")
|
||||
BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "nc")
|
||||
BUILTIN(__builtin_constant_p, "UsUs", "ncC")
|
||||
BUILTIN(__builtin_classify_type, "i.", "ncC")
|
||||
BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "ncC")
|
||||
BUILTIN(__builtin_va_start, "va&.", "n")
|
||||
BUILTIN(__builtin_va_end, "va&", "n")
|
||||
BUILTIN(__builtin_va_copy, "va&a", "n")
|
||||
|
|
|
@ -73,11 +73,17 @@ public:
|
|||
}
|
||||
|
||||
/// isLibFunction - Return true if this is a builtin for a libc/libm function,
|
||||
/// with a "__builtin_" prefix (e.g. __builtin_inf).
|
||||
/// with a "__builtin_" prefix (e.g. __builtin_abs).
|
||||
bool isLibFunction(unsigned ID) const {
|
||||
return strchr(GetRecord(ID).Attributes, 'F') != 0;
|
||||
}
|
||||
|
||||
/// isConstantExpr - Return true if this builtin can be used where a
|
||||
/// constant expression is required.
|
||||
bool isConstantExpr(unsigned ID) const {
|
||||
return strchr(GetRecord(ID).Attributes, 'C') != 0;
|
||||
}
|
||||
|
||||
/// hasVAListUse - Return true of the specified builtin uses __builtin_va_list
|
||||
/// as an operand or return type.
|
||||
bool hasVAListUse(unsigned ID) const {
|
||||
|
|
|
@ -704,7 +704,7 @@ public:
|
|||
bool isBuiltinClassifyType(llvm::APSInt &Result) const;
|
||||
|
||||
/// isBuiltinConstantExpr - Return true if this built-in call is constant.
|
||||
bool isBuiltinConstantExpr() const;
|
||||
bool isBuiltinConstantExpr(ASTContext &Ctx) const;
|
||||
|
||||
SourceLocation getRParenLoc() const { return RParenLoc; }
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ void CallExpr::setNumArgs(unsigned NumArgs) {
|
|||
this->NumArgs = NumArgs;
|
||||
}
|
||||
|
||||
bool CallExpr::isBuiltinConstantExpr() const {
|
||||
bool CallExpr::isBuiltinConstantExpr(ASTContext &Ctx) const {
|
||||
// All simple function calls (e.g. func()) are implicitly cast to pointer to
|
||||
// function. As a result, we try and obtain the DeclRefExpr from the
|
||||
// ImplicitCastExpr.
|
||||
|
@ -159,10 +159,7 @@ bool CallExpr::isBuiltinConstantExpr() const {
|
|||
if (!builtinID)
|
||||
return false;
|
||||
|
||||
// We have a builtin that is a constant expression
|
||||
return builtinID == Builtin::BI__builtin___CFStringMakeConstantString ||
|
||||
builtinID == Builtin::BI__builtin_classify_type ||
|
||||
builtinID == Builtin::BI__builtin_huge_valf;
|
||||
return Ctx.BuiltinInfo.isConstantExpr(builtinID);
|
||||
}
|
||||
|
||||
bool CallExpr::isBuiltinClassifyType(llvm::APSInt &Result) const {
|
||||
|
@ -585,7 +582,7 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const {
|
|||
return true;
|
||||
case CallExprClass: {
|
||||
const CallExpr *CE = cast<CallExpr>(this);
|
||||
if (CE->isBuiltinConstantExpr())
|
||||
if (CE->isBuiltinConstantExpr(Ctx))
|
||||
return true;
|
||||
if (Loc) *Loc = getLocStart();
|
||||
return false;
|
||||
|
|
|
@ -878,7 +878,7 @@ bool Sema::CheckAddressConstantExpression(const Expr* Init) {
|
|||
return false;
|
||||
case Expr::CallExprClass: {
|
||||
const CallExpr *CE = cast<CallExpr>(Init);
|
||||
if (CE->isBuiltinConstantExpr())
|
||||
if (CE->isBuiltinConstantExpr(Context))
|
||||
return false;
|
||||
Diag(Init->getExprLoc(),
|
||||
diag::err_init_element_not_constant, Init->getSourceRange());
|
||||
|
@ -1077,7 +1077,7 @@ bool Sema::CheckArithmeticConstantExpression(const Expr* Init) {
|
|||
return false;
|
||||
case Expr::CallExprClass: {
|
||||
const CallExpr *CE = cast<CallExpr>(Init);
|
||||
if (CE->isBuiltinConstantExpr())
|
||||
if (CE->isBuiltinConstantExpr(Context))
|
||||
return false;
|
||||
Diag(Init->getExprLoc(),
|
||||
diag::err_init_element_not_constant, Init->getSourceRange());
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
// RUN: clang -fsyntax-only %s
|
||||
|
||||
// Math stuff
|
||||
|
||||
float g0 = __builtin_huge_val();
|
||||
double g1 = __builtin_huge_valf();
|
||||
long double g2 = __builtin_huge_vall();
|
||||
float g3 = __builtin_inf();
|
||||
double g4 = __builtin_inff();
|
||||
long double g5 = __builtin_infl();
|
||||
|
||||
// GCC misc stuff
|
||||
|
||||
extern int f();
|
||||
|
||||
int h0 = __builtin_types_compatible_p(int,float);
|
||||
//int h1 = __builtin_choose_expr(1, 10, f());
|
||||
//int h2 = __builtin_expect(0, 0);
|
Загрузка…
Ссылка в новой задаче