diff options
author | Dmitri Gribenko <gribozavr@gmail.com> | 2012-08-07 17:54:38 +0000 |
---|---|---|
committer | Dmitri Gribenko <gribozavr@gmail.com> | 2012-08-07 17:54:38 +0000 |
commit | f303d4cb10648ac9c2080ae7c9dd507ba615e3a7 (patch) | |
tree | f0cd0e787fcfce0ca1ba3324b2b715147ce26d94 | |
parent | cff863fd803874d251ef8725d5c08dec90924627 (diff) |
libclang API for comment-to-xml conversion.
The implementation also includes a Relax NG schema and tests for the schema
itself. The schema is used in c-index-test to verify that XML documents we
produce are valid. In order to do the validation, we add an optional libxml2
dependency for c-index-test.
Credits for CMake part go to Doug Gregor. Credits for Autoconf part go to Eric
Christopher. Thanks!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161431 91177308-0d34-0410-b5e6-96231b3b80d8
43 files changed, 1423 insertions, 59 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index de85806957..9bfc3a4bc6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,6 +139,10 @@ if (APPLE) set(CMAKE_MODULE_LINKER_FLAGS "-Wl,-flat_namespace -Wl,-undefined -Wl,suppress") endif () +# libxml2 is an optional dependency, required only to run validation +# tests on XML output. +find_package(libxml2) + configure_file( ${CLANG_SOURCE_DIR}/include/clang/Config/config.h.cmake ${CLANG_BINARY_DIR}/include/clang/Config/config.h) @@ -278,3 +282,4 @@ endif() set(BUG_REPORT_URL "http://llvm.org/bugs/" CACHE STRING "Default URL where bug reports are to be submitted.") + diff --git a/bindings/xml/comment-xml-schema.rng b/bindings/xml/comment-xml-schema.rng new file mode 100644 index 0000000000..8071b3a06c --- /dev/null +++ b/bindings/xml/comment-xml-schema.rng @@ -0,0 +1,400 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<grammar xmlns="http://relaxng.org/ns/structure/1.0" + datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"> + + <start> + <choice> + <!-- Everything else not explicitly mentioned below. --> + <ref name="Other" /> + + <ref name="Function" /> + <ref name="Class" /> + <ref name="Variable" /> + <ref name="Namespace" /> + <ref name="Typedef" /> + </choice> + </start> + + <define name="Other"> + <element name="Other"> + <ref name="attrSourceLocation" /> + <ref name="Name" /> + <optional> + <ref name="USR" /> + </optional> + <optional> + <ref name="Abstract" /> + </optional> + <optional> + <ref name="TemplateParameters" /> + </optional> + <optional> + <ref name="Parameters" /> + </optional> + <optional> + <ref name="ResultDiscussion" /> + </optional> + <optional> + <ref name="Discussion" /> + </optional> + </element> + </define> + + <define name="Function"> + <element name="Function"> + <optional> + <attribute name="templateKind"> + <choice> + <value>template</value> + <value>specialization</value> + </choice> + </attribute> + </optional> + <ref name="attrSourceLocation" /> + + <optional> + <attribute name="isInstanceMethod"> + <data type="boolean" /> + </attribute> + </optional> + <optional> + <attribute name="isClassMethod"> + <data type="boolean" /> + </attribute> + </optional> + + <ref name="Name" /> + <optional> + <ref name="USR" /> + </optional> + <!-- TODO: Add exception specification. --> + <optional> + <ref name="Abstract" /> + </optional> + <optional> + <ref name="TemplateParameters" /> + </optional> + <optional> + <ref name="Parameters" /> + </optional> + <optional> + <ref name="ResultDiscussion" /> + </optional> + <optional> + <ref name="Discussion" /> + </optional> + </element> + </define> + + <define name="Class"> + <element name="Class"> + <optional> + <attribute name="templateKind"> + <choice> + <value>template</value> + <value>specialization</value> + <value>partialSpecialization</value> + </choice> + </attribute> + </optional> + <ref name="attrSourceLocation" /> + + <ref name="Name" /> + <optional> + <ref name="USR" /> + </optional> + <optional> + <ref name="Abstract" /> + </optional> + <optional> + <ref name="TemplateParameters" /> + </optional> + + <!-- Parameters and results don't make sense for classes, but the user + can specify \param or \returns in a comment anyway. --> + <optional> + <ref name="Parameters" /> + </optional> + <optional> + <ref name="ResultDiscussion" /> + </optional> + + <optional> + <ref name="Discussion" /> + </optional> + </element> + </define> + + <define name="Variable"> + <element name="Variable"> + <ref name="attrSourceLocation" /> + <ref name="Name" /> + <optional> + <ref name="USR" /> + </optional> + <optional> + <ref name="Abstract" /> + </optional> + + <!-- Template parameters, parameters and results don't make sense for + variables, but the user can specify \tparam \param or \returns + in a comment anyway. --> + <optional> + <ref name="TemplateParameters" /> + </optional> + <optional> + <ref name="Parameters" /> + </optional> + <optional> + <ref name="ResultDiscussion" /> + </optional> + + <optional> + <ref name="Discussion" /> + </optional> + </element> + </define> + + <define name="Namespace"> + <element name="Namespace"> + <ref name="attrSourceLocation" /> + <ref name="Name" /> + <optional> + <ref name="USR" /> + </optional> + <optional> + <ref name="Abstract" /> + </optional> + + <!-- Template parameters, parameters and results don't make sense for + namespaces, but the user can specify \tparam, \param or \returns + in a comment anyway. --> + <optional> + <ref name="TemplateParameters" /> + </optional> + <optional> + <ref name="Parameters" /> + </optional> + <optional> + <ref name="ResultDiscussion" /> + </optional> + + <optional> + <ref name="Discussion" /> + </optional> + </element> + </define> + + <define name="Typedef"> + <element name="Typedef"> + <ref name="attrSourceLocation" /> + <ref name="Name" /> + <optional> + <ref name="USR" /> + </optional> + <optional> + <ref name="Abstract" /> + </optional> + + <optional> + <ref name="TemplateParameters" /> + </optional> + + <!-- Parameters and results might make sense for typedefs if the type is + a function pointer type. --> + <optional> + <ref name="Parameters" /> + </optional> + <optional> + <ref name="ResultDiscussion" /> + </optional> + + <optional> + <ref name="Discussion" /> + </optional> + </element> + </define> + + <define name="attrSourceLocation"> + <optional> + <attribute name="file"> + <!-- Non-empty text content. --> + <data type="string"> + <param name="pattern">.*\S.*</param> + </data> + </attribute> + </optional> + <optional> + <attribute name="line"> + <data type="positiveInteger" /> + </attribute> + <attribute name="column"> + <data type="positiveInteger" /> + </attribute> + </optional> + </define> + + <define name="Name"> + <element name="Name"> + <!-- Non-empty text content. --> + <data type="string"> + <param name="pattern">.*\S.*</param> + </data> + </element> + </define> + + <define name="USR"> + <element name="USR"> + <!-- Non-empty text content. --> + <data type="string"> + <param name="pattern">.*\S.*</param> + </data> + </element> + </define> + + <define name="Abstract"> + <element name="Abstract"> + <zeroOrMore> + <ref name="TextBlockContent" /> + </zeroOrMore> + </element> + </define> + + <define name="Discussion"> + <element name="Discussion"> + <oneOrMore> + <ref name="TextBlockContent" /> + </oneOrMore> + </element> + </define> + + <define name="TemplateParameters"> + <element name="TemplateParameters"> + <!-- Parameter elements should be sorted according to position. --> + <oneOrMore> + <element name="Parameter"> + <element name="Name"> + <!-- Non-empty text content. --> + <data type="string"> + <param name="pattern">.*\S.*</param> + </data> + </element> + <optional> + <!-- This is index at depth 0. libclang API can return more + information about position, but we expose only essential + information here, since "Parameter" elements are already + sorted. + + "Position" element could be added in future if needed. --> + <element name="Index"> + <data type="nonNegativeInteger" /> + </element> + </optional> + <!-- In general, template parameters with whitespace discussion + should not be emitted. Schema might be more strict here. --> + <element name="Discussion"> + <ref name="TextBlockContent" /> + </element> + </element> + </oneOrMore> + </element> + </define> + + <define name="Parameters"> + <element name="Parameters"> + <!-- Parameter elements should be sorted according to index. --> + <oneOrMore> + <element name="Parameter"> + <element name="Name"> + <!-- Non-empty text content. --> + <data type="string"> + <param name="pattern">.*\S.*</param> + </data> + </element> + <optional> + <element name="Index"> + <data type="nonNegativeInteger" /> + </element> + </optional> + <element name="Direction"> + <attribute name="isExplicit"> + <data type="boolean" /> + </attribute> + <choice> + <value>in</value> + <value>out</value> + <value>in,out</value> + </choice> + </element> + <!-- In general, template parameters with whitespace discussion + should not be emitted, unless direction is explicitly specified. + Schema might be more strict here. --> + <element name="Discussion"> + <ref name="TextBlockContent" /> + </element> + </element> + </oneOrMore> + </element> + </define> + + <define name="ResultDiscussion"> + <element name="ResultDiscussion"> + <zeroOrMore> + <ref name="TextBlockContent" /> + </zeroOrMore> + </element> + </define> + + <define name="TextBlockContent"> + <choice> + <element name="Para"> + <zeroOrMore> + <ref name="TextInlineContent" /> + </zeroOrMore> + </element> + <element name="Verbatim"> + <attribute name="kind"> + <!-- TODO: add all Doxygen verbatim kinds --> + <choice> + <value>code</value> + <value>verbatim</value> + </choice> + </attribute> + <text /> + </element> + </choice> + </define> + + <define name="TextInlineContent"> + <choice> + <text /> + <element name="bold"> + <!-- Non-empty text content. --> + <data type="string"> + <param name="pattern">.*\S.*</param> + </data> + </element> + <element name="monospaced"> + <!-- Non-empty text content. --> + <data type="string"> + <param name="pattern">.*\S.*</param> + </data> + </element> + <element name="emphasized"> + <!-- Non-empty text content. --> + <data type="string"> + <param name="pattern">.*\S.*</param> + </data> + </element> + <element name="rawHTML"> + <!-- Non-empty text content. --> + <data type="string"> + <param name="pattern">.*\S.*</param> + </data> + </element> + </choice> + </define> + +</grammar> + diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index c725bcfad1..edd3cbb4a7 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -3687,6 +3687,21 @@ CINDEX_LINKAGE CXString clang_HTMLTagComment_getAsString(CXComment Comment); CINDEX_LINKAGE CXString clang_FullComment_getAsHTML(CXComment Comment); /** + * \brief Convert a given full parsed comment to an XML document. + * + * A Relax NG schema for the XML can be found in comment-xml-schema.rng file + * inside clang source tree. + * + * \param TU the translation unit \c Comment belongs to. + * + * \param Comment a \c CXComment_FullComment AST node. + * + * \returns string containing an XML document. + */ +CINDEX_LINKAGE CXString clang_FullComment_getAsXML(CXTranslationUnit TU, + CXComment Comment); + +/** * @} */ diff --git a/test/Index/Inputs/CommentXML/invalid-function-01.xml b/test/Index/Inputs/CommentXML/invalid-function-01.xml new file mode 100644 index 0000000000..85f06695a0 --- /dev/null +++ b/test/Index/Inputs/CommentXML/invalid-function-01.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +<Parameters> +</Parameters> +</Function> diff --git a/test/Index/Inputs/CommentXML/invalid-function-02.xml b/test/Index/Inputs/CommentXML/invalid-function-02.xml new file mode 100644 index 0000000000..700711b0a0 --- /dev/null +++ b/test/Index/Inputs/CommentXML/invalid-function-02.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +<Parameters> + <Parameter> + </Parameter> +</Parameters> +</Function> diff --git a/test/Index/Inputs/CommentXML/invalid-function-03.xml b/test/Index/Inputs/CommentXML/invalid-function-03.xml new file mode 100644 index 0000000000..0c4618f1ef --- /dev/null +++ b/test/Index/Inputs/CommentXML/invalid-function-03.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +<Parameters> + <Parameter> + <Term></Term> + <Definition><Para>Bbb.</Para></Definition> + </Parameter> +</Parameters> +</Function> diff --git a/test/Index/Inputs/CommentXML/invalid-function-04.xml b/test/Index/Inputs/CommentXML/invalid-function-04.xml new file mode 100644 index 0000000000..88dd5a851c --- /dev/null +++ b/test/Index/Inputs/CommentXML/invalid-function-04.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +<Parameters> + <Parameter> + <Term> </Term> + <Definition><Para>Bbb.</Para></Definition> + </Parameter> +</Parameters> +</Function> diff --git a/test/Index/Inputs/CommentXML/invalid-function-05.xml b/test/Index/Inputs/CommentXML/invalid-function-05.xml new file mode 100644 index 0000000000..ce96b7d05f --- /dev/null +++ b/test/Index/Inputs/CommentXML/invalid-function-05.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +<Parameters> + <Parameter> + <Term>x1</Term> + </Parameter> +</Parameters> +</Function> diff --git a/test/Index/Inputs/CommentXML/invalid-function-06.xml b/test/Index/Inputs/CommentXML/invalid-function-06.xml new file mode 100644 index 0000000000..5419c677aa --- /dev/null +++ b/test/Index/Inputs/CommentXML/invalid-function-06.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function> +<Name>aaa</Name> +<Abstract><Para>Aaa <monospaced></monospaced>.</Para></Abstract> +</Function> diff --git a/test/Index/Inputs/CommentXML/invalid-function-07.xml b/test/Index/Inputs/CommentXML/invalid-function-07.xml new file mode 100644 index 0000000000..ce7eccec1e --- /dev/null +++ b/test/Index/Inputs/CommentXML/invalid-function-07.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +<Parameters> + <Parameter> + <Name>x1</Name> + <Index>-1</Index> + <Direction isExplicit="0">in</Direction> + <Discussion><Para>Bbb</Para></Discussion> + </Parameter> +</Parameters> +</Function> diff --git a/test/Index/Inputs/CommentXML/invalid-function-08.xml b/test/Index/Inputs/CommentXML/invalid-function-08.xml new file mode 100644 index 0000000000..66e69e8172 --- /dev/null +++ b/test/Index/Inputs/CommentXML/invalid-function-08.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +<Parameters> + <Parameter> + <Name>x1</Name> + <Index>0</Index> + <Direction isExplicit="aaa">in</Direction> + <Discussion><Para>Bbb</Para></Discussion> + </Parameter> +</Parameters> +</Function> diff --git a/test/Index/Inputs/CommentXML/invalid-function-09.xml b/test/Index/Inputs/CommentXML/invalid-function-09.xml new file mode 100644 index 0000000000..39617b6a87 --- /dev/null +++ b/test/Index/Inputs/CommentXML/invalid-function-09.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +<Parameters> + <Parameter> + <Name>x1</Name> + <Index>0</Index> + <Direction isExplicit="0">aaa</Direction> + <Discussion><Para>Bbb</Para></Discussion> + </Parameter> +</Parameters> +</Function> diff --git a/test/Index/Inputs/CommentXML/invalid-function-10.xml b/test/Index/Inputs/CommentXML/invalid-function-10.xml new file mode 100644 index 0000000000..ccce4bbe56 --- /dev/null +++ b/test/Index/Inputs/CommentXML/invalid-function-10.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +<TemplateParameters> + <Parameter> + <Name>x1</Name> + </Parameter> +</TemplateParameters> +</Function> + diff --git a/test/Index/Inputs/CommentXML/invalid-function-11.xml b/test/Index/Inputs/CommentXML/invalid-function-11.xml new file mode 100644 index 0000000000..167911e9e7 --- /dev/null +++ b/test/Index/Inputs/CommentXML/invalid-function-11.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +<TemplateParameters> + <Parameter> + <Name>x1</Name> + <Index>aaa</Index> + <Discussion><Para>Bbb</Para></Discussion> + </Parameter> +</TemplateParameters> +</Function> + diff --git a/test/Index/Inputs/CommentXML/invalid-function-12.xml b/test/Index/Inputs/CommentXML/invalid-function-12.xml new file mode 100644 index 0000000000..f5b5e03e33 --- /dev/null +++ b/test/Index/Inputs/CommentXML/invalid-function-12.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function templateKind="aaa"> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +</Function> + diff --git a/test/Index/Inputs/CommentXML/valid-class-01.xml b/test/Index/Inputs/CommentXML/valid-class-01.xml new file mode 100644 index 0000000000..bd893e62d5 --- /dev/null +++ b/test/Index/Inputs/CommentXML/valid-class-01.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<Class> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +</Class> diff --git a/test/Index/Inputs/CommentXML/valid-class-02.xml b/test/Index/Inputs/CommentXML/valid-class-02.xml new file mode 100644 index 0000000000..2e20a921f7 --- /dev/null +++ b/test/Index/Inputs/CommentXML/valid-class-02.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<Class templateKind="template"> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +</Class> diff --git a/test/Index/Inputs/CommentXML/valid-class-03.xml b/test/Index/Inputs/CommentXML/valid-class-03.xml new file mode 100644 index 0000000000..2ce1a2c98d --- /dev/null +++ b/test/Index/Inputs/CommentXML/valid-class-03.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<Class templateKind="specialization"> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +</Class> diff --git a/test/Index/Inputs/CommentXML/valid-class-04.xml b/test/Index/Inputs/CommentXML/valid-class-04.xml new file mode 100644 index 0000000000..da1522d85a --- /dev/null +++ b/test/Index/Inputs/CommentXML/valid-class-04.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<Class templateKind="partialSpecialization"> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +</Class> diff --git a/test/Index/Inputs/CommentXML/valid-function-01.xml b/test/Index/Inputs/CommentXML/valid-function-01.xml new file mode 100644 index 0000000000..02060e7fb7 --- /dev/null +++ b/test/Index/Inputs/CommentXML/valid-function-01.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +</Function> diff --git a/test/Index/Inputs/CommentXML/valid-function-02.xml b/test/Index/Inputs/CommentXML/valid-function-02.xml new file mode 100644 index 0000000000..989d6a7c14 --- /dev/null +++ b/test/Index/Inputs/CommentXML/valid-function-02.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function> +<Name>aaa</Name> +<Abstract><Para>Aaa <bold>bbb</bold> <monospaced>ccc</monospaced> <emphasized>ddd</emphasized>.</Para></Abstract> +</Function> diff --git a/test/Index/Inputs/CommentXML/valid-function-03.xml b/test/Index/Inputs/CommentXML/valid-function-03.xml new file mode 100644 index 0000000000..891211d81c --- /dev/null +++ b/test/Index/Inputs/CommentXML/valid-function-03.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +<Parameters> + <Parameter> + <Name>x1</Name> + <Direction isExplicit="0">in</Direction> + <Discussion><Para>Bbb</Para></Discussion> + </Parameter> +</Parameters> +</Function> diff --git a/test/Index/Inputs/CommentXML/valid-function-04.xml b/test/Index/Inputs/CommentXML/valid-function-04.xml new file mode 100644 index 0000000000..b65b3e92ff --- /dev/null +++ b/test/Index/Inputs/CommentXML/valid-function-04.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +<Parameters> + <Parameter> + <Name>x1</Name> + <Index>0</Index> + <Direction isExplicit="0">in</Direction> + <Discussion><Para>Bbb</Para></Discussion> + </Parameter> +</Parameters> +</Function> diff --git a/test/Index/Inputs/CommentXML/valid-function-05.xml b/test/Index/Inputs/CommentXML/valid-function-05.xml new file mode 100644 index 0000000000..2dddbd7be2 --- /dev/null +++ b/test/Index/Inputs/CommentXML/valid-function-05.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +<Discussion> + <Para>Ccc</Para> +</Discussion> +</Function> diff --git a/test/Index/Inputs/CommentXML/valid-function-06.xml b/test/Index/Inputs/CommentXML/valid-function-06.xml new file mode 100644 index 0000000000..1df3aa42b8 --- /dev/null +++ b/test/Index/Inputs/CommentXML/valid-function-06.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +<ResultDiscussion><Para>Ccc.</Para></ResultDiscussion> +</Function> diff --git a/test/Index/Inputs/CommentXML/valid-function-07.xml b/test/Index/Inputs/CommentXML/valid-function-07.xml new file mode 100644 index 0000000000..1521e2aa16 --- /dev/null +++ b/test/Index/Inputs/CommentXML/valid-function-07.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +<Parameters> + <Parameter> + <Name>x2</Name> + <Index>0</Index> + <Direction isExplicit="0">in</Direction> + <Discussion><Para>Bbb</Para></Discussion> + </Parameter> + <Parameter> + <Name>x3</Name> + <Index>2</Index> + <Direction isExplicit="1">out</Direction> + <Discussion><Para>Ccc</Para></Discussion> + </Parameter> + <Parameter> + <Name>x1</Name> + <Direction isExplicit="1">in,out</Direction> + <Discussion><Para>Ddd</Para></Discussion> + </Parameter> +</Parameters> +<ResultDiscussion><Para>Eee.</Para></ResultDiscussion> +<Discussion> + <Para>Fff</Para> +</Discussion> +</Function> + diff --git a/test/Index/Inputs/CommentXML/valid-function-08.xml b/test/Index/Inputs/CommentXML/valid-function-08.xml new file mode 100644 index 0000000000..481a6c0658 --- /dev/null +++ b/test/Index/Inputs/CommentXML/valid-function-08.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +<TemplateParameters> + <Parameter> + <Name>x1</Name> + <Index>0</Index> + <Discussion><Para>Bbb</Para></Discussion> + </Parameter> + <Parameter> + <Name>x2</Name> + <Discussion><Para>Ccc</Para></Discussion> + </Parameter> +</TemplateParameters> +</Function> + diff --git a/test/Index/Inputs/CommentXML/valid-function-09.xml b/test/Index/Inputs/CommentXML/valid-function-09.xml new file mode 100644 index 0000000000..cf4cc8fbd7 --- /dev/null +++ b/test/Index/Inputs/CommentXML/valid-function-09.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function templateKind="template"> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +</Function> + diff --git a/test/Index/Inputs/CommentXML/valid-function-10.xml b/test/Index/Inputs/CommentXML/valid-function-10.xml new file mode 100644 index 0000000000..4fadf30e6f --- /dev/null +++ b/test/Index/Inputs/CommentXML/valid-function-10.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<Function templateKind="specialization"> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +</Function> + diff --git a/test/Index/Inputs/CommentXML/valid-namespace-01.xml b/test/Index/Inputs/CommentXML/valid-namespace-01.xml new file mode 100644 index 0000000000..a73aad5548 --- /dev/null +++ b/test/Index/Inputs/CommentXML/valid-namespace-01.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<Namespace> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +</Namespace> + diff --git a/test/Index/Inputs/CommentXML/valid-other-01.xml b/test/Index/Inputs/CommentXML/valid-other-01.xml new file mode 100644 index 0000000000..46b8a4676f --- /dev/null +++ b/test/Index/Inputs/CommentXML/valid-other-01.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<Other> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +</Other> diff --git a/test/Index/Inputs/CommentXML/valid-typedef-01.xml b/test/Index/Inputs/CommentXML/valid-typedef-01.xml new file mode 100644 index 0000000000..1b7da8d83b --- /dev/null +++ b/test/Index/Inputs/CommentXML/valid-typedef-01.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<Typedef> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +</Typedef> + diff --git a/test/Index/Inputs/CommentXML/valid-typedef-02.xml b/test/Index/Inputs/CommentXML/valid-typedef-02.xml new file mode 100644 index 0000000000..2a3218906b --- /dev/null +++ b/test/Index/Inputs/CommentXML/valid-typedef-02.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<Typedef> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +<TemplateParameters> + <Parameter> + <Name>x1</Name> + <Index>0</Index> + <Discussion><Para>Bbb</Para></Discussion> + </Parameter> +</TemplateParameters> +<Parameters> + <Parameter> + <Name>x1</Name> + <Index>0</Index> + <Direction isExplicit="0">in</Direction> + <Discussion><Para>Ccc</Para></Discussion> + </Parameter> +</Parameters> +<ResultDiscussion><Para>Ddd.</Para></ResultDiscussion> +<Discussion> + <Para>Eee.</Para> +</Discussion> +</Typedef> + diff --git a/test/Index/Inputs/CommentXML/valid-variable-01.xml b/test/Index/Inputs/CommentXML/valid-variable-01.xml new file mode 100644 index 0000000000..e17da91da3 --- /dev/null +++ b/test/Index/Inputs/CommentXML/valid-variable-01.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<Variable> +<Name>aaa</Name> +<Abstract><Para>Aaa.</Para></Abstract> +</Variable> + diff --git a/test/Index/annotate-comments.cpp b/test/Index/annotate-comments.cpp index a13613954e..03aae9bee4 100644 --- a/test/Index/annotate-comments.cpp +++ b/test/Index/annotate-comments.cpp @@ -358,14 +358,84 @@ void comment_to_html_conversion_30(); /// <em>0<i</em> void comment_to_html_conversion_31(); +/// Aaa. +class comment_to_xml_conversion_01 { + /// \param aaa Blah blah. + comment_to_xml_conversion_01(int aaa); + + /// Aaa. + ~comment_to_xml_conversion_01(); + + /// \param aaa Blah blah. + int comment_to_xml_conversion_02(int aaa); + + /// \param aaa Blah blah. + static int comment_to_xml_conversion_03(int aaa); + + /// Aaa. + int comment_to_xml_conversion_04; + + /// Aaa. + static int comment_to_xml_conversion_05; + + /// \param aaa Blah blah. + void operator()(int aaa); + + /// Aaa. + operator bool(); + + /// Aaa. + typedef int comment_to_xml_conversion_06; + + /// Aaa. + using comment_to_xml_conversion_07 = int; + + template<typename T, typename U> + class comment_to_xml_conversion_08 { }; + + /// Aaa. + template<typename T> + using comment_to_xml_conversion_09 = comment_to_xml_conversion_08<T, int>; +}; + +/// Aaa. +template<typename T, typename U> +void comment_to_xml_conversion_10(T aaa, U bbb); + +/// Aaa. +template<> +void comment_to_xml_conversion_10(int aaa, int bbb); + +/// Aaa. +template<typename T, typename U> +class comment_to_xml_conversion_11 { }; + +/// Aaa. +template<typename T> +class comment_to_xml_conversion_11<T, int> { }; + +/// Aaa. +template<> +class comment_to_xml_conversion_11<int, int> { }; + +/// Aaa. +int comment_to_xml_conversion_12; + +/// Aaa. +namespace comment_to_xml_conversion_13 { + /// Aaa. + namespace comment_to_xml_conversion_14 { + } +} + #endif // RUN: rm -rf %t // RUN: mkdir %t -// RUN: %clang_cc1 -x c++ -emit-pch -o %t/out.pch %s -// RUN: %clang_cc1 -x c++ -include-pch %t/out.pch -fsyntax-only %s +// RUN: %clang_cc1 -x c++ -std=c++11 -emit-pch -o %t/out.pch %s +// RUN: %clang_cc1 -x c++ -std=c++11 -include-pch %t/out.pch -fsyntax-only %s -// RUN: c-index-test -test-load-source all %s > %t/out.c-index-direct +// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s -std=c++11 > %t/out.c-index-direct // RUN: c-index-test -test-load-tu %t/out.pch all > %t/out.c-index-pch // RUN: FileCheck %s -check-prefix=WRONG < %t/out.c-index-direct @@ -384,6 +454,9 @@ void comment_to_html_conversion_31(); // Ensure we don't pick up extra comments. // WRONG-NOT: IS_DOXYGEN_START{{.*}}IS_DOXYGEN_START{{.*}}BriefComment= // WRONG-NOT: IS_DOXYGEN_END{{.*}}IS_DOXYGEN_END{{.*}}BriefComment= +// +// Ensure that XML is not invalid +// WRONG-NOT: CommentXMLInvalid // RUN: FileCheck %s < %t/out.c-index-direct // RUN: FileCheck %s < %t/out.c-index-pch @@ -427,12 +500,12 @@ void comment_to_html_conversion_31(); // CHECK: annotate-comments.cpp:218:6: FunctionDecl=isdoxy49:{{.*}} BriefComment=[IS_DOXYGEN_START Aaa] // CHECK: annotate-comments.cpp:222:6: FunctionDecl=isdoxy50:{{.*}} BriefComment=[Returns ddd IS_DOXYGEN_END] -// CHECK: annotate-comments.cpp:225:6: FunctionDecl=comment_to_html_conversion_1:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p>] +// CHECK: annotate-comments.cpp:225:6: FunctionDecl=comment_to_html_conversion_1:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="225" column="6"><Name>comment_to_html_conversion_1</Name><USR>c:@F@comment_to_html_conversion_1#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Aaa.])))] -// CHECK: annotate-comments.cpp:228:6: FunctionDecl=comment_to_html_conversion_2:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p>] +// CHECK: annotate-comments.cpp:228:6: FunctionDecl=comment_to_html_conversion_2:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="228" column="6"><Name>comment_to_html_conversion_2</Name><USR>c:@F@comment_to_html_conversion_2#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph IsWhitespace @@ -440,7 +513,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_BlockCommand CommandName=[brief] // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Aaa.]))))] -// CHECK: annotate-comments.cpp:231:6: FunctionDecl=comment_to_html_conversion_3:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p>] +// CHECK: annotate-comments.cpp:231:6: FunctionDecl=comment_to_html_conversion_3:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="231" column="6"><Name>comment_to_html_conversion_3</Name><USR>c:@F@comment_to_html_conversion_3#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph IsWhitespace @@ -448,7 +521,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_BlockCommand CommandName=[short] // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Aaa.]))))] -// CHECK: annotate-comments.cpp:236:6: FunctionDecl=comment_to_html_conversion_4:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Bbb.</p><p> Aaa.</p>] +// CHECK: annotate-comments.cpp:236:6: FunctionDecl=comment_to_html_conversion_4:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Bbb.</p><p> Aaa.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="236" column="6"><Name>comment_to_html_conversion_4</Name><USR>c:@F@comment_to_html_conversion_4#</USR><Abstract><Para> Bbb.</Para></Abstract><Discussion><Para> Aaa.</Para></Discussion></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph @@ -458,7 +531,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_BlockCommand CommandName=[brief] // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Bbb.]))))] -// CHECK: annotate-comments.cpp:243:6: FunctionDecl=comment_to_html_conversion_5:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Bbb.</p><p> Aaa.</p><p> Ccc.</p>] +// CHECK: annotate-comments.cpp:243:6: FunctionDecl=comment_to_html_conversion_5:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Bbb.</p><p> Aaa.</p><p> Ccc.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="243" column="6"><Name>comment_to_html_conversion_5</Name><USR>c:@F@comment_to_html_conversion_5#</USR><Abstract><Para> Bbb.</Para></Abstract><Discussion><Para> Aaa.</Para><Para> Ccc.</Para></Discussion></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph @@ -470,7 +543,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_Text Text=[ Bbb.]))) // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Ccc.])))] -// CHECK: annotate-comments.cpp:247:6: FunctionDecl=comment_to_html_conversion_6:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa. </p><p class="para-brief"> Bbb.</p>] +// CHECK: annotate-comments.cpp:247:6: FunctionDecl=comment_to_html_conversion_6:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa. </p><p class="para-brief"> Bbb.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="247" column="6"><Name>comment_to_html_conversion_6</Name><USR>c:@F@comment_to_html_conversion_6#</USR><Abstract><Para> Aaa. </Para></Abstract><Discussion><Para> Bbb.</Para></Discussion></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph IsWhitespace @@ -482,7 +555,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_BlockCommand CommandName=[brief] // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Bbb.]))))] -// CHECK: annotate-comments.cpp:252:6: FunctionDecl=comment_to_html_conversion_7:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p class="para-returns"><span class="word-returns">Returns</span> Bbb.</p>] +// CHECK: annotate-comments.cpp:252:6: FunctionDecl=comment_to_html_conversion_7:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p class="para-returns"><span class="word-returns">Returns</span> Bbb.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="252" column="6"><Name>comment_to_html_conversion_7</Name><USR>c:@F@comment_to_html_conversion_7#</USR><Abstract><Para> Aaa.</Para></Abstract><ResultDiscussion><Para> Bbb.</Para></ResultDiscussion></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph @@ -492,7 +565,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_BlockCommand CommandName=[return] // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Bbb.]))))] -// CHECK: annotate-comments.cpp:257:6: FunctionDecl=comment_to_html_conversion_8:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p class="para-returns"><span class="word-returns">Returns</span> Bbb.</p>] +// CHECK: annotate-comments.cpp:257:6: FunctionDecl=comment_to_html_conversion_8:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p class="para-returns"><span class="word-returns">Returns</span> Bbb.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="257" column="6"><Name>comment_to_html_conversion_8</Name><USR>c:@F@comment_to_html_conversion_8#</USR><Abstract><Para> Aaa.</Para></Abstract><ResultDiscussion><Para> Bbb.</Para></ResultDiscussion></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph @@ -502,7 +575,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_BlockCommand CommandName=[returns] // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Bbb.]))))] -// CHECK: annotate-comments.cpp:262:6: FunctionDecl=comment_to_html_conversion_9:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p class="para-returns"><span class="word-returns">Returns</span> Bbb.</p>] +// CHECK: annotate-comments.cpp:262:6: FunctionDecl=comment_to_html_conversion_9:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p class="para-returns"><span class="word-returns">Returns</span> Bbb.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="262" column="6"><Name>comment_to_html_conversion_9</Name><USR>c:@F@comment_to_html_conversion_9#</USR><Abstract><Para> Aaa.</Para></Abstract><Discussion><Para> Bbb.</Para></Discussion></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph @@ -512,7 +585,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_BlockCommand CommandName=[result] // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Bbb.]))))] -// CHECK: annotate-comments.cpp:266:6: FunctionDecl=comment_to_html_conversion_10:{{.*}} FullCommentAsHTML=[<p class="para-returns"><span class="word-returns">Returns</span> Bbb.</p><p class="para-returns"><span class="word-returns">Returns</span> Aaa. </p>] +// CHECK: annotate-comments.cpp:266:6: FunctionDecl=comment_to_html_conversion_10:{{.*}} FullCommentAsHTML=[<p class="para-returns"><span class="word-returns">Returns</span> Bbb.</p><p class="para-returns"><span class="word-returns">Returns</span> Aaa. </p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="266" column="6"><Name>comment_to_html_conversion_10</Name><USR>c:@F@comment_to_html_conversion_10#</USR><ResultDiscussion><Para> Aaa. </Para></ResultDiscussion><Discussion><Para> Bbb.</Para></Discussion></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph IsWhitespace @@ -524,7 +597,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_BlockCommand CommandName=[returns] // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Bbb.]))))] -// CHECK: annotate-comments.cpp:273:6: FunctionDecl=comment_to_html_conversion_11:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p> Bbb.</p><p class="para-returns"><span class="word-returns">Returns</span> Ccc.</p>] +// CHECK: annotate-comments.cpp:273:6: FunctionDecl=comment_to_html_conversion_11:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p> Bbb.</p><p class="para-returns"><span class="word-returns">Returns</span> Ccc.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="273" column="6"><Name>comment_to_html_conversion_11</Name><USR>c:@F@comment_to_html_conversion_11#</USR><Abstract><Para> Aaa.</Para></Abstract><ResultDiscussion><Para> Ccc.</Para></ResultDiscussion><Discussion><Para> Bbb.</Para></Discussion></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph @@ -536,14 +609,14 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_BlockCommand CommandName=[returns] // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Ccc.]))))] -// CHECK: annotate-comments.cpp:276:6: FunctionDecl=comment_to_html_conversion_12:{{.*}} FullCommentAsHTML=[] +// CHECK: annotate-comments.cpp:276:6: FunctionDecl=comment_to_html_conversion_12:{{.*}} FullCommentAsHTML=[] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="276" column="6"><Name>comment_to_html_conversion_12</Name><USR>c:@F@comment_to_html_conversion_12#I#</USR></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph IsWhitespace // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)) // CHECK-NEXT: (CXComment_ParamCommand in implicitly ParamName=[] ParamIndex=Invalid // CHECK-NEXT: (CXComment_Paragraph IsWhitespace)))] -// CHECK: annotate-comments.cpp:279:6: FunctionDecl=comment_to_html_conversion_13:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa.</dd></dl>] +// CHECK: annotate-comments.cpp:279:6: FunctionDecl=comment_to_html_conversion_13:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa.</dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="279" column="6"><Name>comment_to_html_conversion_13</Name><USR>c:@F@comment_to_html_conversion_13#I#</USR><Parameters><Parameter><Name>x1</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa.</Para></Discussion></Parameter></Parameters></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph IsWhitespace @@ -551,7 +624,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_ParamCommand in implicitly ParamName=[x1] ParamIndex=0 // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Aaa.]))))] -// CHECK: annotate-comments.cpp:282:6: FunctionDecl=comment_to_html_conversion_14:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-invalid">zzz</dt><dd class="param-descr-index-invalid"> Aaa.</dd></dl>] +// CHECK: annotate-comments.cpp:282:6: FunctionDecl=comment_to_html_conversion_14:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-invalid">zzz</dt><dd class="param-descr-index-invalid"> Aaa.</dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="282" column="6"><Name>comment_to_html_conversion_14</Name><USR>c:@F@comment_to_html_conversion_14#I#</USR><Parameters><Parameter><Name>zzz</Name><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa.</Para></Discussion></Parameter></Parameters></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph IsWhitespace @@ -559,7 +632,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_ParamCommand in implicitly ParamName=[zzz] ParamIndex=Invalid // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Aaa.]))))] -// CHECK: annotate-comments.cpp:286:6: FunctionDecl=comment_to_html_conversion_15:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa.</dd><dt class="param-name-index-1">x2</dt><dd class="param-descr-index-1"> Bbb. </dd></dl>] +// CHECK: annotate-comments.cpp:286:6: FunctionDecl=comment_to_html_conversion_15:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa.</dd><dt class="param-name-index-1">x2</dt><dd class="param-descr-index-1"> Bbb. </dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="286" column="6"><Name>comment_to_html_conversion_15</Name><USR>c:@F@comment_to_html_conversion_15#I#I#</USR><Parameters><Parameter><Name>x1</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa.</Para></Discussion></Parameter><Parameter><Name>x2</Name><Index>1</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Bbb. </Para></Discussion></Parameter></Parameters></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph IsWhitespace @@ -571,7 +644,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_ParamCommand in implicitly ParamName=[x1] ParamIndex=0 // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Aaa.]))))] -// CHECK: annotate-comments.cpp:291:6: FunctionDecl=comment_to_html_conversion_16:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa.</dd><dt class="param-name-index-1">x2</dt><dd class="param-descr-index-1"> Bbb. </dd><dt class="param-name-index-invalid">zzz</dt><dd class="param-descr-index-invalid"> Aaa. </dd></dl>] +// CHECK: annotate-comments.cpp:291:6: FunctionDecl=comment_to_html_conversion_16:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa.</dd><dt class="param-name-index-1">x2</dt><dd class="param-descr-index-1"> Bbb. </dd><dt class="param-name-index-invalid">zzz</dt><dd class="param-descr-index-invalid"> Aaa. </dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="291" column="6"><Name>comment_to_html_conversion_16</Name><USR>c:@F@comment_to_html_conversion_16#I#I#</USR><Parameters><Parameter><Name>x1</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa.</Para></Discussion></Parameter><Parameter><Name>x2</Name><Index>1</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Bbb. </Para></Discussion></Parameter><Parameter><Name>zzz</Name><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa. </Para></Discussion></Parameter></Parameters></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph IsWhitespace @@ -587,7 +660,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_ParamCommand in implicitly ParamName=[x1] ParamIndex=0 // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Aaa.]))))] -// CHECK: annotate-comments.cpp:296:6: FunctionTemplate=comment_to_html_conversion_17:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">aaa</dt><dd class="param-descr-index-0"> Blah blah</dd></dl>] +// CHECK: annotate-comments.cpp:296:6: FunctionTemplate=comment_to_html_conversion_17:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">aaa</dt><dd class="param-descr-index-0"> Blah blah</dd></dl>] FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}annotate-comments.cpp" line="296" column="6"><Name>comment_to_html_conversion_17</Name><USR>c:@FT@>1#Tcomment_to_html_conversion_17#t0.0#</USR><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah</Para></Discussion></Parameter></Parameters></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph IsWhitespace @@ -598,7 +671,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_ParamCommand in implicitly ParamName=[aaa] ParamIndex=0 // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Blah blah]))))] -// CHECK: annotate-comments.cpp:301:6: FunctionTemplate=comment_to_html_conversion_18:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">aaa</dt><dd class="param-descr-index-0"> Blah blah</dd></dl>] +// CHECK: annotate-comments.cpp:301:6: FunctionTemplate=comment_to_html_conversion_18:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">aaa</dt><dd class="param-descr-index-0"> Blah blah</dd></dl>] FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}annotate-comments.cpp" line="301" column="6"><Name>comment_to_html_conversion_18</Name><USR>c:@FT@>1#Tcomment_to_html_conversion_18#t0.0#</USR><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah</Para></Discussion></Parameter></Parameters></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph IsWhitespace @@ -609,7 +682,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_ParamCommand in implicitly ParamName=[aaa] ParamIndex=0 // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Blah blah]))))] -// CHECK: annotate-comments.cpp:306:6: FunctionTemplate=comment_to_html_conversion_19:{{.*}} FullCommentAsHTML=[<dl><dt class="tparam-name-index-0">T1</dt><dd class="tparam-descr-index-0"> Aaa</dd><dt class="tparam-name-index-1">T2</dt><dd class="tparam-descr-index-1"> Bbb </dd></dl>] +// CHECK: annotate-comments.cpp:306:6: FunctionTemplate=comment_to_html_conversion_19:{{.*}} FullCommentAsHTML=[<dl><dt class="tparam-name-index-0">T1</dt><dd class="tparam-descr-index-0"> Aaa</dd><dt class="tparam-name-index-1">T2</dt><dd class="tparam-descr-index-1"> Bbb </dd></dl>] FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}annotate-comments.cpp" line="306" column="6"><Name>comment_to_html_conversion_19</Name><USR>c:@FT@>2#T#Tcomment_to_html_conversion_19#t0.0#t0.1#</USR><TemplateParameters><Parameter><Name>T1</Name><Index>0</Index><Discussion><Para> Aaa</Para></Discussion></Parameter><Parameter><Name>T2</Name><Index>1</Index><Discussion><Para> Bbb </Para></Discussion></Parameter></TemplateParameters></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph IsWhitespace @@ -621,7 +694,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_TParamCommand ParamName=[T1] ParamPosition={0} // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Aaa]))))] -// CHECK: annotate-comments.cpp:313:6: FunctionTemplate=comment_to_html_conversion_20:{{.*}} FullCommentAsHTML=[<dl><dt class="tparam-name-index-0">T1</dt><dd class="tparam-descr-index-0"> Aaa</dd><dt class="tparam-name-index-1">T2</dt><dd class="tparam-descr-index-1"> Bbb </dd><dt class="tparam-name-index-2">V</dt><dd class="tparam-descr-index-2"> Ccc </dd><dt class="tparam-name-index-invalid">U</dt><dd class="tparam-descr-index-invalid"> Zzz </dd></dl>] +// CHECK: annotate-comments.cpp:313:6: FunctionTemplate=comment_to_html_conversion_20:{{.*}} FullCommentAsHTML=[<dl><dt class="tparam-name-index-0">T1</dt><dd class="tparam-descr-index-0"> Aaa</dd><dt class="tparam-name-index-1">T2</dt><dd class="tparam-descr-index-1"> Bbb </dd><dt class="tparam-name-index-2">V</dt><dd class="tparam-descr-index-2"> Ccc </dd><dt class="tparam-name-index-invalid">U</dt><dd class="tparam-descr-index-invalid"> Zzz </dd></dl>] FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}annotate-comments.cpp" line="313" column="6"><Name>comment_to_html_conversion_20</Name><USR>c:@FT@>3#T#T#NIcomment_to_html_conversion_20#t0.0#t0.1#</USR><TemplateParameters><Parameter><Name>T1</Name><Index>0</Index><Discussion><Para> Aaa</Para></Discussion></Parameter><Parameter><Name>T2</Name><Index>1</Index><Discussion><Para> Bbb </Para></Discussion></Parameter><Parameter><Name>V</Name><Index>2</Index><Discussion><Para> Ccc </Para></Discussion></Parameter><Parameter><Name>U</Name><Discussion><Para> Zzz </Para></Discussion></Parameter></TemplateParameters></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph IsWhitespace @@ -641,7 +714,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_TParamCommand ParamName=[T1] ParamPosition={0} // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Aaa]))))] -// CHECK: annotate-comments.cpp:320:6: FunctionTemplate=comment_to_html_conversion_21:{{.*}} FullCommentAsHTML=[<dl><dt class="tparam-name-index-0">TTT</dt><dd class="tparam-descr-index-0"> Ddd </dd><dt class="tparam-name-index-other">C</dt><dd class="tparam-descr-index-other"> Ccc </dd><dt class="tparam-name-index-other">T</dt><dd class="tparam-descr-index-other"> Aaa </dd><dt class="tparam-name-index-other">TT</dt><dd class="tparam-descr-index-other"> Bbb</dd></dl>] +// CHECK: annotate-comments.cpp:320:6: FunctionTemplate=comment_to_html_conversion_21:{{.*}} FullCommentAsHTML=[<dl><dt class="tparam-name-index-0">TTT</dt><dd class="tparam-descr-index-0"> Ddd </dd><dt class="tparam-name-index-other">C</dt><dd class="tparam-descr-index-other"> Ccc </dd><dt class="tparam-name-index-other">T</dt><dd class="tparam-descr-index-other"> Aaa </dd><dt class="tparam-name-index-other">TT</dt><dd class="tparam-descr-index-other"> Bbb</dd></dl>] FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}annotate-comments.cpp" line="320" column="6"><Name>comment_to_html_conversion_21</Name><USR>c:@FT@>1#t>2#t>1#T#Tcomment_to_html_conversion_21#</USR><TemplateParameters><Parameter><Name>TTT</Name><Index>0</Index><Discussion><Para> Ddd </Para></Discussion></Parameter><Parameter><Name>C</Name><Discussion><Para> Ccc </Para></Discussion></Parameter><Parameter><Name>T</Name><Discussion><Para> Aaa </Para></Discussion></Parameter><Parameter><Name>TT</Name><Discussion><Para> Bbb</Para></Discussion></Parameter></TemplateParameters></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph IsWhitespace @@ -661,7 +734,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_TParamCommand ParamName=[TT] ParamPosition={0, 0} // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Bbb]))))] -// CHECK: annotate-comments.cpp:329:6: FunctionDecl=comment_to_html_conversion_22:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p> Bbb.</p><dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Ccc. </dd><dt class="param-name-index-1">x2</dt><dd class="param-descr-index-1"> Ddd. </dd></dl><p class="para-returns"><span class="word-returns">Returns</span> Eee.</p>] +// CHECK: annotate-comments.cpp:329:6: FunctionDecl=comment_to_html_conversion_22:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p> Bbb.</p><dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Ccc. </dd><dt class="param-name-index-1">x2</dt><dd class="param-descr-index-1"> Ddd. </dd></dl><p class="para-returns"><span class="word-returns">Returns</span> Eee.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="329" column="6"><Name>comment_to_html_conversion_22</Name><USR>c:@F@comment_to_html_conversion_22#I#I#</USR><Abstract><Para> Aaa.</Para></Abstract><Parameters><Parameter><Name>x1</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Ccc. </Para></Discussion></Parameter><Parameter><Name>x2</Name><Index>1</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Ddd. </Para></Discussion></Parameter></Parameters><ResultDiscussion><Para> Eee.</Para></ResultDiscussion><Discussion><Para> Bbb.</Para></Discussion></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph IsWhitespace @@ -684,7 +757,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_BlockCommand CommandName=[returns] // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Eee.]))))] -// CHECK: annotate-comments.cpp:332:6: FunctionDecl=comment_to_html_conversion_23:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <br><a href="http://example.com/">Aaa</a></p>] +// CHECK: annotate-comments.cpp:332:6: FunctionDecl=comment_to_html_conversion_23:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <br><a href="http://example.com/">Aaa</a></p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="332" column="6"><Name>comment_to_html_conversion_23</Name><USR>c:@F@comment_to_html_conversion_23#</USR><Abstract><Para> <rawHTML><![CDATA[<br>]]></rawHTML><rawHTML><![CDATA[<a href="http://example.com/">]]></rawHTML>Aaa<rawHTML></a></rawHTML></Para></Abstract></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph @@ -693,7 +766,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_HTMLStartTag Name=[a] Attrs: href=http://example.com/) // CHECK-NEXT: (CXComment_Text Text=[Aaa]) // CHECK-NEXT: (CXComment_HTMLEndTag Name=[a])))] -// CHECK: annotate-comments.cpp:338:6: FunctionDecl=comment_to_html_conversion_24:{{.*}} FullCommentAsHTML=[<pre> <a href="http://example.com/">Aaa</a>\n <a href='http://example.com/'>Aaa</a></pre>] +// CHECK: annotate-comments.cpp:338:6: FunctionDecl=comment_to_html_conversion_24:{{.*}} FullCommentAsHTML=[<pre> <a href="http://example.com/">Aaa</a>\n <a href='http://example.com/'>Aaa</a></pre>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="338" column="6"><Name>comment_to_html_conversion_24</Name><USR>c:@F@comment_to_html_conversion_24#</USR><Discussion><Verbatim kind="verbatim"> <a href="http://example.com/">Aaa</a>\n <a href='http://example.com/'>Aaa</a></Verbatim></Discussion></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph IsWhitespace @@ -701,13 +774,13 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_VerbatimBlockCommand CommandName=[verbatim] // CHECK-NEXT: (CXComment_VerbatimBlockLine Text=[ <a href="http://example.com/">Aaa</a>]) // CHECK-NEXT: (CXComment_VerbatimBlockLine Text=[ <a href='http://example.com/'>Aaa</a>])))] -// CHECK: annotate-comments.cpp:341:6: FunctionDecl=comment_to_html_conversion_25:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <b>Aaa</b></p>] +// CHECK: annotate-comments.cpp:341:6: FunctionDecl=comment_to_html_conversion_25:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <b>Aaa</b></p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="341" column="6"><Name>comment_to_html_conversion_25</Name><USR>c:@F@comment_to_html_conversion_25#</USR><Abstract><Para> <bold>Aaa</bold></Para></Abstract></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace) // CHECK-NEXT: (CXComment_InlineCommand CommandName=[b] RenderBold Arg[0]=Aaa)))] -// CHECK: annotate-comments.cpp:344:6: FunctionDecl=comment_to_html_conversion_26:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <tt>Aaa</tt> <tt>Bbb</tt></p>] +// CHECK: annotate-comments.cpp:344:6: FunctionDecl=comment_to_html_conversion_26:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <tt>Aaa</tt> <tt>Bbb</tt></p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="344" column="6"><Name>comment_to_html_conversion_26</Name><USR>c:@F@comment_to_html_conversion_26#</USR><Abstract><Para> <monospaced>Aaa</monospaced> <monospaced>Bbb</monospaced></Para></Abstract></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph @@ -715,7 +788,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_InlineCommand CommandName=[c] RenderMonospaced Arg[0]=Aaa) // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace) // CHECK-NEXT: (CXComment_InlineCommand CommandName=[p] RenderMonospaced Arg[0]=Bbb)))] -// CHECK: annotate-comments.cpp:347:6: FunctionDecl=comment_to_html_conversion_27:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <em>Aaa</em> <em>Bbb</em> <em>Ccc</em></p>] +// CHECK: annotate-comments.cpp:347:6: FunctionDecl=comment_to_html_conversion_27:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <em>Aaa</em> <em>Bbb</em> <em>Ccc</em></p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="347" column="6"><Name>comment_to_html_conversion_27</Name><USR>c:@F@comment_to_html_conversion_27#</USR><Abstract><Para> <emphasized>Aaa</emphasized> <emphasized>Bbb</emphasized> <emphasized>Ccc</emphasized></Para></Abstract></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph @@ -725,7 +798,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_InlineCommand CommandName=[e] RenderEmphasized Arg[0]=Bbb) // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace) // CHECK-NEXT: (CXComment_InlineCommand CommandName=[em] RenderEmphasized Arg[0]=Ccc)))] -// CHECK: annotate-comments.cpp:350:6: FunctionDecl=comment_to_html_conversion_28:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <em>1<2</em> <em>3<4</em> <em>5<6</em> </p><dl><dt class="tparam-name-index-invalid">9<10</dt><dd class="tparam-descr-index-invalid"> bbb</dd></dl><dl><dt class="param-name-index-invalid">7<8</dt><dd class="param-descr-index-invalid"> aaa </dd></dl>] +// CHECK: annotate-comments.cpp:350:6: FunctionDecl=comment_to_html_conversion_28:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <em>1<2</em> <em>3<4</em> <em>5<6</em> </p><dl><dt class="tparam-name-index-invalid">9<10</dt><dd class="tparam-descr-index-invalid"> bbb</dd></dl><dl><dt class="param-name-index-invalid">7<8</dt><dd class="param-descr-index-invalid"> aaa </dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="350" column="6"><Name>comment_to_html_conversion_28</Name><USR>c:@F@comment_to_html_conversion_28#</USR><Abstract><Para> <emphasized>1<2</emphasized> <emphasized>3<4</emphasized> <emphasized>5<6</emphasized> </Para></Abstract><TemplateParameters><Parameter><Name>9<10</Name><Discussion><Para> bbb</Para></Discussion></Parameter></TemplateParameters><Parameters><Parameter><Name>7<8</Name><Direction isExplicit="0">in</Direction><Discussion><Para> aaa </Para></Discussion></Parameter></Parameters></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph @@ -742,7 +815,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_TParamCommand ParamName=[9<10] ParamPosition=Invalid // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ bbb]))))] -// CHECK: annotate-comments.cpp:353:6: FunctionDecl=comment_to_html_conversion_29:{{.*}} FullCommentAsHTML=[<p class="para-brief"> \ @ & $ # < > % " . ::</p>] +// CHECK: annotate-comments.cpp:353:6: FunctionDecl=comment_to_html_conversion_29:{{.*}} FullCommentAsHTML=[<p class="para-brief"> \ @ & $ # < > % " . ::</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="353" column="6"><Name>comment_to_html_conversion_29</Name><USR>c:@F@comment_to_html_conversion_29#</USR><Abstract><Para> \ @ & $ # < > % " . ::</Para></Abstract></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph @@ -768,7 +841,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_Text Text=[.]) // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace) // CHECK-NEXT: (CXComment_Text Text=[::])))] -// CHECK: annotate-comments.cpp:356:6: FunctionDecl=comment_to_html_conversion_30:{{.*}} FullCommentAsHTML=[<p class="para-brief"> & < > "</p>] +// CHECK: annotate-comments.cpp:356:6: FunctionDecl=comment_to_html_conversion_30:{{.*}} FullCommentAsHTML=[<p class="para-brief"> & < > "</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="356" column="6"><Name>comment_to_html_conversion_30</Name><USR>c:@F@comment_to_html_conversion_30#</USR><Abstract><Para> & < > "</Para></Abstract></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph @@ -780,7 +853,7 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_Text Text=[>]) // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace) // CHECK-NEXT: (CXComment_Text Text=["])))] -// CHECK: annotate-comments.cpp:359:6: FunctionDecl=comment_to_html_conversion_31:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <em>0<i</em></p>] +// CHECK: annotate-comments.cpp:359:6: FunctionDecl=comment_to_html_conversion_31:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <em>0<i</em></p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="359" column="6"><Name>comment_to_html_conversion_31</Name><USR>c:@F@comment_to_html_conversion_31#</USR><Abstract><Para> <rawHTML><![CDATA[<em>]]></rawHTML>0<i<rawHTML></em></rawHTML></Para></Abstract></Function>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph @@ -791,3 +864,24 @@ void comment_to_html_conversion_31(); // CHECK-NEXT: (CXComment_Text Text=[i]) // CHECK-NEXT: (CXComment_HTMLEndTag Name=[em])))] +// CHECK: annotate-comments.cpp:362:7: ClassDecl=comment_to_xml_conversion_01:{{.*}} FullCommentAsXML=[<Class file="{{[^"]+}}annotate-comments.cpp" line="362" column="7"><Name>comment_to_xml_conversion_01</Name><USR>c:@C@comment_to_xml_conversion_01</USR><Abstract><Para> Aaa.</Para></Abstract></Class>] +// CHECK: annotate-comments.cpp:364:3: CXXConstructor=comment_to_xml_conversion_01:{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="364" column="3"><Name>comment_to_xml_conversion_01</Name><USR>c:@C@comment_to_xml_conversion_01@F@comment_to_xml_conversion_01#I#</USR><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah.</Para></Discussion></Parameter></Parameters></Function>] +// CHECK: annotate-comments.cpp:367:3: CXXDestructor=~comment_to_xml_conversion_01:{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="367" column="3"><Name>~comment_to_xml_conversion_01</Name><USR>c:@C@comment_to_xml_conversion_01@F@~comment_to_xml_conversion_01#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>] +// CHECK: annotate-comments.cpp:370:7: CXXMethod=comment_to_xml_conversion_02:{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="370" column="7"><Name>comment_to_xml_conversion_02</Name><USR>c:@C@comment_to_xml_conversion_01@F@comment_to_xml_conversion_02#I#</USR><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah.</Para></Discussion></Parameter></Parameters></Function>] +// CHECK: annotate-comments.cpp:373:14: CXXMethod=comment_to_xml_conversion_03:{{.*}} FullCommentAsXML=[<Function isClassMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="373" column="14"><Name>comment_to_xml_conversion_03</Name><USR>c:@C@comment_to_xml_conversion_01@F@comment_to_xml_conversion_03#I#S</USR><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah.</Para></Discussion></Parameter></Parameters></Function>] +// CHECK: annotate-comments.cpp:376:7: FieldDecl=comment_to_xml_conversion_04:{{.*}} FullCommentAsXML=[<Variable file="{{[^"]+}}annotate-comments.cpp" line="376" column="7"><Name>comment_to_xml_conversion_04</Name><USR>c:@C@comment_to_xml_conversion_01@FI@comment_to_xml_conversion_04</USR><Abstract><Para> Aaa.</Para></Abstract></Variable>] +// CHECK: annotate-comments.cpp:379:14: VarDecl=comment_to_xml_conversion_05:{{.*}} FullCommentAsXML=[<Variable file="{{[^"]+}}annotate-comments.cpp" line="379" column="14"><Name>comment_to_xml_conversion_05</Name><USR>c:@C@comment_to_xml_conversion_01@comment_to_xml_conversion_05</USR><Abstract><Para> Aaa.</Para></Abstract></Variable>] +// CHECK: annotate-comments.cpp:382:8: CXXMethod=operator():{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="382" column="8"><Name>operator()</Name><USR>c:@C@comment_to_xml_conversion_01@F@operator()#I#</USR><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah.</Para></Discussion></Parameter></Parameters></Function>] +// CHECK: annotate-comments.cpp:385:3: CXXConversion=operator _Bool:{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="385" column="3"><Name>operator _Bool</Name><USR>c:@C@comment_to_xml_conversion_01@F@operator _Bool#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>] +// CHECK: annotate-comments.cpp:388:15: TypedefDecl=comment_to_xml_conversion_06:{{.*}} FullCommentAsXML=[<Typedef file="{{[^"]+}}annotate-comments.cpp" line="388" column="15"><Name>comment_to_xml_conversion_06</Name><USR>c:annotate-comments.cpp@7933@C@comment_to_xml_conversion_01@T@comment_to_xml_conversion_06</USR><Abstract><Para> Aaa.</Para></Abstract></Typedef>] +// CHECK: annotate-comments.cpp:391:9: TypeAliasDecl=comment_to_xml_conversion_07:{{.*}} FullCommentAsXML=[<Typedef file="{{[^"]+}}annotate-comments.cpp" line="391" column="9"><Name>comment_to_xml_conversion_07</Name><USR>c:@C@comment_to_xml_conversion_01@comment_to_xml_conversion_07</USR><Abstract><Para> Aaa.</Para></Abstract></Typedef>] +// CHECK: annotate-comments.cpp:398:3: UnexposedDecl=comment_to_xml_conversion_09:{{.*}} FullCommentAsXML=[<Typedef file="{{[^"]+}}annotate-comments.cpp" line="398" column="3"><Name>comment_to_xml_conversion_09</Name><USR>c:@C@comment_to_xml_conversion_01@comment_to_xml_conversion_09</USR><Abstract><Para> Aaa.</Para></Abstract></Typedef>] +// CHECK: annotate-comments.cpp:403:6: FunctionTemplate=comment_to_xml_conversion_10:{{.*}} FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}annotate-comments.cpp" line="403" column="6"><Name>comment_to_xml_conversion_10</Name><USR>c:@FT@>2#T#Tcomment_to_xml_conversion_10#t0.0#t0.1#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>] +// CHECK: annotate-comments.cpp:407:6: FunctionDecl=comment_to_xml_conversion_10:{{.*}} FullCommentAsXML=[<Function templateKind="specialization" file="{{[^"]+}}annotate-comments.cpp" line="407" column="6"><Name>comment_to_xml_conversion_10</Name><USR>c:@F@comment_to_xml_conversion_10<#I#I>#I#I#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>] +// CHECK: annotate-comments.cpp:411:7: ClassTemplate=comment_to_xml_conversion_11:{{.*}} FullCommentAsXML=[<Class templateKind="template" file="{{[^"]+}}annotate-comments.cpp" line="411" column="7"><Name>comment_to_xml_conversion_11</Name><USR>c:@CT>2#T#T@comment_to_xml_conversion_11</USR><Abstract><Para> Aaa.</Para></Abstract></Class>] +// CHECK: annotate-comments.cpp:415:7: ClassTemplatePartialSpecialization=comment_to_xml_conversion_11:{{.*}} FullCommentAsXML=[<Class templateKind="partialSpecialization" file="{{[^"]+}}annotate-comments.cpp" line="415" column="7"><Name>comment_to_xml_conversion_11</Name><USR>c:@CP>1#T@comment_to_xml_conversion_11>#t0.0#I</USR><Abstract><Para> Aaa.</Para></Abstract></Class>] +// CHECK: annotate-comments.cpp:419:7: ClassDecl=comment_to_xml_conversion_11:{{.*}} FullCommentAsXML=[<Class templateKind="specialization" file="{{[^"]+}}annotate-comments.cpp" line="419" column="7"><Name>comment_to_xml_conversion_11</Name><USR>c:@C@comment_to_xml_conversion_11>#I#I</USR><Abstract><Para> Aaa.</Para></Abstract></Class>] +// CHECK: annotate-comments.cpp:422:5: VarDecl=comment_to_xml_conversion_12:{{.*}} FullCommentAsXML=[<Variable file="{{[^"]+}}annotate-comments.cpp" line="422" column="5"><Name>comment_to_xml_conversion_12</Name><USR>c:@comment_to_xml_conversion_12</USR><Abstract><Para> Aaa.</Para></Abstract></Variable>] +// CHECK: annotate-comments.cpp:425:11: Namespace=comment_to_xml_conversion_13:{{.*}} FullCommentAsXML=[<Namespace file="{{[^"]+}}annotate-comments.cpp" line="425" column="11"><Name>comment_to_xml_conversion_13</Name><USR>c:@N@comment_to_xml_conversion_13</USR><Abstract><Para> Aaa.</Para></Abstract></Namespace>] +// CHECK: annotate-comments.cpp:427:13: Namespace=comment_to_xml_conversion_14:{{.*}} FullCommentAsXML=[<Namespace file="{{[^"]+}}annotate-comments.cpp" line="427" column="13"><Name>comment_to_xml_conversion_14</Name><USR>c:@N@comment_to_xml_conversion_13@N@comment_to_xml_conversion_14</USR><Abstract><Para> Aaa.</Para></Abstract></Namespace>] + diff --git a/test/Index/comment-xml-schema.c b/test/Index/comment-xml-schema.c new file mode 100644 index 0000000000..05a4ecaf00 --- /dev/null +++ b/test/Index/comment-xml-schema.c @@ -0,0 +1,42 @@ +// REQUIRES: xmllint + +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-other-01.xml +// +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-01.xml +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-02.xml +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-03.xml +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-04.xml +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-05.xml +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-06.xml +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-07.xml +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-08.xml +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-09.xml +// +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-class-01.xml +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-class-02.xml +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-class-03.xml +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-class-04.xml +// +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-variable-01.xml +// +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-namespace-01.xml +// +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-typedef-01.xml +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-typedef-02.xml + + +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-01.xml 2>&1 | FileCheck %s -check-prefix=INVALID +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-02.xml 2>&1 | FileCheck %s -check-prefix=INVALID +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-03.xml 2>&1 | FileCheck %s -check-prefix=INVALID +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-04.xml 2>&1 | FileCheck %s -check-prefix=INVALID +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-05.xml 2>&1 | FileCheck %s -check-prefix=INVALID +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-06.xml 2>&1 | FileCheck %s -check-prefix=INVALID +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-07.xml 2>&1 | FileCheck %s -check-prefix=INVALID +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-08.xml 2>&1 | FileCheck %s -check-prefix=INVALID +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-09.xml 2>&1 | FileCheck %s -check-prefix=INVALID +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-10.xml 2>&1 | FileCheck %s -check-prefix=INVALID +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-11.xml 2>&1 | FileCheck %s -check-prefix=INVALID +// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-12.xml 2>&1 | FileCheck %s -check-prefix=INVALID + +// CHECK-INVALID: fails to validate + diff --git a/test/Sema/warn-documentation.cpp b/test/Sema/warn-documentation.cpp index c6ba0151b9..d116c3f8ca 100644 --- a/test/Sema/warn-documentation.cpp +++ b/test/Sema/warn-documentation.cpp @@ -1,5 +1,9 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wdocumentation -Wdocumentation-pedantic -verify %s +// This file contains lots of corner cases, so ensure that XML we generate is not invalid. +// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s | FileCheck %s -check-prefix=WRONG +// WRONG-NOT: CommentXMLInvalid + // expected-warning@+1 {{expected quoted string after equals sign}} /// <a href=> int test_html1(int); diff --git a/test/lit.cfg b/test/lit.cfg index 1fc6059326..7bc9620926 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -259,3 +259,7 @@ else: if llc_props['enable_assertions']: config.available_features.add('asserts') + +if lit.util.which('xmllint'): + config.available_features.add('xmllint') + diff --git a/tools/c-index-test/CMakeLists.txt b/tools/c-index-test/CMakeLists.txt index afe49ed6a7..6379194c55 100644 --- a/tools/c-index-test/CMakeLists.txt +++ b/tools/c-index-test/CMakeLists.txt @@ -14,3 +14,10 @@ target_link_libraries(c-index-test set_target_properties(c-index-test PROPERTIES LINKER_LANGUAGE CXX) + +# If libxml2 is available, make it available for c-index-test. +if (LIBXML2_FOUND) + add_definitions(${LIBXML2_DEFINITIONS} "-DCLANG_HAVE_LIBXML") + include_directories(${LIBXML2_INCLUDE_DIR}) + target_link_libraries(c-index-test ${LIBXML2_LIBRARIES}) +endif() diff --git a/tools/c-index-test/Makefile b/tools/c-index-test/Makefile index 932dbb2d16..25478e1f96 100644 --- a/tools/c-index-test/Makefile +++ b/tools/c-index-test/Makefile @@ -28,3 +28,6 @@ USEDLIBS = clang.a clangFrontend.a clangDriver.a \ clangBasic.a include $(CLANG_LEVEL)/Makefile + +LIBS += "$(LIBXML2_LIBS)" +CPPFLAGS += "$(LIBXML2_INC)" diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index 4af2548895..f9b5cdf96b 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -2,12 +2,19 @@ #include "clang-c/Index.h" #include "clang-c/CXCompilationDatabase.h" +#include "llvm/Config/config.h" #include <ctype.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <assert.h> +#ifdef CLANG_HAVE_LIBXML +#include <libxml/parser.h> +#include <libxml/relaxng.h> +#include <libxml/xmlerror.h> +#endif + /******************************************************************************/ /* Utility functions. */ /******************************************************************************/ @@ -179,6 +186,19 @@ int parse_remapped_files(int argc, const char **argv, int start_arg, return 0; } +static const char *parse_comments_schema(int argc, const char **argv) { + const char *CommentsSchemaArg = "-comments-xml-schema="; + const char *CommentSchemaFile = NULL; + + if (argc == 0) + return CommentSchemaFile; + + if (!strncmp(argv[0], CommentsSchemaArg, strlen(CommentsSchemaArg))) + CommentSchemaFile = argv[0] + strlen(CommentsSchemaArg); + + return CommentSchemaFile; +} + /******************************************************************************/ /* Pretty-printing. */ /******************************************************************************/ @@ -212,6 +232,10 @@ static void PrintCXStringAndDispose(CXString Str) { clang_disposeString(Str); } +static void PrintCXStringWithPrefix(const char *Prefix, CXString Str) { + PrintCStringWithPrefix(Prefix, clang_getCString(Str)); +} + static void PrintCXStringWithPrefixAndDispose(const char *Prefix, CXString Str) { PrintCStringWithPrefix(Prefix, clang_getCString(Str)); @@ -437,7 +461,60 @@ static void DumpCXComment(CXComment Comment) { printf("]"); } -static void PrintCursorComments(CXCursor Cursor) { +typedef struct { + const char *CommentSchemaFile; +#ifdef CLANG_HAVE_LIBXML + xmlRelaxNGParserCtxtPtr RNGParser; + xmlRelaxNGPtr Schema; +#endif +} CommentXMLValidationData; + +static void ValidateCommentXML(const char *Str, + CommentXMLValidationData *ValidationData) { +#ifdef CLANG_HAVE_LIBXML + xmlDocPtr Doc; + xmlRelaxNGValidCtxtPtr ValidationCtxt; + int status; + + if (!ValidationData || !ValidationData->CommentSchemaFile) + return; + + if (!ValidationData->RNGParser) { + ValidationData->RNGParser = + xmlRelaxNGNewParserCtxt(ValidationData->CommentSchemaFile); + ValidationData->Schema = xmlRelaxNGParse(ValidationData->RNGParser); + } + if (!ValidationData->RNGParser) { + printf(" libXMLError"); + return; + } + + Doc = xmlParseDoc((const xmlChar *) Str); + + if (!Doc) { + xmlErrorPtr Error = xmlGetLastError(); + printf(" CommentXMLInvalid [not well-formed XML: %s]", Error->message); + return; + } + + ValidationCtxt = xmlRelaxNGNewValidCtxt(ValidationData->Schema); + status = xmlRelaxNGValidateDoc(ValidationCtxt, Doc); + if (!status) + printf(" CommentXMLValid"); + else if (status > 0) { + xmlErrorPtr Error = xmlGetLastError(); + printf(" CommentXMLInvalid [not vaild XML: %s]", Error->message); + } else + printf(" libXMLError"); + + xmlRelaxNGFreeValidCtxt(ValidationCtxt); + xmlFreeDoc(Doc); +#endif +} + +static void PrintCursorComments(CXTranslationUnit TU, + CXCursor Cursor, + CommentXMLValidationData *ValidationData) { { CXString RawComment; const char *RawCommentCString; @@ -464,12 +541,21 @@ static void PrintCursorComments(CXCursor Cursor) { if (clang_Comment_getKind(Comment) != CXComment_Null) { PrintCXStringWithPrefixAndDispose("FullCommentAsHTML", clang_FullComment_getAsHTML(Comment)); + { + CXString XML; + XML = clang_FullComment_getAsXML(TU, Comment); + PrintCXStringWithPrefix("FullCommentAsXML", XML); + ValidateCommentXML(clang_getCString(XML), ValidationData); + clang_disposeString(XML); + } + DumpCXComment(Comment); } } } -static void PrintCursor(CXCursor Cursor) { +static void PrintCursor(CXCursor Cursor, + CommentXMLValidationData *ValidationData) { CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor); if (clang_isInvalid(Cursor.kind)) { CXString ks = clang_getCursorKindSpelling(Cursor.kind); @@ -674,7 +760,7 @@ static void PrintCursor(CXCursor Cursor) { PrintRange(RefNameRange, "RefName"); } - PrintCursorComments(Cursor); + PrintCursorComments(TU, Cursor, ValidationData); } } @@ -802,10 +888,11 @@ static void PrintCursorExtent(CXCursor C) { PrintRange(extent, "Extent"); } -/* Data used by all of the visitors. */ -typedef struct { +/* Data used by the visitors. */ +typedef struct { CXTranslationUnit TU; enum CXCursorKind *Filter; + CommentXMLValidationData ValidationData; } VisitorData; @@ -819,7 +906,7 @@ enum CXChildVisitResult FilteredPrintingVisitor(CXCursor Cursor, clang_getSpellingLocation(Loc, 0, &line, &column, 0); printf("// %s: %s:%d:%d: ", FileCheckPrefix, GetCursorSource(Cursor), line, column); - PrintCursor(Cursor); + PrintCursor(Cursor, &Data->ValidationData); PrintCursorExtent(Cursor); printf("\n"); return CXChildVisit_Recurse; @@ -872,7 +959,7 @@ static enum CXChildVisitResult FunctionScanVisitor(CXCursor Cursor, } else if (Ref.kind != CXCursor_FunctionDecl) { printf("// %s: %s:%d:%d: ", FileCheckPrefix, GetCursorSource(Ref), curLine, curColumn); - PrintCursor(Ref); + PrintCursor(Ref, &Data->ValidationData); printf("\n"); } } @@ -959,7 +1046,7 @@ static enum CXChildVisitResult PrintLinkage(CXCursor cursor, CXCursor p, } if (linkage) { - PrintCursor(cursor); + PrintCursor(cursor, NULL); printf("linkage=%s\n", linkage); } @@ -975,7 +1062,7 @@ static enum CXChildVisitResult PrintTypeKind(CXCursor cursor, CXCursor p, if (!clang_isInvalid(clang_getCursorKind(cursor))) { CXType T = clang_getCursorType(cursor); CXString S = clang_getTypeKindSpelling(T.kind); - PrintCursor(cursor); + PrintCursor(cursor, NULL); printf(" typekind=%s", clang_getCString(S)); if (clang_isConstQualifiedType(T)) printf(" const"); @@ -1035,7 +1122,8 @@ static enum CXChildVisitResult PrintTypeKind(CXCursor cursor, CXCursor p, static int perform_test_load(CXIndex Idx, CXTranslationUnit TU, const char *filter, const char *prefix, CXCursorVisitor Visitor, - PostVisitTU PV) { + PostVisitTU PV, + const char *CommentSchemaFile) { if (prefix) FileCheckPrefix = prefix; @@ -1066,6 +1154,11 @@ static int perform_test_load(CXIndex Idx, CXTranslationUnit TU, Data.TU = TU; Data.Filter = ck; + Data.ValidationData.CommentSchemaFile = CommentSchemaFile; +#ifdef CLANG_HAVE_LIBXML + Data.ValidationData.RNGParser = NULL; + Data.ValidationData.Schema = NULL; +#endif clang_visitChildren(clang_getTranslationUnitCursor(TU), Visitor, &Data); } @@ -1097,7 +1190,7 @@ int perform_test_load_tu(const char *file, const char *filter, return 1; } - result = perform_test_load(Idx, TU, filter, prefix, Visitor, PV); + result = perform_test_load(Idx, TU, filter, prefix, Visitor, PV, NULL); clang_disposeIndex(Idx); return result; } @@ -1107,6 +1200,7 @@ int perform_test_load_source(int argc, const char **argv, PostVisitTU PV) { CXIndex Idx; CXTranslationUnit TU; + const char *CommentSchemaFile; struct CXUnsavedFile *unsaved_files = 0; int num_unsaved_files = 0; int result; @@ -1116,6 +1210,11 @@ int perform_test_load_source(int argc, const char **argv, !strcmp(filter, "local-display"))? 1 : 0, /* displayDiagnosics=*/0); + if ((CommentSchemaFile = parse_comments_schema(argc, argv))) { + argc--; + argv++; + } + if (parse_remapped_files(argc, argv, 0, &unsaved_files, &num_unsaved_files)) { clang_disposeIndex(Idx); return -1; @@ -1133,7 +1232,8 @@ int perform_test_load_source(int argc, const char **argv, return 1; } - result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV); + result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV, + CommentSchemaFile); free_remapped_files(unsaved_files, num_unsaved_files); clang_disposeIndex(Idx); return result; @@ -1197,7 +1297,7 @@ int perform_test_reparse_source(int argc, const char **argv, int trials, return -1; } - result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV); + result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV, NULL); free_remapped_files(unsaved_files, num_unsaved_files); clang_disposeIndex(Idx); @@ -1217,7 +1317,7 @@ static void print_cursor_file_scan(CXTranslationUnit TU, CXCursor cursor, printf("-%s", prefix); PrintExtent(stdout, start_line, start_col, end_line, end_col); printf(" "); - PrintCursor(cursor); + PrintCursor(cursor, NULL); printf("\n"); } @@ -1814,7 +1914,7 @@ static int inspect_cursor_at(int argc, const char **argv) { unsigned line, column; clang_getSpellingLocation(CursorLoc, 0, &line, &column, 0); printf("%d:%d ", line, column); - PrintCursor(Cursor); + PrintCursor(Cursor, NULL); PrintCursorExtent(Cursor); Spelling = clang_getCursorSpelling(Cursor); cspell = clang_getCString(Spelling); @@ -1859,7 +1959,7 @@ static enum CXVisitorResult findFileRefsVisit(void *context, if (clang_Range_isNull(range)) return CXVisit_Continue; - PrintCursor(cursor); + PrintCursor(cursor, NULL); PrintRange(range, ""); printf("\n"); return CXVisit_Continue; @@ -1943,7 +2043,7 @@ static int find_file_refs_at(int argc, const char **argv) { if (I + 1 == Repeats) { CXCursorAndRangeVisitor visitor = { 0, findFileRefsVisit }; - PrintCursor(Cursor); + PrintCursor(Cursor, NULL); printf("\n"); clang_findReferencesInFile(Cursor, file, visitor); free(Locations[Loc].filename); @@ -2141,7 +2241,7 @@ static void printEntityInfo(const char *cb, for (i = 0; i != info->numAttributes; ++i) { const CXIdxAttrInfo *Attr = info->attributes[i]; printf(" <attribute>: "); - PrintCursor(Attr->cursor); + PrintCursor(Attr->cursor, NULL); } } @@ -2149,7 +2249,7 @@ static void printBaseClassInfo(CXClientData client_data, const CXIdxBaseClassInfo *info) { printEntityInfo(" <base>", client_data, info->base); printf(" | cursor: "); - PrintCursor(info->cursor); + PrintCursor(info->cursor, NULL); printf(" | loc: "); printCXIndexLoc(info->loc, client_data); } @@ -2161,7 +2261,7 @@ static void printProtocolList(const CXIdxObjCProtocolRefListInfo *ProtoInfo, printEntityInfo(" <protocol>", client_data, ProtoInfo->protocols[i]->protocol); printf(" | cursor: "); - PrintCursor(ProtoInfo->protocols[i]->cursor); + PrintCursor(ProtoInfo->protocols[i]->cursor, NULL); printf(" | loc: "); printCXIndexLoc(ProtoInfo->protocols[i]->loc, client_data); printf("\n"); @@ -2251,7 +2351,7 @@ static void index_indexDeclaration(CXClientData client_data, printEntityInfo("[indexDeclaration]", client_data, info->entityInfo); printf(" | cursor: "); - PrintCursor(info->cursor); + PrintCursor(info->cursor, NULL); printf(" | loc: "); printCXIndexLoc(info->loc, client_data); printf(" | semantic-container: "); @@ -2266,7 +2366,7 @@ static void index_indexDeclaration(CXClientData client_data, for (i = 0; i != info->numAttributes; ++i) { const CXIdxAttrInfo *Attr = info->attributes[i]; printf(" <attribute>: "); - PrintCursor(Attr->cursor); + PrintCursor(Attr->cursor, NULL); printf("\n"); } @@ -2289,7 +2389,7 @@ static void index_indexDeclaration(CXClientData client_data, printEntityInfo(" <ObjCCategoryInfo>: class", client_data, CatInfo->objcClass); printf(" | cursor: "); - PrintCursor(CatInfo->classCursor); + PrintCursor(CatInfo->classCursor, NULL); printf(" | loc: "); printCXIndexLoc(CatInfo->classLoc, client_data); printf("\n"); @@ -2333,7 +2433,7 @@ static void index_indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo *info) { printEntityInfo("[indexEntityReference]", client_data, info->referencedEntity); printf(" | cursor: "); - PrintCursor(info->cursor); + PrintCursor(info->cursor, NULL); printf(" | loc: "); printCXIndexLoc(info->loc, client_data); printEntityInfo(" | <parent>:", client_data, info->parentEntity); @@ -2602,7 +2702,7 @@ int perform_token_annotation(int argc, const char **argv) { PrintExtent(stdout, start_line, start_column, end_line, end_column); if (!clang_isInvalid(cursors[i].kind)) { printf(" "); - PrintCursor(cursors[i]); + PrintCursor(cursors[i], NULL); } printf("\n"); } @@ -3255,6 +3355,10 @@ void thread_runner(void *client_data_v) { } int main(int argc, const char **argv) { +#ifdef CLANG_HAVE_LIBXML + LIBXML_TEST_VERSION +#endif + thread_info client_data; if (getenv("CINDEXTEST_NOTHREADS")) diff --git a/tools/libclang/CXComment.cpp b/tools/libclang/CXComment.cpp index fe6fddb795..acb4353418 100644 --- a/tools/libclang/CXComment.cpp +++ b/tools/libclang/CXComment.cpp @@ -14,9 +14,14 @@ #include "clang-c/Index.h" #include "CXString.h" #include "CXComment.h" +#include "CXCursor.h" +#include "CXTranslationUnit.h" #include "clang/AST/CommentVisitor.h" +#include "clang/AST/Decl.h" +#include "clang/Frontend/ASTUnit.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" @@ -826,3 +831,386 @@ CXString clang_FullComment_getAsHTML(CXComment CXC) { } // end extern "C" +namespace { +class CommentASTToXMLConverter : + public ConstCommentVisitor<CommentASTToXMLConverter> { +public: + /// \param Str accumulator for XML. + CommentASTToXMLConverter(const SourceManager &SM, + SmallVectorImpl<char> &Str) : + SM(SM), Result(Str) { } + + // Inline content. + void visitTextComment(const TextComment *C); + void visitInlineCommandComment(const InlineCommandComment *C); + void visitHTMLStartTagComment(const HTMLStartTagComment *C); + void visitHTMLEndTagComment(const HTMLEndTagComment *C); + + // Block content. + void visitParagraphComment(const ParagraphComment *C); + void visitBlockCommandComment(const BlockCommandComment *C); + void visitParamCommandComment(const ParamCommandComment *C); + void visitTParamCommandComment(const TParamCommandComment *C); + void visitVerbatimBlockComment(const VerbatimBlockComment *C); + void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C); + void visitVerbatimLineComment(const VerbatimLineComment *C); + + void visitFullComment(const FullComment *C); + + // Helpers. + void appendToResultWithXMLEscaping(StringRef S); + +private: + const SourceManager &SM; + /// Output stream for XML. + llvm::raw_svector_ostream Result; +}; +} // end unnamed namespace + +void CommentASTToXMLConverter::visitTextComment(const TextComment *C) { + appendToResultWithXMLEscaping(C->getText()); +} + +void CommentASTToXMLConverter::visitInlineCommandComment(const InlineCommandComment *C) { + // Nothing to render if no arguments supplied. + if (C->getNumArgs() == 0) + return; + + // Nothing to render if argument is empty. + StringRef Arg0 = C->getArgText(0); + if (Arg0.empty()) + return; + + switch (C->getRenderKind()) { + case InlineCommandComment::RenderNormal: + for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) { + appendToResultWithXMLEscaping(C->getArgText(i)); + Result << " "; + } + return; + case InlineCommandComment::RenderBold: + assert(C->getNumArgs() == 1); + Result << "<bold>"; + appendToResultWithXMLEscaping(Arg0); + Result << "</bold>"; + return; + case InlineCommandComment::RenderMonospaced: + assert(C->getNumArgs() == 1); + Result << "<monospaced>"; + appendToResultWithXMLEscaping(Arg0); + Result << "</monospaced>"; + return; + case InlineCommandComment::RenderEmphasized: + assert(C->getNumArgs() == 1); + Result << "<emphasized>"; + appendToResultWithXMLEscaping(Arg0); + Result << "</emphasized>"; + return; + } +} + +void CommentASTToXMLConverter::visitHTMLStartTagComment(const HTMLStartTagComment *C) { + Result << "<rawHTML><![CDATA["; + PrintHTMLStartTagComment(C, Result); + Result << "]]></rawHTML>"; +} + +void CommentASTToXMLConverter::visitHTMLEndTagComment(const HTMLEndTagComment *C) { + Result << "<rawHTML></" << C->getTagName() << "></rawHTML>"; +} + +void CommentASTToXMLConverter::visitParagraphComment(const ParagraphComment *C) { + if (C->isWhitespace()) + return; + + Result << "<Para>"; + for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); + I != E; ++I) { + visit(*I); + } + Result << "</Para>"; +} + +void CommentASTToXMLConverter::visitBlockCommandComment(const BlockCommandComment *C) { + visit(C->getParagraph()); +} + +void CommentASTToXMLConverter::visitParamCommandComment(const ParamCommandComment *C) { + Result << "<Parameter><Name>"; + appendToResultWithXMLEscaping(C->getParamName()); + Result << "</Name>"; + + if (C->isParamIndexValid()) + Result << "<Index>" << C->getParamIndex() << "</Index>"; + + Result << "<Direction isExplicit=\"" << C->isDirectionExplicit() << "\">"; + switch (C->getDirection()) { + case ParamCommandComment::In: + Result << "in"; + break; + case ParamCommandComment::Out: + Result << "out"; + break; + case ParamCommandComment::InOut: + Result << "in,out"; + break; + } + Result << "</Direction><Discussion>"; + visit(C->getParagraph()); + Result << "</Discussion></Parameter>"; +} + +void CommentASTToXMLConverter::visitTParamCommandComment( + const TParamCommandComment *C) { + Result << "<Parameter><Name>"; + appendToResultWithXMLEscaping(C->getParamName()); + Result << "</Name>"; + + if (C->isPositionValid() && C->getDepth() == 1) { + Result << "<Index>" << C->getIndex(0) << "</Index>"; + } + + Result << "<Discussion>"; + visit(C->getParagraph()); + Result << "</Discussion></Parameter>"; +} + +void CommentASTToXMLConverter::visitVerbatimBlockComment( + const VerbatimBlockComment *C) { + unsigned NumLines = C->getNumLines(); + if (NumLines == 0) + return; + + Result << llvm::StringSwitch<const char *>(C->getCommandName()) + .Case("code", "<Verbatim kind=\"code\">") + .Default("<Verbatim kind=\"verbatim\">"); + for (unsigned i = 0; i != NumLines; ++i) { + appendToResultWithXMLEscaping(C->getText(i)); + if (i + 1 != NumLines) + Result << '\n'; + } + Result << "</Verbatim>"; +} + +void CommentASTToXMLConverter::visitVerbatimBlockLineComment( + const VerbatimBlockLineComment *C) { + llvm_unreachable("should not see this AST node"); +} + +void CommentASTToXMLConverter::visitVerbatimLineComment( + const VerbatimLineComment *C) { + Result << "<Verbatim kind=\"verbatim\">"; + appendToResultWithXMLEscaping(C->getText()); + Result << "</Verbatim>"; +} + +void CommentASTToXMLConverter::visitFullComment(const FullComment *C) { + FullCommentParts Parts(C); + + const DeclInfo *DI = C->getDeclInfo(); + StringRef RootEndTag; + if (DI) { + switch (DI->getKind()) { + case DeclInfo::OtherKind: + RootEndTag = "</Other>"; + Result << "<Other"; + break; + case DeclInfo::FunctionKind: + RootEndTag = "</Function>"; + Result << "<Function"; + switch (DI->TemplateKind) { + case DeclInfo::NotTemplate: + break; + case DeclInfo::Template: + Result << " templateKind=\"template\""; + break; + case DeclInfo::TemplateSpecialization: + Result << " templateKind=\"specialization\""; + break; + case DeclInfo::TemplatePartialSpecialization: + llvm_unreachable("partial specializations of functions " + "are not allowed in C++"); + } + if (DI->IsInstanceMethod) + Result << " isInstanceMethod=\"1\""; + if (DI->IsClassMethod) + Result << " isClassMethod=\"1\""; + break; + case DeclInfo::ClassKind: + RootEndTag = "</Class>"; + Result << "<Class"; + switch (DI->TemplateKind) { + case DeclInfo::NotTemplate: + break; + case DeclInfo::Template: + Result << " templateKind=\"template\""; + break; + case DeclInfo::TemplateSpecialization: + Result << " templateKind=\"specialization\""; + break; + case DeclInfo::TemplatePartialSpecialization: + Result << " templateKind=\"partialSpecialization\""; + break; + } + break; + case DeclInfo::VariableKind: + RootEndTag = "</Variable>"; + Result << "<Variable"; + break; + case DeclInfo::NamespaceKind: + RootEndTag = "</Namespace>"; + Result << "<Namespace"; + break; + case DeclInfo::TypedefKind: + RootEndTag = "</Typedef>"; + Result << "<Typedef"; + break; + } + + { + // Print line and column number. + SourceLocation Loc = DI->ThisDecl->getLocation(); + std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc); + FileID FID = LocInfo.first; + unsigned FileOffset = LocInfo.second; + + if (!FID.isInvalid()) { + if (const FileEntry *FE = SM.getFileEntryForID(FID)) { + Result << " file=\""; + appendToResultWithXMLEscaping(FE->getName()); + Result << "\""; + } + Result << " line=\"" << SM.getLineNumber(FID, FileOffset) + << "\" column=\"" << SM.getColumnNumber(FID, FileOffset) + << "\""; + } + } + + // Finish the root tag. + Result << ">"; + + bool FoundName = false; + if (const NamedDecl *ND = dyn_cast<NamedDecl>(DI->ThisDecl)) { + if (DeclarationName DeclName = ND->getDeclName()) { + Result << "<Name>"; + std::string Name = DeclName.getAsString(); + appendToResultWithXMLEscaping(Name); + FoundName = true; + Result << "</Name>"; + } + } + if (!FoundName) + Result << "<Name><anonymous></Name>"; + + { + // Print USR. + SmallString<128> USR; + cxcursor::getDeclCursorUSR(DI->ThisDecl, USR); + if (!USR.empty()) { + Result << "<USR>"; + appendToResultWithXMLEscaping(USR); + Result << "</USR>"; + } + } + } else { + // No DeclInfo -- just emit some root tag and name tag. + RootEndTag = "</Other>"; + Result << "<Other><Name>unknown</Name>"; + } + + bool FirstParagraphIsBrief = false; + if (Parts.Brief) { + Result << "<Abstract>"; + visit(Parts.Brief); + Result << "</Abstract>"; + } else if (Parts.FirstParagraph) { + Result << "<Abstract>"; + visit(Parts.FirstParagraph); + Result << "</Abstract>"; + FirstParagraphIsBrief = true; + } + + if (Parts.TParams.size() != 0) { + Result << "<TemplateParameters>"; + for (unsigned i = 0, e = Parts.TParams.size(); i != e; ++i) + visit(Parts.TParams[i]); + Result << "</TemplateParameters>"; + } + + if (Parts.Params.size() != 0) { + Result << "<Parameters>"; + for (unsigned i = 0, e = Parts.Params.size(); i != e; ++i) + visit(Parts.Params[i]); + Result << "</Parameters>"; + } + + if (Parts.Returns) { + Result << "<ResultDiscussion>"; + visit(Parts.Returns); + Result << "</ResultDiscussion>"; + } + + { + bool StartTagEmitted = false; + for (unsigned i = 0, e = Parts.MiscBlocks.size(); i != e; ++i) { + const Comment *C = Parts.MiscBlocks[i]; + if (FirstParagraphIsBrief && C == Parts.FirstParagraph) + continue; + if (!StartTagEmitted) { + Result << "<Discussion>"; + StartTagEmitted = true; + } + visit(C); + } + if (StartTagEmitted) + Result << "</Discussion>"; + } + + Result << RootEndTag; + + Result.flush(); +} + +void CommentASTToXMLConverter::appendToResultWithXMLEscaping(StringRef S) { + for (StringRef::iterator I = S.begin(), E = S.end(); I != E; ++I) { + const char C = *I; + switch (C) { + case '&': + Result << "&"; + break; + case '<': + Result << "<"; + break; + case '>': + Result << ">"; + break; + case '"': + Result << """; + break; + case '\'': + Result << "'"; + break; + default: + Result << C; + break; + } + } +} + +extern "C" { + +CXString clang_FullComment_getAsXML(CXTranslationUnit TU, CXComment CXC) { + const FullComment *FC = getASTNodeAs<FullComment>(CXC); + if (!FC) + return createCXString((const char *) 0); + + SourceManager &SM = static_cast<ASTUnit *>(TU->TUData)->getSourceManager(); + + SmallString<1024> XML; + CommentASTToXMLConverter Converter(SM, XML); + Converter.visit(FC); + return createCXString(XML.str(), /* DupString = */ true); +} + +} // end extern "C" + diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports index d796b154ad..610bd91c6a 100644 --- a/tools/libclang/libclang.exports +++ b/tools/libclang/libclang.exports @@ -50,6 +50,7 @@ clang_VerbatimBlockLineComment_getText clang_VerbatimLineComment_getText clang_HTMLTagComment_getAsString clang_FullComment_getAsHTML +clang_FullComment_getAsXML clang_annotateTokens clang_codeCompleteAt clang_codeCompleteGetContainerKind |