Add initial support for fixed-size local vardecls. This allows us to compile:

int func() {
  register int X;
  {
    int Y;

into:

define i32 @func() {
entry:
        %X = alloca i32         ; <i32*> [#uses=0]
        %Y = alloca i32         ; <i32*> [#uses=0]
        %allocapt = bitcast i32 undef to i32            ; <i32> [#uses=0]
...

llvm-svn: 39553
This commit is contained in:
Chris Lattner 2007-06-02 04:53:11 +00:00
parent 238cbc58c3
commit 03df12294b
3 changed files with 53 additions and 7 deletions

View File

@ -46,11 +46,47 @@ void CodeGenFunction::EmitDeclStmt(const DeclStmt &S) {
}
}
void CodeGenFunction::EmitBlockVarDecl(const BlockVarDecl &D) {
//assert(0 && "FIXME: Enum constant decls not implemented yet!");
}
void CodeGenFunction::EmitEnumConstantDecl(const EnumConstantDecl &D) {
assert(0 && "FIXME: Enum constant decls not implemented yet!");
}
/// EmitBlockVarDecl - This method handles emission of any variable declaration
/// inside a function, including static vars etc.
void CodeGenFunction::EmitBlockVarDecl(const BlockVarDecl &D) {
switch (D.getStorageClass()) {
case VarDecl::Static:
assert(0 && "FIXME: local static vars not implemented yet");
case VarDecl::Extern:
assert(0 && "FIXME: should call up to codegenmodule");
default:
assert((D.getStorageClass() == VarDecl::None ||
D.getStorageClass() == VarDecl::Auto ||
D.getStorageClass() == VarDecl::Register) &&
"Unknown storage class");
return EmitLocalBlockVarDecl(D);
}
}
/// EmitLocalBlockVarDecl - Emit code and set up an entry in LocalDeclMap for a
/// variable declaration with auto, register, or no storage class specifier.
/// These turn into simple stack objects.
void CodeGenFunction::EmitLocalBlockVarDecl(const BlockVarDecl &D) {
QualType Ty = D.getCanonicalType();
llvm::Value *DeclPtr;
if (Ty->isConstantSizeType()) {
// A normal fixed sized variable becomes an alloca in the entry block.
const llvm::Type *LTy = ConvertType(Ty, D.getLocation());
// TODO: Alignment
DeclPtr = new AllocaInst(LTy, 0, D.getName(), AllocaInsertPt);
} else {
// TODO: Create a dynamic alloca.
assert(0 && "FIXME: Local VLAs not implemented yet");
}
llvm::Value *&DMEntry = LocalDeclMap[&D];
assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
DMEntry = DeclPtr;
// FIXME: Evaluate initializer.
}

View File

@ -125,6 +125,11 @@ void CodeGenFunction::GenerateCode(const FunctionDecl *FD) {
// TODO: Walk the decls, creating allocas etc.
Builder.SetInsertPoint(EntryBB);
// Create a marker to make it easy to insert allocas into the entryblock
// later.
AllocaInsertPt = Builder.CreateBitCast(UndefValue::get(llvm::Type::Int32Ty),
llvm::Type::Int32Ty, "allocapt");
// TODO: handle params.

View File

@ -90,6 +90,10 @@ class CodeGenFunction {
const FunctionDecl *CurFuncDecl;
llvm::Function *CurFn;
/// AllocaInsertPoint - This is an instruction in the entry block before which
/// we prefer to insert allocas.
llvm::Instruction *AllocaInsertPt;
/// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C
/// decls.
DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
@ -117,9 +121,10 @@ public:
//===--------------------------------------------------------------------===//
void EmitDeclStmt(const DeclStmt &S);
void EmitBlockVarDecl(const BlockVarDecl &D);
void EmitEnumConstantDecl(const EnumConstantDecl &D);
void EmitBlockVarDecl(const BlockVarDecl &D);
void EmitLocalBlockVarDecl(const BlockVarDecl &D);
//===--------------------------------------------------------------------===//
// Statement Emission
//===--------------------------------------------------------------------===//