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