aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2013-03-01 22:51:30 +0000
committerFariborz Jahanian <fjahanian@apple.com>2013-03-01 22:51:30 +0000
commitc98e9130bcddd0258c110d30749edd2284087e3d (patch)
treeb1bef38e783e38b9a92774dd24175d9a327cbc51
parentfc09336a5965040736f9bc63a70416003972364e (diff)
comment parsing. Keep the original command format
in AST for source fidelity and use it in diagnostics to refer to the original format. // rdar://13066276 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176387 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/Comment.h17
-rw-r--r--include/clang/AST/CommentLexer.h7
-rw-r--r--include/clang/Basic/DiagnosticCommentKinds.td16
-rw-r--r--lib/AST/CommentLexer.cpp1
-rw-r--r--lib/AST/CommentParser.cpp4
-rw-r--r--lib/AST/CommentSema.cpp6
-rw-r--r--test/Sema/warn-documentation.cpp28
7 files changed, 60 insertions, 19 deletions
diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h
index 78b703d78a..f00993bf6c 100644
--- a/include/clang/AST/Comment.h
+++ b/include/clang/AST/Comment.h
@@ -570,13 +570,16 @@ protected:
/// Paragraph argument.
ParagraphComment *Paragraph;
-
+
+ /// Header Doc command, if true
+ bool HDCommand;
+
BlockCommandComment(CommentKind K,
SourceLocation LocBegin,
SourceLocation LocEnd,
unsigned CommandID) :
BlockContentComment(K, LocBegin, LocEnd),
- Paragraph(NULL) {
+ Paragraph(NULL), HDCommand(false) {
setLocation(getCommandNameBeginLoc());
BlockCommandCommentBits.CommandID = CommandID;
}
@@ -586,7 +589,7 @@ public:
SourceLocation LocEnd,
unsigned CommandID) :
BlockContentComment(BlockCommandCommentKind, LocBegin, LocEnd),
- Paragraph(NULL) {
+ Paragraph(NULL), HDCommand(false) {
setLocation(getCommandNameBeginLoc());
BlockCommandCommentBits.CommandID = CommandID;
}
@@ -657,6 +660,14 @@ public:
if (NewLocEnd.isValid())
setSourceRange(SourceRange(getLocStart(), NewLocEnd));
}
+
+ bool getHDCommand() const LLVM_READONLY {
+ return HDCommand;
+ }
+
+ void setHDCommand(bool HDC) {
+ HDCommand = HDC;
+ }
};
/// Doxygen \\param command.
diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h
index b90414ba01..240a8eac9a 100644
--- a/include/clang/AST/CommentLexer.h
+++ b/include/clang/AST/CommentLexer.h
@@ -75,6 +75,9 @@ class Token {
/// unused (command spelling can be found with CommandTraits). Otherwise,
/// contains the length of the string that starts at TextPtr.
unsigned IntVal;
+
+ /// This command is a Header Doc command (command starts with '@').
+ bool HDCommand;
public:
SourceLocation getLocation() const LLVM_READONLY { return Loc; }
@@ -122,6 +125,10 @@ public:
return IntVal;
}
+ bool getHDCommand() const LLVM_READONLY {
+ return HDCommand;
+ }
+
void setCommandID(unsigned ID) {
assert(is(tok::command));
IntVal = ID;
diff --git a/include/clang/Basic/DiagnosticCommentKinds.td b/include/clang/Basic/DiagnosticCommentKinds.td
index e6dfe5b638..f8a2af398d 100644
--- a/include/clang/Basic/DiagnosticCommentKinds.td
+++ b/include/clang/Basic/DiagnosticCommentKinds.td
@@ -44,18 +44,18 @@ def note_doc_html_end_tag : Note<
// Commands
def warn_doc_block_command_empty_paragraph : Warning<
- "empty paragraph passed to '\\%0' command">,
+ "empty paragraph passed to '%select{\\|@}0%1' command">,
InGroup<Documentation>, DefaultIgnore;
def warn_doc_block_command_duplicate : Warning<
- "duplicated command '\\%0'">,
+ "duplicated command '%select{\\|@}0%1'">,
InGroup<Documentation>, DefaultIgnore;
def note_doc_block_command_previous : Note<
- "previous command '\\%0' here">;
+ "previous command '%select{\\|@}0%1' here">;
def note_doc_block_command_previous_alias : Note<
- "previous command '\\%0' (an alias of '\\%1') here">;
+ "previous command '%select{\\|@}0%1' (an alias of '\\%2') here">;
// \param command
@@ -111,14 +111,14 @@ def note_doc_tparam_name_suggestion : Note<
// \returns command
def warn_doc_returns_not_attached_to_a_function_decl : Warning<
- "'\\%0' command used in a comment that is not attached to "
+ "'%select{\\|@}0%1' command used in a comment that is not attached to "
"a function or method declaration">,
InGroup<Documentation>, DefaultIgnore;
def warn_doc_returns_attached_to_a_void_function : Warning<
- "'\\%0' command used in a comment that is attached to a "
+ "'%select{\\|@}0%1' command used in a comment that is attached to a "
"%select{function returning void|constructor|destructor|"
- "method returning void}1">,
+ "method returning void}2">,
InGroup<Documentation>, DefaultIgnore;
// \deprecated command
@@ -134,7 +134,7 @@ def note_add_deprecation_attr : Note<
// verbatim block commands
def warn_verbatim_block_end_without_start : Warning<
- "'\\%0' command does not terminate a verbatim text block">,
+ "'%select{\\|@}0%1' command does not terminate a verbatim text block">,
InGroup<Documentation>, DefaultIgnore;
} // end of documentation issue category
diff --git a/lib/AST/CommentLexer.cpp b/lib/AST/CommentLexer.cpp
index cee086e103..da865d2ee3 100644
--- a/lib/AST/CommentLexer.cpp
+++ b/lib/AST/CommentLexer.cpp
@@ -298,6 +298,7 @@ void Lexer::lexCommentText(Token &T) {
switch(*TokenPtr) {
case '\\':
case '@': {
+ T.HDCommand = (*TokenPtr == '@');
TokenPtr++;
if (TokenPtr == CommentEnd) {
formTextToken(T, TokenPtr);
diff --git a/lib/AST/CommentParser.cpp b/lib/AST/CommentParser.cpp
index 952c10c4a8..f5c933e7bb 100644
--- a/lib/AST/CommentParser.cpp
+++ b/lib/AST/CommentParser.cpp
@@ -313,15 +313,18 @@ BlockCommandComment *Parser::parseBlockCommand() {
PC = S.actOnParamCommandStart(Tok.getLocation(),
Tok.getEndLocation(),
Tok.getCommandID());
+ PC->setHDCommand(Tok.getHDCommand());
} else if (Info->IsTParamCommand) {
IsTParam = true;
TPC = S.actOnTParamCommandStart(Tok.getLocation(),
Tok.getEndLocation(),
Tok.getCommandID());
+ TPC->setHDCommand(Tok.getHDCommand());
} else {
BC = S.actOnBlockCommandStart(Tok.getLocation(),
Tok.getEndLocation(),
Tok.getCommandID());
+ BC->setHDCommand(Tok.getHDCommand());
}
consumeToken();
@@ -569,6 +572,7 @@ BlockContentComment *Parser::parseParagraphOrBlockCommand() {
if (Info->IsVerbatimBlockEndCommand) {
Diag(Tok.getLocation(),
diag::warn_verbatim_block_end_without_start)
+ << Tok.getHDCommand()
<< Info->Name
<< SourceRange(Tok.getLocation(), Tok.getEndLocation());
consumeToken();
diff --git a/lib/AST/CommentSema.cpp b/lib/AST/CommentSema.cpp
index 73e49e71db..3227138807 100644
--- a/lib/AST/CommentSema.cpp
+++ b/lib/AST/CommentSema.cpp
@@ -432,6 +432,7 @@ void Sema::checkBlockCommandEmptyParagraph(BlockCommandComment *Command) {
if (!DiagLoc.isValid())
DiagLoc = Command->getCommandNameRange(Traits).getEnd();
Diag(DiagLoc, diag::warn_doc_block_command_empty_paragraph)
+ << Command->getHDCommand()
<< Command->getCommandName(Traits)
<< Command->getSourceRange();
}
@@ -459,6 +460,7 @@ void Sema::checkReturnsCommand(const BlockCommandComment *Command) {
}
Diag(Command->getLocation(),
diag::warn_doc_returns_attached_to_a_void_function)
+ << Command->getHDCommand()
<< Command->getCommandName(Traits)
<< DiagKind
<< Command->getSourceRange();
@@ -470,6 +472,7 @@ void Sema::checkReturnsCommand(const BlockCommandComment *Command) {
Diag(Command->getLocation(),
diag::warn_doc_returns_not_attached_to_a_function_decl)
+ << Command->getHDCommand()
<< Command->getCommandName(Traits)
<< Command->getSourceRange();
}
@@ -502,15 +505,18 @@ void Sema::checkBlockCommandDuplicate(const BlockCommandComment *Command) {
StringRef CommandName = Command->getCommandName(Traits);
StringRef PrevCommandName = PrevCommand->getCommandName(Traits);
Diag(Command->getLocation(), diag::warn_doc_block_command_duplicate)
+ << Command->getHDCommand()
<< CommandName
<< Command->getSourceRange();
if (CommandName == PrevCommandName)
Diag(PrevCommand->getLocation(), diag::note_doc_block_command_previous)
+ << PrevCommand->getHDCommand()
<< PrevCommandName
<< PrevCommand->getSourceRange();
else
Diag(PrevCommand->getLocation(),
diag::note_doc_block_command_previous_alias)
+ << PrevCommand->getHDCommand()
<< PrevCommandName
<< CommandName;
}
diff --git a/test/Sema/warn-documentation.cpp b/test/Sema/warn-documentation.cpp
index e2e49e59bf..d166ae0b58 100644
--- a/test/Sema/warn-documentation.cpp
+++ b/test/Sema/warn-documentation.cpp
@@ -862,28 +862,28 @@ int test_nocrash9;
// We used to crash on this. PR15068
-// expected-warning@+2 {{empty paragraph passed to '\param' command}}
-// expected-warning@+2 {{empty paragraph passed to '\param' command}}
+// expected-warning@+2 {{empty paragraph passed to '@param' command}}
+// expected-warning@+2 {{empty paragraph passed to '@param' command}}
///@param x
///@param y
int test_nocrash10(int x, int y);
-// expected-warning@+2 {{empty paragraph passed to '\param' command}} expected-warning@+2 {{parameter 'x' not found in the function declaration}}
-// expected-warning@+2 {{empty paragraph passed to '\param' command}} expected-warning@+2 {{parameter 'y' not found in the function declaration}}
+// expected-warning@+2 {{empty paragraph passed to '@param' command}} expected-warning@+2 {{parameter 'x' not found in the function declaration}}
+// expected-warning@+2 {{empty paragraph passed to '@param' command}} expected-warning@+2 {{parameter 'y' not found in the function declaration}}
///@param x
///@param y
int test_nocrash11();
-// expected-warning@+3 {{empty paragraph passed to '\param' command}} expected-warning@+3 {{parameter 'x' not found in the function declaration}}
-// expected-warning@+3 {{empty paragraph passed to '\param' command}} expected-warning@+3 {{parameter 'y' not found in the function declaration}}
+// expected-warning@+3 {{empty paragraph passed to '@param' command}} expected-warning@+3 {{parameter 'x' not found in the function declaration}}
+// expected-warning@+3 {{empty paragraph passed to '@param' command}} expected-warning@+3 {{parameter 'y' not found in the function declaration}}
/**
@param x
@param y
**/
int test_nocrash12();
-// expected-warning@+2 {{empty paragraph passed to '\param' command}}
-// expected-warning@+1 {{empty paragraph passed to '\param' command}}
+// expected-warning@+2 {{empty paragraph passed to '@param' command}}
+// expected-warning@+1 {{empty paragraph passed to '@param' command}}
///@param x@param y
int test_nocrash13(int x, int y);
@@ -895,3 +895,15 @@ int test_nocrash13(int x, int y);
/// \headerfile foo.h
int test_duplicate_headerfile1(int);
+
+// rdar://13066276
+// expected-warning@+1 {{'@return' command used in a comment that is not attached to a function or method declaration}}
+/** @return s */
+struct s* f(void);
+struct s;
+
+// expected-warning@+1 {{'\return' command used in a comment that is not attached to a function or method declaration}}
+/** \return s */
+struct q* g(void);
+struct q;
+