Index: clang/include/clang/AST/Expr.h =================================================================== --- clang/include/clang/AST/Expr.h +++ clang/include/clang/AST/Expr.h @@ -1031,6 +1031,7 @@ static ResultStorageKind getStorageKind(const Type *T, const ASTContext &Context); + SourceLocation getLocation() const { return getBeginLoc(); } SourceLocation getBeginLoc() const LLVM_READONLY { return SubExpr->getBeginLoc(); } Index: clang/lib/CodeGen/CGExpr.cpp =================================================================== --- clang/lib/CodeGen/CGExpr.cpp +++ clang/lib/CodeGen/CGExpr.cpp @@ -1292,8 +1292,20 @@ return EmitVAArgExprLValue(cast(E)); case Expr::DeclRefExprClass: return EmitDeclRefLValue(cast(E)); - case Expr::ConstantExprClass: - return EmitLValue(cast(E)->getSubExpr()); + case Expr::ConstantExprClass: { + const ConstantExpr *CE = cast(E); + + if (CE->hasAPValueResult()) { + QualType T = getContext().getPointerType(CE->getType()); + llvm::Constant *C = ConstantEmitter(*this).emitAbstract( + CE->getLocation(), CE->getAPValueResult(), T); + ConstantAddress Addr(C, getContext().getTypeAlignInChars(T)); + LValueBaseInfo BI; + return LValue::MakeAddr(Addr, T, getContext(), BI, TBAAAccessInfo()); + } + + return EmitLValue(CE->getSubExpr()); + } case Expr::ParenExprClass: return EmitLValue(cast(E)->getSubExpr()); case Expr::GenericSelectionExprClass: Index: clang/lib/CodeGen/CGExprAgg.cpp =================================================================== --- clang/lib/CodeGen/CGExprAgg.cpp +++ clang/lib/CodeGen/CGExprAgg.cpp @@ -126,7 +126,17 @@ } void VisitConstantExpr(ConstantExpr *E) { - return Visit(E->getSubExpr()); + if (E->hasAPValueResult()) { + // Create a temporary for the value and store the constant. + llvm::Constant *Const = ConstantEmitter(CGF).emitAbstract( + E->getLocation(), E->getAPValueResult(), E->getType()); + Address Addr = CGF.CreateMemTemp(E->getType()); + CGF.InitTempAlloca(Addr, Const); + RValue RV = RValue::getAggregate(Addr); + EmitFinalDestCopy(E->getType(), RV); + } else { + Visit(E->getSubExpr()); + } } // l-values. Index: clang/lib/CodeGen/CGExprScalar.cpp =================================================================== --- clang/lib/CodeGen/CGExprScalar.cpp +++ clang/lib/CodeGen/CGExprScalar.cpp @@ -433,7 +433,13 @@ Value *VisitExpr(Expr *S); Value *VisitConstantExpr(ConstantExpr *E) { - return Visit(E->getSubExpr()); + if (E->hasAPValueResult()) { + assert(!E->getType()->isVoidType()); + return ConstantEmitter(CGF).emitAbstract( + E->getLocation(), E->getAPValueResult(), E->getType()); + } else { + return Visit(E->getSubExpr()); + } } Value *VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr()); Index: clang/lib/CodeGen/CGStmt.cpp =================================================================== --- clang/lib/CodeGen/CGStmt.cpp +++ clang/lib/CodeGen/CGStmt.cpp @@ -1092,8 +1092,13 @@ // statements following block literals with non-trivial cleanups. RunCleanupsScope cleanupScope(*this); if (const FullExpr *fe = dyn_cast_or_null(RV)) { - enterFullExpression(fe); - RV = fe->getSubExpr(); + // Constant expressions will emit their cached APValues, so + // we don't want to handle this here, as it will unwrap them, + // preventing the cached results from being used. + if (!isa(fe)) { + enterFullExpression(fe); + RV = fe->getSubExpr(); + } } // FIXME: Clean this up by using an LValue for ReturnTemp,