IRGen for implementation of init-priority attribute.
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
diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp
index a59ed0a..fafc85d 100644
--- a/lib/CodeGen/CGDeclCXX.cpp
+++ b/lib/CodeGen/CGDeclCXX.cpp
@@ -171,12 +171,17 @@
 
   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 @@
   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);
 }
 
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 3538330..0bb9d4d 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -139,6 +139,11 @@
   /// 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.