From 774e7c6881ee6cb970cd42239d700dce87ed402a Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Fri, 3 Apr 2009 22:50:24 +0000 Subject: [PATCH] Add support for calling C++ member functions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68412 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGCXX.cpp | 41 +++++++++++++++++++++++++++++++++++ lib/CodeGen/CGExpr.cpp | 3 +++ lib/CodeGen/CodeGenFunction.h | 1 + 3 files changed, 45 insertions(+) diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index f43130a12b..5fb26d0048 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -17,6 +17,7 @@ #include "CodeGenModule.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "llvm/ADT/StringExtras.h" using namespace clang; @@ -135,3 +136,43 @@ CodeGenFunction::GenerateStaticCXXBlockVarDeclInit(const VarDecl &D, EmitBlock(EndBlock); } +RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE) { + const MemberExpr *ME = cast(CE->getCallee()); + const CXXMethodDecl *MD = cast(ME->getMemberDecl()); + assert(MD->isInstance() && + "Trying to emit a member call expr on a static method!"); + + bool IsVariadic = MD->getType()->getAsFunctionProtoType()->isVariadic(); + const llvm::Type *Ty = + CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), + IsVariadic); + + llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, Ty); + + llvm::Value *BaseValue = 0; + + // There's a deref operator node added in Sema::BuildCallToMemberFunction + // that's giving the wrong type for -> call exprs so we just ignore them + // for now. + if (ME->isArrow()) + return EmitUnsupportedRValue(CE, "C++ member call expr"); + else { + LValue BaseLV = EmitLValue(ME->getBase()); + BaseValue = BaseLV.getAddress(); + } + + CallArgList Args; + + // Push the 'this' pointer. + Args.push_back(std::make_pair(RValue::get(BaseValue), + MD->getThisType(getContext()))); + + for (CallExpr::const_arg_iterator I = CE->arg_begin(), E = CE->arg_end(); + I != E; ++I) + Args.push_back(std::make_pair(EmitAnyExprToTemp(*I), I->getType())); + + QualType ResultType = MD->getType()->getAsFunctionType()->getResultType(); + return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args), + Callee, Args, MD); + return EmitUnsupportedRValue(CE, "C++ member call expr"); +} diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index b52c81eb0b..7f3645556b 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -1062,6 +1062,9 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) { if (E->getCallee()->getType()->isBlockPointerType()) return EmitBlockCallExpr(E); + if (const CXXMemberCallExpr *CE = dyn_cast(E)) + return EmitCXXMemberCallExpr(CE); + const Decl *TargetDecl = 0; if (const ImplicitCastExpr *CE = dyn_cast(E->getCallee())) { if (const DeclRefExpr *DRE = dyn_cast(CE->getSubExpr())) { diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 61b2665428..13a0e85486 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -653,6 +653,7 @@ public: const Decl *TargetDecl = 0); RValue EmitCallExpr(const CallExpr *E); + RValue EmitCXXMemberCallExpr(const CXXMemberCallExpr *E); RValue EmitCallExpr(llvm::Value *Callee, QualType FnType, CallExpr::const_arg_iterator ArgBeg, -- 2.40.0