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 llvm_unreachable("HLSL resource type attributes handled separately");
1976
1977 case attr::OpenCLPrivateAddressSpace:
1978 case attr::OpenCLGlobalAddressSpace:
1979 case attr::OpenCLGlobalDeviceAddressSpace:
1980 case attr::OpenCLGlobalHostAddressSpace:
1981 case attr::OpenCLLocalAddressSpace:
1982 case attr::OpenCLConstantAddressSpace:
1983 case attr::OpenCLGenericAddressSpace:
1984 case attr::HLSLGroupSharedAddressSpace:
1985 // FIXME: Update printAttributedBefore to print these once we generate
1986 // AttributedType nodes for them.
1987 break;
1988
1989 case attr::CountedBy:
1990 case attr::CountedByOrNull:
1991 case attr::SizedBy:
1992 case attr::SizedByOrNull:
1993 case attr::LifetimeBound:
1994 case attr::LifetimeCaptureBy:
1995 case attr::TypeNonNull:
1996 case attr::TypeNullable:
1997 case attr::TypeNullableResult:
1998 case attr::TypeNullUnspecified:
1999 case attr::ObjCGC:
2000 case attr::ObjCInertUnsafeUnretained:
2001 case attr::ObjCKindOf:
2002 case attr::ObjCOwnership:
2003 case attr::Ptr32:
2004 case attr::Ptr64:
2005 case attr::SPtr:
2006 case attr::UPtr:
2007 case attr::PointerAuth:
2008 case attr::AddressSpace:
2009 case attr::CmseNSCall:
2010 case attr::AnnotateType:
2011 case attr::WebAssemblyFuncref:
2012 case attr::ArmAgnostic:
2013 case attr::ArmStreaming:
2014 case attr::ArmStreamingCompatible:
2015 case attr::ArmIn:
2016 case attr::ArmOut:
2017 case attr::ArmInOut:
2018 case attr::ArmPreserves:
2019 case attr::NonBlocking:
2020 case attr::NonAllocating:
2021 case attr::Blocking:
2022 case attr::Allocating:
2023 case attr::SwiftAttr:
2024 case attr::PreserveAll:
2025 case attr::PreserveMost:
2026 case attr::PreserveNone:
2027 llvm_unreachable("This attribute should have been handled already");
2028
2029 case attr::NSReturnsRetained:
2030 OS << "ns_returns_retained";
2031 break;
2032
2033 // FIXME: When Sema learns to form this AttributedType, avoid printing the
2034 // attribute again in printFunctionProtoAfter.
2035 case attr::AnyX86NoCfCheck: OS << "nocf_check"; break;
2036 case attr::CDecl: OS << "cdecl"; break;
2037 case attr::FastCall: OS << "fastcall"; break;
2038 case attr::StdCall: OS << "stdcall"; break;
2039 case attr::ThisCall: OS << "thiscall"; break;
2040 case attr::SwiftCall: OS << "swiftcall"; break;
2041 case attr::SwiftAsyncCall: OS << "swiftasynccall"; break;
2042 case attr::VectorCall: OS << "vectorcall"; break;
2043 case attr::Pascal: OS << "pascal"; break;
2044 case attr::MSABI: OS << "ms_abi"; break;
2045 case attr::SysVABI: OS << "sysv_abi"; break;
2046 case attr::RegCall: OS << "regcall"; break;
2047 case attr::Pcs: {
2048 OS << "pcs(";
2049 QualType t = T->getEquivalentType();
2050 while (!t->isFunctionType())
2051 t = t->getPointeeType();
2052 OS << (t->castAs<FunctionType>()->getCallConv() == CC_AAPCS ?
2053 "\"aapcs\"" : "\"aapcs-vfp\"");
2054 OS << ')';
2055 break;
2056 }
2057 case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break;
2058 case attr::AArch64SVEPcs: OS << "aarch64_sve_pcs"; break;
2059 case attr::IntelOclBicc:
2060 OS << "inteloclbicc";
2061 break;
2062 case attr::M68kRTD:
2063 OS << "m68k_rtd";
2064 break;
2065 case attr::RISCVVectorCC:
2066 OS << "riscv_vector_cc";
2067 break;
2068 case attr::RISCVVLSCC:
2069 OS << "riscv_vls_cc";
2070 break;
2071 case attr::NoDeref:
2072 OS << "noderef";
2073 break;
2074 case attr::CFIUncheckedCallee:
2075 OS << "cfi_unchecked_callee";
2076 break;
2077 case attr::AcquireHandle:
2078 OS << "acquire_handle";
2079 break;
2080 case attr::ArmMveStrictPolymorphism:
2081 OS << "__clang_arm_mve_strict_polymorphism";
2082 break;
2083 case attr::ExtVectorType:
2084 OS << "ext_vector_type";
2085 break;
2086 case attr::CFISalt:
2087 OS << "cfi_salt(\"" << cast<CFISaltAttr>(T->getAttr())->getSalt() << "\")";
2088 break;
2089 }
2090 OS << "))";
2091}
2092
2093void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T,
2094 raw_ostream &OS) {
2095 printBefore(T->getWrappedType(), OS);
2096 OS << " __attribute__((btf_type_tag(\"" << T->getAttr()->getBTFTypeTag() << "\")))";
2097}
2098
2099void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,
2100 raw_ostream &OS) {
2101 printAfter(T->getWrappedType(), OS);
2102}
2103
2104void TypePrinter::printHLSLAttributedResourceBefore(
2105 const HLSLAttributedResourceType *T, raw_ostream &OS) {
2106 printBefore(T->getWrappedType(), OS);
2107}
2108
2109void TypePrinter::printHLSLAttributedResourceAfter(
2110 const HLSLAttributedResourceType *T, raw_ostream &OS) {
2111 printAfter(T->getWrappedType(), OS);
2112 const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs();
2113 OS << " [[hlsl::resource_class("
2114 << HLSLResourceClassAttr::ConvertResourceClassToStr(Attrs.ResourceClass)
2115 << ")]]";
2116 if (Attrs.IsROV)
2117 OS << " [[hlsl::is_rov]]";
2118 if (Attrs.RawBuffer)
2119 OS << " [[hlsl::raw_buffer]]";
2120 if (Attrs.IsCounter)
2121 OS << " [[hlsl::is_counter]]";
2122
2123 QualType ContainedTy = T->getContainedType();
2124 if (!ContainedTy.isNull()) {
2125 OS << " [[hlsl::contained_type(";
2126 printBefore(ContainedTy, OS);
2127 printAfter(ContainedTy, OS);
2128 OS << ")]]";
2129 }
2130}
2131
2132void TypePrinter::printHLSLInlineSpirvBefore(const HLSLInlineSpirvType *T,
2133 raw_ostream &OS) {
2134 OS << "__hlsl_spirv_type<" << T->getOpcode();
2135
2136 OS << ", " << T->getSize();
2137 OS << ", " << T->getAlignment();
2138
2139 for (auto &Operand : T->getOperands()) {
2140 using SpirvOperandKind = SpirvOperand::SpirvOperandKind;
2141
2142 OS << ", ";
2143 switch (Operand.getKind()) {
2144 case SpirvOperandKind::ConstantId: {
2145 QualType ConstantType = Operand.getResultType();
2146 OS << "vk::integral_constant<";
2147 printBefore(ConstantType, OS);
2148 printAfter(ConstantType, OS);
2149 OS << ", ";
2150 OS << Operand.getValue();
2151 OS << ">";
2152 break;
2153 }
2154 case SpirvOperandKind::Literal:
2155 OS << "vk::Literal<vk::integral_constant<uint, ";
2156 OS << Operand.getValue();
2157 OS << ">>";
2158 break;
2159 case SpirvOperandKind::TypeId: {
2160 QualType Type = Operand.getResultType();
2161 printBefore(Type, OS);
2162 printAfter(Type, OS);
2163 break;
2164 }
2165 default:
2166 llvm_unreachable("Invalid SpirvOperand kind!");
2167 break;
2168 }
2169 }
2170
2171 OS << ">";
2172}
2173
2174void TypePrinter::printHLSLInlineSpirvAfter(const HLSLInlineSpirvType *T,
2175 raw_ostream &OS) {
2176 // nothing to do
2177}
2178
2179void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
2180 raw_ostream &OS) {
2181 OS << T->getDecl()->getName();
2182 spaceBeforePlaceHolder(OS);
2183}
2184
2185void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
2186 raw_ostream &OS) {}
2187
2188void TypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType *T,
2189 raw_ostream &OS) {
2190 OS << T->getDecl()->getName();
2191 if (!T->qual_empty()) {
2192 bool isFirst = true;
2193 OS << '<';
2194 for (const auto *I : T->quals()) {
2195 if (isFirst)
2196 isFirst = false;
2197 else
2198 OS << ',';
2199 OS << I->getName();
2200 }
2201 OS << '>';
2202 }
2203
2204 spaceBeforePlaceHolder(OS);
2205}
2206
2207void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T,
2208 raw_ostream &OS) {}
2209
2210void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
2211 raw_ostream &OS) {
2212 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2213 !T->isKindOfTypeAsWritten())
2214 return printBefore(T->getBaseType(), OS);
2215
2216 if (T->isKindOfTypeAsWritten())
2217 OS << "__kindof ";
2218
2219 print(T->getBaseType(), OS, StringRef());
2220
2221 if (T->isSpecializedAsWritten()) {
2222 bool isFirst = true;
2223 OS << '<';
2224 for (auto typeArg : T->getTypeArgsAsWritten()) {
2225 if (isFirst)
2226 isFirst = false;
2227 else
2228 OS << ",";
2229
2230 print(typeArg, OS, StringRef());
2231 }
2232 OS << '>';
2233 }
2234
2235 if (!T->qual_empty()) {
2236 bool isFirst = true;
2237 OS << '<';
2238 for (const auto *I : T->quals()) {
2239 if (isFirst)
2240 isFirst = false;
2241 else
2242 OS << ',';
2243 OS << I->getName();
2244 }
2245 OS << '>';
2246 }
2247
2248 spaceBeforePlaceHolder(OS);
2249}
2250
2251void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
2252 raw_ostream &OS) {
2253 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2254 !T->isKindOfTypeAsWritten())
2255 return printAfter(T->getBaseType(), OS);
2256}
2257
2258void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
2259 raw_ostream &OS) {
2260 printBefore(T->getPointeeType(), OS);
2261
2262 // If we need to print the pointer, print it now.
2263 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&
2265 if (HasEmptyPlaceHolder)
2266 OS << ' ';
2267 OS << '*';
2268 }
2269}
2270
2271void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
2272 raw_ostream &OS) {}
2273
2274static
2275const TemplateArgument &getArgument(const TemplateArgument &A) { return A; }
2276
2278 return A.getArgument();
2279}
2280
2281static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP,
2282 llvm::raw_ostream &OS, bool IncludeType) {
2283 A.print(PP, OS, IncludeType);
2284}
2285
2287 const PrintingPolicy &PP, llvm::raw_ostream &OS,
2288 bool IncludeType) {
2289 const TemplateArgument::ArgKind &Kind = A.getArgument().getKind();
2291 return A.getTypeSourceInfo()->getType().print(OS, PP);
2292 return A.getArgument().print(PP, OS, IncludeType);
2293}
2294
2295static bool isSubstitutedTemplateArgument(ASTContext &Ctx, TemplateArgument Arg,
2296 TemplateArgument Pattern,
2297 ArrayRef<TemplateArgument> Args,
2298 unsigned Depth);
2299
2301 ArrayRef<TemplateArgument> Args, unsigned Depth) {
2302 if (Ctx.hasSameType(T, Pattern))
2303 return true;
2304
2305 // A type parameter matches its argument.
2306 if (auto *TTPT = Pattern->getAsCanonical<TemplateTypeParmType>()) {
2307 if (TTPT->getDepth() == Depth && TTPT->getIndex() < Args.size() &&
2308 Args[TTPT->getIndex()].getKind() == TemplateArgument::Type) {
2309 QualType SubstArg = Ctx.getQualifiedType(
2310 Args[TTPT->getIndex()].getAsType(), Pattern.getQualifiers());
2311 return Ctx.hasSameType(SubstArg, T);
2312 }
2313 return false;
2314 }
2315
2316 // FIXME: Recurse into array types.
2317
2318 // All other cases will need the types to be identically qualified.
2319 Qualifiers TQual, PatQual;
2320 T = Ctx.getUnqualifiedArrayType(T, TQual);
2321 Pattern = Ctx.getUnqualifiedArrayType(Pattern, PatQual);
2322 if (TQual != PatQual)
2323 return false;
2324
2325 // Recurse into pointer-like types.
2326 {
2327 QualType TPointee = T->getPointeeType();
2328 QualType PPointee = Pattern->getPointeeType();
2329 if (!TPointee.isNull() && !PPointee.isNull())
2330 return T->getTypeClass() == Pattern->getTypeClass() &&
2331 isSubstitutedType(Ctx, TPointee, PPointee, Args, Depth);
2332 }
2333
2334 // Recurse into template specialization types.
2335 if (auto *PTST =
2336 Pattern.getCanonicalType()->getAs<TemplateSpecializationType>()) {
2338 ArrayRef<TemplateArgument> TemplateArgs;
2339 if (auto *TTST = T->getAs<TemplateSpecializationType>()) {
2340 Template = TTST->getTemplateName();
2341 TemplateArgs = TTST->template_arguments();
2342 } else if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
2343 T->getAsCXXRecordDecl())) {
2344 Template = TemplateName(CTSD->getSpecializedTemplate());
2345 TemplateArgs = CTSD->getTemplateArgs().asArray();
2346 } else {
2347 return false;
2348 }
2349
2350 if (!isSubstitutedTemplateArgument(Ctx, Template, PTST->getTemplateName(),
2351 Args, Depth))
2352 return false;
2353 if (TemplateArgs.size() != PTST->template_arguments().size())
2354 return false;
2355 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
2357 Ctx, TemplateArgs[I], PTST->template_arguments()[I], Args, Depth))
2358 return false;
2359 return true;
2360 }
2361
2362 // FIXME: Handle more cases.
2363 return false;
2364}
2365
2366/// Evaluates the expression template argument 'Pattern' and returns true
2367/// if 'Arg' evaluates to the same result.
2369 TemplateArgument const &Pattern,
2370 TemplateArgument const &Arg) {
2371 if (Pattern.getKind() != TemplateArgument::Expression)
2372 return false;
2373
2374 // Can't evaluate value-dependent expressions so bail early
2375 Expr const *pattern_expr = Pattern.getAsExpr();
2376 if (pattern_expr->isValueDependent() ||
2377 !pattern_expr->isIntegerConstantExpr(Ctx))
2378 return false;
2379
2381 return llvm::APSInt::isSameValue(pattern_expr->EvaluateKnownConstInt(Ctx),
2382 Arg.getAsIntegral());
2383
2385 Expr const *args_expr = Arg.getAsExpr();
2386 if (args_expr->isValueDependent() || !args_expr->isIntegerConstantExpr(Ctx))
2387 return false;
2388
2389 return llvm::APSInt::isSameValue(args_expr->EvaluateKnownConstInt(Ctx),
2390 pattern_expr->EvaluateKnownConstInt(Ctx));
2391 }
2392
2393 return false;
2394}
2395
2397 TemplateArgument Pattern,
2399 unsigned Depth) {
2400 Arg = Ctx.getCanonicalTemplateArgument(Arg);
2401 Pattern = Ctx.getCanonicalTemplateArgument(Pattern);
2402 if (Arg.structurallyEquals(Pattern))
2403 return true;
2404
2405 if (Pattern.getKind() == TemplateArgument::Expression) {
2406 if (auto *DRE =
2407 dyn_cast<DeclRefExpr>(Pattern.getAsExpr()->IgnoreParenImpCasts())) {
2408 if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
2409 return NTTP->getDepth() == Depth && Args.size() > NTTP->getIndex() &&
2410 Args[NTTP->getIndex()].structurallyEquals(Arg);
2411 }
2412 }
2413
2414 if (templateArgumentExpressionsEqual(Ctx, Pattern, Arg))
2415 return true;
2416
2417 if (Arg.getKind() != Pattern.getKind())
2418 return false;
2419
2420 if (Arg.getKind() == TemplateArgument::Type)
2421 return isSubstitutedType(Ctx, Arg.getAsType(), Pattern.getAsType(), Args,
2422 Depth);
2423
2424 if (Arg.getKind() == TemplateArgument::Template) {
2425 TemplateDecl *PatTD = Pattern.getAsTemplate().getAsTemplateDecl();
2426 if (auto *TTPD = dyn_cast_or_null<TemplateTemplateParmDecl>(PatTD))
2427 return TTPD->getDepth() == Depth && Args.size() > TTPD->getIndex() &&
2428 Ctx.getCanonicalTemplateArgument(Args[TTPD->getIndex()])
2429 .structurallyEquals(Arg);
2430 }
2431
2432 // FIXME: Handle more cases.
2433 return false;
2434}
2435
2436bool clang::isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg,
2437 const NamedDecl *Param,
2438 ArrayRef<TemplateArgument> Args,
2439 unsigned Depth) {
2440 // An empty pack is equivalent to not providing a pack argument.
2441 if (Arg.getKind() == TemplateArgument::Pack && Arg.pack_size() == 0)
2442 return true;
2443
2444 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Param)) {
2445 return TTPD->hasDefaultArgument() &&
2447 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2448 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
2449 return TTPD->hasDefaultArgument() &&
2451 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2452 } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
2453 return NTTPD->hasDefaultArgument() &&
2455 Ctx, Arg, NTTPD->getDefaultArgument().getArgument(), Args,
2456 Depth);
2457 }
2458 return false;
2459}
2460
2461template <typename TA>
2462static void
2463printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy,
2464 const TemplateParameterList *TPL, bool IsPack, unsigned ParmIndex) {
2465 // Drop trailing template arguments that match default arguments.
2466 if (TPL && Policy.SuppressDefaultTemplateArgs && !Policy.PrintAsCanonical &&
2467 !Args.empty() && !IsPack && Args.size() <= TPL->size()) {
2469 for (const TA &A : Args)
2470 OrigArgs.push_back(getArgument(A));
2471 while (!Args.empty() && getArgument(Args.back()).getIsDefaulted())
2472 Args = Args.drop_back();
2473 }
2474
2475 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
2476 if (!IsPack)
2477 OS << '<';
2478
2479 bool NeedSpace = false;
2480 bool FirstArg = true;
2481 for (const auto &Arg : Args) {
2482 // Print the argument into a string.
2483 SmallString<128> Buf;
2484 llvm::raw_svector_ostream ArgOS(Buf);
2485 const TemplateArgument &Argument = getArgument(Arg);
2486 if (Argument.getKind() == TemplateArgument::Pack) {
2487 if (Argument.pack_size() && !FirstArg)
2488 OS << Comma;
2489 printTo(ArgOS, Argument.getPackAsArray(), Policy, TPL,
2490 /*IsPack*/ true, ParmIndex);
2491 } else {
2492 if (!FirstArg)
2493 OS << Comma;
2494 // Tries to print the argument with location info if exists.
2495 printArgument(Arg, Policy, ArgOS,
2497 Policy, TPL, ParmIndex));
2498 }
2499 StringRef ArgString = ArgOS.str();
2500
2501 // If this is the first argument and its string representation
2502 // begins with the global scope specifier ('::foo'), add a space
2503 // to avoid printing the diagraph '<:'.
2504 if (FirstArg && ArgString.starts_with(":"))
2505 OS << ' ';
2506
2507 OS << ArgString;
2508
2509 // If the last character of our string is '>', add another space to
2510 // keep the two '>''s separate tokens.
2511 if (!ArgString.empty()) {
2512 NeedSpace = Policy.SplitTemplateClosers && ArgString.back() == '>';
2513 FirstArg = false;
2514 }
2515
2516 // Use same template parameter for all elements of Pack
2517 if (!IsPack)
2518 ParmIndex++;
2519 }
2520
2521 if (!IsPack) {
2522 if (NeedSpace)
2523 OS << ' ';
2524 OS << '>';
2525 }
2526}
2527
2528void clang::printTemplateArgumentList(raw_ostream &OS,
2529 const TemplateArgumentListInfo &Args,
2530 const PrintingPolicy &Policy,
2531 const TemplateParameterList *TPL) {
2532 printTemplateArgumentList(OS, Args.arguments(), Policy, TPL);
2533}
2534
2535void clang::printTemplateArgumentList(raw_ostream &OS,
2536 ArrayRef<TemplateArgument> Args,
2537 const PrintingPolicy &Policy,
2538 const TemplateParameterList *TPL) {
2539 PrintingPolicy InnerPolicy = Policy;
2540 InnerPolicy.SuppressScope = false;
2541 printTo(OS, Args, InnerPolicy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2542}
2543
2544void clang::printTemplateArgumentList(raw_ostream &OS,
2545 ArrayRef<TemplateArgumentLoc> Args,
2546 const PrintingPolicy &Policy,
2547 const TemplateParameterList *TPL) {
2548 PrintingPolicy InnerPolicy = Policy;
2549 InnerPolicy.SuppressScope = false;
2550 printTo(OS, Args, InnerPolicy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2551}
2552
2554 LangOptions LO;
2555 return getAsString(PrintingPolicy(LO));
2556}
2557
2559 SmallString<64> Buf;
2560 llvm::raw_svector_ostream StrOS(Buf);
2561 print(StrOS, P);
2562 return StrOS.str().str();
2563}
2564
2566 return !isPresent();
2567}
2568
2569void PointerAuthQualifier::print(raw_ostream &OS,
2570 const PrintingPolicy &P) const {
2571 if (!isPresent())
2572 return;
2573
2574 OS << "__ptrauth(";
2575 OS << getKey();
2576 OS << "," << unsigned(isAddressDiscriminated()) << ","
2577 << getExtraDiscriminator() << ")";
2578}
2579
2580std::string Qualifiers::getAsString() const {
2581 LangOptions LO;
2582 return getAsString(PrintingPolicy(LO));
2583}
2584
2585// Appends qualifiers to the given string, separated by spaces. Will
2586// prefix a space if the string is non-empty. Will not append a final
2587// space.
2588std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {
2589 SmallString<64> Buf;
2590 llvm::raw_svector_ostream StrOS(Buf);
2591 print(StrOS, Policy);
2592 return std::string(StrOS.str());
2593}
2594
2596 if (getCVRQualifiers())
2597 return false;
2598
2600 return false;
2601
2602 if (getObjCGCAttr())
2603 return false;
2604
2606 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
2607 return false;
2608
2609 if (PointerAuthQualifier PointerAuth = getPointerAuth();
2610 PointerAuth && !PointerAuth.isEmptyWhenPrinted(Policy))
2611 return false;
2612
2613 return true;
2614}
2615
2617 switch (AS) {
2618 case LangAS::Default:
2619 return "";
2622 return "__global";
2624 case LangAS::sycl_local:
2625 return "__local";
2628 return "__private";
2630 return "__constant";
2632 return "__generic";
2635 return "__global_device";
2638 return "__global_host";
2640 return "__device__";
2642 return "__constant__";
2644 return "__shared__";
2645 case LangAS::ptr32_sptr:
2646 return "__sptr __ptr32";
2647 case LangAS::ptr32_uptr:
2648 return "__uptr __ptr32";
2649 case LangAS::ptr64:
2650 return "__ptr64";
2652 return "groupshared";
2654 return "hlsl_constant";
2656 return "hlsl_private";
2658 return "hlsl_device";
2659 case LangAS::hlsl_input:
2660 return "hlsl_input";
2662 return "hlsl_push_constant";
2664 return "__funcref";
2665 default:
2666 return std::to_string(toTargetAddressSpace(AS));
2667 }
2668}
2669
2670// Appends qualifiers to the given string, separated by spaces. Will
2671// prefix a space if the string is non-empty. Will not append a final
2672// space.
2673void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
2674 bool appendSpaceIfNonEmpty) const {
2675 bool addSpace = false;
2676
2677 unsigned quals = getCVRQualifiers();
2678 if (quals) {
2679 AppendTypeQualList(OS, quals, Policy.Restrict);
2680 addSpace = true;
2681 }
2682 if (hasUnaligned()) {
2683 if (addSpace)
2684 OS << ' ';
2685 OS << "__unaligned";
2686 addSpace = true;
2687 }
2688 auto ASStr = getAddrSpaceAsString(getAddressSpace());
2689 if (!ASStr.empty()) {
2690 if (addSpace)
2691 OS << ' ';
2692 addSpace = true;
2693 // Wrap target address space into an attribute syntax
2695 OS << "__attribute__((address_space(" << ASStr << ")))";
2696 else
2697 OS << ASStr;
2698 }
2699
2700 if (Qualifiers::GC gc = getObjCGCAttr()) {
2701 if (addSpace)
2702 OS << ' ';
2703 addSpace = true;
2704 if (gc == Qualifiers::Weak)
2705 OS << "__weak";
2706 else
2707 OS << "__strong";
2708 }
2709 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
2710 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
2711 if (addSpace)
2712 OS << ' ';
2713 addSpace = true;
2714 }
2715
2716 switch (lifetime) {
2717 case Qualifiers::OCL_None: llvm_unreachable("none but true");
2718 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;
2720 if (!Policy.SuppressStrongLifetime)
2721 OS << "__strong";
2722 break;
2723
2724 case Qualifiers::OCL_Weak: OS << "__weak"; break;
2725 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
2726 }
2727 }
2728
2729 if (PointerAuthQualifier PointerAuth = getPointerAuth()) {
2730 if (addSpace)
2731 OS << ' ';
2732 addSpace = true;
2733
2734 PointerAuth.print(OS, Policy);
2735 }
2736
2737 if (appendSpaceIfNonEmpty && addSpace)
2738 OS << ' ';
2739}
2740
2741std::string QualType::getAsString() const {
2742 return getAsString(split(), LangOptions());
2743}
2744
2745std::string QualType::getAsString(const PrintingPolicy &Policy) const {
2746 std::string S;
2747 getAsStringInternal(S, Policy);
2748 return S;
2749}
2750
2751std::string QualType::getAsString(const Type *ty, Qualifiers qs,
2752 const PrintingPolicy &Policy) {
2753 std::string buffer;
2754 getAsStringInternal(ty, qs, buffer, Policy);
2755 return buffer;
2756}
2757
2758void QualType::print(raw_ostream &OS, const PrintingPolicy &Policy,
2759 const Twine &PlaceHolder, unsigned Indentation) const {
2760 print(splitAccordingToPolicy(*this, Policy), OS, Policy, PlaceHolder,
2761 Indentation);
2762}
2763
2765 raw_ostream &OS, const PrintingPolicy &policy,
2766 const Twine &PlaceHolder, unsigned Indentation) {
2767 SmallString<128> PHBuf;
2768 StringRef PH = PlaceHolder.toStringRef(PHBuf);
2769
2770 TypePrinter(policy, Indentation).print(ty, qs, OS, PH);
2771}
2772
2773void QualType::getAsStringInternal(std::string &Str,
2774 const PrintingPolicy &Policy) const {
2775 return getAsStringInternal(splitAccordingToPolicy(*this, Policy), Str,
2776 Policy);
2777}
2778
2780 std::string &buffer,
2781 const PrintingPolicy &policy) {
2782 SmallString<256> Buf;
2783 llvm::raw_svector_ostream StrOS(Buf);
2784 TypePrinter(policy).print(ty, qs, StrOS, buffer);
2785 std::string str = std::string(StrOS.str());
2786 buffer.swap(str);
2787}
2788
2789raw_ostream &clang::operator<<(raw_ostream &OS, QualType QT) {
2790 SplitQualType S = QT.split();
2791 TypePrinter(LangOptions()).print(S.Ty, S.Quals, OS, /*PlaceHolder=*/"");
2792 return OS;
2793}
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:8332
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:8344
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
Definition TypeBase.h:8313
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:8274
The base class of the type hierarchy.
Definition TypeBase.h:1833
bool isArrayType() const
Definition TypeBase.h:8628
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:9178
bool isObjCQualifiedIdType() const
Definition TypeBase.h:8725
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:8737
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:8525
bool isObjCQualifiedClassType() const
Definition TypeBase.h:8731
bool isObjCClassType() const
Definition TypeBase.h:8743
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:9111
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:561
@ Type
The name was classified as a type.
Definition Sema.h:563
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