]> granicus.if.org Git - clang/commitdiff
[MS ABI] Cleanup selectBasePath
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 5 May 2015 01:39:20 +0000 (01:39 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 5 May 2015 01:39:20 +0000 (01:39 +0000)
Handle some common cases quickly when deeper introspection into the path
has no effect on the final result.

No functional change intended.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@236475 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/VTableBuilder.cpp

index fedf76b3222a9cb58b4f6108c4e80a0707f92116..1739fa3e0328e5bb3ac7844c6ae68017b9687383 100644 (file)
@@ -3528,12 +3528,17 @@ static CharUnits getOffsetOfFullPath(ASTContext &Context,
 static const FullPathTy *selectBestPath(ASTContext &Context,
                                         const CXXRecordDecl *RD, VPtrInfo *Info,
                                         std::list<FullPathTy> &FullPaths) {
+  // Handle some easy cases first.
+  if (FullPaths.empty())
+    return nullptr;
+  if (FullPaths.size() == 1)
+    return &FullPaths.front();
+
   const FullPathTy *BestPath = nullptr;
   typedef std::set<const CXXMethodDecl *> OverriderSetTy;
   OverriderSetTy LastOverrides;
   for (const FullPathTy &SpecificPath : FullPaths) {
-    if (SpecificPath.empty())
-      continue;
+    assert(!SpecificPath.empty());
     OverriderSetTy CurrentOverrides;
     const CXXRecordDecl *TopLevelRD = SpecificPath.begin()->getBase();
     // Find the distance from the start of the path to the subobject with the
@@ -3546,19 +3551,21 @@ static const FullPathTy *selectBestPath(ASTContext &Context,
         continue;
       FinalOverriders::OverriderInfo OI =
           Overriders.getOverrider(MD->getCanonicalDecl(), BaseOffset);
+      const CXXMethodDecl *OverridingMethod = OI.Method;
       // Only overriders which have a return adjustment introduce problematic
       // thunks.
-      if (ComputeReturnAdjustmentBaseOffset(Context, OI.Method, MD).isEmpty())
+      if (ComputeReturnAdjustmentBaseOffset(Context, OverridingMethod, MD)
+              .isEmpty())
         continue;
       // It's possible that the overrider isn't in this path.  If so, skip it
       // because this path didn't introduce it.
-      const CXXRecordDecl *OverridingParent = OI.Method->getParent();
+      const CXXRecordDecl *OverridingParent = OverridingMethod->getParent();
       if (std::none_of(SpecificPath.begin(), SpecificPath.end(),
                        [&](const BaseSubobject &BSO) {
                          return BSO.getBase() == OverridingParent;
                        }))
         continue;
-      CurrentOverrides.insert(OI.Method);
+      CurrentOverrides.insert(OverridingMethod);
     }
     OverriderSetTy NewOverrides =
         llvm::set_difference(CurrentOverrides, LastOverrides);
@@ -3583,16 +3590,9 @@ static const FullPathTy *selectBestPath(ASTContext &Context,
           << ConflictMD;
     }
   }
-  // Select the longest path if no path introduces covariant overrides.
-  // Technically, the path we choose should have no effect but longer paths are
-  // nicer to see in -fdump-vtable-layouts.
-  if (!BestPath)
-    BestPath =
-        &*std::max_element(FullPaths.begin(), FullPaths.end(),
-                           [](const FullPathTy &FP1, const FullPathTy &FP2) {
-                             return FP1.size() < FP2.size();
-                           });
-  return BestPath;
+  // Go with the path that introduced the most covariant overrides.  If there is
+  // no such path, pick the first path.
+  return BestPath ? BestPath : &FullPaths.front();
 }
 
 static void computeFullPathsForVFTables(ASTContext &Context,