summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/AST/Decl.cpp6
-rw-r--r--clang/CodeGen/CGDecl.cpp38
-rw-r--r--clang/CodeGen/CGExpr.cpp2
-rw-r--r--clang/CodeGen/CodeGenFunction.cpp26
-rw-r--r--clang/CodeGen/CodeGenFunction.h4
-rw-r--r--clang/Lex/Preprocessor.cpp4
-rw-r--r--clang/Sema/Sema.h5
-rw-r--r--clang/Sema/SemaDecl.cpp10
-rw-r--r--clang/include/clang/AST/Decl.h10
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.
OpenPOWER on IntegriCloud