diff options
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 |