diff --git a/clang/bindings/xml/comment-xml-schema.rng b/clang/bindings/xml/comment-xml-schema.rng
index 13cf7addecc7..a8913a360b79 100644
--- a/clang/bindings/xml/comment-xml-schema.rng
+++ b/clang/bindings/xml/comment-xml-schema.rng
@@ -75,7 +75,6 @@
-
@@ -91,6 +90,9 @@
+
+
+
@@ -440,6 +442,14 @@
+
+
+
+
+
+
+
+
diff --git a/clang/include/clang/AST/CommentCommandTraits.h b/clang/include/clang/AST/CommentCommandTraits.h
index 629329dc1bf9..dde7a1442fe1 100644
--- a/clang/include/clang/AST/CommentCommandTraits.h
+++ b/clang/include/clang/AST/CommentCommandTraits.h
@@ -67,6 +67,9 @@ struct CommandInfo {
/// a template parameter (\\tparam or an alias).
unsigned IsTParamCommand : 1;
+ /// True if this command is \\throws or an alias.
+ unsigned IsThrowsCommand : 1;
+
/// True if this command is \\deprecated or an alias.
unsigned IsDeprecatedCommand : 1;
diff --git a/clang/include/clang/AST/CommentCommands.td b/clang/include/clang/AST/CommentCommands.td
index 4942430a06f5..ed323daa9f8b 100644
--- a/clang/include/clang/AST/CommentCommands.td
+++ b/clang/include/clang/AST/CommentCommands.td
@@ -15,6 +15,7 @@ class Command {
bit IsReturnsCommand = 0;
bit IsParamCommand = 0;
bit IsTParamCommand = 0;
+ bit IsThrowsCommand = 0;
bit IsDeprecatedCommand = 0;
bit IsHeaderfileCommand = 0;
@@ -109,6 +110,10 @@ def Tparam : BlockCommand<"tparam"> { let IsTParamCommand = 1; }
// HeaderDoc command for template parameter documentation.
def Templatefield : BlockCommand<"templatefield"> { let IsTParamCommand = 1; }
+def Throws : BlockCommand<"throws"> { let IsThrowsCommand = 1; }
+def Throw : BlockCommand<"throw"> { let IsThrowsCommand = 1; }
+def Exception : BlockCommand<"exception"> { let IsThrowsCommand = 1; }
+
def Deprecated : BlockCommand<"deprecated"> {
let IsEmptyParagraphAllowed = 1;
let IsDeprecatedCommand = 1;
diff --git a/clang/test/Index/Inputs/CommentXML/valid-function-07.xml b/clang/test/Index/Inputs/CommentXML/valid-function-07.xml
index e9f59115374e..b567e6b265bf 100644
--- a/clang/test/Index/Inputs/CommentXML/valid-function-07.xml
+++ b/clang/test/Index/Inputs/CommentXML/valid-function-07.xml
@@ -27,13 +27,17 @@
Eee
-
+
Fff.
Ggg
+
+
+ Hhh.
+ Iii
- Hhh
- Iii
+ Jjj
+ Kkk
diff --git a/clang/test/Index/comment-to-html-xml-conversion.cpp b/clang/test/Index/comment-to-html-xml-conversion.cpp
index 94e657086469..8c0ed21b2f04 100644
--- a/clang/test/Index/comment-to-html-xml-conversion.cpp
+++ b/clang/test/Index/comment-to-html-xml-conversion.cpp
@@ -890,6 +890,92 @@ void comment_to_xml_conversion_todo_3();
void comment_to_xml_conversion_todo_4();
// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_todo_4:{{.*}} FullCommentAsXML=[comment_to_xml_conversion_todo_4c:@F@comment_to_xml_conversion_todo_4#void comment_to_xml_conversion_todo_4() Aaa. Bbb. Ccc.]
+
+//===---
+// Test the representation of exception specifications in AST and XML.
+//===---
+
+/// Aaa.
+/// \throws Bbb.
+void comment_to_xml_conversion_exceptions_1();
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_exceptions_1:{{.*}} FullCommentAsXML=[comment_to_xml_conversion_exceptions_1c:@F@comment_to_xml_conversion_exceptions_1#void comment_to_xml_conversion_exceptions_1() Aaa. Bbb.]
+// CHECK-NEXT: CommentAST=[
+// CHECK-NEXT: (CXComment_FullComment
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ Aaa.] HasTrailingNewline)
+// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace))
+// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throws]
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ Bbb.]))))]
+
+/// Aaa.
+/// \throw Bbb.
+void comment_to_xml_conversion_exceptions_2();
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_exceptions_2:{{.*}} FullCommentAsXML=[comment_to_xml_conversion_exceptions_2c:@F@comment_to_xml_conversion_exceptions_2#void comment_to_xml_conversion_exceptions_2() Aaa. Bbb.]
+// CHECK-NEXT: CommentAST=[
+// CHECK-NEXT: (CXComment_FullComment
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ Aaa.] HasTrailingNewline)
+// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace))
+// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throw]
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ Bbb.]))))]
+
+/// Aaa.
+/// \exception Bbb.
+void comment_to_xml_conversion_exceptions_3();
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_exceptions_3:{{.*}} FullCommentAsXML=[comment_to_xml_conversion_exceptions_3c:@F@comment_to_xml_conversion_exceptions_3#void comment_to_xml_conversion_exceptions_3() Aaa. Bbb.]
+// CHECK-NEXT: CommentAST=[
+// CHECK-NEXT: (CXComment_FullComment
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ Aaa.] HasTrailingNewline)
+// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace))
+// CHECK-NEXT: (CXComment_BlockCommand CommandName=[exception]
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ Bbb.]))))]
+
+/// Aaa.
+/// \throws Bbb.
+/// \throws Ccc.
+/// \throws Ddd.
+void comment_to_xml_conversion_exceptions_4();
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_exceptions_4:{{.*}} FullCommentAsXML=[comment_to_xml_conversion_exceptions_4c:@F@comment_to_xml_conversion_exceptions_4#void comment_to_xml_conversion_exceptions_4() Aaa. Bbb. Ccc. Ddd.]
+// CHECK-NEXT: CommentAST=[
+// CHECK-NEXT: (CXComment_FullComment
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ Aaa.] HasTrailingNewline)
+// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace))
+// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throws]
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ Bbb.] HasTrailingNewline)
+// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)))
+// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throws]
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ Ccc.] HasTrailingNewline)
+// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)))
+// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throws]
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ Ddd.]))))]
+
+/// Aaa.
+/// \throws Bbb.
+/// \throw Ccc.
+void comment_to_xml_conversion_exceptions_5();
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_exceptions_5:{{.*}} FullCommentAsXML=[comment_to_xml_conversion_exceptions_5c:@F@comment_to_xml_conversion_exceptions_5#void comment_to_xml_conversion_exceptions_5() Aaa. Bbb. Ccc.]
+// CHECK-NEXT: CommentAST=[
+// CHECK-NEXT: (CXComment_FullComment
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ Aaa.] HasTrailingNewline)
+// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace))
+// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throws]
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ Bbb.] HasTrailingNewline)
+// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)))
+// CHECK-NEXT: (CXComment_BlockCommand CommandName=[throw]
+// CHECK-NEXT: (CXComment_Paragraph
+// CHECK-NEXT: (CXComment_Text Text=[ Ccc.]))))]
+
+
// rdar://14348912
#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
diff --git a/clang/tools/libclang/CXComment.cpp b/clang/tools/libclang/CXComment.cpp
index 46588568dc63..1df6e240d9e2 100644
--- a/clang/tools/libclang/CXComment.cpp
+++ b/clang/tools/libclang/CXComment.cpp
@@ -25,6 +25,7 @@
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include
@@ -424,6 +425,7 @@ struct FullCommentParts {
SmallVector Returns;
SmallVector Params;
SmallVector TParams;
+ llvm::TinyPtrVector Exceptions;
SmallVector MiscBlocks;
};
@@ -465,6 +467,10 @@ FullCommentParts::FullCommentParts(const FullComment *C,
Returns.push_back(BCC);
break;
}
+ if (Info->IsThrowsCommand) {
+ Exceptions.push_back(BCC);
+ break;
+ }
MiscBlocks.push_back(BCC);
break;
}
@@ -1322,6 +1328,13 @@ void CommentASTToXMLConverter::visitFullComment(const FullComment *C) {
Result << "";
}
+ if (Parts.Exceptions.size() != 0) {
+ Result << "";
+ for (unsigned i = 0, e = Parts.Exceptions.size(); i != e; ++i)
+ visit(Parts.Exceptions[i]);
+ Result << "";
+ }
+
if (Parts.Returns.size() != 0) {
Result << "";
for (unsigned i = 0, e = Parts.Returns.size(); i != e; ++i)
diff --git a/clang/utils/TableGen/ClangCommentCommandInfoEmitter.cpp b/clang/utils/TableGen/ClangCommentCommandInfoEmitter.cpp
index cab1c2b9b269..857b22e2f0b8 100644
--- a/clang/utils/TableGen/ClangCommentCommandInfoEmitter.cpp
+++ b/clang/utils/TableGen/ClangCommentCommandInfoEmitter.cpp
@@ -40,6 +40,7 @@ void EmitClangCommentCommandInfo(RecordKeeper &Records, raw_ostream &OS) {
<< Tag.getValueAsBit("IsReturnsCommand") << ", "
<< Tag.getValueAsBit("IsParamCommand") << ", "
<< Tag.getValueAsBit("IsTParamCommand") << ", "
+ << Tag.getValueAsBit("IsThrowsCommand") << ", "
<< Tag.getValueAsBit("IsDeprecatedCommand") << ", "
<< Tag.getValueAsBit("IsHeaderfileCommand") << ", "
<< Tag.getValueAsBit("IsEmptyParagraphAllowed") << ", "