Revert 192220 as it fails on an assertion

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@192225 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index 2c37709..ab0db1a 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -15,7 +15,6 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/CharUnits.h"
-#include "clang/AST/CXXInheritance.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
@@ -1406,8 +1405,7 @@
   //                   ::= Z # global far
   if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
     switch (MD->getAccess()) {
-      case AS_none:
-        llvm_unreachable("Unsupported access specifier");
+      default:
       case AS_private:
         if (MD->isStatic())
           Out << 'C';
@@ -1860,70 +1858,36 @@
   return Mangler.mangle(D);
 }
 
-static void mangleThunkThisAdjustment(const CXXMethodDecl *MD,
-                                      const ThisAdjustment &Adjustment,
-                                      MicrosoftCXXNameMangler &Mangler,
-                                      raw_ostream &Out) {
-  // FIXME: add support for vtordisp thunks.
-  if (Adjustment.NonVirtual != 0) {
-    switch (MD->getAccess()) {
-    case AS_none:
-      llvm_unreachable("Unsupported access specifier");
-    case AS_private:
-      Out << 'G';
-      break;
-    case AS_protected:
-      Out << 'O';
-      break;
-    case AS_public:
-      Out << 'W';
-    }
-    llvm::APSInt APSNumber(/*BitWidth=*/32, /*isUnsigned=*/true);
-    APSNumber = -Adjustment.NonVirtual;
-    Mangler.mangleNumber(APSNumber);
-  } else {
-    switch (MD->getAccess()) {
-    case AS_none:
-      llvm_unreachable("Unsupported access specifier");
-    case AS_private:
-      Out << 'A';
-      break;
-    case AS_protected:
-      Out << 'I';
-      break;
-    case AS_public:
-      Out << 'Q';
-    }
-  }
-}
-
 void MicrosoftMangleContextImpl::mangleThunk(const CXXMethodDecl *MD,
                                              const ThunkInfo &Thunk,
                                              raw_ostream &Out) {
+  // FIXME: this is not yet a complete implementation, but merely a
+  // reasonably-working stub to avoid crashing when required to emit a thunk.
   MicrosoftCXXNameMangler Mangler(*this, Out);
   Out << "\01?";
   Mangler.mangleName(MD);
-  mangleThunkThisAdjustment(MD, Thunk.This, Mangler, Out);
-  if (!Thunk.Return.isEmpty())
-    assert(Thunk.Method != 0 && "Thunk info should hold the overridee decl");
-
-  const CXXMethodDecl *DeclForFPT = Thunk.Method ? Thunk.Method : MD;
-  Mangler.mangleFunctionType(
-      DeclForFPT->getType()->castAs<FunctionProtoType>(), MD);
+  if (Thunk.This.NonVirtual != 0) {
+    // FIXME: add support for protected/private or use mangleFunctionClass.
+    Out << "W";
+    llvm::APSInt APSNumber(/*BitWidth=*/32 /*FIXME: check on x64*/,
+                           /*isUnsigned=*/true);
+    APSNumber = -Thunk.This.NonVirtual;
+    Mangler.mangleNumber(APSNumber);
+  } else {
+    // FIXME: add support for protected/private or use mangleFunctionClass.
+    Out << "Q";
+  }
+  // FIXME: mangle return adjustment? Most likely includes using an overridee FPT?
+  Mangler.mangleFunctionType(MD->getType()->castAs<FunctionProtoType>(), MD);
 }
 
-void MicrosoftMangleContextImpl::mangleCXXDtorThunk(
-    const CXXDestructorDecl *DD, CXXDtorType Type,
-    const ThisAdjustment &Adjustment, raw_ostream &Out) {
-  // FIXME: Actually, the dtor thunk should be emitted for vector deleting
-  // dtors rather than scalar deleting dtors. Just use the vector deleting dtor
-  // mangling manually until we support both deleting dtor types.
-  assert(Type == Dtor_Deleting);
-  MicrosoftCXXNameMangler Mangler(*this, Out, DD, Type);
-  Out << "\01??_E";
-  Mangler.mangleName(DD->getParent());
-  mangleThunkThisAdjustment(DD, Adjustment, Mangler, Out);
-  Mangler.mangleFunctionType(DD->getType()->castAs<FunctionProtoType>(), DD);
+void MicrosoftMangleContextImpl::mangleCXXDtorThunk(const CXXDestructorDecl *DD,
+                                                    CXXDtorType Type,
+                                                    const ThisAdjustment &,
+                                                    raw_ostream &) {
+  unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
+    "cannot mangle thunk for this destructor yet");
+  getDiags().Report(DD->getLocation(), DiagID);
 }
 
 void MicrosoftMangleContextImpl::mangleCXXVFTable(
diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp
index fbc5e3d..9aad711 100644
--- a/lib/AST/VTableBuilder.cpp
+++ b/lib/AST/VTableBuilder.cpp
@@ -992,7 +992,6 @@
     MostDerivedClassIsVirtual(MostDerivedClassIsVirtual), 
     LayoutClass(LayoutClass), Context(MostDerivedClass->getASTContext()), 
     Overriders(MostDerivedClass, MostDerivedClassOffset, LayoutClass) {
-    assert(!Context.getTargetInfo().getCXXABI().isMicrosoft());
 
     LayoutVTable();
 
@@ -1905,21 +1904,6 @@
   }
 }
 
-struct ItaniumThunkInfoComparator {
-  bool operator() (const ThunkInfo &LHS, const ThunkInfo &RHS) {
-    assert(LHS.Method == 0);
-    assert(RHS.Method == 0);
-
-    if (LHS.This != RHS.This)
-      return LHS.This < RHS.This;
-
-    if (LHS.Return != RHS.Return)
-      return LHS.Return < RHS.Return;
-
-    llvm_unreachable("Shouldn't observe two equal thunks");
-  }
-};
-
 /// dumpLayout - Dump the vtable layout.
 void VTableBuilder::dumpLayout(raw_ostream& Out) {
   // FIXME: write more tests that actually use the dumpLayout output to prevent
@@ -2162,8 +2146,7 @@
       const CXXMethodDecl *MD = I->second;
 
       ThunkInfoVectorTy ThunksVector = Thunks[MD];
-      std::sort(ThunksVector.begin(), ThunksVector.end(),
-                ItaniumThunkInfoComparator());
+      std::sort(ThunksVector.begin(), ThunksVector.end());
 
       Out << "Thunks for '" << MethodName << "' (" << ThunksVector.size();
       Out << (ThunksVector.size() == 1 ? " entry" : " entries") << ").\n";
@@ -2250,15 +2233,7 @@
 
   Out << '\n';
 }
-
-struct VTableThunksComparator {
-  bool operator()(const VTableLayout::VTableThunkTy &LHS,
-                  const VTableLayout::VTableThunkTy &RHS) {
-    assert(LHS.first != RHS.first &&
-            "All thunks should have unique indices!");
-    return LHS.first < RHS.first;
-  }
-};
+  
 }
 
 VTableLayout::VTableLayout(uint64_t NumVTableComponents,
@@ -2277,9 +2252,6 @@
             this->VTableComponents.get());
   std::copy(VTableThunks, VTableThunks+NumVTableThunks,
             this->VTableThunks.get());
-  std::sort(this->VTableThunks.get(),
-            this->VTableThunks.get() + NumVTableThunks,
-            VTableThunksComparator());
 }
 
 VTableLayout::~VTableLayout() { }
@@ -2340,6 +2312,7 @@
 static VTableLayout *CreateVTableLayout(const VTableBuilder &Builder) {
   SmallVector<VTableLayout::VTableThunkTy, 1>
     VTableThunks(Builder.vtable_thunks_begin(), Builder.vtable_thunks_end());
+  std::sort(VTableThunks.begin(), VTableThunks.end());
 
   return new VTableLayout(Builder.getNumVTableComponents(),
                           Builder.vtable_component_begin(),
@@ -2547,14 +2520,18 @@
 
   /// AddMethod - Add a single virtual member function to the vftable
   /// components vector.
-  void AddMethod(const CXXMethodDecl *MD, ThunkInfo TI) {
+  void AddMethod(const CXXMethodDecl *MD, ThisAdjustment ThisAdjustment,
+                 ReturnAdjustment ReturnAdjustment) {
     if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
-      assert(TI.Return.isEmpty() &&
+      assert(ReturnAdjustment.isEmpty() &&
              "Destructor can't have return adjustment!");
       Components.push_back(VTableComponent::MakeDeletingDtor(DD));
     } else {
-      if (!TI.isEmpty())
-        VTableThunks[Components.size()] = TI;
+      // Add the return adjustment if necessary.
+      if (!ReturnAdjustment.isEmpty() || !ThisAdjustment.isEmpty()) {
+        VTableThunks[Components.size()].Return = ReturnAdjustment;
+        VTableThunks[Components.size()].This = ThisAdjustment;
+      }
       Components.push_back(VTableComponent::MakeFunction(MD));
     }
   }
@@ -2839,7 +2816,6 @@
     FinalOverriders::OverriderInfo Overrider =
         Overriders.getOverrider(MD, Base.getBaseOffset());
     ThisAdjustment ThisAdjustmentOffset;
-    bool ForceThunk = false;
 
     // Check if this virtual member function overrides
     // a method in one of the visited bases.
@@ -2864,7 +2840,8 @@
         AddThunk(MD, VTableThunks[OverriddenMethodInfo.VFTableIndex]);
       }
 
-      if (MD->getResultType() == OverriddenMD->getResultType()) {
+      if (ComputeReturnAdjustmentBaseOffset(Context, MD, OverriddenMD)
+              .isEmpty()) {
         // No return adjustment needed - just replace the overridden method info
         // with the current info.
         MethodInfo MI(OverriddenMethodInfo.VBTableIndex,
@@ -2882,7 +2859,6 @@
         // method was in the vftable.
         // For now, just mark the overriden method as shadowed by a new slot.
         OverriddenMethodInfo.Shadowed = true;
-        ForceThunk = true;
 
         // Also apply this adjustment to the shadowed slots.
         if (!ThisAdjustmentOffset.isEmpty()) {
@@ -2931,7 +2907,6 @@
           ComputeReturnAdjustmentBaseOffset(Context, OverriderMD, MD);
     }
     if (!ReturnAdjustmentOffset.isEmpty()) {
-      ForceThunk = true;
       ReturnAdjustment.NonVirtual =
           ReturnAdjustmentOffset.NonVirtualOffset.getQuantity();
       if (ReturnAdjustmentOffset.VirtualBase) {
@@ -2943,8 +2918,7 @@
       }
     }
 
-    AddMethod(OverriderMD, ThunkInfo(ThisAdjustmentOffset, ReturnAdjustment,
-                                     ForceThunk ? MD : 0));
+    AddMethod(Overrider.Method, ThisAdjustmentOffset, ReturnAdjustment);
   }
 }
 
@@ -2955,20 +2929,6 @@
   }
 }
 
-struct MicrosoftThunkInfoStableSortComparator {
-  bool operator() (const ThunkInfo &LHS, const ThunkInfo &RHS) {
-    if (LHS.This != RHS.This)
-      return LHS.This < RHS.This;
-
-    if (LHS.Return != RHS.Return)
-      return LHS.Return < RHS.Return;
-
-    // Keep different thunks with the same adjustments in the order they
-    // were put into the vector.
-    return false;
-  }
-};
-
 void VFTableBuilder::dumpLayout(raw_ostream &Out) {
   Out << "VFTable for ";
   PrintBasePath(WhichVFPtr.PathToBaseWithVFPtr, Out);
@@ -3082,8 +3042,7 @@
       const CXXMethodDecl *MD = I->second;
 
       ThunkInfoVectorTy ThunksVector = Thunks[MD];
-      std::stable_sort(ThunksVector.begin(), ThunksVector.end(),
-                       MicrosoftThunkInfoStableSortComparator());
+      std::sort(ThunksVector.begin(), ThunksVector.end());
 
       Out << "Thunks for '" << MethodName << "' (" << ThunksVector.size();
       Out << (ThunksVector.size() == 1 ? " entry" : " entries") << ").\n";
@@ -3259,6 +3218,7 @@
     assert(VFTableLayouts.count(id) == 0);
     SmallVector<VTableLayout::VTableThunkTy, 1> VTableThunks(
         Builder.vtable_thunks_begin(), Builder.vtable_thunks_end());
+    std::sort(VTableThunks.begin(), VTableThunks.end());
     VFTableLayouts[id] = new VTableLayout(
         Builder.getNumVTableComponents(), Builder.vtable_component_begin(),
         VTableThunks.size(), VTableThunks.data(), EmptyAddressPointsMap, true);