clang 20.0.0git
TypePrinter.cpp
Go to the documentation of this file.
1//===- TypePrinter.cpp - Pretty-Print Clang Types -------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This contains code to print types from Clang's type system.
10//
11//===----------------------------------------------------------------------===//
12
14#include "clang/AST/Attr.h"
15#include "clang/AST/Decl.h"
16#include "clang/AST/DeclBase.h"
17#include "clang/AST/DeclCXX.h"
18#include "clang/AST/DeclObjC.h"
20#include "clang/AST/Expr.h"
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) {
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 AppendScope(DeclContext *DC, raw_ostream &OS,
135 DeclarationName NameInScope);
136 void printTag(TagDecl *T, raw_ostream &OS);
137 void printFunctionAfter(const FunctionType::ExtInfo &Info, raw_ostream &OS);
138#define ABSTRACT_TYPE(CLASS, PARENT)
139#define TYPE(CLASS, PARENT) \
140 void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS); \
141 void print##CLASS##After(const CLASS##Type *T, raw_ostream &OS);
142#include "clang/AST/TypeNodes.inc"
143
144private:
145 void printBefore(const Type *ty, Qualifiers qs, raw_ostream &OS);
146 void printAfter(const Type *ty, Qualifiers qs, raw_ostream &OS);
147};
148
149} // namespace
150
151static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals,
152 bool HasRestrictKeyword) {
153 bool appendSpace = false;
154 if (TypeQuals & Qualifiers::Const) {
155 OS << "const";
156 appendSpace = true;
157 }
158 if (TypeQuals & Qualifiers::Volatile) {
159 if (appendSpace) OS << ' ';
160 OS << "volatile";
161 appendSpace = true;
162 }
163 if (TypeQuals & Qualifiers::Restrict) {
164 if (appendSpace) OS << ' ';
165 if (HasRestrictKeyword) {
166 OS << "restrict";
167 } else {
168 OS << "__restrict";
169 }
170 }
171}
172
173void TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) {
174 if (!HasEmptyPlaceHolder)
175 OS << ' ';
176}
177
179 const PrintingPolicy &Policy) {
180 if (Policy.PrintCanonicalTypes)
181 QT = QT.getCanonicalType();
182 return QT.split();
183}
184
185void TypePrinter::print(QualType t, raw_ostream &OS, StringRef PlaceHolder) {
186 SplitQualType split = splitAccordingToPolicy(t, Policy);
187 print(split.Ty, split.Quals, OS, PlaceHolder);
188}
189
190void TypePrinter::print(const Type *T, Qualifiers Quals, raw_ostream &OS,
191 StringRef PlaceHolder) {
192 if (!T) {
193 OS << "NULL TYPE";
194 return;
195 }
196
197 SaveAndRestore PHVal(HasEmptyPlaceHolder, PlaceHolder.empty());
198
199 printBefore(T, Quals, OS);
200 OS << PlaceHolder;
201 printAfter(T, Quals, OS);
202}
203
204bool TypePrinter::canPrefixQualifiers(const Type *T,
205 bool &NeedARCStrongQualifier) {
206 // CanPrefixQualifiers - We prefer to print type qualifiers before the type,
207 // so that we get "const int" instead of "int const", but we can't do this if
208 // the type is complex. For example if the type is "int*", we *must* print
209 // "int * const", printing "const int *" is different. Only do this when the
210 // type expands to a simple string.
211 bool CanPrefixQualifiers = false;
212 NeedARCStrongQualifier = false;
213 const Type *UnderlyingType = T;
214 if (const auto *AT = dyn_cast<AutoType>(T))
215 UnderlyingType = AT->desugar().getTypePtr();
216 if (const auto *Subst = dyn_cast<SubstTemplateTypeParmType>(T))
217 UnderlyingType = Subst->getReplacementType().getTypePtr();
218 Type::TypeClass TC = UnderlyingType->getTypeClass();
219
220 switch (TC) {
221 case Type::Auto:
222 case Type::Builtin:
223 case Type::Complex:
224 case Type::UnresolvedUsing:
225 case Type::Using:
226 case Type::Typedef:
227 case Type::TypeOfExpr:
228 case Type::TypeOf:
229 case Type::Decltype:
230 case Type::UnaryTransform:
231 case Type::Record:
232 case Type::Enum:
233 case Type::Elaborated:
234 case Type::TemplateTypeParm:
235 case Type::SubstTemplateTypeParmPack:
236 case Type::DeducedTemplateSpecialization:
237 case Type::TemplateSpecialization:
238 case Type::InjectedClassName:
239 case Type::DependentName:
240 case Type::DependentTemplateSpecialization:
241 case Type::ObjCObject:
242 case Type::ObjCTypeParam:
243 case Type::ObjCInterface:
244 case Type::Atomic:
245 case Type::Pipe:
246 case Type::BitInt:
247 case Type::DependentBitInt:
248 case Type::BTFTagAttributed:
249 case Type::HLSLAttributedResource:
250 CanPrefixQualifiers = true;
251 break;
252
253 case Type::ObjCObjectPointer:
254 CanPrefixQualifiers = T->isObjCIdType() || T->isObjCClassType() ||
256 break;
257
258 case Type::VariableArray:
259 case Type::DependentSizedArray:
260 NeedARCStrongQualifier = true;
261 [[fallthrough]];
262
263 case Type::ConstantArray:
264 case Type::IncompleteArray:
265 return canPrefixQualifiers(
266 cast<ArrayType>(UnderlyingType)->getElementType().getTypePtr(),
267 NeedARCStrongQualifier);
268
269 case Type::Adjusted:
270 case Type::Decayed:
271 case Type::ArrayParameter:
272 case Type::Pointer:
273 case Type::BlockPointer:
274 case Type::LValueReference:
275 case Type::RValueReference:
276 case Type::MemberPointer:
277 case Type::DependentAddressSpace:
278 case Type::DependentVector:
279 case Type::DependentSizedExtVector:
280 case Type::Vector:
281 case Type::ExtVector:
282 case Type::ConstantMatrix:
283 case Type::DependentSizedMatrix:
284 case Type::FunctionProto:
285 case Type::FunctionNoProto:
286 case Type::Paren:
287 case Type::PackExpansion:
288 case Type::SubstTemplateTypeParm:
289 case Type::MacroQualified:
290 case Type::CountAttributed:
291 CanPrefixQualifiers = false;
292 break;
293
294 case Type::Attributed: {
295 // We still want to print the address_space before the type if it is an
296 // address_space attribute.
297 const auto *AttrTy = cast<AttributedType>(UnderlyingType);
298 CanPrefixQualifiers = AttrTy->getAttrKind() == attr::AddressSpace;
299 break;
300 }
301 case Type::PackIndexing: {
302 return canPrefixQualifiers(
303 cast<PackIndexingType>(UnderlyingType)->getPattern().getTypePtr(),
304 NeedARCStrongQualifier);
305 }
306 }
307
308 return CanPrefixQualifiers;
309}
310
311void TypePrinter::printBefore(QualType T, raw_ostream &OS) {
313
314 // If we have cv1 T, where T is substituted for cv2 U, only print cv1 - cv2
315 // at this level.
316 Qualifiers Quals = Split.Quals;
317 if (const auto *Subst = dyn_cast<SubstTemplateTypeParmType>(Split.Ty))
318 Quals -= QualType(Subst, 0).getQualifiers();
319
320 printBefore(Split.Ty, Quals, OS);
321}
322
323/// Prints the part of the type string before an identifier, e.g. for
324/// "int foo[10]" it prints "int ".
325void TypePrinter::printBefore(const Type *T,Qualifiers Quals, raw_ostream &OS) {
326 if (Policy.SuppressSpecifiers && T->isSpecifierType())
327 return;
328
329 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder);
330
331 // Print qualifiers as appropriate.
332
333 bool CanPrefixQualifiers = false;
334 bool NeedARCStrongQualifier = false;
335 CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier);
336
337 if (CanPrefixQualifiers && !Quals.empty()) {
338 if (NeedARCStrongQualifier) {
339 IncludeStrongLifetimeRAII Strong(Policy);
340 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
341 } else {
342 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
343 }
344 }
345
346 bool hasAfterQuals = false;
347 if (!CanPrefixQualifiers && !Quals.empty()) {
348 hasAfterQuals = !Quals.isEmptyWhenPrinted(Policy);
349 if (hasAfterQuals)
350 HasEmptyPlaceHolder = false;
351 }
352
353 switch (T->getTypeClass()) {
354#define ABSTRACT_TYPE(CLASS, PARENT)
355#define TYPE(CLASS, PARENT) case Type::CLASS: \
356 print##CLASS##Before(cast<CLASS##Type>(T), OS); \
357 break;
358#include "clang/AST/TypeNodes.inc"
359 }
360
361 if (hasAfterQuals) {
362 if (NeedARCStrongQualifier) {
363 IncludeStrongLifetimeRAII Strong(Policy);
364 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
365 } else {
366 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
367 }
368 }
369}
370
371void TypePrinter::printAfter(QualType t, raw_ostream &OS) {
372 SplitQualType split = splitAccordingToPolicy(t, Policy);
373 printAfter(split.Ty, split.Quals, OS);
374}
375
376/// Prints the part of the type string after an identifier, e.g. for
377/// "int foo[10]" it prints "[10]".
378void TypePrinter::printAfter(const Type *T, Qualifiers Quals, raw_ostream &OS) {
379 switch (T->getTypeClass()) {
380#define ABSTRACT_TYPE(CLASS, PARENT)
381#define TYPE(CLASS, PARENT) case Type::CLASS: \
382 print##CLASS##After(cast<CLASS##Type>(T), OS); \
383 break;
384#include "clang/AST/TypeNodes.inc"
385 }
386}
387
388void TypePrinter::printBuiltinBefore(const BuiltinType *T, raw_ostream &OS) {
389 OS << T->getName(Policy);
390 spaceBeforePlaceHolder(OS);
391}
392
393void TypePrinter::printBuiltinAfter(const BuiltinType *T, raw_ostream &OS) {}
394
395void TypePrinter::printComplexBefore(const ComplexType *T, raw_ostream &OS) {
396 OS << "_Complex ";
397 printBefore(T->getElementType(), OS);
398}
399
400void TypePrinter::printComplexAfter(const ComplexType *T, raw_ostream &OS) {
401 printAfter(T->getElementType(), OS);
402}
403
404void TypePrinter::printPointerBefore(const PointerType *T, raw_ostream &OS) {
405 IncludeStrongLifetimeRAII Strong(Policy);
406 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
407 printBefore(T->getPointeeType(), OS);
408 // Handle things like 'int (*A)[4];' correctly.
409 // FIXME: this should include vectors, but vectors use attributes I guess.
410 if (isa<ArrayType>(T->getPointeeType()))
411 OS << '(';
412 OS << '*';
413}
414
415void TypePrinter::printPointerAfter(const PointerType *T, raw_ostream &OS) {
416 IncludeStrongLifetimeRAII Strong(Policy);
417 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
418 // Handle things like 'int (*A)[4];' correctly.
419 // FIXME: this should include vectors, but vectors use attributes I guess.
420 if (isa<ArrayType>(T->getPointeeType()))
421 OS << ')';
422 printAfter(T->getPointeeType(), OS);
423}
424
425void TypePrinter::printBlockPointerBefore(const BlockPointerType *T,
426 raw_ostream &OS) {
427 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
428 printBefore(T->getPointeeType(), OS);
429 OS << '^';
430}
431
432void TypePrinter::printBlockPointerAfter(const BlockPointerType *T,
433 raw_ostream &OS) {
434 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
435 printAfter(T->getPointeeType(), OS);
436}
437
438// When printing a reference, the referenced type might also be a reference.
439// If so, we want to skip that before printing the inner type.
441 if (auto *Ref = T->getAs<ReferenceType>())
442 return skipTopLevelReferences(Ref->getPointeeTypeAsWritten());
443 return T;
444}
445
446void TypePrinter::printLValueReferenceBefore(const LValueReferenceType *T,
447 raw_ostream &OS) {
448 IncludeStrongLifetimeRAII Strong(Policy);
449 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
450 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
451 printBefore(Inner, OS);
452 // Handle things like 'int (&A)[4];' correctly.
453 // FIXME: this should include vectors, but vectors use attributes I guess.
454 if (isa<ArrayType>(Inner))
455 OS << '(';
456 OS << '&';
457}
458
459void TypePrinter::printLValueReferenceAfter(const LValueReferenceType *T,
460 raw_ostream &OS) {
461 IncludeStrongLifetimeRAII Strong(Policy);
462 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
463 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
464 // Handle things like 'int (&A)[4];' correctly.
465 // FIXME: this should include vectors, but vectors use attributes I guess.
466 if (isa<ArrayType>(Inner))
467 OS << ')';
468 printAfter(Inner, OS);
469}
470
471void TypePrinter::printRValueReferenceBefore(const RValueReferenceType *T,
472 raw_ostream &OS) {
473 IncludeStrongLifetimeRAII Strong(Policy);
474 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
475 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
476 printBefore(Inner, OS);
477 // Handle things like 'int (&&A)[4];' correctly.
478 // FIXME: this should include vectors, but vectors use attributes I guess.
479 if (isa<ArrayType>(Inner))
480 OS << '(';
481 OS << "&&";
482}
483
484void TypePrinter::printRValueReferenceAfter(const RValueReferenceType *T,
485 raw_ostream &OS) {
486 IncludeStrongLifetimeRAII Strong(Policy);
487 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
488 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
489 // Handle things like 'int (&&A)[4];' correctly.
490 // FIXME: this should include vectors, but vectors use attributes I guess.
491 if (isa<ArrayType>(Inner))
492 OS << ')';
493 printAfter(Inner, OS);
494}
495
496void TypePrinter::printMemberPointerBefore(const MemberPointerType *T,
497 raw_ostream &OS) {
498 IncludeStrongLifetimeRAII Strong(Policy);
499 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
500 printBefore(T->getPointeeType(), OS);
501 // Handle things like 'int (Cls::*A)[4];' correctly.
502 // FIXME: this should include vectors, but vectors use attributes I guess.
503 if (isa<ArrayType>(T->getPointeeType()))
504 OS << '(';
505
506 PrintingPolicy InnerPolicy(Policy);
507 InnerPolicy.IncludeTagDefinition = false;
508 TypePrinter(InnerPolicy).print(QualType(T->getClass(), 0), OS, StringRef());
509
510 OS << "::*";
511}
512
513void TypePrinter::printMemberPointerAfter(const MemberPointerType *T,
514 raw_ostream &OS) {
515 IncludeStrongLifetimeRAII Strong(Policy);
516 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
517 // Handle things like 'int (Cls::*A)[4];' correctly.
518 // FIXME: this should include vectors, but vectors use attributes I guess.
519 if (isa<ArrayType>(T->getPointeeType()))
520 OS << ')';
521 printAfter(T->getPointeeType(), OS);
522}
523
524void TypePrinter::printConstantArrayBefore(const ConstantArrayType *T,
525 raw_ostream &OS) {
526 IncludeStrongLifetimeRAII Strong(Policy);
527 printBefore(T->getElementType(), OS);
528}
529
530void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T,
531 raw_ostream &OS) {
532 OS << '[';
533 if (T->getIndexTypeQualifiers().hasQualifiers()) {
534 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(),
535 Policy.Restrict);
536 OS << ' ';
537 }
538
539 if (T->getSizeModifier() == ArraySizeModifier::Static)
540 OS << "static ";
541
542 OS << T->getZExtSize() << ']';
543 printAfter(T->getElementType(), OS);
544}
545
546void TypePrinter::printIncompleteArrayBefore(const IncompleteArrayType *T,
547 raw_ostream &OS) {
548 IncludeStrongLifetimeRAII Strong(Policy);
549 printBefore(T->getElementType(), OS);
550}
551
552void TypePrinter::printIncompleteArrayAfter(const IncompleteArrayType *T,
553 raw_ostream &OS) {
554 OS << "[]";
555 printAfter(T->getElementType(), OS);
556}
557
558void TypePrinter::printVariableArrayBefore(const VariableArrayType *T,
559 raw_ostream &OS) {
560 IncludeStrongLifetimeRAII Strong(Policy);
561 printBefore(T->getElementType(), OS);
562}
563
564void TypePrinter::printVariableArrayAfter(const VariableArrayType *T,
565 raw_ostream &OS) {
566 OS << '[';
567 if (T->getIndexTypeQualifiers().hasQualifiers()) {
568 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.Restrict);
569 OS << ' ';
570 }
571
572 if (T->getSizeModifier() == ArraySizeModifier::Static)
573 OS << "static ";
574 else if (T->getSizeModifier() == ArraySizeModifier::Star)
575 OS << '*';
576
577 if (T->getSizeExpr())
578 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
579 OS << ']';
580
581 printAfter(T->getElementType(), OS);
582}
583
584void TypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream &OS) {
585 // Print the adjusted representation, otherwise the adjustment will be
586 // invisible.
587 printBefore(T->getAdjustedType(), OS);
588}
589
590void TypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) {
591 printAfter(T->getAdjustedType(), OS);
592}
593
594void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {
595 // Print as though it's a pointer.
596 printAdjustedBefore(T, OS);
597}
598
599void TypePrinter::printArrayParameterAfter(const ArrayParameterType *T,
600 raw_ostream &OS) {
601 printConstantArrayAfter(T, OS);
602}
603
604void TypePrinter::printArrayParameterBefore(const ArrayParameterType *T,
605 raw_ostream &OS) {
606 printConstantArrayBefore(T, OS);
607}
608
609void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {
610 printAdjustedAfter(T, OS);
611}
612
613void TypePrinter::printDependentSizedArrayBefore(
615 raw_ostream &OS) {
616 IncludeStrongLifetimeRAII Strong(Policy);
617 printBefore(T->getElementType(), OS);
618}
619
620void TypePrinter::printDependentSizedArrayAfter(
622 raw_ostream &OS) {
623 OS << '[';
624 if (T->getSizeExpr())
625 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
626 OS << ']';
627 printAfter(T->getElementType(), OS);
628}
629
630void TypePrinter::printDependentAddressSpaceBefore(
631 const DependentAddressSpaceType *T, raw_ostream &OS) {
632 printBefore(T->getPointeeType(), OS);
633}
634
635void TypePrinter::printDependentAddressSpaceAfter(
636 const DependentAddressSpaceType *T, raw_ostream &OS) {
637 OS << " __attribute__((address_space(";
638 if (T->getAddrSpaceExpr())
639 T->getAddrSpaceExpr()->printPretty(OS, nullptr, Policy);
640 OS << ")))";
641 printAfter(T->getPointeeType(), OS);
642}
643
644void TypePrinter::printDependentSizedExtVectorBefore(
646 raw_ostream &OS) {
647 if (Policy.UseHLSLTypes)
648 OS << "vector<";
649 printBefore(T->getElementType(), OS);
650}
651
652void TypePrinter::printDependentSizedExtVectorAfter(
654 raw_ostream &OS) {
655 if (Policy.UseHLSLTypes) {
656 OS << ", ";
657 if (T->getSizeExpr())
658 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
659 OS << ">";
660 } else {
661 OS << " __attribute__((ext_vector_type(";
662 if (T->getSizeExpr())
663 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
664 OS << ")))";
665 }
666 printAfter(T->getElementType(), OS);
667}
668
669void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {
670 switch (T->getVectorKind()) {
671 case VectorKind::AltiVecPixel:
672 OS << "__vector __pixel ";
673 break;
674 case VectorKind::AltiVecBool:
675 OS << "__vector __bool ";
676 printBefore(T->getElementType(), OS);
677 break;
678 case VectorKind::AltiVecVector:
679 OS << "__vector ";
680 printBefore(T->getElementType(), OS);
681 break;
682 case VectorKind::Neon:
683 OS << "__attribute__((neon_vector_type("
684 << T->getNumElements() << "))) ";
685 printBefore(T->getElementType(), OS);
686 break;
687 case VectorKind::NeonPoly:
688 OS << "__attribute__((neon_polyvector_type(" <<
689 T->getNumElements() << "))) ";
690 printBefore(T->getElementType(), OS);
691 break;
692 case VectorKind::Generic: {
693 // FIXME: We prefer to print the size directly here, but have no way
694 // to get the size of the type.
695 OS << "__attribute__((__vector_size__("
696 << T->getNumElements()
697 << " * sizeof(";
698 print(T->getElementType(), OS, StringRef());
699 OS << ")))) ";
700 printBefore(T->getElementType(), OS);
701 break;
702 }
703 case VectorKind::SveFixedLengthData:
704 case VectorKind::SveFixedLengthPredicate:
705 // FIXME: We prefer to print the size directly here, but have no way
706 // to get the size of the type.
707 OS << "__attribute__((__arm_sve_vector_bits__(";
708
709 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
710 // Predicates take a bit per byte of the vector size, multiply by 8 to
711 // get the number of bits passed to the attribute.
712 OS << T->getNumElements() * 8;
713 else
714 OS << T->getNumElements();
715
716 OS << " * sizeof(";
717 print(T->getElementType(), OS, StringRef());
718 // Multiply by 8 for the number of bits.
719 OS << ") * 8))) ";
720 printBefore(T->getElementType(), OS);
721 break;
722 case VectorKind::RVVFixedLengthData:
723 case VectorKind::RVVFixedLengthMask:
724 case VectorKind::RVVFixedLengthMask_1:
725 case VectorKind::RVVFixedLengthMask_2:
726 case VectorKind::RVVFixedLengthMask_4:
727 // FIXME: We prefer to print the size directly here, but have no way
728 // to get the size of the type.
729 OS << "__attribute__((__riscv_rvv_vector_bits__(";
730
731 OS << T->getNumElements();
732
733 OS << " * sizeof(";
734 print(T->getElementType(), OS, StringRef());
735 // Multiply by 8 for the number of bits.
736 OS << ") * 8))) ";
737 printBefore(T->getElementType(), OS);
738 break;
739 }
740}
741
742void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) {
743 printAfter(T->getElementType(), OS);
744}
745
746void TypePrinter::printDependentVectorBefore(
747 const DependentVectorType *T, raw_ostream &OS) {
748 switch (T->getVectorKind()) {
749 case VectorKind::AltiVecPixel:
750 OS << "__vector __pixel ";
751 break;
752 case VectorKind::AltiVecBool:
753 OS << "__vector __bool ";
754 printBefore(T->getElementType(), OS);
755 break;
756 case VectorKind::AltiVecVector:
757 OS << "__vector ";
758 printBefore(T->getElementType(), OS);
759 break;
760 case VectorKind::Neon:
761 OS << "__attribute__((neon_vector_type(";
762 if (T->getSizeExpr())
763 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
764 OS << "))) ";
765 printBefore(T->getElementType(), OS);
766 break;
767 case VectorKind::NeonPoly:
768 OS << "__attribute__((neon_polyvector_type(";
769 if (T->getSizeExpr())
770 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
771 OS << "))) ";
772 printBefore(T->getElementType(), OS);
773 break;
774 case VectorKind::Generic: {
775 // FIXME: We prefer to print the size directly here, but have no way
776 // to get the size of the type.
777 OS << "__attribute__((__vector_size__(";
778 if (T->getSizeExpr())
779 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
780 OS << " * sizeof(";
781 print(T->getElementType(), OS, StringRef());
782 OS << ")))) ";
783 printBefore(T->getElementType(), OS);
784 break;
785 }
786 case VectorKind::SveFixedLengthData:
787 case VectorKind::SveFixedLengthPredicate:
788 // FIXME: We prefer to print the size directly here, but have no way
789 // to get the size of the type.
790 OS << "__attribute__((__arm_sve_vector_bits__(";
791 if (T->getSizeExpr()) {
792 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
793 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
794 // Predicates take a bit per byte of the vector size, multiply by 8 to
795 // get the number of bits passed to the attribute.
796 OS << " * 8";
797 OS << " * sizeof(";
798 print(T->getElementType(), OS, StringRef());
799 // Multiply by 8 for the number of bits.
800 OS << ") * 8";
801 }
802 OS << "))) ";
803 printBefore(T->getElementType(), OS);
804 break;
805 case VectorKind::RVVFixedLengthData:
806 case VectorKind::RVVFixedLengthMask:
807 case VectorKind::RVVFixedLengthMask_1:
808 case VectorKind::RVVFixedLengthMask_2:
809 case VectorKind::RVVFixedLengthMask_4:
810 // FIXME: We prefer to print the size directly here, but have no way
811 // to get the size of the type.
812 OS << "__attribute__((__riscv_rvv_vector_bits__(";
813 if (T->getSizeExpr()) {
814 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
815 OS << " * sizeof(";
816 print(T->getElementType(), OS, StringRef());
817 // Multiply by 8 for the number of bits.
818 OS << ") * 8";
819 }
820 OS << "))) ";
821 printBefore(T->getElementType(), OS);
822 break;
823 }
824}
825
826void TypePrinter::printDependentVectorAfter(
827 const DependentVectorType *T, raw_ostream &OS) {
828 printAfter(T->getElementType(), OS);
829}
830
831void TypePrinter::printExtVectorBefore(const ExtVectorType *T,
832 raw_ostream &OS) {
833 if (Policy.UseHLSLTypes)
834 OS << "vector<";
835 printBefore(T->getElementType(), OS);
836}
837
838void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) {
839 printAfter(T->getElementType(), OS);
840
841 if (Policy.UseHLSLTypes) {
842 OS << ", ";
843 OS << T->getNumElements();
844 OS << ">";
845 } else {
846 OS << " __attribute__((ext_vector_type(";
847 OS << T->getNumElements();
848 OS << ")))";
849 }
850}
851
852void TypePrinter::printConstantMatrixBefore(const ConstantMatrixType *T,
853 raw_ostream &OS) {
854 printBefore(T->getElementType(), OS);
855 OS << " __attribute__((matrix_type(";
856 OS << T->getNumRows() << ", " << T->getNumColumns();
857 OS << ")))";
858}
859
860void TypePrinter::printConstantMatrixAfter(const ConstantMatrixType *T,
861 raw_ostream &OS) {
862 printAfter(T->getElementType(), OS);
863}
864
865void TypePrinter::printDependentSizedMatrixBefore(
866 const DependentSizedMatrixType *T, raw_ostream &OS) {
867 printBefore(T->getElementType(), OS);
868 OS << " __attribute__((matrix_type(";
869 if (T->getRowExpr()) {
870 T->getRowExpr()->printPretty(OS, nullptr, Policy);
871 }
872 OS << ", ";
873 if (T->getColumnExpr()) {
874 T->getColumnExpr()->printPretty(OS, nullptr, Policy);
875 }
876 OS << ")))";
877}
878
879void TypePrinter::printDependentSizedMatrixAfter(
880 const DependentSizedMatrixType *T, raw_ostream &OS) {
881 printAfter(T->getElementType(), OS);
882}
883
884void
886 const PrintingPolicy &Policy)
887 const {
889 OS << " throw(";
891 OS << "...";
892 else
893 for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) {
894 if (I)
895 OS << ", ";
896
897 OS << getExceptionType(I).stream(Policy);
898 }
899 OS << ')';
900 } else if (EST_NoThrow == getExceptionSpecType()) {
901 OS << " __attribute__((nothrow))";
903 OS << " noexcept";
904 // FIXME:Is it useful to print out the expression for a non-dependent
905 // noexcept specification?
907 OS << '(';
908 if (getNoexceptExpr())
909 getNoexceptExpr()->printPretty(OS, nullptr, Policy);
910 OS << ')';
911 }
912 }
913}
914
915void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,
916 raw_ostream &OS) {
917 if (T->hasTrailingReturn()) {
918 OS << "auto ";
919 if (!HasEmptyPlaceHolder)
920 OS << '(';
921 } else {
922 // If needed for precedence reasons, wrap the inner part in grouping parens.
923 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
924 printBefore(T->getReturnType(), OS);
925 if (!PrevPHIsEmpty.get())
926 OS << '(';
927 }
928}
929
931 switch (ABI) {
933 llvm_unreachable("asking for spelling of ordinary parameter ABI");
935 return "swift_context";
937 return "swift_async_context";
939 return "swift_error_result";
941 return "swift_indirect_result";
943 return "out";
945 return "inout";
946 }
947 llvm_unreachable("bad parameter ABI kind");
948}
949
950void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
951 raw_ostream &OS) {
952 // If needed for precedence reasons, wrap the inner part in grouping parens.
953 if (!HasEmptyPlaceHolder)
954 OS << ')';
955 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
956
957 OS << '(';
958 {
959 ParamPolicyRAII ParamPolicy(Policy);
960 for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {
961 if (i) OS << ", ";
962
963 auto EPI = T->getExtParameterInfo(i);
964 if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) ";
965 if (EPI.isNoEscape())
966 OS << "__attribute__((noescape)) ";
967 auto ABI = EPI.getABI();
968 if (ABI == ParameterABI::HLSLInOut || ABI == ParameterABI::HLSLOut) {
969 OS << getParameterABISpelling(ABI) << " ";
970 if (Policy.UseHLSLTypes) {
971 // This is a bit of a hack because we _do_ use reference types in the
972 // AST for representing inout and out parameters so that code
973 // generation is sane, but when re-printing these for HLSL we need to
974 // skip the reference.
975 print(T->getParamType(i).getNonReferenceType(), OS, StringRef());
976 continue;
977 }
978 } else if (ABI != ParameterABI::Ordinary)
979 OS << "__attribute__((" << getParameterABISpelling(ABI) << ")) ";
980
981 print(T->getParamType(i), OS, StringRef());
982 }
983 }
984
985 if (T->isVariadic()) {
986 if (T->getNumParams())
987 OS << ", ";
988 OS << "...";
989 } else if (T->getNumParams() == 0 && Policy.UseVoidForZeroParams) {
990 // Do not emit int() if we have a proto, emit 'int(void)'.
991 OS << "void";
992 }
993
994 OS << ')';
995
997 unsigned SMEBits = T->getAArch64SMEAttributes();
998
1000 OS << " __arm_streaming_compatible";
1002 OS << " __arm_streaming";
1004 OS << "__arm_agnostic(\"sme_za_state\")";
1006 OS << " __arm_preserves(\"za\")";
1008 OS << " __arm_in(\"za\")";
1010 OS << " __arm_out(\"za\")";
1012 OS << " __arm_inout(\"za\")";
1014 OS << " __arm_preserves(\"zt0\")";
1016 OS << " __arm_in(\"zt0\")";
1018 OS << " __arm_out(\"zt0\")";
1020 OS << " __arm_inout(\"zt0\")";
1021
1022 printFunctionAfter(Info, OS);
1023
1024 if (!T->getMethodQuals().empty())
1025 OS << " " << T->getMethodQuals().getAsString();
1026
1027 switch (T->getRefQualifier()) {
1028 case RQ_None:
1029 break;
1030
1031 case RQ_LValue:
1032 OS << " &";
1033 break;
1034
1035 case RQ_RValue:
1036 OS << " &&";
1037 break;
1038 }
1039 T->printExceptionSpecification(OS, Policy);
1040
1042 for (const auto &CFE : FX) {
1043 OS << " __attribute__((" << CFE.Effect.name();
1044 if (const Expr *E = CFE.Cond.getCondition()) {
1045 OS << '(';
1046 E->printPretty(OS, nullptr, Policy);
1047 OS << ')';
1048 }
1049 OS << "))";
1050 }
1051
1052 if (T->hasTrailingReturn()) {
1053 OS << " -> ";
1054 print(T->getReturnType(), OS, StringRef());
1055 } else
1056 printAfter(T->getReturnType(), OS);
1057}
1058
1059void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
1060 raw_ostream &OS) {
1061 if (!InsideCCAttribute) {
1062 switch (Info.getCC()) {
1063 case CC_C:
1064 // The C calling convention is the default on the vast majority of platforms
1065 // we support. If the user wrote it explicitly, it will usually be printed
1066 // while traversing the AttributedType. If the type has been desugared, let
1067 // the canonical spelling be the implicit calling convention.
1068 // FIXME: It would be better to be explicit in certain contexts, such as a
1069 // cdecl function typedef used to declare a member function with the
1070 // Microsoft C++ ABI.
1071 break;
1072 case CC_X86StdCall:
1073 OS << " __attribute__((stdcall))";
1074 break;
1075 case CC_X86FastCall:
1076 OS << " __attribute__((fastcall))";
1077 break;
1078 case CC_X86ThisCall:
1079 OS << " __attribute__((thiscall))";
1080 break;
1081 case CC_X86VectorCall:
1082 OS << " __attribute__((vectorcall))";
1083 break;
1084 case CC_X86Pascal:
1085 OS << " __attribute__((pascal))";
1086 break;
1087 case CC_AAPCS:
1088 OS << " __attribute__((pcs(\"aapcs\")))";
1089 break;
1090 case CC_AAPCS_VFP:
1091 OS << " __attribute__((pcs(\"aapcs-vfp\")))";
1092 break;
1094 OS << "__attribute__((aarch64_vector_pcs))";
1095 break;
1096 case CC_AArch64SVEPCS:
1097 OS << "__attribute__((aarch64_sve_pcs))";
1098 break;
1100 OS << "__attribute__((amdgpu_kernel))";
1101 break;
1102 case CC_IntelOclBicc:
1103 OS << " __attribute__((intel_ocl_bicc))";
1104 break;
1105 case CC_Win64:
1106 OS << " __attribute__((ms_abi))";
1107 break;
1108 case CC_X86_64SysV:
1109 OS << " __attribute__((sysv_abi))";
1110 break;
1111 case CC_X86RegCall:
1112 OS << " __attribute__((regcall))";
1113 break;
1114 case CC_SpirFunction:
1115 case CC_OpenCLKernel:
1116 // Do nothing. These CCs are not available as attributes.
1117 break;
1118 case CC_Swift:
1119 OS << " __attribute__((swiftcall))";
1120 break;
1121 case CC_SwiftAsync:
1122 OS << "__attribute__((swiftasynccall))";
1123 break;
1124 case CC_PreserveMost:
1125 OS << " __attribute__((preserve_most))";
1126 break;
1127 case CC_PreserveAll:
1128 OS << " __attribute__((preserve_all))";
1129 break;
1130 case CC_M68kRTD:
1131 OS << " __attribute__((m68k_rtd))";
1132 break;
1133 case CC_PreserveNone:
1134 OS << " __attribute__((preserve_none))";
1135 break;
1136 case CC_RISCVVectorCall:
1137 OS << "__attribute__((riscv_vector_cc))";
1138 break;
1139 }
1140 }
1141
1142 if (Info.getNoReturn())
1143 OS << " __attribute__((noreturn))";
1144 if (Info.getCmseNSCall())
1145 OS << " __attribute__((cmse_nonsecure_call))";
1146 if (Info.getProducesResult())
1147 OS << " __attribute__((ns_returns_retained))";
1148 if (Info.getRegParm())
1149 OS << " __attribute__((regparm ("
1150 << Info.getRegParm() << ")))";
1151 if (Info.getNoCallerSavedRegs())
1152 OS << " __attribute__((no_caller_saved_registers))";
1153 if (Info.getNoCfCheck())
1154 OS << " __attribute__((nocf_check))";
1155}
1156
1157void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T,
1158 raw_ostream &OS) {
1159 // If needed for precedence reasons, wrap the inner part in grouping parens.
1160 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
1161 printBefore(T->getReturnType(), OS);
1162 if (!PrevPHIsEmpty.get())
1163 OS << '(';
1164}
1165
1166void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,
1167 raw_ostream &OS) {
1168 // If needed for precedence reasons, wrap the inner part in grouping parens.
1169 if (!HasEmptyPlaceHolder)
1170 OS << ')';
1171 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
1172
1173 OS << "()";
1174 printFunctionAfter(T->getExtInfo(), OS);
1175 printAfter(T->getReturnType(), OS);
1176}
1177
1178void TypePrinter::printTypeSpec(NamedDecl *D, raw_ostream &OS) {
1179
1180 // Compute the full nested-name-specifier for this type.
1181 // In C, this will always be empty except when the type
1182 // being printed is anonymous within other Record.
1183 if (!Policy.SuppressScope)
1184 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1185
1186 IdentifierInfo *II = D->getIdentifier();
1187 OS << II->getName();
1188 spaceBeforePlaceHolder(OS);
1189}
1190
1191void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,
1192 raw_ostream &OS) {
1193 printTypeSpec(T->getDecl(), OS);
1194}
1195
1196void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,
1197 raw_ostream &OS) {}
1198
1199void TypePrinter::printUsingBefore(const UsingType *T, raw_ostream &OS) {
1200 // After `namespace b { using a::X }`, is the type X within B a::X or b::X?
1201 //
1202 // - b::X is more formally correct given the UsingType model
1203 // - b::X makes sense if "re-exporting" a symbol in a new namespace
1204 // - a::X makes sense if "importing" a symbol for convenience
1205 //
1206 // The "importing" use seems much more common, so we print a::X.
1207 // This could be a policy option, but the right choice seems to rest more
1208 // with the intent of the code than the caller.
1209 printTypeSpec(T->getFoundDecl()->getUnderlyingDecl(), OS);
1210}
1211
1212void TypePrinter::printUsingAfter(const UsingType *T, raw_ostream &OS) {}
1213
1214void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
1215 printTypeSpec(T->getDecl(), OS);
1216}
1217
1218void TypePrinter::printMacroQualifiedBefore(const MacroQualifiedType *T,
1219 raw_ostream &OS) {
1220 StringRef MacroName = T->getMacroIdentifier()->getName();
1221 OS << MacroName << " ";
1222
1223 // Since this type is meant to print the macro instead of the whole attribute,
1224 // we trim any attributes and go directly to the original modified type.
1225 printBefore(T->getModifiedType(), OS);
1226}
1227
1228void TypePrinter::printMacroQualifiedAfter(const MacroQualifiedType *T,
1229 raw_ostream &OS) {
1230 printAfter(T->getModifiedType(), OS);
1231}
1232
1233void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) {}
1234
1235void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
1236 raw_ostream &OS) {
1237 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual "
1238 : "typeof ");
1239 if (T->getUnderlyingExpr())
1240 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
1241 spaceBeforePlaceHolder(OS);
1242}
1243
1244void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
1245 raw_ostream &OS) {}
1246
1247void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) {
1248 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual("
1249 : "typeof(");
1250 print(T->getUnmodifiedType(), OS, StringRef());
1251 OS << ')';
1252 spaceBeforePlaceHolder(OS);
1253}
1254
1255void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) {}
1256
1257void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {
1258 OS << "decltype(";
1259 if (T->getUnderlyingExpr())
1260 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
1261 OS << ')';
1262 spaceBeforePlaceHolder(OS);
1263}
1264
1265void TypePrinter::printPackIndexingBefore(const PackIndexingType *T,
1266 raw_ostream &OS) {
1267 if (T->hasSelectedType()) {
1268 OS << T->getSelectedType();
1269 } else {
1270 OS << T->getPattern() << "...[";
1271 T->getIndexExpr()->printPretty(OS, nullptr, Policy);
1272 OS << "]";
1273 }
1274 spaceBeforePlaceHolder(OS);
1275}
1276
1277void TypePrinter::printPackIndexingAfter(const PackIndexingType *T,
1278 raw_ostream &OS) {}
1279
1280void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) {}
1281
1282void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,
1283 raw_ostream &OS) {
1284 IncludeStrongLifetimeRAII Strong(Policy);
1285
1286 static llvm::DenseMap<int, const char *> Transformation = {{
1287#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
1288 {UnaryTransformType::Enum, "__" #Trait},
1289#include "clang/Basic/TransformTypeTraits.def"
1290 }};
1291 OS << Transformation[T->getUTTKind()] << '(';
1292 print(T->getBaseType(), OS, StringRef());
1293 OS << ')';
1294 spaceBeforePlaceHolder(OS);
1295}
1296
1297void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,
1298 raw_ostream &OS) {}
1299
1300void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
1301 // If the type has been deduced, do not print 'auto'.
1302 if (!T->getDeducedType().isNull()) {
1303 printBefore(T->getDeducedType(), OS);
1304 } else {
1305 if (T->isConstrained()) {
1306 // FIXME: Track a TypeConstraint as type sugar, so that we can print the
1307 // type as it was written.
1308 T->getTypeConstraintConcept()->getDeclName().print(OS, Policy);
1309 auto Args = T->getTypeConstraintArguments();
1310 if (!Args.empty())
1312 OS, Args, Policy,
1313 T->getTypeConstraintConcept()->getTemplateParameters());
1314 OS << ' ';
1315 }
1316 switch (T->getKeyword()) {
1317 case AutoTypeKeyword::Auto: OS << "auto"; break;
1318 case AutoTypeKeyword::DecltypeAuto: OS << "decltype(auto)"; break;
1319 case AutoTypeKeyword::GNUAutoType: OS << "__auto_type"; break;
1320 }
1321 spaceBeforePlaceHolder(OS);
1322 }
1323}
1324
1325void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {
1326 // If the type has been deduced, do not print 'auto'.
1327 if (!T->getDeducedType().isNull())
1328 printAfter(T->getDeducedType(), OS);
1329}
1330
1331void TypePrinter::printDeducedTemplateSpecializationBefore(
1332 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1333 // If the type has been deduced, print the deduced type.
1334 if (!T->getDeducedType().isNull()) {
1335 printBefore(T->getDeducedType(), OS);
1336 } else {
1337 IncludeStrongLifetimeRAII Strong(Policy);
1338 T->getTemplateName().print(OS, Policy);
1339 spaceBeforePlaceHolder(OS);
1340 }
1341}
1342
1343void TypePrinter::printDeducedTemplateSpecializationAfter(
1344 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1345 // If the type has been deduced, print the deduced type.
1346 if (!T->getDeducedType().isNull())
1347 printAfter(T->getDeducedType(), OS);
1348}
1349
1350void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {
1351 IncludeStrongLifetimeRAII Strong(Policy);
1352
1353 OS << "_Atomic(";
1354 print(T->getValueType(), OS, StringRef());
1355 OS << ')';
1356 spaceBeforePlaceHolder(OS);
1357}
1358
1359void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) {}
1360
1361void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) {
1362 IncludeStrongLifetimeRAII Strong(Policy);
1363
1364 if (T->isReadOnly())
1365 OS << "read_only ";
1366 else
1367 OS << "write_only ";
1368 OS << "pipe ";
1369 print(T->getElementType(), OS, StringRef());
1370 spaceBeforePlaceHolder(OS);
1371}
1372
1373void TypePrinter::printPipeAfter(const PipeType *T, raw_ostream &OS) {}
1374
1375void TypePrinter::printBitIntBefore(const BitIntType *T, raw_ostream &OS) {
1376 if (T->isUnsigned())
1377 OS << "unsigned ";
1378 OS << "_BitInt(" << T->getNumBits() << ")";
1379 spaceBeforePlaceHolder(OS);
1380}
1381
1382void TypePrinter::printBitIntAfter(const BitIntType *T, raw_ostream &OS) {}
1383
1384void TypePrinter::printDependentBitIntBefore(const DependentBitIntType *T,
1385 raw_ostream &OS) {
1386 if (T->isUnsigned())
1387 OS << "unsigned ";
1388 OS << "_BitInt(";
1389 T->getNumBitsExpr()->printPretty(OS, nullptr, Policy);
1390 OS << ")";
1391 spaceBeforePlaceHolder(OS);
1392}
1393
1394void TypePrinter::printDependentBitIntAfter(const DependentBitIntType *T,
1395 raw_ostream &OS) {}
1396
1397/// Appends the given scope to the end of a string.
1398void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS,
1399 DeclarationName NameInScope) {
1400 if (DC->isTranslationUnit())
1401 return;
1402
1403 // FIXME: Consider replacing this with NamedDecl::printNestedNameSpecifier,
1404 // which can also print names for function and method scopes.
1405 if (DC->isFunctionOrMethod())
1406 return;
1407
1408 if (Policy.Callbacks && Policy.Callbacks->isScopeVisible(DC))
1409 return;
1410
1411 if (const auto *NS = dyn_cast<NamespaceDecl>(DC)) {
1412 if (Policy.SuppressUnwrittenScope && NS->isAnonymousNamespace())
1413 return AppendScope(DC->getParent(), OS, NameInScope);
1414
1415 // Only suppress an inline namespace if the name has the same lookup
1416 // results in the enclosing namespace.
1417 if (Policy.SuppressInlineNamespace !=
1419 NS->isInline() && NameInScope &&
1420 NS->isRedundantInlineQualifierFor(NameInScope))
1421 return AppendScope(DC->getParent(), OS, NameInScope);
1422
1423 AppendScope(DC->getParent(), OS, NS->getDeclName());
1424 if (NS->getIdentifier())
1425 OS << NS->getName() << "::";
1426 else
1427 OS << "(anonymous namespace)::";
1428 } else if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
1429 AppendScope(DC->getParent(), OS, Spec->getDeclName());
1430 IncludeStrongLifetimeRAII Strong(Policy);
1431 OS << Spec->getIdentifier()->getName();
1432 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
1434 OS, TemplateArgs.asArray(), Policy,
1435 Spec->getSpecializedTemplate()->getTemplateParameters());
1436 OS << "::";
1437 } else if (const auto *Tag = dyn_cast<TagDecl>(DC)) {
1438 AppendScope(DC->getParent(), OS, Tag->getDeclName());
1439 if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl())
1440 OS << Typedef->getIdentifier()->getName() << "::";
1441 else if (Tag->getIdentifier())
1442 OS << Tag->getIdentifier()->getName() << "::";
1443 else
1444 return;
1445 } else {
1446 AppendScope(DC->getParent(), OS, NameInScope);
1447 }
1448}
1449
1450void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {
1451 if (Policy.IncludeTagDefinition) {
1452 PrintingPolicy SubPolicy = Policy;
1453 SubPolicy.IncludeTagDefinition = false;
1454 D->print(OS, SubPolicy, Indentation);
1455 spaceBeforePlaceHolder(OS);
1456 return;
1457 }
1458
1459 bool HasKindDecoration = false;
1460
1461 // We don't print tags unless this is an elaborated type.
1462 // In C, we just assume every RecordType is an elaborated type.
1463 if (!Policy.SuppressTagKeyword && !D->getTypedefNameForAnonDecl()) {
1464 HasKindDecoration = true;
1465 OS << D->getKindName();
1466 OS << ' ';
1467 }
1468
1469 // Compute the full nested-name-specifier for this type.
1470 // In C, this will always be empty except when the type
1471 // being printed is anonymous within other Record.
1472 if (!Policy.SuppressScope)
1473 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1474
1475 if (const IdentifierInfo *II = D->getIdentifier())
1476 OS << II->getName();
1477 else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) {
1478 assert(Typedef->getIdentifier() && "Typedef without identifier?");
1479 OS << Typedef->getIdentifier()->getName();
1480 } else {
1481 // Make an unambiguous representation for anonymous types, e.g.
1482 // (anonymous enum at /usr/include/string.h:120:9)
1483 OS << (Policy.MSVCFormatting ? '`' : '(');
1484
1485 if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
1486 OS << "lambda";
1487 HasKindDecoration = true;
1488 } else if ((isa<RecordDecl>(D) && cast<RecordDecl>(D)->isAnonymousStructOrUnion())) {
1489 OS << "anonymous";
1490 } else {
1491 OS << "unnamed";
1492 }
1493
1494 if (Policy.AnonymousTagLocations) {
1495 // Suppress the redundant tag keyword if we just printed one.
1496 // We don't have to worry about ElaboratedTypes here because you can't
1497 // refer to an anonymous type with one.
1498 if (!HasKindDecoration)
1499 OS << " " << D->getKindName();
1500
1502 D->getLocation());
1503 if (PLoc.isValid()) {
1504 OS << " at ";
1505 StringRef File = PLoc.getFilename();
1506 llvm::SmallString<1024> WrittenFile(File);
1507 if (auto *Callbacks = Policy.Callbacks)
1508 WrittenFile = Callbacks->remapPath(File);
1509 // Fix inconsistent path separator created by
1510 // clang::DirectoryLookup::LookupFile when the file path is relative
1511 // path.
1512 llvm::sys::path::Style Style =
1513 llvm::sys::path::is_absolute(WrittenFile)
1514 ? llvm::sys::path::Style::native
1515 : (Policy.MSVCFormatting
1516 ? llvm::sys::path::Style::windows_backslash
1517 : llvm::sys::path::Style::posix);
1518 llvm::sys::path::native(WrittenFile, Style);
1519 OS << WrittenFile << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
1520 }
1521 }
1522
1523 OS << (Policy.MSVCFormatting ? '\'' : ')');
1524 }
1525
1526 // If this is a class template specialization, print the template
1527 // arguments.
1528 if (auto *S = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1529 const TemplateParameterList *TParams =
1530 S->getSpecializedTemplate()->getTemplateParameters();
1531 const ASTTemplateArgumentListInfo *TArgAsWritten =
1532 S->getTemplateArgsAsWritten();
1533 IncludeStrongLifetimeRAII Strong(Policy);
1534 if (TArgAsWritten && !Policy.PrintCanonicalTypes)
1535 printTemplateArgumentList(OS, TArgAsWritten->arguments(), Policy,
1536 TParams);
1537 else
1538 printTemplateArgumentList(OS, S->getTemplateArgs().asArray(), Policy,
1539 TParams);
1540 }
1541
1542 spaceBeforePlaceHolder(OS);
1543}
1544
1545void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
1546 // Print the preferred name if we have one for this type.
1547 if (Policy.UsePreferredNames) {
1548 for (const auto *PNA : T->getDecl()->specific_attrs<PreferredNameAttr>()) {
1549 if (!declaresSameEntity(PNA->getTypedefType()->getAsCXXRecordDecl(),
1550 T->getDecl()))
1551 continue;
1552 // Find the outermost typedef or alias template.
1553 QualType T = PNA->getTypedefType();
1554 while (true) {
1555 if (auto *TT = dyn_cast<TypedefType>(T))
1556 return printTypeSpec(TT->getDecl(), OS);
1557 if (auto *TST = dyn_cast<TemplateSpecializationType>(T))
1558 return printTemplateId(TST, OS, /*FullyQualify=*/true);
1560 }
1561 }
1562 }
1563
1564 printTag(T->getDecl(), OS);
1565}
1566
1567void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) {}
1568
1569void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {
1570 printTag(T->getDecl(), OS);
1571}
1572
1573void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {}
1574
1575void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
1576 raw_ostream &OS) {
1577 TemplateTypeParmDecl *D = T->getDecl();
1578 if (D && D->isImplicit()) {
1579 if (auto *TC = D->getTypeConstraint()) {
1580 TC->print(OS, Policy);
1581 OS << ' ';
1582 }
1583 OS << "auto";
1584 } else if (IdentifierInfo *Id = T->getIdentifier())
1585 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1586 : Id->getName());
1587 else
1588 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
1589
1590 spaceBeforePlaceHolder(OS);
1591}
1592
1593void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,
1594 raw_ostream &OS) {}
1595
1596void TypePrinter::printSubstTemplateTypeParmBefore(
1598 raw_ostream &OS) {
1599 IncludeStrongLifetimeRAII Strong(Policy);
1600 printBefore(T->getReplacementType(), OS);
1601}
1602
1603void TypePrinter::printSubstTemplateTypeParmAfter(
1605 raw_ostream &OS) {
1606 IncludeStrongLifetimeRAII Strong(Policy);
1607 printAfter(T->getReplacementType(), OS);
1608}
1609
1610void TypePrinter::printSubstTemplateTypeParmPackBefore(
1612 raw_ostream &OS) {
1613 IncludeStrongLifetimeRAII Strong(Policy);
1614 if (const TemplateTypeParmDecl *D = T->getReplacedParameter()) {
1615 if (D && D->isImplicit()) {
1616 if (auto *TC = D->getTypeConstraint()) {
1617 TC->print(OS, Policy);
1618 OS << ' ';
1619 }
1620 OS << "auto";
1621 } else if (IdentifierInfo *Id = D->getIdentifier())
1622 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1623 : Id->getName());
1624 else
1625 OS << "type-parameter-" << D->getDepth() << '-' << D->getIndex();
1626
1627 spaceBeforePlaceHolder(OS);
1628 }
1629}
1630
1631void TypePrinter::printSubstTemplateTypeParmPackAfter(
1633 raw_ostream &OS) {
1634 IncludeStrongLifetimeRAII Strong(Policy);
1635}
1636
1637void TypePrinter::printTemplateId(const TemplateSpecializationType *T,
1638 raw_ostream &OS, bool FullyQualify) {
1639 IncludeStrongLifetimeRAII Strong(Policy);
1640
1641 TemplateDecl *TD =
1642 T->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true);
1643 // FIXME: Null TD never exercised in test suite.
1644 if (FullyQualify && TD) {
1645 if (!Policy.SuppressScope)
1646 AppendScope(TD->getDeclContext(), OS, TD->getDeclName());
1647
1648 OS << TD->getName();
1649 } else {
1650 T->getTemplateName().print(OS, Policy, TemplateName::Qualified::None);
1651 }
1652
1653 DefaultTemplateArgsPolicyRAII TemplateArgs(Policy);
1654 const TemplateParameterList *TPL = TD ? TD->getTemplateParameters() : nullptr;
1655 printTemplateArgumentList(OS, T->template_arguments(), Policy, TPL);
1656 spaceBeforePlaceHolder(OS);
1657}
1658
1659void TypePrinter::printTemplateSpecializationBefore(
1661 raw_ostream &OS) {
1662 printTemplateId(T, OS, Policy.FullyQualifiedName);
1663}
1664
1665void TypePrinter::printTemplateSpecializationAfter(
1667 raw_ostream &OS) {}
1668
1669void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
1670 raw_ostream &OS) {
1671 if (Policy.PrintInjectedClassNameWithArguments)
1672 return printTemplateSpecializationBefore(T->getInjectedTST(), OS);
1673
1674 IncludeStrongLifetimeRAII Strong(Policy);
1675 T->getTemplateName().print(OS, Policy);
1676 spaceBeforePlaceHolder(OS);
1677}
1678
1679void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
1680 raw_ostream &OS) {}
1681
1682void TypePrinter::printElaboratedBefore(const ElaboratedType *T,
1683 raw_ostream &OS) {
1684 if (Policy.IncludeTagDefinition && T->getOwnedTagDecl()) {
1685 TagDecl *OwnedTagDecl = T->getOwnedTagDecl();
1686 assert(OwnedTagDecl->getTypeForDecl() == T->getNamedType().getTypePtr() &&
1687 "OwnedTagDecl expected to be a declaration for the type");
1688 PrintingPolicy SubPolicy = Policy;
1689 SubPolicy.IncludeTagDefinition = false;
1690 OwnedTagDecl->print(OS, SubPolicy, Indentation);
1691 spaceBeforePlaceHolder(OS);
1692 return;
1693 }
1694
1695 if (Policy.SuppressElaboration) {
1696 printBefore(T->getNamedType(), OS);
1697 return;
1698 }
1699
1700 // The tag definition will take care of these.
1701 if (!Policy.IncludeTagDefinition)
1702 {
1703 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1704 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1705 OS << " ";
1706 NestedNameSpecifier *Qualifier = T->getQualifier();
1707 if (!Policy.SuppressTagKeyword && Policy.SuppressScope &&
1708 !Policy.SuppressUnwrittenScope) {
1709 bool OldTagKeyword = Policy.SuppressTagKeyword;
1710 bool OldSupressScope = Policy.SuppressScope;
1711 Policy.SuppressTagKeyword = true;
1712 Policy.SuppressScope = false;
1713 printBefore(T->getNamedType(), OS);
1714 Policy.SuppressTagKeyword = OldTagKeyword;
1715 Policy.SuppressScope = OldSupressScope;
1716 return;
1717 }
1718 if (Qualifier)
1719 Qualifier->print(OS, Policy);
1720 }
1721
1722 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1723 printBefore(T->getNamedType(), OS);
1724}
1725
1726void TypePrinter::printElaboratedAfter(const ElaboratedType *T,
1727 raw_ostream &OS) {
1728 if (Policy.IncludeTagDefinition && T->getOwnedTagDecl())
1729 return;
1730
1731 if (Policy.SuppressElaboration) {
1732 printAfter(T->getNamedType(), OS);
1733 return;
1734 }
1735
1736 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1737 printAfter(T->getNamedType(), OS);
1738}
1739
1740void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {
1741 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1742 printBefore(T->getInnerType(), OS);
1743 OS << '(';
1744 } else
1745 printBefore(T->getInnerType(), OS);
1746}
1747
1748void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {
1749 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1750 OS << ')';
1751 printAfter(T->getInnerType(), OS);
1752 } else
1753 printAfter(T->getInnerType(), OS);
1754}
1755
1756void TypePrinter::printDependentNameBefore(const DependentNameType *T,
1757 raw_ostream &OS) {
1758 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1759 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1760 OS << " ";
1761
1762 T->getQualifier()->print(OS, Policy);
1763
1764 OS << T->getIdentifier()->getName();
1765 spaceBeforePlaceHolder(OS);
1766}
1767
1768void TypePrinter::printDependentNameAfter(const DependentNameType *T,
1769 raw_ostream &OS) {}
1770
1771void TypePrinter::printDependentTemplateSpecializationBefore(
1772 const DependentTemplateSpecializationType *T, raw_ostream &OS) {
1773 IncludeStrongLifetimeRAII Strong(Policy);
1774
1775 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1776 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1777 OS << " ";
1778
1779 if (T->getQualifier())
1780 T->getQualifier()->print(OS, Policy);
1781 OS << "template " << T->getIdentifier()->getName();
1782 printTemplateArgumentList(OS, T->template_arguments(), Policy);
1783 spaceBeforePlaceHolder(OS);
1784}
1785
1786void TypePrinter::printDependentTemplateSpecializationAfter(
1787 const DependentTemplateSpecializationType *T, raw_ostream &OS) {}
1788
1789void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,
1790 raw_ostream &OS) {
1791 printBefore(T->getPattern(), OS);
1792}
1793
1794void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
1795 raw_ostream &OS) {
1796 printAfter(T->getPattern(), OS);
1797 OS << "...";
1798}
1799
1801 raw_ostream &OS,
1802 const PrintingPolicy &Policy) {
1803 OS << ' ';
1804 if (T->isCountInBytes() && T->isOrNull())
1805 OS << "__sized_by_or_null(";
1806 else if (T->isCountInBytes())
1807 OS << "__sized_by(";
1808 else if (T->isOrNull())
1809 OS << "__counted_by_or_null(";
1810 else
1811 OS << "__counted_by(";
1812 if (T->getCountExpr())
1813 T->getCountExpr()->printPretty(OS, nullptr, Policy);
1814 OS << ')';
1815}
1816
1817void TypePrinter::printCountAttributedBefore(const CountAttributedType *T,
1818 raw_ostream &OS) {
1819 printBefore(T->desugar(), OS);
1820 if (!T->isArrayType())
1821 printCountAttributedImpl(T, OS, Policy);
1822}
1823
1824void TypePrinter::printCountAttributedAfter(const CountAttributedType *T,
1825 raw_ostream &OS) {
1826 printAfter(T->desugar(), OS);
1827 if (T->isArrayType())
1828 printCountAttributedImpl(T, OS, Policy);
1829}
1830
1831void TypePrinter::printAttributedBefore(const AttributedType *T,
1832 raw_ostream &OS) {
1833 // FIXME: Generate this with TableGen.
1834
1835 // Prefer the macro forms of the GC and ownership qualifiers.
1836 if (T->getAttrKind() == attr::ObjCGC ||
1837 T->getAttrKind() == attr::ObjCOwnership)
1838 return printBefore(T->getEquivalentType(), OS);
1839
1840 if (T->getAttrKind() == attr::ObjCKindOf)
1841 OS << "__kindof ";
1842
1843 if (T->getAttrKind() == attr::AddressSpace)
1844 printBefore(T->getEquivalentType(), OS);
1845 else
1846 printBefore(T->getModifiedType(), OS);
1847
1848 if (T->isMSTypeSpec()) {
1849 switch (T->getAttrKind()) {
1850 default: return;
1851 case attr::Ptr32: OS << " __ptr32"; break;
1852 case attr::Ptr64: OS << " __ptr64"; break;
1853 case attr::SPtr: OS << " __sptr"; break;
1854 case attr::UPtr: OS << " __uptr"; break;
1855 }
1856 spaceBeforePlaceHolder(OS);
1857 }
1858
1859 if (T->isWebAssemblyFuncrefSpec())
1860 OS << "__funcref";
1861
1862 // Print nullability type specifiers.
1863 if (T->getImmediateNullability()) {
1864 if (T->getAttrKind() == attr::TypeNonNull)
1865 OS << " _Nonnull";
1866 else if (T->getAttrKind() == attr::TypeNullable)
1867 OS << " _Nullable";
1868 else if (T->getAttrKind() == attr::TypeNullUnspecified)
1869 OS << " _Null_unspecified";
1870 else if (T->getAttrKind() == attr::TypeNullableResult)
1871 OS << " _Nullable_result";
1872 else
1873 llvm_unreachable("unhandled nullability");
1874 spaceBeforePlaceHolder(OS);
1875 }
1876}
1877
1878void TypePrinter::printAttributedAfter(const AttributedType *T,
1879 raw_ostream &OS) {
1880 // FIXME: Generate this with TableGen.
1881
1882 // Prefer the macro forms of the GC and ownership qualifiers.
1883 if (T->getAttrKind() == attr::ObjCGC ||
1884 T->getAttrKind() == attr::ObjCOwnership)
1885 return printAfter(T->getEquivalentType(), OS);
1886
1887 // If this is a calling convention attribute, don't print the implicit CC from
1888 // the modified type.
1889 SaveAndRestore MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());
1890
1891 printAfter(T->getModifiedType(), OS);
1892
1893 // Some attributes are printed as qualifiers before the type, so we have
1894 // nothing left to do.
1895 if (T->getAttrKind() == attr::ObjCKindOf || T->isMSTypeSpec() ||
1896 T->getImmediateNullability() || T->isWebAssemblyFuncrefSpec())
1897 return;
1898
1899 // Don't print the inert __unsafe_unretained attribute at all.
1900 if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained)
1901 return;
1902
1903 // Don't print ns_returns_retained unless it had an effect.
1904 if (T->getAttrKind() == attr::NSReturnsRetained &&
1905 !T->getEquivalentType()->castAs<FunctionType>()
1907 return;
1908
1909 if (T->getAttrKind() == attr::LifetimeBound) {
1910 OS << " [[clang::lifetimebound]]";
1911 return;
1912 }
1913 if (T->getAttrKind() == attr::LifetimeCaptureBy) {
1914 OS << " [[clang::lifetime_capture_by(";
1915 if (auto *attr = dyn_cast_or_null<LifetimeCaptureByAttr>(T->getAttr()))
1916 llvm::interleaveComma(attr->getArgIdents(), OS,
1917 [&](auto it) { OS << it->getName(); });
1918 OS << ")]]";
1919 return;
1920 }
1921
1922 // The printing of the address_space attribute is handled by the qualifier
1923 // since it is still stored in the qualifier. Return early to prevent printing
1924 // this twice.
1925 if (T->getAttrKind() == attr::AddressSpace)
1926 return;
1927
1928 if (T->getAttrKind() == attr::AnnotateType) {
1929 // FIXME: Print the attribute arguments once we have a way to retrieve these
1930 // here. For the meantime, we just print `[[clang::annotate_type(...)]]`
1931 // without the arguments so that we know at least that we had _some_
1932 // annotation on the type.
1933 OS << " [[clang::annotate_type(...)]]";
1934 return;
1935 }
1936
1937 if (T->getAttrKind() == attr::ArmStreaming) {
1938 OS << "__arm_streaming";
1939 return;
1940 }
1941 if (T->getAttrKind() == attr::ArmStreamingCompatible) {
1942 OS << "__arm_streaming_compatible";
1943 return;
1944 }
1945
1946 if (T->getAttrKind() == attr::SwiftAttr) {
1947 if (auto *swiftAttr = dyn_cast_or_null<SwiftAttrAttr>(T->getAttr())) {
1948 OS << " __attribute__((swift_attr(\"" << swiftAttr->getAttribute()
1949 << "\")))";
1950 }
1951 return;
1952 }
1953
1954 OS << " __attribute__((";
1955 switch (T->getAttrKind()) {
1956#define TYPE_ATTR(NAME)
1957#define DECL_OR_TYPE_ATTR(NAME)
1958#define ATTR(NAME) case attr::NAME:
1959#include "clang/Basic/AttrList.inc"
1960 llvm_unreachable("non-type attribute attached to type");
1961
1962 case attr::BTFTypeTag:
1963 llvm_unreachable("BTFTypeTag attribute handled separately");
1964
1965 case attr::HLSLResourceClass:
1966 case attr::HLSLROV:
1967 case attr::HLSLRawBuffer:
1968 case attr::HLSLContainedType:
1969 llvm_unreachable("HLSL resource type attributes handled separately");
1970
1971 case attr::OpenCLPrivateAddressSpace:
1972 case attr::OpenCLGlobalAddressSpace:
1973 case attr::OpenCLGlobalDeviceAddressSpace:
1974 case attr::OpenCLGlobalHostAddressSpace:
1975 case attr::OpenCLLocalAddressSpace:
1976 case attr::OpenCLConstantAddressSpace:
1977 case attr::OpenCLGenericAddressSpace:
1978 case attr::HLSLGroupSharedAddressSpace:
1979 // FIXME: Update printAttributedBefore to print these once we generate
1980 // AttributedType nodes for them.
1981 break;
1982
1983 case attr::CountedBy:
1984 case attr::CountedByOrNull:
1985 case attr::SizedBy:
1986 case attr::SizedByOrNull:
1987 case attr::LifetimeBound:
1988 case attr::LifetimeCaptureBy:
1989 case attr::TypeNonNull:
1990 case attr::TypeNullable:
1991 case attr::TypeNullableResult:
1992 case attr::TypeNullUnspecified:
1993 case attr::ObjCGC:
1994 case attr::ObjCInertUnsafeUnretained:
1995 case attr::ObjCKindOf:
1996 case attr::ObjCOwnership:
1997 case attr::Ptr32:
1998 case attr::Ptr64:
1999 case attr::SPtr:
2000 case attr::UPtr:
2001 case attr::AddressSpace:
2002 case attr::CmseNSCall:
2003 case attr::AnnotateType:
2004 case attr::WebAssemblyFuncref:
2005 case attr::ArmAgnostic:
2006 case attr::ArmStreaming:
2007 case attr::ArmStreamingCompatible:
2008 case attr::ArmIn:
2009 case attr::ArmOut:
2010 case attr::ArmInOut:
2011 case attr::ArmPreserves:
2012 case attr::NonBlocking:
2013 case attr::NonAllocating:
2014 case attr::Blocking:
2015 case attr::Allocating:
2016 case attr::SwiftAttr:
2017 llvm_unreachable("This attribute should have been handled already");
2018
2019 case attr::NSReturnsRetained:
2020 OS << "ns_returns_retained";
2021 break;
2022
2023 // FIXME: When Sema learns to form this AttributedType, avoid printing the
2024 // attribute again in printFunctionProtoAfter.
2025 case attr::AnyX86NoCfCheck: OS << "nocf_check"; break;
2026 case attr::CDecl: OS << "cdecl"; break;
2027 case attr::FastCall: OS << "fastcall"; break;
2028 case attr::StdCall: OS << "stdcall"; break;
2029 case attr::ThisCall: OS << "thiscall"; break;
2030 case attr::SwiftCall: OS << "swiftcall"; break;
2031 case attr::SwiftAsyncCall: OS << "swiftasynccall"; break;
2032 case attr::VectorCall: OS << "vectorcall"; break;
2033 case attr::Pascal: OS << "pascal"; break;
2034 case attr::MSABI: OS << "ms_abi"; break;
2035 case attr::SysVABI: OS << "sysv_abi"; break;
2036 case attr::RegCall: OS << "regcall"; break;
2037 case attr::Pcs: {
2038 OS << "pcs(";
2039 QualType t = T->getEquivalentType();
2040 while (!t->isFunctionType())
2041 t = t->getPointeeType();
2042 OS << (t->castAs<FunctionType>()->getCallConv() == CC_AAPCS ?
2043 "\"aapcs\"" : "\"aapcs-vfp\"");
2044 OS << ')';
2045 break;
2046 }
2047 case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break;
2048 case attr::AArch64SVEPcs: OS << "aarch64_sve_pcs"; break;
2049 case attr::AMDGPUKernelCall: OS << "amdgpu_kernel"; break;
2050 case attr::IntelOclBicc: OS << "inteloclbicc"; break;
2051 case attr::PreserveMost:
2052 OS << "preserve_most";
2053 break;
2054
2055 case attr::PreserveAll:
2056 OS << "preserve_all";
2057 break;
2058 case attr::M68kRTD:
2059 OS << "m68k_rtd";
2060 break;
2061 case attr::PreserveNone:
2062 OS << "preserve_none";
2063 break;
2064 case attr::RISCVVectorCC:
2065 OS << "riscv_vector_cc";
2066 break;
2067 case attr::NoDeref:
2068 OS << "noderef";
2069 break;
2070 case attr::AcquireHandle:
2071 OS << "acquire_handle";
2072 break;
2073 case attr::ArmMveStrictPolymorphism:
2074 OS << "__clang_arm_mve_strict_polymorphism";
2075 break;
2076 }
2077 OS << "))";
2078}
2079
2080void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T,
2081 raw_ostream &OS) {
2082 printBefore(T->getWrappedType(), OS);
2083 OS << " __attribute__((btf_type_tag(\"" << T->getAttr()->getBTFTypeTag() << "\")))";
2084}
2085
2086void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,
2087 raw_ostream &OS) {
2088 printAfter(T->getWrappedType(), OS);
2089}
2090
2091void TypePrinter::printHLSLAttributedResourceBefore(
2092 const HLSLAttributedResourceType *T, raw_ostream &OS) {
2093 printBefore(T->getWrappedType(), OS);
2094}
2095
2096void TypePrinter::printHLSLAttributedResourceAfter(
2097 const HLSLAttributedResourceType *T, raw_ostream &OS) {
2098 printAfter(T->getWrappedType(), OS);
2099 const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs();
2100 OS << " [[hlsl::resource_class("
2101 << HLSLResourceClassAttr::ConvertResourceClassToStr(Attrs.ResourceClass)
2102 << ")]]";
2103 if (Attrs.IsROV)
2104 OS << " [[hlsl::is_rov]]";
2105 if (Attrs.RawBuffer)
2106 OS << " [[hlsl::raw_buffer]]";
2107
2108 QualType ContainedTy = T->getContainedType();
2109 if (!ContainedTy.isNull()) {
2110 OS << " [[hlsl::contained_type(";
2111 printBefore(ContainedTy, OS);
2112 printAfter(ContainedTy, OS);
2113 OS << ")]]";
2114 }
2115}
2116
2117void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
2118 raw_ostream &OS) {
2119 OS << T->getDecl()->getName();
2120 spaceBeforePlaceHolder(OS);
2121}
2122
2123void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
2124 raw_ostream &OS) {}
2125
2126void TypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType *T,
2127 raw_ostream &OS) {
2128 OS << T->getDecl()->getName();
2129 if (!T->qual_empty()) {
2130 bool isFirst = true;
2131 OS << '<';
2132 for (const auto *I : T->quals()) {
2133 if (isFirst)
2134 isFirst = false;
2135 else
2136 OS << ',';
2137 OS << I->getName();
2138 }
2139 OS << '>';
2140 }
2141
2142 spaceBeforePlaceHolder(OS);
2143}
2144
2145void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T,
2146 raw_ostream &OS) {}
2147
2148void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
2149 raw_ostream &OS) {
2150 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2151 !T->isKindOfTypeAsWritten())
2152 return printBefore(T->getBaseType(), OS);
2153
2154 if (T->isKindOfTypeAsWritten())
2155 OS << "__kindof ";
2156
2157 print(T->getBaseType(), OS, StringRef());
2158
2159 if (T->isSpecializedAsWritten()) {
2160 bool isFirst = true;
2161 OS << '<';
2162 for (auto typeArg : T->getTypeArgsAsWritten()) {
2163 if (isFirst)
2164 isFirst = false;
2165 else
2166 OS << ",";
2167
2168 print(typeArg, OS, StringRef());
2169 }
2170 OS << '>';
2171 }
2172
2173 if (!T->qual_empty()) {
2174 bool isFirst = true;
2175 OS << '<';
2176 for (const auto *I : T->quals()) {
2177 if (isFirst)
2178 isFirst = false;
2179 else
2180 OS << ',';
2181 OS << I->getName();
2182 }
2183 OS << '>';
2184 }
2185
2186 spaceBeforePlaceHolder(OS);
2187}
2188
2189void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
2190 raw_ostream &OS) {
2191 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2192 !T->isKindOfTypeAsWritten())
2193 return printAfter(T->getBaseType(), OS);
2194}
2195
2196void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
2197 raw_ostream &OS) {
2198 printBefore(T->getPointeeType(), OS);
2199
2200 // If we need to print the pointer, print it now.
2201 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&
2203 if (HasEmptyPlaceHolder)
2204 OS << ' ';
2205 OS << '*';
2206 }
2207}
2208
2209void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
2210 raw_ostream &OS) {}
2211
2212static
2213const TemplateArgument &getArgument(const TemplateArgument &A) { return A; }
2214
2216 return A.getArgument();
2217}
2218
2219static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP,
2220 llvm::raw_ostream &OS, bool IncludeType) {
2221 A.print(PP, OS, IncludeType);
2222}
2223
2225 const PrintingPolicy &PP, llvm::raw_ostream &OS,
2226 bool IncludeType) {
2227 const TemplateArgument::ArgKind &Kind = A.getArgument().getKind();
2229 return A.getTypeSourceInfo()->getType().print(OS, PP);
2230 return A.getArgument().print(PP, OS, IncludeType);
2231}
2232
2234 TemplateArgument Pattern,
2236 unsigned Depth);
2237
2239 ArrayRef<TemplateArgument> Args, unsigned Depth) {
2240 if (Ctx.hasSameType(T, Pattern))
2241 return true;
2242
2243 // A type parameter matches its argument.
2244 if (auto *TTPT = Pattern->getAs<TemplateTypeParmType>()) {
2245 if (TTPT->getDepth() == Depth && TTPT->getIndex() < Args.size() &&
2246 Args[TTPT->getIndex()].getKind() == TemplateArgument::Type) {
2247 QualType SubstArg = Ctx.getQualifiedType(
2248 Args[TTPT->getIndex()].getAsType(), Pattern.getQualifiers());
2249 return Ctx.hasSameType(SubstArg, T);
2250 }
2251 return false;
2252 }
2253
2254 // FIXME: Recurse into array types.
2255
2256 // All other cases will need the types to be identically qualified.
2257 Qualifiers TQual, PatQual;
2258 T = Ctx.getUnqualifiedArrayType(T, TQual);
2259 Pattern = Ctx.getUnqualifiedArrayType(Pattern, PatQual);
2260 if (TQual != PatQual)
2261 return false;
2262
2263 // Recurse into pointer-like types.
2264 {
2265 QualType TPointee = T->getPointeeType();
2266 QualType PPointee = Pattern->getPointeeType();
2267 if (!TPointee.isNull() && !PPointee.isNull())
2268 return T->getTypeClass() == Pattern->getTypeClass() &&
2269 isSubstitutedType(Ctx, TPointee, PPointee, Args, Depth);
2270 }
2271
2272 // Recurse into template specialization types.
2273 if (auto *PTST =
2275 TemplateName Template;
2276 ArrayRef<TemplateArgument> TemplateArgs;
2277 if (auto *TTST = T->getAs<TemplateSpecializationType>()) {
2278 Template = TTST->getTemplateName();
2279 TemplateArgs = TTST->template_arguments();
2280 } else if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
2281 T->getAsCXXRecordDecl())) {
2282 Template = TemplateName(CTSD->getSpecializedTemplate());
2283 TemplateArgs = CTSD->getTemplateArgs().asArray();
2284 } else {
2285 return false;
2286 }
2287
2288 if (!isSubstitutedTemplateArgument(Ctx, Template, PTST->getTemplateName(),
2289 Args, Depth))
2290 return false;
2291 if (TemplateArgs.size() != PTST->template_arguments().size())
2292 return false;
2293 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
2295 Ctx, TemplateArgs[I], PTST->template_arguments()[I], Args, Depth))
2296 return false;
2297 return true;
2298 }
2299
2300 // FIXME: Handle more cases.
2301 return false;
2302}
2303
2304/// Evaluates the expression template argument 'Pattern' and returns true
2305/// if 'Arg' evaluates to the same result.
2307 TemplateArgument const &Pattern,
2308 TemplateArgument const &Arg) {
2309 if (Pattern.getKind() != TemplateArgument::Expression)
2310 return false;
2311
2312 // Can't evaluate value-dependent expressions so bail early
2313 Expr const *pattern_expr = Pattern.getAsExpr();
2314 if (pattern_expr->isValueDependent() ||
2315 !pattern_expr->isIntegerConstantExpr(Ctx))
2316 return false;
2317
2319 return llvm::APSInt::isSameValue(pattern_expr->EvaluateKnownConstInt(Ctx),
2320 Arg.getAsIntegral());
2321
2323 Expr const *args_expr = Arg.getAsExpr();
2324 if (args_expr->isValueDependent() || !args_expr->isIntegerConstantExpr(Ctx))
2325 return false;
2326
2327 return llvm::APSInt::isSameValue(args_expr->EvaluateKnownConstInt(Ctx),
2328 pattern_expr->EvaluateKnownConstInt(Ctx));
2329 }
2330
2331 return false;
2332}
2333
2335 TemplateArgument Pattern,
2337 unsigned Depth) {
2338 Arg = Ctx.getCanonicalTemplateArgument(Arg);
2339 Pattern = Ctx.getCanonicalTemplateArgument(Pattern);
2340 if (Arg.structurallyEquals(Pattern))
2341 return true;
2342
2343 if (Pattern.getKind() == TemplateArgument::Expression) {
2344 if (auto *DRE =
2345 dyn_cast<DeclRefExpr>(Pattern.getAsExpr()->IgnoreParenImpCasts())) {
2346 if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
2347 return NTTP->getDepth() == Depth && Args.size() > NTTP->getIndex() &&
2348 Args[NTTP->getIndex()].structurallyEquals(Arg);
2349 }
2350 }
2351
2352 if (templateArgumentExpressionsEqual(Ctx, Pattern, Arg))
2353 return true;
2354
2355 if (Arg.getKind() != Pattern.getKind())
2356 return false;
2357
2358 if (Arg.getKind() == TemplateArgument::Type)
2359 return isSubstitutedType(Ctx, Arg.getAsType(), Pattern.getAsType(), Args,
2360 Depth);
2361
2362 if (Arg.getKind() == TemplateArgument::Template) {
2363 TemplateDecl *PatTD = Pattern.getAsTemplate().getAsTemplateDecl();
2364 if (auto *TTPD = dyn_cast_or_null<TemplateTemplateParmDecl>(PatTD))
2365 return TTPD->getDepth() == Depth && Args.size() > TTPD->getIndex() &&
2366 Ctx.getCanonicalTemplateArgument(Args[TTPD->getIndex()])
2367 .structurallyEquals(Arg);
2368 }
2369
2370 // FIXME: Handle more cases.
2371 return false;
2372}
2373
2375 const NamedDecl *Param,
2377 unsigned Depth) {
2378 // An empty pack is equivalent to not providing a pack argument.
2379 if (Arg.getKind() == TemplateArgument::Pack && Arg.pack_size() == 0)
2380 return true;
2381
2382 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Param)) {
2383 return TTPD->hasDefaultArgument() &&
2385 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2386 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
2387 return TTPD->hasDefaultArgument() &&
2389 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2390 } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
2391 return NTTPD->hasDefaultArgument() &&
2393 Ctx, Arg, NTTPD->getDefaultArgument().getArgument(), Args,
2394 Depth);
2395 }
2396 return false;
2397}
2398
2399template <typename TA>
2400static void
2401printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy,
2402 const TemplateParameterList *TPL, bool IsPack, unsigned ParmIndex) {
2403 // Drop trailing template arguments that match default arguments.
2404 if (TPL && Policy.SuppressDefaultTemplateArgs &&
2405 !Policy.PrintCanonicalTypes && !Args.empty() && !IsPack &&
2406 Args.size() <= TPL->size()) {
2408 for (const TA &A : Args)
2409 OrigArgs.push_back(getArgument(A));
2410 while (!Args.empty() && getArgument(Args.back()).getIsDefaulted())
2411 Args = Args.drop_back();
2412 }
2413
2414 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
2415 if (!IsPack)
2416 OS << '<';
2417
2418 bool NeedSpace = false;
2419 bool FirstArg = true;
2420 for (const auto &Arg : Args) {
2421 // Print the argument into a string.
2422 SmallString<128> Buf;
2423 llvm::raw_svector_ostream ArgOS(Buf);
2424 const TemplateArgument &Argument = getArgument(Arg);
2425 if (Argument.getKind() == TemplateArgument::Pack) {
2426 if (Argument.pack_size() && !FirstArg)
2427 OS << Comma;
2428 printTo(ArgOS, Argument.getPackAsArray(), Policy, TPL,
2429 /*IsPack*/ true, ParmIndex);
2430 } else {
2431 if (!FirstArg)
2432 OS << Comma;
2433 // Tries to print the argument with location info if exists.
2434 printArgument(Arg, Policy, ArgOS,
2436 Policy, TPL, ParmIndex));
2437 }
2438 StringRef ArgString = ArgOS.str();
2439
2440 // If this is the first argument and its string representation
2441 // begins with the global scope specifier ('::foo'), add a space
2442 // to avoid printing the diagraph '<:'.
2443 if (FirstArg && ArgString.starts_with(":"))
2444 OS << ' ';
2445
2446 OS << ArgString;
2447
2448 // If the last character of our string is '>', add another space to
2449 // keep the two '>''s separate tokens.
2450 if (!ArgString.empty()) {
2451 NeedSpace = Policy.SplitTemplateClosers && ArgString.back() == '>';
2452 FirstArg = false;
2453 }
2454
2455 // Use same template parameter for all elements of Pack
2456 if (!IsPack)
2457 ParmIndex++;
2458 }
2459
2460 if (!IsPack) {
2461 if (NeedSpace)
2462 OS << ' ';
2463 OS << '>';
2464 }
2465}
2466
2468 const TemplateArgumentListInfo &Args,
2469 const PrintingPolicy &Policy,
2470 const TemplateParameterList *TPL) {
2471 printTemplateArgumentList(OS, Args.arguments(), Policy, TPL);
2472}
2473
2476 const PrintingPolicy &Policy,
2477 const TemplateParameterList *TPL) {
2478 printTo(OS, Args, Policy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2479}
2480
2483 const PrintingPolicy &Policy,
2484 const TemplateParameterList *TPL) {
2485 printTo(OS, Args, Policy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2486}
2487
2488std::string Qualifiers::getAsString() const {
2489 LangOptions LO;
2490 return getAsString(PrintingPolicy(LO));
2491}
2492
2493// Appends qualifiers to the given string, separated by spaces. Will
2494// prefix a space if the string is non-empty. Will not append a final
2495// space.
2496std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {
2497 SmallString<64> Buf;
2498 llvm::raw_svector_ostream StrOS(Buf);
2499 print(StrOS, Policy);
2500 return std::string(StrOS.str());
2501}
2502
2504 if (getCVRQualifiers())
2505 return false;
2506
2508 return false;
2509
2510 if (getObjCGCAttr())
2511 return false;
2512
2514 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
2515 return false;
2516
2517 return true;
2518}
2519
2521 switch (AS) {
2522 case LangAS::Default:
2523 return "";
2526 return "__global";
2528 case LangAS::sycl_local:
2529 return "__local";
2532 return "__private";
2534 return "__constant";
2536 return "__generic";
2539 return "__global_device";
2542 return "__global_host";
2544 return "__device__";
2546 return "__constant__";
2548 return "__shared__";
2549 case LangAS::ptr32_sptr:
2550 return "__sptr __ptr32";
2551 case LangAS::ptr32_uptr:
2552 return "__uptr __ptr32";
2553 case LangAS::ptr64:
2554 return "__ptr64";
2556 return "__funcref";
2558 return "groupshared";
2559 default:
2560 return std::to_string(toTargetAddressSpace(AS));
2561 }
2562}
2563
2564// Appends qualifiers to the given string, separated by spaces. Will
2565// prefix a space if the string is non-empty. Will not append a final
2566// space.
2567void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
2568 bool appendSpaceIfNonEmpty) const {
2569 bool addSpace = false;
2570
2571 unsigned quals = getCVRQualifiers();
2572 if (quals) {
2573 AppendTypeQualList(OS, quals, Policy.Restrict);
2574 addSpace = true;
2575 }
2576 if (hasUnaligned()) {
2577 if (addSpace)
2578 OS << ' ';
2579 OS << "__unaligned";
2580 addSpace = true;
2581 }
2582 auto ASStr = getAddrSpaceAsString(getAddressSpace());
2583 if (!ASStr.empty()) {
2584 if (addSpace)
2585 OS << ' ';
2586 addSpace = true;
2587 // Wrap target address space into an attribute syntax
2589 OS << "__attribute__((address_space(" << ASStr << ")))";
2590 else
2591 OS << ASStr;
2592 }
2593
2594 if (Qualifiers::GC gc = getObjCGCAttr()) {
2595 if (addSpace)
2596 OS << ' ';
2597 addSpace = true;
2598 if (gc == Qualifiers::Weak)
2599 OS << "__weak";
2600 else
2601 OS << "__strong";
2602 }
2603 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
2604 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
2605 if (addSpace)
2606 OS << ' ';
2607 addSpace = true;
2608 }
2609
2610 switch (lifetime) {
2611 case Qualifiers::OCL_None: llvm_unreachable("none but true");
2612 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;
2614 if (!Policy.SuppressStrongLifetime)
2615 OS << "__strong";
2616 break;
2617
2618 case Qualifiers::OCL_Weak: OS << "__weak"; break;
2619 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
2620 }
2621 }
2622
2623 if (appendSpaceIfNonEmpty && addSpace)
2624 OS << ' ';
2625}
2626
2627std::string QualType::getAsString() const {
2628 return getAsString(split(), LangOptions());
2629}
2630
2631std::string QualType::getAsString(const PrintingPolicy &Policy) const {
2632 std::string S;
2633 getAsStringInternal(S, Policy);
2634 return S;
2635}
2636
2637std::string QualType::getAsString(const Type *ty, Qualifiers qs,
2638 const PrintingPolicy &Policy) {
2639 std::string buffer;
2640 getAsStringInternal(ty, qs, buffer, Policy);
2641 return buffer;
2642}
2643
2644void QualType::print(raw_ostream &OS, const PrintingPolicy &Policy,
2645 const Twine &PlaceHolder, unsigned Indentation) const {
2646 print(splitAccordingToPolicy(*this, Policy), OS, Policy, PlaceHolder,
2647 Indentation);
2648}
2649
2651 raw_ostream &OS, const PrintingPolicy &policy,
2652 const Twine &PlaceHolder, unsigned Indentation) {
2653 SmallString<128> PHBuf;
2654 StringRef PH = PlaceHolder.toStringRef(PHBuf);
2655
2656 TypePrinter(policy, Indentation).print(ty, qs, OS, PH);
2657}
2658
2659void QualType::getAsStringInternal(std::string &Str,
2660 const PrintingPolicy &Policy) const {
2661 return getAsStringInternal(splitAccordingToPolicy(*this, Policy), Str,
2662 Policy);
2663}
2664
2666 std::string &buffer,
2667 const PrintingPolicy &policy) {
2668 SmallString<256> Buf;
2669 llvm::raw_svector_ostream StrOS(Buf);
2670 TypePrinter(policy).print(ty, qs, StrOS, buffer);
2671 std::string str = std::string(StrOS.str());
2672 buffer.swap(str);
2673}
2674
2675raw_ostream &clang::operator<<(raw_ostream &OS, QualType QT) {
2676 SplitQualType S = QT.split();
2677 TypePrinter(LangOptions()).print(S.Ty, S.Quals, OS, /*PlaceHolder=*/"");
2678 return OS;
2679}
Defines the clang::ASTContext interface.
Provides definitions for the various language-specific address spaces.
Defines the clang::attr::Kind enum.
const Decl * D
Expr * E
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the ExceptionSpecificationType enumeration and various utility functions.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
static void print(llvm::raw_ostream &OS, const T &V, ASTContext &ASTCtx, QualType Ty)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
uint32_t Id
Definition: SemaARM.cpp:1134
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
static void printTo(raw_ostream &OS, ArrayRef< TA > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL, bool IsPack, unsigned ParmIndex)
static const TemplateArgument & getArgument(const TemplateArgument &A)
static bool isSubstitutedType(ASTContext &Ctx, QualType T, QualType Pattern, ArrayRef< TemplateArgument > Args, unsigned Depth)
static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP, llvm::raw_ostream &OS, bool IncludeType)
static QualType skipTopLevelReferences(QualType T)
static void printCountAttributedImpl(const CountAttributedType *T, raw_ostream &OS, const PrintingPolicy &Policy)
static SplitQualType splitAccordingToPolicy(QualType QT, const PrintingPolicy &Policy)
static bool isSubstitutedTemplateArgument(ASTContext &Ctx, TemplateArgument Arg, TemplateArgument Pattern, ArrayRef< TemplateArgument > Args, unsigned Depth)
static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals, bool HasRestrictKeyword)
static bool templateArgumentExpressionsEqual(ASTContext const &Ctx, TemplateArgument const &Pattern, TemplateArgument const &Arg)
Evaluates the expression template argument 'Pattern' and returns true if 'Arg' evaluates to the same ...
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
SourceManager & getSourceManager()
Definition: ASTContext.h:741
TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg) const
Retrieve the "canonical" template argument.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:2732
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
Definition: ASTContext.h:2289
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals) const
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals.
Represents a type which was implicitly adjusted by the semantic engine for arbitrary reasons.
Definition: Type.h:3357
Represents a constant array type that does not decay to a pointer when used as a function parameter.
Definition: Type.h:3747
An attributed type is a type to which a type attribute has been applied.
Definition: Type.h:6132
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Definition: Type.h:6561
A fixed int type of a specified bitwidth.
Definition: Type.h:7819
Pointer to a block type.
Definition: Type.h:3408
This class is used for builtin types like 'int'.
Definition: Type.h:3034
Complex values, per C99 6.2.5p11.
Definition: Type.h:3145
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:3615
Represents a concrete matrix type with constant number of rows and columns.
Definition: Type.h:4232
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
Definition: Type.h:3306
Represents a pointer type decayed from an array or function type.
Definition: Type.h:3391
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1435
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2089
bool isTranslationUnit() const
Definition: DeclBase.h:2165
bool isFunctionOrMethod() const
Definition: DeclBase.h:2141
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:520
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:596
SourceLocation getLocation() const
Definition: DeclBase.h:442
DeclContext * getDeclContext()
Definition: DeclBase.h:451
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
The name of a declaration.
Represents the type decltype(expr) (C++11).
Definition: Type.h:5879
Represents a C++17 deduced template specialization type.
Definition: Type.h:6609
Represents an extended address space qualifier where the input address space value is dependent.
Definition: Type.h:3920
Represents a qualified type name for which the type name is dependent.
Definition: Type.h:7029
Represents an array type in C++ whose size is a value-dependent expression.
Definition: Type.h:3862
Represents an extended vector type where either the type or size is dependent.
Definition: Type.h:3960
Represents a matrix type where the type and the number of rows and columns is dependent on a template...
Definition: Type.h:4291
Represents a template specialization type whose template cannot be resolved, e.g.
Definition: Type.h:7081
Represents a vector type where either the type or size is dependent.
Definition: Type.h:4086
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
Definition: Type.h:6948
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Definition: Type.h:6103
This represents one expression.
Definition: Expr.h:110
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition: Expr.h:175
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition: Expr.cpp:3097
bool isIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
ExtVectorType - Extended vector type.
Definition: Type.h:4126
An immutable set of FunctionEffects and possibly conditions attached to them.
Definition: Type.h:4908
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition: Type.h:4686
Represents a prototype with parameter type info, e.g.
Definition: Type.h:5107
QualType desugar() const
Definition: Type.h:5651
ExtParameterInfo getExtParameterInfo(unsigned I) const
Definition: Type.h:5573
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Definition: Type.h:5387
unsigned getNumParams() const
Definition: Type.h:5360
void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
Definition: Type.h:5500
Qualifiers getMethodQuals() const
Definition: Type.h:5502
QualType getParamType(unsigned i) const
Definition: Type.h:5362
FunctionEffectsRef getFunctionEffects() const
Definition: Type.h:5633
unsigned getAArch64SMEAttributes() const
Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...
Definition: Type.h:5566
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
Definition: Type.h:5438
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition: Type.h:5430
bool hasDynamicExceptionSpec() const
Return whether this function has a dynamic (throw) exception spec.
Definition: Type.h:5396
bool isVariadic() const
Whether this function prototype is variadic.
Definition: Type.h:5484
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
Definition: Type.h:5445
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Definition: Type.h:5510
A class which abstracts out some details necessary for making a call.
Definition: Type.h:4432
CallingConv getCC() const
Definition: Type.h:4494
bool getCmseNSCall() const
Definition: Type.h:4482
bool getNoCfCheck() const
Definition: Type.h:4484
unsigned getRegParm() const
Definition: Type.h:4487
bool getNoCallerSavedRegs() const
Definition: Type.h:4483
bool getNoReturn() const
Definition: Type.h:4480
bool getProducesResult() const
Definition: Type.h:4481
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:4321
ExtInfo getExtInfo() const
Definition: Type.h:4660
static ArmStateValue getArmZT0State(unsigned AttrBits)
Definition: Type.h:4618
static ArmStateValue getArmZAState(unsigned AttrBits)
Definition: Type.h:4614
QualType getReturnType() const
Definition: Type.h:4648
@ SME_PStateSMEnabledMask
Definition: Type.h:4587
@ SME_PStateSMCompatibleMask
Definition: Type.h:4588
@ SME_AgnosticZAStateMask
Definition: Type.h:4598
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Represents a C array with an unspecified size.
Definition: Type.h:3764
The injected class name of a C++ class template or class template partial specialization.
Definition: Type.h:6798
An lvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:3483
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:499
Sugar type that represents a type that was qualified by a qualifier written as a macro invocation.
Definition: Type.h:5770
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition: Type.h:3519
This represents a decl that may have a name.
Definition: Decl.h:253
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:280
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:319
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
Interfaces are the core concept in Objective-C for object oriented design.
Definition: Type.h:7529
Represents a pointer to an Objective C object.
Definition: Type.h:7585
Represents a class type in Objective C.
Definition: Type.h:7331
Represents a type parameter type in Objective C.
Definition: Type.h:7257
Represents a pack expansion of types.
Definition: Type.h:7146
Sugar for parentheses used when specifying types.
Definition: Type.h:3172
PipeType - OpenCL20.
Definition: Type.h:7785
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:3198
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
bool isValid() const
unsigned getLine() const
Return the presumed line number of this location.
A (possibly-)qualified type.
Definition: Type.h:929
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:996
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition: Type.h:7976
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 getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Definition: Type.h:8139
QualType getCanonicalType() const
Definition: Type.h:7988
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
Definition: Type.h:7957
std::string getAsString() const
StreamedQualTypeHelper stream(const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Definition: Type.h:1383
The collection of all-type qualifiers we support.
Definition: Type.h:324
unsigned getCVRQualifiers() const
Definition: Type.h:481
GC getObjCGCAttr() const
Definition: Type.h:512
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Definition: Type.h:354
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
Definition: Type.h:347
@ OCL_None
There is no lifetime qualification on this type.
Definition: Type.h:343
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Definition: Type.h:357
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
Definition: Type.h:360
bool hasUnaligned() const
Definition: Type.h:504
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool appendSpaceIfNonEmpty=false) const
bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const
ObjCLifetime getObjCLifetime() const
Definition: Type.h:538
bool empty() const
Definition: Type.h:640
std::string getAsString() const
LangAS getAddressSpace() const
Definition: Type.h:564
static std::string getAddrSpaceAsString(LangAS AS)
An rvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:3501
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:6077
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3439
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
Represents the result of substituting a set of types for a template type parameter pack.
Definition: Type.h:6469
Represents the result of substituting a type for a template type parameter.
Definition: Type.h:6388
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3578
A convenient class for passing around template argument information.
Definition: TemplateBase.h:632
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
Definition: TemplateBase.h:659
A template argument list.
Definition: DeclTemplate.h:250
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Definition: DeclTemplate.h:280
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:524
const TemplateArgument & getArgument() const
Definition: TemplateBase.h:574
TypeSourceInfo * getTypeSourceInfo() const
Definition: TemplateBase.h:578
Represents a template argument.
Definition: TemplateBase.h:61
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
Definition: TemplateBase.h:444
Expr * getAsExpr() const
Retrieve the template argument as an expression.
Definition: TemplateBase.h:408
QualType getAsType() const
Retrieve the type for a type template argument.
Definition: TemplateBase.h:319
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
Definition: TemplateBase.h:363
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
Definition: TemplateBase.h:343
unsigned pack_size() const
The number of template arguments in the given template argument pack.
Definition: TemplateBase.h:438
bool structurallyEquals(const TemplateArgument &Other) const
Determines whether two template arguments are superficially the same.
void print(const PrintingPolicy &Policy, raw_ostream &Out, bool IncludeType) const
Print this template argument to the given output stream.
bool getIsDefaulted() const
If returns 'true', this TemplateArgument corresponds to a default template parameter.
Definition: TemplateBase.h:393
ArgKind
The kind of template argument we're storing.
Definition: TemplateBase.h:64
@ Template
The template argument is a template name that was provided for a template template parameter.
Definition: TemplateBase.h:93
@ Pack
The template argument is actually a parameter pack.
Definition: TemplateBase.h:107
@ Type
The template argument is a type.
Definition: TemplateBase.h:70
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
Definition: TemplateBase.h:82
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
Definition: TemplateBase.h:103
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:295
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:399
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:418
Represents a C++ template name within the type system.
Definition: TemplateName.h:220
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:73
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: Type.h:6666
Declaration of a template type parameter.
const Type * getTypeForDecl() const
Definition: Decl.h:3409
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
Definition: Type.h:5802
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
Definition: Type.h:5852
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:7918
static StringRef getKeywordName(ElaboratedTypeKeyword Keyword)
Definition: Type.cpp:3248
The base class of the type hierarchy.
Definition: Type.h:1828
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1916
bool isArrayType() const
Definition: Type.h:8263
QualType getLocallyUnqualifiedSingleStepDesugaredType() const
Pull a single level of sugar off of this locally-unqualified type.
Definition: Type.cpp:509
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8805
bool isObjCQualifiedIdType() const
Definition: Type.h:8354
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:738
bool isObjCIdType() const
Definition: Type.h:8366
bool isSpecifierType() const
Returns true if this type can be represented by some set of type specifiers.
Definition: Type.cpp:3133
bool isFunctionType() const
Definition: Type.h:8187
bool isObjCQualifiedClassType() const
Definition: Type.h:8360
bool isObjCClassType() const
Definition: Type.h:8372
TypeClass getTypeClass() const
Definition: Type.h:2341
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8736
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3427
A unary type transform, which is a type constructed from another.
Definition: Type.h:5994
Represents the dependent type named by a dependently-scoped typename using declaration,...
Definition: Type.h:5672
Represents a C array with a specified size that is not an integer-constant-expression.
Definition: Type.h:3808
Represents a GCC generic vector type.
Definition: Type.h:4034
const internal::VariadicAllOfMatcher< Attr > attr
Matches attributes.
The JSON file list parser is used to communicate input to InstallAPI.
@ GNUAutoType
__auto_type (GNU extension)
@ DecltypeAuto
decltype(auto)
llvm::StringRef getParameterABISpelling(ParameterABI kind)
bool isTargetAddressSpace(LangAS AS)
Definition: AddressSpaces.h:77
@ RQ_None
No ref-qualifier was provided.
Definition: Type.h:1768
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
Definition: Type.h:1771
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition: Type.h:1774
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)
Insertion operator for diagnostics.
unsigned toTargetAddressSpace(LangAS AS)
Definition: AddressSpaces.h:81
ParameterABI
Kinds of parameter ABI.
Definition: Specifiers.h:366
@ SwiftAsyncContext
This parameter (which must have pointer type) uses the special Swift asynchronous context-pointer ABI...
@ SwiftErrorResult
This parameter (which must have pointer-to-pointer type) uses the special Swift error-result ABI trea...
@ Ordinary
This parameter uses ordinary ABI rules for its type.
@ SwiftIndirectResult
This parameter (which must have pointer type) is a Swift indirect result parameter.
@ SwiftContext
This parameter (which must have pointer type) uses the special Swift context-pointer ABI treatment.
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
LangAS
Defines the address space values used by the address space qualifier of QualType.
Definition: AddressSpaces.h:25
bool isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg, const NamedDecl *Param, ArrayRef< TemplateArgument > Args, unsigned Depth)
Make a best-effort determination of whether the type T can be produced by substituting Args into the ...
const FunctionProtoType * T
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
Definition: DeclBase.h:1274
@ CC_X86Pascal
Definition: Specifiers.h:284
@ CC_Swift
Definition: Specifiers.h:293
@ CC_IntelOclBicc
Definition: Specifiers.h:290
@ CC_OpenCLKernel
Definition: Specifiers.h:292
@ CC_PreserveMost
Definition: Specifiers.h:295
@ CC_Win64
Definition: Specifiers.h:285
@ CC_X86ThisCall
Definition: Specifiers.h:282
@ CC_AArch64VectorCall
Definition: Specifiers.h:297
@ CC_AAPCS
Definition: Specifiers.h:288
@ CC_PreserveNone
Definition: Specifiers.h:301
@ CC_C
Definition: Specifiers.h:279
@ CC_AMDGPUKernelCall
Definition: Specifiers.h:299
@ CC_M68kRTD
Definition: Specifiers.h:300
@ CC_SwiftAsync
Definition: Specifiers.h:294
@ CC_X86RegCall
Definition: Specifiers.h:287
@ CC_RISCVVectorCall
Definition: Specifiers.h:302
@ CC_X86VectorCall
Definition: Specifiers.h:283
@ CC_SpirFunction
Definition: Specifiers.h:291
@ CC_AArch64SVEPCS
Definition: Specifiers.h:298
@ CC_X86StdCall
Definition: Specifiers.h:280
@ CC_X86_64SysV
Definition: Specifiers.h:286
@ CC_PreserveAll
Definition: Specifiers.h:296
@ CC_X86FastCall
Definition: Specifiers.h:281
@ CC_AAPCS_VFP
Definition: Specifiers.h:289
@ None
No keyword precedes the qualified type name.
@ EST_NoThrow
Microsoft __declspec(nothrow) extension.
@ EST_MSAny
Microsoft throw(...) extension.
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:676
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
Definition: TemplateBase.h:705
llvm::dxil::ResourceClass ResourceClass
Definition: Type.h:6260
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
unsigned MSVCFormatting
Use whitespace and punctuation like MSVC does.
unsigned SuppressDefaultTemplateArgs
When true, attempt to suppress template arguments that match the default argument for the parameter.
unsigned SplitTemplateClosers
Whether nested templates must be closed like 'a<b<c> >' rather than 'a<b<c>>'.
unsigned PrintCanonicalTypes
Whether to print types as written or canonically.
unsigned SuppressSpecifiers
Whether we should suppress printing of the actual specifiers for the given type or declaration.
unsigned SuppressTagKeyword
Whether type printing should skip printing the tag keyword.
unsigned SuppressStrongLifetime
When true, suppress printing of the __strong lifetime qualifier in ARC.
unsigned Restrict
Whether we can use 'restrict' rather than '__restrict'.
unsigned SuppressScope
Suppresses printing of scope specifiers.
unsigned IncludeTagDefinition
When true, include the body of a tag definition.
unsigned SuppressLifetimeQualifiers
When true, suppress printing of lifetime qualifier in ARC.
A std::pair-like structure for storing a qualified type split into its local qualifiers and its local...
Definition: Type.h:862
const Type * Ty
The locally-unqualified type.
Definition: Type.h:864
Qualifiers Quals
The local qualifiers.
Definition: Type.h:867