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