]> granicus.if.org Git - clang/commitdiff
Implement codegen for the following static var init.
authorLauro Ramos Venancio <lauro.venancio@gmail.com>
Tue, 26 Feb 2008 21:41:45 +0000 (21:41 +0000)
committerLauro Ramos Venancio <lauro.venancio@gmail.com>
Tue, 26 Feb 2008 21:41:45 +0000 (21:41 +0000)
void g() {
  static char a[10];
  static char *b = a;
}

Now we can compile wget!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47627 91177308-0d34-0410-b5e6-96231b3b80d8

CodeGen/CGDecl.cpp
CodeGen/CGExprConstant.cpp
CodeGen/CodeGenFunction.cpp
CodeGen/CodeGenFunction.h
CodeGen/CodeGenModule.h
test/CodeGen/staticinit.c

index cd31fa7a7d3c8dac97b746222a795945ec899a3f..c80cecc76ee26488b176bfd905a2e21a879a0955 100644 (file)
@@ -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");
index 1a60cae5a07bdfbf4e16ac89eb40b57f05ac8bea..ec16b16a9d49f9fd6f0c63f9d3369ffecfab8c7b 100644 (file)
@@ -25,9 +25,10 @@ namespace  {
 class VISIBILITY_HIDDEN ConstExprEmitter : 
   public StmtVisitor<ConstExprEmitter, llvm::Constant*> {
   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<FileVarDecl>(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<BlockVarDecl>(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<Expr*>(E));
+  return ConstExprEmitter(*this, CGF).Visit(const_cast<Expr*>(E));
 }
index dc31a27945b57e905d2819ca2d41309c02eafe85..c2a303c7557c850bef7b0db4035282cf54c39356 100644 (file)
@@ -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<llvm::Constant>(LocalDeclMap[BVD]);
+}
 
 const llvm::Type *CodeGenFunction::ConvertType(QualType T) {
   return CGM.getTypes().ConvertType(T);
index e88575293311cd453559a4272ce5c94ee8153a3c..b136c2b06150ea793c96b7aafc63ec264835c2cf 100644 (file)
@@ -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
   //===--------------------------------------------------------------------===//
index 48283c53a66cb32a150ef0c7ede1b14f1c83bc85..7ea6ef9941e770f4da53525bc1d4c958505d55a5 100644 (file)
@@ -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.
index e226179768caf96d0544cdaa1177b146bdefa4ed..50c837a1c2f1fd7d22c40fd5aac90bfc4d30b011 100644 (file)
@@ -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;
+}