aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/CodeGenModule.cpp21
-rw-r--r--lib/CodeGen/CodeGenModule.h4
-rw-r--r--test/CodeGen/static-order.c19
3 files changed, 33 insertions, 11 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index fc1b108b0d..021e9af676 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -361,26 +361,27 @@ void CodeGenModule::EmitStatics() {
bool Changed;
do {
Changed = false;
- for (unsigned i = 0, e = StaticDecls.size(); i != e; ++i) {
- const ValueDecl *D = StaticDecls[i];
-
+
+ for (std::list<const ValueDecl*>::iterator i = StaticDecls.begin(),
+ e = StaticDecls.end(); i != e; ) {
+ const ValueDecl *D = *i;
+
// Check if we have used a decl with the same name
// FIXME: The AST should have some sort of aggregate decls or
// global symbol map.
// FIXME: This is missing some important cases. For example, we
// need to check for uses in an alias and in a constructor.
- if (!GlobalDeclMap.count(D->getIdentifier()))
+ if (!GlobalDeclMap.count(D->getIdentifier())) {
+ i++;
continue;
-
+ }
+
// Emit the definition.
EmitGlobalDefinition(D);
// Erase the used decl from the list.
- StaticDecls[i] = StaticDecls.back();
- StaticDecls.pop_back();
- --i;
- --e;
-
+ i = StaticDecls.erase(i);
+
// Remember that we made a change.
Changed = true;
}
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 3f604dd048..0bd0e2c724 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -21,6 +21,8 @@
#include "CGCall.h"
+#include <list>
+
namespace llvm {
class Module;
class Constant;
@@ -97,7 +99,7 @@ class CodeGenModule {
/// will lazily emit definitions for only the decls that were
/// actually used. This should contain only Function and Var decls,
/// and only those which actually define something.
- std::vector<const ValueDecl*> StaticDecls;
+ std::list<const ValueDecl*> StaticDecls;
/// GlobalCtors - Store the list of global constructors and their
/// respective priorities to be emitted when the translation unit is
diff --git a/test/CodeGen/static-order.c b/test/CodeGen/static-order.c
new file mode 100644
index 0000000000..c63f4ed892
--- /dev/null
+++ b/test/CodeGen/static-order.c
@@ -0,0 +1,19 @@
+// RUN: clang -emit-llvm -o - %s | not grep "zeroinitializer"
+
+struct s {
+ int a;
+};
+
+static void *v;
+
+static struct s a;
+
+static struct s a = {
+ 10
+};
+
+void *f()
+{
+ if (a.a)
+ return v;
+}