From 01a72ff5d3a152dde8ffa5a8e61b9a4c70b0426d Mon Sep 17 00:00:00 2001 From: Lauro Ramos Venancio Date: Tue, 26 Feb 2008 21:41:45 +0000 Subject: [PATCH] Implement codegen for the following static var init. void g() { static char a[10]; static char *b = a; } Now we can compile wget! llvm-svn: 47627 --- clang/CodeGen/CGDecl.cpp | 2 +- clang/CodeGen/CGExprConstant.cpp | 16 ++++++++++------ clang/CodeGen/CodeGenFunction.cpp | 4 ++++ clang/CodeGen/CodeGenFunction.h | 3 +++ clang/CodeGen/CodeGenModule.h | 4 +++- clang/test/CodeGen/staticinit.c | 7 ++++++- 6 files changed, 27 insertions(+), 9 deletions(-) diff --git a/clang/CodeGen/CGDecl.cpp b/clang/CodeGen/CGDecl.cpp index cd31fa7a7d3c..c80cecc76ee2 100644 --- a/clang/CodeGen/CGDecl.cpp +++ b/clang/CodeGen/CGDecl.cpp @@ -77,7 +77,7 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const BlockVarDecl &D) { if (D.getInit() == 0) { Init = llvm::Constant::getNullValue(LTy); } else { - Init = CGM.EmitGlobalInit(D.getInit()); + Init = CGM.EmitConstantExpr(D.getInit(), this); } assert(Init && "Unable to create initialiser for static decl"); diff --git a/clang/CodeGen/CGExprConstant.cpp b/clang/CodeGen/CGExprConstant.cpp index 1a60cae5a07b..ec16b16a9d49 100644 --- a/clang/CodeGen/CGExprConstant.cpp +++ b/clang/CodeGen/CGExprConstant.cpp @@ -25,9 +25,10 @@ namespace { class VISIBILITY_HIDDEN ConstExprEmitter : public StmtVisitor { CodeGenModule &CGM; + CodeGenFunction *CGF; public: - ConstExprEmitter(CodeGenModule &cgm) - : CGM(cgm) { + ConstExprEmitter(CodeGenModule &cgm, CodeGenFunction *cgf) + : CGM(cgm), CGF(cgf) { } //===--------------------------------------------------------------------===// @@ -534,8 +535,10 @@ public: return CGM.GetAddrOfFunctionDecl(FD, false); if (const FileVarDecl* VD = dyn_cast(Decl)) return CGM.GetAddrOfGlobalVar(VD, false); - // We can end up here with static block-scope variables (and others?) - // FIXME: How do we implement block-scope variables?! + if (const BlockVarDecl* BVD = dyn_cast(Decl)) { + assert(CGF && "Can't access static local vars without CGF"); + return CGF->GetAddrOfStaticLocalVar(BVD); + } break; } case Expr::MemberExprClass: { @@ -604,7 +607,8 @@ public: } // end anonymous namespace. -llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E) +llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E, + CodeGenFunction *CGF) { QualType type = E->getType().getCanonicalType(); @@ -616,5 +620,5 @@ llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E) } } - return ConstExprEmitter(*this).Visit(const_cast(E)); + return ConstExprEmitter(*this, CGF).Visit(const_cast(E)); } diff --git a/clang/CodeGen/CodeGenFunction.cpp b/clang/CodeGen/CodeGenFunction.cpp index dc31a27945b5..c2a303c7557c 100644 --- a/clang/CodeGen/CodeGenFunction.cpp +++ b/clang/CodeGen/CodeGenFunction.cpp @@ -40,6 +40,10 @@ llvm::BasicBlock *CodeGenFunction::getBasicBlockForLabel(const LabelStmt *S) { return BB = new llvm::BasicBlock(S->getName()); } +llvm::Constant * +CodeGenFunction::GetAddrOfStaticLocalVar(const BlockVarDecl *BVD) { + return cast(LocalDeclMap[BVD]); +} const llvm::Type *CodeGenFunction::ConvertType(QualType T) { return CGM.getTypes().ConvertType(T); diff --git a/clang/CodeGen/CodeGenFunction.h b/clang/CodeGen/CodeGenFunction.h index e88575293311..b136c2b06150 100644 --- a/clang/CodeGen/CodeGenFunction.h +++ b/clang/CodeGen/CodeGenFunction.h @@ -335,6 +335,9 @@ public: /// getCGRecordLayout - Return record layout info. const CGRecordLayout *getCGRecordLayout(CodeGenTypes &CGT, QualType RTy); + + /// GetAddrOfStaticLocalVar - Return the address of a static local variable. + llvm::Constant *GetAddrOfStaticLocalVar(const BlockVarDecl *BVD); //===--------------------------------------------------------------------===// // Declaration Emission //===--------------------------------------------------------------------===// diff --git a/clang/CodeGen/CodeGenModule.h b/clang/CodeGen/CodeGenModule.h index 48283c53a66c..7ea6ef9941e7 100644 --- a/clang/CodeGen/CodeGenModule.h +++ b/clang/CodeGen/CodeGenModule.h @@ -41,6 +41,8 @@ namespace clang { namespace CodeGen { + class CodeGenFunction; + /// CodeGenModule - This class organizes the cross-module state that is used /// while generating LLVM code. class CodeGenModule { @@ -95,7 +97,7 @@ public: void EmitGlobalVarDeclarator(const FileVarDecl *D); void UpdateCompletedType(const TagDecl *D); llvm::Constant *EmitGlobalInit(const Expr *E); - llvm::Constant *EmitConstantExpr(const Expr *E); + llvm::Constant *EmitConstantExpr(const Expr *E, CodeGenFunction *CGF = 0); /// WarnUnsupported - Print out a warning that codegen doesn't support the /// specified stmt yet. diff --git a/clang/test/CodeGen/staticinit.c b/clang/test/CodeGen/staticinit.c index e226179768ca..50c837a1c2f1 100644 --- a/clang/test/CodeGen/staticinit.c +++ b/clang/test/CodeGen/staticinit.c @@ -1,4 +1,4 @@ -// RUN: clang -emit-llvm %s +// RUN: clang -emit-llvm < %s | grep "g.b = internal global i8. getelementptr" struct AStruct { int i; @@ -13,3 +13,8 @@ void f() { static char* strs[] = { "one", "two", "three", "four" }; static struct AStruct myStruct = { 1, "two", 3.0 }; } + +void g() { + static char a[10]; + static char *b = a; +}