diff options
-rw-r--r-- | clang/AST/Decl.cpp | 6 | ||||
-rw-r--r-- | clang/CodeGen/CGDecl.cpp | 38 | ||||
-rw-r--r-- | clang/CodeGen/CGExpr.cpp | 2 | ||||
-rw-r--r-- | clang/CodeGen/CodeGenFunction.cpp | 26 | ||||
-rw-r--r-- | clang/CodeGen/CodeGenFunction.h | 4 | ||||
-rw-r--r-- | clang/Lex/Preprocessor.cpp | 4 | ||||
-rw-r--r-- | clang/Sema/Sema.h | 5 | ||||
-rw-r--r-- | clang/Sema/SemaDecl.cpp | 10 | ||||
-rw-r--r-- | clang/include/clang/AST/Decl.h | 10 |
9 files changed, 77 insertions, 28 deletions
diff --git a/clang/AST/Decl.cpp b/clang/AST/Decl.cpp index ca37f7cfc9f..f7301181d72 100644 --- a/clang/AST/Decl.cpp +++ b/clang/AST/Decl.cpp @@ -124,14 +124,14 @@ unsigned FunctionDecl::getNumParams() const { return cast<FunctionTypeProto>(getType().getTypePtr())->getNumArgs(); } -void FunctionDecl::setParams(VarDecl **NewParamInfo, unsigned NumParams) { +void FunctionDecl::setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) { assert(ParamInfo == 0 && "Already has param info!"); assert(NumParams == getNumParams() && "Parameter count mismatch!"); // Zero params -> null pointer. if (NumParams) { - ParamInfo = new VarDecl*[NumParams]; - memcpy(ParamInfo, NewParamInfo, sizeof(VarDecl*)*NumParams); + ParamInfo = new ParmVarDecl*[NumParams]; + memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams); } } diff --git a/clang/CodeGen/CGDecl.cpp b/clang/CodeGen/CGDecl.cpp index 7bd430d15b8..bebf6752fb3 100644 --- a/clang/CodeGen/CGDecl.cpp +++ b/clang/CodeGen/CGDecl.cpp @@ -13,9 +13,7 @@ #include "CodeGenFunction.h" #include "clang/AST/AST.h" -//#include "llvm/Constants.h" -//#include "llvm/DerivedTypes.h" -//#include "llvm/Function.h" +#include "llvm/Type.h" using namespace llvm; using namespace clang; using namespace CodeGen; @@ -89,3 +87,37 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const BlockVarDecl &D) { // FIXME: Evaluate initializer. } + +/// Emit an alloca for the specified parameter and set up LocalDeclMap. +void CodeGenFunction::EmitParmDecl(const ParmVarDecl &D, llvm::Value *Arg) { + QualType Ty = D.getCanonicalType(); + + llvm::Value *DeclPtr; + if (!Ty->isConstantSizeType()) { + // Variable sized values always are passed by-reference. + DeclPtr = Arg; + Arg->setName(DeclPtr->getName()); + } else { + // A fixed sized first class variable becomes an alloca in the entry block. + const llvm::Type *LTy = ConvertType(Ty, D.getLocation()); + if (LTy->isFirstClassType()) { + // TODO: Alignment + DeclPtr = new AllocaInst(LTy, 0, + std::string(D.getName())+".addr",AllocaInsertPt); + + // Store the initial value into the alloca. + Builder.CreateStore(Arg, DeclPtr); + + Arg->setName(D.getName()); + } else { + // Otherwise, if this is an aggregate, just use the input pointer. + DeclPtr = Arg; + Arg->setName(DeclPtr->getName()); + } + } + + llvm::Value *&DMEntry = LocalDeclMap[&D]; + assert(DMEntry == 0 && "Decl already exists in localdeclmap!"); + DMEntry = DeclPtr; +} + diff --git a/clang/CodeGen/CGExpr.cpp b/clang/CodeGen/CGExpr.cpp index 1b89e2be511..bd7abec58dd 100644 --- a/clang/CodeGen/CGExpr.cpp +++ b/clang/CodeGen/CGExpr.cpp @@ -258,7 +258,7 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { const Decl *D = E->getDecl(); - if (isa<BlockVarDecl>(D)) { + if (isa<BlockVarDecl>(D) || isa<ParmVarDecl>(D)) { Value *V = LocalDeclMap[D]; assert(V && "BlockVarDecl not entered in LocalDeclMap?"); return LValue::getAddr(V); diff --git a/clang/CodeGen/CodeGenFunction.cpp b/clang/CodeGen/CodeGenFunction.cpp index bb7a05717ad..6b6f3cbbdc7 100644 --- a/clang/CodeGen/CodeGenFunction.cpp +++ b/clang/CodeGen/CodeGenFunction.cpp @@ -141,11 +141,16 @@ const llvm::Type *CodeGenFunction::ConvertType(QualType T, SourceLocation Loc) { return OpaqueType::get(); } -void CodeGenFunction::DecodeArgumentTypes(const FunctionTypeProto &FTP, - std::vector<const llvm::Type*> & - ArgTys, SourceLocation Loc) { - for (unsigned i = 0, e = FTP.getNumArgs(); i != e; ++i) - ArgTys.push_back(ConvertType(FTP.getArgType(i), Loc)); +void CodeGenFunction::DecodeArgumentTypes(const FunctionTypeProto &FTP, + std::vector<const llvm::Type*> & + ArgTys, SourceLocation Loc) { + for (unsigned i = 0, e = FTP.getNumArgs(); i != e; ++i) { + const llvm::Type *Ty = ConvertType(FTP.getArgType(i), Loc); + if (Ty->isFirstClassType()) + ArgTys.push_back(Ty); + else + ArgTys.push_back(llvm::PointerType::get(Ty)); + } } void CodeGenFunction::GenerateCode(const FunctionDecl *FD) { @@ -155,14 +160,14 @@ void CodeGenFunction::GenerateCode(const FunctionDecl *FD) { const llvm::FunctionType *Ty = cast<llvm::FunctionType>(ConvertType(FD->getType(), FD->getLocation())); + // FIXME: param attributes for sext/zext etc. + CurFuncDecl = FD; CurFn = new Function(Ty, Function::ExternalLinkage, FD->getName(), &CGM.getModule()); BasicBlock *EntryBB = new BasicBlock("entry", CurFn); - // TODO: Walk the decls, creating allocas etc. - Builder.SetInsertPoint(EntryBB); // Create a marker to make it easy to insert allocas into the entryblock @@ -170,7 +175,12 @@ void CodeGenFunction::GenerateCode(const FunctionDecl *FD) { AllocaInsertPt = Builder.CreateBitCast(UndefValue::get(llvm::Type::Int32Ty), llvm::Type::Int32Ty, "allocapt"); - // TODO: handle params. + // Emit allocs for param decls. + llvm::Function::arg_iterator AI = CurFn->arg_begin(); + for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i, ++AI) { + assert(AI != CurFn->arg_end() && "Argument mismatch!"); + EmitParmDecl(*FD->getParamDecl(i), AI); + } // Emit the function body. EmitStmt(FD->getBody()); diff --git a/clang/CodeGen/CodeGenFunction.h b/clang/CodeGen/CodeGenFunction.h index e5be910ad31..ad80b382e27 100644 --- a/clang/CodeGen/CodeGenFunction.h +++ b/clang/CodeGen/CodeGenFunction.h @@ -51,6 +51,7 @@ namespace clang { class BlockVarDecl; class EnumConstantDecl; + class ParmVarDecl; namespace CodeGen { class CodeGenModule; @@ -177,13 +178,14 @@ public: Value *ConvertScalarValueToBool(RValue Val, QualType Ty); //===--------------------------------------------------------------------===// - // Local Declaration Emission + // Declaration Emission //===--------------------------------------------------------------------===// void EmitDecl(const Decl &D); void EmitEnumConstantDecl(const EnumConstantDecl &D); void EmitBlockVarDecl(const BlockVarDecl &D); void EmitLocalBlockVarDecl(const BlockVarDecl &D); + void EmitParmDecl(const ParmVarDecl &D, llvm::Value *Arg); //===--------------------------------------------------------------------===// // Statement Emission diff --git a/clang/Lex/Preprocessor.cpp b/clang/Lex/Preprocessor.cpp index d8e548ef62b..77e1677755a 100644 --- a/clang/Lex/Preprocessor.cpp +++ b/clang/Lex/Preprocessor.cpp @@ -971,8 +971,8 @@ void Preprocessor::HandleIdentifier(LexerToken &Identifier) { // If this is an extension token, diagnose its use. // FIXME: tried (unsuccesfully) to shut this up when compiling with gnu99 // For now, I'm just commenting it out (while I work on attributes). - //if (II.isExtensionToken() && Features.C99) - // Diag(Identifier, diag::ext_token_used); + if (II.isExtensionToken() && Features.C99) + Diag(Identifier, diag::ext_token_used); } /// HandleEndOfFile - This callback is invoked when the lexer hits the end of diff --git a/clang/Sema/Sema.h b/clang/Sema/Sema.h index ef3bb564b41..54cc87e8566 100644 --- a/clang/Sema/Sema.h +++ b/clang/Sema/Sema.h @@ -27,6 +27,7 @@ namespace clang { class Decl; class Expr; class VarDecl; + class ParmVarDecl; class TypedefDecl; class FunctionDecl; class QualType; @@ -132,8 +133,8 @@ private: void AddTopLevelDecl(Decl *current, Decl *last); /// More parsing and symbol table subroutines... - VarDecl *ParseParamDeclarator(DeclaratorChunk &FI, unsigned ArgNo, - Scope *FnBodyScope); + ParmVarDecl *ParseParamDeclarator(DeclaratorChunk &FI, unsigned ArgNo, + Scope *FnBodyScope); Decl *LookupScopedDecl(IdentifierInfo *II, unsigned NSI, SourceLocation IdLoc, Scope *S); Decl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, Scope *S); diff --git a/clang/Sema/SemaDecl.cpp b/clang/Sema/SemaDecl.cpp index 88d081a65bd..40b82c71c74 100644 --- a/clang/Sema/SemaDecl.cpp +++ b/clang/Sema/SemaDecl.cpp @@ -439,7 +439,7 @@ Sema::DeclTy *Sema::FinalizeDeclaratorGroup(Scope *S, DeclTy *group) { return NewGroup; } -VarDecl * +ParmVarDecl * Sema::ParseParamDeclarator(DeclaratorChunk &FTI, unsigned ArgNo, Scope *FnScope) { const DeclaratorChunk::ParamInfo &PI = FTI.Fun.ArgInfo[ArgNo]; @@ -455,9 +455,9 @@ Sema::ParseParamDeclarator(DeclaratorChunk &FTI, unsigned ArgNo, // FIXME: Handle storage class (auto, register). No declarator? // TODO: Chain to previous parameter with the prevdeclarator chain? - VarDecl *New = new ParmVarDecl(PI.IdentLoc, II, - QualType::getFromOpaquePtr(PI.TypeInfo), - VarDecl::None, 0); + ParmVarDecl *New = new ParmVarDecl(PI.IdentLoc, II, + QualType::getFromOpaquePtr(PI.TypeInfo), + VarDecl::None, 0); // If this has an identifier, add it to the scope stack. if (II) { @@ -504,7 +504,7 @@ Sema::DeclTy *Sema::ParseStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) { CurFunctionDecl = FD; // Create Decl objects for each parameter, adding them to the FunctionDecl. - SmallVector<VarDecl*, 16> Params; + SmallVector<ParmVarDecl*, 16> Params; // Check for C99 6.7.5.3p10 - foo(void) is a non-varargs function that takes // no arguments, not a function that takes a single void argument. diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index a05fd8e81cb..92a897b489b 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -220,11 +220,15 @@ public: void setDeclChain(Decl *D) { DeclChain = D; } unsigned getNumParams() const; - VarDecl *getParamDecl(unsigned i) const { + const ParmVarDecl *getParamDecl(unsigned i) const { assert(i < getNumParams() && "Illegal param #"); return ParamInfo[i]; } - void setParams(VarDecl **NewParamInfo, unsigned NumParams); + ParmVarDecl *getParamDecl(unsigned i) { + assert(i < getNumParams() && "Illegal param #"); + return ParamInfo[i]; + } + void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams); QualType getResultType() const { return cast<FunctionType>(getType())->getResultType(); @@ -239,7 +243,7 @@ private: /// parameters of this function. This is null if a prototype or if there are /// no formals. TODO: we could allocate this space immediately after the /// FunctionDecl object to save an allocation like FunctionType does. - VarDecl **ParamInfo; + ParmVarDecl **ParamInfo; Stmt *Body; // Null if a prototype. |