From 42e31323b6f2448af4c2e7c68f6b50f532ad3a50 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Thu, 11 Oct 2012 23:52:50 +0000 Subject: [PATCH] search for overridden methods with comment when overriding method has none of its own. Factor in Doug's comments. // rdar://12378793 llvm-svn: 165771 --- clang/include/clang/AST/ASTContext.h | 3 +++ clang/include/clang/AST/Comment.h | 33 ++++---------------------- clang/lib/AST/ASTContext.cpp | 30 +++++++++++++---------- clang/lib/AST/Comment.cpp | 6 +++++ clang/lib/AST/CommentSema.cpp | 2 +- clang/test/Index/overriding-method-comments.mm | 2 +- clang/tools/libclang/CXComment.cpp | 4 ++-- 7 files changed, 35 insertions(+), 45 deletions(-) diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index c9e9f4c..1ba2400 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -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; diff --git a/clang/include/clang/AST/Comment.h b/clang/include/clang/AST/Comment.h index e4b3d2c..b946816 100644 --- a/clang/include/clang/AST/Comment.h +++ b/clang/include/clang/AST/Comment.h @@ -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(OverridingDecl)) { - const ParmVarDecl *ParamDecl = OMD->param_begin()[getParamIndex()]; - return ParamDecl->getName(); - } - else if (const FunctionDecl *FD = dyn_cast(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 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 Blocks, DeclInfo *D, - Decl *TD) : + FullComment(llvm::ArrayRef 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(Blocks.end()); + return reinterpret_cast(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 getBlocks() const { return Blocks; } }; - } // end namespace comments } // end namespace clang diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index a58eca6..71764db 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -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(D) || isa(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(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(D)); + comments::FullComment *CFC = cloneFullComment(FC, D); return CFC; } } diff --git a/clang/lib/AST/Comment.cpp b/clang/lib/AST/Comment.cpp index 09f4290..a443b91 100644 --- a/clang/lib/AST/Comment.cpp +++ b/clang/lib/AST/Comment.cpp @@ -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 diff --git a/clang/lib/AST/CommentSema.cpp b/clang/lib/AST/CommentSema.cpp index 59dc6c7..d664bdb 100644 --- a/clang/lib/AST/CommentSema.cpp +++ b/clang/lib/AST/CommentSema.cpp @@ -413,7 +413,7 @@ HTMLEndTagComment *Sema::actOnHTMLEndTag(SourceLocation LocBegin, FullComment *Sema::actOnFullComment( ArrayRef Blocks) { - FullComment *FC = new (Allocator) FullComment(Blocks, ThisDeclInfo, 0); + FullComment *FC = new (Allocator) FullComment(Blocks, ThisDeclInfo); resolveParamCommandIndexes(FC); return FC; } diff --git a/clang/test/Index/overriding-method-comments.mm b/clang/test/Index/overriding-method-comments.mm index ab0e921..ed3e65a 100644 --- a/clang/test/Index/overriding-method-comments.mm +++ b/clang/test/Index/overriding-method-comments.mm @@ -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 diff --git a/clang/tools/libclang/CXComment.cpp b/clang/tools/libclang/CXComment.cpp index 5fac0d8..5fa249a 100644 --- a/clang/tools/libclang/CXComment.cpp +++ b/clang/tools/libclang/CXComment.cpp @@ -671,7 +671,7 @@ void CommentASTToHTMLConverter::visitParamCommandComment( } else Result << "
"; - appendToResultWithHTMLEscaping(C->getParamName(FC->getDeclForCommentLookup())); + appendToResultWithHTMLEscaping(C->getParamName(FC)); Result << "
"; if (C->isParamIndexValid()) { @@ -960,7 +960,7 @@ void CommentASTToXMLConverter::visitBlockCommandComment(const BlockCommandCommen void CommentASTToXMLConverter::visitParamCommandComment(const ParamCommandComment *C) { Result << ""; - appendToResultWithXMLEscaping(C->getParamName(FC->getDeclForCommentLookup())); + appendToResultWithXMLEscaping(C->getParamName(FC)); Result << ""; if (C->isParamIndexValid()) -- 2.7.4