clang 23.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"
25#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/Compiler.h"
41#include "llvm/Support/ErrorHandling.h"
42#include "llvm/Support/SaveAndRestore.h"
43#include "llvm/Support/raw_ostream.h"
44#include <cassert>
45#include <string>
46
47using namespace clang;
48
49namespace {
50
51/// RAII object that enables printing of the ARC __strong lifetime
52/// qualifier.
53class IncludeStrongLifetimeRAII {
54 PrintingPolicy &Policy;
55 bool Old;
56
57public:
58 explicit IncludeStrongLifetimeRAII(PrintingPolicy &Policy)
59 : Policy(Policy), Old(Policy.SuppressStrongLifetime) {
60 if (!Policy.SuppressLifetimeQualifiers)
61 Policy.SuppressStrongLifetime = false;
62 }
63
64 ~IncludeStrongLifetimeRAII() { Policy.SuppressStrongLifetime = Old; }
65};
66
67class ParamPolicyRAII {
68 PrintingPolicy &Policy;
69 bool Old;
70
71public:
72 explicit ParamPolicyRAII(PrintingPolicy &Policy)
73 : Policy(Policy), Old(Policy.SuppressSpecifiers) {
74 Policy.SuppressSpecifiers = false;
75 }
76
77 ~ParamPolicyRAII() { Policy.SuppressSpecifiers = Old; }
78};
79
80class DefaultTemplateArgsPolicyRAII {
81 PrintingPolicy &Policy;
82 bool Old;
83
84public:
85 explicit DefaultTemplateArgsPolicyRAII(PrintingPolicy &Policy)
86 : Policy(Policy), Old(Policy.SuppressDefaultTemplateArgs) {
87 Policy.SuppressDefaultTemplateArgs = false;
88 }
89
90 ~DefaultTemplateArgsPolicyRAII() { Policy.SuppressDefaultTemplateArgs = Old; }
91};
92
93class ElaboratedTypePolicyRAII {
94 PrintingPolicy &Policy;
95 bool SuppressTagKeyword;
96 bool SuppressScope;
97
98public:
99 explicit ElaboratedTypePolicyRAII(PrintingPolicy &Policy) : Policy(Policy) {
100 SuppressTagKeyword = Policy.SuppressTagKeyword;
101 SuppressScope = Policy.SuppressScope;
102 Policy.SuppressTagKeyword = true;
103 Policy.SuppressScope = true;
104 }
105
106 ~ElaboratedTypePolicyRAII() {
107 Policy.SuppressTagKeyword = SuppressTagKeyword;
108 Policy.SuppressScope = SuppressScope;
109 }
110};
111
112class TypePrinter {
113 PrintingPolicy Policy;
114 unsigned Indentation;
115 bool HasEmptyPlaceHolder = false;
116 bool InsideCCAttribute = false;
117
118public:
119 explicit TypePrinter(const PrintingPolicy &Policy, unsigned Indentation = 0)
120 : Policy(Policy), Indentation(Indentation) {}
121
122 void print(const Type *ty, Qualifiers qs, raw_ostream &OS,
123 StringRef PlaceHolder);
124 void print(QualType T, raw_ostream &OS, StringRef PlaceHolder);
125
126 static bool canPrefixQualifiers(const Type *T, bool &NeedARCStrongQualifier);
127 void spaceBeforePlaceHolder(raw_ostream &OS);
128 void printTypeSpec(NamedDecl *D, raw_ostream &OS);
129 void printTemplateId(const TemplateSpecializationType *T, raw_ostream &OS,
130 bool FullyQualify);
131
132 void printBefore(QualType T, raw_ostream &OS);
133 void printAfter(QualType T, raw_ostream &OS);
134 void printTagType(const TagType *T, raw_ostream &OS);
135 void printFunctionAfter(const FunctionType::ExtInfo &Info, raw_ostream &OS);
136#define ABSTRACT_TYPE(CLASS, PARENT)
137#define TYPE(CLASS, PARENT) \
138 void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS); \
139 void print##CLASS##After(const CLASS##Type *T, raw_ostream &OS);
140#include "clang/AST/TypeNodes.inc"
141
142private:
143 void printBefore(const Type *ty, Qualifiers qs, raw_ostream &OS);
144 void printAfter(const Type *ty, Qualifiers qs, raw_ostream &OS);
145};
146
147} // namespace
148
149static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals,
150 bool HasRestrictKeyword) {
151 bool appendSpace = false;
152 if (TypeQuals & Qualifiers::Const) {
153 OS << "const";
154 appendSpace = true;
155 }
156 if (TypeQuals & Qualifiers::Volatile) {
157 if (appendSpace) OS << ' ';
158 OS << "volatile";
159 appendSpace = true;
160 }
161 if (TypeQuals & Qualifiers::Restrict) {
162 if (appendSpace) OS << ' ';
163 if (HasRestrictKeyword) {
164 OS << "restrict";
165 } else {
166 OS << "__restrict";
167 }
168 }
169}
170
171void TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) {
172 if (!HasEmptyPlaceHolder)
173 OS << ' ';
174}
175
177 const PrintingPolicy &Policy) {
178 if (Policy.PrintAsCanonical)
179 QT = QT.getCanonicalType();
180 return QT.split();
181}
182
183void TypePrinter::print(QualType t, raw_ostream &OS, StringRef PlaceHolder) {
184 SplitQualType split = splitAccordingToPolicy(t, Policy);
185 print(split.Ty, split.Quals, OS, PlaceHolder);
186}
187
188void TypePrinter::print(const Type *T, Qualifiers Quals, raw_ostream &OS,
189 StringRef PlaceHolder) {
190 if (!T) {
191 OS << "NULL TYPE";
192 return;
193 }
194
195 SaveAndRestore PHVal(HasEmptyPlaceHolder, PlaceHolder.empty());
196
197 printBefore(T, Quals, OS);
198 OS << PlaceHolder;
199 printAfter(T, Quals, OS);
200}
201
202bool TypePrinter::canPrefixQualifiers(const Type *T,
203 bool &NeedARCStrongQualifier) {
204 // CanPrefixQualifiers - We prefer to print type qualifiers before the type,
205 // so that we get "const int" instead of "int const", but we can't do this if
206 // the type is complex. For example if the type is "int*", we *must* print
207 // "int * const", printing "const int *" is different. Only do this when the
208 // type expands to a simple string.
209 bool CanPrefixQualifiers = false;
210 NeedARCStrongQualifier = false;
211 const Type *UnderlyingType = T;
212 if (const auto *AT = dyn_cast<AutoType>(T))
213 UnderlyingType = AT->desugar().getTypePtr();
214 if (const auto *Subst = dyn_cast<SubstTemplateTypeParmType>(T))
215 UnderlyingType = Subst->getReplacementType().getTypePtr();
216 Type::TypeClass TC = UnderlyingType->getTypeClass();
217
218 switch (TC) {
219 case Type::Auto:
220 case Type::Builtin:
221 case Type::Complex:
222 case Type::UnresolvedUsing:
223 case Type::Using:
224 case Type::Typedef:
225 case Type::TypeOfExpr:
226 case Type::TypeOf:
227 case Type::Decltype:
228 case Type::UnaryTransform:
229 case Type::Record:
230 case Type::Enum:
231 case Type::TemplateTypeParm:
232 case Type::SubstTemplateTypeParmPack:
233 case Type::SubstBuiltinTemplatePack:
234 case Type::DeducedTemplateSpecialization:
235 case Type::TemplateSpecialization:
236 case Type::InjectedClassName:
237 case Type::DependentName:
238 case Type::ObjCObject:
239 case Type::ObjCTypeParam:
240 case Type::ObjCInterface:
241 case Type::Atomic:
242 case Type::Pipe:
243 case Type::BitInt:
244 case Type::DependentBitInt:
245 case Type::BTFTagAttributed:
246 case Type::HLSLAttributedResource:
247 case Type::HLSLInlineSpirv:
248 case Type::PredefinedSugar:
249 CanPrefixQualifiers = true;
250 break;
251
252 case Type::ObjCObjectPointer:
253 CanPrefixQualifiers = T->isObjCIdType() || T->isObjCClassType() ||
255 break;
256
257 case Type::VariableArray:
258 case Type::DependentSizedArray:
259 NeedARCStrongQualifier = true;
260 [[fallthrough]];
261
262 case Type::ConstantArray:
263 case Type::IncompleteArray:
264 return canPrefixQualifiers(
265 cast<ArrayType>(UnderlyingType)->getElementType().getTypePtr(),
266 NeedARCStrongQualifier);
267
268 case Type::Adjusted:
269 case Type::Decayed:
270 case Type::ArrayParameter:
271 case Type::Pointer:
272 case Type::BlockPointer:
273 case Type::LValueReference:
274 case Type::RValueReference:
275 case Type::MemberPointer:
276 case Type::DependentAddressSpace:
277 case Type::DependentVector:
278 case Type::DependentSizedExtVector:
279 case Type::Vector:
280 case Type::ExtVector:
281 case Type::ConstantMatrix:
282 case Type::DependentSizedMatrix:
283 case Type::FunctionProto:
284 case Type::FunctionNoProto:
285 case Type::Paren:
286 case Type::PackExpansion:
287 case Type::SubstTemplateTypeParm:
288 case Type::MacroQualified:
289 case Type::CountAttributed:
290 CanPrefixQualifiers = false;
291 break;
292
293 case Type::Attributed: {
294 // We still want to print the address_space before the type if it is an
295 // address_space attribute.
296 const auto *AttrTy = cast<AttributedType>(UnderlyingType);
297 CanPrefixQualifiers = AttrTy->getAttrKind() == attr::AddressSpace;
298 break;
299 }
300 case Type::PackIndexing: {
301 return canPrefixQualifiers(
302 cast<PackIndexingType>(UnderlyingType)->getPattern().getTypePtr(),
303 NeedARCStrongQualifier);
304 }
305 }
306
307 return CanPrefixQualifiers;
308}
309
310void TypePrinter::printBefore(QualType T, raw_ostream &OS) {
311 SplitQualType Split = splitAccordingToPolicy(T, Policy);
312
313 // If we have cv1 T, where T is substituted for cv2 U, only print cv1 - cv2
314 // at this level.
315 Qualifiers Quals = Split.Quals;
316 if (const auto *Subst = dyn_cast<SubstTemplateTypeParmType>(Split.Ty))
317 Quals -= QualType(Subst, 0).getQualifiers();
318
319 printBefore(Split.Ty, Quals, OS);
320}
321
322/// Prints the part of the type string before an identifier, e.g. for
323/// "int foo[10]" it prints "int ".
324void TypePrinter::printBefore(const Type *T,Qualifiers Quals, raw_ostream &OS) {
325 if (Policy.SuppressSpecifiers && T->isSpecifierType())
326 return;
327
328 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder);
329
330 // Print qualifiers as appropriate.
331
332 bool CanPrefixQualifiers = false;
333 bool NeedARCStrongQualifier = false;
334 CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier);
335
336 if (CanPrefixQualifiers && !Quals.empty()) {
337 if (NeedARCStrongQualifier) {
338 IncludeStrongLifetimeRAII Strong(Policy);
339 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
340 } else {
341 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
342 }
343 }
344
345 bool hasAfterQuals = false;
346 if (!CanPrefixQualifiers && !Quals.empty()) {
347 hasAfterQuals = !Quals.isEmptyWhenPrinted(Policy);
348 if (hasAfterQuals)
349 HasEmptyPlaceHolder = false;
350 }
351
352 switch (T->getTypeClass()) {
353#define ABSTRACT_TYPE(CLASS, PARENT)
354#define TYPE(CLASS, PARENT) case Type::CLASS: \
355 print##CLASS##Before(cast<CLASS##Type>(T), OS); \
356 break;
357#include "clang/AST/TypeNodes.inc"
358 }
359
360 if (hasAfterQuals) {
361 if (NeedARCStrongQualifier) {
362 IncludeStrongLifetimeRAII Strong(Policy);
363 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
364 } else {
365 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
366 }
367 }
368}
369
370void TypePrinter::printAfter(QualType t, raw_ostream &OS) {
371 SplitQualType split = splitAccordingToPolicy(t, Policy);
372 printAfter(split.Ty, split.Quals, OS);
373}
374
375/// Prints the part of the type string after an identifier, e.g. for
376/// "int foo[10]" it prints "[10]".
377void TypePrinter::printAfter(const Type *T, Qualifiers Quals, raw_ostream &OS) {
378 switch (T->getTypeClass()) {
379#define ABSTRACT_TYPE(CLASS, PARENT)
380#define TYPE(CLASS, PARENT) case Type::CLASS: \
381 print##CLASS##After(cast<CLASS##Type>(T), OS); \
382 break;
383#include "clang/AST/TypeNodes.inc"
384 }
385}
386
387void TypePrinter::printBuiltinBefore(const BuiltinType *T, raw_ostream &OS) {
388 OS << T->getName(Policy);
389 spaceBeforePlaceHolder(OS);
390}
391
392void TypePrinter::printBuiltinAfter(const BuiltinType *T, raw_ostream &OS) {}
393
394void TypePrinter::printComplexBefore(const ComplexType *T, raw_ostream &OS) {
395 OS << "_Complex ";
396 printBefore(T->getElementType(), OS);
397}
398
399void TypePrinter::printComplexAfter(const ComplexType *T, raw_ostream &OS) {
400 printAfter(T->getElementType(), OS);
401}
402
403void TypePrinter::printPointerBefore(const PointerType *T, raw_ostream &OS) {
404 IncludeStrongLifetimeRAII Strong(Policy);
405 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
406 printBefore(T->getPointeeType(), OS);
407 // Handle things like 'int (*A)[4];' correctly.
408 // FIXME: this should include vectors, but vectors use attributes I guess.
410 OS << '(';
411 OS << '*';
412}
413
414void TypePrinter::printPointerAfter(const PointerType *T, raw_ostream &OS) {
415 IncludeStrongLifetimeRAII Strong(Policy);
416 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
417 // Handle things like 'int (*A)[4];' correctly.
418 // FIXME: this should include vectors, but vectors use attributes I guess.
420 OS << ')';
421 printAfter(T->getPointeeType(), OS);
422}
423
424void TypePrinter::printBlockPointerBefore(const BlockPointerType *T,
425 raw_ostream &OS) {
426 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
427 printBefore(T->getPointeeType(), OS);
428 OS << '^';
429}
430
431void TypePrinter::printBlockPointerAfter(const BlockPointerType *T,
432 raw_ostream &OS) {
433 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
434 printAfter(T->getPointeeType(), OS);
435}
436
437// When printing a reference, the referenced type might also be a reference.
438// If so, we want to skip that before printing the inner type.
440 if (auto *Ref = T->getAs<ReferenceType>())
441 return skipTopLevelReferences(Ref->getPointeeTypeAsWritten());
442 return T;
443}
444
445void TypePrinter::printLValueReferenceBefore(const LValueReferenceType *T,
446 raw_ostream &OS) {
447 IncludeStrongLifetimeRAII Strong(Policy);
448 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
449 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
450 printBefore(Inner, OS);
451 // Handle things like 'int (&A)[4];' correctly.
452 // FIXME: this should include vectors, but vectors use attributes I guess.
453 if (isa<ArrayType>(Inner))
454 OS << '(';
455 OS << '&';
456}
457
458void TypePrinter::printLValueReferenceAfter(const LValueReferenceType *T,
459 raw_ostream &OS) {
460 IncludeStrongLifetimeRAII Strong(Policy);
461 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
462 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
463 // Handle things like 'int (&A)[4];' correctly.
464 // FIXME: this should include vectors, but vectors use attributes I guess.
465 if (isa<ArrayType>(Inner))
466 OS << ')';
467 printAfter(Inner, OS);
468}
469
470void TypePrinter::printRValueReferenceBefore(const RValueReferenceType *T,
471 raw_ostream &OS) {
472 IncludeStrongLifetimeRAII Strong(Policy);
473 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
474 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
475 printBefore(Inner, OS);
476 // Handle things like 'int (&&A)[4];' correctly.
477 // FIXME: this should include vectors, but vectors use attributes I guess.
478 if (isa<ArrayType>(Inner))
479 OS << '(';
480 OS << "&&";
481}
482
483void TypePrinter::printRValueReferenceAfter(const RValueReferenceType *T,
484 raw_ostream &OS) {
485 IncludeStrongLifetimeRAII Strong(Policy);
486 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
487 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
488 // Handle things like 'int (&&A)[4];' correctly.
489 // FIXME: this should include vectors, but vectors use attributes I guess.
490 if (isa<ArrayType>(Inner))
491 OS << ')';
492 printAfter(Inner, OS);
493}
494
495void TypePrinter::printMemberPointerBefore(const MemberPointerType *T,
496 raw_ostream &OS) {
497 IncludeStrongLifetimeRAII Strong(Policy);
498 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
499 printBefore(T->getPointeeType(), OS);
500 // Handle things like 'int (Cls::*A)[4];' correctly.
501 // FIXME: this should include vectors, but vectors use attributes I guess.
503 OS << '(';
504 T->getQualifier().print(OS, Policy);
505 OS << "*";
506}
507
508void TypePrinter::printMemberPointerAfter(const MemberPointerType *T,
509 raw_ostream &OS) {
510 IncludeStrongLifetimeRAII Strong(Policy);
511 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
512 // Handle things like 'int (Cls::*A)[4];' correctly.
513 // FIXME: this should include vectors, but vectors use attributes I guess.
515 OS << ')';
516 printAfter(T->getPointeeType(), OS);
517}
518
519void TypePrinter::printConstantArrayBefore(const ConstantArrayType *T,
520 raw_ostream &OS) {
521 IncludeStrongLifetimeRAII Strong(Policy);
522 printBefore(T->getElementType(), OS);
523}
524
525void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T,
526 raw_ostream &OS) {
527 OS << '[';
528 if (T->getIndexTypeQualifiers().hasQualifiers()) {
529 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(),
530 Policy.Restrict);
531 OS << ' ';
532 }
533
534 if (T->getSizeModifier() == ArraySizeModifier::Static)
535 OS << "static ";
536
537 OS << T->getZExtSize() << ']';
538 printAfter(T->getElementType(), OS);
539}
540
541void TypePrinter::printIncompleteArrayBefore(const IncompleteArrayType *T,
542 raw_ostream &OS) {
543 IncludeStrongLifetimeRAII Strong(Policy);
544 printBefore(T->getElementType(), OS);
545}
546
547void TypePrinter::printIncompleteArrayAfter(const IncompleteArrayType *T,
548 raw_ostream &OS) {
549 OS << "[]";
550 printAfter(T->getElementType(), OS);
551}
552
553void TypePrinter::printVariableArrayBefore(const VariableArrayType *T,
554 raw_ostream &OS) {
555 IncludeStrongLifetimeRAII Strong(Policy);
556 printBefore(T->getElementType(), OS);
557}
558
559void TypePrinter::printVariableArrayAfter(const VariableArrayType *T,
560 raw_ostream &OS) {
561 OS << '[';
562 if (T->getIndexTypeQualifiers().hasQualifiers()) {
563 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.Restrict);
564 OS << ' ';
565 }
566
567 if (T->getSizeModifier() == ArraySizeModifier::Static)
568 OS << "static ";
569 else if (T->getSizeModifier() == ArraySizeModifier::Star)
570 OS << '*';
571
572 if (T->getSizeExpr())
573 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
574 OS << ']';
575
576 printAfter(T->getElementType(), OS);
577}
578
579void TypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream &OS) {
580 // Print the adjusted representation, otherwise the adjustment will be
581 // invisible.
582 printBefore(T->getAdjustedType(), OS);
583}
584
585void TypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) {
586 printAfter(T->getAdjustedType(), OS);
587}
588
589void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {
590 // Print as though it's a pointer.
591 printAdjustedBefore(T, OS);
592}
593
594void TypePrinter::printArrayParameterAfter(const ArrayParameterType *T,
595 raw_ostream &OS) {
596 printConstantArrayAfter(T, OS);
597}
598
599void TypePrinter::printArrayParameterBefore(const ArrayParameterType *T,
600 raw_ostream &OS) {
601 printConstantArrayBefore(T, OS);
602}
603
604void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {
605 printAdjustedAfter(T, OS);
606}
607
608void TypePrinter::printDependentSizedArrayBefore(
609 const DependentSizedArrayType *T,
610 raw_ostream &OS) {
611 IncludeStrongLifetimeRAII Strong(Policy);
612 printBefore(T->getElementType(), OS);
613}
614
615void TypePrinter::printDependentSizedArrayAfter(
616 const DependentSizedArrayType *T,
617 raw_ostream &OS) {
618 OS << '[';
619 if (T->getSizeExpr())
620 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
621 OS << ']';
622 printAfter(T->getElementType(), OS);
623}
624
625void TypePrinter::printDependentAddressSpaceBefore(
626 const DependentAddressSpaceType *T, raw_ostream &OS) {
627 printBefore(T->getPointeeType(), OS);
628}
629
630void TypePrinter::printDependentAddressSpaceAfter(
631 const DependentAddressSpaceType *T, raw_ostream &OS) {
632 OS << " __attribute__((address_space(";
633 if (T->getAddrSpaceExpr())
634 T->getAddrSpaceExpr()->printPretty(OS, nullptr, Policy);
635 OS << ")))";
636 printAfter(T->getPointeeType(), OS);
637}
638
639void TypePrinter::printDependentSizedExtVectorBefore(
640 const DependentSizedExtVectorType *T,
641 raw_ostream &OS) {
642 if (Policy.UseHLSLTypes)
643 OS << "vector<";
644 printBefore(T->getElementType(), OS);
645}
646
647void TypePrinter::printDependentSizedExtVectorAfter(
648 const DependentSizedExtVectorType *T,
649 raw_ostream &OS) {
650 if (Policy.UseHLSLTypes) {
651 OS << ", ";
652 if (T->getSizeExpr())
653 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
654 OS << ">";
655 } else {
656 OS << " __attribute__((ext_vector_type(";
657 if (T->getSizeExpr())
658 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
659 OS << ")))";
660 }
661 printAfter(T->getElementType(), OS);
662}
663
664void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {
665 switch (T->getVectorKind()) {
666 case VectorKind::AltiVecPixel:
667 OS << "__vector __pixel ";
668 break;
669 case VectorKind::AltiVecBool:
670 OS << "__vector __bool ";
671 printBefore(T->getElementType(), OS);
672 break;
673 case VectorKind::AltiVecVector:
674 OS << "__vector ";
675 printBefore(T->getElementType(), OS);
676 break;
677 case VectorKind::Neon:
678 OS << "__attribute__((neon_vector_type("
679 << T->getNumElements() << "))) ";
680 printBefore(T->getElementType(), OS);
681 break;
682 case VectorKind::NeonPoly:
683 OS << "__attribute__((neon_polyvector_type(" <<
684 T->getNumElements() << "))) ";
685 printBefore(T->getElementType(), OS);
686 break;
687 case VectorKind::Generic: {
688 // FIXME: We prefer to print the size directly here, but have no way
689 // to get the size of the type.
690 OS << "__attribute__((__vector_size__("
691 << T->getNumElements()
692 << " * sizeof(";
693 print(T->getElementType(), OS, StringRef());
694 OS << ")))) ";
695 printBefore(T->getElementType(), OS);
696 break;
697 }
698 case VectorKind::SveFixedLengthData:
699 case VectorKind::SveFixedLengthPredicate:
700 // FIXME: We prefer to print the size directly here, but have no way
701 // to get the size of the type.
702 OS << "__attribute__((__arm_sve_vector_bits__(";
703
704 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
705 // Predicates take a bit per byte of the vector size, multiply by 8 to
706 // get the number of bits passed to the attribute.
707 OS << T->getNumElements() * 8;
708 else
709 OS << T->getNumElements();
710
711 OS << " * sizeof(";
712 print(T->getElementType(), OS, StringRef());
713 // Multiply by 8 for the number of bits.
714 OS << ") * 8))) ";
715 printBefore(T->getElementType(), OS);
716 break;
717 case VectorKind::RVVFixedLengthData:
718 case VectorKind::RVVFixedLengthMask:
719 case VectorKind::RVVFixedLengthMask_1:
720 case VectorKind::RVVFixedLengthMask_2:
721 case VectorKind::RVVFixedLengthMask_4:
722 // FIXME: We prefer to print the size directly here, but have no way
723 // to get the size of the type.
724 OS << "__attribute__((__riscv_rvv_vector_bits__(";
725
726 OS << T->getNumElements();
727
728 OS << " * sizeof(";
729 print(T->getElementType(), OS, StringRef());
730 // Multiply by 8 for the number of bits.
731 OS << ") * 8))) ";
732 printBefore(T->getElementType(), OS);
733 break;
734 }
735}
736
737void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) {
738 printAfter(T->getElementType(), OS);
739}
740
741void TypePrinter::printDependentVectorBefore(
742 const DependentVectorType *T, raw_ostream &OS) {
743 switch (T->getVectorKind()) {
744 case VectorKind::AltiVecPixel:
745 OS << "__vector __pixel ";
746 break;
747 case VectorKind::AltiVecBool:
748 OS << "__vector __bool ";
749 printBefore(T->getElementType(), OS);
750 break;
751 case VectorKind::AltiVecVector:
752 OS << "__vector ";
753 printBefore(T->getElementType(), OS);
754 break;
755 case VectorKind::Neon:
756 OS << "__attribute__((neon_vector_type(";
757 if (T->getSizeExpr())
758 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
759 OS << "))) ";
760 printBefore(T->getElementType(), OS);
761 break;
762 case VectorKind::NeonPoly:
763 OS << "__attribute__((neon_polyvector_type(";
764 if (T->getSizeExpr())
765 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
766 OS << "))) ";
767 printBefore(T->getElementType(), OS);
768 break;
769 case VectorKind::Generic: {
770 // FIXME: We prefer to print the size directly here, but have no way
771 // to get the size of the type.
772 OS << "__attribute__((__vector_size__(";
773 if (T->getSizeExpr())
774 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
775 OS << " * sizeof(";
776 print(T->getElementType(), OS, StringRef());
777 OS << ")))) ";
778 printBefore(T->getElementType(), OS);
779 break;
780 }
781 case VectorKind::SveFixedLengthData:
782 case VectorKind::SveFixedLengthPredicate:
783 // FIXME: We prefer to print the size directly here, but have no way
784 // to get the size of the type.
785 OS << "__attribute__((__arm_sve_vector_bits__(";
786 if (T->getSizeExpr()) {
787 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
788 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
789 // Predicates take a bit per byte of the vector size, multiply by 8 to
790 // get the number of bits passed to the attribute.
791 OS << " * 8";
792 OS << " * sizeof(";
793 print(T->getElementType(), OS, StringRef());
794 // Multiply by 8 for the number of bits.
795 OS << ") * 8";
796 }
797 OS << "))) ";
798 printBefore(T->getElementType(), OS);
799 break;
800 case VectorKind::RVVFixedLengthData:
801 case VectorKind::RVVFixedLengthMask:
802 case VectorKind::RVVFixedLengthMask_1:
803 case VectorKind::RVVFixedLengthMask_2:
804 case VectorKind::RVVFixedLengthMask_4:
805 // FIXME: We prefer to print the size directly here, but have no way
806 // to get the size of the type.
807 OS << "__attribute__((__riscv_rvv_vector_bits__(";
808 if (T->getSizeExpr()) {
809 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
810 OS << " * sizeof(";
811 print(T->getElementType(), OS, StringRef());
812 // Multiply by 8 for the number of bits.
813 OS << ") * 8";
814 }
815 OS << "))) ";
816 printBefore(T->getElementType(), OS);
817 break;
818 }
819}
820
821void TypePrinter::printDependentVectorAfter(
822 const DependentVectorType *T, raw_ostream &OS) {
823 printAfter(T->getElementType(), OS);
824}
825
826void TypePrinter::printExtVectorBefore(const ExtVectorType *T,
827 raw_ostream &OS) {
828 if (Policy.UseHLSLTypes)
829 OS << "vector<";
830 printBefore(T->getElementType(), OS);
831}
832
833void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) {
834 printAfter(T->getElementType(), OS);
835
836 if (Policy.UseHLSLTypes) {
837 OS << ", ";
838 OS << T->getNumElements();
839 OS << ">";
840 } else {
841 OS << " __attribute__((ext_vector_type(";
842 OS << T->getNumElements();
843 OS << ")))";
844 }
845}
846
847static void printDims(const ConstantMatrixType *T, raw_ostream &OS) {
848 OS << T->getNumRows() << ", " << T->getNumColumns();
849}
850
851static void printHLSLMatrixBefore(TypePrinter &TP, const ConstantMatrixType *T,
852 raw_ostream &OS) {
853 OS << "matrix<";
854 TP.printBefore(T->getElementType(), OS);
855}
856
857static void printHLSLMatrixAfter(const ConstantMatrixType *T, raw_ostream &OS) {
858 OS << ", ";
859 printDims(T, OS);
860 OS << ">";
861}
862
863static void printClangMatrixBefore(TypePrinter &TP, const ConstantMatrixType *T,
864 raw_ostream &OS) {
865 TP.printBefore(T->getElementType(), OS);
866 OS << " __attribute__((matrix_type(";
867 printDims(T, OS);
868 OS << ")))";
869}
870
871void TypePrinter::printConstantMatrixBefore(const ConstantMatrixType *T,
872 raw_ostream &OS) {
873 if (Policy.UseHLSLTypes) {
874 printHLSLMatrixBefore(*this, T, OS);
875 return;
876 }
877 printClangMatrixBefore(*this, T, OS);
878}
879
880void TypePrinter::printConstantMatrixAfter(const ConstantMatrixType *T,
881 raw_ostream &OS) {
882 if (Policy.UseHLSLTypes) {
884 return;
885 }
886 printAfter(T->getElementType(), OS);
887}
888
889void TypePrinter::printDependentSizedMatrixBefore(
890 const DependentSizedMatrixType *T, raw_ostream &OS) {
891 printBefore(T->getElementType(), OS);
892 OS << " __attribute__((matrix_type(";
893 if (T->getRowExpr()) {
894 T->getRowExpr()->printPretty(OS, nullptr, Policy);
895 }
896 OS << ", ";
897 if (T->getColumnExpr()) {
898 T->getColumnExpr()->printPretty(OS, nullptr, Policy);
899 }
900 OS << ")))";
901}
902
903void TypePrinter::printDependentSizedMatrixAfter(
904 const DependentSizedMatrixType *T, raw_ostream &OS) {
905 printAfter(T->getElementType(), OS);
906}
907
908void
910 const PrintingPolicy &Policy)
911 const {
913 OS << " throw(";
915 OS << "...";
916 else
917 for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) {
918 if (I)
919 OS << ", ";
920
921 OS << getExceptionType(I).stream(Policy);
922 }
923 OS << ')';
924 } else if (EST_NoThrow == getExceptionSpecType()) {
925 OS << " __attribute__((nothrow))";
927 OS << " noexcept";
928 // FIXME:Is it useful to print out the expression for a non-dependent
929 // noexcept specification?
931 OS << '(';
932 if (getNoexceptExpr())
933 getNoexceptExpr()->printPretty(OS, nullptr, Policy);
934 OS << ')';
935 }
936 }
937}
938
939void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,
940 raw_ostream &OS) {
941 if (T->hasTrailingReturn()) {
942 OS << "auto ";
943 if (!HasEmptyPlaceHolder)
944 OS << '(';
945 } else {
946 // If needed for precedence reasons, wrap the inner part in grouping parens.
947 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
948 printBefore(T->getReturnType(), OS);
949 if (!PrevPHIsEmpty.get())
950 OS << '(';
951 }
952}
953
955 switch (ABI) {
957 llvm_unreachable("asking for spelling of ordinary parameter ABI");
959 return "swift_context";
961 return "swift_async_context";
963 return "swift_error_result";
965 return "swift_indirect_result";
967 return "out";
969 return "inout";
970 }
971 llvm_unreachable("bad parameter ABI kind");
972}
973
974void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
975 raw_ostream &OS) {
976 // If needed for precedence reasons, wrap the inner part in grouping parens.
977 if (!HasEmptyPlaceHolder)
978 OS << ')';
979 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
980
981 OS << '(';
982 {
983 ParamPolicyRAII ParamPolicy(Policy);
984 for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {
985 if (i) OS << ", ";
986
987 auto EPI = T->getExtParameterInfo(i);
988 if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) ";
989 if (EPI.isNoEscape())
990 OS << "__attribute__((noescape)) ";
991 auto ABI = EPI.getABI();
992 if (ABI == ParameterABI::HLSLInOut || ABI == ParameterABI::HLSLOut) {
993 OS << getParameterABISpelling(ABI) << " ";
994 if (Policy.UseHLSLTypes) {
995 // This is a bit of a hack because we _do_ use reference types in the
996 // AST for representing inout and out parameters so that code
997 // generation is sane, but when re-printing these for HLSL we need to
998 // skip the reference.
999 print(T->getParamType(i).getNonReferenceType(), OS, StringRef());
1000 continue;
1001 }
1002 } else if (ABI != ParameterABI::Ordinary)
1003 OS << "__attribute__((" << getParameterABISpelling(ABI) << ")) ";
1004
1005 print(T->getParamType(i), OS, StringRef());
1006 }
1007 }
1008
1009 if (T->isVariadic()) {
1010 if (T->getNumParams())
1011 OS << ", ";
1012 OS << "...";
1013 } else if (T->getNumParams() == 0 && Policy.UseVoidForZeroParams) {
1014 // Do not emit int() if we have a proto, emit 'int(void)'.
1015 OS << "void";
1016 }
1017
1018 OS << ')';
1019
1020 FunctionType::ExtInfo Info = T->getExtInfo();
1021 unsigned SMEBits = T->getAArch64SMEAttributes();
1022
1024 OS << " __arm_streaming_compatible";
1026 OS << " __arm_streaming";
1028 OS << "__arm_agnostic(\"sme_za_state\")";
1030 OS << " __arm_preserves(\"za\")";
1032 OS << " __arm_in(\"za\")";
1034 OS << " __arm_out(\"za\")";
1036 OS << " __arm_inout(\"za\")";
1038 OS << " __arm_preserves(\"zt0\")";
1040 OS << " __arm_in(\"zt0\")";
1042 OS << " __arm_out(\"zt0\")";
1044 OS << " __arm_inout(\"zt0\")";
1045
1046 printFunctionAfter(Info, OS);
1047
1048 if (!T->getMethodQuals().empty())
1049 OS << " " << T->getMethodQuals().getAsString();
1050
1051 switch (T->getRefQualifier()) {
1052 case RQ_None:
1053 break;
1054
1055 case RQ_LValue:
1056 OS << " &";
1057 break;
1058
1059 case RQ_RValue:
1060 OS << " &&";
1061 break;
1062 }
1063 T->printExceptionSpecification(OS, Policy);
1064
1065 const FunctionEffectsRef FX = T->getFunctionEffects();
1066 for (const auto &CFE : FX) {
1067 OS << " __attribute__((" << CFE.Effect.name();
1068 if (const Expr *E = CFE.Cond.getCondition()) {
1069 OS << '(';
1070 E->printPretty(OS, nullptr, Policy);
1071 OS << ')';
1072 }
1073 OS << "))";
1074 }
1075
1076 if (T->hasCFIUncheckedCallee())
1077 OS << " __attribute__((cfi_unchecked_callee))";
1078
1079 if (T->hasTrailingReturn()) {
1080 OS << " -> ";
1081 print(T->getReturnType(), OS, StringRef());
1082 } else
1083 printAfter(T->getReturnType(), OS);
1084}
1085
1086void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
1087 raw_ostream &OS) {
1088 if (!InsideCCAttribute) {
1089 switch (Info.getCC()) {
1090 case CC_C:
1091 // The C calling convention is the default on the vast majority of platforms
1092 // we support. If the user wrote it explicitly, it will usually be printed
1093 // while traversing the AttributedType. If the type has been desugared, let
1094 // the canonical spelling be the implicit calling convention.
1095 // FIXME: It would be better to be explicit in certain contexts, such as a
1096 // cdecl function typedef used to declare a member function with the
1097 // Microsoft C++ ABI.
1098 break;
1099 case CC_X86StdCall:
1100 OS << " __attribute__((stdcall))";
1101 break;
1102 case CC_X86FastCall:
1103 OS << " __attribute__((fastcall))";
1104 break;
1105 case CC_X86ThisCall:
1106 OS << " __attribute__((thiscall))";
1107 break;
1108 case CC_X86VectorCall:
1109 OS << " __attribute__((vectorcall))";
1110 break;
1111 case CC_X86Pascal:
1112 OS << " __attribute__((pascal))";
1113 break;
1114 case CC_AAPCS:
1115 OS << " __attribute__((pcs(\"aapcs\")))";
1116 break;
1117 case CC_AAPCS_VFP:
1118 OS << " __attribute__((pcs(\"aapcs-vfp\")))";
1119 break;
1121 OS << " __attribute__((aarch64_vector_pcs))";
1122 break;
1123 case CC_AArch64SVEPCS:
1124 OS << " __attribute__((aarch64_sve_pcs))";
1125 break;
1126 case CC_DeviceKernel:
1127 OS << " __attribute__((device_kernel))";
1128 break;
1129 case CC_IntelOclBicc:
1130 OS << " __attribute__((intel_ocl_bicc))";
1131 break;
1132 case CC_Win64:
1133 OS << " __attribute__((ms_abi))";
1134 break;
1135 case CC_X86_64SysV:
1136 OS << " __attribute__((sysv_abi))";
1137 break;
1138 case CC_X86RegCall:
1139 OS << " __attribute__((regcall))";
1140 break;
1141 case CC_SpirFunction:
1142 // Do nothing. These CCs are not available as attributes.
1143 break;
1144 case CC_Swift:
1145 OS << " __attribute__((swiftcall))";
1146 break;
1147 case CC_SwiftAsync:
1148 OS << "__attribute__((swiftasynccall))";
1149 break;
1150 case CC_PreserveMost:
1151 OS << " __attribute__((preserve_most))";
1152 break;
1153 case CC_PreserveAll:
1154 OS << " __attribute__((preserve_all))";
1155 break;
1156 case CC_M68kRTD:
1157 OS << " __attribute__((m68k_rtd))";
1158 break;
1159 case CC_PreserveNone:
1160 OS << " __attribute__((preserve_none))";
1161 break;
1162 case CC_RISCVVectorCall:
1163 OS << "__attribute__((riscv_vector_cc))";
1164 break;
1165#define CC_VLS_CASE(ABI_VLEN) \
1166 case CC_RISCVVLSCall_##ABI_VLEN: \
1167 OS << "__attribute__((riscv_vls_cc" #ABI_VLEN "))"; \
1168 break;
1169 CC_VLS_CASE(32)
1170 CC_VLS_CASE(64)
1171 CC_VLS_CASE(128)
1172 CC_VLS_CASE(256)
1173 CC_VLS_CASE(512)
1174 CC_VLS_CASE(1024)
1175 CC_VLS_CASE(2048)
1176 CC_VLS_CASE(4096)
1177 CC_VLS_CASE(8192)
1178 CC_VLS_CASE(16384)
1179 CC_VLS_CASE(32768)
1180 CC_VLS_CASE(65536)
1181#undef CC_VLS_CASE
1182 }
1183 }
1184
1185 if (Info.getNoReturn())
1186 OS << " __attribute__((noreturn))";
1187 if (Info.getCmseNSCall())
1188 OS << " __attribute__((cmse_nonsecure_call))";
1189 if (Info.getProducesResult())
1190 OS << " __attribute__((ns_returns_retained))";
1191 if (Info.getRegParm())
1192 OS << " __attribute__((regparm ("
1193 << Info.getRegParm() << ")))";
1194 if (Info.getNoCallerSavedRegs())
1195 OS << " __attribute__((no_caller_saved_registers))";
1196 if (Info.getNoCfCheck())
1197 OS << " __attribute__((nocf_check))";
1198}
1199
1200void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T,
1201 raw_ostream &OS) {
1202 // If needed for precedence reasons, wrap the inner part in grouping parens.
1203 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
1204 printBefore(T->getReturnType(), OS);
1205 if (!PrevPHIsEmpty.get())
1206 OS << '(';
1207}
1208
1209void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,
1210 raw_ostream &OS) {
1211 // If needed for precedence reasons, wrap the inner part in grouping parens.
1212 if (!HasEmptyPlaceHolder)
1213 OS << ')';
1214 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
1215
1216 OS << "()";
1217 printFunctionAfter(T->getExtInfo(), OS);
1218 printAfter(T->getReturnType(), OS);
1219}
1220
1221void TypePrinter::printTypeSpec(NamedDecl *D, raw_ostream &OS) {
1222
1223 // Compute the full nested-name-specifier for this type.
1224 // In C, this will always be empty except when the type
1225 // being printed is anonymous within other Record.
1226 if (!Policy.SuppressScope)
1227 D->printNestedNameSpecifier(OS, Policy);
1228
1229 IdentifierInfo *II = D->getIdentifier();
1230 OS << II->getName();
1231 spaceBeforePlaceHolder(OS);
1232}
1233
1234void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,
1235 raw_ostream &OS) {
1236 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1237 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1238 OS << ' ';
1239 auto *D = T->getDecl();
1240 if (Policy.FullyQualifiedName || T->isCanonicalUnqualified()) {
1241 D->printNestedNameSpecifier(OS, Policy);
1242 } else {
1243 T->getQualifier().print(OS, Policy);
1244 }
1245 OS << D->getIdentifier()->getName();
1246 spaceBeforePlaceHolder(OS);
1247}
1248
1249void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,
1250 raw_ostream &OS) {}
1251
1252void TypePrinter::printUsingBefore(const UsingType *T, raw_ostream &OS) {
1253 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1254 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1255 OS << ' ';
1256 auto *D = T->getDecl();
1257 if (Policy.FullyQualifiedName) {
1258 D->printNestedNameSpecifier(OS, Policy);
1259 } else {
1260 T->getQualifier().print(OS, Policy);
1261 }
1262 OS << D->getIdentifier()->getName();
1263 spaceBeforePlaceHolder(OS);
1264}
1265
1266void TypePrinter::printUsingAfter(const UsingType *T, raw_ostream &OS) {}
1267
1268void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
1269 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1270 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1271 OS << ' ';
1272 auto *D = T->getDecl();
1273 if (Policy.FullyQualifiedName) {
1274 D->printNestedNameSpecifier(OS, Policy);
1275 } else {
1276 T->getQualifier().print(OS, Policy);
1277 }
1278 OS << D->getIdentifier()->getName();
1279 spaceBeforePlaceHolder(OS);
1280}
1281
1282void TypePrinter::printMacroQualifiedBefore(const MacroQualifiedType *T,
1283 raw_ostream &OS) {
1284 StringRef MacroName = T->getMacroIdentifier()->getName();
1285 OS << MacroName << " ";
1286
1287 // Since this type is meant to print the macro instead of the whole attribute,
1288 // we trim any attributes and go directly to the original modified type.
1289 printBefore(T->getModifiedType(), OS);
1290}
1291
1292void TypePrinter::printMacroQualifiedAfter(const MacroQualifiedType *T,
1293 raw_ostream &OS) {
1294 printAfter(T->getModifiedType(), OS);
1295}
1296
1297void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) {}
1298
1299void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
1300 raw_ostream &OS) {
1301 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual "
1302 : "typeof ");
1303 if (T->getUnderlyingExpr())
1304 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
1305 spaceBeforePlaceHolder(OS);
1306}
1307
1308void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
1309 raw_ostream &OS) {}
1310
1311void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) {
1312 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual("
1313 : "typeof(");
1314 print(T->getUnmodifiedType(), OS, StringRef());
1315 OS << ')';
1316 spaceBeforePlaceHolder(OS);
1317}
1318
1319void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) {}
1320
1321void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {
1322 OS << "decltype(";
1323 if (const Expr *E = T->getUnderlyingExpr()) {
1324 PrintingPolicy ExprPolicy = Policy;
1326 E->printPretty(OS, nullptr, ExprPolicy);
1327 }
1328 OS << ')';
1329 spaceBeforePlaceHolder(OS);
1330}
1331
1332void TypePrinter::printPackIndexingBefore(const PackIndexingType *T,
1333 raw_ostream &OS) {
1334 if (T->hasSelectedType()) {
1335 OS << T->getSelectedType();
1336 } else {
1337 OS << T->getPattern() << "...[";
1338 T->getIndexExpr()->printPretty(OS, nullptr, Policy);
1339 OS << "]";
1340 }
1341 spaceBeforePlaceHolder(OS);
1342}
1343
1344void TypePrinter::printPackIndexingAfter(const PackIndexingType *T,
1345 raw_ostream &OS) {}
1346
1347void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) {}
1348
1349void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,
1350 raw_ostream &OS) {
1351 IncludeStrongLifetimeRAII Strong(Policy);
1352
1353 static llvm::DenseMap<int, const char *> Transformation = {{
1354#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
1355 {UnaryTransformType::Enum, "__" #Trait},
1356#include "clang/Basic/TransformTypeTraits.def"
1357 }};
1358 OS << Transformation[T->getUTTKind()] << '(';
1359 print(T->getBaseType(), OS, StringRef());
1360 OS << ')';
1361 spaceBeforePlaceHolder(OS);
1362}
1363
1364void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,
1365 raw_ostream &OS) {}
1366
1367void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
1368 // If the type has been deduced, do not print 'auto'.
1369 if (!T->getDeducedType().isNull()) {
1370 printBefore(T->getDeducedType(), OS);
1371 } else {
1372 if (T->isConstrained()) {
1373 // FIXME: Track a TypeConstraint as type sugar, so that we can print the
1374 // type as it was written.
1375 T->getTypeConstraintConcept()->getDeclName().print(OS, Policy);
1376 auto Args = T->getTypeConstraintArguments();
1377 if (!Args.empty())
1378 printTemplateArgumentList(
1379 OS, Args, Policy,
1380 T->getTypeConstraintConcept()->getTemplateParameters());
1381 OS << ' ';
1382 }
1383 switch (T->getKeyword()) {
1384 case AutoTypeKeyword::Auto: OS << "auto"; break;
1385 case AutoTypeKeyword::DecltypeAuto: OS << "decltype(auto)"; break;
1386 case AutoTypeKeyword::GNUAutoType: OS << "__auto_type"; break;
1387 }
1388 spaceBeforePlaceHolder(OS);
1389 }
1390}
1391
1392void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {
1393 // If the type has been deduced, do not print 'auto'.
1394 if (!T->getDeducedType().isNull())
1395 printAfter(T->getDeducedType(), OS);
1396}
1397
1398void TypePrinter::printDeducedTemplateSpecializationBefore(
1399 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1400 if (ElaboratedTypeKeyword Keyword = T->getKeyword();
1401 T->getKeyword() != ElaboratedTypeKeyword::None)
1403
1404 TemplateName Name = T->getTemplateName();
1405
1406 // If the type has been deduced, print the template arguments, as if this was
1407 // printing the deduced type, but including elaboration and template name
1408 // qualification.
1409 // FIXME: There should probably be a policy which controls this.
1410 // We would probably want to do this on diagnostics, but not on -ast-print.
1411 ArrayRef<TemplateArgument> Args;
1412 TemplateDecl *DeducedTD = nullptr;
1413 if (!T->getDeducedType().isNull()) {
1414 if (const auto *TST =
1415 dyn_cast<TemplateSpecializationType>(T->getDeducedType())) {
1416 DeducedTD = TST->getTemplateName().getAsTemplateDecl(
1417 /*IgnoreDeduced=*/true);
1418 Args = TST->template_arguments();
1419 } else {
1420 // Should only get here for canonical types.
1422 cast<RecordType>(T->getDeducedType())->getDecl());
1423 DeducedTD = CD->getSpecializedTemplate();
1424 Args = CD->getTemplateArgs().asArray();
1425 }
1426
1427 // FIXME: Workaround for alias template CTAD not producing guides which
1428 // include the alias template specialization type.
1429 // Purposefully disregard qualification when building this TemplateName;
1430 // any qualification we might have, might not make sense in the
1431 // context this was deduced.
1432 if (!declaresSameEntity(DeducedTD, Name.getAsTemplateDecl(
1433 /*IgnoreDeduced=*/true)))
1434 Name = TemplateName(DeducedTD);
1435 }
1436
1437 {
1438 IncludeStrongLifetimeRAII Strong(Policy);
1439 Name.print(OS, Policy);
1440 }
1441 if (DeducedTD) {
1442 printTemplateArgumentList(OS, Args, Policy,
1443 DeducedTD->getTemplateParameters());
1444 }
1445
1446 spaceBeforePlaceHolder(OS);
1447}
1448
1449void TypePrinter::printDeducedTemplateSpecializationAfter(
1450 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1451 // If the type has been deduced, print the deduced type.
1452 if (!T->getDeducedType().isNull())
1453 printAfter(T->getDeducedType(), OS);
1454}
1455
1456void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {
1457 IncludeStrongLifetimeRAII Strong(Policy);
1458
1459 OS << "_Atomic(";
1460 print(T->getValueType(), OS, StringRef());
1461 OS << ')';
1462 spaceBeforePlaceHolder(OS);
1463}
1464
1465void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) {}
1466
1467void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) {
1468 IncludeStrongLifetimeRAII Strong(Policy);
1469
1470 if (T->isReadOnly())
1471 OS << "read_only ";
1472 else
1473 OS << "write_only ";
1474 OS << "pipe ";
1475 print(T->getElementType(), OS, StringRef());
1476 spaceBeforePlaceHolder(OS);
1477}
1478
1479void TypePrinter::printPipeAfter(const PipeType *T, raw_ostream &OS) {}
1480
1481void TypePrinter::printBitIntBefore(const BitIntType *T, raw_ostream &OS) {
1482 if (T->isUnsigned())
1483 OS << "unsigned ";
1484 OS << "_BitInt(" << T->getNumBits() << ")";
1485 spaceBeforePlaceHolder(OS);
1486}
1487
1488void TypePrinter::printBitIntAfter(const BitIntType *T, raw_ostream &OS) {}
1489
1490void TypePrinter::printDependentBitIntBefore(const DependentBitIntType *T,
1491 raw_ostream &OS) {
1492 if (T->isUnsigned())
1493 OS << "unsigned ";
1494 OS << "_BitInt(";
1495 T->getNumBitsExpr()->printPretty(OS, nullptr, Policy);
1496 OS << ")";
1497 spaceBeforePlaceHolder(OS);
1498}
1499
1500void TypePrinter::printDependentBitIntAfter(const DependentBitIntType *T,
1501 raw_ostream &OS) {}
1502
1503void TypePrinter::printPredefinedSugarBefore(const PredefinedSugarType *T,
1504 raw_ostream &OS) {
1505 OS << T->getIdentifier()->getName();
1506 spaceBeforePlaceHolder(OS);
1507}
1508
1509void TypePrinter::printPredefinedSugarAfter(const PredefinedSugarType *T,
1510 raw_ostream &OS) {}
1511
1512void TypePrinter::printTagType(const TagType *T, raw_ostream &OS) {
1513 TagDecl *D = T->getDecl();
1514
1515 if (Policy.IncludeTagDefinition && T->isTagOwned()) {
1516 D->print(OS, Policy, Indentation);
1517 spaceBeforePlaceHolder(OS);
1518 return;
1519 }
1520
1521 bool PrintedKindDecoration = false;
1522 if (T->isCanonicalUnqualified()) {
1523 if (!Policy.SuppressTagKeyword && !D->getTypedefNameForAnonDecl()) {
1524 PrintedKindDecoration = true;
1525 OS << D->getKindName();
1526 OS << ' ';
1527 }
1528 } else {
1529 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1530 if (T->getKeyword() != ElaboratedTypeKeyword::None) {
1531 PrintedKindDecoration = true;
1532 OS << ' ';
1533 }
1534 }
1535
1536 if (!Policy.FullyQualifiedName && !T->isCanonicalUnqualified()) {
1537 T->getQualifier().print(OS, Policy);
1538 } else if (!Policy.SuppressScope) {
1539 // Compute the full nested-name-specifier for this type.
1540 // In C, this will always be empty except when the type
1541 // being printed is anonymous within other Record.
1542 D->printNestedNameSpecifier(OS, Policy);
1543 }
1544
1545 if (const IdentifierInfo *II = D->getIdentifier())
1546 OS << II->getName();
1547 else {
1548 clang::PrintingPolicy Copy(Policy);
1549
1550 // Suppress the redundant tag keyword if we just printed one.
1551 if (PrintedKindDecoration) {
1552 Copy.SuppressTagKeywordInAnonNames = true;
1553 Copy.SuppressTagKeyword = true;
1554 }
1555
1556 D->printName(OS, Copy);
1557 }
1558
1559 // If this is a class template specialization, print the template
1560 // arguments.
1561 if (auto *S = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1562 const TemplateParameterList *TParams =
1563 S->getSpecializedTemplate()->getTemplateParameters();
1564 const ASTTemplateArgumentListInfo *TArgAsWritten =
1565 S->getTemplateArgsAsWritten();
1566 IncludeStrongLifetimeRAII Strong(Policy);
1567 if (TArgAsWritten && !Policy.PrintAsCanonical)
1568 printTemplateArgumentList(OS, TArgAsWritten->arguments(), Policy,
1569 TParams);
1570 else
1571 printTemplateArgumentList(OS, S->getTemplateArgs().asArray(), Policy,
1572 TParams);
1573 }
1574
1575 spaceBeforePlaceHolder(OS);
1576}
1577
1578void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
1579 // Print the preferred name if we have one for this type.
1580 if (Policy.UsePreferredNames) {
1581 for (const auto *PNA : T->getDecl()
1582 ->getMostRecentDecl()
1583 ->specific_attrs<PreferredNameAttr>()) {
1584 if (!declaresSameEntity(PNA->getTypedefType()->getAsCXXRecordDecl(),
1585 T->getDecl()))
1586 continue;
1587 // Find the outermost typedef or alias template.
1588 QualType T = PNA->getTypedefType();
1589 while (true) {
1590 if (auto *TT = dyn_cast<TypedefType>(T))
1591 return printTypeSpec(TT->getDecl(), OS);
1592 if (auto *TST = dyn_cast<TemplateSpecializationType>(T))
1593 return printTemplateId(TST, OS, /*FullyQualify=*/true);
1595 }
1596 }
1597 }
1598
1599 printTagType(T, OS);
1600}
1601
1602void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) {}
1603
1604void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {
1605 printTagType(T, OS);
1606}
1607
1608void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {}
1609
1610void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
1611 raw_ostream &OS) {
1612 const ASTContext &Ctx = T->getDecl()->getASTContext();
1613 IncludeStrongLifetimeRAII Strong(Policy);
1614 T->getTemplateName(Ctx).print(OS, Policy);
1616 auto *Decl = T->getDecl();
1617 // FIXME: Use T->getTemplateArgs(Ctx) when that supports as-written
1618 // arguments.
1619 if (auto *RD = dyn_cast<ClassTemplateSpecializationDecl>(Decl)) {
1620 printTemplateArgumentList(OS, RD->getTemplateArgsAsWritten()->arguments(),
1621 Policy,
1622 T->getTemplateDecl()->getTemplateParameters());
1623 } else {
1624 ClassTemplateDecl *TD = Decl->getDescribedClassTemplate();
1625 assert(TD);
1626 printTemplateArgumentList(
1627 OS, TD->getTemplateParameters()->getInjectedTemplateArgs(Ctx), Policy,
1628 T->getTemplateDecl()->getTemplateParameters());
1629 }
1630 }
1631 spaceBeforePlaceHolder(OS);
1632}
1633
1634void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
1635 raw_ostream &OS) {}
1636
1637void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
1638 raw_ostream &OS) {
1639 TemplateTypeParmDecl *D = T->getDecl();
1640 if (D && D->isImplicit()) {
1641 if (auto *TC = D->getTypeConstraint()) {
1642 TC->print(OS, Policy);
1643 OS << ' ';
1644 }
1645 OS << "auto";
1646 } else if (IdentifierInfo *Id = T->getIdentifier())
1647 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1648 : Id->getName());
1649 else
1650 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
1651
1652 spaceBeforePlaceHolder(OS);
1653}
1654
1655void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,
1656 raw_ostream &OS) {}
1657
1658void TypePrinter::printSubstTemplateTypeParmBefore(
1659 const SubstTemplateTypeParmType *T,
1660 raw_ostream &OS) {
1661 IncludeStrongLifetimeRAII Strong(Policy);
1662 printBefore(T->getReplacementType(), OS);
1663}
1664
1665void TypePrinter::printSubstTemplateTypeParmAfter(
1666 const SubstTemplateTypeParmType *T,
1667 raw_ostream &OS) {
1668 IncludeStrongLifetimeRAII Strong(Policy);
1669 printAfter(T->getReplacementType(), OS);
1670}
1671
1672void TypePrinter::printSubstBuiltinTemplatePackBefore(
1673 const SubstBuiltinTemplatePackType *T, raw_ostream &OS) {
1674 IncludeStrongLifetimeRAII Strong(Policy);
1675 OS << "type-pack";
1676}
1677
1678void TypePrinter::printSubstBuiltinTemplatePackAfter(
1679 const SubstBuiltinTemplatePackType *T, raw_ostream &OS) {}
1680
1681void TypePrinter::printSubstTemplateTypeParmPackBefore(
1682 const SubstTemplateTypeParmPackType *T,
1683 raw_ostream &OS) {
1684 IncludeStrongLifetimeRAII Strong(Policy);
1685 if (const TemplateTypeParmDecl *D = T->getReplacedParameter()) {
1686 if (D && D->isImplicit()) {
1687 if (auto *TC = D->getTypeConstraint()) {
1688 TC->print(OS, Policy);
1689 OS << ' ';
1690 }
1691 OS << "auto";
1692 } else if (IdentifierInfo *Id = D->getIdentifier())
1693 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1694 : Id->getName());
1695 else
1696 OS << "type-parameter-" << D->getDepth() << '-' << D->getIndex();
1697
1698 spaceBeforePlaceHolder(OS);
1699 }
1700}
1701
1702void TypePrinter::printSubstTemplateTypeParmPackAfter(
1703 const SubstTemplateTypeParmPackType *T,
1704 raw_ostream &OS) {
1705 IncludeStrongLifetimeRAII Strong(Policy);
1706}
1707
1708void TypePrinter::printTemplateId(const TemplateSpecializationType *T,
1709 raw_ostream &OS, bool FullyQualify) {
1710 IncludeStrongLifetimeRAII Strong(Policy);
1711
1712 if (ElaboratedTypeKeyword K = T->getKeyword();
1713 K != ElaboratedTypeKeyword::None)
1714 OS << TypeWithKeyword::getKeywordName(K) << ' ';
1715
1716 TemplateDecl *TD =
1717 T->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true);
1718 // FIXME: Null TD never exercised in test suite.
1719 if (FullyQualify && TD) {
1720 if (!Policy.SuppressScope)
1721 TD->printNestedNameSpecifier(OS, Policy);
1722
1723 OS << TD->getName();
1724 } else {
1725 T->getTemplateName().print(OS, Policy,
1726 !Policy.SuppressScope
1727 ? TemplateName::Qualified::AsWritten
1728 : TemplateName::Qualified::None);
1729 }
1730
1731 DefaultTemplateArgsPolicyRAII TemplateArgs(Policy);
1732 const TemplateParameterList *TPL = TD ? TD->getTemplateParameters() : nullptr;
1733 printTemplateArgumentList(OS, T->template_arguments(), Policy, TPL);
1734 spaceBeforePlaceHolder(OS);
1735}
1736
1737void TypePrinter::printTemplateSpecializationBefore(
1738 const TemplateSpecializationType *T,
1739 raw_ostream &OS) {
1740 printTemplateId(T, OS, Policy.FullyQualifiedName);
1741}
1742
1743void TypePrinter::printTemplateSpecializationAfter(
1744 const TemplateSpecializationType *T,
1745 raw_ostream &OS) {}
1746
1747void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {
1748 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1749 printBefore(T->getInnerType(), OS);
1750 OS << '(';
1751 } else
1752 printBefore(T->getInnerType(), OS);
1753}
1754
1755void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {
1756 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1757 OS << ')';
1758 printAfter(T->getInnerType(), OS);
1759 } else
1760 printAfter(T->getInnerType(), OS);
1761}
1762
1763void TypePrinter::printDependentNameBefore(const DependentNameType *T,
1764 raw_ostream &OS) {
1765 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1766 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1767 OS << " ";
1768 T->getQualifier().print(OS, Policy);
1769 OS << T->getIdentifier()->getName();
1770 spaceBeforePlaceHolder(OS);
1771}
1772
1773void TypePrinter::printDependentNameAfter(const DependentNameType *T,
1774 raw_ostream &OS) {}
1775
1776void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,
1777 raw_ostream &OS) {
1778 printBefore(T->getPattern(), OS);
1779}
1780
1781void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
1782 raw_ostream &OS) {
1783 printAfter(T->getPattern(), OS);
1784 OS << "...";
1785}
1786
1788 raw_ostream &OS,
1789 const PrintingPolicy &Policy) {
1790 OS << ' ';
1791 if (T->isCountInBytes() && T->isOrNull())
1792 OS << "__sized_by_or_null(";
1793 else if (T->isCountInBytes())
1794 OS << "__sized_by(";
1795 else if (T->isOrNull())
1796 OS << "__counted_by_or_null(";
1797 else
1798 OS << "__counted_by(";
1799 if (T->getCountExpr())
1800 T->getCountExpr()->printPretty(OS, nullptr, Policy);
1801 OS << ')';
1802}
1803
1804void TypePrinter::printCountAttributedBefore(const CountAttributedType *T,
1805 raw_ostream &OS) {
1806 printBefore(T->desugar(), OS);
1807 if (!T->isArrayType())
1808 printCountAttributedImpl(T, OS, Policy);
1809}
1810
1811void TypePrinter::printCountAttributedAfter(const CountAttributedType *T,
1812 raw_ostream &OS) {
1813 printAfter(T->desugar(), OS);
1814 if (T->isArrayType())
1815 printCountAttributedImpl(T, OS, Policy);
1816}
1817
1818void TypePrinter::printAttributedBefore(const AttributedType *T,
1819 raw_ostream &OS) {
1820 // FIXME: Generate this with TableGen.
1821
1822 // Prefer the macro forms of the GC and ownership qualifiers.
1823 if (T->getAttrKind() == attr::ObjCGC ||
1824 T->getAttrKind() == attr::ObjCOwnership)
1825 return printBefore(T->getEquivalentType(), OS);
1826
1827 if (T->getAttrKind() == attr::ObjCKindOf)
1828 OS << "__kindof ";
1829
1830 if (T->getAttrKind() == attr::PreserveNone) {
1831 OS << "__attribute__((preserve_none)) ";
1832 spaceBeforePlaceHolder(OS);
1833 } else if (T->getAttrKind() == attr::PreserveMost) {
1834 OS << "__attribute__((preserve_most)) ";
1835 spaceBeforePlaceHolder(OS);
1836 } else if (T->getAttrKind() == attr::PreserveAll) {
1837 OS << "__attribute__((preserve_all)) ";
1838 spaceBeforePlaceHolder(OS);
1839 }
1840
1841 if (T->getAttrKind() == attr::AddressSpace)
1842 printBefore(T->getEquivalentType(), OS);
1843 else
1844 printBefore(T->getModifiedType(), OS);
1845
1846 if (T->isMSTypeSpec()) {
1847 switch (T->getAttrKind()) {
1848 default: return;
1849 case attr::Ptr32: OS << " __ptr32"; break;
1850 case attr::Ptr64: OS << " __ptr64"; break;
1851 case attr::SPtr: OS << " __sptr"; break;
1852 case attr::UPtr: OS << " __uptr"; break;
1853 }
1854 spaceBeforePlaceHolder(OS);
1855 }
1856
1857 if (T->isWebAssemblyFuncrefSpec())
1858 OS << "__funcref";
1859
1860 // Print nullability type specifiers.
1861 if (T->getImmediateNullability()) {
1862 if (T->getAttrKind() == attr::TypeNonNull)
1863 OS << " _Nonnull";
1864 else if (T->getAttrKind() == attr::TypeNullable)
1865 OS << " _Nullable";
1866 else if (T->getAttrKind() == attr::TypeNullUnspecified)
1867 OS << " _Null_unspecified";
1868 else if (T->getAttrKind() == attr::TypeNullableResult)
1869 OS << " _Nullable_result";
1870 else
1871 llvm_unreachable("unhandled nullability");
1872 spaceBeforePlaceHolder(OS);
1873 }
1874}
1875
1876void TypePrinter::printAttributedAfter(const AttributedType *T,
1877 raw_ostream &OS) {
1878 // FIXME: Generate this with TableGen.
1879
1880 // Prefer the macro forms of the GC and ownership qualifiers.
1881 if (T->getAttrKind() == attr::ObjCGC ||
1882 T->getAttrKind() == attr::ObjCOwnership)
1883 return printAfter(T->getEquivalentType(), OS);
1884
1885 // If this is a calling convention attribute, don't print the implicit CC from
1886 // the modified type.
1887 SaveAndRestore MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());
1888
1889 printAfter(T->getModifiedType(), OS);
1890
1891 // Some attributes are printed as qualifiers before the type, so we have
1892 // nothing left to do.
1893 if (T->getAttrKind() == attr::ObjCKindOf || T->isMSTypeSpec() ||
1894 T->getImmediateNullability() || T->isWebAssemblyFuncrefSpec())
1895 return;
1896
1897 // Don't print the inert __unsafe_unretained attribute at all.
1898 if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained)
1899 return;
1900
1901 // Don't print ns_returns_retained unless it had an effect.
1902 if (T->getAttrKind() == attr::NSReturnsRetained &&
1903 !T->getEquivalentType()->castAs<FunctionType>()
1904 ->getExtInfo().getProducesResult())
1905 return;
1906
1907 if (T->getAttrKind() == attr::LifetimeBound) {
1908 OS << " [[clang::lifetimebound]]";
1909 return;
1910 }
1911 if (T->getAttrKind() == attr::LifetimeCaptureBy) {
1912 OS << " [[clang::lifetime_capture_by(";
1913 if (auto *attr = dyn_cast_or_null<LifetimeCaptureByAttr>(T->getAttr()))
1914 llvm::interleaveComma(attr->getArgIdents(), OS,
1915 [&](auto it) { OS << it->getName(); });
1916 OS << ")]]";
1917 return;
1918 }
1919
1920 // The printing of the address_space attribute is handled by the qualifier
1921 // since it is still stored in the qualifier. Return early to prevent printing
1922 // this twice.
1923 if (T->getAttrKind() == attr::AddressSpace)
1924 return;
1925
1926 if (T->getAttrKind() == attr::AnnotateType) {
1927 // FIXME: Print the attribute arguments once we have a way to retrieve these
1928 // here. For the meantime, we just print `[[clang::annotate_type(...)]]`
1929 // without the arguments so that we know at least that we had _some_
1930 // annotation on the type.
1931 OS << " [[clang::annotate_type(...)]]";
1932 return;
1933 }
1934
1935 if (T->getAttrKind() == attr::ArmStreaming) {
1936 OS << "__arm_streaming";
1937 return;
1938 }
1939 if (T->getAttrKind() == attr::ArmStreamingCompatible) {
1940 OS << "__arm_streaming_compatible";
1941 return;
1942 }
1943
1944 if (T->getAttrKind() == attr::SwiftAttr) {
1945 if (auto *swiftAttr = dyn_cast_or_null<SwiftAttrAttr>(T->getAttr())) {
1946 OS << " __attribute__((swift_attr(\"" << swiftAttr->getAttribute()
1947 << "\")))";
1948 }
1949 return;
1950 }
1951
1952 if (T->getAttrKind() == attr::PreserveAll ||
1953 T->getAttrKind() == attr::PreserveMost ||
1954 T->getAttrKind() == attr::PreserveNone) {
1955 // This has to be printed before the type.
1956 return;
1957 }
1958
1959 OS << " __attribute__((";
1960 switch (T->getAttrKind()) {
1961#define TYPE_ATTR(NAME)
1962#define DECL_OR_TYPE_ATTR(NAME)
1963#define ATTR(NAME) case attr::NAME:
1964#include "clang/Basic/AttrList.inc"
1965 llvm_unreachable("non-type attribute attached to type");
1966
1967 case attr::BTFTypeTag:
1968 llvm_unreachable("BTFTypeTag attribute handled separately");
1969
1970 case attr::HLSLResourceClass:
1971 case attr::HLSLROV:
1972 case attr::HLSLRawBuffer:
1973 case attr::HLSLContainedType:
1974 case attr::HLSLIsCounter:
1975 case attr::HLSLResourceDimension:
1976 llvm_unreachable("HLSL resource type attributes handled separately");
1977
1978 case attr::OpenCLPrivateAddressSpace:
1979 case attr::OpenCLGlobalAddressSpace:
1980 case attr::OpenCLGlobalDeviceAddressSpace:
1981 case attr::OpenCLGlobalHostAddressSpace:
1982 case attr::OpenCLLocalAddressSpace:
1983 case attr::OpenCLConstantAddressSpace:
1984 case attr::OpenCLGenericAddressSpace:
1985 case attr::HLSLGroupSharedAddressSpace:
1986 // FIXME: Update printAttributedBefore to print these once we generate
1987 // AttributedType nodes for them.
1988 break;
1989
1990 case attr::CountedBy:
1991 case attr::CountedByOrNull:
1992 case attr::SizedBy:
1993 case attr::SizedByOrNull:
1994 case attr::LifetimeBound:
1995 case attr::LifetimeCaptureBy:
1996 case attr::TypeNonNull:
1997 case attr::TypeNullable:
1998 case attr::TypeNullableResult:
1999 case attr::TypeNullUnspecified:
2000 case attr::ObjCGC:
2001 case attr::ObjCInertUnsafeUnretained:
2002 case attr::ObjCKindOf:
2003 case attr::ObjCOwnership:
2004 case attr::Ptr32:
2005 case attr::Ptr64:
2006 case attr::SPtr:
2007 case attr::UPtr:
2008 case attr::PointerAuth:
2009 case attr::AddressSpace:
2010 case attr::CmseNSCall:
2011 case attr::AnnotateType:
2012 case attr::WebAssemblyFuncref:
2013 case attr::ArmAgnostic:
2014 case attr::ArmStreaming:
2015 case attr::ArmStreamingCompatible:
2016 case attr::ArmIn:
2017 case attr::ArmOut:
2018 case attr::ArmInOut:
2019 case attr::ArmPreserves:
2020 case attr::NonBlocking:
2021 case attr::NonAllocating:
2022 case attr::Blocking:
2023 case attr::Allocating:
2024 case attr::SwiftAttr:
2025 case attr::PreserveAll:
2026 case attr::PreserveMost:
2027 case attr::PreserveNone:
2028 llvm_unreachable("This attribute should have been handled already");
2029
2030 case attr::NSReturnsRetained:
2031 OS << "ns_returns_retained";
2032 break;
2033
2034 // FIXME: When Sema learns to form this AttributedType, avoid printing the
2035 // attribute again in printFunctionProtoAfter.
2036 case attr::AnyX86NoCfCheck: OS << "nocf_check"; break;
2037 case attr::CDecl: OS << "cdecl"; break;
2038 case attr::FastCall: OS << "fastcall"; break;
2039 case attr::StdCall: OS << "stdcall"; break;
2040 case attr::ThisCall: OS << "thiscall"; break;
2041 case attr::SwiftCall: OS << "swiftcall"; break;
2042 case attr::SwiftAsyncCall: OS << "swiftasynccall"; break;
2043 case attr::VectorCall: OS << "vectorcall"; break;
2044 case attr::Pascal: OS << "pascal"; break;
2045 case attr::MSABI: OS << "ms_abi"; break;
2046 case attr::SysVABI: OS << "sysv_abi"; break;
2047 case attr::RegCall: OS << "regcall"; break;
2048 case attr::Pcs: {
2049 OS << "pcs(";
2050 QualType t = T->getEquivalentType();
2051 while (!t->isFunctionType())
2052 t = t->getPointeeType();
2053 OS << (t->castAs<FunctionType>()->getCallConv() == CC_AAPCS ?
2054 "\"aapcs\"" : "\"aapcs-vfp\"");
2055 OS << ')';
2056 break;
2057 }
2058 case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break;
2059 case attr::AArch64SVEPcs: OS << "aarch64_sve_pcs"; break;
2060 case attr::IntelOclBicc:
2061 OS << "inteloclbicc";
2062 break;
2063 case attr::M68kRTD:
2064 OS << "m68k_rtd";
2065 break;
2066 case attr::RISCVVectorCC:
2067 OS << "riscv_vector_cc";
2068 break;
2069 case attr::RISCVVLSCC:
2070 OS << "riscv_vls_cc";
2071 break;
2072 case attr::NoDeref:
2073 OS << "noderef";
2074 break;
2075 case attr::CFIUncheckedCallee:
2076 OS << "cfi_unchecked_callee";
2077 break;
2078 case attr::AcquireHandle:
2079 OS << "acquire_handle";
2080 break;
2081 case attr::ArmMveStrictPolymorphism:
2082 OS << "__clang_arm_mve_strict_polymorphism";
2083 break;
2084 case attr::ExtVectorType:
2085 OS << "ext_vector_type";
2086 break;
2087 case attr::CFISalt:
2088 OS << "cfi_salt(\"" << cast<CFISaltAttr>(T->getAttr())->getSalt() << "\")";
2089 break;
2090 }
2091 OS << "))";
2092}
2093
2094void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T,
2095 raw_ostream &OS) {
2096 printBefore(T->getWrappedType(), OS);
2097 OS << " __attribute__((btf_type_tag(\"" << T->getAttr()->getBTFTypeTag() << "\")))";
2098}
2099
2100void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,
2101 raw_ostream &OS) {
2102 printAfter(T->getWrappedType(), OS);
2103}
2104
2105void TypePrinter::printHLSLAttributedResourceBefore(
2106 const HLSLAttributedResourceType *T, raw_ostream &OS) {
2107 printBefore(T->getWrappedType(), OS);
2108}
2109
2110void TypePrinter::printHLSLAttributedResourceAfter(
2111 const HLSLAttributedResourceType *T, raw_ostream &OS) {
2112 printAfter(T->getWrappedType(), OS);
2113 const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs();
2114 OS << " [[hlsl::resource_class("
2115 << HLSLResourceClassAttr::ConvertResourceClassToStr(Attrs.ResourceClass)
2116 << ")]]";
2117 if (Attrs.IsROV)
2118 OS << " [[hlsl::is_rov]]";
2119 if (Attrs.RawBuffer)
2120 OS << " [[hlsl::raw_buffer]]";
2121 if (Attrs.IsCounter)
2122 OS << " [[hlsl::is_counter]]";
2123
2124 QualType ContainedTy = T->getContainedType();
2125 if (!ContainedTy.isNull()) {
2126 OS << " [[hlsl::contained_type(";
2127 printBefore(ContainedTy, OS);
2128 printAfter(ContainedTy, OS);
2129 OS << ")]]";
2130 }
2131
2132 if (Attrs.ResourceDimension != llvm::dxil::ResourceDimension::Unknown)
2133 OS << " [[hlsl::resource_dimension("
2134 << HLSLResourceDimensionAttr::ConvertResourceDimensionToStr(
2135 Attrs.ResourceDimension)
2136 << ")]]";
2137}
2138
2139void TypePrinter::printHLSLInlineSpirvBefore(const HLSLInlineSpirvType *T,
2140 raw_ostream &OS) {
2141 OS << "__hlsl_spirv_type<" << T->getOpcode();
2142
2143 OS << ", " << T->getSize();
2144 OS << ", " << T->getAlignment();
2145
2146 for (auto &Operand : T->getOperands()) {
2147 using SpirvOperandKind = SpirvOperand::SpirvOperandKind;
2148
2149 OS << ", ";
2150 switch (Operand.getKind()) {
2151 case SpirvOperandKind::ConstantId: {
2152 QualType ConstantType = Operand.getResultType();
2153 OS << "vk::integral_constant<";
2154 printBefore(ConstantType, OS);
2155 printAfter(ConstantType, OS);
2156 OS << ", ";
2157 OS << Operand.getValue();
2158 OS << ">";
2159 break;
2160 }
2161 case SpirvOperandKind::Literal:
2162 OS << "vk::Literal<vk::integral_constant<uint, ";
2163 OS << Operand.getValue();
2164 OS << ">>";
2165 break;
2166 case SpirvOperandKind::TypeId: {
2167 QualType Type = Operand.getResultType();
2168 printBefore(Type, OS);
2169 printAfter(Type, OS);
2170 break;
2171 }
2172 default:
2173 llvm_unreachable("Invalid SpirvOperand kind!");
2174 break;
2175 }
2176 }
2177
2178 OS << ">";
2179}
2180
2181void TypePrinter::printHLSLInlineSpirvAfter(const HLSLInlineSpirvType *T,
2182 raw_ostream &OS) {
2183 // nothing to do
2184}
2185
2186void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
2187 raw_ostream &OS) {
2188 OS << T->getDecl()->getName();
2189 spaceBeforePlaceHolder(OS);
2190}
2191
2192void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
2193 raw_ostream &OS) {}
2194
2195void TypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType *T,
2196 raw_ostream &OS) {
2197 OS << T->getDecl()->getName();
2198 if (!T->qual_empty()) {
2199 bool isFirst = true;
2200 OS << '<';
2201 for (const auto *I : T->quals()) {
2202 if (isFirst)
2203 isFirst = false;
2204 else
2205 OS << ',';
2206 OS << I->getName();
2207 }
2208 OS << '>';
2209 }
2210
2211 spaceBeforePlaceHolder(OS);
2212}
2213
2214void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T,
2215 raw_ostream &OS) {}
2216
2217void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
2218 raw_ostream &OS) {
2219 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2220 !T->isKindOfTypeAsWritten())
2221 return printBefore(T->getBaseType(), OS);
2222
2223 if (T->isKindOfTypeAsWritten())
2224 OS << "__kindof ";
2225
2226 print(T->getBaseType(), OS, StringRef());
2227
2228 if (T->isSpecializedAsWritten()) {
2229 bool isFirst = true;
2230 OS << '<';
2231 for (auto typeArg : T->getTypeArgsAsWritten()) {
2232 if (isFirst)
2233 isFirst = false;
2234 else
2235 OS << ",";
2236
2237 print(typeArg, OS, StringRef());
2238 }
2239 OS << '>';
2240 }
2241
2242 if (!T->qual_empty()) {
2243 bool isFirst = true;
2244 OS << '<';
2245 for (const auto *I : T->quals()) {
2246 if (isFirst)
2247 isFirst = false;
2248 else
2249 OS << ',';
2250 OS << I->getName();
2251 }
2252 OS << '>';
2253 }
2254
2255 spaceBeforePlaceHolder(OS);
2256}
2257
2258void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
2259 raw_ostream &OS) {
2260 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2261 !T->isKindOfTypeAsWritten())
2262 return printAfter(T->getBaseType(), OS);
2263}
2264
2265void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
2266 raw_ostream &OS) {
2267 printBefore(T->getPointeeType(), OS);
2268
2269 // If we need to print the pointer, print it now.
2270 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&
2272 if (HasEmptyPlaceHolder)
2273 OS << ' ';
2274 OS << '*';
2275 }
2276}
2277
2278void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
2279 raw_ostream &OS) {}
2280
2281static
2282const TemplateArgument &getArgument(const TemplateArgument &A) { return A; }
2283
2285 return A.getArgument();
2286}
2287
2288static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP,
2289 llvm::raw_ostream &OS, bool IncludeType) {
2290 A.print(PP, OS, IncludeType);
2291}
2292
2294 const PrintingPolicy &PP, llvm::raw_ostream &OS,
2295 bool IncludeType) {
2296 const TemplateArgument::ArgKind &Kind = A.getArgument().getKind();
2298 return A.getTypeSourceInfo()->getType().print(OS, PP);
2299 return A.getArgument().print(PP, OS, IncludeType);
2300}
2301
2302static bool isSubstitutedTemplateArgument(ASTContext &Ctx, TemplateArgument Arg,
2303 TemplateArgument Pattern,
2304 ArrayRef<TemplateArgument> Args,
2305 unsigned Depth);
2306
2308 ArrayRef<TemplateArgument> Args, unsigned Depth) {
2309 if (Ctx.hasSameType(T, Pattern))
2310 return true;
2311
2312 // A type parameter matches its argument.
2313 if (auto *TTPT = Pattern->getAsCanonical<TemplateTypeParmType>()) {
2314 if (TTPT->getDepth() == Depth && TTPT->getIndex() < Args.size() &&
2315 Args[TTPT->getIndex()].getKind() == TemplateArgument::Type) {
2316 QualType SubstArg = Ctx.getQualifiedType(
2317 Args[TTPT->getIndex()].getAsType(), Pattern.getQualifiers());
2318 return Ctx.hasSameType(SubstArg, T);
2319 }
2320 return false;
2321 }
2322
2323 // FIXME: Recurse into array types.
2324
2325 // All other cases will need the types to be identically qualified.
2326 Qualifiers TQual, PatQual;
2327 T = Ctx.getUnqualifiedArrayType(T, TQual);
2328 Pattern = Ctx.getUnqualifiedArrayType(Pattern, PatQual);
2329 if (TQual != PatQual)
2330 return false;
2331
2332 // Recurse into pointer-like types.
2333 {
2334 QualType TPointee = T->getPointeeType();
2335 QualType PPointee = Pattern->getPointeeType();
2336 if (!TPointee.isNull() && !PPointee.isNull())
2337 return T->getTypeClass() == Pattern->getTypeClass() &&
2338 isSubstitutedType(Ctx, TPointee, PPointee, Args, Depth);
2339 }
2340
2341 // Recurse into template specialization types.
2342 if (auto *PTST =
2343 Pattern.getCanonicalType()->getAs<TemplateSpecializationType>()) {
2345 ArrayRef<TemplateArgument> TemplateArgs;
2346 if (auto *TTST = T->getAs<TemplateSpecializationType>()) {
2347 Template = TTST->getTemplateName();
2348 TemplateArgs = TTST->template_arguments();
2349 } else if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
2350 T->getAsCXXRecordDecl())) {
2351 Template = TemplateName(CTSD->getSpecializedTemplate());
2352 TemplateArgs = CTSD->getTemplateArgs().asArray();
2353 } else {
2354 return false;
2355 }
2356
2357 if (!isSubstitutedTemplateArgument(Ctx, Template, PTST->getTemplateName(),
2358 Args, Depth))
2359 return false;
2360 if (TemplateArgs.size() != PTST->template_arguments().size())
2361 return false;
2362 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
2364 Ctx, TemplateArgs[I], PTST->template_arguments()[I], Args, Depth))
2365 return false;
2366 return true;
2367 }
2368
2369 // FIXME: Handle more cases.
2370 return false;
2371}
2372
2373/// Evaluates the expression template argument 'Pattern' and returns true
2374/// if 'Arg' evaluates to the same result.
2376 TemplateArgument const &Pattern,
2377 TemplateArgument const &Arg) {
2378 if (Pattern.getKind() != TemplateArgument::Expression)
2379 return false;
2380
2381 // Can't evaluate value-dependent expressions so bail early
2382 Expr const *pattern_expr = Pattern.getAsExpr();
2383 if (pattern_expr->isValueDependent() ||
2384 !pattern_expr->isIntegerConstantExpr(Ctx))
2385 return false;
2386
2388 return llvm::APSInt::isSameValue(pattern_expr->EvaluateKnownConstInt(Ctx),
2389 Arg.getAsIntegral());
2390
2392 Expr const *args_expr = Arg.getAsExpr();
2393 if (args_expr->isValueDependent() || !args_expr->isIntegerConstantExpr(Ctx))
2394 return false;
2395
2396 return llvm::APSInt::isSameValue(args_expr->EvaluateKnownConstInt(Ctx),
2397 pattern_expr->EvaluateKnownConstInt(Ctx));
2398 }
2399
2400 return false;
2401}
2402
2404 TemplateArgument Pattern,
2406 unsigned Depth) {
2407 Arg = Ctx.getCanonicalTemplateArgument(Arg);
2408 Pattern = Ctx.getCanonicalTemplateArgument(Pattern);
2409 if (Arg.structurallyEquals(Pattern))
2410 return true;
2411
2412 if (Pattern.getKind() == TemplateArgument::Expression) {
2413 if (auto *DRE =
2414 dyn_cast<DeclRefExpr>(Pattern.getAsExpr()->IgnoreParenImpCasts())) {
2415 if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
2416 return NTTP->getDepth() == Depth && Args.size() > NTTP->getIndex() &&
2417 Args[NTTP->getIndex()].structurallyEquals(Arg);
2418 }
2419 }
2420
2421 if (templateArgumentExpressionsEqual(Ctx, Pattern, Arg))
2422 return true;
2423
2424 if (Arg.getKind() != Pattern.getKind())
2425 return false;
2426
2427 if (Arg.getKind() == TemplateArgument::Type)
2428 return isSubstitutedType(Ctx, Arg.getAsType(), Pattern.getAsType(), Args,
2429 Depth);
2430
2431 if (Arg.getKind() == TemplateArgument::Template) {
2432 TemplateDecl *PatTD = Pattern.getAsTemplate().getAsTemplateDecl();
2433 if (auto *TTPD = dyn_cast_or_null<TemplateTemplateParmDecl>(PatTD))
2434 return TTPD->getDepth() == Depth && Args.size() > TTPD->getIndex() &&
2435 Ctx.getCanonicalTemplateArgument(Args[TTPD->getIndex()])
2436 .structurallyEquals(Arg);
2437 }
2438
2439 // FIXME: Handle more cases.
2440 return false;
2441}
2442
2443bool clang::isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg,
2444 const NamedDecl *Param,
2445 ArrayRef<TemplateArgument> Args,
2446 unsigned Depth) {
2447 // An empty pack is equivalent to not providing a pack argument.
2448 if (Arg.getKind() == TemplateArgument::Pack && Arg.pack_size() == 0)
2449 return true;
2450
2451 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Param)) {
2452 return TTPD->hasDefaultArgument() &&
2454 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2455 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
2456 return TTPD->hasDefaultArgument() &&
2458 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2459 } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
2460 return NTTPD->hasDefaultArgument() &&
2462 Ctx, Arg, NTTPD->getDefaultArgument().getArgument(), Args,
2463 Depth);
2464 }
2465 return false;
2466}
2467
2468template <typename TA>
2469static void
2470printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy,
2471 const TemplateParameterList *TPL, bool IsPack, unsigned ParmIndex) {
2472 // Drop trailing template arguments that match default arguments.
2473 if (TPL && Policy.SuppressDefaultTemplateArgs && !Policy.PrintAsCanonical &&
2474 !Args.empty() && !IsPack && Args.size() <= TPL->size()) {
2476 for (const TA &A : Args)
2477 OrigArgs.push_back(getArgument(A));
2478 while (!Args.empty() && getArgument(Args.back()).getIsDefaulted())
2479 Args = Args.drop_back();
2480 }
2481
2482 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
2483 if (!IsPack)
2484 OS << '<';
2485
2486 bool NeedSpace = false;
2487 bool FirstArg = true;
2488 for (const auto &Arg : Args) {
2489 // Print the argument into a string.
2490 SmallString<128> Buf;
2491 llvm::raw_svector_ostream ArgOS(Buf);
2492 const TemplateArgument &Argument = getArgument(Arg);
2493 if (Argument.getKind() == TemplateArgument::Pack) {
2494 if (Argument.pack_size() && !FirstArg)
2495 OS << Comma;
2496 printTo(ArgOS, Argument.getPackAsArray(), Policy, TPL,
2497 /*IsPack*/ true, ParmIndex);
2498 } else {
2499 if (!FirstArg)
2500 OS << Comma;
2501 // Tries to print the argument with location info if exists.
2502 printArgument(Arg, Policy, ArgOS,
2504 Policy, TPL, ParmIndex));
2505 }
2506 StringRef ArgString = ArgOS.str();
2507
2508 // If this is the first argument and its string representation
2509 // begins with the global scope specifier ('::foo'), add a space
2510 // to avoid printing the diagraph '<:'.
2511 if (FirstArg && ArgString.starts_with(":"))
2512 OS << ' ';
2513
2514 OS << ArgString;
2515
2516 // If the last character of our string is '>', add another space to
2517 // keep the two '>''s separate tokens.
2518 if (!ArgString.empty()) {
2519 NeedSpace = Policy.SplitTemplateClosers && ArgString.back() == '>';
2520 FirstArg = false;
2521 }
2522
2523 // Use same template parameter for all elements of Pack
2524 if (!IsPack)
2525 ParmIndex++;
2526 }
2527
2528 if (!IsPack) {
2529 if (NeedSpace)
2530 OS << ' ';
2531 OS << '>';
2532 }
2533}
2534
2535void clang::printTemplateArgumentList(raw_ostream &OS,
2536 const TemplateArgumentListInfo &Args,
2537 const PrintingPolicy &Policy,
2538 const TemplateParameterList *TPL) {
2539 printTemplateArgumentList(OS, Args.arguments(), Policy, TPL);
2540}
2541
2542void clang::printTemplateArgumentList(raw_ostream &OS,
2543 ArrayRef<TemplateArgument> Args,
2544 const PrintingPolicy &Policy,
2545 const TemplateParameterList *TPL) {
2546 PrintingPolicy InnerPolicy = Policy;
2547 InnerPolicy.SuppressScope = false;
2548 printTo(OS, Args, InnerPolicy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2549}
2550
2551void clang::printTemplateArgumentList(raw_ostream &OS,
2552 ArrayRef<TemplateArgumentLoc> Args,
2553 const PrintingPolicy &Policy,
2554 const TemplateParameterList *TPL) {
2555 PrintingPolicy InnerPolicy = Policy;
2556 InnerPolicy.SuppressScope = false;
2557 printTo(OS, Args, InnerPolicy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2558}
2559
2561 LangOptions LO;
2562 return getAsString(PrintingPolicy(LO));
2563}
2564
2566 SmallString<64> Buf;
2567 llvm::raw_svector_ostream StrOS(Buf);
2568 print(StrOS, P);
2569 return StrOS.str().str();
2570}
2571
2573 return !isPresent();
2574}
2575
2576void PointerAuthQualifier::print(raw_ostream &OS,
2577 const PrintingPolicy &P) const {
2578 if (!isPresent())
2579 return;
2580
2581 OS << "__ptrauth(";
2582 OS << getKey();
2583 OS << "," << unsigned(isAddressDiscriminated()) << ","
2584 << getExtraDiscriminator() << ")";
2585}
2586
2587std::string Qualifiers::getAsString() const {
2588 LangOptions LO;
2589 return getAsString(PrintingPolicy(LO));
2590}
2591
2592// Appends qualifiers to the given string, separated by spaces. Will
2593// prefix a space if the string is non-empty. Will not append a final
2594// space.
2595std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {
2596 SmallString<64> Buf;
2597 llvm::raw_svector_ostream StrOS(Buf);
2598 print(StrOS, Policy);
2599 return std::string(StrOS.str());
2600}
2601
2603 if (getCVRQualifiers())
2604 return false;
2605
2607 return false;
2608
2609 if (getObjCGCAttr())
2610 return false;
2611
2613 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
2614 return false;
2615
2616 if (PointerAuthQualifier PointerAuth = getPointerAuth();
2617 PointerAuth && !PointerAuth.isEmptyWhenPrinted(Policy))
2618 return false;
2619
2620 return true;
2621}
2622
2624 switch (AS) {
2625 case LangAS::Default:
2626 return "";
2629 return "__global";
2631 case LangAS::sycl_local:
2632 return "__local";
2635 return "__private";
2637 return "__constant";
2639 return "__generic";
2642 return "__global_device";
2645 return "__global_host";
2647 return "__device__";
2649 return "__constant__";
2651 return "__shared__";
2652 case LangAS::ptr32_sptr:
2653 return "__sptr __ptr32";
2654 case LangAS::ptr32_uptr:
2655 return "__uptr __ptr32";
2656 case LangAS::ptr64:
2657 return "__ptr64";
2659 return "groupshared";
2661 return "hlsl_constant";
2663 return "hlsl_private";
2665 return "hlsl_device";
2666 case LangAS::hlsl_input:
2667 return "hlsl_input";
2669 return "hlsl_push_constant";
2671 return "__funcref";
2672 default:
2673 return std::to_string(toTargetAddressSpace(AS));
2674 }
2675}
2676
2677// Appends qualifiers to the given string, separated by spaces. Will
2678// prefix a space if the string is non-empty. Will not append a final
2679// space.
2680void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
2681 bool appendSpaceIfNonEmpty) const {
2682 bool addSpace = false;
2683
2684 unsigned quals = getCVRQualifiers();
2685 if (quals) {
2686 AppendTypeQualList(OS, quals, Policy.Restrict);
2687 addSpace = true;
2688 }
2689 if (hasUnaligned()) {
2690 if (addSpace)
2691 OS << ' ';
2692 OS << "__unaligned";
2693 addSpace = true;
2694 }
2695 auto ASStr = getAddrSpaceAsString(getAddressSpace());
2696 if (!ASStr.empty()) {
2697 if (addSpace)
2698 OS << ' ';
2699 addSpace = true;
2700 // Wrap target address space into an attribute syntax
2702 OS << "__attribute__((address_space(" << ASStr << ")))";
2703 else
2704 OS << ASStr;
2705 }
2706
2707 if (Qualifiers::GC gc = getObjCGCAttr()) {
2708 if (addSpace)
2709 OS << ' ';
2710 addSpace = true;
2711 if (gc == Qualifiers::Weak)
2712 OS << "__weak";
2713 else
2714 OS << "__strong";
2715 }
2716 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
2717 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
2718 if (addSpace)
2719 OS << ' ';
2720 addSpace = true;
2721 }
2722
2723 switch (lifetime) {
2724 case Qualifiers::OCL_None: llvm_unreachable("none but true");
2725 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;
2727 if (!Policy.SuppressStrongLifetime)
2728 OS << "__strong";
2729 break;
2730
2731 case Qualifiers::OCL_Weak: OS << "__weak"; break;
2732 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
2733 }
2734 }
2735
2736 if (PointerAuthQualifier PointerAuth = getPointerAuth()) {
2737 if (addSpace)
2738 OS << ' ';
2739 addSpace = true;
2740
2741 PointerAuth.print(OS, Policy);
2742 }
2743
2744 if (appendSpaceIfNonEmpty && addSpace)
2745 OS << ' ';
2746}
2747
2748std::string QualType::getAsString() const {
2749 return getAsString(split(), LangOptions());
2750}
2751
2752std::string QualType::getAsString(const PrintingPolicy &Policy) const {
2753 std::string S;
2754 getAsStringInternal(S, Policy);
2755 return S;
2756}
2757
2758std::string QualType::getAsString(const Type *ty, Qualifiers qs,
2759 const PrintingPolicy &Policy) {
2760 std::string buffer;
2761 getAsStringInternal(ty, qs, buffer, Policy);
2762 return buffer;
2763}
2764
2765void QualType::print(raw_ostream &OS, const PrintingPolicy &Policy,
2766 const Twine &PlaceHolder, unsigned Indentation) const {
2767 print(splitAccordingToPolicy(*this, Policy), OS, Policy, PlaceHolder,
2768 Indentation);
2769}
2770
2772 raw_ostream &OS, const PrintingPolicy &policy,
2773 const Twine &PlaceHolder, unsigned Indentation) {
2774 SmallString<128> PHBuf;
2775 StringRef PH = PlaceHolder.toStringRef(PHBuf);
2776
2777 TypePrinter(policy, Indentation).print(ty, qs, OS, PH);
2778}
2779
2780void QualType::getAsStringInternal(std::string &Str,
2781 const PrintingPolicy &Policy) const {
2782 return getAsStringInternal(splitAccordingToPolicy(*this, Policy), Str,
2783 Policy);
2784}
2785
2787 std::string &buffer,
2788 const PrintingPolicy &policy) {
2789 SmallString<256> Buf;
2790 llvm::raw_svector_ostream StrOS(Buf);
2791 TypePrinter(policy).print(ty, qs, StrOS, buffer);
2792 std::string str = std::string(StrOS.str());
2793 buffer.swap(str);
2794}
2795
2796raw_ostream &clang::operator<<(raw_ostream &OS, QualType QT) {
2797 SplitQualType S = QT.split();
2798 TypePrinter(LangOptions()).print(S.Ty, S.Quals, OS, /*PlaceHolder=*/"");
2799 return OS;
2800}
Defines the clang::ASTContext interface.
Provides definitions for the various language-specific address spaces.
Defines the clang::attr::Kind enum.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the ExceptionSpecificationType enumeration and various utility functions.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
static void print(llvm::raw_ostream &OS, const T &V, ASTContext &ASTCtx, QualType Ty)
#define CC_VLS_CASE(ABI_VLEN)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
static void printHLSLMatrixBefore(TypePrinter &TP, const ConstantMatrixType *T, raw_ostream &OS)
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 printClangMatrixBefore(TypePrinter &TP, const ConstantMatrixType *T, raw_ostream &OS)
static void printDims(const ConstantMatrixType *T, raw_ostream &OS)
static void printHLSLMatrixAfter(const ConstantMatrixType *T, raw_ostream &OS)
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:220
TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg) const
Retrieve the "canonical" template argument.
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals) const
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals.
Represents a concrete matrix type with constant number of rows and columns.
Definition TypeBase.h:4388
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
Definition TypeBase.h:3437
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition DeclBase.h:593
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
This represents one expression.
Definition Expr.h:112
bool isIntegerConstantExpr(const ASTContext &Ctx) const
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition Expr.h:177
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) 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:3089
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5269
QualType desugar() const
Definition TypeBase.h:5850
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Definition TypeBase.h:5576
unsigned getNumParams() const
Definition TypeBase.h:5547
void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
Definition TypeBase.h:5689
Qualifiers getMethodQuals() const
Definition TypeBase.h:5695
QualType getParamType(unsigned i) const
Definition TypeBase.h:5549
FunctionEffectsRef getFunctionEffects() const
Definition TypeBase.h:5833
unsigned getAArch64SMEAttributes() const
Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...
Definition TypeBase.h:5766
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
Definition TypeBase.h:5627
bool hasCFIUncheckedCallee() const
Definition TypeBase.h:5691
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition TypeBase.h:5619
bool hasDynamicExceptionSpec() const
Return whether this function has a dynamic (throw) exception spec.
Definition TypeBase.h:5585
bool isVariadic() const
Whether this function prototype is variadic.
Definition TypeBase.h:5673
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
Definition TypeBase.h:5634
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Definition TypeBase.h:5703
CallingConv getCC() const
Definition TypeBase.h:4635
unsigned getRegParm() const
Definition TypeBase.h:4628
bool getNoCallerSavedRegs() const
Definition TypeBase.h:4624
ExtInfo getExtInfo() const
Definition TypeBase.h:4821
static ArmStateValue getArmZT0State(unsigned AttrBits)
Definition TypeBase.h:4774
static ArmStateValue getArmZAState(unsigned AttrBits)
Definition TypeBase.h:4770
QualType getReturnType() const
Definition TypeBase.h:4805
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:295
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:301
void printNestedNameSpecifier(raw_ostream &OS) const
Print only the nested name specifier part of a fully-qualified name, including the '::' at the end.
Definition Decl.cpp:1714
Pointer-authentication qualifiers.
Definition TypeBase.h:152
bool isAddressDiscriminated() const
Definition TypeBase.h:265
unsigned getExtraDiscriminator() const
Definition TypeBase.h:270
void print(raw_ostream &OS, const PrintingPolicy &Policy) const
bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const
std::string getAsString() const
unsigned getKey() const
Definition TypeBase.h:258
A (possibly-)qualified type.
Definition TypeBase.h:937
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1004
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition TypeBase.h:8342
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 TypeBase.h:8354
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
Definition TypeBase.h:8323
std::string getAsString() const
The collection of all-type qualifiers we support.
Definition TypeBase.h:331
unsigned getCVRQualifiers() const
Definition TypeBase.h:488
GC getObjCGCAttr() const
Definition TypeBase.h:519
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Definition TypeBase.h:361
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
Definition TypeBase.h:354
@ OCL_None
There is no lifetime qualification on this type.
Definition TypeBase.h:350
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Definition TypeBase.h:364
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
Definition TypeBase.h:367
bool hasUnaligned() const
Definition TypeBase.h:511
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool appendSpaceIfNonEmpty=false) const
bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const
PointerAuthQualifier getPointerAuth() const
Definition TypeBase.h:603
ObjCLifetime getObjCLifetime() const
Definition TypeBase.h:545
bool empty() const
Definition TypeBase.h:647
std::string getAsString() const
LangAS getAddressSpace() const
Definition TypeBase.h:571
static std::string getAddrSpaceAsString(LangAS AS)
Base for LValueReferenceType and RValueReferenceType.
Definition TypeBase.h:3574
StringRef getKindName() const
Definition Decl.h:3910
TypedefNameDecl * getTypedefNameForAnonDecl() const
Definition Decl.h:3951
void printName(raw_ostream &OS, const PrintingPolicy &Policy) const override
Pretty-print the unqualified name of this declaration.
Definition Decl.cpp:5023
ArrayRef< TemplateArgumentLoc > arguments() const
Location wrapper for a TemplateArgument.
const TemplateArgument & getArgument() const
TypeSourceInfo * getTypeSourceInfo() const
Represents a template argument.
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
Expr * getAsExpr() const
Retrieve the template argument as an expression.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
unsigned pack_size() const
The number of template arguments in the given template argument pack.
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.
ArgKind
The kind of template argument we're storing.
@ Template
The template argument is a template name that was provided for a template template parameter.
@ Pack
The template argument is actually a parameter pack.
@ Type
The template argument is a type.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
The base class of all kinds of template declarations (e.g., class, function, etc.).
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a C++ template name within the type system.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
void print(raw_ostream &OS, const PrintingPolicy &Policy, Qualified Qual=Qualified::AsWritten) const
Print the template name.
Stores a list of template parameters for a TemplateDecl and its derived classes.
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context)
Get the template argument list of the template parameter list.
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
unsigned getIndex() const
Retrieve the index of the template parameter.
const TypeConstraint * getTypeConstraint() const
Returns the type constraint associated with this template parameter (if any).
unsigned getDepth() const
Retrieve the depth of the template parameter.
QualType getType() const
Return the type wrapped by this type source info.
Definition TypeBase.h:8284
The base class of the type hierarchy.
Definition TypeBase.h:1833
bool isArrayType() const
Definition TypeBase.h:8638
QualType getLocallyUnqualifiedSingleStepDesugaredType() const
Pull a single level of sugar off of this locally-unqualified type.
Definition Type.cpp:522
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9188
bool isObjCQualifiedIdType() const
Definition TypeBase.h:8735
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:753
bool isObjCIdType() const
Definition TypeBase.h:8747
bool isSpecifierType() const
Returns true if this type can be represented by some set of type specifiers.
Definition Type.cpp:3200
bool isFunctionType() const
Definition TypeBase.h:8535
bool isObjCQualifiedClassType() const
Definition TypeBase.h:8741
bool isObjCClassType() const
Definition TypeBase.h:8753
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:2922
TypeClass getTypeClass() const
Definition TypeBase.h:2385
bool isCanonicalUnqualified() const
Determines if this type would be canonical if it had no further qualification.
Definition TypeBase.h:2411
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9121
const internal::VariadicAllOfMatcher< Attr > attr
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
llvm::StringRef getParameterABISpelling(ParameterABI kind)
bool isTargetAddressSpace(LangAS AS)
@ RQ_None
No ref-qualifier was provided.
Definition TypeBase.h:1782
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
Definition TypeBase.h:1785
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition TypeBase.h:1788
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
Definition Parser.h:61
unsigned toTargetAddressSpace(LangAS AS)
ParameterABI
Kinds of parameter ABI.
Definition Specifiers.h:378
@ SwiftAsyncContext
This parameter (which must have pointer type) uses the special Swift asynchronous context-pointer ABI...
Definition Specifiers.h:399
@ SwiftErrorResult
This parameter (which must have pointer-to-pointer type) uses the special Swift error-result ABI trea...
Definition Specifiers.h:389
@ Ordinary
This parameter uses ordinary ABI rules for its type.
Definition Specifiers.h:380
@ SwiftIndirectResult
This parameter (which must have pointer type) is a Swift indirect result parameter.
Definition Specifiers.h:384
@ SwiftContext
This parameter (which must have pointer type) uses the special Swift context-pointer ABI treatment.
Definition Specifiers.h:394
const FunctionProtoType * T
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
@ Template
We are parsing a template declaration.
Definition Parser.h:81
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
@ Keyword
The name has been typo-corrected to a keyword.
Definition Sema.h:562
@ Type
The name was classified as a type.
Definition Sema.h:564
LangAS
Defines the address space values used by the address space qualifier of QualType.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
Definition DeclBase.h:1288
llvm::StringRef getAsString(SyncScope S)
Definition SyncScope.h:62
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ConceptReference *C)
Insertion operator for diagnostics.
@ CC_X86Pascal
Definition Specifiers.h:284
@ CC_Swift
Definition Specifiers.h:293
@ CC_IntelOclBicc
Definition Specifiers.h:290
@ CC_PreserveMost
Definition Specifiers.h:295
@ CC_Win64
Definition Specifiers.h:285
@ CC_X86ThisCall
Definition Specifiers.h:282
@ CC_AArch64VectorCall
Definition Specifiers.h:297
@ CC_DeviceKernel
Definition Specifiers.h:292
@ CC_AAPCS
Definition Specifiers.h:288
@ CC_PreserveNone
Definition Specifiers.h:300
@ CC_M68kRTD
Definition Specifiers.h:299
@ CC_SwiftAsync
Definition Specifiers.h:294
@ CC_X86RegCall
Definition Specifiers.h:287
@ CC_RISCVVectorCall
Definition Specifiers.h:301
@ CC_X86VectorCall
Definition Specifiers.h:283
@ CC_SpirFunction
Definition Specifiers.h:291
@ CC_AArch64SVEPCS
Definition Specifiers.h:298
@ CC_X86StdCall
Definition Specifiers.h:280
@ CC_X86_64SysV
Definition Specifiers.h:286
@ CC_PreserveAll
Definition Specifiers.h:296
@ CC_X86FastCall
Definition Specifiers.h:281
@ CC_AAPCS_VFP
Definition Specifiers.h:289
U cast(CodeGen::Address addr)
Definition Address.h:327
ElaboratedTypeKeyword
The elaboration keyword that precedes a qualified type name or introduces an elaborated-type-specifie...
Definition TypeBase.h:5868
@ EST_NoThrow
Microsoft __declspec(nothrow) extension.
@ EST_MSAny
Microsoft throw(...) extension.
ArrayRef< TemplateArgumentLoc > arguments() const
static StringRef getKeywordName(ElaboratedTypeKeyword Keyword)
Definition Type.cpp:3310
Describes how types, statements, expressions, and declarations should be printed.
unsigned FullyQualifiedName
When true, print the fully qualified name of function declarations.
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 PrintInjectedClassNameWithArguments
Whether to print an InjectedClassNameType with template arguments or as written.
unsigned UseVoidForZeroParams
Whether we should use '(void)' rather than '()' for a function prototype with zero parameters.
unsigned CleanUglifiedParameters
Whether to strip underscores when printing reserved parameter names.
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 UsePreferredNames
Whether to use C++ template preferred_name attributes when printing templates.
unsigned SuppressStrongLifetime
When true, suppress printing of the __strong lifetime qualifier in ARC.
unsigned Restrict
Whether we can use 'restrict' rather than '__restrict'.
unsigned UseHLSLTypes
Whether or not we're printing known HLSL code and should print HLSL sugared types when possible.
unsigned SuppressScope
Suppresses printing of scope specifiers.
unsigned IncludeTagDefinition
When true, include the body of a tag definition.
unsigned PrintAsCanonical
Whether to print entities as written or canonically.
A std::pair-like structure for storing a qualified type split into its local qualifiers and its local...
Definition TypeBase.h:870
const Type * Ty
The locally-unqualified type.
Definition TypeBase.h:872
Qualifiers Quals
The local qualifiers.
Definition TypeBase.h:875