[clang] Refactor doc comments to Decls attribution

- Create ASTContext::attachCommentsToJustParsedDecls so we don't have to load external comments in Sema when trying to attach existing comments to just parsed Decls.
- Keep comments ordered and cache their decomposed location - faster SourceLoc-based searching.
- Optimize work with redeclarations.
- Keep one comment per redeclaration chain (represented by canonical Decl) instead of comment per redeclaration.
- For redeclaration chains with no comment attached keep just the last declaration in chain that had no comment instead of every comment-less redeclaration.

Differential Revision: https://reviews.llvm.org/D65301

llvm-svn: 368732
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 9a1ebff..0981adc 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -3266,15 +3266,17 @@
   auto _ = llvm::make_scope_exit([this] { Stream.ExitBlock(); });
   if (!PP->getPreprocessorOpts().WriteCommentListToPCH)
     return;
-  ArrayRef<RawComment *> RawComments = Context->Comments.getComments();
   RecordData Record;
-  for (const auto *I : RawComments) {
-    Record.clear();
-    AddSourceRange(I->getSourceRange(), Record);
-    Record.push_back(I->getKind());
-    Record.push_back(I->isTrailingComment());
-    Record.push_back(I->isAlmostTrailingComment());
-    Stream.EmitRecord(COMMENTS_RAW_COMMENT, Record);
+  for (const auto &FO : Context->Comments.OrderedComments) {
+    for (const auto &OC : FO.second) {
+      const RawComment *I = OC.second;
+      Record.clear();
+      AddSourceRange(I->getSourceRange(), Record);
+      Record.push_back(I->getKind());
+      Record.push_back(I->isTrailingComment());
+      Record.push_back(I->isAlmostTrailingComment());
+      Stream.EmitRecord(COMMENTS_RAW_COMMENT, Record);
+    }
   }
 }