Attaching comments to redeclarations: fix wrong assumptions
The reason for the recent fallout for "attaching comments to any redeclaration"
change are two false assumptions:
(1) a RawComment is attached to a single decl (not true for 'typedef struct X *Y'
where we want the comment to be attached to both X and Y);
(2) the whole redeclaration chain has only a single comment (obviously false, the
user can put a separate comment for each redeclaration).
To fix (1) I revert the part of the recent change where a 'Decl*' member was
introduced to RawComment. Now ASTContext has a separate DenseMap for mapping
'Decl*' to 'FullComment*'.
To fix (2) I just removed the test with this assumption. We might not parse
every comment in redecl chain if we already parsed at least one.
llvm-svn: 161878
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index ad48dff..ae531e1 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -66,6 +66,12 @@
if (D->isImplicit())
return NULL;
+ // User can not attach documentation to implicit instantiations.
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
+ return NULL;
+ }
+
// TODO: handle comments for function parameters properly.
if (isa<ParmVarDecl>(D))
return NULL;
@@ -145,7 +151,6 @@
SourceMgr.getLineNumber(DeclLocDecomp.first, DeclLocDecomp.second)
== SourceMgr.getLineNumber(CommentBeginDecomp.first,
CommentBeginDecomp.second)) {
- (*Comment)->setDecl(D);
return *Comment;
}
}
@@ -185,13 +190,13 @@
if (Text.find_first_of(",;{}#@") != StringRef::npos)
return NULL;
- (*Comment)->setDecl(D);
return *Comment;
}
-const RawComment *ASTContext::getRawCommentForAnyRedecl(const Decl *D) const {
- // If we have a 'templated' declaration for a template, adjust 'D' to
- // refer to the actual template.
+namespace {
+/// If we have a 'templated' declaration for a template, adjust 'D' to
+/// refer to the actual template.
+const Decl *adjustDeclToTemplate(const Decl *D) {
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
if (const FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate())
D = FTD;
@@ -200,6 +205,12 @@
D = CTD;
}
// FIXME: Alias templates?
+ return D;
+}
+} // unnamed namespace
+
+const RawComment *ASTContext::getRawCommentForAnyRedecl(const Decl *D) const {
+ D = adjustDeclToTemplate(D);
// Check whether we have cached a comment for this declaration already.
{
@@ -259,11 +270,20 @@
}
comments::FullComment *ASTContext::getCommentForDecl(const Decl *D) const {
+ D = adjustDeclToTemplate(D);
+ const Decl *Canonical = D->getCanonicalDecl();
+ llvm::DenseMap<const Decl *, comments::FullComment *>::iterator Pos =
+ ParsedComments.find(Canonical);
+ if (Pos != ParsedComments.end())
+ return Pos->second;
+
const RawComment *RC = getRawCommentForAnyRedecl(D);
if (!RC)
return NULL;
- return RC->getParsed(*this);
+ comments::FullComment *FC = RC->parse(*this, D);
+ ParsedComments[Canonical] = FC;
+ return FC;
}
void