Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/AST/JSONNodeDumper.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "clang/AST/JSONNodeDumper.h"
2
#include "clang/Lex/Lexer.h"
3
#include "llvm/ADT/StringSwitch.h"
4
5
using namespace clang;
6
7
933
void JSONNodeDumper::addPreviousDeclaration(const Decl *D) {
8
933
  switch (D->getKind()) {
9
933
#define DECL(DERIVED, BASE)                                                    \
10
933
  case Decl::DERIVED:                                                          \
11
933
    return writePreviousDeclImpl(cast<DERIVED##Decl>(D));
12
933
#define ABSTRACT_DECL(DECL)
13
933
#include 
"clang/AST/DeclNodes.inc"1
14
933
#undef ABSTRACT_DECL
15
933
#undef DECL
16
933
  }
17
933
  
llvm_unreachable0
("Decl that isn't part of DeclNodes.inc!");
18
933
}
19
20
9
void JSONNodeDumper::Visit(const Attr *A) {
21
9
  const char *AttrName = nullptr;
22
9
  switch (A->getKind()) {
23
9
#define ATTR(X)                                                                \
24
9
  case attr::X:                                                                \
25
9
    AttrName = #X"Attr";                                                       \
26
9
    break;
27
9
#include 
"clang/Basic/AttrList.inc"0
28
9
#undef ATTR
29
9
  }
30
9
  JOS.attribute("id", createPointerRepresentation(A));
31
9
  JOS.attribute("kind", AttrName);
32
9
  JOS.attributeObject("range", [A, this] { writeSourceRange(A->getRange()); });
33
9
  attributeOnlyIfTrue("inherited", A->isInherited());
34
9
  attributeOnlyIfTrue("implicit", A->isImplicit());
35
9
36
9
  // FIXME: it would be useful for us to output the spelling kind as well as
37
9
  // the actual spelling. This would allow us to distinguish between the
38
9
  // various attribute syntaxes, but we don't currently track that information
39
9
  // within the AST.
40
9
  //JOS.attribute("spelling", A->getSpelling());
41
9
42
9
  InnerAttrVisitor::Visit(A);
43
9
}
44
45
1.37k
void JSONNodeDumper::Visit(const Stmt *S) {
46
1.37k
  if (!S)
47
18
    return;
48
1.35k
49
1.35k
  JOS.attribute("id", createPointerRepresentation(S));
50
1.35k
  JOS.attribute("kind", S->getStmtClassName());
51
1.35k
  JOS.attributeObject("range",
52
1.35k
                      [S, this] { writeSourceRange(S->getSourceRange()); });
53
1.35k
54
1.35k
  if (const auto *E = dyn_cast<Expr>(S)) {
55
1.02k
    JOS.attribute("type", createQualType(E->getType()));
56
1.02k
    const char *Category = nullptr;
57
1.02k
    switch (E->getValueKind()) {
58
1.02k
    
case VK_LValue: Category = "lvalue"; break313
;
59
1.02k
    
case VK_XValue: Category = "xvalue"; break0
;
60
1.02k
    
case VK_RValue: Category = "rvalue"; break713
;
61
1.02k
    }
62
1.02k
    JOS.attribute("valueCategory", Category);
63
1.02k
  }
64
1.35k
  InnerStmtVisitor::Visit(S);
65
1.35k
}
66
67
142
void JSONNodeDumper::Visit(const Type *T) {
68
142
  JOS.attribute("id", createPointerRepresentation(T));
69
142
  JOS.attribute("kind", (llvm::Twine(T->getTypeClassName()) + "Type").str());
70
142
  JOS.attribute("type", createQualType(QualType(T, 0), /*Desugar*/ false));
71
142
  attributeOnlyIfTrue("isDependent", T->isDependentType());
72
142
  attributeOnlyIfTrue("isInstantiationDependent",
73
142
                      T->isInstantiationDependentType());
74
142
  attributeOnlyIfTrue("isVariablyModified", T->isVariablyModifiedType());
75
142
  attributeOnlyIfTrue("containsUnexpandedPack",
76
142
                      T->containsUnexpandedParameterPack());
77
142
  attributeOnlyIfTrue("isImported", T->isFromAST());
78
142
  InnerTypeVisitor::Visit(T);
79
142
}
80
81
1
void JSONNodeDumper::Visit(QualType T) {
82
1
  JOS.attribute("id", createPointerRepresentation(T.getAsOpaquePtr()));
83
1
  JOS.attribute("kind", "QualType");
84
1
  JOS.attribute("type", createQualType(T));
85
1
  JOS.attribute("qualifiers", T.split().Quals.getAsString());
86
1
}
87
88
934
void JSONNodeDumper::Visit(const Decl *D) {
89
934
  JOS.attribute("id", createPointerRepresentation(D));
90
934
91
934
  if (!D)
92
1
    return;
93
933
94
933
  JOS.attribute("kind", (llvm::Twine(D->getDeclKindName()) + "Decl").str());
95
933
  JOS.attributeObject("loc",
96
933
                      [D, this] { writeSourceLocation(D->getLocation()); });
97
933
  JOS.attributeObject("range",
98
933
                      [D, this] { writeSourceRange(D->getSourceRange()); });
99
933
  attributeOnlyIfTrue("isImplicit", D->isImplicit());
100
933
  attributeOnlyIfTrue("isInvalid", D->isInvalidDecl());
101
933
102
933
  if (D->isUsed())
103
101
    JOS.attribute("isUsed", true);
104
832
  else if (D->isThisDeclarationReferenced())
105
56
    JOS.attribute("isReferenced", true);
106
933
107
933
  if (const auto *ND = dyn_cast<NamedDecl>(D))
108
912
    attributeOnlyIfTrue("isHidden", ND->isHidden());
109
933
110
933
  if (D->getLexicalDeclContext() != D->getDeclContext())
111
4
    JOS.attribute("parentDeclContext",
112
4
                  createPointerRepresentation(D->getDeclContext()));
113
933
114
933
  addPreviousDeclaration(D);
115
933
  InnerDeclVisitor::Visit(D);
116
933
}
117
118
void JSONNodeDumper::Visit(const comments::Comment *C,
119
64
                           const comments::FullComment *FC) {
120
64
  if (!C)
121
0
    return;
122
64
123
64
  JOS.attribute("id", createPointerRepresentation(C));
124
64
  JOS.attribute("kind", C->getCommentKindName());
125
64
  JOS.attributeObject("loc",
126
64
                      [C, this] { writeSourceLocation(C->getLocation()); });
127
64
  JOS.attributeObject("range",
128
64
                      [C, this] { writeSourceRange(C->getSourceRange()); });
129
64
130
64
  InnerCommentVisitor::visit(C, FC);
131
64
}
132
133
void JSONNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,
134
10
                           const Decl *From, StringRef Label) {
135
10
  JOS.attribute("kind", "TemplateArgument");
136
10
  if (R.isValid())
137
1
    JOS.attributeObject("range", [R, this] { writeSourceRange(R); });
138
10
139
10
  if (From)
140
0
    JOS.attribute(Label.empty() ? "fromDecl" : Label, createBareDeclRef(From));
141
10
142
10
  InnerTemplateArgVisitor::Visit(TA);
143
10
}
144
145
0
void JSONNodeDumper::Visit(const CXXCtorInitializer *Init) {
146
0
  JOS.attribute("kind", "CXXCtorInitializer");
147
0
  if (Init->isAnyMemberInitializer())
148
0
    JOS.attribute("anyInit", createBareDeclRef(Init->getAnyMember()));
149
0
  else if (Init->isBaseInitializer())
150
0
    JOS.attribute("baseInit",
151
0
                  createQualType(QualType(Init->getBaseClass(), 0)));
152
0
  else if (Init->isDelegatingInitializer())
153
0
    JOS.attribute("delegatingInit",
154
0
                  createQualType(Init->getTypeSourceInfo()->getType()));
155
0
  else
156
0
    llvm_unreachable("Unknown initializer type");
157
0
}
158
159
0
void JSONNodeDumper::Visit(const OMPClause *C) {}
160
161
3
void JSONNodeDumper::Visit(const BlockDecl::Capture &C) {
162
3
  JOS.attribute("kind", "Capture");
163
3
  attributeOnlyIfTrue("byref", C.isByRef());
164
3
  attributeOnlyIfTrue("nested", C.isNested());
165
3
  if (C.getVariable())
166
3
    JOS.attribute("var", createBareDeclRef(C.getVariable()));
167
3
}
168
169
12
void JSONNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
170
12
  JOS.attribute("associationKind", A.getTypeSourceInfo() ? 
"case"7
:
"default"5
);
171
12
  attributeOnlyIfTrue("selected", A.isSelected());
172
12
}
173
174
void JSONNodeDumper::writeBareSourceLocation(SourceLocation Loc,
175
5.73k
                                             bool IsSpelling) {
176
5.73k
  PresumedLoc Presumed = SM.getPresumedLoc(Loc);
177
5.73k
  unsigned ActualLine = IsSpelling ? 
SM.getSpellingLineNumber(Loc)5.72k
178
5.73k
                                   : 
SM.getExpansionLineNumber(Loc)7
;
179
5.73k
  if (Presumed.isValid()) {
180
5.37k
    if (LastLocFilename != Presumed.getFilename()) {
181
114
      JOS.attribute("file", Presumed.getFilename());
182
114
      JOS.attribute("line", ActualLine);
183
5.26k
    } else if (LastLocLine != ActualLine)
184
1.24k
      JOS.attribute("line", ActualLine);
185
5.37k
186
5.37k
    unsigned PresumedLine = Presumed.getLine();
187
5.37k
    if (ActualLine != PresumedLine && 
LastLocPresumedLine != PresumedLine11
)
188
4
      JOS.attribute("presumedLine", PresumedLine);
189
5.37k
190
5.37k
    JOS.attribute("col", Presumed.getColumn());
191
5.37k
    JOS.attribute("tokLen",
192
5.37k
                  Lexer::MeasureTokenLength(Loc, SM, Ctx.getLangOpts()));
193
5.37k
    LastLocFilename = Presumed.getFilename();
194
5.37k
    LastLocPresumedLine = PresumedLine;
195
5.37k
    LastLocLine = ActualLine;
196
5.37k
  }
197
5.73k
}
198
199
5.72k
void JSONNodeDumper::writeSourceLocation(SourceLocation Loc) {
200
5.72k
  SourceLocation Spelling = SM.getSpellingLoc(Loc);
201
5.72k
  SourceLocation Expansion = SM.getExpansionLoc(Loc);
202
5.72k
203
5.72k
  if (Expansion != Spelling) {
204
7
    // If the expansion and the spelling are different, output subobjects
205
7
    // describing both locations.
206
7
    JOS.attributeObject("spellingLoc", [Spelling, this] {
207
7
      writeBareSourceLocation(Spelling, /*IsSpelling*/ true);
208
7
    });
209
7
    JOS.attributeObject("expansionLoc", [Expansion, Loc, this] {
210
7
      writeBareSourceLocation(Expansion, /*IsSpelling*/ false);
211
7
      // If there is a macro expansion, add extra information if the interesting
212
7
      // bit is the macro arg expansion.
213
7
      if (SM.isMacroArgExpansion(Loc))
214
3
        JOS.attribute("isMacroArgExpansion", true);
215
7
    });
216
7
  } else
217
5.72k
    writeBareSourceLocation(Spelling, /*IsSpelling*/ true);
218
5.72k
}
219
220
2.36k
void JSONNodeDumper::writeSourceRange(SourceRange R) {
221
2.36k
  JOS.attributeObject("begin",
222
2.36k
                      [R, this] { writeSourceLocation(R.getBegin()); });
223
2.36k
  JOS.attributeObject("end", [R, this] { writeSourceLocation(R.getEnd()); });
224
2.36k
}
225
226
2.89k
std::string JSONNodeDumper::createPointerRepresentation(const void *Ptr) {
227
2.89k
  // Because JSON stores integer values as signed 64-bit integers, trying to
228
2.89k
  // represent them as such makes for very ugly pointer values in the resulting
229
2.89k
  // output. Instead, we convert the value to hex and treat it as a string.
230
2.89k
  return "0x" + llvm::utohexstr(reinterpret_cast<uint64_t>(Ptr), true);
231
2.89k
}
232
233
2.14k
llvm::json::Object JSONNodeDumper::createQualType(QualType QT, bool Desugar) {
234
2.14k
  SplitQualType SQT = QT.split();
235
2.14k
  llvm::json::Object Ret{{"qualType", QualType::getAsString(SQT, PrintPolicy)}};
236
2.14k
237
2.14k
  if (Desugar && 
!QT.isNull()1.99k
) {
238
1.99k
    SplitQualType DSQT = QT.getSplitDesugaredType();
239
1.99k
    if (DSQT != SQT)
240
145
      Ret["desugaredQualType"] = QualType::getAsString(DSQT, PrintPolicy);
241
1.99k
  }
242
2.14k
  return Ret;
243
2.14k
}
244
245
2
void JSONNodeDumper::writeBareDeclRef(const Decl *D) {
246
2
  JOS.attribute("id", createPointerRepresentation(D));
247
2
  if (!D)
248
0
    return;
249
2
250
2
  JOS.attribute("kind", (llvm::Twine(D->getDeclKindName()) + "Decl").str());
251
2
  if (const auto *ND = dyn_cast<NamedDecl>(D))
252
2
    JOS.attribute("name", ND->getDeclName().getAsString());
253
2
  if (const auto *VD = dyn_cast<ValueDecl>(D))
254
1
    JOS.attribute("type", createQualType(VD->getType()));
255
2
}
256
257
352
llvm::json::Object JSONNodeDumper::createBareDeclRef(const Decl *D) {
258
352
  llvm::json::Object Ret{{"id", createPointerRepresentation(D)}};
259
352
  if (!D)
260
3
    return Ret;
261
349
262
349
  Ret["kind"] = (llvm::Twine(D->getDeclKindName()) + "Decl").str();
263
349
  if (const auto *ND = dyn_cast<NamedDecl>(D))
264
346
    Ret["name"] = ND->getDeclName().getAsString();
265
349
  if (const auto *VD = dyn_cast<ValueDecl>(D))
266
282
    Ret["type"] = createQualType(VD->getType());
267
349
  return Ret;
268
349
}
269
270
302
llvm::json::Array JSONNodeDumper::createCastPath(const CastExpr *C) {
271
302
  llvm::json::Array Ret;
272
302
  if (C->path_empty())
273
301
    return Ret;
274
1
275
2
  
for (auto I = C->path_begin(), E = C->path_end(); 1
I != E;
++I1
) {
276
1
    const CXXBaseSpecifier *Base = *I;
277
1
    const auto *RD =
278
1
        cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
279
1
280
1
    llvm::json::Object Val{{"name", RD->getName()}};
281
1
    if (Base->isVirtual())
282
0
      Val["isVirtual"] = true;
283
1
    Ret.push_back(std::move(Val));
284
1
  }
285
1
  return Ret;
286
1
}
287
288
5.10k
#define FIELD2(Name, Flag)  if (RD->Flag()) 
Ret[Name] = true2.36k
289
1.29k
#define FIELD1(Flag)        FIELD2(#Flag, Flag)
290
291
static llvm::json::Object
292
81
createDefaultConstructorDefinitionData(const CXXRecordDecl *RD) {
293
81
  llvm::json::Object Ret;
294
81
295
81
  FIELD2("exists", hasDefaultConstructor);
296
81
  FIELD2("trivial", hasTrivialDefaultConstructor);
297
81
  FIELD2("nonTrivial", hasNonTrivialDefaultConstructor);
298
81
  FIELD2("userProvided", hasUserProvidedDefaultConstructor);
299
81
  FIELD2("isConstexpr", hasConstexprDefaultConstructor);
300
81
  FIELD2("needsImplicit", needsImplicitDefaultConstructor);
301
81
  FIELD2("defaultedIsConstexpr", defaultedDefaultConstructorIsConstexpr);
302
81
303
81
  return Ret;
304
81
}
305
306
static llvm::json::Object
307
81
createCopyConstructorDefinitionData(const CXXRecordDecl *RD) {
308
81
  llvm::json::Object Ret;
309
81
310
81
  FIELD2("simple", hasSimpleCopyConstructor);
311
81
  FIELD2("trivial", hasTrivialCopyConstructor);
312
81
  FIELD2("nonTrivial", hasNonTrivialCopyConstructor);
313
81
  FIELD2("userDeclared", hasUserDeclaredCopyConstructor);
314
81
  FIELD2("hasConstParam", hasCopyConstructorWithConstParam);
315
81
  FIELD2("implicitHasConstParam", implicitCopyConstructorHasConstParam);
316
81
  FIELD2("needsImplicit", needsImplicitCopyConstructor);
317
81
  FIELD2("needsOverloadResolution", needsOverloadResolutionForCopyConstructor);
318
81
  if (!RD->needsOverloadResolutionForCopyConstructor())
319
81
    
FIELD280
("defaultedIsDeleted", defaultedCopyConstructorIsDeleted);
320
81
321
81
  return Ret;
322
81
}
323
324
static llvm::json::Object
325
81
createMoveConstructorDefinitionData(const CXXRecordDecl *RD) {
326
81
  llvm::json::Object Ret;
327
81
328
81
  FIELD2("exists", hasMoveConstructor);
329
81
  FIELD2("simple", hasSimpleMoveConstructor);
330
81
  FIELD2("trivial", hasTrivialMoveConstructor);
331
81
  FIELD2("nonTrivial", hasNonTrivialMoveConstructor);
332
81
  FIELD2("userDeclared", hasUserDeclaredMoveConstructor);
333
81
  FIELD2("needsImplicit", needsImplicitMoveConstructor);
334
81
  FIELD2("needsOverloadResolution", needsOverloadResolutionForMoveConstructor);
335
81
  if (!RD->needsOverloadResolutionForMoveConstructor())
336
81
    FIELD2("defaultedIsDeleted", defaultedMoveConstructorIsDeleted);
337
81
338
81
  return Ret;
339
81
}
340
341
static llvm::json::Object
342
81
createCopyAssignmentDefinitionData(const CXXRecordDecl *RD) {
343
81
  llvm::json::Object Ret;
344
81
345
81
  FIELD2("trivial", hasTrivialCopyAssignment);
346
81
  FIELD2("nonTrivial", hasNonTrivialCopyAssignment);
347
81
  FIELD2("hasConstParam", hasCopyAssignmentWithConstParam);
348
81
  FIELD2("implicitHasConstParam", implicitCopyAssignmentHasConstParam);
349
81
  FIELD2("userDeclared", hasUserDeclaredCopyAssignment);
350
81
  FIELD2("needsImplicit", needsImplicitCopyAssignment);
351
81
  FIELD2("needsOverloadResolution", needsOverloadResolutionForCopyAssignment);
352
81
353
81
  return Ret;
354
81
}
355
356
static llvm::json::Object
357
81
createMoveAssignmentDefinitionData(const CXXRecordDecl *RD) {
358
81
  llvm::json::Object Ret;
359
81
360
81
  FIELD2("exists", hasMoveAssignment);
361
81
  FIELD2("simple", hasSimpleMoveAssignment);
362
81
  FIELD2("trivial", hasTrivialMoveAssignment);
363
81
  FIELD2("nonTrivial", hasNonTrivialMoveAssignment);
364
81
  FIELD2("userDeclared", hasUserDeclaredMoveAssignment);
365
81
  FIELD2("needsImplicit", needsImplicitMoveAssignment);
366
81
  FIELD2("needsOverloadResolution", needsOverloadResolutionForMoveAssignment);
367
81
368
81
  return Ret;
369
81
}
370
371
static llvm::json::Object
372
81
createDestructorDefinitionData(const CXXRecordDecl *RD) {
373
81
  llvm::json::Object Ret;
374
81
375
81
  FIELD2("simple", hasSimpleDestructor);
376
81
  FIELD2("irrelevant", hasIrrelevantDestructor);
377
81
  FIELD2("trivial", hasTrivialDestructor);
378
81
  FIELD2("nonTrivial", hasNonTrivialDestructor);
379
81
  FIELD2("userDeclared", hasUserDeclaredDestructor);
380
81
  FIELD2("needsImplicit", needsImplicitDestructor);
381
81
  FIELD2("needsOverloadResolution", needsOverloadResolutionForDestructor);
382
81
  if (!RD->needsOverloadResolutionForDestructor())
383
81
    FIELD2("defaultedIsDeleted", defaultedDestructorIsDeleted);
384
81
385
81
  return Ret;
386
81
}
387
388
llvm::json::Object
389
81
JSONNodeDumper::createCXXRecordDefinitionData(const CXXRecordDecl *RD) {
390
81
  llvm::json::Object Ret;
391
81
392
81
  // This data is common to all C++ classes.
393
81
  FIELD1(isGenericLambda);
394
81
  FIELD1(isLambda);
395
81
  FIELD1(isEmpty);
396
81
  FIELD1(isAggregate);
397
81
  FIELD1(isStandardLayout);
398
81
  FIELD1(isTriviallyCopyable);
399
81
  FIELD1(isPOD);
400
81
  FIELD1(isTrivial);
401
81
  FIELD1(isPolymorphic);
402
81
  FIELD1(isAbstract);
403
81
  FIELD1(isLiteral);
404
81
  FIELD1(canPassInRegisters);
405
81
  FIELD1(hasUserDeclaredConstructor);
406
81
  FIELD1(hasConstexprNonCopyMoveConstructor);
407
81
  FIELD1(hasMutableFields);
408
81
  FIELD1(hasVariantMembers);
409
81
  FIELD2("canConstDefaultInit", allowConstDefaultInit);
410
81
411
81
  Ret["defaultCtor"] = createDefaultConstructorDefinitionData(RD);
412
81
  Ret["copyCtor"] = createCopyConstructorDefinitionData(RD);
413
81
  Ret["moveCtor"] = createMoveConstructorDefinitionData(RD);
414
81
  Ret["copyAssign"] = createCopyAssignmentDefinitionData(RD);
415
81
  Ret["moveAssign"] = createMoveAssignmentDefinitionData(RD);
416
81
  Ret["dtor"] = createDestructorDefinitionData(RD);
417
81
418
81
  return Ret;
419
81
}
420
421
#undef FIELD1
422
#undef FIELD2
423
424
17
std::string JSONNodeDumper::createAccessSpecifier(AccessSpecifier AS) {
425
17
  switch (AS) {
426
17
  
case AS_none: return "none"4
;
427
17
  
case AS_private: return "private"3
;
428
17
  
case AS_protected: return "protected"4
;
429
17
  
case AS_public: return "public"6
;
430
0
  }
431
0
  llvm_unreachable("Unknown access specifier");
432
0
}
433
434
llvm::json::Object
435
8
JSONNodeDumper::createCXXBaseSpecifier(const CXXBaseSpecifier &BS) {
436
8
  llvm::json::Object Ret;
437
8
438
8
  Ret["type"] = createQualType(BS.getType());
439
8
  Ret["access"] = createAccessSpecifier(BS.getAccessSpecifier());
440
8
  Ret["writtenAccess"] =
441
8
      createAccessSpecifier(BS.getAccessSpecifierAsWritten());
442
8
  if (BS.isVirtual())
443
4
    Ret["isVirtual"] = true;
444
8
  if (BS.isPackExpansion())
445
1
    Ret["isPackExpansion"] = true;
446
8
447
8
  return Ret;
448
8
}
449
450
0
void JSONNodeDumper::VisitTypedefType(const TypedefType *TT) {
451
0
  JOS.attribute("decl", createBareDeclRef(TT->getDecl()));
452
0
}
453
454
4
void JSONNodeDumper::VisitFunctionType(const FunctionType *T) {
455
4
  FunctionType::ExtInfo E = T->getExtInfo();
456
4
  attributeOnlyIfTrue("noreturn", E.getNoReturn());
457
4
  attributeOnlyIfTrue("producesResult", E.getProducesResult());
458
4
  if (E.getHasRegParm())
459
0
    JOS.attribute("regParm", E.getRegParm());
460
4
  JOS.attribute("cc", FunctionType::getNameForCallConv(E.getCC()));
461
4
}
462
463
4
void JSONNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {
464
4
  FunctionProtoType::ExtProtoInfo E = T->getExtProtoInfo();
465
4
  attributeOnlyIfTrue("trailingReturn", E.HasTrailingReturn);
466
4
  attributeOnlyIfTrue("const", T->isConst());
467
4
  attributeOnlyIfTrue("volatile", T->isVolatile());
468
4
  attributeOnlyIfTrue("restrict", T->isRestrict());
469
4
  attributeOnlyIfTrue("variadic", E.Variadic);
470
4
  switch (E.RefQualifier) {
471
4
  
case RQ_LValue: JOS.attribute("refQualifier", "&"); break0
;
472
4
  
case RQ_RValue: JOS.attribute("refQualifier", "&&"); break0
;
473
4
  case RQ_None: break;
474
4
  }
475
4
  switch (E.ExceptionSpec.Type) {
476
4
  case EST_DynamicNone:
477
0
  case EST_Dynamic: {
478
0
    JOS.attribute("exceptionSpec", "throw");
479
0
    llvm::json::Array Types;
480
0
    for (QualType QT : E.ExceptionSpec.Exceptions)
481
0
      Types.push_back(createQualType(QT));
482
0
    JOS.attribute("exceptionTypes", std::move(Types));
483
0
  } break;
484
0
  case EST_MSAny:
485
0
    JOS.attribute("exceptionSpec", "throw");
486
0
    JOS.attribute("throwsAny", true);
487
0
    break;
488
0
  case EST_BasicNoexcept:
489
0
    JOS.attribute("exceptionSpec", "noexcept");
490
0
    break;
491
0
  case EST_NoexceptTrue:
492
0
  case EST_NoexceptFalse:
493
0
    JOS.attribute("exceptionSpec", "noexcept");
494
0
    JOS.attribute("conditionEvaluatesTo",
495
0
                E.ExceptionSpec.Type == EST_NoexceptTrue);
496
0
    //JOS.attributeWithCall("exceptionSpecExpr",
497
0
    //                    [this, E]() { Visit(E.ExceptionSpec.NoexceptExpr); });
498
0
    break;
499
0
  case EST_NoThrow:
500
0
    JOS.attribute("exceptionSpec", "nothrow");
501
0
    break;
502
0
  // FIXME: I cannot find a way to trigger these cases while dumping the AST. I
503
0
  // suspect you can only run into them when executing an AST dump from within
504
0
  // the debugger, which is not a use case we worry about for the JSON dumping
505
0
  // feature.
506
4
  case EST_DependentNoexcept:
507
4
  case EST_Unevaluated:
508
4
  case EST_Uninstantiated:
509
4
  case EST_Unparsed:
510
4
  case EST_None: break;
511
4
  }
512
4
  VisitFunctionType(T);
513
4
}
514
515
0
void JSONNodeDumper::VisitRValueReferenceType(const ReferenceType *RT) {
516
0
  attributeOnlyIfTrue("spelledAsLValue", RT->isSpelledAsLValue());
517
0
}
518
519
14
void JSONNodeDumper::VisitArrayType(const ArrayType *AT) {
520
14
  switch (AT->getSizeModifier()) {
521
14
  case ArrayType::Star:
522
0
    JOS.attribute("sizeModifier", "*");
523
0
    break;
524
14
  case ArrayType::Static:
525
0
    JOS.attribute("sizeModifier", "static");
526
0
    break;
527
14
  case ArrayType::Normal:
528
14
    break;
529
14
  }
530
14
531
14
  std::string Str = AT->getIndexTypeQualifiers().getAsString();
532
14
  if (!Str.empty())
533
0
    JOS.attribute("indexTypeQualifiers", Str);
534
14
}
535
536
14
void JSONNodeDumper::VisitConstantArrayType(const ConstantArrayType *CAT) {
537
14
  // FIXME: this should use ZExt instead of SExt, but JSON doesn't allow a
538
14
  // narrowing conversion to int64_t so it cannot be expressed.
539
14
  JOS.attribute("size", CAT->getSize().getSExtValue());
540
14
  VisitArrayType(CAT);
541
14
}
542
543
void JSONNodeDumper::VisitDependentSizedExtVectorType(
544
0
    const DependentSizedExtVectorType *VT) {
545
0
  JOS.attributeObject(
546
0
      "attrLoc", [VT, this] { writeSourceLocation(VT->getAttributeLoc()); });
547
0
}
548
549
void JSONNodeDumper::VisitVectorType(const VectorType *VT) {
550
  JOS.attribute("numElements", VT->getNumElements());
551
  switch (VT->getVectorKind()) {
552
  case VectorType::GenericVector:
553
    break;
554
  case VectorType::AltiVecVector:
555
    JOS.attribute("vectorKind", "altivec");
556
    break;
557
  case VectorType::AltiVecPixel:
558
    JOS.attribute("vectorKind", "altivec pixel");
559
    break;
560
  case VectorType::AltiVecBool:
561
    JOS.attribute("vectorKind", "altivec bool");
562
    break;
563
  case VectorType::NeonVector:
564
    JOS.attribute("vectorKind", "neon");
565
    break;
566
  case VectorType::NeonPolyVector:
567
    JOS.attribute("vectorKind", "neon poly");
568
    break;
569
  }
570
}
571
572
0
void JSONNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *UUT) {
573
0
  JOS.attribute("decl", createBareDeclRef(UUT->getDecl()));
574
0
}
575
576
void JSONNodeDumper::VisitUnaryTransformType(const UnaryTransformType *UTT) {
577
  switch (UTT->getUTTKind()) {
578
  case UnaryTransformType::EnumUnderlyingType:
579
    JOS.attribute("transformKind", "underlying_type");
580
    break;
581
  }
582
}
583
584
32
void JSONNodeDumper::VisitTagType(const TagType *TT) {
585
32
  JOS.attribute("decl", createBareDeclRef(TT->getDecl()));
586
32
}
587
588
void JSONNodeDumper::VisitTemplateTypeParmType(
589
2
    const TemplateTypeParmType *TTPT) {
590
2
  JOS.attribute("depth", TTPT->getDepth());
591
2
  JOS.attribute("index", TTPT->getIndex());
592
2
  attributeOnlyIfTrue("isPack", TTPT->isParameterPack());
593
2
  JOS.attribute("decl", createBareDeclRef(TTPT->getDecl()));
594
2
}
595
596
void JSONNodeDumper::VisitAutoType(const AutoType *AT) {
597
  JOS.attribute("undeduced", !AT->isDeduced());
598
  switch (AT->getKeyword()) {
599
  case AutoTypeKeyword::Auto:
600
    JOS.attribute("typeKeyword", "auto");
601
    break;
602
  case AutoTypeKeyword::DecltypeAuto:
603
    JOS.attribute("typeKeyword", "decltype(auto)");
604
    break;
605
  case AutoTypeKeyword::GNUAutoType:
606
    JOS.attribute("typeKeyword", "__auto_type");
607
    break;
608
  }
609
}
610
611
void JSONNodeDumper::VisitTemplateSpecializationType(
612
0
    const TemplateSpecializationType *TST) {
613
0
  attributeOnlyIfTrue("isAlias", TST->isTypeAlias());
614
0
615
0
  std::string Str;
616
0
  llvm::raw_string_ostream OS(Str);
617
0
  TST->getTemplateName().print(OS, PrintPolicy);
618
0
  JOS.attribute("templateName", OS.str());
619
0
}
620
621
void JSONNodeDumper::VisitInjectedClassNameType(
622
0
    const InjectedClassNameType *ICNT) {
623
0
  JOS.attribute("decl", createBareDeclRef(ICNT->getDecl()));
624
0
}
625
626
0
void JSONNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *OIT) {
627
0
  JOS.attribute("decl", createBareDeclRef(OIT->getDecl()));
628
0
}
629
630
0
void JSONNodeDumper::VisitPackExpansionType(const PackExpansionType *PET) {
631
0
  if (llvm::Optional<unsigned> N = PET->getNumExpansions())
632
0
    JOS.attribute("numExpansions", *N);
633
0
}
634
635
2
void JSONNodeDumper::VisitElaboratedType(const ElaboratedType *ET) {
636
2
  if (const NestedNameSpecifier *NNS = ET->getQualifier()) {
637
1
    std::string Str;
638
1
    llvm::raw_string_ostream OS(Str);
639
1
    NNS->print(OS, PrintPolicy, /*ResolveTemplateArgs*/ true);
640
1
    JOS.attribute("qualifier", OS.str());
641
1
  }
642
2
  if (const TagDecl *TD = ET->getOwnedTagDecl())
643
0
    JOS.attribute("ownedTagDecl", createBareDeclRef(TD));
644
2
}
645
646
1
void JSONNodeDumper::VisitMacroQualifiedType(const MacroQualifiedType *MQT) {
647
1
  JOS.attribute("macroName", MQT->getMacroIdentifier()->getName());
648
1
}
649
650
2
void JSONNodeDumper::VisitMemberPointerType(const MemberPointerType *MPT) {
651
2
  attributeOnlyIfTrue("isData", MPT->isMemberDataPointer());
652
2
  attributeOnlyIfTrue("isFunction", MPT->isMemberFunctionPointer());
653
2
}
654
655
909
void JSONNodeDumper::VisitNamedDecl(const NamedDecl *ND) {
656
909
  if (ND && ND->getDeclName())
657
796
    JOS.attribute("name", ND->getNameAsString());
658
909
}
659
660
77
void JSONNodeDumper::VisitTypedefDecl(const TypedefDecl *TD) {
661
77
  VisitNamedDecl(TD);
662
77
  JOS.attribute("type", createQualType(TD->getUnderlyingType()));
663
77
}
664
665
4
void JSONNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *TAD) {
666
4
  VisitNamedDecl(TAD);
667
4
  JOS.attribute("type", createQualType(TAD->getUnderlyingType()));
668
4
}
669
670
9
void JSONNodeDumper::VisitNamespaceDecl(const NamespaceDecl *ND) {
671
9
  VisitNamedDecl(ND);
672
9
  attributeOnlyIfTrue("isInline", ND->isInline());
673
9
  if (!ND->isOriginalNamespace())
674
0
    JOS.attribute("originalNamespace",
675
0
                  createBareDeclRef(ND->getOriginalNamespace()));
676
9
}
677
678
1
void JSONNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *UDD) {
679
1
  JOS.attribute("nominatedNamespace",
680
1
                createBareDeclRef(UDD->getNominatedNamespace()));
681
1
}
682
683
0
void JSONNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *NAD) {
684
0
  VisitNamedDecl(NAD);
685
0
  JOS.attribute("aliasedNamespace",
686
0
                createBareDeclRef(NAD->getAliasedNamespace()));
687
0
}
688
689
3
void JSONNodeDumper::VisitUsingDecl(const UsingDecl *UD) {
690
3
  std::string Name;
691
3
  if (const NestedNameSpecifier *NNS = UD->getQualifier()) {
692
3
    llvm::raw_string_ostream SOS(Name);
693
3
    NNS->print(SOS, UD->getASTContext().getPrintingPolicy());
694
3
  }
695
3
  Name += UD->getNameAsString();
696
3
  JOS.attribute("name", Name);
697
3
}
698
699
2
void JSONNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *USD) {
700
2
  JOS.attribute("target", createBareDeclRef(USD->getTargetDecl()));
701
2
}
702
703
221
void JSONNodeDumper::VisitVarDecl(const VarDecl *VD) {
704
221
  VisitNamedDecl(VD);
705
221
  JOS.attribute("type", createQualType(VD->getType()));
706
221
707
221
  StorageClass SC = VD->getStorageClass();
708
221
  if (SC != SC_None)
709
2
    JOS.attribute("storageClass", VarDecl::getStorageClassSpecifierString(SC));
710
221
  switch (VD->getTLSKind()) {
711
221
  
case VarDecl::TLS_Dynamic: JOS.attribute("tls", "dynamic"); break0
;
712
221
  
case VarDecl::TLS_Static: JOS.attribute("tls", "static"); break1
;
713
221
  
case VarDecl::TLS_None: break220
;
714
221
  }
715
221
  attributeOnlyIfTrue("nrvo", VD->isNRVOVariable());
716
221
  attributeOnlyIfTrue("inline", VD->isInline());
717
221
  attributeOnlyIfTrue("constexpr", VD->isConstexpr());
718
221
  attributeOnlyIfTrue("modulePrivate", VD->isModulePrivate());
719
221
  if (VD->hasInit()) {
720
48
    switch (VD->getInitStyle()) {
721
48
    
case VarDecl::CInit: JOS.attribute("init", "c"); break43
;
722
48
    
case VarDecl::CallInit: JOS.attribute("init", "call"); break5
;
723
48
    
case VarDecl::ListInit: JOS.attribute("init", "list"); break0
;
724
221
    }
725
221
  }
726
221
  attributeOnlyIfTrue("isParameterPack", VD->isParameterPack());
727
221
}
728
729
66
void JSONNodeDumper::VisitFieldDecl(const FieldDecl *FD) {
730
66
  VisitNamedDecl(FD);
731
66
  JOS.attribute("type", createQualType(FD->getType()));
732
66
  attributeOnlyIfTrue("mutable", FD->isMutable());
733
66
  attributeOnlyIfTrue("modulePrivate", FD->isModulePrivate());
734
66
  attributeOnlyIfTrue("isBitfield", FD->isBitField());
735
66
  attributeOnlyIfTrue("hasInClassInitializer", FD->hasInClassInitializer());
736
66
}
737
738
234
void JSONNodeDumper::VisitFunctionDecl(const FunctionDecl *FD) {
739
234
  VisitNamedDecl(FD);
740
234
  JOS.attribute("type", createQualType(FD->getType()));
741
234
  StorageClass SC = FD->getStorageClass();
742
234
  if (SC != SC_None)
743
11
    JOS.attribute("storageClass", VarDecl::getStorageClassSpecifierString(SC));
744
234
  attributeOnlyIfTrue("inline", FD->isInlineSpecified());
745
234
  attributeOnlyIfTrue("virtual", FD->isVirtualAsWritten());
746
234
  attributeOnlyIfTrue("pure", FD->isPure());
747
234
  attributeOnlyIfTrue("explicitlyDeleted", FD->isDeletedAsWritten());
748
234
  attributeOnlyIfTrue("constexpr", FD->isConstexpr());
749
234
  attributeOnlyIfTrue("variadic", FD->isVariadic());
750
234
751
234
  if (FD->isDefaulted())
752
45
    JOS.attribute("explicitlyDefaulted",
753
45
                  FD->isDeleted() ? 
"deleted"0
: "default");
754
234
}
755
756
10
void JSONNodeDumper::VisitEnumDecl(const EnumDecl *ED) {
757
10
  VisitNamedDecl(ED);
758
10
  if (ED->isFixed())
759
4
    JOS.attribute("fixedUnderlyingType", createQualType(ED->getIntegerType()));
760
10
  if (ED->isScoped())
761
3
    JOS.attribute("scopedEnumTag",
762
3
                  ED->isScopedUsingClassTag() ? 
"class"2
:
"struct"1
);
763
10
}
764
17
void JSONNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *ECD) {
765
17
  VisitNamedDecl(ECD);
766
17
  JOS.attribute("type", createQualType(ECD->getType()));
767
17
}
768
769
157
void JSONNodeDumper::VisitRecordDecl(const RecordDecl *RD) {
770
157
  VisitNamedDecl(RD);
771
157
  JOS.attribute("tagUsed", RD->getKindName());
772
157
  attributeOnlyIfTrue("completeDefinition", RD->isCompleteDefinition());
773
157
}
774
143
void JSONNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *RD) {
775
143
  VisitRecordDecl(RD);
776
143
777
143
  // All other information requires a complete definition.
778
143
  if (!RD->isCompleteDefinition())
779
62
    return;
780
81
781
81
  JOS.attribute("definitionData", createCXXRecordDefinitionData(RD));
782
81
  if (RD->getNumBases()) {
783
6
    JOS.attributeArray("bases", [this, RD] {
784
6
      for (const auto &Spec : RD->bases())
785
8
        JOS.value(createCXXBaseSpecifier(Spec));
786
6
    });
787
6
  }
788
81
}
789
790
32
void JSONNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
791
32
  VisitNamedDecl(D);
792
32
  JOS.attribute("tagUsed", D->wasDeclaredWithTypename() ? 
"typename"26
:
"class"6
);
793
32
  JOS.attribute("depth", D->getDepth());
794
32
  JOS.attribute("index", D->getIndex());
795
32
  attributeOnlyIfTrue("isParameterPack", D->isParameterPack());
796
32
797
32
  if (D->hasDefaultArgument())
798
2
    JOS.attributeObject("defaultArg", [=] {
799
2
      Visit(D->getDefaultArgument(), SourceRange(),
800
2
            D->getDefaultArgStorage().getInheritedFrom(),
801
2
            D->defaultArgumentWasInherited() ? 
"inherited from"0
: "previous");
802
2
    });
803
32
}
804
805
void JSONNodeDumper::VisitNonTypeTemplateParmDecl(
806
3
    const NonTypeTemplateParmDecl *D) {
807
3
  VisitNamedDecl(D);
808
3
  JOS.attribute("type", createQualType(D->getType()));
809
3
  JOS.attribute("depth", D->getDepth());
810
3
  JOS.attribute("index", D->getIndex());
811
3
  attributeOnlyIfTrue("isParameterPack", D->isParameterPack());
812
3
813
3
  if (D->hasDefaultArgument())
814
0
    JOS.attributeObject("defaultArg", [=] {
815
0
      Visit(D->getDefaultArgument(), SourceRange(),
816
0
            D->getDefaultArgStorage().getInheritedFrom(),
817
0
            D->defaultArgumentWasInherited() ? "inherited from" : "previous");
818
0
    });
819
3
}
820
821
void JSONNodeDumper::VisitTemplateTemplateParmDecl(
822
1
    const TemplateTemplateParmDecl *D) {
823
1
  VisitNamedDecl(D);
824
1
  JOS.attribute("depth", D->getDepth());
825
1
  JOS.attribute("index", D->getIndex());
826
1
  attributeOnlyIfTrue("isParameterPack", D->isParameterPack());
827
1
828
1
  if (D->hasDefaultArgument())
829
0
    JOS.attributeObject("defaultArg", [=] {
830
0
      Visit(D->getDefaultArgument().getArgument(),
831
0
            D->getDefaultArgStorage().getInheritedFrom()->getSourceRange(),
832
0
            D->getDefaultArgStorage().getInheritedFrom(),
833
0
            D->defaultArgumentWasInherited() ? "inherited from" : "previous");
834
0
    });
835
1
}
836
837
0
void JSONNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *LSD) {
838
0
  StringRef Lang;
839
0
  switch (LSD->getLanguage()) {
840
0
  case LinkageSpecDecl::lang_c: Lang = "C"; break;
841
0
  case LinkageSpecDecl::lang_cxx: Lang = "C++"; break;
842
0
  }
843
0
  JOS.attribute("language", Lang);
844
0
  attributeOnlyIfTrue("hasBraces", LSD->hasBraces());
845
0
}
846
847
1
void JSONNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *ASD) {
848
1
  JOS.attribute("access", createAccessSpecifier(ASD->getAccess()));
849
1
}
850
851
0
void JSONNodeDumper::VisitFriendDecl(const FriendDecl *FD) {
852
0
  if (const TypeSourceInfo *T = FD->getFriendType())
853
0
    JOS.attribute("type", createQualType(T->getType()));
854
0
}
855
856
8
void JSONNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
857
8
  VisitNamedDecl(D);
858
8
  JOS.attribute("type", createQualType(D->getType()));
859
8
  attributeOnlyIfTrue("synthesized", D->getSynthesize());
860
8
  switch (D->getAccessControl()) {
861
8
  
case ObjCIvarDecl::None: JOS.attribute("access", "none"); break0
;
862
8
  
case ObjCIvarDecl::Private: JOS.attribute("access", "private"); break5
;
863
8
  
case ObjCIvarDecl::Protected: JOS.attribute("access", "protected"); break1
;
864
8
  
case ObjCIvarDecl::Public: JOS.attribute("access", "public"); break1
;
865
8
  
case ObjCIvarDecl::Package: JOS.attribute("access", "package"); break1
;
866
8
  }
867
8
}
868
869
11
void JSONNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
870
11
  VisitNamedDecl(D);
871
11
  JOS.attribute("returnType", createQualType(D->getReturnType()));
872
11
  JOS.attribute("instance", D->isInstanceMethod());
873
11
  attributeOnlyIfTrue("variadic", D->isVariadic());
874
11
}
875
876
1
void JSONNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
877
1
  VisitNamedDecl(D);
878
1
  JOS.attribute("type", createQualType(D->getUnderlyingType()));
879
1
  attributeOnlyIfTrue("bounded", D->hasExplicitBound());
880
1
  switch (D->getVariance()) {
881
1
  case ObjCTypeParamVariance::Invariant:
882
1
    break;
883
1
  case ObjCTypeParamVariance::Covariant:
884
0
    JOS.attribute("variance", "covariant");
885
0
    break;
886
1
  case ObjCTypeParamVariance::Contravariant:
887
0
    JOS.attribute("variance", "contravariant");
888
0
    break;
889
1
  }
890
1
}
891
892
1
void JSONNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
893
1
  VisitNamedDecl(D);
894
1
  JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));
895
1
  JOS.attribute("implementation", createBareDeclRef(D->getImplementation()));
896
1
897
1
  llvm::json::Array Protocols;
898
1
  for (const auto* P : D->protocols())
899
1
    Protocols.push_back(createBareDeclRef(P));
900
1
  if (!Protocols.empty())
901
1
    JOS.attribute("protocols", std::move(Protocols));
902
1
}
903
904
1
void JSONNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
905
1
  VisitNamedDecl(D);
906
1
  JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));
907
1
  JOS.attribute("categoryDecl", createBareDeclRef(D->getCategoryDecl()));
908
1
}
909
910
1
void JSONNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
911
1
  VisitNamedDecl(D);
912
1
913
1
  llvm::json::Array Protocols;
914
1
  for (const auto *P : D->protocols())
915
0
    Protocols.push_back(createBareDeclRef(P));
916
1
  if (!Protocols.empty())
917
0
    JOS.attribute("protocols", std::move(Protocols));
918
1
}
919
920
4
void JSONNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
921
4
  VisitNamedDecl(D);
922
4
  JOS.attribute("super", createBareDeclRef(D->getSuperClass()));
923
4
  JOS.attribute("implementation", createBareDeclRef(D->getImplementation()));
924
4
925
4
  llvm::json::Array Protocols;
926
4
  for (const auto* P : D->protocols())
927
2
    Protocols.push_back(createBareDeclRef(P));
928
4
  if (!Protocols.empty())
929
2
    JOS.attribute("protocols", std::move(Protocols));
930
4
}
931
932
void JSONNodeDumper::VisitObjCImplementationDecl(
933
3
    const ObjCImplementationDecl *D) {
934
3
  VisitNamedDecl(D);
935
3
  JOS.attribute("super", createBareDeclRef(D->getSuperClass()));
936
3
  JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));
937
3
}
938
939
void JSONNodeDumper::VisitObjCCompatibleAliasDecl(
940
1
    const ObjCCompatibleAliasDecl *D) {
941
1
  VisitNamedDecl(D);
942
1
  JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));
943
1
}
944
945
2
void JSONNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
946
2
  VisitNamedDecl(D);
947
2
  JOS.attribute("type", createQualType(D->getType()));
948
2
949
2
  switch (D->getPropertyImplementation()) {
950
2
  case ObjCPropertyDecl::None: break;
951
2
  
case ObjCPropertyDecl::Required: JOS.attribute("control", "required"); break0
;
952
2
  
case ObjCPropertyDecl::Optional: JOS.attribute("control", "optional"); break0
;
953
2
  }
954
2
  
955
2
  ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes();
956
2
  if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) {
957
2
    if (Attrs & ObjCPropertyDecl::OBJC_PR_getter)
958
1
      JOS.attribute("getter", createBareDeclRef(D->getGetterMethodDecl()));
959
2
    if (Attrs & ObjCPropertyDecl::OBJC_PR_setter)
960
1
      JOS.attribute("setter", createBareDeclRef(D->getSetterMethodDecl()));
961
2
    attributeOnlyIfTrue("readonly", Attrs & ObjCPropertyDecl::OBJC_PR_readonly);
962
2
    attributeOnlyIfTrue("assign", Attrs & ObjCPropertyDecl::OBJC_PR_assign);
963
2
    attributeOnlyIfTrue("readwrite",
964
2
                        Attrs & ObjCPropertyDecl::OBJC_PR_readwrite);
965
2
    attributeOnlyIfTrue("retain", Attrs & ObjCPropertyDecl::OBJC_PR_retain);
966
2
    attributeOnlyIfTrue("copy", Attrs & ObjCPropertyDecl::OBJC_PR_copy);
967
2
    attributeOnlyIfTrue("nonatomic",
968
2
                        Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic);
969
2
    attributeOnlyIfTrue("atomic", Attrs & ObjCPropertyDecl::OBJC_PR_atomic);
970
2
    attributeOnlyIfTrue("weak", Attrs & ObjCPropertyDecl::OBJC_PR_weak);
971
2
    attributeOnlyIfTrue("strong", Attrs & ObjCPropertyDecl::OBJC_PR_strong);
972
2
    attributeOnlyIfTrue("unsafe_unretained",
973
2
                        Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained);
974
2
    attributeOnlyIfTrue("class", Attrs & ObjCPropertyDecl::OBJC_PR_class);
975
2
    attributeOnlyIfTrue("nullability",
976
2
                        Attrs & ObjCPropertyDecl::OBJC_PR_nullability);
977
2
    attributeOnlyIfTrue("null_resettable",
978
2
                        Attrs & ObjCPropertyDecl::OBJC_PR_null_resettable);
979
2
  }
980
2
}
981
982
2
void JSONNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
983
2
  VisitNamedDecl(D->getPropertyDecl());
984
2
  JOS.attribute("implKind", D->getPropertyImplementation() ==
985
2
                                    ObjCPropertyImplDecl::Synthesize
986
2
                                ? "synthesize"
987
2
                                : 
"dynamic"0
);
988
2
  JOS.attribute("propertyDecl", createBareDeclRef(D->getPropertyDecl()));
989
2
  JOS.attribute("ivarDecl", createBareDeclRef(D->getPropertyIvarDecl()));
990
2
}
991
992
3
void JSONNodeDumper::VisitBlockDecl(const BlockDecl *D) {
993
3
  attributeOnlyIfTrue("variadic", D->isVariadic());
994
3
  attributeOnlyIfTrue("capturesThis", D->capturesCXXThis());
995
3
}
996
997
2
void JSONNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *OEE) {
998
2
  JOS.attribute("encodedType", createQualType(OEE->getEncodedType()));
999
2
}
1000
1001
9
void JSONNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *OME) {
1002
9
  std::string Str;
1003
9
  llvm::raw_string_ostream OS(Str);
1004
9
1005
9
  OME->getSelector().print(OS);
1006
9
  JOS.attribute("selector", OS.str());
1007
9
1008
9
  switch (OME->getReceiverKind()) {
1009
9
  case ObjCMessageExpr::Instance:
1010
8
    JOS.attribute("receiverKind", "instance");
1011
8
    break;
1012
9
  case ObjCMessageExpr::Class:
1013
1
    JOS.attribute("receiverKind", "class");
1014
1
    JOS.attribute("classType", createQualType(OME->getClassReceiver()));
1015
1
    break;
1016
9
  case ObjCMessageExpr::SuperInstance:
1017
0
    JOS.attribute("receiverKind", "super (instance)");
1018
0
    JOS.attribute("superType", createQualType(OME->getSuperType()));
1019
0
    break;
1020
9
  case ObjCMessageExpr::SuperClass:
1021
0
    JOS.attribute("receiverKind", "super (class)");
1022
0
    JOS.attribute("superType", createQualType(OME->getSuperType()));
1023
0
    break;
1024
9
  }
1025
9
1026
9
  QualType CallReturnTy = OME->getCallReturnType(Ctx);
1027
9
  if (OME->getType() != CallReturnTy)
1028
0
    JOS.attribute("callReturnType", createQualType(CallReturnTy));
1029
9
}
1030
1031
1
void JSONNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *OBE) {
1032
1
  if (const ObjCMethodDecl *MD = OBE->getBoxingMethod()) {
1033
1
    std::string Str;
1034
1
    llvm::raw_string_ostream OS(Str);
1035
1
1036
1
    MD->getSelector().print(OS);
1037
1
    JOS.attribute("selector", OS.str());
1038
1
  }
1039
1
}
1040
1041
1
void JSONNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *OSE) {
1042
1
  std::string Str;
1043
1
  llvm::raw_string_ostream OS(Str);
1044
1
1045
1
  OSE->getSelector().print(OS);
1046
1
  JOS.attribute("selector", OS.str());
1047
1
}
1048
1049
1
void JSONNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *OPE) {
1050
1
  JOS.attribute("protocol", createBareDeclRef(OPE->getProtocol()));
1051
1
}
1052
1053
2
void JSONNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *OPRE) {
1054
2
  if (OPRE->isImplicitProperty()) {
1055
0
    JOS.attribute("propertyKind", "implicit");
1056
0
    if (const ObjCMethodDecl *MD = OPRE->getImplicitPropertyGetter())
1057
0
      JOS.attribute("getter", createBareDeclRef(MD));
1058
0
    if (const ObjCMethodDecl *MD = OPRE->getImplicitPropertySetter())
1059
0
      JOS.attribute("setter", createBareDeclRef(MD));
1060
2
  } else {
1061
2
    JOS.attribute("propertyKind", "explicit");
1062
2
    JOS.attribute("property", createBareDeclRef(OPRE->getExplicitProperty()));
1063
2
  }
1064
2
1065
2
  attributeOnlyIfTrue("isSuperReceiver", OPRE->isSuperReceiver());
1066
2
  attributeOnlyIfTrue("isMessagingGetter", OPRE->isMessagingGetter());
1067
2
  attributeOnlyIfTrue("isMessagingSetter", OPRE->isMessagingSetter());
1068
2
}
1069
1070
void JSONNodeDumper::VisitObjCSubscriptRefExpr(
1071
4
    const ObjCSubscriptRefExpr *OSRE) {
1072
4
  JOS.attribute("subscriptKind",
1073
4
                OSRE->isArraySubscriptRefExpr() ? 
"array"2
:
"dictionary"2
);
1074
4
1075
4
  if (const ObjCMethodDecl *MD = OSRE->getAtIndexMethodDecl())
1076
0
    JOS.attribute("getter", createBareDeclRef(MD));
1077
4
  if (const ObjCMethodDecl *MD = OSRE->setAtIndexMethodDecl())
1078
0
    JOS.attribute("setter", createBareDeclRef(MD));
1079
4
}
1080
1081
1
void JSONNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *OIRE) {
1082
1
  JOS.attribute("decl", createBareDeclRef(OIRE->getDecl()));
1083
1
  attributeOnlyIfTrue("isFreeIvar", OIRE->isFreeIvar());
1084
1
  JOS.attribute("isArrow", OIRE->isArrow());
1085
1
}
1086
1087
2
void JSONNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *OBLE) {
1088
2
  JOS.attribute("value", OBLE->getValue() ? 
"__objc_yes"1
:
"__objc_no"1
);
1089
2
}
1090
1091
254
void JSONNodeDumper::VisitDeclRefExpr(const DeclRefExpr *DRE) {
1092
254
  JOS.attribute("referencedDecl", createBareDeclRef(DRE->getDecl()));
1093
254
  if (DRE->getDecl() != DRE->getFoundDecl())
1094
3
    JOS.attribute("foundReferencedDecl",
1095
3
                  createBareDeclRef(DRE->getFoundDecl()));
1096
254
  switch (DRE->isNonOdrUse()) {
1097
254
  
case NOUR_None: break241
;
1098
254
  
case NOUR_Unevaluated: JOS.attribute("nonOdrUseReason", "unevaluated"); break12
;
1099
254
  
case NOUR_Constant: JOS.attribute("nonOdrUseReason", "constant"); break1
;
1100
254
  
case NOUR_Discarded: JOS.attribute("nonOdrUseReason", "discarded"); break0
;
1101
254
  }
1102
254
}
1103
1104
0
void JSONNodeDumper::VisitPredefinedExpr(const PredefinedExpr *PE) {
1105
0
  JOS.attribute("name", PredefinedExpr::getIdentKindName(PE->getIdentKind()));
1106
0
}
1107
1108
25
void JSONNodeDumper::VisitUnaryOperator(const UnaryOperator *UO) {
1109
25
  JOS.attribute("isPostfix", UO->isPostfix());
1110
25
  JOS.attribute("opcode", UnaryOperator::getOpcodeStr(UO->getOpcode()));
1111
25
  if (!UO->canOverflow())
1112
17
    JOS.attribute("canOverflow", false);
1113
25
}
1114
1115
55
void JSONNodeDumper::VisitBinaryOperator(const BinaryOperator *BO) {
1116
55
  JOS.attribute("opcode", BinaryOperator::getOpcodeStr(BO->getOpcode()));
1117
55
}
1118
1119
void JSONNodeDumper::VisitCompoundAssignOperator(
1120
1
    const CompoundAssignOperator *CAO) {
1121
1
  VisitBinaryOperator(CAO);
1122
1
  JOS.attribute("computeLHSType", createQualType(CAO->getComputationLHSType()));
1123
1
  JOS.attribute("computeResultType",
1124
1
                createQualType(CAO->getComputationResultType()));
1125
1
}
1126
1127
13
void JSONNodeDumper::VisitMemberExpr(const MemberExpr *ME) {
1128
13
  // Note, we always write this Boolean field because the information it conveys
1129
13
  // is critical to understanding the AST node.
1130
13
  ValueDecl *VD = ME->getMemberDecl();
1131
13
  JOS.attribute("name", VD && VD->getDeclName() ? VD->getNameAsString() : 
""0
);
1132
13
  JOS.attribute("isArrow", ME->isArrow());
1133
13
  JOS.attribute("referencedMemberDecl", createPointerRepresentation(VD));
1134
13
  switch (ME->isNonOdrUse()) {
1135
13
  case NOUR_None: break;
1136
13
  
case NOUR_Unevaluated: JOS.attribute("nonOdrUseReason", "unevaluated"); break0
;
1137
13
  
case NOUR_Constant: JOS.attribute("nonOdrUseReason", "constant"); break0
;
1138
13
  
case NOUR_Discarded: JOS.attribute("nonOdrUseReason", "discarded"); break0
;
1139
13
  }
1140
13
}
1141
1142
11
void JSONNodeDumper::VisitCXXNewExpr(const CXXNewExpr *NE) {
1143
11
  attributeOnlyIfTrue("isGlobal", NE->isGlobalNew());
1144
11
  attributeOnlyIfTrue("isArray", NE->isArray());
1145
11
  attributeOnlyIfTrue("isPlacement", NE->getNumPlacementArgs() != 0);
1146
11
  switch (NE->getInitializationStyle()) {
1147
11
  
case CXXNewExpr::NoInit: break8
;
1148
11
  
case CXXNewExpr::CallInit: JOS.attribute("initStyle", "call"); break0
;
1149
11
  
case CXXNewExpr::ListInit: JOS.attribute("initStyle", "list"); break3
;
1150
11
  }
1151
11
  if (const FunctionDecl *FD = NE->getOperatorNew())
1152
10
    JOS.attribute("operatorNewDecl", createBareDeclRef(FD));
1153
11
  if (const FunctionDecl *FD = NE->getOperatorDelete())
1154
0
    JOS.attribute("operatorDeleteDecl", createBareDeclRef(FD));
1155
11
}
1156
6
void JSONNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *DE) {
1157
6
  attributeOnlyIfTrue("isGlobal", DE->isGlobalDelete());
1158
6
  attributeOnlyIfTrue("isArray", DE->isArrayForm());
1159
6
  attributeOnlyIfTrue("isArrayAsWritten", DE->isArrayFormAsWritten());
1160
6
  if (const FunctionDecl *FD = DE->getOperatorDelete())
1161
5
    JOS.attribute("operatorDeleteDecl", createBareDeclRef(FD));
1162
6
}
1163
1164
3
void JSONNodeDumper::VisitCXXThisExpr(const CXXThisExpr *TE) {
1165
3
  attributeOnlyIfTrue("implicit", TE->isImplicit());
1166
3
}
1167
1168
302
void JSONNodeDumper::VisitCastExpr(const CastExpr *CE) {
1169
302
  JOS.attribute("castKind", CE->getCastKindName());
1170
302
  llvm::json::Array Path = createCastPath(CE);
1171
302
  if (!Path.empty())
1172
1
    JOS.attribute("path", std::move(Path));
1173
302
  // FIXME: This may not be useful information as it can be obtusely gleaned
1174
302
  // from the inner[] array.
1175
302
  if (const NamedDecl *ND = CE->getConversionFunction())
1176
0
    JOS.attribute("conversionFunc", createBareDeclRef(ND));
1177
302
}
1178
1179
273
void JSONNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *ICE) {
1180
273
  VisitCastExpr(ICE);
1181
273
  attributeOnlyIfTrue("isPartOfExplicitCast", ICE->isPartOfExplicitCast());
1182
273
}
1183
1184
22
void JSONNodeDumper::VisitCallExpr(const CallExpr *CE) {
1185
22
  attributeOnlyIfTrue("adl", CE->usesADL());
1186
22
}
1187
1188
void JSONNodeDumper::VisitUnaryExprOrTypeTraitExpr(
1189
5
    const UnaryExprOrTypeTraitExpr *TTE) {
1190
5
  switch (TTE->getKind()) {
1191
5
  
case UETT_SizeOf: JOS.attribute("name", "sizeof"); break4
;
1192
5
  
case UETT_AlignOf: JOS.attribute("name", "alignof"); break1
;
1193
5
  
case UETT_VecStep: JOS.attribute("name", "vec_step"); break0
;
1194
5
  
case UETT_PreferredAlignOf: JOS.attribute("name", "__alignof"); break0
;
1195
5
  case UETT_OpenMPRequiredSimdAlign:
1196
0
    JOS.attribute("name", "__builtin_omp_required_simd_align"); break;
1197
5
  }
1198
5
  if (TTE->isArgumentType())
1199
2
    JOS.attribute("argType", createQualType(TTE->getArgumentType()));
1200
5
}
1201
1202
1
void JSONNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *SOPE) {
1203
1
  VisitNamedDecl(SOPE->getPack());
1204
1
}
1205
1206
void JSONNodeDumper::VisitUnresolvedLookupExpr(
1207
0
    const UnresolvedLookupExpr *ULE) {
1208
0
  JOS.attribute("usesADL", ULE->requiresADL());
1209
0
  JOS.attribute("name", ULE->getName().getAsString());
1210
0
1211
0
  JOS.attributeArray("lookups", [this, ULE] {
1212
0
    for (const NamedDecl *D : ULE->decls())
1213
0
      JOS.value(createBareDeclRef(D));
1214
0
  });
1215
0
}
1216
1217
1
void JSONNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *ALE) {
1218
1
  JOS.attribute("name", ALE->getLabel()->getName());
1219
1
  JOS.attribute("labelDeclId", createPointerRepresentation(ALE->getLabel()));
1220
1
}
1221
1222
3
void JSONNodeDumper::VisitCXXTypeidExpr(const CXXTypeidExpr *CTE) {
1223
3
  if (CTE->isTypeOperand()) {
1224
2
    QualType Adjusted = CTE->getTypeOperand(Ctx);
1225
2
    QualType Unadjusted = CTE->getTypeOperandSourceInfo()->getType();
1226
2
    JOS.attribute("typeArg", createQualType(Unadjusted));
1227
2
    if (Adjusted != Unadjusted)
1228
1
      JOS.attribute("adjustedTypeArg", createQualType(Adjusted));
1229
2
  }
1230
3
}
1231
1232
16
void JSONNodeDumper::VisitConstantExpr(const ConstantExpr *CE) {
1233
16
  if (CE->getResultAPValueKind() != APValue::None) {
1234
9
    std::string Str;
1235
9
    llvm::raw_string_ostream OS(Str);
1236
9
    CE->getAPValueResult().printPretty(OS, Ctx, CE->getType());
1237
9
    JOS.attribute("value", OS.str());
1238
9
  }
1239
16
}
1240
1241
9
void JSONNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
1242
9
  if (const FieldDecl *FD = ILE->getInitializedFieldInUnion())
1243
2
    JOS.attribute("field", createBareDeclRef(FD));
1244
9
}
1245
1246
void JSONNodeDumper::VisitGenericSelectionExpr(
1247
7
    const GenericSelectionExpr *GSE) {
1248
7
  attributeOnlyIfTrue("resultDependent", GSE->isResultDependent());
1249
7
}
1250
1251
void JSONNodeDumper::VisitCXXUnresolvedConstructExpr(
1252
3
    const CXXUnresolvedConstructExpr *UCE) {
1253
3
  if (UCE->getType() != UCE->getTypeAsWritten())
1254
0
    JOS.attribute("typeAsWritten", createQualType(UCE->getTypeAsWritten()));
1255
3
  attributeOnlyIfTrue("list", UCE->isListInitialization());
1256
3
}
1257
1258
12
void JSONNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *CE) {
1259
12
  CXXConstructorDecl *Ctor = CE->getConstructor();
1260
12
  JOS.attribute("ctorType", createQualType(Ctor->getType()));
1261
12
  attributeOnlyIfTrue("elidable", CE->isElidable());
1262
12
  attributeOnlyIfTrue("list", CE->isListInitialization());
1263
12
  attributeOnlyIfTrue("initializer_list", CE->isStdInitListInitialization());
1264
12
  attributeOnlyIfTrue("zeroing", CE->requiresZeroInitialization());
1265
12
  attributeOnlyIfTrue("hadMultipleCandidates", CE->hadMultipleCandidates());
1266
12
1267
12
  switch (CE->getConstructionKind()) {
1268
12
  case CXXConstructExpr::CK_Complete:
1269
12
    JOS.attribute("constructionKind", "complete");
1270
12
    break;
1271
12
  case CXXConstructExpr::CK_Delegating:
1272
0
    JOS.attribute("constructionKind", "delegating");
1273
0
    break;
1274
12
  case CXXConstructExpr::CK_NonVirtualBase:
1275
0
    JOS.attribute("constructionKind", "non-virtual base");
1276
0
    break;
1277
12
  case CXXConstructExpr::CK_VirtualBase:
1278
0
    JOS.attribute("constructionKind", "virtual base");
1279
0
    break;
1280
12
  }
1281
12
}
1282
1283
6
void JSONNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *EWC) {
1284
6
  attributeOnlyIfTrue("cleanupsHaveSideEffects",
1285
6
                      EWC->cleanupsHaveSideEffects());
1286
6
  if (EWC->getNumObjects()) {
1287
3
    JOS.attributeArray("cleanups", [this, EWC] {
1288
3
      for (const ExprWithCleanups::CleanupObject &CO : EWC->getObjects())
1289
3
        JOS.value(createBareDeclRef(CO));
1290
3
    });
1291
3
  }
1292
6
}
1293
1294
void JSONNodeDumper::VisitCXXBindTemporaryExpr(
1295
1
    const CXXBindTemporaryExpr *BTE) {
1296
1
  const CXXTemporary *Temp = BTE->getTemporary();
1297
1
  JOS.attribute("temp", createPointerRepresentation(Temp));
1298
1
  if (const CXXDestructorDecl *Dtor = Temp->getDestructor())
1299
1
    JOS.attribute("dtor", createBareDeclRef(Dtor));
1300
1
}
1301
1302
void JSONNodeDumper::VisitMaterializeTemporaryExpr(
1303
3
    const MaterializeTemporaryExpr *MTE) {
1304
3
  if (const ValueDecl *VD = MTE->getExtendingDecl())
1305
2
    JOS.attribute("extendingDecl", createBareDeclRef(VD));
1306
3
1307
3
  switch (MTE->getStorageDuration()) {
1308
3
  case SD_Automatic:
1309
2
    JOS.attribute("storageDuration", "automatic");
1310
2
    break;
1311
3
  case SD_Dynamic:
1312
0
    JOS.attribute("storageDuration", "dynamic");
1313
0
    break;
1314
3
  case SD_FullExpression:
1315
1
    JOS.attribute("storageDuration", "full expression");
1316
1
    break;
1317
3
  case SD_Static:
1318
0
    JOS.attribute("storageDuration", "static");
1319
0
    break;
1320
3
  case SD_Thread:
1321
0
    JOS.attribute("storageDuration", "thread");
1322
0
    break;
1323
3
  }
1324
3
1325
3
  attributeOnlyIfTrue("boundToLValueRef", MTE->isBoundToLvalueReference());
1326
3
}
1327
1328
void JSONNodeDumper::VisitCXXDependentScopeMemberExpr(
1329
4
    const CXXDependentScopeMemberExpr *DSME) {
1330
4
  JOS.attribute("isArrow", DSME->isArrow());
1331
4
  JOS.attribute("member", DSME->getMember().getAsString());
1332
4
  attributeOnlyIfTrue("hasTemplateKeyword", DSME->hasTemplateKeyword());
1333
4
  attributeOnlyIfTrue("hasExplicitTemplateArgs",
1334
4
                      DSME->hasExplicitTemplateArgs());
1335
4
1336
4
  if (DSME->getNumTemplateArgs()) {
1337
1
    JOS.attributeArray("explicitTemplateArgs", [DSME, this] {
1338
1
      for (const TemplateArgumentLoc &TAL : DSME->template_arguments())
1339
1
        JOS.object(
1340
1
            [&TAL, this] { Visit(TAL.getArgument(), TAL.getSourceRange()); });
1341
1
    });
1342
1
  }
1343
4
}
1344
1345
112
void JSONNodeDumper::VisitIntegerLiteral(const IntegerLiteral *IL) {
1346
112
  JOS.attribute("value",
1347
112
                IL->getValue().toString(
1348
112
                    /*Radix=*/10, IL->getType()->isSignedIntegerType()));
1349
112
}
1350
2
void JSONNodeDumper::VisitCharacterLiteral(const CharacterLiteral *CL) {
1351
2
  // FIXME: This should probably print the character literal as a string,
1352
2
  // rather than as a numerical value. It would be nice if the behavior matched
1353
2
  // what we do to print a string literal; right now, it is impossible to tell
1354
2
  // the difference between 'a' and L'a' in C from the JSON output.
1355
2
  JOS.attribute("value", CL->getValue());
1356
2
}
1357
0
void JSONNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *FPL) {
1358
0
  JOS.attribute("value", FPL->getValueAsString(/*Radix=*/10));
1359
0
}
1360
6
void JSONNodeDumper::VisitFloatingLiteral(const FloatingLiteral *FL) {
1361
6
  llvm::SmallVector<char, 16> Buffer;
1362
6
  FL->getValue().toString(Buffer);
1363
6
  JOS.attribute("value", Buffer);
1364
6
}
1365
11
void JSONNodeDumper::VisitStringLiteral(const StringLiteral *SL) {
1366
11
  std::string Buffer;
1367
11
  llvm::raw_string_ostream SS(Buffer);
1368
11
  SL->outputString(SS);
1369
11
  JOS.attribute("value", SS.str());
1370
11
}
1371
0
void JSONNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *BLE) {
1372
0
  JOS.attribute("value", BLE->getValue());
1373
0
}
1374
1375
18
void JSONNodeDumper::VisitIfStmt(const IfStmt *IS) {
1376
18
  attributeOnlyIfTrue("hasInit", IS->hasInitStorage());
1377
18
  attributeOnlyIfTrue("hasVar", IS->hasVarStorage());
1378
18
  attributeOnlyIfTrue("hasElse", IS->hasElseStorage());
1379
18
  attributeOnlyIfTrue("isConstexpr", IS->isConstexpr());
1380
18
}
1381
1382
2
void JSONNodeDumper::VisitSwitchStmt(const SwitchStmt *SS) {
1383
2
  attributeOnlyIfTrue("hasInit", SS->hasInitStorage());
1384
2
  attributeOnlyIfTrue("hasVar", SS->hasVarStorage());
1385
2
}
1386
4
void JSONNodeDumper::VisitCaseStmt(const CaseStmt *CS) {
1387
4
  attributeOnlyIfTrue("isGNURange", CS->caseStmtIsGNURange());
1388
4
}
1389
1390
2
void JSONNodeDumper::VisitLabelStmt(const LabelStmt *LS) {
1391
2
  JOS.attribute("name", LS->getName());
1392
2
  JOS.attribute("declId", createPointerRepresentation(LS->getDecl()));
1393
2
}
1394
1
void JSONNodeDumper::VisitGotoStmt(const GotoStmt *GS) {
1395
1
  JOS.attribute("targetLabelDeclId",
1396
1
                createPointerRepresentation(GS->getLabel()));
1397
1
}
1398
1399
2
void JSONNodeDumper::VisitWhileStmt(const WhileStmt *WS) {
1400
2
  attributeOnlyIfTrue("hasVar", WS->hasVarStorage());
1401
2
}
1402
1403
2
void JSONNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt* OACS) {
1404
2
  // FIXME: it would be nice for the ASTNodeTraverser would handle the catch
1405
2
  // parameter the same way for C++ and ObjC rather. In this case, C++ gets a
1406
2
  // null child node and ObjC gets no child node.
1407
2
  attributeOnlyIfTrue("isCatchAll", OACS->getCatchParamDecl() == nullptr);
1408
2
}
1409
1410
0
void JSONNodeDumper::VisitNullTemplateArgument(const TemplateArgument &TA) {
1411
0
  JOS.attribute("isNull", true);
1412
0
}
1413
10
void JSONNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {
1414
10
  JOS.attribute("type", createQualType(TA.getAsType()));
1415
10
}
1416
void JSONNodeDumper::VisitDeclarationTemplateArgument(
1417
0
    const TemplateArgument &TA) {
1418
0
  JOS.attribute("decl", createBareDeclRef(TA.getAsDecl()));
1419
0
}
1420
0
void JSONNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &TA) {
1421
0
  JOS.attribute("isNullptr", true);
1422
0
}
1423
0
void JSONNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {
1424
0
  JOS.attribute("value", TA.getAsIntegral().getSExtValue());
1425
0
}
1426
0
void JSONNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) {
1427
0
  // FIXME: cannot just call dump() on the argument, as that doesn't specify
1428
0
  // the output format.
1429
0
}
1430
void JSONNodeDumper::VisitTemplateExpansionTemplateArgument(
1431
0
    const TemplateArgument &TA) {
1432
0
  // FIXME: cannot just call dump() on the argument, as that doesn't specify
1433
0
  // the output format.
1434
0
}
1435
void JSONNodeDumper::VisitExpressionTemplateArgument(
1436
0
    const TemplateArgument &TA) {
1437
0
  JOS.attribute("isExpr", true);
1438
0
}
1439
0
void JSONNodeDumper::VisitPackTemplateArgument(const TemplateArgument &TA) {
1440
0
  JOS.attribute("isPack", true);
1441
0
}
1442
1443
3
StringRef JSONNodeDumper::getCommentCommandName(unsigned CommandID) const {
1444
3
  if (Traits)
1445
3
    return Traits->getCommandInfo(CommandID)->Name;
1446
0
  if (const comments::CommandInfo *Info =
1447
0
          comments::CommandTraits::getBuiltinCommandInfo(CommandID))
1448
0
    return Info->Name;
1449
0
  return "<invalid>";
1450
0
}
1451
1452
void JSONNodeDumper::visitTextComment(const comments::TextComment *C,
1453
21
                                      const comments::FullComment *) {
1454
21
  JOS.attribute("text", C->getText());
1455
21
}
1456
1457
void JSONNodeDumper::visitInlineCommandComment(
1458
1
    const comments::InlineCommandComment *C, const comments::FullComment *) {
1459
1
  JOS.attribute("name", getCommentCommandName(C->getCommandID()));
1460
1
1461
1
  switch (C->getRenderKind()) {
1462
1
  case comments::InlineCommandComment::RenderNormal:
1463
0
    JOS.attribute("renderKind", "normal");
1464
0
    break;
1465
1
  case comments::InlineCommandComment::RenderBold:
1466
0
    JOS.attribute("renderKind", "bold");
1467
0
    break;
1468
1
  case comments::InlineCommandComment::RenderEmphasized:
1469
0
    JOS.attribute("renderKind", "emphasized");
1470
0
    break;
1471
1
  case comments::InlineCommandComment::RenderMonospaced:
1472
1
    JOS.attribute("renderKind", "monospaced");
1473
1
    break;
1474
1
  }
1475
1
1476
1
  llvm::json::Array Args;
1477
2
  for (unsigned I = 0, E = C->getNumArgs(); I < E; 
++I1
)
1478
1
    Args.push_back(C->getArgText(I));
1479
1
1480
1
  if (!Args.empty())
1481
1
    JOS.attribute("args", std::move(Args));
1482
1
}
1483
1484
void JSONNodeDumper::visitHTMLStartTagComment(
1485
2
    const comments::HTMLStartTagComment *C, const comments::FullComment *) {
1486
2
  JOS.attribute("name", C->getTagName());
1487
2
  attributeOnlyIfTrue("selfClosing", C->isSelfClosing());
1488
2
  attributeOnlyIfTrue("malformed", C->isMalformed());
1489
2
1490
2
  llvm::json::Array Attrs;
1491
2
  for (unsigned I = 0, E = C->getNumAttrs(); I < E; 
++I0
)
1492
0
    Attrs.push_back(
1493
0
        {{"name", C->getAttr(I).Name}, {"value", C->getAttr(I).Value}});
1494
2
1495
2
  if (!Attrs.empty())
1496
0
    JOS.attribute("attrs", std::move(Attrs));
1497
2
}
1498
1499
void JSONNodeDumper::visitHTMLEndTagComment(
1500
1
    const comments::HTMLEndTagComment *C, const comments::FullComment *) {
1501
1
  JOS.attribute("name", C->getTagName());
1502
1
}
1503
1504
void JSONNodeDumper::visitBlockCommandComment(
1505
1
    const comments::BlockCommandComment *C, const comments::FullComment *) {
1506
1
  JOS.attribute("name", getCommentCommandName(C->getCommandID()));
1507
1
1508
1
  llvm::json::Array Args;
1509
1
  for (unsigned I = 0, E = C->getNumArgs(); I < E; 
++I0
)
1510
0
    Args.push_back(C->getArgText(I));
1511
1
1512
1
  if (!Args.empty())
1513
0
    JOS.attribute("args", std::move(Args));
1514
1
}
1515
1516
void JSONNodeDumper::visitParamCommandComment(
1517
4
    const comments::ParamCommandComment *C, const comments::FullComment *FC) {
1518
4
  switch (C->getDirection()) {
1519
4
  case comments::ParamCommandComment::In:
1520
3
    JOS.attribute("direction", "in");
1521
3
    break;
1522
4
  case comments::ParamCommandComment::Out:
1523
0
    JOS.attribute("direction", "out");
1524
0
    break;
1525
4
  case comments::ParamCommandComment::InOut:
1526
1
    JOS.attribute("direction", "in,out");
1527
1
    break;
1528
4
  }
1529
4
  attributeOnlyIfTrue("explicit", C->isDirectionExplicit());
1530
4
1531
4
  if (C->hasParamName())
1532
4
    JOS.attribute("param", C->isParamIndexValid() ? C->getParamName(FC)
1533
4
                                                  : 
C->getParamNameAsWritten()0
);
1534
4
1535
4
  if (C->isParamIndexValid() && !C->isVarArgParam())
1536
2
    JOS.attribute("paramIdx", C->getParamIndex());
1537
4
}
1538
1539
void JSONNodeDumper::visitTParamCommandComment(
1540
2
    const comments::TParamCommandComment *C, const comments::FullComment *FC) {
1541
2
  if (C->hasParamName())
1542
2
    JOS.attribute("param", C->isPositionValid() ? 
C->getParamName(FC)1
1543
2
                                                : 
C->getParamNameAsWritten()1
);
1544
2
  if (C->isPositionValid()) {
1545
1
    llvm::json::Array Positions;
1546
2
    for (unsigned I = 0, E = C->getDepth(); I < E; 
++I1
)
1547
1
      Positions.push_back(C->getIndex(I));
1548
1
1549
1
    if (!Positions.empty())
1550
1
      JOS.attribute("positions", std::move(Positions));
1551
1
  }
1552
2
}
1553
1554
void JSONNodeDumper::visitVerbatimBlockComment(
1555
1
    const comments::VerbatimBlockComment *C, const comments::FullComment *) {
1556
1
  JOS.attribute("name", getCommentCommandName(C->getCommandID()));
1557
1
  JOS.attribute("closeName", C->getCloseName());
1558
1
}
1559
1560
void JSONNodeDumper::visitVerbatimBlockLineComment(
1561
    const comments::VerbatimBlockLineComment *C,
1562
1
    const comments::FullComment *) {
1563
1
  JOS.attribute("text", C->getText());
1564
1
}
1565
1566
void JSONNodeDumper::visitVerbatimLineComment(
1567
0
    const comments::VerbatimLineComment *C, const comments::FullComment *) {
1568
0
  JOS.attribute("text", C->getText());
1569
0
}