diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 60 | ||||
-rw-r--r-- | lib/AST/Comment.cpp | 20 | ||||
-rw-r--r-- | lib/AST/CommentDumper.cpp | 2 | ||||
-rw-r--r-- | lib/AST/CommentSema.cpp | 12 | ||||
-rw-r--r-- | lib/AST/DeclObjC.cpp | 2 |
5 files changed, 75 insertions, 21 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 diff --git a/lib/AST/Comment.cpp b/lib/AST/Comment.cpp index 4336885d39..09f4290f1b 100644 --- a/lib/AST/Comment.cpp +++ b/lib/AST/Comment.cpp @@ -151,13 +151,13 @@ void DeclInfo::fill() { ParamVars = ArrayRef<const ParmVarDecl *>(); TemplateParameters = NULL; - if (!ThisDecl) { + if (!CommentDecl) { // If there is no declaration, the defaults is our only guess. IsFilled = true; return; } - Decl::Kind K = ThisDecl->getKind(); + Decl::Kind K = CommentDecl->getKind(); switch (K) { default: // Defaults are should be good for declarations we don't handle explicitly. @@ -167,7 +167,7 @@ void DeclInfo::fill() { case Decl::CXXConstructor: case Decl::CXXDestructor: case Decl::CXXConversion: { - const FunctionDecl *FD = cast<FunctionDecl>(ThisDecl); + const FunctionDecl *FD = cast<FunctionDecl>(CommentDecl); Kind = FunctionKind; ParamVars = ArrayRef<const ParmVarDecl *>(FD->param_begin(), FD->getNumParams()); @@ -181,14 +181,14 @@ void DeclInfo::fill() { if (K == Decl::CXXMethod || K == Decl::CXXConstructor || K == Decl::CXXDestructor || K == Decl::CXXConversion) { - const CXXMethodDecl *MD = cast<CXXMethodDecl>(ThisDecl); + const CXXMethodDecl *MD = cast<CXXMethodDecl>(CommentDecl); IsInstanceMethod = MD->isInstance(); IsClassMethod = !IsInstanceMethod; } break; } case Decl::ObjCMethod: { - const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(ThisDecl); + const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(CommentDecl); Kind = FunctionKind; ParamVars = ArrayRef<const ParmVarDecl *>(MD->param_begin(), MD->param_size()); @@ -199,7 +199,7 @@ void DeclInfo::fill() { break; } case Decl::FunctionTemplate: { - const FunctionTemplateDecl *FTD = cast<FunctionTemplateDecl>(ThisDecl); + const FunctionTemplateDecl *FTD = cast<FunctionTemplateDecl>(CommentDecl); Kind = FunctionKind; TemplateKind = Template; const FunctionDecl *FD = FTD->getTemplatedDecl(); @@ -210,7 +210,7 @@ void DeclInfo::fill() { break; } case Decl::ClassTemplate: { - const ClassTemplateDecl *CTD = cast<ClassTemplateDecl>(ThisDecl); + const ClassTemplateDecl *CTD = cast<ClassTemplateDecl>(CommentDecl); Kind = ClassKind; TemplateKind = Template; TemplateParameters = CTD->getTemplateParameters(); @@ -218,7 +218,7 @@ void DeclInfo::fill() { } case Decl::ClassTemplatePartialSpecialization: { const ClassTemplatePartialSpecializationDecl *CTPSD = - cast<ClassTemplatePartialSpecializationDecl>(ThisDecl); + cast<ClassTemplatePartialSpecializationDecl>(CommentDecl); Kind = ClassKind; TemplateKind = TemplatePartialSpecialization; TemplateParameters = CTPSD->getTemplateParameters(); @@ -246,7 +246,7 @@ void DeclInfo::fill() { Kind = TypedefKind; // If this is a typedef to something we consider a function, extract // arguments and return type. - const TypedefDecl *TD = cast<TypedefDecl>(ThisDecl); + const TypedefDecl *TD = cast<TypedefDecl>(CommentDecl); const TypeSourceInfo *TSI = TD->getTypeSourceInfo(); if (!TSI) break; @@ -290,7 +290,7 @@ void DeclInfo::fill() { Kind = TypedefKind; break; case Decl::TypeAliasTemplate: { - const TypeAliasTemplateDecl *TAT = cast<TypeAliasTemplateDecl>(ThisDecl); + const TypeAliasTemplateDecl *TAT = cast<TypeAliasTemplateDecl>(CommentDecl); Kind = TypedefKind; TemplateKind = Template; TemplateParameters = TAT->getTemplateParameters(); diff --git a/lib/AST/CommentDumper.cpp b/lib/AST/CommentDumper.cpp index f6fb3b1baa..f9050d5f71 100644 --- a/lib/AST/CommentDumper.cpp +++ b/lib/AST/CommentDumper.cpp @@ -183,7 +183,7 @@ void CommentDumper::visitParamCommandComment(const ParamCommandComment *C) { OS << " implicitly"; if (C->hasParamName()) - OS << " Param=\"" << C->getParamName() << "\""; + OS << " Param=\"" << C->getParamName(0) << "\""; if (C->isParamIndexValid()) OS << " ParamIndex=" << C->getParamIndex(); diff --git a/lib/AST/CommentSema.cpp b/lib/AST/CommentSema.cpp index dd746ad119..59dc6c7295 100644 --- a/lib/AST/CommentSema.cpp +++ b/lib/AST/CommentSema.cpp @@ -36,7 +36,7 @@ void Sema::setDecl(const Decl *D) { return; ThisDeclInfo = new (Allocator) DeclInfo; - ThisDeclInfo->ThisDecl = D; + ThisDeclInfo->CommentDecl = D; ThisDeclInfo->IsFilled = false; } @@ -413,7 +413,7 @@ HTMLEndTagComment *Sema::actOnHTMLEndTag(SourceLocation LocBegin, FullComment *Sema::actOnFullComment( ArrayRef<BlockContentComment *> Blocks) { - FullComment *FC = new (Allocator) FullComment(Blocks, ThisDeclInfo); + FullComment *FC = new (Allocator) FullComment(Blocks, ThisDeclInfo, 0); resolveParamCommandIndexes(FC); return FC; } @@ -441,7 +441,7 @@ void Sema::checkReturnsCommand(const BlockCommandComment *Command) { if (isFunctionDecl()) { if (ThisDeclInfo->ResultType->isVoidType()) { unsigned DiagKind; - switch (ThisDeclInfo->ThisDecl->getKind()) { + switch (ThisDeclInfo->CommentDecl->getKind()) { default: if (ThisDeclInfo->IsObjCMethod) DiagKind = 3; @@ -508,7 +508,7 @@ void Sema::checkDeprecatedCommand(const BlockCommandComment *Command) { if (!Traits.getCommandInfo(Command->getCommandID())->IsDeprecatedCommand) return; - const Decl *D = ThisDeclInfo->ThisDecl; + const Decl *D = ThisDeclInfo->CommentDecl; if (!D) return; @@ -574,7 +574,7 @@ void Sema::resolveParamCommandIndexes(const FullComment *FC) { ParamCommandComment *PCC = dyn_cast<ParamCommandComment>(*I); if (!PCC || !PCC->hasParamName()) continue; - StringRef ParamName = PCC->getParamName(); + StringRef ParamName = PCC->getParamName(0); // Check that referenced parameter name is in the function decl. const unsigned ResolvedParamIndex = resolveParmVarReference(ParamName, @@ -609,7 +609,7 @@ void Sema::resolveParamCommandIndexes(const FullComment *FC) { const ParamCommandComment *PCC = UnresolvedParamCommands[i]; SourceRange ArgRange = PCC->getParamNameRange(); - StringRef ParamName = PCC->getParamName(); + StringRef ParamName = PCC->getParamName(0); Diag(ArgRange.getBegin(), diag::warn_doc_param_not_found) << ParamName << ArgRange; diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index 90b8807be9..f4a0bdf38b 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -859,6 +859,8 @@ static void collectOnCategoriesAfterLocation(SourceLocation Loc, /// overrides lookup that it does for methods, inside implementations, will /// stop at the interface level (if there is a method there) and not look /// further in super classes. +/// Methods in an implementation can overide methods in super class's category +/// but not in current class's category. But, such methods static void collectOverriddenMethodsFast(SourceManager &SM, const ObjCMethodDecl *Method, SmallVectorImpl<const ObjCMethodDecl *> &Methods) { |