diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2010-06-21 18:45:05 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2010-06-21 18:45:05 +0000 |
commit | 9f967c5e4bbeb48caf6d0e62056b3d3fee20bf7c (patch) | |
tree | 2abcfab991ee325b37a5c2182835267334653f56 | |
parent | af896897f7485176f43d40c4adced7efb0fb2b06 (diff) |
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
-rw-r--r-- | lib/CodeGen/CGDeclCXX.cpp | 30 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 5 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 2 |
3 files changed, 31 insertions, 6 deletions
diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp index a59ed0abe6..fafc85d628 100644 --- a/lib/CodeGen/CGDeclCXX.cpp +++ b/lib/CodeGen/CGDeclCXX.cpp @@ -171,12 +171,17 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D) { 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 @@ CodeGenModule::EmitCXXGlobalInitFunc() { 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 35383301e0..0bb9d4ded9 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -139,6 +139,11 @@ class CodeGenModule : public BlockModule { /// 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. diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index c5eb048577..5858de0669 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -1218,7 +1218,7 @@ static void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr, Attr.setInvalid(); return; } - unsigned prioritynum = static_cast<unsigned>(priority.getZExtValue() * 8); + unsigned prioritynum = priority.getZExtValue(); if (prioritynum < 101 || prioritynum > 65535) { S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) << priorityExpr->getSourceRange(); |