]> granicus.if.org Git - clang/commitdiff
In supporting init-priority, globals with the same init_priority must be
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 21 Jun 2010 21:27:42 +0000 (21:27 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 21 Jun 2010 21:27:42 +0000 (21:27 +0000)
emitted in the order in which they are seen (still radar 8076356).

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

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

index be4e3a5bf9926e6ffc3b7a63b7f974f1fe521c28..9faaed55386d1f777e9b6538328b06bde6e1a483 100644 (file)
@@ -172,13 +172,32 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D) {
   CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D);
 
   if (D->hasAttr<InitPriorityAttr>()) {
+    static unsigned lix = 0; // to keep the lexical order of equal priority
+                             // objects intact;
     unsigned int order = D->getAttr<InitPriorityAttr>()->getPriority();
-    PrioritizedCXXGlobalInits.push_back(std::make_pair(order,Fn));
+    OrderGlobalInitsType Key(order, lix++);
+    PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
   }
   else
     CXXGlobalInits.push_back(Fn);
 }
 
+typedef std::pair<CodeGen::OrderGlobalInitsType, 
+                  llvm::Function *> global_init_pair;
+static int PrioritizedCXXGlobalInitsCmp(const void* a, const void* b) {
+  const global_init_pair *LHS = static_cast<const global_init_pair*>(a);
+  const global_init_pair *RHS = static_cast<const global_init_pair*>(b);
+  if (LHS->first.priority < RHS->first.priority)
+    return -1;
+  if (LHS->first.priority == RHS->first.priority) {
+    if (LHS->first.lex_order < RHS->first.lex_order)
+      return -1;
+    if (LHS->first.lex_order == RHS->first.lex_order)
+      return 0;
+  }
+  return +1;
+}
+                                        
 void
 CodeGenModule::EmitCXXGlobalInitFunc() {
   if (CXXGlobalInits.empty() && PrioritizedCXXGlobalInits.empty())
@@ -195,7 +214,8 @@ CodeGenModule::EmitCXXGlobalInitFunc() {
   if (!PrioritizedCXXGlobalInits.empty()) {
     llvm::SmallVector<llvm::Constant*, 8> LocalCXXGlobalInits;
     llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(), 
-                         PrioritizedCXXGlobalInits.end());
+                         PrioritizedCXXGlobalInits.end(), 
+                         PrioritizedCXXGlobalInitsCmp);
     for (unsigned i = 0; i < PrioritizedCXXGlobalInits.size(); i++) {
       llvm::Function *Fn = PrioritizedCXXGlobalInits[i].second;
       LocalCXXGlobalInits.push_back(Fn);
index 0bb9d4ded93a85bc0c6b77fe37847eee82bd5f41..713a5fdd64a302141547100a07e8336b10fcb227 100644 (file)
@@ -75,6 +75,13 @@ namespace CodeGen {
   class CGObjCRuntime;
   class MangleBuffer;
   
+  typedef struct OrderGlobalInits{
+    unsigned int priority;
+    unsigned int lex_order;
+    OrderGlobalInits(unsigned int p, unsigned int l) 
+    : priority(p), lex_order(l) {}
+  } OrderGlobalInitsType;
+  
 /// CodeGenModule - This class organizes the cross-function state that is used
 /// while generating LLVM code.
 class CodeGenModule : public BlockModule {
@@ -142,7 +149,8 @@ class CodeGenModule : public BlockModule {
   
   /// - Global variables with initializers whose order of initialization
   /// is set by init_priority attribute.
-  llvm::SmallVector<std::pair<unsigned int, llvm::Function*>, 8> 
+  
+  llvm::SmallVector<std::pair<OrderGlobalInitsType, llvm::Function*>, 8> 
     PrioritizedCXXGlobalInits;
 
   /// CXXGlobalDtors - Global destructor functions and arguments that need to