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:
parent
238cbc58c3
commit
03df12294b
|
@ -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.
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
|
Loading…
Reference in New Issue