diff options
author | John McCall <rjmccall@apple.com> | 2011-04-11 07:02:50 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-04-11 07:02:50 +0000 |
commit | 2d2e870745c22a05a173e1fcec85e57535b5314b (patch) | |
tree | 635d38db68de34a33d2690faf839f05bdb467283 /clang/lib/CodeGen/CGExpr.cpp | |
parent | 62920834fa7a9ea0ac717e3b6d4c63449eb551a6 (diff) | |
download | bcm5719-llvm-2d2e870745c22a05a173e1fcec85e57535b5314b.tar.gz bcm5719-llvm-2d2e870745c22a05a173e1fcec85e57535b5314b.zip |
More __unknown_anytype work.
llvm-svn: 129269
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index a35f81ca206..496c3fc0aa1 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/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); } } |