CXComment.cpp revision 8da68b8b03d72314b67ea44568e013ef79d93b40
1ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko//===- CXComment.cpp - libclang APIs for manipulating CXComments ----------===//
2ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko//
3ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko//                     The LLVM Compiler Infrastructure
4ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko//
5ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko// This file is distributed under the University of Illinois Open Source
6ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko// License. See LICENSE.TXT for details.
7ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko//
8ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko//===----------------------------------------------------------------------===//
9ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko//
10ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko// This file defines all libclang APIs related to walking comment AST.
11ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko//
12ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko//===----------------------------------------------------------------------===//
13ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
14ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko#include "clang-c/Index.h"
15ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko#include "CXString.h"
16ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko#include "CXComment.h"
17f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko#include "CXCursor.h"
18ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
19ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko#include "clang/AST/CommentVisitor.h"
20d1db12540e572d6e3d998a4b770a6b2c7267d7fcDmitri Gribenko#include "clang/AST/CommentCommandTraits.h"
21f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko#include "clang/AST/Decl.h"
22ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
23f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko#include "llvm/ADT/StringSwitch.h"
24ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko#include "llvm/Support/ErrorHandling.h"
253e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko#include "llvm/Support/raw_ostream.h"
26ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
27221a6d74d48fb3eaa73b68eb04f253080bedd5fdDmitri Gribenko#include <climits>
28221a6d74d48fb3eaa73b68eb04f253080bedd5fdDmitri Gribenko
29ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkousing namespace clang;
30ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkousing namespace clang::cxstring;
31ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkousing namespace clang::comments;
32ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkousing namespace clang::cxcomment;
33ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
34ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkoextern "C" {
35ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
36ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkoenum CXCommentKind clang_Comment_getKind(CXComment CXC) {
37ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const Comment *C = getASTNode(CXC);
38ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!C)
39ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_Null;
40ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
41ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  switch (C->getCommentKind()) {
42ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::NoCommentKind:
43ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_Null;
44ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
45ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::TextCommentKind:
46ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_Text;
47ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
48ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::InlineCommandCommentKind:
49ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_InlineCommand;
50ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
51ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::HTMLStartTagCommentKind:
52ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_HTMLStartTag;
53ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
54ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::HTMLEndTagCommentKind:
55ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_HTMLEndTag;
56ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
57ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::ParagraphCommentKind:
58ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_Paragraph;
59ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
60ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::BlockCommandCommentKind:
61ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_BlockCommand;
62ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
63ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::ParamCommandCommentKind:
64ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_ParamCommand;
65ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
6696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  case Comment::TParamCommandCommentKind:
6796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    return CXComment_TParamCommand;
6896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
69ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::VerbatimBlockCommentKind:
70ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_VerbatimBlockCommand;
71ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
72ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::VerbatimBlockLineCommentKind:
73ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_VerbatimBlockLine;
74ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
75ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::VerbatimLineCommentKind:
76ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_VerbatimLine;
77ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
78ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::FullCommentKind:
79ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_FullComment;
80ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
81ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  llvm_unreachable("unknown CommentKind");
82ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
83ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
84ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_Comment_getNumChildren(CXComment CXC) {
85ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const Comment *C = getASTNode(CXC);
86ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!C)
87ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return 0;
88ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
89ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return C->child_count();
90ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
91ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
92ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXComment clang_Comment_getChild(CXComment CXC, unsigned ChildIdx) {
93ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const Comment *C = getASTNode(CXC);
94ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!C || ChildIdx >= C->child_count())
95e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko    return createCXComment(NULL, NULL);
96ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
97e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  return createCXComment(*(C->child_begin() + ChildIdx), CXC.TranslationUnit);
98ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
99ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
100ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_Comment_isWhitespace(CXComment CXC) {
101ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const Comment *C = getASTNode(CXC);
102ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!C)
103ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return false;
104ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
105ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (const TextComment *TC = dyn_cast<TextComment>(C))
106ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return TC->isWhitespace();
107ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
108ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (const ParagraphComment *PC = dyn_cast<ParagraphComment>(C))
109ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return PC->isWhitespace();
110ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
111ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return false;
112ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
113ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
114ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_InlineContentComment_hasTrailingNewline(CXComment CXC) {
115ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const InlineContentComment *ICC = getASTNodeAs<InlineContentComment>(CXC);
116ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!ICC)
117ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return false;
118ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
119ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return ICC->hasTrailingNewline();
120ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
121ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
122ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_TextComment_getText(CXComment CXC) {
123ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const TextComment *TC = getASTNodeAs<TextComment>(CXC);
124ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!TC)
125ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
126ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
127ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(TC->getText(), /*DupString=*/ false);
128ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
129ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
130ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_InlineCommandComment_getCommandName(CXComment CXC) {
131ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
132ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!ICC)
133ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
134ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
135e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  const CommandTraits &Traits = getCommandTraits(CXC);
136e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  return createCXString(ICC->getCommandName(Traits), /*DupString=*/ false);
137ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
138ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
1392d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenkoenum CXCommentInlineCommandRenderKind
1402d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenkoclang_InlineCommandComment_getRenderKind(CXComment CXC) {
1412d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
1422d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  if (!ICC)
1432d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    return CXCommentInlineCommandRenderKind_Normal;
1442d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko
1452d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  switch (ICC->getRenderKind()) {
1462d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  case InlineCommandComment::RenderNormal:
1472d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    return CXCommentInlineCommandRenderKind_Normal;
1482d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko
1492d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  case InlineCommandComment::RenderBold:
1502d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    return CXCommentInlineCommandRenderKind_Bold;
1512d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko
1522d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  case InlineCommandComment::RenderMonospaced:
1532d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    return CXCommentInlineCommandRenderKind_Monospaced;
1542d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko
1552d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  case InlineCommandComment::RenderEmphasized:
1562d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    return CXCommentInlineCommandRenderKind_Emphasized;
1572d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  }
1582d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  llvm_unreachable("unknown InlineCommandComment::RenderKind");
1592d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko}
1602d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko
161ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_InlineCommandComment_getNumArgs(CXComment CXC) {
162ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
163ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!ICC)
164ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return 0;
165ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
166ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return ICC->getNumArgs();
167ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
168ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
169ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_InlineCommandComment_getArgText(CXComment CXC,
170ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                               unsigned ArgIdx) {
171ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
172ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!ICC || ArgIdx >= ICC->getNumArgs())
173ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
174ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
175ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(ICC->getArgText(ArgIdx), /*DupString=*/ false);
176ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
177ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
178ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_HTMLTagComment_getTagName(CXComment CXC) {
179ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const HTMLTagComment *HTC = getASTNodeAs<HTMLTagComment>(CXC);
180ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!HTC)
181ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
182ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
183ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(HTC->getTagName(), /*DupString=*/ false);
184ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
185ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
186ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_HTMLStartTagComment_isSelfClosing(CXComment CXC) {
187ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
188ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!HST)
189ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return false;
190ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
191ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return HST->isSelfClosing();
192ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
193ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
194ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_HTMLStartTag_getNumAttrs(CXComment CXC) {
195ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
196ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!HST)
197ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return 0;
198ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
199ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return HST->getNumAttrs();
200ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
201ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
202ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_HTMLStartTag_getAttrName(CXComment CXC, unsigned AttrIdx) {
203ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
204ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!HST || AttrIdx >= HST->getNumAttrs())
205ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
206ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
207ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(HST->getAttr(AttrIdx).Name, /*DupString=*/ false);
208ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
209ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
210ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_HTMLStartTag_getAttrValue(CXComment CXC, unsigned AttrIdx) {
211ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
212ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!HST || AttrIdx >= HST->getNumAttrs())
213ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
214ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
215ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(HST->getAttr(AttrIdx).Value, /*DupString=*/ false);
216ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
217ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
218ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_BlockCommandComment_getCommandName(CXComment CXC) {
219ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
220ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!BCC)
221ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
222ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
223e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  const CommandTraits &Traits = getCommandTraits(CXC);
224e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  return createCXString(BCC->getCommandName(Traits), /*DupString=*/ false);
225ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
226ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
227ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_BlockCommandComment_getNumArgs(CXComment CXC) {
228ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
229ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!BCC)
230ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return 0;
231ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
232ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return BCC->getNumArgs();
233ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
234ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
235ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_BlockCommandComment_getArgText(CXComment CXC,
236ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                              unsigned ArgIdx) {
237ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
238ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!BCC || ArgIdx >= BCC->getNumArgs())
239ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
240ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
241ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(BCC->getArgText(ArgIdx), /*DupString=*/ false);
242ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
243ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
244ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXComment clang_BlockCommandComment_getParagraph(CXComment CXC) {
245ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
246ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!BCC)
247e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko    return createCXComment(NULL, NULL);
248ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
249e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  return createCXComment(BCC->getParagraph(), CXC.TranslationUnit);
250ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
251ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
252ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_ParamCommandComment_getParamName(CXComment CXC) {
253ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
2541f8c529a2a938a5055f440aa063ea0b49eafae98Dmitri Gribenko  if (!PCC || !PCC->hasParamName())
255ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
256ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
257ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(PCC->getParamName(), /*DupString=*/ false);
258ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
259ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
260ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_ParamCommandComment_isParamIndexValid(CXComment CXC) {
261ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
262ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!PCC)
263ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return false;
264ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
265ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return PCC->isParamIndexValid();
266ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
267ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
268ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_ParamCommandComment_getParamIndex(CXComment CXC) {
269ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
270b740316a122b5ceaaa7cf50557b1b39af5fbbf5fDmitri Gribenko  if (!PCC || !PCC->isParamIndexValid())
271ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return ParamCommandComment::InvalidParamIndex;
272ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
273ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return PCC->getParamIndex();
274ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
275ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
276ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_ParamCommandComment_isDirectionExplicit(CXComment CXC) {
277ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
278ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!PCC)
279ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return false;
280ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
281ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return PCC->isDirectionExplicit();
282ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
283ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
284ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkoenum CXCommentParamPassDirection clang_ParamCommandComment_getDirection(
285ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                                            CXComment CXC) {
286ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
287ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!PCC)
288ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXCommentParamPassDirection_In;
289ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
290ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  switch (PCC->getDirection()) {
291ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case ParamCommandComment::In:
292ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXCommentParamPassDirection_In;
293ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
294ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case ParamCommandComment::Out:
295ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXCommentParamPassDirection_Out;
296ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
297ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case ParamCommandComment::InOut:
298ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXCommentParamPassDirection_InOut;
299ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
300ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  llvm_unreachable("unknown ParamCommandComment::PassDirection");
301ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
302ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
30396b098674908eaa59a9128f3305cda6fbbdad563Dmitri GribenkoCXString clang_TParamCommandComment_getParamName(CXComment CXC) {
30496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
30596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  if (!TPCC || !TPCC->hasParamName())
30696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    return createCXString((const char *) 0);
30796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
30896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  return createCXString(TPCC->getParamName(), /*DupString=*/ false);
30996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko}
31096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
31196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkounsigned clang_TParamCommandComment_isParamPositionValid(CXComment CXC) {
31296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
31396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  if (!TPCC)
31496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    return false;
31596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
31696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  return TPCC->isPositionValid();
31796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko}
31896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
31996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkounsigned clang_TParamCommandComment_getDepth(CXComment CXC) {
32096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
32196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  if (!TPCC || !TPCC->isPositionValid())
32296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    return 0;
32396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
32496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  return TPCC->getDepth();
32596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko}
32696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
32796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkounsigned clang_TParamCommandComment_getIndex(CXComment CXC, unsigned Depth) {
32896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
32996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  if (!TPCC || !TPCC->isPositionValid() || Depth >= TPCC->getDepth())
33096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    return 0;
33196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
33296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  return TPCC->getIndex(Depth);
33396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko}
33496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
335ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_VerbatimBlockLineComment_getText(CXComment CXC) {
336ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const VerbatimBlockLineComment *VBL =
337ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      getASTNodeAs<VerbatimBlockLineComment>(CXC);
338ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!VBL)
339ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
340ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
341ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(VBL->getText(), /*DupString=*/ false);
342ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
343ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
344ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_VerbatimLineComment_getText(CXComment CXC) {
345ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const VerbatimLineComment *VLC = getASTNodeAs<VerbatimLineComment>(CXC);
346ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!VLC)
347ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
348ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
349ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(VLC->getText(), /*DupString=*/ false);
350ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
351ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
352ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko} // end extern "C"
353ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
354ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko//===----------------------------------------------------------------------===//
355ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko// Helpers for converting comment AST to HTML.
356ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko//===----------------------------------------------------------------------===//
357ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
358ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkonamespace {
359ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
360e5db09cf6772332c14dc7dc541de53f918f89125Dmitri Gribenko/// This comparison will sort parameters with valid index by index and
361e5db09cf6772332c14dc7dc541de53f918f89125Dmitri Gribenko/// invalid (unresolved) parameters last.
362ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkoclass ParamCommandCommentCompareIndex {
363ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkopublic:
364ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  bool operator()(const ParamCommandComment *LHS,
365ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                  const ParamCommandComment *RHS) const {
366b740316a122b5ceaaa7cf50557b1b39af5fbbf5fDmitri Gribenko    unsigned LHSIndex = UINT_MAX;
367b740316a122b5ceaaa7cf50557b1b39af5fbbf5fDmitri Gribenko    unsigned RHSIndex = UINT_MAX;
368b740316a122b5ceaaa7cf50557b1b39af5fbbf5fDmitri Gribenko    if (LHS->isParamIndexValid())
369b740316a122b5ceaaa7cf50557b1b39af5fbbf5fDmitri Gribenko      LHSIndex = LHS->getParamIndex();
370b740316a122b5ceaaa7cf50557b1b39af5fbbf5fDmitri Gribenko    if (RHS->isParamIndexValid())
371b740316a122b5ceaaa7cf50557b1b39af5fbbf5fDmitri Gribenko      RHSIndex = RHS->getParamIndex();
372b740316a122b5ceaaa7cf50557b1b39af5fbbf5fDmitri Gribenko
373b740316a122b5ceaaa7cf50557b1b39af5fbbf5fDmitri Gribenko    return LHSIndex < RHSIndex;
374ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
375ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko};
376ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
37796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko/// This comparison will sort template parameters in the following order:
37896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko/// \li real template parameters (depth = 1) in index order;
37996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko/// \li all other names (depth > 1);
38096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko/// \li unresolved names.
38196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkoclass TParamCommandCommentComparePosition {
38296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkopublic:
38396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  bool operator()(const TParamCommandComment *LHS,
38496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko                  const TParamCommandComment *RHS) const {
38596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    // Sort unresolved names last.
38696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    if (!LHS->isPositionValid())
38796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko      return false;
38896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    if (!RHS->isPositionValid())
38996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko      return true;
39096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
39196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    if (LHS->getDepth() > 1)
39296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko      return false;
39396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    if (RHS->getDepth() > 1)
39496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko      return true;
39596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
39696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    // Sort template parameters in index order.
39796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    if (LHS->getDepth() == 1 && RHS->getDepth() == 1)
39896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko      return LHS->getIndex(0) < RHS->getIndex(0);
39996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
40096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    // Leave all other names in source order.
40196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    return true;
40296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  }
40396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko};
40496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
4052ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko/// Separate parts of a FullComment.
4062ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenkostruct FullCommentParts {
4072ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  /// Take a full comment apart and initialize members accordingly.
408e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  FullCommentParts(const FullComment *C,
409e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko                   const CommandTraits &Traits);
4102ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4112ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  const BlockContentComment *Brief;
4122ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  const ParagraphComment *FirstParagraph;
4132ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  const BlockCommandComment *Returns;
4142ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  SmallVector<const ParamCommandComment *, 8> Params;
4152ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  SmallVector<const TParamCommandComment *, 4> TParams;
4162ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  SmallVector<const BlockContentComment *, 8> MiscBlocks;
4172ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko};
4182ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
419e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri GribenkoFullCommentParts::FullCommentParts(const FullComment *C,
420e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko                                   const CommandTraits &Traits) :
4212ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    Brief(NULL), FirstParagraph(NULL), Returns(NULL) {
4222ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
4232ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko       I != E; ++I) {
4242ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    const Comment *Child = *I;
4252ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    if (!Child)
4262ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      continue;
4272ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    switch (Child->getCommentKind()) {
4282ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::NoCommentKind:
4292ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      continue;
4302ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4312ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::ParagraphCommentKind: {
4322ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      const ParagraphComment *PC = cast<ParagraphComment>(Child);
4332ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      if (PC->isWhitespace())
4342ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko        break;
4352ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      if (!FirstParagraph)
4362ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko        FirstParagraph = PC;
4372ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4382ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      MiscBlocks.push_back(PC);
4392ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      break;
4402ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    }
4412ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4422ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::BlockCommandCommentKind: {
4432ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      const BlockCommandComment *BCC = cast<BlockCommandComment>(Child);
444e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko      const CommandInfo *Info = Traits.getCommandInfo(BCC->getCommandID());
445e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko      if (!Brief && Info->IsBriefCommand) {
4462ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko        Brief = BCC;
4472ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko        break;
4482ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      }
449e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko      if (!Returns && Info->IsReturnsCommand) {
4502ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko        Returns = BCC;
4512ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko        break;
4522ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      }
4532ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      MiscBlocks.push_back(BCC);
4542ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      break;
4552ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    }
4562ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4572ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::ParamCommandCommentKind: {
4582ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      const ParamCommandComment *PCC = cast<ParamCommandComment>(Child);
4592ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      if (!PCC->hasParamName())
4602ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko        break;
4612ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4622ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      if (!PCC->isDirectionExplicit() && !PCC->hasNonWhitespaceParagraph())
4632ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko        break;
4642ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4652ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      Params.push_back(PCC);
4662ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      break;
4672ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    }
4682ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4692ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::TParamCommandCommentKind: {
4702ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      const TParamCommandComment *TPCC = cast<TParamCommandComment>(Child);
4712ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      if (!TPCC->hasParamName())
4722ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko        break;
4732ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4742ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      if (!TPCC->hasNonWhitespaceParagraph())
4752ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko        break;
4762ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4772ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      TParams.push_back(TPCC);
4782ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      break;
4792ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    }
4802ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4812ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::VerbatimBlockCommentKind:
4822ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      MiscBlocks.push_back(cast<BlockCommandComment>(Child));
4832ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      break;
4842ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
48562290ae569016345b79d4e11dd93abc300e5a681Dmitri Gribenko    case Comment::VerbatimLineCommentKind: {
48662290ae569016345b79d4e11dd93abc300e5a681Dmitri Gribenko      const VerbatimLineComment *VLC = cast<VerbatimLineComment>(Child);
487e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko      const CommandInfo *Info = Traits.getCommandInfo(VLC->getCommandID());
488e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko      if (!Info->IsDeclarationCommand)
48962290ae569016345b79d4e11dd93abc300e5a681Dmitri Gribenko        MiscBlocks.push_back(VLC);
49062290ae569016345b79d4e11dd93abc300e5a681Dmitri Gribenko      break;
49162290ae569016345b79d4e11dd93abc300e5a681Dmitri Gribenko    }
49262290ae569016345b79d4e11dd93abc300e5a681Dmitri Gribenko
4932ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::TextCommentKind:
4942ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::InlineCommandCommentKind:
4952ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::HTMLStartTagCommentKind:
4962ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::HTMLEndTagCommentKind:
4972ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::VerbatimBlockLineCommentKind:
4982ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::FullCommentKind:
4992ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      llvm_unreachable("AST node of this kind can't be a child of "
5002ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko                       "a FullComment");
5012ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    }
5022ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  }
5032ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
5042ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  // Sort params in order they are declared in the function prototype.
5052ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  // Unresolved parameters are put at the end of the list in the same order
5062ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  // they were seen in the comment.
5072ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  std::stable_sort(Params.begin(), Params.end(),
5082ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko                   ParamCommandCommentCompareIndex());
5092ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
5102ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  std::stable_sort(TParams.begin(), TParams.end(),
5112ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko                   TParamCommandCommentComparePosition());
5122ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko}
5132ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
5142ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenkovoid PrintHTMLStartTagComment(const HTMLStartTagComment *C,
5152ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko                              llvm::raw_svector_ostream &Result) {
5162ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  Result << "<" << C->getTagName();
5172ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
5182ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  if (C->getNumAttrs() != 0) {
5192ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    for (unsigned i = 0, e = C->getNumAttrs(); i != e; i++) {
5202ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      Result << " ";
5212ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      const HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
5222ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      Result << Attr.Name;
5232ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      if (!Attr.Value.empty())
5242ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko        Result << "=\"" << Attr.Value << "\"";
5252ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    }
5262ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  }
5272ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
5282ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  if (!C->isSelfClosing())
5292ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    Result << ">";
5302ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  else
5312ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    Result << "/>";
5322ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko}
5332ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
534ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkoclass CommentASTToHTMLConverter :
535ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    public ConstCommentVisitor<CommentASTToHTMLConverter> {
536ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkopublic:
5373e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  /// \param Str accumulator for HTML.
538e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  CommentASTToHTMLConverter(SmallVectorImpl<char> &Str,
539e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko                            const CommandTraits &Traits) :
540e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko      Result(Str), Traits(Traits)
541e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  { }
542ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
543ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  // Inline content.
544ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitTextComment(const TextComment *C);
545ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitInlineCommandComment(const InlineCommandComment *C);
546ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitHTMLStartTagComment(const HTMLStartTagComment *C);
547ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitHTMLEndTagComment(const HTMLEndTagComment *C);
548ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
549ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  // Block content.
550ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitParagraphComment(const ParagraphComment *C);
551ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitBlockCommandComment(const BlockCommandComment *C);
552ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitParamCommandComment(const ParamCommandComment *C);
55396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  void visitTParamCommandComment(const TParamCommandComment *C);
554ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitVerbatimBlockComment(const VerbatimBlockComment *C);
555ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
556ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitVerbatimLineComment(const VerbatimLineComment *C);
557ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
558ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitFullComment(const FullComment *C);
559ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
560ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  // Helpers.
561ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
562ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  /// Convert a paragraph that is not a block by itself (an argument to some
563ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  /// command).
564ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitNonStandaloneParagraphComment(const ParagraphComment *C);
565ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
566ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void appendToResultWithHTMLEscaping(StringRef S);
567ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
568ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkoprivate:
5693e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  /// Output stream for HTML.
5703e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  llvm::raw_svector_ostream Result;
571e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko
572e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  const CommandTraits &Traits;
573ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko};
574ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko} // end unnamed namespace
575ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
576ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitTextComment(const TextComment *C) {
577ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  appendToResultWithHTMLEscaping(C->getText());
578ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
579ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
580ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitInlineCommandComment(
581ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const InlineCommandComment *C) {
5822d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  // Nothing to render if no arguments supplied.
5832d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  if (C->getNumArgs() == 0)
5842d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    return;
5852d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko
5862d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  // Nothing to render if argument is empty.
5872d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  StringRef Arg0 = C->getArgText(0);
5882d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  if (Arg0.empty())
5892d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    return;
5902d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko
5912d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  switch (C->getRenderKind()) {
5922d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  case InlineCommandComment::RenderNormal:
59359500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) {
59459500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko      appendToResultWithHTMLEscaping(C->getArgText(i));
59559500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko      Result << " ";
59659500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    }
5972d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    return;
5982d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko
5992d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  case InlineCommandComment::RenderBold:
6002d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    assert(C->getNumArgs() == 1);
60159500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    Result << "<b>";
60259500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    appendToResultWithHTMLEscaping(Arg0);
60359500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    Result << "</b>";
604ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
6052d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  case InlineCommandComment::RenderMonospaced:
6062d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    assert(C->getNumArgs() == 1);
60759500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    Result << "<tt>";
60859500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    appendToResultWithHTMLEscaping(Arg0);
60959500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    Result<< "</tt>";
610ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
6112d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  case InlineCommandComment::RenderEmphasized:
6122d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    assert(C->getNumArgs() == 1);
61359500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    Result << "<em>";
61459500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    appendToResultWithHTMLEscaping(Arg0);
61559500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    Result << "</em>";
616ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
617ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
618ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
619ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
620ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitHTMLStartTagComment(
621ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const HTMLStartTagComment *C) {
6222ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  PrintHTMLStartTagComment(C, Result);
623ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
624ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
625ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitHTMLEndTagComment(
626ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const HTMLEndTagComment *C) {
6273e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  Result << "</" << C->getTagName() << ">";
628ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
629ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
630ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitParagraphComment(
631ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const ParagraphComment *C) {
632ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (C->isWhitespace())
633ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
634ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
6353e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  Result << "<p>";
636ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
637ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko       I != E; ++I) {
638ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    visit(*I);
639ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
6403e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  Result << "</p>";
641ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
642ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
643ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitBlockCommandComment(
644ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const BlockCommandComment *C) {
645e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  const CommandInfo *Info = Traits.getCommandInfo(C->getCommandID());
646e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  if (Info->IsBriefCommand) {
6473e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "<p class=\"para-brief\">";
648ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    visitNonStandaloneParagraphComment(C->getParagraph());
6493e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "</p>";
650ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
651ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
652e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  if (Info->IsReturnsCommand) {
6533e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "<p class=\"para-returns\">"
6543e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko              "<span class=\"word-returns\">Returns</span> ";
655ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    visitNonStandaloneParagraphComment(C->getParagraph());
6563e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "</p>";
657ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
658ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
659ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  // We don't know anything about this command.  Just render the paragraph.
660ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  visit(C->getParagraph());
661ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
662ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
663ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitParamCommandComment(
664ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const ParamCommandComment *C) {
6653e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  if (C->isParamIndexValid()) {
6663e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "<dt class=\"param-name-index-"
6673e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko           << C->getParamIndex()
6683e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko           << "\">";
6693e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  } else
6703e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "<dt class=\"param-name-index-invalid\">";
6713e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko
67259500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko  appendToResultWithHTMLEscaping(C->getParamName());
67359500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko  Result << "</dt>";
6743e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko
6753e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  if (C->isParamIndexValid()) {
6763e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "<dd class=\"param-descr-index-"
6773e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko           << C->getParamIndex()
6783e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko           << "\">";
6793e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  } else
6803e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "<dd class=\"param-descr-index-invalid\">";
6813e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko
682ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  visitNonStandaloneParagraphComment(C->getParagraph());
6833e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  Result << "</dd>";
684ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
685ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
68696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkovoid CommentASTToHTMLConverter::visitTParamCommandComment(
68796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko                                  const TParamCommandComment *C) {
68896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  if (C->isPositionValid()) {
68996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    if (C->getDepth() == 1)
6906a425525e52aba5a8e14db35d50a712be4e5e2e1Dmitri Gribenko      Result << "<dt class=\"tparam-name-index-"
69196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko             << C->getIndex(0)
69296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko             << "\">";
69396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    else
6946a425525e52aba5a8e14db35d50a712be4e5e2e1Dmitri Gribenko      Result << "<dt class=\"tparam-name-index-other\">";
69596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  } else
69696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    Result << "<dt class=\"tparam-name-index-invalid\">";
69796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
69859500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko  appendToResultWithHTMLEscaping(C->getParamName());
69959500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko  Result << "</dt>";
70096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
70196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  if (C->isPositionValid()) {
70296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    if (C->getDepth() == 1)
70396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko      Result << "<dd class=\"tparam-descr-index-"
70496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko             << C->getIndex(0)
70596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko             << "\">";
70696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    else
70796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko      Result << "<dd class=\"tparam-descr-index-other\">";
70896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  } else
70996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    Result << "<dd class=\"tparam-descr-index-invalid\">";
71096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
71196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  visitNonStandaloneParagraphComment(C->getParagraph());
71296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  Result << "</dd>";
71396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko}
71496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
715ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitVerbatimBlockComment(
716ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const VerbatimBlockComment *C) {
717ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  unsigned NumLines = C->getNumLines();
718ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (NumLines == 0)
719ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
720ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
7213e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  Result << "<pre>";
722ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  for (unsigned i = 0; i != NumLines; ++i) {
723ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    appendToResultWithHTMLEscaping(C->getText(i));
724ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    if (i + 1 != NumLines)
7253e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko      Result << '\n';
726ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
7273e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  Result << "</pre>";
728ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
729ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
730ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitVerbatimBlockLineComment(
731ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const VerbatimBlockLineComment *C) {
732ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  llvm_unreachable("should not see this AST node");
733ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
734ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
735ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitVerbatimLineComment(
736ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const VerbatimLineComment *C) {
7373e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  Result << "<pre>";
738ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  appendToResultWithHTMLEscaping(C->getText());
7393e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  Result << "</pre>";
740ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
741ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
742ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitFullComment(const FullComment *C) {
743e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  FullCommentParts Parts(C, Traits);
74496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
745ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  bool FirstParagraphIsBrief = false;
7462ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  if (Parts.Brief)
7472ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    visit(Parts.Brief);
7482ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  else if (Parts.FirstParagraph) {
7493e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "<p class=\"para-brief\">";
7502ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    visitNonStandaloneParagraphComment(Parts.FirstParagraph);
7513e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "</p>";
752ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    FirstParagraphIsBrief = true;
753ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
754ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
7552ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  for (unsigned i = 0, e = Parts.MiscBlocks.size(); i != e; ++i) {
7562ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    const Comment *C = Parts.MiscBlocks[i];
7572ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    if (FirstParagraphIsBrief && C == Parts.FirstParagraph)
758ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      continue;
759ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    visit(C);
760ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
761ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
7622ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  if (Parts.TParams.size() != 0) {
76396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    Result << "<dl>";
7642ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    for (unsigned i = 0, e = Parts.TParams.size(); i != e; ++i)
7652ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      visit(Parts.TParams[i]);
76696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    Result << "</dl>";
76796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  }
76896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
7692ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  if (Parts.Params.size() != 0) {
7703e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "<dl>";
7712ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    for (unsigned i = 0, e = Parts.Params.size(); i != e; ++i)
7722ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      visit(Parts.Params[i]);
7733e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "</dl>";
774ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
775ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
7762ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  if (Parts.Returns)
7772ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    visit(Parts.Returns);
7783e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko
7793e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  Result.flush();
780ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
781ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
782ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitNonStandaloneParagraphComment(
783ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const ParagraphComment *C) {
784ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!C)
785ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
786ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
787ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
788ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko       I != E; ++I) {
789ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    visit(*I);
790ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
791ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
792ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
793ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::appendToResultWithHTMLEscaping(StringRef S) {
794ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  for (StringRef::iterator I = S.begin(), E = S.end(); I != E; ++I) {
795ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    const char C = *I;
796ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    switch (C) {
797ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      case '&':
7983e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko        Result << "&amp;";
799ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
800ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      case '<':
8013e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko        Result << "&lt;";
802ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
803ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      case '>':
8043e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko        Result << "&gt;";
805ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
806ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      case '"':
8073e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko        Result << "&quot;";
808ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
809ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      case '\'':
8103e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko        Result << "&#39;";
811ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
812ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      case '/':
8133e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko        Result << "&#47;";
814ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
815ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      default:
8163e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko        Result << C;
817ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
818ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    }
819ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
820ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
821ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
822ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkoextern "C" {
823ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
824ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_HTMLTagComment_getAsString(CXComment CXC) {
825ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const HTMLTagComment *HTC = getASTNodeAs<HTMLTagComment>(CXC);
826ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!HTC)
827ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
828ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
8293e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  SmallString<128> HTML;
830e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  CommentASTToHTMLConverter Converter(HTML, getCommandTraits(CXC));
831ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Converter.visit(HTC);
8323e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  return createCXString(HTML.str(), /* DupString = */ true);
833ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
834ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
835ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_FullComment_getAsHTML(CXComment CXC) {
836ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const FullComment *FC = getASTNodeAs<FullComment>(CXC);
837ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!FC)
838ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
839ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
8403e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  SmallString<1024> HTML;
841e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  CommentASTToHTMLConverter Converter(HTML, getCommandTraits(CXC));
842ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Converter.visit(FC);
8433e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  return createCXString(HTML.str(), /* DupString = */ true);
844ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
845ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
846ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko} // end extern "C"
847ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
848f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkonamespace {
849f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkoclass CommentASTToXMLConverter :
850f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    public ConstCommentVisitor<CommentASTToXMLConverter> {
851f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkopublic:
852f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  /// \param Str accumulator for XML.
853e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  CommentASTToXMLConverter(SmallVectorImpl<char> &Str,
854e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko                           const CommandTraits &Traits,
855e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko                           const SourceManager &SM) :
856e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko      Result(Str), Traits(Traits), SM(SM) { }
857f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
858f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  // Inline content.
859f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitTextComment(const TextComment *C);
860f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitInlineCommandComment(const InlineCommandComment *C);
861f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitHTMLStartTagComment(const HTMLStartTagComment *C);
862f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitHTMLEndTagComment(const HTMLEndTagComment *C);
863f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
864f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  // Block content.
865f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitParagraphComment(const ParagraphComment *C);
866f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitBlockCommandComment(const BlockCommandComment *C);
867f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitParamCommandComment(const ParamCommandComment *C);
868f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitTParamCommandComment(const TParamCommandComment *C);
869f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitVerbatimBlockComment(const VerbatimBlockComment *C);
870f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
871f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitVerbatimLineComment(const VerbatimLineComment *C);
872f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
873f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitFullComment(const FullComment *C);
874f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
875f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  // Helpers.
876f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void appendToResultWithXMLEscaping(StringRef S);
877f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
878f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkoprivate:
879f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  /// Output stream for XML.
880f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  llvm::raw_svector_ostream Result;
881e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko
882e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  const CommandTraits &Traits;
883e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  const SourceManager &SM;
884f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko};
885f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko} // end unnamed namespace
886f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
887f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitTextComment(const TextComment *C) {
888f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  appendToResultWithXMLEscaping(C->getText());
889f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
890f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
891f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitInlineCommandComment(const InlineCommandComment *C) {
892f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  // Nothing to render if no arguments supplied.
893f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (C->getNumArgs() == 0)
894f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    return;
895f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
896f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  // Nothing to render if argument is empty.
897f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  StringRef Arg0 = C->getArgText(0);
898f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (Arg0.empty())
899f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    return;
900f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
901f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  switch (C->getRenderKind()) {
902f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  case InlineCommandComment::RenderNormal:
903f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) {
904f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      appendToResultWithXMLEscaping(C->getArgText(i));
905f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      Result << " ";
906f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    }
907f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    return;
908f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  case InlineCommandComment::RenderBold:
909f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    assert(C->getNumArgs() == 1);
910f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "<bold>";
911f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    appendToResultWithXMLEscaping(Arg0);
912f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "</bold>";
913f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    return;
914f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  case InlineCommandComment::RenderMonospaced:
915f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    assert(C->getNumArgs() == 1);
916f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "<monospaced>";
917f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    appendToResultWithXMLEscaping(Arg0);
918f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "</monospaced>";
919f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    return;
920f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  case InlineCommandComment::RenderEmphasized:
921f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    assert(C->getNumArgs() == 1);
922f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "<emphasized>";
923f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    appendToResultWithXMLEscaping(Arg0);
924f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "</emphasized>";
925f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    return;
926f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
927f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
928f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
929f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitHTMLStartTagComment(const HTMLStartTagComment *C) {
930f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "<rawHTML><![CDATA[";
931f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  PrintHTMLStartTagComment(C, Result);
932f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "]]></rawHTML>";
933f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
934f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
935f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitHTMLEndTagComment(const HTMLEndTagComment *C) {
936f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "<rawHTML>&lt;/" << C->getTagName() << "&gt;</rawHTML>";
937f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
938f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
939f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitParagraphComment(const ParagraphComment *C) {
940f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (C->isWhitespace())
941f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    return;
942f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
943f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "<Para>";
944f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
945f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko       I != E; ++I) {
946f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    visit(*I);
947f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
948f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "</Para>";
949f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
950f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
951f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitBlockCommandComment(const BlockCommandComment *C) {
952f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  visit(C->getParagraph());
953f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
954f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
955f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitParamCommandComment(const ParamCommandComment *C) {
956f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "<Parameter><Name>";
957f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  appendToResultWithXMLEscaping(C->getParamName());
958f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "</Name>";
959f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
960f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (C->isParamIndexValid())
961f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "<Index>" << C->getParamIndex() << "</Index>";
962f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
963f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "<Direction isExplicit=\"" << C->isDirectionExplicit() << "\">";
964f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  switch (C->getDirection()) {
965f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  case ParamCommandComment::In:
966f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "in";
967f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    break;
968f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  case ParamCommandComment::Out:
969f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "out";
970f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    break;
971f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  case ParamCommandComment::InOut:
972f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "in,out";
973f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    break;
974f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
975f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "</Direction><Discussion>";
976f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  visit(C->getParagraph());
977f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "</Discussion></Parameter>";
978f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
979f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
980f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitTParamCommandComment(
981f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko                                  const TParamCommandComment *C) {
982f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "<Parameter><Name>";
983f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  appendToResultWithXMLEscaping(C->getParamName());
984f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "</Name>";
985f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
986f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (C->isPositionValid() && C->getDepth() == 1) {
987f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "<Index>" << C->getIndex(0) << "</Index>";
988f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
989f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
990f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "<Discussion>";
991f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  visit(C->getParagraph());
992f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "</Discussion></Parameter>";
993f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
994f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
995f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitVerbatimBlockComment(
996f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko                                  const VerbatimBlockComment *C) {
997f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  unsigned NumLines = C->getNumLines();
998f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (NumLines == 0)
999f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    return;
1000f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1001e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  Result << llvm::StringSwitch<const char *>(C->getCommandName(Traits))
10026cd4420945489e7331012103048f162288a6c7d8Dmitri Gribenko      .Case("code", "<Verbatim xml:space=\"preserve\" kind=\"code\">")
10036cd4420945489e7331012103048f162288a6c7d8Dmitri Gribenko      .Default("<Verbatim xml:space=\"preserve\" kind=\"verbatim\">");
1004f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  for (unsigned i = 0; i != NumLines; ++i) {
1005f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    appendToResultWithXMLEscaping(C->getText(i));
1006f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    if (i + 1 != NumLines)
1007f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      Result << '\n';
1008f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
1009f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "</Verbatim>";
1010f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
1011f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1012f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitVerbatimBlockLineComment(
1013f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko                                  const VerbatimBlockLineComment *C) {
1014f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  llvm_unreachable("should not see this AST node");
1015f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
1016f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1017f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitVerbatimLineComment(
1018f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko                                  const VerbatimLineComment *C) {
10196cd4420945489e7331012103048f162288a6c7d8Dmitri Gribenko  Result << "<Verbatim xml:space=\"preserve\" kind=\"verbatim\">";
1020f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  appendToResultWithXMLEscaping(C->getText());
1021f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "</Verbatim>";
1022f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
1023f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1024f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitFullComment(const FullComment *C) {
1025e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  FullCommentParts Parts(C, Traits);
1026f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1027f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  const DeclInfo *DI = C->getDeclInfo();
1028f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  StringRef RootEndTag;
1029f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (DI) {
1030f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    switch (DI->getKind()) {
1031f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    case DeclInfo::OtherKind:
1032f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      RootEndTag = "</Other>";
1033f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      Result << "<Other";
1034f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      break;
1035f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    case DeclInfo::FunctionKind:
1036f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      RootEndTag = "</Function>";
1037f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      Result << "<Function";
1038f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      switch (DI->TemplateKind) {
1039f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case DeclInfo::NotTemplate:
1040f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1041f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case DeclInfo::Template:
1042f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << " templateKind=\"template\"";
1043f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1044f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case DeclInfo::TemplateSpecialization:
1045f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << " templateKind=\"specialization\"";
1046f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1047f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case DeclInfo::TemplatePartialSpecialization:
1048f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        llvm_unreachable("partial specializations of functions "
1049f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko                         "are not allowed in C++");
1050f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      }
1051f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      if (DI->IsInstanceMethod)
1052f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << " isInstanceMethod=\"1\"";
1053f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      if (DI->IsClassMethod)
1054f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << " isClassMethod=\"1\"";
1055f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      break;
1056f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    case DeclInfo::ClassKind:
1057f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      RootEndTag = "</Class>";
1058f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      Result << "<Class";
1059f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      switch (DI->TemplateKind) {
1060f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case DeclInfo::NotTemplate:
1061f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1062f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case DeclInfo::Template:
1063f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << " templateKind=\"template\"";
1064f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1065f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case DeclInfo::TemplateSpecialization:
1066f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << " templateKind=\"specialization\"";
1067f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1068f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case DeclInfo::TemplatePartialSpecialization:
1069f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << " templateKind=\"partialSpecialization\"";
1070f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1071f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      }
1072f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      break;
1073f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    case DeclInfo::VariableKind:
1074f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      RootEndTag = "</Variable>";
1075f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      Result << "<Variable";
1076f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      break;
1077f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    case DeclInfo::NamespaceKind:
1078f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      RootEndTag = "</Namespace>";
1079f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      Result << "<Namespace";
1080f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      break;
1081f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    case DeclInfo::TypedefKind:
1082f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      RootEndTag = "</Typedef>";
1083f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      Result << "<Typedef";
1084f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      break;
1085cff339a60a571a606a7510548f661dc6a719368dDmitri Gribenko    case DeclInfo::EnumKind:
1086cff339a60a571a606a7510548f661dc6a719368dDmitri Gribenko      RootEndTag = "</Enum>";
1087cff339a60a571a606a7510548f661dc6a719368dDmitri Gribenko      Result << "<Enum";
1088cff339a60a571a606a7510548f661dc6a719368dDmitri Gribenko      break;
1089f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    }
1090f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1091f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    {
1092f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      // Print line and column number.
1093f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      SourceLocation Loc = DI->ThisDecl->getLocation();
1094f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
1095f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      FileID FID = LocInfo.first;
1096f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      unsigned FileOffset = LocInfo.second;
1097f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1098f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      if (!FID.isInvalid()) {
1099f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        if (const FileEntry *FE = SM.getFileEntryForID(FID)) {
1100f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko          Result << " file=\"";
1101f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko          appendToResultWithXMLEscaping(FE->getName());
1102f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko          Result << "\"";
1103f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        }
1104f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << " line=\"" << SM.getLineNumber(FID, FileOffset)
1105f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko               << "\" column=\"" << SM.getColumnNumber(FID, FileOffset)
1106f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko               << "\"";
1107f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      }
1108f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    }
1109f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1110f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    // Finish the root tag.
1111f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << ">";
1112f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1113f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    bool FoundName = false;
1114f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    if (const NamedDecl *ND = dyn_cast<NamedDecl>(DI->ThisDecl)) {
1115f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      if (DeclarationName DeclName = ND->getDeclName()) {
1116f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << "<Name>";
1117f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        std::string Name = DeclName.getAsString();
1118f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        appendToResultWithXMLEscaping(Name);
1119f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        FoundName = true;
1120f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << "</Name>";
1121f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      }
1122f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    }
1123f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    if (!FoundName)
1124f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      Result << "<Name>&lt;anonymous&gt;</Name>";
1125f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1126f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    {
1127f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      // Print USR.
1128f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      SmallString<128> USR;
1129f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      cxcursor::getDeclCursorUSR(DI->ThisDecl, USR);
1130f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      if (!USR.empty()) {
1131f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << "<USR>";
1132f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        appendToResultWithXMLEscaping(USR);
1133f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << "</USR>";
1134f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      }
1135f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    }
1136f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  } else {
1137f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    // No DeclInfo -- just emit some root tag and name tag.
1138f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    RootEndTag = "</Other>";
1139f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "<Other><Name>unknown</Name>";
1140f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
1141f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1142f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  bool FirstParagraphIsBrief = false;
1143f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (Parts.Brief) {
1144f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "<Abstract>";
1145f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    visit(Parts.Brief);
1146f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "</Abstract>";
1147f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  } else if (Parts.FirstParagraph) {
1148f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "<Abstract>";
1149f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    visit(Parts.FirstParagraph);
1150f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "</Abstract>";
1151f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    FirstParagraphIsBrief = true;
1152f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
1153f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1154f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (Parts.TParams.size() != 0) {
1155f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "<TemplateParameters>";
1156f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    for (unsigned i = 0, e = Parts.TParams.size(); i != e; ++i)
1157f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      visit(Parts.TParams[i]);
1158f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "</TemplateParameters>";
1159f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
1160f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1161f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (Parts.Params.size() != 0) {
1162f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "<Parameters>";
1163f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    for (unsigned i = 0, e = Parts.Params.size(); i != e; ++i)
1164f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      visit(Parts.Params[i]);
1165f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "</Parameters>";
1166f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
1167f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1168f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (Parts.Returns) {
1169f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "<ResultDiscussion>";
1170f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    visit(Parts.Returns);
1171f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "</ResultDiscussion>";
1172f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
1173257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian
1174257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian  if (DI->ThisDecl->hasAttrs()) {
1175257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian    const AttrVec &Attrs = DI->ThisDecl->getAttrs();
1176faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian    for (unsigned i = 0, e = Attrs.size(); i != e; i++) {
1177faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian      const AvailabilityAttr *AA = dyn_cast<AvailabilityAttr>(Attrs[i]);
11782a46533633441176e93b484739a0a27e07150b63Fariborz Jahanian      if (!AA) {
11798da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian        if (const DeprecatedAttr *DA = dyn_cast<DeprecatedAttr>(Attrs[i])) {
11808da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian          if (DA->getMessage().empty())
11818da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian            Result << "<Deprecated/>";
11828da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian          else {
11838da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian            Result << "<Deprecated>"
11848da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian                   << DA->getMessage()
11858da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian                   << "</Deprecated>";
11868da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian          }
11878da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian        }
11888da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian        else if (const UnavailableAttr *UA = dyn_cast<UnavailableAttr>(Attrs[i])) {
11898da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian          if (UA->getMessage().empty())
11908da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian            Result << "<Unavailable/>";
11918da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian          else {
11928da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian            Result << "<Unavailable>"
11938da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian                   << UA->getMessage()
11948da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian                   << "</Unavailable>";
11958da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian          }
11968da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian        }
1197257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian        continue;
11982a46533633441176e93b484739a0a27e07150b63Fariborz Jahanian      }
1199faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian
1200faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian      // 'availability' attribute.
1201257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      Result << "<Availability";
1202faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian      StringRef Distribution;
1203257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      if (AA->getPlatform()) {
1204faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian        Distribution = AvailabilityAttr::getPrettyPlatformName(
1205faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian                                        AA->getPlatform()->getName());
1206faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian        if (Distribution.empty())
1207faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian          Distribution = AA->getPlatform()->getName();
1208257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      }
1209faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian      Result << " distribution=\"" << Distribution << "\">";
1210257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      VersionTuple IntroducedInVersion = AA->getIntroduced();
1211257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      if (!IntroducedInVersion.empty()) {
1212faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian        Result << "<IntroducedInVersion>"
1213faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian               << IntroducedInVersion.getAsString()
1214faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian               << "</IntroducedInVersion>";
1215257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      }
1216257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      VersionTuple DeprecatedInVersion = AA->getDeprecated();
1217257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      if (!DeprecatedInVersion.empty()) {
1218faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian        Result << "<DeprecatedInVersion>"
1219faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian               << DeprecatedInVersion.getAsString()
1220faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian               << "</DeprecatedInVersion>";
1221257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      }
1222257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      VersionTuple RemovedAfterVersion = AA->getObsoleted();
1223257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      if (!RemovedAfterVersion.empty()) {
1224faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian        Result << "<RemovedAfterVersion>"
1225faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian               << RemovedAfterVersion.getAsString()
1226faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian               << "</RemovedAfterVersion>";
1227257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      }
1228faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian      // 'deprecated' attribute.
1229257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      StringRef DeprecationSummary = AA->getMessage();
1230257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      if (!DeprecationSummary.empty()) {
1231faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian        Result << " <DeprecationSummary>"
1232faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian               << DeprecationSummary
1233faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian               << "</DeprecationSummary>";
1234257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      }
1235faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian      // 'unavailable' attribute.
1236257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      if (AA->getUnavailable())
12378da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian        Result << "<Unavailable/>";
1238faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian      Result << "</Availability>";
1239257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian    }
1240257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian  }
1241faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian
1242f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  {
1243f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    bool StartTagEmitted = false;
1244f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    for (unsigned i = 0, e = Parts.MiscBlocks.size(); i != e; ++i) {
1245f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      const Comment *C = Parts.MiscBlocks[i];
1246f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      if (FirstParagraphIsBrief && C == Parts.FirstParagraph)
1247f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        continue;
1248f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      if (!StartTagEmitted) {
1249f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << "<Discussion>";
1250f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        StartTagEmitted = true;
1251f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      }
1252f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      visit(C);
1253f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    }
1254f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    if (StartTagEmitted)
1255f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      Result << "</Discussion>";
1256f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
1257f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1258f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << RootEndTag;
1259f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1260f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result.flush();
1261f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
1262f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1263f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::appendToResultWithXMLEscaping(StringRef S) {
1264f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  for (StringRef::iterator I = S.begin(), E = S.end(); I != E; ++I) {
1265f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    const char C = *I;
1266f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    switch (C) {
1267f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case '&':
1268f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << "&amp;";
1269f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1270f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case '<':
1271f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << "&lt;";
1272f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1273f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case '>':
1274f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << "&gt;";
1275f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1276f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case '"':
1277f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << "&quot;";
1278f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1279f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case '\'':
1280f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << "&apos;";
1281f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1282f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      default:
1283f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << C;
1284f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1285f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    }
1286f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
1287f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
1288f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1289f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkoextern "C" {
1290f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1291e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri GribenkoCXString clang_FullComment_getAsXML(CXComment CXC) {
1292f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  const FullComment *FC = getASTNodeAs<FullComment>(CXC);
1293f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (!FC)
1294f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    return createCXString((const char *) 0);
1295f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1296e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  CXTranslationUnit TU = CXC.TranslationUnit;
1297f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  SourceManager &SM = static_cast<ASTUnit *>(TU->TUData)->getSourceManager();
1298f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1299f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  SmallString<1024> XML;
1300e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  CommentASTToXMLConverter Converter(XML, getCommandTraits(CXC), SM);
1301f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Converter.visit(FC);
1302f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  return createCXString(XML.str(), /* DupString = */ true);
1303f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
1304f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1305f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko} // end extern "C"
1306f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1307