]> granicus.if.org Git - clang/commitdiff
Clean up the heart of the caching code and miss fewer edge cases.
authorSean Hunt <scshunt@csclub.uwaterloo.ca>
Thu, 23 Jun 2011 00:26:20 +0000 (00:26 +0000)
committerSean Hunt <scshunt@csclub.uwaterloo.ca>
Thu, 23 Jun 2011 00:26:20 +0000 (00:26 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133671 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaLookup.cpp
test/SemaCXX/using-decl-assignment-cache.cpp [new file with mode: 0644]

index 204a697e936095248ef2e713a90e13b36f212895..108346a9d1ccf162b17ab15ec3e12b9fc691d4e6 100644 (file)
@@ -2240,7 +2240,7 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *D,
     ThisTy.addConst();
   if (VolatileThis)
     ThisTy.addVolatile();
-  Expr::Classification ObjectClassification =
+  Expr::Classification Classification =
     (new (Context) OpaqueValueExpr(SourceLocation(), ThisTy,
                                    RValueThis ? VK_RValue : VK_LValue))->
         Classify(Context);
@@ -2256,12 +2256,21 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *D,
   assert((I != E) &&
          "lookup for a constructor or assignment operator was empty");
   for ( ; I != E; ++I) {
-    if ((*I)->isInvalidDecl())
+    Decl *DD = *I;
+    
+    if (UsingShadowDecl *U = dyn_cast<UsingShadowDecl>(D))
+      DD = U->getTargetDecl();
+
+    if (DD->isInvalidDecl())
       continue;
 
-    if (CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(*I)) {
-      AddOverloadCandidate(M, DeclAccessPair::make(M, AS_public), &Arg, NumArgs,
-                           OCS, true);
+    if (CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(DD)) {
+      if (SM == CXXCopyAssignment || SM == CXXMoveAssignment)
+        AddMethodCandidate(M, DeclAccessPair::make(M, AS_public), D, ThisTy,
+                           Classification, &Arg, NumArgs, OCS, true);
+      else
+        AddOverloadCandidate(M, DeclAccessPair::make(M, AS_public), &Arg,
+                             NumArgs, OCS, true);
 
       // Here we're looking for a const parameter to speed up creation of
       // implicit copy methods.
@@ -2274,9 +2283,14 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *D,
           Result->setConstParamMatch(true);
       }
     } else if (FunctionTemplateDecl *Tmpl =
-                 dyn_cast<FunctionTemplateDecl>(*I)) {
-      AddTemplateOverloadCandidate(Tmpl, DeclAccessPair::make(Tmpl, AS_public),
-                                   0, &Arg, NumArgs, OCS, true);
+                 dyn_cast<FunctionTemplateDecl>(DD)) {
+      if (SM == CXXCopyAssignment || SM == CXXMoveAssignment)
+        AddMethodTemplateCandidate(Tmpl, DeclAccessPair::make(Tmpl, AS_public),
+                                   D, 0, ThisTy, Classification, &Arg, NumArgs,
+                                   OCS, true);
+      else
+        AddTemplateOverloadCandidate(Tmpl, DeclAccessPair::make(Tmpl, AS_public),
+                                     0, &Arg, NumArgs, OCS, true);
     }
   }
 
diff --git a/test/SemaCXX/using-decl-assignment-cache.cpp b/test/SemaCXX/using-decl-assignment-cache.cpp
new file mode 100644 (file)
index 0000000..a3a50e5
--- /dev/null
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only %s
+
+struct D;
+struct B {
+  D& operator = (const D&);
+};
+struct D : B {
+  using B::operator=;
+};
+struct F : D {
+};
+
+void H () {
+  F f;
+  f = f;
+}