diff options
Diffstat (limited to 'lib/CodeGen/CGExpr.cpp')
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index a35f81ca20..496c3fc0aa 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -1792,6 +1792,35 @@ EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) { return MakeAddrLValue(phi, expr->getType()); } +static LValue emitUnknownAnyLValue(CodeGenFunction &CGF, + const Expr *operand, + QualType resolvedType) { + const ValueDecl *decl; + if (const DeclRefExpr *ref = dyn_cast<DeclRefExpr>(operand)) { + decl = ref->getDecl(); + } else if (const MemberExpr *mem = dyn_cast<MemberExpr>(operand)) { + decl = mem->getMemberDecl(); + + // Emit (and ignore) the base. + if (mem->isArrow()) + CGF.EmitScalarExpr(mem->getBase()); + else + CGF.EmitLValue(mem->getBase()); + } else { + llvm_unreachable("unexpected operand of unknown-any resolution!"); + decl = 0; + } + llvm::Value *addr = CGF.CGM.getAddrOfUnknownAnyDecl(decl, resolvedType); + + QualType type = resolvedType; + if (const ReferenceType *ref = type->getAs<ReferenceType>()) { + addr = CGF.Builder.CreateLoad(addr, "ref.value"); + type = ref->getPointeeType(); + } + + return CGF.MakeAddrLValue(addr, type); +} + /// EmitCastLValue - Casts are never lvalues unless that cast is a dynamic_cast. /// If the cast is a dynamic_cast, we can have the usual lvalue result, /// otherwise if a cast is needed by the code generator in an lvalue context, @@ -1930,11 +1959,12 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { ConvertType(ToType)); return MakeAddrLValue(V, E->getType()); } - case CK_ResolveUnknownAnyType: { - const DeclRefExpr *declRef = cast<DeclRefExpr>(E->getSubExpr()); - llvm::Constant *addr = CGM.getAddrOfUnknownAnyDecl(declRef->getDecl(), - E->getType()); - return MakeAddrLValue(addr, E->getType()); + case CK_ResolveUnknownAnyType: + return emitUnknownAnyLValue(*this, E->getSubExpr(), E->getType()); + case CK_ResolveUnknownAnyTypeToReference: { + // l-value vs. r-value reference type shouldn't matter here. + QualType type = getContext().getLValueReferenceType(E->getType()); + return emitUnknownAnyLValue(*this, E->getSubExpr(), type); } } |