clang 19.0.0git
TypePrinter.cpp
Go to the documentation of this file.
1//===- TypePrinter.cpp - Pretty-Print Clang Types -------------------------===//
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 contains code to print types from Clang's type system.
10//
11//===----------------------------------------------------------------------===//
12
14#include "clang/AST/Attr.h"
15#include "clang/AST/Decl.h"
16#include "clang/AST/DeclBase.h"
17#include "clang/AST/DeclCXX.h"
18#include "clang/AST/DeclObjC.h"
20#include "clang/AST/Expr.h"
26#include "clang/AST/Type.h"
30#include "clang/Basic/LLVM.h"
35#include "llvm/ADT/ArrayRef.h"
36#include "llvm/ADT/DenseMap.h"
37#include "llvm/ADT/SmallString.h"
38#include "llvm/ADT/StringRef.h"
39#include "llvm/ADT/Twine.h"
40#include "llvm/Support/Casting.h"
41#include "llvm/Support/Compiler.h"
42#include "llvm/Support/ErrorHandling.h"
43#include "llvm/Support/SaveAndRestore.h"
44#include "llvm/Support/raw_ostream.h"
45#include <cassert>
46#include <string>
47
48using namespace clang;
49
50namespace {
51
52/// RAII object that enables printing of the ARC __strong lifetime
53/// qualifier.
54class IncludeStrongLifetimeRAII {
55 PrintingPolicy &Policy;
56 bool Old;
57
58public:
59 explicit IncludeStrongLifetimeRAII(PrintingPolicy &Policy)
60 : Policy(Policy), Old(Policy.SuppressStrongLifetime) {
62 Policy.SuppressStrongLifetime = false;
63 }
64
65 ~IncludeStrongLifetimeRAII() { Policy.SuppressStrongLifetime = Old; }
66};
67
68class ParamPolicyRAII {
69 PrintingPolicy &Policy;
70 bool Old;
71
72public:
73 explicit ParamPolicyRAII(PrintingPolicy &Policy)
74 : Policy(Policy), Old(Policy.SuppressSpecifiers) {
75 Policy.SuppressSpecifiers = false;
76 }
77
78 ~ParamPolicyRAII() { Policy.SuppressSpecifiers = Old; }
79};
80
81class DefaultTemplateArgsPolicyRAII {
82 PrintingPolicy &Policy;
83 bool Old;
84
85public:
86 explicit DefaultTemplateArgsPolicyRAII(PrintingPolicy &Policy)
87 : Policy(Policy), Old(Policy.SuppressDefaultTemplateArgs) {
88 Policy.SuppressDefaultTemplateArgs = false;
89 }
90
91 ~DefaultTemplateArgsPolicyRAII() { Policy.SuppressDefaultTemplateArgs = Old; }
92};
93
94class ElaboratedTypePolicyRAII {
95 PrintingPolicy &Policy;
96 bool SuppressTagKeyword;
97 bool SuppressScope;
98
99public:
100 explicit ElaboratedTypePolicyRAII(PrintingPolicy &Policy) : Policy(Policy) {
101 SuppressTagKeyword = Policy.SuppressTagKeyword;
102 SuppressScope = Policy.SuppressScope;
103 Policy.SuppressTagKeyword = true;
104 Policy.SuppressScope = true;
105 }
106
107 ~ElaboratedTypePolicyRAII() {
108 Policy.SuppressTagKeyword = SuppressTagKeyword;
109 Policy.SuppressScope = SuppressScope;
110 }
111};
112
113class TypePrinter {
114 PrintingPolicy Policy;
115 unsigned Indentation;
116 bool HasEmptyPlaceHolder = false;
117 bool InsideCCAttribute = false;
118
119public:
120 explicit TypePrinter(const PrintingPolicy &Policy, unsigned Indentation = 0)
121 : Policy(Policy), Indentation(Indentation) {}
122
123 void print(const Type *ty, Qualifiers qs, raw_ostream &OS,
124 StringRef PlaceHolder);
125 void print(QualType T, raw_ostream &OS, StringRef PlaceHolder);
126
127 static bool canPrefixQualifiers(const Type *T, bool &NeedARCStrongQualifier);
128 void spaceBeforePlaceHolder(raw_ostream &OS);
129 void printTypeSpec(NamedDecl *D, raw_ostream &OS);
130 void printTemplateId(const TemplateSpecializationType *T, raw_ostream &OS,
131 bool FullyQualify);
132
133 void printBefore(QualType T, raw_ostream &OS);
134 void printAfter(QualType T, raw_ostream &OS);
135 void AppendScope(DeclContext *DC, raw_ostream &OS,
136 DeclarationName NameInScope);
137 void printTag(TagDecl *T, raw_ostream &OS);
138 void printFunctionAfter(const FunctionType::ExtInfo &Info, raw_ostream &OS);
139#define ABSTRACT_TYPE(CLASS, PARENT)
140#define TYPE(CLASS, PARENT) \
141 void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS); \
142 void print##CLASS##After(const CLASS##Type *T, raw_ostream &OS);
143#include "clang/AST/TypeNodes.inc"
144
145private:
146 void printBefore(const Type *ty, Qualifiers qs, raw_ostream &OS);
147 void printAfter(const Type *ty, Qualifiers qs, raw_ostream &OS);
148};
149
150} // namespace
151
152static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals,
153 bool HasRestrictKeyword) {
154 bool appendSpace = false;
155 if (TypeQuals & Qualifiers::Const) {
156 OS << "const";
157 appendSpace = true;
158 }
159 if (TypeQuals & Qualifiers::Volatile) {
160 if (appendSpace) OS << ' ';
161 OS << "volatile";
162 appendSpace = true;
163 }
164 if (TypeQuals & Qualifiers::Restrict) {
165 if (appendSpace) OS << ' ';
166 if (HasRestrictKeyword) {
167 OS << "restrict";
168 } else {
169 OS << "__restrict";
170 }
171 }
172}
173
174void TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) {
175 if (!HasEmptyPlaceHolder)
176 OS << ' ';
177}
178
180 const PrintingPolicy &Policy) {
181 if (Policy.PrintCanonicalTypes)
182 QT = QT.getCanonicalType();
183 return QT.split();
184}
185
186void TypePrinter::print(QualType t, raw_ostream &OS, StringRef PlaceHolder) {
187 SplitQualType split = splitAccordingToPolicy(t, Policy);
188 print(split.Ty, split.Quals, OS, PlaceHolder);
189}
190
191void TypePrinter::print(const Type *T, Qualifiers Quals, raw_ostream &OS,
192 StringRef PlaceHolder) {
193 if (!T) {
194 OS << "NULL TYPE";
195 return;
196 }
197
198 SaveAndRestore PHVal(HasEmptyPlaceHolder, PlaceHolder.empty());
199
200 printBefore(T, Quals, OS);
201 OS << PlaceHolder;
202 printAfter(T, Quals, OS);
203}
204
205bool TypePrinter::canPrefixQualifiers(const Type *T,
206 bool &NeedARCStrongQualifier) {
207 // CanPrefixQualifiers - We prefer to print type qualifiers before the type,
208 // so that we get "const int" instead of "int const", but we can't do this if
209 // the type is complex. For example if the type is "int*", we *must* print
210 // "int * const", printing "const int *" is different. Only do this when the
211 // type expands to a simple string.
212 bool CanPrefixQualifiers = false;
213 NeedARCStrongQualifier = false;
214 const Type *UnderlyingType = T;
215 if (const auto *AT = dyn_cast<AutoType>(T))
216 UnderlyingType = AT->desugar().getTypePtr();
217 if (const auto *Subst = dyn_cast<SubstTemplateTypeParmType>(T))
218 UnderlyingType = Subst->getReplacementType().getTypePtr();
219 Type::TypeClass TC = UnderlyingType->getTypeClass();
220
221 switch (TC) {
222 case Type::Auto:
223 case Type::Builtin:
224 case Type::Complex:
225 case Type::UnresolvedUsing:
226 case Type::Using:
227 case Type::Typedef:
228 case Type::TypeOfExpr:
229 case Type::TypeOf:
230 case Type::Decltype:
231 case Type::UnaryTransform:
232 case Type::Record:
233 case Type::Enum:
234 case Type::Elaborated:
235 case Type::TemplateTypeParm:
236 case Type::SubstTemplateTypeParmPack:
237 case Type::DeducedTemplateSpecialization:
238 case Type::TemplateSpecialization:
239 case Type::InjectedClassName:
240 case Type::DependentName:
241 case Type::DependentTemplateSpecialization:
242 case Type::ObjCObject:
243 case Type::ObjCTypeParam:
244 case Type::ObjCInterface:
245 case Type::Atomic:
246 case Type::Pipe:
247 case Type::BitInt:
248 case Type::DependentBitInt:
249 case Type::BTFTagAttributed:
250 CanPrefixQualifiers = true;
251 break;
252
253 case Type::ObjCObjectPointer:
254 CanPrefixQualifiers = T->isObjCIdType() || T->isObjCClassType() ||
256 break;
257
258 case Type::VariableArray:
259 case Type::DependentSizedArray:
260 NeedARCStrongQualifier = true;
261 [[fallthrough]];
262
263 case Type::ConstantArray:
264 case Type::IncompleteArray:
265 return canPrefixQualifiers(
266 cast<ArrayType>(UnderlyingType)->getElementType().getTypePtr(),
267 NeedARCStrongQualifier);
268
269 case Type::Adjusted:
270 case Type::Decayed:
271 case Type::ArrayParameter:
272 case Type::Pointer:
273 case Type::BlockPointer:
274 case Type::LValueReference:
275 case Type::RValueReference:
276 case Type::MemberPointer:
277 case Type::DependentAddressSpace:
278 case Type::DependentVector:
279 case Type::DependentSizedExtVector:
280 case Type::Vector:
281 case Type::ExtVector:
282 case Type::ConstantMatrix:
283 case Type::DependentSizedMatrix:
284 case Type::FunctionProto:
285 case Type::FunctionNoProto:
286 case Type::Paren:
287 case Type::PackExpansion:
288 case Type::SubstTemplateTypeParm:
289 case Type::MacroQualified:
290 case Type::CountAttributed:
291 CanPrefixQualifiers = false;
292 break;
293
294 case Type::Attributed: {
295 // We still want to print the address_space before the type if it is an
296 // address_space attribute.
297 const auto *AttrTy = cast<AttributedType>(UnderlyingType);
298 CanPrefixQualifiers = AttrTy->getAttrKind() == attr::AddressSpace;
299 break;
300 }
301 case Type::PackIndexing: {
302 return canPrefixQualifiers(
303 cast<PackIndexingType>(UnderlyingType)->getPattern().getTypePtr(),
304 NeedARCStrongQualifier);
305 }
306 }
307
308 return CanPrefixQualifiers;
309}
310
311void TypePrinter::printBefore(QualType T, raw_ostream &OS) {
313
314 // If we have cv1 T, where T is substituted for cv2 U, only print cv1 - cv2
315 // at this level.
316 Qualifiers Quals = Split.Quals;
317 if (const auto *Subst = dyn_cast<SubstTemplateTypeParmType>(Split.Ty))
318 Quals -= QualType(Subst, 0).getQualifiers();
319
320 printBefore(Split.Ty, Quals, OS);
321}
322
323/// Prints the part of the type string before an identifier, e.g. for
324/// "int foo[10]" it prints "int ".
325void TypePrinter::printBefore(const Type *T,Qualifiers Quals, raw_ostream &OS) {
326 if (Policy.SuppressSpecifiers && T->isSpecifierType())
327 return;
328
329 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder);
330
331 // Print qualifiers as appropriate.
332
333 bool CanPrefixQualifiers = false;
334 bool NeedARCStrongQualifier = false;
335 CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier);
336
337 if (CanPrefixQualifiers && !Quals.empty()) {
338 if (NeedARCStrongQualifier) {
339 IncludeStrongLifetimeRAII Strong(Policy);
340 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
341 } else {
342 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
343 }
344 }
345
346 bool hasAfterQuals = false;
347 if (!CanPrefixQualifiers && !Quals.empty()) {
348 hasAfterQuals = !Quals.isEmptyWhenPrinted(Policy);
349 if (hasAfterQuals)
350 HasEmptyPlaceHolder = false;
351 }
352
353 switch (T->getTypeClass()) {
354#define ABSTRACT_TYPE(CLASS, PARENT)
355#define TYPE(CLASS, PARENT) case Type::CLASS: \
356 print##CLASS##Before(cast<CLASS##Type>(T), OS); \
357 break;
358#include "clang/AST/TypeNodes.inc"
359 }
360
361 if (hasAfterQuals) {
362 if (NeedARCStrongQualifier) {
363 IncludeStrongLifetimeRAII Strong(Policy);
364 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
365 } else {
366 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
367 }
368 }
369}
370
371void TypePrinter::printAfter(QualType t, raw_ostream &OS) {
372 SplitQualType split = splitAccordingToPolicy(t, Policy);
373 printAfter(split.Ty, split.Quals, OS);
374}
375
376/// Prints the part of the type string after an identifier, e.g. for
377/// "int foo[10]" it prints "[10]".
378void TypePrinter::printAfter(const Type *T, Qualifiers Quals, raw_ostream &OS) {
379 switch (T->getTypeClass()) {
380#define ABSTRACT_TYPE(CLASS, PARENT)
381#define TYPE(CLASS, PARENT) case Type::CLASS: \
382 print##CLASS##After(cast<CLASS##Type>(T), OS); \
383 break;
384#include "clang/AST/TypeNodes.inc"
385 }
386}
387
388void TypePrinter::printBuiltinBefore(const BuiltinType *T, raw_ostream &OS) {
389 OS << T->getName(Policy);
390 spaceBeforePlaceHolder(OS);
391}
392
393void TypePrinter::printBuiltinAfter(const BuiltinType *T, raw_ostream &OS) {}
394
395void TypePrinter::printComplexBefore(const ComplexType *T, raw_ostream &OS) {
396 OS << "_Complex ";
397 printBefore(T->getElementType(), OS);
398}
399
400void TypePrinter::printComplexAfter(const ComplexType *T, raw_ostream &OS) {
401 printAfter(T->getElementType(), OS);
402}
403
404void TypePrinter::printPointerBefore(const PointerType *T, raw_ostream &OS) {
405 IncludeStrongLifetimeRAII Strong(Policy);
406 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
407 printBefore(T->getPointeeType(), OS);
408 // Handle things like 'int (*A)[4];' correctly.
409 // FIXME: this should include vectors, but vectors use attributes I guess.
410 if (isa<ArrayType>(T->getPointeeType()))
411 OS << '(';
412 OS << '*';
413}
414
415void TypePrinter::printPointerAfter(const PointerType *T, raw_ostream &OS) {
416 IncludeStrongLifetimeRAII Strong(Policy);
417 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
418 // Handle things like 'int (*A)[4];' correctly.
419 // FIXME: this should include vectors, but vectors use attributes I guess.
420 if (isa<ArrayType>(T->getPointeeType()))
421 OS << ')';
422 printAfter(T->getPointeeType(), OS);
423}
424
425void TypePrinter::printBlockPointerBefore(const BlockPointerType *T,
426 raw_ostream &OS) {
427 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
428 printBefore(T->getPointeeType(), OS);
429 OS << '^';
430}
431
432void TypePrinter::printBlockPointerAfter(const BlockPointerType *T,
433 raw_ostream &OS) {
434 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
435 printAfter(T->getPointeeType(), OS);
436}
437
438// When printing a reference, the referenced type might also be a reference.
439// If so, we want to skip that before printing the inner type.
441 if (auto *Ref = T->getAs<ReferenceType>())
442 return skipTopLevelReferences(Ref->getPointeeTypeAsWritten());
443 return T;
444}
445
446void TypePrinter::printLValueReferenceBefore(const LValueReferenceType *T,
447 raw_ostream &OS) {
448 IncludeStrongLifetimeRAII Strong(Policy);
449 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
450 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
451 printBefore(Inner, OS);
452 // Handle things like 'int (&A)[4];' correctly.
453 // FIXME: this should include vectors, but vectors use attributes I guess.
454 if (isa<ArrayType>(Inner))
455 OS << '(';
456 OS << '&';
457}
458
459void TypePrinter::printLValueReferenceAfter(const LValueReferenceType *T,
460 raw_ostream &OS) {
461 IncludeStrongLifetimeRAII Strong(Policy);
462 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
463 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
464 // Handle things like 'int (&A)[4];' correctly.
465 // FIXME: this should include vectors, but vectors use attributes I guess.
466 if (isa<ArrayType>(Inner))
467 OS << ')';
468 printAfter(Inner, OS);
469}
470
471void TypePrinter::printRValueReferenceBefore(const RValueReferenceType *T,
472 raw_ostream &OS) {
473 IncludeStrongLifetimeRAII Strong(Policy);
474 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
475 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
476 printBefore(Inner, OS);
477 // Handle things like 'int (&&A)[4];' correctly.
478 // FIXME: this should include vectors, but vectors use attributes I guess.
479 if (isa<ArrayType>(Inner))
480 OS << '(';
481 OS << "&&";
482}
483
484void TypePrinter::printRValueReferenceAfter(const RValueReferenceType *T,
485 raw_ostream &OS) {
486 IncludeStrongLifetimeRAII Strong(Policy);
487 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
488 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
489 // Handle things like 'int (&&A)[4];' correctly.
490 // FIXME: this should include vectors, but vectors use attributes I guess.
491 if (isa<ArrayType>(Inner))
492 OS << ')';
493 printAfter(Inner, OS);
494}
495
496void TypePrinter::printMemberPointerBefore(const MemberPointerType *T,
497 raw_ostream &OS) {
498 IncludeStrongLifetimeRAII Strong(Policy);
499 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
500 printBefore(T->getPointeeType(), OS);
501 // Handle things like 'int (Cls::*A)[4];' correctly.
502 // FIXME: this should include vectors, but vectors use attributes I guess.
503 if (isa<ArrayType>(T->getPointeeType()))
504 OS << '(';
505
506 PrintingPolicy InnerPolicy(Policy);
507 InnerPolicy.IncludeTagDefinition = false;
508 TypePrinter(InnerPolicy).print(QualType(T->getClass(), 0), OS, StringRef());
509
510 OS << "::*";
511}
512
513void TypePrinter::printMemberPointerAfter(const MemberPointerType *T,
514 raw_ostream &OS) {
515 IncludeStrongLifetimeRAII Strong(Policy);
516 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
517 // Handle things like 'int (Cls::*A)[4];' correctly.
518 // FIXME: this should include vectors, but vectors use attributes I guess.
519 if (isa<ArrayType>(T->getPointeeType()))
520 OS << ')';
521 printAfter(T->getPointeeType(), OS);
522}
523
524void TypePrinter::printConstantArrayBefore(const ConstantArrayType *T,
525 raw_ostream &OS) {
526 IncludeStrongLifetimeRAII Strong(Policy);
527 printBefore(T->getElementType(), OS);
528}
529
530void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T,
531 raw_ostream &OS) {
532 OS << '[';
533 if (T->getIndexTypeQualifiers().hasQualifiers()) {
534 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(),
535 Policy.Restrict);
536 OS << ' ';
537 }
538
539 if (T->getSizeModifier() == ArraySizeModifier::Static)
540 OS << "static ";
541
542 OS << T->getZExtSize() << ']';
543 printAfter(T->getElementType(), OS);
544}
545
546void TypePrinter::printIncompleteArrayBefore(const IncompleteArrayType *T,
547 raw_ostream &OS) {
548 IncludeStrongLifetimeRAII Strong(Policy);
549 printBefore(T->getElementType(), OS);
550}
551
552void TypePrinter::printIncompleteArrayAfter(const IncompleteArrayType *T,
553 raw_ostream &OS) {
554 OS << "[]";
555 printAfter(T->getElementType(), OS);
556}
557
558void TypePrinter::printVariableArrayBefore(const VariableArrayType *T,
559 raw_ostream &OS) {
560 IncludeStrongLifetimeRAII Strong(Policy);
561 printBefore(T->getElementType(), OS);
562}
563
564void TypePrinter::printVariableArrayAfter(const VariableArrayType *T,
565 raw_ostream &OS) {
566 OS << '[';
567 if (T->getIndexTypeQualifiers().hasQualifiers()) {
568 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.Restrict);
569 OS << ' ';
570 }
571
572 if (T->getSizeModifier() == ArraySizeModifier::Static)
573 OS << "static ";
574 else if (T->getSizeModifier() == ArraySizeModifier::Star)
575 OS << '*';
576
577 if (T->getSizeExpr())
578 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
579 OS << ']';
580
581 printAfter(T->getElementType(), OS);
582}
583
584void TypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream &OS) {
585 // Print the adjusted representation, otherwise the adjustment will be
586 // invisible.
587 printBefore(T->getAdjustedType(), OS);
588}
589
590void TypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) {
591 printAfter(T->getAdjustedType(), OS);
592}
593
594void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {
595 // Print as though it's a pointer.
596 printAdjustedBefore(T, OS);
597}
598
599void TypePrinter::printArrayParameterAfter(const ArrayParameterType *T,
600 raw_ostream &OS) {
601 printConstantArrayAfter(T, OS);
602}
603
604void TypePrinter::printArrayParameterBefore(const ArrayParameterType *T,
605 raw_ostream &OS) {
606 printConstantArrayBefore(T, OS);
607}
608
609void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {
610 printAdjustedAfter(T, OS);
611}
612
613void TypePrinter::printDependentSizedArrayBefore(
615 raw_ostream &OS) {
616 IncludeStrongLifetimeRAII Strong(Policy);
617 printBefore(T->getElementType(), OS);
618}
619
620void TypePrinter::printDependentSizedArrayAfter(
622 raw_ostream &OS) {
623 OS << '[';
624 if (T->getSizeExpr())
625 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
626 OS << ']';
627 printAfter(T->getElementType(), OS);
628}
629
630void TypePrinter::printDependentAddressSpaceBefore(
631 const DependentAddressSpaceType *T, raw_ostream &OS) {
632 printBefore(T->getPointeeType(), OS);
633}
634
635void TypePrinter::printDependentAddressSpaceAfter(
636 const DependentAddressSpaceType *T, raw_ostream &OS) {
637 OS << " __attribute__((address_space(";
638 if (T->getAddrSpaceExpr())
639 T->getAddrSpaceExpr()->printPretty(OS, nullptr, Policy);
640 OS << ")))";
641 printAfter(T->getPointeeType(), OS);
642}
643
644void TypePrinter::printDependentSizedExtVectorBefore(
646 raw_ostream &OS) {
647 printBefore(T->getElementType(), OS);
648}
649
650void TypePrinter::printDependentSizedExtVectorAfter(
652 raw_ostream &OS) {
653 OS << " __attribute__((ext_vector_type(";
654 if (T->getSizeExpr())
655 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
656 OS << ")))";
657 printAfter(T->getElementType(), OS);
658}
659
660void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {
661 switch (T->getVectorKind()) {
662 case VectorKind::AltiVecPixel:
663 OS << "__vector __pixel ";
664 break;
665 case VectorKind::AltiVecBool:
666 OS << "__vector __bool ";
667 printBefore(T->getElementType(), OS);
668 break;
669 case VectorKind::AltiVecVector:
670 OS << "__vector ";
671 printBefore(T->getElementType(), OS);
672 break;
673 case VectorKind::Neon:
674 OS << "__attribute__((neon_vector_type("
675 << T->getNumElements() << "))) ";
676 printBefore(T->getElementType(), OS);
677 break;
678 case VectorKind::NeonPoly:
679 OS << "__attribute__((neon_polyvector_type(" <<
680 T->getNumElements() << "))) ";
681 printBefore(T->getElementType(), OS);
682 break;
683 case VectorKind::Generic: {
684 // FIXME: We prefer to print the size directly here, but have no way
685 // to get the size of the type.
686 OS << "__attribute__((__vector_size__("
687 << T->getNumElements()
688 << " * sizeof(";
689 print(T->getElementType(), OS, StringRef());
690 OS << ")))) ";
691 printBefore(T->getElementType(), OS);
692 break;
693 }
694 case VectorKind::SveFixedLengthData:
695 case VectorKind::SveFixedLengthPredicate:
696 // FIXME: We prefer to print the size directly here, but have no way
697 // to get the size of the type.
698 OS << "__attribute__((__arm_sve_vector_bits__(";
699
700 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
701 // Predicates take a bit per byte of the vector size, multiply by 8 to
702 // get the number of bits passed to the attribute.
703 OS << T->getNumElements() * 8;
704 else
705 OS << T->getNumElements();
706
707 OS << " * sizeof(";
708 print(T->getElementType(), OS, StringRef());
709 // Multiply by 8 for the number of bits.
710 OS << ") * 8))) ";
711 printBefore(T->getElementType(), OS);
712 break;
713 case VectorKind::RVVFixedLengthData:
714 case VectorKind::RVVFixedLengthMask:
715 // FIXME: We prefer to print the size directly here, but have no way
716 // to get the size of the type.
717 OS << "__attribute__((__riscv_rvv_vector_bits__(";
718
719 OS << T->getNumElements();
720
721 OS << " * sizeof(";
722 print(T->getElementType(), OS, StringRef());
723 // Multiply by 8 for the number of bits.
724 OS << ") * 8))) ";
725 printBefore(T->getElementType(), OS);
726 break;
727 }
728}
729
730void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) {
731 printAfter(T->getElementType(), OS);
732}
733
734void TypePrinter::printDependentVectorBefore(
735 const DependentVectorType *T, raw_ostream &OS) {
736 switch (T->getVectorKind()) {
737 case VectorKind::AltiVecPixel:
738 OS << "__vector __pixel ";
739 break;
740 case VectorKind::AltiVecBool:
741 OS << "__vector __bool ";
742 printBefore(T->getElementType(), OS);
743 break;
744 case VectorKind::AltiVecVector:
745 OS << "__vector ";
746 printBefore(T->getElementType(), OS);
747 break;
748 case VectorKind::Neon:
749 OS << "__attribute__((neon_vector_type(";
750 if (T->getSizeExpr())
751 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
752 OS << "))) ";
753 printBefore(T->getElementType(), OS);
754 break;
755 case VectorKind::NeonPoly:
756 OS << "__attribute__((neon_polyvector_type(";
757 if (T->getSizeExpr())
758 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
759 OS << "))) ";
760 printBefore(T->getElementType(), OS);
761 break;
762 case VectorKind::Generic: {
763 // FIXME: We prefer to print the size directly here, but have no way
764 // to get the size of the type.
765 OS << "__attribute__((__vector_size__(";
766 if (T->getSizeExpr())
767 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
768 OS << " * sizeof(";
769 print(T->getElementType(), OS, StringRef());
770 OS << ")))) ";
771 printBefore(T->getElementType(), OS);
772 break;
773 }
774 case VectorKind::SveFixedLengthData:
775 case VectorKind::SveFixedLengthPredicate:
776 // FIXME: We prefer to print the size directly here, but have no way
777 // to get the size of the type.
778 OS << "__attribute__((__arm_sve_vector_bits__(";
779 if (T->getSizeExpr()) {
780 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
781 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
782 // Predicates take a bit per byte of the vector size, multiply by 8 to
783 // get the number of bits passed to the attribute.
784 OS << " * 8";
785 OS << " * sizeof(";
786 print(T->getElementType(), OS, StringRef());
787 // Multiply by 8 for the number of bits.
788 OS << ") * 8";
789 }
790 OS << "))) ";
791 printBefore(T->getElementType(), OS);
792 break;
793 case VectorKind::RVVFixedLengthData:
794 case VectorKind::RVVFixedLengthMask:
795 // FIXME: We prefer to print the size directly here, but have no way
796 // to get the size of the type.
797 OS << "__attribute__((__riscv_rvv_vector_bits__(";
798 if (T->getSizeExpr()) {
799 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
800 OS << " * sizeof(";
801 print(T->getElementType(), OS, StringRef());
802 // Multiply by 8 for the number of bits.
803 OS << ") * 8";
804 }
805 OS << "))) ";
806 printBefore(T->getElementType(), OS);
807 break;
808 }
809}
810
811void TypePrinter::printDependentVectorAfter(
812 const DependentVectorType *T, raw_ostream &OS) {
813 printAfter(T->getElementType(), OS);
814}
815
816void TypePrinter::printExtVectorBefore(const ExtVectorType *T,
817 raw_ostream &OS) {
818 printBefore(T->getElementType(), OS);
819}
820
821void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) {
822 printAfter(T->getElementType(), OS);
823 OS << " __attribute__((ext_vector_type(";
824 OS << T->getNumElements();
825 OS << ")))";
826}
827
828void TypePrinter::printConstantMatrixBefore(const ConstantMatrixType *T,
829 raw_ostream &OS) {
830 printBefore(T->getElementType(), OS);
831 OS << " __attribute__((matrix_type(";
832 OS << T->getNumRows() << ", " << T->getNumColumns();
833 OS << ")))";
834}
835
836void TypePrinter::printConstantMatrixAfter(const ConstantMatrixType *T,
837 raw_ostream &OS) {
838 printAfter(T->getElementType(), OS);
839}
840
841void TypePrinter::printDependentSizedMatrixBefore(
842 const DependentSizedMatrixType *T, raw_ostream &OS) {
843 printBefore(T->getElementType(), OS);
844 OS << " __attribute__((matrix_type(";
845 if (T->getRowExpr()) {
846 T->getRowExpr()->printPretty(OS, nullptr, Policy);
847 }
848 OS << ", ";
849 if (T->getColumnExpr()) {
850 T->getColumnExpr()->printPretty(OS, nullptr, Policy);
851 }
852 OS << ")))";
853}
854
855void TypePrinter::printDependentSizedMatrixAfter(
856 const DependentSizedMatrixType *T, raw_ostream &OS) {
857 printAfter(T->getElementType(), OS);
858}
859
860void
862 const PrintingPolicy &Policy)
863 const {
865 OS << " throw(";
867 OS << "...";
868 else
869 for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) {
870 if (I)
871 OS << ", ";
872
873 OS << getExceptionType(I).stream(Policy);
874 }
875 OS << ')';
876 } else if (EST_NoThrow == getExceptionSpecType()) {
877 OS << " __attribute__((nothrow))";
879 OS << " noexcept";
880 // FIXME:Is it useful to print out the expression for a non-dependent
881 // noexcept specification?
883 OS << '(';
884 if (getNoexceptExpr())
885 getNoexceptExpr()->printPretty(OS, nullptr, Policy);
886 OS << ')';
887 }
888 }
889}
890
891void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,
892 raw_ostream &OS) {
893 if (T->hasTrailingReturn()) {
894 OS << "auto ";
895 if (!HasEmptyPlaceHolder)
896 OS << '(';
897 } else {
898 // If needed for precedence reasons, wrap the inner part in grouping parens.
899 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
900 printBefore(T->getReturnType(), OS);
901 if (!PrevPHIsEmpty.get())
902 OS << '(';
903 }
904}
905
907 switch (ABI) {
909 llvm_unreachable("asking for spelling of ordinary parameter ABI");
911 return "swift_context";
913 return "swift_async_context";
915 return "swift_error_result";
917 return "swift_indirect_result";
918 }
919 llvm_unreachable("bad parameter ABI kind");
920}
921
922void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
923 raw_ostream &OS) {
924 // If needed for precedence reasons, wrap the inner part in grouping parens.
925 if (!HasEmptyPlaceHolder)
926 OS << ')';
927 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
928
929 OS << '(';
930 {
931 ParamPolicyRAII ParamPolicy(Policy);
932 for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {
933 if (i) OS << ", ";
934
935 auto EPI = T->getExtParameterInfo(i);
936 if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) ";
937 if (EPI.isNoEscape())
938 OS << "__attribute__((noescape)) ";
939 auto ABI = EPI.getABI();
940 if (ABI != ParameterABI::Ordinary)
941 OS << "__attribute__((" << getParameterABISpelling(ABI) << ")) ";
942
943 print(T->getParamType(i), OS, StringRef());
944 }
945 }
946
947 if (T->isVariadic()) {
948 if (T->getNumParams())
949 OS << ", ";
950 OS << "...";
951 } else if (T->getNumParams() == 0 && Policy.UseVoidForZeroParams) {
952 // Do not emit int() if we have a proto, emit 'int(void)'.
953 OS << "void";
954 }
955
956 OS << ')';
957
959 unsigned SMEBits = T->getAArch64SMEAttributes();
960
962 OS << " __arm_streaming_compatible";
964 OS << " __arm_streaming";
966 OS << " __arm_preserves(\"za\")";
968 OS << " __arm_in(\"za\")";
970 OS << " __arm_out(\"za\")";
972 OS << " __arm_inout(\"za\")";
974 OS << " __arm_preserves(\"zt0\")";
976 OS << " __arm_in(\"zt0\")";
978 OS << " __arm_out(\"zt0\")";
980 OS << " __arm_inout(\"zt0\")";
981
982 printFunctionAfter(Info, OS);
983
984 if (!T->getMethodQuals().empty())
985 OS << " " << T->getMethodQuals().getAsString();
986
987 switch (T->getRefQualifier()) {
988 case RQ_None:
989 break;
990
991 case RQ_LValue:
992 OS << " &";
993 break;
994
995 case RQ_RValue:
996 OS << " &&";
997 break;
998 }
999 T->printExceptionSpecification(OS, Policy);
1000
1001 if (T->hasTrailingReturn()) {
1002 OS << " -> ";
1003 print(T->getReturnType(), OS, StringRef());
1004 } else
1005 printAfter(T->getReturnType(), OS);
1006}
1007
1008void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
1009 raw_ostream &OS) {
1010 if (!InsideCCAttribute) {
1011 switch (Info.getCC()) {
1012 case CC_C:
1013 // The C calling convention is the default on the vast majority of platforms
1014 // we support. If the user wrote it explicitly, it will usually be printed
1015 // while traversing the AttributedType. If the type has been desugared, let
1016 // the canonical spelling be the implicit calling convention.
1017 // FIXME: It would be better to be explicit in certain contexts, such as a
1018 // cdecl function typedef used to declare a member function with the
1019 // Microsoft C++ ABI.
1020 break;
1021 case CC_X86StdCall:
1022 OS << " __attribute__((stdcall))";
1023 break;
1024 case CC_X86FastCall:
1025 OS << " __attribute__((fastcall))";
1026 break;
1027 case CC_X86ThisCall:
1028 OS << " __attribute__((thiscall))";
1029 break;
1030 case CC_X86VectorCall:
1031 OS << " __attribute__((vectorcall))";
1032 break;
1033 case CC_X86Pascal:
1034 OS << " __attribute__((pascal))";
1035 break;
1036 case CC_AAPCS:
1037 OS << " __attribute__((pcs(\"aapcs\")))";
1038 break;
1039 case CC_AAPCS_VFP:
1040 OS << " __attribute__((pcs(\"aapcs-vfp\")))";
1041 break;
1043 OS << "__attribute__((aarch64_vector_pcs))";
1044 break;
1045 case CC_AArch64SVEPCS:
1046 OS << "__attribute__((aarch64_sve_pcs))";
1047 break;
1049 OS << "__attribute__((amdgpu_kernel))";
1050 break;
1051 case CC_IntelOclBicc:
1052 OS << " __attribute__((intel_ocl_bicc))";
1053 break;
1054 case CC_Win64:
1055 OS << " __attribute__((ms_abi))";
1056 break;
1057 case CC_X86_64SysV:
1058 OS << " __attribute__((sysv_abi))";
1059 break;
1060 case CC_X86RegCall:
1061 OS << " __attribute__((regcall))";
1062 break;
1063 case CC_SpirFunction:
1064 case CC_OpenCLKernel:
1065 // Do nothing. These CCs are not available as attributes.
1066 break;
1067 case CC_Swift:
1068 OS << " __attribute__((swiftcall))";
1069 break;
1070 case CC_SwiftAsync:
1071 OS << "__attribute__((swiftasynccall))";
1072 break;
1073 case CC_PreserveMost:
1074 OS << " __attribute__((preserve_most))";
1075 break;
1076 case CC_PreserveAll:
1077 OS << " __attribute__((preserve_all))";
1078 break;
1079 case CC_M68kRTD:
1080 OS << " __attribute__((m68k_rtd))";
1081 break;
1082 case CC_PreserveNone:
1083 OS << " __attribute__((preserve_none))";
1084 break;
1085 case CC_RISCVVectorCall:
1086 OS << "__attribute__((riscv_vector_cc))";
1087 break;
1088 }
1089 }
1090
1091 if (Info.getNoReturn())
1092 OS << " __attribute__((noreturn))";
1093 if (Info.getCmseNSCall())
1094 OS << " __attribute__((cmse_nonsecure_call))";
1095 if (Info.getProducesResult())
1096 OS << " __attribute__((ns_returns_retained))";
1097 if (Info.getRegParm())
1098 OS << " __attribute__((regparm ("
1099 << Info.getRegParm() << ")))";
1100 if (Info.getNoCallerSavedRegs())
1101 OS << " __attribute__((no_caller_saved_registers))";
1102 if (Info.getNoCfCheck())
1103 OS << " __attribute__((nocf_check))";
1104}
1105
1106void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T,
1107 raw_ostream &OS) {
1108 // If needed for precedence reasons, wrap the inner part in grouping parens.
1109 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
1110 printBefore(T->getReturnType(), OS);
1111 if (!PrevPHIsEmpty.get())
1112 OS << '(';
1113}
1114
1115void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,
1116 raw_ostream &OS) {
1117 // If needed for precedence reasons, wrap the inner part in grouping parens.
1118 if (!HasEmptyPlaceHolder)
1119 OS << ')';
1120 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
1121
1122 OS << "()";
1123 printFunctionAfter(T->getExtInfo(), OS);
1124 printAfter(T->getReturnType(), OS);
1125}
1126
1127void TypePrinter::printTypeSpec(NamedDecl *D, raw_ostream &OS) {
1128
1129 // Compute the full nested-name-specifier for this type.
1130 // In C, this will always be empty except when the type
1131 // being printed is anonymous within other Record.
1132 if (!Policy.SuppressScope)
1133 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1134
1135 IdentifierInfo *II = D->getIdentifier();
1136 OS << II->getName();
1137 spaceBeforePlaceHolder(OS);
1138}
1139
1140void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,
1141 raw_ostream &OS) {
1142 printTypeSpec(T->getDecl(), OS);
1143}
1144
1145void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,
1146 raw_ostream &OS) {}
1147
1148void TypePrinter::printUsingBefore(const UsingType *T, raw_ostream &OS) {
1149 // After `namespace b { using a::X }`, is the type X within B a::X or b::X?
1150 //
1151 // - b::X is more formally correct given the UsingType model
1152 // - b::X makes sense if "re-exporting" a symbol in a new namespace
1153 // - a::X makes sense if "importing" a symbol for convenience
1154 //
1155 // The "importing" use seems much more common, so we print a::X.
1156 // This could be a policy option, but the right choice seems to rest more
1157 // with the intent of the code than the caller.
1158 printTypeSpec(T->getFoundDecl()->getUnderlyingDecl(), OS);
1159}
1160
1161void TypePrinter::printUsingAfter(const UsingType *T, raw_ostream &OS) {}
1162
1163void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
1164 printTypeSpec(T->getDecl(), OS);
1165}
1166
1167void TypePrinter::printMacroQualifiedBefore(const MacroQualifiedType *T,
1168 raw_ostream &OS) {
1169 StringRef MacroName = T->getMacroIdentifier()->getName();
1170 OS << MacroName << " ";
1171
1172 // Since this type is meant to print the macro instead of the whole attribute,
1173 // we trim any attributes and go directly to the original modified type.
1174 printBefore(T->getModifiedType(), OS);
1175}
1176
1177void TypePrinter::printMacroQualifiedAfter(const MacroQualifiedType *T,
1178 raw_ostream &OS) {
1179 printAfter(T->getModifiedType(), OS);
1180}
1181
1182void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) {}
1183
1184void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
1185 raw_ostream &OS) {
1186 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual "
1187 : "typeof ");
1188 if (T->getUnderlyingExpr())
1189 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
1190 spaceBeforePlaceHolder(OS);
1191}
1192
1193void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
1194 raw_ostream &OS) {}
1195
1196void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) {
1197 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual("
1198 : "typeof(");
1199 print(T->getUnmodifiedType(), OS, StringRef());
1200 OS << ')';
1201 spaceBeforePlaceHolder(OS);
1202}
1203
1204void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) {}
1205
1206void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {
1207 OS << "decltype(";
1208 if (T->getUnderlyingExpr())
1209 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
1210 OS << ')';
1211 spaceBeforePlaceHolder(OS);
1212}
1213
1214void TypePrinter::printPackIndexingBefore(const PackIndexingType *T,
1215 raw_ostream &OS) {
1216 if (T->hasSelectedType()) {
1217 OS << T->getSelectedType();
1218 } else {
1219 OS << T->getPattern() << "...[";
1220 T->getIndexExpr()->printPretty(OS, nullptr, Policy);
1221 OS << "]";
1222 }
1223 spaceBeforePlaceHolder(OS);
1224}
1225
1226void TypePrinter::printPackIndexingAfter(const PackIndexingType *T,
1227 raw_ostream &OS) {}
1228
1229void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) {}
1230
1231void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,
1232 raw_ostream &OS) {
1233 IncludeStrongLifetimeRAII Strong(Policy);
1234
1235 static llvm::DenseMap<int, const char *> Transformation = {{
1236#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
1237 {UnaryTransformType::Enum, "__" #Trait},
1238#include "clang/Basic/TransformTypeTraits.def"
1239 }};
1240 OS << Transformation[T->getUTTKind()] << '(';
1241 print(T->getBaseType(), OS, StringRef());
1242 OS << ')';
1243 spaceBeforePlaceHolder(OS);
1244}
1245
1246void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,
1247 raw_ostream &OS) {}
1248
1249void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
1250 // If the type has been deduced, do not print 'auto'.
1251 if (!T->getDeducedType().isNull()) {
1252 printBefore(T->getDeducedType(), OS);
1253 } else {
1254 if (T->isConstrained()) {
1255 // FIXME: Track a TypeConstraint as type sugar, so that we can print the
1256 // type as it was written.
1257 T->getTypeConstraintConcept()->getDeclName().print(OS, Policy);
1258 auto Args = T->getTypeConstraintArguments();
1259 if (!Args.empty())
1261 OS, Args, Policy,
1262 T->getTypeConstraintConcept()->getTemplateParameters());
1263 OS << ' ';
1264 }
1265 switch (T->getKeyword()) {
1266 case AutoTypeKeyword::Auto: OS << "auto"; break;
1267 case AutoTypeKeyword::DecltypeAuto: OS << "decltype(auto)"; break;
1268 case AutoTypeKeyword::GNUAutoType: OS << "__auto_type"; break;
1269 }
1270 spaceBeforePlaceHolder(OS);
1271 }
1272}
1273
1274void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {
1275 // If the type has been deduced, do not print 'auto'.
1276 if (!T->getDeducedType().isNull())
1277 printAfter(T->getDeducedType(), OS);
1278}
1279
1280void TypePrinter::printDeducedTemplateSpecializationBefore(
1281 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1282 // If the type has been deduced, print the deduced type.
1283 if (!T->getDeducedType().isNull()) {
1284 printBefore(T->getDeducedType(), OS);
1285 } else {
1286 IncludeStrongLifetimeRAII Strong(Policy);
1287 T->getTemplateName().print(OS, Policy);
1288 spaceBeforePlaceHolder(OS);
1289 }
1290}
1291
1292void TypePrinter::printDeducedTemplateSpecializationAfter(
1293 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1294 // If the type has been deduced, print the deduced type.
1295 if (!T->getDeducedType().isNull())
1296 printAfter(T->getDeducedType(), OS);
1297}
1298
1299void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {
1300 IncludeStrongLifetimeRAII Strong(Policy);
1301
1302 OS << "_Atomic(";
1303 print(T->getValueType(), OS, StringRef());
1304 OS << ')';
1305 spaceBeforePlaceHolder(OS);
1306}
1307
1308void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) {}
1309
1310void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) {
1311 IncludeStrongLifetimeRAII Strong(Policy);
1312
1313 if (T->isReadOnly())
1314 OS << "read_only ";
1315 else
1316 OS << "write_only ";
1317 OS << "pipe ";
1318 print(T->getElementType(), OS, StringRef());
1319 spaceBeforePlaceHolder(OS);
1320}
1321
1322void TypePrinter::printPipeAfter(const PipeType *T, raw_ostream &OS) {}
1323
1324void TypePrinter::printBitIntBefore(const BitIntType *T, raw_ostream &OS) {
1325 if (T->isUnsigned())
1326 OS << "unsigned ";
1327 OS << "_BitInt(" << T->getNumBits() << ")";
1328 spaceBeforePlaceHolder(OS);
1329}
1330
1331void TypePrinter::printBitIntAfter(const BitIntType *T, raw_ostream &OS) {}
1332
1333void TypePrinter::printDependentBitIntBefore(const DependentBitIntType *T,
1334 raw_ostream &OS) {
1335 if (T->isUnsigned())
1336 OS << "unsigned ";
1337 OS << "_BitInt(";
1338 T->getNumBitsExpr()->printPretty(OS, nullptr, Policy);
1339 OS << ")";
1340 spaceBeforePlaceHolder(OS);
1341}
1342
1343void TypePrinter::printDependentBitIntAfter(const DependentBitIntType *T,
1344 raw_ostream &OS) {}
1345
1346/// Appends the given scope to the end of a string.
1347void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS,
1348 DeclarationName NameInScope) {
1349 if (DC->isTranslationUnit())
1350 return;
1351
1352 // FIXME: Consider replacing this with NamedDecl::printNestedNameSpecifier,
1353 // which can also print names for function and method scopes.
1354 if (DC->isFunctionOrMethod())
1355 return;
1356
1357 if (Policy.Callbacks && Policy.Callbacks->isScopeVisible(DC))
1358 return;
1359
1360 if (const auto *NS = dyn_cast<NamespaceDecl>(DC)) {
1361 if (Policy.SuppressUnwrittenScope && NS->isAnonymousNamespace())
1362 return AppendScope(DC->getParent(), OS, NameInScope);
1363
1364 // Only suppress an inline namespace if the name has the same lookup
1365 // results in the enclosing namespace.
1366 if (Policy.SuppressInlineNamespace && NS->isInline() && NameInScope &&
1367 NS->isRedundantInlineQualifierFor(NameInScope))
1368 return AppendScope(DC->getParent(), OS, NameInScope);
1369
1370 AppendScope(DC->getParent(), OS, NS->getDeclName());
1371 if (NS->getIdentifier())
1372 OS << NS->getName() << "::";
1373 else
1374 OS << "(anonymous namespace)::";
1375 } else if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
1376 AppendScope(DC->getParent(), OS, Spec->getDeclName());
1377 IncludeStrongLifetimeRAII Strong(Policy);
1378 OS << Spec->getIdentifier()->getName();
1379 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
1381 OS, TemplateArgs.asArray(), Policy,
1382 Spec->getSpecializedTemplate()->getTemplateParameters());
1383 OS << "::";
1384 } else if (const auto *Tag = dyn_cast<TagDecl>(DC)) {
1385 AppendScope(DC->getParent(), OS, Tag->getDeclName());
1386 if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl())
1387 OS << Typedef->getIdentifier()->getName() << "::";
1388 else if (Tag->getIdentifier())
1389 OS << Tag->getIdentifier()->getName() << "::";
1390 else
1391 return;
1392 } else {
1393 AppendScope(DC->getParent(), OS, NameInScope);
1394 }
1395}
1396
1397void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {
1398 if (Policy.IncludeTagDefinition) {
1399 PrintingPolicy SubPolicy = Policy;
1400 SubPolicy.IncludeTagDefinition = false;
1401 D->print(OS, SubPolicy, Indentation);
1402 spaceBeforePlaceHolder(OS);
1403 return;
1404 }
1405
1406 bool HasKindDecoration = false;
1407
1408 // We don't print tags unless this is an elaborated type.
1409 // In C, we just assume every RecordType is an elaborated type.
1410 if (!Policy.SuppressTagKeyword && !D->getTypedefNameForAnonDecl()) {
1411 HasKindDecoration = true;
1412 OS << D->getKindName();
1413 OS << ' ';
1414 }
1415
1416 // Compute the full nested-name-specifier for this type.
1417 // In C, this will always be empty except when the type
1418 // being printed is anonymous within other Record.
1419 if (!Policy.SuppressScope)
1420 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1421
1422 if (const IdentifierInfo *II = D->getIdentifier())
1423 OS << II->getName();
1424 else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) {
1425 assert(Typedef->getIdentifier() && "Typedef without identifier?");
1426 OS << Typedef->getIdentifier()->getName();
1427 } else {
1428 // Make an unambiguous representation for anonymous types, e.g.
1429 // (anonymous enum at /usr/include/string.h:120:9)
1430 OS << (Policy.MSVCFormatting ? '`' : '(');
1431
1432 if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
1433 OS << "lambda";
1434 HasKindDecoration = true;
1435 } else if ((isa<RecordDecl>(D) && cast<RecordDecl>(D)->isAnonymousStructOrUnion())) {
1436 OS << "anonymous";
1437 } else {
1438 OS << "unnamed";
1439 }
1440
1441 if (Policy.AnonymousTagLocations) {
1442 // Suppress the redundant tag keyword if we just printed one.
1443 // We don't have to worry about ElaboratedTypes here because you can't
1444 // refer to an anonymous type with one.
1445 if (!HasKindDecoration)
1446 OS << " " << D->getKindName();
1447
1449 D->getLocation());
1450 if (PLoc.isValid()) {
1451 OS << " at ";
1452 StringRef File = PLoc.getFilename();
1453 llvm::SmallString<1024> WrittenFile(File);
1454 if (auto *Callbacks = Policy.Callbacks)
1455 WrittenFile = Callbacks->remapPath(File);
1456 // Fix inconsistent path separator created by
1457 // clang::DirectoryLookup::LookupFile when the file path is relative
1458 // path.
1459 llvm::sys::path::Style Style =
1460 llvm::sys::path::is_absolute(WrittenFile)
1461 ? llvm::sys::path::Style::native
1462 : (Policy.MSVCFormatting
1463 ? llvm::sys::path::Style::windows_backslash
1464 : llvm::sys::path::Style::posix);
1465 llvm::sys::path::native(WrittenFile, Style);
1466 OS << WrittenFile << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
1467 }
1468 }
1469
1470 OS << (Policy.MSVCFormatting ? '\'' : ')');
1471 }
1472
1473 // If this is a class template specialization, print the template
1474 // arguments.
1475 if (auto *S = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1476 const TemplateParameterList *TParams =
1477 S->getSpecializedTemplate()->getTemplateParameters();
1478 const ASTTemplateArgumentListInfo *TArgAsWritten =
1479 S->getTemplateArgsAsWritten();
1480 IncludeStrongLifetimeRAII Strong(Policy);
1481 if (TArgAsWritten && !Policy.PrintCanonicalTypes)
1482 printTemplateArgumentList(OS, TArgAsWritten->arguments(), Policy,
1483 TParams);
1484 else
1485 printTemplateArgumentList(OS, S->getTemplateArgs().asArray(), Policy,
1486 TParams);
1487 }
1488
1489 spaceBeforePlaceHolder(OS);
1490}
1491
1492void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
1493 // Print the preferred name if we have one for this type.
1494 if (Policy.UsePreferredNames) {
1495 for (const auto *PNA : T->getDecl()->specific_attrs<PreferredNameAttr>()) {
1496 if (!declaresSameEntity(PNA->getTypedefType()->getAsCXXRecordDecl(),
1497 T->getDecl()))
1498 continue;
1499 // Find the outermost typedef or alias template.
1500 QualType T = PNA->getTypedefType();
1501 while (true) {
1502 if (auto *TT = dyn_cast<TypedefType>(T))
1503 return printTypeSpec(TT->getDecl(), OS);
1504 if (auto *TST = dyn_cast<TemplateSpecializationType>(T))
1505 return printTemplateId(TST, OS, /*FullyQualify=*/true);
1507 }
1508 }
1509 }
1510
1511 printTag(T->getDecl(), OS);
1512}
1513
1514void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) {}
1515
1516void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {
1517 printTag(T->getDecl(), OS);
1518}
1519
1520void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {}
1521
1522void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
1523 raw_ostream &OS) {
1524 TemplateTypeParmDecl *D = T->getDecl();
1525 if (D && D->isImplicit()) {
1526 if (auto *TC = D->getTypeConstraint()) {
1527 TC->print(OS, Policy);
1528 OS << ' ';
1529 }
1530 OS << "auto";
1531 } else if (IdentifierInfo *Id = T->getIdentifier())
1532 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1533 : Id->getName());
1534 else
1535 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
1536
1537 spaceBeforePlaceHolder(OS);
1538}
1539
1540void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,
1541 raw_ostream &OS) {}
1542
1543void TypePrinter::printSubstTemplateTypeParmBefore(
1545 raw_ostream &OS) {
1546 IncludeStrongLifetimeRAII Strong(Policy);
1547 printBefore(T->getReplacementType(), OS);
1548}
1549
1550void TypePrinter::printSubstTemplateTypeParmAfter(
1552 raw_ostream &OS) {
1553 IncludeStrongLifetimeRAII Strong(Policy);
1554 printAfter(T->getReplacementType(), OS);
1555}
1556
1557void TypePrinter::printSubstTemplateTypeParmPackBefore(
1559 raw_ostream &OS) {
1560 IncludeStrongLifetimeRAII Strong(Policy);
1561 if (const TemplateTypeParmDecl *D = T->getReplacedParameter()) {
1562 if (D && D->isImplicit()) {
1563 if (auto *TC = D->getTypeConstraint()) {
1564 TC->print(OS, Policy);
1565 OS << ' ';
1566 }
1567 OS << "auto";
1568 } else if (IdentifierInfo *Id = D->getIdentifier())
1569 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1570 : Id->getName());
1571 else
1572 OS << "type-parameter-" << D->getDepth() << '-' << D->getIndex();
1573
1574 spaceBeforePlaceHolder(OS);
1575 }
1576}
1577
1578void TypePrinter::printSubstTemplateTypeParmPackAfter(
1580 raw_ostream &OS) {
1581 IncludeStrongLifetimeRAII Strong(Policy);
1582}
1583
1584void TypePrinter::printTemplateId(const TemplateSpecializationType *T,
1585 raw_ostream &OS, bool FullyQualify) {
1586 IncludeStrongLifetimeRAII Strong(Policy);
1587
1588 TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl();
1589 // FIXME: Null TD never excercised in test suite.
1590 if (FullyQualify && TD) {
1591 if (!Policy.SuppressScope)
1592 AppendScope(TD->getDeclContext(), OS, TD->getDeclName());
1593
1594 OS << TD->getName();
1595 } else {
1596 T->getTemplateName().print(OS, Policy);
1597 }
1598
1599 DefaultTemplateArgsPolicyRAII TemplateArgs(Policy);
1600 const TemplateParameterList *TPL = TD ? TD->getTemplateParameters() : nullptr;
1601 printTemplateArgumentList(OS, T->template_arguments(), Policy, TPL);
1602 spaceBeforePlaceHolder(OS);
1603}
1604
1605void TypePrinter::printTemplateSpecializationBefore(
1607 raw_ostream &OS) {
1608 printTemplateId(T, OS, Policy.FullyQualifiedName);
1609}
1610
1611void TypePrinter::printTemplateSpecializationAfter(
1613 raw_ostream &OS) {}
1614
1615void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
1616 raw_ostream &OS) {
1617 if (Policy.PrintInjectedClassNameWithArguments)
1618 return printTemplateSpecializationBefore(T->getInjectedTST(), OS);
1619
1620 IncludeStrongLifetimeRAII Strong(Policy);
1621 T->getTemplateName().print(OS, Policy);
1622 spaceBeforePlaceHolder(OS);
1623}
1624
1625void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
1626 raw_ostream &OS) {}
1627
1628void TypePrinter::printElaboratedBefore(const ElaboratedType *T,
1629 raw_ostream &OS) {
1630 if (Policy.IncludeTagDefinition && T->getOwnedTagDecl()) {
1631 TagDecl *OwnedTagDecl = T->getOwnedTagDecl();
1632 assert(OwnedTagDecl->getTypeForDecl() == T->getNamedType().getTypePtr() &&
1633 "OwnedTagDecl expected to be a declaration for the type");
1634 PrintingPolicy SubPolicy = Policy;
1635 SubPolicy.IncludeTagDefinition = false;
1636 OwnedTagDecl->print(OS, SubPolicy, Indentation);
1637 spaceBeforePlaceHolder(OS);
1638 return;
1639 }
1640
1641 if (Policy.SuppressElaboration) {
1642 printBefore(T->getNamedType(), OS);
1643 return;
1644 }
1645
1646 // The tag definition will take care of these.
1647 if (!Policy.IncludeTagDefinition)
1648 {
1649 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1650 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1651 OS << " ";
1652 NestedNameSpecifier *Qualifier = T->getQualifier();
1653 if (!Policy.SuppressTagKeyword && Policy.SuppressScope &&
1654 !Policy.SuppressUnwrittenScope) {
1655 bool OldTagKeyword = Policy.SuppressTagKeyword;
1656 bool OldSupressScope = Policy.SuppressScope;
1657 Policy.SuppressTagKeyword = true;
1658 Policy.SuppressScope = false;
1659 printBefore(T->getNamedType(), OS);
1660 Policy.SuppressTagKeyword = OldTagKeyword;
1661 Policy.SuppressScope = OldSupressScope;
1662 return;
1663 }
1664 if (Qualifier)
1665 Qualifier->print(OS, Policy);
1666 }
1667
1668 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1669 printBefore(T->getNamedType(), OS);
1670}
1671
1672void TypePrinter::printElaboratedAfter(const ElaboratedType *T,
1673 raw_ostream &OS) {
1674 if (Policy.IncludeTagDefinition && T->getOwnedTagDecl())
1675 return;
1676
1677 if (Policy.SuppressElaboration) {
1678 printAfter(T->getNamedType(), OS);
1679 return;
1680 }
1681
1682 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1683 printAfter(T->getNamedType(), OS);
1684}
1685
1686void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {
1687 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1688 printBefore(T->getInnerType(), OS);
1689 OS << '(';
1690 } else
1691 printBefore(T->getInnerType(), OS);
1692}
1693
1694void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {
1695 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1696 OS << ')';
1697 printAfter(T->getInnerType(), OS);
1698 } else
1699 printAfter(T->getInnerType(), OS);
1700}
1701
1702void TypePrinter::printDependentNameBefore(const DependentNameType *T,
1703 raw_ostream &OS) {
1704 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1705 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1706 OS << " ";
1707
1708 T->getQualifier()->print(OS, Policy);
1709
1710 OS << T->getIdentifier()->getName();
1711 spaceBeforePlaceHolder(OS);
1712}
1713
1714void TypePrinter::printDependentNameAfter(const DependentNameType *T,
1715 raw_ostream &OS) {}
1716
1717void TypePrinter::printDependentTemplateSpecializationBefore(
1718 const DependentTemplateSpecializationType *T, raw_ostream &OS) {
1719 IncludeStrongLifetimeRAII Strong(Policy);
1720
1721 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1722 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1723 OS << " ";
1724
1725 if (T->getQualifier())
1726 T->getQualifier()->print(OS, Policy);
1727 OS << "template " << T->getIdentifier()->getName();
1728 printTemplateArgumentList(OS, T->template_arguments(), Policy);
1729 spaceBeforePlaceHolder(OS);
1730}
1731
1732void TypePrinter::printDependentTemplateSpecializationAfter(
1733 const DependentTemplateSpecializationType *T, raw_ostream &OS) {}
1734
1735void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,
1736 raw_ostream &OS) {
1737 printBefore(T->getPattern(), OS);
1738}
1739
1740void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
1741 raw_ostream &OS) {
1742 printAfter(T->getPattern(), OS);
1743 OS << "...";
1744}
1745
1747 raw_ostream &OS,
1748 const PrintingPolicy &Policy) {
1749 OS << ' ';
1750 if (T->isCountInBytes() && T->isOrNull())
1751 OS << "__sized_by_or_null(";
1752 else if (T->isCountInBytes())
1753 OS << "__sized_by(";
1754 else if (T->isOrNull())
1755 OS << "__counted_by_or_null(";
1756 else
1757 OS << "__counted_by(";
1758 if (T->getCountExpr())
1759 T->getCountExpr()->printPretty(OS, nullptr, Policy);
1760 OS << ')';
1761}
1762
1763void TypePrinter::printCountAttributedBefore(const CountAttributedType *T,
1764 raw_ostream &OS) {
1765 printBefore(T->desugar(), OS);
1766 if (!T->isArrayType())
1767 printCountAttributedImpl(T, OS, Policy);
1768}
1769
1770void TypePrinter::printCountAttributedAfter(const CountAttributedType *T,
1771 raw_ostream &OS) {
1772 printAfter(T->desugar(), OS);
1773 if (T->isArrayType())
1774 printCountAttributedImpl(T, OS, Policy);
1775}
1776
1777void TypePrinter::printAttributedBefore(const AttributedType *T,
1778 raw_ostream &OS) {
1779 // FIXME: Generate this with TableGen.
1780
1781 // Prefer the macro forms of the GC and ownership qualifiers.
1782 if (T->getAttrKind() == attr::ObjCGC ||
1783 T->getAttrKind() == attr::ObjCOwnership)
1784 return printBefore(T->getEquivalentType(), OS);
1785
1786 if (T->getAttrKind() == attr::ObjCKindOf)
1787 OS << "__kindof ";
1788
1789 if (T->getAttrKind() == attr::AddressSpace)
1790 printBefore(T->getEquivalentType(), OS);
1791 else
1792 printBefore(T->getModifiedType(), OS);
1793
1794 if (T->isMSTypeSpec()) {
1795 switch (T->getAttrKind()) {
1796 default: return;
1797 case attr::Ptr32: OS << " __ptr32"; break;
1798 case attr::Ptr64: OS << " __ptr64"; break;
1799 case attr::SPtr: OS << " __sptr"; break;
1800 case attr::UPtr: OS << " __uptr"; break;
1801 }
1802 spaceBeforePlaceHolder(OS);
1803 }
1804
1805 if (T->isWebAssemblyFuncrefSpec())
1806 OS << "__funcref";
1807
1808 // Print nullability type specifiers.
1809 if (T->getImmediateNullability()) {
1810 if (T->getAttrKind() == attr::TypeNonNull)
1811 OS << " _Nonnull";
1812 else if (T->getAttrKind() == attr::TypeNullable)
1813 OS << " _Nullable";
1814 else if (T->getAttrKind() == attr::TypeNullUnspecified)
1815 OS << " _Null_unspecified";
1816 else if (T->getAttrKind() == attr::TypeNullableResult)
1817 OS << " _Nullable_result";
1818 else
1819 llvm_unreachable("unhandled nullability");
1820 spaceBeforePlaceHolder(OS);
1821 }
1822}
1823
1824void TypePrinter::printAttributedAfter(const AttributedType *T,
1825 raw_ostream &OS) {
1826 // FIXME: Generate this with TableGen.
1827
1828 // Prefer the macro forms of the GC and ownership qualifiers.
1829 if (T->getAttrKind() == attr::ObjCGC ||
1830 T->getAttrKind() == attr::ObjCOwnership)
1831 return printAfter(T->getEquivalentType(), OS);
1832
1833 // If this is a calling convention attribute, don't print the implicit CC from
1834 // the modified type.
1835 SaveAndRestore MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());
1836
1837 printAfter(T->getModifiedType(), OS);
1838
1839 // Some attributes are printed as qualifiers before the type, so we have
1840 // nothing left to do.
1841 if (T->getAttrKind() == attr::ObjCKindOf || T->isMSTypeSpec() ||
1842 T->getImmediateNullability() || T->isWebAssemblyFuncrefSpec())
1843 return;
1844
1845 // Don't print the inert __unsafe_unretained attribute at all.
1846 if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained)
1847 return;
1848
1849 // Don't print ns_returns_retained unless it had an effect.
1850 if (T->getAttrKind() == attr::NSReturnsRetained &&
1851 !T->getEquivalentType()->castAs<FunctionType>()
1853 return;
1854
1855 if (T->getAttrKind() == attr::LifetimeBound) {
1856 OS << " [[clang::lifetimebound]]";
1857 return;
1858 }
1859
1860 // The printing of the address_space attribute is handled by the qualifier
1861 // since it is still stored in the qualifier. Return early to prevent printing
1862 // this twice.
1863 if (T->getAttrKind() == attr::AddressSpace)
1864 return;
1865
1866 if (T->getAttrKind() == attr::AnnotateType) {
1867 // FIXME: Print the attribute arguments once we have a way to retrieve these
1868 // here. For the meantime, we just print `[[clang::annotate_type(...)]]`
1869 // without the arguments so that we know at least that we had _some_
1870 // annotation on the type.
1871 OS << " [[clang::annotate_type(...)]]";
1872 return;
1873 }
1874
1875 if (T->getAttrKind() == attr::ArmStreaming) {
1876 OS << "__arm_streaming";
1877 return;
1878 }
1879 if (T->getAttrKind() == attr::ArmStreamingCompatible) {
1880 OS << "__arm_streaming_compatible";
1881 return;
1882 }
1883
1884 OS << " __attribute__((";
1885 switch (T->getAttrKind()) {
1886#define TYPE_ATTR(NAME)
1887#define DECL_OR_TYPE_ATTR(NAME)
1888#define ATTR(NAME) case attr::NAME:
1889#include "clang/Basic/AttrList.inc"
1890 llvm_unreachable("non-type attribute attached to type");
1891
1892 case attr::BTFTypeTag:
1893 llvm_unreachable("BTFTypeTag attribute handled separately");
1894
1895 case attr::OpenCLPrivateAddressSpace:
1896 case attr::OpenCLGlobalAddressSpace:
1897 case attr::OpenCLGlobalDeviceAddressSpace:
1898 case attr::OpenCLGlobalHostAddressSpace:
1899 case attr::OpenCLLocalAddressSpace:
1900 case attr::OpenCLConstantAddressSpace:
1901 case attr::OpenCLGenericAddressSpace:
1902 case attr::HLSLGroupSharedAddressSpace:
1903 // FIXME: Update printAttributedBefore to print these once we generate
1904 // AttributedType nodes for them.
1905 break;
1906
1907 case attr::CountedBy:
1908 case attr::LifetimeBound:
1909 case attr::TypeNonNull:
1910 case attr::TypeNullable:
1911 case attr::TypeNullableResult:
1912 case attr::TypeNullUnspecified:
1913 case attr::ObjCGC:
1914 case attr::ObjCInertUnsafeUnretained:
1915 case attr::ObjCKindOf:
1916 case attr::ObjCOwnership:
1917 case attr::Ptr32:
1918 case attr::Ptr64:
1919 case attr::SPtr:
1920 case attr::UPtr:
1921 case attr::AddressSpace:
1922 case attr::CmseNSCall:
1923 case attr::AnnotateType:
1924 case attr::WebAssemblyFuncref:
1925 case attr::ArmStreaming:
1926 case attr::ArmStreamingCompatible:
1927 case attr::ArmIn:
1928 case attr::ArmOut:
1929 case attr::ArmInOut:
1930 case attr::ArmPreserves:
1931 llvm_unreachable("This attribute should have been handled already");
1932
1933 case attr::NSReturnsRetained:
1934 OS << "ns_returns_retained";
1935 break;
1936
1937 // FIXME: When Sema learns to form this AttributedType, avoid printing the
1938 // attribute again in printFunctionProtoAfter.
1939 case attr::AnyX86NoCfCheck: OS << "nocf_check"; break;
1940 case attr::CDecl: OS << "cdecl"; break;
1941 case attr::FastCall: OS << "fastcall"; break;
1942 case attr::StdCall: OS << "stdcall"; break;
1943 case attr::ThisCall: OS << "thiscall"; break;
1944 case attr::SwiftCall: OS << "swiftcall"; break;
1945 case attr::SwiftAsyncCall: OS << "swiftasynccall"; break;
1946 case attr::VectorCall: OS << "vectorcall"; break;
1947 case attr::Pascal: OS << "pascal"; break;
1948 case attr::MSABI: OS << "ms_abi"; break;
1949 case attr::SysVABI: OS << "sysv_abi"; break;
1950 case attr::RegCall: OS << "regcall"; break;
1951 case attr::Pcs: {
1952 OS << "pcs(";
1953 QualType t = T->getEquivalentType();
1954 while (!t->isFunctionType())
1955 t = t->getPointeeType();
1956 OS << (t->castAs<FunctionType>()->getCallConv() == CC_AAPCS ?
1957 "\"aapcs\"" : "\"aapcs-vfp\"");
1958 OS << ')';
1959 break;
1960 }
1961 case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break;
1962 case attr::AArch64SVEPcs: OS << "aarch64_sve_pcs"; break;
1963 case attr::AMDGPUKernelCall: OS << "amdgpu_kernel"; break;
1964 case attr::IntelOclBicc: OS << "inteloclbicc"; break;
1965 case attr::PreserveMost:
1966 OS << "preserve_most";
1967 break;
1968
1969 case attr::PreserveAll:
1970 OS << "preserve_all";
1971 break;
1972 case attr::M68kRTD:
1973 OS << "m68k_rtd";
1974 break;
1975 case attr::PreserveNone:
1976 OS << "preserve_none";
1977 break;
1978 case attr::RISCVVectorCC:
1979 OS << "riscv_vector_cc";
1980 break;
1981 case attr::NoDeref:
1982 OS << "noderef";
1983 break;
1984 case attr::AcquireHandle:
1985 OS << "acquire_handle";
1986 break;
1987 case attr::ArmMveStrictPolymorphism:
1988 OS << "__clang_arm_mve_strict_polymorphism";
1989 break;
1990
1991 // Nothing to print for this attribute.
1992 case attr::HLSLParamModifier:
1993 break;
1994 }
1995 OS << "))";
1996}
1997
1998void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T,
1999 raw_ostream &OS) {
2000 printBefore(T->getWrappedType(), OS);
2001 OS << " __attribute__((btf_type_tag(\"" << T->getAttr()->getBTFTypeTag() << "\")))";
2002}
2003
2004void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,
2005 raw_ostream &OS) {
2006 printAfter(T->getWrappedType(), OS);
2007}
2008
2009void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
2010 raw_ostream &OS) {
2011 OS << T->getDecl()->getName();
2012 spaceBeforePlaceHolder(OS);
2013}
2014
2015void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
2016 raw_ostream &OS) {}
2017
2018void TypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType *T,
2019 raw_ostream &OS) {
2020 OS << T->getDecl()->getName();
2021 if (!T->qual_empty()) {
2022 bool isFirst = true;
2023 OS << '<';
2024 for (const auto *I : T->quals()) {
2025 if (isFirst)
2026 isFirst = false;
2027 else
2028 OS << ',';
2029 OS << I->getName();
2030 }
2031 OS << '>';
2032 }
2033
2034 spaceBeforePlaceHolder(OS);
2035}
2036
2037void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T,
2038 raw_ostream &OS) {}
2039
2040void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
2041 raw_ostream &OS) {
2042 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2043 !T->isKindOfTypeAsWritten())
2044 return printBefore(T->getBaseType(), OS);
2045
2046 if (T->isKindOfTypeAsWritten())
2047 OS << "__kindof ";
2048
2049 print(T->getBaseType(), OS, StringRef());
2050
2051 if (T->isSpecializedAsWritten()) {
2052 bool isFirst = true;
2053 OS << '<';
2054 for (auto typeArg : T->getTypeArgsAsWritten()) {
2055 if (isFirst)
2056 isFirst = false;
2057 else
2058 OS << ",";
2059
2060 print(typeArg, OS, StringRef());
2061 }
2062 OS << '>';
2063 }
2064
2065 if (!T->qual_empty()) {
2066 bool isFirst = true;
2067 OS << '<';
2068 for (const auto *I : T->quals()) {
2069 if (isFirst)
2070 isFirst = false;
2071 else
2072 OS << ',';
2073 OS << I->getName();
2074 }
2075 OS << '>';
2076 }
2077
2078 spaceBeforePlaceHolder(OS);
2079}
2080
2081void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
2082 raw_ostream &OS) {
2083 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2084 !T->isKindOfTypeAsWritten())
2085 return printAfter(T->getBaseType(), OS);
2086}
2087
2088void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
2089 raw_ostream &OS) {
2090 printBefore(T->getPointeeType(), OS);
2091
2092 // If we need to print the pointer, print it now.
2093 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&
2095 if (HasEmptyPlaceHolder)
2096 OS << ' ';
2097 OS << '*';
2098 }
2099}
2100
2101void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
2102 raw_ostream &OS) {}
2103
2104static
2105const TemplateArgument &getArgument(const TemplateArgument &A) { return A; }
2106
2108 return A.getArgument();
2109}
2110
2111static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP,
2112 llvm::raw_ostream &OS, bool IncludeType) {
2113 A.print(PP, OS, IncludeType);
2114}
2115
2117 const PrintingPolicy &PP, llvm::raw_ostream &OS,
2118 bool IncludeType) {
2119 const TemplateArgument::ArgKind &Kind = A.getArgument().getKind();
2121 return A.getTypeSourceInfo()->getType().print(OS, PP);
2122 return A.getArgument().print(PP, OS, IncludeType);
2123}
2124
2126 TemplateArgument Pattern,
2128 unsigned Depth);
2129
2131 ArrayRef<TemplateArgument> Args, unsigned Depth) {
2132 if (Ctx.hasSameType(T, Pattern))
2133 return true;
2134
2135 // A type parameter matches its argument.
2136 if (auto *TTPT = Pattern->getAs<TemplateTypeParmType>()) {
2137 if (TTPT->getDepth() == Depth && TTPT->getIndex() < Args.size() &&
2138 Args[TTPT->getIndex()].getKind() == TemplateArgument::Type) {
2139 QualType SubstArg = Ctx.getQualifiedType(
2140 Args[TTPT->getIndex()].getAsType(), Pattern.getQualifiers());
2141 return Ctx.hasSameType(SubstArg, T);
2142 }
2143 return false;
2144 }
2145
2146 // FIXME: Recurse into array types.
2147
2148 // All other cases will need the types to be identically qualified.
2149 Qualifiers TQual, PatQual;
2150 T = Ctx.getUnqualifiedArrayType(T, TQual);
2151 Pattern = Ctx.getUnqualifiedArrayType(Pattern, PatQual);
2152 if (TQual != PatQual)
2153 return false;
2154
2155 // Recurse into pointer-like types.
2156 {
2157 QualType TPointee = T->getPointeeType();
2158 QualType PPointee = Pattern->getPointeeType();
2159 if (!TPointee.isNull() && !PPointee.isNull())
2160 return T->getTypeClass() == Pattern->getTypeClass() &&
2161 isSubstitutedType(Ctx, TPointee, PPointee, Args, Depth);
2162 }
2163
2164 // Recurse into template specialization types.
2165 if (auto *PTST =
2167 TemplateName Template;
2168 ArrayRef<TemplateArgument> TemplateArgs;
2169 if (auto *TTST = T->getAs<TemplateSpecializationType>()) {
2170 Template = TTST->getTemplateName();
2171 TemplateArgs = TTST->template_arguments();
2172 } else if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
2173 T->getAsCXXRecordDecl())) {
2174 Template = TemplateName(CTSD->getSpecializedTemplate());
2175 TemplateArgs = CTSD->getTemplateArgs().asArray();
2176 } else {
2177 return false;
2178 }
2179
2180 if (!isSubstitutedTemplateArgument(Ctx, Template, PTST->getTemplateName(),
2181 Args, Depth))
2182 return false;
2183 if (TemplateArgs.size() != PTST->template_arguments().size())
2184 return false;
2185 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
2187 Ctx, TemplateArgs[I], PTST->template_arguments()[I], Args, Depth))
2188 return false;
2189 return true;
2190 }
2191
2192 // FIXME: Handle more cases.
2193 return false;
2194}
2195
2196/// Evaluates the expression template argument 'Pattern' and returns true
2197/// if 'Arg' evaluates to the same result.
2199 TemplateArgument const &Pattern,
2200 TemplateArgument const &Arg) {
2201 if (Pattern.getKind() != TemplateArgument::Expression)
2202 return false;
2203
2204 // Can't evaluate value-dependent expressions so bail early
2205 Expr const *pattern_expr = Pattern.getAsExpr();
2206 if (pattern_expr->isValueDependent() ||
2207 !pattern_expr->isIntegerConstantExpr(Ctx))
2208 return false;
2209
2211 return llvm::APSInt::isSameValue(pattern_expr->EvaluateKnownConstInt(Ctx),
2212 Arg.getAsIntegral());
2213
2215 Expr const *args_expr = Arg.getAsExpr();
2216 if (args_expr->isValueDependent() || !args_expr->isIntegerConstantExpr(Ctx))
2217 return false;
2218
2219 return llvm::APSInt::isSameValue(args_expr->EvaluateKnownConstInt(Ctx),
2220 pattern_expr->EvaluateKnownConstInt(Ctx));
2221 }
2222
2223 return false;
2224}
2225
2227 TemplateArgument Pattern,
2229 unsigned Depth) {
2230 Arg = Ctx.getCanonicalTemplateArgument(Arg);
2231 Pattern = Ctx.getCanonicalTemplateArgument(Pattern);
2232 if (Arg.structurallyEquals(Pattern))
2233 return true;
2234
2235 if (Pattern.getKind() == TemplateArgument::Expression) {
2236 if (auto *DRE =
2237 dyn_cast<DeclRefExpr>(Pattern.getAsExpr()->IgnoreParenImpCasts())) {
2238 if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
2239 return NTTP->getDepth() == Depth && Args.size() > NTTP->getIndex() &&
2240 Args[NTTP->getIndex()].structurallyEquals(Arg);
2241 }
2242 }
2243
2244 if (templateArgumentExpressionsEqual(Ctx, Pattern, Arg))
2245 return true;
2246
2247 if (Arg.getKind() != Pattern.getKind())
2248 return false;
2249
2250 if (Arg.getKind() == TemplateArgument::Type)
2251 return isSubstitutedType(Ctx, Arg.getAsType(), Pattern.getAsType(), Args,
2252 Depth);
2253
2254 if (Arg.getKind() == TemplateArgument::Template) {
2255 TemplateDecl *PatTD = Pattern.getAsTemplate().getAsTemplateDecl();
2256 if (auto *TTPD = dyn_cast_or_null<TemplateTemplateParmDecl>(PatTD))
2257 return TTPD->getDepth() == Depth && Args.size() > TTPD->getIndex() &&
2258 Ctx.getCanonicalTemplateArgument(Args[TTPD->getIndex()])
2259 .structurallyEquals(Arg);
2260 }
2261
2262 // FIXME: Handle more cases.
2263 return false;
2264}
2265
2267 const NamedDecl *Param,
2269 unsigned Depth) {
2270 // An empty pack is equivalent to not providing a pack argument.
2271 if (Arg.getKind() == TemplateArgument::Pack && Arg.pack_size() == 0)
2272 return true;
2273
2274 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Param)) {
2275 return TTPD->hasDefaultArgument() &&
2276 isSubstitutedTemplateArgument(Ctx, Arg, TTPD->getDefaultArgument(),
2277 Args, Depth);
2278 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
2279 return TTPD->hasDefaultArgument() &&
2281 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2282 } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
2283 return NTTPD->hasDefaultArgument() &&
2284 isSubstitutedTemplateArgument(Ctx, Arg, NTTPD->getDefaultArgument(),
2285 Args, Depth);
2286 }
2287 return false;
2288}
2289
2290template <typename TA>
2291static void
2292printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy,
2293 const TemplateParameterList *TPL, bool IsPack, unsigned ParmIndex) {
2294 // Drop trailing template arguments that match default arguments.
2295 if (TPL && Policy.SuppressDefaultTemplateArgs &&
2296 !Policy.PrintCanonicalTypes && !Args.empty() && !IsPack &&
2297 Args.size() <= TPL->size()) {
2299 for (const TA &A : Args)
2300 OrigArgs.push_back(getArgument(A));
2301 while (!Args.empty() && getArgument(Args.back()).getIsDefaulted())
2302 Args = Args.drop_back();
2303 }
2304
2305 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
2306 if (!IsPack)
2307 OS << '<';
2308
2309 bool NeedSpace = false;
2310 bool FirstArg = true;
2311 for (const auto &Arg : Args) {
2312 // Print the argument into a string.
2313 SmallString<128> Buf;
2314 llvm::raw_svector_ostream ArgOS(Buf);
2315 const TemplateArgument &Argument = getArgument(Arg);
2316 if (Argument.getKind() == TemplateArgument::Pack) {
2317 if (Argument.pack_size() && !FirstArg)
2318 OS << Comma;
2319 printTo(ArgOS, Argument.getPackAsArray(), Policy, TPL,
2320 /*IsPack*/ true, ParmIndex);
2321 } else {
2322 if (!FirstArg)
2323 OS << Comma;
2324 // Tries to print the argument with location info if exists.
2325 printArgument(Arg, Policy, ArgOS,
2327 Policy, TPL, ParmIndex));
2328 }
2329 StringRef ArgString = ArgOS.str();
2330
2331 // If this is the first argument and its string representation
2332 // begins with the global scope specifier ('::foo'), add a space
2333 // to avoid printing the diagraph '<:'.
2334 if (FirstArg && ArgString.starts_with(":"))
2335 OS << ' ';
2336
2337 OS << ArgString;
2338
2339 // If the last character of our string is '>', add another space to
2340 // keep the two '>''s separate tokens.
2341 if (!ArgString.empty()) {
2342 NeedSpace = Policy.SplitTemplateClosers && ArgString.back() == '>';
2343 FirstArg = false;
2344 }
2345
2346 // Use same template parameter for all elements of Pack
2347 if (!IsPack)
2348 ParmIndex++;
2349 }
2350
2351 if (!IsPack) {
2352 if (NeedSpace)
2353 OS << ' ';
2354 OS << '>';
2355 }
2356}
2357
2359 const TemplateArgumentListInfo &Args,
2360 const PrintingPolicy &Policy,
2361 const TemplateParameterList *TPL) {
2362 printTemplateArgumentList(OS, Args.arguments(), Policy, TPL);
2363}
2364
2367 const PrintingPolicy &Policy,
2368 const TemplateParameterList *TPL) {
2369 printTo(OS, Args, Policy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2370}
2371
2374 const PrintingPolicy &Policy,
2375 const TemplateParameterList *TPL) {
2376 printTo(OS, Args, Policy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2377}
2378
2379std::string Qualifiers::getAsString() const {
2380 LangOptions LO;
2381 return getAsString(PrintingPolicy(LO));
2382}
2383
2384// Appends qualifiers to the given string, separated by spaces. Will
2385// prefix a space if the string is non-empty. Will not append a final
2386// space.
2387std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {
2388 SmallString<64> Buf;
2389 llvm::raw_svector_ostream StrOS(Buf);
2390 print(StrOS, Policy);
2391 return std::string(StrOS.str());
2392}
2393
2395 if (getCVRQualifiers())
2396 return false;
2397
2399 return false;
2400
2401 if (getObjCGCAttr())
2402 return false;
2403
2405 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
2406 return false;
2407
2408 return true;
2409}
2410
2412 switch (AS) {
2413 case LangAS::Default:
2414 return "";
2417 return "__global";
2419 case LangAS::sycl_local:
2420 return "__local";
2423 return "__private";
2425 return "__constant";
2427 return "__generic";
2430 return "__global_device";
2433 return "__global_host";
2435 return "__device__";
2437 return "__constant__";
2439 return "__shared__";
2440 case LangAS::ptr32_sptr:
2441 return "__sptr __ptr32";
2442 case LangAS::ptr32_uptr:
2443 return "__uptr __ptr32";
2444 case LangAS::ptr64:
2445 return "__ptr64";
2447 return "__funcref";
2449 return "groupshared";
2450 default:
2451 return std::to_string(toTargetAddressSpace(AS));
2452 }
2453}
2454
2455// Appends qualifiers to the given string, separated by spaces. Will
2456// prefix a space if the string is non-empty. Will not append a final
2457// space.
2458void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
2459 bool appendSpaceIfNonEmpty) const {
2460 bool addSpace = false;
2461
2462 unsigned quals = getCVRQualifiers();
2463 if (quals) {
2464 AppendTypeQualList(OS, quals, Policy.Restrict);
2465 addSpace = true;
2466 }
2467 if (hasUnaligned()) {
2468 if (addSpace)
2469 OS << ' ';
2470 OS << "__unaligned";
2471 addSpace = true;
2472 }
2473 auto ASStr = getAddrSpaceAsString(getAddressSpace());
2474 if (!ASStr.empty()) {
2475 if (addSpace)
2476 OS << ' ';
2477 addSpace = true;
2478 // Wrap target address space into an attribute syntax
2480 OS << "__attribute__((address_space(" << ASStr << ")))";
2481 else
2482 OS << ASStr;
2483 }
2484
2485 if (Qualifiers::GC gc = getObjCGCAttr()) {
2486 if (addSpace)
2487 OS << ' ';
2488 addSpace = true;
2489 if (gc == Qualifiers::Weak)
2490 OS << "__weak";
2491 else
2492 OS << "__strong";
2493 }
2494 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
2495 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
2496 if (addSpace)
2497 OS << ' ';
2498 addSpace = true;
2499 }
2500
2501 switch (lifetime) {
2502 case Qualifiers::OCL_None: llvm_unreachable("none but true");
2503 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;
2505 if (!Policy.SuppressStrongLifetime)
2506 OS << "__strong";
2507 break;
2508
2509 case Qualifiers::OCL_Weak: OS << "__weak"; break;
2510 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
2511 }
2512 }
2513
2514 if (appendSpaceIfNonEmpty && addSpace)
2515 OS << ' ';
2516}
2517
2518std::string QualType::getAsString() const {
2519 return getAsString(split(), LangOptions());
2520}
2521
2522std::string QualType::getAsString(const PrintingPolicy &Policy) const {
2523 std::string S;
2524 getAsStringInternal(S, Policy);
2525 return S;
2526}
2527
2528std::string QualType::getAsString(const Type *ty, Qualifiers qs,
2529 const PrintingPolicy &Policy) {
2530 std::string buffer;
2531 getAsStringInternal(ty, qs, buffer, Policy);
2532 return buffer;
2533}
2534
2535void QualType::print(raw_ostream &OS, const PrintingPolicy &Policy,
2536 const Twine &PlaceHolder, unsigned Indentation) const {
2537 print(splitAccordingToPolicy(*this, Policy), OS, Policy, PlaceHolder,
2538 Indentation);
2539}
2540
2542 raw_ostream &OS, const PrintingPolicy &policy,
2543 const Twine &PlaceHolder, unsigned Indentation) {
2544 SmallString<128> PHBuf;
2545 StringRef PH = PlaceHolder.toStringRef(PHBuf);
2546
2547 TypePrinter(policy, Indentation).print(ty, qs, OS, PH);
2548}
2549
2550void QualType::getAsStringInternal(std::string &Str,
2551 const PrintingPolicy &Policy) const {
2552 return getAsStringInternal(splitAccordingToPolicy(*this, Policy), Str,
2553 Policy);
2554}
2555
2557 std::string &buffer,
2558 const PrintingPolicy &policy) {
2559 SmallString<256> Buf;
2560 llvm::raw_svector_ostream StrOS(Buf);
2561 TypePrinter(policy).print(ty, qs, StrOS, buffer);
2562 std::string str = std::string(StrOS.str());
2563 buffer.swap(str);
2564}
2565
2566raw_ostream &clang::operator<<(raw_ostream &OS, QualType QT) {
2567 SplitQualType S = QT.split();
2568 TypePrinter(LangOptions()).print(S.Ty, S.Quals, OS, /*PlaceHolder=*/"");
2569 return OS;
2570}
Defines the clang::ASTContext interface.
int Id
Definition: ASTDiff.cpp:190
Provides definitions for the various language-specific address spaces.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the ExceptionSpecificationType enumeration and various utility functions.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
static void print(llvm::raw_ostream &OS, const T &V, ASTContext &, QualType)
Definition: InterpFrame.cpp:96
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
static void printTo(raw_ostream &OS, ArrayRef< TA > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL, bool IsPack, unsigned ParmIndex)
static const TemplateArgument & getArgument(const TemplateArgument &A)
static bool isSubstitutedType(ASTContext &Ctx, QualType T, QualType Pattern, ArrayRef< TemplateArgument > Args, unsigned Depth)
static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP, llvm::raw_ostream &OS, bool IncludeType)
static QualType skipTopLevelReferences(QualType T)
static void printCountAttributedImpl(const CountAttributedType *T, raw_ostream &OS, const PrintingPolicy &Policy)
static SplitQualType splitAccordingToPolicy(QualType QT, const PrintingPolicy &Policy)
static bool isSubstitutedTemplateArgument(ASTContext &Ctx, TemplateArgument Arg, TemplateArgument Pattern, ArrayRef< TemplateArgument > Args, unsigned Depth)
static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals, bool HasRestrictKeyword)
static bool templateArgumentExpressionsEqual(ASTContext const &Ctx, TemplateArgument const &Pattern, TemplateArgument const &Arg)
Evaluates the expression template argument 'Pattern' and returns true if 'Arg' evaluates to the same ...
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
SourceManager & getSourceManager()
Definition: ASTContext.h:705
TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg) const
Retrieve the "canonical" template argument.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:2591
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
Definition: ASTContext.h:2157
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals) const
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals.
Represents a type which was implicitly adjusted by the semantic engine for arbitrary reasons.
Definition: Type.h:3298
Represents a constant array type that does not decay to a pointer when used as a function parameter.
Definition: Type.h:3688
An attributed type is a type to which a type attribute has been applied.
Definition: Type.h:5604
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Definition: Type.h:5981
A fixed int type of a specified bitwidth.
Definition: Type.h:7242
Pointer to a block type.
Definition: Type.h:3349
This class is used for builtin types like 'int'.
Definition: Type.h:2981
Complex values, per C99 6.2.5p11.
Definition: Type.h:3086
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:3556
Represents a concrete matrix type with constant number of rows and columns.
Definition: Type.h:4167
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
Definition: Type.h:3247
Represents a pointer type decayed from an array or function type.
Definition: Type.h:3332
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1436
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2066
bool isTranslationUnit() const
Definition: DeclBase.h:2142
bool isFunctionOrMethod() const
Definition: DeclBase.h:2118
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:501
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:599
SourceLocation getLocation() const
Definition: DeclBase.h:445
DeclContext * getDeclContext()
Definition: DeclBase.h:454
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
The name of a declaration.
Represents the type decltype(expr) (C++11).
Definition: Type.h:5358
Represents a C++17 deduced template specialization type.
Definition: Type.h:6029
Represents an extended address space qualifier where the input address space value is dependent.
Definition: Type.h:3859
Represents a qualified type name for which the type name is dependent.
Definition: Type.h:6452
Represents an array type in C++ whose size is a value-dependent expression.
Definition: Type.h:3801
Represents an extended vector type where either the type or size is dependent.
Definition: Type.h:3899
Represents a matrix type where the type and the number of rows and columns is dependent on a template...
Definition: Type.h:4226
Represents a template specialization type whose template cannot be resolved, e.g.
Definition: Type.h:6504
Represents a vector type where either the type or size is dependent.
Definition: Type.h:4021
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
Definition: Type.h:6371
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Definition: Type.h:5575
This represents one expression.
Definition: Expr.h:110
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition: Expr.h:175
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition: Expr.cpp:3059
bool isIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
ExtVectorType - Extended vector type.
Definition: Type.h:4061
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition: Type.h:4611
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4656
QualType desugar() const
Definition: Type.h:5123
ExtParameterInfo getExtParameterInfo(unsigned I) const
Definition: Type.h:5101
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Definition: Type.h:4915
unsigned getNumParams() const
Definition: Type.h:4889
void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
Definition: Type.h:5028
Qualifiers getMethodQuals() const
Definition: Type.h:5030
QualType getParamType(unsigned i) const
Definition: Type.h:4891
unsigned getAArch64SMEAttributes() const
Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...
Definition: Type.h:5094
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
Definition: Type.h:4966
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition: Type.h:4958
bool hasDynamicExceptionSpec() const
Return whether this function has a dynamic (throw) exception spec.
Definition: Type.h:4924
bool isVariadic() const
Whether this function prototype is variadic.
Definition: Type.h:5012
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
Definition: Type.h:4973
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Definition: Type.h:5038
A class which abstracts out some details necessary for making a call.
Definition: Type.h:4367
CallingConv getCC() const
Definition: Type.h:4429
bool getCmseNSCall() const
Definition: Type.h:4417
bool getNoCfCheck() const
Definition: Type.h:4419
unsigned getRegParm() const
Definition: Type.h:4422
bool getNoCallerSavedRegs() const
Definition: Type.h:4418
bool getNoReturn() const
Definition: Type.h:4415
bool getProducesResult() const
Definition: Type.h:4416
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:4256
ExtInfo getExtInfo() const
Definition: Type.h:4585
static ArmStateValue getArmZT0State(unsigned AttrBits)
Definition: Type.h:4543
static ArmStateValue getArmZAState(unsigned AttrBits)
Definition: Type.h:4539
QualType getReturnType() const
Definition: Type.h:4573
@ SME_PStateSMEnabledMask
Definition: Type.h:4517
@ SME_PStateSMCompatibleMask
Definition: Type.h:4518
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Represents a C array with an unspecified size.
Definition: Type.h:3703
The injected class name of a C++ class template or class template partial specialization.
Definition: Type.h:6221
An lvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:3424
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:461
Sugar type that represents a type that was qualified by a qualifier written as a macro invocation.
Definition: Type.h:5242
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition: Type.h:3460
This represents a decl that may have a name.
Definition: Decl.h:249
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:270
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:276
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:315
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
Interfaces are the core concept in Objective-C for object oriented design.
Definition: Type.h:6952
Represents a pointer to an Objective C object.
Definition: Type.h:7008
Represents a class type in Objective C.
Definition: Type.h:6754
Represents a type parameter type in Objective C.
Definition: Type.h:6680
Represents a pack expansion of types.
Definition: Type.h:6569
Sugar for parentheses used when specifying types.
Definition: Type.h:3113
PipeType - OpenCL20.
Definition: Type.h:7208
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:3139
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
bool isValid() const
unsigned getLine() const
Return the presumed line number of this location.
A (possibly-)qualified type.
Definition: Type.h:940
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1007
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition: Type.h:7399
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const
QualType getCanonicalType() const
Definition: Type.h:7411
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
Definition: Type.h:7380
std::string getAsString() const
StreamedQualTypeHelper stream(const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Definition: Type.h:1383
The collection of all-type qualifiers we support.
Definition: Type.h:318
unsigned getCVRQualifiers() const
Definition: Type.h:474
GC getObjCGCAttr() const
Definition: Type.h:505
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Definition: Type.h:347
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
Definition: Type.h:340
@ OCL_None
There is no lifetime qualification on this type.
Definition: Type.h:336
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Definition: Type.h:350
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
Definition: Type.h:353
bool hasUnaligned() const
Definition: Type.h:497
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool appendSpaceIfNonEmpty=false) const
bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const
ObjCLifetime getObjCLifetime() const
Definition: Type.h:531
bool empty() const
Definition: Type.h:633
std::string getAsString() const
LangAS getAddressSpace() const
Definition: Type.h:557
static std::string getAddrSpaceAsString(LangAS AS)
An rvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:3442
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:5549
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3380
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
Represents the result of substituting a set of types for a template type parameter pack.
Definition: Type.h:5889
Represents the result of substituting a type for a template type parameter.
Definition: Type.h:5819
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3584
StringRef getKindName() const
Definition: Decl.h:3775
TypedefNameDecl * getTypedefNameForAnonDecl() const
Definition: Decl.h:3812
A convenient class for passing around template argument information.
Definition: TemplateBase.h:632
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
Definition: TemplateBase.h:659
A template argument list.
Definition: DeclTemplate.h:244
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Definition: DeclTemplate.h:274
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:524
const TemplateArgument & getArgument() const
Definition: TemplateBase.h:574
TypeSourceInfo * getTypeSourceInfo() const
Definition: TemplateBase.h:578
Represents a template argument.
Definition: TemplateBase.h:61
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
Definition: TemplateBase.h:444
Expr * getAsExpr() const
Retrieve the template argument as an expression.
Definition: TemplateBase.h:408
QualType getAsType() const
Retrieve the type for a type template argument.
Definition: TemplateBase.h:319
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
Definition: TemplateBase.h:363
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
Definition: TemplateBase.h:343
unsigned pack_size() const
The number of template arguments in the given template argument pack.
Definition: TemplateBase.h:438
bool structurallyEquals(const TemplateArgument &Other) const
Determines whether two template arguments are superficially the same.
void print(const PrintingPolicy &Policy, raw_ostream &Out, bool IncludeType) const
Print this template argument to the given output stream.
bool getIsDefaulted() const
If returns 'true', this TemplateArgument corresponds to a default template parameter.
Definition: TemplateBase.h:393
ArgKind
The kind of template argument we're storing.
Definition: TemplateBase.h:64
@ Template
The template argument is a template name that was provided for a template template parameter.
Definition: TemplateBase.h:93
@ Pack
The template argument is actually a parameter pack.
Definition: TemplateBase.h:107
@ Type
The template argument is a type.
Definition: TemplateBase.h:70
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
Definition: TemplateBase.h:82
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
Definition: TemplateBase.h:103
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:295
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:394
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:413
Represents a C++ template name within the type system.
Definition: TemplateName.h:202
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known.
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:73
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: Type.h:6089
Declaration of a template type parameter.
unsigned getIndex() const
Retrieve the index of the template parameter.
const TypeConstraint * getTypeConstraint() const
Returns the type constraint associated with this template parameter (if any).
unsigned getDepth() const
Retrieve the depth of the template parameter.
const Type * getTypeForDecl() const
Definition: Decl.h:3414
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
Definition: Type.h:5274
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
Definition: Type.h:5322
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:7341
static StringRef getKeywordName(ElaboratedTypeKeyword Keyword)
Definition: Type.cpp:3212
The base class of the type hierarchy.
Definition: Type.h:1813
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1871
bool isArrayType() const
Definition: Type.h:7678
QualType getLocallyUnqualifiedSingleStepDesugaredType() const
Pull a single level of sugar off of this locally-unqualified type.
Definition: Type.cpp:476
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8193
bool isObjCQualifiedIdType() const
Definition: Type.h:7765
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:695
bool isObjCIdType() const
Definition: Type.h:7777
bool isSpecifierType() const
Returns true if this type can be represented by some set of type specifiers.
Definition: Type.cpp:3097
bool isFunctionType() const
Definition: Type.h:7608
bool isObjCQualifiedClassType() const
Definition: Type.h:7771
bool isObjCClassType() const
Definition: Type.h:7783
TypeClass getTypeClass() const
Definition: Type.h:2300
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8126
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3432
A unary type transform, which is a type constructed from another.
Definition: Type.h:5466
Represents the dependent type named by a dependently-scoped typename using declaration,...
Definition: Type.h:5144
Represents a C array with a specified size that is not an integer-constant-expression.
Definition: Type.h:3747
Represents a GCC generic vector type.
Definition: Type.h:3969
The JSON file list parser is used to communicate input to InstallAPI.
@ GNUAutoType
__auto_type (GNU extension)
@ DecltypeAuto
decltype(auto)
llvm::StringRef getParameterABISpelling(ParameterABI kind)
bool isTargetAddressSpace(LangAS AS)
Definition: AddressSpaces.h:77
@ RQ_None
No ref-qualifier was provided.
Definition: Type.h:1762
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
Definition: Type.h:1765
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition: Type.h:1768
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)
Insertion operator for diagnostics.
unsigned toTargetAddressSpace(LangAS AS)
Definition: AddressSpaces.h:81
ParameterABI
Kinds of parameter ABI.
Definition: Specifiers.h:363
@ SwiftAsyncContext
This parameter (which must have pointer type) uses the special Swift asynchronous context-pointer ABI...
@ SwiftErrorResult
This parameter (which must have pointer-to-pointer type) uses the special Swift error-result ABI trea...
@ Ordinary
This parameter uses ordinary ABI rules for its type.
@ SwiftIndirectResult
This parameter (which must have pointer type) is a Swift indirect result parameter.
@ SwiftContext
This parameter (which must have pointer type) uses the special Swift context-pointer ABI treatment.
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
LangAS
Defines the address space values used by the address space qualifier of QualType.
Definition: AddressSpaces.h:25
bool isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg, const NamedDecl *Param, ArrayRef< TemplateArgument > Args, unsigned Depth)
Make a best-effort determination of whether the type T can be produced by substituting Args into the ...
const FunctionProtoType * T
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
Definition: DeclBase.h:1275
@ CC_X86Pascal
Definition: Specifiers.h:281
@ CC_Swift
Definition: Specifiers.h:290
@ CC_IntelOclBicc
Definition: Specifiers.h:287
@ CC_OpenCLKernel
Definition: Specifiers.h:289
@ CC_PreserveMost
Definition: Specifiers.h:292
@ CC_Win64
Definition: Specifiers.h:282
@ CC_X86ThisCall
Definition: Specifiers.h:279
@ CC_AArch64VectorCall
Definition: Specifiers.h:294
@ CC_AAPCS
Definition: Specifiers.h:285
@ CC_PreserveNone
Definition: Specifiers.h:298
@ CC_C
Definition: Specifiers.h:276
@ CC_AMDGPUKernelCall
Definition: Specifiers.h:296
@ CC_M68kRTD
Definition: Specifiers.h:297
@ CC_SwiftAsync
Definition: Specifiers.h:291
@ CC_X86RegCall
Definition: Specifiers.h:284
@ CC_RISCVVectorCall
Definition: Specifiers.h:299
@ CC_X86VectorCall
Definition: Specifiers.h:280
@ CC_SpirFunction
Definition: Specifiers.h:288
@ CC_AArch64SVEPCS
Definition: Specifiers.h:295
@ CC_X86StdCall
Definition: Specifiers.h:277
@ CC_X86_64SysV
Definition: Specifiers.h:283
@ CC_PreserveAll
Definition: Specifiers.h:293
@ CC_X86FastCall
Definition: Specifiers.h:278
@ CC_AAPCS_VFP
Definition: Specifiers.h:286
@ None
No keyword precedes the qualified type name.
@ EST_NoThrow
Microsoft __declspec(nothrow) extension.
@ EST_MSAny
Microsoft throw(...) extension.
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:676
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
Definition: TemplateBase.h:705
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
unsigned MSVCFormatting
Use whitespace and punctuation like MSVC does.
unsigned SuppressDefaultTemplateArgs
When true, attempt to suppress template arguments that match the default argument for the parameter.
unsigned SplitTemplateClosers
Whether nested templates must be closed like 'a<b<c> >' rather than 'a<b<c>>'.
unsigned PrintCanonicalTypes
Whether to print types as written or canonically.
unsigned SuppressSpecifiers
Whether we should suppress printing of the actual specifiers for the given type or declaration.
unsigned SuppressTagKeyword
Whether type printing should skip printing the tag keyword.
unsigned SuppressStrongLifetime
When true, suppress printing of the __strong lifetime qualifier in ARC.
unsigned Restrict
Whether we can use 'restrict' rather than '__restrict'.
unsigned SuppressScope
Suppresses printing of scope specifiers.
unsigned IncludeTagDefinition
When true, include the body of a tag definition.
unsigned SuppressLifetimeQualifiers
When true, suppress printing of lifetime qualifier in ARC.
A std::pair-like structure for storing a qualified type split into its local qualifiers and its local...
Definition: Type.h:873
const Type * Ty
The locally-unqualified type.
Definition: Type.h:875
Qualifiers Quals
The local qualifiers.
Definition: Type.h:878