search for overridden methods with comment when overriding method
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 11 Oct 2012 23:52:50 +0000 (23:52 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 11 Oct 2012 23:52:50 +0000 (23:52 +0000)
has none of its own. Factor in Doug's comments.
// rdar://12378793

llvm-svn: 165771

clang/include/clang/AST/ASTContext.h
clang/include/clang/AST/Comment.h
clang/lib/AST/ASTContext.cpp
clang/lib/AST/Comment.cpp
clang/lib/AST/CommentSema.cpp
clang/test/Index/overriding-method-comments.mm
clang/tools/libclang/CXComment.cpp

index c9e9f4c..1ba2400 100644 (file)
@@ -537,6 +537,9 @@ public:
   /// preprocessor is not available.
   comments::FullComment *getCommentForDecl(const Decl *D,
                                            const Preprocessor *PP) const;
+  
+  comments::FullComment *cloneFullComment(comments::FullComment *FC,
+                                         const Decl *D) const;
 
 private:
   mutable comments::CommandTraits CommentCommandTraits;
index e4b3d2c..b946816 100644 (file)
@@ -27,7 +27,7 @@ class ParmVarDecl;
 class TemplateParameterList;
 
 namespace comments {
-
+class FullComment;
 /// Any part of the comment.
 /// Abstract class.
 class Comment {
@@ -706,19 +706,7 @@ public:
     return getNumArgs() > 0;
   }
 
-  StringRef getParamName(const Decl *OverridingDecl) const {
-    if (OverridingDecl && isParamIndexValid()) {
-      if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(OverridingDecl)) {
-        const ParmVarDecl *ParamDecl = OMD->param_begin()[getParamIndex()];
-        return ParamDecl->getName();
-      }
-      else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(OverridingDecl)) {
-        const ParmVarDecl *ParamDecl = FD->param_begin()[getParamIndex()];
-        return ParamDecl->getName();
-      }
-    }
-    return Args[0].Text;
-  }
+  StringRef getParamName(comments::FullComment *FC) const;
 
   SourceRange getParamNameRange() const {
     return Args[0].Range;
@@ -1017,18 +1005,12 @@ struct DeclInfo {
 /// A full comment attached to a declaration, contains block content.
 class FullComment : public Comment {
   llvm::ArrayRef<BlockContentComment *> Blocks;
-
   DeclInfo *ThisDeclInfo;
-  /// Declaration that a comment is being looked for. This declaration and
-  /// CommentDecl in ThisDeclInfo are generally the same. But they could be
-  /// different when ThisDecl does not have comment and uses CommentDecl's comment.
-  const Decl *ThisDecl;
 
 public:
-  FullComment(llvm::ArrayRef<BlockContentComment *> Blocks, DeclInfo *D,
-              Decl *TD) :
+  FullComment(llvm::ArrayRef<BlockContentComment *> Blocks, DeclInfo *D) :
       Comment(FullCommentKind, SourceLocation(), SourceLocation()),
-      Blocks(Blocks), ThisDeclInfo(D), ThisDecl(TD) {
+      Blocks(Blocks), ThisDeclInfo(D) {
     if (Blocks.empty())
       return;
 
@@ -1046,16 +1028,12 @@ public:
   }
 
   child_iterator child_end() const {
-    return reinterpret_cast<child_iterator>(Blocks.end());
+    return reinterpret_cast<child_iterator>(Blocks.end()); 
   }
 
   const Decl *getDecl() const LLVM_READONLY {
     return ThisDeclInfo->CommentDecl;
   }
-
-  const Decl *getDeclForCommentLookup() const LLVM_READONLY {
-    return ThisDecl;
-  }
   
   const DeclInfo *getDeclInfo() const LLVM_READONLY {
     if (!ThisDeclInfo->IsFilled)
@@ -1070,7 +1048,6 @@ public:
   llvm::ArrayRef<BlockContentComment *> getBlocks() const { return Blocks; }
   
 };
-  
 } // end namespace comments
 } // end namespace clang
 
index a58eca6..71764db 100644 (file)
@@ -374,6 +374,20 @@ static void addRedeclaredMethods(const ObjCMethodDecl *ObjCMethod,
   }
 }
 
+comments::FullComment *ASTContext::cloneFullComment(comments::FullComment *FC,
+                                                    const Decl *D) const {
+  comments::DeclInfo *ThisDeclInfo = new (*this) comments::DeclInfo;
+  ThisDeclInfo->CommentDecl = D;
+  ThisDeclInfo->IsFilled = false;
+  ThisDeclInfo->fill();
+  ThisDeclInfo->CommentDecl = FC->getDecl();
+  comments::FullComment *CFC =
+    new (*this) comments::FullComment(FC->getBlocks(),
+                                      ThisDeclInfo);
+  return CFC;
+  
+}
+
 comments::FullComment *ASTContext::getCommentForDecl(
                                               const Decl *D,
                                               const Preprocessor *PP) const {
@@ -384,16 +398,9 @@ comments::FullComment *ASTContext::getCommentForDecl(
       ParsedComments.find(Canonical);
   
   if (Pos != ParsedComments.end()) {
-    if (Canonical != D &&
-        (isa<ObjCMethodDecl>(D) || isa<FunctionDecl>(D))) {
-      // case of method being redeclaration of the canonical, not
-      // overriding it; i.e. method in implementation, canonical in
-      // interface. Or, out-of-line cxx-method definition. 
+    if (Canonical != D) {
       comments::FullComment *FC = Pos->second;
-      comments::FullComment *CFC =
-        new (*this) comments::FullComment(FC->getBlocks(),
-                                          FC->getThisDeclInfo(),
-                                          const_cast<Decl *>(D));
+      comments::FullComment *CFC = cloneFullComment(FC, D);
       return CFC;
     }
     return Pos->second;
@@ -411,10 +418,7 @@ comments::FullComment *ASTContext::getCommentForDecl(
                                                            overridden);
       for (unsigned i = 0, e = overridden.size(); i < e; i++) {
         if (comments::FullComment *FC = getCommentForDecl(overridden[i], PP)) {
-          comments::FullComment *CFC =
-            new (*this) comments::FullComment(FC->getBlocks(),
-                                              FC->getThisDeclInfo(),
-                                              const_cast<Decl *>(D));
+          comments::FullComment *CFC = cloneFullComment(FC, D);
           return CFC;
         }
       }
index 09f4290..a443b91 100644 (file)
@@ -304,6 +304,12 @@ void DeclInfo::fill() {
   IsFilled = true;
 }
 
+StringRef ParamCommandComment::getParamName(comments::FullComment *FC) const {
+  if (FC && isParamIndexValid())
+    return FC->getThisDeclInfo()->ParamVars[getParamIndex()]->getName();
+  return Args[0].Text;
+}
+
 } // end namespace comments
 } // end namespace clang
 
index 59dc6c7..d664bdb 100644 (file)
@@ -413,7 +413,7 @@ HTMLEndTagComment *Sema::actOnHTMLEndTag(SourceLocation LocBegin,
 
 FullComment *Sema::actOnFullComment(
                               ArrayRef<BlockContentComment *> Blocks) {
-  FullComment *FC = new (Allocator) FullComment(Blocks, ThisDeclInfo, 0);
+  FullComment *FC = new (Allocator) FullComment(Blocks, ThisDeclInfo);
   resolveParamCommandIndexes(FC);
   return FC;
 }
index ab0e921..ed3e65a 100644 (file)
@@ -2,7 +2,7 @@
 // RUN: mkdir %t
 // RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s > %t/out
 // RUN: FileCheck %s < %t/out
-// rdar://12378793
+// Test to search overridden methods for documentation when overriding method has none. rdar://12378793
 
 // Ensure that XML we generate is not invalid.
 // RUN: FileCheck %s -check-prefix=WRONG < %t/out
index 5fac0d8..5fa249a 100644 (file)
@@ -671,7 +671,7 @@ void CommentASTToHTMLConverter::visitParamCommandComment(
   } else
     Result << "<dt class=\"param-name-index-invalid\">";
 
-  appendToResultWithHTMLEscaping(C->getParamName(FC->getDeclForCommentLookup()));
+  appendToResultWithHTMLEscaping(C->getParamName(FC));
   Result << "</dt>";
 
   if (C->isParamIndexValid()) {
@@ -960,7 +960,7 @@ void CommentASTToXMLConverter::visitBlockCommandComment(const BlockCommandCommen
 
 void CommentASTToXMLConverter::visitParamCommandComment(const ParamCommandComment *C) {
   Result << "<Parameter><Name>";
-  appendToResultWithXMLEscaping(C->getParamName(FC->getDeclForCommentLookup()));
+  appendToResultWithXMLEscaping(C->getParamName(FC));
   Result << "</Name>";
 
   if (C->isParamIndexValid())