aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ASTContext.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2012-10-10 18:34:52 +0000
committerFariborz Jahanian <fjahanian@apple.com>2012-10-10 18:34:52 +0000
commitbf967be66ea8c51b66c61659c23240f762a56dbe (patch)
tree41a5fab46daa1e64b94cd5460874794072abd2b8 /lib/AST/ASTContext.cpp
parent4eff6b5d6a5cbb6bd669854a84365aa61d70819e (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.cpp60
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