llvm.org GIT mirror llvm / 2e2b1e2
[MS Demangler] Add output flags to all function calls. Previously we had a FunctionSigFlags, but it's more flexible to just have one set of output flags that apply to the entire process and just pipe the entire set of flags through the output process. This will be useful when we start allowing the user to customize the outputting behavior. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@340894 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 1 year, 23 days ago
3 changed file(s) with 174 addition(s) and 174 deletion(s). Raw diff Collapse all Expand all
993993 // Render this class template name into a string buffer so that we can
994994 // memorize it for the purpose of back-referencing.
995995 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
996 Identifier->output(OS);
996 Identifier->output(OS, OF_Default);
997997 OS << '\0';
998998 char *Name = OS.getBuffer();
999999
14211421 // Render the parent symbol's name into a buffer.
14221422 OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
14231423 OS << '`';
1424 Scope->output(OS);
1424 Scope->output(OS, OF_Default);
14251425 OS << '\'';
14261426 OS << "::`" << Number.first << "'";
14271427 OS << '\0';
22222222 OS.setCurrentPosition(0);
22232223
22242224 TypeNode *T = Backrefs.FunctionParams[I];
2225 T->output(OS);
2225 T->output(OS, OF_Default);
22262226
22272227 std::printf(" [%d] - %.*s\n", (int)I, (int)OS.getCurrentPosition(),
22282228 OS.getBuffer());
22532253 OS << MangledName;
22542254 *Status = llvm::demangle_invalid_mangled_name;
22552255 } else {
2256 S->output(OS);
2256 S->output(OS, OF_Default);
22572257 *Status = llvm::demangle_success;
22582258 }
22592259
114114
115115 void TypeNode::outputQuals(bool SpaceBefore, bool SpaceAfter) const {}
116116
117 void PrimitiveTypeNode::outputPre(OutputStream &OS) const {
117 void PrimitiveTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
118118 switch (PrimKind) {
119119 OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Void, "void");
120120 OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Bool, "bool");
140140 outputQualifiers(OS, Quals, true, false);
141141 }
142142
143 void NodeArrayNode::output(OutputStream &OS) const { output(OS, ", "); }
144
145 void NodeArrayNode::output(OutputStream &OS, StringView Separator) const {
143 void NodeArrayNode::output(OutputStream &OS, OutputFlags Flags) const {
144 output(OS, Flags, ", ");
145 }
146
147 void NodeArrayNode::output(OutputStream &OS, OutputFlags Flags,
148 StringView Separator) const {
146149 if (Count == 0)
147150 return;
148151 if (Nodes[0])
149 Nodes[0]->output(OS);
152 Nodes[0]->output(OS, Flags);
150153 for (size_t I = 1; I < Count; ++I) {
151154 OS << Separator;
152 Nodes[I]->output(OS);
153 }
154 }
155
156 void EncodedStringLiteralNode::output(OutputStream &OS) const {
155 Nodes[I]->output(OS, Flags);
156 }
157 }
158
159 void EncodedStringLiteralNode::output(OutputStream &OS,
160 OutputFlags Flags) const {
157161 switch (Char) {
158162 case CharKind::Wchar:
159163 OS << "const wchar_t * {L\"";
174178 OS << "}";
175179 }
176180
177 void IntegerLiteralNode::output(OutputStream &OS) const {
181 void IntegerLiteralNode::output(OutputStream &OS, OutputFlags Flags) const {
178182 if (IsNegative)
179183 OS << '-';
180184 OS << Value;
181185 }
182186
183 void TemplateParameterReferenceNode::output(OutputStream &OS) const {
187 void TemplateParameterReferenceNode::output(OutputStream &OS,
188 OutputFlags Flags) const {
184189 if (ThunkOffsetCount > 0)
185190 OS << "{";
186191 else if (Affinity == PointerAffinity::Pointer)
187192 OS << "&";
188193
189194 if (Symbol) {
190 Symbol->output(OS);
195 Symbol->output(OS, Flags);
191196 if (ThunkOffsetCount > 0)
192197 OS << ", ";
193198 }
201206 OS << "}";
202207 }
203208
204 void IdentifierNode::outputTemplateParameters(OutputStream &OS) const {
209 void IdentifierNode::outputTemplateParameters(OutputStream &OS,
210 OutputFlags Flags) const {
205211 if (!TemplateParams)
206212 return;
207213 OS << "<";
208 TemplateParams->output(OS);
214 TemplateParams->output(OS, Flags);
209215 OS << ">";
210216 }
211217
212 void DynamicStructorIdentifierNode::output(OutputStream &OS) const {
218 void DynamicStructorIdentifierNode::output(OutputStream &OS,
219 OutputFlags Flags) const {
213220 if (IsDestructor)
214221 OS << "`dynamic atexit destructor for ";
215222 else
216223 OS << "`dynamic initializer for ";
217224
218225 OS << "'";
219 Name->output(OS);
226 Name->output(OS, Flags);
220227 OS << "''";
221228 }
222229
223 void NamedIdentifierNode::output(OutputStream &OS) const {
230 void NamedIdentifierNode::output(OutputStream &OS, OutputFlags Flags) const {
224231 OS << Name;
225 outputTemplateParameters(OS);
226 }
227
228 void IntrinsicFunctionIdentifierNode::output(OutputStream &OS) const {
232 outputTemplateParameters(OS, Flags);
233 }
234
235 void IntrinsicFunctionIdentifierNode::output(OutputStream &OS,
236 OutputFlags Flags) const {
229237 switch (Operator) {
230238 OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, New, "operator new");
231239 OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Delete, "operator delete");
321329 case IntrinsicFunctionKind::None:
322330 break;
323331 }
324 outputTemplateParameters(OS);
325 }
326
327 void LocalStaticGuardIdentifierNode::output(OutputStream &OS) const {
332 outputTemplateParameters(OS, Flags);
333 }
334
335 void LocalStaticGuardIdentifierNode::output(OutputStream &OS,
336 OutputFlags Flags) const {
328337 OS << "`local static guard'";
329338 if (ScopeIndex > 0)
330339 OS << "{" << ScopeIndex << "}";
331340 }
332341
333 void ConversionOperatorIdentifierNode::output(OutputStream &OS) const {
342 void ConversionOperatorIdentifierNode::output(OutputStream &OS,
343 OutputFlags Flags) const {
334344 OS << "operator";
335 outputTemplateParameters(OS);
345 outputTemplateParameters(OS, Flags);
336346 OS << " ";
337 TargetType->output(OS);
338 }
339
340 void StructorIdentifierNode::output(OutputStream &OS) const {
347 TargetType->output(OS, Flags);
348 }
349
350 void StructorIdentifierNode::output(OutputStream &OS, OutputFlags Flags) const {
341351 if (IsDestructor)
342352 OS << "~";
343 Class->output(OS);
344 outputTemplateParameters(OS);
345 }
346
347 void LiteralOperatorIdentifierNode::output(OutputStream &OS) const {
353 Class->output(OS, Flags);
354 outputTemplateParameters(OS, Flags);
355 }
356
357 void LiteralOperatorIdentifierNode::output(OutputStream &OS,
358 OutputFlags Flags) const {
348359 OS << "operator \"\"" << Name;
349 outputTemplateParameters(OS);
360 outputTemplateParameters(OS, Flags);
350361 }
351362
352363 void FunctionSignatureNode::outputPre(OutputStream &OS,
353 FunctionSigFlags Flags) const {
364 OutputFlags Flags) const {
354365 if (!(FunctionClass & FC_Global)) {
355366 if (FunctionClass & FC_Static)
356367 OS << "static ";
362373 OS << "virtual ";
363374
364375 if (ReturnType) {
365 ReturnType->outputPre(OS);
376 ReturnType->outputPre(OS, Flags);
366377 OS << " ";
367378 }
368379
369 if (!(Flags & FSF_NoCallingConvention))
380 if (!(Flags & OF_NoCallingConvention))
370381 outputCallingConvention(OS, CallConvention);
371382 }
372383
373384 void FunctionSignatureNode::outputPost(OutputStream &OS,
374 FunctionSigFlags Flags) const {
385 OutputFlags Flags) const {
375386 if (!(FunctionClass & FC_NoParameterList)) {
376387 OS << "(";
377388 if (Params)
378 Params->output(OS);
389 Params->output(OS, Flags);
379390 else
380391 OS << "void";
381392 OS << ")";
396407 OS << " &&";
397408
398409 if (ReturnType)
399 ReturnType->outputPost(OS);
400 }
401
402 void ThunkSignatureNode::outputPre(OutputStream &OS,
403 FunctionSigFlags Flags) const {
410 ReturnType->outputPost(OS, Flags);
411 }
412
413 void ThunkSignatureNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
404414 OS << "[thunk]: ";
405415
406416 FunctionSignatureNode::outputPre(OS, Flags);
407417 }
408418
409 void ThunkSignatureNode::outputPost(OutputStream &OS,
410 FunctionSigFlags Flags) const {
419 void ThunkSignatureNode::outputPost(OutputStream &OS, OutputFlags Flags) const {
411420 if (FunctionClass & FC_StaticThisAdjust) {
412421 OS << "`adjustor{" << ThisAdjust.StaticOffset << "}'";
413422 } else if (FunctionClass & FC_VirtualThisAdjust) {
424433 FunctionSignatureNode::outputPost(OS, Flags);
425434 }
426435
427 void PointerTypeNode::outputPre(OutputStream &OS) const {
436 void PointerTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
428437 if (Pointee->kind() == NodeKind::FunctionSignature) {
429438 // If this is a pointer to a function, don't output the calling convention.
430439 // It needs to go inside the parentheses.
431440 const FunctionSignatureNode *Sig =
432441 static_cast(Pointee);
433 Sig->outputPre(OS, FSF_NoCallingConvention);
442 Sig->outputPre(OS, OF_NoCallingConvention);
434443 } else
435 Pointee->outputPre(OS);
444 Pointee->outputPre(OS, Flags);
436445
437446 outputSpaceIfNecessary(OS);
438447
450459 }
451460
452461 if (ClassParent) {
453 ClassParent->output(OS);
462 ClassParent->output(OS, Flags);
454463 OS << "::";
455464 }
456465
470479 outputQualifiers(OS, Quals, false, false);
471480 }
472481
473 void PointerTypeNode::outputPost(OutputStream &OS) const {
482 void PointerTypeNode::outputPost(OutputStream &OS, OutputFlags Flags) const {
474483 if (Pointee->kind() == NodeKind::ArrayType ||
475484 Pointee->kind() == NodeKind::FunctionSignature)
476485 OS << ")";
477486
478 Pointee->outputPost(OS);
479 }
480
481 void TagTypeNode::outputPre(OutputStream &OS) const {
487 Pointee->outputPost(OS, Flags);
488 }
489
490 void TagTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
482491 switch (Tag) {
483492 OUTPUT_ENUM_CLASS_VALUE(TagKind, Class, "class");
484493 OUTPUT_ENUM_CLASS_VALUE(TagKind, Struct, "struct");
486495 OUTPUT_ENUM_CLASS_VALUE(TagKind, Enum, "enum");
487496 }
488497 OS << " ";
489 QualifiedName->output(OS);
498 QualifiedName->output(OS, Flags);
490499 outputQualifiers(OS, Quals, true, false);
491500 }
492501
493 void TagTypeNode::outputPost(OutputStream &OS) const {}
494
495 void ArrayTypeNode::outputPre(OutputStream &OS) const {
496 ElementType->outputPre(OS);
502 void TagTypeNode::outputPost(OutputStream &OS, OutputFlags Flags) const {}
503
504 void ArrayTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
505 ElementType->outputPre(OS, Flags);
497506 outputQualifiers(OS, Quals, true, false);
498507 }
499508
500 void ArrayTypeNode::outputOneDimension(OutputStream &OS, Node *N) const {
509 void ArrayTypeNode::outputOneDimension(OutputStream &OS, OutputFlags Flags,
510 Node *N) const {
501511 assert(N->kind() == NodeKind::IntegerLiteral);
502512 IntegerLiteralNode *ILN = static_cast(N);
503513 if (ILN->Value != 0)
504 ILN->output(OS);
505 }
506
507 void ArrayTypeNode::outputDimensionsImpl(OutputStream &OS) const {
514 ILN->output(OS, Flags);
515 }
516
517 void ArrayTypeNode::outputDimensionsImpl(OutputStream &OS,
518 OutputFlags Flags) const {
508519 if (Dimensions->Count == 0)
509520 return;
510521
511 outputOneDimension(OS, Dimensions->Nodes[0]);
522 outputOneDimension(OS, Flags, Dimensions->Nodes[0]);
512523 for (size_t I = 1; I < Dimensions->Count; ++I) {
513524 OS << "][";
514 outputOneDimension(OS, Dimensions->Nodes[I]);
515 }
516 }
517
518 void ArrayTypeNode::outputPost(OutputStream &OS) const {
525 outputOneDimension(OS, Flags, Dimensions->Nodes[I]);
526 }
527 }
528
529 void ArrayTypeNode::outputPost(OutputStream &OS, OutputFlags Flags) const {
519530 OS << "[";
520 outputDimensionsImpl(OS);
531 outputDimensionsImpl(OS, Flags);
521532 OS << "]";
522533
523 ElementType->outputPost(OS);
524 }
525
526 void SymbolNode::output(OutputStream &OS) const { Name->output(OS); }
527
528 void FunctionSymbolNode::output(OutputStream &OS) const {
529 output(OS, FunctionSigFlags::FSF_Default);
530 }
531
532 void FunctionSymbolNode::output(OutputStream &OS,
533 FunctionSigFlags Flags) const {
534 ElementType->outputPost(OS, Flags);
535 }
536
537 void SymbolNode::output(OutputStream &OS, OutputFlags Flags) const {
538 Name->output(OS, Flags);
539 }
540
541 void FunctionSymbolNode::output(OutputStream &OS, OutputFlags Flags) const {
534542 Signature->outputPre(OS, Flags);
535543 outputSpaceIfNecessary(OS);
536 Name->output(OS);
544 Name->output(OS, Flags);
537545 Signature->outputPost(OS, Flags);
538546 }
539547
540 void VariableSymbolNode::output(OutputStream &OS) const {
548 void VariableSymbolNode::output(OutputStream &OS, OutputFlags Flags) const {
541549 switch (SC) {
542550 case StorageClass::PrivateStatic:
543551 case StorageClass::PublicStatic:
548556 }
549557
550558 if (Type) {
551 Type->outputPre(OS);
559 Type->outputPre(OS, Flags);
552560 outputSpaceIfNecessary(OS);
553561 }
554 Name->output(OS);
562 Name->output(OS, Flags);
555563 if (Type)
556 Type->outputPost(OS);
557 }
558
559 void CustomNode::output(OutputStream &OS) const { OS << Name; }
560
561 void QualifiedNameNode::output(OutputStream &OS) const {
562 Components->output(OS, "::");
563 }
564
565 void RttiBaseClassDescriptorNode::output(OutputStream &OS) const {
564 Type->outputPost(OS, Flags);
565 }
566
567 void CustomNode::output(OutputStream &OS, OutputFlags Flags) const {
568 OS << Name;
569 }
570
571 void QualifiedNameNode::output(OutputStream &OS, OutputFlags Flags) const {
572 Components->output(OS, Flags, "::");
573 }
574
575 void RttiBaseClassDescriptorNode::output(OutputStream &OS,
576 OutputFlags Flags) const {
566577 OS << "`RTTI Base Class Descriptor at (";
567578 OS << NVOffset << ", " << VBPtrOffset << ", " << VBTableOffset << ", "
568 << Flags;
579 << this->Flags;
569580 OS << ")'";
570581 }
571582
572 void LocalStaticGuardVariableNode::output(OutputStream &OS) const {
573 Name->output(OS);
574 }
575
576 void VcallThunkIdentifierNode::output(OutputStream &OS) const {
583 void LocalStaticGuardVariableNode::output(OutputStream &OS,
584 OutputFlags Flags) const {
585 Name->output(OS, Flags);
586 }
587
588 void VcallThunkIdentifierNode::output(OutputStream &OS,
589 OutputFlags Flags) const {
577590 OS << "`vcall'{" << OffsetInVTable << ", {flat}}";
578591 }
579592
580 void SpecialTableSymbolNode::output(OutputStream &OS) const {
593 void SpecialTableSymbolNode::output(OutputStream &OS, OutputFlags Flags) const {
581594 outputQualifiers(OS, Quals, false, true);
582 Name->output(OS);
595 Name->output(OS, Flags);
583596 if (TargetName) {
584597 OS << "{for `";
585 TargetName->output(OS);
598 TargetName->output(OS, Flags);
586599 OS << "'}";
587600 }
588601 return;
147147
148148 enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
149149
150 enum FunctionSigFlags { FSF_Default = 0, FSF_NoCallingConvention = 1 };
150 enum OutputFlags { OF_Default = 0, OF_NoCallingConvention = 1 };
151151
152152 // Types
153153 enum class PrimitiveKind {
327327
328328 NodeKind kind() const { return Kind; }
329329
330 virtual void output(OutputStream &OS) const = 0;
330 virtual void output(OutputStream &OS, OutputFlags Flags) const = 0;
331331
332332 private:
333333 NodeKind Kind;
364364 struct TypeNode : public Node {
365365 explicit TypeNode(NodeKind K) : Node(K) {}
366366
367 virtual void outputPre(OutputStream &OS) const = 0;
368 virtual void outputPost(OutputStream &OS) const = 0;
369
370 void output(OutputStream &OS) const {
371 outputPre(OS);
372 outputPost(OS);
367 virtual void outputPre(OutputStream &OS, OutputFlags Flags) const = 0;
368 virtual void outputPost(OutputStream &OS, OutputFlags Flags) const = 0;
369
370 void output(OutputStream &OS, OutputFlags Flags) const override {
371 outputPre(OS, Flags);
372 outputPost(OS, Flags);
373373 }
374374
375375 void outputQuals(bool SpaceBefore, bool SpaceAfter) const;
381381 explicit PrimitiveTypeNode(PrimitiveKind K)
382382 : TypeNode(NodeKind::PrimitiveType), PrimKind(K) {}
383383
384 void outputPre(OutputStream &OS) const;
385 void outputPost(OutputStream &OS) const {}
384 void outputPre(OutputStream &OS, OutputFlags Flags) const;
385 void outputPost(OutputStream &OS, OutputFlags Flags) const {}
386386
387387 PrimitiveKind PrimKind;
388388 };
391391 explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {}
392392 FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature) {}
393393
394 virtual void outputPre(OutputStream &OS, FunctionSigFlags Flags) const;
395 virtual void outputPost(OutputStream &OS, FunctionSigFlags Flags) const;
396
397 void outputPre(OutputStream &OS) const override {
398 outputPre(OS, FSF_Default);
399 }
400 void outputPost(OutputStream &OS) const override {
401 outputPost(OS, FSF_Default);
402 }
403
404 void output(OutputStream &OS) const override {
405 outputPre(OS, FSF_Default);
406 outputPost(OS);
407 }
394 virtual void outputPre(OutputStream &OS, OutputFlags Flags) const;
395 virtual void outputPost(OutputStream &OS, OutputFlags Flags) const;
408396
409397 // Valid if this FunctionTypeNode is the Pointee of a PointerType or
410398 // MemberPointerType.
434422 NodeArrayNode *TemplateParams = nullptr;
435423
436424 protected:
437 void outputTemplateParameters(OutputStream &OS) const;
425 void outputTemplateParameters(OutputStream &OS, OutputFlags Flags) const;
438426 };
439427
440428 struct VcallThunkIdentifierNode : public IdentifierNode {
441429 VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier) {}
442430
443 void output(OutputStream &OS) const override;
431 void output(OutputStream &OS, OutputFlags Flags) const override;
444432
445433 uint64_t OffsetInVTable = 0;
446434 };
449437 DynamicStructorIdentifierNode()
450438 : IdentifierNode(NodeKind::DynamicStructorIdentifier) {}
451439
452 void output(OutputStream &OS) const override;
440 void output(OutputStream &OS, OutputFlags Flags) const override;
453441
454442 QualifiedNameNode *Name = nullptr;
455443 bool IsDestructor = false;
458446 struct NamedIdentifierNode : public IdentifierNode {
459447 NamedIdentifierNode() : IdentifierNode(NodeKind::NamedIdentifier) {}
460448
461 void output(OutputStream &OS) const override;
449 void output(OutputStream &OS, OutputFlags Flags) const override;
462450
463451 StringView Name;
464452 };
468456 : IdentifierNode(NodeKind::IntrinsicFunctionIdentifier),
469457 Operator(Operator) {}
470458
471 void output(OutputStream &OS) const override;
459 void output(OutputStream &OS, OutputFlags Flags) const override;
472460
473461 IntrinsicFunctionKind Operator;
474462 };
477465 LiteralOperatorIdentifierNode()
478466 : IdentifierNode(NodeKind::LiteralOperatorIdentifier) {}
479467
480 void output(OutputStream &OS) const override;
468 void output(OutputStream &OS, OutputFlags Flags) const override;
481469
482470 StringView Name;
483471 };
486474 LocalStaticGuardIdentifierNode()
487475 : IdentifierNode(NodeKind::LocalStaticGuardIdentifier) {}
488476
489 void output(OutputStream &OS) const override;
477 void output(OutputStream &OS, OutputFlags Flags) const override;
490478
491479 uint32_t ScopeIndex = 0;
492480 };
495483 ConversionOperatorIdentifierNode()
496484 : IdentifierNode(NodeKind::ConversionOperatorIdentifier) {}
497485
498 void output(OutputStream &OS) const override;
486 void output(OutputStream &OS, OutputFlags Flags) const override;
499487
500488 // The type that this operator converts too.
501489 TypeNode *TargetType = nullptr;
507495 : IdentifierNode(NodeKind::StructorIdentifier),
508496 IsDestructor(IsDestructor) {}
509497
510 void output(OutputStream &OS) const override;
498 void output(OutputStream &OS, OutputFlags Flags) const override;
511499
512500 // The name of the class that this is a structor of.
513501 IdentifierNode *Class = nullptr;
517505 struct ThunkSignatureNode : public FunctionSignatureNode {
518506 ThunkSignatureNode() : FunctionSignatureNode(NodeKind::ThunkSignature) {}
519507
520 void outputPre(OutputStream &OS, FunctionSigFlags Flags) const override;
521 void outputPost(OutputStream &OS, FunctionSigFlags Flags) const override;
508 void outputPre(OutputStream &OS, OutputFlags Flags) const override;
509 void outputPost(OutputStream &OS, OutputFlags Flags) const override;
522510
523511 struct ThisAdjustor {
524512 uint32_t StaticOffset = 0;
532520
533521 struct PointerTypeNode : public TypeNode {
534522 PointerTypeNode() : TypeNode(NodeKind::PointerType) {}
535 void outputPre(OutputStream &OS) const override;
536 void outputPost(OutputStream &OS) const override;
523 void outputPre(OutputStream &OS, OutputFlags Flags) const override;
524 void outputPost(OutputStream &OS, OutputFlags Flags) const override;
537525
538526 // Is this a pointer, reference, or rvalue-reference?
539527 PointerAffinity Affinity = PointerAffinity::None;
549537 struct TagTypeNode : public TypeNode {
550538 explicit TagTypeNode(TagKind Tag) : TypeNode(NodeKind::TagType), Tag(Tag) {}
551539
552 void outputPre(OutputStream &OS) const;
553 void outputPost(OutputStream &OS) const;
540 void outputPre(OutputStream &OS, OutputFlags Flags) const;
541 void outputPost(OutputStream &OS, OutputFlags Flags) const;
554542
555543 QualifiedNameNode *QualifiedName = nullptr;
556544 TagKind Tag;
559547 struct ArrayTypeNode : public TypeNode {
560548 ArrayTypeNode() : TypeNode(NodeKind::ArrayType) {}
561549
562 void outputPre(OutputStream &OS) const;
563 void outputPost(OutputStream &OS) const;
564
565 void outputDimensionsImpl(OutputStream &OS) const;
566 void outputOneDimension(OutputStream &OS, Node *N) const;
550 void outputPre(OutputStream &OS, OutputFlags Flags) const;
551 void outputPost(OutputStream &OS, OutputFlags Flags) const;
552
553 void outputDimensionsImpl(OutputStream &OS, OutputFlags Flags) const;
554 void outputOneDimension(OutputStream &OS, OutputFlags Flags, Node *N) const;
567555
568556 // A list of array dimensions. e.g. [3,4,5] in `int Foo[3][4][5]`
569557 NodeArrayNode *Dimensions = nullptr;
574562
575563 struct IntrinsicNode : public TypeNode {
576564 IntrinsicNode() : TypeNode(NodeKind::IntrinsicType) {}
577 void output(OutputStream &OS) const override {}
565 void output(OutputStream &OS, OutputFlags Flags) const override {}
578566 };
579567
580568 struct CustomNode : public Node {
581569 CustomNode() : Node(NodeKind::Custom) {}
582570
583 void output(OutputStream &OS) const override;
571 void output(OutputStream &OS, OutputFlags Flags) const override;
584572
585573 // The string to print.
586574 StringView Name;
589577 struct NodeArrayNode : public Node {
590578 NodeArrayNode() : Node(NodeKind::NodeArray) {}
591579
592 void output(OutputStream &OS) const override;
593
594 void output(OutputStream &OS, StringView Separator) const;
580 void output(OutputStream &OS, OutputFlags Flags) const override;
581
582 void output(OutputStream &OS, OutputFlags Flags, StringView Separator) const;
595583
596584 Node **Nodes = 0;
597585 size_t Count = 0;
600588 struct QualifiedNameNode : public Node {
601589 QualifiedNameNode() : Node(NodeKind::QualifiedName) {}
602590
603 void output(OutputStream &OS) const override;
591 void output(OutputStream &OS, OutputFlags Flags) const override;
604592
605593 NodeArrayNode *Components = nullptr;
606594
614602 TemplateParameterReferenceNode()
615603 : Node(NodeKind::TemplateParameterReference) {}
616604
617 void output(OutputStream &OS) const override;
605 void output(OutputStream &OS, OutputFlags Flags) const override;
618606
619607 SymbolNode *Symbol = nullptr;
620608
629617 IntegerLiteralNode(uint64_t Value, bool IsNegative)
630618 : Node(NodeKind::IntegerLiteral), Value(Value), IsNegative(IsNegative) {}
631619
632 void output(OutputStream &OS) const override;
620 void output(OutputStream &OS, OutputFlags Flags) const override;
633621
634622 uint64_t Value = 0;
635623 bool IsNegative = false;
639627 RttiBaseClassDescriptorNode()
640628 : IdentifierNode(NodeKind::RttiBaseClassDescriptor) {}
641629
642 void output(OutputStream &OS) const override;
630 void output(OutputStream &OS, OutputFlags Flags) const override;
643631
644632 uint32_t NVOffset = 0;
645633 int32_t VBPtrOffset = 0;
649637
650638 struct SymbolNode : public Node {
651639 explicit SymbolNode(NodeKind K) : Node(K) {}
652 void output(OutputStream &OS) const override;
640 void output(OutputStream &OS, OutputFlags Flags) const override;
653641 QualifiedNameNode *Name = nullptr;
654642 };
655643
657645 explicit SpecialTableSymbolNode()
658646 : SymbolNode(NodeKind::SpecialTableSymbol) {}
659647
660 void output(OutputStream &OS) const override;
648 void output(OutputStream &OS, OutputFlags Flags) const override;
661649 QualifiedNameNode *TargetName = nullptr;
662650 Qualifiers Quals;
663651 };
666654 LocalStaticGuardVariableNode()
667655 : SymbolNode(NodeKind::LocalStaticGuardVariable) {}
668656
669 void output(OutputStream &OS) const override;
657 void output(OutputStream &OS, OutputFlags Flags) const override;
670658
671659 bool IsVisible = false;
672660 };
674662 struct EncodedStringLiteralNode : public SymbolNode {
675663 EncodedStringLiteralNode() : SymbolNode(NodeKind::EncodedStringLiteral) {}
676664
677 void output(OutputStream &OS) const override;
665 void output(OutputStream &OS, OutputFlags Flags) const override;
678666
679667 StringView DecodedString;
680668 bool IsTruncated = false;
684672 struct VariableSymbolNode : public SymbolNode {
685673 VariableSymbolNode() : SymbolNode(NodeKind::VariableSymbol) {}
686674
687 void output(OutputStream &OS) const override;
675 void output(OutputStream &OS, OutputFlags Flags) const override;
688676
689677 StorageClass SC = StorageClass::None;
690678 TypeNode *Type = nullptr;
693681 struct FunctionSymbolNode : public SymbolNode {
694682 FunctionSymbolNode() : SymbolNode(NodeKind::FunctionSymbol) {}
695683
696 void output(OutputStream &OS) const override;
697 void output(OutputStream &OS, FunctionSigFlags Flags) const;
684 void output(OutputStream &OS, OutputFlags Flags) const override;
698685
699686 FunctionSignatureNode *Signature = nullptr;
700687 };