[cfe-commits] r68425 - in /cfe/trunk: lib/CodeGen/CodeGenFunction.cpp lib/CodeGen/CodeGenFunction.h lib/CodeGen/CodeGenModule.cpp test/CodeGenCXX/member-functions.cpp

Anders Carlsson andersca at mac.com
Sat Apr 4 13:47:03 PDT 2009


Author: andersca
Date: Sat Apr  4 15:47:02 2009
New Revision: 68425

URL: http://llvm.org/viewvc/llvm-project?rev=68425&view=rev
Log:
Add some basic support for generating C++ member functions.

Added:
    cfe/trunk/test/CodeGenCXX/member-functions.cpp
Modified:
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=68425&r1=68424&r2=68425&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Sat Apr  4 15:47:02 2009
@@ -18,6 +18,7 @@
 #include "clang/AST/APValue.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
 #include "llvm/Support/CFG.h"
 #include "llvm/Target/TargetData.h"
 using namespace clang;
@@ -26,7 +27,8 @@
 CodeGenFunction::CodeGenFunction(CodeGenModule &cgm) 
   : BlockFunction(cgm, *this, Builder), CGM(cgm),
     Target(CGM.getContext().Target),
-    DebugInfo(0), SwitchInsn(0), CaseRangeBlock(0), InvokeDest(0) {
+    DebugInfo(0), SwitchInsn(0), CaseRangeBlock(0), InvokeDest(0), 
+    CXXThisDecl(0) {
   LLVMIntTy = ConvertType(getContext().IntTy);
   LLVMPointerWidth = Target.getPointerWidth(0);
 }
@@ -201,6 +203,19 @@
     DebugInfo = CGM.getDebugInfo();
   
   FunctionArgList Args;
+  
+  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
+    if (MD->isInstance()) {
+      // Create the implicit 'this' decl.
+      // FIXME: I'm not entirely sure I like using a fake decl just for code
+      // generation. Maybe we can come up with a better way?
+      CXXThisDecl = ImplicitParamDecl::Create(getContext(), 0, SourceLocation(),
+                                              &getContext().Idents.get("this"), 
+                                              MD->getThisType(getContext()));
+      Args.push_back(std::make_pair(CXXThisDecl, CXXThisDecl->getType()));
+    }
+  }
+  
   if (FD->getNumParams()) {
     const FunctionProtoType* FProto = FD->getType()->getAsFunctionProtoType();
     assert(FProto && "Function def must have prototype!");
@@ -221,6 +236,10 @@
   } else {
     FinishFunction();
   }
+    
+  // Destroy the 'this' declaration.
+  if (CXXThisDecl)
+    CXXThisDecl->Destroy(getContext());
 }
 
 /// ContainsLabel - Return true if the statement contains a label in it.  If

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=68425&r1=68424&r2=68425&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Sat Apr  4 15:47:02 2009
@@ -232,6 +232,10 @@
   /// BlockScopes - Map of which "cleanup scope" scope basic blocks have.
   BlockScopeMap BlockScopes;
 
+  /// CXXThisDecl - When parsing an C++ function, this will hold the implicit
+  /// 'this' declaration.
+  ImplicitParamDecl *CXXThisDecl;
+  
 public:
   CodeGenFunction(CodeGenModule &cgm);
 

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=68425&r1=68424&r2=68425&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Sat Apr  4 15:47:02 2009
@@ -820,18 +820,26 @@
 
 
 void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) {
-  const llvm::FunctionType *Ty = 
-    cast<llvm::FunctionType>(getTypes().ConvertType(D->getType()));
+  const llvm::FunctionType *Ty;
 
-  // As a special case, make sure that definitions of K&R function
-  // "type foo()" aren't declared as varargs (which forces the backend
-  // to do unnecessary work).
-  if (D->getType()->isFunctionNoProtoType()) {
-    assert(Ty->isVarArg() && "Didn't lower type as expected");
-    // Due to stret, the lowered function could have arguments.  Just create the
-    // same type as was lowered by ConvertType but strip off the varargs bit.
-    std::vector<const llvm::Type*> Args(Ty->param_begin(), Ty->param_end());
-    Ty = llvm::FunctionType::get(Ty->getReturnType(), Args, false);
+  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
+    bool isVariadic = D->getType()->getAsFunctionProtoType()->isVariadic();
+    
+    Ty = getTypes().GetFunctionType(getTypes().getFunctionInfo(MD), isVariadic);
+  } else {
+    Ty = cast<llvm::FunctionType>(getTypes().ConvertType(D->getType()));
+    
+    // As a special case, make sure that definitions of K&R function
+    // "type foo()" aren't declared as varargs (which forces the backend
+    // to do unnecessary work).
+    if (D->getType()->isFunctionNoProtoType()) {
+      assert(Ty->isVarArg() && "Didn't lower type as expected");
+      // Due to stret, the lowered function could have arguments. 
+      // Just create the same type as was lowered by ConvertType 
+      // but strip off the varargs bit.
+      std::vector<const llvm::Type*> Args(Ty->param_begin(), Ty->param_end());
+      Ty = llvm::FunctionType::get(Ty->getReturnType(), Args, false);
+    }
   }
 
   // Get or create the prototype for teh function.
@@ -1305,6 +1313,7 @@
     return;
 
   switch (D->getKind()) {
+  case Decl::CXXMethod:
   case Decl::Function:
   case Decl::Var:
     EmitGlobal(cast<ValueDecl>(D));

Added: cfe/trunk/test/CodeGenCXX/member-functions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/member-functions.cpp?rev=68425&view=auto

==============================================================================
--- cfe/trunk/test/CodeGenCXX/member-functions.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/member-functions.cpp Sat Apr  4 15:47:02 2009
@@ -0,0 +1,15 @@
+// RUN: clang-cc -emit-llvm %s -o %t &&
+struct C {
+  void f();
+};
+
+// RUN: grep "define void @_ZN1C1fEv" %t | count 1 &&
+void C::f() {
+}
+
+// RUN: grep "call void @_ZN1C1fEv" %t | count 1
+void f() {
+  C c;
+  
+  c.f();
+}
\ No newline at end of file





More information about the cfe-commits mailing list