summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitri Gribenko <gribozavr@gmail.com>2012-08-24 00:05:30 +0000
committerDmitri Gribenko <gribozavr@gmail.com>2012-08-24 00:05:30 +0000
commit907f6b8c06f0bfdb345dd2ee480a50d1e489c7d8 (patch)
tree52d02678ec5581cc40f942b1a47eec5a1afb6bdd
parentdd28e7930ccae5dd67f62d6a4221a3112dd93ec8 (diff)
downloadbcm5719-llvm-907f6b8c06f0bfdb345dd2ee480a50d1e489c7d8.tar.gz
bcm5719-llvm-907f6b8c06f0bfdb345dd2ee480a50d1e489c7d8.zip
Comment semantic analysis: treat function typedefs as functions so that one can
use \param and \returns in documentation. Fixes PR13533. llvm-svn: 162507
-rw-r--r--clang/include/clang/AST/Comment.h4
-rw-r--r--clang/lib/AST/Comment.cpp53
-rw-r--r--clang/test/Sema/warn-documentation.cpp23
-rw-r--r--clang/test/Sema/warn-documentation.m8
4 files changed, 85 insertions, 3 deletions
diff --git a/clang/include/clang/AST/Comment.h b/clang/include/clang/AST/Comment.h
index 01aaac3f77a..09d0a26731d 100644
--- a/clang/include/clang/AST/Comment.h
+++ b/clang/include/clang/AST/Comment.h
@@ -942,7 +942,9 @@ struct DeclInfo {
/// \li member function,
/// \li member function template,
/// \li member function template specialization,
- /// \li ObjC method.
+ /// \li ObjC method,
+ /// \li a typedef for a function pointer, member function pointer,
+ /// ObjC block.
FunctionKind,
/// Something that we consider a "class":
diff --git a/clang/lib/AST/Comment.cpp b/clang/lib/AST/Comment.cpp
index 8a711f0c1f8..2af38961563 100644
--- a/clang/lib/AST/Comment.cpp
+++ b/clang/lib/AST/Comment.cpp
@@ -240,7 +240,58 @@ void DeclInfo::fill() {
case Decl::Namespace:
Kind = NamespaceKind;
break;
- case Decl::Typedef:
+ case Decl::Typedef: {
+ 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 TypeSourceInfo *TSI = TD->getTypeSourceInfo();
+ if (!TSI)
+ break;
+ TypeLoc TL = TSI->getTypeLoc().getUnqualifiedLoc();
+ while (true) {
+ TL = TL.IgnoreParens();
+ // Look through typedefs.
+ if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) {
+ TSI = TypedefTL->getTypedefNameDecl()->getTypeSourceInfo();
+ if (TSI)
+ break;
+ TL = TSI->getTypeLoc().getUnqualifiedLoc();
+ continue;
+ }
+ // Look through qualified types.
+ if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) {
+ TL = QualifiedTL->getUnqualifiedLoc();
+ continue;
+ }
+ // Look through pointer types.
+ if (PointerTypeLoc *PointerTL = dyn_cast<PointerTypeLoc>(&TL)) {
+ TL = PointerTL->getPointeeLoc().getUnqualifiedLoc();
+ continue;
+ }
+ if (BlockPointerTypeLoc *BlockPointerTL =
+ dyn_cast<BlockPointerTypeLoc>(&TL)) {
+ TL = BlockPointerTL->getPointeeLoc().getUnqualifiedLoc();
+ continue;
+ }
+ if (MemberPointerTypeLoc *MemberPointerTL =
+ dyn_cast<MemberPointerTypeLoc>(&TL)) {
+ TL = MemberPointerTL->getPointeeLoc().getUnqualifiedLoc();
+ continue;
+ }
+ // Is this a typedef for a function type?
+ if (FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
+ Kind = FunctionKind;
+ ArrayRef<ParmVarDecl *> Params = FTL->getParams();
+ ParamVars = ArrayRef<const ParmVarDecl *>(Params.data(),
+ Params.size());
+ ResultType = FTL->getResultLoc().getType();
+ break;
+ }
+ break;
+ }
+ break;
+ }
case Decl::TypeAlias:
Kind = TypedefKind;
break;
diff --git a/clang/test/Sema/warn-documentation.cpp b/clang/test/Sema/warn-documentation.cpp
index 1cd13585212..43143ff83d0 100644
--- a/clang/test/Sema/warn-documentation.cpp
+++ b/clang/test/Sema/warn-documentation.cpp
@@ -250,6 +250,29 @@ int test_param17(int a);
/// \param x2 Ccc.
int test_param18(int x1, int x2, int x3);
+// expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'aaa'?}}
+/// \param aaa Meow.
+/// \param bbb Bbb.
+/// \returns aaa.
+typedef int test_param19(int aaa);
+
+// expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'aaa'?}}
+/// \param aaa Meow.
+/// \param bbb Bbb.
+/// \returns aaa.
+typedef int (*test_param20)(int aaa);
+
+// expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'aaa'?}}
+/// \param aaa Meow.
+/// \param bbb Bbb.
+/// \returns aaa.
+typedef int (* const test_param21)(int aaa);
+
+// expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'aaa'?}}
+/// \param aaa Meow.
+/// \param bbb Bbb.
+/// \returns aaa.
+typedef int (C::*test_param22)(int aaa);
// expected-warning@+1 {{'\tparam' command used in a comment that is not attached to a template declaration}}
/// \tparam T Aaa
diff --git a/clang/test/Sema/warn-documentation.m b/clang/test/Sema/warn-documentation.m
index d6af6edcc85..04ae4ab6484 100644
--- a/clang/test/Sema/warn-documentation.m
+++ b/clang/test/Sema/warn-documentation.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -Wdocumentation -Wdocumentation-pedantic -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-objc-root-class -Wdocumentation -Wdocumentation-pedantic -verify %s
@class NSString;
@@ -91,3 +91,9 @@ int b;
- (void)test2:(NSString *)aaa;
@end
+// expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'aaa'?}}
+/// \param aaa Meow.
+/// \param bbb Bbb.
+/// \returns aaa.
+typedef int (^test_param1)(int aaa);
+
OpenPOWER on IntegriCloud