Skip to content

Commit f31d8df

Browse files
committed
[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
1 parent d328954 commit f31d8df

File tree

8 files changed

+355
-278
lines changed

8 files changed

+355
-278
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 44 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -729,71 +729,49 @@ class ASTContext : public RefCountedBase<ASTContext> {
729729
/// True if comments are already loaded from ExternalASTSource.
730730
mutable bool CommentsLoaded = false;
731731

732-
class RawCommentAndCacheFlags {
733-
public:
734-
enum Kind {
735-
/// We searched for a comment attached to the particular declaration, but
736-
/// didn't find any.
737-
///
738-
/// getRaw() == 0.
739-
NoCommentInDecl = 0,
740-
741-
/// We have found a comment attached to this particular declaration.
742-
///
743-
/// getRaw() != 0.
744-
FromDecl,
745-
746-
/// This declaration does not have an attached comment, and we have
747-
/// searched the redeclaration chain.
748-
///
749-
/// If getRaw() == 0, the whole redeclaration chain does not have any
750-
/// comments.
751-
///
752-
/// If getRaw() != 0, it is a comment propagated from other
753-
/// redeclaration.
754-
FromRedecl
755-
};
756-
757-
Kind getKind() const LLVM_READONLY {
758-
return Data.getInt();
759-
}
760-
761-
void setKind(Kind K) {
762-
Data.setInt(K);
763-
}
764-
765-
const RawComment *getRaw() const LLVM_READONLY {
766-
return Data.getPointer();
767-
}
768-
769-
void setRaw(const RawComment *RC) {
770-
Data.setPointer(RC);
771-
}
772-
773-
const Decl *getOriginalDecl() const LLVM_READONLY {
774-
return OriginalDecl;
775-
}
776-
777-
void setOriginalDecl(const Decl *Orig) {
778-
OriginalDecl = Orig;
779-
}
780-
781-
private:
782-
llvm::PointerIntPair<const RawComment *, 2, Kind> Data;
783-
const Decl *OriginalDecl;
784-
};
732+
/// Mapping from declaration to directly attached comment.
733+
///
734+
/// Raw comments are owned by Comments list. This mapping is populated
735+
/// lazily.
736+
mutable llvm::DenseMap<const Decl *, const RawComment *> DeclRawComments;
785737

786-
/// Mapping from declarations to comments attached to any
787-
/// redeclaration.
738+
/// Mapping from canonical declaration to the first redeclaration in chain
739+
/// that has a comment attached.
788740
///
789741
/// Raw comments are owned by Comments list. This mapping is populated
790742
/// lazily.
791-
mutable llvm::DenseMap<const Decl *, RawCommentAndCacheFlags> RedeclComments;
743+
mutable llvm::DenseMap<const Decl *, const Decl *> RedeclChainComments;
744+
745+
/// Keeps track of redeclaration chains that don't have any comment attached.
746+
/// Mapping from canonical declaration to redeclaration chain that has no
747+
/// comments attached to any redeclaration. Specifically it's mapping to
748+
/// the last redeclaration we've checked.
749+
///
750+
/// Shall not contain declarations that have comments attached to any
751+
/// redeclaration in their chain.
752+
mutable llvm::DenseMap<const Decl *, const Decl *> CommentlessRedeclChains;
792753

793754
/// Mapping from declarations to parsed comments attached to any
794755
/// redeclaration.
795756
mutable llvm::DenseMap<const Decl *, comments::FullComment *> ParsedComments;
796757

758+
/// Attaches \p Comment to \p OriginalD and to its redeclaration chain
759+
/// and removes the redeclaration chain from the set of commentless chains.
760+
///
761+
/// Don't do anything if a comment has already been attached to \p OriginalD
762+
/// or its redeclaration chain.
763+
void cacheRawCommentForDecl(const Decl &OriginalD,
764+
const RawComment &Comment) const;
765+
766+
/// \returns searches \p CommentsInFile for doc comment for \p D.
767+
///
768+
/// \p RepresentativeLocForDecl is used as a location for searching doc
769+
/// comments. \p CommentsInFile is a mapping offset -> comment of files in the
770+
/// same file where \p RepresentativeLocForDecl is.
771+
RawComment *getRawCommentForDeclNoCacheImpl(
772+
const Decl *D, const SourceLocation RepresentativeLocForDecl,
773+
const std::map<unsigned, RawComment *> &CommentsInFile) const;
774+
797775
/// Return the documentation comment attached to a given declaration,
798776
/// without looking into cache.
799777
RawComment *getRawCommentForDeclNoCache(const Decl *D) const;
@@ -818,6 +796,16 @@ class ASTContext : public RefCountedBase<ASTContext> {
818796
getRawCommentForAnyRedecl(const Decl *D,
819797
const Decl **OriginalDecl = nullptr) const;
820798

799+
/// Searches existing comments for doc comments that should be attached to \p
800+
/// Decls. If any doc comment is found, it is parsed.
801+
///
802+
/// Requirement: All \p Decls are in the same file.
803+
///
804+
/// If the last comment in the file is already attached we assume
805+
/// there are not comments left to be attached to \p Decls.
806+
void attachCommentsToJustParsedDecls(ArrayRef<Decl *> Decls,
807+
const Preprocessor *PP);
808+
821809
/// Return parsed documentation comment attached to a given declaration.
822810
/// Returns nullptr if no comment is attached.
823811
///

clang/include/clang/AST/RawCommentList.h

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@
1010
#define LLVM_CLANG_AST_RAWCOMMENTLIST_H
1111

1212
#include "clang/Basic/CommentOptions.h"
13+
#include "clang/Basic/SourceLocation.h"
1314
#include "clang/Basic/SourceManager.h"
1415
#include "llvm/ADT/ArrayRef.h"
16+
#include "llvm/ADT/DenseMap.h"
17+
#include <map>
1518

1619
namespace clang {
1720

@@ -196,17 +199,24 @@ class RawCommentList {
196199
void addComment(const RawComment &RC, const CommentOptions &CommentOpts,
197200
llvm::BumpPtrAllocator &Allocator);
198201

199-
ArrayRef<RawComment *> getComments() const {
200-
return Comments;
201-
}
202+
/// \returns nullptr in case there are no comments in in \p File.
203+
const std::map<unsigned, RawComment *> *getCommentsInFile(FileID File) const;
204+
205+
bool empty() const;
206+
207+
unsigned getCommentBeginLine(RawComment *C, FileID File,
208+
unsigned Offset) const;
209+
unsigned getCommentEndOffset(RawComment *C) const;
202210

203211
private:
204212
SourceManager &SourceMgr;
205-
std::vector<RawComment *> Comments;
206-
207-
void addDeserializedComments(ArrayRef<RawComment *> DeserializedComments);
213+
// mapping: FileId -> comment begin offset -> comment
214+
llvm::DenseMap<FileID, std::map<unsigned, RawComment *>> OrderedComments;
215+
mutable llvm::DenseMap<RawComment *, unsigned> CommentBeginLine;
216+
mutable llvm::DenseMap<RawComment *, unsigned> CommentEndOffset;
208217

209218
friend class ASTReader;
219+
friend class ASTWriter;
210220
};
211221

212222
} // end namespace clang

0 commit comments

Comments
 (0)