From 9a14630714da7176c981e3c8d050f82bc42c2643 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Thu, 26 Nov 2009 06:08:14 +0000 Subject: [PATCH] Implement IRGen for MemberExpr referring to static member function. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89938 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGExpr.cpp | 41 +++++++++++++++----------- test/CodeGenCXX/member-expressions.cpp | 8 +++++ 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 853715cce2..88429a3c86 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -828,6 +828,24 @@ static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF, return LV; } +static LValue EmitFunctionDeclLValue(CodeGenFunction &CGF, + const Expr *E, const FunctionDecl *FD) { + llvm::Value* V = CGF.CGM.GetAddrOfFunction(FD); + if (!FD->hasPrototype()) { + if (const FunctionProtoType *Proto = + FD->getType()->getAs()) { + // Ugly case: for a K&R-style definition, the type of the definition + // isn't the same as the type of a use. Correct for this with a + // bitcast. + QualType NoProtoType = + CGF.getContext().getFunctionNoProtoType(Proto->getResultType()); + NoProtoType = CGF.getContext().getPointerType(NoProtoType); + V = CGF.Builder.CreateBitCast(V, CGF.ConvertType(NoProtoType), "tmp"); + } + } + return LValue::MakeAddr(V, CGF.MakeQualifiers(E->getType())); +} + LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { const NamedDecl *ND = E->getDecl(); @@ -861,22 +879,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { return LV; } - if (const FunctionDecl *FD = dyn_cast(ND)) { - llvm::Value* V = CGM.GetAddrOfFunction(FD); - if (!FD->hasPrototype()) { - if (const FunctionProtoType *Proto = - FD->getType()->getAs()) { - // Ugly case: for a K&R-style definition, the type of the definition - // isn't the same as the type of a use. Correct for this with a - // bitcast. - QualType NoProtoType = - getContext().getFunctionNoProtoType(Proto->getResultType()); - NoProtoType = getContext().getPointerType(NoProtoType); - V = Builder.CreateBitCast(V, ConvertType(NoProtoType), "tmp"); - } - } - return LValue::MakeAddr(V, MakeQualifiers(E->getType())); - } + if (const FunctionDecl *FD = dyn_cast(ND)) + return EmitFunctionDeclLValue(*this, E, FD); if (E->getQualifier()) { // FIXME: the qualifier check does not seem sufficient here @@ -1163,7 +1167,10 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { if (VarDecl *VD = dyn_cast(ND)) return EmitGlobalVarDeclLValue(*this, E, VD); - + + if (const FunctionDecl *FD = dyn_cast(ND)) + return EmitFunctionDeclLValue(*this, E, FD); + assert(false && "Unhandled member declaration!"); return LValue(); } diff --git a/test/CodeGenCXX/member-expressions.cpp b/test/CodeGenCXX/member-expressions.cpp index 76b81e0688..a38d5f9eaa 100644 --- a/test/CodeGenCXX/member-expressions.cpp +++ b/test/CodeGenCXX/member-expressions.cpp @@ -36,3 +36,11 @@ void f(A *a) { A::E e3 = A().Foo; } +namespace test3 { +struct A { + static int foo(); +}; +int f() { + return A().foo(); +} +} -- 2.40.0