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