[ms-cxxabi] Mangle dynamic initializer stubs the same way MSVC does

Summary: Dynamic initializers are mangled as ??__E <name> YAXXZ.

Reviewers: timurrrr

CC: cfe-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D1477

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190434 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 1d8a311..38a6223 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -153,6 +153,7 @@
                      raw_ostream &);
 
   void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &);
+  void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out);
   void mangleDynamicAtExitDestructor(const VarDecl *D, raw_ostream &Out);
   void mangleItaniumThreadLocalInit(const VarDecl *D, raw_ostream &);
   void mangleItaniumThreadLocalWrapper(const VarDecl *D, raw_ostream &);
@@ -3701,6 +3702,14 @@
   Mangler.mangleName(D);
 }
 
+void ItaniumMangleContext::mangleDynamicInitializer(const VarDecl *MD,
+                                                    raw_ostream &Out) {
+  // These symbols are internal in the Itanium ABI, so the names don't matter.
+  // Clang has traditionally used this symbol and allowed LLVM to adjust it to
+  // avoid duplicate symbols.
+  Out << "__cxx_global_var_init";
+}
+
 void ItaniumMangleContext::mangleDynamicAtExitDestructor(const VarDecl *D,
                                                          raw_ostream &Out) {
   // Prefix the mangling of D with __dtor_.
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index 7e3d6c2..3ccc2bd 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -170,8 +170,12 @@
                              raw_ostream &);
   virtual void mangleReferenceTemporary(const VarDecl *, raw_ostream &);
   virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &Out);
+  virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out);
   virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
                                              raw_ostream &Out);
+
+private:
+  void mangleInitFiniStub(const VarDecl *D, raw_ostream &Out, char CharCode);
 };
 
 }
@@ -1941,15 +1945,27 @@
   Mangler.getStream() << (Visible ? "@51" : "@4IA");
 }
 
+void MicrosoftMangleContext::mangleInitFiniStub(const VarDecl *D,
+                                                raw_ostream &Out,
+                                                char CharCode) {
+  MicrosoftCXXNameMangler Mangler(*this, Out);
+  Mangler.getStream() << "\01??__" << CharCode;
+  Mangler.mangleName(D);
+  // This is the function class mangling.  These stubs are global, non-variadic,
+  // cdecl functions that return void and take no args.
+  Mangler.getStream() << "YAXXZ";
+}
+
+void MicrosoftMangleContext::mangleDynamicInitializer(const VarDecl *D,
+                                                      raw_ostream &Out) {
+  // <initializer-name> ::= ?__E <name> YAXXZ
+  mangleInitFiniStub(D, Out, 'E');
+}
+
 void MicrosoftMangleContext::mangleDynamicAtExitDestructor(const VarDecl *D,
                                                            raw_ostream &Out) {
-  // <destructor-name> ::= ?__F <postfix> YAXXZ
-  MicrosoftCXXNameMangler Mangler(*this, Out);
-  Mangler.getStream() << "\01??__F";
-  Mangler.mangleName(D);
-  // This is the mangling of the function type of the stub, which is a global,
-  // non-variadic, cdecl function that returns void and takes no args.
-  Mangler.getStream() << "YAXXZ";
+  // <destructor-name> ::= ?__F <name> YAXXZ
+  mangleInitFiniStub(D, Out, 'F');
 }
 
 MangleContext *clang::createMicrosoftMangleContext(ASTContext &Context,