[cfe-commits] r161722 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/RawCommentList.h lib/AST/ASTContext.cpp lib/AST/RawCommentList.cpp lib/Sema/SemaCodeComplete.cpp test/Index/complete-documentation.cpp tools/libclang/CIndex.cpp
Dmitri Gribenko
gribozavr at gmail.com
Fri Aug 10 17:51:43 PDT 2012
Author: gribozavr
Date: Fri Aug 10 19:51:43 2012
New Revision: 161722
URL: http://llvm.org/viewvc/llvm-project?rev=161722&view=rev
Log:
Attaching comments to declarations: find comment attached to any redeclaration
Not only look for the comment near the declaration itself, but also walk the
redeclaration chain: the previous declaration might have had a documentation
comment.
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/include/clang/AST/RawCommentList.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/RawCommentList.cpp
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
cfe/trunk/test/Index/complete-documentation.cpp
cfe/trunk/tools/libclang/CIndex.cpp
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=161722&r1=161721&r2=161722&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Fri Aug 10 19:51:43 2012
@@ -433,14 +433,57 @@
/// \brief True if comments are already loaded from ExternalASTSource.
mutable bool CommentsLoaded;
- typedef std::pair<const RawComment *, comments::FullComment *>
- RawAndParsedComment;
+ class RawCommentAndCacheFlags {
+ public:
+ enum Kind {
+ /// We searched for a comment attached to the particular declaration, but
+ /// didn't find any.
+ ///
+ /// getRaw() == 0.
+ NoCommentInDecl = 0,
+
+ /// We have found a comment attached to this particular declaration.
+ ///
+ /// getRaw() != 0.
+ FromDecl,
+
+ /// This declaration does not have an attached comment, and we have
+ /// searched the redeclaration chain.
+ ///
+ /// If getRaw() == 0, the whole redeclaration chain does not have any
+ /// comments.
+ ///
+ /// If getRaw() != 0, it is a comment propagated from other
+ /// redeclaration.
+ FromRedecl
+ };
+
+ Kind getKind() const LLVM_READONLY {
+ return Data.getInt();
+ }
+
+ void setKind(Kind K) {
+ Data.setInt(K);
+ }
+
+ const RawComment *getRaw() const LLVM_READONLY {
+ return Data.getPointer();
+ }
+
+ void setRaw(const RawComment *RC) {
+ Data.setPointer(RC);
+ }
+
+ private:
+ llvm::PointerIntPair<const RawComment *, 2, Kind> Data;
+ };
- /// \brief Mapping from declarations to their comments.
+ /// \brief Mapping from declarations to comments attached to any
+ /// redeclaration.
///
/// Raw comments are owned by Comments list. This mapping is populated
/// lazily.
- mutable llvm::DenseMap<const Decl *, RawAndParsedComment> DeclComments;
+ mutable llvm::DenseMap<const Decl *, RawCommentAndCacheFlags> RedeclComments;
/// \brief Return the documentation comment attached to a given declaration,
/// without looking into cache.
@@ -457,7 +500,7 @@
/// \brief Return the documentation comment attached to a given declaration.
/// Returns NULL if no comment is attached.
- const RawComment *getRawCommentForDecl(const Decl *D) const;
+ const RawComment *getRawCommentForAnyRedecl(const Decl *D) const;
/// Return parsed documentation comment attached to a given declaration.
/// Returns NULL if no comment is attached.
Modified: cfe/trunk/include/clang/AST/RawCommentList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RawCommentList.h?rev=161722&r1=161721&r2=161722&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RawCommentList.h (original)
+++ cfe/trunk/include/clang/AST/RawCommentList.h Fri Aug 10 19:51:43 2012
@@ -17,6 +17,11 @@
class ASTContext;
class ASTReader;
+class Decl;
+
+namespace comments {
+ class FullComment;
+} // end namespace comments
class RawComment {
public:
@@ -48,12 +53,18 @@
return Kind == RCK_Merged;
}
+ /// Is this comment attached to any declaration?
bool isAttached() const LLVM_READONLY {
- return IsAttached;
+ return !DeclOrParsedComment.isNull();
}
- void setAttached() {
- IsAttached = true;
+ /// Return the declaration that this comment is attached to.
+ const Decl *getDecl() const;
+
+ /// Set the declaration that this comment is attached to.
+ void setDecl(const Decl *D) {
+ assert(DeclOrParsedComment.isNull());
+ DeclOrParsedComment = D;
}
/// Returns true if it is a comment that should be put after a member:
@@ -107,20 +118,28 @@
return extractBriefText(Context);
}
+ /// Returns a \c FullComment AST node, parsing the comment if needed.
+ comments::FullComment *getParsed(const ASTContext &Context) const {
+ if (comments::FullComment *FC =
+ DeclOrParsedComment.dyn_cast<comments::FullComment *>())
+ return FC;
+
+ return parse(Context);
+ }
+
private:
SourceRange Range;
mutable StringRef RawText;
mutable const char *BriefText;
+ mutable llvm::PointerUnion<const Decl *, comments::FullComment *>
+ DeclOrParsedComment;
mutable bool RawTextValid : 1; ///< True if RawText is valid
mutable bool BriefTextValid : 1; ///< True if BriefText is valid
unsigned Kind : 3;
- /// True if comment is attached to a declaration in ASTContext.
- bool IsAttached : 1;
-
bool IsTrailingComment : 1;
bool IsAlmostTrailingComment : 1;
@@ -133,7 +152,7 @@
RawComment(SourceRange SR, CommentKind K, bool IsTrailingComment,
bool IsAlmostTrailingComment) :
Range(SR), RawTextValid(false), BriefTextValid(false), Kind(K),
- IsAttached(false), IsTrailingComment(IsTrailingComment),
+ IsTrailingComment(IsTrailingComment),
IsAlmostTrailingComment(IsAlmostTrailingComment),
BeginLineValid(false), EndLineValid(false)
{ }
@@ -142,6 +161,8 @@
const char *extractBriefText(const ASTContext &Context) const;
+ comments::FullComment *parse(const ASTContext &Context) const;
+
friend class ASTReader;
};
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=161722&r1=161721&r2=161722&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Aug 10 19:51:43 2012
@@ -13,11 +13,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/CharUnits.h"
-#include "clang/AST/Comment.h"
#include "clang/AST/CommentCommandTraits.h"
-#include "clang/AST/CommentLexer.h"
-#include "clang/AST/CommentSema.h"
-#include "clang/AST/CommentParser.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
@@ -149,6 +145,7 @@
SourceMgr.getLineNumber(DeclLocDecomp.first, DeclLocDecomp.second)
== SourceMgr.getLineNumber(CommentBeginDecomp.first,
CommentBeginDecomp.second)) {
+ (*Comment)->setDecl(D);
return *Comment;
}
}
@@ -188,59 +185,74 @@
if (Text.find_first_of(",;{}#@") != StringRef::npos)
return NULL;
+ (*Comment)->setDecl(D);
return *Comment;
}
-const RawComment *ASTContext::getRawCommentForDecl(const Decl *D) const {
- // Check whether we have cached a comment string for this declaration
- // already.
- llvm::DenseMap<const Decl *, RawAndParsedComment>::iterator Pos
- = DeclComments.find(D);
- if (Pos != DeclComments.end()) {
- RawAndParsedComment C = Pos->second;
- return C.first;
+const RawComment *ASTContext::getRawCommentForAnyRedecl(const Decl *D) const {
+ // Check whether we have cached a comment for this declaration already.
+ {
+ llvm::DenseMap<const Decl *, RawCommentAndCacheFlags>::iterator Pos =
+ RedeclComments.find(D);
+ if (Pos != RedeclComments.end()) {
+ const RawCommentAndCacheFlags &Raw = Pos->second;
+ if (Raw.getKind() != RawCommentAndCacheFlags::NoCommentInDecl)
+ return Raw.getRaw();
+ }
+ }
+
+ // Search for comments attached to declarations in the redeclaration chain.
+ const RawComment *RC = NULL;
+ for (Decl::redecl_iterator I = D->redecls_begin(),
+ E = D->redecls_end();
+ I != E; ++I) {
+ llvm::DenseMap<const Decl *, RawCommentAndCacheFlags>::iterator Pos =
+ RedeclComments.find(*I);
+ if (Pos != RedeclComments.end()) {
+ const RawCommentAndCacheFlags &Raw = Pos->second;
+ if (Raw.getKind() != RawCommentAndCacheFlags::NoCommentInDecl) {
+ RC = Raw.getRaw();
+ break;
+ }
+ } else {
+ RC = getRawCommentForDeclNoCache(*I);
+ RawCommentAndCacheFlags Raw;
+ if (RC) {
+ Raw.setRaw(RC);
+ Raw.setKind(RawCommentAndCacheFlags::FromDecl);
+ } else
+ Raw.setKind(RawCommentAndCacheFlags::NoCommentInDecl);
+ RedeclComments[*I] = Raw;
+ if (RC)
+ break;
+ }
}
- RawComment *RC = getRawCommentForDeclNoCache(D);
// If we found a comment, it should be a documentation comment.
assert(!RC || RC->isDocumentation());
- DeclComments[D] =
- RawAndParsedComment(RC, static_cast<comments::FullComment *>(NULL));
- if (RC)
- RC->setAttached();
+
+ // Update cache for every declaration in the redeclaration chain.
+ RawCommentAndCacheFlags Raw;
+ Raw.setRaw(RC);
+ Raw.setKind(RawCommentAndCacheFlags::FromRedecl);
+
+ for (Decl::redecl_iterator I = D->redecls_begin(),
+ E = D->redecls_end();
+ I != E; ++I) {
+ RawCommentAndCacheFlags &R = RedeclComments[*I];
+ if (R.getKind() == RawCommentAndCacheFlags::NoCommentInDecl)
+ R = Raw;
+ }
+
return RC;
}
comments::FullComment *ASTContext::getCommentForDecl(const Decl *D) const {
- llvm::DenseMap<const Decl *, RawAndParsedComment>::iterator Pos
- = DeclComments.find(D);
- const RawComment *RC;
- if (Pos != DeclComments.end()) {
- RawAndParsedComment C = Pos->second;
- if (comments::FullComment *FC = C.second)
- return FC;
- RC = C.first;
- } else
- RC = getRawCommentForDecl(D);
-
+ const RawComment *RC = getRawCommentForAnyRedecl(D);
if (!RC)
return NULL;
- const StringRef RawText = RC->getRawText(SourceMgr);
- comments::CommandTraits Traits;
- comments::Lexer L(getAllocator(), Traits,
- RC->getSourceRange().getBegin(), comments::CommentOptions(),
- RawText.begin(), RawText.end());
-
- comments::Sema S(getAllocator(), getSourceManager(), getDiagnostics(),
- Traits);
- S.setDecl(D);
- comments::Parser P(L, S, getAllocator(), getSourceManager(),
- getDiagnostics(), Traits);
-
- comments::FullComment *FC = P.parseFullComment();
- DeclComments[D].second = FC;
- return FC;
+ return RC->getParsed(*this);
}
void
Modified: cfe/trunk/lib/AST/RawCommentList.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RawCommentList.cpp?rev=161722&r1=161721&r2=161722&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RawCommentList.cpp (original)
+++ cfe/trunk/lib/AST/RawCommentList.cpp Fri Aug 10 19:51:43 2012
@@ -9,8 +9,11 @@
#include "clang/AST/RawCommentList.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/Comment.h"
#include "clang/AST/CommentLexer.h"
#include "clang/AST/CommentBriefParser.h"
+#include "clang/AST/CommentSema.h"
+#include "clang/AST/CommentParser.h"
#include "clang/AST/CommentCommandTraits.h"
#include "llvm/ADT/STLExtras.h"
@@ -62,7 +65,7 @@
RawComment::RawComment(const SourceManager &SourceMgr, SourceRange SR,
bool Merged) :
Range(SR), RawTextValid(false), BriefTextValid(false),
- IsAttached(false), IsAlmostTrailingComment(false),
+ IsAlmostTrailingComment(false),
BeginLineValid(false), EndLineValid(false) {
// Extract raw comment text, if possible.
if (SR.getBegin() == SR.getEnd() || getRawText(SourceMgr).empty()) {
@@ -84,6 +87,16 @@
}
}
+const Decl *RawComment::getDecl() const {
+ if (DeclOrParsedComment.isNull())
+ return NULL;
+
+ if (const Decl *D = DeclOrParsedComment.dyn_cast<const Decl *>())
+ return D;
+
+ return DeclOrParsedComment.get<comments::FullComment *>()->getDecl();
+}
+
unsigned RawComment::getBeginLine(const SourceManager &SM) const {
if (BeginLineValid)
return BeginLine;
@@ -156,6 +169,25 @@
return BriefTextPtr;
}
+comments::FullComment *RawComment::parse(const ASTContext &Context) const {
+ // Make sure that RawText is valid.
+ getRawText(Context.getSourceManager());
+
+ comments::CommandTraits Traits;
+ comments::Lexer L(Context.getAllocator(), Traits,
+ getSourceRange().getBegin(), comments::CommentOptions(),
+ RawText.begin(), RawText.end());
+ comments::Sema S(Context.getAllocator(), Context.getSourceManager(),
+ Context.getDiagnostics(), Traits);
+ S.setDecl(getDecl());
+ comments::Parser P(L, S, Context.getAllocator(), Context.getSourceManager(),
+ Context.getDiagnostics(), Traits);
+
+ comments::FullComment *FC = P.parseFullComment();
+ DeclOrParsedComment = FC;
+ return FC;
+}
+
namespace {
bool containsOnlyWhitespace(StringRef Str) {
return Str.find_first_not_of(" \t\f\v\r\n") == StringRef::npos;
Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=161722&r1=161721&r2=161722&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Fri Aug 10 19:51:43 2012
@@ -2543,7 +2543,7 @@
if (IncludeBriefComments) {
// Add documentation comment, if it exists.
- if (const RawComment *RC = Ctx.getRawCommentForDecl(ND)) {
+ if (const RawComment *RC = Ctx.getRawCommentForAnyRedecl(ND)) {
Result.addBriefComment(RC->getBriefText(Ctx));
}
}
Modified: cfe/trunk/test/Index/complete-documentation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-documentation.cpp?rev=161722&r1=161721&r2=161722&view=diff
==============================================================================
--- cfe/trunk/test/Index/complete-documentation.cpp (original)
+++ cfe/trunk/test/Index/complete-documentation.cpp Fri Aug 10 19:51:43 2012
@@ -17,17 +17,35 @@
namespace T5 {
}
-void test() {
+struct T6 {
+ /// \brief Fff.
+ void T7();
+
+ /// \brief Ggg.
+ void T8();
+};
+
+void T6::T7() {
+}
+
+void test1() {
T2 t2;
- t2.
+ t2.T4;
+
+ T6 t6;
+ t6.T8();
}
-// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:21:1 %s | FileCheck -check-prefix=CC1 %s
+// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:32:1 %s | FileCheck -check-prefix=CC1 %s
// CHECK-CC1: FunctionDecl:{ResultType void}{TypedText T1}{{.*}}(brief comment: Aaa.)
// CHECK-CC1: ClassDecl:{TypedText T2}{{.*}}(brief comment: Bbb.)
// CHECK-CC1: Namespace:{TypedText T5}{{.*}}(brief comment: Eee.)
-// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:23:6 %s | FileCheck -check-prefix=CC2 %s
+// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:34:6 %s | FileCheck -check-prefix=CC2 %s
// CHECK-CC2: CXXMethod:{ResultType void}{TypedText T3}{{.*}}(brief comment: Ccc.)
// CHECK-CC2: FieldDecl:{ResultType int}{TypedText T4}{{.*}}(brief comment: Ddd.)
+
+// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:37:6 %s | FileCheck -check-prefix=CC3 %s
+// CHECK-CC3: CXXMethod:{ResultType void}{TypedText T7}{LeftParen (}{RightParen )} (34) (parent: StructDecl 'T6')(brief comment: Fff.)
+// CHECK-CC3: CXXMethod:{ResultType void}{TypedText T8}{LeftParen (}{RightParen )} (34) (parent: StructDecl 'T6')(brief comment: Ggg.)
Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=161722&r1=161721&r2=161722&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Fri Aug 10 19:51:43 2012
@@ -5689,7 +5689,7 @@
const Decl *D = getCursorDecl(C);
ASTContext &Context = getCursorContext(C);
- const RawComment *RC = Context.getRawCommentForDecl(D);
+ const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
if (!RC)
return clang_getNullRange();
@@ -5702,7 +5702,7 @@
const Decl *D = getCursorDecl(C);
ASTContext &Context = getCursorContext(C);
- const RawComment *RC = Context.getRawCommentForDecl(D);
+ const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
StringRef();
@@ -5717,7 +5717,7 @@
const Decl *D = getCursorDecl(C);
const ASTContext &Context = getCursorContext(C);
- const RawComment *RC = Context.getRawCommentForDecl(D);
+ const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
if (RC) {
StringRef BriefText = RC->getBriefText(Context);
More information about the cfe-commits
mailing list