diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2010-06-21 21:27:42 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2010-06-21 21:27:42 +0000 |
commit | 89bdd14f2f89fd7486be5fb0fde62e00182aeb89 (patch) | |
tree | 83ba9de23d76457bbf7efd8ce44030e7444fdefc /clang/lib/CodeGen | |
parent | 72df24037e0f628c01c5f421ba32dfc260ec26be (diff) | |
download | bcm5719-llvm-89bdd14f2f89fd7486be5fb0fde62e00182aeb89.tar.gz bcm5719-llvm-89bdd14f2f89fd7486be5fb0fde62e00182aeb89.zip |
In supporting init-priority, globals with the same init_priority must be
emitted in the order in which they are seen (still radar 8076356).
llvm-svn: 106485
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGDeclCXX.cpp | 24 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 10 |
2 files changed, 31 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp index be4e3a5bf99..9faaed55386 100644 --- a/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/clang/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); diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 0bb9d4ded93..713a5fdd64a 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -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 |