clang 20.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 if (Policy.UseHLSLTypes)
648 OS << "vector<";
649 printBefore(T->getElementType(), OS);
650}
651
652void TypePrinter::printDependentSizedExtVectorAfter(
654 raw_ostream &OS) {
655 if (Policy.UseHLSLTypes) {
656 OS << ", ";
657 if (T->getSizeExpr())
658 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
659 OS << ">";
660 } else {
661 OS << " __attribute__((ext_vector_type(";
662 if (T->getSizeExpr())
663 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
664 OS << ")))";
665 }
666 printAfter(T->getElementType(), OS);
667}
668
669void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {
670 switch (T->getVectorKind()) {
671 case VectorKind::AltiVecPixel:
672 OS << "__vector __pixel ";
673 break;
674 case VectorKind::AltiVecBool:
675 OS << "__vector __bool ";
676 printBefore(T->getElementType(), OS);
677 break;
678 case VectorKind::AltiVecVector:
679 OS << "__vector ";
680 printBefore(T->getElementType(), OS);
681 break;
682 case VectorKind::Neon:
683 OS << "__attribute__((neon_vector_type("
684 << T->getNumElements() << "))) ";
685 printBefore(T->getElementType(), OS);
686 break;
687 case VectorKind::NeonPoly:
688 OS << "__attribute__((neon_polyvector_type(" <<
689 T->getNumElements() << "))) ";
690 printBefore(T->getElementType(), OS);
691 break;
692 case VectorKind::Generic: {
693 // FIXME: We prefer to print the size directly here, but have no way
694 // to get the size of the type.
695 OS << "__attribute__((__vector_size__("
696 << T->getNumElements()
697 << " * sizeof(";
698 print(T->getElementType(), OS, StringRef());
699 OS << ")))) ";
700 printBefore(T->getElementType(), OS);
701 break;
702 }
703 case VectorKind::SveFixedLengthData:
704 case VectorKind::SveFixedLengthPredicate:
705 // FIXME: We prefer to print the size directly here, but have no way
706 // to get the size of the type.
707 OS << "__attribute__((__arm_sve_vector_bits__(";
708
709 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
710 // Predicates take a bit per byte of the vector size, multiply by 8 to
711 // get the number of bits passed to the attribute.
712 OS << T->getNumElements() * 8;
713 else
714 OS << T->getNumElements();
715
716 OS << " * sizeof(";
717 print(T->getElementType(), OS, StringRef());
718 // Multiply by 8 for the number of bits.
719 OS << ") * 8))) ";
720 printBefore(T->getElementType(), OS);
721 break;
722 case VectorKind::RVVFixedLengthData:
723 case VectorKind::RVVFixedLengthMask:
724 case VectorKind::RVVFixedLengthMask_1:
725 case VectorKind::RVVFixedLengthMask_2:
726 case VectorKind::RVVFixedLengthMask_4:
727 // FIXME: We prefer to print the size directly here, but have no way
728 // to get the size of the type.
729 OS << "__attribute__((__riscv_rvv_vector_bits__(";
730
731 OS << T->getNumElements();
732
733 OS << " * sizeof(";
734 print(T->getElementType(), OS, StringRef());
735 // Multiply by 8 for the number of bits.
736 OS << ") * 8))) ";
737 printBefore(T->getElementType(), OS);
738 break;
739 }
740}
741
742void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) {
743 printAfter(T->getElementType(), OS);
744}
745
746void TypePrinter::printDependentVectorBefore(
747 const DependentVectorType *T, raw_ostream &OS) {
748 switch (T->getVectorKind()) {
749 case VectorKind::AltiVecPixel:
750 OS << "__vector __pixel ";
751 break;
752 case VectorKind::AltiVecBool:
753 OS << "__vector __bool ";
754 printBefore(T->getElementType(), OS);
755 break;
756 case VectorKind::AltiVecVector:
757 OS << "__vector ";
758 printBefore(T->getElementType(), OS);
759 break;
760 case VectorKind::Neon:
761 OS << "__attribute__((neon_vector_type(";
762 if (T->getSizeExpr())
763 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
764 OS << "))) ";
765 printBefore(T->getElementType(), OS);
766 break;
767 case VectorKind::NeonPoly:
768 OS << "__attribute__((neon_polyvector_type(";
769 if (T->getSizeExpr())
770 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
771 OS << "))) ";
772 printBefore(T->getElementType(), OS);
773 break;
774 case VectorKind::Generic: {
775 // FIXME: We prefer to print the size directly here, but have no way
776 // to get the size of the type.
777 OS << "__attribute__((__vector_size__(";
778 if (T->getSizeExpr())
779 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
780 OS << " * sizeof(";
781 print(T->getElementType(), OS, StringRef());
782 OS << ")))) ";
783 printBefore(T->getElementType(), OS);
784 break;
785 }
786 case VectorKind::SveFixedLengthData:
787 case VectorKind::SveFixedLengthPredicate:
788 // FIXME: We prefer to print the size directly here, but have no way
789 // to get the size of the type.
790 OS << "__attribute__((__arm_sve_vector_bits__(";
791 if (T->getSizeExpr()) {
792 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
793 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
794 // Predicates take a bit per byte of the vector size, multiply by 8 to
795 // get the number of bits passed to the attribute.
796 OS << " * 8";
797 OS << " * sizeof(";
798 print(T->getElementType(), OS, StringRef());
799 // Multiply by 8 for the number of bits.
800 OS << ") * 8";
801 }
802 OS << "))) ";
803 printBefore(T->getElementType(), OS);
804 break;
805 case VectorKind::RVVFixedLengthData:
806 case VectorKind::RVVFixedLengthMask:
807 case VectorKind::RVVFixedLengthMask_1:
808 case VectorKind::RVVFixedLengthMask_2:
809 case VectorKind::RVVFixedLengthMask_4:
810 // FIXME: We prefer to print the size directly here, but have no way
811 // to get the size of the type.
812 OS << "__attribute__((__riscv_rvv_vector_bits__(";
813 if (T->getSizeExpr()) {
814 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
815 OS << " * sizeof(";
816 print(T->getElementType(), OS, StringRef());
817 // Multiply by 8 for the number of bits.
818 OS << ") * 8";
819 }
820 OS << "))) ";
821 printBefore(T->getElementType(), OS);
822 break;
823 }
824}
825
826void TypePrinter::printDependentVectorAfter(
827 const DependentVectorType *T, raw_ostream &OS) {
828 printAfter(T->getElementType(), OS);
829}
830
831void TypePrinter::printExtVectorBefore(const ExtVectorType *T,
832 raw_ostream &OS) {
833 if (Policy.UseHLSLTypes)
834 OS << "vector<";
835 printBefore(T->getElementType(), OS);
836}
837
838void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) {
839 printAfter(T->getElementType(), OS);
840
841 if (Policy.UseHLSLTypes) {
842 OS << ", ";
843 OS << T->getNumElements();
844 OS << ">";
845 } else {
846 OS << " __attribute__((ext_vector_type(";
847 OS << T->getNumElements();
848 OS << ")))";
849 }
850}
851
852void TypePrinter::printConstantMatrixBefore(const ConstantMatrixType *T,
853 raw_ostream &OS) {
854 printBefore(T->getElementType(), OS);
855 OS << " __attribute__((matrix_type(";
856 OS << T->getNumRows() << ", " << T->getNumColumns();
857 OS << ")))";
858}
859
860void TypePrinter::printConstantMatrixAfter(const ConstantMatrixType *T,
861 raw_ostream &OS) {
862 printAfter(T->getElementType(), OS);
863}
864
865void TypePrinter::printDependentSizedMatrixBefore(
866 const DependentSizedMatrixType *T, raw_ostream &OS) {
867 printBefore(T->getElementType(), OS);
868 OS << " __attribute__((matrix_type(";
869 if (T->getRowExpr()) {
870 T->getRowExpr()->printPretty(OS, nullptr, Policy);
871 }
872 OS << ", ";
873 if (T->getColumnExpr()) {
874 T->getColumnExpr()->printPretty(OS, nullptr, Policy);
875 }
876 OS << ")))";
877}
878
879void TypePrinter::printDependentSizedMatrixAfter(
880 const DependentSizedMatrixType *T, raw_ostream &OS) {
881 printAfter(T->getElementType(), OS);
882}
883
884void
886 const PrintingPolicy &Policy)
887 const {
889 OS << " throw(";
891 OS << "...";
892 else
893 for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) {
894 if (I)
895 OS << ", ";
896
897 OS << getExceptionType(I).stream(Policy);
898 }
899 OS << ')';
900 } else if (EST_NoThrow == getExceptionSpecType()) {
901 OS << " __attribute__((nothrow))";
903 OS << " noexcept";
904 // FIXME:Is it useful to print out the expression for a non-dependent
905 // noexcept specification?
907 OS << '(';
908 if (getNoexceptExpr())
909 getNoexceptExpr()->printPretty(OS, nullptr, Policy);
910 OS << ')';
911 }
912 }
913}
914
915void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,
916 raw_ostream &OS) {
917 if (T->hasTrailingReturn()) {
918 OS << "auto ";
919 if (!HasEmptyPlaceHolder)
920 OS << '(';
921 } else {
922 // If needed for precedence reasons, wrap the inner part in grouping parens.
923 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
924 printBefore(T->getReturnType(), OS);
925 if (!PrevPHIsEmpty.get())
926 OS << '(';
927 }
928}
929
931 switch (ABI) {
933 llvm_unreachable("asking for spelling of ordinary parameter ABI");
935 return "swift_context";
937 return "swift_async_context";
939 return "swift_error_result";
941 return "swift_indirect_result";
942 }
943 llvm_unreachable("bad parameter ABI kind");
944}
945
946void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
947 raw_ostream &OS) {
948 // If needed for precedence reasons, wrap the inner part in grouping parens.
949 if (!HasEmptyPlaceHolder)
950 OS << ')';
951 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
952
953 OS << '(';
954 {
955 ParamPolicyRAII ParamPolicy(Policy);
956 for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {
957 if (i) OS << ", ";
958
959 auto EPI = T->getExtParameterInfo(i);
960 if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) ";
961 if (EPI.isNoEscape())
962 OS << "__attribute__((noescape)) ";
963 auto ABI = EPI.getABI();
964 if (ABI != ParameterABI::Ordinary)
965 OS << "__attribute__((" << getParameterABISpelling(ABI) << ")) ";
966
967 print(T->getParamType(i), OS, StringRef());
968 }
969 }
970
971 if (T->isVariadic()) {
972 if (T->getNumParams())
973 OS << ", ";
974 OS << "...";
975 } else if (T->getNumParams() == 0 && Policy.UseVoidForZeroParams) {
976 // Do not emit int() if we have a proto, emit 'int(void)'.
977 OS << "void";
978 }
979
980 OS << ')';
981
983 unsigned SMEBits = T->getAArch64SMEAttributes();
984
986 OS << " __arm_streaming_compatible";
988 OS << " __arm_streaming";
990 OS << " __arm_preserves(\"za\")";
992 OS << " __arm_in(\"za\")";
994 OS << " __arm_out(\"za\")";
996 OS << " __arm_inout(\"za\")";
998 OS << " __arm_preserves(\"zt0\")";
1000 OS << " __arm_in(\"zt0\")";
1002 OS << " __arm_out(\"zt0\")";
1004 OS << " __arm_inout(\"zt0\")";
1005
1006 printFunctionAfter(Info, OS);
1007
1008 if (!T->getMethodQuals().empty())
1009 OS << " " << T->getMethodQuals().getAsString();
1010
1011 switch (T->getRefQualifier()) {
1012 case RQ_None:
1013 break;
1014
1015 case RQ_LValue:
1016 OS << " &";
1017 break;
1018
1019 case RQ_RValue:
1020 OS << " &&";
1021 break;
1022 }
1023 T->printExceptionSpecification(OS, Policy);
1024
1026 for (const auto &CFE : FX) {
1027 OS << " __attribute__((" << CFE.Effect.name();
1028 if (const Expr *E = CFE.Cond.getCondition()) {
1029 OS << '(';
1030 E->printPretty(OS, nullptr, Policy);
1031 OS << ')';
1032 }
1033 OS << "))";
1034 }
1035
1036 if (T->hasTrailingReturn()) {
1037 OS << " -> ";
1038 print(T->getReturnType(), OS, StringRef());
1039 } else
1040 printAfter(T->getReturnType(), OS);
1041}
1042
1043void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
1044 raw_ostream &OS) {
1045 if (!InsideCCAttribute) {
1046 switch (Info.getCC()) {
1047 case CC_C:
1048 // The C calling convention is the default on the vast majority of platforms
1049 // we support. If the user wrote it explicitly, it will usually be printed
1050 // while traversing the AttributedType. If the type has been desugared, let
1051 // the canonical spelling be the implicit calling convention.
1052 // FIXME: It would be better to be explicit in certain contexts, such as a
1053 // cdecl function typedef used to declare a member function with the
1054 // Microsoft C++ ABI.
1055 break;
1056 case CC_X86StdCall:
1057 OS << " __attribute__((stdcall))";
1058 break;
1059 case CC_X86FastCall:
1060 OS << " __attribute__((fastcall))";
1061 break;
1062 case CC_X86ThisCall:
1063 OS << " __attribute__((thiscall))";
1064 break;
1065 case CC_X86VectorCall:
1066 OS << " __attribute__((vectorcall))";
1067 break;
1068 case CC_X86Pascal:
1069 OS << " __attribute__((pascal))";
1070 break;
1071 case CC_AAPCS:
1072 OS << " __attribute__((pcs(\"aapcs\")))";
1073 break;
1074 case CC_AAPCS_VFP:
1075 OS << " __attribute__((pcs(\"aapcs-vfp\")))";
1076 break;
1078 OS << "__attribute__((aarch64_vector_pcs))";
1079 break;
1080 case CC_AArch64SVEPCS:
1081 OS << "__attribute__((aarch64_sve_pcs))";
1082 break;
1084 OS << "__attribute__((amdgpu_kernel))";
1085 break;
1086 case CC_IntelOclBicc:
1087 OS << " __attribute__((intel_ocl_bicc))";
1088 break;
1089 case CC_Win64:
1090 OS << " __attribute__((ms_abi))";
1091 break;
1092 case CC_X86_64SysV:
1093 OS << " __attribute__((sysv_abi))";
1094 break;
1095 case CC_X86RegCall:
1096 OS << " __attribute__((regcall))";
1097 break;
1098 case CC_SpirFunction:
1099 case CC_OpenCLKernel:
1100 // Do nothing. These CCs are not available as attributes.
1101 break;
1102 case CC_Swift:
1103 OS << " __attribute__((swiftcall))";
1104 break;
1105 case CC_SwiftAsync:
1106 OS << "__attribute__((swiftasynccall))";
1107 break;
1108 case CC_PreserveMost:
1109 OS << " __attribute__((preserve_most))";
1110 break;
1111 case CC_PreserveAll:
1112 OS << " __attribute__((preserve_all))";
1113 break;
1114 case CC_M68kRTD:
1115 OS << " __attribute__((m68k_rtd))";
1116 break;
1117 case CC_PreserveNone:
1118 OS << " __attribute__((preserve_none))";
1119 break;
1120 case CC_RISCVVectorCall:
1121 OS << "__attribute__((riscv_vector_cc))";
1122 break;
1123 }
1124 }
1125
1126 if (Info.getNoReturn())
1127 OS << " __attribute__((noreturn))";
1128 if (Info.getCmseNSCall())
1129 OS << " __attribute__((cmse_nonsecure_call))";
1130 if (Info.getProducesResult())
1131 OS << " __attribute__((ns_returns_retained))";
1132 if (Info.getRegParm())
1133 OS << " __attribute__((regparm ("
1134 << Info.getRegParm() << ")))";
1135 if (Info.getNoCallerSavedRegs())
1136 OS << " __attribute__((no_caller_saved_registers))";
1137 if (Info.getNoCfCheck())
1138 OS << " __attribute__((nocf_check))";
1139}
1140
1141void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T,
1142 raw_ostream &OS) {
1143 // If needed for precedence reasons, wrap the inner part in grouping parens.
1144 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
1145 printBefore(T->getReturnType(), OS);
1146 if (!PrevPHIsEmpty.get())
1147 OS << '(';
1148}
1149
1150void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,
1151 raw_ostream &OS) {
1152 // If needed for precedence reasons, wrap the inner part in grouping parens.
1153 if (!HasEmptyPlaceHolder)
1154 OS << ')';
1155 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
1156
1157 OS << "()";
1158 printFunctionAfter(T->getExtInfo(), OS);
1159 printAfter(T->getReturnType(), OS);
1160}
1161
1162void TypePrinter::printTypeSpec(NamedDecl *D, raw_ostream &OS) {
1163
1164 // Compute the full nested-name-specifier for this type.
1165 // In C, this will always be empty except when the type
1166 // being printed is anonymous within other Record.
1167 if (!Policy.SuppressScope)
1168 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1169
1170 IdentifierInfo *II = D->getIdentifier();
1171 OS << II->getName();
1172 spaceBeforePlaceHolder(OS);
1173}
1174
1175void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,
1176 raw_ostream &OS) {
1177 printTypeSpec(T->getDecl(), OS);
1178}
1179
1180void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,
1181 raw_ostream &OS) {}
1182
1183void TypePrinter::printUsingBefore(const UsingType *T, raw_ostream &OS) {
1184 // After `namespace b { using a::X }`, is the type X within B a::X or b::X?
1185 //
1186 // - b::X is more formally correct given the UsingType model
1187 // - b::X makes sense if "re-exporting" a symbol in a new namespace
1188 // - a::X makes sense if "importing" a symbol for convenience
1189 //
1190 // The "importing" use seems much more common, so we print a::X.
1191 // This could be a policy option, but the right choice seems to rest more
1192 // with the intent of the code than the caller.
1193 printTypeSpec(T->getFoundDecl()->getUnderlyingDecl(), OS);
1194}
1195
1196void TypePrinter::printUsingAfter(const UsingType *T, raw_ostream &OS) {}
1197
1198void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
1199 printTypeSpec(T->getDecl(), OS);
1200}
1201
1202void TypePrinter::printMacroQualifiedBefore(const MacroQualifiedType *T,
1203 raw_ostream &OS) {
1204 StringRef MacroName = T->getMacroIdentifier()->getName();
1205 OS << MacroName << " ";
1206
1207 // Since this type is meant to print the macro instead of the whole attribute,
1208 // we trim any attributes and go directly to the original modified type.
1209 printBefore(T->getModifiedType(), OS);
1210}
1211
1212void TypePrinter::printMacroQualifiedAfter(const MacroQualifiedType *T,
1213 raw_ostream &OS) {
1214 printAfter(T->getModifiedType(), OS);
1215}
1216
1217void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) {}
1218
1219void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
1220 raw_ostream &OS) {
1221 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual "
1222 : "typeof ");
1223 if (T->getUnderlyingExpr())
1224 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
1225 spaceBeforePlaceHolder(OS);
1226}
1227
1228void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
1229 raw_ostream &OS) {}
1230
1231void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) {
1232 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual("
1233 : "typeof(");
1234 print(T->getUnmodifiedType(), OS, StringRef());
1235 OS << ')';
1236 spaceBeforePlaceHolder(OS);
1237}
1238
1239void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) {}
1240
1241void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {
1242 OS << "decltype(";
1243 if (T->getUnderlyingExpr())
1244 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
1245 OS << ')';
1246 spaceBeforePlaceHolder(OS);
1247}
1248
1249void TypePrinter::printPackIndexingBefore(const PackIndexingType *T,
1250 raw_ostream &OS) {
1251 if (T->hasSelectedType()) {
1252 OS << T->getSelectedType();
1253 } else {
1254 OS << T->getPattern() << "...[";
1255 T->getIndexExpr()->printPretty(OS, nullptr, Policy);
1256 OS << "]";
1257 }
1258 spaceBeforePlaceHolder(OS);
1259}
1260
1261void TypePrinter::printPackIndexingAfter(const PackIndexingType *T,
1262 raw_ostream &OS) {}
1263
1264void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) {}
1265
1266void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,
1267 raw_ostream &OS) {
1268 IncludeStrongLifetimeRAII Strong(Policy);
1269
1270 static llvm::DenseMap<int, const char *> Transformation = {{
1271#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
1272 {UnaryTransformType::Enum, "__" #Trait},
1273#include "clang/Basic/TransformTypeTraits.def"
1274 }};
1275 OS << Transformation[T->getUTTKind()] << '(';
1276 print(T->getBaseType(), OS, StringRef());
1277 OS << ')';
1278 spaceBeforePlaceHolder(OS);
1279}
1280
1281void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,
1282 raw_ostream &OS) {}
1283
1284void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
1285 // If the type has been deduced, do not print 'auto'.
1286 if (!T->getDeducedType().isNull()) {
1287 printBefore(T->getDeducedType(), OS);
1288 } else {
1289 if (T->isConstrained()) {
1290 // FIXME: Track a TypeConstraint as type sugar, so that we can print the
1291 // type as it was written.
1292 T->getTypeConstraintConcept()->getDeclName().print(OS, Policy);
1293 auto Args = T->getTypeConstraintArguments();
1294 if (!Args.empty())
1296 OS, Args, Policy,
1297 T->getTypeConstraintConcept()->getTemplateParameters());
1298 OS << ' ';
1299 }
1300 switch (T->getKeyword()) {
1301 case AutoTypeKeyword::Auto: OS << "auto"; break;
1302 case AutoTypeKeyword::DecltypeAuto: OS << "decltype(auto)"; break;
1303 case AutoTypeKeyword::GNUAutoType: OS << "__auto_type"; break;
1304 }
1305 spaceBeforePlaceHolder(OS);
1306 }
1307}
1308
1309void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {
1310 // If the type has been deduced, do not print 'auto'.
1311 if (!T->getDeducedType().isNull())
1312 printAfter(T->getDeducedType(), OS);
1313}
1314
1315void TypePrinter::printDeducedTemplateSpecializationBefore(
1316 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1317 // If the type has been deduced, print the deduced type.
1318 if (!T->getDeducedType().isNull()) {
1319 printBefore(T->getDeducedType(), OS);
1320 } else {
1321 IncludeStrongLifetimeRAII Strong(Policy);
1322 T->getTemplateName().print(OS, Policy);
1323 spaceBeforePlaceHolder(OS);
1324 }
1325}
1326
1327void TypePrinter::printDeducedTemplateSpecializationAfter(
1328 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1329 // If the type has been deduced, print the deduced type.
1330 if (!T->getDeducedType().isNull())
1331 printAfter(T->getDeducedType(), OS);
1332}
1333
1334void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {
1335 IncludeStrongLifetimeRAII Strong(Policy);
1336
1337 OS << "_Atomic(";
1338 print(T->getValueType(), OS, StringRef());
1339 OS << ')';
1340 spaceBeforePlaceHolder(OS);
1341}
1342
1343void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) {}
1344
1345void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) {
1346 IncludeStrongLifetimeRAII Strong(Policy);
1347
1348 if (T->isReadOnly())
1349 OS << "read_only ";
1350 else
1351 OS << "write_only ";
1352 OS << "pipe ";
1353 print(T->getElementType(), OS, StringRef());
1354 spaceBeforePlaceHolder(OS);
1355}
1356
1357void TypePrinter::printPipeAfter(const PipeType *T, raw_ostream &OS) {}
1358
1359void TypePrinter::printBitIntBefore(const BitIntType *T, raw_ostream &OS) {
1360 if (T->isUnsigned())
1361 OS << "unsigned ";
1362 OS << "_BitInt(" << T->getNumBits() << ")";
1363 spaceBeforePlaceHolder(OS);
1364}
1365
1366void TypePrinter::printBitIntAfter(const BitIntType *T, raw_ostream &OS) {}
1367
1368void TypePrinter::printDependentBitIntBefore(const DependentBitIntType *T,
1369 raw_ostream &OS) {
1370 if (T->isUnsigned())
1371 OS << "unsigned ";
1372 OS << "_BitInt(";
1373 T->getNumBitsExpr()->printPretty(OS, nullptr, Policy);
1374 OS << ")";
1375 spaceBeforePlaceHolder(OS);
1376}
1377
1378void TypePrinter::printDependentBitIntAfter(const DependentBitIntType *T,
1379 raw_ostream &OS) {}
1380
1381/// Appends the given scope to the end of a string.
1382void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS,
1383 DeclarationName NameInScope) {
1384 if (DC->isTranslationUnit())
1385 return;
1386
1387 // FIXME: Consider replacing this with NamedDecl::printNestedNameSpecifier,
1388 // which can also print names for function and method scopes.
1389 if (DC->isFunctionOrMethod())
1390 return;
1391
1392 if (Policy.Callbacks && Policy.Callbacks->isScopeVisible(DC))
1393 return;
1394
1395 if (const auto *NS = dyn_cast<NamespaceDecl>(DC)) {
1396 if (Policy.SuppressUnwrittenScope && NS->isAnonymousNamespace())
1397 return AppendScope(DC->getParent(), OS, NameInScope);
1398
1399 // Only suppress an inline namespace if the name has the same lookup
1400 // results in the enclosing namespace.
1401 if (Policy.SuppressInlineNamespace && NS->isInline() && NameInScope &&
1402 NS->isRedundantInlineQualifierFor(NameInScope))
1403 return AppendScope(DC->getParent(), OS, NameInScope);
1404
1405 AppendScope(DC->getParent(), OS, NS->getDeclName());
1406 if (NS->getIdentifier())
1407 OS << NS->getName() << "::";
1408 else
1409 OS << "(anonymous namespace)::";
1410 } else if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
1411 AppendScope(DC->getParent(), OS, Spec->getDeclName());
1412 IncludeStrongLifetimeRAII Strong(Policy);
1413 OS << Spec->getIdentifier()->getName();
1414 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
1416 OS, TemplateArgs.asArray(), Policy,
1417 Spec->getSpecializedTemplate()->getTemplateParameters());
1418 OS << "::";
1419 } else if (const auto *Tag = dyn_cast<TagDecl>(DC)) {
1420 AppendScope(DC->getParent(), OS, Tag->getDeclName());
1421 if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl())
1422 OS << Typedef->getIdentifier()->getName() << "::";
1423 else if (Tag->getIdentifier())
1424 OS << Tag->getIdentifier()->getName() << "::";
1425 else
1426 return;
1427 } else {
1428 AppendScope(DC->getParent(), OS, NameInScope);
1429 }
1430}
1431
1432void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {
1433 if (Policy.IncludeTagDefinition) {
1434 PrintingPolicy SubPolicy = Policy;
1435 SubPolicy.IncludeTagDefinition = false;
1436 D->print(OS, SubPolicy, Indentation);
1437 spaceBeforePlaceHolder(OS);
1438 return;
1439 }
1440
1441 bool HasKindDecoration = false;
1442
1443 // We don't print tags unless this is an elaborated type.
1444 // In C, we just assume every RecordType is an elaborated type.
1445 if (!Policy.SuppressTagKeyword && !D->getTypedefNameForAnonDecl()) {
1446 HasKindDecoration = true;
1447 OS << D->getKindName();
1448 OS << ' ';
1449 }
1450
1451 // Compute the full nested-name-specifier for this type.
1452 // In C, this will always be empty except when the type
1453 // being printed is anonymous within other Record.
1454 if (!Policy.SuppressScope)
1455 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1456
1457 if (const IdentifierInfo *II = D->getIdentifier())
1458 OS << II->getName();
1459 else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) {
1460 assert(Typedef->getIdentifier() && "Typedef without identifier?");
1461 OS << Typedef->getIdentifier()->getName();
1462 } else {
1463 // Make an unambiguous representation for anonymous types, e.g.
1464 // (anonymous enum at /usr/include/string.h:120:9)
1465 OS << (Policy.MSVCFormatting ? '`' : '(');
1466
1467 if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
1468 OS << "lambda";
1469 HasKindDecoration = true;
1470 } else if ((isa<RecordDecl>(D) && cast<RecordDecl>(D)->isAnonymousStructOrUnion())) {
1471 OS << "anonymous";
1472 } else {
1473 OS << "unnamed";
1474 }
1475
1476 if (Policy.AnonymousTagLocations) {
1477 // Suppress the redundant tag keyword if we just printed one.
1478 // We don't have to worry about ElaboratedTypes here because you can't
1479 // refer to an anonymous type with one.
1480 if (!HasKindDecoration)
1481 OS << " " << D->getKindName();
1482
1484 D->getLocation());
1485 if (PLoc.isValid()) {
1486 OS << " at ";
1487 StringRef File = PLoc.getFilename();
1488 llvm::SmallString<1024> WrittenFile(File);
1489 if (auto *Callbacks = Policy.Callbacks)
1490 WrittenFile = Callbacks->remapPath(File);
1491 // Fix inconsistent path separator created by
1492 // clang::DirectoryLookup::LookupFile when the file path is relative
1493 // path.
1494 llvm::sys::path::Style Style =
1495 llvm::sys::path::is_absolute(WrittenFile)
1496 ? llvm::sys::path::Style::native
1497 : (Policy.MSVCFormatting
1498 ? llvm::sys::path::Style::windows_backslash
1499 : llvm::sys::path::Style::posix);
1500 llvm::sys::path::native(WrittenFile, Style);
1501 OS << WrittenFile << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
1502 }
1503 }
1504
1505 OS << (Policy.MSVCFormatting ? '\'' : ')');
1506 }
1507
1508 // If this is a class template specialization, print the template
1509 // arguments.
1510 if (auto *S = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1511 const TemplateParameterList *TParams =
1512 S->getSpecializedTemplate()->getTemplateParameters();
1513 const ASTTemplateArgumentListInfo *TArgAsWritten =
1514 S->getTemplateArgsAsWritten();
1515 IncludeStrongLifetimeRAII Strong(Policy);
1516 if (TArgAsWritten && !Policy.PrintCanonicalTypes)
1517 printTemplateArgumentList(OS, TArgAsWritten->arguments(), Policy,
1518 TParams);
1519 else
1520 printTemplateArgumentList(OS, S->getTemplateArgs().asArray(), Policy,
1521 TParams);
1522 }
1523
1524 spaceBeforePlaceHolder(OS);
1525}
1526
1527void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
1528 // Print the preferred name if we have one for this type.
1529 if (Policy.UsePreferredNames) {
1530 for (const auto *PNA : T->getDecl()->specific_attrs<PreferredNameAttr>()) {
1531 if (!declaresSameEntity(PNA->getTypedefType()->getAsCXXRecordDecl(),
1532 T->getDecl()))
1533 continue;
1534 // Find the outermost typedef or alias template.
1535 QualType T = PNA->getTypedefType();
1536 while (true) {
1537 if (auto *TT = dyn_cast<TypedefType>(T))
1538 return printTypeSpec(TT->getDecl(), OS);
1539 if (auto *TST = dyn_cast<TemplateSpecializationType>(T))
1540 return printTemplateId(TST, OS, /*FullyQualify=*/true);
1542 }
1543 }
1544 }
1545
1546 printTag(T->getDecl(), OS);
1547}
1548
1549void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) {}
1550
1551void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {
1552 printTag(T->getDecl(), OS);
1553}
1554
1555void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {}
1556
1557void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
1558 raw_ostream &OS) {
1559 TemplateTypeParmDecl *D = T->getDecl();
1560 if (D && D->isImplicit()) {
1561 if (auto *TC = D->getTypeConstraint()) {
1562 TC->print(OS, Policy);
1563 OS << ' ';
1564 }
1565 OS << "auto";
1566 } else if (IdentifierInfo *Id = T->getIdentifier())
1567 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1568 : Id->getName());
1569 else
1570 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
1571
1572 spaceBeforePlaceHolder(OS);
1573}
1574
1575void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,
1576 raw_ostream &OS) {}
1577
1578void TypePrinter::printSubstTemplateTypeParmBefore(
1580 raw_ostream &OS) {
1581 IncludeStrongLifetimeRAII Strong(Policy);
1582 printBefore(T->getReplacementType(), OS);
1583}
1584
1585void TypePrinter::printSubstTemplateTypeParmAfter(
1587 raw_ostream &OS) {
1588 IncludeStrongLifetimeRAII Strong(Policy);
1589 printAfter(T->getReplacementType(), OS);
1590}
1591
1592void TypePrinter::printSubstTemplateTypeParmPackBefore(
1594 raw_ostream &OS) {
1595 IncludeStrongLifetimeRAII Strong(Policy);
1596 if (const TemplateTypeParmDecl *D = T->getReplacedParameter()) {
1597 if (D && D->isImplicit()) {
1598 if (auto *TC = D->getTypeConstraint()) {
1599 TC->print(OS, Policy);
1600 OS << ' ';
1601 }
1602 OS << "auto";
1603 } else if (IdentifierInfo *Id = D->getIdentifier())
1604 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1605 : Id->getName());
1606 else
1607 OS << "type-parameter-" << D->getDepth() << '-' << D->getIndex();
1608
1609 spaceBeforePlaceHolder(OS);
1610 }
1611}
1612
1613void TypePrinter::printSubstTemplateTypeParmPackAfter(
1615 raw_ostream &OS) {
1616 IncludeStrongLifetimeRAII Strong(Policy);
1617}
1618
1619void TypePrinter::printTemplateId(const TemplateSpecializationType *T,
1620 raw_ostream &OS, bool FullyQualify) {
1621 IncludeStrongLifetimeRAII Strong(Policy);
1622
1623 TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl();
1624 // FIXME: Null TD never exercised in test suite.
1625 if (FullyQualify && TD) {
1626 if (!Policy.SuppressScope)
1627 AppendScope(TD->getDeclContext(), OS, TD->getDeclName());
1628
1629 OS << TD->getName();
1630 } else {
1631 T->getTemplateName().print(OS, Policy, TemplateName::Qualified::None);
1632 }
1633
1634 DefaultTemplateArgsPolicyRAII TemplateArgs(Policy);
1635 const TemplateParameterList *TPL = TD ? TD->getTemplateParameters() : nullptr;
1636 printTemplateArgumentList(OS, T->template_arguments(), Policy, TPL);
1637 spaceBeforePlaceHolder(OS);
1638}
1639
1640void TypePrinter::printTemplateSpecializationBefore(
1642 raw_ostream &OS) {
1643 printTemplateId(T, OS, Policy.FullyQualifiedName);
1644}
1645
1646void TypePrinter::printTemplateSpecializationAfter(
1648 raw_ostream &OS) {}
1649
1650void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
1651 raw_ostream &OS) {
1652 if (Policy.PrintInjectedClassNameWithArguments)
1653 return printTemplateSpecializationBefore(T->getInjectedTST(), OS);
1654
1655 IncludeStrongLifetimeRAII Strong(Policy);
1656 T->getTemplateName().print(OS, Policy);
1657 spaceBeforePlaceHolder(OS);
1658}
1659
1660void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
1661 raw_ostream &OS) {}
1662
1663void TypePrinter::printElaboratedBefore(const ElaboratedType *T,
1664 raw_ostream &OS) {
1665 if (Policy.IncludeTagDefinition && T->getOwnedTagDecl()) {
1666 TagDecl *OwnedTagDecl = T->getOwnedTagDecl();
1667 assert(OwnedTagDecl->getTypeForDecl() == T->getNamedType().getTypePtr() &&
1668 "OwnedTagDecl expected to be a declaration for the type");
1669 PrintingPolicy SubPolicy = Policy;
1670 SubPolicy.IncludeTagDefinition = false;
1671 OwnedTagDecl->print(OS, SubPolicy, Indentation);
1672 spaceBeforePlaceHolder(OS);
1673 return;
1674 }
1675
1676 if (Policy.SuppressElaboration) {
1677 printBefore(T->getNamedType(), OS);
1678 return;
1679 }
1680
1681 // The tag definition will take care of these.
1682 if (!Policy.IncludeTagDefinition)
1683 {
1684 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1685 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1686 OS << " ";
1687 NestedNameSpecifier *Qualifier = T->getQualifier();
1688 if (!Policy.SuppressTagKeyword && Policy.SuppressScope &&
1689 !Policy.SuppressUnwrittenScope) {
1690 bool OldTagKeyword = Policy.SuppressTagKeyword;
1691 bool OldSupressScope = Policy.SuppressScope;
1692 Policy.SuppressTagKeyword = true;
1693 Policy.SuppressScope = false;
1694 printBefore(T->getNamedType(), OS);
1695 Policy.SuppressTagKeyword = OldTagKeyword;
1696 Policy.SuppressScope = OldSupressScope;
1697 return;
1698 }
1699 if (Qualifier)
1700 Qualifier->print(OS, Policy);
1701 }
1702
1703 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1704 printBefore(T->getNamedType(), OS);
1705}
1706
1707void TypePrinter::printElaboratedAfter(const ElaboratedType *T,
1708 raw_ostream &OS) {
1709 if (Policy.IncludeTagDefinition && T->getOwnedTagDecl())
1710 return;
1711
1712 if (Policy.SuppressElaboration) {
1713 printAfter(T->getNamedType(), OS);
1714 return;
1715 }
1716
1717 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1718 printAfter(T->getNamedType(), OS);
1719}
1720
1721void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {
1722 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1723 printBefore(T->getInnerType(), OS);
1724 OS << '(';
1725 } else
1726 printBefore(T->getInnerType(), OS);
1727}
1728
1729void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {
1730 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1731 OS << ')';
1732 printAfter(T->getInnerType(), OS);
1733 } else
1734 printAfter(T->getInnerType(), OS);
1735}
1736
1737void TypePrinter::printDependentNameBefore(const DependentNameType *T,
1738 raw_ostream &OS) {
1739 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1740 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1741 OS << " ";
1742
1743 T->getQualifier()->print(OS, Policy);
1744
1745 OS << T->getIdentifier()->getName();
1746 spaceBeforePlaceHolder(OS);
1747}
1748
1749void TypePrinter::printDependentNameAfter(const DependentNameType *T,
1750 raw_ostream &OS) {}
1751
1752void TypePrinter::printDependentTemplateSpecializationBefore(
1753 const DependentTemplateSpecializationType *T, raw_ostream &OS) {
1754 IncludeStrongLifetimeRAII Strong(Policy);
1755
1756 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1757 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1758 OS << " ";
1759
1760 if (T->getQualifier())
1761 T->getQualifier()->print(OS, Policy);
1762 OS << "template " << T->getIdentifier()->getName();
1763 printTemplateArgumentList(OS, T->template_arguments(), Policy);
1764 spaceBeforePlaceHolder(OS);
1765}
1766
1767void TypePrinter::printDependentTemplateSpecializationAfter(
1768 const DependentTemplateSpecializationType *T, raw_ostream &OS) {}
1769
1770void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,
1771 raw_ostream &OS) {
1772 printBefore(T->getPattern(), OS);
1773}
1774
1775void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
1776 raw_ostream &OS) {
1777 printAfter(T->getPattern(), OS);
1778 OS << "...";
1779}
1780
1782 raw_ostream &OS,
1783 const PrintingPolicy &Policy) {
1784 OS << ' ';
1785 if (T->isCountInBytes() && T->isOrNull())
1786 OS << "__sized_by_or_null(";
1787 else if (T->isCountInBytes())
1788 OS << "__sized_by(";
1789 else if (T->isOrNull())
1790 OS << "__counted_by_or_null(";
1791 else
1792 OS << "__counted_by(";
1793 if (T->getCountExpr())
1794 T->getCountExpr()->printPretty(OS, nullptr, Policy);
1795 OS << ')';
1796}
1797
1798void TypePrinter::printCountAttributedBefore(const CountAttributedType *T,
1799 raw_ostream &OS) {
1800 printBefore(T->desugar(), OS);
1801 if (!T->isArrayType())
1802 printCountAttributedImpl(T, OS, Policy);
1803}
1804
1805void TypePrinter::printCountAttributedAfter(const CountAttributedType *T,
1806 raw_ostream &OS) {
1807 printAfter(T->desugar(), OS);
1808 if (T->isArrayType())
1809 printCountAttributedImpl(T, OS, Policy);
1810}
1811
1812void TypePrinter::printAttributedBefore(const AttributedType *T,
1813 raw_ostream &OS) {
1814 // FIXME: Generate this with TableGen.
1815
1816 // Prefer the macro forms of the GC and ownership qualifiers.
1817 if (T->getAttrKind() == attr::ObjCGC ||
1818 T->getAttrKind() == attr::ObjCOwnership)
1819 return printBefore(T->getEquivalentType(), OS);
1820
1821 if (T->getAttrKind() == attr::ObjCKindOf)
1822 OS << "__kindof ";
1823
1824 if (T->getAttrKind() == attr::AddressSpace)
1825 printBefore(T->getEquivalentType(), OS);
1826 else
1827 printBefore(T->getModifiedType(), OS);
1828
1829 if (T->isMSTypeSpec()) {
1830 switch (T->getAttrKind()) {
1831 default: return;
1832 case attr::Ptr32: OS << " __ptr32"; break;
1833 case attr::Ptr64: OS << " __ptr64"; break;
1834 case attr::SPtr: OS << " __sptr"; break;
1835 case attr::UPtr: OS << " __uptr"; break;
1836 }
1837 spaceBeforePlaceHolder(OS);
1838 }
1839
1840 if (T->isWebAssemblyFuncrefSpec())
1841 OS << "__funcref";
1842
1843 // Print nullability type specifiers.
1844 if (T->getImmediateNullability()) {
1845 if (T->getAttrKind() == attr::TypeNonNull)
1846 OS << " _Nonnull";
1847 else if (T->getAttrKind() == attr::TypeNullable)
1848 OS << " _Nullable";
1849 else if (T->getAttrKind() == attr::TypeNullUnspecified)
1850 OS << " _Null_unspecified";
1851 else if (T->getAttrKind() == attr::TypeNullableResult)
1852 OS << " _Nullable_result";
1853 else
1854 llvm_unreachable("unhandled nullability");
1855 spaceBeforePlaceHolder(OS);
1856 }
1857}
1858
1859void TypePrinter::printAttributedAfter(const AttributedType *T,
1860 raw_ostream &OS) {
1861 // FIXME: Generate this with TableGen.
1862
1863 // Prefer the macro forms of the GC and ownership qualifiers.
1864 if (T->getAttrKind() == attr::ObjCGC ||
1865 T->getAttrKind() == attr::ObjCOwnership)
1866 return printAfter(T->getEquivalentType(), OS);
1867
1868 // If this is a calling convention attribute, don't print the implicit CC from
1869 // the modified type.
1870 SaveAndRestore MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());
1871
1872 printAfter(T->getModifiedType(), OS);
1873
1874 // Some attributes are printed as qualifiers before the type, so we have
1875 // nothing left to do.
1876 if (T->getAttrKind() == attr::ObjCKindOf || T->isMSTypeSpec() ||
1877 T->getImmediateNullability() || T->isWebAssemblyFuncrefSpec())
1878 return;
1879
1880 // Don't print the inert __unsafe_unretained attribute at all.
1881 if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained)
1882 return;
1883
1884 // Don't print ns_returns_retained unless it had an effect.
1885 if (T->getAttrKind() == attr::NSReturnsRetained &&
1886 !T->getEquivalentType()->castAs<FunctionType>()
1888 return;
1889
1890 if (T->getAttrKind() == attr::LifetimeBound) {
1891 OS << " [[clang::lifetimebound]]";
1892 return;
1893 }
1894
1895 // The printing of the address_space attribute is handled by the qualifier
1896 // since it is still stored in the qualifier. Return early to prevent printing
1897 // this twice.
1898 if (T->getAttrKind() == attr::AddressSpace)
1899 return;
1900
1901 if (T->getAttrKind() == attr::AnnotateType) {
1902 // FIXME: Print the attribute arguments once we have a way to retrieve these
1903 // here. For the meantime, we just print `[[clang::annotate_type(...)]]`
1904 // without the arguments so that we know at least that we had _some_
1905 // annotation on the type.
1906 OS << " [[clang::annotate_type(...)]]";
1907 return;
1908 }
1909
1910 if (T->getAttrKind() == attr::ArmStreaming) {
1911 OS << "__arm_streaming";
1912 return;
1913 }
1914 if (T->getAttrKind() == attr::ArmStreamingCompatible) {
1915 OS << "__arm_streaming_compatible";
1916 return;
1917 }
1918
1919 OS << " __attribute__((";
1920 switch (T->getAttrKind()) {
1921#define TYPE_ATTR(NAME)
1922#define DECL_OR_TYPE_ATTR(NAME)
1923#define ATTR(NAME) case attr::NAME:
1924#include "clang/Basic/AttrList.inc"
1925 llvm_unreachable("non-type attribute attached to type");
1926
1927 case attr::BTFTypeTag:
1928 llvm_unreachable("BTFTypeTag attribute handled separately");
1929
1930 case attr::OpenCLPrivateAddressSpace:
1931 case attr::OpenCLGlobalAddressSpace:
1932 case attr::OpenCLGlobalDeviceAddressSpace:
1933 case attr::OpenCLGlobalHostAddressSpace:
1934 case attr::OpenCLLocalAddressSpace:
1935 case attr::OpenCLConstantAddressSpace:
1936 case attr::OpenCLGenericAddressSpace:
1937 case attr::HLSLGroupSharedAddressSpace:
1938 // FIXME: Update printAttributedBefore to print these once we generate
1939 // AttributedType nodes for them.
1940 break;
1941
1942 case attr::CountedBy:
1943 case attr::CountedByOrNull:
1944 case attr::SizedBy:
1945 case attr::SizedByOrNull:
1946 case attr::LifetimeBound:
1947 case attr::TypeNonNull:
1948 case attr::TypeNullable:
1949 case attr::TypeNullableResult:
1950 case attr::TypeNullUnspecified:
1951 case attr::ObjCGC:
1952 case attr::ObjCInertUnsafeUnretained:
1953 case attr::ObjCKindOf:
1954 case attr::ObjCOwnership:
1955 case attr::Ptr32:
1956 case attr::Ptr64:
1957 case attr::SPtr:
1958 case attr::UPtr:
1959 case attr::AddressSpace:
1960 case attr::CmseNSCall:
1961 case attr::AnnotateType:
1962 case attr::WebAssemblyFuncref:
1963 case attr::ArmStreaming:
1964 case attr::ArmStreamingCompatible:
1965 case attr::ArmIn:
1966 case attr::ArmOut:
1967 case attr::ArmInOut:
1968 case attr::ArmPreserves:
1969 case attr::NonBlocking:
1970 case attr::NonAllocating:
1971 case attr::Blocking:
1972 case attr::Allocating:
1973 llvm_unreachable("This attribute should have been handled already");
1974
1975 case attr::NSReturnsRetained:
1976 OS << "ns_returns_retained";
1977 break;
1978
1979 // FIXME: When Sema learns to form this AttributedType, avoid printing the
1980 // attribute again in printFunctionProtoAfter.
1981 case attr::AnyX86NoCfCheck: OS << "nocf_check"; break;
1982 case attr::CDecl: OS << "cdecl"; break;
1983 case attr::FastCall: OS << "fastcall"; break;
1984 case attr::StdCall: OS << "stdcall"; break;
1985 case attr::ThisCall: OS << "thiscall"; break;
1986 case attr::SwiftCall: OS << "swiftcall"; break;
1987 case attr::SwiftAsyncCall: OS << "swiftasynccall"; break;
1988 case attr::VectorCall: OS << "vectorcall"; break;
1989 case attr::Pascal: OS << "pascal"; break;
1990 case attr::MSABI: OS << "ms_abi"; break;
1991 case attr::SysVABI: OS << "sysv_abi"; break;
1992 case attr::RegCall: OS << "regcall"; break;
1993 case attr::Pcs: {
1994 OS << "pcs(";
1995 QualType t = T->getEquivalentType();
1996 while (!t->isFunctionType())
1997 t = t->getPointeeType();
1998 OS << (t->castAs<FunctionType>()->getCallConv() == CC_AAPCS ?
1999 "\"aapcs\"" : "\"aapcs-vfp\"");
2000 OS << ')';
2001 break;
2002 }
2003 case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break;
2004 case attr::AArch64SVEPcs: OS << "aarch64_sve_pcs"; break;
2005 case attr::AMDGPUKernelCall: OS << "amdgpu_kernel"; break;
2006 case attr::IntelOclBicc: OS << "inteloclbicc"; break;
2007 case attr::PreserveMost:
2008 OS << "preserve_most";
2009 break;
2010
2011 case attr::PreserveAll:
2012 OS << "preserve_all";
2013 break;
2014 case attr::M68kRTD:
2015 OS << "m68k_rtd";
2016 break;
2017 case attr::PreserveNone:
2018 OS << "preserve_none";
2019 break;
2020 case attr::RISCVVectorCC:
2021 OS << "riscv_vector_cc";
2022 break;
2023 case attr::NoDeref:
2024 OS << "noderef";
2025 break;
2026 case attr::AcquireHandle:
2027 OS << "acquire_handle";
2028 break;
2029 case attr::ArmMveStrictPolymorphism:
2030 OS << "__clang_arm_mve_strict_polymorphism";
2031 break;
2032
2033 // Nothing to print for this attribute.
2034 case attr::HLSLParamModifier:
2035 break;
2036 }
2037 OS << "))";
2038}
2039
2040void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T,
2041 raw_ostream &OS) {
2042 printBefore(T->getWrappedType(), OS);
2043 OS << " __attribute__((btf_type_tag(\"" << T->getAttr()->getBTFTypeTag() << "\")))";
2044}
2045
2046void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,
2047 raw_ostream &OS) {
2048 printAfter(T->getWrappedType(), OS);
2049}
2050
2051void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
2052 raw_ostream &OS) {
2053 OS << T->getDecl()->getName();
2054 spaceBeforePlaceHolder(OS);
2055}
2056
2057void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
2058 raw_ostream &OS) {}
2059
2060void TypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType *T,
2061 raw_ostream &OS) {
2062 OS << T->getDecl()->getName();
2063 if (!T->qual_empty()) {
2064 bool isFirst = true;
2065 OS << '<';
2066 for (const auto *I : T->quals()) {
2067 if (isFirst)
2068 isFirst = false;
2069 else
2070 OS << ',';
2071 OS << I->getName();
2072 }
2073 OS << '>';
2074 }
2075
2076 spaceBeforePlaceHolder(OS);
2077}
2078
2079void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T,
2080 raw_ostream &OS) {}
2081
2082void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
2083 raw_ostream &OS) {
2084 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2085 !T->isKindOfTypeAsWritten())
2086 return printBefore(T->getBaseType(), OS);
2087
2088 if (T->isKindOfTypeAsWritten())
2089 OS << "__kindof ";
2090
2091 print(T->getBaseType(), OS, StringRef());
2092
2093 if (T->isSpecializedAsWritten()) {
2094 bool isFirst = true;
2095 OS << '<';
2096 for (auto typeArg : T->getTypeArgsAsWritten()) {
2097 if (isFirst)
2098 isFirst = false;
2099 else
2100 OS << ",";
2101
2102 print(typeArg, OS, StringRef());
2103 }
2104 OS << '>';
2105 }
2106
2107 if (!T->qual_empty()) {
2108 bool isFirst = true;
2109 OS << '<';
2110 for (const auto *I : T->quals()) {
2111 if (isFirst)
2112 isFirst = false;
2113 else
2114 OS << ',';
2115 OS << I->getName();
2116 }
2117 OS << '>';
2118 }
2119
2120 spaceBeforePlaceHolder(OS);
2121}
2122
2123void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
2124 raw_ostream &OS) {
2125 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2126 !T->isKindOfTypeAsWritten())
2127 return printAfter(T->getBaseType(), OS);
2128}
2129
2130void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
2131 raw_ostream &OS) {
2132 printBefore(T->getPointeeType(), OS);
2133
2134 // If we need to print the pointer, print it now.
2135 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&
2137 if (HasEmptyPlaceHolder)
2138 OS << ' ';
2139 OS << '*';
2140 }
2141}
2142
2143void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
2144 raw_ostream &OS) {}
2145
2146static
2147const TemplateArgument &getArgument(const TemplateArgument &A) { return A; }
2148
2150 return A.getArgument();
2151}
2152
2153static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP,
2154 llvm::raw_ostream &OS, bool IncludeType) {
2155 A.print(PP, OS, IncludeType);
2156}
2157
2159 const PrintingPolicy &PP, llvm::raw_ostream &OS,
2160 bool IncludeType) {
2161 const TemplateArgument::ArgKind &Kind = A.getArgument().getKind();
2163 return A.getTypeSourceInfo()->getType().print(OS, PP);
2164 return A.getArgument().print(PP, OS, IncludeType);
2165}
2166
2168 TemplateArgument Pattern,
2170 unsigned Depth);
2171
2173 ArrayRef<TemplateArgument> Args, unsigned Depth) {
2174 if (Ctx.hasSameType(T, Pattern))
2175 return true;
2176
2177 // A type parameter matches its argument.
2178 if (auto *TTPT = Pattern->getAs<TemplateTypeParmType>()) {
2179 if (TTPT->getDepth() == Depth && TTPT->getIndex() < Args.size() &&
2180 Args[TTPT->getIndex()].getKind() == TemplateArgument::Type) {
2181 QualType SubstArg = Ctx.getQualifiedType(
2182 Args[TTPT->getIndex()].getAsType(), Pattern.getQualifiers());
2183 return Ctx.hasSameType(SubstArg, T);
2184 }
2185 return false;
2186 }
2187
2188 // FIXME: Recurse into array types.
2189
2190 // All other cases will need the types to be identically qualified.
2191 Qualifiers TQual, PatQual;
2192 T = Ctx.getUnqualifiedArrayType(T, TQual);
2193 Pattern = Ctx.getUnqualifiedArrayType(Pattern, PatQual);
2194 if (TQual != PatQual)
2195 return false;
2196
2197 // Recurse into pointer-like types.
2198 {
2199 QualType TPointee = T->getPointeeType();
2200 QualType PPointee = Pattern->getPointeeType();
2201 if (!TPointee.isNull() && !PPointee.isNull())
2202 return T->getTypeClass() == Pattern->getTypeClass() &&
2203 isSubstitutedType(Ctx, TPointee, PPointee, Args, Depth);
2204 }
2205
2206 // Recurse into template specialization types.
2207 if (auto *PTST =
2209 TemplateName Template;
2210 ArrayRef<TemplateArgument> TemplateArgs;
2211 if (auto *TTST = T->getAs<TemplateSpecializationType>()) {
2212 Template = TTST->getTemplateName();
2213 TemplateArgs = TTST->template_arguments();
2214 } else if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
2215 T->getAsCXXRecordDecl())) {
2216 Template = TemplateName(CTSD->getSpecializedTemplate());
2217 TemplateArgs = CTSD->getTemplateArgs().asArray();
2218 } else {
2219 return false;
2220 }
2221
2222 if (!isSubstitutedTemplateArgument(Ctx, Template, PTST->getTemplateName(),
2223 Args, Depth))
2224 return false;
2225 if (TemplateArgs.size() != PTST->template_arguments().size())
2226 return false;
2227 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
2229 Ctx, TemplateArgs[I], PTST->template_arguments()[I], Args, Depth))
2230 return false;
2231 return true;
2232 }
2233
2234 // FIXME: Handle more cases.
2235 return false;
2236}
2237
2238/// Evaluates the expression template argument 'Pattern' and returns true
2239/// if 'Arg' evaluates to the same result.
2241 TemplateArgument const &Pattern,
2242 TemplateArgument const &Arg) {
2243 if (Pattern.getKind() != TemplateArgument::Expression)
2244 return false;
2245
2246 // Can't evaluate value-dependent expressions so bail early
2247 Expr const *pattern_expr = Pattern.getAsExpr();
2248 if (pattern_expr->isValueDependent() ||
2249 !pattern_expr->isIntegerConstantExpr(Ctx))
2250 return false;
2251
2253 return llvm::APSInt::isSameValue(pattern_expr->EvaluateKnownConstInt(Ctx),
2254 Arg.getAsIntegral());
2255
2257 Expr const *args_expr = Arg.getAsExpr();
2258 if (args_expr->isValueDependent() || !args_expr->isIntegerConstantExpr(Ctx))
2259 return false;
2260
2261 return llvm::APSInt::isSameValue(args_expr->EvaluateKnownConstInt(Ctx),
2262 pattern_expr->EvaluateKnownConstInt(Ctx));
2263 }
2264
2265 return false;
2266}
2267
2269 TemplateArgument Pattern,
2271 unsigned Depth) {
2272 Arg = Ctx.getCanonicalTemplateArgument(Arg);
2273 Pattern = Ctx.getCanonicalTemplateArgument(Pattern);
2274 if (Arg.structurallyEquals(Pattern))
2275 return true;
2276
2277 if (Pattern.getKind() == TemplateArgument::Expression) {
2278 if (auto *DRE =
2279 dyn_cast<DeclRefExpr>(Pattern.getAsExpr()->IgnoreParenImpCasts())) {
2280 if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
2281 return NTTP->getDepth() == Depth && Args.size() > NTTP->getIndex() &&
2282 Args[NTTP->getIndex()].structurallyEquals(Arg);
2283 }
2284 }
2285
2286 if (templateArgumentExpressionsEqual(Ctx, Pattern, Arg))
2287 return true;
2288
2289 if (Arg.getKind() != Pattern.getKind())
2290 return false;
2291
2292 if (Arg.getKind() == TemplateArgument::Type)
2293 return isSubstitutedType(Ctx, Arg.getAsType(), Pattern.getAsType(), Args,
2294 Depth);
2295
2296 if (Arg.getKind() == TemplateArgument::Template) {
2297 TemplateDecl *PatTD = Pattern.getAsTemplate().getAsTemplateDecl();
2298 if (auto *TTPD = dyn_cast_or_null<TemplateTemplateParmDecl>(PatTD))
2299 return TTPD->getDepth() == Depth && Args.size() > TTPD->getIndex() &&
2300 Ctx.getCanonicalTemplateArgument(Args[TTPD->getIndex()])
2301 .structurallyEquals(Arg);
2302 }
2303
2304 // FIXME: Handle more cases.
2305 return false;
2306}
2307
2309 const NamedDecl *Param,
2311 unsigned Depth) {
2312 // An empty pack is equivalent to not providing a pack argument.
2313 if (Arg.getKind() == TemplateArgument::Pack && Arg.pack_size() == 0)
2314 return true;
2315
2316 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Param)) {
2317 return TTPD->hasDefaultArgument() &&
2319 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2320 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
2321 return TTPD->hasDefaultArgument() &&
2323 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2324 } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
2325 return NTTPD->hasDefaultArgument() &&
2327 Ctx, Arg, NTTPD->getDefaultArgument().getArgument(), Args,
2328 Depth);
2329 }
2330 return false;
2331}
2332
2333template <typename TA>
2334static void
2335printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy,
2336 const TemplateParameterList *TPL, bool IsPack, unsigned ParmIndex) {
2337 // Drop trailing template arguments that match default arguments.
2338 if (TPL && Policy.SuppressDefaultTemplateArgs &&
2339 !Policy.PrintCanonicalTypes && !Args.empty() && !IsPack &&
2340 Args.size() <= TPL->size()) {
2342 for (const TA &A : Args)
2343 OrigArgs.push_back(getArgument(A));
2344 while (!Args.empty() && getArgument(Args.back()).getIsDefaulted())
2345 Args = Args.drop_back();
2346 }
2347
2348 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
2349 if (!IsPack)
2350 OS << '<';
2351
2352 bool NeedSpace = false;
2353 bool FirstArg = true;
2354 for (const auto &Arg : Args) {
2355 // Print the argument into a string.
2356 SmallString<128> Buf;
2357 llvm::raw_svector_ostream ArgOS(Buf);
2358 const TemplateArgument &Argument = getArgument(Arg);
2359 if (Argument.getKind() == TemplateArgument::Pack) {
2360 if (Argument.pack_size() && !FirstArg)
2361 OS << Comma;
2362 printTo(ArgOS, Argument.getPackAsArray(), Policy, TPL,
2363 /*IsPack*/ true, ParmIndex);
2364 } else {
2365 if (!FirstArg)
2366 OS << Comma;
2367 // Tries to print the argument with location info if exists.
2368 printArgument(Arg, Policy, ArgOS,
2370 Policy, TPL, ParmIndex));
2371 }
2372 StringRef ArgString = ArgOS.str();
2373
2374 // If this is the first argument and its string representation
2375 // begins with the global scope specifier ('::foo'), add a space
2376 // to avoid printing the diagraph '<:'.
2377 if (FirstArg && ArgString.starts_with(":"))
2378 OS << ' ';
2379
2380 OS << ArgString;
2381
2382 // If the last character of our string is '>', add another space to
2383 // keep the two '>''s separate tokens.
2384 if (!ArgString.empty()) {
2385 NeedSpace = Policy.SplitTemplateClosers && ArgString.back() == '>';
2386 FirstArg = false;
2387 }
2388
2389 // Use same template parameter for all elements of Pack
2390 if (!IsPack)
2391 ParmIndex++;
2392 }
2393
2394 if (!IsPack) {
2395 if (NeedSpace)
2396 OS << ' ';
2397 OS << '>';
2398 }
2399}
2400
2402 const TemplateArgumentListInfo &Args,
2403 const PrintingPolicy &Policy,
2404 const TemplateParameterList *TPL) {
2405 printTemplateArgumentList(OS, Args.arguments(), Policy, TPL);
2406}
2407
2410 const PrintingPolicy &Policy,
2411 const TemplateParameterList *TPL) {
2412 printTo(OS, Args, Policy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2413}
2414
2417 const PrintingPolicy &Policy,
2418 const TemplateParameterList *TPL) {
2419 printTo(OS, Args, Policy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2420}
2421
2422std::string Qualifiers::getAsString() const {
2423 LangOptions LO;
2424 return getAsString(PrintingPolicy(LO));
2425}
2426
2427// Appends qualifiers to the given string, separated by spaces. Will
2428// prefix a space if the string is non-empty. Will not append a final
2429// space.
2430std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {
2431 SmallString<64> Buf;
2432 llvm::raw_svector_ostream StrOS(Buf);
2433 print(StrOS, Policy);
2434 return std::string(StrOS.str());
2435}
2436
2438 if (getCVRQualifiers())
2439 return false;
2440
2442 return false;
2443
2444 if (getObjCGCAttr())
2445 return false;
2446
2448 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
2449 return false;
2450
2451 return true;
2452}
2453
2455 switch (AS) {
2456 case LangAS::Default:
2457 return "";
2460 return "__global";
2462 case LangAS::sycl_local:
2463 return "__local";
2466 return "__private";
2468 return "__constant";
2470 return "__generic";
2473 return "__global_device";
2476 return "__global_host";
2478 return "__device__";
2480 return "__constant__";
2482 return "__shared__";
2483 case LangAS::ptr32_sptr:
2484 return "__sptr __ptr32";
2485 case LangAS::ptr32_uptr:
2486 return "__uptr __ptr32";
2487 case LangAS::ptr64:
2488 return "__ptr64";
2490 return "__funcref";
2492 return "groupshared";
2493 default:
2494 return std::to_string(toTargetAddressSpace(AS));
2495 }
2496}
2497
2498// Appends qualifiers to the given string, separated by spaces. Will
2499// prefix a space if the string is non-empty. Will not append a final
2500// space.
2501void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
2502 bool appendSpaceIfNonEmpty) const {
2503 bool addSpace = false;
2504
2505 unsigned quals = getCVRQualifiers();
2506 if (quals) {
2507 AppendTypeQualList(OS, quals, Policy.Restrict);
2508 addSpace = true;
2509 }
2510 if (hasUnaligned()) {
2511 if (addSpace)
2512 OS << ' ';
2513 OS << "__unaligned";
2514 addSpace = true;
2515 }
2516 auto ASStr = getAddrSpaceAsString(getAddressSpace());
2517 if (!ASStr.empty()) {
2518 if (addSpace)
2519 OS << ' ';
2520 addSpace = true;
2521 // Wrap target address space into an attribute syntax
2523 OS << "__attribute__((address_space(" << ASStr << ")))";
2524 else
2525 OS << ASStr;
2526 }
2527
2528 if (Qualifiers::GC gc = getObjCGCAttr()) {
2529 if (addSpace)
2530 OS << ' ';
2531 addSpace = true;
2532 if (gc == Qualifiers::Weak)
2533 OS << "__weak";
2534 else
2535 OS << "__strong";
2536 }
2537 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
2538 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
2539 if (addSpace)
2540 OS << ' ';
2541 addSpace = true;
2542 }
2543
2544 switch (lifetime) {
2545 case Qualifiers::OCL_None: llvm_unreachable("none but true");
2546 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;
2548 if (!Policy.SuppressStrongLifetime)
2549 OS << "__strong";
2550 break;
2551
2552 case Qualifiers::OCL_Weak: OS << "__weak"; break;
2553 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
2554 }
2555 }
2556
2557 if (appendSpaceIfNonEmpty && addSpace)
2558 OS << ' ';
2559}
2560
2561std::string QualType::getAsString() const {
2562 return getAsString(split(), LangOptions());
2563}
2564
2565std::string QualType::getAsString(const PrintingPolicy &Policy) const {
2566 std::string S;
2567 getAsStringInternal(S, Policy);
2568 return S;
2569}
2570
2571std::string QualType::getAsString(const Type *ty, Qualifiers qs,
2572 const PrintingPolicy &Policy) {
2573 std::string buffer;
2574 getAsStringInternal(ty, qs, buffer, Policy);
2575 return buffer;
2576}
2577
2578void QualType::print(raw_ostream &OS, const PrintingPolicy &Policy,
2579 const Twine &PlaceHolder, unsigned Indentation) const {
2580 print(splitAccordingToPolicy(*this, Policy), OS, Policy, PlaceHolder,
2581 Indentation);
2582}
2583
2585 raw_ostream &OS, const PrintingPolicy &policy,
2586 const Twine &PlaceHolder, unsigned Indentation) {
2587 SmallString<128> PHBuf;
2588 StringRef PH = PlaceHolder.toStringRef(PHBuf);
2589
2590 TypePrinter(policy, Indentation).print(ty, qs, OS, PH);
2591}
2592
2593void QualType::getAsStringInternal(std::string &Str,
2594 const PrintingPolicy &Policy) const {
2595 return getAsStringInternal(splitAccordingToPolicy(*this, Policy), Str,
2596 Policy);
2597}
2598
2600 std::string &buffer,
2601 const PrintingPolicy &policy) {
2602 SmallString<256> Buf;
2603 llvm::raw_svector_ostream StrOS(Buf);
2604 TypePrinter(policy).print(ty, qs, StrOS, buffer);
2605 std::string str = std::string(StrOS.str());
2606 buffer.swap(str);
2607}
2608
2609raw_ostream &clang::operator<<(raw_ostream &OS, QualType QT) {
2610 SplitQualType S = QT.split();
2611 TypePrinter(LangOptions()).print(S.Ty, S.Quals, OS, /*PlaceHolder=*/"");
2612 return OS;
2613}
Defines the clang::ASTContext interface.
Provides definitions for the various language-specific address spaces.
const Decl * D
Expr * E
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 &ASTCtx, QualType Ty)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
uint32_t Id
Definition: SemaARM.cpp:1144
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:187
SourceManager & getSourceManager()
Definition: ASTContext.h:721
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:2644
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
Definition: ASTContext.h:2210
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals) const
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals.
Represents a type which was implicitly adjusted by the semantic engine for arbitrary reasons.
Definition: Type.h:3346
Represents a constant array type that does not decay to a pointer when used as a function parameter.
Definition: Type.h:3736
An attributed type is a type to which a type attribute has been applied.
Definition: Type.h:6020
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Definition: Type.h:6375
A fixed int type of a specified bitwidth.
Definition: Type.h:7633
Pointer to a block type.
Definition: Type.h:3397
This class is used for builtin types like 'int'.
Definition: Type.h:3023
Complex values, per C99 6.2.5p11.
Definition: Type.h:3134
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:3604
Represents a concrete matrix type with constant number of rows and columns.
Definition: Type.h:4219
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
Definition: Type.h:3295
Represents a pointer type decayed from an array or function type.
Definition: Type.h:3380
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:2090
bool isTranslationUnit() const
Definition: DeclBase.h:2166
bool isFunctionOrMethod() const
Definition: DeclBase.h:2142
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:523
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:600
SourceLocation getLocation() const
Definition: DeclBase.h:446
DeclContext * getDeclContext()
Definition: DeclBase.h:455
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:5774
Represents a C++17 deduced template specialization type.
Definition: Type.h:6423
Represents an extended address space qualifier where the input address space value is dependent.
Definition: Type.h:3907
Represents a qualified type name for which the type name is dependent.
Definition: Type.h:6843
Represents an array type in C++ whose size is a value-dependent expression.
Definition: Type.h:3849
Represents an extended vector type where either the type or size is dependent.
Definition: Type.h:3947
Represents a matrix type where the type and the number of rows and columns is dependent on a template...
Definition: Type.h:4278
Represents a template specialization type whose template cannot be resolved, e.g.
Definition: Type.h:6895
Represents a vector type where either the type or size is dependent.
Definition: Type.h:4073
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
Definition: Type.h:6762
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Definition: Type.h:5991
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:3070
bool isIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
ExtVectorType - Extended vector type.
Definition: Type.h:4113
An immutable set of FunctionEffects and possibly conditions attached to them.
Definition: Type.h:4882
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition: Type.h:4668
Represents a prototype with parameter type info, e.g.
Definition: Type.h:5002
QualType desugar() const
Definition: Type.h:5546
ExtParameterInfo getExtParameterInfo(unsigned I) const
Definition: Type.h:5468
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Definition: Type.h:5282
unsigned getNumParams() const
Definition: Type.h:5255
void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
Definition: Type.h:5395
Qualifiers getMethodQuals() const
Definition: Type.h:5397
QualType getParamType(unsigned i) const
Definition: Type.h:5257
FunctionEffectsRef getFunctionEffects() const
Definition: Type.h:5528
unsigned getAArch64SMEAttributes() const
Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...
Definition: Type.h:5461
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
Definition: Type.h:5333
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition: Type.h:5325
bool hasDynamicExceptionSpec() const
Return whether this function has a dynamic (throw) exception spec.
Definition: Type.h:5291
bool isVariadic() const
Whether this function prototype is variadic.
Definition: Type.h:5379
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
Definition: Type.h:5340
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Definition: Type.h:5405
A class which abstracts out some details necessary for making a call.
Definition: Type.h:4419
CallingConv getCC() const
Definition: Type.h:4481
bool getCmseNSCall() const
Definition: Type.h:4469
bool getNoCfCheck() const
Definition: Type.h:4471
unsigned getRegParm() const
Definition: Type.h:4474
bool getNoCallerSavedRegs() const
Definition: Type.h:4470
bool getNoReturn() const
Definition: Type.h:4467
bool getProducesResult() const
Definition: Type.h:4468
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:4308
ExtInfo getExtInfo() const
Definition: Type.h:4642
static ArmStateValue getArmZT0State(unsigned AttrBits)
Definition: Type.h:4600
static ArmStateValue getArmZAState(unsigned AttrBits)
Definition: Type.h:4596
QualType getReturnType() const
Definition: Type.h:4630
@ SME_PStateSMEnabledMask
Definition: Type.h:4574
@ SME_PStateSMCompatibleMask
Definition: Type.h:4575
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:3751
The injected class name of a C++ class template or class template partial specialization.
Definition: Type.h:6612
An lvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:3472
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:476
Sugar type that represents a type that was qualified by a qualifier written as a macro invocation.
Definition: Type.h:5665
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition: Type.h:3508
This represents a decl that may have a name.
Definition: Decl.h:249
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:7343
Represents a pointer to an Objective C object.
Definition: Type.h:7399
Represents a class type in Objective C.
Definition: Type.h:7145
Represents a type parameter type in Objective C.
Definition: Type.h:7071
Represents a pack expansion of types.
Definition: Type.h:6960
Sugar for parentheses used when specifying types.
Definition: Type.h:3161
PipeType - OpenCL20.
Definition: Type.h:7599
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:3187
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:941
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1008
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition: Type.h:7790
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:7802
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
Definition: Type.h:7771
std::string getAsString() const
StreamedQualTypeHelper stream(const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Definition: Type.h:1395
The collection of all-type qualifiers we support.
Definition: Type.h:319
unsigned getCVRQualifiers() const
Definition: Type.h:475
GC getObjCGCAttr() const
Definition: Type.h:506
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Definition: Type.h:348
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
Definition: Type.h:341
@ OCL_None
There is no lifetime qualification on this type.
Definition: Type.h:337
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Definition: Type.h:351
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
Definition: Type.h:354
bool hasUnaligned() const
Definition: Type.h:498
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool appendSpaceIfNonEmpty=false) const
bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const
ObjCLifetime getObjCLifetime() const
Definition: Type.h:532
bool empty() const
Definition: Type.h:634
std::string getAsString() const
LangAS getAddressSpace() const
Definition: Type.h:558
static std::string getAddrSpaceAsString(LangAS AS)
An rvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:3490
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:5965
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3428
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:6283
Represents the result of substituting a type for a template type parameter.
Definition: Type.h:6213
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3561
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:203
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:6480
Declaration of a template type parameter.
const Type * getTypeForDecl() const
Definition: Decl.h:3391
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
Definition: Type.h:5697
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
Definition: Type.h:5747
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:7732
static StringRef getKeywordName(ElaboratedTypeKeyword Keyword)
Definition: Type.cpp:3203
The base class of the type hierarchy.
Definition: Type.h:1829
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1882
bool isArrayType() const
Definition: Type.h:8075
QualType getLocallyUnqualifiedSingleStepDesugaredType() const
Pull a single level of sugar off of this locally-unqualified type.
Definition: Type.cpp:476
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8607
bool isObjCQualifiedIdType() const
Definition: Type.h:8166
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:705
bool isObjCIdType() const
Definition: Type.h:8178
bool isSpecifierType() const
Returns true if this type can be represented by some set of type specifiers.
Definition: Type.cpp:3088
bool isFunctionType() const
Definition: Type.h:7999
bool isObjCQualifiedClassType() const
Definition: Type.h:8172
bool isObjCClassType() const
Definition: Type.h:8184
TypeClass getTypeClass() const
Definition: Type.h:2334
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8540
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3409
A unary type transform, which is a type constructed from another.
Definition: Type.h:5882
Represents the dependent type named by a dependently-scoped typename using declaration,...
Definition: Type.h:5567
Represents a C array with a specified size that is not an integer-constant-expression.
Definition: Type.h:3795
Represents a GCC generic vector type.
Definition: Type.h:4021
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:1778
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
Definition: Type.h:1781
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition: Type.h:1784
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:366
@ 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:284
@ CC_Swift
Definition: Specifiers.h:293
@ CC_IntelOclBicc
Definition: Specifiers.h:290
@ CC_OpenCLKernel
Definition: Specifiers.h:292
@ CC_PreserveMost
Definition: Specifiers.h:295
@ CC_Win64
Definition: Specifiers.h:285
@ CC_X86ThisCall
Definition: Specifiers.h:282
@ CC_AArch64VectorCall
Definition: Specifiers.h:297
@ CC_AAPCS
Definition: Specifiers.h:288
@ CC_PreserveNone
Definition: Specifiers.h:301
@ CC_C
Definition: Specifiers.h:279
@ CC_AMDGPUKernelCall
Definition: Specifiers.h:299
@ CC_M68kRTD
Definition: Specifiers.h:300
@ CC_SwiftAsync
Definition: Specifiers.h:294
@ CC_X86RegCall
Definition: Specifiers.h:287
@ CC_RISCVVectorCall
Definition: Specifiers.h:302
@ CC_X86VectorCall
Definition: Specifiers.h:283
@ CC_SpirFunction
Definition: Specifiers.h:291
@ CC_AArch64SVEPCS
Definition: Specifiers.h:298
@ CC_X86StdCall
Definition: Specifiers.h:280
@ CC_X86_64SysV
Definition: Specifiers.h:286
@ CC_PreserveAll
Definition: Specifiers.h:296
@ CC_X86FastCall
Definition: Specifiers.h:281
@ CC_AAPCS_VFP
Definition: Specifiers.h:289
@ None
No keyword precedes the qualified type name.
@ EST_NoThrow
Microsoft __declspec(nothrow) extension.
@ EST_MSAny
Microsoft throw(...) extension.
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:676
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
Definition: TemplateBase.h:705
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
unsigned MSVCFormatting
Use whitespace and punctuation like MSVC does.
unsigned SuppressDefaultTemplateArgs
When true, attempt to suppress template arguments that match the default argument for the parameter.
unsigned SplitTemplateClosers
Whether nested templates must be closed like 'a<b<c> >' rather than 'a<b<c>>'.
unsigned PrintCanonicalTypes
Whether to print types as written or canonically.
unsigned SuppressSpecifiers
Whether we should suppress printing of the actual specifiers for the given type or declaration.
unsigned SuppressTagKeyword
Whether type printing should skip printing the tag keyword.
unsigned SuppressStrongLifetime
When true, suppress printing of the __strong lifetime qualifier in ARC.
unsigned Restrict
Whether we can use 'restrict' rather than '__restrict'.
unsigned SuppressScope
Suppresses printing of scope specifiers.
unsigned IncludeTagDefinition
When true, include the body of a tag definition.
unsigned SuppressLifetimeQualifiers
When true, suppress printing of lifetime qualifier in ARC.
A std::pair-like structure for storing a qualified type split into its local qualifiers and its local...
Definition: Type.h:874
const Type * Ty
The locally-unqualified type.
Definition: Type.h:876
Qualifiers Quals
The local qualifiers.
Definition: Type.h:879