diff options
author | Mike Stump <mrs@apple.com> | 2009-10-26 18:35:08 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-10-26 18:35:08 +0000 |
commit | 722cedfb0dbb4617d99695b1444b65bc7b796f99 (patch) | |
tree | d8fafd759db42856b522b49c89d625c9496e7e8c /clang/lib/AST/ExprConstant.cpp | |
parent | 9aba0d9988c6d3056ed4e3628934c29943888bc7 (diff) | |
download | bcm5719-llvm-722cedfb0dbb4617d99695b1444b65bc7b796f99.tar.gz bcm5719-llvm-722cedfb0dbb4617d99695b1444b65bc7b796f99.zip |
__builtin_object_size refinements. WIP.
llvm-svn: 85136
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 94d22998ebb..91295584214 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -873,6 +873,36 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { switch (E->isBuiltinCall(Info.Ctx)) { default: return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E); + + case Builtin::BI__builtin_object_size: { + llvm::APSInt Result(32); + + if (!E->getArg(1)->isIntegerConstantExpr(Result, Info.Ctx)) + assert(0 && "arg2 not ice in __builtin_object_size"); + + const Expr *Arg = E->getArg(0)->IgnoreParens(); + Expr::EvalResult Base; + if (Arg->Evaluate(Base, Info.Ctx) + && Base.Val.getKind() == APValue::LValue + && !Base.HasSideEffects) + if (const Expr *LVBase = Base.Val.getLValueBase()) + if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(LVBase)) { + if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) { + uint64_t Size = Info.Ctx.getTypeSize(VD->getType()) / 8; + Size -= Base.Val.getLValueOffset(); + return Success(Size, E); + } + } + + if (Base.HasSideEffects) { + if (Result.getSExtValue() < 2) + return Success(-1, E); + return Success(0, E); + } + + return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E); + } + case Builtin::BI__builtin_classify_type: return Success(EvaluateBuiltinClassifyType(E), E); |