]> granicus.if.org Git - clang/commitdiff
IRGen for implementation of init-priority attribute.
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 21 Jun 2010 18:45:05 +0000 (18:45 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 21 Jun 2010 18:45:05 +0000 (18:45 +0000)
Test case will be checked in llvm test suite.
(finishes off radar 8076356).

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

lib/CodeGen/CGDeclCXX.cpp
lib/CodeGen/CodeGenModule.h
lib/Sema/SemaDeclAttr.cpp

index a59ed0abe6212be55fb8d5b0634ba208812ba495..fafc85d628e7722a46f9f32571d3ad8c350cbd1b 100644 (file)
@@ -171,12 +171,17 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D) {
 
   CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D);
 
-  CXXGlobalInits.push_back(Fn);
+  if (D->hasAttr<InitPriorityAttr>()) {
+    unsigned int order = D->getAttr<InitPriorityAttr>()->getPriority();
+    PrioritizedCXXGlobalInits.push_back(std::make_pair(order,Fn));
+  }
+  else
+    CXXGlobalInits.push_back(Fn);
 }
 
 void
 CodeGenModule::EmitCXXGlobalInitFunc() {
-  if (CXXGlobalInits.empty())
+  if (CXXGlobalInits.empty() && PrioritizedCXXGlobalInits.empty())
     return;
 
   const llvm::FunctionType *FTy
@@ -187,9 +192,24 @@ CodeGenModule::EmitCXXGlobalInitFunc() {
   llvm::Function *Fn = 
     CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__I_a");
 
-  CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn,
-                                                   &CXXGlobalInits[0],
-                                                   CXXGlobalInits.size());
+  if (!PrioritizedCXXGlobalInits.empty()) {
+    std::vector<llvm::Constant*> LocalCXXGlobalInits;
+    std::sort(PrioritizedCXXGlobalInits.begin(), 
+              PrioritizedCXXGlobalInits.end());
+    for (unsigned i = 0; i < PrioritizedCXXGlobalInits.size(); i++) {
+      llvm::Function *Fn = PrioritizedCXXGlobalInits[i].second;
+      LocalCXXGlobalInits.push_back(Fn);
+    }
+    for (unsigned i = 0; i < CXXGlobalInits.size(); i++)
+      LocalCXXGlobalInits.push_back(CXXGlobalInits[i]);
+    CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn,
+                                                    &LocalCXXGlobalInits[0],
+                                                    LocalCXXGlobalInits.size());
+  }
+  else
+    CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn,
+                                                     &CXXGlobalInits[0],
+                                                     CXXGlobalInits.size());
   AddGlobalCtor(Fn);
 }
 
index 35383301e0c6740b643fec2c347d11eafb9e2be2..0bb9d4ded93a85bc0c6b77fe37847eee82bd5f41 100644 (file)
@@ -139,6 +139,11 @@ class CodeGenModule : public BlockModule {
   /// CXXGlobalInits - Global variables with initializers that need to run
   /// before main.
   std::vector<llvm::Constant*> CXXGlobalInits;
+  
+  /// - Global variables with initializers whose order of initialization
+  /// is set by init_priority attribute.
+  llvm::SmallVector<std::pair<unsigned int, llvm::Function*>, 8> 
+    PrioritizedCXXGlobalInits;
 
   /// CXXGlobalDtors - Global destructor functions and arguments that need to
   /// run on termination.
index c5eb048577a467a5567ae7fd54be729033f975d6..5858de06698af7480247e71f54805f5c758d2db4 100644 (file)
@@ -1218,7 +1218,7 @@ static void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr,
     Attr.setInvalid();
     return;
   }
-  unsigned prioritynum = static_cast<unsigned>(priority.getZExtValue() * 8);
+  unsigned prioritynum = priority.getZExtValue();
   if (prioritynum < 101 || prioritynum > 65535) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
     <<  priorityExpr->getSourceRange();