diff --git a/clang/include/clang/AST/Comment.h b/clang/include/clang/AST/Comment.h --- a/clang/include/clang/AST/Comment.h +++ b/clang/include/clang/AST/Comment.h @@ -1019,9 +1019,6 @@ /// \li member function template, /// \li member function template specialization, /// \li ObjC method, - /// \li variable of function pointer, member function pointer or block type, - /// \li a typedef for a function pointer, member function pointer, - /// ObjC block. FunctionKind, /// Something that we consider a "class": @@ -1089,6 +1086,8 @@ TemplateDeclKind getTemplateKind() const LLVM_READONLY { return static_cast(TemplateKind); } + + bool involvesFunctionType() const { return !ReturnType.isNull(); } }; /// A full comment attached to a declaration, contains block content. diff --git a/clang/include/clang/AST/CommentSema.h b/clang/include/clang/AST/CommentSema.h --- a/clang/include/clang/AST/CommentSema.h +++ b/clang/include/clang/AST/CommentSema.h @@ -201,6 +201,10 @@ /// Emit diagnostics about unknown parametrs. void resolveParamCommandIndexes(const FullComment *FC); + /// \returns \c true if the declaration that this comment is attached to + /// is a pointer to function/method/block type or has such a type. + bool involvesFunctionType(); + bool isFunctionDecl(); bool isAnyFunctionDecl(); diff --git a/clang/lib/AST/Comment.cpp b/clang/lib/AST/Comment.cpp --- a/clang/lib/AST/Comment.cpp +++ b/clang/lib/AST/Comment.cpp @@ -250,6 +250,7 @@ IsClassMethod = !IsInstanceMethod; } IsVariadic = FD->isVariadic(); + assert(involvesFunctionType()); break; } case Decl::ObjCMethod: { @@ -261,6 +262,7 @@ IsInstanceMethod = MD->isInstanceMethod(); IsClassMethod = !IsInstanceMethod; IsVariadic = MD->isVariadic(); + assert(involvesFunctionType()); break; } case Decl::FunctionTemplate: { @@ -272,6 +274,7 @@ ReturnType = FD->getReturnType(); TemplateParameters = FTD->getTemplateParameters(); IsVariadic = FD->isVariadic(); + assert(involvesFunctionType()); break; } case Decl::ClassTemplate: { @@ -352,11 +355,11 @@ TypeLoc TL = TSI->getTypeLoc().getUnqualifiedLoc(); FunctionTypeLoc FTL; if (getFunctionTypeLoc(TL, FTL)) { - Kind = FunctionKind; ParamVars = FTL.getParams(); ReturnType = FTL.getReturnLoc().getType(); if (const auto *FPT = dyn_cast(FTL.getTypePtr())) IsVariadic = FPT->isVariadic(); + assert(involvesFunctionType()); } } diff --git a/clang/lib/AST/CommentSema.cpp b/clang/lib/AST/CommentSema.cpp --- a/clang/lib/AST/CommentSema.cpp +++ b/clang/lib/AST/CommentSema.cpp @@ -86,7 +86,7 @@ new (Allocator) ParamCommandComment(LocBegin, LocEnd, CommandID, CommandMarker); - if (!isFunctionDecl()) + if (!involvesFunctionType()) Diag(Command->getLocation(), diag::warn_doc_param_not_attached_to_a_function_decl) << CommandMarker @@ -588,7 +588,7 @@ // to document the value that the property getter returns. if (isObjCPropertyDecl()) return; - if (isFunctionDecl()) { + if (involvesFunctionType()) { assert(!ThisDeclInfo->ReturnType.isNull() && "should have a valid return type"); if (ThisDeclInfo->ReturnType->isVoidType()) { @@ -728,7 +728,7 @@ } void Sema::resolveParamCommandIndexes(const FullComment *FC) { - if (!isFunctionDecl()) { + if (!involvesFunctionType()) { // We already warned that \\param commands are not attached to a function // decl. return; @@ -816,6 +816,14 @@ } } +bool Sema::involvesFunctionType() { + if (!ThisDeclInfo) + return false; + if (!ThisDeclInfo->IsFilled) + inspectThisDecl(); + return ThisDeclInfo->involvesFunctionType(); +} + bool Sema::isFunctionDecl() { if (!ThisDeclInfo) return false;