Skip to content

Commit fb3711a

Browse files
committed
[clangd] Collect comments from function definitions into the index
This is useful with projects that put their (doxygen) comments at the implementation site, rather than the header.
1 parent 743946e commit fb3711a

File tree

3 files changed

+39
-5
lines changed

3 files changed

+39
-5
lines changed

clang-tools-extra/clangd/index/Symbol.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,11 @@ struct Symbol {
145145
ImplementationDetail = 1 << 2,
146146
/// Symbol is visible to other files (not e.g. a static helper function).
147147
VisibleOutsideFile = 1 << 3,
148+
/// Symbol has an attached documentation comment.
149+
HasDocComment = 1 << 4
148150
};
149-
150151
SymbolFlag Flags = SymbolFlag::None;
152+
151153
/// FIXME: also add deprecation message and fixit?
152154
};
153155

clang-tools-extra/clangd/index/SymbolCollector.cpp

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,15 +1020,17 @@ const Symbol *SymbolCollector::addDeclaration(const NamedDecl &ND, SymbolID ID,
10201020
*ASTCtx, *PP, CodeCompletionContext::CCC_Symbol, *CompletionAllocator,
10211021
*CompletionTUInfo,
10221022
/*IncludeBriefComments*/ false);
1023-
std::string Documentation =
1024-
formatDocumentation(*CCS, getDocComment(Ctx, SymbolCompletion,
1025-
/*CommentsFromHeaders=*/true));
1023+
std::string DocComment = getDocComment(Ctx, SymbolCompletion,
1024+
/*CommentsFromHeaders=*/true);
1025+
std::string Documentation = formatDocumentation(*CCS, DocComment);
10261026
if (!(S.Flags & Symbol::IndexedForCodeCompletion)) {
10271027
if (Opts.StoreAllDocumentation)
10281028
S.Documentation = Documentation;
10291029
Symbols.insert(S);
10301030
return Symbols.find(S.ID);
10311031
}
1032+
if (!DocComment.empty())
1033+
S.Flags |= Symbol::HasDocComment;
10321034
S.Documentation = Documentation;
10331035
std::string Signature;
10341036
std::string SnippetSuffix;
@@ -1069,6 +1071,27 @@ void SymbolCollector::addDefinition(const NamedDecl &ND,
10691071
Symbol S = DeclSym;
10701072
// FIXME: use the result to filter out symbols.
10711073
S.Definition = *DefLoc;
1074+
1075+
std::string DocComment;
1076+
std::string Documentation;
1077+
if (!(S.Flags & Symbol::HasDocComment) &&
1078+
(llvm::isa<FunctionDecl>(ND) || llvm::isa<CXXMethodDecl>(ND))) {
1079+
CodeCompletionResult SymbolCompletion(&getTemplateOrThis(ND), 0);
1080+
const auto *CCS = SymbolCompletion.CreateCodeCompletionString(
1081+
*ASTCtx, *PP, CodeCompletionContext::CCC_Symbol, *CompletionAllocator,
1082+
*CompletionTUInfo,
1083+
/*IncludeBriefComments*/ false);
1084+
DocComment = getDocComment(ND.getASTContext(), SymbolCompletion,
1085+
/*CommentsFromHeaders=*/true);
1086+
if (!S.Documentation.empty())
1087+
Documentation = S.Documentation.str() + '\n' + DocComment;
1088+
else
1089+
Documentation = formatDocumentation(*CCS, DocComment);
1090+
if (!DocComment.empty())
1091+
S.Flags |= Symbol::HasDocComment;
1092+
S.Documentation = Documentation;
1093+
}
1094+
10721095
Symbols.insert(S);
10731096
}
10741097

clang/lib/AST/ASTContext.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,17 @@ const RawComment *ASTContext::getRawCommentForAnyRedecl(
448448
if (LastCheckedRedecl) {
449449
if (LastCheckedRedecl == Redecl) {
450450
LastCheckedRedecl = nullptr;
451+
continue;
452+
}
453+
if (auto F = llvm::dyn_cast<FunctionDecl>(Redecl)) {
454+
if (!F->isThisDeclarationADefinition())
455+
continue;
456+
} else if (auto M = llvm::dyn_cast<CXXMethodDecl>(Redecl)) {
457+
if (!M->isThisDeclarationADefinition())
458+
continue;
459+
} else {
460+
continue;
451461
}
452-
continue;
453462
}
454463
const RawComment *RedeclComment = getRawCommentForDeclNoCache(Redecl);
455464
if (RedeclComment) {

0 commit comments

Comments
 (0)