aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ASTContext.cpp
diff options
context:
space:
mode:
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