clang 22.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 printTagType(const TagType *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.PrintAsCanonical)
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::TemplateTypeParm:
234 case Type::SubstTemplateTypeParmPack:
235 case Type::SubstBuiltinTemplatePack:
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 case Type::HLSLInlineSpirv:
251 case Type::PredefinedSugar:
252 CanPrefixQualifiers = true;
253 break;
254
255 case Type::ObjCObjectPointer:
256 CanPrefixQualifiers = T->isObjCIdType() || T->isObjCClassType() ||
258 break;
259
260 case Type::VariableArray:
261 case Type::DependentSizedArray:
262 NeedARCStrongQualifier = true;
263 [[fallthrough]];
264
265 case Type::ConstantArray:
266 case Type::IncompleteArray:
267 return canPrefixQualifiers(
268 cast<ArrayType>(UnderlyingType)->getElementType().getTypePtr(),
269 NeedARCStrongQualifier);
270
271 case Type::Adjusted:
272 case Type::Decayed:
273 case Type::ArrayParameter:
274 case Type::Pointer:
275 case Type::BlockPointer:
276 case Type::LValueReference:
277 case Type::RValueReference:
278 case Type::MemberPointer:
279 case Type::DependentAddressSpace:
280 case Type::DependentVector:
281 case Type::DependentSizedExtVector:
282 case Type::Vector:
283 case Type::ExtVector:
284 case Type::ConstantMatrix:
285 case Type::DependentSizedMatrix:
286 case Type::FunctionProto:
287 case Type::FunctionNoProto:
288 case Type::Paren:
289 case Type::PackExpansion:
290 case Type::SubstTemplateTypeParm:
291 case Type::MacroQualified:
292 case Type::CountAttributed:
293 CanPrefixQualifiers = false;
294 break;
295
296 case Type::Attributed: {
297 // We still want to print the address_space before the type if it is an
298 // address_space attribute.
299 const auto *AttrTy = cast<AttributedType>(UnderlyingType);
300 CanPrefixQualifiers = AttrTy->getAttrKind() == attr::AddressSpace;
301 break;
302 }
303 case Type::PackIndexing: {
304 return canPrefixQualifiers(
305 cast<PackIndexingType>(UnderlyingType)->getPattern().getTypePtr(),
306 NeedARCStrongQualifier);
307 }
308 }
309
310 return CanPrefixQualifiers;
311}
312
313void TypePrinter::printBefore(QualType T, raw_ostream &OS) {
315
316 // If we have cv1 T, where T is substituted for cv2 U, only print cv1 - cv2
317 // at this level.
318 Qualifiers Quals = Split.Quals;
319 if (const auto *Subst = dyn_cast<SubstTemplateTypeParmType>(Split.Ty))
320 Quals -= QualType(Subst, 0).getQualifiers();
321
322 printBefore(Split.Ty, Quals, OS);
323}
324
325/// Prints the part of the type string before an identifier, e.g. for
326/// "int foo[10]" it prints "int ".
327void TypePrinter::printBefore(const Type *T,Qualifiers Quals, raw_ostream &OS) {
328 if (Policy.SuppressSpecifiers && T->isSpecifierType())
329 return;
330
331 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder);
332
333 // Print qualifiers as appropriate.
334
335 bool CanPrefixQualifiers = false;
336 bool NeedARCStrongQualifier = false;
337 CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier);
338
339 if (CanPrefixQualifiers && !Quals.empty()) {
340 if (NeedARCStrongQualifier) {
341 IncludeStrongLifetimeRAII Strong(Policy);
342 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
343 } else {
344 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
345 }
346 }
347
348 bool hasAfterQuals = false;
349 if (!CanPrefixQualifiers && !Quals.empty()) {
350 hasAfterQuals = !Quals.isEmptyWhenPrinted(Policy);
351 if (hasAfterQuals)
352 HasEmptyPlaceHolder = false;
353 }
354
355 switch (T->getTypeClass()) {
356#define ABSTRACT_TYPE(CLASS, PARENT)
357#define TYPE(CLASS, PARENT) case Type::CLASS: \
358 print##CLASS##Before(cast<CLASS##Type>(T), OS); \
359 break;
360#include "clang/AST/TypeNodes.inc"
361 }
362
363 if (hasAfterQuals) {
364 if (NeedARCStrongQualifier) {
365 IncludeStrongLifetimeRAII Strong(Policy);
366 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
367 } else {
368 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
369 }
370 }
371}
372
373void TypePrinter::printAfter(QualType t, raw_ostream &OS) {
374 SplitQualType split = splitAccordingToPolicy(t, Policy);
375 printAfter(split.Ty, split.Quals, OS);
376}
377
378/// Prints the part of the type string after an identifier, e.g. for
379/// "int foo[10]" it prints "[10]".
380void TypePrinter::printAfter(const Type *T, Qualifiers Quals, raw_ostream &OS) {
381 switch (T->getTypeClass()) {
382#define ABSTRACT_TYPE(CLASS, PARENT)
383#define TYPE(CLASS, PARENT) case Type::CLASS: \
384 print##CLASS##After(cast<CLASS##Type>(T), OS); \
385 break;
386#include "clang/AST/TypeNodes.inc"
387 }
388}
389
390void TypePrinter::printBuiltinBefore(const BuiltinType *T, raw_ostream &OS) {
391 OS << T->getName(Policy);
392 spaceBeforePlaceHolder(OS);
393}
394
395void TypePrinter::printBuiltinAfter(const BuiltinType *T, raw_ostream &OS) {}
396
397void TypePrinter::printComplexBefore(const ComplexType *T, raw_ostream &OS) {
398 OS << "_Complex ";
399 printBefore(T->getElementType(), OS);
400}
401
402void TypePrinter::printComplexAfter(const ComplexType *T, raw_ostream &OS) {
403 printAfter(T->getElementType(), OS);
404}
405
406void TypePrinter::printPointerBefore(const PointerType *T, raw_ostream &OS) {
407 IncludeStrongLifetimeRAII Strong(Policy);
408 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
409 printBefore(T->getPointeeType(), OS);
410 // Handle things like 'int (*A)[4];' correctly.
411 // FIXME: this should include vectors, but vectors use attributes I guess.
412 if (isa<ArrayType>(T->getPointeeType()))
413 OS << '(';
414 OS << '*';
415}
416
417void TypePrinter::printPointerAfter(const PointerType *T, raw_ostream &OS) {
418 IncludeStrongLifetimeRAII Strong(Policy);
419 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
420 // Handle things like 'int (*A)[4];' correctly.
421 // FIXME: this should include vectors, but vectors use attributes I guess.
422 if (isa<ArrayType>(T->getPointeeType()))
423 OS << ')';
424 printAfter(T->getPointeeType(), OS);
425}
426
427void TypePrinter::printBlockPointerBefore(const BlockPointerType *T,
428 raw_ostream &OS) {
429 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
430 printBefore(T->getPointeeType(), OS);
431 OS << '^';
432}
433
434void TypePrinter::printBlockPointerAfter(const BlockPointerType *T,
435 raw_ostream &OS) {
436 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
437 printAfter(T->getPointeeType(), OS);
438}
439
440// When printing a reference, the referenced type might also be a reference.
441// If so, we want to skip that before printing the inner type.
443 if (auto *Ref = T->getAs<ReferenceType>())
444 return skipTopLevelReferences(Ref->getPointeeTypeAsWritten());
445 return T;
446}
447
448void TypePrinter::printLValueReferenceBefore(const LValueReferenceType *T,
449 raw_ostream &OS) {
450 IncludeStrongLifetimeRAII Strong(Policy);
451 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
452 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
453 printBefore(Inner, OS);
454 // Handle things like 'int (&A)[4];' correctly.
455 // FIXME: this should include vectors, but vectors use attributes I guess.
456 if (isa<ArrayType>(Inner))
457 OS << '(';
458 OS << '&';
459}
460
461void TypePrinter::printLValueReferenceAfter(const LValueReferenceType *T,
462 raw_ostream &OS) {
463 IncludeStrongLifetimeRAII Strong(Policy);
464 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
465 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
466 // Handle things like 'int (&A)[4];' correctly.
467 // FIXME: this should include vectors, but vectors use attributes I guess.
468 if (isa<ArrayType>(Inner))
469 OS << ')';
470 printAfter(Inner, OS);
471}
472
473void TypePrinter::printRValueReferenceBefore(const RValueReferenceType *T,
474 raw_ostream &OS) {
475 IncludeStrongLifetimeRAII Strong(Policy);
476 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
477 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
478 printBefore(Inner, OS);
479 // Handle things like 'int (&&A)[4];' correctly.
480 // FIXME: this should include vectors, but vectors use attributes I guess.
481 if (isa<ArrayType>(Inner))
482 OS << '(';
483 OS << "&&";
484}
485
486void TypePrinter::printRValueReferenceAfter(const RValueReferenceType *T,
487 raw_ostream &OS) {
488 IncludeStrongLifetimeRAII Strong(Policy);
489 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
490 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
491 // Handle things like 'int (&&A)[4];' correctly.
492 // FIXME: this should include vectors, but vectors use attributes I guess.
493 if (isa<ArrayType>(Inner))
494 OS << ')';
495 printAfter(Inner, OS);
496}
497
498void TypePrinter::printMemberPointerBefore(const MemberPointerType *T,
499 raw_ostream &OS) {
500 IncludeStrongLifetimeRAII Strong(Policy);
501 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
502 printBefore(T->getPointeeType(), OS);
503 // Handle things like 'int (Cls::*A)[4];' correctly.
504 // FIXME: this should include vectors, but vectors use attributes I guess.
505 if (isa<ArrayType>(T->getPointeeType()))
506 OS << '(';
507 T->getQualifier().print(OS, Policy);
508 OS << "*";
509}
510
511void TypePrinter::printMemberPointerAfter(const MemberPointerType *T,
512 raw_ostream &OS) {
513 IncludeStrongLifetimeRAII Strong(Policy);
514 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
515 // Handle things like 'int (Cls::*A)[4];' correctly.
516 // FIXME: this should include vectors, but vectors use attributes I guess.
517 if (isa<ArrayType>(T->getPointeeType()))
518 OS << ')';
519 printAfter(T->getPointeeType(), OS);
520}
521
522void TypePrinter::printConstantArrayBefore(const ConstantArrayType *T,
523 raw_ostream &OS) {
524 IncludeStrongLifetimeRAII Strong(Policy);
525 printBefore(T->getElementType(), OS);
526}
527
528void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T,
529 raw_ostream &OS) {
530 OS << '[';
531 if (T->getIndexTypeQualifiers().hasQualifiers()) {
532 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(),
533 Policy.Restrict);
534 OS << ' ';
535 }
536
537 if (T->getSizeModifier() == ArraySizeModifier::Static)
538 OS << "static ";
539
540 OS << T->getZExtSize() << ']';
541 printAfter(T->getElementType(), OS);
542}
543
544void TypePrinter::printIncompleteArrayBefore(const IncompleteArrayType *T,
545 raw_ostream &OS) {
546 IncludeStrongLifetimeRAII Strong(Policy);
547 printBefore(T->getElementType(), OS);
548}
549
550void TypePrinter::printIncompleteArrayAfter(const IncompleteArrayType *T,
551 raw_ostream &OS) {
552 OS << "[]";
553 printAfter(T->getElementType(), OS);
554}
555
556void TypePrinter::printVariableArrayBefore(const VariableArrayType *T,
557 raw_ostream &OS) {
558 IncludeStrongLifetimeRAII Strong(Policy);
559 printBefore(T->getElementType(), OS);
560}
561
562void TypePrinter::printVariableArrayAfter(const VariableArrayType *T,
563 raw_ostream &OS) {
564 OS << '[';
565 if (T->getIndexTypeQualifiers().hasQualifiers()) {
566 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.Restrict);
567 OS << ' ';
568 }
569
570 if (T->getSizeModifier() == ArraySizeModifier::Static)
571 OS << "static ";
572 else if (T->getSizeModifier() == ArraySizeModifier::Star)
573 OS << '*';
574
575 if (T->getSizeExpr())
576 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
577 OS << ']';
578
579 printAfter(T->getElementType(), OS);
580}
581
582void TypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream &OS) {
583 // Print the adjusted representation, otherwise the adjustment will be
584 // invisible.
585 printBefore(T->getAdjustedType(), OS);
586}
587
588void TypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) {
589 printAfter(T->getAdjustedType(), OS);
590}
591
592void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {
593 // Print as though it's a pointer.
594 printAdjustedBefore(T, OS);
595}
596
597void TypePrinter::printArrayParameterAfter(const ArrayParameterType *T,
598 raw_ostream &OS) {
599 printConstantArrayAfter(T, OS);
600}
601
602void TypePrinter::printArrayParameterBefore(const ArrayParameterType *T,
603 raw_ostream &OS) {
604 printConstantArrayBefore(T, OS);
605}
606
607void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {
608 printAdjustedAfter(T, OS);
609}
610
611void TypePrinter::printDependentSizedArrayBefore(
613 raw_ostream &OS) {
614 IncludeStrongLifetimeRAII Strong(Policy);
615 printBefore(T->getElementType(), OS);
616}
617
618void TypePrinter::printDependentSizedArrayAfter(
620 raw_ostream &OS) {
621 OS << '[';
622 if (T->getSizeExpr())
623 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
624 OS << ']';
625 printAfter(T->getElementType(), OS);
626}
627
628void TypePrinter::printDependentAddressSpaceBefore(
629 const DependentAddressSpaceType *T, raw_ostream &OS) {
630 printBefore(T->getPointeeType(), OS);
631}
632
633void TypePrinter::printDependentAddressSpaceAfter(
634 const DependentAddressSpaceType *T, raw_ostream &OS) {
635 OS << " __attribute__((address_space(";
636 if (T->getAddrSpaceExpr())
637 T->getAddrSpaceExpr()->printPretty(OS, nullptr, Policy);
638 OS << ")))";
639 printAfter(T->getPointeeType(), OS);
640}
641
642void TypePrinter::printDependentSizedExtVectorBefore(
644 raw_ostream &OS) {
645 if (Policy.UseHLSLTypes)
646 OS << "vector<";
647 printBefore(T->getElementType(), OS);
648}
649
650void TypePrinter::printDependentSizedExtVectorAfter(
652 raw_ostream &OS) {
653 if (Policy.UseHLSLTypes) {
654 OS << ", ";
655 if (T->getSizeExpr())
656 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
657 OS << ">";
658 } else {
659 OS << " __attribute__((ext_vector_type(";
660 if (T->getSizeExpr())
661 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
662 OS << ")))";
663 }
664 printAfter(T->getElementType(), OS);
665}
666
667void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {
668 switch (T->getVectorKind()) {
669 case VectorKind::AltiVecPixel:
670 OS << "__vector __pixel ";
671 break;
672 case VectorKind::AltiVecBool:
673 OS << "__vector __bool ";
674 printBefore(T->getElementType(), OS);
675 break;
676 case VectorKind::AltiVecVector:
677 OS << "__vector ";
678 printBefore(T->getElementType(), OS);
679 break;
680 case VectorKind::Neon:
681 OS << "__attribute__((neon_vector_type("
682 << T->getNumElements() << "))) ";
683 printBefore(T->getElementType(), OS);
684 break;
685 case VectorKind::NeonPoly:
686 OS << "__attribute__((neon_polyvector_type(" <<
687 T->getNumElements() << "))) ";
688 printBefore(T->getElementType(), OS);
689 break;
690 case VectorKind::Generic: {
691 // FIXME: We prefer to print the size directly here, but have no way
692 // to get the size of the type.
693 OS << "__attribute__((__vector_size__("
694 << T->getNumElements()
695 << " * sizeof(";
696 print(T->getElementType(), OS, StringRef());
697 OS << ")))) ";
698 printBefore(T->getElementType(), OS);
699 break;
700 }
701 case VectorKind::SveFixedLengthData:
702 case VectorKind::SveFixedLengthPredicate:
703 // FIXME: We prefer to print the size directly here, but have no way
704 // to get the size of the type.
705 OS << "__attribute__((__arm_sve_vector_bits__(";
706
707 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
708 // Predicates take a bit per byte of the vector size, multiply by 8 to
709 // get the number of bits passed to the attribute.
710 OS << T->getNumElements() * 8;
711 else
712 OS << T->getNumElements();
713
714 OS << " * sizeof(";
715 print(T->getElementType(), OS, StringRef());
716 // Multiply by 8 for the number of bits.
717 OS << ") * 8))) ";
718 printBefore(T->getElementType(), OS);
719 break;
720 case VectorKind::RVVFixedLengthData:
721 case VectorKind::RVVFixedLengthMask:
722 case VectorKind::RVVFixedLengthMask_1:
723 case VectorKind::RVVFixedLengthMask_2:
724 case VectorKind::RVVFixedLengthMask_4:
725 // FIXME: We prefer to print the size directly here, but have no way
726 // to get the size of the type.
727 OS << "__attribute__((__riscv_rvv_vector_bits__(";
728
729 OS << T->getNumElements();
730
731 OS << " * sizeof(";
732 print(T->getElementType(), OS, StringRef());
733 // Multiply by 8 for the number of bits.
734 OS << ") * 8))) ";
735 printBefore(T->getElementType(), OS);
736 break;
737 }
738}
739
740void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) {
741 printAfter(T->getElementType(), OS);
742}
743
744void TypePrinter::printDependentVectorBefore(
745 const DependentVectorType *T, raw_ostream &OS) {
746 switch (T->getVectorKind()) {
747 case VectorKind::AltiVecPixel:
748 OS << "__vector __pixel ";
749 break;
750 case VectorKind::AltiVecBool:
751 OS << "__vector __bool ";
752 printBefore(T->getElementType(), OS);
753 break;
754 case VectorKind::AltiVecVector:
755 OS << "__vector ";
756 printBefore(T->getElementType(), OS);
757 break;
758 case VectorKind::Neon:
759 OS << "__attribute__((neon_vector_type(";
760 if (T->getSizeExpr())
761 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
762 OS << "))) ";
763 printBefore(T->getElementType(), OS);
764 break;
765 case VectorKind::NeonPoly:
766 OS << "__attribute__((neon_polyvector_type(";
767 if (T->getSizeExpr())
768 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
769 OS << "))) ";
770 printBefore(T->getElementType(), OS);
771 break;
772 case VectorKind::Generic: {
773 // FIXME: We prefer to print the size directly here, but have no way
774 // to get the size of the type.
775 OS << "__attribute__((__vector_size__(";
776 if (T->getSizeExpr())
777 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
778 OS << " * sizeof(";
779 print(T->getElementType(), OS, StringRef());
780 OS << ")))) ";
781 printBefore(T->getElementType(), OS);
782 break;
783 }
784 case VectorKind::SveFixedLengthData:
785 case VectorKind::SveFixedLengthPredicate:
786 // FIXME: We prefer to print the size directly here, but have no way
787 // to get the size of the type.
788 OS << "__attribute__((__arm_sve_vector_bits__(";
789 if (T->getSizeExpr()) {
790 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
791 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
792 // Predicates take a bit per byte of the vector size, multiply by 8 to
793 // get the number of bits passed to the attribute.
794 OS << " * 8";
795 OS << " * sizeof(";
796 print(T->getElementType(), OS, StringRef());
797 // Multiply by 8 for the number of bits.
798 OS << ") * 8";
799 }
800 OS << "))) ";
801 printBefore(T->getElementType(), OS);
802 break;
803 case VectorKind::RVVFixedLengthData:
804 case VectorKind::RVVFixedLengthMask:
805 case VectorKind::RVVFixedLengthMask_1:
806 case VectorKind::RVVFixedLengthMask_2:
807 case VectorKind::RVVFixedLengthMask_4:
808 // FIXME: We prefer to print the size directly here, but have no way
809 // to get the size of the type.
810 OS << "__attribute__((__riscv_rvv_vector_bits__(";
811 if (T->getSizeExpr()) {
812 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
813 OS << " * sizeof(";
814 print(T->getElementType(), OS, StringRef());
815 // Multiply by 8 for the number of bits.
816 OS << ") * 8";
817 }
818 OS << "))) ";
819 printBefore(T->getElementType(), OS);
820 break;
821 }
822}
823
824void TypePrinter::printDependentVectorAfter(
825 const DependentVectorType *T, raw_ostream &OS) {
826 printAfter(T->getElementType(), OS);
827}
828
829void TypePrinter::printExtVectorBefore(const ExtVectorType *T,
830 raw_ostream &OS) {
831 if (Policy.UseHLSLTypes)
832 OS << "vector<";
833 printBefore(T->getElementType(), OS);
834}
835
836void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) {
837 printAfter(T->getElementType(), OS);
838
839 if (Policy.UseHLSLTypes) {
840 OS << ", ";
841 OS << T->getNumElements();
842 OS << ">";
843 } else {
844 OS << " __attribute__((ext_vector_type(";
845 OS << T->getNumElements();
846 OS << ")))";
847 }
848}
849
850void TypePrinter::printConstantMatrixBefore(const ConstantMatrixType *T,
851 raw_ostream &OS) {
852 printBefore(T->getElementType(), OS);
853 OS << " __attribute__((matrix_type(";
854 OS << T->getNumRows() << ", " << T->getNumColumns();
855 OS << ")))";
856}
857
858void TypePrinter::printConstantMatrixAfter(const ConstantMatrixType *T,
859 raw_ostream &OS) {
860 printAfter(T->getElementType(), OS);
861}
862
863void TypePrinter::printDependentSizedMatrixBefore(
864 const DependentSizedMatrixType *T, raw_ostream &OS) {
865 printBefore(T->getElementType(), OS);
866 OS << " __attribute__((matrix_type(";
867 if (T->getRowExpr()) {
868 T->getRowExpr()->printPretty(OS, nullptr, Policy);
869 }
870 OS << ", ";
871 if (T->getColumnExpr()) {
872 T->getColumnExpr()->printPretty(OS, nullptr, Policy);
873 }
874 OS << ")))";
875}
876
877void TypePrinter::printDependentSizedMatrixAfter(
878 const DependentSizedMatrixType *T, raw_ostream &OS) {
879 printAfter(T->getElementType(), OS);
880}
881
882void
884 const PrintingPolicy &Policy)
885 const {
887 OS << " throw(";
889 OS << "...";
890 else
891 for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) {
892 if (I)
893 OS << ", ";
894
895 OS << getExceptionType(I).stream(Policy);
896 }
897 OS << ')';
898 } else if (EST_NoThrow == getExceptionSpecType()) {
899 OS << " __attribute__((nothrow))";
901 OS << " noexcept";
902 // FIXME:Is it useful to print out the expression for a non-dependent
903 // noexcept specification?
905 OS << '(';
906 if (getNoexceptExpr())
907 getNoexceptExpr()->printPretty(OS, nullptr, Policy);
908 OS << ')';
909 }
910 }
911}
912
913void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,
914 raw_ostream &OS) {
915 if (T->hasTrailingReturn()) {
916 OS << "auto ";
917 if (!HasEmptyPlaceHolder)
918 OS << '(';
919 } else {
920 // If needed for precedence reasons, wrap the inner part in grouping parens.
921 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
922 printBefore(T->getReturnType(), OS);
923 if (!PrevPHIsEmpty.get())
924 OS << '(';
925 }
926}
927
929 switch (ABI) {
931 llvm_unreachable("asking for spelling of ordinary parameter ABI");
933 return "swift_context";
935 return "swift_async_context";
937 return "swift_error_result";
939 return "swift_indirect_result";
941 return "out";
943 return "inout";
944 }
945 llvm_unreachable("bad parameter ABI kind");
946}
947
948void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
949 raw_ostream &OS) {
950 // If needed for precedence reasons, wrap the inner part in grouping parens.
951 if (!HasEmptyPlaceHolder)
952 OS << ')';
953 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
954
955 OS << '(';
956 {
957 ParamPolicyRAII ParamPolicy(Policy);
958 for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {
959 if (i) OS << ", ";
960
961 auto EPI = T->getExtParameterInfo(i);
962 if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) ";
963 if (EPI.isNoEscape())
964 OS << "__attribute__((noescape)) ";
965 auto ABI = EPI.getABI();
966 if (ABI == ParameterABI::HLSLInOut || ABI == ParameterABI::HLSLOut) {
967 OS << getParameterABISpelling(ABI) << " ";
968 if (Policy.UseHLSLTypes) {
969 // This is a bit of a hack because we _do_ use reference types in the
970 // AST for representing inout and out parameters so that code
971 // generation is sane, but when re-printing these for HLSL we need to
972 // skip the reference.
973 print(T->getParamType(i).getNonReferenceType(), OS, StringRef());
974 continue;
975 }
976 } else if (ABI != ParameterABI::Ordinary)
977 OS << "__attribute__((" << getParameterABISpelling(ABI) << ")) ";
978
979 print(T->getParamType(i), OS, StringRef());
980 }
981 }
982
983 if (T->isVariadic()) {
984 if (T->getNumParams())
985 OS << ", ";
986 OS << "...";
987 } else if (T->getNumParams() == 0 && Policy.UseVoidForZeroParams) {
988 // Do not emit int() if we have a proto, emit 'int(void)'.
989 OS << "void";
990 }
991
992 OS << ')';
993
995 unsigned SMEBits = T->getAArch64SMEAttributes();
996
998 OS << " __arm_streaming_compatible";
1000 OS << " __arm_streaming";
1002 OS << "__arm_agnostic(\"sme_za_state\")";
1004 OS << " __arm_preserves(\"za\")";
1006 OS << " __arm_in(\"za\")";
1008 OS << " __arm_out(\"za\")";
1010 OS << " __arm_inout(\"za\")";
1012 OS << " __arm_preserves(\"zt0\")";
1014 OS << " __arm_in(\"zt0\")";
1016 OS << " __arm_out(\"zt0\")";
1018 OS << " __arm_inout(\"zt0\")";
1019
1020 printFunctionAfter(Info, OS);
1021
1022 if (!T->getMethodQuals().empty())
1023 OS << " " << T->getMethodQuals().getAsString();
1024
1025 switch (T->getRefQualifier()) {
1026 case RQ_None:
1027 break;
1028
1029 case RQ_LValue:
1030 OS << " &";
1031 break;
1032
1033 case RQ_RValue:
1034 OS << " &&";
1035 break;
1036 }
1037 T->printExceptionSpecification(OS, Policy);
1038
1040 for (const auto &CFE : FX) {
1041 OS << " __attribute__((" << CFE.Effect.name();
1042 if (const Expr *E = CFE.Cond.getCondition()) {
1043 OS << '(';
1044 E->printPretty(OS, nullptr, Policy);
1045 OS << ')';
1046 }
1047 OS << "))";
1048 }
1049
1050 if (T->hasCFIUncheckedCallee())
1051 OS << " __attribute__((cfi_unchecked_callee))";
1052
1053 if (T->hasTrailingReturn()) {
1054 OS << " -> ";
1055 print(T->getReturnType(), OS, StringRef());
1056 } else
1057 printAfter(T->getReturnType(), OS);
1058}
1059
1060void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
1061 raw_ostream &OS) {
1062 if (!InsideCCAttribute) {
1063 switch (Info.getCC()) {
1064 case CC_C:
1065 // The C calling convention is the default on the vast majority of platforms
1066 // we support. If the user wrote it explicitly, it will usually be printed
1067 // while traversing the AttributedType. If the type has been desugared, let
1068 // the canonical spelling be the implicit calling convention.
1069 // FIXME: It would be better to be explicit in certain contexts, such as a
1070 // cdecl function typedef used to declare a member function with the
1071 // Microsoft C++ ABI.
1072 break;
1073 case CC_X86StdCall:
1074 OS << " __attribute__((stdcall))";
1075 break;
1076 case CC_X86FastCall:
1077 OS << " __attribute__((fastcall))";
1078 break;
1079 case CC_X86ThisCall:
1080 OS << " __attribute__((thiscall))";
1081 break;
1082 case CC_X86VectorCall:
1083 OS << " __attribute__((vectorcall))";
1084 break;
1085 case CC_X86Pascal:
1086 OS << " __attribute__((pascal))";
1087 break;
1088 case CC_AAPCS:
1089 OS << " __attribute__((pcs(\"aapcs\")))";
1090 break;
1091 case CC_AAPCS_VFP:
1092 OS << " __attribute__((pcs(\"aapcs-vfp\")))";
1093 break;
1095 OS << " __attribute__((aarch64_vector_pcs))";
1096 break;
1097 case CC_AArch64SVEPCS:
1098 OS << " __attribute__((aarch64_sve_pcs))";
1099 break;
1100 case CC_DeviceKernel:
1101 OS << " __attribute__((device_kernel))";
1102 break;
1103 case CC_IntelOclBicc:
1104 OS << " __attribute__((intel_ocl_bicc))";
1105 break;
1106 case CC_Win64:
1107 OS << " __attribute__((ms_abi))";
1108 break;
1109 case CC_X86_64SysV:
1110 OS << " __attribute__((sysv_abi))";
1111 break;
1112 case CC_X86RegCall:
1113 OS << " __attribute__((regcall))";
1114 break;
1115 case CC_SpirFunction:
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#define CC_VLS_CASE(ABI_VLEN) \
1140 case CC_RISCVVLSCall_##ABI_VLEN: \
1141 OS << "__attribute__((riscv_vls_cc" #ABI_VLEN "))"; \
1142 break;
1143 CC_VLS_CASE(32)
1144 CC_VLS_CASE(64)
1145 CC_VLS_CASE(128)
1146 CC_VLS_CASE(256)
1147 CC_VLS_CASE(512)
1148 CC_VLS_CASE(1024)
1149 CC_VLS_CASE(2048)
1150 CC_VLS_CASE(4096)
1151 CC_VLS_CASE(8192)
1152 CC_VLS_CASE(16384)
1153 CC_VLS_CASE(32768)
1154 CC_VLS_CASE(65536)
1155#undef CC_VLS_CASE
1156 }
1157 }
1158
1159 if (Info.getNoReturn())
1160 OS << " __attribute__((noreturn))";
1161 if (Info.getCmseNSCall())
1162 OS << " __attribute__((cmse_nonsecure_call))";
1163 if (Info.getProducesResult())
1164 OS << " __attribute__((ns_returns_retained))";
1165 if (Info.getRegParm())
1166 OS << " __attribute__((regparm ("
1167 << Info.getRegParm() << ")))";
1168 if (Info.getNoCallerSavedRegs())
1169 OS << " __attribute__((no_caller_saved_registers))";
1170 if (Info.getNoCfCheck())
1171 OS << " __attribute__((nocf_check))";
1172}
1173
1174void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T,
1175 raw_ostream &OS) {
1176 // If needed for precedence reasons, wrap the inner part in grouping parens.
1177 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
1178 printBefore(T->getReturnType(), OS);
1179 if (!PrevPHIsEmpty.get())
1180 OS << '(';
1181}
1182
1183void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,
1184 raw_ostream &OS) {
1185 // If needed for precedence reasons, wrap the inner part in grouping parens.
1186 if (!HasEmptyPlaceHolder)
1187 OS << ')';
1188 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
1189
1190 OS << "()";
1191 printFunctionAfter(T->getExtInfo(), OS);
1192 printAfter(T->getReturnType(), OS);
1193}
1194
1195void TypePrinter::printTypeSpec(NamedDecl *D, raw_ostream &OS) {
1196
1197 // Compute the full nested-name-specifier for this type.
1198 // In C, this will always be empty except when the type
1199 // being printed is anonymous within other Record.
1200 if (!Policy.SuppressScope)
1201 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1202
1203 IdentifierInfo *II = D->getIdentifier();
1204 OS << II->getName();
1205 spaceBeforePlaceHolder(OS);
1206}
1207
1208void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,
1209 raw_ostream &OS) {
1210 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1211 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1212 OS << ' ';
1213 auto *D = T->getDecl();
1214 if (Policy.FullyQualifiedName || T->isCanonicalUnqualified()) {
1215 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1216 } else {
1217 T->getQualifier().print(OS, Policy);
1218 }
1219 OS << D->getIdentifier()->getName();
1220 spaceBeforePlaceHolder(OS);
1221}
1222
1223void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,
1224 raw_ostream &OS) {}
1225
1226void TypePrinter::printUsingBefore(const UsingType *T, raw_ostream &OS) {
1227 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1228 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1229 OS << ' ';
1230 auto *D = T->getDecl();
1231 if (Policy.FullyQualifiedName) {
1232 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1233 } else {
1234 T->getQualifier().print(OS, Policy);
1235 }
1236 OS << D->getIdentifier()->getName();
1237 spaceBeforePlaceHolder(OS);
1238}
1239
1240void TypePrinter::printUsingAfter(const UsingType *T, raw_ostream &OS) {}
1241
1242void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
1243 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1244 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1245 OS << ' ';
1246 auto *D = T->getDecl();
1247 if (Policy.FullyQualifiedName) {
1248 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1249 } else {
1250 T->getQualifier().print(OS, Policy);
1251 }
1252 OS << D->getIdentifier()->getName();
1253 spaceBeforePlaceHolder(OS);
1254}
1255
1256void TypePrinter::printMacroQualifiedBefore(const MacroQualifiedType *T,
1257 raw_ostream &OS) {
1258 StringRef MacroName = T->getMacroIdentifier()->getName();
1259 OS << MacroName << " ";
1260
1261 // Since this type is meant to print the macro instead of the whole attribute,
1262 // we trim any attributes and go directly to the original modified type.
1263 printBefore(T->getModifiedType(), OS);
1264}
1265
1266void TypePrinter::printMacroQualifiedAfter(const MacroQualifiedType *T,
1267 raw_ostream &OS) {
1268 printAfter(T->getModifiedType(), OS);
1269}
1270
1271void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) {}
1272
1273void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
1274 raw_ostream &OS) {
1275 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual "
1276 : "typeof ");
1277 if (T->getUnderlyingExpr())
1278 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
1279 spaceBeforePlaceHolder(OS);
1280}
1281
1282void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
1283 raw_ostream &OS) {}
1284
1285void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) {
1286 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual("
1287 : "typeof(");
1288 print(T->getUnmodifiedType(), OS, StringRef());
1289 OS << ')';
1290 spaceBeforePlaceHolder(OS);
1291}
1292
1293void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) {}
1294
1295void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {
1296 OS << "decltype(";
1297 if (const Expr *E = T->getUnderlyingExpr()) {
1298 PrintingPolicy ExprPolicy = Policy;
1300 E->printPretty(OS, nullptr, ExprPolicy);
1301 }
1302 OS << ')';
1303 spaceBeforePlaceHolder(OS);
1304}
1305
1306void TypePrinter::printPackIndexingBefore(const PackIndexingType *T,
1307 raw_ostream &OS) {
1308 if (T->hasSelectedType()) {
1309 OS << T->getSelectedType();
1310 } else {
1311 OS << T->getPattern() << "...[";
1312 T->getIndexExpr()->printPretty(OS, nullptr, Policy);
1313 OS << "]";
1314 }
1315 spaceBeforePlaceHolder(OS);
1316}
1317
1318void TypePrinter::printPackIndexingAfter(const PackIndexingType *T,
1319 raw_ostream &OS) {}
1320
1321void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) {}
1322
1323void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,
1324 raw_ostream &OS) {
1325 IncludeStrongLifetimeRAII Strong(Policy);
1326
1327 static llvm::DenseMap<int, const char *> Transformation = {{
1328#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
1329 {UnaryTransformType::Enum, "__" #Trait},
1330#include "clang/Basic/TransformTypeTraits.def"
1331 }};
1332 OS << Transformation[T->getUTTKind()] << '(';
1333 print(T->getBaseType(), OS, StringRef());
1334 OS << ')';
1335 spaceBeforePlaceHolder(OS);
1336}
1337
1338void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,
1339 raw_ostream &OS) {}
1340
1341void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
1342 // If the type has been deduced, do not print 'auto'.
1343 if (!T->getDeducedType().isNull()) {
1344 printBefore(T->getDeducedType(), OS);
1345 } else {
1346 if (T->isConstrained()) {
1347 // FIXME: Track a TypeConstraint as type sugar, so that we can print the
1348 // type as it was written.
1349 T->getTypeConstraintConcept()->getDeclName().print(OS, Policy);
1350 auto Args = T->getTypeConstraintArguments();
1351 if (!Args.empty())
1353 OS, Args, Policy,
1354 T->getTypeConstraintConcept()->getTemplateParameters());
1355 OS << ' ';
1356 }
1357 switch (T->getKeyword()) {
1358 case AutoTypeKeyword::Auto: OS << "auto"; break;
1359 case AutoTypeKeyword::DecltypeAuto: OS << "decltype(auto)"; break;
1360 case AutoTypeKeyword::GNUAutoType: OS << "__auto_type"; break;
1361 }
1362 spaceBeforePlaceHolder(OS);
1363 }
1364}
1365
1366void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {
1367 // If the type has been deduced, do not print 'auto'.
1368 if (!T->getDeducedType().isNull())
1369 printAfter(T->getDeducedType(), OS);
1370}
1371
1372void TypePrinter::printDeducedTemplateSpecializationBefore(
1373 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1374 if (ElaboratedTypeKeyword Keyword = T->getKeyword();
1375 T->getKeyword() != ElaboratedTypeKeyword::None)
1377
1378 TemplateName Name = T->getTemplateName();
1379
1380 // If the type has been deduced, print the template arguments, as if this was
1381 // printing the deduced type, but including elaboration and template name
1382 // qualification.
1383 // FIXME: There should probably be a policy which controls this.
1384 // We would probably want to do this on diagnostics, but not on -ast-print.
1386 TemplateDecl *DeducedTD = nullptr;
1387 if (!T->getDeducedType().isNull()) {
1388 if (const auto *TST =
1389 dyn_cast<TemplateSpecializationType>(T->getDeducedType())) {
1390 DeducedTD = TST->getTemplateName().getAsTemplateDecl(
1391 /*IgnoreDeduced=*/true);
1392 Args = TST->template_arguments();
1393 } else {
1394 // Should only get here for canonical types.
1395 const auto *CD = cast<ClassTemplateSpecializationDecl>(
1396 cast<RecordType>(T->getDeducedType())->getOriginalDecl());
1397 DeducedTD = CD->getSpecializedTemplate();
1398 Args = CD->getTemplateArgs().asArray();
1399 }
1400
1401 // FIXME: Workaround for alias template CTAD not producing guides which
1402 // include the alias template specialization type.
1403 // Purposefully disregard qualification when building this TemplateName;
1404 // any qualification we might have, might not make sense in the
1405 // context this was deduced.
1406 if (!declaresSameEntity(DeducedTD, Name.getAsTemplateDecl(
1407 /*IgnoreDeduced=*/true)))
1408 Name = TemplateName(DeducedTD);
1409 }
1410
1411 {
1412 IncludeStrongLifetimeRAII Strong(Policy);
1413 Name.print(OS, Policy);
1414 }
1415 if (DeducedTD) {
1416 printTemplateArgumentList(OS, Args, Policy,
1417 DeducedTD->getTemplateParameters());
1418 }
1419
1420 spaceBeforePlaceHolder(OS);
1421}
1422
1423void TypePrinter::printDeducedTemplateSpecializationAfter(
1424 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1425 // If the type has been deduced, print the deduced type.
1426 if (!T->getDeducedType().isNull())
1427 printAfter(T->getDeducedType(), OS);
1428}
1429
1430void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {
1431 IncludeStrongLifetimeRAII Strong(Policy);
1432
1433 OS << "_Atomic(";
1434 print(T->getValueType(), OS, StringRef());
1435 OS << ')';
1436 spaceBeforePlaceHolder(OS);
1437}
1438
1439void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) {}
1440
1441void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) {
1442 IncludeStrongLifetimeRAII Strong(Policy);
1443
1444 if (T->isReadOnly())
1445 OS << "read_only ";
1446 else
1447 OS << "write_only ";
1448 OS << "pipe ";
1449 print(T->getElementType(), OS, StringRef());
1450 spaceBeforePlaceHolder(OS);
1451}
1452
1453void TypePrinter::printPipeAfter(const PipeType *T, raw_ostream &OS) {}
1454
1455void TypePrinter::printBitIntBefore(const BitIntType *T, raw_ostream &OS) {
1456 if (T->isUnsigned())
1457 OS << "unsigned ";
1458 OS << "_BitInt(" << T->getNumBits() << ")";
1459 spaceBeforePlaceHolder(OS);
1460}
1461
1462void TypePrinter::printBitIntAfter(const BitIntType *T, raw_ostream &OS) {}
1463
1464void TypePrinter::printDependentBitIntBefore(const DependentBitIntType *T,
1465 raw_ostream &OS) {
1466 if (T->isUnsigned())
1467 OS << "unsigned ";
1468 OS << "_BitInt(";
1469 T->getNumBitsExpr()->printPretty(OS, nullptr, Policy);
1470 OS << ")";
1471 spaceBeforePlaceHolder(OS);
1472}
1473
1474void TypePrinter::printDependentBitIntAfter(const DependentBitIntType *T,
1475 raw_ostream &OS) {}
1476
1477void TypePrinter::printPredefinedSugarBefore(const PredefinedSugarType *T,
1478 raw_ostream &OS) {
1479 OS << T->getIdentifier()->getName();
1480 spaceBeforePlaceHolder(OS);
1481}
1482
1483void TypePrinter::printPredefinedSugarAfter(const PredefinedSugarType *T,
1484 raw_ostream &OS) {}
1485
1486/// Appends the given scope to the end of a string.
1487void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS,
1488 DeclarationName NameInScope) {
1489 if (DC->isTranslationUnit())
1490 return;
1491
1492 // FIXME: Consider replacing this with NamedDecl::printNestedNameSpecifier,
1493 // which can also print names for function and method scopes.
1494 if (DC->isFunctionOrMethod())
1495 return;
1496
1497 if (Policy.Callbacks && Policy.Callbacks->isScopeVisible(DC))
1498 return;
1499
1500 if (const auto *NS = dyn_cast<NamespaceDecl>(DC)) {
1501 if (Policy.SuppressUnwrittenScope && NS->isAnonymousNamespace())
1502 return AppendScope(DC->getParent(), OS, NameInScope);
1503
1504 // Only suppress an inline namespace if the name has the same lookup
1505 // results in the enclosing namespace.
1506 if (Policy.SuppressInlineNamespace !=
1508 NS->isInline() && NameInScope &&
1509 NS->isRedundantInlineQualifierFor(NameInScope))
1510 return AppendScope(DC->getParent(), OS, NameInScope);
1511
1512 AppendScope(DC->getParent(), OS, NS->getDeclName());
1513 if (NS->getIdentifier())
1514 OS << NS->getName() << "::";
1515 else
1516 OS << "(anonymous namespace)::";
1517 } else if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
1518 AppendScope(DC->getParent(), OS, Spec->getDeclName());
1519 IncludeStrongLifetimeRAII Strong(Policy);
1520 OS << Spec->getIdentifier()->getName();
1521 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
1523 OS, TemplateArgs.asArray(), Policy,
1524 Spec->getSpecializedTemplate()->getTemplateParameters());
1525 OS << "::";
1526 } else if (const auto *Tag = dyn_cast<TagDecl>(DC)) {
1527 AppendScope(DC->getParent(), OS, Tag->getDeclName());
1528 if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl())
1529 OS << Typedef->getIdentifier()->getName() << "::";
1530 else if (Tag->getIdentifier())
1531 OS << Tag->getIdentifier()->getName() << "::";
1532 else
1533 return;
1534 } else {
1535 AppendScope(DC->getParent(), OS, NameInScope);
1536 }
1537}
1538
1539void TypePrinter::printTagType(const TagType *T, raw_ostream &OS) {
1540 TagDecl *D = T->getOriginalDecl();
1541
1542 if (Policy.IncludeTagDefinition && T->isTagOwned()) {
1543 D->print(OS, Policy, Indentation);
1544 spaceBeforePlaceHolder(OS);
1545 return;
1546 }
1547
1548 bool HasKindDecoration = false;
1549
1550 if (T->isCanonicalUnqualified()) {
1551 if (!Policy.SuppressTagKeyword && !D->getTypedefNameForAnonDecl()) {
1552 HasKindDecoration = true;
1553 OS << D->getKindName();
1554 OS << ' ';
1555 }
1556 } else {
1557 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1558 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1559 OS << ' ';
1560 }
1561
1562 if (!Policy.FullyQualifiedName && !T->isCanonicalUnqualified()) {
1563 T->getQualifier().print(OS, Policy);
1564 } else if (!Policy.SuppressScope) {
1565 // Compute the full nested-name-specifier for this type.
1566 // In C, this will always be empty except when the type
1567 // being printed is anonymous within other Record.
1568 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1569 }
1570
1571 if (const IdentifierInfo *II = D->getIdentifier())
1572 OS << II->getName();
1573 else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) {
1574 assert(Typedef->getIdentifier() && "Typedef without identifier?");
1575 OS << Typedef->getIdentifier()->getName();
1576 } else {
1577 // Make an unambiguous representation for anonymous types, e.g.
1578 // (anonymous enum at /usr/include/string.h:120:9)
1579 OS << (Policy.MSVCFormatting ? '`' : '(');
1580
1581 if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
1582 OS << "lambda";
1583 HasKindDecoration = true;
1584 } else if ((isa<RecordDecl>(D) && cast<RecordDecl>(D)->isAnonymousStructOrUnion())) {
1585 OS << "anonymous";
1586 } else {
1587 OS << "unnamed";
1588 }
1589
1590 if (Policy.AnonymousTagLocations) {
1591 // Suppress the redundant tag keyword if we just printed one.
1592 // We don't have to worry about ElaboratedTypes here because you can't
1593 // refer to an anonymous type with one.
1594 if (!HasKindDecoration)
1595 OS << " " << D->getKindName();
1596
1598 D->getLocation());
1599 if (PLoc.isValid()) {
1600 OS << " at ";
1601 StringRef File = PLoc.getFilename();
1602 llvm::SmallString<1024> WrittenFile(File);
1603 if (auto *Callbacks = Policy.Callbacks)
1604 WrittenFile = Callbacks->remapPath(File);
1605 // Fix inconsistent path separator created by
1606 // clang::DirectoryLookup::LookupFile when the file path is relative
1607 // path.
1608 llvm::sys::path::Style Style =
1609 llvm::sys::path::is_absolute(WrittenFile)
1610 ? llvm::sys::path::Style::native
1611 : (Policy.MSVCFormatting
1612 ? llvm::sys::path::Style::windows_backslash
1613 : llvm::sys::path::Style::posix);
1614 llvm::sys::path::native(WrittenFile, Style);
1615 OS << WrittenFile << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
1616 }
1617 }
1618
1619 OS << (Policy.MSVCFormatting ? '\'' : ')');
1620 }
1621
1622 // If this is a class template specialization, print the template
1623 // arguments.
1624 if (auto *S = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1625 const TemplateParameterList *TParams =
1626 S->getSpecializedTemplate()->getTemplateParameters();
1627 const ASTTemplateArgumentListInfo *TArgAsWritten =
1628 S->getTemplateArgsAsWritten();
1629 IncludeStrongLifetimeRAII Strong(Policy);
1630 if (TArgAsWritten && !Policy.PrintAsCanonical)
1631 printTemplateArgumentList(OS, TArgAsWritten->arguments(), Policy,
1632 TParams);
1633 else
1634 printTemplateArgumentList(OS, S->getTemplateArgs().asArray(), Policy,
1635 TParams);
1636 }
1637
1638 spaceBeforePlaceHolder(OS);
1639}
1640
1641void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
1642 // Print the preferred name if we have one for this type.
1643 if (Policy.UsePreferredNames) {
1644 for (const auto *PNA : T->getOriginalDecl()
1645 ->getMostRecentDecl()
1646 ->specific_attrs<PreferredNameAttr>()) {
1647 if (!declaresSameEntity(PNA->getTypedefType()->getAsCXXRecordDecl(),
1648 T->getOriginalDecl()))
1649 continue;
1650 // Find the outermost typedef or alias template.
1651 QualType T = PNA->getTypedefType();
1652 while (true) {
1653 if (auto *TT = dyn_cast<TypedefType>(T))
1654 return printTypeSpec(TT->getDecl(), OS);
1655 if (auto *TST = dyn_cast<TemplateSpecializationType>(T))
1656 return printTemplateId(TST, OS, /*FullyQualify=*/true);
1658 }
1659 }
1660 }
1661
1662 printTagType(T, OS);
1663}
1664
1665void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) {}
1666
1667void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {
1668 printTagType(T, OS);
1669}
1670
1671void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {}
1672
1673void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
1674 raw_ostream &OS) {
1675 const ASTContext &Ctx = T->getOriginalDecl()->getASTContext();
1676 IncludeStrongLifetimeRAII Strong(Policy);
1677 T->getTemplateName(Ctx).print(OS, Policy);
1678 if (Policy.PrintInjectedClassNameWithArguments) {
1679 auto *Decl = T->getOriginalDecl();
1680 // FIXME: Use T->getTemplateArgs(Ctx) when that supports as-written
1681 // arguments.
1682 if (auto *RD = dyn_cast<ClassTemplateSpecializationDecl>(Decl)) {
1683 printTemplateArgumentList(OS, RD->getTemplateArgsAsWritten()->arguments(),
1684 Policy,
1685 T->getTemplateDecl()->getTemplateParameters());
1686 } else {
1687 ClassTemplateDecl *TD = Decl->getDescribedClassTemplate();
1688 assert(TD);
1690 OS, TD->getTemplateParameters()->getInjectedTemplateArgs(Ctx), Policy,
1691 T->getTemplateDecl()->getTemplateParameters());
1692 }
1693 }
1694 spaceBeforePlaceHolder(OS);
1695}
1696
1697void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
1698 raw_ostream &OS) {}
1699
1700void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
1701 raw_ostream &OS) {
1702 TemplateTypeParmDecl *D = T->getDecl();
1703 if (D && D->isImplicit()) {
1704 if (auto *TC = D->getTypeConstraint()) {
1705 TC->print(OS, Policy);
1706 OS << ' ';
1707 }
1708 OS << "auto";
1709 } else if (IdentifierInfo *Id = T->getIdentifier())
1710 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1711 : Id->getName());
1712 else
1713 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
1714
1715 spaceBeforePlaceHolder(OS);
1716}
1717
1718void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,
1719 raw_ostream &OS) {}
1720
1721void TypePrinter::printSubstTemplateTypeParmBefore(
1723 raw_ostream &OS) {
1724 IncludeStrongLifetimeRAII Strong(Policy);
1725 printBefore(T->getReplacementType(), OS);
1726}
1727
1728void TypePrinter::printSubstTemplateTypeParmAfter(
1730 raw_ostream &OS) {
1731 IncludeStrongLifetimeRAII Strong(Policy);
1732 printAfter(T->getReplacementType(), OS);
1733}
1734
1735void TypePrinter::printSubstBuiltinTemplatePackBefore(
1736 const SubstBuiltinTemplatePackType *T, raw_ostream &OS) {
1737 IncludeStrongLifetimeRAII Strong(Policy);
1738 OS << "type-pack";
1739}
1740
1741void TypePrinter::printSubstBuiltinTemplatePackAfter(
1742 const SubstBuiltinTemplatePackType *T, raw_ostream &OS) {}
1743
1744void TypePrinter::printSubstTemplateTypeParmPackBefore(
1746 raw_ostream &OS) {
1747 IncludeStrongLifetimeRAII Strong(Policy);
1748 if (const TemplateTypeParmDecl *D = T->getReplacedParameter()) {
1749 if (D && D->isImplicit()) {
1750 if (auto *TC = D->getTypeConstraint()) {
1751 TC->print(OS, Policy);
1752 OS << ' ';
1753 }
1754 OS << "auto";
1755 } else if (IdentifierInfo *Id = D->getIdentifier())
1756 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1757 : Id->getName());
1758 else
1759 OS << "type-parameter-" << D->getDepth() << '-' << D->getIndex();
1760
1761 spaceBeforePlaceHolder(OS);
1762 }
1763}
1764
1765void TypePrinter::printSubstTemplateTypeParmPackAfter(
1767 raw_ostream &OS) {
1768 IncludeStrongLifetimeRAII Strong(Policy);
1769}
1770
1771void TypePrinter::printTemplateId(const TemplateSpecializationType *T,
1772 raw_ostream &OS, bool FullyQualify) {
1773 IncludeStrongLifetimeRAII Strong(Policy);
1774
1775 if (ElaboratedTypeKeyword K = T->getKeyword();
1777 OS << TypeWithKeyword::getKeywordName(K) << ' ';
1778
1779 TemplateDecl *TD =
1780 T->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true);
1781 // FIXME: Null TD never exercised in test suite.
1782 if (FullyQualify && TD) {
1783 if (!Policy.SuppressScope)
1784 AppendScope(TD->getDeclContext(), OS, TD->getDeclName());
1785
1786 OS << TD->getName();
1787 } else {
1788 T->getTemplateName().print(OS, Policy,
1789 !Policy.SuppressScope
1792 }
1793
1794 DefaultTemplateArgsPolicyRAII TemplateArgs(Policy);
1795 const TemplateParameterList *TPL = TD ? TD->getTemplateParameters() : nullptr;
1796 printTemplateArgumentList(OS, T->template_arguments(), Policy, TPL);
1797 spaceBeforePlaceHolder(OS);
1798}
1799
1800void TypePrinter::printTemplateSpecializationBefore(
1802 raw_ostream &OS) {
1803 printTemplateId(T, OS, Policy.FullyQualifiedName);
1804}
1805
1806void TypePrinter::printTemplateSpecializationAfter(
1808 raw_ostream &OS) {}
1809
1810void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {
1811 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1812 printBefore(T->getInnerType(), OS);
1813 OS << '(';
1814 } else
1815 printBefore(T->getInnerType(), OS);
1816}
1817
1818void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {
1819 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1820 OS << ')';
1821 printAfter(T->getInnerType(), OS);
1822 } else
1823 printAfter(T->getInnerType(), OS);
1824}
1825
1826void TypePrinter::printDependentNameBefore(const DependentNameType *T,
1827 raw_ostream &OS) {
1828 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1829 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1830 OS << " ";
1831 T->getQualifier().print(OS, Policy);
1832 OS << T->getIdentifier()->getName();
1833 spaceBeforePlaceHolder(OS);
1834}
1835
1836void TypePrinter::printDependentNameAfter(const DependentNameType *T,
1837 raw_ostream &OS) {}
1838
1839void TypePrinter::printDependentTemplateSpecializationBefore(
1840 const DependentTemplateSpecializationType *T, raw_ostream &OS) {
1841 IncludeStrongLifetimeRAII Strong(Policy);
1842
1843 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1844 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1845 OS << " ";
1846
1847 T->getDependentTemplateName().print(OS, Policy);
1848 printTemplateArgumentList(OS, T->template_arguments(), Policy);
1849 spaceBeforePlaceHolder(OS);
1850}
1851
1852void TypePrinter::printDependentTemplateSpecializationAfter(
1853 const DependentTemplateSpecializationType *T, raw_ostream &OS) {}
1854
1855void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,
1856 raw_ostream &OS) {
1857 printBefore(T->getPattern(), OS);
1858}
1859
1860void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
1861 raw_ostream &OS) {
1862 printAfter(T->getPattern(), OS);
1863 OS << "...";
1864}
1865
1867 raw_ostream &OS,
1868 const PrintingPolicy &Policy) {
1869 OS << ' ';
1870 if (T->isCountInBytes() && T->isOrNull())
1871 OS << "__sized_by_or_null(";
1872 else if (T->isCountInBytes())
1873 OS << "__sized_by(";
1874 else if (T->isOrNull())
1875 OS << "__counted_by_or_null(";
1876 else
1877 OS << "__counted_by(";
1878 if (T->getCountExpr())
1879 T->getCountExpr()->printPretty(OS, nullptr, Policy);
1880 OS << ')';
1881}
1882
1883void TypePrinter::printCountAttributedBefore(const CountAttributedType *T,
1884 raw_ostream &OS) {
1885 printBefore(T->desugar(), OS);
1886 if (!T->isArrayType())
1887 printCountAttributedImpl(T, OS, Policy);
1888}
1889
1890void TypePrinter::printCountAttributedAfter(const CountAttributedType *T,
1891 raw_ostream &OS) {
1892 printAfter(T->desugar(), OS);
1893 if (T->isArrayType())
1894 printCountAttributedImpl(T, OS, Policy);
1895}
1896
1897void TypePrinter::printAttributedBefore(const AttributedType *T,
1898 raw_ostream &OS) {
1899 // FIXME: Generate this with TableGen.
1900
1901 // Prefer the macro forms of the GC and ownership qualifiers.
1902 if (T->getAttrKind() == attr::ObjCGC ||
1903 T->getAttrKind() == attr::ObjCOwnership)
1904 return printBefore(T->getEquivalentType(), OS);
1905
1906 if (T->getAttrKind() == attr::ObjCKindOf)
1907 OS << "__kindof ";
1908
1909 if (T->getAttrKind() == attr::PreserveNone) {
1910 OS << "__attribute__((preserve_none)) ";
1911 spaceBeforePlaceHolder(OS);
1912 } else if (T->getAttrKind() == attr::PreserveMost) {
1913 OS << "__attribute__((preserve_most)) ";
1914 spaceBeforePlaceHolder(OS);
1915 } else if (T->getAttrKind() == attr::PreserveAll) {
1916 OS << "__attribute__((preserve_all)) ";
1917 spaceBeforePlaceHolder(OS);
1918 }
1919
1920 if (T->getAttrKind() == attr::AddressSpace)
1921 printBefore(T->getEquivalentType(), OS);
1922 else
1923 printBefore(T->getModifiedType(), OS);
1924
1925 if (T->isMSTypeSpec()) {
1926 switch (T->getAttrKind()) {
1927 default: return;
1928 case attr::Ptr32: OS << " __ptr32"; break;
1929 case attr::Ptr64: OS << " __ptr64"; break;
1930 case attr::SPtr: OS << " __sptr"; break;
1931 case attr::UPtr: OS << " __uptr"; break;
1932 }
1933 spaceBeforePlaceHolder(OS);
1934 }
1935
1936 if (T->isWebAssemblyFuncrefSpec())
1937 OS << "__funcref";
1938
1939 // Print nullability type specifiers.
1940 if (T->getImmediateNullability()) {
1941 if (T->getAttrKind() == attr::TypeNonNull)
1942 OS << " _Nonnull";
1943 else if (T->getAttrKind() == attr::TypeNullable)
1944 OS << " _Nullable";
1945 else if (T->getAttrKind() == attr::TypeNullUnspecified)
1946 OS << " _Null_unspecified";
1947 else if (T->getAttrKind() == attr::TypeNullableResult)
1948 OS << " _Nullable_result";
1949 else
1950 llvm_unreachable("unhandled nullability");
1951 spaceBeforePlaceHolder(OS);
1952 }
1953}
1954
1955void TypePrinter::printAttributedAfter(const AttributedType *T,
1956 raw_ostream &OS) {
1957 // FIXME: Generate this with TableGen.
1958
1959 // Prefer the macro forms of the GC and ownership qualifiers.
1960 if (T->getAttrKind() == attr::ObjCGC ||
1961 T->getAttrKind() == attr::ObjCOwnership)
1962 return printAfter(T->getEquivalentType(), OS);
1963
1964 // If this is a calling convention attribute, don't print the implicit CC from
1965 // the modified type.
1966 SaveAndRestore MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());
1967
1968 printAfter(T->getModifiedType(), OS);
1969
1970 // Some attributes are printed as qualifiers before the type, so we have
1971 // nothing left to do.
1972 if (T->getAttrKind() == attr::ObjCKindOf || T->isMSTypeSpec() ||
1973 T->getImmediateNullability() || T->isWebAssemblyFuncrefSpec())
1974 return;
1975
1976 // Don't print the inert __unsafe_unretained attribute at all.
1977 if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained)
1978 return;
1979
1980 // Don't print ns_returns_retained unless it had an effect.
1981 if (T->getAttrKind() == attr::NSReturnsRetained &&
1982 !T->getEquivalentType()->castAs<FunctionType>()
1984 return;
1985
1986 if (T->getAttrKind() == attr::LifetimeBound) {
1987 OS << " [[clang::lifetimebound]]";
1988 return;
1989 }
1990 if (T->getAttrKind() == attr::LifetimeCaptureBy) {
1991 OS << " [[clang::lifetime_capture_by(";
1992 if (auto *attr = dyn_cast_or_null<LifetimeCaptureByAttr>(T->getAttr()))
1993 llvm::interleaveComma(attr->getArgIdents(), OS,
1994 [&](auto it) { OS << it->getName(); });
1995 OS << ")]]";
1996 return;
1997 }
1998
1999 // The printing of the address_space attribute is handled by the qualifier
2000 // since it is still stored in the qualifier. Return early to prevent printing
2001 // this twice.
2002 if (T->getAttrKind() == attr::AddressSpace)
2003 return;
2004
2005 if (T->getAttrKind() == attr::AnnotateType) {
2006 // FIXME: Print the attribute arguments once we have a way to retrieve these
2007 // here. For the meantime, we just print `[[clang::annotate_type(...)]]`
2008 // without the arguments so that we know at least that we had _some_
2009 // annotation on the type.
2010 OS << " [[clang::annotate_type(...)]]";
2011 return;
2012 }
2013
2014 if (T->getAttrKind() == attr::ArmStreaming) {
2015 OS << "__arm_streaming";
2016 return;
2017 }
2018 if (T->getAttrKind() == attr::ArmStreamingCompatible) {
2019 OS << "__arm_streaming_compatible";
2020 return;
2021 }
2022
2023 if (T->getAttrKind() == attr::SwiftAttr) {
2024 if (auto *swiftAttr = dyn_cast_or_null<SwiftAttrAttr>(T->getAttr())) {
2025 OS << " __attribute__((swift_attr(\"" << swiftAttr->getAttribute()
2026 << "\")))";
2027 }
2028 return;
2029 }
2030
2031 if (T->getAttrKind() == attr::PreserveAll ||
2032 T->getAttrKind() == attr::PreserveMost ||
2033 T->getAttrKind() == attr::PreserveNone) {
2034 // This has to be printed before the type.
2035 return;
2036 }
2037
2038 OS << " __attribute__((";
2039 switch (T->getAttrKind()) {
2040#define TYPE_ATTR(NAME)
2041#define DECL_OR_TYPE_ATTR(NAME)
2042#define ATTR(NAME) case attr::NAME:
2043#include "clang/Basic/AttrList.inc"
2044 llvm_unreachable("non-type attribute attached to type");
2045
2046 case attr::BTFTypeTag:
2047 llvm_unreachable("BTFTypeTag attribute handled separately");
2048
2049 case attr::HLSLResourceClass:
2050 case attr::HLSLROV:
2051 case attr::HLSLRawBuffer:
2052 case attr::HLSLContainedType:
2053 llvm_unreachable("HLSL resource type attributes handled separately");
2054
2055 case attr::OpenCLPrivateAddressSpace:
2056 case attr::OpenCLGlobalAddressSpace:
2057 case attr::OpenCLGlobalDeviceAddressSpace:
2058 case attr::OpenCLGlobalHostAddressSpace:
2059 case attr::OpenCLLocalAddressSpace:
2060 case attr::OpenCLConstantAddressSpace:
2061 case attr::OpenCLGenericAddressSpace:
2062 case attr::HLSLGroupSharedAddressSpace:
2063 // FIXME: Update printAttributedBefore to print these once we generate
2064 // AttributedType nodes for them.
2065 break;
2066
2067 case attr::CountedBy:
2068 case attr::CountedByOrNull:
2069 case attr::SizedBy:
2070 case attr::SizedByOrNull:
2071 case attr::LifetimeBound:
2072 case attr::LifetimeCaptureBy:
2073 case attr::TypeNonNull:
2074 case attr::TypeNullable:
2075 case attr::TypeNullableResult:
2076 case attr::TypeNullUnspecified:
2077 case attr::ObjCGC:
2078 case attr::ObjCInertUnsafeUnretained:
2079 case attr::ObjCKindOf:
2080 case attr::ObjCOwnership:
2081 case attr::Ptr32:
2082 case attr::Ptr64:
2083 case attr::SPtr:
2084 case attr::UPtr:
2085 case attr::PointerAuth:
2086 case attr::AddressSpace:
2087 case attr::CmseNSCall:
2088 case attr::AnnotateType:
2089 case attr::WebAssemblyFuncref:
2090 case attr::ArmAgnostic:
2091 case attr::ArmStreaming:
2092 case attr::ArmStreamingCompatible:
2093 case attr::ArmIn:
2094 case attr::ArmOut:
2095 case attr::ArmInOut:
2096 case attr::ArmPreserves:
2097 case attr::NonBlocking:
2098 case attr::NonAllocating:
2099 case attr::Blocking:
2100 case attr::Allocating:
2101 case attr::SwiftAttr:
2102 case attr::PreserveAll:
2103 case attr::PreserveMost:
2104 case attr::PreserveNone:
2105 llvm_unreachable("This attribute should have been handled already");
2106
2107 case attr::NSReturnsRetained:
2108 OS << "ns_returns_retained";
2109 break;
2110
2111 // FIXME: When Sema learns to form this AttributedType, avoid printing the
2112 // attribute again in printFunctionProtoAfter.
2113 case attr::AnyX86NoCfCheck: OS << "nocf_check"; break;
2114 case attr::CDecl: OS << "cdecl"; break;
2115 case attr::FastCall: OS << "fastcall"; break;
2116 case attr::StdCall: OS << "stdcall"; break;
2117 case attr::ThisCall: OS << "thiscall"; break;
2118 case attr::SwiftCall: OS << "swiftcall"; break;
2119 case attr::SwiftAsyncCall: OS << "swiftasynccall"; break;
2120 case attr::VectorCall: OS << "vectorcall"; break;
2121 case attr::Pascal: OS << "pascal"; break;
2122 case attr::MSABI: OS << "ms_abi"; break;
2123 case attr::SysVABI: OS << "sysv_abi"; break;
2124 case attr::RegCall: OS << "regcall"; break;
2125 case attr::Pcs: {
2126 OS << "pcs(";
2127 QualType t = T->getEquivalentType();
2128 while (!t->isFunctionType())
2129 t = t->getPointeeType();
2130 OS << (t->castAs<FunctionType>()->getCallConv() == CC_AAPCS ?
2131 "\"aapcs\"" : "\"aapcs-vfp\"");
2132 OS << ')';
2133 break;
2134 }
2135 case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break;
2136 case attr::AArch64SVEPcs: OS << "aarch64_sve_pcs"; break;
2137 case attr::DeviceKernel:
2138 OS << T->getAttr()->getSpelling();
2139 break;
2140 case attr::IntelOclBicc:
2141 OS << "inteloclbicc";
2142 break;
2143 case attr::M68kRTD:
2144 OS << "m68k_rtd";
2145 break;
2146 case attr::RISCVVectorCC:
2147 OS << "riscv_vector_cc";
2148 break;
2149 case attr::RISCVVLSCC:
2150 OS << "riscv_vls_cc";
2151 break;
2152 case attr::NoDeref:
2153 OS << "noderef";
2154 break;
2155 case attr::CFIUncheckedCallee:
2156 OS << "cfi_unchecked_callee";
2157 break;
2158 case attr::AcquireHandle:
2159 OS << "acquire_handle";
2160 break;
2161 case attr::ArmMveStrictPolymorphism:
2162 OS << "__clang_arm_mve_strict_polymorphism";
2163 break;
2164 case attr::ExtVectorType:
2165 OS << "ext_vector_type";
2166 break;
2167 case attr::CFISalt:
2168 OS << "cfi_salt(\"" << cast<CFISaltAttr>(T->getAttr())->getSalt() << "\")";
2169 break;
2170 }
2171 OS << "))";
2172}
2173
2174void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T,
2175 raw_ostream &OS) {
2176 printBefore(T->getWrappedType(), OS);
2177 OS << " __attribute__((btf_type_tag(\"" << T->getAttr()->getBTFTypeTag() << "\")))";
2178}
2179
2180void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,
2181 raw_ostream &OS) {
2182 printAfter(T->getWrappedType(), OS);
2183}
2184
2185void TypePrinter::printHLSLAttributedResourceBefore(
2186 const HLSLAttributedResourceType *T, raw_ostream &OS) {
2187 printBefore(T->getWrappedType(), OS);
2188}
2189
2190void TypePrinter::printHLSLAttributedResourceAfter(
2191 const HLSLAttributedResourceType *T, raw_ostream &OS) {
2192 printAfter(T->getWrappedType(), OS);
2193 const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs();
2194 OS << " [[hlsl::resource_class("
2195 << HLSLResourceClassAttr::ConvertResourceClassToStr(Attrs.ResourceClass)
2196 << ")]]";
2197 if (Attrs.IsROV)
2198 OS << " [[hlsl::is_rov]]";
2199 if (Attrs.RawBuffer)
2200 OS << " [[hlsl::raw_buffer]]";
2201
2202 QualType ContainedTy = T->getContainedType();
2203 if (!ContainedTy.isNull()) {
2204 OS << " [[hlsl::contained_type(";
2205 printBefore(ContainedTy, OS);
2206 printAfter(ContainedTy, OS);
2207 OS << ")]]";
2208 }
2209}
2210
2211void TypePrinter::printHLSLInlineSpirvBefore(const HLSLInlineSpirvType *T,
2212 raw_ostream &OS) {
2213 OS << "__hlsl_spirv_type<" << T->getOpcode();
2214
2215 OS << ", " << T->getSize();
2216 OS << ", " << T->getAlignment();
2217
2218 for (auto &Operand : T->getOperands()) {
2219 using SpirvOperandKind = SpirvOperand::SpirvOperandKind;
2220
2221 OS << ", ";
2222 switch (Operand.getKind()) {
2223 case SpirvOperandKind::ConstantId: {
2224 QualType ConstantType = Operand.getResultType();
2225 OS << "vk::integral_constant<";
2226 printBefore(ConstantType, OS);
2227 printAfter(ConstantType, OS);
2228 OS << ", ";
2229 OS << Operand.getValue();
2230 OS << ">";
2231 break;
2232 }
2233 case SpirvOperandKind::Literal:
2234 OS << "vk::Literal<vk::integral_constant<uint, ";
2235 OS << Operand.getValue();
2236 OS << ">>";
2237 break;
2238 case SpirvOperandKind::TypeId: {
2239 QualType Type = Operand.getResultType();
2240 printBefore(Type, OS);
2241 printAfter(Type, OS);
2242 break;
2243 }
2244 default:
2245 llvm_unreachable("Invalid SpirvOperand kind!");
2246 break;
2247 }
2248 }
2249
2250 OS << ">";
2251}
2252
2253void TypePrinter::printHLSLInlineSpirvAfter(const HLSLInlineSpirvType *T,
2254 raw_ostream &OS) {
2255 // nothing to do
2256}
2257
2258void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
2259 raw_ostream &OS) {
2260 OS << T->getDecl()->getName();
2261 spaceBeforePlaceHolder(OS);
2262}
2263
2264void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
2265 raw_ostream &OS) {}
2266
2267void TypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType *T,
2268 raw_ostream &OS) {
2269 OS << T->getDecl()->getName();
2270 if (!T->qual_empty()) {
2271 bool isFirst = true;
2272 OS << '<';
2273 for (const auto *I : T->quals()) {
2274 if (isFirst)
2275 isFirst = false;
2276 else
2277 OS << ',';
2278 OS << I->getName();
2279 }
2280 OS << '>';
2281 }
2282
2283 spaceBeforePlaceHolder(OS);
2284}
2285
2286void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T,
2287 raw_ostream &OS) {}
2288
2289void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
2290 raw_ostream &OS) {
2291 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2292 !T->isKindOfTypeAsWritten())
2293 return printBefore(T->getBaseType(), OS);
2294
2295 if (T->isKindOfTypeAsWritten())
2296 OS << "__kindof ";
2297
2298 print(T->getBaseType(), OS, StringRef());
2299
2300 if (T->isSpecializedAsWritten()) {
2301 bool isFirst = true;
2302 OS << '<';
2303 for (auto typeArg : T->getTypeArgsAsWritten()) {
2304 if (isFirst)
2305 isFirst = false;
2306 else
2307 OS << ",";
2308
2309 print(typeArg, OS, StringRef());
2310 }
2311 OS << '>';
2312 }
2313
2314 if (!T->qual_empty()) {
2315 bool isFirst = true;
2316 OS << '<';
2317 for (const auto *I : T->quals()) {
2318 if (isFirst)
2319 isFirst = false;
2320 else
2321 OS << ',';
2322 OS << I->getName();
2323 }
2324 OS << '>';
2325 }
2326
2327 spaceBeforePlaceHolder(OS);
2328}
2329
2330void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
2331 raw_ostream &OS) {
2332 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2333 !T->isKindOfTypeAsWritten())
2334 return printAfter(T->getBaseType(), OS);
2335}
2336
2337void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
2338 raw_ostream &OS) {
2339 printBefore(T->getPointeeType(), OS);
2340
2341 // If we need to print the pointer, print it now.
2342 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&
2344 if (HasEmptyPlaceHolder)
2345 OS << ' ';
2346 OS << '*';
2347 }
2348}
2349
2350void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
2351 raw_ostream &OS) {}
2352
2353static
2354const TemplateArgument &getArgument(const TemplateArgument &A) { return A; }
2355
2357 return A.getArgument();
2358}
2359
2360static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP,
2361 llvm::raw_ostream &OS, bool IncludeType) {
2362 A.print(PP, OS, IncludeType);
2363}
2364
2366 const PrintingPolicy &PP, llvm::raw_ostream &OS,
2367 bool IncludeType) {
2368 const TemplateArgument::ArgKind &Kind = A.getArgument().getKind();
2370 return A.getTypeSourceInfo()->getType().print(OS, PP);
2371 return A.getArgument().print(PP, OS, IncludeType);
2372}
2373
2375 TemplateArgument Pattern,
2377 unsigned Depth);
2378
2380 ArrayRef<TemplateArgument> Args, unsigned Depth) {
2381 if (Ctx.hasSameType(T, Pattern))
2382 return true;
2383
2384 // A type parameter matches its argument.
2385 if (auto *TTPT = Pattern->getAsCanonical<TemplateTypeParmType>()) {
2386 if (TTPT->getDepth() == Depth && TTPT->getIndex() < Args.size() &&
2387 Args[TTPT->getIndex()].getKind() == TemplateArgument::Type) {
2388 QualType SubstArg = Ctx.getQualifiedType(
2389 Args[TTPT->getIndex()].getAsType(), Pattern.getQualifiers());
2390 return Ctx.hasSameType(SubstArg, T);
2391 }
2392 return false;
2393 }
2394
2395 // FIXME: Recurse into array types.
2396
2397 // All other cases will need the types to be identically qualified.
2398 Qualifiers TQual, PatQual;
2399 T = Ctx.getUnqualifiedArrayType(T, TQual);
2400 Pattern = Ctx.getUnqualifiedArrayType(Pattern, PatQual);
2401 if (TQual != PatQual)
2402 return false;
2403
2404 // Recurse into pointer-like types.
2405 {
2406 QualType TPointee = T->getPointeeType();
2407 QualType PPointee = Pattern->getPointeeType();
2408 if (!TPointee.isNull() && !PPointee.isNull())
2409 return T->getTypeClass() == Pattern->getTypeClass() &&
2410 isSubstitutedType(Ctx, TPointee, PPointee, Args, Depth);
2411 }
2412
2413 // Recurse into template specialization types.
2414 if (auto *PTST =
2417 ArrayRef<TemplateArgument> TemplateArgs;
2418 if (auto *TTST = T->getAs<TemplateSpecializationType>()) {
2419 Template = TTST->getTemplateName();
2420 TemplateArgs = TTST->template_arguments();
2421 } else if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
2422 T->getAsCXXRecordDecl())) {
2423 Template = TemplateName(CTSD->getSpecializedTemplate());
2424 TemplateArgs = CTSD->getTemplateArgs().asArray();
2425 } else {
2426 return false;
2427 }
2428
2429 if (!isSubstitutedTemplateArgument(Ctx, Template, PTST->getTemplateName(),
2430 Args, Depth))
2431 return false;
2432 if (TemplateArgs.size() != PTST->template_arguments().size())
2433 return false;
2434 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
2436 Ctx, TemplateArgs[I], PTST->template_arguments()[I], Args, Depth))
2437 return false;
2438 return true;
2439 }
2440
2441 // FIXME: Handle more cases.
2442 return false;
2443}
2444
2445/// Evaluates the expression template argument 'Pattern' and returns true
2446/// if 'Arg' evaluates to the same result.
2448 TemplateArgument const &Pattern,
2449 TemplateArgument const &Arg) {
2450 if (Pattern.getKind() != TemplateArgument::Expression)
2451 return false;
2452
2453 // Can't evaluate value-dependent expressions so bail early
2454 Expr const *pattern_expr = Pattern.getAsExpr();
2455 if (pattern_expr->isValueDependent() ||
2456 !pattern_expr->isIntegerConstantExpr(Ctx))
2457 return false;
2458
2460 return llvm::APSInt::isSameValue(pattern_expr->EvaluateKnownConstInt(Ctx),
2461 Arg.getAsIntegral());
2462
2464 Expr const *args_expr = Arg.getAsExpr();
2465 if (args_expr->isValueDependent() || !args_expr->isIntegerConstantExpr(Ctx))
2466 return false;
2467
2468 return llvm::APSInt::isSameValue(args_expr->EvaluateKnownConstInt(Ctx),
2469 pattern_expr->EvaluateKnownConstInt(Ctx));
2470 }
2471
2472 return false;
2473}
2474
2476 TemplateArgument Pattern,
2478 unsigned Depth) {
2479 Arg = Ctx.getCanonicalTemplateArgument(Arg);
2480 Pattern = Ctx.getCanonicalTemplateArgument(Pattern);
2481 if (Arg.structurallyEquals(Pattern))
2482 return true;
2483
2484 if (Pattern.getKind() == TemplateArgument::Expression) {
2485 if (auto *DRE =
2486 dyn_cast<DeclRefExpr>(Pattern.getAsExpr()->IgnoreParenImpCasts())) {
2487 if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
2488 return NTTP->getDepth() == Depth && Args.size() > NTTP->getIndex() &&
2489 Args[NTTP->getIndex()].structurallyEquals(Arg);
2490 }
2491 }
2492
2493 if (templateArgumentExpressionsEqual(Ctx, Pattern, Arg))
2494 return true;
2495
2496 if (Arg.getKind() != Pattern.getKind())
2497 return false;
2498
2499 if (Arg.getKind() == TemplateArgument::Type)
2500 return isSubstitutedType(Ctx, Arg.getAsType(), Pattern.getAsType(), Args,
2501 Depth);
2502
2503 if (Arg.getKind() == TemplateArgument::Template) {
2504 TemplateDecl *PatTD = Pattern.getAsTemplate().getAsTemplateDecl();
2505 if (auto *TTPD = dyn_cast_or_null<TemplateTemplateParmDecl>(PatTD))
2506 return TTPD->getDepth() == Depth && Args.size() > TTPD->getIndex() &&
2507 Ctx.getCanonicalTemplateArgument(Args[TTPD->getIndex()])
2508 .structurallyEquals(Arg);
2509 }
2510
2511 // FIXME: Handle more cases.
2512 return false;
2513}
2514
2516 const NamedDecl *Param,
2518 unsigned Depth) {
2519 // An empty pack is equivalent to not providing a pack argument.
2520 if (Arg.getKind() == TemplateArgument::Pack && Arg.pack_size() == 0)
2521 return true;
2522
2523 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Param)) {
2524 return TTPD->hasDefaultArgument() &&
2526 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2527 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
2528 return TTPD->hasDefaultArgument() &&
2530 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2531 } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
2532 return NTTPD->hasDefaultArgument() &&
2534 Ctx, Arg, NTTPD->getDefaultArgument().getArgument(), Args,
2535 Depth);
2536 }
2537 return false;
2538}
2539
2540template <typename TA>
2541static void
2542printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy,
2543 const TemplateParameterList *TPL, bool IsPack, unsigned ParmIndex) {
2544 // Drop trailing template arguments that match default arguments.
2545 if (TPL && Policy.SuppressDefaultTemplateArgs && !Policy.PrintAsCanonical &&
2546 !Args.empty() && !IsPack && Args.size() <= TPL->size()) {
2548 for (const TA &A : Args)
2549 OrigArgs.push_back(getArgument(A));
2550 while (!Args.empty() && getArgument(Args.back()).getIsDefaulted())
2551 Args = Args.drop_back();
2552 }
2553
2554 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
2555 if (!IsPack)
2556 OS << '<';
2557
2558 bool NeedSpace = false;
2559 bool FirstArg = true;
2560 for (const auto &Arg : Args) {
2561 // Print the argument into a string.
2562 SmallString<128> Buf;
2563 llvm::raw_svector_ostream ArgOS(Buf);
2564 const TemplateArgument &Argument = getArgument(Arg);
2565 if (Argument.getKind() == TemplateArgument::Pack) {
2566 if (Argument.pack_size() && !FirstArg)
2567 OS << Comma;
2568 printTo(ArgOS, Argument.getPackAsArray(), Policy, TPL,
2569 /*IsPack*/ true, ParmIndex);
2570 } else {
2571 if (!FirstArg)
2572 OS << Comma;
2573 // Tries to print the argument with location info if exists.
2574 printArgument(Arg, Policy, ArgOS,
2576 Policy, TPL, ParmIndex));
2577 }
2578 StringRef ArgString = ArgOS.str();
2579
2580 // If this is the first argument and its string representation
2581 // begins with the global scope specifier ('::foo'), add a space
2582 // to avoid printing the diagraph '<:'.
2583 if (FirstArg && ArgString.starts_with(":"))
2584 OS << ' ';
2585
2586 OS << ArgString;
2587
2588 // If the last character of our string is '>', add another space to
2589 // keep the two '>''s separate tokens.
2590 if (!ArgString.empty()) {
2591 NeedSpace = Policy.SplitTemplateClosers && ArgString.back() == '>';
2592 FirstArg = false;
2593 }
2594
2595 // Use same template parameter for all elements of Pack
2596 if (!IsPack)
2597 ParmIndex++;
2598 }
2599
2600 if (!IsPack) {
2601 if (NeedSpace)
2602 OS << ' ';
2603 OS << '>';
2604 }
2605}
2606
2608 const TemplateArgumentListInfo &Args,
2609 const PrintingPolicy &Policy,
2610 const TemplateParameterList *TPL) {
2611 printTemplateArgumentList(OS, Args.arguments(), Policy, TPL);
2612}
2613
2616 const PrintingPolicy &Policy,
2617 const TemplateParameterList *TPL) {
2618 PrintingPolicy InnerPolicy = Policy;
2619 InnerPolicy.SuppressScope = false;
2620 printTo(OS, Args, InnerPolicy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2621}
2622
2625 const PrintingPolicy &Policy,
2626 const TemplateParameterList *TPL) {
2627 PrintingPolicy InnerPolicy = Policy;
2628 InnerPolicy.SuppressScope = false;
2629 printTo(OS, Args, InnerPolicy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2630}
2631
2633 LangOptions LO;
2634 return getAsString(PrintingPolicy(LO));
2635}
2636
2638 SmallString<64> Buf;
2639 llvm::raw_svector_ostream StrOS(Buf);
2640 print(StrOS, P);
2641 return StrOS.str().str();
2642}
2643
2645 return !isPresent();
2646}
2647
2648void PointerAuthQualifier::print(raw_ostream &OS,
2649 const PrintingPolicy &P) const {
2650 if (!isPresent())
2651 return;
2652
2653 OS << "__ptrauth(";
2654 OS << getKey();
2655 OS << "," << unsigned(isAddressDiscriminated()) << ","
2656 << getExtraDiscriminator() << ")";
2657}
2658
2659std::string Qualifiers::getAsString() const {
2660 LangOptions LO;
2661 return getAsString(PrintingPolicy(LO));
2662}
2663
2664// Appends qualifiers to the given string, separated by spaces. Will
2665// prefix a space if the string is non-empty. Will not append a final
2666// space.
2667std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {
2668 SmallString<64> Buf;
2669 llvm::raw_svector_ostream StrOS(Buf);
2670 print(StrOS, Policy);
2671 return std::string(StrOS.str());
2672}
2673
2675 if (getCVRQualifiers())
2676 return false;
2677
2679 return false;
2680
2681 if (getObjCGCAttr())
2682 return false;
2683
2685 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
2686 return false;
2687
2688 if (PointerAuthQualifier PointerAuth = getPointerAuth();
2689 PointerAuth && !PointerAuth.isEmptyWhenPrinted(Policy))
2690 return false;
2691
2692 return true;
2693}
2694
2696 switch (AS) {
2697 case LangAS::Default:
2698 return "";
2701 return "__global";
2703 case LangAS::sycl_local:
2704 return "__local";
2707 return "__private";
2709 return "__constant";
2711 return "__generic";
2714 return "__global_device";
2717 return "__global_host";
2719 return "__device__";
2721 return "__constant__";
2723 return "__shared__";
2724 case LangAS::ptr32_sptr:
2725 return "__sptr __ptr32";
2726 case LangAS::ptr32_uptr:
2727 return "__uptr __ptr32";
2728 case LangAS::ptr64:
2729 return "__ptr64";
2731 return "groupshared";
2733 return "hlsl_constant";
2735 return "hlsl_private";
2737 return "hlsl_device";
2738 case LangAS::hlsl_input:
2739 return "hlsl_input";
2741 return "__funcref";
2742 default:
2743 return std::to_string(toTargetAddressSpace(AS));
2744 }
2745}
2746
2747// Appends qualifiers to the given string, separated by spaces. Will
2748// prefix a space if the string is non-empty. Will not append a final
2749// space.
2750void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
2751 bool appendSpaceIfNonEmpty) const {
2752 bool addSpace = false;
2753
2754 unsigned quals = getCVRQualifiers();
2755 if (quals) {
2756 AppendTypeQualList(OS, quals, Policy.Restrict);
2757 addSpace = true;
2758 }
2759 if (hasUnaligned()) {
2760 if (addSpace)
2761 OS << ' ';
2762 OS << "__unaligned";
2763 addSpace = true;
2764 }
2765 auto ASStr = getAddrSpaceAsString(getAddressSpace());
2766 if (!ASStr.empty()) {
2767 if (addSpace)
2768 OS << ' ';
2769 addSpace = true;
2770 // Wrap target address space into an attribute syntax
2772 OS << "__attribute__((address_space(" << ASStr << ")))";
2773 else
2774 OS << ASStr;
2775 }
2776
2777 if (Qualifiers::GC gc = getObjCGCAttr()) {
2778 if (addSpace)
2779 OS << ' ';
2780 addSpace = true;
2781 if (gc == Qualifiers::Weak)
2782 OS << "__weak";
2783 else
2784 OS << "__strong";
2785 }
2786 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
2787 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
2788 if (addSpace)
2789 OS << ' ';
2790 addSpace = true;
2791 }
2792
2793 switch (lifetime) {
2794 case Qualifiers::OCL_None: llvm_unreachable("none but true");
2795 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;
2797 if (!Policy.SuppressStrongLifetime)
2798 OS << "__strong";
2799 break;
2800
2801 case Qualifiers::OCL_Weak: OS << "__weak"; break;
2802 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
2803 }
2804 }
2805
2806 if (PointerAuthQualifier PointerAuth = getPointerAuth()) {
2807 if (addSpace)
2808 OS << ' ';
2809 addSpace = true;
2810
2811 PointerAuth.print(OS, Policy);
2812 }
2813
2814 if (appendSpaceIfNonEmpty && addSpace)
2815 OS << ' ';
2816}
2817
2818std::string QualType::getAsString() const {
2819 return getAsString(split(), LangOptions());
2820}
2821
2822std::string QualType::getAsString(const PrintingPolicy &Policy) const {
2823 std::string S;
2824 getAsStringInternal(S, Policy);
2825 return S;
2826}
2827
2828std::string QualType::getAsString(const Type *ty, Qualifiers qs,
2829 const PrintingPolicy &Policy) {
2830 std::string buffer;
2831 getAsStringInternal(ty, qs, buffer, Policy);
2832 return buffer;
2833}
2834
2835void QualType::print(raw_ostream &OS, const PrintingPolicy &Policy,
2836 const Twine &PlaceHolder, unsigned Indentation) const {
2837 print(splitAccordingToPolicy(*this, Policy), OS, Policy, PlaceHolder,
2838 Indentation);
2839}
2840
2842 raw_ostream &OS, const PrintingPolicy &policy,
2843 const Twine &PlaceHolder, unsigned Indentation) {
2844 SmallString<128> PHBuf;
2845 StringRef PH = PlaceHolder.toStringRef(PHBuf);
2846
2847 TypePrinter(policy, Indentation).print(ty, qs, OS, PH);
2848}
2849
2850void QualType::getAsStringInternal(std::string &Str,
2851 const PrintingPolicy &Policy) const {
2852 return getAsStringInternal(splitAccordingToPolicy(*this, Policy), Str,
2853 Policy);
2854}
2855
2857 std::string &buffer,
2858 const PrintingPolicy &policy) {
2859 SmallString<256> Buf;
2860 llvm::raw_svector_ostream StrOS(Buf);
2861 TypePrinter(policy).print(ty, qs, StrOS, buffer);
2862 std::string str = std::string(StrOS.str());
2863 buffer.swap(str);
2864}
2865
2866raw_ostream &clang::operator<<(raw_ostream &OS, QualType QT) {
2867 SplitQualType S = QT.split();
2868 TypePrinter(LangOptions()).print(S.Ty, S.Quals, OS, /*PlaceHolder=*/"");
2869 return OS;
2870}
Defines the clang::ASTContext interface.
StringRef P
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)
#define CC_VLS_CASE(ABI_VLEN)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
uint32_t Id
Definition: SemaARM.cpp:1179
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:801
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:2867
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
Definition: ASTContext.h:2442
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: TypeBase.h:3507
Represents a constant array type that does not decay to a pointer when used as a function parameter.
Definition: TypeBase.h:3908
An attributed type is a type to which a type attribute has been applied.
Definition: TypeBase.h:6585
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Definition: TypeBase.h:7180
A fixed int type of a specified bitwidth.
Definition: TypeBase.h:8195
Pointer to a block type.
Definition: TypeBase.h:3558
This class is used for builtin types like 'int'.
Definition: TypeBase.h:3182
Declaration of a class template.
Complex values, per C99 6.2.5p11.
Definition: TypeBase.h:3293
Represents the canonical version of C arrays with a specified constant size.
Definition: TypeBase.h:3776
Represents a concrete matrix type with constant number of rows and columns.
Definition: TypeBase.h:4389
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
Definition: TypeBase.h:3454
Represents a pointer type decayed from an array or function type.
Definition: TypeBase.h:3541
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1449
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2109
bool isTranslationUnit() const
Definition: DeclBase.h:2185
bool isFunctionOrMethod() const
Definition: DeclBase.h:2161
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:524
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:593
SourceLocation getLocation() const
Definition: DeclBase.h:439
DeclContext * getDeclContext()
Definition: DeclBase.h:448
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: TypeBase.h:6270
Represents a C++17 deduced template specialization type.
Definition: TypeBase.h:7228
Represents an extended address space qualifier where the input address space value is dependent.
Definition: TypeBase.h:4077
Represents a qualified type name for which the type name is dependent.
Definition: TypeBase.h:7414
Represents an array type in C++ whose size is a value-dependent expression.
Definition: TypeBase.h:4027
Represents an extended vector type where either the type or size is dependent.
Definition: TypeBase.h:4117
Represents a matrix type where the type and the number of rows and columns is dependent on a template...
Definition: TypeBase.h:4448
Represents a template specialization type whose template cannot be resolved, e.g.
Definition: TypeBase.h:7465
Represents a vector type where either the type or size is dependent.
Definition: TypeBase.h:4243
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Definition: TypeBase.h:6522
This represents one expression.
Definition: Expr.h:112
bool isIntegerConstantExpr(const ASTContext &Ctx) const
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition: Expr.h:177
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, 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:3073
ExtVectorType - Extended vector type.
Definition: TypeBase.h:4283
An immutable set of FunctionEffects and possibly conditions attached to them.
Definition: TypeBase.h:5082
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition: TypeBase.h:4860
Represents a prototype with parameter type info, e.g.
Definition: TypeBase.h:5282
QualType desugar() const
Definition: TypeBase.h:5863
ExtParameterInfo getExtParameterInfo(unsigned I) const
Definition: TypeBase.h:5786
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Definition: TypeBase.h:5589
unsigned getNumParams() const
Definition: TypeBase.h:5560
void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
Definition: TypeBase.h:5702
Qualifiers getMethodQuals() const
Definition: TypeBase.h:5708
QualType getParamType(unsigned i) const
Definition: TypeBase.h:5562
FunctionEffectsRef getFunctionEffects() const
Definition: TypeBase.h:5846
unsigned getAArch64SMEAttributes() const
Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...
Definition: TypeBase.h:5779
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
Definition: TypeBase.h:5640
bool hasCFIUncheckedCallee() const
Definition: TypeBase.h:5704
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition: TypeBase.h:5632
bool hasDynamicExceptionSpec() const
Return whether this function has a dynamic (throw) exception spec.
Definition: TypeBase.h:5598
bool isVariadic() const
Whether this function prototype is variadic.
Definition: TypeBase.h:5686
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
Definition: TypeBase.h:5647
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Definition: TypeBase.h:5716
A class which abstracts out some details necessary for making a call.
Definition: TypeBase.h:4589
CallingConv getCC() const
Definition: TypeBase.h:4648
unsigned getRegParm() const
Definition: TypeBase.h:4641
bool getNoCallerSavedRegs() const
Definition: TypeBase.h:4637
bool getProducesResult() const
Definition: TypeBase.h:4635
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: TypeBase.h:4478
ExtInfo getExtInfo() const
Definition: TypeBase.h:4834
static ArmStateValue getArmZT0State(unsigned AttrBits)
Definition: TypeBase.h:4787
static ArmStateValue getArmZAState(unsigned AttrBits)
Definition: TypeBase.h:4783
QualType getReturnType() const
Definition: TypeBase.h:4818
Represents an arbitrary, user-specified SPIR-V type instruction.
Definition: TypeBase.h:6860
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: TypeBase.h:3925
The injected class name of a C++ class template or class template partial specialization.
Definition: TypeBase.h:6553
An lvalue reference type, per C++11 [dcl.ref].
Definition: TypeBase.h:3633
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:434
Sugar type that represents a type that was qualified by a qualifier written as a macro invocation.
Definition: TypeBase.h:6161
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition: TypeBase.h:3669
This represents a decl that may have a name.
Definition: Decl.h:273
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:300
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:339
Interfaces are the core concept in Objective-C for object oriented design.
Definition: TypeBase.h:7905
Represents a pointer to an Objective C object.
Definition: TypeBase.h:7961
Represents a class type in Objective C.
Definition: TypeBase.h:7707
Represents a type parameter type in Objective C.
Definition: TypeBase.h:7633
Represents a pack expansion of types.
Definition: TypeBase.h:7524
Sugar for parentheses used when specifying types.
Definition: TypeBase.h:3320
PipeType - OpenCL20.
Definition: TypeBase.h:8161
Pointer-authentication qualifiers.
Definition: TypeBase.h:152
bool isAddressDiscriminated() const
Definition: TypeBase.h:265
unsigned getExtraDiscriminator() const
Definition: TypeBase.h:270
void print(raw_ostream &OS, const PrintingPolicy &Policy) const
bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const
std::string getAsString() const
unsigned getKey() const
Definition: TypeBase.h:258
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: TypeBase.h:3346
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: TypeBase.h:937
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: TypeBase.h:1004
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition: TypeBase.h:8383
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: TypeBase.h:8528
QualType getCanonicalType() const
Definition: TypeBase.h:8395
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
Definition: TypeBase.h:8364
std::string getAsString() const
StreamedQualTypeHelper stream(const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Definition: TypeBase.h:1388
The collection of all-type qualifiers we support.
Definition: TypeBase.h:331
unsigned getCVRQualifiers() const
Definition: TypeBase.h:488
GC getObjCGCAttr() const
Definition: TypeBase.h:519
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Definition: TypeBase.h:361
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
Definition: TypeBase.h:354
@ OCL_None
There is no lifetime qualification on this type.
Definition: TypeBase.h:350
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Definition: TypeBase.h:364
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
Definition: TypeBase.h:367
bool hasUnaligned() const
Definition: TypeBase.h:511
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool appendSpaceIfNonEmpty=false) const
bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const
PointerAuthQualifier getPointerAuth() const
Definition: TypeBase.h:603
ObjCLifetime getObjCLifetime() const
Definition: TypeBase.h:545
bool empty() const
Definition: TypeBase.h:647
std::string getAsString() const
LangAS getAddressSpace() const
Definition: TypeBase.h:571
static std::string getAddrSpaceAsString(LangAS AS)
An rvalue reference type, per C++11 [dcl.ref].
Definition: TypeBase.h:3651
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: TypeBase.h:6502
Base for LValueReferenceType and RValueReferenceType.
Definition: TypeBase.h:3589
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 builtin template as a pack.
Definition: TypeBase.h:7062
Represents the result of substituting a set of types for a template type parameter pack.
Definition: TypeBase.h:7091
Represents the result of substituting a type for a template type parameter.
Definition: TypeBase.h:6972
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3710
A convenient class for passing around template argument information.
Definition: TemplateBase.h:634
ArrayRef< TemplateArgumentLoc > arguments() const
Definition: TemplateBase.h:661
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:528
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:452
Expr * getAsExpr() const
Retrieve the template argument as an expression.
Definition: TemplateBase.h:411
QualType getAsType() const
Retrieve the type for a type template argument.
Definition: TemplateBase.h:322
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
Definition: TemplateBase.h:366
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
Definition: TemplateBase.h:346
unsigned pack_size() const
The number of template arguments in the given template argument pack.
Definition: TemplateBase.h:446
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:396
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:296
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:396
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:415
Represents a C++ template name within the type system.
Definition: TemplateName.h:222
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:74
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context)
Get the template argument list of the template parameter list.
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: TypeBase.h:7290
Declaration of a template type parameter.
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
Definition: TypeBase.h:6193
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
Definition: TypeBase.h:6243
QualType getType() const
Return the type wrapped by this type source info.
Definition: TypeBase.h:8325
The base class of the type hierarchy.
Definition: TypeBase.h:1833
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.h:26
bool isArrayType() const
Definition: TypeBase.h:8679
QualType getLocallyUnqualifiedSingleStepDesugaredType() const
Pull a single level of sugar off of this locally-unqualified type.
Definition: Type.cpp:521
const T * castAs() const
Member-template castAs<specific type>.
Definition: TypeBase.h:9226
bool isObjCQualifiedIdType() const
Definition: TypeBase.h:8770
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:752
bool isObjCIdType() const
Definition: TypeBase.h:8782
bool isSpecifierType() const
Returns true if this type can be represented by some set of type specifiers.
Definition: Type.cpp:3204
bool isFunctionType() const
Definition: TypeBase.h:8576
bool isObjCQualifiedClassType() const
Definition: TypeBase.h:8776
bool isObjCClassType() const
Definition: TypeBase.h:8788
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition: TypeBase.h:2939
TypeClass getTypeClass() const
Definition: TypeBase.h:2403
bool isCanonicalUnqualified() const
Determines if this type would be canonical if it had no further qualification.
Definition: TypeBase.h:2429
const T * getAs() const
Member-template getAs<specific type>'.
Definition: TypeBase.h:9159
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3555
A unary type transform, which is a type constructed from another.
Definition: TypeBase.h:6375
Represents the dependent type named by a dependently-scoped typename using declaration,...
Definition: TypeBase.h:5998
Represents a C array with a specified size that is not an integer-constant-expression.
Definition: TypeBase.h:3982
Represents a GCC generic vector type.
Definition: TypeBase.h:4191
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:81
@ RQ_None
No ref-qualifier was provided.
Definition: TypeBase.h:1782
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
Definition: TypeBase.h:1785
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition: TypeBase.h:1788
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)
Insertion operator for diagnostics.
unsigned toTargetAddressSpace(LangAS AS)
Definition: AddressSpaces.h:85
ParameterABI
Kinds of parameter ABI.
Definition: Specifiers.h:378
@ SwiftAsyncContext
This parameter (which must have pointer type) uses the special Swift asynchronous context-pointer ABI...
@ 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)
@ Template
We are parsing a template declaration.
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
@ Keyword
The name has been typo-corrected to a keyword.
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:1288
@ CC_X86Pascal
Definition: Specifiers.h:284
@ CC_Swift
Definition: Specifiers.h:293
@ CC_IntelOclBicc
Definition: Specifiers.h:290
@ CC_PreserveMost
Definition: Specifiers.h:295
@ CC_Win64
Definition: Specifiers.h:285
@ CC_X86ThisCall
Definition: Specifiers.h:282
@ CC_AArch64VectorCall
Definition: Specifiers.h:297
@ CC_DeviceKernel
Definition: Specifiers.h:292
@ CC_AAPCS
Definition: Specifiers.h:288
@ CC_PreserveNone
Definition: Specifiers.h:300
@ CC_C
Definition: Specifiers.h:279
@ CC_M68kRTD
Definition: Specifiers.h:299
@ CC_SwiftAsync
Definition: Specifiers.h:294
@ CC_X86RegCall
Definition: Specifiers.h:287
@ CC_RISCVVectorCall
Definition: Specifiers.h:301
@ CC_X86VectorCall
Definition: Specifiers.h:283
@ CC_SpirFunction
Definition: Specifiers.h:291
@ CC_AArch64SVEPCS
Definition: Specifiers.h:298
@ CC_X86StdCall
Definition: Specifiers.h:280
@ CC_X86_64SysV
Definition: Specifiers.h:286
@ CC_PreserveAll
Definition: Specifiers.h:296
@ CC_X86FastCall
Definition: Specifiers.h:281
@ CC_AAPCS_VFP
Definition: Specifiers.h:289
ElaboratedTypeKeyword
The elaboration keyword that precedes a qualified type name or introduces an elaborated-type-specifie...
Definition: TypeBase.h:5881
@ 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:678
ArrayRef< TemplateArgumentLoc > arguments() const
Definition: TemplateBase.h:707
llvm::dxil::ResourceClass ResourceClass
Definition: TypeBase.h:6713
static StringRef getKeywordName(ElaboratedTypeKeyword Keyword)
Definition: Type.cpp:3315
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 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 PrintAsCanonical
Whether to print entities as written or canonically.
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: TypeBase.h:870
const Type * Ty
The locally-unqualified type.
Definition: TypeBase.h:872
Qualifiers Quals
The local qualifiers.
Definition: TypeBase.h:875