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 (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1477 TypeSourceInfo *TAW = Spec->getTypeAsWritten();
1478 if (!Policy.PrintCanonicalTypes && TAW) {
1479 const TemplateSpecializationType *TST =
1480 cast<TemplateSpecializationType>(TAW->getType());
1481 Args = TST->template_arguments();
1482 } else {
1483 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
1484 Args = TemplateArgs.asArray();
1485 }
1486 IncludeStrongLifetimeRAII Strong(Policy);
1488 OS, Args, Policy,
1489 Spec->getSpecializedTemplate()->getTemplateParameters());
1490 }
1491
1492 spaceBeforePlaceHolder(OS);
1493}
1494
1495void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
1496 // Print the preferred name if we have one for this type.
1497 if (Policy.UsePreferredNames) {
1498 for (const auto *PNA : T->getDecl()->specific_attrs<PreferredNameAttr>()) {
1499 if (!declaresSameEntity(PNA->getTypedefType()->getAsCXXRecordDecl(),
1500 T->getDecl()))
1501 continue;
1502 // Find the outermost typedef or alias template.
1503 QualType T = PNA->getTypedefType();
1504 while (true) {
1505 if (auto *TT = dyn_cast<TypedefType>(T))
1506 return printTypeSpec(TT->getDecl(), OS);
1507 if (auto *TST = dyn_cast<TemplateSpecializationType>(T))
1508 return printTemplateId(TST, OS, /*FullyQualify=*/true);
1510 }
1511 }
1512 }
1513
1514 printTag(T->getDecl(), OS);
1515}
1516
1517void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) {}
1518
1519void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {
1520 printTag(T->getDecl(), OS);
1521}
1522
1523void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {}
1524
1525void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
1526 raw_ostream &OS) {
1527 TemplateTypeParmDecl *D = T->getDecl();
1528 if (D && D->isImplicit()) {
1529 if (auto *TC = D->getTypeConstraint()) {
1530 TC->print(OS, Policy);
1531 OS << ' ';
1532 }
1533 OS << "auto";
1534 } else if (IdentifierInfo *Id = T->getIdentifier())
1535 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1536 : Id->getName());
1537 else
1538 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
1539
1540 spaceBeforePlaceHolder(OS);
1541}
1542
1543void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,
1544 raw_ostream &OS) {}
1545
1546void TypePrinter::printSubstTemplateTypeParmBefore(
1548 raw_ostream &OS) {
1549 IncludeStrongLifetimeRAII Strong(Policy);
1550 printBefore(T->getReplacementType(), OS);
1551}
1552
1553void TypePrinter::printSubstTemplateTypeParmAfter(
1555 raw_ostream &OS) {
1556 IncludeStrongLifetimeRAII Strong(Policy);
1557 printAfter(T->getReplacementType(), OS);
1558}
1559
1560void TypePrinter::printSubstTemplateTypeParmPackBefore(
1562 raw_ostream &OS) {
1563 IncludeStrongLifetimeRAII Strong(Policy);
1564 if (const TemplateTypeParmDecl *D = T->getReplacedParameter()) {
1565 if (D && D->isImplicit()) {
1566 if (auto *TC = D->getTypeConstraint()) {
1567 TC->print(OS, Policy);
1568 OS << ' ';
1569 }
1570 OS << "auto";
1571 } else if (IdentifierInfo *Id = D->getIdentifier())
1572 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1573 : Id->getName());
1574 else
1575 OS << "type-parameter-" << D->getDepth() << '-' << D->getIndex();
1576
1577 spaceBeforePlaceHolder(OS);
1578 }
1579}
1580
1581void TypePrinter::printSubstTemplateTypeParmPackAfter(
1583 raw_ostream &OS) {
1584 IncludeStrongLifetimeRAII Strong(Policy);
1585}
1586
1587void TypePrinter::printTemplateId(const TemplateSpecializationType *T,
1588 raw_ostream &OS, bool FullyQualify) {
1589 IncludeStrongLifetimeRAII Strong(Policy);
1590
1591 TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl();
1592 // FIXME: Null TD never excercised in test suite.
1593 if (FullyQualify && TD) {
1594 if (!Policy.SuppressScope)
1595 AppendScope(TD->getDeclContext(), OS, TD->getDeclName());
1596
1597 OS << TD->getName();
1598 } else {
1599 T->getTemplateName().print(OS, Policy);
1600 }
1601
1602 DefaultTemplateArgsPolicyRAII TemplateArgs(Policy);
1603 const TemplateParameterList *TPL = TD ? TD->getTemplateParameters() : nullptr;
1604 printTemplateArgumentList(OS, T->template_arguments(), Policy, TPL);
1605 spaceBeforePlaceHolder(OS);
1606}
1607
1608void TypePrinter::printTemplateSpecializationBefore(
1610 raw_ostream &OS) {
1611 printTemplateId(T, OS, Policy.FullyQualifiedName);
1612}
1613
1614void TypePrinter::printTemplateSpecializationAfter(
1616 raw_ostream &OS) {}
1617
1618void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
1619 raw_ostream &OS) {
1620 if (Policy.PrintInjectedClassNameWithArguments)
1621 return printTemplateSpecializationBefore(T->getInjectedTST(), OS);
1622
1623 IncludeStrongLifetimeRAII Strong(Policy);
1624 T->getTemplateName().print(OS, Policy);
1625 spaceBeforePlaceHolder(OS);
1626}
1627
1628void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
1629 raw_ostream &OS) {}
1630
1631void TypePrinter::printElaboratedBefore(const ElaboratedType *T,
1632 raw_ostream &OS) {
1633 if (Policy.IncludeTagDefinition && T->getOwnedTagDecl()) {
1634 TagDecl *OwnedTagDecl = T->getOwnedTagDecl();
1635 assert(OwnedTagDecl->getTypeForDecl() == T->getNamedType().getTypePtr() &&
1636 "OwnedTagDecl expected to be a declaration for the type");
1637 PrintingPolicy SubPolicy = Policy;
1638 SubPolicy.IncludeTagDefinition = false;
1639 OwnedTagDecl->print(OS, SubPolicy, Indentation);
1640 spaceBeforePlaceHolder(OS);
1641 return;
1642 }
1643
1644 if (Policy.SuppressElaboration) {
1645 printBefore(T->getNamedType(), OS);
1646 return;
1647 }
1648
1649 // The tag definition will take care of these.
1650 if (!Policy.IncludeTagDefinition)
1651 {
1652 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1653 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1654 OS << " ";
1655 NestedNameSpecifier *Qualifier = T->getQualifier();
1656 if (!Policy.SuppressTagKeyword && Policy.SuppressScope &&
1657 !Policy.SuppressUnwrittenScope) {
1658 bool OldTagKeyword = Policy.SuppressTagKeyword;
1659 bool OldSupressScope = Policy.SuppressScope;
1660 Policy.SuppressTagKeyword = true;
1661 Policy.SuppressScope = false;
1662 printBefore(T->getNamedType(), OS);
1663 Policy.SuppressTagKeyword = OldTagKeyword;
1664 Policy.SuppressScope = OldSupressScope;
1665 return;
1666 }
1667 if (Qualifier)
1668 Qualifier->print(OS, Policy);
1669 }
1670
1671 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1672 printBefore(T->getNamedType(), OS);
1673}
1674
1675void TypePrinter::printElaboratedAfter(const ElaboratedType *T,
1676 raw_ostream &OS) {
1677 if (Policy.IncludeTagDefinition && T->getOwnedTagDecl())
1678 return;
1679
1680 if (Policy.SuppressElaboration) {
1681 printAfter(T->getNamedType(), OS);
1682 return;
1683 }
1684
1685 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1686 printAfter(T->getNamedType(), OS);
1687}
1688
1689void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {
1690 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1691 printBefore(T->getInnerType(), OS);
1692 OS << '(';
1693 } else
1694 printBefore(T->getInnerType(), OS);
1695}
1696
1697void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {
1698 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1699 OS << ')';
1700 printAfter(T->getInnerType(), OS);
1701 } else
1702 printAfter(T->getInnerType(), OS);
1703}
1704
1705void TypePrinter::printDependentNameBefore(const DependentNameType *T,
1706 raw_ostream &OS) {
1707 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1708 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1709 OS << " ";
1710
1711 T->getQualifier()->print(OS, Policy);
1712
1713 OS << T->getIdentifier()->getName();
1714 spaceBeforePlaceHolder(OS);
1715}
1716
1717void TypePrinter::printDependentNameAfter(const DependentNameType *T,
1718 raw_ostream &OS) {}
1719
1720void TypePrinter::printDependentTemplateSpecializationBefore(
1721 const DependentTemplateSpecializationType *T, raw_ostream &OS) {
1722 IncludeStrongLifetimeRAII Strong(Policy);
1723
1724 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1725 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1726 OS << " ";
1727
1728 if (T->getQualifier())
1729 T->getQualifier()->print(OS, Policy);
1730 OS << "template " << T->getIdentifier()->getName();
1731 printTemplateArgumentList(OS, T->template_arguments(), Policy);
1732 spaceBeforePlaceHolder(OS);
1733}
1734
1735void TypePrinter::printDependentTemplateSpecializationAfter(
1736 const DependentTemplateSpecializationType *T, raw_ostream &OS) {}
1737
1738void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,
1739 raw_ostream &OS) {
1740 printBefore(T->getPattern(), OS);
1741}
1742
1743void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
1744 raw_ostream &OS) {
1745 printAfter(T->getPattern(), OS);
1746 OS << "...";
1747}
1748
1750 raw_ostream &OS,
1751 const PrintingPolicy &Policy) {
1752 OS << ' ';
1753 if (T->isCountInBytes() && T->isOrNull())
1754 OS << "__sized_by_or_null(";
1755 else if (T->isCountInBytes())
1756 OS << "__sized_by(";
1757 else if (T->isOrNull())
1758 OS << "__counted_by_or_null(";
1759 else
1760 OS << "__counted_by(";
1761 if (T->getCountExpr())
1762 T->getCountExpr()->printPretty(OS, nullptr, Policy);
1763 OS << ')';
1764}
1765
1766void TypePrinter::printCountAttributedBefore(const CountAttributedType *T,
1767 raw_ostream &OS) {
1768 printBefore(T->desugar(), OS);
1769 if (!T->isArrayType())
1770 printCountAttributedImpl(T, OS, Policy);
1771}
1772
1773void TypePrinter::printCountAttributedAfter(const CountAttributedType *T,
1774 raw_ostream &OS) {
1775 printAfter(T->desugar(), OS);
1776 if (T->isArrayType())
1777 printCountAttributedImpl(T, OS, Policy);
1778}
1779
1780void TypePrinter::printAttributedBefore(const AttributedType *T,
1781 raw_ostream &OS) {
1782 // FIXME: Generate this with TableGen.
1783
1784 // Prefer the macro forms of the GC and ownership qualifiers.
1785 if (T->getAttrKind() == attr::ObjCGC ||
1786 T->getAttrKind() == attr::ObjCOwnership)
1787 return printBefore(T->getEquivalentType(), OS);
1788
1789 if (T->getAttrKind() == attr::ObjCKindOf)
1790 OS << "__kindof ";
1791
1792 if (T->getAttrKind() == attr::AddressSpace)
1793 printBefore(T->getEquivalentType(), OS);
1794 else
1795 printBefore(T->getModifiedType(), OS);
1796
1797 if (T->isMSTypeSpec()) {
1798 switch (T->getAttrKind()) {
1799 default: return;
1800 case attr::Ptr32: OS << " __ptr32"; break;
1801 case attr::Ptr64: OS << " __ptr64"; break;
1802 case attr::SPtr: OS << " __sptr"; break;
1803 case attr::UPtr: OS << " __uptr"; break;
1804 }
1805 spaceBeforePlaceHolder(OS);
1806 }
1807
1808 if (T->isWebAssemblyFuncrefSpec())
1809 OS << "__funcref";
1810
1811 // Print nullability type specifiers.
1812 if (T->getImmediateNullability()) {
1813 if (T->getAttrKind() == attr::TypeNonNull)
1814 OS << " _Nonnull";
1815 else if (T->getAttrKind() == attr::TypeNullable)
1816 OS << " _Nullable";
1817 else if (T->getAttrKind() == attr::TypeNullUnspecified)
1818 OS << " _Null_unspecified";
1819 else if (T->getAttrKind() == attr::TypeNullableResult)
1820 OS << " _Nullable_result";
1821 else
1822 llvm_unreachable("unhandled nullability");
1823 spaceBeforePlaceHolder(OS);
1824 }
1825}
1826
1827void TypePrinter::printAttributedAfter(const AttributedType *T,
1828 raw_ostream &OS) {
1829 // FIXME: Generate this with TableGen.
1830
1831 // Prefer the macro forms of the GC and ownership qualifiers.
1832 if (T->getAttrKind() == attr::ObjCGC ||
1833 T->getAttrKind() == attr::ObjCOwnership)
1834 return printAfter(T->getEquivalentType(), OS);
1835
1836 // If this is a calling convention attribute, don't print the implicit CC from
1837 // the modified type.
1838 SaveAndRestore MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());
1839
1840 printAfter(T->getModifiedType(), OS);
1841
1842 // Some attributes are printed as qualifiers before the type, so we have
1843 // nothing left to do.
1844 if (T->getAttrKind() == attr::ObjCKindOf || T->isMSTypeSpec() ||
1845 T->getImmediateNullability() || T->isWebAssemblyFuncrefSpec())
1846 return;
1847
1848 // Don't print the inert __unsafe_unretained attribute at all.
1849 if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained)
1850 return;
1851
1852 // Don't print ns_returns_retained unless it had an effect.
1853 if (T->getAttrKind() == attr::NSReturnsRetained &&
1854 !T->getEquivalentType()->castAs<FunctionType>()
1856 return;
1857
1858 if (T->getAttrKind() == attr::LifetimeBound) {
1859 OS << " [[clang::lifetimebound]]";
1860 return;
1861 }
1862
1863 // The printing of the address_space attribute is handled by the qualifier
1864 // since it is still stored in the qualifier. Return early to prevent printing
1865 // this twice.
1866 if (T->getAttrKind() == attr::AddressSpace)
1867 return;
1868
1869 if (T->getAttrKind() == attr::AnnotateType) {
1870 // FIXME: Print the attribute arguments once we have a way to retrieve these
1871 // here. For the meantime, we just print `[[clang::annotate_type(...)]]`
1872 // without the arguments so that we know at least that we had _some_
1873 // annotation on the type.
1874 OS << " [[clang::annotate_type(...)]]";
1875 return;
1876 }
1877
1878 if (T->getAttrKind() == attr::ArmStreaming) {
1879 OS << "__arm_streaming";
1880 return;
1881 }
1882 if (T->getAttrKind() == attr::ArmStreamingCompatible) {
1883 OS << "__arm_streaming_compatible";
1884 return;
1885 }
1886
1887 OS << " __attribute__((";
1888 switch (T->getAttrKind()) {
1889#define TYPE_ATTR(NAME)
1890#define DECL_OR_TYPE_ATTR(NAME)
1891#define ATTR(NAME) case attr::NAME:
1892#include "clang/Basic/AttrList.inc"
1893 llvm_unreachable("non-type attribute attached to type");
1894
1895 case attr::BTFTypeTag:
1896 llvm_unreachable("BTFTypeTag attribute handled separately");
1897
1898 case attr::OpenCLPrivateAddressSpace:
1899 case attr::OpenCLGlobalAddressSpace:
1900 case attr::OpenCLGlobalDeviceAddressSpace:
1901 case attr::OpenCLGlobalHostAddressSpace:
1902 case attr::OpenCLLocalAddressSpace:
1903 case attr::OpenCLConstantAddressSpace:
1904 case attr::OpenCLGenericAddressSpace:
1905 case attr::HLSLGroupSharedAddressSpace:
1906 // FIXME: Update printAttributedBefore to print these once we generate
1907 // AttributedType nodes for them.
1908 break;
1909
1910 case attr::CountedBy:
1911 case attr::LifetimeBound:
1912 case attr::TypeNonNull:
1913 case attr::TypeNullable:
1914 case attr::TypeNullableResult:
1915 case attr::TypeNullUnspecified:
1916 case attr::ObjCGC:
1917 case attr::ObjCInertUnsafeUnretained:
1918 case attr::ObjCKindOf:
1919 case attr::ObjCOwnership:
1920 case attr::Ptr32:
1921 case attr::Ptr64:
1922 case attr::SPtr:
1923 case attr::UPtr:
1924 case attr::AddressSpace:
1925 case attr::CmseNSCall:
1926 case attr::AnnotateType:
1927 case attr::WebAssemblyFuncref:
1928 case attr::ArmStreaming:
1929 case attr::ArmStreamingCompatible:
1930 case attr::ArmIn:
1931 case attr::ArmOut:
1932 case attr::ArmInOut:
1933 case attr::ArmPreserves:
1934 llvm_unreachable("This attribute should have been handled already");
1935
1936 case attr::NSReturnsRetained:
1937 OS << "ns_returns_retained";
1938 break;
1939
1940 // FIXME: When Sema learns to form this AttributedType, avoid printing the
1941 // attribute again in printFunctionProtoAfter.
1942 case attr::AnyX86NoCfCheck: OS << "nocf_check"; break;
1943 case attr::CDecl: OS << "cdecl"; break;
1944 case attr::FastCall: OS << "fastcall"; break;
1945 case attr::StdCall: OS << "stdcall"; break;
1946 case attr::ThisCall: OS << "thiscall"; break;
1947 case attr::SwiftCall: OS << "swiftcall"; break;
1948 case attr::SwiftAsyncCall: OS << "swiftasynccall"; break;
1949 case attr::VectorCall: OS << "vectorcall"; break;
1950 case attr::Pascal: OS << "pascal"; break;
1951 case attr::MSABI: OS << "ms_abi"; break;
1952 case attr::SysVABI: OS << "sysv_abi"; break;
1953 case attr::RegCall: OS << "regcall"; break;
1954 case attr::Pcs: {
1955 OS << "pcs(";
1956 QualType t = T->getEquivalentType();
1957 while (!t->isFunctionType())
1958 t = t->getPointeeType();
1959 OS << (t->castAs<FunctionType>()->getCallConv() == CC_AAPCS ?
1960 "\"aapcs\"" : "\"aapcs-vfp\"");
1961 OS << ')';
1962 break;
1963 }
1964 case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break;
1965 case attr::AArch64SVEPcs: OS << "aarch64_sve_pcs"; break;
1966 case attr::AMDGPUKernelCall: OS << "amdgpu_kernel"; break;
1967 case attr::IntelOclBicc: OS << "inteloclbicc"; break;
1968 case attr::PreserveMost:
1969 OS << "preserve_most";
1970 break;
1971
1972 case attr::PreserveAll:
1973 OS << "preserve_all";
1974 break;
1975 case attr::M68kRTD:
1976 OS << "m68k_rtd";
1977 break;
1978 case attr::PreserveNone:
1979 OS << "preserve_none";
1980 break;
1981 case attr::RISCVVectorCC:
1982 OS << "riscv_vector_cc";
1983 break;
1984 case attr::NoDeref:
1985 OS << "noderef";
1986 break;
1987 case attr::AcquireHandle:
1988 OS << "acquire_handle";
1989 break;
1990 case attr::ArmMveStrictPolymorphism:
1991 OS << "__clang_arm_mve_strict_polymorphism";
1992 break;
1993
1994 // Nothing to print for this attribute.
1995 case attr::HLSLParamModifier:
1996 break;
1997 }
1998 OS << "))";
1999}
2000
2001void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T,
2002 raw_ostream &OS) {
2003 printBefore(T->getWrappedType(), OS);
2004 OS << " __attribute__((btf_type_tag(\"" << T->getAttr()->getBTFTypeTag() << "\")))";
2005}
2006
2007void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,
2008 raw_ostream &OS) {
2009 printAfter(T->getWrappedType(), OS);
2010}
2011
2012void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
2013 raw_ostream &OS) {
2014 OS << T->getDecl()->getName();
2015 spaceBeforePlaceHolder(OS);
2016}
2017
2018void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
2019 raw_ostream &OS) {}
2020
2021void TypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType *T,
2022 raw_ostream &OS) {
2023 OS << T->getDecl()->getName();
2024 if (!T->qual_empty()) {
2025 bool isFirst = true;
2026 OS << '<';
2027 for (const auto *I : T->quals()) {
2028 if (isFirst)
2029 isFirst = false;
2030 else
2031 OS << ',';
2032 OS << I->getName();
2033 }
2034 OS << '>';
2035 }
2036
2037 spaceBeforePlaceHolder(OS);
2038}
2039
2040void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T,
2041 raw_ostream &OS) {}
2042
2043void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
2044 raw_ostream &OS) {
2045 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2046 !T->isKindOfTypeAsWritten())
2047 return printBefore(T->getBaseType(), OS);
2048
2049 if (T->isKindOfTypeAsWritten())
2050 OS << "__kindof ";
2051
2052 print(T->getBaseType(), OS, StringRef());
2053
2054 if (T->isSpecializedAsWritten()) {
2055 bool isFirst = true;
2056 OS << '<';
2057 for (auto typeArg : T->getTypeArgsAsWritten()) {
2058 if (isFirst)
2059 isFirst = false;
2060 else
2061 OS << ",";
2062
2063 print(typeArg, OS, StringRef());
2064 }
2065 OS << '>';
2066 }
2067
2068 if (!T->qual_empty()) {
2069 bool isFirst = true;
2070 OS << '<';
2071 for (const auto *I : T->quals()) {
2072 if (isFirst)
2073 isFirst = false;
2074 else
2075 OS << ',';
2076 OS << I->getName();
2077 }
2078 OS << '>';
2079 }
2080
2081 spaceBeforePlaceHolder(OS);
2082}
2083
2084void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
2085 raw_ostream &OS) {
2086 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2087 !T->isKindOfTypeAsWritten())
2088 return printAfter(T->getBaseType(), OS);
2089}
2090
2091void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
2092 raw_ostream &OS) {
2093 printBefore(T->getPointeeType(), OS);
2094
2095 // If we need to print the pointer, print it now.
2096 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&
2098 if (HasEmptyPlaceHolder)
2099 OS << ' ';
2100 OS << '*';
2101 }
2102}
2103
2104void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
2105 raw_ostream &OS) {}
2106
2107static
2108const TemplateArgument &getArgument(const TemplateArgument &A) { return A; }
2109
2111 return A.getArgument();
2112}
2113
2114static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP,
2115 llvm::raw_ostream &OS, bool IncludeType) {
2116 A.print(PP, OS, IncludeType);
2117}
2118
2120 const PrintingPolicy &PP, llvm::raw_ostream &OS,
2121 bool IncludeType) {
2122 const TemplateArgument::ArgKind &Kind = A.getArgument().getKind();
2124 return A.getTypeSourceInfo()->getType().print(OS, PP);
2125 return A.getArgument().print(PP, OS, IncludeType);
2126}
2127
2129 TemplateArgument Pattern,
2131 unsigned Depth);
2132
2134 ArrayRef<TemplateArgument> Args, unsigned Depth) {
2135 if (Ctx.hasSameType(T, Pattern))
2136 return true;
2137
2138 // A type parameter matches its argument.
2139 if (auto *TTPT = Pattern->getAs<TemplateTypeParmType>()) {
2140 if (TTPT->getDepth() == Depth && TTPT->getIndex() < Args.size() &&
2141 Args[TTPT->getIndex()].getKind() == TemplateArgument::Type) {
2142 QualType SubstArg = Ctx.getQualifiedType(
2143 Args[TTPT->getIndex()].getAsType(), Pattern.getQualifiers());
2144 return Ctx.hasSameType(SubstArg, T);
2145 }
2146 return false;
2147 }
2148
2149 // FIXME: Recurse into array types.
2150
2151 // All other cases will need the types to be identically qualified.
2152 Qualifiers TQual, PatQual;
2153 T = Ctx.getUnqualifiedArrayType(T, TQual);
2154 Pattern = Ctx.getUnqualifiedArrayType(Pattern, PatQual);
2155 if (TQual != PatQual)
2156 return false;
2157
2158 // Recurse into pointer-like types.
2159 {
2160 QualType TPointee = T->getPointeeType();
2161 QualType PPointee = Pattern->getPointeeType();
2162 if (!TPointee.isNull() && !PPointee.isNull())
2163 return T->getTypeClass() == Pattern->getTypeClass() &&
2164 isSubstitutedType(Ctx, TPointee, PPointee, Args, Depth);
2165 }
2166
2167 // Recurse into template specialization types.
2168 if (auto *PTST =
2170 TemplateName Template;
2171 ArrayRef<TemplateArgument> TemplateArgs;
2172 if (auto *TTST = T->getAs<TemplateSpecializationType>()) {
2173 Template = TTST->getTemplateName();
2174 TemplateArgs = TTST->template_arguments();
2175 } else if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
2176 T->getAsCXXRecordDecl())) {
2177 Template = TemplateName(CTSD->getSpecializedTemplate());
2178 TemplateArgs = CTSD->getTemplateArgs().asArray();
2179 } else {
2180 return false;
2181 }
2182
2183 if (!isSubstitutedTemplateArgument(Ctx, Template, PTST->getTemplateName(),
2184 Args, Depth))
2185 return false;
2186 if (TemplateArgs.size() != PTST->template_arguments().size())
2187 return false;
2188 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
2190 Ctx, TemplateArgs[I], PTST->template_arguments()[I], Args, Depth))
2191 return false;
2192 return true;
2193 }
2194
2195 // FIXME: Handle more cases.
2196 return false;
2197}
2198
2199/// Evaluates the expression template argument 'Pattern' and returns true
2200/// if 'Arg' evaluates to the same result.
2202 TemplateArgument const &Pattern,
2203 TemplateArgument const &Arg) {
2204 if (Pattern.getKind() != TemplateArgument::Expression)
2205 return false;
2206
2207 // Can't evaluate value-dependent expressions so bail early
2208 Expr const *pattern_expr = Pattern.getAsExpr();
2209 if (pattern_expr->isValueDependent() ||
2210 !pattern_expr->isIntegerConstantExpr(Ctx))
2211 return false;
2212
2214 return llvm::APSInt::isSameValue(pattern_expr->EvaluateKnownConstInt(Ctx),
2215 Arg.getAsIntegral());
2216
2218 Expr const *args_expr = Arg.getAsExpr();
2219 if (args_expr->isValueDependent() || !args_expr->isIntegerConstantExpr(Ctx))
2220 return false;
2221
2222 return llvm::APSInt::isSameValue(args_expr->EvaluateKnownConstInt(Ctx),
2223 pattern_expr->EvaluateKnownConstInt(Ctx));
2224 }
2225
2226 return false;
2227}
2228
2230 TemplateArgument Pattern,
2232 unsigned Depth) {
2233 Arg = Ctx.getCanonicalTemplateArgument(Arg);
2234 Pattern = Ctx.getCanonicalTemplateArgument(Pattern);
2235 if (Arg.structurallyEquals(Pattern))
2236 return true;
2237
2238 if (Pattern.getKind() == TemplateArgument::Expression) {
2239 if (auto *DRE =
2240 dyn_cast<DeclRefExpr>(Pattern.getAsExpr()->IgnoreParenImpCasts())) {
2241 if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
2242 return NTTP->getDepth() == Depth && Args.size() > NTTP->getIndex() &&
2243 Args[NTTP->getIndex()].structurallyEquals(Arg);
2244 }
2245 }
2246
2247 if (templateArgumentExpressionsEqual(Ctx, Pattern, Arg))
2248 return true;
2249
2250 if (Arg.getKind() != Pattern.getKind())
2251 return false;
2252
2253 if (Arg.getKind() == TemplateArgument::Type)
2254 return isSubstitutedType(Ctx, Arg.getAsType(), Pattern.getAsType(), Args,
2255 Depth);
2256
2257 if (Arg.getKind() == TemplateArgument::Template) {
2258 TemplateDecl *PatTD = Pattern.getAsTemplate().getAsTemplateDecl();
2259 if (auto *TTPD = dyn_cast_or_null<TemplateTemplateParmDecl>(PatTD))
2260 return TTPD->getDepth() == Depth && Args.size() > TTPD->getIndex() &&
2261 Ctx.getCanonicalTemplateArgument(Args[TTPD->getIndex()])
2262 .structurallyEquals(Arg);
2263 }
2264
2265 // FIXME: Handle more cases.
2266 return false;
2267}
2268
2270 const NamedDecl *Param,
2272 unsigned Depth) {
2273 // An empty pack is equivalent to not providing a pack argument.
2274 if (Arg.getKind() == TemplateArgument::Pack && Arg.pack_size() == 0)
2275 return true;
2276
2277 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Param)) {
2278 return TTPD->hasDefaultArgument() &&
2279 isSubstitutedTemplateArgument(Ctx, Arg, TTPD->getDefaultArgument(),
2280 Args, Depth);
2281 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
2282 return TTPD->hasDefaultArgument() &&
2284 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2285 } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
2286 return NTTPD->hasDefaultArgument() &&
2287 isSubstitutedTemplateArgument(Ctx, Arg, NTTPD->getDefaultArgument(),
2288 Args, Depth);
2289 }
2290 return false;
2291}
2292
2293template <typename TA>
2294static void
2295printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy,
2296 const TemplateParameterList *TPL, bool IsPack, unsigned ParmIndex) {
2297 // Drop trailing template arguments that match default arguments.
2298 if (TPL && Policy.SuppressDefaultTemplateArgs &&
2299 !Policy.PrintCanonicalTypes && !Args.empty() && !IsPack &&
2300 Args.size() <= TPL->size()) {
2302 for (const TA &A : Args)
2303 OrigArgs.push_back(getArgument(A));
2304 while (!Args.empty() && getArgument(Args.back()).getIsDefaulted())
2305 Args = Args.drop_back();
2306 }
2307
2308 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
2309 if (!IsPack)
2310 OS << '<';
2311
2312 bool NeedSpace = false;
2313 bool FirstArg = true;
2314 for (const auto &Arg : Args) {
2315 // Print the argument into a string.
2316 SmallString<128> Buf;
2317 llvm::raw_svector_ostream ArgOS(Buf);
2318 const TemplateArgument &Argument = getArgument(Arg);
2319 if (Argument.getKind() == TemplateArgument::Pack) {
2320 if (Argument.pack_size() && !FirstArg)
2321 OS << Comma;
2322 printTo(ArgOS, Argument.getPackAsArray(), Policy, TPL,
2323 /*IsPack*/ true, ParmIndex);
2324 } else {
2325 if (!FirstArg)
2326 OS << Comma;
2327 // Tries to print the argument with location info if exists.
2328 printArgument(Arg, Policy, ArgOS,
2330 Policy, TPL, ParmIndex));
2331 }
2332 StringRef ArgString = ArgOS.str();
2333
2334 // If this is the first argument and its string representation
2335 // begins with the global scope specifier ('::foo'), add a space
2336 // to avoid printing the diagraph '<:'.
2337 if (FirstArg && ArgString.starts_with(":"))
2338 OS << ' ';
2339
2340 OS << ArgString;
2341
2342 // If the last character of our string is '>', add another space to
2343 // keep the two '>''s separate tokens.
2344 if (!ArgString.empty()) {
2345 NeedSpace = Policy.SplitTemplateClosers && ArgString.back() == '>';
2346 FirstArg = false;
2347 }
2348
2349 // Use same template parameter for all elements of Pack
2350 if (!IsPack)
2351 ParmIndex++;
2352 }
2353
2354 if (!IsPack) {
2355 if (NeedSpace)
2356 OS << ' ';
2357 OS << '>';
2358 }
2359}
2360
2362 const TemplateArgumentListInfo &Args,
2363 const PrintingPolicy &Policy,
2364 const TemplateParameterList *TPL) {
2365 printTemplateArgumentList(OS, Args.arguments(), Policy, TPL);
2366}
2367
2370 const PrintingPolicy &Policy,
2371 const TemplateParameterList *TPL) {
2372 printTo(OS, Args, Policy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2373}
2374
2377 const PrintingPolicy &Policy,
2378 const TemplateParameterList *TPL) {
2379 printTo(OS, Args, Policy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2380}
2381
2382std::string Qualifiers::getAsString() const {
2383 LangOptions LO;
2384 return getAsString(PrintingPolicy(LO));
2385}
2386
2387// Appends qualifiers to the given string, separated by spaces. Will
2388// prefix a space if the string is non-empty. Will not append a final
2389// space.
2390std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {
2391 SmallString<64> Buf;
2392 llvm::raw_svector_ostream StrOS(Buf);
2393 print(StrOS, Policy);
2394 return std::string(StrOS.str());
2395}
2396
2398 if (getCVRQualifiers())
2399 return false;
2400
2402 return false;
2403
2404 if (getObjCGCAttr())
2405 return false;
2406
2408 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
2409 return false;
2410
2411 return true;
2412}
2413
2415 switch (AS) {
2416 case LangAS::Default:
2417 return "";
2420 return "__global";
2422 case LangAS::sycl_local:
2423 return "__local";
2426 return "__private";
2428 return "__constant";
2430 return "__generic";
2433 return "__global_device";
2436 return "__global_host";
2438 return "__device__";
2440 return "__constant__";
2442 return "__shared__";
2443 case LangAS::ptr32_sptr:
2444 return "__sptr __ptr32";
2445 case LangAS::ptr32_uptr:
2446 return "__uptr __ptr32";
2447 case LangAS::ptr64:
2448 return "__ptr64";
2450 return "__funcref";
2452 return "groupshared";
2453 default:
2454 return std::to_string(toTargetAddressSpace(AS));
2455 }
2456}
2457
2458// Appends qualifiers to the given string, separated by spaces. Will
2459// prefix a space if the string is non-empty. Will not append a final
2460// space.
2461void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
2462 bool appendSpaceIfNonEmpty) const {
2463 bool addSpace = false;
2464
2465 unsigned quals = getCVRQualifiers();
2466 if (quals) {
2467 AppendTypeQualList(OS, quals, Policy.Restrict);
2468 addSpace = true;
2469 }
2470 if (hasUnaligned()) {
2471 if (addSpace)
2472 OS << ' ';
2473 OS << "__unaligned";
2474 addSpace = true;
2475 }
2476 auto ASStr = getAddrSpaceAsString(getAddressSpace());
2477 if (!ASStr.empty()) {
2478 if (addSpace)
2479 OS << ' ';
2480 addSpace = true;
2481 // Wrap target address space into an attribute syntax
2483 OS << "__attribute__((address_space(" << ASStr << ")))";
2484 else
2485 OS << ASStr;
2486 }
2487
2488 if (Qualifiers::GC gc = getObjCGCAttr()) {
2489 if (addSpace)
2490 OS << ' ';
2491 addSpace = true;
2492 if (gc == Qualifiers::Weak)
2493 OS << "__weak";
2494 else
2495 OS << "__strong";
2496 }
2497 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
2498 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
2499 if (addSpace)
2500 OS << ' ';
2501 addSpace = true;
2502 }
2503
2504 switch (lifetime) {
2505 case Qualifiers::OCL_None: llvm_unreachable("none but true");
2506 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;
2508 if (!Policy.SuppressStrongLifetime)
2509 OS << "__strong";
2510 break;
2511
2512 case Qualifiers::OCL_Weak: OS << "__weak"; break;
2513 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
2514 }
2515 }
2516
2517 if (appendSpaceIfNonEmpty && addSpace)
2518 OS << ' ';
2519}
2520
2521std::string QualType::getAsString() const {
2522 return getAsString(split(), LangOptions());
2523}
2524
2525std::string QualType::getAsString(const PrintingPolicy &Policy) const {
2526 std::string S;
2527 getAsStringInternal(S, Policy);
2528 return S;
2529}
2530
2531std::string QualType::getAsString(const Type *ty, Qualifiers qs,
2532 const PrintingPolicy &Policy) {
2533 std::string buffer;
2534 getAsStringInternal(ty, qs, buffer, Policy);
2535 return buffer;
2536}
2537
2538void QualType::print(raw_ostream &OS, const PrintingPolicy &Policy,
2539 const Twine &PlaceHolder, unsigned Indentation) const {
2540 print(splitAccordingToPolicy(*this, Policy), OS, Policy, PlaceHolder,
2541 Indentation);
2542}
2543
2545 raw_ostream &OS, const PrintingPolicy &policy,
2546 const Twine &PlaceHolder, unsigned Indentation) {
2547 SmallString<128> PHBuf;
2548 StringRef PH = PlaceHolder.toStringRef(PHBuf);
2549
2550 TypePrinter(policy, Indentation).print(ty, qs, OS, PH);
2551}
2552
2553void QualType::getAsStringInternal(std::string &Str,
2554 const PrintingPolicy &Policy) const {
2555 return getAsStringInternal(splitAccordingToPolicy(*this, Policy), Str,
2556 Policy);
2557}
2558
2560 std::string &buffer,
2561 const PrintingPolicy &policy) {
2562 SmallString<256> Buf;
2563 llvm::raw_svector_ostream StrOS(Buf);
2564 TypePrinter(policy).print(ty, qs, StrOS, buffer);
2565 std::string str = std::string(StrOS.str());
2566 buffer.swap(str);
2567}
2568
2569raw_ostream &clang::operator<<(raw_ostream &OS, QualType QT) {
2570 SplitQualType S = QT.split();
2571 TypePrinter(LangOptions()).print(S.Ty, S.Quals, OS, /*PlaceHolder=*/"");
2572 return OS;
2573}
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:2590
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
Definition: ASTContext.h:2156
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals)
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:3294
Represents a constant array type that does not decay to a pointer when used as a function parameter.
Definition: Type.h:3684
An attributed type is a type to which a type attribute has been applied.
Definition: Type.h:5600
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Definition: Type.h:5977
A fixed int type of a specified bitwidth.
Definition: Type.h:7238
Pointer to a block type.
Definition: Type.h:3345
This class is used for builtin types like 'int'.
Definition: Type.h:2977
Complex values, per C99 6.2.5p11.
Definition: Type.h:3082
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:3552
Represents a concrete matrix type with constant number of rows and columns.
Definition: Type.h:4163
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
Definition: Type.h:3243
Represents a pointer type decayed from an array or function type.
Definition: Type.h:3328
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:5354
Represents a C++17 deduced template specialization type.
Definition: Type.h:6025
Represents an extended address space qualifier where the input address space value is dependent.
Definition: Type.h:3855
Represents a qualified type name for which the type name is dependent.
Definition: Type.h:6448
Represents an array type in C++ whose size is a value-dependent expression.
Definition: Type.h:3797
Represents an extended vector type where either the type or size is dependent.
Definition: Type.h:3895
Represents a matrix type where the type and the number of rows and columns is dependent on a template...
Definition: Type.h:4222
Represents a template specialization type whose template cannot be resolved, e.g.
Definition: Type.h:6500
Represents a vector type where either the type or size is dependent.
Definition: Type.h:4017
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
Definition: Type.h:6367
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Definition: Type.h:5571
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:4057
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition: Type.h:4607
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4652
QualType desugar() const
Definition: Type.h:5119
ExtParameterInfo getExtParameterInfo(unsigned I) const
Definition: Type.h:5097
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Definition: Type.h:4911
unsigned getNumParams() const
Definition: Type.h:4885
void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
Definition: Type.h:5024
Qualifiers getMethodQuals() const
Definition: Type.h:5026
QualType getParamType(unsigned i) const
Definition: Type.h:4887
unsigned getAArch64SMEAttributes() const
Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...
Definition: Type.h:5090
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
Definition: Type.h:4962
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition: Type.h:4954
bool hasDynamicExceptionSpec() const
Return whether this function has a dynamic (throw) exception spec.
Definition: Type.h:4920
bool isVariadic() const
Whether this function prototype is variadic.
Definition: Type.h:5008
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
Definition: Type.h:4969
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Definition: Type.h:5034
A class which abstracts out some details necessary for making a call.
Definition: Type.h:4363
CallingConv getCC() const
Definition: Type.h:4425
bool getCmseNSCall() const
Definition: Type.h:4413
bool getNoCfCheck() const
Definition: Type.h:4415
unsigned getRegParm() const
Definition: Type.h:4418
bool getNoCallerSavedRegs() const
Definition: Type.h:4414
bool getNoReturn() const
Definition: Type.h:4411
bool getProducesResult() const
Definition: Type.h:4412
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:4252
ExtInfo getExtInfo() const
Definition: Type.h:4581
static ArmStateValue getArmZT0State(unsigned AttrBits)
Definition: Type.h:4539
static ArmStateValue getArmZAState(unsigned AttrBits)
Definition: Type.h:4535
QualType getReturnType() const
Definition: Type.h:4569
@ SME_PStateSMEnabledMask
Definition: Type.h:4513
@ SME_PStateSMCompatibleMask
Definition: Type.h:4514
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:3699
The injected class name of a C++ class template or class template partial specialization.
Definition: Type.h:6217
An lvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:3420
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:5238
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition: Type.h:3456
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:6948
Represents a pointer to an Objective C object.
Definition: Type.h:7004
Represents a class type in Objective C.
Definition: Type.h:6750
Represents a type parameter type in Objective C.
Definition: Type.h:6676
Represents a pack expansion of types.
Definition: Type.h:6565
Sugar for parentheses used when specifying types.
Definition: Type.h:3109
PipeType - OpenCL20.
Definition: Type.h:7204
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:3135
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:7395
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:7407
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
Definition: Type.h:7376
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:3438
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:5545
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3376
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:5885
Represents the result of substituting a type for a template type parameter.
Definition: Type.h:5815
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3585
StringRef getKindName() const
Definition: Decl.h:3776
TypedefNameDecl * getTypedefNameForAnonDecl() const
Definition: Decl.h:3813
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:6085
ArrayRef< TemplateArgument > template_arguments() const
Definition: Type.h:6153
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:3415
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
Definition: Type.h:5270
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
Definition: Type.h:5318
A container of type source information.
Definition: Type.h:7326
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:7337
static StringRef getKeywordName(ElaboratedTypeKeyword Keyword)
Definition: Type.cpp:3191
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:1870
bool isArrayType() const
Definition: Type.h:7674
QualType getLocallyUnqualifiedSingleStepDesugaredType() const
Pull a single level of sugar off of this locally-unqualified type.
Definition: Type.cpp:475
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8186
bool isObjCQualifiedIdType() const
Definition: Type.h:7761
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:694
bool isObjCIdType() const
Definition: Type.h:7773
bool isSpecifierType() const
Returns true if this type can be represented by some set of type specifiers.
Definition: Type.cpp:3076
bool isFunctionType() const
Definition: Type.h:7604
bool isObjCQualifiedClassType() const
Definition: Type.h:7767
bool isObjCClassType() const
Definition: Type.h:7779
TypeClass getTypeClass() const
Definition: Type.h:2300
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8119
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3433
A unary type transform, which is a type constructed from another.
Definition: Type.h:5462
Represents the dependent type named by a dependently-scoped typename using declaration,...
Definition: Type.h:5140
Represents a C array with a specified size that is not an integer-constant-expression.
Definition: Type.h:3743
Represents a GCC generic vector type.
Definition: Type.h:3965
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.
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