diff options
author | Dmitri Gribenko <gribozavr@gmail.com> | 2012-08-06 17:08:27 +0000 |
---|---|---|
committer | Dmitri Gribenko <gribozavr@gmail.com> | 2012-08-06 17:08:27 +0000 |
commit | 9443c57150e870e308406e1e4e6d9d64712b417e (patch) | |
tree | 032f3836c1a14731bfa0524b311c9af07dbb79af /lib/AST/CommentSema.cpp | |
parent | 88815f3f81361692dd281000e3e46bf163b2f28b (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.cpp | 43 |
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"; } |