diff --git a/clang/CodeGen/CGDecl.cpp b/clang/CodeGen/CGDecl.cpp index 1645b6b2b5b6..bc6892dacb6b 100644 --- a/clang/CodeGen/CGDecl.cpp +++ b/clang/CodeGen/CGDecl.cpp @@ -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. +} diff --git a/clang/CodeGen/CodeGenFunction.cpp b/clang/CodeGen/CodeGenFunction.cpp index 00f55b8bce98..0283760dc994 100644 --- a/clang/CodeGen/CodeGenFunction.cpp +++ b/clang/CodeGen/CodeGenFunction.cpp @@ -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. diff --git a/clang/CodeGen/CodeGenFunction.h b/clang/CodeGen/CodeGenFunction.h index de7c84e1ada3..de14842271f9 100644 --- a/clang/CodeGen/CodeGenFunction.h +++ b/clang/CodeGen/CodeGenFunction.h @@ -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 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 //===--------------------------------------------------------------------===//