[cfe-commits] r39652 - in /cfe/cfe/trunk: AST/Decl.cpp CodeGen/CGDecl.cpp CodeGen/CGExpr.cpp CodeGen/CodeGenFunction.cpp CodeGen/CodeGenFunction.h Lex/Preprocessor.cpp Sema/Sema.h Sema/SemaDecl.cpp include/clang/AST/Decl.h
clattner at cs.uiuc.edu
clattner at cs.uiuc.edu
Wed Jul 11 09:46:41 PDT 2007
Author: clattner
Date: Wed Jul 11 11:46:40 2007
New Revision: 39652
URL: http://llvm.org/viewvc/llvm-project?rev=39652&view=rev
Log:
Implement support for formal arguments. We can now compile this:
int test(int X, short Y, float Z) {
return (int)(X*Y+Z);
}
to:
define i32 @test(i32 %X, i16 %Y, float %Z) {
entry:
%promote = sext i16 %Y to i32 ; <i32> [#uses=1]
%mul = mul i32 %promote, %X ; <i32> [#uses=1]
%promote3 = sitofp i32 %mul to float ; <float> [#uses=1]
%add = add float %promote3, %Z ; <float> [#uses=1]
%conv = fptosi float %add to i32 ; <i32> [#uses=1]
ret i32 %conv
}
with:
$ clang -emit-llvm t.c | llvm-as | opt -std-compile-opts | llvm-dis
Modified:
cfe/cfe/trunk/AST/Decl.cpp
cfe/cfe/trunk/CodeGen/CGDecl.cpp
cfe/cfe/trunk/CodeGen/CGExpr.cpp
cfe/cfe/trunk/CodeGen/CodeGenFunction.cpp
cfe/cfe/trunk/CodeGen/CodeGenFunction.h
cfe/cfe/trunk/Lex/Preprocessor.cpp
cfe/cfe/trunk/Sema/Sema.h
cfe/cfe/trunk/Sema/SemaDecl.cpp
cfe/cfe/trunk/include/clang/AST/Decl.h
Modified: cfe/cfe/trunk/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Decl.cpp?rev=39652&r1=39651&r2=39652&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Decl.cpp (original)
+++ cfe/cfe/trunk/AST/Decl.cpp Wed Jul 11 11:46:40 2007
@@ -124,14 +124,14 @@
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);
}
}
Modified: cfe/cfe/trunk/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CGDecl.cpp?rev=39652&r1=39651&r2=39652&view=diff
==============================================================================
--- cfe/cfe/trunk/CodeGen/CGDecl.cpp (original)
+++ cfe/cfe/trunk/CodeGen/CGDecl.cpp Wed Jul 11 11:46:40 2007
@@ -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 @@
// 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;
+}
+
Modified: cfe/cfe/trunk/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CGExpr.cpp?rev=39652&r1=39651&r2=39652&view=diff
==============================================================================
--- cfe/cfe/trunk/CodeGen/CGExpr.cpp (original)
+++ cfe/cfe/trunk/CodeGen/CGExpr.cpp Wed Jul 11 11:46:40 2007
@@ -258,7 +258,7 @@
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);
Modified: cfe/cfe/trunk/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CodeGenFunction.cpp?rev=39652&r1=39651&r2=39652&view=diff
==============================================================================
--- cfe/cfe/trunk/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/cfe/trunk/CodeGen/CodeGenFunction.cpp Wed Jul 11 11:46:40 2007
@@ -141,11 +141,16 @@
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 @@
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 @@
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());
Modified: cfe/cfe/trunk/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CodeGenFunction.h?rev=39652&r1=39651&r2=39652&view=diff
==============================================================================
--- cfe/cfe/trunk/CodeGen/CodeGenFunction.h (original)
+++ cfe/cfe/trunk/CodeGen/CodeGenFunction.h Wed Jul 11 11:46:40 2007
@@ -51,6 +51,7 @@
class BlockVarDecl;
class EnumConstantDecl;
+ class ParmVarDecl;
namespace CodeGen {
class CodeGenModule;
@@ -177,13 +178,14 @@
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
Modified: cfe/cfe/trunk/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/Preprocessor.cpp?rev=39652&r1=39651&r2=39652&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/Preprocessor.cpp (original)
+++ cfe/cfe/trunk/Lex/Preprocessor.cpp Wed Jul 11 11:46:40 2007
@@ -971,8 +971,8 @@
// 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
Modified: cfe/cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.h?rev=39652&r1=39651&r2=39652&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:46:40 2007
@@ -27,6 +27,7 @@
class Decl;
class Expr;
class VarDecl;
+ class ParmVarDecl;
class TypedefDecl;
class FunctionDecl;
class QualType;
@@ -132,8 +133,8 @@
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);
Modified: cfe/cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaDecl.cpp?rev=39652&r1=39651&r2=39652&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:46:40 2007
@@ -439,7 +439,7 @@
return NewGroup;
}
-VarDecl *
+ParmVarDecl *
Sema::ParseParamDeclarator(DeclaratorChunk &FTI, unsigned ArgNo,
Scope *FnScope) {
const DeclaratorChunk::ParamInfo &PI = FTI.Fun.ArgInfo[ArgNo];
@@ -455,9 +455,9 @@
// 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 @@
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.
Modified: cfe/cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Decl.h?rev=39652&r1=39651&r2=39652&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Decl.h Wed Jul 11 11:46:40 2007
@@ -220,11 +220,15 @@
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 @@
/// 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.
More information about the cfe-commits
mailing list