dlj created this revision.
dlj added a reviewer: rsmith.
dlj added a project: clang.
Herald added a subscriber: sanjoy.

This changes how RawComments are looked up, so that they can be added to the
cache or updated independently of parsing.

Loosely, the comment cache has two conceptually separate separate layers:

  RedeclComments - maps Decls to RawComments, which may have come from the Decl
  that is the key (a 'local' comment), or one of its redeclarations. The cache
  entry can keep track of whether the comment is local or a redecl.
  
  ParsedComments - maps Decls to FullComments, which may have come from the Decl
  that is the key, one of its redecls, or one of its bases (a base class, and
  overridden class method, ObjC interface, typedef, etc.).

This patch factors out the logic that maintains the lower RedeclComments portion
of the cache.


Repository:
  rC Clang

https://reviews.llvm.org/D44122

Files:
  include/clang/AST/ASTContext.h
  lib/AST/ASTContext.cpp

Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -379,53 +379,54 @@
   return D;
 }
 
-const RawComment *ASTContext::getRawCommentForAnyRedecl(
-                                                const Decl *D,
-                                                const Decl **OriginalDecl) const {
+ASTContext::RawCommentAndCacheFlags &
+ASTContext::getRawCommentForDeclCached(const Decl *D) const {
   D = adjustDeclToTemplate(D);
 
   // 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) {
-        if (OriginalDecl)
-          *OriginalDecl = Raw.getOriginalDecl();
-        return Raw.getRaw();
-      }
-    }
+  auto ItInserted = RedeclComments.insert({D, RawCommentAndCacheFlags()});
+  RawCommentAndCacheFlags& Raw = ItInserted.first->second;
+  if (!ItInserted.second)
+    return Raw;
+
+  // 'Raw' is a new entry in the cache. Populate it with any comments for the
+  // local definition.
+  Raw.setOriginalDecl(D);
+  const RawComment *RC = getRawCommentForDeclNoCache(D);
+  if (!RC) {
+    Raw.setKind(RawCommentAndCacheFlags::NoCommentInDecl);
+    return Raw;
+  }
+
+  // If we found a comment, it should be a documentation comment.
+  assert(RC->isDocumentation() || LangOpts.CommentOpts.ParseAllComments);
+  // Call order swapped to work around ICE in VS2015 RTM (Release Win32)
+  // https://connect.microsoft.com/VisualStudio/feedback/details/1741530
+  Raw.setKind(RawCommentAndCacheFlags::FromDecl);
+  Raw.setRaw(RC);
+  return Raw;
+}
+
+const RawComment *
+ASTContext::getRawCommentForAnyRedecl(const Decl *D,
+                                      const Decl **OriginalDecl) const {
+  RawCommentAndCacheFlags &OrigRaw = getRawCommentForDeclCached(D);
+  if (OrigRaw.getKind() != RawCommentAndCacheFlags::NoCommentInDecl) {
+    if (OriginalDecl)
+      *OriginalDecl = OrigRaw.getOriginalDecl();
+    return OrigRaw.getRaw();
   }
 
   // Search for comments attached to declarations in the redeclaration chain.
   const RawComment *RC = nullptr;
+
   const Decl *OriginalDeclForRC = nullptr;
   for (auto I : D->redecls()) {
-    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();
-        OriginalDeclForRC = Raw.getOriginalDecl();
-        break;
-      }
-    } else {
-      RC = getRawCommentForDeclNoCache(I);
-      OriginalDeclForRC = I;
-      RawCommentAndCacheFlags Raw;
-      if (RC) {
-        // Call order swapped to work around ICE in VS2015 RTM (Release Win32)
-        // https://connect.microsoft.com/VisualStudio/feedback/details/1741530
-        Raw.setKind(RawCommentAndCacheFlags::FromDecl);
-        Raw.setRaw(RC);
-      } else
-        Raw.setKind(RawCommentAndCacheFlags::NoCommentInDecl);
-      Raw.setOriginalDecl(I);
-      RedeclComments[I] = Raw;
-      if (RC)
-        break;
+    RawCommentAndCacheFlags &Raw = getRawCommentForDeclCached(I);
+    if (Raw.getKind() != RawCommentAndCacheFlags::NoCommentInDecl) {
+      RC = Raw.getRaw();
+      OriginalDeclForRC = Raw.getOriginalDecl();
+      break;
     }
   }
 
@@ -487,9 +488,9 @@
   return RC ? RC->parse(*this, nullptr, D) : nullptr;
 }
 
-comments::FullComment *ASTContext::getCommentForDecl(
-                                              const Decl *D,
-                                              const Preprocessor *PP) const {
+comments::FullComment *
+ASTContext::getCommentForDecl(const Decl *D,
+                                    const Preprocessor *PP) const {
   if (D->isInvalidDecl())
     return nullptr;
   D = adjustDeclToTemplate(D);
Index: include/clang/AST/ASTContext.h
===================================================================
--- include/clang/AST/ASTContext.h
+++ include/clang/AST/ASTContext.h
@@ -776,6 +776,10 @@
   /// without looking into cache.
   RawComment *getRawCommentForDeclNoCache(const Decl *D) const;
 
+  /// \brief Return the documentation comment attached to a given declaration,
+  /// adding it to the cache if necessary.
+  RawCommentAndCacheFlags &getRawCommentForDeclCached(const Decl *D) const;
+
 public:
   RawCommentList &getRawCommentList() {
     return Comments;
@@ -796,7 +800,8 @@
   getRawCommentForAnyRedecl(const Decl *D,
                             const Decl **OriginalDecl = nullptr) const;
 
-  /// Return parsed documentation comment attached to a given declaration.
+  /// Return parsed documentation comment attached to a given declaration, its
+  /// redeclarations, or its bases.
   /// Returns nullptr if no comment is attached.
   ///
   /// \param PP the Preprocessor used with this TU.  Could be nullptr if
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to