diff options
Diffstat (limited to 'clang/Sema')
-rw-r--r-- | clang/Sema/Sema.h | 5 | ||||
-rw-r--r-- | clang/Sema/SemaExpr.cpp | 22 |
2 files changed, 27 insertions, 0 deletions
diff --git a/clang/Sema/Sema.h b/clang/Sema/Sema.h index ff2e5d1fd04..b6d47971f0b 100644 --- a/clang/Sema/Sema.h +++ b/clang/Sema/Sema.h @@ -285,6 +285,11 @@ public: virtual ExprResult ParseTypesCompatibleExpr(SourceLocation BuiltinLoc, TypeTy *arg1, TypeTy *arg2, SourceLocation RPLoc); + + // __builtin_choose_expr(constExpr, expr1, expr2) + virtual ExprResult ParseChooseExpr(SourceLocation BuiltinLoc, + ExprTy *cond, ExprTy *expr1, ExprTy *expr2, + SourceLocation RPLoc); /// ParseCXXCasts - Parse {dynamic,static,reinterpret,const}_cast's. virtual ExprResult ParseCXXCasts(SourceLocation OpLoc, tok::TokenKind Kind, diff --git a/clang/Sema/SemaExpr.cpp b/clang/Sema/SemaExpr.cpp index 2f072f12ab0..7a4200632ce 100644 --- a/clang/Sema/SemaExpr.cpp +++ b/clang/Sema/SemaExpr.cpp @@ -1584,3 +1584,25 @@ Sema::ExprResult Sema::ParseTypesCompatibleExpr(SourceLocation BuiltinLoc, return new TypesCompatibleExpr(Context.IntTy, BuiltinLoc, argT1, argT2, RPLoc); } +Sema::ExprResult Sema::ParseChooseExpr(SourceLocation BuiltinLoc, ExprTy *cond, + ExprTy *expr1, ExprTy *expr2, + SourceLocation RPLoc) { + Expr *CondExpr = static_cast<Expr*>(cond); + Expr *LHSExpr = static_cast<Expr*>(expr1); + Expr *RHSExpr = static_cast<Expr*>(expr2); + + assert((CondExpr && LHSExpr && RHSExpr) && "Missing type argument(s)"); + + // The conditional expression is required to be a constant expression. + llvm::APSInt condEval(32); + SourceLocation ExpLoc; + if (!CondExpr->isIntegerConstantExpr(condEval, Context, &ExpLoc)) + return Diag(ExpLoc, diag::err_typecheck_choose_expr_requires_constant, + CondExpr->getSourceRange()); + + // If the condition is > zero, then the AST type is the same as the LSHExpr. + QualType resType = condEval.getZExtValue() ? LHSExpr->getType() : + RHSExpr->getType(); + return new ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr, resType, RPLoc); +} + |