aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitri Gribenko <gribozavr@gmail.com>2012-07-13 01:06:46 +0000
committerDmitri Gribenko <gribozavr@gmail.com>2012-07-13 01:06:46 +0000
commitabd56c816e9164b17bb3e7154a511b0c9896ffdb (patch)
tree1c46ada4b16e1e90bdc91413be5ebcd3da981db2
parentbb39c3f8db1d8f1b40cf6f7d4c3a0cf110bc7639 (diff)
Attaching comments to declarations during parsing: handle more Objective-C declarations.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160156 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AST/ASTContext.cpp16
-rw-r--r--lib/Sema/SemaDecl.cpp1
-rw-r--r--lib/Sema/SemaDeclObjC.cpp1
-rw-r--r--lib/Sema/SemaObjCProperty.cpp2
-rw-r--r--test/Sema/warn-documentation.m70
5 files changed, 82 insertions, 8 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 2a1521e21e..a9681d8669 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -78,9 +78,21 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
if (RawComments.empty())
return NULL;
+ // Find declaration location.
+ // For Objective-C declarations we generally don't expect to have multiple
+ // declarators, thus use declaration starting location as the "declaration
+ // location".
+ // For all other declarations multiple declarators are used quite frequently,
+ // so we use the location of the identifier as the "declaration location".
+ SourceLocation DeclLoc;
+ if (isa<ObjCMethodDecl>(D) || isa<ObjCContainerDecl>(D) ||
+ isa<ObjCPropertyDecl>(D))
+ DeclLoc = D->getLocStart();
+ else
+ DeclLoc = D->getLocation();
+
// If the declaration doesn't map directly to a location in a file, we
// can't find the comment.
- SourceLocation DeclLoc = D->getLocation();
if (DeclLoc.isInvalid() || !DeclLoc.isFileID())
return NULL;
@@ -144,7 +156,7 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
// There should be no other declarations or preprocessor directives between
// comment and declaration.
- if (Text.find_first_of(",;{}#") != StringRef::npos)
+ if (Text.find_first_of(",;{}#@") != StringRef::npos)
return NULL;
return *Comment;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 47453762d9..f00ed8279b 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -8932,7 +8932,6 @@ Decl *Sema::ActOnObjCContainerStartDefinition(Decl *IDecl) {
assert(getContainingDC(OCD) == CurContext &&
"The next DeclContext should be lexically contained in the current one.");
CurContext = OCD;
- ActOnDocumentableDecl(IDecl);
return IDecl;
}
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 8d4694662d..17c34a239d 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -2429,6 +2429,7 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
Consumer.HandleTopLevelDeclInObjCContainer(DG);
}
+ ActOnDocumentableDecl(ClassDecl);
return ClassDecl;
}
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index 34dd068945..335dad18dd 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -149,6 +149,7 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
if (getLangOpts().ObjCAutoRefCount)
checkARCPropertyDecl(*this, cast<ObjCPropertyDecl>(Res));
}
+ ActOnDocumentableDecl(Res);
return Res;
}
@@ -169,6 +170,7 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
if (getLangOpts().ObjCAutoRefCount)
checkARCPropertyDecl(*this, Res);
+ ActOnDocumentableDecl(Res);
return Res;
}
diff --git a/test/Sema/warn-documentation.m b/test/Sema/warn-documentation.m
index 0a02f7bb26..3a661c5ef4 100644
--- a/test/Sema/warn-documentation.m
+++ b/test/Sema/warn-documentation.m
@@ -2,11 +2,9 @@
@class NSString;
-// expected-warning@+2 {{empty paragraph passed to '\brief' command}}
-/**
- * \brief\brief Aaa
- */
-@interface A
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\brief Aaa
+@interface Test1
// expected-warning@+2 {{empty paragraph passed to '\brief' command}}
/**
* \brief\brief Aaa
@@ -20,5 +18,67 @@
* \param aab Aaa
*/
+ (NSString *)test2:(NSString *)aaa;
+
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\brief Aaa
+@property int test3; // a property: ObjCPropertyDecl
+
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\brief Aaa
+@property int test4; // a property: ObjCPropertyDecl
@end
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\brief Aaa
+@interface Test1()
+@end
+
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\brief Aaa
+@implementation Test1 // a class implementation : ObjCImplementationDecl
++ (NSString *)test1:(NSString *)aaa suffix:(NSString *)bbb {
+ return 0;
+}
+
++ (NSString *)test2:(NSString *)aaa {
+ return 0;
+}
+
+@synthesize test3; // a property implementation: ObjCPropertyImplDecl
+@dynamic test4; // a property implementation: ObjCPropertyImplDecl
+
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\brief Aaa
+NSString *_test5;
+@end
+
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\brief Aaa
+@interface Test1(Test1Category) // a category: ObjCCategoryDecl
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\brief Aaa
++ (NSString *)test3:(NSString *)aaa;
+@end
+
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\brief Aaa
+@implementation Test1(Test1Category) // a category implementation: ObjCCategoryImplDecl
++ (NSString *)test3:(NSString *)aaa {
+ return 0;
+}
+@end
+
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\brief Aaa
+@protocol TestProto1 // a protocol: ObjCProtocolDecl
+@end
+
+int a;
+
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\brief Aaa
+@interface Test4
+@end
+
+int b;
+