aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/CommentSema.cpp
diff options
context:
space:
mode:
authorDmitri Gribenko <gribozavr@gmail.com>2012-08-06 17:08:27 +0000
committerDmitri Gribenko <gribozavr@gmail.com>2012-08-06 17:08:27 +0000
commit9443c57150e870e308406e1e4e6d9d64712b417e (patch)
tree032f3836c1a14731bfa0524b311c9af07dbb79af /lib/AST/CommentSema.cpp
parent88815f3f81361692dd281000e3e46bf163b2f28b (diff)
Comment diagnostics: warn on duplicate \brief and \return commands.
Doxygen manual claims that multiple \brief or \returns commands will be merged together, but actual behavior is different (second \brief command becomes a part of a discussion, second \returns becomes a "Returns: blah" paragraph on its own). Anyway, it seems to be a bad idea to use multiple \brief or \returns commands in a single command. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161325 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/CommentSema.cpp')
-rw-r--r--lib/AST/CommentSema.cpp43
1 files changed, 40 insertions, 3 deletions
diff --git a/lib/AST/CommentSema.cpp b/lib/AST/CommentSema.cpp
index 770d5bba24..57f8fda07c 100644
--- a/lib/AST/CommentSema.cpp
+++ b/lib/AST/CommentSema.cpp
@@ -20,7 +20,7 @@ namespace comments {
Sema::Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr,
DiagnosticsEngine &Diags) :
Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags),
- ThisDeclInfo(NULL) {
+ ThisDeclInfo(NULL), BriefCommand(NULL), ReturnsCommand(NULL) {
}
void Sema::setDecl(const Decl *D) {
@@ -55,6 +55,7 @@ BlockCommandComment *Sema::actOnBlockCommandFinish(
ParagraphComment *Paragraph) {
Command->setParagraph(Paragraph);
checkBlockCommandEmptyParagraph(Command);
+ checkBlockCommandDuplicate(Command);
checkReturnsCommand(Command);
return Command;
}
@@ -507,6 +508,39 @@ void Sema::checkReturnsCommand(const BlockCommandComment *Command) {
<< Command->getSourceRange();
}
+void Sema::checkBlockCommandDuplicate(const BlockCommandComment *Command) {
+ StringRef Name = Command->getCommandName();
+ const BlockCommandComment *PrevCommand = NULL;
+ if (isBriefCommand(Name)) {
+ if (!BriefCommand) {
+ BriefCommand = Command;
+ return;
+ }
+ PrevCommand = BriefCommand;
+ } else if (isReturnsCommand(Name)) {
+ if (!ReturnsCommand) {
+ ReturnsCommand = Command;
+ return;
+ }
+ PrevCommand = ReturnsCommand;
+ } else {
+ // We don't want to check this command for duplicates.
+ return;
+ }
+ Diag(Command->getLocation(), diag::warn_doc_block_command_duplicate)
+ << Name
+ << Command->getSourceRange();
+ if (Name == PrevCommand->getCommandName())
+ Diag(PrevCommand->getLocation(), diag::note_doc_block_command_previous)
+ << PrevCommand->getCommandName()
+ << Command->getSourceRange();
+ else
+ Diag(PrevCommand->getLocation(),
+ diag::note_doc_block_command_previous_alias)
+ << PrevCommand->getCommandName()
+ << Name;
+}
+
bool Sema::isFunctionDecl() {
if (!ThisDeclInfo)
return false;
@@ -678,10 +712,9 @@ StringRef Sema::correctTypoInTParamReference(
// TODO: tablegen
bool Sema::isBlockCommand(StringRef Name) {
- return isReturnsCommand(Name) ||
+ return isBriefCommand(Name) || isReturnsCommand(Name) ||
isParamCommand(Name) || isTParamCommand(Name) ||
llvm::StringSwitch<bool>(Name)
- .Cases("brief", "short", true)
.Case("author", true)
.Case("authors", true)
.Case("pre", true)
@@ -700,6 +733,10 @@ bool Sema::isTParamCommand(StringRef Name) {
return Name == "tparam";
}
+bool Sema::isBriefCommand(StringRef Name) {
+ return Name == "brief" || Name == "short";
+}
+
bool Sema::isReturnsCommand(StringRef Name) {
return Name == "returns" || Name == "return" || Name == "result";
}