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 | |
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')
-rw-r--r-- | clang/lib/CodeGen/CGCXXABI.cpp | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGCXXABI.h | 7 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 40 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprAgg.cpp | 1 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprCXX.cpp | 8 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprConstant.cpp | 1 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 13 | ||||
-rw-r--r-- | clang/lib/CodeGen/ItaniumCXXABI.cpp | 35 |
8 files changed, 85 insertions, 23 deletions
diff --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp index 92f1c63a382..e8b6f567247 100644 --- a/clang/lib/CodeGen/CGCXXABI.cpp +++ b/clang/lib/CodeGen/CGCXXABI.cpp @@ -99,7 +99,8 @@ CGCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) { return GetBogusMemberPointer(CGM, QualType(MPT, 0)); } -llvm::Constant *CGCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) { +llvm::Constant *CGCXXABI::EmitMemberPointer(const CXXMethodDecl *MD, + QualType unknownType) { return GetBogusMemberPointer(CGM, CGM.getContext().getMemberPointerType(MD->getType(), MD->getParent()->getTypeForDecl())); diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h index de4df3dcbe8..a34ca9bcdce 100644 --- a/clang/lib/CodeGen/CGCXXABI.h +++ b/clang/lib/CodeGen/CGCXXABI.h @@ -119,7 +119,12 @@ public: virtual llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT); /// Create a member pointer for the given method. - virtual llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD); + /// + /// \param unknownType - if non-null, use this type as the operand + /// to CodeGenModule::getAddrOfUnknownAnyDecl instead of + /// fetching the method's address in the normal way + virtual llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD, + QualType unknownType = QualType()); /// Create a member pointer for the given field. virtual llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT, 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); } } diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 75e3a7879d4..5d22fc33041 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -311,6 +311,7 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) { break; case CK_ResolveUnknownAnyType: + case CK_ResolveUnknownAnyTypeToReference: EmitAggLoadOfLValue(E); break; diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index a3d3f439b63..ef71e890778 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -167,10 +167,12 @@ static bool canDevirtualizeMemberFunctionCalls(ASTContext &Context, // extensions allowing explicit constructor function call. RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE, ReturnValueSlot ReturnValue) { - if (isa<BinaryOperator>(CE->getCallee()->IgnoreParens())) + const Expr *callee = CE->getCallee()->IgnoreParens(); + + if (isa<BinaryOperator>(callee)) return EmitCXXMemberPointerCallExpr(CE, ReturnValue); - - const MemberExpr *ME = cast<MemberExpr>(CE->getCallee()->IgnoreParens()); + + const MemberExpr *ME = cast<MemberExpr>(callee); const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl()); CGDebugInfo *DI = getDebugInfo(); diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 822a999b963..b04ff0aefbc 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -553,6 +553,7 @@ public: case CK_ToVoid: case CK_Dynamic: case CK_ResolveUnknownAnyType: + case CK_ResolveUnknownAnyTypeToReference: return 0; // These might need to be supported for constexpr. diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 65aa46fff06..f2ab0a2e063 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -1128,6 +1128,19 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) { } case CK_ResolveUnknownAnyType: + // Special case: resolving a member pointer constant. + if (const UnaryOperator *uo = dyn_cast<UnaryOperator>(E)) { + DeclRefExpr *declRef = cast<DeclRefExpr>(uo->getSubExpr()); + const CXXMethodDecl *method = cast<CXXMethodDecl>(declRef->getDecl()); + + const MemberPointerType *mpt = CE->getType()->castAs<MemberPointerType>(); + QualType resolvedType = mpt->getPointeeType(); + + return CGF.CGM.getCXXABI().EmitMemberPointer(method, resolvedType); + } + // fallthrough + + case CK_ResolveUnknownAnyTypeToReference: return EmitLoadOfLValue(CE); case CK_LValueToRValue: diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 53163ed6a5d..6c864ca7f41 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -78,7 +78,8 @@ public: llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT); - llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD); + llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD, + QualType unknownType); llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT, CharUnits offset); @@ -502,7 +503,8 @@ ItaniumCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT, return llvm::ConstantInt::get(getPtrDiffTy(), offset.getQuantity()); } -llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) { +llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const CXXMethodDecl *MD, + QualType unknownType) { assert(MD->isInstance() && "Member function must not be static!"); MD = MD->getCanonicalDecl(); @@ -537,20 +539,27 @@ llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) { MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, 0); } } else { - const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); - const llvm::Type *Ty; - // Check whether the function has a computable LLVM signature. - if (!CodeGenTypes::VerifyFuncTypeComplete(FPT)) { - // The function has a computable LLVM signature; use the correct type. - Ty = Types.GetFunctionType(Types.getFunctionInfo(MD), FPT->isVariadic()); + llvm::Constant *addr; + if (!unknownType.isNull()) { + addr = CGM.getAddrOfUnknownAnyDecl(MD, unknownType); } else { - // Use an arbitrary non-function type to tell GetAddrOfFunction that the - // function type is incomplete. - Ty = ptrdiff_t; + QualType fnType = MD->getType(); + const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>(); + const llvm::Type *Ty; + // Check whether the function has a computable LLVM signature. + if (!CodeGenTypes::VerifyFuncTypeComplete(FPT)) { + // The function has a computable LLVM signature; use the correct type. + Ty = Types.GetFunctionType(Types.getFunctionInfo(MD), + FPT->isVariadic()); + } else { + // Use an arbitrary non-function type to tell GetAddrOfFunction that the + // function type is incomplete. + Ty = ptrdiff_t; + } + addr = CGM.GetAddrOfFunction(MD, Ty); } - llvm::Constant *Addr = CGM.GetAddrOfFunction(MD, Ty); - MemPtr[0] = llvm::ConstantExpr::getPtrToInt(Addr, ptrdiff_t); + MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, ptrdiff_t); MemPtr[1] = llvm::ConstantInt::get(ptrdiff_t, 0); } |