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
13 #include "clang/AST/ASTContext.h"
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"
19 #include "clang/AST/DeclTemplate.h"
20 #include "clang/AST/Expr.h"
21 #include "clang/AST/NestedNameSpecifier.h"
22 #include "clang/AST/PrettyPrinter.h"
23 #include "clang/AST/TemplateBase.h"
24 #include "clang/AST/TemplateName.h"
25 #include "clang/AST/Type.h"
26 #include "clang/Basic/AddressSpaces.h"
27 #include "clang/Basic/ExceptionSpecificationType.h"
28 #include "clang/Basic/IdentifierTable.h"
29 #include "clang/Basic/LLVM.h"
30 #include "clang/Basic/LangOptions.h"
31 #include "clang/Basic/SourceLocation.h"
32 #include "clang/Basic/SourceManager.h"
33 #include "clang/Basic/Specifiers.h"
34 #include "llvm/ADT/ArrayRef.h"
35 #include "llvm/ADT/SmallString.h"
36 #include "llvm/ADT/StringRef.h"
37 #include "llvm/ADT/Twine.h"
38 #include "llvm/Support/Casting.h"
39 #include "llvm/Support/Compiler.h"
40 #include "llvm/Support/ErrorHandling.h"
41 #include "llvm/Support/SaveAndRestore.h"
42 #include "llvm/Support/raw_ostream.h"
43 #include <cassert>
44 #include <string>
45
46 using namespace clang;
47
48 namespace {
49
50 /// RAII object that enables printing of the ARC __strong lifetime
51 /// qualifier.
52 class IncludeStrongLifetimeRAII {
53 PrintingPolicy &Policy;
54 bool Old;
55
56 public:
IncludeStrongLifetimeRAII(PrintingPolicy & Policy)57 explicit IncludeStrongLifetimeRAII(PrintingPolicy &Policy)
58 : Policy(Policy), Old(Policy.SuppressStrongLifetime) {
59 if (!Policy.SuppressLifetimeQualifiers)
60 Policy.SuppressStrongLifetime = false;
61 }
62
~IncludeStrongLifetimeRAII()63 ~IncludeStrongLifetimeRAII() {
64 Policy.SuppressStrongLifetime = Old;
65 }
66 };
67
68 class ParamPolicyRAII {
69 PrintingPolicy &Policy;
70 bool Old;
71
72 public:
ParamPolicyRAII(PrintingPolicy & Policy)73 explicit ParamPolicyRAII(PrintingPolicy &Policy)
74 : Policy(Policy), Old(Policy.SuppressSpecifiers) {
75 Policy.SuppressSpecifiers = false;
76 }
77
~ParamPolicyRAII()78 ~ParamPolicyRAII() {
79 Policy.SuppressSpecifiers = Old;
80 }
81 };
82
83 class ElaboratedTypePolicyRAII {
84 PrintingPolicy &Policy;
85 bool SuppressTagKeyword;
86 bool SuppressScope;
87
88 public:
ElaboratedTypePolicyRAII(PrintingPolicy & Policy)89 explicit ElaboratedTypePolicyRAII(PrintingPolicy &Policy) : Policy(Policy) {
90 SuppressTagKeyword = Policy.SuppressTagKeyword;
91 SuppressScope = Policy.SuppressScope;
92 Policy.SuppressTagKeyword = true;
93 Policy.SuppressScope = true;
94 }
95
~ElaboratedTypePolicyRAII()96 ~ElaboratedTypePolicyRAII() {
97 Policy.SuppressTagKeyword = SuppressTagKeyword;
98 Policy.SuppressScope = SuppressScope;
99 }
100 };
101
102 class TypePrinter {
103 PrintingPolicy Policy;
104 unsigned Indentation;
105 bool HasEmptyPlaceHolder = false;
106 bool InsideCCAttribute = false;
107
108 public:
TypePrinter(const PrintingPolicy & Policy,unsigned Indentation=0)109 explicit TypePrinter(const PrintingPolicy &Policy, unsigned Indentation = 0)
110 : Policy(Policy), Indentation(Indentation) {}
111
112 void print(const Type *ty, Qualifiers qs, raw_ostream &OS,
113 StringRef PlaceHolder);
114 void print(QualType T, raw_ostream &OS, StringRef PlaceHolder);
115
116 static bool canPrefixQualifiers(const Type *T, bool &NeedARCStrongQualifier);
117 void spaceBeforePlaceHolder(raw_ostream &OS);
118 void printTypeSpec(NamedDecl *D, raw_ostream &OS);
119 void printTemplateId(const TemplateSpecializationType *T, raw_ostream &OS,
120 bool FullyQualify);
121
122 void printBefore(QualType T, raw_ostream &OS);
123 void printAfter(QualType T, raw_ostream &OS);
124 void AppendScope(DeclContext *DC, raw_ostream &OS,
125 DeclarationName NameInScope);
126 void printTag(TagDecl *T, raw_ostream &OS);
127 void printFunctionAfter(const FunctionType::ExtInfo &Info, raw_ostream &OS);
128 #define ABSTRACT_TYPE(CLASS, PARENT)
129 #define TYPE(CLASS, PARENT) \
130 void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS); \
131 void print##CLASS##After(const CLASS##Type *T, raw_ostream &OS);
132 #include "clang/AST/TypeNodes.inc"
133
134 private:
135 void printBefore(const Type *ty, Qualifiers qs, raw_ostream &OS);
136 void printAfter(const Type *ty, Qualifiers qs, raw_ostream &OS);
137 };
138
139 } // namespace
140
AppendTypeQualList(raw_ostream & OS,unsigned TypeQuals,bool HasRestrictKeyword)141 static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals,
142 bool HasRestrictKeyword) {
143 bool appendSpace = false;
144 if (TypeQuals & Qualifiers::Const) {
145 OS << "const";
146 appendSpace = true;
147 }
148 if (TypeQuals & Qualifiers::Volatile) {
149 if (appendSpace) OS << ' ';
150 OS << "volatile";
151 appendSpace = true;
152 }
153 if (TypeQuals & Qualifiers::Restrict) {
154 if (appendSpace) OS << ' ';
155 if (HasRestrictKeyword) {
156 OS << "restrict";
157 } else {
158 OS << "__restrict";
159 }
160 }
161 }
162
spaceBeforePlaceHolder(raw_ostream & OS)163 void TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) {
164 if (!HasEmptyPlaceHolder)
165 OS << ' ';
166 }
167
splitAccordingToPolicy(QualType QT,const PrintingPolicy & Policy)168 static SplitQualType splitAccordingToPolicy(QualType QT,
169 const PrintingPolicy &Policy) {
170 if (Policy.PrintCanonicalTypes)
171 QT = QT.getCanonicalType();
172 return QT.split();
173 }
174
print(QualType t,raw_ostream & OS,StringRef PlaceHolder)175 void TypePrinter::print(QualType t, raw_ostream &OS, StringRef PlaceHolder) {
176 SplitQualType split = splitAccordingToPolicy(t, Policy);
177 print(split.Ty, split.Quals, OS, PlaceHolder);
178 }
179
print(const Type * T,Qualifiers Quals,raw_ostream & OS,StringRef PlaceHolder)180 void TypePrinter::print(const Type *T, Qualifiers Quals, raw_ostream &OS,
181 StringRef PlaceHolder) {
182 if (!T) {
183 OS << "NULL TYPE";
184 return;
185 }
186
187 SaveAndRestore<bool> PHVal(HasEmptyPlaceHolder, PlaceHolder.empty());
188
189 printBefore(T, Quals, OS);
190 OS << PlaceHolder;
191 printAfter(T, Quals, OS);
192 }
193
canPrefixQualifiers(const Type * T,bool & NeedARCStrongQualifier)194 bool TypePrinter::canPrefixQualifiers(const Type *T,
195 bool &NeedARCStrongQualifier) {
196 // CanPrefixQualifiers - We prefer to print type qualifiers before the type,
197 // so that we get "const int" instead of "int const", but we can't do this if
198 // the type is complex. For example if the type is "int*", we *must* print
199 // "int * const", printing "const int *" is different. Only do this when the
200 // type expands to a simple string.
201 bool CanPrefixQualifiers = false;
202 NeedARCStrongQualifier = false;
203 Type::TypeClass TC = T->getTypeClass();
204 if (const auto *AT = dyn_cast<AutoType>(T))
205 TC = AT->desugar()->getTypeClass();
206 if (const auto *Subst = dyn_cast<SubstTemplateTypeParmType>(T))
207 TC = Subst->getReplacementType()->getTypeClass();
208
209 switch (TC) {
210 case Type::Auto:
211 case Type::Builtin:
212 case Type::Complex:
213 case Type::UnresolvedUsing:
214 case Type::Typedef:
215 case Type::TypeOfExpr:
216 case Type::TypeOf:
217 case Type::Decltype:
218 case Type::UnaryTransform:
219 case Type::Record:
220 case Type::Enum:
221 case Type::Elaborated:
222 case Type::TemplateTypeParm:
223 case Type::SubstTemplateTypeParmPack:
224 case Type::DeducedTemplateSpecialization:
225 case Type::TemplateSpecialization:
226 case Type::InjectedClassName:
227 case Type::DependentName:
228 case Type::DependentTemplateSpecialization:
229 case Type::ObjCObject:
230 case Type::ObjCTypeParam:
231 case Type::ObjCInterface:
232 case Type::Atomic:
233 case Type::Pipe:
234 case Type::ExtInt:
235 case Type::DependentExtInt:
236 CanPrefixQualifiers = true;
237 break;
238
239 case Type::ObjCObjectPointer:
240 CanPrefixQualifiers = T->isObjCIdType() || T->isObjCClassType() ||
241 T->isObjCQualifiedIdType() || T->isObjCQualifiedClassType();
242 break;
243
244 case Type::ConstantArray:
245 case Type::IncompleteArray:
246 case Type::VariableArray:
247 case Type::DependentSizedArray:
248 NeedARCStrongQualifier = true;
249 LLVM_FALLTHROUGH;
250
251 case Type::Adjusted:
252 case Type::Decayed:
253 case Type::Pointer:
254 case Type::BlockPointer:
255 case Type::LValueReference:
256 case Type::RValueReference:
257 case Type::MemberPointer:
258 case Type::DependentAddressSpace:
259 case Type::DependentVector:
260 case Type::DependentSizedExtVector:
261 case Type::Vector:
262 case Type::ExtVector:
263 case Type::ConstantMatrix:
264 case Type::DependentSizedMatrix:
265 case Type::FunctionProto:
266 case Type::FunctionNoProto:
267 case Type::Paren:
268 case Type::PackExpansion:
269 case Type::SubstTemplateTypeParm:
270 case Type::MacroQualified:
271 CanPrefixQualifiers = false;
272 break;
273
274 case Type::Attributed: {
275 // We still want to print the address_space before the type if it is an
276 // address_space attribute.
277 const auto *AttrTy = cast<AttributedType>(T);
278 CanPrefixQualifiers = AttrTy->getAttrKind() == attr::AddressSpace;
279 }
280 }
281
282 return CanPrefixQualifiers;
283 }
284
printBefore(QualType T,raw_ostream & OS)285 void TypePrinter::printBefore(QualType T, raw_ostream &OS) {
286 SplitQualType Split = splitAccordingToPolicy(T, Policy);
287
288 // If we have cv1 T, where T is substituted for cv2 U, only print cv1 - cv2
289 // at this level.
290 Qualifiers Quals = Split.Quals;
291 if (const auto *Subst = dyn_cast<SubstTemplateTypeParmType>(Split.Ty))
292 Quals -= QualType(Subst, 0).getQualifiers();
293
294 printBefore(Split.Ty, Quals, OS);
295 }
296
297 /// Prints the part of the type string before an identifier, e.g. for
298 /// "int foo[10]" it prints "int ".
printBefore(const Type * T,Qualifiers Quals,raw_ostream & OS)299 void TypePrinter::printBefore(const Type *T,Qualifiers Quals, raw_ostream &OS) {
300 if (Policy.SuppressSpecifiers && T->isSpecifierType())
301 return;
302
303 SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder);
304
305 // Print qualifiers as appropriate.
306
307 bool CanPrefixQualifiers = false;
308 bool NeedARCStrongQualifier = false;
309 CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier);
310
311 if (CanPrefixQualifiers && !Quals.empty()) {
312 if (NeedARCStrongQualifier) {
313 IncludeStrongLifetimeRAII Strong(Policy);
314 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
315 } else {
316 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
317 }
318 }
319
320 bool hasAfterQuals = false;
321 if (!CanPrefixQualifiers && !Quals.empty()) {
322 hasAfterQuals = !Quals.isEmptyWhenPrinted(Policy);
323 if (hasAfterQuals)
324 HasEmptyPlaceHolder = false;
325 }
326
327 switch (T->getTypeClass()) {
328 #define ABSTRACT_TYPE(CLASS, PARENT)
329 #define TYPE(CLASS, PARENT) case Type::CLASS: \
330 print##CLASS##Before(cast<CLASS##Type>(T), OS); \
331 break;
332 #include "clang/AST/TypeNodes.inc"
333 }
334
335 if (hasAfterQuals) {
336 if (NeedARCStrongQualifier) {
337 IncludeStrongLifetimeRAII Strong(Policy);
338 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
339 } else {
340 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
341 }
342 }
343 }
344
printAfter(QualType t,raw_ostream & OS)345 void TypePrinter::printAfter(QualType t, raw_ostream &OS) {
346 SplitQualType split = splitAccordingToPolicy(t, Policy);
347 printAfter(split.Ty, split.Quals, OS);
348 }
349
350 /// Prints the part of the type string after an identifier, e.g. for
351 /// "int foo[10]" it prints "[10]".
printAfter(const Type * T,Qualifiers Quals,raw_ostream & OS)352 void TypePrinter::printAfter(const Type *T, Qualifiers Quals, raw_ostream &OS) {
353 switch (T->getTypeClass()) {
354 #define ABSTRACT_TYPE(CLASS, PARENT)
355 #define TYPE(CLASS, PARENT) case Type::CLASS: \
356 print##CLASS##After(cast<CLASS##Type>(T), OS); \
357 break;
358 #include "clang/AST/TypeNodes.inc"
359 }
360 }
361
printBuiltinBefore(const BuiltinType * T,raw_ostream & OS)362 void TypePrinter::printBuiltinBefore(const BuiltinType *T, raw_ostream &OS) {
363 OS << T->getName(Policy);
364 spaceBeforePlaceHolder(OS);
365 }
366
printBuiltinAfter(const BuiltinType * T,raw_ostream & OS)367 void TypePrinter::printBuiltinAfter(const BuiltinType *T, raw_ostream &OS) {}
368
printComplexBefore(const ComplexType * T,raw_ostream & OS)369 void TypePrinter::printComplexBefore(const ComplexType *T, raw_ostream &OS) {
370 OS << "_Complex ";
371 printBefore(T->getElementType(), OS);
372 }
373
printComplexAfter(const ComplexType * T,raw_ostream & OS)374 void TypePrinter::printComplexAfter(const ComplexType *T, raw_ostream &OS) {
375 printAfter(T->getElementType(), OS);
376 }
377
printPointerBefore(const PointerType * T,raw_ostream & OS)378 void TypePrinter::printPointerBefore(const PointerType *T, raw_ostream &OS) {
379 IncludeStrongLifetimeRAII Strong(Policy);
380 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
381 printBefore(T->getPointeeType(), OS);
382 // Handle things like 'int (*A)[4];' correctly.
383 // FIXME: this should include vectors, but vectors use attributes I guess.
384 if (isa<ArrayType>(T->getPointeeType()))
385 OS << '(';
386 OS << '*';
387 }
388
printPointerAfter(const PointerType * T,raw_ostream & OS)389 void TypePrinter::printPointerAfter(const PointerType *T, raw_ostream &OS) {
390 IncludeStrongLifetimeRAII Strong(Policy);
391 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
392 // Handle things like 'int (*A)[4];' correctly.
393 // FIXME: this should include vectors, but vectors use attributes I guess.
394 if (isa<ArrayType>(T->getPointeeType()))
395 OS << ')';
396 printAfter(T->getPointeeType(), OS);
397 }
398
printBlockPointerBefore(const BlockPointerType * T,raw_ostream & OS)399 void TypePrinter::printBlockPointerBefore(const BlockPointerType *T,
400 raw_ostream &OS) {
401 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
402 printBefore(T->getPointeeType(), OS);
403 OS << '^';
404 }
405
printBlockPointerAfter(const BlockPointerType * T,raw_ostream & OS)406 void TypePrinter::printBlockPointerAfter(const BlockPointerType *T,
407 raw_ostream &OS) {
408 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
409 printAfter(T->getPointeeType(), OS);
410 }
411
412 // When printing a reference, the referenced type might also be a reference.
413 // If so, we want to skip that before printing the inner type.
skipTopLevelReferences(QualType T)414 static QualType skipTopLevelReferences(QualType T) {
415 if (auto *Ref = T->getAs<ReferenceType>())
416 return skipTopLevelReferences(Ref->getPointeeTypeAsWritten());
417 return T;
418 }
419
printLValueReferenceBefore(const LValueReferenceType * T,raw_ostream & OS)420 void TypePrinter::printLValueReferenceBefore(const LValueReferenceType *T,
421 raw_ostream &OS) {
422 IncludeStrongLifetimeRAII Strong(Policy);
423 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
424 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
425 printBefore(Inner, OS);
426 // Handle things like 'int (&A)[4];' correctly.
427 // FIXME: this should include vectors, but vectors use attributes I guess.
428 if (isa<ArrayType>(Inner))
429 OS << '(';
430 OS << '&';
431 }
432
printLValueReferenceAfter(const LValueReferenceType * T,raw_ostream & OS)433 void TypePrinter::printLValueReferenceAfter(const LValueReferenceType *T,
434 raw_ostream &OS) {
435 IncludeStrongLifetimeRAII Strong(Policy);
436 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
437 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
438 // Handle things like 'int (&A)[4];' correctly.
439 // FIXME: this should include vectors, but vectors use attributes I guess.
440 if (isa<ArrayType>(Inner))
441 OS << ')';
442 printAfter(Inner, OS);
443 }
444
printRValueReferenceBefore(const RValueReferenceType * T,raw_ostream & OS)445 void TypePrinter::printRValueReferenceBefore(const RValueReferenceType *T,
446 raw_ostream &OS) {
447 IncludeStrongLifetimeRAII Strong(Policy);
448 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
449 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
450 printBefore(Inner, OS);
451 // Handle things like 'int (&&A)[4];' correctly.
452 // FIXME: this should include vectors, but vectors use attributes I guess.
453 if (isa<ArrayType>(Inner))
454 OS << '(';
455 OS << "&&";
456 }
457
printRValueReferenceAfter(const RValueReferenceType * T,raw_ostream & OS)458 void TypePrinter::printRValueReferenceAfter(const RValueReferenceType *T,
459 raw_ostream &OS) {
460 IncludeStrongLifetimeRAII Strong(Policy);
461 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
462 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
463 // Handle things like 'int (&&A)[4];' correctly.
464 // FIXME: this should include vectors, but vectors use attributes I guess.
465 if (isa<ArrayType>(Inner))
466 OS << ')';
467 printAfter(Inner, OS);
468 }
469
printMemberPointerBefore(const MemberPointerType * T,raw_ostream & OS)470 void TypePrinter::printMemberPointerBefore(const MemberPointerType *T,
471 raw_ostream &OS) {
472 IncludeStrongLifetimeRAII Strong(Policy);
473 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
474 printBefore(T->getPointeeType(), OS);
475 // Handle things like 'int (Cls::*A)[4];' correctly.
476 // FIXME: this should include vectors, but vectors use attributes I guess.
477 if (isa<ArrayType>(T->getPointeeType()))
478 OS << '(';
479
480 PrintingPolicy InnerPolicy(Policy);
481 InnerPolicy.IncludeTagDefinition = false;
482 TypePrinter(InnerPolicy).print(QualType(T->getClass(), 0), OS, StringRef());
483
484 OS << "::*";
485 }
486
printMemberPointerAfter(const MemberPointerType * T,raw_ostream & OS)487 void TypePrinter::printMemberPointerAfter(const MemberPointerType *T,
488 raw_ostream &OS) {
489 IncludeStrongLifetimeRAII Strong(Policy);
490 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
491 // Handle things like 'int (Cls::*A)[4];' correctly.
492 // FIXME: this should include vectors, but vectors use attributes I guess.
493 if (isa<ArrayType>(T->getPointeeType()))
494 OS << ')';
495 printAfter(T->getPointeeType(), OS);
496 }
497
printConstantArrayBefore(const ConstantArrayType * T,raw_ostream & OS)498 void TypePrinter::printConstantArrayBefore(const ConstantArrayType *T,
499 raw_ostream &OS) {
500 IncludeStrongLifetimeRAII Strong(Policy);
501 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
502 printBefore(T->getElementType(), OS);
503 }
504
printConstantArrayAfter(const ConstantArrayType * T,raw_ostream & OS)505 void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T,
506 raw_ostream &OS) {
507 OS << '[';
508 if (T->getIndexTypeQualifiers().hasQualifiers()) {
509 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(),
510 Policy.Restrict);
511 OS << ' ';
512 }
513
514 if (T->getSizeModifier() == ArrayType::Static)
515 OS << "static ";
516
517 OS << T->getSize().getZExtValue() << ']';
518 printAfter(T->getElementType(), OS);
519 }
520
printIncompleteArrayBefore(const IncompleteArrayType * T,raw_ostream & OS)521 void TypePrinter::printIncompleteArrayBefore(const IncompleteArrayType *T,
522 raw_ostream &OS) {
523 IncludeStrongLifetimeRAII Strong(Policy);
524 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
525 printBefore(T->getElementType(), OS);
526 }
527
printIncompleteArrayAfter(const IncompleteArrayType * T,raw_ostream & OS)528 void TypePrinter::printIncompleteArrayAfter(const IncompleteArrayType *T,
529 raw_ostream &OS) {
530 OS << "[]";
531 printAfter(T->getElementType(), OS);
532 }
533
printVariableArrayBefore(const VariableArrayType * T,raw_ostream & OS)534 void TypePrinter::printVariableArrayBefore(const VariableArrayType *T,
535 raw_ostream &OS) {
536 IncludeStrongLifetimeRAII Strong(Policy);
537 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
538 printBefore(T->getElementType(), OS);
539 }
540
printVariableArrayAfter(const VariableArrayType * T,raw_ostream & OS)541 void TypePrinter::printVariableArrayAfter(const VariableArrayType *T,
542 raw_ostream &OS) {
543 OS << '[';
544 if (T->getIndexTypeQualifiers().hasQualifiers()) {
545 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.Restrict);
546 OS << ' ';
547 }
548
549 if (T->getSizeModifier() == VariableArrayType::Static)
550 OS << "static ";
551 else if (T->getSizeModifier() == VariableArrayType::Star)
552 OS << '*';
553
554 if (T->getSizeExpr())
555 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
556 OS << ']';
557
558 printAfter(T->getElementType(), OS);
559 }
560
printAdjustedBefore(const AdjustedType * T,raw_ostream & OS)561 void TypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream &OS) {
562 // Print the adjusted representation, otherwise the adjustment will be
563 // invisible.
564 printBefore(T->getAdjustedType(), OS);
565 }
566
printAdjustedAfter(const AdjustedType * T,raw_ostream & OS)567 void TypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) {
568 printAfter(T->getAdjustedType(), OS);
569 }
570
printDecayedBefore(const DecayedType * T,raw_ostream & OS)571 void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {
572 // Print as though it's a pointer.
573 printAdjustedBefore(T, OS);
574 }
575
printDecayedAfter(const DecayedType * T,raw_ostream & OS)576 void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {
577 printAdjustedAfter(T, OS);
578 }
579
printDependentSizedArrayBefore(const DependentSizedArrayType * T,raw_ostream & OS)580 void TypePrinter::printDependentSizedArrayBefore(
581 const DependentSizedArrayType *T,
582 raw_ostream &OS) {
583 IncludeStrongLifetimeRAII Strong(Policy);
584 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
585 printBefore(T->getElementType(), OS);
586 }
587
printDependentSizedArrayAfter(const DependentSizedArrayType * T,raw_ostream & OS)588 void TypePrinter::printDependentSizedArrayAfter(
589 const DependentSizedArrayType *T,
590 raw_ostream &OS) {
591 OS << '[';
592 if (T->getSizeExpr())
593 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
594 OS << ']';
595 printAfter(T->getElementType(), OS);
596 }
597
printDependentAddressSpaceBefore(const DependentAddressSpaceType * T,raw_ostream & OS)598 void TypePrinter::printDependentAddressSpaceBefore(
599 const DependentAddressSpaceType *T, raw_ostream &OS) {
600 printBefore(T->getPointeeType(), OS);
601 }
602
printDependentAddressSpaceAfter(const DependentAddressSpaceType * T,raw_ostream & OS)603 void TypePrinter::printDependentAddressSpaceAfter(
604 const DependentAddressSpaceType *T, raw_ostream &OS) {
605 OS << " __attribute__((address_space(";
606 if (T->getAddrSpaceExpr())
607 T->getAddrSpaceExpr()->printPretty(OS, nullptr, Policy);
608 OS << ")))";
609 printAfter(T->getPointeeType(), OS);
610 }
611
printDependentSizedExtVectorBefore(const DependentSizedExtVectorType * T,raw_ostream & OS)612 void TypePrinter::printDependentSizedExtVectorBefore(
613 const DependentSizedExtVectorType *T,
614 raw_ostream &OS) {
615 printBefore(T->getElementType(), OS);
616 }
617
printDependentSizedExtVectorAfter(const DependentSizedExtVectorType * T,raw_ostream & OS)618 void TypePrinter::printDependentSizedExtVectorAfter(
619 const DependentSizedExtVectorType *T,
620 raw_ostream &OS) {
621 OS << " __attribute__((ext_vector_type(";
622 if (T->getSizeExpr())
623 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
624 OS << ")))";
625 printAfter(T->getElementType(), OS);
626 }
627
printVectorBefore(const VectorType * T,raw_ostream & OS)628 void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {
629 switch (T->getVectorKind()) {
630 case VectorType::AltiVecPixel:
631 OS << "__vector __pixel ";
632 break;
633 case VectorType::AltiVecBool:
634 OS << "__vector __bool ";
635 printBefore(T->getElementType(), OS);
636 break;
637 case VectorType::AltiVecVector:
638 OS << "__vector ";
639 printBefore(T->getElementType(), OS);
640 break;
641 case VectorType::NeonVector:
642 OS << "__attribute__((neon_vector_type("
643 << T->getNumElements() << "))) ";
644 printBefore(T->getElementType(), OS);
645 break;
646 case VectorType::NeonPolyVector:
647 OS << "__attribute__((neon_polyvector_type(" <<
648 T->getNumElements() << "))) ";
649 printBefore(T->getElementType(), OS);
650 break;
651 case VectorType::GenericVector: {
652 // FIXME: We prefer to print the size directly here, but have no way
653 // to get the size of the type.
654 OS << "__attribute__((__vector_size__("
655 << T->getNumElements()
656 << " * sizeof(";
657 print(T->getElementType(), OS, StringRef());
658 OS << ")))) ";
659 printBefore(T->getElementType(), OS);
660 break;
661 }
662 case VectorType::SveFixedLengthDataVector:
663 case VectorType::SveFixedLengthPredicateVector:
664 // FIXME: We prefer to print the size directly here, but have no way
665 // to get the size of the type.
666 OS << "__attribute__((__arm_sve_vector_bits__(";
667
668 if (T->getVectorKind() == VectorType::SveFixedLengthPredicateVector)
669 // Predicates take a bit per byte of the vector size, multiply by 8 to
670 // get the number of bits passed to the attribute.
671 OS << T->getNumElements() * 8;
672 else
673 OS << T->getNumElements();
674
675 OS << " * sizeof(";
676 print(T->getElementType(), OS, StringRef());
677 // Multiply by 8 for the number of bits.
678 OS << ") * 8))) ";
679 printBefore(T->getElementType(), OS);
680 }
681 }
682
printVectorAfter(const VectorType * T,raw_ostream & OS)683 void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) {
684 printAfter(T->getElementType(), OS);
685 }
686
printDependentVectorBefore(const DependentVectorType * T,raw_ostream & OS)687 void TypePrinter::printDependentVectorBefore(
688 const DependentVectorType *T, raw_ostream &OS) {
689 switch (T->getVectorKind()) {
690 case VectorType::AltiVecPixel:
691 OS << "__vector __pixel ";
692 break;
693 case VectorType::AltiVecBool:
694 OS << "__vector __bool ";
695 printBefore(T->getElementType(), OS);
696 break;
697 case VectorType::AltiVecVector:
698 OS << "__vector ";
699 printBefore(T->getElementType(), OS);
700 break;
701 case VectorType::NeonVector:
702 OS << "__attribute__((neon_vector_type(";
703 if (T->getSizeExpr())
704 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
705 OS << "))) ";
706 printBefore(T->getElementType(), OS);
707 break;
708 case VectorType::NeonPolyVector:
709 OS << "__attribute__((neon_polyvector_type(";
710 if (T->getSizeExpr())
711 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
712 OS << "))) ";
713 printBefore(T->getElementType(), OS);
714 break;
715 case VectorType::GenericVector: {
716 // FIXME: We prefer to print the size directly here, but have no way
717 // to get the size of the type.
718 OS << "__attribute__((__vector_size__(";
719 if (T->getSizeExpr())
720 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
721 OS << " * sizeof(";
722 print(T->getElementType(), OS, StringRef());
723 OS << ")))) ";
724 printBefore(T->getElementType(), OS);
725 break;
726 }
727 case VectorType::SveFixedLengthDataVector:
728 case VectorType::SveFixedLengthPredicateVector:
729 // FIXME: We prefer to print the size directly here, but have no way
730 // to get the size of the type.
731 OS << "__attribute__((__arm_sve_vector_bits__(";
732 if (T->getSizeExpr()) {
733 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
734 if (T->getVectorKind() == VectorType::SveFixedLengthPredicateVector)
735 // Predicates take a bit per byte of the vector size, multiply by 8 to
736 // get the number of bits passed to the attribute.
737 OS << " * 8";
738 OS << " * sizeof(";
739 print(T->getElementType(), OS, StringRef());
740 // Multiply by 8 for the number of bits.
741 OS << ") * 8";
742 }
743 OS << "))) ";
744 printBefore(T->getElementType(), OS);
745 }
746 }
747
printDependentVectorAfter(const DependentVectorType * T,raw_ostream & OS)748 void TypePrinter::printDependentVectorAfter(
749 const DependentVectorType *T, raw_ostream &OS) {
750 printAfter(T->getElementType(), OS);
751 }
752
printExtVectorBefore(const ExtVectorType * T,raw_ostream & OS)753 void TypePrinter::printExtVectorBefore(const ExtVectorType *T,
754 raw_ostream &OS) {
755 printBefore(T->getElementType(), OS);
756 }
757
printExtVectorAfter(const ExtVectorType * T,raw_ostream & OS)758 void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) {
759 printAfter(T->getElementType(), OS);
760 OS << " __attribute__((ext_vector_type(";
761 OS << T->getNumElements();
762 OS << ")))";
763 }
764
printConstantMatrixBefore(const ConstantMatrixType * T,raw_ostream & OS)765 void TypePrinter::printConstantMatrixBefore(const ConstantMatrixType *T,
766 raw_ostream &OS) {
767 printBefore(T->getElementType(), OS);
768 OS << " __attribute__((matrix_type(";
769 OS << T->getNumRows() << ", " << T->getNumColumns();
770 OS << ")))";
771 }
772
printConstantMatrixAfter(const ConstantMatrixType * T,raw_ostream & OS)773 void TypePrinter::printConstantMatrixAfter(const ConstantMatrixType *T,
774 raw_ostream &OS) {
775 printAfter(T->getElementType(), OS);
776 }
777
printDependentSizedMatrixBefore(const DependentSizedMatrixType * T,raw_ostream & OS)778 void TypePrinter::printDependentSizedMatrixBefore(
779 const DependentSizedMatrixType *T, raw_ostream &OS) {
780 printBefore(T->getElementType(), OS);
781 OS << " __attribute__((matrix_type(";
782 if (T->getRowExpr()) {
783 T->getRowExpr()->printPretty(OS, nullptr, Policy);
784 }
785 OS << ", ";
786 if (T->getColumnExpr()) {
787 T->getColumnExpr()->printPretty(OS, nullptr, Policy);
788 }
789 OS << ")))";
790 }
791
printDependentSizedMatrixAfter(const DependentSizedMatrixType * T,raw_ostream & OS)792 void TypePrinter::printDependentSizedMatrixAfter(
793 const DependentSizedMatrixType *T, raw_ostream &OS) {
794 printAfter(T->getElementType(), OS);
795 }
796
797 void
printExceptionSpecification(raw_ostream & OS,const PrintingPolicy & Policy) const798 FunctionProtoType::printExceptionSpecification(raw_ostream &OS,
799 const PrintingPolicy &Policy)
800 const {
801 if (hasDynamicExceptionSpec()) {
802 OS << " throw(";
803 if (getExceptionSpecType() == EST_MSAny)
804 OS << "...";
805 else
806 for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) {
807 if (I)
808 OS << ", ";
809
810 OS << getExceptionType(I).stream(Policy);
811 }
812 OS << ')';
813 } else if (EST_NoThrow == getExceptionSpecType()) {
814 OS << " __attribute__((nothrow))";
815 } else if (isNoexceptExceptionSpec(getExceptionSpecType())) {
816 OS << " noexcept";
817 // FIXME:Is it useful to print out the expression for a non-dependent
818 // noexcept specification?
819 if (isComputedNoexcept(getExceptionSpecType())) {
820 OS << '(';
821 if (getNoexceptExpr())
822 getNoexceptExpr()->printPretty(OS, nullptr, Policy);
823 OS << ')';
824 }
825 }
826 }
827
printFunctionProtoBefore(const FunctionProtoType * T,raw_ostream & OS)828 void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,
829 raw_ostream &OS) {
830 if (T->hasTrailingReturn()) {
831 OS << "auto ";
832 if (!HasEmptyPlaceHolder)
833 OS << '(';
834 } else {
835 // If needed for precedence reasons, wrap the inner part in grouping parens.
836 SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder, false);
837 printBefore(T->getReturnType(), OS);
838 if (!PrevPHIsEmpty.get())
839 OS << '(';
840 }
841 }
842
getParameterABISpelling(ParameterABI ABI)843 StringRef clang::getParameterABISpelling(ParameterABI ABI) {
844 switch (ABI) {
845 case ParameterABI::Ordinary:
846 llvm_unreachable("asking for spelling of ordinary parameter ABI");
847 case ParameterABI::SwiftContext:
848 return "swift_context";
849 case ParameterABI::SwiftAsyncContext:
850 return "swift_async_context";
851 case ParameterABI::SwiftErrorResult:
852 return "swift_error_result";
853 case ParameterABI::SwiftIndirectResult:
854 return "swift_indirect_result";
855 }
856 llvm_unreachable("bad parameter ABI kind");
857 }
858
printFunctionProtoAfter(const FunctionProtoType * T,raw_ostream & OS)859 void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
860 raw_ostream &OS) {
861 // If needed for precedence reasons, wrap the inner part in grouping parens.
862 if (!HasEmptyPlaceHolder)
863 OS << ')';
864 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
865
866 OS << '(';
867 {
868 ParamPolicyRAII ParamPolicy(Policy);
869 for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {
870 if (i) OS << ", ";
871
872 auto EPI = T->getExtParameterInfo(i);
873 if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) ";
874 if (EPI.isNoEscape())
875 OS << "__attribute__((noescape)) ";
876 auto ABI = EPI.getABI();
877 if (ABI != ParameterABI::Ordinary)
878 OS << "__attribute__((" << getParameterABISpelling(ABI) << ")) ";
879
880 print(T->getParamType(i), OS, StringRef());
881 }
882 }
883
884 if (T->isVariadic()) {
885 if (T->getNumParams())
886 OS << ", ";
887 OS << "...";
888 } else if (T->getNumParams() == 0 && Policy.UseVoidForZeroParams) {
889 // Do not emit int() if we have a proto, emit 'int(void)'.
890 OS << "void";
891 }
892
893 OS << ')';
894
895 FunctionType::ExtInfo Info = T->getExtInfo();
896
897 printFunctionAfter(Info, OS);
898
899 if (!T->getMethodQuals().empty())
900 OS << " " << T->getMethodQuals().getAsString();
901
902 switch (T->getRefQualifier()) {
903 case RQ_None:
904 break;
905
906 case RQ_LValue:
907 OS << " &";
908 break;
909
910 case RQ_RValue:
911 OS << " &&";
912 break;
913 }
914 T->printExceptionSpecification(OS, Policy);
915
916 if (T->hasTrailingReturn()) {
917 OS << " -> ";
918 print(T->getReturnType(), OS, StringRef());
919 } else
920 printAfter(T->getReturnType(), OS);
921 }
922
printFunctionAfter(const FunctionType::ExtInfo & Info,raw_ostream & OS)923 void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
924 raw_ostream &OS) {
925 if (!InsideCCAttribute) {
926 switch (Info.getCC()) {
927 case CC_C:
928 // The C calling convention is the default on the vast majority of platforms
929 // we support. If the user wrote it explicitly, it will usually be printed
930 // while traversing the AttributedType. If the type has been desugared, let
931 // the canonical spelling be the implicit calling convention.
932 // FIXME: It would be better to be explicit in certain contexts, such as a
933 // cdecl function typedef used to declare a member function with the
934 // Microsoft C++ ABI.
935 break;
936 case CC_X86StdCall:
937 OS << " __attribute__((stdcall))";
938 break;
939 case CC_X86FastCall:
940 OS << " __attribute__((fastcall))";
941 break;
942 case CC_X86ThisCall:
943 OS << " __attribute__((thiscall))";
944 break;
945 case CC_X86VectorCall:
946 OS << " __attribute__((vectorcall))";
947 break;
948 case CC_X86Pascal:
949 OS << " __attribute__((pascal))";
950 break;
951 case CC_AAPCS:
952 OS << " __attribute__((pcs(\"aapcs\")))";
953 break;
954 case CC_AAPCS_VFP:
955 OS << " __attribute__((pcs(\"aapcs-vfp\")))";
956 break;
957 case CC_AArch64VectorCall:
958 OS << "__attribute__((aarch64_vector_pcs))";
959 break;
960 case CC_IntelOclBicc:
961 OS << " __attribute__((intel_ocl_bicc))";
962 break;
963 case CC_Win64:
964 OS << " __attribute__((ms_abi))";
965 break;
966 case CC_X86_64SysV:
967 OS << " __attribute__((sysv_abi))";
968 break;
969 case CC_X86RegCall:
970 OS << " __attribute__((regcall))";
971 break;
972 case CC_SpirFunction:
973 case CC_OpenCLKernel:
974 // Do nothing. These CCs are not available as attributes.
975 break;
976 case CC_Swift:
977 OS << " __attribute__((swiftcall))";
978 break;
979 case CC_SwiftAsync:
980 OS << "__attribute__((swiftasynccall))";
981 break;
982 case CC_PreserveMost:
983 OS << " __attribute__((preserve_most))";
984 break;
985 case CC_PreserveAll:
986 OS << " __attribute__((preserve_all))";
987 break;
988 }
989 }
990
991 if (Info.getNoReturn())
992 OS << " __attribute__((noreturn))";
993 if (Info.getCmseNSCall())
994 OS << " __attribute__((cmse_nonsecure_call))";
995 if (Info.getProducesResult())
996 OS << " __attribute__((ns_returns_retained))";
997 if (Info.getRegParm())
998 OS << " __attribute__((regparm ("
999 << Info.getRegParm() << ")))";
1000 if (Info.getNoCallerSavedRegs())
1001 OS << " __attribute__((no_caller_saved_registers))";
1002 if (Info.getNoCfCheck())
1003 OS << " __attribute__((nocf_check))";
1004 }
1005
printFunctionNoProtoBefore(const FunctionNoProtoType * T,raw_ostream & OS)1006 void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T,
1007 raw_ostream &OS) {
1008 // If needed for precedence reasons, wrap the inner part in grouping parens.
1009 SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder, false);
1010 printBefore(T->getReturnType(), OS);
1011 if (!PrevPHIsEmpty.get())
1012 OS << '(';
1013 }
1014
printFunctionNoProtoAfter(const FunctionNoProtoType * T,raw_ostream & OS)1015 void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,
1016 raw_ostream &OS) {
1017 // If needed for precedence reasons, wrap the inner part in grouping parens.
1018 if (!HasEmptyPlaceHolder)
1019 OS << ')';
1020 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
1021
1022 OS << "()";
1023 printFunctionAfter(T->getExtInfo(), OS);
1024 printAfter(T->getReturnType(), OS);
1025 }
1026
printTypeSpec(NamedDecl * D,raw_ostream & OS)1027 void TypePrinter::printTypeSpec(NamedDecl *D, raw_ostream &OS) {
1028
1029 // Compute the full nested-name-specifier for this type.
1030 // In C, this will always be empty except when the type
1031 // being printed is anonymous within other Record.
1032 if (!Policy.SuppressScope)
1033 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1034
1035 IdentifierInfo *II = D->getIdentifier();
1036 OS << II->getName();
1037 spaceBeforePlaceHolder(OS);
1038 }
1039
printUnresolvedUsingBefore(const UnresolvedUsingType * T,raw_ostream & OS)1040 void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,
1041 raw_ostream &OS) {
1042 printTypeSpec(T->getDecl(), OS);
1043 }
1044
printUnresolvedUsingAfter(const UnresolvedUsingType * T,raw_ostream & OS)1045 void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,
1046 raw_ostream &OS) {}
1047
printTypedefBefore(const TypedefType * T,raw_ostream & OS)1048 void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
1049 printTypeSpec(T->getDecl(), OS);
1050 }
1051
printMacroQualifiedBefore(const MacroQualifiedType * T,raw_ostream & OS)1052 void TypePrinter::printMacroQualifiedBefore(const MacroQualifiedType *T,
1053 raw_ostream &OS) {
1054 StringRef MacroName = T->getMacroIdentifier()->getName();
1055 OS << MacroName << " ";
1056
1057 // Since this type is meant to print the macro instead of the whole attribute,
1058 // we trim any attributes and go directly to the original modified type.
1059 printBefore(T->getModifiedType(), OS);
1060 }
1061
printMacroQualifiedAfter(const MacroQualifiedType * T,raw_ostream & OS)1062 void TypePrinter::printMacroQualifiedAfter(const MacroQualifiedType *T,
1063 raw_ostream &OS) {
1064 printAfter(T->getModifiedType(), OS);
1065 }
1066
printTypedefAfter(const TypedefType * T,raw_ostream & OS)1067 void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) {}
1068
printTypeOfExprBefore(const TypeOfExprType * T,raw_ostream & OS)1069 void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
1070 raw_ostream &OS) {
1071 OS << "typeof ";
1072 if (T->getUnderlyingExpr())
1073 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
1074 spaceBeforePlaceHolder(OS);
1075 }
1076
printTypeOfExprAfter(const TypeOfExprType * T,raw_ostream & OS)1077 void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
1078 raw_ostream &OS) {}
1079
printTypeOfBefore(const TypeOfType * T,raw_ostream & OS)1080 void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) {
1081 OS << "typeof(";
1082 print(T->getUnderlyingType(), OS, StringRef());
1083 OS << ')';
1084 spaceBeforePlaceHolder(OS);
1085 }
1086
printTypeOfAfter(const TypeOfType * T,raw_ostream & OS)1087 void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) {}
1088
printDecltypeBefore(const DecltypeType * T,raw_ostream & OS)1089 void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {
1090 OS << "decltype(";
1091 if (T->getUnderlyingExpr())
1092 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
1093 OS << ')';
1094 spaceBeforePlaceHolder(OS);
1095 }
1096
printDecltypeAfter(const DecltypeType * T,raw_ostream & OS)1097 void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) {}
1098
printUnaryTransformBefore(const UnaryTransformType * T,raw_ostream & OS)1099 void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,
1100 raw_ostream &OS) {
1101 IncludeStrongLifetimeRAII Strong(Policy);
1102
1103 switch (T->getUTTKind()) {
1104 case UnaryTransformType::EnumUnderlyingType:
1105 OS << "__underlying_type(";
1106 print(T->getBaseType(), OS, StringRef());
1107 OS << ')';
1108 spaceBeforePlaceHolder(OS);
1109 return;
1110 }
1111
1112 printBefore(T->getBaseType(), OS);
1113 }
1114
printUnaryTransformAfter(const UnaryTransformType * T,raw_ostream & OS)1115 void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,
1116 raw_ostream &OS) {
1117 IncludeStrongLifetimeRAII Strong(Policy);
1118
1119 switch (T->getUTTKind()) {
1120 case UnaryTransformType::EnumUnderlyingType:
1121 return;
1122 }
1123
1124 printAfter(T->getBaseType(), OS);
1125 }
1126
printAutoBefore(const AutoType * T,raw_ostream & OS)1127 void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
1128 // If the type has been deduced, do not print 'auto'.
1129 if (!T->getDeducedType().isNull()) {
1130 printBefore(T->getDeducedType(), OS);
1131 } else {
1132 if (T->isConstrained()) {
1133 // FIXME: Track a TypeConstraint as type sugar, so that we can print the
1134 // type as it was written.
1135 T->getTypeConstraintConcept()->getDeclName().print(OS, Policy);
1136 auto Args = T->getTypeConstraintArguments();
1137 if (!Args.empty())
1138 printTemplateArgumentList(
1139 OS, Args, Policy,
1140 T->getTypeConstraintConcept()->getTemplateParameters());
1141 OS << ' ';
1142 }
1143 switch (T->getKeyword()) {
1144 case AutoTypeKeyword::Auto: OS << "auto"; break;
1145 case AutoTypeKeyword::DecltypeAuto: OS << "decltype(auto)"; break;
1146 case AutoTypeKeyword::GNUAutoType: OS << "__auto_type"; break;
1147 }
1148 spaceBeforePlaceHolder(OS);
1149 }
1150 }
1151
printAutoAfter(const AutoType * T,raw_ostream & OS)1152 void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {
1153 // If the type has been deduced, do not print 'auto'.
1154 if (!T->getDeducedType().isNull())
1155 printAfter(T->getDeducedType(), OS);
1156 }
1157
printDeducedTemplateSpecializationBefore(const DeducedTemplateSpecializationType * T,raw_ostream & OS)1158 void TypePrinter::printDeducedTemplateSpecializationBefore(
1159 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1160 // If the type has been deduced, print the deduced type.
1161 if (!T->getDeducedType().isNull()) {
1162 printBefore(T->getDeducedType(), OS);
1163 } else {
1164 IncludeStrongLifetimeRAII Strong(Policy);
1165 T->getTemplateName().print(OS, Policy);
1166 spaceBeforePlaceHolder(OS);
1167 }
1168 }
1169
printDeducedTemplateSpecializationAfter(const DeducedTemplateSpecializationType * T,raw_ostream & OS)1170 void TypePrinter::printDeducedTemplateSpecializationAfter(
1171 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1172 // If the type has been deduced, print the deduced type.
1173 if (!T->getDeducedType().isNull())
1174 printAfter(T->getDeducedType(), OS);
1175 }
1176
printAtomicBefore(const AtomicType * T,raw_ostream & OS)1177 void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {
1178 IncludeStrongLifetimeRAII Strong(Policy);
1179
1180 OS << "_Atomic(";
1181 print(T->getValueType(), OS, StringRef());
1182 OS << ')';
1183 spaceBeforePlaceHolder(OS);
1184 }
1185
printAtomicAfter(const AtomicType * T,raw_ostream & OS)1186 void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) {}
1187
printPipeBefore(const PipeType * T,raw_ostream & OS)1188 void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) {
1189 IncludeStrongLifetimeRAII Strong(Policy);
1190
1191 if (T->isReadOnly())
1192 OS << "read_only ";
1193 else
1194 OS << "write_only ";
1195 OS << "pipe ";
1196 print(T->getElementType(), OS, StringRef());
1197 spaceBeforePlaceHolder(OS);
1198 }
1199
printPipeAfter(const PipeType * T,raw_ostream & OS)1200 void TypePrinter::printPipeAfter(const PipeType *T, raw_ostream &OS) {}
1201
printExtIntBefore(const ExtIntType * T,raw_ostream & OS)1202 void TypePrinter::printExtIntBefore(const ExtIntType *T, raw_ostream &OS) {
1203 if (T->isUnsigned())
1204 OS << "unsigned ";
1205 OS << "_ExtInt(" << T->getNumBits() << ")";
1206 spaceBeforePlaceHolder(OS);
1207 }
1208
printExtIntAfter(const ExtIntType * T,raw_ostream & OS)1209 void TypePrinter::printExtIntAfter(const ExtIntType *T, raw_ostream &OS) {}
1210
printDependentExtIntBefore(const DependentExtIntType * T,raw_ostream & OS)1211 void TypePrinter::printDependentExtIntBefore(const DependentExtIntType *T,
1212 raw_ostream &OS) {
1213 if (T->isUnsigned())
1214 OS << "unsigned ";
1215 OS << "_ExtInt(";
1216 T->getNumBitsExpr()->printPretty(OS, nullptr, Policy);
1217 OS << ")";
1218 spaceBeforePlaceHolder(OS);
1219 }
1220
printDependentExtIntAfter(const DependentExtIntType * T,raw_ostream & OS)1221 void TypePrinter::printDependentExtIntAfter(const DependentExtIntType *T,
1222 raw_ostream &OS) {}
1223
1224 /// Appends the given scope to the end of a string.
AppendScope(DeclContext * DC,raw_ostream & OS,DeclarationName NameInScope)1225 void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS,
1226 DeclarationName NameInScope) {
1227 if (DC->isTranslationUnit())
1228 return;
1229
1230 // FIXME: Consider replacing this with NamedDecl::printNestedNameSpecifier,
1231 // which can also print names for function and method scopes.
1232 if (DC->isFunctionOrMethod())
1233 return;
1234
1235 if (Policy.Callbacks && Policy.Callbacks->isScopeVisible(DC))
1236 return;
1237
1238 if (const auto *NS = dyn_cast<NamespaceDecl>(DC)) {
1239 if (Policy.SuppressUnwrittenScope && NS->isAnonymousNamespace())
1240 return AppendScope(DC->getParent(), OS, NameInScope);
1241
1242 // Only suppress an inline namespace if the name has the same lookup
1243 // results in the enclosing namespace.
1244 if (Policy.SuppressInlineNamespace && NS->isInline() && NameInScope &&
1245 NS->isRedundantInlineQualifierFor(NameInScope))
1246 return AppendScope(DC->getParent(), OS, NameInScope);
1247
1248 AppendScope(DC->getParent(), OS, NS->getDeclName());
1249 if (NS->getIdentifier())
1250 OS << NS->getName() << "::";
1251 else
1252 OS << "(anonymous namespace)::";
1253 } else if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
1254 AppendScope(DC->getParent(), OS, Spec->getDeclName());
1255 IncludeStrongLifetimeRAII Strong(Policy);
1256 OS << Spec->getIdentifier()->getName();
1257 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
1258 printTemplateArgumentList(
1259 OS, TemplateArgs.asArray(), Policy,
1260 Spec->getSpecializedTemplate()->getTemplateParameters());
1261 OS << "::";
1262 } else if (const auto *Tag = dyn_cast<TagDecl>(DC)) {
1263 AppendScope(DC->getParent(), OS, Tag->getDeclName());
1264 if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl())
1265 OS << Typedef->getIdentifier()->getName() << "::";
1266 else if (Tag->getIdentifier())
1267 OS << Tag->getIdentifier()->getName() << "::";
1268 else
1269 return;
1270 } else {
1271 AppendScope(DC->getParent(), OS, NameInScope);
1272 }
1273 }
1274
printTag(TagDecl * D,raw_ostream & OS)1275 void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {
1276 if (Policy.IncludeTagDefinition) {
1277 PrintingPolicy SubPolicy = Policy;
1278 SubPolicy.IncludeTagDefinition = false;
1279 D->print(OS, SubPolicy, Indentation);
1280 spaceBeforePlaceHolder(OS);
1281 return;
1282 }
1283
1284 bool HasKindDecoration = false;
1285
1286 // We don't print tags unless this is an elaborated type.
1287 // In C, we just assume every RecordType is an elaborated type.
1288 if (!Policy.SuppressTagKeyword && !D->getTypedefNameForAnonDecl()) {
1289 HasKindDecoration = true;
1290 OS << D->getKindName();
1291 OS << ' ';
1292 }
1293
1294 // Compute the full nested-name-specifier for this type.
1295 // In C, this will always be empty except when the type
1296 // being printed is anonymous within other Record.
1297 if (!Policy.SuppressScope)
1298 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1299
1300 if (const IdentifierInfo *II = D->getIdentifier())
1301 OS << II->getName();
1302 else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) {
1303 assert(Typedef->getIdentifier() && "Typedef without identifier?");
1304 OS << Typedef->getIdentifier()->getName();
1305 } else {
1306 // Make an unambiguous representation for anonymous types, e.g.
1307 // (anonymous enum at /usr/include/string.h:120:9)
1308 OS << (Policy.MSVCFormatting ? '`' : '(');
1309
1310 if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
1311 OS << "lambda";
1312 HasKindDecoration = true;
1313 } else if ((isa<RecordDecl>(D) && cast<RecordDecl>(D)->isAnonymousStructOrUnion())) {
1314 OS << "anonymous";
1315 } else {
1316 OS << "unnamed";
1317 }
1318
1319 if (Policy.AnonymousTagLocations) {
1320 // Suppress the redundant tag keyword if we just printed one.
1321 // We don't have to worry about ElaboratedTypes here because you can't
1322 // refer to an anonymous type with one.
1323 if (!HasKindDecoration)
1324 OS << " " << D->getKindName();
1325
1326 PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc(
1327 D->getLocation());
1328 if (PLoc.isValid()) {
1329 OS << " at ";
1330 StringRef File = PLoc.getFilename();
1331 if (auto *Callbacks = Policy.Callbacks)
1332 OS << Callbacks->remapPath(File);
1333 else
1334 OS << File;
1335 OS << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
1336 }
1337 }
1338
1339 OS << (Policy.MSVCFormatting ? '\'' : ')');
1340 }
1341
1342 // If this is a class template specialization, print the template
1343 // arguments.
1344 if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1345 ArrayRef<TemplateArgument> Args;
1346 TypeSourceInfo *TAW = Spec->getTypeAsWritten();
1347 if (!Policy.PrintCanonicalTypes && TAW) {
1348 const TemplateSpecializationType *TST =
1349 cast<TemplateSpecializationType>(TAW->getType());
1350 Args = TST->template_arguments();
1351 } else {
1352 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
1353 Args = TemplateArgs.asArray();
1354 }
1355 IncludeStrongLifetimeRAII Strong(Policy);
1356 printTemplateArgumentList(
1357 OS, Args, Policy,
1358 Spec->getSpecializedTemplate()->getTemplateParameters());
1359 }
1360
1361 spaceBeforePlaceHolder(OS);
1362 }
1363
printRecordBefore(const RecordType * T,raw_ostream & OS)1364 void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
1365 // Print the preferred name if we have one for this type.
1366 for (const auto *PNA : T->getDecl()->specific_attrs<PreferredNameAttr>()) {
1367 if (declaresSameEntity(PNA->getTypedefType()->getAsCXXRecordDecl(),
1368 T->getDecl())) {
1369 // Find the outermost typedef or alias template.
1370 QualType T = PNA->getTypedefType();
1371 while (true) {
1372 if (auto *TT = dyn_cast<TypedefType>(T))
1373 return printTypeSpec(TT->getDecl(), OS);
1374 if (auto *TST = dyn_cast<TemplateSpecializationType>(T))
1375 return printTemplateId(TST, OS, /*FullyQualify=*/true);
1376 T = T->getLocallyUnqualifiedSingleStepDesugaredType();
1377 }
1378 }
1379 }
1380
1381 printTag(T->getDecl(), OS);
1382 }
1383
printRecordAfter(const RecordType * T,raw_ostream & OS)1384 void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) {}
1385
printEnumBefore(const EnumType * T,raw_ostream & OS)1386 void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {
1387 printTag(T->getDecl(), OS);
1388 }
1389
printEnumAfter(const EnumType * T,raw_ostream & OS)1390 void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {}
1391
printTemplateTypeParmBefore(const TemplateTypeParmType * T,raw_ostream & OS)1392 void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
1393 raw_ostream &OS) {
1394 TemplateTypeParmDecl *D = T->getDecl();
1395 if (D && D->isImplicit()) {
1396 if (auto *TC = D->getTypeConstraint()) {
1397 TC->print(OS, Policy);
1398 OS << ' ';
1399 }
1400 OS << "auto";
1401 } else if (IdentifierInfo *Id = T->getIdentifier())
1402 OS << Id->getName();
1403 else
1404 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
1405
1406 spaceBeforePlaceHolder(OS);
1407 }
1408
printTemplateTypeParmAfter(const TemplateTypeParmType * T,raw_ostream & OS)1409 void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,
1410 raw_ostream &OS) {}
1411
printSubstTemplateTypeParmBefore(const SubstTemplateTypeParmType * T,raw_ostream & OS)1412 void TypePrinter::printSubstTemplateTypeParmBefore(
1413 const SubstTemplateTypeParmType *T,
1414 raw_ostream &OS) {
1415 IncludeStrongLifetimeRAII Strong(Policy);
1416 printBefore(T->getReplacementType(), OS);
1417 }
1418
printSubstTemplateTypeParmAfter(const SubstTemplateTypeParmType * T,raw_ostream & OS)1419 void TypePrinter::printSubstTemplateTypeParmAfter(
1420 const SubstTemplateTypeParmType *T,
1421 raw_ostream &OS) {
1422 IncludeStrongLifetimeRAII Strong(Policy);
1423 printAfter(T->getReplacementType(), OS);
1424 }
1425
printSubstTemplateTypeParmPackBefore(const SubstTemplateTypeParmPackType * T,raw_ostream & OS)1426 void TypePrinter::printSubstTemplateTypeParmPackBefore(
1427 const SubstTemplateTypeParmPackType *T,
1428 raw_ostream &OS) {
1429 IncludeStrongLifetimeRAII Strong(Policy);
1430 printTemplateTypeParmBefore(T->getReplacedParameter(), OS);
1431 }
1432
printSubstTemplateTypeParmPackAfter(const SubstTemplateTypeParmPackType * T,raw_ostream & OS)1433 void TypePrinter::printSubstTemplateTypeParmPackAfter(
1434 const SubstTemplateTypeParmPackType *T,
1435 raw_ostream &OS) {
1436 IncludeStrongLifetimeRAII Strong(Policy);
1437 printTemplateTypeParmAfter(T->getReplacedParameter(), OS);
1438 }
1439
printTemplateId(const TemplateSpecializationType * T,raw_ostream & OS,bool FullyQualify)1440 void TypePrinter::printTemplateId(const TemplateSpecializationType *T,
1441 raw_ostream &OS, bool FullyQualify) {
1442 IncludeStrongLifetimeRAII Strong(Policy);
1443
1444 TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl();
1445 if (FullyQualify && TD) {
1446 if (!Policy.SuppressScope)
1447 AppendScope(TD->getDeclContext(), OS, TD->getDeclName());
1448
1449 IdentifierInfo *II = TD->getIdentifier();
1450 OS << II->getName();
1451 } else {
1452 T->getTemplateName().print(OS, Policy);
1453 }
1454
1455 printTemplateArgumentList(OS, T->template_arguments(), Policy);
1456 spaceBeforePlaceHolder(OS);
1457 }
1458
printTemplateSpecializationBefore(const TemplateSpecializationType * T,raw_ostream & OS)1459 void TypePrinter::printTemplateSpecializationBefore(
1460 const TemplateSpecializationType *T,
1461 raw_ostream &OS) {
1462 printTemplateId(T, OS, Policy.FullyQualifiedName);
1463 }
1464
printTemplateSpecializationAfter(const TemplateSpecializationType * T,raw_ostream & OS)1465 void TypePrinter::printTemplateSpecializationAfter(
1466 const TemplateSpecializationType *T,
1467 raw_ostream &OS) {}
1468
printInjectedClassNameBefore(const InjectedClassNameType * T,raw_ostream & OS)1469 void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
1470 raw_ostream &OS) {
1471 if (Policy.PrintInjectedClassNameWithArguments)
1472 return printTemplateSpecializationBefore(T->getInjectedTST(), OS);
1473
1474 IncludeStrongLifetimeRAII Strong(Policy);
1475 T->getTemplateName().print(OS, Policy);
1476 spaceBeforePlaceHolder(OS);
1477 }
1478
printInjectedClassNameAfter(const InjectedClassNameType * T,raw_ostream & OS)1479 void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
1480 raw_ostream &OS) {}
1481
printElaboratedBefore(const ElaboratedType * T,raw_ostream & OS)1482 void TypePrinter::printElaboratedBefore(const ElaboratedType *T,
1483 raw_ostream &OS) {
1484 if (Policy.IncludeTagDefinition && T->getOwnedTagDecl()) {
1485 TagDecl *OwnedTagDecl = T->getOwnedTagDecl();
1486 assert(OwnedTagDecl->getTypeForDecl() == T->getNamedType().getTypePtr() &&
1487 "OwnedTagDecl expected to be a declaration for the type");
1488 PrintingPolicy SubPolicy = Policy;
1489 SubPolicy.IncludeTagDefinition = false;
1490 OwnedTagDecl->print(OS, SubPolicy, Indentation);
1491 spaceBeforePlaceHolder(OS);
1492 return;
1493 }
1494
1495 // The tag definition will take care of these.
1496 if (!Policy.IncludeTagDefinition)
1497 {
1498 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1499 if (T->getKeyword() != ETK_None)
1500 OS << " ";
1501 NestedNameSpecifier *Qualifier = T->getQualifier();
1502 if (Qualifier)
1503 Qualifier->print(OS, Policy);
1504 }
1505
1506 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1507 printBefore(T->getNamedType(), OS);
1508 }
1509
printElaboratedAfter(const ElaboratedType * T,raw_ostream & OS)1510 void TypePrinter::printElaboratedAfter(const ElaboratedType *T,
1511 raw_ostream &OS) {
1512 if (Policy.IncludeTagDefinition && T->getOwnedTagDecl())
1513 return;
1514 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1515 printAfter(T->getNamedType(), OS);
1516 }
1517
printParenBefore(const ParenType * T,raw_ostream & OS)1518 void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {
1519 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1520 printBefore(T->getInnerType(), OS);
1521 OS << '(';
1522 } else
1523 printBefore(T->getInnerType(), OS);
1524 }
1525
printParenAfter(const ParenType * T,raw_ostream & OS)1526 void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {
1527 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1528 OS << ')';
1529 printAfter(T->getInnerType(), OS);
1530 } else
1531 printAfter(T->getInnerType(), OS);
1532 }
1533
printDependentNameBefore(const DependentNameType * T,raw_ostream & OS)1534 void TypePrinter::printDependentNameBefore(const DependentNameType *T,
1535 raw_ostream &OS) {
1536 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1537 if (T->getKeyword() != ETK_None)
1538 OS << " ";
1539
1540 T->getQualifier()->print(OS, Policy);
1541
1542 OS << T->getIdentifier()->getName();
1543 spaceBeforePlaceHolder(OS);
1544 }
1545
printDependentNameAfter(const DependentNameType * T,raw_ostream & OS)1546 void TypePrinter::printDependentNameAfter(const DependentNameType *T,
1547 raw_ostream &OS) {}
1548
printDependentTemplateSpecializationBefore(const DependentTemplateSpecializationType * T,raw_ostream & OS)1549 void TypePrinter::printDependentTemplateSpecializationBefore(
1550 const DependentTemplateSpecializationType *T, raw_ostream &OS) {
1551 IncludeStrongLifetimeRAII Strong(Policy);
1552
1553 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1554 if (T->getKeyword() != ETK_None)
1555 OS << " ";
1556
1557 if (T->getQualifier())
1558 T->getQualifier()->print(OS, Policy);
1559 OS << "template " << T->getIdentifier()->getName();
1560 printTemplateArgumentList(OS, T->template_arguments(), Policy);
1561 spaceBeforePlaceHolder(OS);
1562 }
1563
printDependentTemplateSpecializationAfter(const DependentTemplateSpecializationType * T,raw_ostream & OS)1564 void TypePrinter::printDependentTemplateSpecializationAfter(
1565 const DependentTemplateSpecializationType *T, raw_ostream &OS) {}
1566
printPackExpansionBefore(const PackExpansionType * T,raw_ostream & OS)1567 void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,
1568 raw_ostream &OS) {
1569 printBefore(T->getPattern(), OS);
1570 }
1571
printPackExpansionAfter(const PackExpansionType * T,raw_ostream & OS)1572 void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
1573 raw_ostream &OS) {
1574 printAfter(T->getPattern(), OS);
1575 OS << "...";
1576 }
1577
printAttributedBefore(const AttributedType * T,raw_ostream & OS)1578 void TypePrinter::printAttributedBefore(const AttributedType *T,
1579 raw_ostream &OS) {
1580 // FIXME: Generate this with TableGen.
1581
1582 // Prefer the macro forms of the GC and ownership qualifiers.
1583 if (T->getAttrKind() == attr::ObjCGC ||
1584 T->getAttrKind() == attr::ObjCOwnership)
1585 return printBefore(T->getEquivalentType(), OS);
1586
1587 if (T->getAttrKind() == attr::ObjCKindOf)
1588 OS << "__kindof ";
1589
1590 if (T->getAttrKind() == attr::AddressSpace)
1591 printBefore(T->getEquivalentType(), OS);
1592 else
1593 printBefore(T->getModifiedType(), OS);
1594
1595 if (T->isMSTypeSpec()) {
1596 switch (T->getAttrKind()) {
1597 default: return;
1598 case attr::Ptr32: OS << " __ptr32"; break;
1599 case attr::Ptr64: OS << " __ptr64"; break;
1600 case attr::SPtr: OS << " __sptr"; break;
1601 case attr::UPtr: OS << " __uptr"; break;
1602 }
1603 spaceBeforePlaceHolder(OS);
1604 }
1605
1606 // Print nullability type specifiers.
1607 if (T->getImmediateNullability()) {
1608 if (T->getAttrKind() == attr::TypeNonNull)
1609 OS << " _Nonnull";
1610 else if (T->getAttrKind() == attr::TypeNullable)
1611 OS << " _Nullable";
1612 else if (T->getAttrKind() == attr::TypeNullUnspecified)
1613 OS << " _Null_unspecified";
1614 else if (T->getAttrKind() == attr::TypeNullableResult)
1615 OS << " _Nullable_result";
1616 else
1617 llvm_unreachable("unhandled nullability");
1618 spaceBeforePlaceHolder(OS);
1619 }
1620 }
1621
printAttributedAfter(const AttributedType * T,raw_ostream & OS)1622 void TypePrinter::printAttributedAfter(const AttributedType *T,
1623 raw_ostream &OS) {
1624 // FIXME: Generate this with TableGen.
1625
1626 // Prefer the macro forms of the GC and ownership qualifiers.
1627 if (T->getAttrKind() == attr::ObjCGC ||
1628 T->getAttrKind() == attr::ObjCOwnership)
1629 return printAfter(T->getEquivalentType(), OS);
1630
1631 // If this is a calling convention attribute, don't print the implicit CC from
1632 // the modified type.
1633 SaveAndRestore<bool> MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());
1634
1635 printAfter(T->getModifiedType(), OS);
1636
1637 // Some attributes are printed as qualifiers before the type, so we have
1638 // nothing left to do.
1639 if (T->getAttrKind() == attr::ObjCKindOf ||
1640 T->isMSTypeSpec() || T->getImmediateNullability())
1641 return;
1642
1643 // Don't print the inert __unsafe_unretained attribute at all.
1644 if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained)
1645 return;
1646
1647 // Don't print ns_returns_retained unless it had an effect.
1648 if (T->getAttrKind() == attr::NSReturnsRetained &&
1649 !T->getEquivalentType()->castAs<FunctionType>()
1650 ->getExtInfo().getProducesResult())
1651 return;
1652
1653 if (T->getAttrKind() == attr::LifetimeBound) {
1654 OS << " [[clang::lifetimebound]]";
1655 return;
1656 }
1657
1658 // The printing of the address_space attribute is handled by the qualifier
1659 // since it is still stored in the qualifier. Return early to prevent printing
1660 // this twice.
1661 if (T->getAttrKind() == attr::AddressSpace)
1662 return;
1663
1664 OS << " __attribute__((";
1665 switch (T->getAttrKind()) {
1666 #define TYPE_ATTR(NAME)
1667 #define DECL_OR_TYPE_ATTR(NAME)
1668 #define ATTR(NAME) case attr::NAME:
1669 #include "clang/Basic/AttrList.inc"
1670 llvm_unreachable("non-type attribute attached to type");
1671
1672 case attr::OpenCLPrivateAddressSpace:
1673 case attr::OpenCLGlobalAddressSpace:
1674 case attr::OpenCLGlobalDeviceAddressSpace:
1675 case attr::OpenCLGlobalHostAddressSpace:
1676 case attr::OpenCLLocalAddressSpace:
1677 case attr::OpenCLConstantAddressSpace:
1678 case attr::OpenCLGenericAddressSpace:
1679 // FIXME: Update printAttributedBefore to print these once we generate
1680 // AttributedType nodes for them.
1681 break;
1682
1683 case attr::LifetimeBound:
1684 case attr::TypeNonNull:
1685 case attr::TypeNullable:
1686 case attr::TypeNullableResult:
1687 case attr::TypeNullUnspecified:
1688 case attr::ObjCGC:
1689 case attr::ObjCInertUnsafeUnretained:
1690 case attr::ObjCKindOf:
1691 case attr::ObjCOwnership:
1692 case attr::Ptr32:
1693 case attr::Ptr64:
1694 case attr::SPtr:
1695 case attr::UPtr:
1696 case attr::AddressSpace:
1697 case attr::CmseNSCall:
1698 llvm_unreachable("This attribute should have been handled already");
1699
1700 case attr::NSReturnsRetained:
1701 OS << "ns_returns_retained";
1702 break;
1703
1704 // FIXME: When Sema learns to form this AttributedType, avoid printing the
1705 // attribute again in printFunctionProtoAfter.
1706 case attr::AnyX86NoCfCheck: OS << "nocf_check"; break;
1707 case attr::CDecl: OS << "cdecl"; break;
1708 case attr::FastCall: OS << "fastcall"; break;
1709 case attr::StdCall: OS << "stdcall"; break;
1710 case attr::ThisCall: OS << "thiscall"; break;
1711 case attr::SwiftCall: OS << "swiftcall"; break;
1712 case attr::SwiftAsyncCall: OS << "swiftasynccall"; break;
1713 case attr::VectorCall: OS << "vectorcall"; break;
1714 case attr::Pascal: OS << "pascal"; break;
1715 case attr::MSABI: OS << "ms_abi"; break;
1716 case attr::SysVABI: OS << "sysv_abi"; break;
1717 case attr::RegCall: OS << "regcall"; break;
1718 case attr::Pcs: {
1719 OS << "pcs(";
1720 QualType t = T->getEquivalentType();
1721 while (!t->isFunctionType())
1722 t = t->getPointeeType();
1723 OS << (t->castAs<FunctionType>()->getCallConv() == CC_AAPCS ?
1724 "\"aapcs\"" : "\"aapcs-vfp\"");
1725 OS << ')';
1726 break;
1727 }
1728 case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break;
1729 case attr::IntelOclBicc: OS << "inteloclbicc"; break;
1730 case attr::PreserveMost:
1731 OS << "preserve_most";
1732 break;
1733
1734 case attr::PreserveAll:
1735 OS << "preserve_all";
1736 break;
1737 case attr::NoDeref:
1738 OS << "noderef";
1739 break;
1740 case attr::AcquireHandle:
1741 OS << "acquire_handle";
1742 break;
1743 case attr::ArmMveStrictPolymorphism:
1744 OS << "__clang_arm_mve_strict_polymorphism";
1745 break;
1746 }
1747 OS << "))";
1748 }
1749
printObjCInterfaceBefore(const ObjCInterfaceType * T,raw_ostream & OS)1750 void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
1751 raw_ostream &OS) {
1752 OS << T->getDecl()->getName();
1753 spaceBeforePlaceHolder(OS);
1754 }
1755
printObjCInterfaceAfter(const ObjCInterfaceType * T,raw_ostream & OS)1756 void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
1757 raw_ostream &OS) {}
1758
printObjCTypeParamBefore(const ObjCTypeParamType * T,raw_ostream & OS)1759 void TypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType *T,
1760 raw_ostream &OS) {
1761 OS << T->getDecl()->getName();
1762 if (!T->qual_empty()) {
1763 bool isFirst = true;
1764 OS << '<';
1765 for (const auto *I : T->quals()) {
1766 if (isFirst)
1767 isFirst = false;
1768 else
1769 OS << ',';
1770 OS << I->getName();
1771 }
1772 OS << '>';
1773 }
1774
1775 spaceBeforePlaceHolder(OS);
1776 }
1777
printObjCTypeParamAfter(const ObjCTypeParamType * T,raw_ostream & OS)1778 void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T,
1779 raw_ostream &OS) {}
1780
printObjCObjectBefore(const ObjCObjectType * T,raw_ostream & OS)1781 void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
1782 raw_ostream &OS) {
1783 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
1784 !T->isKindOfTypeAsWritten())
1785 return printBefore(T->getBaseType(), OS);
1786
1787 if (T->isKindOfTypeAsWritten())
1788 OS << "__kindof ";
1789
1790 print(T->getBaseType(), OS, StringRef());
1791
1792 if (T->isSpecializedAsWritten()) {
1793 bool isFirst = true;
1794 OS << '<';
1795 for (auto typeArg : T->getTypeArgsAsWritten()) {
1796 if (isFirst)
1797 isFirst = false;
1798 else
1799 OS << ",";
1800
1801 print(typeArg, OS, StringRef());
1802 }
1803 OS << '>';
1804 }
1805
1806 if (!T->qual_empty()) {
1807 bool isFirst = true;
1808 OS << '<';
1809 for (const auto *I : T->quals()) {
1810 if (isFirst)
1811 isFirst = false;
1812 else
1813 OS << ',';
1814 OS << I->getName();
1815 }
1816 OS << '>';
1817 }
1818
1819 spaceBeforePlaceHolder(OS);
1820 }
1821
printObjCObjectAfter(const ObjCObjectType * T,raw_ostream & OS)1822 void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
1823 raw_ostream &OS) {
1824 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
1825 !T->isKindOfTypeAsWritten())
1826 return printAfter(T->getBaseType(), OS);
1827 }
1828
printObjCObjectPointerBefore(const ObjCObjectPointerType * T,raw_ostream & OS)1829 void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
1830 raw_ostream &OS) {
1831 printBefore(T->getPointeeType(), OS);
1832
1833 // If we need to print the pointer, print it now.
1834 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&
1835 !T->isObjCClassType() && !T->isObjCQualifiedClassType()) {
1836 if (HasEmptyPlaceHolder)
1837 OS << ' ';
1838 OS << '*';
1839 }
1840 }
1841
printObjCObjectPointerAfter(const ObjCObjectPointerType * T,raw_ostream & OS)1842 void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
1843 raw_ostream &OS) {}
1844
1845 static
getArgument(const TemplateArgument & A)1846 const TemplateArgument &getArgument(const TemplateArgument &A) { return A; }
1847
getArgument(const TemplateArgumentLoc & A)1848 static const TemplateArgument &getArgument(const TemplateArgumentLoc &A) {
1849 return A.getArgument();
1850 }
1851
printArgument(const TemplateArgument & A,const PrintingPolicy & PP,llvm::raw_ostream & OS,bool IncludeType)1852 static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP,
1853 llvm::raw_ostream &OS, bool IncludeType) {
1854 A.print(PP, OS, IncludeType);
1855 }
1856
printArgument(const TemplateArgumentLoc & A,const PrintingPolicy & PP,llvm::raw_ostream & OS,bool IncludeType)1857 static void printArgument(const TemplateArgumentLoc &A,
1858 const PrintingPolicy &PP, llvm::raw_ostream &OS,
1859 bool IncludeType) {
1860 const TemplateArgument::ArgKind &Kind = A.getArgument().getKind();
1861 if (Kind == TemplateArgument::ArgKind::Type)
1862 return A.getTypeSourceInfo()->getType().print(OS, PP);
1863 return A.getArgument().print(PP, OS, IncludeType);
1864 }
1865
1866 static bool isSubstitutedTemplateArgument(ASTContext &Ctx, TemplateArgument Arg,
1867 TemplateArgument Pattern,
1868 ArrayRef<TemplateArgument> Args,
1869 unsigned Depth);
1870
isSubstitutedType(ASTContext & Ctx,QualType T,QualType Pattern,ArrayRef<TemplateArgument> Args,unsigned Depth)1871 static bool isSubstitutedType(ASTContext &Ctx, QualType T, QualType Pattern,
1872 ArrayRef<TemplateArgument> Args, unsigned Depth) {
1873 if (Ctx.hasSameType(T, Pattern))
1874 return true;
1875
1876 // A type parameter matches its argument.
1877 if (auto *TTPT = Pattern->getAs<TemplateTypeParmType>()) {
1878 if (TTPT->getDepth() == Depth && TTPT->getIndex() < Args.size() &&
1879 Args[TTPT->getIndex()].getKind() == TemplateArgument::Type) {
1880 QualType SubstArg = Ctx.getQualifiedType(
1881 Args[TTPT->getIndex()].getAsType(), Pattern.getQualifiers());
1882 return Ctx.hasSameType(SubstArg, T);
1883 }
1884 return false;
1885 }
1886
1887 // FIXME: Recurse into array types.
1888
1889 // All other cases will need the types to be identically qualified.
1890 Qualifiers TQual, PatQual;
1891 T = Ctx.getUnqualifiedArrayType(T, TQual);
1892 Pattern = Ctx.getUnqualifiedArrayType(Pattern, PatQual);
1893 if (TQual != PatQual)
1894 return false;
1895
1896 // Recurse into pointer-like types.
1897 {
1898 QualType TPointee = T->getPointeeType();
1899 QualType PPointee = Pattern->getPointeeType();
1900 if (!TPointee.isNull() && !PPointee.isNull())
1901 return T->getTypeClass() == Pattern->getTypeClass() &&
1902 isSubstitutedType(Ctx, TPointee, PPointee, Args, Depth);
1903 }
1904
1905 // Recurse into template specialization types.
1906 if (auto *PTST =
1907 Pattern.getCanonicalType()->getAs<TemplateSpecializationType>()) {
1908 TemplateName Template;
1909 ArrayRef<TemplateArgument> TemplateArgs;
1910 if (auto *TTST = T->getAs<TemplateSpecializationType>()) {
1911 Template = TTST->getTemplateName();
1912 TemplateArgs = TTST->template_arguments();
1913 } else if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
1914 T->getAsCXXRecordDecl())) {
1915 Template = TemplateName(CTSD->getSpecializedTemplate());
1916 TemplateArgs = CTSD->getTemplateArgs().asArray();
1917 } else {
1918 return false;
1919 }
1920
1921 if (!isSubstitutedTemplateArgument(Ctx, Template, PTST->getTemplateName(),
1922 Args, Depth))
1923 return false;
1924 if (TemplateArgs.size() != PTST->getNumArgs())
1925 return false;
1926 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
1927 if (!isSubstitutedTemplateArgument(Ctx, TemplateArgs[I], PTST->getArg(I),
1928 Args, Depth))
1929 return false;
1930 return true;
1931 }
1932
1933 // FIXME: Handle more cases.
1934 return false;
1935 }
1936
isSubstitutedTemplateArgument(ASTContext & Ctx,TemplateArgument Arg,TemplateArgument Pattern,ArrayRef<TemplateArgument> Args,unsigned Depth)1937 static bool isSubstitutedTemplateArgument(ASTContext &Ctx, TemplateArgument Arg,
1938 TemplateArgument Pattern,
1939 ArrayRef<TemplateArgument> Args,
1940 unsigned Depth) {
1941 Arg = Ctx.getCanonicalTemplateArgument(Arg);
1942 Pattern = Ctx.getCanonicalTemplateArgument(Pattern);
1943 if (Arg.structurallyEquals(Pattern))
1944 return true;
1945
1946 if (Pattern.getKind() == TemplateArgument::Expression) {
1947 if (auto *DRE =
1948 dyn_cast<DeclRefExpr>(Pattern.getAsExpr()->IgnoreParenImpCasts())) {
1949 if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
1950 return NTTP->getDepth() == Depth && Args.size() > NTTP->getIndex() &&
1951 Args[NTTP->getIndex()].structurallyEquals(Arg);
1952 }
1953 }
1954
1955 if (Arg.getKind() != Pattern.getKind())
1956 return false;
1957
1958 if (Arg.getKind() == TemplateArgument::Type)
1959 return isSubstitutedType(Ctx, Arg.getAsType(), Pattern.getAsType(), Args,
1960 Depth);
1961
1962 if (Arg.getKind() == TemplateArgument::Template) {
1963 TemplateDecl *PatTD = Pattern.getAsTemplate().getAsTemplateDecl();
1964 if (auto *TTPD = dyn_cast_or_null<TemplateTemplateParmDecl>(PatTD))
1965 return TTPD->getDepth() == Depth && Args.size() > TTPD->getIndex() &&
1966 Ctx.getCanonicalTemplateArgument(Args[TTPD->getIndex()])
1967 .structurallyEquals(Arg);
1968 }
1969
1970 // FIXME: Handle more cases.
1971 return false;
1972 }
1973
1974 /// Make a best-effort determination of whether the type T can be produced by
1975 /// substituting Args into the default argument of Param.
isSubstitutedDefaultArgument(ASTContext & Ctx,TemplateArgument Arg,const NamedDecl * Param,ArrayRef<TemplateArgument> Args,unsigned Depth)1976 static bool isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg,
1977 const NamedDecl *Param,
1978 ArrayRef<TemplateArgument> Args,
1979 unsigned Depth) {
1980 // An empty pack is equivalent to not providing a pack argument.
1981 if (Arg.getKind() == TemplateArgument::Pack && Arg.pack_size() == 0)
1982 return true;
1983
1984 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Param)) {
1985 return TTPD->hasDefaultArgument() &&
1986 isSubstitutedTemplateArgument(Ctx, Arg, TTPD->getDefaultArgument(),
1987 Args, Depth);
1988 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
1989 return TTPD->hasDefaultArgument() &&
1990 isSubstitutedTemplateArgument(
1991 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
1992 } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
1993 return NTTPD->hasDefaultArgument() &&
1994 isSubstitutedTemplateArgument(Ctx, Arg, NTTPD->getDefaultArgument(),
1995 Args, Depth);
1996 }
1997 return false;
1998 }
1999
2000 template <typename TA>
printTo(raw_ostream & OS,ArrayRef<TA> Args,const PrintingPolicy & Policy,bool SkipBrackets,const TemplateParameterList * TPL,bool IsPack,unsigned ParmIndex)2001 static void printTo(raw_ostream &OS, ArrayRef<TA> Args,
2002 const PrintingPolicy &Policy, bool SkipBrackets,
2003 const TemplateParameterList *TPL, bool IsPack,
2004 unsigned ParmIndex) {
2005 // Drop trailing template arguments that match default arguments.
2006 if (TPL && Policy.SuppressDefaultTemplateArgs &&
2007 !Policy.PrintCanonicalTypes && !Args.empty() && !IsPack &&
2008 Args.size() <= TPL->size()) {
2009 ASTContext &Ctx = TPL->getParam(0)->getASTContext();
2010 llvm::SmallVector<TemplateArgument, 8> OrigArgs;
2011 for (const TA &A : Args)
2012 OrigArgs.push_back(getArgument(A));
2013 while (!Args.empty() &&
2014 isSubstitutedDefaultArgument(Ctx, getArgument(Args.back()),
2015 TPL->getParam(Args.size() - 1),
2016 OrigArgs, TPL->getDepth()))
2017 Args = Args.drop_back();
2018 }
2019
2020 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
2021 if (!SkipBrackets)
2022 OS << '<';
2023
2024 bool NeedSpace = false;
2025 bool FirstArg = true;
2026 for (const auto &Arg : Args) {
2027 // Print the argument into a string.
2028 SmallString<128> Buf;
2029 llvm::raw_svector_ostream ArgOS(Buf);
2030 const TemplateArgument &Argument = getArgument(Arg);
2031 if (Argument.getKind() == TemplateArgument::Pack) {
2032 if (Argument.pack_size() && !FirstArg)
2033 OS << Comma;
2034 printTo(ArgOS, Argument.getPackAsArray(), Policy, true, TPL,
2035 /*IsPack*/ true, ParmIndex);
2036 } else {
2037 if (!FirstArg)
2038 OS << Comma;
2039 // Tries to print the argument with location info if exists.
2040 printArgument(
2041 Arg, Policy, ArgOS,
2042 TemplateParameterList::shouldIncludeTypeForArgument(TPL, ParmIndex));
2043 }
2044 StringRef ArgString = ArgOS.str();
2045
2046 // If this is the first argument and its string representation
2047 // begins with the global scope specifier ('::foo'), add a space
2048 // to avoid printing the diagraph '<:'.
2049 if (FirstArg && !ArgString.empty() && ArgString[0] == ':')
2050 OS << ' ';
2051
2052 OS << ArgString;
2053
2054 // If the last character of our string is '>', add another space to
2055 // keep the two '>''s separate tokens.
2056 NeedSpace = Policy.SplitTemplateClosers && !ArgString.empty() &&
2057 ArgString.back() == '>';
2058 FirstArg = false;
2059
2060 // Use same template parameter for all elements of Pack
2061 if (!IsPack)
2062 ParmIndex++;
2063 }
2064
2065 if (NeedSpace)
2066 OS << ' ';
2067
2068 if (!SkipBrackets)
2069 OS << '>';
2070 }
2071
printTemplateArgumentList(raw_ostream & OS,const TemplateArgumentListInfo & Args,const PrintingPolicy & Policy,const TemplateParameterList * TPL)2072 void clang::printTemplateArgumentList(raw_ostream &OS,
2073 const TemplateArgumentListInfo &Args,
2074 const PrintingPolicy &Policy,
2075 const TemplateParameterList *TPL) {
2076 printTemplateArgumentList(OS, Args.arguments(), Policy, TPL);
2077 }
2078
printTemplateArgumentList(raw_ostream & OS,ArrayRef<TemplateArgument> Args,const PrintingPolicy & Policy,const TemplateParameterList * TPL)2079 void clang::printTemplateArgumentList(raw_ostream &OS,
2080 ArrayRef<TemplateArgument> Args,
2081 const PrintingPolicy &Policy,
2082 const TemplateParameterList *TPL) {
2083 printTo(OS, Args, Policy, false, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2084 }
2085
printTemplateArgumentList(raw_ostream & OS,ArrayRef<TemplateArgumentLoc> Args,const PrintingPolicy & Policy,const TemplateParameterList * TPL)2086 void clang::printTemplateArgumentList(raw_ostream &OS,
2087 ArrayRef<TemplateArgumentLoc> Args,
2088 const PrintingPolicy &Policy,
2089 const TemplateParameterList *TPL) {
2090 printTo(OS, Args, Policy, false, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2091 }
2092
getAsString() const2093 std::string Qualifiers::getAsString() const {
2094 LangOptions LO;
2095 return getAsString(PrintingPolicy(LO));
2096 }
2097
2098 // Appends qualifiers to the given string, separated by spaces. Will
2099 // prefix a space if the string is non-empty. Will not append a final
2100 // space.
getAsString(const PrintingPolicy & Policy) const2101 std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {
2102 SmallString<64> Buf;
2103 llvm::raw_svector_ostream StrOS(Buf);
2104 print(StrOS, Policy);
2105 return std::string(StrOS.str());
2106 }
2107
isEmptyWhenPrinted(const PrintingPolicy & Policy) const2108 bool Qualifiers::isEmptyWhenPrinted(const PrintingPolicy &Policy) const {
2109 if (getCVRQualifiers())
2110 return false;
2111
2112 if (getAddressSpace() != LangAS::Default)
2113 return false;
2114
2115 if (getObjCGCAttr())
2116 return false;
2117
2118 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime())
2119 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
2120 return false;
2121
2122 return true;
2123 }
2124
getAddrSpaceAsString(LangAS AS)2125 std::string Qualifiers::getAddrSpaceAsString(LangAS AS) {
2126 switch (AS) {
2127 case LangAS::Default:
2128 return "";
2129 case LangAS::opencl_global:
2130 case LangAS::sycl_global:
2131 return "__global";
2132 case LangAS::opencl_local:
2133 case LangAS::sycl_local:
2134 return "__local";
2135 case LangAS::opencl_private:
2136 case LangAS::sycl_private:
2137 return "__private";
2138 case LangAS::opencl_constant:
2139 return "__constant";
2140 case LangAS::opencl_generic:
2141 return "__generic";
2142 case LangAS::opencl_global_device:
2143 case LangAS::sycl_global_device:
2144 return "__global_device";
2145 case LangAS::opencl_global_host:
2146 case LangAS::sycl_global_host:
2147 return "__global_host";
2148 case LangAS::cuda_device:
2149 return "__device__";
2150 case LangAS::cuda_constant:
2151 return "__constant__";
2152 case LangAS::cuda_shared:
2153 return "__shared__";
2154 case LangAS::ptr32_sptr:
2155 return "__sptr __ptr32";
2156 case LangAS::ptr32_uptr:
2157 return "__uptr __ptr32";
2158 case LangAS::ptr64:
2159 return "__ptr64";
2160 default:
2161 return std::to_string(toTargetAddressSpace(AS));
2162 }
2163 }
2164
2165 // Appends qualifiers to the given string, separated by spaces. Will
2166 // prefix a space if the string is non-empty. Will not append a final
2167 // space.
print(raw_ostream & OS,const PrintingPolicy & Policy,bool appendSpaceIfNonEmpty) const2168 void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
2169 bool appendSpaceIfNonEmpty) const {
2170 bool addSpace = false;
2171
2172 unsigned quals = getCVRQualifiers();
2173 if (quals) {
2174 AppendTypeQualList(OS, quals, Policy.Restrict);
2175 addSpace = true;
2176 }
2177 if (hasUnaligned()) {
2178 if (addSpace)
2179 OS << ' ';
2180 OS << "__unaligned";
2181 addSpace = true;
2182 }
2183 auto ASStr = getAddrSpaceAsString(getAddressSpace());
2184 if (!ASStr.empty()) {
2185 if (addSpace)
2186 OS << ' ';
2187 addSpace = true;
2188 // Wrap target address space into an attribute syntax
2189 if (isTargetAddressSpace(getAddressSpace()))
2190 OS << "__attribute__((address_space(" << ASStr << ")))";
2191 else
2192 OS << ASStr;
2193 }
2194
2195 if (Qualifiers::GC gc = getObjCGCAttr()) {
2196 if (addSpace)
2197 OS << ' ';
2198 addSpace = true;
2199 if (gc == Qualifiers::Weak)
2200 OS << "__weak";
2201 else
2202 OS << "__strong";
2203 }
2204 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
2205 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
2206 if (addSpace)
2207 OS << ' ';
2208 addSpace = true;
2209 }
2210
2211 switch (lifetime) {
2212 case Qualifiers::OCL_None: llvm_unreachable("none but true");
2213 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;
2214 case Qualifiers::OCL_Strong:
2215 if (!Policy.SuppressStrongLifetime)
2216 OS << "__strong";
2217 break;
2218
2219 case Qualifiers::OCL_Weak: OS << "__weak"; break;
2220 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
2221 }
2222 }
2223
2224 if (appendSpaceIfNonEmpty && addSpace)
2225 OS << ' ';
2226 }
2227
getAsString() const2228 std::string QualType::getAsString() const {
2229 return getAsString(split(), LangOptions());
2230 }
2231
getAsString(const PrintingPolicy & Policy) const2232 std::string QualType::getAsString(const PrintingPolicy &Policy) const {
2233 std::string S;
2234 getAsStringInternal(S, Policy);
2235 return S;
2236 }
2237
getAsString(const Type * ty,Qualifiers qs,const PrintingPolicy & Policy)2238 std::string QualType::getAsString(const Type *ty, Qualifiers qs,
2239 const PrintingPolicy &Policy) {
2240 std::string buffer;
2241 getAsStringInternal(ty, qs, buffer, Policy);
2242 return buffer;
2243 }
2244
print(raw_ostream & OS,const PrintingPolicy & Policy,const Twine & PlaceHolder,unsigned Indentation) const2245 void QualType::print(raw_ostream &OS, const PrintingPolicy &Policy,
2246 const Twine &PlaceHolder, unsigned Indentation) const {
2247 print(splitAccordingToPolicy(*this, Policy), OS, Policy, PlaceHolder,
2248 Indentation);
2249 }
2250
print(const Type * ty,Qualifiers qs,raw_ostream & OS,const PrintingPolicy & policy,const Twine & PlaceHolder,unsigned Indentation)2251 void QualType::print(const Type *ty, Qualifiers qs,
2252 raw_ostream &OS, const PrintingPolicy &policy,
2253 const Twine &PlaceHolder, unsigned Indentation) {
2254 SmallString<128> PHBuf;
2255 StringRef PH = PlaceHolder.toStringRef(PHBuf);
2256
2257 TypePrinter(policy, Indentation).print(ty, qs, OS, PH);
2258 }
2259
getAsStringInternal(std::string & Str,const PrintingPolicy & Policy) const2260 void QualType::getAsStringInternal(std::string &Str,
2261 const PrintingPolicy &Policy) const {
2262 return getAsStringInternal(splitAccordingToPolicy(*this, Policy), Str,
2263 Policy);
2264 }
2265
getAsStringInternal(const Type * ty,Qualifiers qs,std::string & buffer,const PrintingPolicy & policy)2266 void QualType::getAsStringInternal(const Type *ty, Qualifiers qs,
2267 std::string &buffer,
2268 const PrintingPolicy &policy) {
2269 SmallString<256> Buf;
2270 llvm::raw_svector_ostream StrOS(Buf);
2271 TypePrinter(policy).print(ty, qs, StrOS, buffer);
2272 std::string str = std::string(StrOS.str());
2273 buffer.swap(str);
2274 }
2275