]> granicus.if.org Git - clang/commitdiff
Add support for calling C++ member functions.
authorAnders Carlsson <andersca@mac.com>
Fri, 3 Apr 2009 22:50:24 +0000 (22:50 +0000)
committerAnders Carlsson <andersca@mac.com>
Fri, 3 Apr 2009 22:50:24 +0000 (22:50 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68412 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCXX.cpp
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CodeGenFunction.h

index f43130a12b2d10fa4f5c2ae2719c842dc52f7552..5fb26d0048d93563cb0d46667fc8310e564a9bf6 100644 (file)
@@ -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<MemberExpr>(CE->getCallee());
+  const CXXMethodDecl *MD = cast<CXXMethodDecl>(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");
+}
index b52c81eb0bc854607bdbc4aee8dc7f00dbd44478..7f3645556be3117391f34833fcb8583e3ecf7c33 100644 (file)
@@ -1062,6 +1062,9 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) {
   if (E->getCallee()->getType()->isBlockPointerType())
     return EmitBlockCallExpr(E);
 
+  if (const CXXMemberCallExpr *CE = dyn_cast<CXXMemberCallExpr>(E))
+    return EmitCXXMemberCallExpr(CE);
+  
   const Decl *TargetDecl = 0;
   if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E->getCallee())) {
     if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CE->getSubExpr())) {
index 61b266542898c20ab0ab7bf213e922013fae7b68..13a0e85486a6127c5d117126e7746dcb640e688e 100644 (file)
@@ -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,