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 "CXComment.h"
16f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko#include "CXCursor.h"
17f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "CXString.h"
1888b9521364735a6c9a7ccd23c5bd19d81a80cdd3Fariborz Jahanian#include "SimpleFormatContext.h"
19d1db12540e572d6e3d998a4b770a6b2c7267d7fcDmitri Gribenko#include "clang/AST/CommentCommandTraits.h"
20f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "clang/AST/CommentVisitor.h"
21f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko#include "clang/AST/Decl.h"
22f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "clang/AST/PrettyPrinter.h"
23b99083e60325a28063fb588f458a871151971fdcChandler Carruth#include "clang/Format/Format.h"
24b99083e60325a28063fb588f458a871151971fdcChandler Carruth#include "clang/Lex/Lexer.h"
2588b9521364735a6c9a7ccd23c5bd19d81a80cdd3Fariborz Jahanian#include "llvm/ADT/StringExtras.h"
26f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko#include "llvm/ADT/StringSwitch.h"
27ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko#include "llvm/Support/ErrorHandling.h"
283e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko#include "llvm/Support/raw_ostream.h"
29221a6d74d48fb3eaa73b68eb04f253080bedd5fdDmitri Gribenko#include <climits>
30221a6d74d48fb3eaa73b68eb04f253080bedd5fdDmitri Gribenko
31ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkousing namespace clang;
32ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkousing namespace clang::comments;
33ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkousing namespace clang::cxcomment;
34ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
35ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkoextern "C" {
36ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
37ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkoenum CXCommentKind clang_Comment_getKind(CXComment CXC) {
38ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const Comment *C = getASTNode(CXC);
39ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!C)
40ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_Null;
41ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
42ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  switch (C->getCommentKind()) {
43ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::NoCommentKind:
44ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_Null;
45ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
46ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::TextCommentKind:
47ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_Text;
48ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
49ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::InlineCommandCommentKind:
50ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_InlineCommand;
51ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
52ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::HTMLStartTagCommentKind:
53ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_HTMLStartTag;
54ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
55ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::HTMLEndTagCommentKind:
56ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_HTMLEndTag;
57ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
58ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::ParagraphCommentKind:
59ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_Paragraph;
60ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
61ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::BlockCommandCommentKind:
62ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_BlockCommand;
63ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
64ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::ParamCommandCommentKind:
65ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_ParamCommand;
66ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
6796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  case Comment::TParamCommandCommentKind:
6896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    return CXComment_TParamCommand;
6996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
70ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::VerbatimBlockCommentKind:
71ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_VerbatimBlockCommand;
72ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
73ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::VerbatimBlockLineCommentKind:
74ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_VerbatimBlockLine;
75ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
76ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::VerbatimLineCommentKind:
77ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_VerbatimLine;
78ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
79ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case Comment::FullCommentKind:
80ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXComment_FullComment;
81ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
82ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  llvm_unreachable("unknown CommentKind");
83ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
84ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
85ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_Comment_getNumChildren(CXComment CXC) {
86ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const Comment *C = getASTNode(CXC);
87ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!C)
88ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return 0;
89ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
90ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return C->child_count();
91ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
92ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
93ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXComment clang_Comment_getChild(CXComment CXC, unsigned ChildIdx) {
94ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const Comment *C = getASTNode(CXC);
95ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!C || ChildIdx >= C->child_count())
96e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko    return createCXComment(NULL, NULL);
97ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
98e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  return createCXComment(*(C->child_begin() + ChildIdx), CXC.TranslationUnit);
99ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
100ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
101ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_Comment_isWhitespace(CXComment CXC) {
102ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const Comment *C = getASTNode(CXC);
103ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!C)
104ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return false;
105ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
106ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (const TextComment *TC = dyn_cast<TextComment>(C))
107ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return TC->isWhitespace();
108ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
109ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (const ParagraphComment *PC = dyn_cast<ParagraphComment>(C))
110ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return PC->isWhitespace();
111ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
112ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return false;
113ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
114ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
115ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_InlineContentComment_hasTrailingNewline(CXComment CXC) {
116ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const InlineContentComment *ICC = getASTNodeAs<InlineContentComment>(CXC);
117ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!ICC)
118ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return false;
119ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
120ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return ICC->hasTrailingNewline();
121ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
122ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
123ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_TextComment_getText(CXComment CXC) {
124ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const TextComment *TC = getASTNodeAs<TextComment>(CXC);
125ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!TC)
126dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2aDmitri Gribenko    return cxstring::createNull();
127ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
1285595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko  return cxstring::createRef(TC->getText());
129ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
130ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
131ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_InlineCommandComment_getCommandName(CXComment CXC) {
132ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
133ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!ICC)
134dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2aDmitri Gribenko    return cxstring::createNull();
135ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
136e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  const CommandTraits &Traits = getCommandTraits(CXC);
1375595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko  return cxstring::createRef(ICC->getCommandName(Traits));
138ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
139ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
1402d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenkoenum CXCommentInlineCommandRenderKind
1412d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenkoclang_InlineCommandComment_getRenderKind(CXComment CXC) {
1422d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
1432d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  if (!ICC)
1442d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    return CXCommentInlineCommandRenderKind_Normal;
1452d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko
1462d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  switch (ICC->getRenderKind()) {
1472d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  case InlineCommandComment::RenderNormal:
1482d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    return CXCommentInlineCommandRenderKind_Normal;
1492d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko
1502d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  case InlineCommandComment::RenderBold:
1512d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    return CXCommentInlineCommandRenderKind_Bold;
1522d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko
1532d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  case InlineCommandComment::RenderMonospaced:
1542d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    return CXCommentInlineCommandRenderKind_Monospaced;
1552d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko
1562d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  case InlineCommandComment::RenderEmphasized:
1572d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    return CXCommentInlineCommandRenderKind_Emphasized;
1582d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  }
1592d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  llvm_unreachable("unknown InlineCommandComment::RenderKind");
1602d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko}
1612d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko
162ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_InlineCommandComment_getNumArgs(CXComment CXC) {
163ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
164ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!ICC)
165ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return 0;
166ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
167ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return ICC->getNumArgs();
168ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
169ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
170ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_InlineCommandComment_getArgText(CXComment CXC,
171ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                               unsigned ArgIdx) {
172ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
173ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!ICC || ArgIdx >= ICC->getNumArgs())
174dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2aDmitri Gribenko    return cxstring::createNull();
175ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
1765595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko  return cxstring::createRef(ICC->getArgText(ArgIdx));
177ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
178ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
179ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_HTMLTagComment_getTagName(CXComment CXC) {
180ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const HTMLTagComment *HTC = getASTNodeAs<HTMLTagComment>(CXC);
181ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!HTC)
182dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2aDmitri Gribenko    return cxstring::createNull();
183ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
1845595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko  return cxstring::createRef(HTC->getTagName());
185ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
186ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
187ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_HTMLStartTagComment_isSelfClosing(CXComment CXC) {
188ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
189ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!HST)
190ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return false;
191ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
192ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return HST->isSelfClosing();
193ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
194ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
195ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_HTMLStartTag_getNumAttrs(CXComment CXC) {
196ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
197ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!HST)
198ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return 0;
199ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
200ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return HST->getNumAttrs();
201ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
202ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
203ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_HTMLStartTag_getAttrName(CXComment CXC, unsigned AttrIdx) {
204ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
205ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!HST || AttrIdx >= HST->getNumAttrs())
206dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2aDmitri Gribenko    return cxstring::createNull();
207ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
2085595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko  return cxstring::createRef(HST->getAttr(AttrIdx).Name);
209ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
210ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
211ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_HTMLStartTag_getAttrValue(CXComment CXC, unsigned AttrIdx) {
212ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
213ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!HST || AttrIdx >= HST->getNumAttrs())
214dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2aDmitri Gribenko    return cxstring::createNull();
215ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
2165595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko  return cxstring::createRef(HST->getAttr(AttrIdx).Value);
217ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
218ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
219ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_BlockCommandComment_getCommandName(CXComment CXC) {
220ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
221ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!BCC)
222dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2aDmitri Gribenko    return cxstring::createNull();
223ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
224e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  const CommandTraits &Traits = getCommandTraits(CXC);
2255595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko  return cxstring::createRef(BCC->getCommandName(Traits));
226ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
227ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
228ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_BlockCommandComment_getNumArgs(CXComment CXC) {
229ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
230ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!BCC)
231ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return 0;
232ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
233ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return BCC->getNumArgs();
234ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
235ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
236ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_BlockCommandComment_getArgText(CXComment CXC,
237ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                              unsigned ArgIdx) {
238ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
239ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!BCC || ArgIdx >= BCC->getNumArgs())
240dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2aDmitri Gribenko    return cxstring::createNull();
241ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
2425595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko  return cxstring::createRef(BCC->getArgText(ArgIdx));
243ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
244ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
245ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXComment clang_BlockCommandComment_getParagraph(CXComment CXC) {
246ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
247ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!BCC)
248e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko    return createCXComment(NULL, NULL);
249ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
250e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  return createCXComment(BCC->getParagraph(), CXC.TranslationUnit);
251ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
252ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
253ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_ParamCommandComment_getParamName(CXComment CXC) {
254ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
2551f8c529a2a938a5055f440aa063ea0b49eafae98Dmitri Gribenko  if (!PCC || !PCC->hasParamName())
256dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2aDmitri Gribenko    return cxstring::createNull();
257ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
2585595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko  return cxstring::createRef(PCC->getParamNameAsWritten());
259ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
260ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
261ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_ParamCommandComment_isParamIndexValid(CXComment CXC) {
262ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
263ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!PCC)
264ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return false;
265ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
266ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return PCC->isParamIndexValid();
267ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
268ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
269ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_ParamCommandComment_getParamIndex(CXComment CXC) {
270ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
271c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko  if (!PCC || !PCC->isParamIndexValid() || PCC->isVarArgParam())
272ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return ParamCommandComment::InvalidParamIndex;
273ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
274ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return PCC->getParamIndex();
275ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
276ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
277ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkounsigned clang_ParamCommandComment_isDirectionExplicit(CXComment CXC) {
278ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
279ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!PCC)
280ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return false;
281ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
282ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  return PCC->isDirectionExplicit();
283ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
284ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
285ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkoenum CXCommentParamPassDirection clang_ParamCommandComment_getDirection(
286ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                                            CXComment CXC) {
287ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
288ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!PCC)
289ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXCommentParamPassDirection_In;
290ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
291ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  switch (PCC->getDirection()) {
292ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case ParamCommandComment::In:
293ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXCommentParamPassDirection_In;
294ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
295ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case ParamCommandComment::Out:
296ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXCommentParamPassDirection_Out;
297ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
298ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  case ParamCommandComment::InOut:
299ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return CXCommentParamPassDirection_InOut;
300ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
301ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  llvm_unreachable("unknown ParamCommandComment::PassDirection");
302ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
303ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
30496b098674908eaa59a9128f3305cda6fbbdad563Dmitri GribenkoCXString clang_TParamCommandComment_getParamName(CXComment CXC) {
30596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
30696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  if (!TPCC || !TPCC->hasParamName())
307dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2aDmitri Gribenko    return cxstring::createNull();
30896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
3095595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko  return cxstring::createRef(TPCC->getParamNameAsWritten());
31096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko}
31196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
31296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkounsigned clang_TParamCommandComment_isParamPositionValid(CXComment CXC) {
31396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
31496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  if (!TPCC)
31596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    return false;
31696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
31796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  return TPCC->isPositionValid();
31896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko}
31996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
32096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkounsigned clang_TParamCommandComment_getDepth(CXComment CXC) {
32196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
32296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  if (!TPCC || !TPCC->isPositionValid())
32396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    return 0;
32496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
32596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  return TPCC->getDepth();
32696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko}
32796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
32896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkounsigned clang_TParamCommandComment_getIndex(CXComment CXC, unsigned Depth) {
32996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
33096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  if (!TPCC || !TPCC->isPositionValid() || Depth >= TPCC->getDepth())
33196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    return 0;
33296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
33396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  return TPCC->getIndex(Depth);
33496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko}
33596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
336ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_VerbatimBlockLineComment_getText(CXComment CXC) {
337ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const VerbatimBlockLineComment *VBL =
338ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      getASTNodeAs<VerbatimBlockLineComment>(CXC);
339ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!VBL)
340dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2aDmitri Gribenko    return cxstring::createNull();
341ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
3425595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko  return cxstring::createRef(VBL->getText());
343ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
344ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
345ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_VerbatimLineComment_getText(CXComment CXC) {
346ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const VerbatimLineComment *VLC = getASTNodeAs<VerbatimLineComment>(CXC);
347ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!VLC)
348dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2aDmitri Gribenko    return cxstring::createNull();
349ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
3505595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko  return cxstring::createRef(VLC->getText());
351ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
352ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
353ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko} // end extern "C"
354ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
355ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko//===----------------------------------------------------------------------===//
356ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko// Helpers for converting comment AST to HTML.
357ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko//===----------------------------------------------------------------------===//
358ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
359ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkonamespace {
360ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
361c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko/// This comparison will sort parameters with valid index by index, then vararg
362c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko/// parameters, and invalid (unresolved) parameters last.
363ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkoclass ParamCommandCommentCompareIndex {
364ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkopublic:
365ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  bool operator()(const ParamCommandComment *LHS,
366ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                  const ParamCommandComment *RHS) const {
367b740316a122b5ceaaa7cf50557b1b39af5fbbf5fDmitri Gribenko    unsigned LHSIndex = UINT_MAX;
368b740316a122b5ceaaa7cf50557b1b39af5fbbf5fDmitri Gribenko    unsigned RHSIndex = UINT_MAX;
369b740316a122b5ceaaa7cf50557b1b39af5fbbf5fDmitri Gribenko
370c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko    if (LHS->isParamIndexValid()) {
371c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko      if (LHS->isVarArgParam())
372c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko        LHSIndex = UINT_MAX - 1;
373c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko      else
374c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko        LHSIndex = LHS->getParamIndex();
375c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko    }
376c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko    if (RHS->isParamIndexValid()) {
377c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko      if (RHS->isVarArgParam())
378c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko        RHSIndex = UINT_MAX - 1;
379c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko      else
380c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko        RHSIndex = RHS->getParamIndex();
381c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko    }
382b740316a122b5ceaaa7cf50557b1b39af5fbbf5fDmitri Gribenko    return LHSIndex < RHSIndex;
383ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
384ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko};
385ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
38696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko/// This comparison will sort template parameters in the following order:
38796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko/// \li real template parameters (depth = 1) in index order;
38896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko/// \li all other names (depth > 1);
38996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko/// \li unresolved names.
39096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkoclass TParamCommandCommentComparePosition {
39196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkopublic:
39296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  bool operator()(const TParamCommandComment *LHS,
39396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko                  const TParamCommandComment *RHS) const {
39496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    // Sort unresolved names last.
39596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    if (!LHS->isPositionValid())
39696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko      return false;
39796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    if (!RHS->isPositionValid())
39896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko      return true;
39996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
40096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    if (LHS->getDepth() > 1)
40196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko      return false;
40296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    if (RHS->getDepth() > 1)
40396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko      return true;
40496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
40596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    // Sort template parameters in index order.
40696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    if (LHS->getDepth() == 1 && RHS->getDepth() == 1)
40796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko      return LHS->getIndex(0) < RHS->getIndex(0);
40896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
40996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    // Leave all other names in source order.
41096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    return true;
41196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  }
41296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko};
41396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
4142ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko/// Separate parts of a FullComment.
4152ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenkostruct FullCommentParts {
4162ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  /// Take a full comment apart and initialize members accordingly.
417e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  FullCommentParts(const FullComment *C,
418e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko                   const CommandTraits &Traits);
4192ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4202ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  const BlockContentComment *Brief;
421f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian  const BlockContentComment *Headerfile;
4222ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  const ParagraphComment *FirstParagraph;
423d52b20c706326cc2c5c3707a902e7ca4474719b6Fariborz Jahanian  SmallVector<const BlockCommandComment *, 4> Returns;
4242ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  SmallVector<const ParamCommandComment *, 8> Params;
4252ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  SmallVector<const TParamCommandComment *, 4> TParams;
4262ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  SmallVector<const BlockContentComment *, 8> MiscBlocks;
4272ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko};
4282ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
429e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri GribenkoFullCommentParts::FullCommentParts(const FullComment *C,
430e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko                                   const CommandTraits &Traits) :
431d52b20c706326cc2c5c3707a902e7ca4474719b6Fariborz Jahanian    Brief(NULL), Headerfile(NULL), FirstParagraph(NULL) {
4322ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
4332ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko       I != E; ++I) {
4342ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    const Comment *Child = *I;
4352ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    if (!Child)
4362ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      continue;
4372ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    switch (Child->getCommentKind()) {
4382ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::NoCommentKind:
4392ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      continue;
4402ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4412ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::ParagraphCommentKind: {
4422ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      const ParagraphComment *PC = cast<ParagraphComment>(Child);
4432ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      if (PC->isWhitespace())
4442ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko        break;
4452ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      if (!FirstParagraph)
4462ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko        FirstParagraph = PC;
4472ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4482ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      MiscBlocks.push_back(PC);
4492ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      break;
4502ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    }
4512ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4522ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::BlockCommandCommentKind: {
4532ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      const BlockCommandComment *BCC = cast<BlockCommandComment>(Child);
454e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko      const CommandInfo *Info = Traits.getCommandInfo(BCC->getCommandID());
455e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko      if (!Brief && Info->IsBriefCommand) {
4562ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko        Brief = BCC;
4572ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko        break;
4582ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      }
459f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian      if (!Headerfile && Info->IsHeaderfileCommand) {
460f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian        Headerfile = BCC;
461f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian        break;
462f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian      }
463d52b20c706326cc2c5c3707a902e7ca4474719b6Fariborz Jahanian      if (Info->IsReturnsCommand) {
464d52b20c706326cc2c5c3707a902e7ca4474719b6Fariborz Jahanian        Returns.push_back(BCC);
4652ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko        break;
4662ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      }
4672ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      MiscBlocks.push_back(BCC);
4682ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      break;
4692ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    }
4702ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4712ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::ParamCommandCommentKind: {
4722ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      const ParamCommandComment *PCC = cast<ParamCommandComment>(Child);
4732ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      if (!PCC->hasParamName())
4742ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko        break;
4752ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4762ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      if (!PCC->isDirectionExplicit() && !PCC->hasNonWhitespaceParagraph())
4772ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko        break;
4782ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4792ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      Params.push_back(PCC);
4802ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      break;
4812ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    }
4822ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4832ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::TParamCommandCommentKind: {
4842ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      const TParamCommandComment *TPCC = cast<TParamCommandComment>(Child);
4852ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      if (!TPCC->hasParamName())
4862ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko        break;
4872ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4882ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      if (!TPCC->hasNonWhitespaceParagraph())
4892ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko        break;
4902ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4912ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      TParams.push_back(TPCC);
4922ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      break;
4932ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    }
4942ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
4952ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::VerbatimBlockCommentKind:
4962ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      MiscBlocks.push_back(cast<BlockCommandComment>(Child));
4972ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      break;
4982ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
49962290ae569016345b79d4e11dd93abc300e5a681Dmitri Gribenko    case Comment::VerbatimLineCommentKind: {
50062290ae569016345b79d4e11dd93abc300e5a681Dmitri Gribenko      const VerbatimLineComment *VLC = cast<VerbatimLineComment>(Child);
501e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko      const CommandInfo *Info = Traits.getCommandInfo(VLC->getCommandID());
502e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko      if (!Info->IsDeclarationCommand)
50362290ae569016345b79d4e11dd93abc300e5a681Dmitri Gribenko        MiscBlocks.push_back(VLC);
50462290ae569016345b79d4e11dd93abc300e5a681Dmitri Gribenko      break;
50562290ae569016345b79d4e11dd93abc300e5a681Dmitri Gribenko    }
50662290ae569016345b79d4e11dd93abc300e5a681Dmitri Gribenko
5072ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::TextCommentKind:
5082ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::InlineCommandCommentKind:
5092ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::HTMLStartTagCommentKind:
5102ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::HTMLEndTagCommentKind:
5112ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::VerbatimBlockLineCommentKind:
5122ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    case Comment::FullCommentKind:
5132ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      llvm_unreachable("AST node of this kind can't be a child of "
5142ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko                       "a FullComment");
5152ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    }
5162ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  }
5172ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
5182ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  // Sort params in order they are declared in the function prototype.
5192ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  // Unresolved parameters are put at the end of the list in the same order
5202ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  // they were seen in the comment.
5212ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  std::stable_sort(Params.begin(), Params.end(),
5222ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko                   ParamCommandCommentCompareIndex());
5232ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
5242ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  std::stable_sort(TParams.begin(), TParams.end(),
5252ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko                   TParamCommandCommentComparePosition());
5262ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko}
5272ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
5282ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenkovoid PrintHTMLStartTagComment(const HTMLStartTagComment *C,
5292ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko                              llvm::raw_svector_ostream &Result) {
5302ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  Result << "<" << C->getTagName();
5312ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
5322ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  if (C->getNumAttrs() != 0) {
5332ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    for (unsigned i = 0, e = C->getNumAttrs(); i != e; i++) {
5342ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      Result << " ";
5352ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      const HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
5362ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      Result << Attr.Name;
5372ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      if (!Attr.Value.empty())
5382ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko        Result << "=\"" << Attr.Value << "\"";
5392ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    }
5402ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  }
5412ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
5422ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  if (!C->isSelfClosing())
5432ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    Result << ">";
5442ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  else
5452ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    Result << "/>";
5462ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko}
5472ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko
548ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkoclass CommentASTToHTMLConverter :
549ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    public ConstCommentVisitor<CommentASTToHTMLConverter> {
550ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkopublic:
5513e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  /// \param Str accumulator for HTML.
5528cfabf2cb278efc1f694f1d9aab76888a60ee3acDmitri Gribenko  CommentASTToHTMLConverter(const FullComment *FC,
553bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian                            SmallVectorImpl<char> &Str,
554e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko                            const CommandTraits &Traits) :
555bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian      FC(FC), Result(Str), Traits(Traits)
556e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  { }
557ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
558ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  // Inline content.
559ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitTextComment(const TextComment *C);
560ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitInlineCommandComment(const InlineCommandComment *C);
561ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitHTMLStartTagComment(const HTMLStartTagComment *C);
562ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitHTMLEndTagComment(const HTMLEndTagComment *C);
563ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
564ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  // Block content.
565ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitParagraphComment(const ParagraphComment *C);
566ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitBlockCommandComment(const BlockCommandComment *C);
567ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitParamCommandComment(const ParamCommandComment *C);
56896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  void visitTParamCommandComment(const TParamCommandComment *C);
569ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitVerbatimBlockComment(const VerbatimBlockComment *C);
570ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
571ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitVerbatimLineComment(const VerbatimLineComment *C);
572ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
573ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitFullComment(const FullComment *C);
574ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
575ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  // Helpers.
576ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
577ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  /// Convert a paragraph that is not a block by itself (an argument to some
578ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  /// command).
579ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void visitNonStandaloneParagraphComment(const ParagraphComment *C);
580ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
581ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  void appendToResultWithHTMLEscaping(StringRef S);
582ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
583ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkoprivate:
5848cfabf2cb278efc1f694f1d9aab76888a60ee3acDmitri Gribenko  const FullComment *FC;
5853e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  /// Output stream for HTML.
5863e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  llvm::raw_svector_ostream Result;
587e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko
588e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  const CommandTraits &Traits;
589ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko};
590ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko} // end unnamed namespace
591ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
592ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitTextComment(const TextComment *C) {
593ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  appendToResultWithHTMLEscaping(C->getText());
594ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
595ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
596ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitInlineCommandComment(
597ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const InlineCommandComment *C) {
5982d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  // Nothing to render if no arguments supplied.
5992d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  if (C->getNumArgs() == 0)
6002d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    return;
6012d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko
6022d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  // Nothing to render if argument is empty.
6032d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  StringRef Arg0 = C->getArgText(0);
6042d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  if (Arg0.empty())
6052d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    return;
6062d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko
6072d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  switch (C->getRenderKind()) {
6082d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  case InlineCommandComment::RenderNormal:
60959500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) {
61059500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko      appendToResultWithHTMLEscaping(C->getArgText(i));
61159500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko      Result << " ";
61259500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    }
6132d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    return;
6142d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko
6152d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  case InlineCommandComment::RenderBold:
6162d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    assert(C->getNumArgs() == 1);
61759500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    Result << "<b>";
61859500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    appendToResultWithHTMLEscaping(Arg0);
61959500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    Result << "</b>";
620ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
6212d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  case InlineCommandComment::RenderMonospaced:
6222d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    assert(C->getNumArgs() == 1);
62359500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    Result << "<tt>";
62459500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    appendToResultWithHTMLEscaping(Arg0);
62559500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    Result<< "</tt>";
626ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
6272d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko  case InlineCommandComment::RenderEmphasized:
6282d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko    assert(C->getNumArgs() == 1);
62959500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    Result << "<em>";
63059500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    appendToResultWithHTMLEscaping(Arg0);
63159500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko    Result << "</em>";
632ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
633ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
634ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
635ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
636ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitHTMLStartTagComment(
637ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const HTMLStartTagComment *C) {
6382ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  PrintHTMLStartTagComment(C, Result);
639ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
640ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
641ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitHTMLEndTagComment(
642ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const HTMLEndTagComment *C) {
6433e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  Result << "</" << C->getTagName() << ">";
644ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
645ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
646ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitParagraphComment(
647ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const ParagraphComment *C) {
648ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (C->isWhitespace())
649ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
650ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
6513e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  Result << "<p>";
652ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
653ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko       I != E; ++I) {
654ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    visit(*I);
655ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
6563e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  Result << "</p>";
657ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
658ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
659ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitBlockCommandComment(
660ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const BlockCommandComment *C) {
661e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  const CommandInfo *Info = Traits.getCommandInfo(C->getCommandID());
662e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  if (Info->IsBriefCommand) {
6633e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "<p class=\"para-brief\">";
664ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    visitNonStandaloneParagraphComment(C->getParagraph());
6653e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "</p>";
666ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
667ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
668e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  if (Info->IsReturnsCommand) {
6693e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "<p class=\"para-returns\">"
6703e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko              "<span class=\"word-returns\">Returns</span> ";
671ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    visitNonStandaloneParagraphComment(C->getParagraph());
6723e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "</p>";
673ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
674ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
675ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  // We don't know anything about this command.  Just render the paragraph.
676ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  visit(C->getParagraph());
677ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
678ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
679ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitParamCommandComment(
680ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const ParamCommandComment *C) {
6813e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  if (C->isParamIndexValid()) {
682c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko    if (C->isVarArgParam()) {
683c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko      Result << "<dt class=\"param-name-index-vararg\">";
684c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko      appendToResultWithHTMLEscaping(C->getParamNameAsWritten());
685c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko    } else {
686c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko      Result << "<dt class=\"param-name-index-"
687c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko             << C->getParamIndex()
688c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko             << "\">";
689c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko      appendToResultWithHTMLEscaping(C->getParamName(FC));
690c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko    }
691262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian  } else {
6923e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "<dt class=\"param-name-index-invalid\">";
693262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian    appendToResultWithHTMLEscaping(C->getParamNameAsWritten());
694262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian  }
69559500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko  Result << "</dt>";
6963e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko
6973e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  if (C->isParamIndexValid()) {
698c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko    if (C->isVarArgParam())
699c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko      Result << "<dd class=\"param-descr-index-vararg\">";
700c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko    else
701c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko      Result << "<dd class=\"param-descr-index-"
702c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko             << C->getParamIndex()
703c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko             << "\">";
7043e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  } else
7053e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "<dd class=\"param-descr-index-invalid\">";
7063e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko
707ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  visitNonStandaloneParagraphComment(C->getParagraph());
7083e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  Result << "</dd>";
709ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
710ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
71196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkovoid CommentASTToHTMLConverter::visitTParamCommandComment(
71296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko                                  const TParamCommandComment *C) {
71396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  if (C->isPositionValid()) {
71496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    if (C->getDepth() == 1)
7156a425525e52aba5a8e14db35d50a712be4e5e2e1Dmitri Gribenko      Result << "<dt class=\"tparam-name-index-"
71696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko             << C->getIndex(0)
71796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko             << "\">";
71896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    else
7196a425525e52aba5a8e14db35d50a712be4e5e2e1Dmitri Gribenko      Result << "<dt class=\"tparam-name-index-other\">";
720262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian    appendToResultWithHTMLEscaping(C->getParamName(FC));
721262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian  } else {
72296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    Result << "<dt class=\"tparam-name-index-invalid\">";
723262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian    appendToResultWithHTMLEscaping(C->getParamNameAsWritten());
724262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian  }
725262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian
72659500fec689f7def27bb83bd21e19417ad527906Dmitri Gribenko  Result << "</dt>";
72796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
72896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  if (C->isPositionValid()) {
72996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    if (C->getDepth() == 1)
73096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko      Result << "<dd class=\"tparam-descr-index-"
73196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko             << C->getIndex(0)
73296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko             << "\">";
73396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    else
73496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko      Result << "<dd class=\"tparam-descr-index-other\">";
73596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  } else
73696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    Result << "<dd class=\"tparam-descr-index-invalid\">";
73796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
73896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  visitNonStandaloneParagraphComment(C->getParagraph());
73996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  Result << "</dd>";
74096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko}
74196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
742ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitVerbatimBlockComment(
743ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const VerbatimBlockComment *C) {
744ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  unsigned NumLines = C->getNumLines();
745ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (NumLines == 0)
746ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
747ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
7483e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  Result << "<pre>";
749ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  for (unsigned i = 0; i != NumLines; ++i) {
750ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    appendToResultWithHTMLEscaping(C->getText(i));
751ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    if (i + 1 != NumLines)
7523e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko      Result << '\n';
753ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
7543e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  Result << "</pre>";
755ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
756ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
757ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitVerbatimBlockLineComment(
758ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const VerbatimBlockLineComment *C) {
759ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  llvm_unreachable("should not see this AST node");
760ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
761ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
762ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitVerbatimLineComment(
763ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const VerbatimLineComment *C) {
7643e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  Result << "<pre>";
765ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  appendToResultWithHTMLEscaping(C->getText());
7663e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  Result << "</pre>";
767ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
768ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
769ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitFullComment(const FullComment *C) {
770e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  FullCommentParts Parts(C, Traits);
77196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
772ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  bool FirstParagraphIsBrief = false;
773f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian  if (Parts.Headerfile)
774f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian    visit(Parts.Headerfile);
7752ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  if (Parts.Brief)
7762ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    visit(Parts.Brief);
7772ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  else if (Parts.FirstParagraph) {
7783e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "<p class=\"para-brief\">";
7792ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    visitNonStandaloneParagraphComment(Parts.FirstParagraph);
7803e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "</p>";
781ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    FirstParagraphIsBrief = true;
782ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
783ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
7842ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  for (unsigned i = 0, e = Parts.MiscBlocks.size(); i != e; ++i) {
7852ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    const Comment *C = Parts.MiscBlocks[i];
7862ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    if (FirstParagraphIsBrief && C == Parts.FirstParagraph)
787ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      continue;
788ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    visit(C);
789ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
790ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
7912ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  if (Parts.TParams.size() != 0) {
79296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    Result << "<dl>";
7932ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    for (unsigned i = 0, e = Parts.TParams.size(); i != e; ++i)
7942ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      visit(Parts.TParams[i]);
79596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    Result << "</dl>";
79696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  }
79796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
7982ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko  if (Parts.Params.size() != 0) {
7993e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "<dl>";
8002ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko    for (unsigned i = 0, e = Parts.Params.size(); i != e; ++i)
8012ff84b514e53f4273c7067a5aade680a155a9045Dmitri Gribenko      visit(Parts.Params[i]);
8023e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko    Result << "</dl>";
803ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
804ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
805d52b20c706326cc2c5c3707a902e7ca4474719b6Fariborz Jahanian  if (Parts.Returns.size() != 0) {
80697e5bc2643dd1478ca10d1b9a6581f332801c958Dmitri Gribenko    Result << "<div class=\"result-discussion\">";
807d52b20c706326cc2c5c3707a902e7ca4474719b6Fariborz Jahanian    for (unsigned i = 0, e = Parts.Returns.size(); i != e; ++i)
808d52b20c706326cc2c5c3707a902e7ca4474719b6Fariborz Jahanian      visit(Parts.Returns[i]);
80997e5bc2643dd1478ca10d1b9a6581f332801c958Dmitri Gribenko    Result << "</div>";
810d52b20c706326cc2c5c3707a902e7ca4474719b6Fariborz Jahanian  }
8113e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko
8123e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  Result.flush();
813ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
814ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
815ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::visitNonStandaloneParagraphComment(
816ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko                                  const ParagraphComment *C) {
817ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!C)
818ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    return;
819ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
820ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
821ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko       I != E; ++I) {
822ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    visit(*I);
823ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
824ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
825ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
826ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkovoid CommentASTToHTMLConverter::appendToResultWithHTMLEscaping(StringRef S) {
827ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  for (StringRef::iterator I = S.begin(), E = S.end(); I != E; ++I) {
828ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    const char C = *I;
829ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    switch (C) {
830ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      case '&':
8313e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko        Result << "&amp;";
832ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
833ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      case '<':
8343e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko        Result << "&lt;";
835ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
836ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      case '>':
8373e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko        Result << "&gt;";
838ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
839ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      case '"':
8403e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko        Result << "&quot;";
841ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
842ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      case '\'':
8433e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko        Result << "&#39;";
844ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
845ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      case '/':
8463e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko        Result << "&#47;";
847ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
848ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko      default:
8493e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko        Result << C;
850ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko        break;
851ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko    }
852ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  }
853ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
854ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
855ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenkoextern "C" {
856ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
857ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_HTMLTagComment_getAsString(CXComment CXC) {
858ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const HTMLTagComment *HTC = getASTNodeAs<HTMLTagComment>(CXC);
859ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!HTC)
860dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2aDmitri Gribenko    return cxstring::createNull();
861ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
8623e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  SmallString<128> HTML;
863bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian  CommentASTToHTMLConverter Converter(0, HTML, getCommandTraits(CXC));
864ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Converter.visit(HTC);
8655595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko  return cxstring::createDup(HTML.str());
866ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
867ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
868ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri GribenkoCXString clang_FullComment_getAsHTML(CXComment CXC) {
869ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  const FullComment *FC = getASTNodeAs<FullComment>(CXC);
870ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  if (!FC)
871dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2aDmitri Gribenko    return cxstring::createNull();
872ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
8733e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47Dmitri Gribenko  SmallString<1024> HTML;
8748cfabf2cb278efc1f694f1d9aab76888a60ee3acDmitri Gribenko  CommentASTToHTMLConverter Converter(FC, HTML, getCommandTraits(CXC));
875ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko  Converter.visit(FC);
8765595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko  return cxstring::createDup(HTML.str());
877ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko}
878ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
879ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko} // end extern "C"
880ae99b75fbbac1deaccdcc1b326b8fb6b07a1e72dDmitri Gribenko
881f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkonamespace {
882f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkoclass CommentASTToXMLConverter :
883f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    public ConstCommentVisitor<CommentASTToXMLConverter> {
884f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkopublic:
885f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  /// \param Str accumulator for XML.
8868cfabf2cb278efc1f694f1d9aab76888a60ee3acDmitri Gribenko  CommentASTToXMLConverter(const FullComment *FC,
887bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian                           SmallVectorImpl<char> &Str,
888e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko                           const CommandTraits &Traits,
88988b9521364735a6c9a7ccd23c5bd19d81a80cdd3Fariborz Jahanian                           const SourceManager &SM,
8907c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian                           SimpleFormatContext &SFC,
89188b9521364735a6c9a7ccd23c5bd19d81a80cdd3Fariborz Jahanian                           unsigned FUID) :
89288b9521364735a6c9a7ccd23c5bd19d81a80cdd3Fariborz Jahanian      FC(FC), Result(Str), Traits(Traits), SM(SM),
8937c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian      FormatRewriterContext(SFC),
89488b9521364735a6c9a7ccd23c5bd19d81a80cdd3Fariborz Jahanian      FormatInMemoryUniqueId(FUID) { }
895f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
896f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  // Inline content.
897f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitTextComment(const TextComment *C);
898f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitInlineCommandComment(const InlineCommandComment *C);
899f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitHTMLStartTagComment(const HTMLStartTagComment *C);
900f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitHTMLEndTagComment(const HTMLEndTagComment *C);
901f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
902f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  // Block content.
903f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitParagraphComment(const ParagraphComment *C);
904af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko
905af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  void appendParagraphCommentWithKind(const ParagraphComment *C,
906af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko                                      StringRef Kind);
907af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko
908f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitBlockCommandComment(const BlockCommandComment *C);
909f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitParamCommandComment(const ParamCommandComment *C);
910f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitTParamCommandComment(const TParamCommandComment *C);
911f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitVerbatimBlockComment(const VerbatimBlockComment *C);
912f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
913f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitVerbatimLineComment(const VerbatimLineComment *C);
914f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
915f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void visitFullComment(const FullComment *C);
916f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
917f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  // Helpers.
918f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  void appendToResultWithXMLEscaping(StringRef S);
919af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko
9207c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian  void formatTextOfDeclaration(const DeclInfo *DI,
9217c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian                               SmallString<128> &Declaration);
922f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
923f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkoprivate:
9248cfabf2cb278efc1f694f1d9aab76888a60ee3acDmitri Gribenko  const FullComment *FC;
9258cfabf2cb278efc1f694f1d9aab76888a60ee3acDmitri Gribenko
926f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  /// Output stream for XML.
927f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  llvm::raw_svector_ostream Result;
928e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko
929e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  const CommandTraits &Traits;
930e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  const SourceManager &SM;
93188b9521364735a6c9a7ccd23c5bd19d81a80cdd3Fariborz Jahanian  SimpleFormatContext &FormatRewriterContext;
93288b9521364735a6c9a7ccd23c5bd19d81a80cdd3Fariborz Jahanian  unsigned FormatInMemoryUniqueId;
933f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko};
9347c98499ba594116d75555f39a1cce28cd26d76a5Dmitri Gribenko
9357c98499ba594116d75555f39a1cce28cd26d76a5Dmitri Gribenkovoid getSourceTextOfDeclaration(const DeclInfo *ThisDecl,
9367c98499ba594116d75555f39a1cce28cd26d76a5Dmitri Gribenko                                SmallVectorImpl<char> &Str) {
9377c98499ba594116d75555f39a1cce28cd26d76a5Dmitri Gribenko  ASTContext &Context = ThisDecl->CurrentDecl->getASTContext();
9387c98499ba594116d75555f39a1cce28cd26d76a5Dmitri Gribenko  const LangOptions &LangOpts = Context.getLangOpts();
9397c98499ba594116d75555f39a1cce28cd26d76a5Dmitri Gribenko  llvm::raw_svector_ostream OS(Str);
9407c98499ba594116d75555f39a1cce28cd26d76a5Dmitri Gribenko  PrintingPolicy PPolicy(LangOpts);
94140902d817e5a73850045d8a0c9795bc5047ee000Fariborz Jahanian  PPolicy.PolishForDeclaration = true;
9427c98499ba594116d75555f39a1cce28cd26d76a5Dmitri Gribenko  PPolicy.TerseOutput = true;
9437c98499ba594116d75555f39a1cce28cd26d76a5Dmitri Gribenko  ThisDecl->CurrentDecl->print(OS, PPolicy,
94427c2cb24d5e2e9fda68b929c6d03c761196d8e2dDmitri Gribenko                               /*Indentation*/0, /*PrintInstantiation*/false);
9457c98499ba594116d75555f39a1cce28cd26d76a5Dmitri Gribenko}
94688b9521364735a6c9a7ccd23c5bd19d81a80cdd3Fariborz Jahanian
9477c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanianvoid CommentASTToXMLConverter::formatTextOfDeclaration(
9487c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian                                              const DeclInfo *DI,
9497c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian                                              SmallString<128> &Declaration) {
9507c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian  // FIXME. formatting API expects null terminated input string.
9517c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian  // There might be more efficient way of doing this.
9527c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian  std::string StringDecl = Declaration.str();
95388b9521364735a6c9a7ccd23c5bd19d81a80cdd3Fariborz Jahanian
9547c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian  // Formatter specific code.
9557c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian  // Form a unique in memory buffer name.
956cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko  SmallString<128> filename;
9577c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian  filename += "xmldecl";
9587c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian  filename += llvm::utostr(FormatInMemoryUniqueId);
9597c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian  filename += ".xd";
9607c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian  FileID ID = FormatRewriterContext.createInMemoryFile(filename, StringDecl);
9617c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian  SourceLocation Start =
9627c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian    FormatRewriterContext.Sources.getLocForStartOfFile(ID).getLocWithOffset(0);
9637c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian  unsigned Length = Declaration.size();
96488b9521364735a6c9a7ccd23c5bd19d81a80cdd3Fariborz Jahanian
9657c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian  std::vector<CharSourceRange>
9667c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian    Ranges(1, CharSourceRange::getCharRange(Start, Start.getLocWithOffset(Length)));
9677c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian  ASTContext &Context = DI->CurrentDecl->getASTContext();
9687c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian  const LangOptions &LangOpts = Context.getLangOpts();
9697c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian  Lexer Lex(ID, FormatRewriterContext.Sources.getBuffer(ID),
9707c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian            FormatRewriterContext.Sources, LangOpts);
9717c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian  tooling::Replacements Replace =
9727c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian    reformat(format::getLLVMStyle(), Lex, FormatRewriterContext.Sources, Ranges);
9737c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian  applyAllReplacements(Replace, FormatRewriterContext.Rewrite);
9747c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian  Declaration = FormatRewriterContext.getRewrittenText(ID);
97588b9521364735a6c9a7ccd23c5bd19d81a80cdd3Fariborz Jahanian}
9767c98499ba594116d75555f39a1cce28cd26d76a5Dmitri Gribenko
977f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko} // end unnamed namespace
978f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
979f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitTextComment(const TextComment *C) {
980f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  appendToResultWithXMLEscaping(C->getText());
981f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
982f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
983f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitInlineCommandComment(const InlineCommandComment *C) {
984f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  // Nothing to render if no arguments supplied.
985f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (C->getNumArgs() == 0)
986f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    return;
987f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
988f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  // Nothing to render if argument is empty.
989f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  StringRef Arg0 = C->getArgText(0);
990f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (Arg0.empty())
991f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    return;
992f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
993f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  switch (C->getRenderKind()) {
994f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  case InlineCommandComment::RenderNormal:
995f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) {
996f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      appendToResultWithXMLEscaping(C->getArgText(i));
997f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      Result << " ";
998f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    }
999f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    return;
1000f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  case InlineCommandComment::RenderBold:
1001f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    assert(C->getNumArgs() == 1);
1002f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "<bold>";
1003f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    appendToResultWithXMLEscaping(Arg0);
1004f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "</bold>";
1005f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    return;
1006f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  case InlineCommandComment::RenderMonospaced:
1007f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    assert(C->getNumArgs() == 1);
1008f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "<monospaced>";
1009f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    appendToResultWithXMLEscaping(Arg0);
1010f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "</monospaced>";
1011f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    return;
1012f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  case InlineCommandComment::RenderEmphasized:
1013f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    assert(C->getNumArgs() == 1);
1014f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "<emphasized>";
1015f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    appendToResultWithXMLEscaping(Arg0);
1016f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "</emphasized>";
1017f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    return;
1018f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
1019f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
1020f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1021f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitHTMLStartTagComment(const HTMLStartTagComment *C) {
1022f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "<rawHTML><![CDATA[";
1023f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  PrintHTMLStartTagComment(C, Result);
1024f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "]]></rawHTML>";
1025f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
1026f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1027f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitHTMLEndTagComment(const HTMLEndTagComment *C) {
1028f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "<rawHTML>&lt;/" << C->getTagName() << "&gt;</rawHTML>";
1029f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
1030f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1031f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitParagraphComment(const ParagraphComment *C) {
1032af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  appendParagraphCommentWithKind(C, StringRef());
1033af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko}
1034af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko
1035af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenkovoid CommentASTToXMLConverter::appendParagraphCommentWithKind(
1036af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko                                  const ParagraphComment *C,
1037af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko                                  StringRef ParagraphKind) {
1038f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (C->isWhitespace())
1039f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    return;
1040f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1041af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  if (ParagraphKind.empty())
1042af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko    Result << "<Para>";
1043af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  else
1044af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko    Result << "<Para kind=\"" << ParagraphKind << "\">";
1045af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko
1046f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
1047f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko       I != E; ++I) {
1048f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    visit(*I);
1049f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
1050f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "</Para>";
1051f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
1052f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1053f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitBlockCommandComment(const BlockCommandComment *C) {
1054af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  StringRef ParagraphKind;
1055af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko
1056af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  switch (C->getCommandID()) {
10579db0fe97f533513f88e7141f0b2a405ebe86fa67Fariborz Jahanian  case CommandTraits::KCI_attention:
1058af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  case CommandTraits::KCI_author:
1059af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  case CommandTraits::KCI_authors:
1060af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  case CommandTraits::KCI_bug:
1061af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  case CommandTraits::KCI_copyright:
1062af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  case CommandTraits::KCI_date:
1063af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  case CommandTraits::KCI_invariant:
1064af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  case CommandTraits::KCI_note:
1065af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  case CommandTraits::KCI_post:
1066af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  case CommandTraits::KCI_pre:
1067af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  case CommandTraits::KCI_remark:
1068af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  case CommandTraits::KCI_remarks:
1069af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  case CommandTraits::KCI_sa:
1070af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  case CommandTraits::KCI_see:
1071af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  case CommandTraits::KCI_since:
1072af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  case CommandTraits::KCI_todo:
1073af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  case CommandTraits::KCI_version:
1074af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  case CommandTraits::KCI_warning:
1075af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko    ParagraphKind = C->getCommandName(Traits);
1076af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  default:
1077af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko    break;
1078af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  }
1079af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko
1080af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko  appendParagraphCommentWithKind(C->getParagraph(), ParagraphKind);
1081f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
1082f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1083f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitParamCommandComment(const ParamCommandComment *C) {
1084f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "<Parameter><Name>";
1085262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian  appendToResultWithXMLEscaping(C->isParamIndexValid() ? C->getParamName(FC)
1086262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian                                                       : C->getParamNameAsWritten());
1087f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "</Name>";
1088f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1089c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko  if (C->isParamIndexValid()) {
1090c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko    if (C->isVarArgParam())
1091c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko      Result << "<IsVarArg />";
1092c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko    else
1093c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko      Result << "<Index>" << C->getParamIndex() << "</Index>";
1094c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko  }
1095f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1096f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "<Direction isExplicit=\"" << C->isDirectionExplicit() << "\">";
1097f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  switch (C->getDirection()) {
1098f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  case ParamCommandComment::In:
1099f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "in";
1100f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    break;
1101f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  case ParamCommandComment::Out:
1102f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "out";
1103f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    break;
1104f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  case ParamCommandComment::InOut:
1105f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "in,out";
1106f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    break;
1107f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
1108f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "</Direction><Discussion>";
1109f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  visit(C->getParagraph());
1110f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "</Discussion></Parameter>";
1111f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
1112f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1113f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitTParamCommandComment(
1114f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko                                  const TParamCommandComment *C) {
1115f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "<Parameter><Name>";
1116262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian  appendToResultWithXMLEscaping(C->isPositionValid() ? C->getParamName(FC)
1117262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian                                : C->getParamNameAsWritten());
1118f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "</Name>";
1119f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1120f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (C->isPositionValid() && C->getDepth() == 1) {
1121f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "<Index>" << C->getIndex(0) << "</Index>";
1122f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
1123f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1124f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "<Discussion>";
1125f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  visit(C->getParagraph());
1126f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "</Discussion></Parameter>";
1127f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
1128f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1129f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitVerbatimBlockComment(
1130f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko                                  const VerbatimBlockComment *C) {
1131f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  unsigned NumLines = C->getNumLines();
1132f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (NumLines == 0)
1133f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    return;
1134f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
11354c494f4af76017e2bb389a3a96cbcdbb8973cf97Dmitri Gribenko  switch (C->getCommandID()) {
11364c494f4af76017e2bb389a3a96cbcdbb8973cf97Dmitri Gribenko  case CommandTraits::KCI_code:
11374c494f4af76017e2bb389a3a96cbcdbb8973cf97Dmitri Gribenko    Result << "<Verbatim xml:space=\"preserve\" kind=\"code\">";
11384c494f4af76017e2bb389a3a96cbcdbb8973cf97Dmitri Gribenko    break;
11394c494f4af76017e2bb389a3a96cbcdbb8973cf97Dmitri Gribenko  default:
11404c494f4af76017e2bb389a3a96cbcdbb8973cf97Dmitri Gribenko    Result << "<Verbatim xml:space=\"preserve\" kind=\"verbatim\">";
11414c494f4af76017e2bb389a3a96cbcdbb8973cf97Dmitri Gribenko    break;
11424c494f4af76017e2bb389a3a96cbcdbb8973cf97Dmitri Gribenko  }
1143f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  for (unsigned i = 0; i != NumLines; ++i) {
1144f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    appendToResultWithXMLEscaping(C->getText(i));
1145f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    if (i + 1 != NumLines)
1146f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      Result << '\n';
1147f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
1148f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "</Verbatim>";
1149f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
1150f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1151f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitVerbatimBlockLineComment(
1152f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko                                  const VerbatimBlockLineComment *C) {
1153f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  llvm_unreachable("should not see this AST node");
1154f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
1155f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1156f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitVerbatimLineComment(
1157f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko                                  const VerbatimLineComment *C) {
11586cd4420945489e7331012103048f162288a6c7d8Dmitri Gribenko  Result << "<Verbatim xml:space=\"preserve\" kind=\"verbatim\">";
1159f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  appendToResultWithXMLEscaping(C->getText());
1160f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << "</Verbatim>";
1161f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
1162f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1163f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::visitFullComment(const FullComment *C) {
1164e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  FullCommentParts Parts(C, Traits);
1165f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1166f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  const DeclInfo *DI = C->getDeclInfo();
1167f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  StringRef RootEndTag;
1168f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (DI) {
1169f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    switch (DI->getKind()) {
1170f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    case DeclInfo::OtherKind:
1171f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      RootEndTag = "</Other>";
1172f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      Result << "<Other";
1173f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      break;
1174f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    case DeclInfo::FunctionKind:
1175f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      RootEndTag = "</Function>";
1176f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      Result << "<Function";
1177f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      switch (DI->TemplateKind) {
1178f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case DeclInfo::NotTemplate:
1179f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1180f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case DeclInfo::Template:
1181f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << " templateKind=\"template\"";
1182f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1183f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case DeclInfo::TemplateSpecialization:
1184f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << " templateKind=\"specialization\"";
1185f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1186f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case DeclInfo::TemplatePartialSpecialization:
1187f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        llvm_unreachable("partial specializations of functions "
1188f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko                         "are not allowed in C++");
1189f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      }
1190f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      if (DI->IsInstanceMethod)
1191f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << " isInstanceMethod=\"1\"";
1192f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      if (DI->IsClassMethod)
1193f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << " isClassMethod=\"1\"";
1194f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      break;
1195f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    case DeclInfo::ClassKind:
1196f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      RootEndTag = "</Class>";
1197f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      Result << "<Class";
1198f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      switch (DI->TemplateKind) {
1199f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case DeclInfo::NotTemplate:
1200f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1201f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case DeclInfo::Template:
1202f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << " templateKind=\"template\"";
1203f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1204f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case DeclInfo::TemplateSpecialization:
1205f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << " templateKind=\"specialization\"";
1206f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1207f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case DeclInfo::TemplatePartialSpecialization:
1208f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << " templateKind=\"partialSpecialization\"";
1209f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1210f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      }
1211f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      break;
1212f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    case DeclInfo::VariableKind:
1213f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      RootEndTag = "</Variable>";
1214f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      Result << "<Variable";
1215f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      break;
1216f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    case DeclInfo::NamespaceKind:
1217f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      RootEndTag = "</Namespace>";
1218f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      Result << "<Namespace";
1219f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      break;
1220f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    case DeclInfo::TypedefKind:
1221f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      RootEndTag = "</Typedef>";
1222f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      Result << "<Typedef";
1223f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      break;
1224cff339a60a571a606a7510548f661dc6a719368dDmitri Gribenko    case DeclInfo::EnumKind:
1225cff339a60a571a606a7510548f661dc6a719368dDmitri Gribenko      RootEndTag = "</Enum>";
1226cff339a60a571a606a7510548f661dc6a719368dDmitri Gribenko      Result << "<Enum";
1227cff339a60a571a606a7510548f661dc6a719368dDmitri Gribenko      break;
1228f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    }
1229f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1230f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    {
1231f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      // Print line and column number.
12321bfb00dabf83d8c8b95b7276b4c0ae3fd64832c8Fariborz Jahanian      SourceLocation Loc = DI->CurrentDecl->getLocation();
1233f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
1234f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      FileID FID = LocInfo.first;
1235f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      unsigned FileOffset = LocInfo.second;
1236f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1237f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      if (!FID.isInvalid()) {
1238f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        if (const FileEntry *FE = SM.getFileEntryForID(FID)) {
1239f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko          Result << " file=\"";
1240f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko          appendToResultWithXMLEscaping(FE->getName());
1241f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko          Result << "\"";
1242f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        }
1243f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << " line=\"" << SM.getLineNumber(FID, FileOffset)
1244f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko               << "\" column=\"" << SM.getColumnNumber(FID, FileOffset)
1245f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko               << "\"";
1246f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      }
1247f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    }
1248f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1249f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    // Finish the root tag.
1250f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << ">";
1251f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1252f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    bool FoundName = false;
1253bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian    if (const NamedDecl *ND = dyn_cast<NamedDecl>(DI->CommentDecl)) {
1254f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      if (DeclarationName DeclName = ND->getDeclName()) {
1255f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << "<Name>";
1256f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        std::string Name = DeclName.getAsString();
1257f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        appendToResultWithXMLEscaping(Name);
1258f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        FoundName = true;
1259f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << "</Name>";
1260f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      }
1261f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    }
1262f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    if (!FoundName)
1263f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      Result << "<Name>&lt;anonymous&gt;</Name>";
1264f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1265f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    {
1266f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      // Print USR.
1267f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      SmallString<128> USR;
1268bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian      cxcursor::getDeclCursorUSR(DI->CommentDecl, USR);
1269f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      if (!USR.empty()) {
1270f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << "<USR>";
1271f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        appendToResultWithXMLEscaping(USR);
1272f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << "</USR>";
1273f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      }
1274f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    }
1275f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  } else {
1276f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    // No DeclInfo -- just emit some root tag and name tag.
1277f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    RootEndTag = "</Other>";
1278f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "<Other><Name>unknown</Name>";
1279f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
1280f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian
1281f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian  if (Parts.Headerfile) {
1282f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian    Result << "<Headerfile>";
1283f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian    visit(Parts.Headerfile);
1284f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian    Result << "</Headerfile>";
1285f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian  }
1286f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
12877c98499ba594116d75555f39a1cce28cd26d76a5Dmitri Gribenko  {
12887c98499ba594116d75555f39a1cce28cd26d76a5Dmitri Gribenko    // Pretty-print the declaration.
12897c98499ba594116d75555f39a1cce28cd26d76a5Dmitri Gribenko    Result << "<Declaration>";
12907c98499ba594116d75555f39a1cce28cd26d76a5Dmitri Gribenko    SmallString<128> Declaration;
12917c98499ba594116d75555f39a1cce28cd26d76a5Dmitri Gribenko    getSourceTextOfDeclaration(DI, Declaration);
12927c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian    formatTextOfDeclaration(DI, Declaration);
12937c98499ba594116d75555f39a1cce28cd26d76a5Dmitri Gribenko    appendToResultWithXMLEscaping(Declaration);
129488b9521364735a6c9a7ccd23c5bd19d81a80cdd3Fariborz Jahanian
12957c98499ba594116d75555f39a1cce28cd26d76a5Dmitri Gribenko    Result << "</Declaration>";
12967c98499ba594116d75555f39a1cce28cd26d76a5Dmitri Gribenko  }
12977c98499ba594116d75555f39a1cce28cd26d76a5Dmitri Gribenko
1298f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  bool FirstParagraphIsBrief = false;
1299f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (Parts.Brief) {
1300f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "<Abstract>";
1301f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    visit(Parts.Brief);
1302f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "</Abstract>";
1303f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  } else if (Parts.FirstParagraph) {
1304f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "<Abstract>";
1305f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    visit(Parts.FirstParagraph);
1306f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "</Abstract>";
1307f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    FirstParagraphIsBrief = true;
1308f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
1309f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian
1310f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (Parts.TParams.size() != 0) {
1311f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "<TemplateParameters>";
1312f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    for (unsigned i = 0, e = Parts.TParams.size(); i != e; ++i)
1313f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      visit(Parts.TParams[i]);
1314f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "</TemplateParameters>";
1315f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
1316f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1317f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (Parts.Params.size() != 0) {
1318f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "<Parameters>";
1319f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    for (unsigned i = 0, e = Parts.Params.size(); i != e; ++i)
1320f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      visit(Parts.Params[i]);
1321f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "</Parameters>";
1322f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
1323f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1324d52b20c706326cc2c5c3707a902e7ca4474719b6Fariborz Jahanian  if (Parts.Returns.size() != 0) {
1325f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "<ResultDiscussion>";
1326d52b20c706326cc2c5c3707a902e7ca4474719b6Fariborz Jahanian    for (unsigned i = 0, e = Parts.Returns.size(); i != e; ++i)
1327d52b20c706326cc2c5c3707a902e7ca4474719b6Fariborz Jahanian      visit(Parts.Returns[i]);
1328f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    Result << "</ResultDiscussion>";
1329f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
1330257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian
1331bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian  if (DI->CommentDecl->hasAttrs()) {
1332bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian    const AttrVec &Attrs = DI->CommentDecl->getAttrs();
1333faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian    for (unsigned i = 0, e = Attrs.size(); i != e; i++) {
1334faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian      const AvailabilityAttr *AA = dyn_cast<AvailabilityAttr>(Attrs[i]);
13352a46533633441176e93b484739a0a27e07150b63Fariborz Jahanian      if (!AA) {
13368da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian        if (const DeprecatedAttr *DA = dyn_cast<DeprecatedAttr>(Attrs[i])) {
13378da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian          if (DA->getMessage().empty())
13388da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian            Result << "<Deprecated/>";
13398da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian          else {
13407d9c975bf2ea8e607646e23c15da744490e10d5dDmitri Gribenko            Result << "<Deprecated>";
13417d9c975bf2ea8e607646e23c15da744490e10d5dDmitri Gribenko            appendToResultWithXMLEscaping(DA->getMessage());
13427d9c975bf2ea8e607646e23c15da744490e10d5dDmitri Gribenko            Result << "</Deprecated>";
13438da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian          }
13448da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian        }
13458da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian        else if (const UnavailableAttr *UA = dyn_cast<UnavailableAttr>(Attrs[i])) {
13468da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian          if (UA->getMessage().empty())
13478da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian            Result << "<Unavailable/>";
13488da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian          else {
13497d9c975bf2ea8e607646e23c15da744490e10d5dDmitri Gribenko            Result << "<Unavailable>";
13507d9c975bf2ea8e607646e23c15da744490e10d5dDmitri Gribenko            appendToResultWithXMLEscaping(UA->getMessage());
13517d9c975bf2ea8e607646e23c15da744490e10d5dDmitri Gribenko            Result << "</Unavailable>";
13528da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian          }
13538da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian        }
1354257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian        continue;
13552a46533633441176e93b484739a0a27e07150b63Fariborz Jahanian      }
1356faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian
1357faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian      // 'availability' attribute.
1358257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      Result << "<Availability";
1359faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian      StringRef Distribution;
1360257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      if (AA->getPlatform()) {
1361faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian        Distribution = AvailabilityAttr::getPrettyPlatformName(
1362faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian                                        AA->getPlatform()->getName());
1363faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian        if (Distribution.empty())
1364faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian          Distribution = AA->getPlatform()->getName();
1365257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      }
1366faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian      Result << " distribution=\"" << Distribution << "\">";
1367257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      VersionTuple IntroducedInVersion = AA->getIntroduced();
1368257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      if (!IntroducedInVersion.empty()) {
1369faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian        Result << "<IntroducedInVersion>"
1370faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian               << IntroducedInVersion.getAsString()
1371faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian               << "</IntroducedInVersion>";
1372257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      }
1373257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      VersionTuple DeprecatedInVersion = AA->getDeprecated();
1374257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      if (!DeprecatedInVersion.empty()) {
1375faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian        Result << "<DeprecatedInVersion>"
1376faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian               << DeprecatedInVersion.getAsString()
1377faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian               << "</DeprecatedInVersion>";
1378257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      }
1379257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      VersionTuple RemovedAfterVersion = AA->getObsoleted();
1380257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      if (!RemovedAfterVersion.empty()) {
1381faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian        Result << "<RemovedAfterVersion>"
1382faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian               << RemovedAfterVersion.getAsString()
1383faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian               << "</RemovedAfterVersion>";
1384257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      }
1385257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      StringRef DeprecationSummary = AA->getMessage();
1386257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      if (!DeprecationSummary.empty()) {
13877d9c975bf2ea8e607646e23c15da744490e10d5dDmitri Gribenko        Result << "<DeprecationSummary>";
13887d9c975bf2ea8e607646e23c15da744490e10d5dDmitri Gribenko        appendToResultWithXMLEscaping(DeprecationSummary);
13897d9c975bf2ea8e607646e23c15da744490e10d5dDmitri Gribenko        Result << "</DeprecationSummary>";
1390257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      }
1391257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian      if (AA->getUnavailable())
13928da68b8b03d72314b67ea44568e013ef79d93b40Fariborz Jahanian        Result << "<Unavailable/>";
1393faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian      Result << "</Availability>";
1394257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian    }
1395257e2e836160c7e55cf160b7cae8e5665f988a5eFariborz Jahanian  }
1396faab5618b5beed350d7444de97cf513ef1a42ca6Fariborz Jahanian
1397f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  {
1398f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    bool StartTagEmitted = false;
1399f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    for (unsigned i = 0, e = Parts.MiscBlocks.size(); i != e; ++i) {
1400f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      const Comment *C = Parts.MiscBlocks[i];
1401f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      if (FirstParagraphIsBrief && C == Parts.FirstParagraph)
1402f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        continue;
1403f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      if (!StartTagEmitted) {
1404f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << "<Discussion>";
1405f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        StartTagEmitted = true;
1406f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      }
1407f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      visit(C);
1408f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    }
1409f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    if (StartTagEmitted)
1410f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      Result << "</Discussion>";
1411f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
1412f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1413f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result << RootEndTag;
1414f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1415f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Result.flush();
1416f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
1417f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1418f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkovoid CommentASTToXMLConverter::appendToResultWithXMLEscaping(StringRef S) {
1419f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  for (StringRef::iterator I = S.begin(), E = S.end(); I != E; ++I) {
1420f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    const char C = *I;
1421f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    switch (C) {
1422f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case '&':
1423f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << "&amp;";
1424f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1425f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case '<':
1426f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << "&lt;";
1427f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1428f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case '>':
1429f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << "&gt;";
1430f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1431f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case '"':
1432f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << "&quot;";
1433f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1434f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      case '\'':
1435f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << "&apos;";
1436f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1437f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko      default:
1438f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        Result << C;
1439f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko        break;
1440f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko    }
1441f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  }
1442f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
1443f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1444f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenkoextern "C" {
1445f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1446e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri GribenkoCXString clang_FullComment_getAsXML(CXComment CXC) {
1447f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  const FullComment *FC = getASTNodeAs<FullComment>(CXC);
1448f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  if (!FC)
1449dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2aDmitri Gribenko    return cxstring::createNull();
145088b9521364735a6c9a7ccd23c5bd19d81a80cdd3Fariborz Jahanian  ASTContext &Context = FC->getDeclInfo()->CurrentDecl->getASTContext();
1451e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko  CXTranslationUnit TU = CXC.TranslationUnit;
14525694feb5ccd6eb862cb600b55753cecc13794471Dmitri Gribenko  SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();
1453337ee24785a784ba5418c2e78716d15b94fd57f0Dmitri Gribenko
1454337ee24785a784ba5418c2e78716d15b94fd57f0Dmitri Gribenko  if (!TU->FormatContext) {
1455337ee24785a784ba5418c2e78716d15b94fd57f0Dmitri Gribenko    TU->FormatContext = new SimpleFormatContext(Context.getLangOpts());
14568a68da12c71efeeaca0ed24c39288a2117d07f9dFariborz Jahanian  } else if ((TU->FormatInMemoryUniqueId % 1000) == 0) {
14577c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian    // Delete after some number of iterators, so the buffers don't grow
14587c10683c834f051e018c89b090d64bf5e4ca3bccFariborz Jahanian    // too large.
1459337ee24785a784ba5418c2e78716d15b94fd57f0Dmitri Gribenko    delete TU->FormatContext;
1460337ee24785a784ba5418c2e78716d15b94fd57f0Dmitri Gribenko    TU->FormatContext = new SimpleFormatContext(Context.getLangOpts());
146188b9521364735a6c9a7ccd23c5bd19d81a80cdd3Fariborz Jahanian  }
1462f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1463f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  SmallString<1024> XML;
146488b9521364735a6c9a7ccd23c5bd19d81a80cdd3Fariborz Jahanian  CommentASTToXMLConverter Converter(FC, XML, getCommandTraits(CXC), SM,
1465337ee24785a784ba5418c2e78716d15b94fd57f0Dmitri Gribenko                                     *TU->FormatContext,
1466337ee24785a784ba5418c2e78716d15b94fd57f0Dmitri Gribenko                                     TU->FormatInMemoryUniqueId++);
1467f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko  Converter.visit(FC);
14685595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko  return cxstring::createDup(XML.str());
1469f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko}
1470f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1471f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko} // end extern "C"
1472f303d4cb10648ac9c2080ae7c9dd507ba615e3a7Dmitri Gribenko
1473