aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGDeclCXX.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2010-06-21 21:27:42 +0000
committerFariborz Jahanian <fjahanian@apple.com>2010-06-21 21:27:42 +0000
commite0b691a25f801d8be552c9387863637b9526e639 (patch)
tree3c89a582b033ac76928dabf37dce5e5c966a9c3d /lib/CodeGen/CGDeclCXX.cpp
parent45f9b7e8f23072d662ee1cc758f4ecb0da5e3322 (diff)
In supporting init-priority, globals with the same init_priority must be
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
Diffstat (limited to 'lib/CodeGen/CGDeclCXX.cpp')
-rw-r--r--lib/CodeGen/CGDeclCXX.cpp24
1 files changed, 22 insertions, 2 deletions
diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp
index be4e3a5bf9..9faaed5538 100644
--- a/lib/CodeGen/CGDeclCXX.cpp
+++ b/lib/CodeGen/CGDeclCXX.cpp
@@ -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);