Issue description

tools\win\static_initializers generates a report listing all static initializers and destructors (global constructors and destructors). On binaries created with clang-cl this report lists constructors/destructors from f:\binaries\Intermediate\vctools\ (those from the VC++ CRT) but nothing else.
The report for VC++ chrome.dll listed constructors for kDefaultColorNTPBackground, kDefaultColorNTPText, and kDefaultColorNTPLink, all of which are const globals that are initialized through calls to color_utils::GetSysSkColor(COLOR_WINDOW); which calls GetSysColor which is an OS call. Thus, these three globals have static initializers. However they do not show up in the report for clang chrome.dll. Running symbolsort on clang's chrome.dll and searching for kDefaultColorNTPBackground finds nothing.
It appears that no symbol is being generated for these static initializers, so it is possible that clang-cl needs to be updated to emit such a symbol. And, the static_initialiers tool may also need updating.

I think I see what's up with those initializers now. To ensure that they run in the same order that they appeared in the source file, clang emits code that looks like:
__GLOBAL_sub_I_$basename:
call "??__Eglobal1@YAXXZ"
call "??__Eglobal2@YAXXZ"
call "??__Eglobal3@YAXXZ"
ret
And we inline the "??__E" functions into the __GLOBAL_sub_I* function.
I guess we just need to look for __GLOBAL_sub_I like we do on Linux.

I tested with this change and it works nicely. I had to add an include of Windows.h, adjust the name to search for from __GLOBAL_sub_I to _GLOBAL__sub_I (note the movement of one underscore). I also printed the phrase "dynamic initializer" on those for consistent grepping.
With this change my results (on 64.0.3260.0) show 33 static initializers and 158 dynamic atexit destructors, which is consistent with the 48/140 results from VC++ builds, and gives me enough information to file a separate clang bug (constructors generated for __PURE_APPDOMAIN_GLOBAL static locale::id id;). In particular, the initializers for kDefaultColorNTPBackground, kDefaultColorNTPText, and kDefaultColorNTPLink are visible:
obj/chrome/browser/browser_3/theme_properties.obj: _GLOBAL__sub_I_theme_properties.cc (dynamic initializer)
My full patch (on top of your previous patch) is shown below. I think it's ready now. You can land it or I can.
diff --git a/tools/win/static_initializers/static_initializers.cc b/tools/win/static_initializers/static_initializers.cc
index 305500e95448..2800ac385aad 100644
--- a/tools/win/static_initializers/static_initializers.cc
+++ b/tools/win/static_initializers/static_initializers.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <Windows.h>
#include <dbghelp.h>
#include <dia2.h>
#include <stdio.h>
@@ -105,6 +106,15 @@ static void PrintIfDynamicInitializer(const std::wstring& module,
wcsstr(bstr_name, L"`dynamic atexit destructor for '")) {
wprintf(L"%s: %s\n", module.c_str(), bstr_name);
}
+ // If there are multiple dynamic initializers in one translation unit then
+ // a shared function is created and the individual initializers may be
+ // inlined into it. These functions start with a characteristic name that
+ // includes the source file. Finding the actual objects can be done through
+ // source inspection or by setting a breakpoint on the printed name. The
+ // "dynamic initializer" string is printed for consistent grepping.
+ if (wcsstr(bstr_name, L"_GLOBAL__sub_I")) {
+ wprintf(L"%s: %s (dynamic initializer)\n", module.c_str(), bstr_name);
+ }
// As of this writing, Clang does not undecorate the symbol names for
// dynamic initializers, so the debug info contains the decorated name,
// which starts with "??__E" or "??__F" for atexit destructors. Check for