diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2012-10-10 18:34:52 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2012-10-10 18:34:52 +0000 |
commit | bf967be66ea8c51b66c61659c23240f762a56dbe (patch) | |
tree | 41a5fab46daa1e64b94cd5460874794072abd2b8 /lib/AST/ASTContext.cpp | |
parent | 4eff6b5d6a5cbb6bd669854a84365aa61d70819e (diff) |
[Doc parsing] This patch searches overridden objc/c++
methods looking for documentation on a particular base
class inherited by any method that overrides the base class.
In case of redeclaration, as when objc method is defined
in the implementation, it also looks up for documentation
in class/class extension being redeclared.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@165643 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ASTContext.cpp')
-rw-r--r-- | lib/AST/ASTContext.cpp | 60 |
1 files changed, 56 insertions, 4 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 874861872a..a58eca6a0a 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -24,6 +24,7 @@ #include "clang/AST/ASTMutationListener.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/Mangle.h" +#include "clang/AST/Comment.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" @@ -355,21 +356,72 @@ const RawComment *ASTContext::getRawCommentForAnyRedecl( return RC; } +static void addRedeclaredMethods(const ObjCMethodDecl *ObjCMethod, + SmallVectorImpl<const NamedDecl *> &Redeclared) { + const DeclContext *DC = ObjCMethod->getDeclContext(); + if (const ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(DC)) { + const ObjCInterfaceDecl *ID = IMD->getClassInterface(); + if (!ID) + return; + // Add redeclared method here. + for (const ObjCCategoryDecl *ClsExtDecl = ID->getFirstClassExtension(); + ClsExtDecl; ClsExtDecl = ClsExtDecl->getNextClassExtension()) { + if (ObjCMethodDecl *RedeclaredMethod = + ClsExtDecl->getMethod(ObjCMethod->getSelector(), + ObjCMethod->isInstanceMethod())) + Redeclared.push_back(RedeclaredMethod); + } + } +} + comments::FullComment *ASTContext::getCommentForDecl( const Decl *D, const Preprocessor *PP) const { D = adjustDeclToTemplate(D); + const Decl *Canonical = D->getCanonicalDecl(); llvm::DenseMap<const Decl *, comments::FullComment *>::iterator Pos = ParsedComments.find(Canonical); - if (Pos != ParsedComments.end()) + + 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. + comments::FullComment *FC = Pos->second; + comments::FullComment *CFC = + new (*this) comments::FullComment(FC->getBlocks(), + FC->getThisDeclInfo(), + const_cast<Decl *>(D)); + return CFC; + } return Pos->second; - + } + const Decl *OriginalDecl; + const RawComment *RC = getRawCommentForAnyRedecl(D, &OriginalDecl); - if (!RC) + if (!RC) { + if (isa<ObjCMethodDecl>(D) || isa<FunctionDecl>(D)) { + SmallVector<const NamedDecl*, 8> overridden; + if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) + addRedeclaredMethods(OMD, overridden); + const_cast<ASTContext *>(this)->getOverriddenMethods(dyn_cast<NamedDecl>(D), + 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)); + return CFC; + } + } + } return NULL; - + } + // If the RawComment was attached to other redeclaration of this Decl, we // should parse the comment in context of that other Decl. This is important // because comments can contain references to parameter names which can be |