clang 19.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 case Type::PackIndexing: {
300 return canPrefixQualifiers(
301 cast<PackIndexingType>(UnderlyingType)->getPattern().getTypePtr(),
302 NeedARCStrongQualifier);
303 }
304 }
305
306 return CanPrefixQualifiers;
307}
308
309void TypePrinter::printBefore(QualType T, raw_ostream &OS) {
311
312 // If we have cv1 T, where T is substituted for cv2 U, only print cv1 - cv2
313 // at this level.
314 Qualifiers Quals = Split.Quals;
315 if (const auto *Subst = dyn_cast<SubstTemplateTypeParmType>(Split.Ty))
316 Quals -= QualType(Subst, 0).getQualifiers();
317
318 printBefore(Split.Ty, Quals, OS);
319}
320
321/// Prints the part of the type string before an identifier, e.g. for
322/// "int foo[10]" it prints "int ".
323void TypePrinter::printBefore(const Type *T,Qualifiers Quals, raw_ostream &OS) {
324 if (Policy.SuppressSpecifiers && T->isSpecifierType())
325 return;
326
327 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder);
328
329 // Print qualifiers as appropriate.
330
331 bool CanPrefixQualifiers = false;
332 bool NeedARCStrongQualifier = false;
333 CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier);
334
335 if (CanPrefixQualifiers && !Quals.empty()) {
336 if (NeedARCStrongQualifier) {
337 IncludeStrongLifetimeRAII Strong(Policy);
338 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
339 } else {
340 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
341 }
342 }
343
344 bool hasAfterQuals = false;
345 if (!CanPrefixQualifiers && !Quals.empty()) {
346 hasAfterQuals = !Quals.isEmptyWhenPrinted(Policy);
347 if (hasAfterQuals)
348 HasEmptyPlaceHolder = false;
349 }
350
351 switch (T->getTypeClass()) {
352#define ABSTRACT_TYPE(CLASS, PARENT)
353#define TYPE(CLASS, PARENT) case Type::CLASS: \
354 print##CLASS##Before(cast<CLASS##Type>(T), OS); \
355 break;
356#include "clang/AST/TypeNodes.inc"
357 }
358
359 if (hasAfterQuals) {
360 if (NeedARCStrongQualifier) {
361 IncludeStrongLifetimeRAII Strong(Policy);
362 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
363 } else {
364 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
365 }
366 }
367}
368
369void TypePrinter::printAfter(QualType t, raw_ostream &OS) {
370 SplitQualType split = splitAccordingToPolicy(t, Policy);
371 printAfter(split.Ty, split.Quals, OS);
372}
373
374/// Prints the part of the type string after an identifier, e.g. for
375/// "int foo[10]" it prints "[10]".
376void TypePrinter::printAfter(const Type *T, Qualifiers Quals, raw_ostream &OS) {
377 switch (T->getTypeClass()) {
378#define ABSTRACT_TYPE(CLASS, PARENT)
379#define TYPE(CLASS, PARENT) case Type::CLASS: \
380 print##CLASS##After(cast<CLASS##Type>(T), OS); \
381 break;
382#include "clang/AST/TypeNodes.inc"
383 }
384}
385
386void TypePrinter::printBuiltinBefore(const BuiltinType *T, raw_ostream &OS) {
387 OS << T->getName(Policy);
388 spaceBeforePlaceHolder(OS);
389}
390
391void TypePrinter::printBuiltinAfter(const BuiltinType *T, raw_ostream &OS) {}
392
393void TypePrinter::printComplexBefore(const ComplexType *T, raw_ostream &OS) {
394 OS << "_Complex ";
395 printBefore(T->getElementType(), OS);
396}
397
398void TypePrinter::printComplexAfter(const ComplexType *T, raw_ostream &OS) {
399 printAfter(T->getElementType(), OS);
400}
401
402void TypePrinter::printPointerBefore(const PointerType *T, raw_ostream &OS) {
403 IncludeStrongLifetimeRAII Strong(Policy);
404 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
405 printBefore(T->getPointeeType(), OS);
406 // Handle things like 'int (*A)[4];' correctly.
407 // FIXME: this should include vectors, but vectors use attributes I guess.
408 if (isa<ArrayType>(T->getPointeeType()))
409 OS << '(';
410 OS << '*';
411}
412
413void TypePrinter::printPointerAfter(const PointerType *T, raw_ostream &OS) {
414 IncludeStrongLifetimeRAII Strong(Policy);
415 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
416 // Handle things like 'int (*A)[4];' correctly.
417 // FIXME: this should include vectors, but vectors use attributes I guess.
418 if (isa<ArrayType>(T->getPointeeType()))
419 OS << ')';
420 printAfter(T->getPointeeType(), OS);
421}
422
423void TypePrinter::printBlockPointerBefore(const BlockPointerType *T,
424 raw_ostream &OS) {
425 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
426 printBefore(T->getPointeeType(), OS);
427 OS << '^';
428}
429
430void TypePrinter::printBlockPointerAfter(const BlockPointerType *T,
431 raw_ostream &OS) {
432 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
433 printAfter(T->getPointeeType(), OS);
434}
435
436// When printing a reference, the referenced type might also be a reference.
437// If so, we want to skip that before printing the inner type.
439 if (auto *Ref = T->getAs<ReferenceType>())
440 return skipTopLevelReferences(Ref->getPointeeTypeAsWritten());
441 return T;
442}
443
444void TypePrinter::printLValueReferenceBefore(const LValueReferenceType *T,
445 raw_ostream &OS) {
446 IncludeStrongLifetimeRAII Strong(Policy);
447 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
449 printBefore(Inner, OS);
450 // Handle things like 'int (&A)[4];' correctly.
451 // FIXME: this should include vectors, but vectors use attributes I guess.
452 if (isa<ArrayType>(Inner))
453 OS << '(';
454 OS << '&';
455}
456
457void TypePrinter::printLValueReferenceAfter(const LValueReferenceType *T,
458 raw_ostream &OS) {
459 IncludeStrongLifetimeRAII Strong(Policy);
460 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
462 // Handle things like 'int (&A)[4];' correctly.
463 // FIXME: this should include vectors, but vectors use attributes I guess.
464 if (isa<ArrayType>(Inner))
465 OS << ')';
466 printAfter(Inner, OS);
467}
468
469void TypePrinter::printRValueReferenceBefore(const RValueReferenceType *T,
470 raw_ostream &OS) {
471 IncludeStrongLifetimeRAII Strong(Policy);
472 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
474 printBefore(Inner, OS);
475 // Handle things like 'int (&&A)[4];' correctly.
476 // FIXME: this should include vectors, but vectors use attributes I guess.
477 if (isa<ArrayType>(Inner))
478 OS << '(';
479 OS << "&&";
480}
481
482void TypePrinter::printRValueReferenceAfter(const RValueReferenceType *T,
483 raw_ostream &OS) {
484 IncludeStrongLifetimeRAII Strong(Policy);
485 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
487 // Handle things like 'int (&&A)[4];' correctly.
488 // FIXME: this should include vectors, but vectors use attributes I guess.
489 if (isa<ArrayType>(Inner))
490 OS << ')';
491 printAfter(Inner, OS);
492}
493
494void TypePrinter::printMemberPointerBefore(const MemberPointerType *T,
495 raw_ostream &OS) {
496 IncludeStrongLifetimeRAII Strong(Policy);
497 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
498 printBefore(T->getPointeeType(), OS);
499 // Handle things like 'int (Cls::*A)[4];' correctly.
500 // FIXME: this should include vectors, but vectors use attributes I guess.
501 if (isa<ArrayType>(T->getPointeeType()))
502 OS << '(';
503
504 PrintingPolicy InnerPolicy(Policy);
505 InnerPolicy.IncludeTagDefinition = false;
506 TypePrinter(InnerPolicy).print(QualType(T->getClass(), 0), OS, StringRef());
507
508 OS << "::*";
509}
510
511void TypePrinter::printMemberPointerAfter(const MemberPointerType *T,
512 raw_ostream &OS) {
513 IncludeStrongLifetimeRAII Strong(Policy);
514 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
515 // Handle things like 'int (Cls::*A)[4];' correctly.
516 // FIXME: this should include vectors, but vectors use attributes I guess.
517 if (isa<ArrayType>(T->getPointeeType()))
518 OS << ')';
519 printAfter(T->getPointeeType(), OS);
520}
521
522void TypePrinter::printConstantArrayBefore(const ConstantArrayType *T,
523 raw_ostream &OS) {
524 IncludeStrongLifetimeRAII Strong(Policy);
525 printBefore(T->getElementType(), OS);
526}
527
528void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T,
529 raw_ostream &OS) {
530 OS << '[';
533 Policy.Restrict);
534 OS << ' ';
535 }
536
537 if (T->getSizeModifier() == ArraySizeModifier::Static)
538 OS << "static ";
539
540 OS << T->getSize().getZExtValue() << ']';
541 printAfter(T->getElementType(), OS);
542}
543
544void TypePrinter::printIncompleteArrayBefore(const IncompleteArrayType *T,
545 raw_ostream &OS) {
546 IncludeStrongLifetimeRAII Strong(Policy);
547 printBefore(T->getElementType(), OS);
548}
549
550void TypePrinter::printIncompleteArrayAfter(const IncompleteArrayType *T,
551 raw_ostream &OS) {
552 OS << "[]";
553 printAfter(T->getElementType(), OS);
554}
555
556void TypePrinter::printVariableArrayBefore(const VariableArrayType *T,
557 raw_ostream &OS) {
558 IncludeStrongLifetimeRAII Strong(Policy);
559 printBefore(T->getElementType(), OS);
560}
561
562void TypePrinter::printVariableArrayAfter(const VariableArrayType *T,
563 raw_ostream &OS) {
564 OS << '[';
566 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.Restrict);
567 OS << ' ';
568 }
569
570 if (T->getSizeModifier() == ArraySizeModifier::Static)
571 OS << "static ";
572 else if (T->getSizeModifier() == ArraySizeModifier::Star)
573 OS << '*';
574
575 if (T->getSizeExpr())
576 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
577 OS << ']';
578
579 printAfter(T->getElementType(), OS);
580}
581
582void TypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream &OS) {
583 // Print the adjusted representation, otherwise the adjustment will be
584 // invisible.
585 printBefore(T->getAdjustedType(), OS);
586}
587
588void TypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) {
589 printAfter(T->getAdjustedType(), OS);
590}
591
592void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {
593 // Print as though it's a pointer.
594 printAdjustedBefore(T, OS);
595}
596
597void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {
598 printAdjustedAfter(T, OS);
599}
600
601void TypePrinter::printDependentSizedArrayBefore(
603 raw_ostream &OS) {
604 IncludeStrongLifetimeRAII Strong(Policy);
605 printBefore(T->getElementType(), OS);
606}
607
608void TypePrinter::printDependentSizedArrayAfter(
610 raw_ostream &OS) {
611 OS << '[';
612 if (T->getSizeExpr())
613 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
614 OS << ']';
615 printAfter(T->getElementType(), OS);
616}
617
618void TypePrinter::printDependentAddressSpaceBefore(
619 const DependentAddressSpaceType *T, raw_ostream &OS) {
620 printBefore(T->getPointeeType(), OS);
621}
622
623void TypePrinter::printDependentAddressSpaceAfter(
624 const DependentAddressSpaceType *T, raw_ostream &OS) {
625 OS << " __attribute__((address_space(";
626 if (T->getAddrSpaceExpr())
627 T->getAddrSpaceExpr()->printPretty(OS, nullptr, Policy);
628 OS << ")))";
629 printAfter(T->getPointeeType(), OS);
630}
631
632void TypePrinter::printDependentSizedExtVectorBefore(
634 raw_ostream &OS) {
635 printBefore(T->getElementType(), OS);
636}
637
638void TypePrinter::printDependentSizedExtVectorAfter(
640 raw_ostream &OS) {
641 OS << " __attribute__((ext_vector_type(";
642 if (T->getSizeExpr())
643 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
644 OS << ")))";
645 printAfter(T->getElementType(), OS);
646}
647
648void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {
649 switch (T->getVectorKind()) {
650 case VectorKind::AltiVecPixel:
651 OS << "__vector __pixel ";
652 break;
653 case VectorKind::AltiVecBool:
654 OS << "__vector __bool ";
655 printBefore(T->getElementType(), OS);
656 break;
657 case VectorKind::AltiVecVector:
658 OS << "__vector ";
659 printBefore(T->getElementType(), OS);
660 break;
661 case VectorKind::Neon:
662 OS << "__attribute__((neon_vector_type("
663 << T->getNumElements() << "))) ";
664 printBefore(T->getElementType(), OS);
665 break;
666 case VectorKind::NeonPoly:
667 OS << "__attribute__((neon_polyvector_type(" <<
668 T->getNumElements() << "))) ";
669 printBefore(T->getElementType(), OS);
670 break;
671 case VectorKind::Generic: {
672 // FIXME: We prefer to print the size directly here, but have no way
673 // to get the size of the type.
674 OS << "__attribute__((__vector_size__("
675 << T->getNumElements()
676 << " * sizeof(";
677 print(T->getElementType(), OS, StringRef());
678 OS << ")))) ";
679 printBefore(T->getElementType(), OS);
680 break;
681 }
682 case VectorKind::SveFixedLengthData:
683 case VectorKind::SveFixedLengthPredicate:
684 // FIXME: We prefer to print the size directly here, but have no way
685 // to get the size of the type.
686 OS << "__attribute__((__arm_sve_vector_bits__(";
687
688 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
689 // Predicates take a bit per byte of the vector size, multiply by 8 to
690 // get the number of bits passed to the attribute.
691 OS << T->getNumElements() * 8;
692 else
693 OS << T->getNumElements();
694
695 OS << " * sizeof(";
696 print(T->getElementType(), OS, StringRef());
697 // Multiply by 8 for the number of bits.
698 OS << ") * 8))) ";
699 printBefore(T->getElementType(), OS);
700 break;
701 case VectorKind::RVVFixedLengthData:
702 case VectorKind::RVVFixedLengthMask:
703 // FIXME: We prefer to print the size directly here, but have no way
704 // to get the size of the type.
705 OS << "__attribute__((__riscv_rvv_vector_bits__(";
706
707 OS << T->getNumElements();
708
709 OS << " * sizeof(";
710 print(T->getElementType(), OS, StringRef());
711 // Multiply by 8 for the number of bits.
712 OS << ") * 8))) ";
713 printBefore(T->getElementType(), OS);
714 break;
715 }
716}
717
718void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) {
719 printAfter(T->getElementType(), OS);
720}
721
722void TypePrinter::printDependentVectorBefore(
723 const DependentVectorType *T, raw_ostream &OS) {
724 switch (T->getVectorKind()) {
725 case VectorKind::AltiVecPixel:
726 OS << "__vector __pixel ";
727 break;
728 case VectorKind::AltiVecBool:
729 OS << "__vector __bool ";
730 printBefore(T->getElementType(), OS);
731 break;
732 case VectorKind::AltiVecVector:
733 OS << "__vector ";
734 printBefore(T->getElementType(), OS);
735 break;
736 case VectorKind::Neon:
737 OS << "__attribute__((neon_vector_type(";
738 if (T->getSizeExpr())
739 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
740 OS << "))) ";
741 printBefore(T->getElementType(), OS);
742 break;
743 case VectorKind::NeonPoly:
744 OS << "__attribute__((neon_polyvector_type(";
745 if (T->getSizeExpr())
746 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
747 OS << "))) ";
748 printBefore(T->getElementType(), OS);
749 break;
750 case VectorKind::Generic: {
751 // FIXME: We prefer to print the size directly here, but have no way
752 // to get the size of the type.
753 OS << "__attribute__((__vector_size__(";
754 if (T->getSizeExpr())
755 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
756 OS << " * sizeof(";
757 print(T->getElementType(), OS, StringRef());
758 OS << ")))) ";
759 printBefore(T->getElementType(), OS);
760 break;
761 }
762 case VectorKind::SveFixedLengthData:
763 case VectorKind::SveFixedLengthPredicate:
764 // FIXME: We prefer to print the size directly here, but have no way
765 // to get the size of the type.
766 OS << "__attribute__((__arm_sve_vector_bits__(";
767 if (T->getSizeExpr()) {
768 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
769 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
770 // Predicates take a bit per byte of the vector size, multiply by 8 to
771 // get the number of bits passed to the attribute.
772 OS << " * 8";
773 OS << " * sizeof(";
774 print(T->getElementType(), OS, StringRef());
775 // Multiply by 8 for the number of bits.
776 OS << ") * 8";
777 }
778 OS << "))) ";
779 printBefore(T->getElementType(), OS);
780 break;
781 case VectorKind::RVVFixedLengthData:
782 case VectorKind::RVVFixedLengthMask:
783 // FIXME: We prefer to print the size directly here, but have no way
784 // to get the size of the type.
785 OS << "__attribute__((__riscv_rvv_vector_bits__(";
786 if (T->getSizeExpr()) {
787 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
788 OS << " * sizeof(";
789 print(T->getElementType(), OS, StringRef());
790 // Multiply by 8 for the number of bits.
791 OS << ") * 8";
792 }
793 OS << "))) ";
794 printBefore(T->getElementType(), OS);
795 break;
796 }
797}
798
799void TypePrinter::printDependentVectorAfter(
800 const DependentVectorType *T, raw_ostream &OS) {
801 printAfter(T->getElementType(), OS);
802}
803
804void TypePrinter::printExtVectorBefore(const ExtVectorType *T,
805 raw_ostream &OS) {
806 printBefore(T->getElementType(), OS);
807}
808
809void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) {
810 printAfter(T->getElementType(), OS);
811 OS << " __attribute__((ext_vector_type(";
812 OS << T->getNumElements();
813 OS << ")))";
814}
815
816void TypePrinter::printConstantMatrixBefore(const ConstantMatrixType *T,
817 raw_ostream &OS) {
818 printBefore(T->getElementType(), OS);
819 OS << " __attribute__((matrix_type(";
820 OS << T->getNumRows() << ", " << T->getNumColumns();
821 OS << ")))";
822}
823
824void TypePrinter::printConstantMatrixAfter(const ConstantMatrixType *T,
825 raw_ostream &OS) {
826 printAfter(T->getElementType(), OS);
827}
828
829void TypePrinter::printDependentSizedMatrixBefore(
830 const DependentSizedMatrixType *T, raw_ostream &OS) {
831 printBefore(T->getElementType(), OS);
832 OS << " __attribute__((matrix_type(";
833 if (T->getRowExpr()) {
834 T->getRowExpr()->printPretty(OS, nullptr, Policy);
835 }
836 OS << ", ";
837 if (T->getColumnExpr()) {
838 T->getColumnExpr()->printPretty(OS, nullptr, Policy);
839 }
840 OS << ")))";
841}
842
843void TypePrinter::printDependentSizedMatrixAfter(
844 const DependentSizedMatrixType *T, raw_ostream &OS) {
845 printAfter(T->getElementType(), OS);
846}
847
848void
850 const PrintingPolicy &Policy)
851 const {
853 OS << " throw(";
855 OS << "...";
856 else
857 for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) {
858 if (I)
859 OS << ", ";
860
861 OS << getExceptionType(I).stream(Policy);
862 }
863 OS << ')';
864 } else if (EST_NoThrow == getExceptionSpecType()) {
865 OS << " __attribute__((nothrow))";
867 OS << " noexcept";
868 // FIXME:Is it useful to print out the expression for a non-dependent
869 // noexcept specification?
871 OS << '(';
872 if (getNoexceptExpr())
873 getNoexceptExpr()->printPretty(OS, nullptr, Policy);
874 OS << ')';
875 }
876 }
877}
878
879void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,
880 raw_ostream &OS) {
881 if (T->hasTrailingReturn()) {
882 OS << "auto ";
883 if (!HasEmptyPlaceHolder)
884 OS << '(';
885 } else {
886 // If needed for precedence reasons, wrap the inner part in grouping parens.
887 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
888 printBefore(T->getReturnType(), OS);
889 if (!PrevPHIsEmpty.get())
890 OS << '(';
891 }
892}
893
895 switch (ABI) {
897 llvm_unreachable("asking for spelling of ordinary parameter ABI");
899 return "swift_context";
901 return "swift_async_context";
903 return "swift_error_result";
905 return "swift_indirect_result";
906 }
907 llvm_unreachable("bad parameter ABI kind");
908}
909
910void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
911 raw_ostream &OS) {
912 // If needed for precedence reasons, wrap the inner part in grouping parens.
913 if (!HasEmptyPlaceHolder)
914 OS << ')';
915 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
916
917 OS << '(';
918 {
919 ParamPolicyRAII ParamPolicy(Policy);
920 for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {
921 if (i) OS << ", ";
922
923 auto EPI = T->getExtParameterInfo(i);
924 if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) ";
925 if (EPI.isNoEscape())
926 OS << "__attribute__((noescape)) ";
927 auto ABI = EPI.getABI();
928 if (ABI != ParameterABI::Ordinary)
929 OS << "__attribute__((" << getParameterABISpelling(ABI) << ")) ";
930
931 print(T->getParamType(i), OS, StringRef());
932 }
933 }
934
935 if (T->isVariadic()) {
936 if (T->getNumParams())
937 OS << ", ";
938 OS << "...";
939 } else if (T->getNumParams() == 0 && Policy.UseVoidForZeroParams) {
940 // Do not emit int() if we have a proto, emit 'int(void)'.
941 OS << "void";
942 }
943
944 OS << ')';
945
947 unsigned SMEBits = T->getAArch64SMEAttributes();
948
950 OS << " __arm_streaming_compatible";
952 OS << " __arm_streaming";
954 OS << " __arm_preserves(\"za\")";
956 OS << " __arm_in(\"za\")";
958 OS << " __arm_out(\"za\")";
960 OS << " __arm_inout(\"za\")";
962 OS << " __arm_preserves(\"zt0\")";
964 OS << " __arm_in(\"zt0\")";
966 OS << " __arm_out(\"zt0\")";
968 OS << " __arm_inout(\"zt0\")";
969
970 printFunctionAfter(Info, OS);
971
972 if (!T->getMethodQuals().empty())
973 OS << " " << T->getMethodQuals().getAsString();
974
975 switch (T->getRefQualifier()) {
976 case RQ_None:
977 break;
978
979 case RQ_LValue:
980 OS << " &";
981 break;
982
983 case RQ_RValue:
984 OS << " &&";
985 break;
986 }
987 T->printExceptionSpecification(OS, Policy);
988
989 if (T->hasTrailingReturn()) {
990 OS << " -> ";
991 print(T->getReturnType(), OS, StringRef());
992 } else
993 printAfter(T->getReturnType(), OS);
994}
995
996void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
997 raw_ostream &OS) {
998 if (!InsideCCAttribute) {
999 switch (Info.getCC()) {
1000 case CC_C:
1001 // The C calling convention is the default on the vast majority of platforms
1002 // we support. If the user wrote it explicitly, it will usually be printed
1003 // while traversing the AttributedType. If the type has been desugared, let
1004 // the canonical spelling be the implicit calling convention.
1005 // FIXME: It would be better to be explicit in certain contexts, such as a
1006 // cdecl function typedef used to declare a member function with the
1007 // Microsoft C++ ABI.
1008 break;
1009 case CC_X86StdCall:
1010 OS << " __attribute__((stdcall))";
1011 break;
1012 case CC_X86FastCall:
1013 OS << " __attribute__((fastcall))";
1014 break;
1015 case CC_X86ThisCall:
1016 OS << " __attribute__((thiscall))";
1017 break;
1018 case CC_X86VectorCall:
1019 OS << " __attribute__((vectorcall))";
1020 break;
1021 case CC_X86Pascal:
1022 OS << " __attribute__((pascal))";
1023 break;
1024 case CC_AAPCS:
1025 OS << " __attribute__((pcs(\"aapcs\")))";
1026 break;
1027 case CC_AAPCS_VFP:
1028 OS << " __attribute__((pcs(\"aapcs-vfp\")))";
1029 break;
1031 OS << "__attribute__((aarch64_vector_pcs))";
1032 break;
1033 case CC_AArch64SVEPCS:
1034 OS << "__attribute__((aarch64_sve_pcs))";
1035 break;
1037 OS << "__attribute__((amdgpu_kernel))";
1038 break;
1039 case CC_IntelOclBicc:
1040 OS << " __attribute__((intel_ocl_bicc))";
1041 break;
1042 case CC_Win64:
1043 OS << " __attribute__((ms_abi))";
1044 break;
1045 case CC_X86_64SysV:
1046 OS << " __attribute__((sysv_abi))";
1047 break;
1048 case CC_X86RegCall:
1049 OS << " __attribute__((regcall))";
1050 break;
1051 case CC_SpirFunction:
1052 case CC_OpenCLKernel:
1053 // Do nothing. These CCs are not available as attributes.
1054 break;
1055 case CC_Swift:
1056 OS << " __attribute__((swiftcall))";
1057 break;
1058 case CC_SwiftAsync:
1059 OS << "__attribute__((swiftasynccall))";
1060 break;
1061 case CC_PreserveMost:
1062 OS << " __attribute__((preserve_most))";
1063 break;
1064 case CC_PreserveAll:
1065 OS << " __attribute__((preserve_all))";
1066 break;
1067 case CC_M68kRTD:
1068 OS << " __attribute__((m68k_rtd))";
1069 break;
1070 case CC_PreserveNone:
1071 OS << " __attribute__((preserve_none))";
1072 break;
1073 }
1074 }
1075
1076 if (Info.getNoReturn())
1077 OS << " __attribute__((noreturn))";
1078 if (Info.getCmseNSCall())
1079 OS << " __attribute__((cmse_nonsecure_call))";
1080 if (Info.getProducesResult())
1081 OS << " __attribute__((ns_returns_retained))";
1082 if (Info.getRegParm())
1083 OS << " __attribute__((regparm ("
1084 << Info.getRegParm() << ")))";
1085 if (Info.getNoCallerSavedRegs())
1086 OS << " __attribute__((no_caller_saved_registers))";
1087 if (Info.getNoCfCheck())
1088 OS << " __attribute__((nocf_check))";
1089}
1090
1091void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T,
1092 raw_ostream &OS) {
1093 // If needed for precedence reasons, wrap the inner part in grouping parens.
1094 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
1095 printBefore(T->getReturnType(), OS);
1096 if (!PrevPHIsEmpty.get())
1097 OS << '(';
1098}
1099
1100void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,
1101 raw_ostream &OS) {
1102 // If needed for precedence reasons, wrap the inner part in grouping parens.
1103 if (!HasEmptyPlaceHolder)
1104 OS << ')';
1105 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
1106
1107 OS << "()";
1108 printFunctionAfter(T->getExtInfo(), OS);
1109 printAfter(T->getReturnType(), OS);
1110}
1111
1112void TypePrinter::printTypeSpec(NamedDecl *D, raw_ostream &OS) {
1113
1114 // Compute the full nested-name-specifier for this type.
1115 // In C, this will always be empty except when the type
1116 // being printed is anonymous within other Record.
1117 if (!Policy.SuppressScope)
1118 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1119
1120 IdentifierInfo *II = D->getIdentifier();
1121 OS << II->getName();
1122 spaceBeforePlaceHolder(OS);
1123}
1124
1125void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,
1126 raw_ostream &OS) {
1127 printTypeSpec(T->getDecl(), OS);
1128}
1129
1130void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,
1131 raw_ostream &OS) {}
1132
1133void TypePrinter::printUsingBefore(const UsingType *T, raw_ostream &OS) {
1134 // After `namespace b { using a::X }`, is the type X within B a::X or b::X?
1135 //
1136 // - b::X is more formally correct given the UsingType model
1137 // - b::X makes sense if "re-exporting" a symbol in a new namespace
1138 // - a::X makes sense if "importing" a symbol for convenience
1139 //
1140 // The "importing" use seems much more common, so we print a::X.
1141 // This could be a policy option, but the right choice seems to rest more
1142 // with the intent of the code than the caller.
1143 printTypeSpec(T->getFoundDecl()->getUnderlyingDecl(), OS);
1144}
1145
1146void TypePrinter::printUsingAfter(const UsingType *T, raw_ostream &OS) {}
1147
1148void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
1149 printTypeSpec(T->getDecl(), OS);
1150}
1151
1152void TypePrinter::printMacroQualifiedBefore(const MacroQualifiedType *T,
1153 raw_ostream &OS) {
1154 StringRef MacroName = T->getMacroIdentifier()->getName();
1155 OS << MacroName << " ";
1156
1157 // Since this type is meant to print the macro instead of the whole attribute,
1158 // we trim any attributes and go directly to the original modified type.
1159 printBefore(T->getModifiedType(), OS);
1160}
1161
1162void TypePrinter::printMacroQualifiedAfter(const MacroQualifiedType *T,
1163 raw_ostream &OS) {
1164 printAfter(T->getModifiedType(), OS);
1165}
1166
1167void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) {}
1168
1169void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
1170 raw_ostream &OS) {
1171 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual "
1172 : "typeof ");
1173 if (T->getUnderlyingExpr())
1174 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
1175 spaceBeforePlaceHolder(OS);
1176}
1177
1178void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
1179 raw_ostream &OS) {}
1180
1181void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) {
1182 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual("
1183 : "typeof(");
1184 print(T->getUnmodifiedType(), OS, StringRef());
1185 OS << ')';
1186 spaceBeforePlaceHolder(OS);
1187}
1188
1189void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) {}
1190
1191void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {
1192 OS << "decltype(";
1193 if (T->getUnderlyingExpr())
1194 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
1195 OS << ')';
1196 spaceBeforePlaceHolder(OS);
1197}
1198
1199void TypePrinter::printPackIndexingBefore(const PackIndexingType *T,
1200 raw_ostream &OS) {
1201 if (T->hasSelectedType())
1202 OS << T->getSelectedType();
1203 else
1204 OS << T->getPattern() << "...[" << T->getIndexExpr() << "]";
1205 spaceBeforePlaceHolder(OS);
1206}
1207
1208void TypePrinter::printPackIndexingAfter(const PackIndexingType *T,
1209 raw_ostream &OS) {}
1210
1211void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) {}
1212
1213void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,
1214 raw_ostream &OS) {
1215 IncludeStrongLifetimeRAII Strong(Policy);
1216
1217 static llvm::DenseMap<int, const char *> Transformation = {{
1218#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
1219 {UnaryTransformType::Enum, "__" #Trait},
1220#include "clang/Basic/TransformTypeTraits.def"
1221 }};
1222 OS << Transformation[T->getUTTKind()] << '(';
1223 print(T->getBaseType(), OS, StringRef());
1224 OS << ')';
1225 spaceBeforePlaceHolder(OS);
1226}
1227
1228void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,
1229 raw_ostream &OS) {}
1230
1231void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
1232 // If the type has been deduced, do not print 'auto'.
1233 if (!T->getDeducedType().isNull()) {
1234 printBefore(T->getDeducedType(), OS);
1235 } else {
1236 if (T->isConstrained()) {
1237 // FIXME: Track a TypeConstraint as type sugar, so that we can print the
1238 // type as it was written.
1239 T->getTypeConstraintConcept()->getDeclName().print(OS, Policy);
1240 auto Args = T->getTypeConstraintArguments();
1241 if (!Args.empty())
1243 OS, Args, Policy,
1245 OS << ' ';
1246 }
1247 switch (T->getKeyword()) {
1248 case AutoTypeKeyword::Auto: OS << "auto"; break;
1249 case AutoTypeKeyword::DecltypeAuto: OS << "decltype(auto)"; break;
1250 case AutoTypeKeyword::GNUAutoType: OS << "__auto_type"; break;
1251 }
1252 spaceBeforePlaceHolder(OS);
1253 }
1254}
1255
1256void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {
1257 // If the type has been deduced, do not print 'auto'.
1258 if (!T->getDeducedType().isNull())
1259 printAfter(T->getDeducedType(), OS);
1260}
1261
1262void TypePrinter::printDeducedTemplateSpecializationBefore(
1263 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1264 // If the type has been deduced, print the deduced type.
1265 if (!T->getDeducedType().isNull()) {
1266 printBefore(T->getDeducedType(), OS);
1267 } else {
1268 IncludeStrongLifetimeRAII Strong(Policy);
1269 T->getTemplateName().print(OS, Policy);
1270 spaceBeforePlaceHolder(OS);
1271 }
1272}
1273
1274void TypePrinter::printDeducedTemplateSpecializationAfter(
1275 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1276 // If the type has been deduced, print the deduced type.
1277 if (!T->getDeducedType().isNull())
1278 printAfter(T->getDeducedType(), OS);
1279}
1280
1281void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {
1282 IncludeStrongLifetimeRAII Strong(Policy);
1283
1284 OS << "_Atomic(";
1285 print(T->getValueType(), OS, StringRef());
1286 OS << ')';
1287 spaceBeforePlaceHolder(OS);
1288}
1289
1290void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) {}
1291
1292void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) {
1293 IncludeStrongLifetimeRAII Strong(Policy);
1294
1295 if (T->isReadOnly())
1296 OS << "read_only ";
1297 else
1298 OS << "write_only ";
1299 OS << "pipe ";
1300 print(T->getElementType(), OS, StringRef());
1301 spaceBeforePlaceHolder(OS);
1302}
1303
1304void TypePrinter::printPipeAfter(const PipeType *T, raw_ostream &OS) {}
1305
1306void TypePrinter::printBitIntBefore(const BitIntType *T, raw_ostream &OS) {
1307 if (T->isUnsigned())
1308 OS << "unsigned ";
1309 OS << "_BitInt(" << T->getNumBits() << ")";
1310 spaceBeforePlaceHolder(OS);
1311}
1312
1313void TypePrinter::printBitIntAfter(const BitIntType *T, raw_ostream &OS) {}
1314
1315void TypePrinter::printDependentBitIntBefore(const DependentBitIntType *T,
1316 raw_ostream &OS) {
1317 if (T->isUnsigned())
1318 OS << "unsigned ";
1319 OS << "_BitInt(";
1320 T->getNumBitsExpr()->printPretty(OS, nullptr, Policy);
1321 OS << ")";
1322 spaceBeforePlaceHolder(OS);
1323}
1324
1325void TypePrinter::printDependentBitIntAfter(const DependentBitIntType *T,
1326 raw_ostream &OS) {}
1327
1328/// Appends the given scope to the end of a string.
1329void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS,
1330 DeclarationName NameInScope) {
1331 if (DC->isTranslationUnit())
1332 return;
1333
1334 // FIXME: Consider replacing this with NamedDecl::printNestedNameSpecifier,
1335 // which can also print names for function and method scopes.
1336 if (DC->isFunctionOrMethod())
1337 return;
1338
1339 if (Policy.Callbacks && Policy.Callbacks->isScopeVisible(DC))
1340 return;
1341
1342 if (const auto *NS = dyn_cast<NamespaceDecl>(DC)) {
1343 if (Policy.SuppressUnwrittenScope && NS->isAnonymousNamespace())
1344 return AppendScope(DC->getParent(), OS, NameInScope);
1345
1346 // Only suppress an inline namespace if the name has the same lookup
1347 // results in the enclosing namespace.
1348 if (Policy.SuppressInlineNamespace && NS->isInline() && NameInScope &&
1349 NS->isRedundantInlineQualifierFor(NameInScope))
1350 return AppendScope(DC->getParent(), OS, NameInScope);
1351
1352 AppendScope(DC->getParent(), OS, NS->getDeclName());
1353 if (NS->getIdentifier())
1354 OS << NS->getName() << "::";
1355 else
1356 OS << "(anonymous namespace)::";
1357 } else if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
1358 AppendScope(DC->getParent(), OS, Spec->getDeclName());
1359 IncludeStrongLifetimeRAII Strong(Policy);
1360 OS << Spec->getIdentifier()->getName();
1361 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
1363 OS, TemplateArgs.asArray(), Policy,
1364 Spec->getSpecializedTemplate()->getTemplateParameters());
1365 OS << "::";
1366 } else if (const auto *Tag = dyn_cast<TagDecl>(DC)) {
1367 AppendScope(DC->getParent(), OS, Tag->getDeclName());
1368 if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl())
1369 OS << Typedef->getIdentifier()->getName() << "::";
1370 else if (Tag->getIdentifier())
1371 OS << Tag->getIdentifier()->getName() << "::";
1372 else
1373 return;
1374 } else {
1375 AppendScope(DC->getParent(), OS, NameInScope);
1376 }
1377}
1378
1379void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {
1380 if (Policy.IncludeTagDefinition) {
1381 PrintingPolicy SubPolicy = Policy;
1382 SubPolicy.IncludeTagDefinition = false;
1383 D->print(OS, SubPolicy, Indentation);
1384 spaceBeforePlaceHolder(OS);
1385 return;
1386 }
1387
1388 bool HasKindDecoration = false;
1389
1390 // We don't print tags unless this is an elaborated type.
1391 // In C, we just assume every RecordType is an elaborated type.
1392 if (!Policy.SuppressTagKeyword && !D->getTypedefNameForAnonDecl()) {
1393 HasKindDecoration = true;
1394 OS << D->getKindName();
1395 OS << ' ';
1396 }
1397
1398 // Compute the full nested-name-specifier for this type.
1399 // In C, this will always be empty except when the type
1400 // being printed is anonymous within other Record.
1401 if (!Policy.SuppressScope)
1402 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1403
1404 if (const IdentifierInfo *II = D->getIdentifier())
1405 OS << II->getName();
1406 else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) {
1407 assert(Typedef->getIdentifier() && "Typedef without identifier?");
1408 OS << Typedef->getIdentifier()->getName();
1409 } else {
1410 // Make an unambiguous representation for anonymous types, e.g.
1411 // (anonymous enum at /usr/include/string.h:120:9)
1412 OS << (Policy.MSVCFormatting ? '`' : '(');
1413
1414 if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
1415 OS << "lambda";
1416 HasKindDecoration = true;
1417 } else if ((isa<RecordDecl>(D) && cast<RecordDecl>(D)->isAnonymousStructOrUnion())) {
1418 OS << "anonymous";
1419 } else {
1420 OS << "unnamed";
1421 }
1422
1423 if (Policy.AnonymousTagLocations) {
1424 // Suppress the redundant tag keyword if we just printed one.
1425 // We don't have to worry about ElaboratedTypes here because you can't
1426 // refer to an anonymous type with one.
1427 if (!HasKindDecoration)
1428 OS << " " << D->getKindName();
1429
1431 D->getLocation());
1432 if (PLoc.isValid()) {
1433 OS << " at ";
1434 StringRef File = PLoc.getFilename();
1435 llvm::SmallString<1024> WrittenFile(File);
1436 if (auto *Callbacks = Policy.Callbacks)
1437 WrittenFile = Callbacks->remapPath(File);
1438 // Fix inconsistent path separator created by
1439 // clang::DirectoryLookup::LookupFile when the file path is relative
1440 // path.
1441 llvm::sys::path::Style Style =
1442 llvm::sys::path::is_absolute(WrittenFile)
1443 ? llvm::sys::path::Style::native
1444 : (Policy.MSVCFormatting
1445 ? llvm::sys::path::Style::windows_backslash
1446 : llvm::sys::path::Style::posix);
1447 llvm::sys::path::native(WrittenFile, Style);
1448 OS << WrittenFile << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
1449 }
1450 }
1451
1452 OS << (Policy.MSVCFormatting ? '\'' : ')');
1453 }
1454
1455 // If this is a class template specialization, print the template
1456 // arguments.
1457 if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1459 TypeSourceInfo *TAW = Spec->getTypeAsWritten();
1460 if (!Policy.PrintCanonicalTypes && TAW) {
1461 const TemplateSpecializationType *TST =
1462 cast<TemplateSpecializationType>(TAW->getType());
1463 Args = TST->template_arguments();
1464 } else {
1465 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
1466 Args = TemplateArgs.asArray();
1467 }
1468 IncludeStrongLifetimeRAII Strong(Policy);
1470 OS, Args, Policy,
1471 Spec->getSpecializedTemplate()->getTemplateParameters());
1472 }
1473
1474 spaceBeforePlaceHolder(OS);
1475}
1476
1477void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
1478 // Print the preferred name if we have one for this type.
1479 if (Policy.UsePreferredNames) {
1480 for (const auto *PNA : T->getDecl()->specific_attrs<PreferredNameAttr>()) {
1481 if (!declaresSameEntity(PNA->getTypedefType()->getAsCXXRecordDecl(),
1482 T->getDecl()))
1483 continue;
1484 // Find the outermost typedef or alias template.
1485 QualType T = PNA->getTypedefType();
1486 while (true) {
1487 if (auto *TT = dyn_cast<TypedefType>(T))
1488 return printTypeSpec(TT->getDecl(), OS);
1489 if (auto *TST = dyn_cast<TemplateSpecializationType>(T))
1490 return printTemplateId(TST, OS, /*FullyQualify=*/true);
1492 }
1493 }
1494 }
1495
1496 printTag(T->getDecl(), OS);
1497}
1498
1499void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) {}
1500
1501void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {
1502 printTag(T->getDecl(), OS);
1503}
1504
1505void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {}
1506
1507void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
1508 raw_ostream &OS) {
1509 TemplateTypeParmDecl *D = T->getDecl();
1510 if (D && D->isImplicit()) {
1511 if (auto *TC = D->getTypeConstraint()) {
1512 TC->print(OS, Policy);
1513 OS << ' ';
1514 }
1515 OS << "auto";
1516 } else if (IdentifierInfo *Id = T->getIdentifier())
1517 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1518 : Id->getName());
1519 else
1520 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
1521
1522 spaceBeforePlaceHolder(OS);
1523}
1524
1525void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,
1526 raw_ostream &OS) {}
1527
1528void TypePrinter::printSubstTemplateTypeParmBefore(
1530 raw_ostream &OS) {
1531 IncludeStrongLifetimeRAII Strong(Policy);
1532 printBefore(T->getReplacementType(), OS);
1533}
1534
1535void TypePrinter::printSubstTemplateTypeParmAfter(
1537 raw_ostream &OS) {
1538 IncludeStrongLifetimeRAII Strong(Policy);
1539 printAfter(T->getReplacementType(), OS);
1540}
1541
1542void TypePrinter::printSubstTemplateTypeParmPackBefore(
1544 raw_ostream &OS) {
1545 IncludeStrongLifetimeRAII Strong(Policy);
1546 if (const TemplateTypeParmDecl *D = T->getReplacedParameter()) {
1547 if (D && D->isImplicit()) {
1548 if (auto *TC = D->getTypeConstraint()) {
1549 TC->print(OS, Policy);
1550 OS << ' ';
1551 }
1552 OS << "auto";
1553 } else if (IdentifierInfo *Id = D->getIdentifier())
1554 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1555 : Id->getName());
1556 else
1557 OS << "type-parameter-" << D->getDepth() << '-' << D->getIndex();
1558
1559 spaceBeforePlaceHolder(OS);
1560 }
1561}
1562
1563void TypePrinter::printSubstTemplateTypeParmPackAfter(
1565 raw_ostream &OS) {
1566 IncludeStrongLifetimeRAII Strong(Policy);
1567}
1568
1569void TypePrinter::printTemplateId(const TemplateSpecializationType *T,
1570 raw_ostream &OS, bool FullyQualify) {
1571 IncludeStrongLifetimeRAII Strong(Policy);
1572
1574 // FIXME: Null TD never excercised in test suite.
1575 if (FullyQualify && TD) {
1576 if (!Policy.SuppressScope)
1577 AppendScope(TD->getDeclContext(), OS, TD->getDeclName());
1578
1579 OS << TD->getName();
1580 } else {
1581 T->getTemplateName().print(OS, Policy);
1582 }
1583
1584 DefaultTemplateArgsPolicyRAII TemplateArgs(Policy);
1585 const TemplateParameterList *TPL = TD ? TD->getTemplateParameters() : nullptr;
1586 printTemplateArgumentList(OS, T->template_arguments(), Policy, TPL);
1587 spaceBeforePlaceHolder(OS);
1588}
1589
1590void TypePrinter::printTemplateSpecializationBefore(
1592 raw_ostream &OS) {
1593 printTemplateId(T, OS, Policy.FullyQualifiedName);
1594}
1595
1596void TypePrinter::printTemplateSpecializationAfter(
1598 raw_ostream &OS) {}
1599
1600void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
1601 raw_ostream &OS) {
1602 if (Policy.PrintInjectedClassNameWithArguments)
1603 return printTemplateSpecializationBefore(T->getInjectedTST(), OS);
1604
1605 IncludeStrongLifetimeRAII Strong(Policy);
1606 T->getTemplateName().print(OS, Policy);
1607 spaceBeforePlaceHolder(OS);
1608}
1609
1610void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
1611 raw_ostream &OS) {}
1612
1613void TypePrinter::printElaboratedBefore(const ElaboratedType *T,
1614 raw_ostream &OS) {
1615 if (Policy.IncludeTagDefinition && T->getOwnedTagDecl()) {
1616 TagDecl *OwnedTagDecl = T->getOwnedTagDecl();
1617 assert(OwnedTagDecl->getTypeForDecl() == T->getNamedType().getTypePtr() &&
1618 "OwnedTagDecl expected to be a declaration for the type");
1619 PrintingPolicy SubPolicy = Policy;
1620 SubPolicy.IncludeTagDefinition = false;
1621 OwnedTagDecl->print(OS, SubPolicy, Indentation);
1622 spaceBeforePlaceHolder(OS);
1623 return;
1624 }
1625
1626 if (Policy.SuppressElaboration) {
1627 printBefore(T->getNamedType(), OS);
1628 return;
1629 }
1630
1631 // The tag definition will take care of these.
1632 if (!Policy.IncludeTagDefinition)
1633 {
1636 OS << " ";
1638 if (Qualifier)
1639 Qualifier->print(OS, Policy);
1640 }
1641
1642 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1643 printBefore(T->getNamedType(), OS);
1644}
1645
1646void TypePrinter::printElaboratedAfter(const ElaboratedType *T,
1647 raw_ostream &OS) {
1648 if (Policy.IncludeTagDefinition && T->getOwnedTagDecl())
1649 return;
1650
1651 if (Policy.SuppressElaboration) {
1652 printAfter(T->getNamedType(), OS);
1653 return;
1654 }
1655
1656 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1657 printAfter(T->getNamedType(), OS);
1658}
1659
1660void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {
1661 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1662 printBefore(T->getInnerType(), OS);
1663 OS << '(';
1664 } else
1665 printBefore(T->getInnerType(), OS);
1666}
1667
1668void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {
1669 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1670 OS << ')';
1671 printAfter(T->getInnerType(), OS);
1672 } else
1673 printAfter(T->getInnerType(), OS);
1674}
1675
1676void TypePrinter::printDependentNameBefore(const DependentNameType *T,
1677 raw_ostream &OS) {
1680 OS << " ";
1681
1682 T->getQualifier()->print(OS, Policy);
1683
1684 OS << T->getIdentifier()->getName();
1685 spaceBeforePlaceHolder(OS);
1686}
1687
1688void TypePrinter::printDependentNameAfter(const DependentNameType *T,
1689 raw_ostream &OS) {}
1690
1691void TypePrinter::printDependentTemplateSpecializationBefore(
1692 const DependentTemplateSpecializationType *T, raw_ostream &OS) {
1693 IncludeStrongLifetimeRAII Strong(Policy);
1694
1697 OS << " ";
1698
1699 if (T->getQualifier())
1700 T->getQualifier()->print(OS, Policy);
1701 OS << "template " << T->getIdentifier()->getName();
1703 spaceBeforePlaceHolder(OS);
1704}
1705
1706void TypePrinter::printDependentTemplateSpecializationAfter(
1707 const DependentTemplateSpecializationType *T, raw_ostream &OS) {}
1708
1709void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,
1710 raw_ostream &OS) {
1711 printBefore(T->getPattern(), OS);
1712}
1713
1714void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
1715 raw_ostream &OS) {
1716 printAfter(T->getPattern(), OS);
1717 OS << "...";
1718}
1719
1720void TypePrinter::printAttributedBefore(const AttributedType *T,
1721 raw_ostream &OS) {
1722 // FIXME: Generate this with TableGen.
1723
1724 // Prefer the macro forms of the GC and ownership qualifiers.
1725 if (T->getAttrKind() == attr::ObjCGC ||
1726 T->getAttrKind() == attr::ObjCOwnership)
1727 return printBefore(T->getEquivalentType(), OS);
1728
1729 if (T->getAttrKind() == attr::ObjCKindOf)
1730 OS << "__kindof ";
1731
1732 if (T->getAttrKind() == attr::AddressSpace)
1733 printBefore(T->getEquivalentType(), OS);
1734 else
1735 printBefore(T->getModifiedType(), OS);
1736
1737 if (T->isMSTypeSpec()) {
1738 switch (T->getAttrKind()) {
1739 default: return;
1740 case attr::Ptr32: OS << " __ptr32"; break;
1741 case attr::Ptr64: OS << " __ptr64"; break;
1742 case attr::SPtr: OS << " __sptr"; break;
1743 case attr::UPtr: OS << " __uptr"; break;
1744 }
1745 spaceBeforePlaceHolder(OS);
1746 }
1747
1748 if (T->isWebAssemblyFuncrefSpec())
1749 OS << "__funcref";
1750
1751 // Print nullability type specifiers.
1752 if (T->getImmediateNullability()) {
1753 if (T->getAttrKind() == attr::TypeNonNull)
1754 OS << " _Nonnull";
1755 else if (T->getAttrKind() == attr::TypeNullable)
1756 OS << " _Nullable";
1757 else if (T->getAttrKind() == attr::TypeNullUnspecified)
1758 OS << " _Null_unspecified";
1759 else if (T->getAttrKind() == attr::TypeNullableResult)
1760 OS << " _Nullable_result";
1761 else
1762 llvm_unreachable("unhandled nullability");
1763 spaceBeforePlaceHolder(OS);
1764 }
1765}
1766
1767void TypePrinter::printAttributedAfter(const AttributedType *T,
1768 raw_ostream &OS) {
1769 // FIXME: Generate this with TableGen.
1770
1771 // Prefer the macro forms of the GC and ownership qualifiers.
1772 if (T->getAttrKind() == attr::ObjCGC ||
1773 T->getAttrKind() == attr::ObjCOwnership)
1774 return printAfter(T->getEquivalentType(), OS);
1775
1776 // If this is a calling convention attribute, don't print the implicit CC from
1777 // the modified type.
1778 SaveAndRestore MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());
1779
1780 printAfter(T->getModifiedType(), OS);
1781
1782 // Some attributes are printed as qualifiers before the type, so we have
1783 // nothing left to do.
1784 if (T->getAttrKind() == attr::ObjCKindOf || T->isMSTypeSpec() ||
1786 return;
1787
1788 // Don't print the inert __unsafe_unretained attribute at all.
1789 if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained)
1790 return;
1791
1792 // Don't print ns_returns_retained unless it had an effect.
1793 if (T->getAttrKind() == attr::NSReturnsRetained &&
1796 return;
1797
1798 if (T->getAttrKind() == attr::LifetimeBound) {
1799 OS << " [[clang::lifetimebound]]";
1800 return;
1801 }
1802
1803 // The printing of the address_space attribute is handled by the qualifier
1804 // since it is still stored in the qualifier. Return early to prevent printing
1805 // this twice.
1806 if (T->getAttrKind() == attr::AddressSpace)
1807 return;
1808
1809 if (T->getAttrKind() == attr::AnnotateType) {
1810 // FIXME: Print the attribute arguments once we have a way to retrieve these
1811 // here. For the meantime, we just print `[[clang::annotate_type(...)]]`
1812 // without the arguments so that we know at least that we had _some_
1813 // annotation on the type.
1814 OS << " [[clang::annotate_type(...)]]";
1815 return;
1816 }
1817
1818 if (T->getAttrKind() == attr::ArmStreaming) {
1819 OS << "__arm_streaming";
1820 return;
1821 }
1822 if (T->getAttrKind() == attr::ArmStreamingCompatible) {
1823 OS << "__arm_streaming_compatible";
1824 return;
1825 }
1826
1827 OS << " __attribute__((";
1828 switch (T->getAttrKind()) {
1829#define TYPE_ATTR(NAME)
1830#define DECL_OR_TYPE_ATTR(NAME)
1831#define ATTR(NAME) case attr::NAME:
1832#include "clang/Basic/AttrList.inc"
1833 llvm_unreachable("non-type attribute attached to type");
1834
1835 case attr::BTFTypeTag:
1836 llvm_unreachable("BTFTypeTag attribute handled separately");
1837
1838 case attr::OpenCLPrivateAddressSpace:
1839 case attr::OpenCLGlobalAddressSpace:
1840 case attr::OpenCLGlobalDeviceAddressSpace:
1841 case attr::OpenCLGlobalHostAddressSpace:
1842 case attr::OpenCLLocalAddressSpace:
1843 case attr::OpenCLConstantAddressSpace:
1844 case attr::OpenCLGenericAddressSpace:
1845 case attr::HLSLGroupSharedAddressSpace:
1846 // FIXME: Update printAttributedBefore to print these once we generate
1847 // AttributedType nodes for them.
1848 break;
1849
1850 case attr::LifetimeBound:
1851 case attr::TypeNonNull:
1852 case attr::TypeNullable:
1853 case attr::TypeNullableResult:
1854 case attr::TypeNullUnspecified:
1855 case attr::ObjCGC:
1856 case attr::ObjCInertUnsafeUnretained:
1857 case attr::ObjCKindOf:
1858 case attr::ObjCOwnership:
1859 case attr::Ptr32:
1860 case attr::Ptr64:
1861 case attr::SPtr:
1862 case attr::UPtr:
1863 case attr::AddressSpace:
1864 case attr::CmseNSCall:
1865 case attr::AnnotateType:
1866 case attr::WebAssemblyFuncref:
1867 case attr::ArmStreaming:
1868 case attr::ArmStreamingCompatible:
1869 case attr::ArmIn:
1870 case attr::ArmOut:
1871 case attr::ArmInOut:
1872 case attr::ArmPreserves:
1873 llvm_unreachable("This attribute should have been handled already");
1874
1875 case attr::NSReturnsRetained:
1876 OS << "ns_returns_retained";
1877 break;
1878
1879 // FIXME: When Sema learns to form this AttributedType, avoid printing the
1880 // attribute again in printFunctionProtoAfter.
1881 case attr::AnyX86NoCfCheck: OS << "nocf_check"; break;
1882 case attr::CDecl: OS << "cdecl"; break;
1883 case attr::FastCall: OS << "fastcall"; break;
1884 case attr::StdCall: OS << "stdcall"; break;
1885 case attr::ThisCall: OS << "thiscall"; break;
1886 case attr::SwiftCall: OS << "swiftcall"; break;
1887 case attr::SwiftAsyncCall: OS << "swiftasynccall"; break;
1888 case attr::VectorCall: OS << "vectorcall"; break;
1889 case attr::Pascal: OS << "pascal"; break;
1890 case attr::MSABI: OS << "ms_abi"; break;
1891 case attr::SysVABI: OS << "sysv_abi"; break;
1892 case attr::RegCall: OS << "regcall"; break;
1893 case attr::Pcs: {
1894 OS << "pcs(";
1895 QualType t = T->getEquivalentType();
1896 while (!t->isFunctionType())
1897 t = t->getPointeeType();
1898 OS << (t->castAs<FunctionType>()->getCallConv() == CC_AAPCS ?
1899 "\"aapcs\"" : "\"aapcs-vfp\"");
1900 OS << ')';
1901 break;
1902 }
1903 case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break;
1904 case attr::AArch64SVEPcs: OS << "aarch64_sve_pcs"; break;
1905 case attr::AMDGPUKernelCall: OS << "amdgpu_kernel"; break;
1906 case attr::IntelOclBicc: OS << "inteloclbicc"; break;
1907 case attr::PreserveMost:
1908 OS << "preserve_most";
1909 break;
1910
1911 case attr::PreserveAll:
1912 OS << "preserve_all";
1913 break;
1914 case attr::M68kRTD:
1915 OS << "m68k_rtd";
1916 break;
1917 case attr::PreserveNone:
1918 OS << "preserve_none";
1919 break;
1920 case attr::NoDeref:
1921 OS << "noderef";
1922 break;
1923 case attr::AcquireHandle:
1924 OS << "acquire_handle";
1925 break;
1926 case attr::ArmMveStrictPolymorphism:
1927 OS << "__clang_arm_mve_strict_polymorphism";
1928 break;
1929
1930 // Nothing to print for this attribute.
1931 case attr::HLSLParamModifier:
1932 break;
1933 }
1934 OS << "))";
1935}
1936
1937void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T,
1938 raw_ostream &OS) {
1939 printBefore(T->getWrappedType(), OS);
1940 OS << " __attribute__((btf_type_tag(\"" << T->getAttr()->getBTFTypeTag() << "\")))";
1941}
1942
1943void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,
1944 raw_ostream &OS) {
1945 printAfter(T->getWrappedType(), OS);
1946}
1947
1948void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
1949 raw_ostream &OS) {
1950 OS << T->getDecl()->getName();
1951 spaceBeforePlaceHolder(OS);
1952}
1953
1954void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
1955 raw_ostream &OS) {}
1956
1957void TypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType *T,
1958 raw_ostream &OS) {
1959 OS << T->getDecl()->getName();
1960 if (!T->qual_empty()) {
1961 bool isFirst = true;
1962 OS << '<';
1963 for (const auto *I : T->quals()) {
1964 if (isFirst)
1965 isFirst = false;
1966 else
1967 OS << ',';
1968 OS << I->getName();
1969 }
1970 OS << '>';
1971 }
1972
1973 spaceBeforePlaceHolder(OS);
1974}
1975
1976void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T,
1977 raw_ostream &OS) {}
1978
1979void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
1980 raw_ostream &OS) {
1981 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
1983 return printBefore(T->getBaseType(), OS);
1984
1985 if (T->isKindOfTypeAsWritten())
1986 OS << "__kindof ";
1987
1988 print(T->getBaseType(), OS, StringRef());
1989
1990 if (T->isSpecializedAsWritten()) {
1991 bool isFirst = true;
1992 OS << '<';
1993 for (auto typeArg : T->getTypeArgsAsWritten()) {
1994 if (isFirst)
1995 isFirst = false;
1996 else
1997 OS << ",";
1998
1999 print(typeArg, OS, StringRef());
2000 }
2001 OS << '>';
2002 }
2003
2004 if (!T->qual_empty()) {
2005 bool isFirst = true;
2006 OS << '<';
2007 for (const auto *I : T->quals()) {
2008 if (isFirst)
2009 isFirst = false;
2010 else
2011 OS << ',';
2012 OS << I->getName();
2013 }
2014 OS << '>';
2015 }
2016
2017 spaceBeforePlaceHolder(OS);
2018}
2019
2020void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
2021 raw_ostream &OS) {
2022 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2024 return printAfter(T->getBaseType(), OS);
2025}
2026
2027void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
2028 raw_ostream &OS) {
2029 printBefore(T->getPointeeType(), OS);
2030
2031 // If we need to print the pointer, print it now.
2032 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&
2034 if (HasEmptyPlaceHolder)
2035 OS << ' ';
2036 OS << '*';
2037 }
2038}
2039
2040void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
2041 raw_ostream &OS) {}
2042
2043static
2044const TemplateArgument &getArgument(const TemplateArgument &A) { return A; }
2045
2047 return A.getArgument();
2048}
2049
2050static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP,
2051 llvm::raw_ostream &OS, bool IncludeType) {
2052 A.print(PP, OS, IncludeType);
2053}
2054
2056 const PrintingPolicy &PP, llvm::raw_ostream &OS,
2057 bool IncludeType) {
2058 const TemplateArgument::ArgKind &Kind = A.getArgument().getKind();
2060 return A.getTypeSourceInfo()->getType().print(OS, PP);
2061 return A.getArgument().print(PP, OS, IncludeType);
2062}
2063
2065 TemplateArgument Pattern,
2067 unsigned Depth);
2068
2069static bool isSubstitutedType(ASTContext &Ctx, QualType T, QualType Pattern,
2070 ArrayRef<TemplateArgument> Args, unsigned Depth) {
2071 if (Ctx.hasSameType(T, Pattern))
2072 return true;
2073
2074 // A type parameter matches its argument.
2075 if (auto *TTPT = Pattern->getAs<TemplateTypeParmType>()) {
2076 if (TTPT->getDepth() == Depth && TTPT->getIndex() < Args.size() &&
2077 Args[TTPT->getIndex()].getKind() == TemplateArgument::Type) {
2078 QualType SubstArg = Ctx.getQualifiedType(
2079 Args[TTPT->getIndex()].getAsType(), Pattern.getQualifiers());
2080 return Ctx.hasSameType(SubstArg, T);
2081 }
2082 return false;
2083 }
2084
2085 // FIXME: Recurse into array types.
2086
2087 // All other cases will need the types to be identically qualified.
2088 Qualifiers TQual, PatQual;
2089 T = Ctx.getUnqualifiedArrayType(T, TQual);
2090 Pattern = Ctx.getUnqualifiedArrayType(Pattern, PatQual);
2091 if (TQual != PatQual)
2092 return false;
2093
2094 // Recurse into pointer-like types.
2095 {
2096 QualType TPointee = T->getPointeeType();
2097 QualType PPointee = Pattern->getPointeeType();
2098 if (!TPointee.isNull() && !PPointee.isNull())
2099 return T->getTypeClass() == Pattern->getTypeClass() &&
2100 isSubstitutedType(Ctx, TPointee, PPointee, Args, Depth);
2101 }
2102
2103 // Recurse into template specialization types.
2104 if (auto *PTST =
2106 TemplateName Template;
2107 ArrayRef<TemplateArgument> TemplateArgs;
2108 if (auto *TTST = T->getAs<TemplateSpecializationType>()) {
2109 Template = TTST->getTemplateName();
2110 TemplateArgs = TTST->template_arguments();
2111 } else if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
2112 T->getAsCXXRecordDecl())) {
2113 Template = TemplateName(CTSD->getSpecializedTemplate());
2114 TemplateArgs = CTSD->getTemplateArgs().asArray();
2115 } else {
2116 return false;
2117 }
2118
2119 if (!isSubstitutedTemplateArgument(Ctx, Template, PTST->getTemplateName(),
2120 Args, Depth))
2121 return false;
2122 if (TemplateArgs.size() != PTST->template_arguments().size())
2123 return false;
2124 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
2126 Ctx, TemplateArgs[I], PTST->template_arguments()[I], Args, Depth))
2127 return false;
2128 return true;
2129 }
2130
2131 // FIXME: Handle more cases.
2132 return false;
2133}
2134
2135/// Evaluates the expression template argument 'Pattern' and returns true
2136/// if 'Arg' evaluates to the same result.
2138 TemplateArgument const &Pattern,
2139 TemplateArgument const &Arg) {
2140 if (Pattern.getKind() != TemplateArgument::Expression)
2141 return false;
2142
2143 // Can't evaluate value-dependent expressions so bail early
2144 Expr const *pattern_expr = Pattern.getAsExpr();
2145 if (pattern_expr->isValueDependent() ||
2146 !pattern_expr->isIntegerConstantExpr(Ctx))
2147 return false;
2148
2150 return llvm::APSInt::isSameValue(pattern_expr->EvaluateKnownConstInt(Ctx),
2151 Arg.getAsIntegral());
2152
2154 Expr const *args_expr = Arg.getAsExpr();
2155 if (args_expr->isValueDependent() || !args_expr->isIntegerConstantExpr(Ctx))
2156 return false;
2157
2158 return llvm::APSInt::isSameValue(args_expr->EvaluateKnownConstInt(Ctx),
2159 pattern_expr->EvaluateKnownConstInt(Ctx));
2160 }
2161
2162 return false;
2163}
2164
2166 TemplateArgument Pattern,
2168 unsigned Depth) {
2169 Arg = Ctx.getCanonicalTemplateArgument(Arg);
2170 Pattern = Ctx.getCanonicalTemplateArgument(Pattern);
2171 if (Arg.structurallyEquals(Pattern))
2172 return true;
2173
2174 if (Pattern.getKind() == TemplateArgument::Expression) {
2175 if (auto *DRE =
2176 dyn_cast<DeclRefExpr>(Pattern.getAsExpr()->IgnoreParenImpCasts())) {
2177 if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
2178 return NTTP->getDepth() == Depth && Args.size() > NTTP->getIndex() &&
2179 Args[NTTP->getIndex()].structurallyEquals(Arg);
2180 }
2181 }
2182
2183 if (templateArgumentExpressionsEqual(Ctx, Pattern, Arg))
2184 return true;
2185
2186 if (Arg.getKind() != Pattern.getKind())
2187 return false;
2188
2189 if (Arg.getKind() == TemplateArgument::Type)
2190 return isSubstitutedType(Ctx, Arg.getAsType(), Pattern.getAsType(), Args,
2191 Depth);
2192
2193 if (Arg.getKind() == TemplateArgument::Template) {
2194 TemplateDecl *PatTD = Pattern.getAsTemplate().getAsTemplateDecl();
2195 if (auto *TTPD = dyn_cast_or_null<TemplateTemplateParmDecl>(PatTD))
2196 return TTPD->getDepth() == Depth && Args.size() > TTPD->getIndex() &&
2197 Ctx.getCanonicalTemplateArgument(Args[TTPD->getIndex()])
2198 .structurallyEquals(Arg);
2199 }
2200
2201 // FIXME: Handle more cases.
2202 return false;
2203}
2204
2206 const NamedDecl *Param,
2208 unsigned Depth) {
2209 // An empty pack is equivalent to not providing a pack argument.
2210 if (Arg.getKind() == TemplateArgument::Pack && Arg.pack_size() == 0)
2211 return true;
2212
2213 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Param)) {
2214 return TTPD->hasDefaultArgument() &&
2215 isSubstitutedTemplateArgument(Ctx, Arg, TTPD->getDefaultArgument(),
2216 Args, Depth);
2217 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
2218 return TTPD->hasDefaultArgument() &&
2220 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2221 } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
2222 return NTTPD->hasDefaultArgument() &&
2223 isSubstitutedTemplateArgument(Ctx, Arg, NTTPD->getDefaultArgument(),
2224 Args, Depth);
2225 }
2226 return false;
2227}
2228
2229template <typename TA>
2230static void
2231printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy,
2232 const TemplateParameterList *TPL, bool IsPack, unsigned ParmIndex) {
2233 // Drop trailing template arguments that match default arguments.
2234 if (TPL && Policy.SuppressDefaultTemplateArgs &&
2235 !Policy.PrintCanonicalTypes && !Args.empty() && !IsPack &&
2236 Args.size() <= TPL->size()) {
2238 for (const TA &A : Args)
2239 OrigArgs.push_back(getArgument(A));
2240 while (!Args.empty() && getArgument(Args.back()).getIsDefaulted())
2241 Args = Args.drop_back();
2242 }
2243
2244 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
2245 if (!IsPack)
2246 OS << '<';
2247
2248 bool NeedSpace = false;
2249 bool FirstArg = true;
2250 for (const auto &Arg : Args) {
2251 // Print the argument into a string.
2252 SmallString<128> Buf;
2253 llvm::raw_svector_ostream ArgOS(Buf);
2254 const TemplateArgument &Argument = getArgument(Arg);
2255 if (Argument.getKind() == TemplateArgument::Pack) {
2256 if (Argument.pack_size() && !FirstArg)
2257 OS << Comma;
2258 printTo(ArgOS, Argument.getPackAsArray(), Policy, TPL,
2259 /*IsPack*/ true, ParmIndex);
2260 } else {
2261 if (!FirstArg)
2262 OS << Comma;
2263 // Tries to print the argument with location info if exists.
2264 printArgument(Arg, Policy, ArgOS,
2266 Policy, TPL, ParmIndex));
2267 }
2268 StringRef ArgString = ArgOS.str();
2269
2270 // If this is the first argument and its string representation
2271 // begins with the global scope specifier ('::foo'), add a space
2272 // to avoid printing the diagraph '<:'.
2273 if (FirstArg && ArgString.starts_with(":"))
2274 OS << ' ';
2275
2276 OS << ArgString;
2277
2278 // If the last character of our string is '>', add another space to
2279 // keep the two '>''s separate tokens.
2280 if (!ArgString.empty()) {
2281 NeedSpace = Policy.SplitTemplateClosers && ArgString.back() == '>';
2282 FirstArg = false;
2283 }
2284
2285 // Use same template parameter for all elements of Pack
2286 if (!IsPack)
2287 ParmIndex++;
2288 }
2289
2290 if (!IsPack) {
2291 if (NeedSpace)
2292 OS << ' ';
2293 OS << '>';
2294 }
2295}
2296
2298 const TemplateArgumentListInfo &Args,
2299 const PrintingPolicy &Policy,
2300 const TemplateParameterList *TPL) {
2301 printTemplateArgumentList(OS, Args.arguments(), Policy, TPL);
2302}
2303
2306 const PrintingPolicy &Policy,
2307 const TemplateParameterList *TPL) {
2308 printTo(OS, Args, Policy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2309}
2310
2313 const PrintingPolicy &Policy,
2314 const TemplateParameterList *TPL) {
2315 printTo(OS, Args, Policy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2316}
2317
2318std::string Qualifiers::getAsString() const {
2319 LangOptions LO;
2320 return getAsString(PrintingPolicy(LO));
2321}
2322
2323// Appends qualifiers to the given string, separated by spaces. Will
2324// prefix a space if the string is non-empty. Will not append a final
2325// space.
2326std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {
2327 SmallString<64> Buf;
2328 llvm::raw_svector_ostream StrOS(Buf);
2329 print(StrOS, Policy);
2330 return std::string(StrOS.str());
2331}
2332
2334 if (getCVRQualifiers())
2335 return false;
2336
2338 return false;
2339
2340 if (getObjCGCAttr())
2341 return false;
2342
2344 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
2345 return false;
2346
2347 return true;
2348}
2349
2351 switch (AS) {
2352 case LangAS::Default:
2353 return "";
2356 return "__global";
2358 case LangAS::sycl_local:
2359 return "__local";
2362 return "__private";
2364 return "__constant";
2366 return "__generic";
2369 return "__global_device";
2372 return "__global_host";
2374 return "__device__";
2376 return "__constant__";
2378 return "__shared__";
2379 case LangAS::ptr32_sptr:
2380 return "__sptr __ptr32";
2381 case LangAS::ptr32_uptr:
2382 return "__uptr __ptr32";
2383 case LangAS::ptr64:
2384 return "__ptr64";
2386 return "__funcref";
2388 return "groupshared";
2389 default:
2390 return std::to_string(toTargetAddressSpace(AS));
2391 }
2392}
2393
2394// Appends qualifiers to the given string, separated by spaces. Will
2395// prefix a space if the string is non-empty. Will not append a final
2396// space.
2397void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
2398 bool appendSpaceIfNonEmpty) const {
2399 bool addSpace = false;
2400
2401 unsigned quals = getCVRQualifiers();
2402 if (quals) {
2403 AppendTypeQualList(OS, quals, Policy.Restrict);
2404 addSpace = true;
2405 }
2406 if (hasUnaligned()) {
2407 if (addSpace)
2408 OS << ' ';
2409 OS << "__unaligned";
2410 addSpace = true;
2411 }
2412 auto ASStr = getAddrSpaceAsString(getAddressSpace());
2413 if (!ASStr.empty()) {
2414 if (addSpace)
2415 OS << ' ';
2416 addSpace = true;
2417 // Wrap target address space into an attribute syntax
2419 OS << "__attribute__((address_space(" << ASStr << ")))";
2420 else
2421 OS << ASStr;
2422 }
2423
2424 if (Qualifiers::GC gc = getObjCGCAttr()) {
2425 if (addSpace)
2426 OS << ' ';
2427 addSpace = true;
2428 if (gc == Qualifiers::Weak)
2429 OS << "__weak";
2430 else
2431 OS << "__strong";
2432 }
2433 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
2434 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
2435 if (addSpace)
2436 OS << ' ';
2437 addSpace = true;
2438 }
2439
2440 switch (lifetime) {
2441 case Qualifiers::OCL_None: llvm_unreachable("none but true");
2442 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;
2444 if (!Policy.SuppressStrongLifetime)
2445 OS << "__strong";
2446 break;
2447
2448 case Qualifiers::OCL_Weak: OS << "__weak"; break;
2449 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
2450 }
2451 }
2452
2453 if (appendSpaceIfNonEmpty && addSpace)
2454 OS << ' ';
2455}
2456
2457std::string QualType::getAsString() const {
2458 return getAsString(split(), LangOptions());
2459}
2460
2461std::string QualType::getAsString(const PrintingPolicy &Policy) const {
2462 std::string S;
2463 getAsStringInternal(S, Policy);
2464 return S;
2465}
2466
2467std::string QualType::getAsString(const Type *ty, Qualifiers qs,
2468 const PrintingPolicy &Policy) {
2469 std::string buffer;
2470 getAsStringInternal(ty, qs, buffer, Policy);
2471 return buffer;
2472}
2473
2474void QualType::print(raw_ostream &OS, const PrintingPolicy &Policy,
2475 const Twine &PlaceHolder, unsigned Indentation) const {
2476 print(splitAccordingToPolicy(*this, Policy), OS, Policy, PlaceHolder,
2477 Indentation);
2478}
2479
2481 raw_ostream &OS, const PrintingPolicy &policy,
2482 const Twine &PlaceHolder, unsigned Indentation) {
2483 SmallString<128> PHBuf;
2484 StringRef PH = PlaceHolder.toStringRef(PHBuf);
2485
2486 TypePrinter(policy, Indentation).print(ty, qs, OS, PH);
2487}
2488
2489void QualType::getAsStringInternal(std::string &Str,
2490 const PrintingPolicy &Policy) const {
2491 return getAsStringInternal(splitAccordingToPolicy(*this, Policy), Str,
2492 Policy);
2493}
2494
2496 std::string &buffer,
2497 const PrintingPolicy &policy) {
2498 SmallString<256> Buf;
2499 llvm::raw_svector_ostream StrOS(Buf);
2500 TypePrinter(policy).print(ty, qs, StrOS, buffer);
2501 std::string str = std::string(StrOS.str());
2502 buffer.swap(str);
2503}
2504
2505raw_ostream &clang::operator<<(raw_ostream &OS, QualType QT) {
2506 SplitQualType S = QT.split();
2507 TypePrinter(LangOptions()).print(S.Ty, S.Quals, OS, /*PlaceHolder=*/"");
2508 return OS;
2509}
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:96
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:700
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:2565
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
Definition: ASTContext.h:2141
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:2927
QualType getAdjustedType() const
Definition: Type.h:2941
ArraySizeModifier getSizeModifier() const
Definition: Type.h:3161
Qualifiers getIndexTypeQualifiers() const
Definition: Type.h:3165
QualType getElementType() const
Definition: Type.h:3159
unsigned getIndexTypeCVRQualifiers() const
Definition: Type.h:3169
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
Definition: Type.h:6732
An attributed type is a type to which a type attribute has been applied.
Definition: Type.h:5147
QualType getModifiedType() const
Definition: Type.h:5169
bool isCallingConv() const
Definition: Type.cpp:3973
std::optional< NullabilityKind > getImmediateNullability() const
Definition: Type.cpp:4660
bool isMSTypeSpec() const
Definition: Type.cpp:3956
QualType getEquivalentType() const
Definition: Type.h:5170
Kind getAttrKind() const
Definition: Type.h:5165
bool isWebAssemblyFuncrefSpec() const
Definition: Type.cpp:3969
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Definition: Type.h:5524
ArrayRef< TemplateArgument > getTypeConstraintArguments() const
Definition: Type.h:5534
ConceptDecl * getTypeConstraintConcept() const
Definition: Type.h:5539
AutoTypeKeyword getKeyword() const
Definition: Type.h:5555
bool isConstrained() const
Definition: Type.h:5543
const BTFTypeTagAttr * getAttr() const
Definition: Type.h:5260
QualType getWrappedType() const
Definition: Type.h:5259
A fixed int type of a specified bitwidth.
Definition: Type.h:6785
bool isUnsigned() const
Definition: Type.h:6795
unsigned getNumBits() const
Definition: Type.h:6797
Pointer to a block type.
Definition: Type.h:2978
QualType getPointeeType() const
Definition: Type.h:2990
This class is used for builtin types like 'int'.
Definition: Type.h:2740
StringRef getName(const PrintingPolicy &Policy) const
Definition: Type.cpp:3220
Complex values, per C99 6.2.5p11.
Definition: Type.h:2845
QualType getElementType() const
Definition: Type.h:2855
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:3186
const llvm::APInt & getSize() const
Definition: Type.h:3207
Represents a concrete matrix type with constant number of rows and columns.
Definition: Type.h:3710
unsigned getNumColumns() const
Returns the number of columns in the matrix.
Definition: Type.h:3731
unsigned getNumRows() const
Returns the number of rows in the matrix.
Definition: Type.h:3728
Represents a pointer type decayed from an array or function type.
Definition: Type.h:2961
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1446
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2076
bool isTranslationUnit() const
Definition: DeclBase.h:2152
bool isFunctionOrMethod() const
Definition: DeclBase.h:2128
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:501
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:598
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
Definition: DeclBase.h:564
SourceLocation getLocation() const
Definition: DeclBase.h:444
DeclContext * getDeclContext()
Definition: DeclBase.h:453
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:4901
Expr * getUnderlyingExpr() const
Definition: Type.h:4911
Represents a C++17 deduced template specialization type.
Definition: Type.h:5572
TemplateName getTemplateName() const
Retrieve the name of the template that we are deducing.
Definition: Type.h:5592
QualType getDeducedType() const
Get the type deduced for this placeholder type, or null if it has not been deduced.
Definition: Type.h:5511
Represents an extended address space qualifier where the input address space value is dependent.
Definition: Type.h:3402
Expr * getAddrSpaceExpr() const
Definition: Type.h:3413
QualType getPointeeType() const
Definition: Type.h:3414
Expr * getNumBitsExpr() const
Definition: Type.cpp:377
bool isUnsigned() const
Definition: Type.cpp:373
Represents a qualified type name for which the type name is dependent.
Definition: Type.h:5995
NestedNameSpecifier * getQualifier() const
Retrieve the qualification on this type.
Definition: Type.h:6013
const IdentifierInfo * getIdentifier() const
Retrieve the type named by the typename specifier as an identifier.
Definition: Type.h:6020
Represents an array type in C++ whose size is a value-dependent expression.
Definition: Type.h:3344
Expr * getSizeExpr() const
Definition: Type.h:3364
Represents an extended vector type where either the type or size is dependent.
Definition: Type.h:3442
QualType getElementType() const
Definition: Type.h:3457
Represents a matrix type where the type and the number of rows and columns is dependent on a template...
Definition: Type.h:3769
Expr * getColumnExpr() const
Definition: Type.h:3782
Expr * getRowExpr() const
Definition: Type.h:3781
Represents a template specialization type whose template cannot be resolved, e.g.
Definition: Type.h:6047
const IdentifierInfo * getIdentifier() const
Definition: Type.h:6064
ArrayRef< TemplateArgument > template_arguments() const
Definition: Type.h:6066
NestedNameSpecifier * getQualifier() const
Definition: Type.h:6063
Represents a vector type where either the type or size is dependent.
Definition: Type.h:3564
Expr * getSizeExpr() const
Definition: Type.h:3575
VectorKind getVectorKind() const
Definition: Type.h:3578
QualType getElementType() const
Definition: Type.h:3576
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
Definition: Type.h:5914
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:5962
NestedNameSpecifier * getQualifier() const
Retrieve the qualification on this type.
Definition: Type.h:5949
QualType getNamedType() const
Retrieve the type named by the qualified-id.
Definition: Type.h:5952
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Definition: Type.h:5118
EnumDecl * getDecl() const
Definition: Type.h:5125
This represents one expression.
Definition: Expr.h:110
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition: Expr.h:175
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition: Expr.cpp:3045
bool isIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
ExtVectorType - Extended vector type.
Definition: Type.h:3604
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition: Type.h:4154
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4199
ExtParameterInfo getExtParameterInfo(unsigned I) const
Definition: Type.h:4644
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Definition: Type.h:4458
unsigned getNumParams() const
Definition: Type.h:4432
void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
Definition: Type.h:4571
Qualifiers getMethodQuals() const
Definition: Type.h:4573
QualType getParamType(unsigned i) const
Definition: Type.h:4434
unsigned getAArch64SMEAttributes() const
Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...
Definition: Type.h:4637
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
Definition: Type.h:4509
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition: Type.h:4501
bool hasDynamicExceptionSpec() const
Return whether this function has a dynamic (throw) exception spec.
Definition: Type.h:4467
bool isVariadic() const
Whether this function prototype is variadic.
Definition: Type.h:4555
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
Definition: Type.h:4516
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Definition: Type.h:4581
A class which abstracts out some details necessary for making a call.
Definition: Type.h:3910
CallingConv getCC() const
Definition: Type.h:3972
bool getCmseNSCall() const
Definition: Type.h:3960
bool getNoCfCheck() const
Definition: Type.h:3962
unsigned getRegParm() const
Definition: Type.h:3965
bool getNoCallerSavedRegs() const
Definition: Type.h:3961
bool getNoReturn() const
Definition: Type.h:3958
bool getProducesResult() const
Definition: Type.h:3959
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:3799
ExtInfo getExtInfo() const
Definition: Type.h:4128
static ArmStateValue getArmZT0State(unsigned AttrBits)
Definition: Type.h:4086
static ArmStateValue getArmZAState(unsigned AttrBits)
Definition: Type.h:4082
QualType getReturnType() const
Definition: Type.h:4116
@ SME_PStateSMEnabledMask
Definition: Type.h:4060
@ SME_PStateSMCompatibleMask
Definition: Type.h:4061
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:3246
The injected class name of a C++ class template or class template partial specialization.
Definition: Type.h:5764
const TemplateSpecializationType * getInjectedTST() const
Definition: Type.h:5797
TemplateName getTemplateName() const
Definition: Type.h:5801
An lvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:3053
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:418
Sugar type that represents a type that was qualified by a qualifier written as a macro invocation.
Definition: Type.h:4785
QualType getModifiedType() const
Return this attributed type's modified type with no qualifiers attached to it.
Definition: Type.cpp:3745
const IdentifierInfo * getMacroIdentifier() const
Definition: Type.h:4800
QualType getElementType() const
Returns type of the elements being stored in the matrix.
Definition: Type.h:3688
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition: Type.h:3089
QualType getPointeeType() const
Definition: Type.h:3105
const Type * getClass() const
Definition: Type.h:3119
This represents a decl that may have a name.
Definition: Decl.h:249
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
Definition: Decl.h:462
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:270
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:276
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:315
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:6495
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
Definition: Type.cpp:849
Represents a pointer to an Objective C object.
Definition: Type.h:6551
bool isObjCQualifiedClassType() const
True if this is equivalent to 'Class.
Definition: Type.h:6632
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
Definition: Type.h:6626
bool isObjCIdType() const
True if this is equivalent to the 'id' type, i.e.
Definition: Type.h:6609
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
Definition: Type.h:6563
bool isObjCClassType() const
True if this is equivalent to the 'Class' type, i.e.
Definition: Type.h:6615
Represents a class type in Objective C.
Definition: Type.h:6297
bool isKindOfTypeAsWritten() const
Whether this is a "__kindof" type as written.
Definition: Type.h:6412
ArrayRef< QualType > getTypeArgsAsWritten() const
Retrieve the type arguments of this object type as they were written.
Definition: Type.h:6407
bool isUnspecializedAsWritten() const
Determine whether this object type is "unspecialized" as written, meaning that it has no type argumen...
Definition: Type.h:6400
QualType getBaseType() const
Gets the base type of this object type.
Definition: Type.h:6359
bool isSpecializedAsWritten() const
Determine whether this object type was written with type arguments.
Definition: Type.h:6390
qual_range quals() const
Definition: Type.h:6195
bool qual_empty() const
Definition: Type.h:6199
Represents a type parameter type in Objective C.
Definition: Type.h:6223
ObjCTypeParamDecl * getDecl() const
Definition: Type.h:6265
Represents a pack expansion of types.
Definition: Type.h:6112
QualType getPattern() const
Retrieve the pattern of this pack expansion, which is the type that will be repeatedly instantiated w...
Definition: Type.h:6133
bool hasSelectedType() const
Definition: Type.h:4978
QualType getPattern() const
Definition: Type.h:4961
QualType getSelectedType() const
Definition: Type.h:4971
Expr * getIndexExpr() const
Definition: Type.h:4960
Sugar for parentheses used when specifying types.
Definition: Type.h:2872
QualType getInnerType() const
Definition: Type.h:2881
PipeType - OpenCL20.
Definition: Type.h:6751
QualType getElementType() const
Definition: Type.h:6762
bool isReadOnly() const
Definition: Type.h:6781
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:2898
QualType getPointeeType() const
Definition: Type.h:2908
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:737
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:804
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:6902
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition: Type.h:6942
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:6954
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
Definition: Type.h:6923
std::string getAsString() const
StreamedQualTypeHelper stream(const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Definition: Type.h:1180
The collection of all-type qualifiers we support.
Definition: Type.h:147
unsigned getCVRQualifiers() const
Definition: Type.h:295
GC getObjCGCAttr() const
Definition: Type.h:326
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Definition: Type.h:175
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
Definition: Type.h:168
@ OCL_None
There is no lifetime qualification on this type.
Definition: Type.h:164
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Definition: Type.h:178
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
Definition: Type.h:181
bool hasQualifiers() const
Return true if the set contains any qualifiers.
Definition: Type.h:439
bool hasUnaligned() const
Definition: Type.h:318
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool appendSpaceIfNonEmpty=false) const
bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const
ObjCLifetime getObjCLifetime() const
Definition: Type.h:352
bool empty() const
Definition: Type.h:440
std::string getAsString() const
LangAS getAddressSpace() const
Definition: Type.h:378
static std::string getAddrSpaceAsString(LangAS AS)
An rvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:3071
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:5092
RecordDecl * getDecl() const
Definition: Type.h:5102
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3009
QualType getPointeeTypeAsWritten() const
Definition: Type.h:3025
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:5432
const TemplateTypeParmDecl * getReplacedParameter() const
Gets the template parameter declaration that was substituted for.
Definition: Type.cpp:4061
Represents the result of substituting a type for a template type parameter.
Definition: Type.h:5362
QualType getReplacementType() const
Gets the type that was substituted for the template parameter.
Definition: Type.h:5374
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3549
StringRef getKindName() const
Definition: Decl.h:3740
TypedefNameDecl * getTypedefNameForAnonDecl() const
Definition: Decl.h:3777
A convenient class for passing around template argument information.
Definition: TemplateBase.h:632
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
Definition: TemplateBase.h:659
A template argument list.
Definition: DeclTemplate.h:244
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Definition: DeclTemplate.h:274
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:524
const TemplateArgument & getArgument() const
Definition: TemplateBase.h:574
TypeSourceInfo * getTypeSourceInfo() const
Definition: TemplateBase.h:578
Represents a template argument.
Definition: TemplateBase.h:61
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
Definition: TemplateBase.h:444
Expr * getAsExpr() const
Retrieve the template argument as an expression.
Definition: TemplateBase.h:408
QualType getAsType() const
Retrieve the type for a type template argument.
Definition: TemplateBase.h:319
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
Definition: TemplateBase.h:363
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
Definition: TemplateBase.h:343
unsigned pack_size() const
The number of template arguments in the given template argument pack.
Definition: TemplateBase.h:438
bool structurallyEquals(const TemplateArgument &Other) const
Determines whether two template arguments are superficially the same.
void print(const PrintingPolicy &Policy, raw_ostream &Out, bool IncludeType) const
Print this template argument to the given output stream.
bool getIsDefaulted() const
If returns 'true', this TemplateArgument corresponds to a default template parameter.
Definition: TemplateBase.h:393
ArgKind
The kind of template argument we're storing.
Definition: TemplateBase.h:64
@ Template
The template argument is a template name that was provided for a template template parameter.
Definition: TemplateBase.h:93
@ Pack
The template argument is actually a parameter pack.
Definition: TemplateBase.h:107
@ Type
The template argument is a type.
Definition: TemplateBase.h:70
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
Definition: TemplateBase.h:82
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
Definition: TemplateBase.h:103
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:295
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:394
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:413
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:5632
ArrayRef< TemplateArgument > template_arguments() const
Definition: Type.h:5700
TemplateName getTemplateName() const
Retrieve the name of the template that we are specializing.
Definition: Type.h:5698
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:5325
unsigned getIndex() const
Definition: Type.h:5322
IdentifierInfo * getIdentifier() const
Definition: Type.cpp:4006
unsigned getDepth() const
Definition: Type.h:5321
const Type * getTypeForDecl() const
Definition: Decl.h:3381
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
Definition: Type.h:4817
TypeOfKind getKind() const
Returns the kind of 'typeof' type this is.
Definition: Type.h:4829
Expr * getUnderlyingExpr() const
Definition: Type.h:4826
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
Definition: Type.h:4865
TypeOfKind getKind() const
Returns the kind of 'typeof' type this is.
Definition: Type.h:4892
QualType getUnmodifiedType() const
Definition: Type.h:4880
A container of type source information.
Definition: Type.h:6873
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:6884
static StringRef getKeywordName(ElaboratedTypeKeyword Keyword)
Definition: Type.cpp:3140
ElaboratedTypeKeyword getKeyword() const
Definition: Type.h:5872
The base class of the type hierarchy.
Definition: Type.h:1606
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1819
QualType getLocallyUnqualifiedSingleStepDesugaredType() const
Pull a single level of sugar off of this locally-unqualified type.
Definition: Type.cpp:444
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:7724
bool isObjCQualifiedIdType() const
Definition: Type.h:7303
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:651
bool isObjCIdType() const
Definition: Type.h:7315
bool isSpecifierType() const
Returns true if this type can be represented by some set of type specifiers.
Definition: Type.cpp:3025
bool isFunctionType() const
Definition: Type.h:7150
bool isObjCQualifiedClassType() const
Definition: Type.h:7309
bool isObjCClassType() const
Definition: Type.h:7321
TypeClass getTypeClass() const
Definition: Type.h:2074
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7657
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3399
TypedefNameDecl * getDecl() const
Definition: Type.h:4760
A unary type transform, which is a type constructed from another.
Definition: Type.h:5009
QualType getBaseType() const
Definition: Type.h:5036
UTTKind getUTTKind() const
Definition: Type.h:5038
Represents the dependent type named by a dependently-scoped typename using declaration,...
Definition: Type.h:4687
UnresolvedUsingTypenameDecl * getDecl() const
Definition: Type.h:4698
UsingShadowDecl * getFoundDecl() const
Definition: Type.h:4727
Represents a C array with a specified size that is not an integer-constant-expression.
Definition: Type.h:3290
Expr * getSizeExpr() const
Definition: Type.h:3309
Represents a GCC generic vector type.
Definition: Type.h:3512
unsigned getNumElements() const
Definition: Type.h:3527
VectorKind getVectorKind() const
Definition: Type.h:3532
QualType getElementType() const
Definition: Type.h:3526
The JSON file list parser is used to communicate input to InstallAPI.
@ GNUAutoType
__auto_type (GNU extension)
@ DecltypeAuto
decltype(auto)
llvm::StringRef getParameterABISpelling(ParameterABI kind)
bool isTargetAddressSpace(LangAS AS)
Definition: AddressSpaces.h:77
@ RQ_None
No ref-qualifier was provided.
Definition: Type.h:1555
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
Definition: Type.h:1558
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition: Type.h:1561
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:362
@ 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:1285
@ CC_X86Pascal
Definition: Specifiers.h:281
@ CC_Swift
Definition: Specifiers.h:290
@ CC_IntelOclBicc
Definition: Specifiers.h:287
@ CC_OpenCLKernel
Definition: Specifiers.h:289
@ CC_PreserveMost
Definition: Specifiers.h:292
@ CC_Win64
Definition: Specifiers.h:282
@ CC_X86ThisCall
Definition: Specifiers.h:279
@ CC_AArch64VectorCall
Definition: Specifiers.h:294
@ CC_AAPCS
Definition: Specifiers.h:285
@ CC_PreserveNone
Definition: Specifiers.h:298
@ CC_C
Definition: Specifiers.h:276
@ CC_AMDGPUKernelCall
Definition: Specifiers.h:296
@ CC_M68kRTD
Definition: Specifiers.h:297
@ CC_SwiftAsync
Definition: Specifiers.h:291
@ CC_X86RegCall
Definition: Specifiers.h:284
@ CC_X86VectorCall
Definition: Specifiers.h:280
@ CC_SpirFunction
Definition: Specifiers.h:288
@ CC_AArch64SVEPCS
Definition: Specifiers.h:295
@ CC_X86StdCall
Definition: Specifiers.h:277
@ CC_X86_64SysV
Definition: Specifiers.h:283
@ CC_PreserveAll
Definition: Specifiers.h:293
@ CC_X86FastCall
Definition: Specifiers.h:278
@ CC_AAPCS_VFP
Definition: Specifiers.h:286
@ None
No keyword precedes the qualified type name.
@ 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:670
const Type * Ty
The locally-unqualified type.
Definition: Type.h:672
Qualifiers Quals
The local qualifiers.
Definition: Type.h:675