Add support for out-of-line definitions of conversion functions and member operators

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61442 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index bb0dd4d..1f6cbc4 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1186,8 +1186,7 @@
       } else {
         InvalidDecl = InvalidDecl || CheckConversionDeclarator(D, R, SC);
 
-        NewFD = CXXConversionDecl::Create(Context, 
-                                          cast<CXXRecordDecl>(DC),
+        NewFD = CXXConversionDecl::Create(Context, cast<CXXRecordDecl>(DC),
                                           D.getIdentifierLoc(), Name, R,
                                           isInline, isExplicit);
         
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 4837336..5ba2850 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1230,21 +1230,6 @@
 
   // Make sure we aren't redeclaring the conversion function.
   QualType ConvType = Context.getCanonicalType(Conversion->getConversionType());
-  OverloadedFunctionDecl *Conversions = ClassDecl->getConversionFunctions();
-  for (OverloadedFunctionDecl::function_iterator Func 
-         = Conversions->function_begin();
-       Func != Conversions->function_end(); ++Func) {
-    CXXConversionDecl *OtherConv = cast<CXXConversionDecl>(*Func);
-    if (ConvType == Context.getCanonicalType(OtherConv->getConversionType())) {
-      Diag(Conversion->getLocation(), diag::err_conv_function_redeclared);
-      Diag(OtherConv->getLocation(),
-           OtherConv->isThisDeclarationADefinition()?
-              diag::note_previous_definition
-            : diag::note_previous_declaration);
-      Conversion->setInvalidDecl();
-      return (DeclTy *)Conversion;      
-    }
-  }
 
   // C++ [class.conv.fct]p1:
   //   [...] A conversion function is never used to convert a
@@ -1272,7 +1257,20 @@
       << ClassType << ConvType;
   }
 
-  ClassDecl->addConversionFunction(Context, Conversion);
+  if (Conversion->getPreviousDeclaration()) {
+    OverloadedFunctionDecl *Conversions = ClassDecl->getConversionFunctions();
+    for (OverloadedFunctionDecl::function_iterator 
+           Conv = Conversions->function_begin(),
+           ConvEnd = Conversions->function_end();
+         Conv != ConvEnd; ++Conv) {
+      if (*Conv == Conversion->getPreviousDeclaration()) {
+        *Conv = Conversion;
+        return (DeclTy *)Conversion;
+      }
+    }
+    assert(Conversion->isInvalidDecl() && "Conversion should not get here.");
+  } else 
+    ClassDecl->addConversionFunction(Context, Conversion);
 
   return (DeclTy *)Conversion;
 }