diff --git a/clang-tools-extra/clangd/index/Symbol.h b/clang-tools-extra/clangd/index/Symbol.h index 1aa5265299231..62c47ddfc5758 100644 --- a/clang-tools-extra/clangd/index/Symbol.h +++ b/clang-tools-extra/clangd/index/Symbol.h @@ -145,9 +145,11 @@ struct Symbol { ImplementationDetail = 1 << 2, /// Symbol is visible to other files (not e.g. a static helper function). VisibleOutsideFile = 1 << 3, + /// Symbol has an attached documentation comment. + HasDocComment = 1 << 4 }; - SymbolFlag Flags = SymbolFlag::None; + /// FIXME: also add deprecation message and fixit? }; diff --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp b/clang-tools-extra/clangd/index/SymbolCollector.cpp index bf838e53f2a21..d071228455836 100644 --- a/clang-tools-extra/clangd/index/SymbolCollector.cpp +++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp @@ -1020,15 +1020,17 @@ const Symbol *SymbolCollector::addDeclaration(const NamedDecl &ND, SymbolID ID, *ASTCtx, *PP, CodeCompletionContext::CCC_Symbol, *CompletionAllocator, *CompletionTUInfo, /*IncludeBriefComments*/ false); - std::string Documentation = - formatDocumentation(*CCS, getDocComment(Ctx, SymbolCompletion, - /*CommentsFromHeaders=*/true)); + std::string DocComment = getDocComment(Ctx, SymbolCompletion, + /*CommentsFromHeaders=*/true); + std::string Documentation = formatDocumentation(*CCS, DocComment); if (!(S.Flags & Symbol::IndexedForCodeCompletion)) { if (Opts.StoreAllDocumentation) S.Documentation = Documentation; Symbols.insert(S); return Symbols.find(S.ID); } + if (!DocComment.empty()) + S.Flags |= Symbol::HasDocComment; S.Documentation = Documentation; std::string Signature; std::string SnippetSuffix; @@ -1069,6 +1071,27 @@ void SymbolCollector::addDefinition(const NamedDecl &ND, Symbol S = DeclSym; // FIXME: use the result to filter out symbols. S.Definition = *DefLoc; + + std::string DocComment; + std::string Documentation; + if (!(S.Flags & Symbol::HasDocComment) && + (llvm::isa(ND) || llvm::isa(ND))) { + CodeCompletionResult SymbolCompletion(&getTemplateOrThis(ND), 0); + const auto *CCS = SymbolCompletion.CreateCodeCompletionString( + *ASTCtx, *PP, CodeCompletionContext::CCC_Symbol, *CompletionAllocator, + *CompletionTUInfo, + /*IncludeBriefComments*/ false); + DocComment = getDocComment(ND.getASTContext(), SymbolCompletion, + /*CommentsFromHeaders=*/true); + if (!S.Documentation.empty()) + Documentation = S.Documentation.str() + '\n' + DocComment; + else + Documentation = formatDocumentation(*CCS, DocComment); + if (!DocComment.empty()) + S.Flags |= Symbol::HasDocComment; + S.Documentation = Documentation; + } + Symbols.insert(S); } diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index f7c9e4521b5f1..aa06a1ada4ba7 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -448,8 +448,17 @@ const RawComment *ASTContext::getRawCommentForAnyRedecl( if (LastCheckedRedecl) { if (LastCheckedRedecl == Redecl) { LastCheckedRedecl = nullptr; + continue; + } + if (auto F = llvm::dyn_cast(Redecl)) { + if (!F->isThisDeclarationADefinition()) + continue; + } else if (auto M = llvm::dyn_cast(Redecl)) { + if (!M->isThisDeclarationADefinition()) + continue; + } else { + continue; } - continue; } const RawComment *RedeclComment = getRawCommentForDeclNoCache(Redecl); if (RedeclComment) {