Coverage Report

Created: 2020-09-19 12:23

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/tools/libclang/CXComment.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- CXComment.cpp - libclang APIs for manipulating CXComments ----------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file defines all libclang APIs related to walking comment AST.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "CXComment.h"
14
#include "CXCursor.h"
15
#include "CXString.h"
16
#include "clang-c/Documentation.h"
17
#include "clang-c/Index.h"
18
#include "clang/AST/Decl.h"
19
#include "clang/Index/CommentToXML.h"
20
#include "llvm/ADT/StringExtras.h"
21
#include "llvm/Support/ErrorHandling.h"
22
#include <climits>
23
24
using namespace clang;
25
using namespace clang::comments;
26
using namespace clang::cxcomment;
27
28
79.9k
CXComment clang_Cursor_getParsedComment(CXCursor C) {
29
79.9k
  using namespace clang::cxcursor;
30
79.9k
31
79.9k
  if (!clang_isDeclaration(C.kind))
32
73.2k
    return createCXComment(nullptr, nullptr);
33
6.69k
34
6.69k
  const Decl *D = getCursorDecl(C);
35
6.69k
  const ASTContext &Context = getCursorContext(C);
36
6.69k
  const FullComment *FC = Context.getCommentForDecl(D, /*PP=*/nullptr);
37
6.69k
38
6.69k
  return createCXComment(FC, getCursorTU(C));
39
6.69k
}
40
41
86.2k
enum CXCommentKind clang_Comment_getKind(CXComment CXC) {
42
86.2k
  const Comment *C = getASTNode(CXC);
43
86.2k
  if (!C)
44
79.0k
    return CXComment_Null;
45
7.25k
46
7.25k
  switch (C->getCommentKind()) {
47
0
  case Comment::NoCommentKind:
48
0
    return CXComment_Null;
49
0
50
2.27k
  case Comment::TextCommentKind:
51
2.27k
    return CXComment_Text;
52
0
53
183
  case Comment::InlineCommandCommentKind:
54
183
    return CXComment_InlineCommand;
55
0
56
47
  case Comment::HTMLStartTagCommentKind:
57
47
    return CXComment_HTMLStartTag;
58
0
59
31
  case Comment::HTMLEndTagCommentKind:
60
31
    return CXComment_HTMLEndTag;
61
0
62
1.90k
  case Comment::ParagraphCommentKind:
63
1.90k
    return CXComment_Paragraph;
64
0
65
504
  case Comment::BlockCommandCommentKind:
66
504
    return CXComment_BlockCommand;
67
0
68
200
  case Comment::ParamCommandCommentKind:
69
200
    return CXComment_ParamCommand;
70
0
71
118
  case Comment::TParamCommandCommentKind:
72
118
    return CXComment_TParamCommand;
73
0
74
9
  case Comment::VerbatimBlockCommentKind:
75
9
    return CXComment_VerbatimBlockCommand;
76
0
77
17
  case Comment::VerbatimBlockLineCommentKind:
78
17
    return CXComment_VerbatimBlockLine;
79
0
80
42
  case Comment::VerbatimLineCommentKind:
81
42
    return CXComment_VerbatimLine;
82
0
83
1.92k
  case Comment::FullCommentKind:
84
1.92k
    return CXComment_FullComment;
85
0
  }
86
0
  llvm_unreachable("unknown CommentKind");
87
0
}
88
89
6.29k
unsigned clang_Comment_getNumChildren(CXComment CXC) {
90
6.29k
  const Comment *C = getASTNode(CXC);
91
6.29k
  if (!C)
92
0
    return 0;
93
6.29k
94
6.29k
  return C->child_count();
95
6.29k
}
96
97
5.33k
CXComment clang_Comment_getChild(CXComment CXC, unsigned ChildIdx) {
98
5.33k
  const Comment *C = getASTNode(CXC);
99
5.33k
  if (!C || ChildIdx >= C->child_count())
100
0
    return createCXComment(nullptr, nullptr);
101
5.33k
102
5.33k
  return createCXComment(*(C->child_begin() + ChildIdx), CXC.TranslationUnit);
103
5.33k
}
104
105
4.18k
unsigned clang_Comment_isWhitespace(CXComment CXC) {
106
4.18k
  const Comment *C = getASTNode(CXC);
107
4.18k
  if (!C)
108
0
    return false;
109
4.18k
110
4.18k
  if (const TextComment *TC = dyn_cast<TextComment>(C))
111
2.27k
    return TC->isWhitespace();
112
1.90k
113
1.90k
  if (const ParagraphComment *PC = dyn_cast<ParagraphComment>(C))
114
1.90k
    return PC->isWhitespace();
115
0
116
0
  return false;
117
0
}
118
119
2.53k
unsigned clang_InlineContentComment_hasTrailingNewline(CXComment CXC) {
120
2.53k
  const InlineContentComment *ICC = getASTNodeAs<InlineContentComment>(CXC);
121
2.53k
  if (!ICC)
122
0
    return false;
123
2.53k
124
2.53k
  return ICC->hasTrailingNewline();
125
2.53k
}
126
127
2.27k
CXString clang_TextComment_getText(CXComment CXC) {
128
2.27k
  const TextComment *TC = getASTNodeAs<TextComment>(CXC);
129
2.27k
  if (!TC)
130
0
    return cxstring::createNull();
131
2.27k
132
2.27k
  return cxstring::createRef(TC->getText());
133
2.27k
}
134
135
183
CXString clang_InlineCommandComment_getCommandName(CXComment CXC) {
136
183
  const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
137
183
  if (!ICC)
138
0
    return cxstring::createNull();
139
183
140
183
  const CommandTraits &Traits = getCommandTraits(CXC);
141
183
  return cxstring::createRef(ICC->getCommandName(Traits));
142
183
}
143
144
enum CXCommentInlineCommandRenderKind
145
183
clang_InlineCommandComment_getRenderKind(CXComment CXC) {
146
183
  const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
147
183
  if (!ICC)
148
0
    return CXCommentInlineCommandRenderKind_Normal;
149
183
150
183
  switch (ICC->getRenderKind()) {
151
146
  case InlineCommandComment::RenderNormal:
152
146
    return CXCommentInlineCommandRenderKind_Normal;
153
0
154
4
  case InlineCommandComment::RenderBold:
155
4
    return CXCommentInlineCommandRenderKind_Bold;
156
0
157
11
  case InlineCommandComment::RenderMonospaced:
158
11
    return CXCommentInlineCommandRenderKind_Monospaced;
159
0
160
18
  case InlineCommandComment::RenderEmphasized:
161
18
    return CXCommentInlineCommandRenderKind_Emphasized;
162
0
163
4
  case InlineCommandComment::RenderAnchor:
164
4
    return CXCommentInlineCommandRenderKind_Anchor;
165
0
  }
166
0
  llvm_unreachable("unknown InlineCommandComment::RenderKind");
167
0
}
168
169
183
unsigned clang_InlineCommandComment_getNumArgs(CXComment CXC) {
170
183
  const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
171
183
  if (!ICC)
172
0
    return 0;
173
183
174
183
  return ICC->getNumArgs();
175
183
}
176
177
CXString clang_InlineCommandComment_getArgText(CXComment CXC,
178
31
                                               unsigned ArgIdx) {
179
31
  const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
180
31
  if (!ICC || ArgIdx >= ICC->getNumArgs())
181
0
    return cxstring::createNull();
182
31
183
31
  return cxstring::createRef(ICC->getArgText(ArgIdx));
184
31
}
185
186
78
CXString clang_HTMLTagComment_getTagName(CXComment CXC) {
187
78
  const HTMLTagComment *HTC = getASTNodeAs<HTMLTagComment>(CXC);
188
78
  if (!HTC)
189
0
    return cxstring::createNull();
190
78
191
78
  return cxstring::createRef(HTC->getTagName());
192
78
}
193
194
47
unsigned clang_HTMLStartTagComment_isSelfClosing(CXComment CXC) {
195
47
  const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
196
47
  if (!HST)
197
0
    return false;
198
47
199
47
  return HST->isSelfClosing();
200
47
}
201
202
47
unsigned clang_HTMLStartTag_getNumAttrs(CXComment CXC) {
203
47
  const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
204
47
  if (!HST)
205
0
    return 0;
206
47
207
47
  return HST->getNumAttrs();
208
47
}
209
210
21
CXString clang_HTMLStartTag_getAttrName(CXComment CXC, unsigned AttrIdx) {
211
21
  const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
212
21
  if (!HST || AttrIdx >= HST->getNumAttrs())
213
0
    return cxstring::createNull();
214
21
215
21
  return cxstring::createRef(HST->getAttr(AttrIdx).Name);
216
21
}
217
218
21
CXString clang_HTMLStartTag_getAttrValue(CXComment CXC, unsigned AttrIdx) {
219
21
  const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
220
21
  if (!HST || AttrIdx >= HST->getNumAttrs())
221
0
    return cxstring::createNull();
222
21
223
21
  return cxstring::createRef(HST->getAttr(AttrIdx).Value);
224
21
}
225
226
513
CXString clang_BlockCommandComment_getCommandName(CXComment CXC) {
227
513
  const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
228
513
  if (!BCC)
229
0
    return cxstring::createNull();
230
513
231
513
  const CommandTraits &Traits = getCommandTraits(CXC);
232
513
  return cxstring::createRef(BCC->getCommandName(Traits));
233
513
}
234
235
504
unsigned clang_BlockCommandComment_getNumArgs(CXComment CXC) {
236
504
  const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
237
504
  if (!BCC)
238
0
    return 0;
239
504
240
504
  return BCC->getNumArgs();
241
504
}
242
243
CXString clang_BlockCommandComment_getArgText(CXComment CXC,
244
0
                                              unsigned ArgIdx) {
245
0
  const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
246
0
  if (!BCC || ArgIdx >= BCC->getNumArgs())
247
0
    return cxstring::createNull();
248
0
249
0
  return cxstring::createRef(BCC->getArgText(ArgIdx));
250
0
}
251
252
0
CXComment clang_BlockCommandComment_getParagraph(CXComment CXC) {
253
0
  const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
254
0
  if (!BCC)
255
0
    return createCXComment(nullptr, nullptr);
256
0
257
0
  return createCXComment(BCC->getParagraph(), CXC.TranslationUnit);
258
0
}
259
260
200
CXString clang_ParamCommandComment_getParamName(CXComment CXC) {
261
200
  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
262
200
  if (!PCC || !PCC->hasParamName())
263
4
    return cxstring::createNull();
264
196
265
196
  return cxstring::createRef(PCC->getParamNameAsWritten());
266
196
}
267
268
200
unsigned clang_ParamCommandComment_isParamIndexValid(CXComment CXC) {
269
200
  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
270
200
  if (!PCC)
271
0
    return false;
272
200
273
200
  return PCC->isParamIndexValid();
274
200
}
275
276
130
unsigned clang_ParamCommandComment_getParamIndex(CXComment CXC) {
277
130
  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
278
130
  if (!PCC || !PCC->isParamIndexValid() || PCC->isVarArgParam())
279
8
    return ParamCommandComment::InvalidParamIndex;
280
122
281
122
  return PCC->getParamIndex();
282
122
}
283
284
200
unsigned clang_ParamCommandComment_isDirectionExplicit(CXComment CXC) {
285
200
  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
286
200
  if (!PCC)
287
0
    return false;
288
200
289
200
  return PCC->isDirectionExplicit();
290
200
}
291
292
enum CXCommentParamPassDirection clang_ParamCommandComment_getDirection(
293
200
                                                            CXComment CXC) {
294
200
  const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
295
200
  if (!PCC)
296
0
    return CXCommentParamPassDirection_In;
297
200
298
200
  switch (PCC->getDirection()) {
299
195
  case ParamCommandComment::In:
300
195
    return CXCommentParamPassDirection_In;
301
0
302
3
  case ParamCommandComment::Out:
303
3
    return CXCommentParamPassDirection_Out;
304
0
305
2
  case ParamCommandComment::InOut:
306
2
    return CXCommentParamPassDirection_InOut;
307
0
  }
308
0
  llvm_unreachable("unknown ParamCommandComment::PassDirection");
309
0
}
310
311
118
CXString clang_TParamCommandComment_getParamName(CXComment CXC) {
312
118
  const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
313
118
  if (!TPCC || !TPCC->hasParamName())
314
6
    return cxstring::createNull();
315
112
316
112
  return cxstring::createRef(TPCC->getParamNameAsWritten());
317
112
}
318
319
118
unsigned clang_TParamCommandComment_isParamPositionValid(CXComment CXC) {
320
118
  const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
321
118
  if (!TPCC)
322
0
    return false;
323
118
324
118
  return TPCC->isPositionValid();
325
118
}
326
327
82
unsigned clang_TParamCommandComment_getDepth(CXComment CXC) {
328
82
  const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
329
82
  if (!TPCC || !TPCC->isPositionValid())
330
0
    return 0;
331
82
332
82
  return TPCC->getDepth();
333
82
}
334
335
114
unsigned clang_TParamCommandComment_getIndex(CXComment CXC, unsigned Depth) {
336
114
  const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
337
114
  if (!TPCC || !TPCC->isPositionValid() || Depth >= TPCC->getDepth())
338
0
    return 0;
339
114
340
114
  return TPCC->getIndex(Depth);
341
114
}
342
343
17
CXString clang_VerbatimBlockLineComment_getText(CXComment CXC) {
344
17
  const VerbatimBlockLineComment *VBL =
345
17
      getASTNodeAs<VerbatimBlockLineComment>(CXC);
346
17
  if (!VBL)
347
0
    return cxstring::createNull();
348
17
349
17
  return cxstring::createRef(VBL->getText());
350
17
}
351
352
42
CXString clang_VerbatimLineComment_getText(CXComment CXC) {
353
42
  const VerbatimLineComment *VLC = getASTNodeAs<VerbatimLineComment>(CXC);
354
42
  if (!VLC)
355
0
    return cxstring::createNull();
356
42
357
42
  return cxstring::createRef(VLC->getText());
358
42
}
359
360
//===----------------------------------------------------------------------===//
361
// Converting comments to XML.
362
//===----------------------------------------------------------------------===//
363
364
0
CXString clang_HTMLTagComment_getAsString(CXComment CXC) {
365
0
  const HTMLTagComment *HTC = getASTNodeAs<HTMLTagComment>(CXC);
366
0
  if (!HTC)
367
0
    return cxstring::createNull();
368
0
369
0
  CXTranslationUnit TU = CXC.TranslationUnit;
370
0
  if (!TU->CommentToXML)
371
0
    TU->CommentToXML = new clang::index::CommentToXMLConverter();
372
0
373
0
  SmallString<128> Text;
374
0
  TU->CommentToXML->convertHTMLTagNodeToText(
375
0
      HTC, Text, cxtu::getASTUnit(TU)->getASTContext());
376
0
  return cxstring::createDup(Text.str());
377
0
}
378
379
961
CXString clang_FullComment_getAsHTML(CXComment CXC) {
380
961
  const FullComment *FC = getASTNodeAs<FullComment>(CXC);
381
961
  if (!FC)
382
0
    return cxstring::createNull();
383
961
384
961
  CXTranslationUnit TU = CXC.TranslationUnit;
385
961
  if (!TU->CommentToXML)
386
42
    TU->CommentToXML = new clang::index::CommentToXMLConverter();
387
961
388
961
  SmallString<1024> HTML;
389
961
  TU->CommentToXML
390
961
      ->convertCommentToHTML(FC, HTML, cxtu::getASTUnit(TU)->getASTContext());
391
961
  return cxstring::createDup(HTML.str());
392
961
}
393
394
961
CXString clang_FullComment_getAsXML(CXComment CXC) {
395
961
  const FullComment *FC = getASTNodeAs<FullComment>(CXC);
396
961
  if (!FC)
397
0
    return cxstring::createNull();
398
961
399
961
  CXTranslationUnit TU = CXC.TranslationUnit;
400
961
  if (!TU->CommentToXML)
401
0
    TU->CommentToXML = new clang::index::CommentToXMLConverter();
402
961
403
961
  SmallString<1024> XML;
404
961
  TU->CommentToXML
405
961
      ->convertCommentToXML(FC, XML, cxtu::getASTUnit(TU)->getASTContext());
406
961
  return cxstring::createDup(XML.str());
407
961
}
408