Revert "[ASTImporter] Import the whole redecl chain of functions"

This reverts commit r335480.

llvm-svn: 335491
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 7dfcdeb..f812244 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -71,25 +71,6 @@
 
 namespace clang {
 
-  template <class T>
-  SmallVector<Decl*, 2>
-  getCanonicalForwardRedeclChain(Redeclarable<T>* D) {
-    SmallVector<Decl*, 2> Redecls;
-    for (auto *R : D->getFirstDecl()->redecls()) {
-      if (R != D->getFirstDecl())
-        Redecls.push_back(R);
-    }
-    Redecls.push_back(D->getFirstDecl());
-    std::reverse(Redecls.begin(), Redecls.end());
-    return Redecls;
-  }
-
-  SmallVector<Decl*, 2> getCanonicalForwardRedeclChain(Decl* D) {
-    // Currently only FunctionDecl is supported
-    auto FD = cast<FunctionDecl>(D);
-    return getCanonicalForwardRedeclChain<FunctionDecl>(FD);
-  }
-
   class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, QualType>,
                           public DeclVisitor<ASTNodeImporter, Decl *>,
                           public StmtVisitor<ASTNodeImporter, Stmt *> {
@@ -214,12 +195,6 @@
                                         const InContainerTy &Container,
                                         TemplateArgumentListInfo &Result);
 
-    using TemplateArgsTy = SmallVector<TemplateArgument, 8>;
-    using OptionalTemplateArgsTy = Optional<TemplateArgsTy>;
-    std::tuple<FunctionTemplateDecl *, OptionalTemplateArgsTy>
-    ImportFunctionTemplateWithTemplateArgsFromSpecialization(
-        FunctionDecl *FromFD);
-
     bool ImportTemplateInformation(FunctionDecl *FromFD, FunctionDecl *ToFD);
 
     bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord,
@@ -433,8 +408,6 @@
 
     // Importing overrides.
     void ImportOverrides(CXXMethodDecl *ToMethod, CXXMethodDecl *FromMethod);
-
-    FunctionDecl *FindFunctionTemplateSpecialization(FunctionDecl *FromFD);
   };
 
 template <typename InContainerTy>
@@ -464,25 +437,6 @@
                                         From.arguments(), Result);
 }
 
-std::tuple<FunctionTemplateDecl *, ASTNodeImporter::OptionalTemplateArgsTy>
-ASTNodeImporter::ImportFunctionTemplateWithTemplateArgsFromSpecialization(
-    FunctionDecl *FromFD) {
-  assert(FromFD->getTemplatedKind() ==
-         FunctionDecl::TK_FunctionTemplateSpecialization);
-  auto *FTSInfo = FromFD->getTemplateSpecializationInfo();
-  auto *Template = cast_or_null<FunctionTemplateDecl>(
-      Importer.Import(FTSInfo->getTemplate()));
-
-  // Import template arguments.
-  auto TemplArgs = FTSInfo->TemplateArguments->asArray();
-  TemplateArgsTy ToTemplArgs;
-  if (ImportTemplateArguments(TemplArgs.data(), TemplArgs.size(),
-                              ToTemplArgs)) // Error during import.
-    return std::make_tuple(Template, OptionalTemplateArgsTy());
-
-  return std::make_tuple(Template, ToTemplArgs);
-}
-
 } // namespace clang
 
 //----------------------------------------------------------------------------
@@ -2298,17 +2252,23 @@
   }
 
   case FunctionDecl::TK_FunctionTemplateSpecialization: {
-    FunctionTemplateDecl* Template;
-    OptionalTemplateArgsTy ToTemplArgs;
-    std::tie(Template, ToTemplArgs) =
-        ImportFunctionTemplateWithTemplateArgsFromSpecialization(FromFD);
-    if (!Template || !ToTemplArgs)
+    auto *FTSInfo = FromFD->getTemplateSpecializationInfo();
+    auto *Template = cast_or_null<FunctionTemplateDecl>(
+        Importer.Import(FTSInfo->getTemplate()));
+    if (!Template)
+      return true;
+    TemplateSpecializationKind TSK = FTSInfo->getTemplateSpecializationKind();
+
+    // Import template arguments.
+    auto TemplArgs = FTSInfo->TemplateArguments->asArray();
+    SmallVector<TemplateArgument, 8> ToTemplArgs;
+    if (ImportTemplateArguments(TemplArgs.data(), TemplArgs.size(),
+                                ToTemplArgs))
       return true;
 
     TemplateArgumentList *ToTAList = TemplateArgumentList::CreateCopy(
-          Importer.getToContext(), *ToTemplArgs);
+          Importer.getToContext(), ToTemplArgs);
 
-    auto *FTSInfo = FromFD->getTemplateSpecializationInfo();
     TemplateArgumentListInfo ToTAInfo;
     const auto *FromTAArgsAsWritten = FTSInfo->TemplateArgumentsAsWritten;
     if (FromTAArgsAsWritten)
@@ -2317,7 +2277,6 @@
 
     SourceLocation POI = Importer.Import(FTSInfo->getPointOfInstantiation());
 
-    TemplateSpecializationKind TSK = FTSInfo->getTemplateSpecializationKind();
     ToFD->setFunctionTemplateSpecialization(
         Template, ToTAList, /* InsertPos= */ nullptr,
         TSK, FromTAArgsAsWritten ? &ToTAInfo : nullptr, POI);
@@ -2353,31 +2312,7 @@
   llvm_unreachable("All cases should be covered!");
 }
 
-FunctionDecl *
-ASTNodeImporter::FindFunctionTemplateSpecialization(FunctionDecl *FromFD) {
-  FunctionTemplateDecl* Template;
-  OptionalTemplateArgsTy ToTemplArgs;
-  std::tie(Template, ToTemplArgs) =
-      ImportFunctionTemplateWithTemplateArgsFromSpecialization(FromFD);
-  if (!Template || !ToTemplArgs)
-    return nullptr;
-
-  void *InsertPos = nullptr;
-  auto *FoundSpec = Template->findSpecialization(*ToTemplArgs, InsertPos);
-  return FoundSpec;
-}
-
 Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
-
-  SmallVector<Decl*, 2> Redecls = getCanonicalForwardRedeclChain(D);
-  auto RedeclIt = Redecls.begin();
-  // Import the first part of the decl chain. I.e. import all previous
-  // declarations starting from the canonical decl.
-  for (; RedeclIt != Redecls.end() && *RedeclIt != D; ++RedeclIt)
-    if (!Importer.Import(*RedeclIt))
-      return nullptr;
-  assert(*RedeclIt == D);
-
   // Import the major distinguishing characteristics of this function.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
@@ -2388,27 +2323,13 @@
   if (ToD)
     return ToD;
 
-  const FunctionDecl *FoundByLookup = nullptr;
+  const FunctionDecl *FoundWithoutBody = nullptr;
 
-  // If this is a function template specialization, then try to find the same
-  // existing specialization in the "to" context. The localUncachedLookup
-  // below will not find any specialization, but would find the primary
-  // template; thus, we have to skip normal lookup in case of specializations.
-  // FIXME handle member function templates (TK_MemberSpecialization) similarly?
-  if (D->getTemplatedKind() ==
-      FunctionDecl::TK_FunctionTemplateSpecialization) {
-    if (FunctionDecl *FoundFunction = FindFunctionTemplateSpecialization(D)) {
-      if (D->doesThisDeclarationHaveABody() &&
-          FoundFunction->hasBody())
-        return Importer.Imported(D, FoundFunction);
-      FoundByLookup = FoundFunction;
-    }
-  }
   // Try to find a function in our own ("to") context with the same name, same
   // type, and in the same context as the function we're importing.
-  else if (!LexicalDC->isFunctionOrMethod()) {
+  if (!LexicalDC->isFunctionOrMethod()) {
     SmallVector<NamedDecl *, 4> ConflictingDecls;
-    unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_OrdinaryFriend;
+    unsigned IDNS = Decl::IDNS_Ordinary;
     SmallVector<NamedDecl *, 2> FoundDecls;
     DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
     for (auto *FoundDecl : FoundDecls) {
@@ -2420,11 +2341,15 @@
             D->hasExternalFormalLinkage()) {
           if (Importer.IsStructurallyEquivalent(D->getType(), 
                                                 FoundFunction->getType())) {
-              if (D->doesThisDeclarationHaveABody() &&
-                  FoundFunction->hasBody())
-                return Importer.Imported(D, FoundFunction);
-              FoundByLookup = FoundFunction;
+            // FIXME: Actually try to merge the body and other attributes.
+            const FunctionDecl *FromBodyDecl = nullptr;
+            D->hasBody(FromBodyDecl);
+            if (D == FromBodyDecl && !FoundFunction->hasBody()) {
+              // This function is needed to merge completely.
+              FoundWithoutBody = FoundFunction;
               break;
+            }
+            return Importer.Imported(D, FoundFunction);
           }
 
           // FIXME: Check for overloading more carefully, e.g., by boosting
@@ -2574,9 +2499,9 @@
   }
   ToFunction->setParams(Parameters);
 
-  if (FoundByLookup) {
+  if (FoundWithoutBody) {
     auto *Recent = const_cast<FunctionDecl *>(
-          FoundByLookup->getMostRecentDecl());
+          FoundWithoutBody->getMostRecentDecl());
     ToFunction->setPreviousDecl(Recent);
   }
 
@@ -2598,11 +2523,10 @@
     ToFunction->setType(T);
   }
 
-  if (D->doesThisDeclarationHaveABody()) {
-    if (Stmt *FromBody = D->getBody()) {
-      if (Stmt *ToBody = Importer.Import(FromBody)) {
-        ToFunction->setBody(ToBody);
-      }
+  // Import the body, if any.
+  if (Stmt *FromBody = D->getBody()) {
+    if (Stmt *ToBody = Importer.Import(FromBody)) {
+      ToFunction->setBody(ToBody);
     }
   }
 
@@ -2612,29 +2536,14 @@
   if (ImportTemplateInformation(D, ToFunction))
     return nullptr;
 
-  bool IsFriend = D->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend);
-
-  // TODO Can we generalize this approach to other AST nodes as well?
-  if (D->getDeclContext()->containsDecl(D))
-    DC->addDeclInternal(ToFunction);
-  if (DC != LexicalDC && D->getLexicalDeclContext()->containsDecl(D))
+  // Add this function to the lexical context.
+  // NOTE: If the function is templated declaration, it should be not added into
+  // LexicalDC. But described template is imported during import of
+  // FunctionTemplateDecl (it happens later). So, we use source declaration
+  // to determine if we should add the result function.
+  if (!D->getDescribedFunctionTemplate())
     LexicalDC->addDeclInternal(ToFunction);
 
-  // Friend declaration's lexical context is the befriending class, but the
-  // semantic context is the enclosing scope of the befriending class.
-  // We want the friend functions to be found in the semantic context by lookup.
-  // FIXME should we handle this generically in VisitFriendDecl?
-  // In Other cases when LexicalDC != DC we don't want it to be added,
-  // e.g out-of-class definitions like void B::f() {} .
-  if (LexicalDC != DC && IsFriend) {
-    DC->makeDeclVisibleInContext(ToFunction);
-  }
-
-  // Import the rest of the chain. I.e. import all subsequent declarations.
-  for (++RedeclIt; RedeclIt != Redecls.end(); ++RedeclIt)
-    if (!Importer.Import(*RedeclIt))
-      return nullptr;
-
   if (auto *FromCXXMethod = dyn_cast<CXXMethodDecl>(D))
     ImportOverrides(cast<CXXMethodDecl>(ToFunction), FromCXXMethod);