зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
45f9b7e8f2
Коммит
e0b691a25f
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче