diff options
Diffstat (limited to 'clang/lib/CodeGen')
-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)); |