CXComment.cpp revision 4d0ddecbe7dbbfeb89e428ed6e19c3cf12325087
16d47bae50b63d47441321d6a367c37625e38d390Chris Lattner//===- CXComment.cpp - libclang APIs for manipulating CXComments ----------===//
2113ec35f7f69bd66c0fbab7b42e2b9d59eddb946Mikhail Glushenkov//
3e2fab734ade8a2e3e8679c11cac7236b920d567bJohn Criswell//                     The LLVM Compiler Infrastructure
4e2fab734ade8a2e3e8679c11cac7236b920d567bJohn Criswell//
551167848265a0fa006c32557caa4aeb3f482f45eChris Lattner// This file is distributed under the University of Illinois Open Source
651167848265a0fa006c32557caa4aeb3f482f45eChris Lattner// License. See LICENSE.TXT for details.
7113ec35f7f69bd66c0fbab7b42e2b9d59eddb946Mikhail Glushenkov//
8e2fab734ade8a2e3e8679c11cac7236b920d567bJohn Criswell//===----------------------------------------------------------------------===//
96d47bae50b63d47441321d6a367c37625e38d390Chris Lattner//
10698e9ce56864223fe73b1ebefaf19845daf0c3d7Chris Lattner// This file defines all libclang APIs related to walking comment AST.
110a26891ce9b6de840c087d73c04324729c3d1a8bMike Stump//
12e5ab51d51f6e5cebf57db76c7f8527febc6a2b71NAKAMURA Takumi//===----------------------------------------------------------------------===//
13e5ab51d51f6e5cebf57db76c7f8527febc6a2b71NAKAMURA Takumi
140a26891ce9b6de840c087d73c04324729c3d1a8bMike Stump#include "clang-c/Index.h"
15e5ab51d51f6e5cebf57db76c7f8527febc6a2b71NAKAMURA Takumi#include "CXComment.h"
16e5ab51d51f6e5cebf57db76c7f8527febc6a2b71NAKAMURA Takumi#include "CXCursor.h"
17e5ab51d51f6e5cebf57db76c7f8527febc6a2b71NAKAMURA Takumi#include "CXString.h"
18e5ab51d51f6e5cebf57db76c7f8527febc6a2b71NAKAMURA Takumi#include "clang/AST/Decl.h"
19e5ab51d51f6e5cebf57db76c7f8527febc6a2b71NAKAMURA Takumi#include "clang/Index/CommentToXML.h"
20e5ab51d51f6e5cebf57db76c7f8527febc6a2b71NAKAMURA Takumi#include "llvm/ADT/StringExtras.h"
210a26891ce9b6de840c087d73c04324729c3d1a8bMike Stump#include "llvm/ADT/StringSwitch.h"
22cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/Support/ErrorHandling.h"
23cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include <climits>
24cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
25ebccf0891a2f6b75c2ac8de97557ca0cf5ad61c3Stephen Wilsonusing namespace clang;
26113ec35f7f69bd66c0fbab7b42e2b9d59eddb946Mikhail Glushenkovusing namespace clang::comments;
27113ec35f7f69bd66c0fbab7b42e2b9d59eddb946Mikhail Glushenkovusing namespace clang::cxcomment;
2836a987eed00886f6508668942df140fa053256caReid Spencer
291cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbachextern "C" {
30dd5d86d992eb129ecd0bb013d2db2d6a0e8d2605Chandler Carruth
31b6adb4216cbc466cae62eff75ec9b2b552ecf866Chandler Carruthenum CXCommentKind clang_Comment_getKind(CXComment CXC) {
32b6adb4216cbc466cae62eff75ec9b2b552ecf866Chandler Carruth  const Comment *C = getASTNode(CXC);
33b6adb4216cbc466cae62eff75ec9b2b552ecf866Chandler Carruth  if (!C)
3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return CXComment_Null;
35041b3f835682588cb63df7e609d726369dd6b7d3Bill Wendling
36b709f9fe5a578e05c371ff58771b9d1582ff259fAndrew Kaylor  switch (C->getCommentKind()) {
37b709f9fe5a578e05c371ff58771b9d1582ff259fAndrew Kaylor  case Comment::NoCommentKind:
38b709f9fe5a578e05c371ff58771b9d1582ff259fAndrew Kaylor    return CXComment_Null;
39b709f9fe5a578e05c371ff58771b9d1582ff259fAndrew Kaylor
40b709f9fe5a578e05c371ff58771b9d1582ff259fAndrew Kaylor  case Comment::TextCommentKind:
41069429062d15a020047a3e52680822709aeb6d51Chris Lattner    return CXComment_Text;
42069429062d15a020047a3e52680822709aeb6d51Chris Lattner
43069429062d15a020047a3e52680822709aeb6d51Chris Lattner  case Comment::InlineCommandCommentKind:
44ebccf0891a2f6b75c2ac8de97557ca0cf5ad61c3Stephen Wilson    return CXComment_InlineCommand;
45ebccf0891a2f6b75c2ac8de97557ca0cf5ad61c3Stephen Wilson
46069429062d15a020047a3e52680822709aeb6d51Chris Lattner  case Comment::HTMLStartTagCommentKind:
47069429062d15a020047a3e52680822709aeb6d51Chris Lattner    return CXComment_HTMLStartTag;
4823e6d2b88a34e4a7aea9120446683c598da470d7Chris Lattner
4923e6d2b88a34e4a7aea9120446683c598da470d7Chris Lattner  case Comment::HTMLEndTagCommentKind:
50b8810a38865974ed41420ce85f21495e77990a80Daniel Dunbar    return CXComment_HTMLEndTag;
51e9742d2f6c21522afda3a5c79936b9469be3e6d3Nick Lewycky
52b4b544debac44da375d316e410ec447d967036a9NAKAMURA Takumi  case Comment::ParagraphCommentKind:
5388fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne    return CXComment_Paragraph;
5488fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne
55b4b544debac44da375d316e410ec447d967036a9NAKAMURA Takumi  case Comment::BlockCommandCommentKind:
5688fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne    return CXComment_BlockCommand;
57b4b544debac44da375d316e410ec447d967036a9NAKAMURA Takumi
58847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner  case Comment::ParamCommandCommentKind:
59b4b544debac44da375d316e410ec447d967036a9NAKAMURA Takumi    return CXComment_ParamCommand;
60294492b25f9a953e9210e4e1a23465e1b599fef8Anton Korobeynikov
61ac28588def0093238a28c52952c37919190873f5Reid Spencer  case Comment::TParamCommandCommentKind:
62baaadb2672e70916eb7e35b48b5ca34bec772fb8Tobias Grosser    return CXComment_TParamCommand;
63baaadb2672e70916eb7e35b48b5ca34bec772fb8Tobias Grosser
64baaadb2672e70916eb7e35b48b5ca34bec772fb8Tobias Grosser  case Comment::VerbatimBlockCommentKind:
65b8810a38865974ed41420ce85f21495e77990a80Daniel Dunbar    return CXComment_VerbatimBlockCommand;
66baaadb2672e70916eb7e35b48b5ca34bec772fb8Tobias Grosser
67f5f6588304f803f09e36e7fc23c8f756b200b127NAKAMURA Takumi  case Comment::VerbatimBlockLineCommentKind:
68f5f6588304f803f09e36e7fc23c8f756b200b127NAKAMURA Takumi    return CXComment_VerbatimBlockLine;
690ae59f4c07a85ba8455c8119534c06c78a62614aNAKAMURA Takumi
70f5f6588304f803f09e36e7fc23c8f756b200b127NAKAMURA Takumi  case Comment::VerbatimLineCommentKind:
71f5f6588304f803f09e36e7fc23c8f756b200b127NAKAMURA Takumi    return CXComment_VerbatimLine;
72f5f6588304f803f09e36e7fc23c8f756b200b127NAKAMURA Takumi
73f5f6588304f803f09e36e7fc23c8f756b200b127NAKAMURA Takumi  case Comment::FullCommentKind:
74f5f6588304f803f09e36e7fc23c8f756b200b127NAKAMURA Takumi    return CXComment_FullComment;
75cf8cb6d56445823a51965f00d54517594f36e0b6Chris Lattner  }
76  llvm_unreachable("unknown CommentKind");
77}
78
79unsigned clang_Comment_getNumChildren(CXComment CXC) {
80  const Comment *C = getASTNode(CXC);
81  if (!C)
82    return 0;
83
84  return C->child_count();
85}
86
87CXComment clang_Comment_getChild(CXComment CXC, unsigned ChildIdx) {
88  const Comment *C = getASTNode(CXC);
89  if (!C || ChildIdx >= C->child_count())
90    return createCXComment(NULL, NULL);
91
92  return createCXComment(*(C->child_begin() + ChildIdx), CXC.TranslationUnit);
93}
94
95unsigned clang_Comment_isWhitespace(CXComment CXC) {
96  const Comment *C = getASTNode(CXC);
97  if (!C)
98    return false;
99
100  if (const TextComment *TC = dyn_cast<TextComment>(C))
101    return TC->isWhitespace();
102
103  if (const ParagraphComment *PC = dyn_cast<ParagraphComment>(C))
104    return PC->isWhitespace();
105
106  return false;
107}
108
109unsigned clang_InlineContentComment_hasTrailingNewline(CXComment CXC) {
110  const InlineContentComment *ICC = getASTNodeAs<InlineContentComment>(CXC);
111  if (!ICC)
112    return false;
113
114  return ICC->hasTrailingNewline();
115}
116
117CXString clang_TextComment_getText(CXComment CXC) {
118  const TextComment *TC = getASTNodeAs<TextComment>(CXC);
119  if (!TC)
120    return cxstring::createNull();
121
122  return cxstring::createRef(TC->getText());
123}
124
125CXString clang_InlineCommandComment_getCommandName(CXComment CXC) {
126  const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
127  if (!ICC)
128    return cxstring::createNull();
129
130  const CommandTraits &Traits = getCommandTraits(CXC);
131  return cxstring::createRef(ICC->getCommandName(Traits));
132}
133
134enum CXCommentInlineCommandRenderKind
135clang_InlineCommandComment_getRenderKind(CXComment CXC) {
136  const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
137  if (!ICC)
138    return CXCommentInlineCommandRenderKind_Normal;
139
140  switch (ICC->getRenderKind()) {
141  case InlineCommandComment::RenderNormal:
142    return CXCommentInlineCommandRenderKind_Normal;
143
144  case InlineCommandComment::RenderBold:
145    return CXCommentInlineCommandRenderKind_Bold;
146
147  case InlineCommandComment::RenderMonospaced:
148    return CXCommentInlineCommandRenderKind_Monospaced;
149
150  case InlineCommandComment::RenderEmphasized:
151    return CXCommentInlineCommandRenderKind_Emphasized;
152  }
153  llvm_unreachable("unknown InlineCommandComment::RenderKind");
154}
155
156unsigned clang_InlineCommandComment_getNumArgs(CXComment CXC) {
157  const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
158  if (!ICC)
159    return 0;
160
161  return ICC->getNumArgs();
162}
163
164CXString clang_InlineCommandComment_getArgText(CXComment CXC,
165                                               unsigned ArgIdx) {
166  const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
167  if (!ICC || ArgIdx >= ICC->getNumArgs())
168    return cxstring::createNull();
169
170  return cxstring::createRef(ICC->getArgText(ArgIdx));
171}
172
173CXString clang_HTMLTagComment_getTagName(CXComment CXC) {
174  const HTMLTagComment *HTC = getASTNodeAs<HTMLTagComment>(CXC);
175  if (!HTC)
176    return cxstring::createNull();
177
178  return cxstring::createRef(HTC->getTagName());
179}
180
181unsigned clang_HTMLStartTagComment_isSelfClosing(CXComment CXC) {
182  const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
183  if (!HST)
184    return false;
185
186  return HST->isSelfClosing();
187}
188
189unsigned clang_HTMLStartTag_getNumAttrs(CXComment CXC) {
190  const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
191  if (!HST)
192    return 0;
193
194  return HST->getNumAttrs();
195}
196
197CXString clang_HTMLStartTag_getAttrName(CXComment CXC, unsigned AttrIdx) {
198  const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
199  if (!HST || AttrIdx >= HST->getNumAttrs())
200    return cxstring::createNull();
201
202  return cxstring::createRef(HST->getAttr(AttrIdx).Name);
203}
204
205CXString clang_HTMLStartTag_getAttrValue(CXComment CXC, unsigned AttrIdx) {
206  const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
207  if (!HST || AttrIdx >= HST->getNumAttrs())
208    return cxstring::createNull();
209
210  return cxstring::createRef(HST->getAttr(AttrIdx).Value);
211}
212
213CXString clang_BlockCommandComment_getCommandName(CXComment CXC) {
214  const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
215  if (!BCC)
216    return cxstring::createNull();
217
218  const CommandTraits &Traits = getCommandTraits(CXC);
219  return cxstring::createRef(BCC->getCommandName(Traits));
220}
221
222unsigned clang_BlockCommandComment_getNumArgs(CXComment CXC) {
223  const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
224  if (!BCC)
225    return 0;
226
227  return BCC->getNumArgs();
228}
229
230CXString clang_BlockCommandComment_getArgText(CXComment CXC,
231                                              unsigned ArgIdx) {
232  const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
233  if (!BCC || ArgIdx >= BCC->getNumArgs())
234    return cxstring::createNull();
235
236  return cxstring::createRef(BCC->getArgText(ArgIdx));
237}
238
239CXComment clang_BlockCommandComment_getParagraph(CXComment CXC) {
240  const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
241  if (!BCC)
242    return createCXComment(NULL, NULL);
243
244  return createCXComment(BCC->getParagraph(), CXC.TranslationUnit);
245}
246
247CXString clang_ParamCommandComment_getParamName(CXComment CXC) {
248  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
249  if (!PCC || !PCC->hasParamName())
250    return cxstring::createNull();
251
252  return cxstring::createRef(PCC->getParamNameAsWritten());
253}
254
255unsigned clang_ParamCommandComment_isParamIndexValid(CXComment CXC) {
256  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
257  if (!PCC)
258    return false;
259
260  return PCC->isParamIndexValid();
261}
262
263unsigned clang_ParamCommandComment_getParamIndex(CXComment CXC) {
264  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
265  if (!PCC || !PCC->isParamIndexValid() || PCC->isVarArgParam())
266    return ParamCommandComment::InvalidParamIndex;
267
268  return PCC->getParamIndex();
269}
270
271unsigned clang_ParamCommandComment_isDirectionExplicit(CXComment CXC) {
272  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
273  if (!PCC)
274    return false;
275
276  return PCC->isDirectionExplicit();
277}
278
279enum CXCommentParamPassDirection clang_ParamCommandComment_getDirection(
280                                                            CXComment CXC) {
281  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
282  if (!PCC)
283    return CXCommentParamPassDirection_In;
284
285  switch (PCC->getDirection()) {
286  case ParamCommandComment::In:
287    return CXCommentParamPassDirection_In;
288
289  case ParamCommandComment::Out:
290    return CXCommentParamPassDirection_Out;
291
292  case ParamCommandComment::InOut:
293    return CXCommentParamPassDirection_InOut;
294  }
295  llvm_unreachable("unknown ParamCommandComment::PassDirection");
296}
297
298CXString clang_TParamCommandComment_getParamName(CXComment CXC) {
299  const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
300  if (!TPCC || !TPCC->hasParamName())
301    return cxstring::createNull();
302
303  return cxstring::createRef(TPCC->getParamNameAsWritten());
304}
305
306unsigned clang_TParamCommandComment_isParamPositionValid(CXComment CXC) {
307  const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
308  if (!TPCC)
309    return false;
310
311  return TPCC->isPositionValid();
312}
313
314unsigned clang_TParamCommandComment_getDepth(CXComment CXC) {
315  const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
316  if (!TPCC || !TPCC->isPositionValid())
317    return 0;
318
319  return TPCC->getDepth();
320}
321
322unsigned clang_TParamCommandComment_getIndex(CXComment CXC, unsigned Depth) {
323  const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
324  if (!TPCC || !TPCC->isPositionValid() || Depth >= TPCC->getDepth())
325    return 0;
326
327  return TPCC->getIndex(Depth);
328}
329
330CXString clang_VerbatimBlockLineComment_getText(CXComment CXC) {
331  const VerbatimBlockLineComment *VBL =
332      getASTNodeAs<VerbatimBlockLineComment>(CXC);
333  if (!VBL)
334    return cxstring::createNull();
335
336  return cxstring::createRef(VBL->getText());
337}
338
339CXString clang_VerbatimLineComment_getText(CXComment CXC) {
340  const VerbatimLineComment *VLC = getASTNodeAs<VerbatimLineComment>(CXC);
341  if (!VLC)
342    return cxstring::createNull();
343
344  return cxstring::createRef(VLC->getText());
345}
346
347//===----------------------------------------------------------------------===//
348// Converting comments to XML.
349//===----------------------------------------------------------------------===//
350
351CXString clang_HTMLTagComment_getAsString(CXComment CXC) {
352  const HTMLTagComment *HTC = getASTNodeAs<HTMLTagComment>(CXC);
353  if (!HTC)
354    return cxstring::createNull();
355
356  CXTranslationUnit TU = CXC.TranslationUnit;
357  if (!TU->CommentToXML)
358    TU->CommentToXML = new clang::index::CommentToXMLConverter();
359
360  SmallString<128> Text;
361  TU->CommentToXML->convertHTMLTagNodeToText(
362      HTC, Text, cxtu::getASTUnit(TU)->getASTContext());
363  return cxstring::createDup(Text.str());
364}
365
366CXString clang_FullComment_getAsHTML(CXComment CXC) {
367  const FullComment *FC = getASTNodeAs<FullComment>(CXC);
368  if (!FC)
369    return cxstring::createNull();
370
371  CXTranslationUnit TU = CXC.TranslationUnit;
372  if (!TU->CommentToXML)
373    TU->CommentToXML = new clang::index::CommentToXMLConverter();
374
375  SmallString<1024> HTML;
376  TU->CommentToXML
377      ->convertCommentToHTML(FC, HTML, cxtu::getASTUnit(TU)->getASTContext());
378  return cxstring::createDup(HTML.str());
379}
380
381CXString clang_FullComment_getAsXML(CXComment CXC) {
382  const FullComment *FC = getASTNodeAs<FullComment>(CXC);
383  if (!FC)
384    return cxstring::createNull();
385
386  CXTranslationUnit TU = CXC.TranslationUnit;
387  if (!TU->CommentToXML)
388    TU->CommentToXML = new clang::index::CommentToXMLConverter();
389
390  SmallString<1024> XML;
391  TU->CommentToXML
392      ->convertCommentToXML(FC, XML, cxtu::getASTUnit(TU)->getASTContext());
393  return cxstring::createDup(XML.str());
394}
395
396} // end extern "C"
397
398