]> granicus.if.org Git - clang/commitdiff
Pull COdeGenFunction::CreateStaticBlockVarDecl (just for creating the
authorDaniel Dunbar <daniel@zuster.org>
Wed, 25 Feb 2009 19:24:29 +0000 (19:24 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Wed, 25 Feb 2009 19:24:29 +0000 (19:24 +0000)
global variable) out of GenerateStaticBlockVarDecl.
 - No intended functionality change.
 - Prep for some mild cleanups and PR3662.

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

lib/CodeGen/CGCXX.cpp
lib/CodeGen/CGDecl.cpp
lib/CodeGen/CodeGenFunction.cpp
lib/CodeGen/CodeGenFunction.h

index 489c67bc6b74455be9a6f9a058197b02afaac2cd..f43130a12b2d10fa4f5c2ae2719c842dc52f7552 100644 (file)
@@ -83,28 +83,24 @@ static std::string mangleGuardVariable(const VarDecl& D)
   return S;
 }
 
-llvm::GlobalValue *
-CodeGenFunction::GenerateStaticCXXBlockVarDecl(const VarDecl &D)
-{
+void 
+CodeGenFunction::GenerateStaticCXXBlockVarDeclInit(const VarDecl &D, 
+                                                   llvm::GlobalVariable *GV) {
+  // FIXME: This should use __cxa_guard_{acquire,release}?
+
   assert(!getContext().getLangOptions().ThreadsafeStatics &&
          "thread safe statics are currently not supported!");
-  const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(D.getType());
 
-  // FIXME: If the function is inline, the linkage should be weak.
-  llvm::GlobalValue::LinkageTypes linkage = llvm::GlobalValue::InternalLinkage;
-  
   // Create the guard variable.
   llvm::GlobalValue *GuardV = 
     new llvm::GlobalVariable(llvm::Type::Int64Ty, false,
-                             linkage,
+                             GV->getLinkage(),
                              llvm::Constant::getNullValue(llvm::Type::Int64Ty),
                              mangleGuardVariable(D),
                              &CGM.getModule());
   
-  // FIXME: Address space.
-  const llvm::Type *PtrTy = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
-
   // Load the first byte of the guard variable.
+  const llvm::Type *PtrTy = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
   llvm::Value *V = Builder.CreateLoad(Builder.CreateBitCast(GuardV, PtrTy), 
                                       "tmp");
   
@@ -120,13 +116,8 @@ CodeGenFunction::GenerateStaticCXXBlockVarDecl(const VarDecl &D)
                          
   EmitBlock(InitBlock);
 
-  llvm::GlobalValue *GV =
-    new llvm::GlobalVariable(LTy, false,
-                             llvm::GlobalValue::InternalLinkage,
-                             llvm::Constant::getNullValue(LTy), 
-                             mangleVarDecl(D),
-                             &CGM.getModule(), 0, 
-                             D.getType().getAddressSpace());
+  // Patch the name. FIXME: We shouldn't need to do this.
+  GV->setName(mangleVarDecl(D));
     
   const Expr *Init = D.getInit();
   if (!hasAggregateLLVMType(Init->getType())) {
@@ -142,6 +133,5 @@ CodeGenFunction::GenerateStaticCXXBlockVarDecl(const VarDecl &D)
                       Builder.CreateBitCast(GuardV, PtrTy));
                       
   EmitBlock(EndBlock);
-  return GV;
 }
 
index 0ca2ad351c9a9bc94fa36633bf98855dcec125c9..c0f2054394b701d277e8ed670d205e4429b30b1e 100644 (file)
@@ -74,50 +74,78 @@ void CodeGenFunction::EmitBlockVarDecl(const VarDecl &D) {
   }
 }
 
-llvm::GlobalValue *
+llvm::GlobalVariable *
+CodeGenFunction::CreateStaticBlockVarDecl(const VarDecl &D,
+                                          const char *Separator,
+                                          llvm::GlobalValue::LinkageTypes
+                                          Linkage) {
+  QualType Ty = D.getType();
+  assert(Ty->isConstantSizeType() && "VLAs can't be static");
+
+  std::string ContextName;
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurFuncDecl))
+    ContextName = CGM.getMangledName(FD);
+  else if (isa<ObjCMethodDecl>(CurFuncDecl))
+    ContextName = std::string(CurFn->getNameStart(), 
+                              CurFn->getNameStart() + CurFn->getNameLen());
+  else
+    assert(0 && "Unknown context for block var decl");
+
+  const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(Ty);
+  return new llvm::GlobalVariable(LTy, Ty.isConstant(getContext()), Linkage,
+                                  llvm::Constant::getNullValue(LTy), 
+                                  ContextName + Separator + D.getNameAsString(),
+                                  &CGM.getModule(), 0, Ty.getAddressSpace());
+}
+
+llvm::GlobalVariable *
 CodeGenFunction::GenerateStaticBlockVarDecl(const VarDecl &D,
                                             bool NoInit,
                                             const char *Separator,
                                             llvm::GlobalValue
                                                ::LinkageTypes Linkage) {
-  QualType Ty = D.getType();
-  assert(Ty->isConstantSizeType() && "VLAs can't be static");
-  
-  const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(Ty);
-  llvm::Constant *Init = 0;
-  if ((D.getInit() == 0) || NoInit) {
-    Init = llvm::Constant::getNullValue(LTy);
-  } else {
-    Init = CGM.EmitConstantExpr(D.getInit(), this);
+  llvm::GlobalVariable *GV = CreateStaticBlockVarDecl(D, Separator, Linkage);
+
+  if (D.getInit() && !NoInit) {
+    llvm::Constant *Init = CGM.EmitConstantExpr(D.getInit(), this);
 
     // If constant emission failed, then this should be a C++ static
     // initializer.
     if (!Init) {
-      if (!getContext().getLangOptions().CPlusPlus) {
+      if (!getContext().getLangOptions().CPlusPlus)
         CGM.ErrorUnsupported(D.getInit(), "constant l-value expression");
-        Init = llvm::Constant::getNullValue(LTy);
-      } else {
-        return GenerateStaticCXXBlockVarDecl(D);
-      }
-    }
-  }
+      else
+        GenerateStaticCXXBlockVarDeclInit(D, GV);
+    } else {
+      // The initializer may differ in type from the global. Rewrite
+      // the global to match the initializer!?
+      //
+      // FIXME: This matches what we have been doing historically, but
+      // it seems bad. Shouldn't the init expression have the right
+      // type?
+      if (GV->getType() != Init->getType()) {
+        llvm::GlobalVariable *OldGV = GV;
+        
+        GV = new llvm::GlobalVariable(Init->getType(), OldGV->isConstant(),
+                                      OldGV->getLinkage(), Init, "",
+                                      &CGM.getModule(), 0, 
+                                      D.getType().getAddressSpace());
 
-  assert(Init && "Unable to create initialiser for static decl");
+        // Steal the name of the old global
+        GV->takeName(OldGV);
 
-  std::string ContextName;
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurFuncDecl))
-    ContextName = CGM.getMangledName(FD);
-  else if (isa<ObjCMethodDecl>(CurFuncDecl))
-    ContextName = std::string(CurFn->getNameStart(), 
-                              CurFn->getNameStart() + CurFn->getNameLen());
-  else
-    assert(0 && "Unknown context for block var decl");
+        // Replace all uses of the old global with the new global
+        llvm::Constant *NewPtrForOldDecl = 
+          llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
+        OldGV->replaceAllUsesWith(NewPtrForOldDecl);
+
+        // Erase the old global, since it is no longer used.
+        OldGV->eraseFromParent();
+      } 
 
-  llvm::GlobalValue *GV =
-    new llvm::GlobalVariable(Init->getType(), Ty.isConstant(getContext()),
-                             Linkage,
-                             Init, ContextName + Separator +D.getNameAsString(),
-                             &CGM.getModule(), 0, Ty.getAddressSpace());
+      GV->setInitializer(Init);
+    }
+  }
 
   return GV;
 }
index ccd961ac28335dfc6a750ce3243934dc4d6de8ff..879b85891de6088b1ebceecaab3cdec3cb39ba85 100644 (file)
@@ -53,14 +53,15 @@ llvm::BasicBlock *CodeGenFunction::getBasicBlockForLabel(const LabelStmt *S) {
   return BB = createBasicBlock(S->getName());
 }
 
-llvm::Constant *
-CodeGenFunction::GetAddrOfStaticLocalVar(const VarDecl *BVD) {
-  return cast<llvm::Constant>(LocalDeclMap[BVD]);
+llvm::Value *CodeGenFunction::GetAddrOfLocalVar(const VarDecl *VD) {
+  llvm::Value *Res = LocalDeclMap[VD];
+  assert(Res && "Invalid argument to GetAddrOfLocalVar(), no decl!");
+  return Res;
 }
 
-llvm::Value *CodeGenFunction::GetAddrOfLocalVar(const VarDecl *VD)
-{
-  return LocalDeclMap[VD];
+llvm::Constant *
+CodeGenFunction::GetAddrOfStaticLocalVar(const VarDecl *BVD) {
+  return cast<llvm::Constant>(GetAddrOfLocalVar(BVD));
 }
 
 const llvm::Type *CodeGenFunction::ConvertTypeForMem(QualType T) {
index f13e79ae1d690c25bc7d29c893348ddc51f89043..02276b98b0602374bd2559c387b8cb6a3d83a0b8 100644 (file)
@@ -746,17 +746,25 @@ public:
   /// LoadComplexFromAddr - Load a complex number from the specified address.
   ComplexPairTy LoadComplexFromAddr(llvm::Value *SrcAddr, bool SrcIsVolatile);
 
+  /// CreateStaticBlockVarDecl - Create a zero-initialized LLVM global
+  /// for a static block var decl.
+  llvm::GlobalVariable * CreateStaticBlockVarDecl(const VarDecl &D,
+                                                  const char *Separator,
+                                                  llvm::GlobalValue::LinkageTypes
+                                                  Linkage);
+
   /// GenerateStaticBlockVarDecl - Return the the static declaration of local
   /// variable.
-  llvm::GlobalValue * GenerateStaticBlockVarDecl(const VarDecl &D,
-                                                 bool NoInit,
-                                                 const char *Separator,
-                                                 llvm::GlobalValue
-                                                 ::LinkageTypes Linkage);
-
-  /// GenerateStaticCXXBlockVarDecl - Return the static declaration of a local
-  /// variable. Performs initialization of the variable if necessary.
-  llvm::GlobalValue *GenerateStaticCXXBlockVarDecl(const VarDecl &D);
+  llvm::GlobalVariable * GenerateStaticBlockVarDecl(const VarDecl &D,
+                                                    bool NoInit,
+                                                    const char *Separator,
+                                                    llvm::GlobalValue
+                                                    ::LinkageTypes Linkage);
+
+  /// GenerateStaticCXXBlockVarDecl - Create the initializer for a C++
+  /// runtime initialized static block var decl.
+  void GenerateStaticCXXBlockVarDeclInit(const VarDecl &D,
+                                         llvm::GlobalVariable *GV);
 
   //===--------------------------------------------------------------------===//
   //                             Internal Helpers