diff options
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 21 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 4 | ||||
-rw-r--r-- | test/CodeGen/static-order.c | 19 |
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; +} |