diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 21 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 4 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 33 | 
3 files changed, 45 insertions, 13 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index dc00a76ff91..5b63e6594d3 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -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 @@ using namespace CodeGen;  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 @@ void CodeGenFunction::GenerateCode(const FunctionDecl *FD,      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 @@ void CodeGenFunction::GenerateCode(const FunctionDecl *FD,    } else {      FinishFunction();    } +     +  // Destroy the 'this' declaration. +  if (CXXThisDecl) +    CXXThisDecl->Destroy(getContext());  }  /// ContainsLabel - Return true if the statement contains a label in it.  If diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 13a0e85486a..96db4a45c77 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -232,6 +232,10 @@ private:    /// 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); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index b4cf5331869..379ff9b4240 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -820,18 +820,26 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {  void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) { -  const llvm::FunctionType *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); +  const llvm::FunctionType *Ty; + +  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 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {      return;    switch (D->getKind()) { +  case Decl::CXXMethod:    case Decl::Function:    case Decl::Var:      EmitGlobal(cast<ValueDecl>(D));  | 

