clang 17.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"
26#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/Casting.h"
41#include "llvm/Support/Compiler.h"
42#include "llvm/Support/ErrorHandling.h"
43#include "llvm/Support/SaveAndRestore.h"
44#include "llvm/Support/raw_ostream.h"
45#include <cassert>
46#include <string>
47
48using namespace clang;
49
50namespace {
51
52/// RAII object that enables printing of the ARC __strong lifetime
53/// qualifier.
54class IncludeStrongLifetimeRAII {
55 PrintingPolicy &Policy;
56 bool Old;
57
58public:
59 explicit IncludeStrongLifetimeRAII(PrintingPolicy &Policy)
60 : Policy(Policy), Old(Policy.SuppressStrongLifetime) {
62 Policy.SuppressStrongLifetime = false;
63 }
64
65 ~IncludeStrongLifetimeRAII() { Policy.SuppressStrongLifetime = Old; }
66};
67
68class ParamPolicyRAII {
69 PrintingPolicy &Policy;
70 bool Old;
71
72public:
73 explicit ParamPolicyRAII(PrintingPolicy &Policy)
74 : Policy(Policy), Old(Policy.SuppressSpecifiers) {
75 Policy.SuppressSpecifiers = false;
76 }
77
78 ~ParamPolicyRAII() { Policy.SuppressSpecifiers = Old; }
79};
80
81class DefaultTemplateArgsPolicyRAII {
82 PrintingPolicy &Policy;
83 bool Old;
84
85public:
86 explicit DefaultTemplateArgsPolicyRAII(PrintingPolicy &Policy)
87 : Policy(Policy), Old(Policy.SuppressDefaultTemplateArgs) {
88 Policy.SuppressDefaultTemplateArgs = false;
89 }
90
91 ~DefaultTemplateArgsPolicyRAII() { Policy.SuppressDefaultTemplateArgs = Old; }
92};
93
94class ElaboratedTypePolicyRAII {
95 PrintingPolicy &Policy;
96 bool SuppressTagKeyword;
97 bool SuppressScope;
98
99public:
100 explicit ElaboratedTypePolicyRAII(PrintingPolicy &Policy) : Policy(Policy) {
101 SuppressTagKeyword = Policy.SuppressTagKeyword;
102 SuppressScope = Policy.SuppressScope;
103 Policy.SuppressTagKeyword = true;
104 Policy.SuppressScope = true;
105 }
106
107 ~ElaboratedTypePolicyRAII() {
108 Policy.SuppressTagKeyword = SuppressTagKeyword;
109 Policy.SuppressScope = SuppressScope;
110 }
111};
112
113class TypePrinter {
114 PrintingPolicy Policy;
115 unsigned Indentation;
116 bool HasEmptyPlaceHolder = false;
117 bool InsideCCAttribute = false;
118
119public:
120 explicit TypePrinter(const PrintingPolicy &Policy, unsigned Indentation = 0)
121 : Policy(Policy), Indentation(Indentation) {}
122
123 void print(const Type *ty, Qualifiers qs, raw_ostream &OS,
124 StringRef PlaceHolder);
125 void print(QualType T, raw_ostream &OS, StringRef PlaceHolder);
126
127 static bool canPrefixQualifiers(const Type *T, bool &NeedARCStrongQualifier);
128 void spaceBeforePlaceHolder(raw_ostream &OS);
129 void printTypeSpec(NamedDecl *D, raw_ostream &OS);
130 void printTemplateId(const TemplateSpecializationType *T, raw_ostream &OS,
131 bool FullyQualify);
132
133 void printBefore(QualType T, raw_ostream &OS);
134 void printAfter(QualType T, raw_ostream &OS);
135 void AppendScope(DeclContext *DC, raw_ostream &OS,
136 DeclarationName NameInScope);
137 void printTag(TagDecl *T, raw_ostream &OS);
138 void printFunctionAfter(const FunctionType::ExtInfo &Info, raw_ostream &OS);
139#define ABSTRACT_TYPE(CLASS, PARENT)
140#define TYPE(CLASS, PARENT) \
141 void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS); \
142 void print##CLASS##After(const CLASS##Type *T, raw_ostream &OS);
143#include "clang/AST/TypeNodes.inc"
144
145private:
146 void printBefore(const Type *ty, Qualifiers qs, raw_ostream &OS);
147 void printAfter(const Type *ty, Qualifiers qs, raw_ostream &OS);
148};
149
150} // namespace
151
152static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals,
153 bool HasRestrictKeyword) {
154 bool appendSpace = false;
155 if (TypeQuals & Qualifiers::Const) {
156 OS << "const";
157 appendSpace = true;
158 }
159 if (TypeQuals & Qualifiers::Volatile) {
160 if (appendSpace) OS << ' ';
161 OS << "volatile";
162 appendSpace = true;
163 }
164 if (TypeQuals & Qualifiers::Restrict) {
165 if (appendSpace) OS << ' ';
166 if (HasRestrictKeyword) {
167 OS << "restrict";
168 } else {
169 OS << "__restrict";
170 }
171 }
172}
173
174void TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) {
175 if (!HasEmptyPlaceHolder)
176 OS << ' ';
177}
178
180 const PrintingPolicy &Policy) {
181 if (Policy.PrintCanonicalTypes)
182 QT = QT.getCanonicalType();
183 return QT.split();
184}
185
186void TypePrinter::print(QualType t, raw_ostream &OS, StringRef PlaceHolder) {
187 SplitQualType split = splitAccordingToPolicy(t, Policy);
188 print(split.Ty, split.Quals, OS, PlaceHolder);
189}
190
191void TypePrinter::print(const Type *T, Qualifiers Quals, raw_ostream &OS,
192 StringRef PlaceHolder) {
193 if (!T) {
194 OS << "NULL TYPE";
195 return;
196 }
197
198 SaveAndRestore PHVal(HasEmptyPlaceHolder, PlaceHolder.empty());
199
200 printBefore(T, Quals, OS);
201 OS << PlaceHolder;
202 printAfter(T, Quals, OS);
203}
204
205bool TypePrinter::canPrefixQualifiers(const Type *T,
206 bool &NeedARCStrongQualifier) {
207 // CanPrefixQualifiers - We prefer to print type qualifiers before the type,
208 // so that we get "const int" instead of "int const", but we can't do this if
209 // the type is complex. For example if the type is "int*", we *must* print
210 // "int * const", printing "const int *" is different. Only do this when the
211 // type expands to a simple string.
212 bool CanPrefixQualifiers = false;
213 NeedARCStrongQualifier = false;
214 const Type *UnderlyingType = T;
215 if (const auto *AT = dyn_cast<AutoType>(T))
216 UnderlyingType = AT->desugar().getTypePtr();
217 if (const auto *Subst = dyn_cast<SubstTemplateTypeParmType>(T))
218 UnderlyingType = Subst->getReplacementType().getTypePtr();
219 Type::TypeClass TC = UnderlyingType->getTypeClass();
220
221 switch (TC) {
222 case Type::Auto:
223 case Type::Builtin:
224 case Type::Complex:
225 case Type::UnresolvedUsing:
226 case Type::Using:
227 case Type::Typedef:
228 case Type::TypeOfExpr:
229 case Type::TypeOf:
230 case Type::Decltype:
231 case Type::UnaryTransform:
232 case Type::Record:
233 case Type::Enum:
234 case Type::Elaborated:
235 case Type::TemplateTypeParm:
236 case Type::SubstTemplateTypeParmPack:
237 case Type::DeducedTemplateSpecialization:
238 case Type::TemplateSpecialization:
239 case Type::InjectedClassName:
240 case Type::DependentName:
241 case Type::DependentTemplateSpecialization:
242 case Type::ObjCObject:
243 case Type::ObjCTypeParam:
244 case Type::ObjCInterface:
245 case Type::Atomic:
246 case Type::Pipe:
247 case Type::BitInt:
248 case Type::DependentBitInt:
249 case Type::BTFTagAttributed:
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::Pointer:
272 case Type::BlockPointer:
273 case Type::LValueReference:
274 case Type::RValueReference:
275 case Type::MemberPointer:
276 case Type::DependentAddressSpace:
277 case Type::DependentVector:
278 case Type::DependentSizedExtVector:
279 case Type::Vector:
280 case Type::ExtVector:
281 case Type::ConstantMatrix:
282 case Type::DependentSizedMatrix:
283 case Type::FunctionProto:
284 case Type::FunctionNoProto:
285 case Type::Paren:
286 case Type::PackExpansion:
287 case Type::SubstTemplateTypeParm:
288 case Type::MacroQualified:
289 CanPrefixQualifiers = false;
290 break;
291
292 case Type::Attributed: {
293 // We still want to print the address_space before the type if it is an
294 // address_space attribute.
295 const auto *AttrTy = cast<AttributedType>(UnderlyingType);
296 CanPrefixQualifiers = AttrTy->getAttrKind() == attr::AddressSpace;
297 break;
298 }
299 }
300
301 return CanPrefixQualifiers;
302}
303
304void TypePrinter::printBefore(QualType T, raw_ostream &OS) {
306
307 // If we have cv1 T, where T is substituted for cv2 U, only print cv1 - cv2
308 // at this level.
309 Qualifiers Quals = Split.Quals;
310 if (const auto *Subst = dyn_cast<SubstTemplateTypeParmType>(Split.Ty))
311 Quals -= QualType(Subst, 0).getQualifiers();
312
313 printBefore(Split.Ty, Quals, OS);
314}
315
316/// Prints the part of the type string before an identifier, e.g. for
317/// "int foo[10]" it prints "int ".
318void TypePrinter::printBefore(const Type *T,Qualifiers Quals, raw_ostream &OS) {
319 if (Policy.SuppressSpecifiers && T->isSpecifierType())
320 return;
321
322 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder);
323
324 // Print qualifiers as appropriate.
325
326 bool CanPrefixQualifiers = false;
327 bool NeedARCStrongQualifier = false;
328 CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier);
329
330 if (CanPrefixQualifiers && !Quals.empty()) {
331 if (NeedARCStrongQualifier) {
332 IncludeStrongLifetimeRAII Strong(Policy);
333 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
334 } else {
335 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
336 }
337 }
338
339 bool hasAfterQuals = false;
340 if (!CanPrefixQualifiers && !Quals.empty()) {
341 hasAfterQuals = !Quals.isEmptyWhenPrinted(Policy);
342 if (hasAfterQuals)
343 HasEmptyPlaceHolder = false;
344 }
345
346 switch (T->getTypeClass()) {
347#define ABSTRACT_TYPE(CLASS, PARENT)
348#define TYPE(CLASS, PARENT) case Type::CLASS: \
349 print##CLASS##Before(cast<CLASS##Type>(T), OS); \
350 break;
351#include "clang/AST/TypeNodes.inc"
352 }
353
354 if (hasAfterQuals) {
355 if (NeedARCStrongQualifier) {
356 IncludeStrongLifetimeRAII Strong(Policy);
357 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
358 } else {
359 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
360 }
361 }
362}
363
364void TypePrinter::printAfter(QualType t, raw_ostream &OS) {
365 SplitQualType split = splitAccordingToPolicy(t, Policy);
366 printAfter(split.Ty, split.Quals, OS);
367}
368
369/// Prints the part of the type string after an identifier, e.g. for
370/// "int foo[10]" it prints "[10]".
371void TypePrinter::printAfter(const Type *T, Qualifiers Quals, raw_ostream &OS) {
372 switch (T->getTypeClass()) {
373#define ABSTRACT_TYPE(CLASS, PARENT)
374#define TYPE(CLASS, PARENT) case Type::CLASS: \
375 print##CLASS##After(cast<CLASS##Type>(T), OS); \
376 break;
377#include "clang/AST/TypeNodes.inc"
378 }
379}
380
381void TypePrinter::printBuiltinBefore(const BuiltinType *T, raw_ostream &OS) {
382 OS << T->getName(Policy);
383 spaceBeforePlaceHolder(OS);
384}
385
386void TypePrinter::printBuiltinAfter(const BuiltinType *T, raw_ostream &OS) {}
387
388void TypePrinter::printComplexBefore(const ComplexType *T, raw_ostream &OS) {
389 OS << "_Complex ";
390 printBefore(T->getElementType(), OS);
391}
392
393void TypePrinter::printComplexAfter(const ComplexType *T, raw_ostream &OS) {
394 printAfter(T->getElementType(), OS);
395}
396
397void TypePrinter::printPointerBefore(const PointerType *T, raw_ostream &OS) {
398 IncludeStrongLifetimeRAII Strong(Policy);
399 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
400 printBefore(T->getPointeeType(), OS);
401 // Handle things like 'int (*A)[4];' correctly.
402 // FIXME: this should include vectors, but vectors use attributes I guess.
403 if (isa<ArrayType>(T->getPointeeType()))
404 OS << '(';
405 OS << '*';
406}
407
408void TypePrinter::printPointerAfter(const PointerType *T, raw_ostream &OS) {
409 IncludeStrongLifetimeRAII Strong(Policy);
410 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
411 // Handle things like 'int (*A)[4];' correctly.
412 // FIXME: this should include vectors, but vectors use attributes I guess.
413 if (isa<ArrayType>(T->getPointeeType()))
414 OS << ')';
415 printAfter(T->getPointeeType(), OS);
416}
417
418void TypePrinter::printBlockPointerBefore(const BlockPointerType *T,
419 raw_ostream &OS) {
420 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
421 printBefore(T->getPointeeType(), OS);
422 OS << '^';
423}
424
425void TypePrinter::printBlockPointerAfter(const BlockPointerType *T,
426 raw_ostream &OS) {
427 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
428 printAfter(T->getPointeeType(), OS);
429}
430
431// When printing a reference, the referenced type might also be a reference.
432// If so, we want to skip that before printing the inner type.
434 if (auto *Ref = T->getAs<ReferenceType>())
435 return skipTopLevelReferences(Ref->getPointeeTypeAsWritten());
436 return T;
437}
438
439void TypePrinter::printLValueReferenceBefore(const LValueReferenceType *T,
440 raw_ostream &OS) {
441 IncludeStrongLifetimeRAII Strong(Policy);
442 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
444 printBefore(Inner, OS);
445 // Handle things like 'int (&A)[4];' correctly.
446 // FIXME: this should include vectors, but vectors use attributes I guess.
447 if (isa<ArrayType>(Inner))
448 OS << '(';
449 OS << '&';
450}
451
452void TypePrinter::printLValueReferenceAfter(const LValueReferenceType *T,
453 raw_ostream &OS) {
454 IncludeStrongLifetimeRAII Strong(Policy);
455 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
457 // Handle things like 'int (&A)[4];' correctly.
458 // FIXME: this should include vectors, but vectors use attributes I guess.
459 if (isa<ArrayType>(Inner))
460 OS << ')';
461 printAfter(Inner, OS);
462}
463
464void TypePrinter::printRValueReferenceBefore(const RValueReferenceType *T,
465 raw_ostream &OS) {
466 IncludeStrongLifetimeRAII Strong(Policy);
467 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
469 printBefore(Inner, OS);
470 // Handle things like 'int (&&A)[4];' correctly.
471 // FIXME: this should include vectors, but vectors use attributes I guess.
472 if (isa<ArrayType>(Inner))
473 OS << '(';
474 OS << "&&";
475}
476
477void TypePrinter::printRValueReferenceAfter(const RValueReferenceType *T,
478 raw_ostream &OS) {
479 IncludeStrongLifetimeRAII Strong(Policy);
480 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
482 // Handle things like 'int (&&A)[4];' correctly.
483 // FIXME: this should include vectors, but vectors use attributes I guess.
484 if (isa<ArrayType>(Inner))
485 OS << ')';
486 printAfter(Inner, OS);
487}
488
489void TypePrinter::printMemberPointerBefore(const MemberPointerType *T,
490 raw_ostream &OS) {
491 IncludeStrongLifetimeRAII Strong(Policy);
492 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
493 printBefore(T->getPointeeType(), OS);
494 // Handle things like 'int (Cls::*A)[4];' correctly.
495 // FIXME: this should include vectors, but vectors use attributes I guess.
496 if (isa<ArrayType>(T->getPointeeType()))
497 OS << '(';
498
499 PrintingPolicy InnerPolicy(Policy);
500 InnerPolicy.IncludeTagDefinition = false;
501 TypePrinter(InnerPolicy).print(QualType(T->getClass(), 0), OS, StringRef());
502
503 OS << "::*";
504}
505
506void TypePrinter::printMemberPointerAfter(const MemberPointerType *T,
507 raw_ostream &OS) {
508 IncludeStrongLifetimeRAII Strong(Policy);
509 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
510 // Handle things like 'int (Cls::*A)[4];' correctly.
511 // FIXME: this should include vectors, but vectors use attributes I guess.
512 if (isa<ArrayType>(T->getPointeeType()))
513 OS << ')';
514 printAfter(T->getPointeeType(), OS);
515}
516
517void TypePrinter::printConstantArrayBefore(const ConstantArrayType *T,
518 raw_ostream &OS) {
519 IncludeStrongLifetimeRAII Strong(Policy);
520 printBefore(T->getElementType(), OS);
521}
522
523void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T,
524 raw_ostream &OS) {
525 OS << '[';
528 Policy.Restrict);
529 OS << ' ';
530 }
531
533 OS << "static ";
534
535 OS << T->getSize().getZExtValue() << ']';
536 printAfter(T->getElementType(), OS);
537}
538
539void TypePrinter::printIncompleteArrayBefore(const IncompleteArrayType *T,
540 raw_ostream &OS) {
541 IncludeStrongLifetimeRAII Strong(Policy);
542 printBefore(T->getElementType(), OS);
543}
544
545void TypePrinter::printIncompleteArrayAfter(const IncompleteArrayType *T,
546 raw_ostream &OS) {
547 OS << "[]";
548 printAfter(T->getElementType(), OS);
549}
550
551void TypePrinter::printVariableArrayBefore(const VariableArrayType *T,
552 raw_ostream &OS) {
553 IncludeStrongLifetimeRAII Strong(Policy);
554 printBefore(T->getElementType(), OS);
555}
556
557void TypePrinter::printVariableArrayAfter(const VariableArrayType *T,
558 raw_ostream &OS) {
559 OS << '[';
561 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.Restrict);
562 OS << ' ';
563 }
564
565 if (T->getSizeModifier() == VariableArrayType::Static)
566 OS << "static ";
567 else if (T->getSizeModifier() == VariableArrayType::Star)
568 OS << '*';
569
570 if (T->getSizeExpr())
571 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
572 OS << ']';
573
574 printAfter(T->getElementType(), OS);
575}
576
577void TypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream &OS) {
578 // Print the adjusted representation, otherwise the adjustment will be
579 // invisible.
580 printBefore(T->getAdjustedType(), OS);
581}
582
583void TypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) {
584 printAfter(T->getAdjustedType(), OS);
585}
586
587void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {
588 // Print as though it's a pointer.
589 printAdjustedBefore(T, OS);
590}
591
592void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {
593 printAdjustedAfter(T, OS);
594}
595
596void TypePrinter::printDependentSizedArrayBefore(
598 raw_ostream &OS) {
599 IncludeStrongLifetimeRAII Strong(Policy);
600 printBefore(T->getElementType(), OS);
601}
602
603void TypePrinter::printDependentSizedArrayAfter(
605 raw_ostream &OS) {
606 OS << '[';
607 if (T->getSizeExpr())
608 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
609 OS << ']';
610 printAfter(T->getElementType(), OS);
611}
612
613void TypePrinter::printDependentAddressSpaceBefore(
614 const DependentAddressSpaceType *T, raw_ostream &OS) {
615 printBefore(T->getPointeeType(), OS);
616}
617
618void TypePrinter::printDependentAddressSpaceAfter(
619 const DependentAddressSpaceType *T, raw_ostream &OS) {
620 OS << " __attribute__((address_space(";
621 if (T->getAddrSpaceExpr())
622 T->getAddrSpaceExpr()->printPretty(OS, nullptr, Policy);
623 OS << ")))";
624 printAfter(T->getPointeeType(), OS);
625}
626
627void TypePrinter::printDependentSizedExtVectorBefore(
629 raw_ostream &OS) {
630 printBefore(T->getElementType(), OS);
631}
632
633void TypePrinter::printDependentSizedExtVectorAfter(
635 raw_ostream &OS) {
636 OS << " __attribute__((ext_vector_type(";
637 if (T->getSizeExpr())
638 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
639 OS << ")))";
640 printAfter(T->getElementType(), OS);
641}
642
643void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {
644 switch (T->getVectorKind()) {
646 OS << "__vector __pixel ";
647 break;
649 OS << "__vector __bool ";
650 printBefore(T->getElementType(), OS);
651 break;
653 OS << "__vector ";
654 printBefore(T->getElementType(), OS);
655 break;
657 OS << "__attribute__((neon_vector_type("
658 << T->getNumElements() << "))) ";
659 printBefore(T->getElementType(), OS);
660 break;
662 OS << "__attribute__((neon_polyvector_type(" <<
663 T->getNumElements() << "))) ";
664 printBefore(T->getElementType(), OS);
665 break;
667 // FIXME: We prefer to print the size directly here, but have no way
668 // to get the size of the type.
669 OS << "__attribute__((__vector_size__("
670 << T->getNumElements()
671 << " * sizeof(";
672 print(T->getElementType(), OS, StringRef());
673 OS << ")))) ";
674 printBefore(T->getElementType(), OS);
675 break;
676 }
679 // FIXME: We prefer to print the size directly here, but have no way
680 // to get the size of the type.
681 OS << "__attribute__((__arm_sve_vector_bits__(";
682
684 // Predicates take a bit per byte of the vector size, multiply by 8 to
685 // get the number of bits passed to the attribute.
686 OS << T->getNumElements() * 8;
687 else
688 OS << T->getNumElements();
689
690 OS << " * sizeof(";
691 print(T->getElementType(), OS, StringRef());
692 // Multiply by 8 for the number of bits.
693 OS << ") * 8))) ";
694 printBefore(T->getElementType(), OS);
695 break;
697 // FIXME: We prefer to print the size directly here, but have no way
698 // to get the size of the type.
699 OS << "__attribute__((__riscv_rvv_vector_bits__(";
700
701 OS << T->getNumElements();
702
703 OS << " * sizeof(";
704 print(T->getElementType(), OS, StringRef());
705 // Multiply by 8 for the number of bits.
706 OS << ") * 8))) ";
707 printBefore(T->getElementType(), OS);
708 break;
709 }
710}
711
712void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) {
713 printAfter(T->getElementType(), OS);
714}
715
716void TypePrinter::printDependentVectorBefore(
717 const DependentVectorType *T, raw_ostream &OS) {
718 switch (T->getVectorKind()) {
720 OS << "__vector __pixel ";
721 break;
723 OS << "__vector __bool ";
724 printBefore(T->getElementType(), OS);
725 break;
727 OS << "__vector ";
728 printBefore(T->getElementType(), OS);
729 break;
731 OS << "__attribute__((neon_vector_type(";
732 if (T->getSizeExpr())
733 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
734 OS << "))) ";
735 printBefore(T->getElementType(), OS);
736 break;
738 OS << "__attribute__((neon_polyvector_type(";
739 if (T->getSizeExpr())
740 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
741 OS << "))) ";
742 printBefore(T->getElementType(), OS);
743 break;
745 // FIXME: We prefer to print the size directly here, but have no way
746 // to get the size of the type.
747 OS << "__attribute__((__vector_size__(";
748 if (T->getSizeExpr())
749 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
750 OS << " * sizeof(";
751 print(T->getElementType(), OS, StringRef());
752 OS << ")))) ";
753 printBefore(T->getElementType(), OS);
754 break;
755 }
758 // FIXME: We prefer to print the size directly here, but have no way
759 // to get the size of the type.
760 OS << "__attribute__((__arm_sve_vector_bits__(";
761 if (T->getSizeExpr()) {
762 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
764 // Predicates take a bit per byte of the vector size, multiply by 8 to
765 // get the number of bits passed to the attribute.
766 OS << " * 8";
767 OS << " * sizeof(";
768 print(T->getElementType(), OS, StringRef());
769 // Multiply by 8 for the number of bits.
770 OS << ") * 8";
771 }
772 OS << "))) ";
773 printBefore(T->getElementType(), OS);
774 break;
776 // FIXME: We prefer to print the size directly here, but have no way
777 // to get the size of the type.
778 OS << "__attribute__((__riscv_rvv_vector_bits__(";
779 if (T->getSizeExpr()) {
780 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
781 OS << " * sizeof(";
782 print(T->getElementType(), OS, StringRef());
783 // Multiply by 8 for the number of bits.
784 OS << ") * 8";
785 }
786 OS << "))) ";
787 printBefore(T->getElementType(), OS);
788 break;
789 }
790}
791
792void TypePrinter::printDependentVectorAfter(
793 const DependentVectorType *T, raw_ostream &OS) {
794 printAfter(T->getElementType(), OS);
795}
796
797void TypePrinter::printExtVectorBefore(const ExtVectorType *T,
798 raw_ostream &OS) {
799 printBefore(T->getElementType(), OS);
800}
801
802void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) {
803 printAfter(T->getElementType(), OS);
804 OS << " __attribute__((ext_vector_type(";
805 OS << T->getNumElements();
806 OS << ")))";
807}
808
809void TypePrinter::printConstantMatrixBefore(const ConstantMatrixType *T,
810 raw_ostream &OS) {
811 printBefore(T->getElementType(), OS);
812 OS << " __attribute__((matrix_type(";
813 OS << T->getNumRows() << ", " << T->getNumColumns();
814 OS << ")))";
815}
816
817void TypePrinter::printConstantMatrixAfter(const ConstantMatrixType *T,
818 raw_ostream &OS) {
819 printAfter(T->getElementType(), OS);
820}
821
822void TypePrinter::printDependentSizedMatrixBefore(
823 const DependentSizedMatrixType *T, raw_ostream &OS) {
824 printBefore(T->getElementType(), OS);
825 OS << " __attribute__((matrix_type(";
826 if (T->getRowExpr()) {
827 T->getRowExpr()->printPretty(OS, nullptr, Policy);
828 }
829 OS << ", ";
830 if (T->getColumnExpr()) {
831 T->getColumnExpr()->printPretty(OS, nullptr, Policy);
832 }
833 OS << ")))";
834}
835
836void TypePrinter::printDependentSizedMatrixAfter(
837 const DependentSizedMatrixType *T, raw_ostream &OS) {
838 printAfter(T->getElementType(), OS);
839}
840
841void
843 const PrintingPolicy &Policy)
844 const {
846 OS << " throw(";
848 OS << "...";
849 else
850 for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) {
851 if (I)
852 OS << ", ";
853
854 OS << getExceptionType(I).stream(Policy);
855 }
856 OS << ')';
857 } else if (EST_NoThrow == getExceptionSpecType()) {
858 OS << " __attribute__((nothrow))";
860 OS << " noexcept";
861 // FIXME:Is it useful to print out the expression for a non-dependent
862 // noexcept specification?
864 OS << '(';
865 if (getNoexceptExpr())
866 getNoexceptExpr()->printPretty(OS, nullptr, Policy);
867 OS << ')';
868 }
869 }
870}
871
872void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,
873 raw_ostream &OS) {
874 if (T->hasTrailingReturn()) {
875 OS << "auto ";
876 if (!HasEmptyPlaceHolder)
877 OS << '(';
878 } else {
879 // If needed for precedence reasons, wrap the inner part in grouping parens.
880 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
881 printBefore(T->getReturnType(), OS);
882 if (!PrevPHIsEmpty.get())
883 OS << '(';
884 }
885}
886
888 switch (ABI) {
890 llvm_unreachable("asking for spelling of ordinary parameter ABI");
892 return "swift_context";
894 return "swift_async_context";
896 return "swift_error_result";
898 return "swift_indirect_result";
899 }
900 llvm_unreachable("bad parameter ABI kind");
901}
902
903void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
904 raw_ostream &OS) {
905 // If needed for precedence reasons, wrap the inner part in grouping parens.
906 if (!HasEmptyPlaceHolder)
907 OS << ')';
908 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
909
910 OS << '(';
911 {
912 ParamPolicyRAII ParamPolicy(Policy);
913 for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {
914 if (i) OS << ", ";
915
916 auto EPI = T->getExtParameterInfo(i);
917 if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) ";
918 if (EPI.isNoEscape())
919 OS << "__attribute__((noescape)) ";
920 auto ABI = EPI.getABI();
921 if (ABI != ParameterABI::Ordinary)
922 OS << "__attribute__((" << getParameterABISpelling(ABI) << ")) ";
923
924 print(T->getParamType(i), OS, StringRef());
925 }
926 }
927
928 if (T->isVariadic()) {
929 if (T->getNumParams())
930 OS << ", ";
931 OS << "...";
932 } else if (T->getNumParams() == 0 && Policy.UseVoidForZeroParams) {
933 // Do not emit int() if we have a proto, emit 'int(void)'.
934 OS << "void";
935 }
936
937 OS << ')';
938
940
941 printFunctionAfter(Info, OS);
942
943 if (!T->getMethodQuals().empty())
944 OS << " " << T->getMethodQuals().getAsString();
945
946 switch (T->getRefQualifier()) {
947 case RQ_None:
948 break;
949
950 case RQ_LValue:
951 OS << " &";
952 break;
953
954 case RQ_RValue:
955 OS << " &&";
956 break;
957 }
958 T->printExceptionSpecification(OS, Policy);
959
960 if (T->hasTrailingReturn()) {
961 OS << " -> ";
962 print(T->getReturnType(), OS, StringRef());
963 } else
964 printAfter(T->getReturnType(), OS);
965}
966
967void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
968 raw_ostream &OS) {
969 if (!InsideCCAttribute) {
970 switch (Info.getCC()) {
971 case CC_C:
972 // The C calling convention is the default on the vast majority of platforms
973 // we support. If the user wrote it explicitly, it will usually be printed
974 // while traversing the AttributedType. If the type has been desugared, let
975 // the canonical spelling be the implicit calling convention.
976 // FIXME: It would be better to be explicit in certain contexts, such as a
977 // cdecl function typedef used to declare a member function with the
978 // Microsoft C++ ABI.
979 break;
980 case CC_X86StdCall:
981 OS << " __attribute__((stdcall))";
982 break;
983 case CC_X86FastCall:
984 OS << " __attribute__((fastcall))";
985 break;
986 case CC_X86ThisCall:
987 OS << " __attribute__((thiscall))";
988 break;
989 case CC_X86VectorCall:
990 OS << " __attribute__((vectorcall))";
991 break;
992 case CC_X86Pascal:
993 OS << " __attribute__((pascal))";
994 break;
995 case CC_AAPCS:
996 OS << " __attribute__((pcs(\"aapcs\")))";
997 break;
998 case CC_AAPCS_VFP:
999 OS << " __attribute__((pcs(\"aapcs-vfp\")))";
1000 break;
1002 OS << "__attribute__((aarch64_vector_pcs))";
1003 break;
1004 case CC_AArch64SVEPCS:
1005 OS << "__attribute__((aarch64_sve_pcs))";
1006 break;
1008 OS << "__attribute__((amdgpu_kernel))";
1009 break;
1010 case CC_IntelOclBicc:
1011 OS << " __attribute__((intel_ocl_bicc))";
1012 break;
1013 case CC_Win64:
1014 OS << " __attribute__((ms_abi))";
1015 break;
1016 case CC_X86_64SysV:
1017 OS << " __attribute__((sysv_abi))";
1018 break;
1019 case CC_X86RegCall:
1020 OS << " __attribute__((regcall))";
1021 break;
1022 case CC_SpirFunction:
1023 case CC_OpenCLKernel:
1024 // Do nothing. These CCs are not available as attributes.
1025 break;
1026 case CC_Swift:
1027 OS << " __attribute__((swiftcall))";
1028 break;
1029 case CC_SwiftAsync:
1030 OS << "__attribute__((swiftasynccall))";
1031 break;
1032 case CC_PreserveMost:
1033 OS << " __attribute__((preserve_most))";
1034 break;
1035 case CC_PreserveAll:
1036 OS << " __attribute__((preserve_all))";
1037 break;
1038 }
1039 }
1040
1041 if (Info.getNoReturn())
1042 OS << " __attribute__((noreturn))";
1043 if (Info.getCmseNSCall())
1044 OS << " __attribute__((cmse_nonsecure_call))";
1045 if (Info.getProducesResult())
1046 OS << " __attribute__((ns_returns_retained))";
1047 if (Info.getRegParm())
1048 OS << " __attribute__((regparm ("
1049 << Info.getRegParm() << ")))";
1050 if (Info.getNoCallerSavedRegs())
1051 OS << " __attribute__((no_caller_saved_registers))";
1052 if (Info.getNoCfCheck())
1053 OS << " __attribute__((nocf_check))";
1054}
1055
1056void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T,
1057 raw_ostream &OS) {
1058 // If needed for precedence reasons, wrap the inner part in grouping parens.
1059 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
1060 printBefore(T->getReturnType(), OS);
1061 if (!PrevPHIsEmpty.get())
1062 OS << '(';
1063}
1064
1065void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,
1066 raw_ostream &OS) {
1067 // If needed for precedence reasons, wrap the inner part in grouping parens.
1068 if (!HasEmptyPlaceHolder)
1069 OS << ')';
1070 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
1071
1072 OS << "()";
1073 printFunctionAfter(T->getExtInfo(), OS);
1074 printAfter(T->getReturnType(), OS);
1075}
1076
1077void TypePrinter::printTypeSpec(NamedDecl *D, raw_ostream &OS) {
1078
1079 // Compute the full nested-name-specifier for this type.
1080 // In C, this will always be empty except when the type
1081 // being printed is anonymous within other Record.
1082 if (!Policy.SuppressScope)
1083 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1084
1085 IdentifierInfo *II = D->getIdentifier();
1086 OS << II->getName();
1087 spaceBeforePlaceHolder(OS);
1088}
1089
1090void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,
1091 raw_ostream &OS) {
1092 printTypeSpec(T->getDecl(), OS);
1093}
1094
1095void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,
1096 raw_ostream &OS) {}
1097
1098void TypePrinter::printUsingBefore(const UsingType *T, raw_ostream &OS) {
1099 // After `namespace b { using a::X }`, is the type X within B a::X or b::X?
1100 //
1101 // - b::X is more formally correct given the UsingType model
1102 // - b::X makes sense if "re-exporting" a symbol in a new namespace
1103 // - a::X makes sense if "importing" a symbol for convenience
1104 //
1105 // The "importing" use seems much more common, so we print a::X.
1106 // This could be a policy option, but the right choice seems to rest more
1107 // with the intent of the code than the caller.
1108 printTypeSpec(T->getFoundDecl()->getUnderlyingDecl(), OS);
1109}
1110
1111void TypePrinter::printUsingAfter(const UsingType *T, raw_ostream &OS) {}
1112
1113void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
1114 printTypeSpec(T->getDecl(), OS);
1115}
1116
1117void TypePrinter::printMacroQualifiedBefore(const MacroQualifiedType *T,
1118 raw_ostream &OS) {
1119 StringRef MacroName = T->getMacroIdentifier()->getName();
1120 OS << MacroName << " ";
1121
1122 // Since this type is meant to print the macro instead of the whole attribute,
1123 // we trim any attributes and go directly to the original modified type.
1124 printBefore(T->getModifiedType(), OS);
1125}
1126
1127void TypePrinter::printMacroQualifiedAfter(const MacroQualifiedType *T,
1128 raw_ostream &OS) {
1129 printAfter(T->getModifiedType(), OS);
1130}
1131
1132void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) {}
1133
1134void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
1135 raw_ostream &OS) {
1136 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual "
1137 : "typeof ");
1138 if (T->getUnderlyingExpr())
1139 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
1140 spaceBeforePlaceHolder(OS);
1141}
1142
1143void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
1144 raw_ostream &OS) {}
1145
1146void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) {
1147 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual("
1148 : "typeof(");
1149 print(T->getUnmodifiedType(), OS, StringRef());
1150 OS << ')';
1151 spaceBeforePlaceHolder(OS);
1152}
1153
1154void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) {}
1155
1156void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {
1157 OS << "decltype(";
1158 if (T->getUnderlyingExpr())
1159 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
1160 OS << ')';
1161 spaceBeforePlaceHolder(OS);
1162}
1163
1164void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) {}
1165
1166void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,
1167 raw_ostream &OS) {
1168 IncludeStrongLifetimeRAII Strong(Policy);
1169
1170 static llvm::DenseMap<int, const char *> Transformation = {{
1171#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
1172 {UnaryTransformType::Enum, "__" #Trait},
1173#include "clang/Basic/TransformTypeTraits.def"
1174 }};
1175 OS << Transformation[T->getUTTKind()] << '(';
1176 print(T->getBaseType(), OS, StringRef());
1177 OS << ')';
1178 spaceBeforePlaceHolder(OS);
1179}
1180
1181void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,
1182 raw_ostream &OS) {}
1183
1184void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
1185 // If the type has been deduced, do not print 'auto'.
1186 if (!T->getDeducedType().isNull()) {
1187 printBefore(T->getDeducedType(), OS);
1188 } else {
1189 if (T->isConstrained()) {
1190 // FIXME: Track a TypeConstraint as type sugar, so that we can print the
1191 // type as it was written.
1192 T->getTypeConstraintConcept()->getDeclName().print(OS, Policy);
1193 auto Args = T->getTypeConstraintArguments();
1194 if (!Args.empty())
1196 OS, Args, Policy,
1198 OS << ' ';
1199 }
1200 switch (T->getKeyword()) {
1201 case AutoTypeKeyword::Auto: OS << "auto"; break;
1202 case AutoTypeKeyword::DecltypeAuto: OS << "decltype(auto)"; break;
1203 case AutoTypeKeyword::GNUAutoType: OS << "__auto_type"; break;
1204 }
1205 spaceBeforePlaceHolder(OS);
1206 }
1207}
1208
1209void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {
1210 // If the type has been deduced, do not print 'auto'.
1211 if (!T->getDeducedType().isNull())
1212 printAfter(T->getDeducedType(), OS);
1213}
1214
1215void TypePrinter::printDeducedTemplateSpecializationBefore(
1216 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1217 // If the type has been deduced, print the deduced type.
1218 if (!T->getDeducedType().isNull()) {
1219 printBefore(T->getDeducedType(), OS);
1220 } else {
1221 IncludeStrongLifetimeRAII Strong(Policy);
1222 T->getTemplateName().print(OS, Policy);
1223 spaceBeforePlaceHolder(OS);
1224 }
1225}
1226
1227void TypePrinter::printDeducedTemplateSpecializationAfter(
1228 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1229 // If the type has been deduced, print the deduced type.
1230 if (!T->getDeducedType().isNull())
1231 printAfter(T->getDeducedType(), OS);
1232}
1233
1234void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {
1235 IncludeStrongLifetimeRAII Strong(Policy);
1236
1237 OS << "_Atomic(";
1238 print(T->getValueType(), OS, StringRef());
1239 OS << ')';
1240 spaceBeforePlaceHolder(OS);
1241}
1242
1243void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) {}
1244
1245void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) {
1246 IncludeStrongLifetimeRAII Strong(Policy);
1247
1248 if (T->isReadOnly())
1249 OS << "read_only ";
1250 else
1251 OS << "write_only ";
1252 OS << "pipe ";
1253 print(T->getElementType(), OS, StringRef());
1254 spaceBeforePlaceHolder(OS);
1255}
1256
1257void TypePrinter::printPipeAfter(const PipeType *T, raw_ostream &OS) {}
1258
1259void TypePrinter::printBitIntBefore(const BitIntType *T, raw_ostream &OS) {
1260 if (T->isUnsigned())
1261 OS << "unsigned ";
1262 OS << "_BitInt(" << T->getNumBits() << ")";
1263 spaceBeforePlaceHolder(OS);
1264}
1265
1266void TypePrinter::printBitIntAfter(const BitIntType *T, raw_ostream &OS) {}
1267
1268void TypePrinter::printDependentBitIntBefore(const DependentBitIntType *T,
1269 raw_ostream &OS) {
1270 if (T->isUnsigned())
1271 OS << "unsigned ";
1272 OS << "_BitInt(";
1273 T->getNumBitsExpr()->printPretty(OS, nullptr, Policy);
1274 OS << ")";
1275 spaceBeforePlaceHolder(OS);
1276}
1277
1278void TypePrinter::printDependentBitIntAfter(const DependentBitIntType *T,
1279 raw_ostream &OS) {}
1280
1281/// Appends the given scope to the end of a string.
1282void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS,
1283 DeclarationName NameInScope) {
1284 if (DC->isTranslationUnit())
1285 return;
1286
1287 // FIXME: Consider replacing this with NamedDecl::printNestedNameSpecifier,
1288 // which can also print names for function and method scopes.
1289 if (DC->isFunctionOrMethod())
1290 return;
1291
1292 if (Policy.Callbacks && Policy.Callbacks->isScopeVisible(DC))
1293 return;
1294
1295 if (const auto *NS = dyn_cast<NamespaceDecl>(DC)) {
1296 if (Policy.SuppressUnwrittenScope && NS->isAnonymousNamespace())
1297 return AppendScope(DC->getParent(), OS, NameInScope);
1298
1299 // Only suppress an inline namespace if the name has the same lookup
1300 // results in the enclosing namespace.
1301 if (Policy.SuppressInlineNamespace && NS->isInline() && NameInScope &&
1302 NS->isRedundantInlineQualifierFor(NameInScope))
1303 return AppendScope(DC->getParent(), OS, NameInScope);
1304
1305 AppendScope(DC->getParent(), OS, NS->getDeclName());
1306 if (NS->getIdentifier())
1307 OS << NS->getName() << "::";
1308 else
1309 OS << "(anonymous namespace)::";
1310 } else if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
1311 AppendScope(DC->getParent(), OS, Spec->getDeclName());
1312 IncludeStrongLifetimeRAII Strong(Policy);
1313 OS << Spec->getIdentifier()->getName();
1314 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
1316 OS, TemplateArgs.asArray(), Policy,
1317 Spec->getSpecializedTemplate()->getTemplateParameters());
1318 OS << "::";
1319 } else if (const auto *Tag = dyn_cast<TagDecl>(DC)) {
1320 AppendScope(DC->getParent(), OS, Tag->getDeclName());
1321 if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl())
1322 OS << Typedef->getIdentifier()->getName() << "::";
1323 else if (Tag->getIdentifier())
1324 OS << Tag->getIdentifier()->getName() << "::";
1325 else
1326 return;
1327 } else {
1328 AppendScope(DC->getParent(), OS, NameInScope);
1329 }
1330}
1331
1332void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {
1333 if (Policy.IncludeTagDefinition) {
1334 PrintingPolicy SubPolicy = Policy;
1335 SubPolicy.IncludeTagDefinition = false;
1336 D->print(OS, SubPolicy, Indentation);
1337 spaceBeforePlaceHolder(OS);
1338 return;
1339 }
1340
1341 bool HasKindDecoration = false;
1342
1343 // We don't print tags unless this is an elaborated type.
1344 // In C, we just assume every RecordType is an elaborated type.
1345 if (!Policy.SuppressTagKeyword && !D->getTypedefNameForAnonDecl()) {
1346 HasKindDecoration = true;
1347 OS << D->getKindName();
1348 OS << ' ';
1349 }
1350
1351 // Compute the full nested-name-specifier for this type.
1352 // In C, this will always be empty except when the type
1353 // being printed is anonymous within other Record.
1354 if (!Policy.SuppressScope)
1355 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1356
1357 if (const IdentifierInfo *II = D->getIdentifier())
1358 OS << II->getName();
1359 else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) {
1360 assert(Typedef->getIdentifier() && "Typedef without identifier?");
1361 OS << Typedef->getIdentifier()->getName();
1362 } else {
1363 // Make an unambiguous representation for anonymous types, e.g.
1364 // (anonymous enum at /usr/include/string.h:120:9)
1365 OS << (Policy.MSVCFormatting ? '`' : '(');
1366
1367 if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
1368 OS << "lambda";
1369 HasKindDecoration = true;
1370 } else if ((isa<RecordDecl>(D) && cast<RecordDecl>(D)->isAnonymousStructOrUnion())) {
1371 OS << "anonymous";
1372 } else {
1373 OS << "unnamed";
1374 }
1375
1376 if (Policy.AnonymousTagLocations) {
1377 // Suppress the redundant tag keyword if we just printed one.
1378 // We don't have to worry about ElaboratedTypes here because you can't
1379 // refer to an anonymous type with one.
1380 if (!HasKindDecoration)
1381 OS << " " << D->getKindName();
1382
1384 D->getLocation());
1385 if (PLoc.isValid()) {
1386 OS << " at ";
1387 StringRef File = PLoc.getFilename();
1388 llvm::SmallString<1024> WrittenFile(File);
1389 if (auto *Callbacks = Policy.Callbacks)
1390 WrittenFile = Callbacks->remapPath(File);
1391 // Fix inconsistent path separator created by
1392 // clang::DirectoryLookup::LookupFile when the file path is relative
1393 // path.
1394 llvm::sys::path::Style Style =
1395 llvm::sys::path::is_absolute(WrittenFile)
1396 ? llvm::sys::path::Style::native
1397 : (Policy.MSVCFormatting
1398 ? llvm::sys::path::Style::windows_backslash
1399 : llvm::sys::path::Style::posix);
1400 llvm::sys::path::native(WrittenFile, Style);
1401 OS << WrittenFile << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
1402 }
1403 }
1404
1405 OS << (Policy.MSVCFormatting ? '\'' : ')');
1406 }
1407
1408 // If this is a class template specialization, print the template
1409 // arguments.
1410 if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1412 TypeSourceInfo *TAW = Spec->getTypeAsWritten();
1413 if (!Policy.PrintCanonicalTypes && TAW) {
1414 const TemplateSpecializationType *TST =
1415 cast<TemplateSpecializationType>(TAW->getType());
1416 Args = TST->template_arguments();
1417 } else {
1418 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
1419 Args = TemplateArgs.asArray();
1420 }
1421 IncludeStrongLifetimeRAII Strong(Policy);
1423 OS, Args, Policy,
1424 Spec->getSpecializedTemplate()->getTemplateParameters());
1425 }
1426
1427 spaceBeforePlaceHolder(OS);
1428}
1429
1430void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
1431 // Print the preferred name if we have one for this type.
1432 if (Policy.UsePreferredNames) {
1433 for (const auto *PNA : T->getDecl()->specific_attrs<PreferredNameAttr>()) {
1434 if (!declaresSameEntity(PNA->getTypedefType()->getAsCXXRecordDecl(),
1435 T->getDecl()))
1436 continue;
1437 // Find the outermost typedef or alias template.
1438 QualType T = PNA->getTypedefType();
1439 while (true) {
1440 if (auto *TT = dyn_cast<TypedefType>(T))
1441 return printTypeSpec(TT->getDecl(), OS);
1442 if (auto *TST = dyn_cast<TemplateSpecializationType>(T))
1443 return printTemplateId(TST, OS, /*FullyQualify=*/true);
1445 }
1446 }
1447 }
1448
1449 printTag(T->getDecl(), OS);
1450}
1451
1452void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) {}
1453
1454void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {
1455 printTag(T->getDecl(), OS);
1456}
1457
1458void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {}
1459
1460void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
1461 raw_ostream &OS) {
1462 TemplateTypeParmDecl *D = T->getDecl();
1463 if (D && D->isImplicit()) {
1464 if (auto *TC = D->getTypeConstraint()) {
1465 TC->print(OS, Policy);
1466 OS << ' ';
1467 }
1468 OS << "auto";
1469 } else if (IdentifierInfo *Id = T->getIdentifier())
1470 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1471 : Id->getName());
1472 else
1473 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
1474
1475 spaceBeforePlaceHolder(OS);
1476}
1477
1478void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,
1479 raw_ostream &OS) {}
1480
1481void TypePrinter::printSubstTemplateTypeParmBefore(
1483 raw_ostream &OS) {
1484 IncludeStrongLifetimeRAII Strong(Policy);
1485 printBefore(T->getReplacementType(), OS);
1486}
1487
1488void TypePrinter::printSubstTemplateTypeParmAfter(
1490 raw_ostream &OS) {
1491 IncludeStrongLifetimeRAII Strong(Policy);
1492 printAfter(T->getReplacementType(), OS);
1493}
1494
1495void TypePrinter::printSubstTemplateTypeParmPackBefore(
1497 raw_ostream &OS) {
1498 IncludeStrongLifetimeRAII Strong(Policy);
1499 if (const TemplateTypeParmDecl *D = T->getReplacedParameter()) {
1500 if (D && D->isImplicit()) {
1501 if (auto *TC = D->getTypeConstraint()) {
1502 TC->print(OS, Policy);
1503 OS << ' ';
1504 }
1505 OS << "auto";
1506 } else if (IdentifierInfo *Id = D->getIdentifier())
1507 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1508 : Id->getName());
1509 else
1510 OS << "type-parameter-" << D->getDepth() << '-' << D->getIndex();
1511
1512 spaceBeforePlaceHolder(OS);
1513 }
1514}
1515
1516void TypePrinter::printSubstTemplateTypeParmPackAfter(
1518 raw_ostream &OS) {
1519 IncludeStrongLifetimeRAII Strong(Policy);
1520}
1521
1522void TypePrinter::printTemplateId(const TemplateSpecializationType *T,
1523 raw_ostream &OS, bool FullyQualify) {
1524 IncludeStrongLifetimeRAII Strong(Policy);
1525
1527 // FIXME: Null TD never excercised in test suite.
1528 if (FullyQualify && TD) {
1529 if (!Policy.SuppressScope)
1530 AppendScope(TD->getDeclContext(), OS, TD->getDeclName());
1531
1532 OS << TD->getName();
1533 } else {
1534 T->getTemplateName().print(OS, Policy);
1535 }
1536
1537 DefaultTemplateArgsPolicyRAII TemplateArgs(Policy);
1538 const TemplateParameterList *TPL = TD ? TD->getTemplateParameters() : nullptr;
1539 printTemplateArgumentList(OS, T->template_arguments(), Policy, TPL);
1540 spaceBeforePlaceHolder(OS);
1541}
1542
1543void TypePrinter::printTemplateSpecializationBefore(
1545 raw_ostream &OS) {
1546 printTemplateId(T, OS, Policy.FullyQualifiedName);
1547}
1548
1549void TypePrinter::printTemplateSpecializationAfter(
1551 raw_ostream &OS) {}
1552
1553void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
1554 raw_ostream &OS) {
1555 if (Policy.PrintInjectedClassNameWithArguments)
1556 return printTemplateSpecializationBefore(T->getInjectedTST(), OS);
1557
1558 IncludeStrongLifetimeRAII Strong(Policy);
1559 T->getTemplateName().print(OS, Policy);
1560 spaceBeforePlaceHolder(OS);
1561}
1562
1563void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
1564 raw_ostream &OS) {}
1565
1566void TypePrinter::printElaboratedBefore(const ElaboratedType *T,
1567 raw_ostream &OS) {
1568 if (Policy.IncludeTagDefinition && T->getOwnedTagDecl()) {
1569 TagDecl *OwnedTagDecl = T->getOwnedTagDecl();
1570 assert(OwnedTagDecl->getTypeForDecl() == T->getNamedType().getTypePtr() &&
1571 "OwnedTagDecl expected to be a declaration for the type");
1572 PrintingPolicy SubPolicy = Policy;
1573 SubPolicy.IncludeTagDefinition = false;
1574 OwnedTagDecl->print(OS, SubPolicy, Indentation);
1575 spaceBeforePlaceHolder(OS);
1576 return;
1577 }
1578
1579 // The tag definition will take care of these.
1580 if (!Policy.IncludeTagDefinition)
1581 {
1583 if (T->getKeyword() != ETK_None)
1584 OS << " ";
1586 if (Qualifier)
1587 Qualifier->print(OS, Policy);
1588 }
1589
1590 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1591 printBefore(T->getNamedType(), OS);
1592}
1593
1594void TypePrinter::printElaboratedAfter(const ElaboratedType *T,
1595 raw_ostream &OS) {
1596 if (Policy.IncludeTagDefinition && T->getOwnedTagDecl())
1597 return;
1598 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1599 printAfter(T->getNamedType(), OS);
1600}
1601
1602void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {
1603 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1604 printBefore(T->getInnerType(), OS);
1605 OS << '(';
1606 } else
1607 printBefore(T->getInnerType(), OS);
1608}
1609
1610void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {
1611 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1612 OS << ')';
1613 printAfter(T->getInnerType(), OS);
1614 } else
1615 printAfter(T->getInnerType(), OS);
1616}
1617
1618void TypePrinter::printDependentNameBefore(const DependentNameType *T,
1619 raw_ostream &OS) {
1621 if (T->getKeyword() != ETK_None)
1622 OS << " ";
1623
1624 T->getQualifier()->print(OS, Policy);
1625
1626 OS << T->getIdentifier()->getName();
1627 spaceBeforePlaceHolder(OS);
1628}
1629
1630void TypePrinter::printDependentNameAfter(const DependentNameType *T,
1631 raw_ostream &OS) {}
1632
1633void TypePrinter::printDependentTemplateSpecializationBefore(
1634 const DependentTemplateSpecializationType *T, raw_ostream &OS) {
1635 IncludeStrongLifetimeRAII Strong(Policy);
1636
1638 if (T->getKeyword() != ETK_None)
1639 OS << " ";
1640
1641 if (T->getQualifier())
1642 T->getQualifier()->print(OS, Policy);
1643 OS << "template " << T->getIdentifier()->getName();
1645 spaceBeforePlaceHolder(OS);
1646}
1647
1648void TypePrinter::printDependentTemplateSpecializationAfter(
1649 const DependentTemplateSpecializationType *T, raw_ostream &OS) {}
1650
1651void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,
1652 raw_ostream &OS) {
1653 printBefore(T->getPattern(), OS);
1654}
1655
1656void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
1657 raw_ostream &OS) {
1658 printAfter(T->getPattern(), OS);
1659 OS << "...";
1660}
1661
1662void TypePrinter::printAttributedBefore(const AttributedType *T,
1663 raw_ostream &OS) {
1664 // FIXME: Generate this with TableGen.
1665
1666 // Prefer the macro forms of the GC and ownership qualifiers.
1667 if (T->getAttrKind() == attr::ObjCGC ||
1668 T->getAttrKind() == attr::ObjCOwnership)
1669 return printBefore(T->getEquivalentType(), OS);
1670
1671 if (T->getAttrKind() == attr::ObjCKindOf)
1672 OS << "__kindof ";
1673
1674 if (T->getAttrKind() == attr::AddressSpace)
1675 printBefore(T->getEquivalentType(), OS);
1676 else
1677 printBefore(T->getModifiedType(), OS);
1678
1679 if (T->isMSTypeSpec()) {
1680 switch (T->getAttrKind()) {
1681 default: return;
1682 case attr::Ptr32: OS << " __ptr32"; break;
1683 case attr::Ptr64: OS << " __ptr64"; break;
1684 case attr::SPtr: OS << " __sptr"; break;
1685 case attr::UPtr: OS << " __uptr"; break;
1686 }
1687 spaceBeforePlaceHolder(OS);
1688 }
1689
1690 if (T->isWebAssemblyFuncrefSpec())
1691 OS << "__funcref";
1692
1693 // Print nullability type specifiers.
1694 if (T->getImmediateNullability()) {
1695 if (T->getAttrKind() == attr::TypeNonNull)
1696 OS << " _Nonnull";
1697 else if (T->getAttrKind() == attr::TypeNullable)
1698 OS << " _Nullable";
1699 else if (T->getAttrKind() == attr::TypeNullUnspecified)
1700 OS << " _Null_unspecified";
1701 else if (T->getAttrKind() == attr::TypeNullableResult)
1702 OS << " _Nullable_result";
1703 else
1704 llvm_unreachable("unhandled nullability");
1705 spaceBeforePlaceHolder(OS);
1706 }
1707}
1708
1709void TypePrinter::printAttributedAfter(const AttributedType *T,
1710 raw_ostream &OS) {
1711 // FIXME: Generate this with TableGen.
1712
1713 // Prefer the macro forms of the GC and ownership qualifiers.
1714 if (T->getAttrKind() == attr::ObjCGC ||
1715 T->getAttrKind() == attr::ObjCOwnership)
1716 return printAfter(T->getEquivalentType(), OS);
1717
1718 // If this is a calling convention attribute, don't print the implicit CC from
1719 // the modified type.
1720 SaveAndRestore MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());
1721
1722 printAfter(T->getModifiedType(), OS);
1723
1724 // Some attributes are printed as qualifiers before the type, so we have
1725 // nothing left to do.
1726 if (T->getAttrKind() == attr::ObjCKindOf || T->isMSTypeSpec() ||
1728 return;
1729
1730 // Don't print the inert __unsafe_unretained attribute at all.
1731 if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained)
1732 return;
1733
1734 // Don't print ns_returns_retained unless it had an effect.
1735 if (T->getAttrKind() == attr::NSReturnsRetained &&
1738 return;
1739
1740 if (T->getAttrKind() == attr::LifetimeBound) {
1741 OS << " [[clang::lifetimebound]]";
1742 return;
1743 }
1744
1745 // The printing of the address_space attribute is handled by the qualifier
1746 // since it is still stored in the qualifier. Return early to prevent printing
1747 // this twice.
1748 if (T->getAttrKind() == attr::AddressSpace)
1749 return;
1750
1751 if (T->getAttrKind() == attr::AnnotateType) {
1752 // FIXME: Print the attribute arguments once we have a way to retrieve these
1753 // here. For the meantime, we just print `[[clang::annotate_type(...)]]`
1754 // without the arguments so that we know at least that we had _some_
1755 // annotation on the type.
1756 OS << " [[clang::annotate_type(...)]]";
1757 return;
1758 }
1759
1760 OS << " __attribute__((";
1761 switch (T->getAttrKind()) {
1762#define TYPE_ATTR(NAME)
1763#define DECL_OR_TYPE_ATTR(NAME)
1764#define ATTR(NAME) case attr::NAME:
1765#include "clang/Basic/AttrList.inc"
1766 llvm_unreachable("non-type attribute attached to type");
1767
1768 case attr::BTFTypeTag:
1769 llvm_unreachable("BTFTypeTag attribute handled separately");
1770
1771 case attr::OpenCLPrivateAddressSpace:
1772 case attr::OpenCLGlobalAddressSpace:
1773 case attr::OpenCLGlobalDeviceAddressSpace:
1774 case attr::OpenCLGlobalHostAddressSpace:
1775 case attr::OpenCLLocalAddressSpace:
1776 case attr::OpenCLConstantAddressSpace:
1777 case attr::OpenCLGenericAddressSpace:
1778 case attr::HLSLGroupSharedAddressSpace:
1779 // FIXME: Update printAttributedBefore to print these once we generate
1780 // AttributedType nodes for them.
1781 break;
1782
1783 case attr::LifetimeBound:
1784 case attr::TypeNonNull:
1785 case attr::TypeNullable:
1786 case attr::TypeNullableResult:
1787 case attr::TypeNullUnspecified:
1788 case attr::ObjCGC:
1789 case attr::ObjCInertUnsafeUnretained:
1790 case attr::ObjCKindOf:
1791 case attr::ObjCOwnership:
1792 case attr::Ptr32:
1793 case attr::Ptr64:
1794 case attr::SPtr:
1795 case attr::UPtr:
1796 case attr::AddressSpace:
1797 case attr::CmseNSCall:
1798 case attr::AnnotateType:
1799 case attr::WebAssemblyFuncref:
1800 llvm_unreachable("This attribute should have been handled already");
1801
1802 case attr::NSReturnsRetained:
1803 OS << "ns_returns_retained";
1804 break;
1805
1806 // FIXME: When Sema learns to form this AttributedType, avoid printing the
1807 // attribute again in printFunctionProtoAfter.
1808 case attr::AnyX86NoCfCheck: OS << "nocf_check"; break;
1809 case attr::CDecl: OS << "cdecl"; break;
1810 case attr::FastCall: OS << "fastcall"; break;
1811 case attr::StdCall: OS << "stdcall"; break;
1812 case attr::ThisCall: OS << "thiscall"; break;
1813 case attr::SwiftCall: OS << "swiftcall"; break;
1814 case attr::SwiftAsyncCall: OS << "swiftasynccall"; break;
1815 case attr::VectorCall: OS << "vectorcall"; break;
1816 case attr::Pascal: OS << "pascal"; break;
1817 case attr::MSABI: OS << "ms_abi"; break;
1818 case attr::SysVABI: OS << "sysv_abi"; break;
1819 case attr::RegCall: OS << "regcall"; break;
1820 case attr::Pcs: {
1821 OS << "pcs(";
1822 QualType t = T->getEquivalentType();
1823 while (!t->isFunctionType())
1824 t = t->getPointeeType();
1825 OS << (t->castAs<FunctionType>()->getCallConv() == CC_AAPCS ?
1826 "\"aapcs\"" : "\"aapcs-vfp\"");
1827 OS << ')';
1828 break;
1829 }
1830 case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break;
1831 case attr::AArch64SVEPcs: OS << "aarch64_sve_pcs"; break;
1832 case attr::AMDGPUKernelCall: OS << "amdgpu_kernel"; break;
1833 case attr::IntelOclBicc: OS << "inteloclbicc"; break;
1834 case attr::PreserveMost:
1835 OS << "preserve_most";
1836 break;
1837
1838 case attr::PreserveAll:
1839 OS << "preserve_all";
1840 break;
1841 case attr::NoDeref:
1842 OS << "noderef";
1843 break;
1844 case attr::AcquireHandle:
1845 OS << "acquire_handle";
1846 break;
1847 case attr::ArmMveStrictPolymorphism:
1848 OS << "__clang_arm_mve_strict_polymorphism";
1849 break;
1850 }
1851 OS << "))";
1852}
1853
1854void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T,
1855 raw_ostream &OS) {
1856 printBefore(T->getWrappedType(), OS);
1857 OS << " __attribute__((btf_type_tag(\"" << T->getAttr()->getBTFTypeTag() << "\")))";
1858}
1859
1860void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,
1861 raw_ostream &OS) {
1862 printAfter(T->getWrappedType(), OS);
1863}
1864
1865void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
1866 raw_ostream &OS) {
1867 OS << T->getDecl()->getName();
1868 spaceBeforePlaceHolder(OS);
1869}
1870
1871void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
1872 raw_ostream &OS) {}
1873
1874void TypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType *T,
1875 raw_ostream &OS) {
1876 OS << T->getDecl()->getName();
1877 if (!T->qual_empty()) {
1878 bool isFirst = true;
1879 OS << '<';
1880 for (const auto *I : T->quals()) {
1881 if (isFirst)
1882 isFirst = false;
1883 else
1884 OS << ',';
1885 OS << I->getName();
1886 }
1887 OS << '>';
1888 }
1889
1890 spaceBeforePlaceHolder(OS);
1891}
1892
1893void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T,
1894 raw_ostream &OS) {}
1895
1896void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
1897 raw_ostream &OS) {
1898 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
1900 return printBefore(T->getBaseType(), OS);
1901
1902 if (T->isKindOfTypeAsWritten())
1903 OS << "__kindof ";
1904
1905 print(T->getBaseType(), OS, StringRef());
1906
1907 if (T->isSpecializedAsWritten()) {
1908 bool isFirst = true;
1909 OS << '<';
1910 for (auto typeArg : T->getTypeArgsAsWritten()) {
1911 if (isFirst)
1912 isFirst = false;
1913 else
1914 OS << ",";
1915
1916 print(typeArg, OS, StringRef());
1917 }
1918 OS << '>';
1919 }
1920
1921 if (!T->qual_empty()) {
1922 bool isFirst = true;
1923 OS << '<';
1924 for (const auto *I : T->quals()) {
1925 if (isFirst)
1926 isFirst = false;
1927 else
1928 OS << ',';
1929 OS << I->getName();
1930 }
1931 OS << '>';
1932 }
1933
1934 spaceBeforePlaceHolder(OS);
1935}
1936
1937void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
1938 raw_ostream &OS) {
1939 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
1941 return printAfter(T->getBaseType(), OS);
1942}
1943
1944void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
1945 raw_ostream &OS) {
1946 printBefore(T->getPointeeType(), OS);
1947
1948 // If we need to print the pointer, print it now.
1949 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&
1951 if (HasEmptyPlaceHolder)
1952 OS << ' ';
1953 OS << '*';
1954 }
1955}
1956
1957void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
1958 raw_ostream &OS) {}
1959
1960static
1961const TemplateArgument &getArgument(const TemplateArgument &A) { return A; }
1962
1964 return A.getArgument();
1965}
1966
1967static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP,
1968 llvm::raw_ostream &OS, bool IncludeType) {
1969 A.print(PP, OS, IncludeType);
1970}
1971
1973 const PrintingPolicy &PP, llvm::raw_ostream &OS,
1974 bool IncludeType) {
1975 const TemplateArgument::ArgKind &Kind = A.getArgument().getKind();
1977 return A.getTypeSourceInfo()->getType().print(OS, PP);
1978 return A.getArgument().print(PP, OS, IncludeType);
1979}
1980
1982 TemplateArgument Pattern,
1984 unsigned Depth);
1985
1986static bool isSubstitutedType(ASTContext &Ctx, QualType T, QualType Pattern,
1987 ArrayRef<TemplateArgument> Args, unsigned Depth) {
1988 if (Ctx.hasSameType(T, Pattern))
1989 return true;
1990
1991 // A type parameter matches its argument.
1992 if (auto *TTPT = Pattern->getAs<TemplateTypeParmType>()) {
1993 if (TTPT->getDepth() == Depth && TTPT->getIndex() < Args.size() &&
1994 Args[TTPT->getIndex()].getKind() == TemplateArgument::Type) {
1995 QualType SubstArg = Ctx.getQualifiedType(
1996 Args[TTPT->getIndex()].getAsType(), Pattern.getQualifiers());
1997 return Ctx.hasSameType(SubstArg, T);
1998 }
1999 return false;
2000 }
2001
2002 // FIXME: Recurse into array types.
2003
2004 // All other cases will need the types to be identically qualified.
2005 Qualifiers TQual, PatQual;
2006 T = Ctx.getUnqualifiedArrayType(T, TQual);
2007 Pattern = Ctx.getUnqualifiedArrayType(Pattern, PatQual);
2008 if (TQual != PatQual)
2009 return false;
2010
2011 // Recurse into pointer-like types.
2012 {
2013 QualType TPointee = T->getPointeeType();
2014 QualType PPointee = Pattern->getPointeeType();
2015 if (!TPointee.isNull() && !PPointee.isNull())
2016 return T->getTypeClass() == Pattern->getTypeClass() &&
2017 isSubstitutedType(Ctx, TPointee, PPointee, Args, Depth);
2018 }
2019
2020 // Recurse into template specialization types.
2021 if (auto *PTST =
2023 TemplateName Template;
2024 ArrayRef<TemplateArgument> TemplateArgs;
2025 if (auto *TTST = T->getAs<TemplateSpecializationType>()) {
2026 Template = TTST->getTemplateName();
2027 TemplateArgs = TTST->template_arguments();
2028 } else if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
2029 T->getAsCXXRecordDecl())) {
2030 Template = TemplateName(CTSD->getSpecializedTemplate());
2031 TemplateArgs = CTSD->getTemplateArgs().asArray();
2032 } else {
2033 return false;
2034 }
2035
2036 if (!isSubstitutedTemplateArgument(Ctx, Template, PTST->getTemplateName(),
2037 Args, Depth))
2038 return false;
2039 if (TemplateArgs.size() != PTST->template_arguments().size())
2040 return false;
2041 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
2043 Ctx, TemplateArgs[I], PTST->template_arguments()[I], Args, Depth))
2044 return false;
2045 return true;
2046 }
2047
2048 // FIXME: Handle more cases.
2049 return false;
2050}
2051
2052/// Evaluates the expression template argument 'Pattern' and returns true
2053/// if 'Arg' evaluates to the same result.
2055 TemplateArgument const &Pattern,
2056 TemplateArgument const &Arg) {
2057 if (Pattern.getKind() != TemplateArgument::Expression)
2058 return false;
2059
2060 // Can't evaluate value-dependent expressions so bail early
2061 Expr const *pattern_expr = Pattern.getAsExpr();
2062 if (pattern_expr->isValueDependent() ||
2063 !pattern_expr->isIntegerConstantExpr(Ctx))
2064 return false;
2065
2067 return llvm::APSInt::isSameValue(pattern_expr->EvaluateKnownConstInt(Ctx),
2068 Arg.getAsIntegral());
2069
2071 Expr const *args_expr = Arg.getAsExpr();
2072 if (args_expr->isValueDependent() || !args_expr->isIntegerConstantExpr(Ctx))
2073 return false;
2074
2075 return llvm::APSInt::isSameValue(args_expr->EvaluateKnownConstInt(Ctx),
2076 pattern_expr->EvaluateKnownConstInt(Ctx));
2077 }
2078
2079 return false;
2080}
2081
2083 TemplateArgument Pattern,
2085 unsigned Depth) {
2086 Arg = Ctx.getCanonicalTemplateArgument(Arg);
2087 Pattern = Ctx.getCanonicalTemplateArgument(Pattern);
2088 if (Arg.structurallyEquals(Pattern))
2089 return true;
2090
2091 if (Pattern.getKind() == TemplateArgument::Expression) {
2092 if (auto *DRE =
2093 dyn_cast<DeclRefExpr>(Pattern.getAsExpr()->IgnoreParenImpCasts())) {
2094 if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
2095 return NTTP->getDepth() == Depth && Args.size() > NTTP->getIndex() &&
2096 Args[NTTP->getIndex()].structurallyEquals(Arg);
2097 }
2098 }
2099
2100 if (templateArgumentExpressionsEqual(Ctx, Pattern, Arg))
2101 return true;
2102
2103 if (Arg.getKind() != Pattern.getKind())
2104 return false;
2105
2106 if (Arg.getKind() == TemplateArgument::Type)
2107 return isSubstitutedType(Ctx, Arg.getAsType(), Pattern.getAsType(), Args,
2108 Depth);
2109
2110 if (Arg.getKind() == TemplateArgument::Template) {
2111 TemplateDecl *PatTD = Pattern.getAsTemplate().getAsTemplateDecl();
2112 if (auto *TTPD = dyn_cast_or_null<TemplateTemplateParmDecl>(PatTD))
2113 return TTPD->getDepth() == Depth && Args.size() > TTPD->getIndex() &&
2114 Ctx.getCanonicalTemplateArgument(Args[TTPD->getIndex()])
2115 .structurallyEquals(Arg);
2116 }
2117
2118 // FIXME: Handle more cases.
2119 return false;
2120}
2121
2123 const NamedDecl *Param,
2125 unsigned Depth) {
2126 // An empty pack is equivalent to not providing a pack argument.
2127 if (Arg.getKind() == TemplateArgument::Pack && Arg.pack_size() == 0)
2128 return true;
2129
2130 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Param)) {
2131 return TTPD->hasDefaultArgument() &&
2132 isSubstitutedTemplateArgument(Ctx, Arg, TTPD->getDefaultArgument(),
2133 Args, Depth);
2134 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
2135 return TTPD->hasDefaultArgument() &&
2137 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2138 } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
2139 return NTTPD->hasDefaultArgument() &&
2140 isSubstitutedTemplateArgument(Ctx, Arg, NTTPD->getDefaultArgument(),
2141 Args, Depth);
2142 }
2143 return false;
2144}
2145
2146template <typename TA>
2147static void
2148printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy,
2149 const TemplateParameterList *TPL, bool IsPack, unsigned ParmIndex) {
2150 // Drop trailing template arguments that match default arguments.
2151 if (TPL && Policy.SuppressDefaultTemplateArgs &&
2152 !Policy.PrintCanonicalTypes && !Args.empty() && !IsPack &&
2153 Args.size() <= TPL->size()) {
2155 for (const TA &A : Args)
2156 OrigArgs.push_back(getArgument(A));
2157 while (!Args.empty() && getArgument(Args.back()).getIsDefaulted())
2158 Args = Args.drop_back();
2159 }
2160
2161 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
2162 if (!IsPack)
2163 OS << '<';
2164
2165 bool NeedSpace = false;
2166 bool FirstArg = true;
2167 for (const auto &Arg : Args) {
2168 // Print the argument into a string.
2169 SmallString<128> Buf;
2170 llvm::raw_svector_ostream ArgOS(Buf);
2171 const TemplateArgument &Argument = getArgument(Arg);
2172 if (Argument.getKind() == TemplateArgument::Pack) {
2173 if (Argument.pack_size() && !FirstArg)
2174 OS << Comma;
2175 printTo(ArgOS, Argument.getPackAsArray(), Policy, TPL,
2176 /*IsPack*/ true, ParmIndex);
2177 } else {
2178 if (!FirstArg)
2179 OS << Comma;
2180 // Tries to print the argument with location info if exists.
2181 printArgument(Arg, Policy, ArgOS,
2183 Policy, TPL, ParmIndex));
2184 }
2185 StringRef ArgString = ArgOS.str();
2186
2187 // If this is the first argument and its string representation
2188 // begins with the global scope specifier ('::foo'), add a space
2189 // to avoid printing the diagraph '<:'.
2190 if (FirstArg && !ArgString.empty() && ArgString[0] == ':')
2191 OS << ' ';
2192
2193 OS << ArgString;
2194
2195 // If the last character of our string is '>', add another space to
2196 // keep the two '>''s separate tokens.
2197 if (!ArgString.empty()) {
2198 NeedSpace = Policy.SplitTemplateClosers && ArgString.back() == '>';
2199 FirstArg = false;
2200 }
2201
2202 // Use same template parameter for all elements of Pack
2203 if (!IsPack)
2204 ParmIndex++;
2205 }
2206
2207 if (!IsPack) {
2208 if (NeedSpace)
2209 OS << ' ';
2210 OS << '>';
2211 }
2212}
2213
2215 const TemplateArgumentListInfo &Args,
2216 const PrintingPolicy &Policy,
2217 const TemplateParameterList *TPL) {
2218 printTemplateArgumentList(OS, Args.arguments(), Policy, TPL);
2219}
2220
2223 const PrintingPolicy &Policy,
2224 const TemplateParameterList *TPL) {
2225 printTo(OS, Args, Policy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2226}
2227
2230 const PrintingPolicy &Policy,
2231 const TemplateParameterList *TPL) {
2232 printTo(OS, Args, Policy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2233}
2234
2235std::string Qualifiers::getAsString() const {
2236 LangOptions LO;
2237 return getAsString(PrintingPolicy(LO));
2238}
2239
2240// Appends qualifiers to the given string, separated by spaces. Will
2241// prefix a space if the string is non-empty. Will not append a final
2242// space.
2243std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {
2244 SmallString<64> Buf;
2245 llvm::raw_svector_ostream StrOS(Buf);
2246 print(StrOS, Policy);
2247 return std::string(StrOS.str());
2248}
2249
2251 if (getCVRQualifiers())
2252 return false;
2253
2255 return false;
2256
2257 if (getObjCGCAttr())
2258 return false;
2259
2261 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
2262 return false;
2263
2264 return true;
2265}
2266
2268 switch (AS) {
2269 case LangAS::Default:
2270 return "";
2273 return "__global";
2275 case LangAS::sycl_local:
2276 return "__local";
2279 return "__private";
2281 return "__constant";
2283 return "__generic";
2286 return "__global_device";
2289 return "__global_host";
2291 return "__device__";
2293 return "__constant__";
2295 return "__shared__";
2296 case LangAS::ptr32_sptr:
2297 return "__sptr __ptr32";
2298 case LangAS::ptr32_uptr:
2299 return "__uptr __ptr32";
2300 case LangAS::ptr64:
2301 return "__ptr64";
2303 return "__funcref";
2305 return "groupshared";
2306 default:
2307 return std::to_string(toTargetAddressSpace(AS));
2308 }
2309}
2310
2311// Appends qualifiers to the given string, separated by spaces. Will
2312// prefix a space if the string is non-empty. Will not append a final
2313// space.
2314void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
2315 bool appendSpaceIfNonEmpty) const {
2316 bool addSpace = false;
2317
2318 unsigned quals = getCVRQualifiers();
2319 if (quals) {
2320 AppendTypeQualList(OS, quals, Policy.Restrict);
2321 addSpace = true;
2322 }
2323 if (hasUnaligned()) {
2324 if (addSpace)
2325 OS << ' ';
2326 OS << "__unaligned";
2327 addSpace = true;
2328 }
2329 auto ASStr = getAddrSpaceAsString(getAddressSpace());
2330 if (!ASStr.empty()) {
2331 if (addSpace)
2332 OS << ' ';
2333 addSpace = true;
2334 // Wrap target address space into an attribute syntax
2336 OS << "__attribute__((address_space(" << ASStr << ")))";
2337 else
2338 OS << ASStr;
2339 }
2340
2341 if (Qualifiers::GC gc = getObjCGCAttr()) {
2342 if (addSpace)
2343 OS << ' ';
2344 addSpace = true;
2345 if (gc == Qualifiers::Weak)
2346 OS << "__weak";
2347 else
2348 OS << "__strong";
2349 }
2350 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
2351 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
2352 if (addSpace)
2353 OS << ' ';
2354 addSpace = true;
2355 }
2356
2357 switch (lifetime) {
2358 case Qualifiers::OCL_None: llvm_unreachable("none but true");
2359 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;
2361 if (!Policy.SuppressStrongLifetime)
2362 OS << "__strong";
2363 break;
2364
2365 case Qualifiers::OCL_Weak: OS << "__weak"; break;
2366 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
2367 }
2368 }
2369
2370 if (appendSpaceIfNonEmpty && addSpace)
2371 OS << ' ';
2372}
2373
2374std::string QualType::getAsString() const {
2375 return getAsString(split(), LangOptions());
2376}
2377
2378std::string QualType::getAsString(const PrintingPolicy &Policy) const {
2379 std::string S;
2380 getAsStringInternal(S, Policy);
2381 return S;
2382}
2383
2384std::string QualType::getAsString(const Type *ty, Qualifiers qs,
2385 const PrintingPolicy &Policy) {
2386 std::string buffer;
2387 getAsStringInternal(ty, qs, buffer, Policy);
2388 return buffer;
2389}
2390
2391void QualType::print(raw_ostream &OS, const PrintingPolicy &Policy,
2392 const Twine &PlaceHolder, unsigned Indentation) const {
2393 print(splitAccordingToPolicy(*this, Policy), OS, Policy, PlaceHolder,
2394 Indentation);
2395}
2396
2398 raw_ostream &OS, const PrintingPolicy &policy,
2399 const Twine &PlaceHolder, unsigned Indentation) {
2400 SmallString<128> PHBuf;
2401 StringRef PH = PlaceHolder.toStringRef(PHBuf);
2402
2403 TypePrinter(policy, Indentation).print(ty, qs, OS, PH);
2404}
2405
2406void QualType::getAsStringInternal(std::string &Str,
2407 const PrintingPolicy &Policy) const {
2408 return getAsStringInternal(splitAccordingToPolicy(*this, Policy), Str,
2409 Policy);
2410}
2411
2413 std::string &buffer,
2414 const PrintingPolicy &policy) {
2415 SmallString<256> Buf;
2416 llvm::raw_svector_ostream StrOS(Buf);
2417 TypePrinter(policy).print(ty, qs, StrOS, buffer);
2418 std::string str = std::string(StrOS.str());
2419 buffer.swap(str);
2420}
2421
2422raw_ostream &clang::operator<<(raw_ostream &OS, QualType QT) {
2423 SplitQualType S = QT.split();
2424 TypePrinter(LangOptions()).print(S.Ty, S.Quals, OS, /*PlaceHolder=*/"");
2425 return OS;
2426}
Defines the clang::ASTContext interface.
int Id
Definition: ASTDiff.cpp:190
Provides definitions for the various language-specific address spaces.
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 &, QualType)
Definition: InterpFrame.cpp:89
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
static void 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 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:182
SourceManager & getSourceManager()
Definition: ASTContext.h:691
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:2540
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
Definition: ASTContext.h:2122
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals)
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:2829
QualType getAdjustedType() const
Definition: Type.h:2843
ArraySizeModifier getSizeModifier() const
Definition: Type.h:3066
Qualifiers getIndexTypeQualifiers() const
Definition: Type.h:3070
QualType getElementType() const
Definition: Type.h:3064
unsigned getIndexTypeCVRQualifiers() const
Definition: Type.h:3074
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
Definition: Type.h:6493
An attributed type is a type to which a type attribute has been applied.
Definition: Type.h:4905
QualType getModifiedType() const
Definition: Type.h:4927
bool isCallingConv() const
Definition: Type.cpp:3778
std::optional< NullabilityKind > getImmediateNullability() const
Definition: Type.cpp:4462
bool isMSTypeSpec() const
Definition: Type.cpp:3761
QualType getEquivalentType() const
Definition: Type.h:4928
Kind getAttrKind() const
Definition: Type.h:4923
bool isWebAssemblyFuncrefSpec() const
Definition: Type.cpp:3774
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Definition: Type.h:5282
ArrayRef< TemplateArgument > getTypeConstraintArguments() const
Definition: Type.h:5292
ConceptDecl * getTypeConstraintConcept() const
Definition: Type.h:5297
AutoTypeKeyword getKeyword() const
Definition: Type.h:5313
bool isConstrained() const
Definition: Type.h:5301
const BTFTypeTagAttr * getAttr() const
Definition: Type.h:5018
QualType getWrappedType() const
Definition: Type.h:5017
A fixed int type of a specified bitwidth.
Definition: Type.h:6546
bool isUnsigned() const
Definition: Type.h:6555
unsigned getNumBits() const
Definition: Type.h:6557
Pointer to a block type.
Definition: Type.h:2880
QualType getPointeeType() const
Definition: Type.h:2892
This class is used for builtin types like 'int'.
Definition: Type.h:2646
StringRef getName(const PrintingPolicy &Policy) const
Definition: Type.cpp:3113
Complex values, per C99 6.2.5p11.
Definition: Type.h:2747
QualType getElementType() const
Definition: Type.h:2757
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:3091
const llvm::APInt & getSize() const
Definition: Type.h:3112
Represents a concrete matrix type with constant number of rows and columns.
Definition: Type.h:3618
unsigned getNumColumns() const
Returns the number of columns in the matrix.
Definition: Type.h:3639
unsigned getNumRows() const
Returns the number of rows in the matrix.
Definition: Type.h:3636
Represents a pointer type decayed from an array or function type.
Definition: Type.h:2863
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1402
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1942
bool isTranslationUnit() const
Definition: DeclBase.h:2017
bool isFunctionOrMethod() const
Definition: DeclBase.h:1994
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:429
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:576
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
Definition: DeclBase.h:542
SourceLocation getLocation() const
Definition: DeclBase.h:432
DeclContext * getDeclContext()
Definition: DeclBase.h:441
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
The name of a declaration.
void print(raw_ostream &OS, const PrintingPolicy &Policy) const
Represents the type decltype(expr) (C++11).
Definition: Type.h:4724
Expr * getUnderlyingExpr() const
Definition: Type.h:4734
Represents a C++17 deduced template specialization type.
Definition: Type.h:5330
TemplateName getTemplateName() const
Retrieve the name of the template that we are deducing.
Definition: Type.h:5350
QualType getDeducedType() const
Get the type deduced for this placeholder type, or null if it has not been deduced.
Definition: Type.h:5269
Represents an extended address space qualifier where the input address space value is dependent.
Definition: Type.h:3307
Expr * getAddrSpaceExpr() const
Definition: Type.h:3320
QualType getPointeeType() const
Definition: Type.h:3321
Expr * getNumBitsExpr() const
Definition: Type.cpp:357
bool isUnsigned() const
Definition: Type.cpp:353
Represents a qualified type name for which the type name is dependent.
Definition: Type.h:5755
NestedNameSpecifier * getQualifier() const
Retrieve the qualification on this type.
Definition: Type.h:5773
const IdentifierInfo * getIdentifier() const
Retrieve the type named by the typename specifier as an identifier.
Definition: Type.h:5780
Represents an array type in C++ whose size is a value-dependent expression.
Definition: Type.h:3247
Expr * getSizeExpr() const
Definition: Type.h:3269
Represents an extended vector type where either the type or size is dependent.
Definition: Type.h:3349
QualType getElementType() const
Definition: Type.h:3365
Represents a matrix type where the type and the number of rows and columns is dependent on a template...
Definition: Type.h:3677
Expr * getColumnExpr() const
Definition: Type.h:3692
Expr * getRowExpr() const
Definition: Type.h:3691
Represents a template specialization type whose template cannot be resolved, e.g.
Definition: Type.h:5808
const IdentifierInfo * getIdentifier() const
Definition: Type.h:5825
ArrayRef< TemplateArgument > template_arguments() const
Definition: Type.h:5827
NestedNameSpecifier * getQualifier() const
Definition: Type.h:5824
Represents a vector type where either the type or size is dependent.
Definition: Type.h:3471
Expr * getSizeExpr() const
Definition: Type.h:3484
VectorType::VectorKind getVectorKind() const
Definition: Type.h:3487
QualType getElementType() const
Definition: Type.h:3485
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
Definition: Type.h:5674
TagDecl * getOwnedTagDecl() const
Return the (re)declaration of this type owned by this occurrence of this type, or nullptr if there is...
Definition: Type.h:5722
NestedNameSpecifier * getQualifier() const
Retrieve the qualification on this type.
Definition: Type.h:5709
QualType getNamedType() const
Retrieve the type named by the qualified-id.
Definition: Type.h:5712
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Definition: Type.h:4876
EnumDecl * getDecl() const
Definition: Type.h:4883
This represents one expression.
Definition: Expr.h:110
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition: Expr.h:169
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:3055
bool isIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
ExtVectorType - Extended vector type.
Definition: Type.h:3513
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition: Type.h:4012
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4056
ExtParameterInfo getExtParameterInfo(unsigned I) const
Definition: Type.h:4463
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Definition: Type.h:4286
unsigned getNumParams() const
Definition: Type.h:4261
void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
Definition: Type.h:4399
Qualifiers getMethodQuals() const
Definition: Type.h:4401
QualType getParamType(unsigned i) const
Definition: Type.h:4263
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
Definition: Type.h:4337
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition: Type.h:4329
bool hasDynamicExceptionSpec() const
Return whether this function has a dynamic (throw) exception spec.
Definition: Type.h:4295
bool isVariadic() const
Whether this function prototype is variadic.
Definition: Type.h:4383
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
Definition: Type.h:4344
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Definition: Type.h:4409
A class which abstracts out some details necessary for making a call.
Definition: Type.h:3820
CallingConv getCC() const
Definition: Type.h:3882
bool getCmseNSCall() const
Definition: Type.h:3870
bool getNoCfCheck() const
Definition: Type.h:3872
unsigned getRegParm() const
Definition: Type.h:3875
bool getNoCallerSavedRegs() const
Definition: Type.h:3871
bool getNoReturn() const
Definition: Type.h:3868
bool getProducesResult() const
Definition: Type.h:3869
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:3709
ExtInfo getExtInfo() const
Definition: Type.h:3986
QualType getReturnType() const
Definition: Type.h:3974
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:3149
The injected class name of a C++ class template or class template partial specialization.
Definition: Type.h:5524
const TemplateSpecializationType * getInjectedTST() const
Definition: Type.h:5557
TemplateName getTemplateName() const
Definition: Type.h:5561
An lvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:2955
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:82
Sugar type that represents a type that was qualified by a qualifier written as a macro invocation.
Definition: Type.h:4605
QualType getModifiedType() const
Return this attributed type's modified type with no qualifiers attached to it.
Definition: Type.cpp:3607
const IdentifierInfo * getMacroIdentifier() const
Definition: Type.h:4620
QualType getElementType() const
Returns type of the elements being stored in the matrix.
Definition: Type.h:3596
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition: Type.h:2991
QualType getPointeeType() const
Definition: Type.h:3007
const Type * getClass() const
Definition: Type.h:3021
This represents a decl that may have a name.
Definition: Decl.h:247
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
Definition: Decl.h:457
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:268
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:274
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:313
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false) const
Print this nested name specifier to the given output stream.
Interfaces are the core concept in Objective-C for object oriented design.
Definition: Type.h:6256
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
Definition: Type.cpp:829
Represents a pointer to an Objective C object.
Definition: Type.h:6312
bool isObjCQualifiedClassType() const
True if this is equivalent to 'Class.
Definition: Type.h:6393
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
Definition: Type.h:6387
bool isObjCIdType() const
True if this is equivalent to the 'id' type, i.e.
Definition: Type.h:6370
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
Definition: Type.h:6324
bool isObjCClassType() const
True if this is equivalent to the 'Class' type, i.e.
Definition: Type.h:6376
Represents a class type in Objective C.
Definition: Type.h:6058
bool isKindOfTypeAsWritten() const
Whether this is a "__kindof" type as written.
Definition: Type.h:6173
ArrayRef< QualType > getTypeArgsAsWritten() const
Retrieve the type arguments of this object type as they were written.
Definition: Type.h:6168
bool isUnspecializedAsWritten() const
Determine whether this object type is "unspecialized" as written, meaning that it has no type argumen...
Definition: Type.h:6161
QualType getBaseType() const
Gets the base type of this object type.
Definition: Type.h:6120
bool isSpecializedAsWritten() const
Determine whether this object type was written with type arguments.
Definition: Type.h:6151
qual_range quals() const
Definition: Type.h:5956
bool qual_empty() const
Definition: Type.h:5960
Represents a type parameter type in Objective C.
Definition: Type.h:5984
ObjCTypeParamDecl * getDecl() const
Definition: Type.h:6026
Represents a pack expansion of types.
Definition: Type.h:5873
QualType getPattern() const
Retrieve the pattern of this pack expansion, which is the type that will be repeatedly instantiated w...
Definition: Type.h:5894
Sugar for parentheses used when specifying types.
Definition: Type.h:2774
QualType getInnerType() const
Definition: Type.h:2783
PipeType - OpenCL20.
Definition: Type.h:6512
QualType getElementType() const
Definition: Type.h:6523
bool isReadOnly() const
Definition: Type.h:6542
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:2800
QualType getPointeeType() const
Definition: Type.h:2810
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:736
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:803
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:6664
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition: Type.h:6704
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const
QualType getCanonicalType() const
Definition: Type.h:6716
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
Definition: Type.h:6685
std::string getAsString() const
StreamedQualTypeHelper stream(const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Definition: Type.h:1147
The collection of all-type qualifiers we support.
Definition: Type.h:146
unsigned getCVRQualifiers() const
Definition: Type.h:294
GC getObjCGCAttr() const
Definition: Type.h:325
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Definition: Type.h:174
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
Definition: Type.h:167
@ OCL_None
There is no lifetime qualification on this type.
Definition: Type.h:163
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Definition: Type.h:177
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
Definition: Type.h:180
bool hasQualifiers() const
Return true if the set contains any qualifiers.
Definition: Type.h:438
bool hasUnaligned() const
Definition: Type.h:317
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool appendSpaceIfNonEmpty=false) const
bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const
ObjCLifetime getObjCLifetime() const
Definition: Type.h:351
bool empty() const
Definition: Type.h:439
std::string getAsString() const
LangAS getAddressSpace() const
Definition: Type.h:377
static std::string getAddrSpaceAsString(LangAS AS)
An rvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:2973
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4850
RecordDecl * getDecl() const
Definition: Type.h:4860
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:2911
QualType getPointeeTypeAsWritten() const
Definition: Type.h:2927
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:5190
const TemplateTypeParmDecl * getReplacedParameter() const
Gets the template parameter declaration that was substituted for.
Definition: Type.cpp:3864
Represents the result of substituting a type for a template type parameter.
Definition: Type.h:5120
QualType getReplacementType() const
Gets the type that was substituted for the template parameter.
Definition: Type.h:5132
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3454
StringRef getKindName() const
Definition: Decl.h:3645
TypedefNameDecl * getTypedefNameForAnonDecl() const
Definition: Decl.h:3680
A convenient class for passing around template argument information.
Definition: TemplateBase.h:590
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
Definition: TemplateBase.h:618
A template argument list.
Definition: DeclTemplate.h:240
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Definition: DeclTemplate.h:292
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:484
const TemplateArgument & getArgument() const
Definition: TemplateBase.h:533
TypeSourceInfo * getTypeSourceInfo() const
Definition: TemplateBase.h:541
Represents a template argument.
Definition: TemplateBase.h:60
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
Definition: TemplateBase.h:404
Expr * getAsExpr() const
Retrieve the template argument as an expression.
Definition: TemplateBase.h:368
QualType getAsType() const
Retrieve the type for a type template argument.
Definition: TemplateBase.h:287
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
Definition: TemplateBase.h:331
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
Definition: TemplateBase.h:311
unsigned pack_size() const
The number of template arguments in the given template argument pack.
Definition: TemplateBase.h:398
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:361
ArgKind
The kind of template argument we're storing.
Definition: TemplateBase.h:63
@ Template
The template argument is a template name that was provided for a template template parameter.
Definition: TemplateBase.h:85
@ Pack
The template argument is actually a parameter pack.
Definition: TemplateBase.h:99
@ Type
The template argument is a type.
Definition: TemplateBase.h:69
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
Definition: TemplateBase.h:81
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
Definition: TemplateBase.h:95
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:263
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:409
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:428
Represents a C++ template name within the type system.
Definition: TemplateName.h:202
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known.
void print(raw_ostream &OS, const PrintingPolicy &Policy, Qualified Qual=Qualified::AsWritten) const
Print the template name.
Stores a list of template parameters for a TemplateDecl and its derived classes.
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:5392
ArrayRef< TemplateArgument > template_arguments() const
Definition: Type.h:5460
TemplateName getTemplateName() const
Retrieve the name of the template that we are specializing.
Definition: Type.h:5458
Declaration of a template type parameter.
unsigned getIndex() const
Retrieve the index of the template parameter.
const TypeConstraint * getTypeConstraint() const
Returns the type constraint associated with this template parameter (if any).
unsigned getDepth() const
Retrieve the depth of the template parameter.
TemplateTypeParmDecl * getDecl() const
Definition: Type.h:5083
unsigned getIndex() const
Definition: Type.h:5080
IdentifierInfo * getIdentifier() const
Definition: Type.cpp:3809
unsigned getDepth() const
Definition: Type.h:5079
const Type * getTypeForDecl() const
Definition: Decl.h:3286
Represents a typeof (or typeof) expression (a C2x feature and GCC extension) or a typeof_unqual expre...
Definition: Type.h:4637
TypeOfKind getKind() const
Returns the kind of 'typeof' type this is.
Definition: Type.h:4649
Expr * getUnderlyingExpr() const
Definition: Type.h:4646
Represents typeof(type), a C2x feature and GCC extension, or `typeof_unqual(type),...
Definition: Type.h:4688
TypeOfKind getKind() const
Returns the kind of 'typeof' type this is.
Definition: Type.h:4715
QualType getUnmodifiedType() const
Definition: Type.h:4703
A container of type source information.
Definition: Type.h:6635
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:6646
static StringRef getKeywordName(ElaboratedTypeKeyword Keyword)
Definition: Type.cpp:3040
ElaboratedTypeKeyword getKeyword() const
Definition: Type.h:5632
The base class of the type hierarchy.
Definition: Type.h:1568
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1799
QualType getLocallyUnqualifiedSingleStepDesugaredType() const
Pull a single level of sugar off of this locally-unqualified type.
Definition: Type.cpp:424
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:7497
bool isObjCQualifiedIdType() const
Definition: Type.h:7065
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:631
bool isObjCIdType() const
Definition: Type.h:7077
bool isSpecifierType() const
Returns true if this type can be represented by some set of type specifiers.
Definition: Type.cpp:2947
bool isFunctionType() const
Definition: Type.h:6912
bool isObjCQualifiedClassType() const
Definition: Type.h:7071
bool isObjCClassType() const
Definition: Type.h:7083
TypeClass getTypeClass() const
Definition: Type.h:1987
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7430
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3304
TypedefNameDecl * getDecl() const
Definition: Type.h:4580
A unary type transform, which is a type constructed from another.
Definition: Type.h:4767
QualType getBaseType() const
Definition: Type.h:4794
UTTKind getUTTKind() const
Definition: Type.h:4796
Represents the dependent type named by a dependently-scoped typename using declaration,...
Definition: Type.h:4506
UnresolvedUsingTypenameDecl * getDecl() const
Definition: Type.h:4517
UsingShadowDecl * getFoundDecl() const
Definition: Type.h:4546
Represents a C array with a specified size that is not an integer-constant-expression.
Definition: Type.h:3193
Expr * getSizeExpr() const
Definition: Type.h:3212
Represents a GCC generic vector type.
Definition: Type.h:3389
unsigned getNumElements() const
Definition: Type.h:3434
@ AltiVecBool
is AltiVec 'vector bool ...'
Definition: Type.h:3402
@ RVVFixedLengthDataVector
is RISC-V RVV fixed-length data vector
Definition: Type.h:3417
@ SveFixedLengthPredicateVector
is AArch64 SVE fixed-length predicate vector
Definition: Type.h:3414
@ NeonPolyVector
is ARM Neon polynomial vector
Definition: Type.h:3408
@ GenericVector
not a target-specific vector type
Definition: Type.h:3393
@ AltiVecPixel
is AltiVec 'vector Pixel'
Definition: Type.h:3399
@ SveFixedLengthDataVector
is AArch64 SVE fixed-length data vector
Definition: Type.h:3411
@ AltiVecVector
is AltiVec vector
Definition: Type.h:3396
@ NeonVector
is ARM Neon vector
Definition: Type.h:3405
VectorKind getVectorKind() const
Definition: Type.h:3439
QualType getElementType() const
Definition: Type.h:3433
@ 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:1521
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
Definition: Type.h:1524
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition: Type.h:1527
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:353
@ 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 ...
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:1253
@ CC_X86Pascal
Definition: Specifiers.h:275
@ CC_Swift
Definition: Specifiers.h:284
@ CC_IntelOclBicc
Definition: Specifiers.h:281
@ CC_OpenCLKernel
Definition: Specifiers.h:283
@ CC_PreserveMost
Definition: Specifiers.h:286
@ CC_Win64
Definition: Specifiers.h:276
@ CC_X86ThisCall
Definition: Specifiers.h:273
@ CC_AArch64VectorCall
Definition: Specifiers.h:288
@ CC_AAPCS
Definition: Specifiers.h:279
@ CC_C
Definition: Specifiers.h:270
@ CC_AMDGPUKernelCall
Definition: Specifiers.h:290
@ CC_SwiftAsync
Definition: Specifiers.h:285
@ CC_X86RegCall
Definition: Specifiers.h:278
@ CC_X86VectorCall
Definition: Specifiers.h:274
@ CC_SpirFunction
Definition: Specifiers.h:282
@ CC_AArch64SVEPCS
Definition: Specifiers.h:289
@ CC_X86StdCall
Definition: Specifiers.h:271
@ CC_X86_64SysV
Definition: Specifiers.h:277
@ CC_PreserveAll
Definition: Specifiers.h:287
@ CC_X86FastCall
Definition: Specifiers.h:272
@ CC_AAPCS_VFP
Definition: Specifiers.h:280
@ ETK_None
No keyword precedes the qualified type name.
Definition: Type.h:5616
@ EST_NoThrow
Microsoft __declspec(nothrow) extension.
@ EST_MSAny
Microsoft throw(...) extension.
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:669
const Type * Ty
The locally-unqualified type.
Definition: Type.h:671
Qualifiers Quals
The local qualifiers.
Definition: Type.h:674