CXComment.cpp revision ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72d
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"
17ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
18ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko#include "clang/AST/CommentVisitor.h"
19ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
20ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko#include "llvm/Support/ErrorHandling.h"
21ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
22ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkousing namespace clang;
23ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkousing namespace clang::cxstring;
24ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkousing namespace clang::comments;
25ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkousing namespace clang::cxcomment;
26ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
27ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkoextern "C" {
28ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
29ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkoenum CXCommentKind clang_Comment_getKind(CXComment CXC) {
30ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const Comment *C = getASTNode(CXC);
31ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!C)
32ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_Null;
33ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
34ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  switch (C->getCommentKind()) {
35ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::NoCommentKind:
36ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_Null;
37ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
38ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::TextCommentKind:
39ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_Text;
40ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
41ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::InlineCommandCommentKind:
42ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_InlineCommand;
43ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
44ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::HTMLStartTagCommentKind:
45ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_HTMLStartTag;
46ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
47ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::HTMLEndTagCommentKind:
48ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_HTMLEndTag;
49ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
50ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::ParagraphCommentKind:
51ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_Paragraph;
52ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
53ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::BlockCommandCommentKind:
54ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_BlockCommand;
55ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
56ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::ParamCommandCommentKind:
57ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_ParamCommand;
58ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
59ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::VerbatimBlockCommentKind:
60ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_VerbatimBlockCommand;
61ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
62ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::VerbatimBlockLineCommentKind:
63ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_VerbatimBlockLine;
64ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
65ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::VerbatimLineCommentKind:
66ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_VerbatimLine;
67ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
68ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::FullCommentKind:
69ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_FullComment;
70ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
71ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  llvm_unreachable("unknown CommentKind");
72ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
73ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
74ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_Comment_getNumChildren(CXComment CXC) {
75ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const Comment *C = getASTNode(CXC);
76ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!C)
77ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return 0;
78ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
79ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return C->child_count();
80ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
81ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
82ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXComment clang_Comment_getChild(CXComment CXC, unsigned ChildIdx) {
83ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const Comment *C = getASTNode(CXC);
84ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!C || ChildIdx >= C->child_count())
85ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXComment(NULL);
86ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
87ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXComment(*(C->child_begin() + ChildIdx));
88ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
89ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
90ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_Comment_isWhitespace(CXComment CXC) {
91ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const Comment *C = getASTNode(CXC);
92ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!C)
93ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return false;
94ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
95ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (const TextComment *TC = dyn_cast<TextComment>(C))
96ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return TC->isWhitespace();
97ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
98ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (const ParagraphComment *PC = dyn_cast<ParagraphComment>(C))
99ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return PC->isWhitespace();
100ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
101ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return false;
102ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
103ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
104ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_InlineContentComment_hasTrailingNewline(CXComment CXC) {
105ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const InlineContentComment *ICC = getASTNodeAs<InlineContentComment>(CXC);
106ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!ICC)
107ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return false;
108ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
109ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return ICC->hasTrailingNewline();
110ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
111ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
112ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_TextComment_getText(CXComment CXC) {
113ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const TextComment *TC = getASTNodeAs<TextComment>(CXC);
114ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!TC)
115ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
116ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
117ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(TC->getText(), /*DupString=*/ false);
118ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
119ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
120ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_InlineCommandComment_getCommandName(CXComment CXC) {
121ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
122ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!ICC)
123ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
124ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
125ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(ICC->getCommandName(), /*DupString=*/ false);
126ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
127ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
128ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_InlineCommandComment_getNumArgs(CXComment CXC) {
129ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
130ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!ICC)
131ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return 0;
132ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
133ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return ICC->getNumArgs();
134ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
135ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
136ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_InlineCommandComment_getArgText(CXComment CXC,
137ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                               unsigned ArgIdx) {
138ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
139ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!ICC || ArgIdx >= ICC->getNumArgs())
140ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
141ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
142ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(ICC->getArgText(ArgIdx), /*DupString=*/ false);
143ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
144ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
145ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_HTMLTagComment_getTagName(CXComment CXC) {
146ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const HTMLTagComment *HTC = getASTNodeAs<HTMLTagComment>(CXC);
147ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!HTC)
148ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
149ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
150ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(HTC->getTagName(), /*DupString=*/ false);
151ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
152ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
153ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_HTMLStartTagComment_isSelfClosing(CXComment CXC) {
154ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
155ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!HST)
156ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return false;
157ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
158ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return HST->isSelfClosing();
159ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
160ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
161ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_HTMLStartTag_getNumAttrs(CXComment CXC) {
162ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
163ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!HST)
164ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return 0;
165ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
166ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return HST->getNumAttrs();
167ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
168ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
169ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_HTMLStartTag_getAttrName(CXComment CXC, unsigned AttrIdx) {
170ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
171ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!HST || AttrIdx >= HST->getNumAttrs())
172ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
173ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
174ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(HST->getAttr(AttrIdx).Name, /*DupString=*/ false);
175ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
176ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
177ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_HTMLStartTag_getAttrValue(CXComment CXC, unsigned AttrIdx) {
178ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
179ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!HST || AttrIdx >= HST->getNumAttrs())
180ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
181ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
182ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(HST->getAttr(AttrIdx).Value, /*DupString=*/ false);
183ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
184ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
185ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_BlockCommandComment_getCommandName(CXComment CXC) {
186ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
187ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!BCC)
188ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
189ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
190ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(BCC->getCommandName(), /*DupString=*/ false);
191ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
192ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
193ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_BlockCommandComment_getNumArgs(CXComment CXC) {
194ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
195ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!BCC)
196ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return 0;
197ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
198ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return BCC->getNumArgs();
199ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
200ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
201ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_BlockCommandComment_getArgText(CXComment CXC,
202ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                              unsigned ArgIdx) {
203ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
204ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!BCC || ArgIdx >= BCC->getNumArgs())
205ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
206ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
207ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(BCC->getArgText(ArgIdx), /*DupString=*/ false);
208ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
209ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
210ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXComment clang_BlockCommandComment_getParagraph(CXComment CXC) {
211ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
212ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!BCC)
213ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXComment(NULL);
214ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
215ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXComment(BCC->getParagraph());
216ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
217ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
218ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_ParamCommandComment_getParamName(CXComment CXC) {
219ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
220ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!PCC)
221ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
222ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
223ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(PCC->getParamName(), /*DupString=*/ false);
224ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
225ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
226ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_ParamCommandComment_isParamIndexValid(CXComment CXC) {
227ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
228ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!PCC)
229ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return false;
230ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
231ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return PCC->isParamIndexValid();
232ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
233ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
234ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_ParamCommandComment_getParamIndex(CXComment CXC) {
235ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
236ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!PCC)
237ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return ParamCommandComment::InvalidParamIndex;
238ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
239ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return PCC->getParamIndex();
240ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
241ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
242ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_ParamCommandComment_isDirectionExplicit(CXComment CXC) {
243ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
244ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!PCC)
245ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return false;
246ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
247ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return PCC->isDirectionExplicit();
248ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
249ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
250ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkoenum CXCommentParamPassDirection clang_ParamCommandComment_getDirection(
251ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                                            CXComment CXC) {
252ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
253ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!PCC)
254ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXCommentParamPassDirection_In;
255ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
256ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  switch (PCC->getDirection()) {
257ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case ParamCommandComment::In:
258ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXCommentParamPassDirection_In;
259ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
260ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case ParamCommandComment::Out:
261ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXCommentParamPassDirection_Out;
262ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
263ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case ParamCommandComment::InOut:
264ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXCommentParamPassDirection_InOut;
265ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
266ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  llvm_unreachable("unknown ParamCommandComment::PassDirection");
267ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
268ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
269ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_VerbatimBlockLineComment_getText(CXComment CXC) {
270ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const VerbatimBlockLineComment *VBL =
271ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      getASTNodeAs<VerbatimBlockLineComment>(CXC);
272ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!VBL)
273ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
274ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
275ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(VBL->getText(), /*DupString=*/ false);
276ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
277ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
278ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_VerbatimLineComment_getText(CXComment CXC) {
279ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const VerbatimLineComment *VLC = getASTNodeAs<VerbatimLineComment>(CXC);
280ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!VLC)
281ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
282ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
283ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(VLC->getText(), /*DupString=*/ false);
284ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
285ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
286ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko} // end extern "C"
287ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
288ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko//===----------------------------------------------------------------------===//
289ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko// Helpers for converting comment AST to HTML.
290ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko//===----------------------------------------------------------------------===//
291ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
292ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkonamespace {
293ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
294ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkoclass ParamCommandCommentCompareIndex {
295ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkopublic:
296ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  bool operator()(const ParamCommandComment *LHS,
297ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                  const ParamCommandComment *RHS) const {
298ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    // To sort invalid (unresolved) parameters last, this comparison relies on
299ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    // invalid indices to be UINT_MAX.
300ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return LHS->getParamIndex() < RHS->getParamIndex();
301ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
302ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko};
303ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
304ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkoclass CommentASTToHTMLConverter :
305ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    public ConstCommentVisitor<CommentASTToHTMLConverter> {
306ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkopublic:
307ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  CommentASTToHTMLConverter() { }
308ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
309ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  // Inline content.
310ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitTextComment(const TextComment *C);
311ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitInlineCommandComment(const InlineCommandComment *C);
312ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitHTMLStartTagComment(const HTMLStartTagComment *C);
313ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitHTMLEndTagComment(const HTMLEndTagComment *C);
314ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
315ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  // Block content.
316ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitParagraphComment(const ParagraphComment *C);
317ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitBlockCommandComment(const BlockCommandComment *C);
318ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitParamCommandComment(const ParamCommandComment *C);
319ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitVerbatimBlockComment(const VerbatimBlockComment *C);
320ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
321ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitVerbatimLineComment(const VerbatimLineComment *C);
322ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
323ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitFullComment(const FullComment *C);
324ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
325ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  // Helpers.
326ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
327ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  /// Convert a paragraph that is not a block by itself (an argument to some
328ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  /// command).
329ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitNonStandaloneParagraphComment(const ParagraphComment *C);
330ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
331ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void appendToResultWithHTMLEscaping(StringRef S);
332ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
333ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  StringRef getAsHTML() const {
334ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return Result;
335ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
336ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
337ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkoprivate:
338ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  /// Accumulator for converted HTML.
339ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  std::string Result;
340ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko};
341ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko} // end unnamed namespace
342ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
343ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitTextComment(const TextComment *C) {
344ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  appendToResultWithHTMLEscaping(C->getText());
345ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
346ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
347ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitInlineCommandComment(
348ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const InlineCommandComment *C) {
349ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  StringRef CommandName = C->getCommandName();
350ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  bool HasArg0 = C->getNumArgs() > 0 && !C->getArgText(0).empty();
351ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  StringRef Arg0;
352ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (HasArg0)
353ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Arg0 = C->getArgText(0);
354ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
355ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (CommandName == "b") {
356ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    if (!HasArg0)
357ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      return;
358ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += "<b>";
359ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += Arg0;
360ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += "</b>";
361ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
362ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
363ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (CommandName == "c" || CommandName == "p") {
364ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    if (!HasArg0)
365ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      return;
366ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += "<tt>";
367ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += Arg0;
368ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += "</tt>";
369ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
370ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
371ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (CommandName == "a" || CommandName == "e" || CommandName == "em") {
372ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    if (!HasArg0)
373ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      return;
374ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += "<em>";
375ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += Arg0;
376ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += "</em>";
377ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
378ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
379ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
380ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  // We don't recognize this command, so just print its arguments.
381ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) {
382ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += C->getArgText(i);
383ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += " ";
384ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
385ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
386ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
387ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitHTMLStartTagComment(
388ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const HTMLStartTagComment *C) {
389ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Result += "<";
390ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Result += C->getTagName();
391ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
392ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (C->getNumAttrs() != 0) {
393ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    for (unsigned i = 0, e = C->getNumAttrs(); i != e; i++) {
394ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      Result += " ";
395ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      const HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
396ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      Result += Attr.Name;
397ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      if (!Attr.Value.empty()) {
398ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        Result += "=\"";
399ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        Result += Attr.Value;
400ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        Result += " \"";
401ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      }
402ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    }
403ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
404ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
405ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!C->isSelfClosing())
406ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += ">";
407ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  else
408ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += "/>";
409ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
410ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
411ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitHTMLEndTagComment(
412ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const HTMLEndTagComment *C) {
413ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Result += "</";
414ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Result += C->getTagName();
415ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Result += ">";
416ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
417ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
418ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitParagraphComment(
419ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const ParagraphComment *C) {
420ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (C->isWhitespace())
421ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
422ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
423ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Result += "<p>";
424ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
425ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko       I != E; ++I) {
426ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    visit(*I);
427ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
428ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Result += "</p>";
429ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
430ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
431ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitBlockCommandComment(
432ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const BlockCommandComment *C) {
433ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  StringRef CommandName = C->getCommandName();
434ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (CommandName == "brief" || CommandName == "short") {
435ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += "<p class=\"para-brief\">";
436ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    visitNonStandaloneParagraphComment(C->getParagraph());
437ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += "</p>";
438ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
439ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
440ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (CommandName == "returns" || CommandName == "return") {
441ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += "<p class=\"para-returns\">";
442ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += "<span class=\"word-returns\">Returns</span> ";
443ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    visitNonStandaloneParagraphComment(C->getParagraph());
444ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += "</p>";
445ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
446ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
447ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  // We don't know anything about this command.  Just render the paragraph.
448ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  visit(C->getParagraph());
449ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
450ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
451ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitParamCommandComment(
452ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const ParamCommandComment *C) {
453ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Result += "<dt>";
454ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Result += C->getParamName();
455ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Result += "</dt>";
456ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Result += "<dd>";
457ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  visitNonStandaloneParagraphComment(C->getParagraph());
458ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Result += "</dd>";
459ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
460ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
461ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitVerbatimBlockComment(
462ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const VerbatimBlockComment *C) {
463ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  unsigned NumLines = C->getNumLines();
464ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (NumLines == 0)
465ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
466ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
467ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Result += "<pre>";
468ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  for (unsigned i = 0; i != NumLines; ++i) {
469ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    appendToResultWithHTMLEscaping(C->getText(i));
470ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    if (i + 1 != NumLines)
471ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      Result.append("\n");
472ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
473ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Result += "</pre>";
474ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
475ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
476ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitVerbatimBlockLineComment(
477ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const VerbatimBlockLineComment *C) {
478ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  llvm_unreachable("should not see this AST node");
479ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
480ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
481ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitVerbatimLineComment(
482ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const VerbatimLineComment *C) {
483ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Result += "<pre>";
484ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  appendToResultWithHTMLEscaping(C->getText());
485ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Result += "</pre>";
486ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
487ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
488ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitFullComment(const FullComment *C) {
489ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const BlockContentComment *Brief = NULL;
490ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const ParagraphComment *FirstParagraph = NULL;
491ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const BlockCommandComment *Returns = NULL;
492ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  SmallVector<const ParamCommandComment *, 8> Params;
493ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  SmallVector<const BlockContentComment *, 8> MiscBlocks;
494ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
495ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  // Extract various blocks into separate variables and vectors above.
496ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
497ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko       I != E; ++I) {
498ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    const Comment *Child = *I;
499ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    if (!Child)
500ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      continue;
501ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    switch (Child->getCommentKind()) {
502ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    case Comment::NoCommentKind:
503ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      continue;
504ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
505ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    case Comment::ParagraphCommentKind: {
506ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      const ParagraphComment *PC = cast<ParagraphComment>(Child);
507ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      if (PC->isWhitespace())
508ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
509ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      if (!FirstParagraph)
510ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        FirstParagraph = PC;
511ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
512ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      MiscBlocks.push_back(PC);
513ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      break;
514ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    }
515ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
516ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    case Comment::BlockCommandCommentKind: {
517ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      const BlockCommandComment *BCC = cast<BlockCommandComment>(Child);
518ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      StringRef CommandName = BCC->getCommandName();
519ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      if (!Brief && (CommandName == "brief" || CommandName == "short")) {
520ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        Brief = BCC;
521ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
522ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      }
523ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      if (!Returns && (CommandName == "returns" || CommandName == "return")) {
524ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        Returns = BCC;
525ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
526ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      }
527ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      MiscBlocks.push_back(BCC);
528ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      break;
529ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    }
530ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
531ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    case Comment::ParamCommandCommentKind: {
532ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      const ParamCommandComment *PCC = cast<ParamCommandComment>(Child);
533ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      if (!PCC->hasParamName())
534ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
535ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
536ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      if (!PCC->isDirectionExplicit() && !PCC->hasNonWhitespaceParagraph())
537ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
538ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
539ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      Params.push_back(PCC);
540ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      break;
541ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    }
542ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
543ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    case Comment::VerbatimBlockCommentKind:
544ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    case Comment::VerbatimLineCommentKind:
545ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      MiscBlocks.push_back(cast<BlockCommandComment>(Child));
546ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      break;
547ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
548ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    case Comment::TextCommentKind:
549ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    case Comment::InlineCommandCommentKind:
550ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    case Comment::HTMLStartTagCommentKind:
551ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    case Comment::HTMLEndTagCommentKind:
552ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    case Comment::VerbatimBlockLineCommentKind:
553ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    case Comment::FullCommentKind:
554ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      llvm_unreachable("AST node of this kind can't be a child of "
555ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                       "a FullComment");
556ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    }
557ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
558ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
559ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  // Sort params in order they are declared in the function prototype.
560ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  // Unresolved parameters are put at the end of the list in the same order
561ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  // they were seen in the comment.
562ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  std::stable_sort(Params.begin(), Params.end(),
563ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                   ParamCommandCommentCompareIndex());
564ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
565ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  bool FirstParagraphIsBrief = false;
566ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (Brief)
567ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    visit(Brief);
568ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  else if (FirstParagraph) {
569ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += "<p class=\"para-brief\">";
570ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    visitNonStandaloneParagraphComment(FirstParagraph);
571ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += "</p>";
572ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    FirstParagraphIsBrief = true;
573ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
574ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
575ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  for (unsigned i = 0, e = MiscBlocks.size(); i != e; ++i) {
576ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    const Comment *C = MiscBlocks[i];
577ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    if (FirstParagraphIsBrief && C == FirstParagraph)
578ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      continue;
579ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    visit(C);
580ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
581ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
582ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (Params.size() != 0) {
583ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += "<dl>";
584ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    for (unsigned i = 0, e = Params.size(); i != e; ++i)
585ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      visit(Params[i]);
586ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    Result += "</dl>";
587ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
588ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
589ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (Returns)
590ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    visit(Returns);
591ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
592ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
593ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitNonStandaloneParagraphComment(
594ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const ParagraphComment *C) {
595ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!C)
596ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
597ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
598ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
599ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko       I != E; ++I) {
600ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    visit(*I);
601ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
602ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
603ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
604ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::appendToResultWithHTMLEscaping(StringRef S) {
605ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Result.reserve(Result.size() + S.size());
606ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  for (StringRef::iterator I = S.begin(), E = S.end(); I != E; ++I) {
607ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    const char C = *I;
608ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    switch (C) {
609ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      case '&':
610ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        Result.append("&amp;");
611ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
612ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      case '<':
613ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        Result.append("&lt;");
614ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
615ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      case '>':
616ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        Result.append("&gt;");
617ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
618ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      case '"':
619ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        Result.append("&quot;");
620ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
621ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      case '\'':
622ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        Result.append("&#39;");
623ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
624ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      case '/':
625ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        Result.append("&#47;");
626ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
627ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      default:
628ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        Result.push_back(C);
629ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
630ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    }
631ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
632ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
633ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
634ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkoextern "C" {
635ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
636ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_HTMLTagComment_getAsString(CXComment CXC) {
637ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const HTMLTagComment *HTC = getASTNodeAs<HTMLTagComment>(CXC);
638ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!HTC)
639ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
640ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
641ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  CommentASTToHTMLConverter Converter;
642ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Converter.visit(HTC);
643ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(Converter.getAsHTML());
644ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
645ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
646ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_FullComment_getAsHTML(CXComment CXC) {
647ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const FullComment *FC = getASTNodeAs<FullComment>(CXC);
648ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!FC)
649ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return createCXString((const char *) 0);
650ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
651ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  CommentASTToHTMLConverter Converter;
652ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Converter.visit(FC);
653ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return createCXString(Converter.getAsHTML());
654ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
655ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
656ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko} // end extern "C"
657ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
658