150
|
1 //===--- TextNodeDumper.cpp - Printing of AST nodes -----------------------===//
|
|
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 implements AST dumping of components of individual AST nodes.
|
|
10 //
|
|
11 //===----------------------------------------------------------------------===//
|
|
12
|
|
13 #include "clang/AST/TextNodeDumper.h"
|
|
14 #include "clang/AST/DeclFriend.h"
|
|
15 #include "clang/AST/DeclOpenMP.h"
|
|
16 #include "clang/AST/DeclTemplate.h"
|
|
17 #include "clang/AST/LocInfoType.h"
|
173
|
18 #include "clang/Basic/Module.h"
|
|
19 #include "clang/Basic/SourceManager.h"
|
150
|
20
|
|
21 using namespace clang;
|
|
22
|
|
23 static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}
|
|
24
|
|
25 template <typename T>
|
|
26 static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) {
|
|
27 const T *First = D->getFirstDecl();
|
|
28 if (First != D)
|
|
29 OS << " first " << First;
|
|
30 }
|
|
31
|
|
32 template <typename T>
|
|
33 static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
|
|
34 const T *Prev = D->getPreviousDecl();
|
|
35 if (Prev)
|
|
36 OS << " prev " << Prev;
|
|
37 }
|
|
38
|
|
39 /// Dump the previous declaration in the redeclaration chain for a declaration,
|
|
40 /// if any.
|
|
41 static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) {
|
|
42 switch (D->getKind()) {
|
|
43 #define DECL(DERIVED, BASE) \
|
|
44 case Decl::DERIVED: \
|
|
45 return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D));
|
|
46 #define ABSTRACT_DECL(DECL)
|
|
47 #include "clang/AST/DeclNodes.inc"
|
|
48 }
|
|
49 llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
|
|
50 }
|
|
51
|
|
52 TextNodeDumper::TextNodeDumper(raw_ostream &OS, bool ShowColors,
|
|
53 const SourceManager *SM,
|
|
54 const PrintingPolicy &PrintPolicy,
|
|
55 const comments::CommandTraits *Traits)
|
|
56 : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors), SM(SM),
|
|
57 PrintPolicy(PrintPolicy), Traits(Traits) {}
|
|
58
|
|
59 void TextNodeDumper::Visit(const comments::Comment *C,
|
|
60 const comments::FullComment *FC) {
|
|
61 if (!C) {
|
|
62 ColorScope Color(OS, ShowColors, NullColor);
|
|
63 OS << "<<<NULL>>>";
|
|
64 return;
|
|
65 }
|
|
66
|
|
67 {
|
|
68 ColorScope Color(OS, ShowColors, CommentColor);
|
|
69 OS << C->getCommentKindName();
|
|
70 }
|
|
71 dumpPointer(C);
|
|
72 dumpSourceRange(C->getSourceRange());
|
|
73
|
|
74 ConstCommentVisitor<TextNodeDumper, void,
|
|
75 const comments::FullComment *>::visit(C, FC);
|
|
76 }
|
|
77
|
|
78 void TextNodeDumper::Visit(const Attr *A) {
|
|
79 {
|
|
80 ColorScope Color(OS, ShowColors, AttrColor);
|
|
81
|
|
82 switch (A->getKind()) {
|
|
83 #define ATTR(X) \
|
|
84 case attr::X: \
|
|
85 OS << #X; \
|
|
86 break;
|
|
87 #include "clang/Basic/AttrList.inc"
|
|
88 }
|
|
89 OS << "Attr";
|
|
90 }
|
|
91 dumpPointer(A);
|
|
92 dumpSourceRange(A->getRange());
|
|
93 if (A->isInherited())
|
|
94 OS << " Inherited";
|
|
95 if (A->isImplicit())
|
|
96 OS << " Implicit";
|
|
97
|
|
98 ConstAttrVisitor<TextNodeDumper>::Visit(A);
|
|
99 }
|
|
100
|
|
101 void TextNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,
|
|
102 const Decl *From, StringRef Label) {
|
|
103 OS << "TemplateArgument";
|
|
104 if (R.isValid())
|
|
105 dumpSourceRange(R);
|
|
106
|
|
107 if (From)
|
|
108 dumpDeclRef(From, Label);
|
|
109
|
|
110 ConstTemplateArgumentVisitor<TextNodeDumper>::Visit(TA);
|
|
111 }
|
|
112
|
|
113 void TextNodeDumper::Visit(const Stmt *Node) {
|
|
114 if (!Node) {
|
|
115 ColorScope Color(OS, ShowColors, NullColor);
|
|
116 OS << "<<<NULL>>>";
|
|
117 return;
|
|
118 }
|
|
119 {
|
|
120 ColorScope Color(OS, ShowColors, StmtColor);
|
|
121 OS << Node->getStmtClassName();
|
|
122 }
|
|
123 dumpPointer(Node);
|
|
124 dumpSourceRange(Node->getSourceRange());
|
|
125
|
|
126 if (const auto *E = dyn_cast<Expr>(Node)) {
|
|
127 dumpType(E->getType());
|
|
128
|
173
|
129 if (E->containsErrors()) {
|
|
130 ColorScope Color(OS, ShowColors, ErrorsColor);
|
|
131 OS << " contains-errors";
|
|
132 }
|
|
133
|
150
|
134 {
|
|
135 ColorScope Color(OS, ShowColors, ValueKindColor);
|
|
136 switch (E->getValueKind()) {
|
|
137 case VK_RValue:
|
|
138 break;
|
|
139 case VK_LValue:
|
|
140 OS << " lvalue";
|
|
141 break;
|
|
142 case VK_XValue:
|
|
143 OS << " xvalue";
|
|
144 break;
|
|
145 }
|
|
146 }
|
|
147
|
|
148 {
|
|
149 ColorScope Color(OS, ShowColors, ObjectKindColor);
|
|
150 switch (E->getObjectKind()) {
|
|
151 case OK_Ordinary:
|
|
152 break;
|
|
153 case OK_BitField:
|
|
154 OS << " bitfield";
|
|
155 break;
|
|
156 case OK_ObjCProperty:
|
|
157 OS << " objcproperty";
|
|
158 break;
|
|
159 case OK_ObjCSubscript:
|
|
160 OS << " objcsubscript";
|
|
161 break;
|
|
162 case OK_VectorComponent:
|
|
163 OS << " vectorcomponent";
|
|
164 break;
|
|
165 }
|
|
166 }
|
|
167 }
|
|
168
|
|
169 ConstStmtVisitor<TextNodeDumper>::Visit(Node);
|
|
170 }
|
|
171
|
|
172 void TextNodeDumper::Visit(const Type *T) {
|
|
173 if (!T) {
|
|
174 ColorScope Color(OS, ShowColors, NullColor);
|
|
175 OS << "<<<NULL>>>";
|
|
176 return;
|
|
177 }
|
|
178 if (isa<LocInfoType>(T)) {
|
|
179 {
|
|
180 ColorScope Color(OS, ShowColors, TypeColor);
|
|
181 OS << "LocInfo Type";
|
|
182 }
|
|
183 dumpPointer(T);
|
|
184 return;
|
|
185 }
|
|
186
|
|
187 {
|
|
188 ColorScope Color(OS, ShowColors, TypeColor);
|
|
189 OS << T->getTypeClassName() << "Type";
|
|
190 }
|
|
191 dumpPointer(T);
|
|
192 OS << " ";
|
|
193 dumpBareType(QualType(T, 0), false);
|
|
194
|
|
195 QualType SingleStepDesugar =
|
|
196 T->getLocallyUnqualifiedSingleStepDesugaredType();
|
|
197 if (SingleStepDesugar != QualType(T, 0))
|
|
198 OS << " sugar";
|
|
199
|
|
200 if (T->isDependentType())
|
|
201 OS << " dependent";
|
|
202 else if (T->isInstantiationDependentType())
|
|
203 OS << " instantiation_dependent";
|
|
204
|
|
205 if (T->isVariablyModifiedType())
|
|
206 OS << " variably_modified";
|
|
207 if (T->containsUnexpandedParameterPack())
|
|
208 OS << " contains_unexpanded_pack";
|
|
209 if (T->isFromAST())
|
|
210 OS << " imported";
|
|
211
|
|
212 TypeVisitor<TextNodeDumper>::Visit(T);
|
|
213 }
|
|
214
|
|
215 void TextNodeDumper::Visit(QualType T) {
|
|
216 OS << "QualType";
|
|
217 dumpPointer(T.getAsOpaquePtr());
|
|
218 OS << " ";
|
|
219 dumpBareType(T, false);
|
|
220 OS << " " << T.split().Quals.getAsString();
|
|
221 }
|
|
222
|
|
223 void TextNodeDumper::Visit(const Decl *D) {
|
|
224 if (!D) {
|
|
225 ColorScope Color(OS, ShowColors, NullColor);
|
|
226 OS << "<<<NULL>>>";
|
|
227 return;
|
|
228 }
|
|
229
|
|
230 {
|
|
231 ColorScope Color(OS, ShowColors, DeclKindNameColor);
|
|
232 OS << D->getDeclKindName() << "Decl";
|
|
233 }
|
|
234 dumpPointer(D);
|
|
235 if (D->getLexicalDeclContext() != D->getDeclContext())
|
|
236 OS << " parent " << cast<Decl>(D->getDeclContext());
|
|
237 dumpPreviousDecl(OS, D);
|
|
238 dumpSourceRange(D->getSourceRange());
|
|
239 OS << ' ';
|
|
240 dumpLocation(D->getLocation());
|
|
241 if (D->isFromASTFile())
|
|
242 OS << " imported";
|
|
243 if (Module *M = D->getOwningModule())
|
|
244 OS << " in " << M->getFullModuleName();
|
|
245 if (auto *ND = dyn_cast<NamedDecl>(D))
|
|
246 for (Module *M : D->getASTContext().getModulesWithMergedDefinition(
|
|
247 const_cast<NamedDecl *>(ND)))
|
|
248 AddChild([=] { OS << "also in " << M->getFullModuleName(); });
|
|
249 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
|
|
250 if (ND->isHidden())
|
|
251 OS << " hidden";
|
|
252 if (D->isImplicit())
|
|
253 OS << " implicit";
|
|
254
|
|
255 if (D->isUsed())
|
|
256 OS << " used";
|
|
257 else if (D->isThisDeclarationReferenced())
|
|
258 OS << " referenced";
|
|
259
|
|
260 if (D->isInvalidDecl())
|
|
261 OS << " invalid";
|
|
262 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
|
263 if (FD->isConstexprSpecified())
|
|
264 OS << " constexpr";
|
|
265 if (FD->isConsteval())
|
|
266 OS << " consteval";
|
|
267 }
|
|
268
|
|
269 if (!isa<FunctionDecl>(*D)) {
|
|
270 const auto *MD = dyn_cast<ObjCMethodDecl>(D);
|
|
271 if (!MD || !MD->isThisDeclarationADefinition()) {
|
|
272 const auto *DC = dyn_cast<DeclContext>(D);
|
|
273 if (DC && DC->hasExternalLexicalStorage()) {
|
|
274 ColorScope Color(OS, ShowColors, UndeserializedColor);
|
|
275 OS << " <undeserialized declarations>";
|
|
276 }
|
|
277 }
|
|
278 }
|
|
279
|
|
280 ConstDeclVisitor<TextNodeDumper>::Visit(D);
|
|
281 }
|
|
282
|
|
283 void TextNodeDumper::Visit(const CXXCtorInitializer *Init) {
|
|
284 OS << "CXXCtorInitializer";
|
|
285 if (Init->isAnyMemberInitializer()) {
|
|
286 OS << ' ';
|
|
287 dumpBareDeclRef(Init->getAnyMember());
|
|
288 } else if (Init->isBaseInitializer()) {
|
|
289 dumpType(QualType(Init->getBaseClass(), 0));
|
|
290 } else if (Init->isDelegatingInitializer()) {
|
|
291 dumpType(Init->getTypeSourceInfo()->getType());
|
|
292 } else {
|
|
293 llvm_unreachable("Unknown initializer type");
|
|
294 }
|
|
295 }
|
|
296
|
|
297 void TextNodeDumper::Visit(const BlockDecl::Capture &C) {
|
|
298 OS << "capture";
|
|
299 if (C.isByRef())
|
|
300 OS << " byref";
|
|
301 if (C.isNested())
|
|
302 OS << " nested";
|
|
303 if (C.getVariable()) {
|
|
304 OS << ' ';
|
|
305 dumpBareDeclRef(C.getVariable());
|
|
306 }
|
|
307 }
|
|
308
|
|
309 void TextNodeDumper::Visit(const OMPClause *C) {
|
|
310 if (!C) {
|
|
311 ColorScope Color(OS, ShowColors, NullColor);
|
|
312 OS << "<<<NULL>>> OMPClause";
|
|
313 return;
|
|
314 }
|
|
315 {
|
|
316 ColorScope Color(OS, ShowColors, AttrColor);
|
173
|
317 StringRef ClauseName(llvm::omp::getOpenMPClauseName(C->getClauseKind()));
|
150
|
318 OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
|
|
319 << ClauseName.drop_front() << "Clause";
|
|
320 }
|
|
321 dumpPointer(C);
|
|
322 dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
|
|
323 if (C->isImplicit())
|
|
324 OS << " <implicit>";
|
|
325 }
|
|
326
|
|
327 void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
|
|
328 const TypeSourceInfo *TSI = A.getTypeSourceInfo();
|
|
329 if (TSI) {
|
|
330 OS << "case ";
|
|
331 dumpType(TSI->getType());
|
|
332 } else {
|
|
333 OS << "default";
|
|
334 }
|
|
335
|
|
336 if (A.isSelected())
|
|
337 OS << " selected";
|
|
338 }
|
|
339
|
|
340 void TextNodeDumper::dumpPointer(const void *Ptr) {
|
|
341 ColorScope Color(OS, ShowColors, AddressColor);
|
|
342 OS << ' ' << Ptr;
|
|
343 }
|
|
344
|
|
345 void TextNodeDumper::dumpLocation(SourceLocation Loc) {
|
|
346 if (!SM)
|
|
347 return;
|
|
348
|
|
349 ColorScope Color(OS, ShowColors, LocationColor);
|
|
350 SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
|
|
351
|
|
352 // The general format we print out is filename:line:col, but we drop pieces
|
|
353 // that haven't changed since the last loc printed.
|
|
354 PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
|
|
355
|
|
356 if (PLoc.isInvalid()) {
|
|
357 OS << "<invalid sloc>";
|
|
358 return;
|
|
359 }
|
|
360
|
|
361 if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
|
|
362 OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
|
|
363 << PLoc.getColumn();
|
|
364 LastLocFilename = PLoc.getFilename();
|
|
365 LastLocLine = PLoc.getLine();
|
|
366 } else if (PLoc.getLine() != LastLocLine) {
|
|
367 OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
|
|
368 LastLocLine = PLoc.getLine();
|
|
369 } else {
|
|
370 OS << "col" << ':' << PLoc.getColumn();
|
|
371 }
|
|
372 }
|
|
373
|
|
374 void TextNodeDumper::dumpSourceRange(SourceRange R) {
|
|
375 // Can't translate locations if a SourceManager isn't available.
|
|
376 if (!SM)
|
|
377 return;
|
|
378
|
|
379 OS << " <";
|
|
380 dumpLocation(R.getBegin());
|
|
381 if (R.getBegin() != R.getEnd()) {
|
|
382 OS << ", ";
|
|
383 dumpLocation(R.getEnd());
|
|
384 }
|
|
385 OS << ">";
|
|
386
|
|
387 // <t2.c:123:421[blah], t2.c:412:321>
|
|
388 }
|
|
389
|
|
390 void TextNodeDumper::dumpBareType(QualType T, bool Desugar) {
|
|
391 ColorScope Color(OS, ShowColors, TypeColor);
|
|
392
|
|
393 SplitQualType T_split = T.split();
|
|
394 OS << "'" << QualType::getAsString(T_split, PrintPolicy) << "'";
|
|
395
|
|
396 if (Desugar && !T.isNull()) {
|
|
397 // If the type is sugared, also dump a (shallow) desugared type.
|
|
398 SplitQualType D_split = T.getSplitDesugaredType();
|
|
399 if (T_split != D_split)
|
|
400 OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'";
|
|
401 }
|
|
402 }
|
|
403
|
|
404 void TextNodeDumper::dumpType(QualType T) {
|
|
405 OS << ' ';
|
|
406 dumpBareType(T);
|
|
407 }
|
|
408
|
|
409 void TextNodeDumper::dumpBareDeclRef(const Decl *D) {
|
|
410 if (!D) {
|
|
411 ColorScope Color(OS, ShowColors, NullColor);
|
|
412 OS << "<<<NULL>>>";
|
|
413 return;
|
|
414 }
|
|
415
|
|
416 {
|
|
417 ColorScope Color(OS, ShowColors, DeclKindNameColor);
|
|
418 OS << D->getDeclKindName();
|
|
419 }
|
|
420 dumpPointer(D);
|
|
421
|
|
422 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
|
|
423 ColorScope Color(OS, ShowColors, DeclNameColor);
|
|
424 OS << " '" << ND->getDeclName() << '\'';
|
|
425 }
|
|
426
|
|
427 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
|
|
428 dumpType(VD->getType());
|
|
429 }
|
|
430
|
|
431 void TextNodeDumper::dumpName(const NamedDecl *ND) {
|
|
432 if (ND->getDeclName()) {
|
|
433 ColorScope Color(OS, ShowColors, DeclNameColor);
|
|
434 OS << ' ' << ND->getNameAsString();
|
|
435 }
|
|
436 }
|
|
437
|
|
438 void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS) {
|
|
439 switch (AS) {
|
|
440 case AS_none:
|
|
441 break;
|
|
442 case AS_public:
|
|
443 OS << "public";
|
|
444 break;
|
|
445 case AS_protected:
|
|
446 OS << "protected";
|
|
447 break;
|
|
448 case AS_private:
|
|
449 OS << "private";
|
|
450 break;
|
|
451 }
|
|
452 }
|
|
453
|
173
|
454 void TextNodeDumper::dumpCleanupObject(
|
|
455 const ExprWithCleanups::CleanupObject &C) {
|
|
456 if (auto *BD = C.dyn_cast<BlockDecl *>())
|
|
457 dumpDeclRef(BD, "cleanup");
|
|
458 else if (auto *CLE = C.dyn_cast<CompoundLiteralExpr *>())
|
|
459 AddChild([=] {
|
|
460 OS << "cleanup ";
|
|
461 {
|
|
462 ColorScope Color(OS, ShowColors, StmtColor);
|
|
463 OS << CLE->getStmtClassName();
|
|
464 }
|
|
465 dumpPointer(CLE);
|
|
466 });
|
|
467 else
|
|
468 llvm_unreachable("unexpected cleanup type");
|
|
469 }
|
|
470
|
150
|
471 void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) {
|
|
472 if (!D)
|
|
473 return;
|
|
474
|
|
475 AddChild([=] {
|
|
476 if (!Label.empty())
|
|
477 OS << Label << ' ';
|
|
478 dumpBareDeclRef(D);
|
|
479 });
|
|
480 }
|
|
481
|
|
482 const char *TextNodeDumper::getCommandName(unsigned CommandID) {
|
|
483 if (Traits)
|
|
484 return Traits->getCommandInfo(CommandID)->Name;
|
|
485 const comments::CommandInfo *Info =
|
|
486 comments::CommandTraits::getBuiltinCommandInfo(CommandID);
|
|
487 if (Info)
|
|
488 return Info->Name;
|
|
489 return "<not a builtin command>";
|
|
490 }
|
|
491
|
|
492 void TextNodeDumper::visitTextComment(const comments::TextComment *C,
|
|
493 const comments::FullComment *) {
|
|
494 OS << " Text=\"" << C->getText() << "\"";
|
|
495 }
|
|
496
|
|
497 void TextNodeDumper::visitInlineCommandComment(
|
|
498 const comments::InlineCommandComment *C, const comments::FullComment *) {
|
|
499 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
|
|
500 switch (C->getRenderKind()) {
|
|
501 case comments::InlineCommandComment::RenderNormal:
|
|
502 OS << " RenderNormal";
|
|
503 break;
|
|
504 case comments::InlineCommandComment::RenderBold:
|
|
505 OS << " RenderBold";
|
|
506 break;
|
|
507 case comments::InlineCommandComment::RenderMonospaced:
|
|
508 OS << " RenderMonospaced";
|
|
509 break;
|
|
510 case comments::InlineCommandComment::RenderEmphasized:
|
|
511 OS << " RenderEmphasized";
|
|
512 break;
|
|
513 case comments::InlineCommandComment::RenderAnchor:
|
|
514 OS << " RenderAnchor";
|
|
515 break;
|
|
516 }
|
|
517
|
|
518 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
|
|
519 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
|
|
520 }
|
|
521
|
|
522 void TextNodeDumper::visitHTMLStartTagComment(
|
|
523 const comments::HTMLStartTagComment *C, const comments::FullComment *) {
|
|
524 OS << " Name=\"" << C->getTagName() << "\"";
|
|
525 if (C->getNumAttrs() != 0) {
|
|
526 OS << " Attrs: ";
|
|
527 for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
|
|
528 const comments::HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
|
|
529 OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
|
|
530 }
|
|
531 }
|
|
532 if (C->isSelfClosing())
|
|
533 OS << " SelfClosing";
|
|
534 }
|
|
535
|
|
536 void TextNodeDumper::visitHTMLEndTagComment(
|
|
537 const comments::HTMLEndTagComment *C, const comments::FullComment *) {
|
|
538 OS << " Name=\"" << C->getTagName() << "\"";
|
|
539 }
|
|
540
|
|
541 void TextNodeDumper::visitBlockCommandComment(
|
|
542 const comments::BlockCommandComment *C, const comments::FullComment *) {
|
|
543 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
|
|
544 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
|
|
545 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
|
|
546 }
|
|
547
|
|
548 void TextNodeDumper::visitParamCommandComment(
|
|
549 const comments::ParamCommandComment *C, const comments::FullComment *FC) {
|
|
550 OS << " "
|
|
551 << comments::ParamCommandComment::getDirectionAsString(C->getDirection());
|
|
552
|
|
553 if (C->isDirectionExplicit())
|
|
554 OS << " explicitly";
|
|
555 else
|
|
556 OS << " implicitly";
|
|
557
|
|
558 if (C->hasParamName()) {
|
|
559 if (C->isParamIndexValid())
|
|
560 OS << " Param=\"" << C->getParamName(FC) << "\"";
|
|
561 else
|
|
562 OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
|
|
563 }
|
|
564
|
|
565 if (C->isParamIndexValid() && !C->isVarArgParam())
|
|
566 OS << " ParamIndex=" << C->getParamIndex();
|
|
567 }
|
|
568
|
|
569 void TextNodeDumper::visitTParamCommandComment(
|
|
570 const comments::TParamCommandComment *C, const comments::FullComment *FC) {
|
|
571 if (C->hasParamName()) {
|
|
572 if (C->isPositionValid())
|
|
573 OS << " Param=\"" << C->getParamName(FC) << "\"";
|
|
574 else
|
|
575 OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
|
|
576 }
|
|
577
|
|
578 if (C->isPositionValid()) {
|
|
579 OS << " Position=<";
|
|
580 for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
|
|
581 OS << C->getIndex(i);
|
|
582 if (i != e - 1)
|
|
583 OS << ", ";
|
|
584 }
|
|
585 OS << ">";
|
|
586 }
|
|
587 }
|
|
588
|
|
589 void TextNodeDumper::visitVerbatimBlockComment(
|
|
590 const comments::VerbatimBlockComment *C, const comments::FullComment *) {
|
|
591 OS << " Name=\"" << getCommandName(C->getCommandID())
|
|
592 << "\""
|
|
593 " CloseName=\""
|
|
594 << C->getCloseName() << "\"";
|
|
595 }
|
|
596
|
|
597 void TextNodeDumper::visitVerbatimBlockLineComment(
|
|
598 const comments::VerbatimBlockLineComment *C,
|
|
599 const comments::FullComment *) {
|
|
600 OS << " Text=\"" << C->getText() << "\"";
|
|
601 }
|
|
602
|
|
603 void TextNodeDumper::visitVerbatimLineComment(
|
|
604 const comments::VerbatimLineComment *C, const comments::FullComment *) {
|
|
605 OS << " Text=\"" << C->getText() << "\"";
|
|
606 }
|
|
607
|
|
608 void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &) {
|
|
609 OS << " null";
|
|
610 }
|
|
611
|
|
612 void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {
|
|
613 OS << " type";
|
|
614 dumpType(TA.getAsType());
|
|
615 }
|
|
616
|
|
617 void TextNodeDumper::VisitDeclarationTemplateArgument(
|
|
618 const TemplateArgument &TA) {
|
|
619 OS << " decl";
|
|
620 dumpDeclRef(TA.getAsDecl());
|
|
621 }
|
|
622
|
|
623 void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &) {
|
|
624 OS << " nullptr";
|
|
625 }
|
|
626
|
|
627 void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {
|
|
628 OS << " integral " << TA.getAsIntegral();
|
|
629 }
|
|
630
|
|
631 void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) {
|
|
632 OS << " template ";
|
|
633 TA.getAsTemplate().dump(OS);
|
|
634 }
|
|
635
|
|
636 void TextNodeDumper::VisitTemplateExpansionTemplateArgument(
|
|
637 const TemplateArgument &TA) {
|
|
638 OS << " template expansion ";
|
|
639 TA.getAsTemplateOrTemplatePattern().dump(OS);
|
|
640 }
|
|
641
|
|
642 void TextNodeDumper::VisitExpressionTemplateArgument(const TemplateArgument &) {
|
|
643 OS << " expr";
|
|
644 }
|
|
645
|
|
646 void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &) {
|
|
647 OS << " pack";
|
|
648 }
|
|
649
|
|
650 static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
|
|
651 if (Node->path_empty())
|
|
652 return;
|
|
653
|
|
654 OS << " (";
|
|
655 bool First = true;
|
|
656 for (CastExpr::path_const_iterator I = Node->path_begin(),
|
|
657 E = Node->path_end();
|
|
658 I != E; ++I) {
|
|
659 const CXXBaseSpecifier *Base = *I;
|
|
660 if (!First)
|
|
661 OS << " -> ";
|
|
662
|
|
663 const auto *RD =
|
|
664 cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
|
|
665
|
|
666 if (Base->isVirtual())
|
|
667 OS << "virtual ";
|
|
668 OS << RD->getName();
|
|
669 First = false;
|
|
670 }
|
|
671
|
|
672 OS << ')';
|
|
673 }
|
|
674
|
|
675 void TextNodeDumper::VisitIfStmt(const IfStmt *Node) {
|
|
676 if (Node->hasInitStorage())
|
|
677 OS << " has_init";
|
|
678 if (Node->hasVarStorage())
|
|
679 OS << " has_var";
|
|
680 if (Node->hasElseStorage())
|
|
681 OS << " has_else";
|
|
682 }
|
|
683
|
|
684 void TextNodeDumper::VisitSwitchStmt(const SwitchStmt *Node) {
|
|
685 if (Node->hasInitStorage())
|
|
686 OS << " has_init";
|
|
687 if (Node->hasVarStorage())
|
|
688 OS << " has_var";
|
|
689 }
|
|
690
|
|
691 void TextNodeDumper::VisitWhileStmt(const WhileStmt *Node) {
|
|
692 if (Node->hasVarStorage())
|
|
693 OS << " has_var";
|
|
694 }
|
|
695
|
|
696 void TextNodeDumper::VisitLabelStmt(const LabelStmt *Node) {
|
|
697 OS << " '" << Node->getName() << "'";
|
|
698 }
|
|
699
|
|
700 void TextNodeDumper::VisitGotoStmt(const GotoStmt *Node) {
|
|
701 OS << " '" << Node->getLabel()->getName() << "'";
|
|
702 dumpPointer(Node->getLabel());
|
|
703 }
|
|
704
|
|
705 void TextNodeDumper::VisitCaseStmt(const CaseStmt *Node) {
|
|
706 if (Node->caseStmtIsGNURange())
|
|
707 OS << " gnu_range";
|
|
708 }
|
|
709
|
|
710 void TextNodeDumper::VisitConstantExpr(const ConstantExpr *Node) {
|
|
711 if (Node->getResultAPValueKind() != APValue::None) {
|
|
712 ColorScope Color(OS, ShowColors, ValueColor);
|
|
713 OS << " ";
|
|
714 Node->getAPValueResult().dump(OS);
|
|
715 }
|
|
716 }
|
|
717
|
|
718 void TextNodeDumper::VisitCallExpr(const CallExpr *Node) {
|
|
719 if (Node->usesADL())
|
|
720 OS << " adl";
|
|
721 }
|
|
722
|
|
723 void TextNodeDumper::VisitCastExpr(const CastExpr *Node) {
|
|
724 OS << " <";
|
|
725 {
|
|
726 ColorScope Color(OS, ShowColors, CastColor);
|
|
727 OS << Node->getCastKindName();
|
|
728 }
|
|
729 dumpBasePath(OS, Node);
|
|
730 OS << ">";
|
|
731 }
|
|
732
|
|
733 void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) {
|
|
734 VisitCastExpr(Node);
|
|
735 if (Node->isPartOfExplicitCast())
|
|
736 OS << " part_of_explicit_cast";
|
|
737 }
|
|
738
|
|
739 void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
|
|
740 OS << " ";
|
|
741 dumpBareDeclRef(Node->getDecl());
|
|
742 if (Node->getDecl() != Node->getFoundDecl()) {
|
|
743 OS << " (";
|
|
744 dumpBareDeclRef(Node->getFoundDecl());
|
|
745 OS << ")";
|
|
746 }
|
|
747 switch (Node->isNonOdrUse()) {
|
|
748 case NOUR_None: break;
|
|
749 case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
|
|
750 case NOUR_Constant: OS << " non_odr_use_constant"; break;
|
|
751 case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
|
|
752 }
|
|
753 }
|
|
754
|
|
755 void TextNodeDumper::VisitUnresolvedLookupExpr(
|
|
756 const UnresolvedLookupExpr *Node) {
|
|
757 OS << " (";
|
|
758 if (!Node->requiresADL())
|
|
759 OS << "no ";
|
|
760 OS << "ADL) = '" << Node->getName() << '\'';
|
|
761
|
|
762 UnresolvedLookupExpr::decls_iterator I = Node->decls_begin(),
|
|
763 E = Node->decls_end();
|
|
764 if (I == E)
|
|
765 OS << " empty";
|
|
766 for (; I != E; ++I)
|
|
767 dumpPointer(*I);
|
|
768 }
|
|
769
|
|
770 void TextNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
|
|
771 {
|
|
772 ColorScope Color(OS, ShowColors, DeclKindNameColor);
|
|
773 OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
|
|
774 }
|
|
775 OS << "='" << *Node->getDecl() << "'";
|
|
776 dumpPointer(Node->getDecl());
|
|
777 if (Node->isFreeIvar())
|
|
778 OS << " isFreeIvar";
|
|
779 }
|
|
780
|
|
781 void TextNodeDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
|
|
782 OS << " " << PredefinedExpr::getIdentKindName(Node->getIdentKind());
|
|
783 }
|
|
784
|
|
785 void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
|
|
786 ColorScope Color(OS, ShowColors, ValueColor);
|
|
787 OS << " " << Node->getValue();
|
|
788 }
|
|
789
|
|
790 void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
|
|
791 bool isSigned = Node->getType()->isSignedIntegerType();
|
|
792 ColorScope Color(OS, ShowColors, ValueColor);
|
|
793 OS << " " << Node->getValue().toString(10, isSigned);
|
|
794 }
|
|
795
|
|
796 void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) {
|
|
797 ColorScope Color(OS, ShowColors, ValueColor);
|
|
798 OS << " " << Node->getValueAsString(/*Radix=*/10);
|
|
799 }
|
|
800
|
|
801 void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
|
|
802 ColorScope Color(OS, ShowColors, ValueColor);
|
|
803 OS << " " << Node->getValueAsApproximateDouble();
|
|
804 }
|
|
805
|
|
806 void TextNodeDumper::VisitStringLiteral(const StringLiteral *Str) {
|
|
807 ColorScope Color(OS, ShowColors, ValueColor);
|
|
808 OS << " ";
|
|
809 Str->outputString(OS);
|
|
810 }
|
|
811
|
|
812 void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
|
|
813 if (auto *Field = ILE->getInitializedFieldInUnion()) {
|
|
814 OS << " field ";
|
|
815 dumpBareDeclRef(Field);
|
|
816 }
|
|
817 }
|
|
818
|
|
819 void TextNodeDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
|
|
820 if (E->isResultDependent())
|
|
821 OS << " result_dependent";
|
|
822 }
|
|
823
|
|
824 void TextNodeDumper::VisitUnaryOperator(const UnaryOperator *Node) {
|
|
825 OS << " " << (Node->isPostfix() ? "postfix" : "prefix") << " '"
|
|
826 << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
|
|
827 if (!Node->canOverflow())
|
|
828 OS << " cannot overflow";
|
|
829 }
|
|
830
|
|
831 void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr(
|
|
832 const UnaryExprOrTypeTraitExpr *Node) {
|
|
833 switch (Node->getKind()) {
|
|
834 case UETT_SizeOf:
|
|
835 OS << " sizeof";
|
|
836 break;
|
|
837 case UETT_AlignOf:
|
|
838 OS << " alignof";
|
|
839 break;
|
|
840 case UETT_VecStep:
|
|
841 OS << " vec_step";
|
|
842 break;
|
|
843 case UETT_OpenMPRequiredSimdAlign:
|
|
844 OS << " __builtin_omp_required_simd_align";
|
|
845 break;
|
|
846 case UETT_PreferredAlignOf:
|
|
847 OS << " __alignof";
|
|
848 break;
|
|
849 }
|
|
850 if (Node->isArgumentType())
|
|
851 dumpType(Node->getArgumentType());
|
|
852 }
|
|
853
|
|
854 void TextNodeDumper::VisitMemberExpr(const MemberExpr *Node) {
|
|
855 OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
|
|
856 dumpPointer(Node->getMemberDecl());
|
|
857 switch (Node->isNonOdrUse()) {
|
|
858 case NOUR_None: break;
|
|
859 case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
|
|
860 case NOUR_Constant: OS << " non_odr_use_constant"; break;
|
|
861 case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
|
|
862 }
|
|
863 }
|
|
864
|
|
865 void TextNodeDumper::VisitExtVectorElementExpr(
|
|
866 const ExtVectorElementExpr *Node) {
|
|
867 OS << " " << Node->getAccessor().getNameStart();
|
|
868 }
|
|
869
|
|
870 void TextNodeDumper::VisitBinaryOperator(const BinaryOperator *Node) {
|
|
871 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
|
|
872 }
|
|
873
|
|
874 void TextNodeDumper::VisitCompoundAssignOperator(
|
|
875 const CompoundAssignOperator *Node) {
|
|
876 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
|
|
877 << "' ComputeLHSTy=";
|
|
878 dumpBareType(Node->getComputationLHSType());
|
|
879 OS << " ComputeResultTy=";
|
|
880 dumpBareType(Node->getComputationResultType());
|
|
881 }
|
|
882
|
|
883 void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
|
|
884 OS << " " << Node->getLabel()->getName();
|
|
885 dumpPointer(Node->getLabel());
|
|
886 }
|
|
887
|
|
888 void TextNodeDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
|
|
889 OS << " " << Node->getCastName() << "<"
|
|
890 << Node->getTypeAsWritten().getAsString() << ">"
|
|
891 << " <" << Node->getCastKindName();
|
|
892 dumpBasePath(OS, Node);
|
|
893 OS << ">";
|
|
894 }
|
|
895
|
|
896 void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
|
|
897 OS << " " << (Node->getValue() ? "true" : "false");
|
|
898 }
|
|
899
|
|
900 void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
|
|
901 if (Node->isImplicit())
|
|
902 OS << " implicit";
|
|
903 OS << " this";
|
|
904 }
|
|
905
|
|
906 void TextNodeDumper::VisitCXXFunctionalCastExpr(
|
|
907 const CXXFunctionalCastExpr *Node) {
|
|
908 OS << " functional cast to " << Node->getTypeAsWritten().getAsString() << " <"
|
|
909 << Node->getCastKindName() << ">";
|
|
910 }
|
|
911
|
|
912 void TextNodeDumper::VisitCXXUnresolvedConstructExpr(
|
|
913 const CXXUnresolvedConstructExpr *Node) {
|
|
914 dumpType(Node->getTypeAsWritten());
|
|
915 if (Node->isListInitialization())
|
|
916 OS << " list";
|
|
917 }
|
|
918
|
|
919 void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
|
|
920 CXXConstructorDecl *Ctor = Node->getConstructor();
|
|
921 dumpType(Ctor->getType());
|
|
922 if (Node->isElidable())
|
|
923 OS << " elidable";
|
|
924 if (Node->isListInitialization())
|
|
925 OS << " list";
|
|
926 if (Node->isStdInitListInitialization())
|
|
927 OS << " std::initializer_list";
|
|
928 if (Node->requiresZeroInitialization())
|
|
929 OS << " zeroing";
|
|
930 }
|
|
931
|
|
932 void TextNodeDumper::VisitCXXBindTemporaryExpr(
|
|
933 const CXXBindTemporaryExpr *Node) {
|
|
934 OS << " (CXXTemporary";
|
|
935 dumpPointer(Node);
|
|
936 OS << ")";
|
|
937 }
|
|
938
|
|
939 void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr *Node) {
|
|
940 if (Node->isGlobalNew())
|
|
941 OS << " global";
|
|
942 if (Node->isArray())
|
|
943 OS << " array";
|
|
944 if (Node->getOperatorNew()) {
|
|
945 OS << ' ';
|
|
946 dumpBareDeclRef(Node->getOperatorNew());
|
|
947 }
|
|
948 // We could dump the deallocation function used in case of error, but it's
|
|
949 // usually not that interesting.
|
|
950 }
|
|
951
|
|
952 void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) {
|
|
953 if (Node->isGlobalDelete())
|
|
954 OS << " global";
|
|
955 if (Node->isArrayForm())
|
|
956 OS << " array";
|
|
957 if (Node->getOperatorDelete()) {
|
|
958 OS << ' ';
|
|
959 dumpBareDeclRef(Node->getOperatorDelete());
|
|
960 }
|
|
961 }
|
|
962
|
|
963 void TextNodeDumper::VisitMaterializeTemporaryExpr(
|
|
964 const MaterializeTemporaryExpr *Node) {
|
|
965 if (const ValueDecl *VD = Node->getExtendingDecl()) {
|
|
966 OS << " extended by ";
|
|
967 dumpBareDeclRef(VD);
|
|
968 }
|
|
969 }
|
|
970
|
|
971 void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
|
|
972 for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
|
173
|
973 dumpCleanupObject(Node->getObject(i));
|
150
|
974 }
|
|
975
|
|
976 void TextNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
|
|
977 dumpPointer(Node->getPack());
|
|
978 dumpName(Node->getPack());
|
|
979 }
|
|
980
|
|
981 void TextNodeDumper::VisitCXXDependentScopeMemberExpr(
|
|
982 const CXXDependentScopeMemberExpr *Node) {
|
|
983 OS << " " << (Node->isArrow() ? "->" : ".") << Node->getMember();
|
|
984 }
|
|
985
|
|
986 void TextNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
|
|
987 OS << " selector=";
|
|
988 Node->getSelector().print(OS);
|
|
989 switch (Node->getReceiverKind()) {
|
|
990 case ObjCMessageExpr::Instance:
|
|
991 break;
|
|
992
|
|
993 case ObjCMessageExpr::Class:
|
|
994 OS << " class=";
|
|
995 dumpBareType(Node->getClassReceiver());
|
|
996 break;
|
|
997
|
|
998 case ObjCMessageExpr::SuperInstance:
|
|
999 OS << " super (instance)";
|
|
1000 break;
|
|
1001
|
|
1002 case ObjCMessageExpr::SuperClass:
|
|
1003 OS << " super (class)";
|
|
1004 break;
|
|
1005 }
|
|
1006 }
|
|
1007
|
|
1008 void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
|
|
1009 if (auto *BoxingMethod = Node->getBoxingMethod()) {
|
|
1010 OS << " selector=";
|
|
1011 BoxingMethod->getSelector().print(OS);
|
|
1012 }
|
|
1013 }
|
|
1014
|
|
1015 void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
|
|
1016 if (!Node->getCatchParamDecl())
|
|
1017 OS << " catch all";
|
|
1018 }
|
|
1019
|
|
1020 void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
|
|
1021 dumpType(Node->getEncodedType());
|
|
1022 }
|
|
1023
|
|
1024 void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
|
|
1025 OS << " ";
|
|
1026 Node->getSelector().print(OS);
|
|
1027 }
|
|
1028
|
|
1029 void TextNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
|
|
1030 OS << ' ' << *Node->getProtocol();
|
|
1031 }
|
|
1032
|
|
1033 void TextNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
|
|
1034 if (Node->isImplicitProperty()) {
|
|
1035 OS << " Kind=MethodRef Getter=\"";
|
|
1036 if (Node->getImplicitPropertyGetter())
|
|
1037 Node->getImplicitPropertyGetter()->getSelector().print(OS);
|
|
1038 else
|
|
1039 OS << "(null)";
|
|
1040
|
|
1041 OS << "\" Setter=\"";
|
|
1042 if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
|
|
1043 Setter->getSelector().print(OS);
|
|
1044 else
|
|
1045 OS << "(null)";
|
|
1046 OS << "\"";
|
|
1047 } else {
|
|
1048 OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty()
|
|
1049 << '"';
|
|
1050 }
|
|
1051
|
|
1052 if (Node->isSuperReceiver())
|
|
1053 OS << " super";
|
|
1054
|
|
1055 OS << " Messaging=";
|
|
1056 if (Node->isMessagingGetter() && Node->isMessagingSetter())
|
|
1057 OS << "Getter&Setter";
|
|
1058 else if (Node->isMessagingGetter())
|
|
1059 OS << "Getter";
|
|
1060 else if (Node->isMessagingSetter())
|
|
1061 OS << "Setter";
|
|
1062 }
|
|
1063
|
|
1064 void TextNodeDumper::VisitObjCSubscriptRefExpr(
|
|
1065 const ObjCSubscriptRefExpr *Node) {
|
|
1066 if (Node->isArraySubscriptRefExpr())
|
|
1067 OS << " Kind=ArraySubscript GetterForArray=\"";
|
|
1068 else
|
|
1069 OS << " Kind=DictionarySubscript GetterForDictionary=\"";
|
|
1070 if (Node->getAtIndexMethodDecl())
|
|
1071 Node->getAtIndexMethodDecl()->getSelector().print(OS);
|
|
1072 else
|
|
1073 OS << "(null)";
|
|
1074
|
|
1075 if (Node->isArraySubscriptRefExpr())
|
|
1076 OS << "\" SetterForArray=\"";
|
|
1077 else
|
|
1078 OS << "\" SetterForDictionary=\"";
|
|
1079 if (Node->setAtIndexMethodDecl())
|
|
1080 Node->setAtIndexMethodDecl()->getSelector().print(OS);
|
|
1081 else
|
|
1082 OS << "(null)";
|
|
1083 }
|
|
1084
|
|
1085 void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
|
|
1086 OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
|
|
1087 }
|
|
1088
|
173
|
1089 void TextNodeDumper::VisitOMPIteratorExpr(const OMPIteratorExpr *Node) {
|
|
1090 OS << " ";
|
|
1091 for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
|
|
1092 Visit(Node->getIteratorDecl(I));
|
|
1093 OS << " = ";
|
|
1094 const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
|
|
1095 OS << " begin ";
|
|
1096 Visit(Range.Begin);
|
|
1097 OS << " end ";
|
|
1098 Visit(Range.End);
|
|
1099 if (Range.Step) {
|
|
1100 OS << " step ";
|
|
1101 Visit(Range.Step);
|
|
1102 }
|
|
1103 }
|
|
1104 }
|
|
1105
|
150
|
1106 void TextNodeDumper::VisitRValueReferenceType(const ReferenceType *T) {
|
|
1107 if (T->isSpelledAsLValue())
|
|
1108 OS << " written as lvalue reference";
|
|
1109 }
|
|
1110
|
|
1111 void TextNodeDumper::VisitArrayType(const ArrayType *T) {
|
|
1112 switch (T->getSizeModifier()) {
|
|
1113 case ArrayType::Normal:
|
|
1114 break;
|
|
1115 case ArrayType::Static:
|
|
1116 OS << " static";
|
|
1117 break;
|
|
1118 case ArrayType::Star:
|
|
1119 OS << " *";
|
|
1120 break;
|
|
1121 }
|
|
1122 OS << " " << T->getIndexTypeQualifiers().getAsString();
|
|
1123 }
|
|
1124
|
|
1125 void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType *T) {
|
|
1126 OS << " " << T->getSize();
|
|
1127 VisitArrayType(T);
|
|
1128 }
|
|
1129
|
|
1130 void TextNodeDumper::VisitVariableArrayType(const VariableArrayType *T) {
|
|
1131 OS << " ";
|
|
1132 dumpSourceRange(T->getBracketsRange());
|
|
1133 VisitArrayType(T);
|
|
1134 }
|
|
1135
|
|
1136 void TextNodeDumper::VisitDependentSizedArrayType(
|
|
1137 const DependentSizedArrayType *T) {
|
|
1138 VisitArrayType(T);
|
|
1139 OS << " ";
|
|
1140 dumpSourceRange(T->getBracketsRange());
|
|
1141 }
|
|
1142
|
|
1143 void TextNodeDumper::VisitDependentSizedExtVectorType(
|
|
1144 const DependentSizedExtVectorType *T) {
|
|
1145 OS << " ";
|
|
1146 dumpLocation(T->getAttributeLoc());
|
|
1147 }
|
|
1148
|
|
1149 void TextNodeDumper::VisitVectorType(const VectorType *T) {
|
|
1150 switch (T->getVectorKind()) {
|
|
1151 case VectorType::GenericVector:
|
|
1152 break;
|
|
1153 case VectorType::AltiVecVector:
|
|
1154 OS << " altivec";
|
|
1155 break;
|
|
1156 case VectorType::AltiVecPixel:
|
|
1157 OS << " altivec pixel";
|
|
1158 break;
|
|
1159 case VectorType::AltiVecBool:
|
|
1160 OS << " altivec bool";
|
|
1161 break;
|
|
1162 case VectorType::NeonVector:
|
|
1163 OS << " neon";
|
|
1164 break;
|
|
1165 case VectorType::NeonPolyVector:
|
|
1166 OS << " neon poly";
|
|
1167 break;
|
|
1168 }
|
|
1169 OS << " " << T->getNumElements();
|
|
1170 }
|
|
1171
|
|
1172 void TextNodeDumper::VisitFunctionType(const FunctionType *T) {
|
|
1173 auto EI = T->getExtInfo();
|
|
1174 if (EI.getNoReturn())
|
|
1175 OS << " noreturn";
|
|
1176 if (EI.getProducesResult())
|
|
1177 OS << " produces_result";
|
|
1178 if (EI.getHasRegParm())
|
|
1179 OS << " regparm " << EI.getRegParm();
|
|
1180 OS << " " << FunctionType::getNameForCallConv(EI.getCC());
|
|
1181 }
|
|
1182
|
|
1183 void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {
|
|
1184 auto EPI = T->getExtProtoInfo();
|
|
1185 if (EPI.HasTrailingReturn)
|
|
1186 OS << " trailing_return";
|
|
1187 if (T->isConst())
|
|
1188 OS << " const";
|
|
1189 if (T->isVolatile())
|
|
1190 OS << " volatile";
|
|
1191 if (T->isRestrict())
|
|
1192 OS << " restrict";
|
|
1193 if (T->getExtProtoInfo().Variadic)
|
|
1194 OS << " variadic";
|
|
1195 switch (EPI.RefQualifier) {
|
|
1196 case RQ_None:
|
|
1197 break;
|
|
1198 case RQ_LValue:
|
|
1199 OS << " &";
|
|
1200 break;
|
|
1201 case RQ_RValue:
|
|
1202 OS << " &&";
|
|
1203 break;
|
|
1204 }
|
|
1205 // FIXME: Exception specification.
|
|
1206 // FIXME: Consumed parameters.
|
|
1207 VisitFunctionType(T);
|
|
1208 }
|
|
1209
|
|
1210 void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
|
|
1211 dumpDeclRef(T->getDecl());
|
|
1212 }
|
|
1213
|
|
1214 void TextNodeDumper::VisitTypedefType(const TypedefType *T) {
|
|
1215 dumpDeclRef(T->getDecl());
|
|
1216 }
|
|
1217
|
|
1218 void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) {
|
|
1219 switch (T->getUTTKind()) {
|
|
1220 case UnaryTransformType::EnumUnderlyingType:
|
|
1221 OS << " underlying_type";
|
|
1222 break;
|
|
1223 }
|
|
1224 }
|
|
1225
|
|
1226 void TextNodeDumper::VisitTagType(const TagType *T) {
|
|
1227 dumpDeclRef(T->getDecl());
|
|
1228 }
|
|
1229
|
|
1230 void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
|
|
1231 OS << " depth " << T->getDepth() << " index " << T->getIndex();
|
|
1232 if (T->isParameterPack())
|
|
1233 OS << " pack";
|
|
1234 dumpDeclRef(T->getDecl());
|
|
1235 }
|
|
1236
|
|
1237 void TextNodeDumper::VisitAutoType(const AutoType *T) {
|
|
1238 if (T->isDecltypeAuto())
|
|
1239 OS << " decltype(auto)";
|
|
1240 if (!T->isDeduced())
|
|
1241 OS << " undeduced";
|
|
1242 if (T->isConstrained()) {
|
|
1243 dumpDeclRef(T->getTypeConstraintConcept());
|
|
1244 for (const auto &Arg : T->getTypeConstraintArguments())
|
|
1245 VisitTemplateArgument(Arg);
|
|
1246 }
|
|
1247 }
|
|
1248
|
|
1249 void TextNodeDumper::VisitTemplateSpecializationType(
|
|
1250 const TemplateSpecializationType *T) {
|
|
1251 if (T->isTypeAlias())
|
|
1252 OS << " alias";
|
|
1253 OS << " ";
|
|
1254 T->getTemplateName().dump(OS);
|
|
1255 }
|
|
1256
|
|
1257 void TextNodeDumper::VisitInjectedClassNameType(
|
|
1258 const InjectedClassNameType *T) {
|
|
1259 dumpDeclRef(T->getDecl());
|
|
1260 }
|
|
1261
|
|
1262 void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
|
|
1263 dumpDeclRef(T->getDecl());
|
|
1264 }
|
|
1265
|
|
1266 void TextNodeDumper::VisitPackExpansionType(const PackExpansionType *T) {
|
|
1267 if (auto N = T->getNumExpansions())
|
|
1268 OS << " expansions " << *N;
|
|
1269 }
|
|
1270
|
|
1271 void TextNodeDumper::VisitLabelDecl(const LabelDecl *D) { dumpName(D); }
|
|
1272
|
|
1273 void TextNodeDumper::VisitTypedefDecl(const TypedefDecl *D) {
|
|
1274 dumpName(D);
|
|
1275 dumpType(D->getUnderlyingType());
|
|
1276 if (D->isModulePrivate())
|
|
1277 OS << " __module_private__";
|
|
1278 }
|
|
1279
|
|
1280 void TextNodeDumper::VisitEnumDecl(const EnumDecl *D) {
|
|
1281 if (D->isScoped()) {
|
|
1282 if (D->isScopedUsingClassTag())
|
|
1283 OS << " class";
|
|
1284 else
|
|
1285 OS << " struct";
|
|
1286 }
|
|
1287 dumpName(D);
|
|
1288 if (D->isModulePrivate())
|
|
1289 OS << " __module_private__";
|
|
1290 if (D->isFixed())
|
|
1291 dumpType(D->getIntegerType());
|
|
1292 }
|
|
1293
|
|
1294 void TextNodeDumper::VisitRecordDecl(const RecordDecl *D) {
|
|
1295 OS << ' ' << D->getKindName();
|
|
1296 dumpName(D);
|
|
1297 if (D->isModulePrivate())
|
|
1298 OS << " __module_private__";
|
|
1299 if (D->isCompleteDefinition())
|
|
1300 OS << " definition";
|
|
1301 }
|
|
1302
|
|
1303 void TextNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
|
|
1304 dumpName(D);
|
|
1305 dumpType(D->getType());
|
|
1306 }
|
|
1307
|
|
1308 void TextNodeDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
|
|
1309 dumpName(D);
|
|
1310 dumpType(D->getType());
|
|
1311
|
|
1312 for (const auto *Child : D->chain())
|
|
1313 dumpDeclRef(Child);
|
|
1314 }
|
|
1315
|
|
1316 void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) {
|
|
1317 dumpName(D);
|
|
1318 dumpType(D->getType());
|
|
1319
|
|
1320 StorageClass SC = D->getStorageClass();
|
|
1321 if (SC != SC_None)
|
|
1322 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
|
|
1323 if (D->isInlineSpecified())
|
|
1324 OS << " inline";
|
|
1325 if (D->isVirtualAsWritten())
|
|
1326 OS << " virtual";
|
|
1327 if (D->isModulePrivate())
|
|
1328 OS << " __module_private__";
|
|
1329
|
|
1330 if (D->isPure())
|
|
1331 OS << " pure";
|
|
1332 if (D->isDefaulted()) {
|
|
1333 OS << " default";
|
|
1334 if (D->isDeleted())
|
|
1335 OS << "_delete";
|
|
1336 }
|
|
1337 if (D->isDeletedAsWritten())
|
|
1338 OS << " delete";
|
|
1339 if (D->isTrivial())
|
|
1340 OS << " trivial";
|
|
1341
|
|
1342 if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) {
|
|
1343 FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
|
|
1344 switch (EPI.ExceptionSpec.Type) {
|
|
1345 default:
|
|
1346 break;
|
|
1347 case EST_Unevaluated:
|
|
1348 OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
|
|
1349 break;
|
|
1350 case EST_Uninstantiated:
|
|
1351 OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
|
|
1352 break;
|
|
1353 }
|
|
1354 }
|
|
1355
|
|
1356 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
|
|
1357 if (MD->size_overridden_methods() != 0) {
|
|
1358 auto dumpOverride = [=](const CXXMethodDecl *D) {
|
|
1359 SplitQualType T_split = D->getType().split();
|
|
1360 OS << D << " " << D->getParent()->getName()
|
|
1361 << "::" << D->getNameAsString() << " '"
|
|
1362 << QualType::getAsString(T_split, PrintPolicy) << "'";
|
|
1363 };
|
|
1364
|
|
1365 AddChild([=] {
|
|
1366 auto Overrides = MD->overridden_methods();
|
|
1367 OS << "Overrides: [ ";
|
|
1368 dumpOverride(*Overrides.begin());
|
|
1369 for (const auto *Override :
|
|
1370 llvm::make_range(Overrides.begin() + 1, Overrides.end())) {
|
|
1371 OS << ", ";
|
|
1372 dumpOverride(Override);
|
|
1373 }
|
|
1374 OS << " ]";
|
|
1375 });
|
|
1376 }
|
|
1377 }
|
|
1378
|
|
1379 // Since NumParams comes from the FunctionProtoType of the FunctionDecl and
|
|
1380 // the Params are set later, it is possible for a dump during debugging to
|
|
1381 // encounter a FunctionDecl that has been created but hasn't been assigned
|
|
1382 // ParmVarDecls yet.
|
|
1383 if (!D->param_empty() && !D->param_begin())
|
|
1384 OS << " <<<NULL params x " << D->getNumParams() << ">>>";
|
|
1385 }
|
|
1386
|
|
1387 void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl(
|
|
1388 const LifetimeExtendedTemporaryDecl *D) {
|
|
1389 OS << " extended by ";
|
|
1390 dumpBareDeclRef(D->getExtendingDecl());
|
|
1391 OS << " mangling ";
|
|
1392 {
|
|
1393 ColorScope Color(OS, ShowColors, ValueColor);
|
|
1394 OS << D->getManglingNumber();
|
|
1395 }
|
|
1396 }
|
|
1397
|
|
1398 void TextNodeDumper::VisitFieldDecl(const FieldDecl *D) {
|
|
1399 dumpName(D);
|
|
1400 dumpType(D->getType());
|
|
1401 if (D->isMutable())
|
|
1402 OS << " mutable";
|
|
1403 if (D->isModulePrivate())
|
|
1404 OS << " __module_private__";
|
|
1405 }
|
|
1406
|
|
1407 void TextNodeDumper::VisitVarDecl(const VarDecl *D) {
|
|
1408 dumpName(D);
|
|
1409 dumpType(D->getType());
|
|
1410 StorageClass SC = D->getStorageClass();
|
|
1411 if (SC != SC_None)
|
|
1412 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
|
|
1413 switch (D->getTLSKind()) {
|
|
1414 case VarDecl::TLS_None:
|
|
1415 break;
|
|
1416 case VarDecl::TLS_Static:
|
|
1417 OS << " tls";
|
|
1418 break;
|
|
1419 case VarDecl::TLS_Dynamic:
|
|
1420 OS << " tls_dynamic";
|
|
1421 break;
|
|
1422 }
|
|
1423 if (D->isModulePrivate())
|
|
1424 OS << " __module_private__";
|
|
1425 if (D->isNRVOVariable())
|
|
1426 OS << " nrvo";
|
|
1427 if (D->isInline())
|
|
1428 OS << " inline";
|
|
1429 if (D->isConstexpr())
|
|
1430 OS << " constexpr";
|
|
1431 if (D->hasInit()) {
|
|
1432 switch (D->getInitStyle()) {
|
|
1433 case VarDecl::CInit:
|
|
1434 OS << " cinit";
|
|
1435 break;
|
|
1436 case VarDecl::CallInit:
|
|
1437 OS << " callinit";
|
|
1438 break;
|
|
1439 case VarDecl::ListInit:
|
|
1440 OS << " listinit";
|
|
1441 break;
|
|
1442 }
|
|
1443 }
|
|
1444 if (D->needsDestruction(D->getASTContext()))
|
|
1445 OS << " destroyed";
|
|
1446 if (D->isParameterPack())
|
|
1447 OS << " pack";
|
|
1448 }
|
|
1449
|
|
1450 void TextNodeDumper::VisitBindingDecl(const BindingDecl *D) {
|
|
1451 dumpName(D);
|
|
1452 dumpType(D->getType());
|
|
1453 }
|
|
1454
|
|
1455 void TextNodeDumper::VisitCapturedDecl(const CapturedDecl *D) {
|
|
1456 if (D->isNothrow())
|
|
1457 OS << " nothrow";
|
|
1458 }
|
|
1459
|
|
1460 void TextNodeDumper::VisitImportDecl(const ImportDecl *D) {
|
|
1461 OS << ' ' << D->getImportedModule()->getFullModuleName();
|
|
1462
|
|
1463 for (Decl *InitD :
|
|
1464 D->getASTContext().getModuleInitializers(D->getImportedModule()))
|
|
1465 dumpDeclRef(InitD, "initializer");
|
|
1466 }
|
|
1467
|
|
1468 void TextNodeDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) {
|
|
1469 OS << ' ';
|
|
1470 switch (D->getCommentKind()) {
|
|
1471 case PCK_Unknown:
|
|
1472 llvm_unreachable("unexpected pragma comment kind");
|
|
1473 case PCK_Compiler:
|
|
1474 OS << "compiler";
|
|
1475 break;
|
|
1476 case PCK_ExeStr:
|
|
1477 OS << "exestr";
|
|
1478 break;
|
|
1479 case PCK_Lib:
|
|
1480 OS << "lib";
|
|
1481 break;
|
|
1482 case PCK_Linker:
|
|
1483 OS << "linker";
|
|
1484 break;
|
|
1485 case PCK_User:
|
|
1486 OS << "user";
|
|
1487 break;
|
|
1488 }
|
|
1489 StringRef Arg = D->getArg();
|
|
1490 if (!Arg.empty())
|
|
1491 OS << " \"" << Arg << "\"";
|
|
1492 }
|
|
1493
|
|
1494 void TextNodeDumper::VisitPragmaDetectMismatchDecl(
|
|
1495 const PragmaDetectMismatchDecl *D) {
|
|
1496 OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\"";
|
|
1497 }
|
|
1498
|
|
1499 void TextNodeDumper::VisitOMPExecutableDirective(
|
|
1500 const OMPExecutableDirective *D) {
|
|
1501 if (D->isStandaloneDirective())
|
|
1502 OS << " openmp_standalone_directive";
|
|
1503 }
|
|
1504
|
|
1505 void TextNodeDumper::VisitOMPDeclareReductionDecl(
|
|
1506 const OMPDeclareReductionDecl *D) {
|
|
1507 dumpName(D);
|
|
1508 dumpType(D->getType());
|
|
1509 OS << " combiner";
|
|
1510 dumpPointer(D->getCombiner());
|
|
1511 if (const auto *Initializer = D->getInitializer()) {
|
|
1512 OS << " initializer";
|
|
1513 dumpPointer(Initializer);
|
|
1514 switch (D->getInitializerKind()) {
|
|
1515 case OMPDeclareReductionDecl::DirectInit:
|
|
1516 OS << " omp_priv = ";
|
|
1517 break;
|
|
1518 case OMPDeclareReductionDecl::CopyInit:
|
|
1519 OS << " omp_priv ()";
|
|
1520 break;
|
|
1521 case OMPDeclareReductionDecl::CallInit:
|
|
1522 break;
|
|
1523 }
|
|
1524 }
|
|
1525 }
|
|
1526
|
|
1527 void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
|
|
1528 for (const auto *C : D->clauselists()) {
|
|
1529 AddChild([=] {
|
|
1530 if (!C) {
|
|
1531 ColorScope Color(OS, ShowColors, NullColor);
|
|
1532 OS << "<<<NULL>>> OMPClause";
|
|
1533 return;
|
|
1534 }
|
|
1535 {
|
|
1536 ColorScope Color(OS, ShowColors, AttrColor);
|
173
|
1537 StringRef ClauseName(
|
|
1538 llvm::omp::getOpenMPClauseName(C->getClauseKind()));
|
150
|
1539 OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
|
|
1540 << ClauseName.drop_front() << "Clause";
|
|
1541 }
|
|
1542 dumpPointer(C);
|
|
1543 dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
|
|
1544 });
|
|
1545 }
|
|
1546 }
|
|
1547
|
|
1548 void TextNodeDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
|
|
1549 dumpName(D);
|
|
1550 dumpType(D->getType());
|
|
1551 }
|
|
1552
|
|
1553 void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
|
|
1554 dumpName(D);
|
|
1555 if (D->isInline())
|
|
1556 OS << " inline";
|
|
1557 if (!D->isOriginalNamespace())
|
|
1558 dumpDeclRef(D->getOriginalNamespace(), "original");
|
|
1559 }
|
|
1560
|
|
1561 void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
|
|
1562 OS << ' ';
|
|
1563 dumpBareDeclRef(D->getNominatedNamespace());
|
|
1564 }
|
|
1565
|
|
1566 void TextNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
|
|
1567 dumpName(D);
|
|
1568 dumpDeclRef(D->getAliasedNamespace());
|
|
1569 }
|
|
1570
|
|
1571 void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
|
|
1572 dumpName(D);
|
|
1573 dumpType(D->getUnderlyingType());
|
|
1574 }
|
|
1575
|
|
1576 void TextNodeDumper::VisitTypeAliasTemplateDecl(
|
|
1577 const TypeAliasTemplateDecl *D) {
|
|
1578 dumpName(D);
|
|
1579 }
|
|
1580
|
|
1581 void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
|
|
1582 VisitRecordDecl(D);
|
|
1583 if (!D->isCompleteDefinition())
|
|
1584 return;
|
|
1585
|
|
1586 AddChild([=] {
|
|
1587 {
|
|
1588 ColorScope Color(OS, ShowColors, DeclKindNameColor);
|
|
1589 OS << "DefinitionData";
|
|
1590 }
|
|
1591 #define FLAG(fn, name) \
|
|
1592 if (D->fn()) \
|
|
1593 OS << " " #name;
|
|
1594 FLAG(isParsingBaseSpecifiers, parsing_base_specifiers);
|
|
1595
|
|
1596 FLAG(isGenericLambda, generic);
|
|
1597 FLAG(isLambda, lambda);
|
|
1598
|
|
1599 FLAG(isAnonymousStructOrUnion, is_anonymous);
|
|
1600 FLAG(canPassInRegisters, pass_in_registers);
|
|
1601 FLAG(isEmpty, empty);
|
|
1602 FLAG(isAggregate, aggregate);
|
|
1603 FLAG(isStandardLayout, standard_layout);
|
|
1604 FLAG(isTriviallyCopyable, trivially_copyable);
|
|
1605 FLAG(isPOD, pod);
|
|
1606 FLAG(isTrivial, trivial);
|
|
1607 FLAG(isPolymorphic, polymorphic);
|
|
1608 FLAG(isAbstract, abstract);
|
|
1609 FLAG(isLiteral, literal);
|
|
1610
|
|
1611 FLAG(hasUserDeclaredConstructor, has_user_declared_ctor);
|
|
1612 FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor);
|
|
1613 FLAG(hasMutableFields, has_mutable_fields);
|
|
1614 FLAG(hasVariantMembers, has_variant_members);
|
|
1615 FLAG(allowConstDefaultInit, can_const_default_init);
|
|
1616
|
|
1617 AddChild([=] {
|
|
1618 {
|
|
1619 ColorScope Color(OS, ShowColors, DeclKindNameColor);
|
|
1620 OS << "DefaultConstructor";
|
|
1621 }
|
|
1622 FLAG(hasDefaultConstructor, exists);
|
|
1623 FLAG(hasTrivialDefaultConstructor, trivial);
|
|
1624 FLAG(hasNonTrivialDefaultConstructor, non_trivial);
|
|
1625 FLAG(hasUserProvidedDefaultConstructor, user_provided);
|
|
1626 FLAG(hasConstexprDefaultConstructor, constexpr);
|
|
1627 FLAG(needsImplicitDefaultConstructor, needs_implicit);
|
|
1628 FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr);
|
|
1629 });
|
|
1630
|
|
1631 AddChild([=] {
|
|
1632 {
|
|
1633 ColorScope Color(OS, ShowColors, DeclKindNameColor);
|
|
1634 OS << "CopyConstructor";
|
|
1635 }
|
|
1636 FLAG(hasSimpleCopyConstructor, simple);
|
|
1637 FLAG(hasTrivialCopyConstructor, trivial);
|
|
1638 FLAG(hasNonTrivialCopyConstructor, non_trivial);
|
|
1639 FLAG(hasUserDeclaredCopyConstructor, user_declared);
|
|
1640 FLAG(hasCopyConstructorWithConstParam, has_const_param);
|
|
1641 FLAG(needsImplicitCopyConstructor, needs_implicit);
|
|
1642 FLAG(needsOverloadResolutionForCopyConstructor,
|
|
1643 needs_overload_resolution);
|
|
1644 if (!D->needsOverloadResolutionForCopyConstructor())
|
|
1645 FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted);
|
|
1646 FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param);
|
|
1647 });
|
|
1648
|
|
1649 AddChild([=] {
|
|
1650 {
|
|
1651 ColorScope Color(OS, ShowColors, DeclKindNameColor);
|
|
1652 OS << "MoveConstructor";
|
|
1653 }
|
|
1654 FLAG(hasMoveConstructor, exists);
|
|
1655 FLAG(hasSimpleMoveConstructor, simple);
|
|
1656 FLAG(hasTrivialMoveConstructor, trivial);
|
|
1657 FLAG(hasNonTrivialMoveConstructor, non_trivial);
|
|
1658 FLAG(hasUserDeclaredMoveConstructor, user_declared);
|
|
1659 FLAG(needsImplicitMoveConstructor, needs_implicit);
|
|
1660 FLAG(needsOverloadResolutionForMoveConstructor,
|
|
1661 needs_overload_resolution);
|
|
1662 if (!D->needsOverloadResolutionForMoveConstructor())
|
|
1663 FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted);
|
|
1664 });
|
|
1665
|
|
1666 AddChild([=] {
|
|
1667 {
|
|
1668 ColorScope Color(OS, ShowColors, DeclKindNameColor);
|
|
1669 OS << "CopyAssignment";
|
|
1670 }
|
|
1671 FLAG(hasTrivialCopyAssignment, trivial);
|
|
1672 FLAG(hasNonTrivialCopyAssignment, non_trivial);
|
|
1673 FLAG(hasCopyAssignmentWithConstParam, has_const_param);
|
|
1674 FLAG(hasUserDeclaredCopyAssignment, user_declared);
|
|
1675 FLAG(needsImplicitCopyAssignment, needs_implicit);
|
|
1676 FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution);
|
|
1677 FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param);
|
|
1678 });
|
|
1679
|
|
1680 AddChild([=] {
|
|
1681 {
|
|
1682 ColorScope Color(OS, ShowColors, DeclKindNameColor);
|
|
1683 OS << "MoveAssignment";
|
|
1684 }
|
|
1685 FLAG(hasMoveAssignment, exists);
|
|
1686 FLAG(hasSimpleMoveAssignment, simple);
|
|
1687 FLAG(hasTrivialMoveAssignment, trivial);
|
|
1688 FLAG(hasNonTrivialMoveAssignment, non_trivial);
|
|
1689 FLAG(hasUserDeclaredMoveAssignment, user_declared);
|
|
1690 FLAG(needsImplicitMoveAssignment, needs_implicit);
|
|
1691 FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution);
|
|
1692 });
|
|
1693
|
|
1694 AddChild([=] {
|
|
1695 {
|
|
1696 ColorScope Color(OS, ShowColors, DeclKindNameColor);
|
|
1697 OS << "Destructor";
|
|
1698 }
|
|
1699 FLAG(hasSimpleDestructor, simple);
|
|
1700 FLAG(hasIrrelevantDestructor, irrelevant);
|
|
1701 FLAG(hasTrivialDestructor, trivial);
|
|
1702 FLAG(hasNonTrivialDestructor, non_trivial);
|
|
1703 FLAG(hasUserDeclaredDestructor, user_declared);
|
|
1704 FLAG(hasConstexprDestructor, constexpr);
|
|
1705 FLAG(needsImplicitDestructor, needs_implicit);
|
|
1706 FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution);
|
|
1707 if (!D->needsOverloadResolutionForDestructor())
|
|
1708 FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted);
|
|
1709 });
|
|
1710 });
|
|
1711
|
|
1712 for (const auto &I : D->bases()) {
|
|
1713 AddChild([=] {
|
|
1714 if (I.isVirtual())
|
|
1715 OS << "virtual ";
|
|
1716 dumpAccessSpecifier(I.getAccessSpecifier());
|
|
1717 dumpType(I.getType());
|
|
1718 if (I.isPackExpansion())
|
|
1719 OS << "...";
|
|
1720 });
|
|
1721 }
|
|
1722 }
|
|
1723
|
|
1724 void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
|
|
1725 dumpName(D);
|
|
1726 }
|
|
1727
|
|
1728 void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
|
|
1729 dumpName(D);
|
|
1730 }
|
|
1731
|
|
1732 void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
|
|
1733 dumpName(D);
|
|
1734 }
|
|
1735
|
|
1736 void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
|
|
1737 dumpName(D);
|
|
1738 }
|
|
1739
|
|
1740 void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
|
|
1741 if (const auto *TC = D->getTypeConstraint()) {
|
|
1742 OS << " ";
|
|
1743 dumpBareDeclRef(TC->getNamedConcept());
|
|
1744 if (TC->getNamedConcept() != TC->getFoundDecl()) {
|
|
1745 OS << " (";
|
|
1746 dumpBareDeclRef(TC->getFoundDecl());
|
|
1747 OS << ")";
|
|
1748 }
|
|
1749 Visit(TC->getImmediatelyDeclaredConstraint());
|
|
1750 } else if (D->wasDeclaredWithTypename())
|
|
1751 OS << " typename";
|
|
1752 else
|
|
1753 OS << " class";
|
|
1754 OS << " depth " << D->getDepth() << " index " << D->getIndex();
|
|
1755 if (D->isParameterPack())
|
|
1756 OS << " ...";
|
|
1757 dumpName(D);
|
|
1758 }
|
|
1759
|
|
1760 void TextNodeDumper::VisitNonTypeTemplateParmDecl(
|
|
1761 const NonTypeTemplateParmDecl *D) {
|
|
1762 dumpType(D->getType());
|
|
1763 OS << " depth " << D->getDepth() << " index " << D->getIndex();
|
|
1764 if (D->isParameterPack())
|
|
1765 OS << " ...";
|
|
1766 dumpName(D);
|
|
1767 }
|
|
1768
|
|
1769 void TextNodeDumper::VisitTemplateTemplateParmDecl(
|
|
1770 const TemplateTemplateParmDecl *D) {
|
|
1771 OS << " depth " << D->getDepth() << " index " << D->getIndex();
|
|
1772 if (D->isParameterPack())
|
|
1773 OS << " ...";
|
|
1774 dumpName(D);
|
|
1775 }
|
|
1776
|
|
1777 void TextNodeDumper::VisitUsingDecl(const UsingDecl *D) {
|
|
1778 OS << ' ';
|
|
1779 if (D->getQualifier())
|
|
1780 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
|
|
1781 OS << D->getNameAsString();
|
|
1782 }
|
|
1783
|
|
1784 void TextNodeDumper::VisitUnresolvedUsingTypenameDecl(
|
|
1785 const UnresolvedUsingTypenameDecl *D) {
|
|
1786 OS << ' ';
|
|
1787 if (D->getQualifier())
|
|
1788 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
|
|
1789 OS << D->getNameAsString();
|
|
1790 }
|
|
1791
|
|
1792 void TextNodeDumper::VisitUnresolvedUsingValueDecl(
|
|
1793 const UnresolvedUsingValueDecl *D) {
|
|
1794 OS << ' ';
|
|
1795 if (D->getQualifier())
|
|
1796 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
|
|
1797 OS << D->getNameAsString();
|
|
1798 dumpType(D->getType());
|
|
1799 }
|
|
1800
|
|
1801 void TextNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
|
|
1802 OS << ' ';
|
|
1803 dumpBareDeclRef(D->getTargetDecl());
|
|
1804 }
|
|
1805
|
|
1806 void TextNodeDumper::VisitConstructorUsingShadowDecl(
|
|
1807 const ConstructorUsingShadowDecl *D) {
|
|
1808 if (D->constructsVirtualBase())
|
|
1809 OS << " virtual";
|
|
1810
|
|
1811 AddChild([=] {
|
|
1812 OS << "target ";
|
|
1813 dumpBareDeclRef(D->getTargetDecl());
|
|
1814 });
|
|
1815
|
|
1816 AddChild([=] {
|
|
1817 OS << "nominated ";
|
|
1818 dumpBareDeclRef(D->getNominatedBaseClass());
|
|
1819 OS << ' ';
|
|
1820 dumpBareDeclRef(D->getNominatedBaseClassShadowDecl());
|
|
1821 });
|
|
1822
|
|
1823 AddChild([=] {
|
|
1824 OS << "constructed ";
|
|
1825 dumpBareDeclRef(D->getConstructedBaseClass());
|
|
1826 OS << ' ';
|
|
1827 dumpBareDeclRef(D->getConstructedBaseClassShadowDecl());
|
|
1828 });
|
|
1829 }
|
|
1830
|
|
1831 void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
|
|
1832 switch (D->getLanguage()) {
|
|
1833 case LinkageSpecDecl::lang_c:
|
|
1834 OS << " C";
|
|
1835 break;
|
|
1836 case LinkageSpecDecl::lang_cxx:
|
|
1837 OS << " C++";
|
|
1838 break;
|
|
1839 }
|
|
1840 }
|
|
1841
|
|
1842 void TextNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
|
|
1843 OS << ' ';
|
|
1844 dumpAccessSpecifier(D->getAccess());
|
|
1845 }
|
|
1846
|
|
1847 void TextNodeDumper::VisitFriendDecl(const FriendDecl *D) {
|
|
1848 if (TypeSourceInfo *T = D->getFriendType())
|
|
1849 dumpType(T->getType());
|
|
1850 }
|
|
1851
|
|
1852 void TextNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
|
|
1853 dumpName(D);
|
|
1854 dumpType(D->getType());
|
|
1855 if (D->getSynthesize())
|
|
1856 OS << " synthesize";
|
|
1857
|
|
1858 switch (D->getAccessControl()) {
|
|
1859 case ObjCIvarDecl::None:
|
|
1860 OS << " none";
|
|
1861 break;
|
|
1862 case ObjCIvarDecl::Private:
|
|
1863 OS << " private";
|
|
1864 break;
|
|
1865 case ObjCIvarDecl::Protected:
|
|
1866 OS << " protected";
|
|
1867 break;
|
|
1868 case ObjCIvarDecl::Public:
|
|
1869 OS << " public";
|
|
1870 break;
|
|
1871 case ObjCIvarDecl::Package:
|
|
1872 OS << " package";
|
|
1873 break;
|
|
1874 }
|
|
1875 }
|
|
1876
|
|
1877 void TextNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
|
|
1878 if (D->isInstanceMethod())
|
|
1879 OS << " -";
|
|
1880 else
|
|
1881 OS << " +";
|
|
1882 dumpName(D);
|
|
1883 dumpType(D->getReturnType());
|
|
1884
|
|
1885 if (D->isVariadic())
|
|
1886 OS << " variadic";
|
|
1887 }
|
|
1888
|
|
1889 void TextNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
|
|
1890 dumpName(D);
|
|
1891 switch (D->getVariance()) {
|
|
1892 case ObjCTypeParamVariance::Invariant:
|
|
1893 break;
|
|
1894
|
|
1895 case ObjCTypeParamVariance::Covariant:
|
|
1896 OS << " covariant";
|
|
1897 break;
|
|
1898
|
|
1899 case ObjCTypeParamVariance::Contravariant:
|
|
1900 OS << " contravariant";
|
|
1901 break;
|
|
1902 }
|
|
1903
|
|
1904 if (D->hasExplicitBound())
|
|
1905 OS << " bounded";
|
|
1906 dumpType(D->getUnderlyingType());
|
|
1907 }
|
|
1908
|
|
1909 void TextNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
|
|
1910 dumpName(D);
|
|
1911 dumpDeclRef(D->getClassInterface());
|
|
1912 dumpDeclRef(D->getImplementation());
|
|
1913 for (const auto *P : D->protocols())
|
|
1914 dumpDeclRef(P);
|
|
1915 }
|
|
1916
|
|
1917 void TextNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
|
|
1918 dumpName(D);
|
|
1919 dumpDeclRef(D->getClassInterface());
|
|
1920 dumpDeclRef(D->getCategoryDecl());
|
|
1921 }
|
|
1922
|
|
1923 void TextNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
|
|
1924 dumpName(D);
|
|
1925
|
|
1926 for (const auto *Child : D->protocols())
|
|
1927 dumpDeclRef(Child);
|
|
1928 }
|
|
1929
|
|
1930 void TextNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
|
|
1931 dumpName(D);
|
|
1932 dumpDeclRef(D->getSuperClass(), "super");
|
|
1933
|
|
1934 dumpDeclRef(D->getImplementation());
|
|
1935 for (const auto *Child : D->protocols())
|
|
1936 dumpDeclRef(Child);
|
|
1937 }
|
|
1938
|
|
1939 void TextNodeDumper::VisitObjCImplementationDecl(
|
|
1940 const ObjCImplementationDecl *D) {
|
|
1941 dumpName(D);
|
|
1942 dumpDeclRef(D->getSuperClass(), "super");
|
|
1943 dumpDeclRef(D->getClassInterface());
|
|
1944 }
|
|
1945
|
|
1946 void TextNodeDumper::VisitObjCCompatibleAliasDecl(
|
|
1947 const ObjCCompatibleAliasDecl *D) {
|
|
1948 dumpName(D);
|
|
1949 dumpDeclRef(D->getClassInterface());
|
|
1950 }
|
|
1951
|
|
1952 void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
|
|
1953 dumpName(D);
|
|
1954 dumpType(D->getType());
|
|
1955
|
|
1956 if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
|
|
1957 OS << " required";
|
|
1958 else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
|
|
1959 OS << " optional";
|
|
1960
|
173
|
1961 ObjCPropertyAttribute::Kind Attrs = D->getPropertyAttributes();
|
|
1962 if (Attrs != ObjCPropertyAttribute::kind_noattr) {
|
|
1963 if (Attrs & ObjCPropertyAttribute::kind_readonly)
|
150
|
1964 OS << " readonly";
|
173
|
1965 if (Attrs & ObjCPropertyAttribute::kind_assign)
|
150
|
1966 OS << " assign";
|
173
|
1967 if (Attrs & ObjCPropertyAttribute::kind_readwrite)
|
150
|
1968 OS << " readwrite";
|
173
|
1969 if (Attrs & ObjCPropertyAttribute::kind_retain)
|
150
|
1970 OS << " retain";
|
173
|
1971 if (Attrs & ObjCPropertyAttribute::kind_copy)
|
150
|
1972 OS << " copy";
|
173
|
1973 if (Attrs & ObjCPropertyAttribute::kind_nonatomic)
|
150
|
1974 OS << " nonatomic";
|
173
|
1975 if (Attrs & ObjCPropertyAttribute::kind_atomic)
|
150
|
1976 OS << " atomic";
|
173
|
1977 if (Attrs & ObjCPropertyAttribute::kind_weak)
|
150
|
1978 OS << " weak";
|
173
|
1979 if (Attrs & ObjCPropertyAttribute::kind_strong)
|
150
|
1980 OS << " strong";
|
173
|
1981 if (Attrs & ObjCPropertyAttribute::kind_unsafe_unretained)
|
150
|
1982 OS << " unsafe_unretained";
|
173
|
1983 if (Attrs & ObjCPropertyAttribute::kind_class)
|
150
|
1984 OS << " class";
|
173
|
1985 if (Attrs & ObjCPropertyAttribute::kind_direct)
|
150
|
1986 OS << " direct";
|
173
|
1987 if (Attrs & ObjCPropertyAttribute::kind_getter)
|
150
|
1988 dumpDeclRef(D->getGetterMethodDecl(), "getter");
|
173
|
1989 if (Attrs & ObjCPropertyAttribute::kind_setter)
|
150
|
1990 dumpDeclRef(D->getSetterMethodDecl(), "setter");
|
|
1991 }
|
|
1992 }
|
|
1993
|
|
1994 void TextNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
|
|
1995 dumpName(D->getPropertyDecl());
|
|
1996 if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
|
|
1997 OS << " synthesize";
|
|
1998 else
|
|
1999 OS << " dynamic";
|
|
2000 dumpDeclRef(D->getPropertyDecl());
|
|
2001 dumpDeclRef(D->getPropertyIvarDecl());
|
|
2002 }
|
|
2003
|
|
2004 void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) {
|
|
2005 if (D->isVariadic())
|
|
2006 OS << " variadic";
|
|
2007
|
|
2008 if (D->capturesCXXThis())
|
|
2009 OS << " captures_this";
|
|
2010 }
|
|
2011
|
|
2012 void TextNodeDumper::VisitConceptDecl(const ConceptDecl *D) {
|
|
2013 dumpName(D);
|
|
2014 }
|