1 //===--- TypePrinter.cpp - Pretty-Print Clang Types -----------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This contains code to print types from Clang's type system.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "clang/AST/PrettyPrinter.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/Decl.h"
17 #include "clang/AST/DeclObjC.h"
18 #include "clang/AST/DeclTemplate.h"
19 #include "clang/AST/Expr.h"
20 #include "clang/AST/Type.h"
21 #include "clang/Basic/LangOptions.h"
22 #include "clang/Basic/SourceManager.h"
23 #include "llvm/ADT/SmallString.h"
24 #include "llvm/ADT/StringExtras.h"
25 #include "llvm/Support/SaveAndRestore.h"
26 #include "llvm/Support/raw_ostream.h"
27 using namespace clang;
28
29 namespace {
30 /// \brief RAII object that enables printing of the ARC __strong lifetime
31 /// qualifier.
32 class IncludeStrongLifetimeRAII {
33 PrintingPolicy &Policy;
34 bool Old;
35
36 public:
IncludeStrongLifetimeRAII(PrintingPolicy & Policy)37 explicit IncludeStrongLifetimeRAII(PrintingPolicy &Policy)
38 : Policy(Policy), Old(Policy.SuppressStrongLifetime) {
39 if (!Policy.SuppressLifetimeQualifiers)
40 Policy.SuppressStrongLifetime = false;
41 }
42
~IncludeStrongLifetimeRAII()43 ~IncludeStrongLifetimeRAII() {
44 Policy.SuppressStrongLifetime = Old;
45 }
46 };
47
48 class ParamPolicyRAII {
49 PrintingPolicy &Policy;
50 bool Old;
51
52 public:
ParamPolicyRAII(PrintingPolicy & Policy)53 explicit ParamPolicyRAII(PrintingPolicy &Policy)
54 : Policy(Policy), Old(Policy.SuppressSpecifiers) {
55 Policy.SuppressSpecifiers = false;
56 }
57
~ParamPolicyRAII()58 ~ParamPolicyRAII() {
59 Policy.SuppressSpecifiers = Old;
60 }
61 };
62
63 class ElaboratedTypePolicyRAII {
64 PrintingPolicy &Policy;
65 bool SuppressTagKeyword;
66 bool SuppressScope;
67
68 public:
ElaboratedTypePolicyRAII(PrintingPolicy & Policy)69 explicit ElaboratedTypePolicyRAII(PrintingPolicy &Policy) : Policy(Policy) {
70 SuppressTagKeyword = Policy.SuppressTagKeyword;
71 SuppressScope = Policy.SuppressScope;
72 Policy.SuppressTagKeyword = true;
73 Policy.SuppressScope = true;
74 }
75
~ElaboratedTypePolicyRAII()76 ~ElaboratedTypePolicyRAII() {
77 Policy.SuppressTagKeyword = SuppressTagKeyword;
78 Policy.SuppressScope = SuppressScope;
79 }
80 };
81
82 class TypePrinter {
83 PrintingPolicy Policy;
84 unsigned Indentation;
85 bool HasEmptyPlaceHolder;
86 bool InsideCCAttribute;
87
88 public:
TypePrinter(const PrintingPolicy & Policy,unsigned Indentation=0)89 explicit TypePrinter(const PrintingPolicy &Policy, unsigned Indentation = 0)
90 : Policy(Policy), Indentation(Indentation),
91 HasEmptyPlaceHolder(false), InsideCCAttribute(false) { }
92
93 void print(const Type *ty, Qualifiers qs, raw_ostream &OS,
94 StringRef PlaceHolder);
95 void print(QualType T, raw_ostream &OS, StringRef PlaceHolder);
96
97 static bool canPrefixQualifiers(const Type *T, bool &NeedARCStrongQualifier);
98 void spaceBeforePlaceHolder(raw_ostream &OS);
99 void printTypeSpec(const NamedDecl *D, raw_ostream &OS);
100
101 void printBefore(const Type *ty, Qualifiers qs, raw_ostream &OS);
102 void printBefore(QualType T, raw_ostream &OS);
103 void printAfter(const Type *ty, Qualifiers qs, raw_ostream &OS);
104 void printAfter(QualType T, raw_ostream &OS);
105 void AppendScope(DeclContext *DC, raw_ostream &OS);
106 void printTag(TagDecl *T, raw_ostream &OS);
107 #define ABSTRACT_TYPE(CLASS, PARENT)
108 #define TYPE(CLASS, PARENT) \
109 void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS); \
110 void print##CLASS##After(const CLASS##Type *T, raw_ostream &OS);
111 #include "clang/AST/TypeNodes.def"
112 };
113 }
114
AppendTypeQualList(raw_ostream & OS,unsigned TypeQuals,bool HasRestrictKeyword)115 static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals,
116 bool HasRestrictKeyword) {
117 bool appendSpace = false;
118 if (TypeQuals & Qualifiers::Const) {
119 OS << "const";
120 appendSpace = true;
121 }
122 if (TypeQuals & Qualifiers::Volatile) {
123 if (appendSpace) OS << ' ';
124 OS << "volatile";
125 appendSpace = true;
126 }
127 if (TypeQuals & Qualifiers::Restrict) {
128 if (appendSpace) OS << ' ';
129 if (HasRestrictKeyword) {
130 OS << "restrict";
131 } else {
132 OS << "__restrict";
133 }
134 }
135 }
136
spaceBeforePlaceHolder(raw_ostream & OS)137 void TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) {
138 if (!HasEmptyPlaceHolder)
139 OS << ' ';
140 }
141
print(QualType t,raw_ostream & OS,StringRef PlaceHolder)142 void TypePrinter::print(QualType t, raw_ostream &OS, StringRef PlaceHolder) {
143 SplitQualType split = t.split();
144 print(split.Ty, split.Quals, OS, PlaceHolder);
145 }
146
print(const Type * T,Qualifiers Quals,raw_ostream & OS,StringRef PlaceHolder)147 void TypePrinter::print(const Type *T, Qualifiers Quals, raw_ostream &OS,
148 StringRef PlaceHolder) {
149 if (!T) {
150 OS << "NULL TYPE";
151 return;
152 }
153
154 SaveAndRestore<bool> PHVal(HasEmptyPlaceHolder, PlaceHolder.empty());
155
156 printBefore(T, Quals, OS);
157 OS << PlaceHolder;
158 printAfter(T, Quals, OS);
159 }
160
canPrefixQualifiers(const Type * T,bool & NeedARCStrongQualifier)161 bool TypePrinter::canPrefixQualifiers(const Type *T,
162 bool &NeedARCStrongQualifier) {
163 // CanPrefixQualifiers - We prefer to print type qualifiers before the type,
164 // so that we get "const int" instead of "int const", but we can't do this if
165 // the type is complex. For example if the type is "int*", we *must* print
166 // "int * const", printing "const int *" is different. Only do this when the
167 // type expands to a simple string.
168 bool CanPrefixQualifiers = false;
169 NeedARCStrongQualifier = false;
170 Type::TypeClass TC = T->getTypeClass();
171 if (const AutoType *AT = dyn_cast<AutoType>(T))
172 TC = AT->desugar()->getTypeClass();
173 if (const SubstTemplateTypeParmType *Subst
174 = dyn_cast<SubstTemplateTypeParmType>(T))
175 TC = Subst->getReplacementType()->getTypeClass();
176
177 switch (TC) {
178 case Type::Auto:
179 case Type::Builtin:
180 case Type::Complex:
181 case Type::UnresolvedUsing:
182 case Type::Typedef:
183 case Type::TypeOfExpr:
184 case Type::TypeOf:
185 case Type::Decltype:
186 case Type::UnaryTransform:
187 case Type::Record:
188 case Type::Enum:
189 case Type::Elaborated:
190 case Type::TemplateTypeParm:
191 case Type::SubstTemplateTypeParmPack:
192 case Type::TemplateSpecialization:
193 case Type::InjectedClassName:
194 case Type::DependentName:
195 case Type::DependentTemplateSpecialization:
196 case Type::ObjCObject:
197 case Type::ObjCInterface:
198 case Type::Atomic:
199 case Type::Pipe:
200 CanPrefixQualifiers = true;
201 break;
202
203 case Type::ObjCObjectPointer:
204 CanPrefixQualifiers = T->isObjCIdType() || T->isObjCClassType() ||
205 T->isObjCQualifiedIdType() || T->isObjCQualifiedClassType();
206 break;
207
208 case Type::ConstantArray:
209 case Type::IncompleteArray:
210 case Type::VariableArray:
211 case Type::DependentSizedArray:
212 NeedARCStrongQualifier = true;
213 // Fall through
214
215 case Type::Adjusted:
216 case Type::Decayed:
217 case Type::Pointer:
218 case Type::BlockPointer:
219 case Type::LValueReference:
220 case Type::RValueReference:
221 case Type::MemberPointer:
222 case Type::DependentSizedExtVector:
223 case Type::Vector:
224 case Type::ExtVector:
225 case Type::FunctionProto:
226 case Type::FunctionNoProto:
227 case Type::Paren:
228 case Type::Attributed:
229 case Type::PackExpansion:
230 case Type::SubstTemplateTypeParm:
231 CanPrefixQualifiers = false;
232 break;
233 }
234
235 return CanPrefixQualifiers;
236 }
237
printBefore(QualType T,raw_ostream & OS)238 void TypePrinter::printBefore(QualType T, raw_ostream &OS) {
239 SplitQualType Split = T.split();
240
241 // If we have cv1 T, where T is substituted for cv2 U, only print cv1 - cv2
242 // at this level.
243 Qualifiers Quals = Split.Quals;
244 if (const SubstTemplateTypeParmType *Subst =
245 dyn_cast<SubstTemplateTypeParmType>(Split.Ty))
246 Quals -= QualType(Subst, 0).getQualifiers();
247
248 printBefore(Split.Ty, Quals, OS);
249 }
250
251 /// \brief Prints the part of the type string before an identifier, e.g. for
252 /// "int foo[10]" it prints "int ".
printBefore(const Type * T,Qualifiers Quals,raw_ostream & OS)253 void TypePrinter::printBefore(const Type *T,Qualifiers Quals, raw_ostream &OS) {
254 if (Policy.SuppressSpecifiers && T->isSpecifierType())
255 return;
256
257 SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder);
258
259 // Print qualifiers as appropriate.
260
261 bool CanPrefixQualifiers = false;
262 bool NeedARCStrongQualifier = false;
263 CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier);
264
265 if (CanPrefixQualifiers && !Quals.empty()) {
266 if (NeedARCStrongQualifier) {
267 IncludeStrongLifetimeRAII Strong(Policy);
268 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
269 } else {
270 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
271 }
272 }
273
274 bool hasAfterQuals = false;
275 if (!CanPrefixQualifiers && !Quals.empty()) {
276 hasAfterQuals = !Quals.isEmptyWhenPrinted(Policy);
277 if (hasAfterQuals)
278 HasEmptyPlaceHolder = false;
279 }
280
281 switch (T->getTypeClass()) {
282 #define ABSTRACT_TYPE(CLASS, PARENT)
283 #define TYPE(CLASS, PARENT) case Type::CLASS: \
284 print##CLASS##Before(cast<CLASS##Type>(T), OS); \
285 break;
286 #include "clang/AST/TypeNodes.def"
287 }
288
289 if (hasAfterQuals) {
290 if (NeedARCStrongQualifier) {
291 IncludeStrongLifetimeRAII Strong(Policy);
292 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
293 } else {
294 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
295 }
296 }
297 }
298
printAfter(QualType t,raw_ostream & OS)299 void TypePrinter::printAfter(QualType t, raw_ostream &OS) {
300 SplitQualType split = t.split();
301 printAfter(split.Ty, split.Quals, OS);
302 }
303
304 /// \brief Prints the part of the type string after an identifier, e.g. for
305 /// "int foo[10]" it prints "[10]".
printAfter(const Type * T,Qualifiers Quals,raw_ostream & OS)306 void TypePrinter::printAfter(const Type *T, Qualifiers Quals, raw_ostream &OS) {
307 switch (T->getTypeClass()) {
308 #define ABSTRACT_TYPE(CLASS, PARENT)
309 #define TYPE(CLASS, PARENT) case Type::CLASS: \
310 print##CLASS##After(cast<CLASS##Type>(T), OS); \
311 break;
312 #include "clang/AST/TypeNodes.def"
313 }
314 }
315
printBuiltinBefore(const BuiltinType * T,raw_ostream & OS)316 void TypePrinter::printBuiltinBefore(const BuiltinType *T, raw_ostream &OS) {
317 OS << T->getName(Policy);
318 spaceBeforePlaceHolder(OS);
319 }
printBuiltinAfter(const BuiltinType * T,raw_ostream & OS)320 void TypePrinter::printBuiltinAfter(const BuiltinType *T, raw_ostream &OS) { }
321
printComplexBefore(const ComplexType * T,raw_ostream & OS)322 void TypePrinter::printComplexBefore(const ComplexType *T, raw_ostream &OS) {
323 OS << "_Complex ";
324 printBefore(T->getElementType(), OS);
325 }
printComplexAfter(const ComplexType * T,raw_ostream & OS)326 void TypePrinter::printComplexAfter(const ComplexType *T, raw_ostream &OS) {
327 printAfter(T->getElementType(), OS);
328 }
329
printPointerBefore(const PointerType * T,raw_ostream & OS)330 void TypePrinter::printPointerBefore(const PointerType *T, raw_ostream &OS) {
331 IncludeStrongLifetimeRAII Strong(Policy);
332 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
333 printBefore(T->getPointeeType(), OS);
334 // Handle things like 'int (*A)[4];' correctly.
335 // FIXME: this should include vectors, but vectors use attributes I guess.
336 if (isa<ArrayType>(T->getPointeeType()))
337 OS << '(';
338 OS << '*';
339 }
printPointerAfter(const PointerType * T,raw_ostream & OS)340 void TypePrinter::printPointerAfter(const PointerType *T, raw_ostream &OS) {
341 IncludeStrongLifetimeRAII Strong(Policy);
342 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
343 // Handle things like 'int (*A)[4];' correctly.
344 // FIXME: this should include vectors, but vectors use attributes I guess.
345 if (isa<ArrayType>(T->getPointeeType()))
346 OS << ')';
347 printAfter(T->getPointeeType(), OS);
348 }
349
printBlockPointerBefore(const BlockPointerType * T,raw_ostream & OS)350 void TypePrinter::printBlockPointerBefore(const BlockPointerType *T,
351 raw_ostream &OS) {
352 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
353 printBefore(T->getPointeeType(), OS);
354 OS << '^';
355 }
printBlockPointerAfter(const BlockPointerType * T,raw_ostream & OS)356 void TypePrinter::printBlockPointerAfter(const BlockPointerType *T,
357 raw_ostream &OS) {
358 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
359 printAfter(T->getPointeeType(), OS);
360 }
361
printLValueReferenceBefore(const LValueReferenceType * T,raw_ostream & OS)362 void TypePrinter::printLValueReferenceBefore(const LValueReferenceType *T,
363 raw_ostream &OS) {
364 IncludeStrongLifetimeRAII Strong(Policy);
365 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
366 printBefore(T->getPointeeTypeAsWritten(), OS);
367 // Handle things like 'int (&A)[4];' correctly.
368 // FIXME: this should include vectors, but vectors use attributes I guess.
369 if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
370 OS << '(';
371 OS << '&';
372 }
printLValueReferenceAfter(const LValueReferenceType * T,raw_ostream & OS)373 void TypePrinter::printLValueReferenceAfter(const LValueReferenceType *T,
374 raw_ostream &OS) {
375 IncludeStrongLifetimeRAII Strong(Policy);
376 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
377 // Handle things like 'int (&A)[4];' correctly.
378 // FIXME: this should include vectors, but vectors use attributes I guess.
379 if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
380 OS << ')';
381 printAfter(T->getPointeeTypeAsWritten(), OS);
382 }
383
printRValueReferenceBefore(const RValueReferenceType * T,raw_ostream & OS)384 void TypePrinter::printRValueReferenceBefore(const RValueReferenceType *T,
385 raw_ostream &OS) {
386 IncludeStrongLifetimeRAII Strong(Policy);
387 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
388 printBefore(T->getPointeeTypeAsWritten(), OS);
389 // Handle things like 'int (&&A)[4];' correctly.
390 // FIXME: this should include vectors, but vectors use attributes I guess.
391 if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
392 OS << '(';
393 OS << "&&";
394 }
printRValueReferenceAfter(const RValueReferenceType * T,raw_ostream & OS)395 void TypePrinter::printRValueReferenceAfter(const RValueReferenceType *T,
396 raw_ostream &OS) {
397 IncludeStrongLifetimeRAII Strong(Policy);
398 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
399 // Handle things like 'int (&&A)[4];' correctly.
400 // FIXME: this should include vectors, but vectors use attributes I guess.
401 if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
402 OS << ')';
403 printAfter(T->getPointeeTypeAsWritten(), OS);
404 }
405
printMemberPointerBefore(const MemberPointerType * T,raw_ostream & OS)406 void TypePrinter::printMemberPointerBefore(const MemberPointerType *T,
407 raw_ostream &OS) {
408 IncludeStrongLifetimeRAII Strong(Policy);
409 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
410 printBefore(T->getPointeeType(), OS);
411 // Handle things like 'int (Cls::*A)[4];' correctly.
412 // FIXME: this should include vectors, but vectors use attributes I guess.
413 if (isa<ArrayType>(T->getPointeeType()))
414 OS << '(';
415
416 PrintingPolicy InnerPolicy(Policy);
417 InnerPolicy.IncludeTagDefinition = false;
418 TypePrinter(InnerPolicy).print(QualType(T->getClass(), 0), OS, StringRef());
419
420 OS << "::*";
421 }
printMemberPointerAfter(const MemberPointerType * T,raw_ostream & OS)422 void TypePrinter::printMemberPointerAfter(const MemberPointerType *T,
423 raw_ostream &OS) {
424 IncludeStrongLifetimeRAII Strong(Policy);
425 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
426 // Handle things like 'int (Cls::*A)[4];' correctly.
427 // FIXME: this should include vectors, but vectors use attributes I guess.
428 if (isa<ArrayType>(T->getPointeeType()))
429 OS << ')';
430 printAfter(T->getPointeeType(), OS);
431 }
432
printConstantArrayBefore(const ConstantArrayType * T,raw_ostream & OS)433 void TypePrinter::printConstantArrayBefore(const ConstantArrayType *T,
434 raw_ostream &OS) {
435 IncludeStrongLifetimeRAII Strong(Policy);
436 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
437 printBefore(T->getElementType(), OS);
438 }
printConstantArrayAfter(const ConstantArrayType * T,raw_ostream & OS)439 void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T,
440 raw_ostream &OS) {
441 OS << '[';
442 if (T->getIndexTypeQualifiers().hasQualifiers()) {
443 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(),
444 Policy.Restrict);
445 OS << ' ';
446 }
447
448 if (T->getSizeModifier() == ArrayType::Static)
449 OS << "static ";
450
451 OS << T->getSize().getZExtValue() << ']';
452 printAfter(T->getElementType(), OS);
453 }
454
printIncompleteArrayBefore(const IncompleteArrayType * T,raw_ostream & OS)455 void TypePrinter::printIncompleteArrayBefore(const IncompleteArrayType *T,
456 raw_ostream &OS) {
457 IncludeStrongLifetimeRAII Strong(Policy);
458 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
459 printBefore(T->getElementType(), OS);
460 }
printIncompleteArrayAfter(const IncompleteArrayType * T,raw_ostream & OS)461 void TypePrinter::printIncompleteArrayAfter(const IncompleteArrayType *T,
462 raw_ostream &OS) {
463 OS << "[]";
464 printAfter(T->getElementType(), OS);
465 }
466
printVariableArrayBefore(const VariableArrayType * T,raw_ostream & OS)467 void TypePrinter::printVariableArrayBefore(const VariableArrayType *T,
468 raw_ostream &OS) {
469 IncludeStrongLifetimeRAII Strong(Policy);
470 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
471 printBefore(T->getElementType(), OS);
472 }
printVariableArrayAfter(const VariableArrayType * T,raw_ostream & OS)473 void TypePrinter::printVariableArrayAfter(const VariableArrayType *T,
474 raw_ostream &OS) {
475 OS << '[';
476 if (T->getIndexTypeQualifiers().hasQualifiers()) {
477 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.Restrict);
478 OS << ' ';
479 }
480
481 if (T->getSizeModifier() == VariableArrayType::Static)
482 OS << "static ";
483 else if (T->getSizeModifier() == VariableArrayType::Star)
484 OS << '*';
485
486 if (T->getSizeExpr())
487 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
488 OS << ']';
489
490 printAfter(T->getElementType(), OS);
491 }
492
printAdjustedBefore(const AdjustedType * T,raw_ostream & OS)493 void TypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream &OS) {
494 // Print the adjusted representation, otherwise the adjustment will be
495 // invisible.
496 printBefore(T->getAdjustedType(), OS);
497 }
printAdjustedAfter(const AdjustedType * T,raw_ostream & OS)498 void TypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) {
499 printAfter(T->getAdjustedType(), OS);
500 }
501
printDecayedBefore(const DecayedType * T,raw_ostream & OS)502 void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {
503 // Print as though it's a pointer.
504 printAdjustedBefore(T, OS);
505 }
printDecayedAfter(const DecayedType * T,raw_ostream & OS)506 void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {
507 printAdjustedAfter(T, OS);
508 }
509
printDependentSizedArrayBefore(const DependentSizedArrayType * T,raw_ostream & OS)510 void TypePrinter::printDependentSizedArrayBefore(
511 const DependentSizedArrayType *T,
512 raw_ostream &OS) {
513 IncludeStrongLifetimeRAII Strong(Policy);
514 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
515 printBefore(T->getElementType(), OS);
516 }
printDependentSizedArrayAfter(const DependentSizedArrayType * T,raw_ostream & OS)517 void TypePrinter::printDependentSizedArrayAfter(
518 const DependentSizedArrayType *T,
519 raw_ostream &OS) {
520 OS << '[';
521 if (T->getSizeExpr())
522 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
523 OS << ']';
524 printAfter(T->getElementType(), OS);
525 }
526
printDependentSizedExtVectorBefore(const DependentSizedExtVectorType * T,raw_ostream & OS)527 void TypePrinter::printDependentSizedExtVectorBefore(
528 const DependentSizedExtVectorType *T,
529 raw_ostream &OS) {
530 printBefore(T->getElementType(), OS);
531 }
printDependentSizedExtVectorAfter(const DependentSizedExtVectorType * T,raw_ostream & OS)532 void TypePrinter::printDependentSizedExtVectorAfter(
533 const DependentSizedExtVectorType *T,
534 raw_ostream &OS) {
535 OS << " __attribute__((ext_vector_type(";
536 if (T->getSizeExpr())
537 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
538 OS << ")))";
539 printAfter(T->getElementType(), OS);
540 }
541
printVectorBefore(const VectorType * T,raw_ostream & OS)542 void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {
543 switch (T->getVectorKind()) {
544 case VectorType::AltiVecPixel:
545 OS << "__vector __pixel ";
546 break;
547 case VectorType::AltiVecBool:
548 OS << "__vector __bool ";
549 printBefore(T->getElementType(), OS);
550 break;
551 case VectorType::AltiVecVector:
552 OS << "__vector ";
553 printBefore(T->getElementType(), OS);
554 break;
555 case VectorType::NeonVector:
556 OS << "__attribute__((neon_vector_type("
557 << T->getNumElements() << "))) ";
558 printBefore(T->getElementType(), OS);
559 break;
560 case VectorType::NeonPolyVector:
561 OS << "__attribute__((neon_polyvector_type(" <<
562 T->getNumElements() << "))) ";
563 printBefore(T->getElementType(), OS);
564 break;
565 case VectorType::GenericVector: {
566 // FIXME: We prefer to print the size directly here, but have no way
567 // to get the size of the type.
568 OS << "__attribute__((__vector_size__("
569 << T->getNumElements()
570 << " * sizeof(";
571 print(T->getElementType(), OS, StringRef());
572 OS << ")))) ";
573 printBefore(T->getElementType(), OS);
574 break;
575 }
576 }
577 }
printVectorAfter(const VectorType * T,raw_ostream & OS)578 void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) {
579 printAfter(T->getElementType(), OS);
580 }
581
printExtVectorBefore(const ExtVectorType * T,raw_ostream & OS)582 void TypePrinter::printExtVectorBefore(const ExtVectorType *T,
583 raw_ostream &OS) {
584 printBefore(T->getElementType(), OS);
585 }
printExtVectorAfter(const ExtVectorType * T,raw_ostream & OS)586 void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) {
587 printAfter(T->getElementType(), OS);
588 OS << " __attribute__((ext_vector_type(";
589 OS << T->getNumElements();
590 OS << ")))";
591 }
592
593 void
printExceptionSpecification(raw_ostream & OS,const PrintingPolicy & Policy) const594 FunctionProtoType::printExceptionSpecification(raw_ostream &OS,
595 const PrintingPolicy &Policy)
596 const {
597
598 if (hasDynamicExceptionSpec()) {
599 OS << " throw(";
600 if (getExceptionSpecType() == EST_MSAny)
601 OS << "...";
602 else
603 for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) {
604 if (I)
605 OS << ", ";
606
607 OS << getExceptionType(I).stream(Policy);
608 }
609 OS << ')';
610 } else if (isNoexceptExceptionSpec(getExceptionSpecType())) {
611 OS << " noexcept";
612 if (getExceptionSpecType() == EST_ComputedNoexcept) {
613 OS << '(';
614 if (getNoexceptExpr())
615 getNoexceptExpr()->printPretty(OS, nullptr, Policy);
616 OS << ')';
617 }
618 }
619 }
620
printFunctionProtoBefore(const FunctionProtoType * T,raw_ostream & OS)621 void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,
622 raw_ostream &OS) {
623 if (T->hasTrailingReturn()) {
624 OS << "auto ";
625 if (!HasEmptyPlaceHolder)
626 OS << '(';
627 } else {
628 // If needed for precedence reasons, wrap the inner part in grouping parens.
629 SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder, false);
630 printBefore(T->getReturnType(), OS);
631 if (!PrevPHIsEmpty.get())
632 OS << '(';
633 }
634 }
635
getParameterABISpelling(ParameterABI ABI)636 llvm::StringRef clang::getParameterABISpelling(ParameterABI ABI) {
637 switch (ABI) {
638 case ParameterABI::Ordinary:
639 llvm_unreachable("asking for spelling of ordinary parameter ABI");
640 case ParameterABI::SwiftContext:
641 return "swift_context";
642 case ParameterABI::SwiftErrorResult:
643 return "swift_error_result";
644 case ParameterABI::SwiftIndirectResult:
645 return "swift_indirect_result";
646 }
647 llvm_unreachable("bad parameter ABI kind");
648 }
649
printFunctionProtoAfter(const FunctionProtoType * T,raw_ostream & OS)650 void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
651 raw_ostream &OS) {
652 // If needed for precedence reasons, wrap the inner part in grouping parens.
653 if (!HasEmptyPlaceHolder)
654 OS << ')';
655 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
656
657 OS << '(';
658 {
659 ParamPolicyRAII ParamPolicy(Policy);
660 for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {
661 if (i) OS << ", ";
662
663 auto EPI = T->getExtParameterInfo(i);
664 if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) ";
665 auto ABI = EPI.getABI();
666 if (ABI != ParameterABI::Ordinary)
667 OS << "__attribute__((" << getParameterABISpelling(ABI) << ")) ";
668
669 print(T->getParamType(i), OS, StringRef());
670 }
671 }
672
673 if (T->isVariadic()) {
674 if (T->getNumParams())
675 OS << ", ";
676 OS << "...";
677 } else if (T->getNumParams() == 0 && Policy.UseVoidForZeroParams) {
678 // Do not emit int() if we have a proto, emit 'int(void)'.
679 OS << "void";
680 }
681
682 OS << ')';
683
684 FunctionType::ExtInfo Info = T->getExtInfo();
685
686 if (!InsideCCAttribute) {
687 switch (Info.getCC()) {
688 case CC_C:
689 // The C calling convention is the default on the vast majority of platforms
690 // we support. If the user wrote it explicitly, it will usually be printed
691 // while traversing the AttributedType. If the type has been desugared, let
692 // the canonical spelling be the implicit calling convention.
693 // FIXME: It would be better to be explicit in certain contexts, such as a
694 // cdecl function typedef used to declare a member function with the
695 // Microsoft C++ ABI.
696 break;
697 case CC_X86StdCall:
698 OS << " __attribute__((stdcall))";
699 break;
700 case CC_X86FastCall:
701 OS << " __attribute__((fastcall))";
702 break;
703 case CC_X86ThisCall:
704 OS << " __attribute__((thiscall))";
705 break;
706 case CC_X86VectorCall:
707 OS << " __attribute__((vectorcall))";
708 break;
709 case CC_X86Pascal:
710 OS << " __attribute__((pascal))";
711 break;
712 case CC_AAPCS:
713 OS << " __attribute__((pcs(\"aapcs\")))";
714 break;
715 case CC_AAPCS_VFP:
716 OS << " __attribute__((pcs(\"aapcs-vfp\")))";
717 break;
718 case CC_IntelOclBicc:
719 OS << " __attribute__((intel_ocl_bicc))";
720 break;
721 case CC_X86_64Win64:
722 OS << " __attribute__((ms_abi))";
723 break;
724 case CC_X86_64SysV:
725 OS << " __attribute__((sysv_abi))";
726 break;
727 case CC_SpirFunction:
728 case CC_OpenCLKernel:
729 // Do nothing. These CCs are not available as attributes.
730 break;
731 case CC_Swift:
732 OS << " __attribute__((swiftcall))";
733 break;
734 case CC_PreserveMost:
735 OS << " __attribute__((preserve_most))";
736 break;
737 case CC_PreserveAll:
738 OS << " __attribute__((preserve_all))";
739 break;
740 }
741 }
742
743 if (Info.getNoReturn())
744 OS << " __attribute__((noreturn))";
745 if (Info.getRegParm())
746 OS << " __attribute__((regparm ("
747 << Info.getRegParm() << ")))";
748
749 if (unsigned quals = T->getTypeQuals()) {
750 OS << ' ';
751 AppendTypeQualList(OS, quals, Policy.Restrict);
752 }
753
754 switch (T->getRefQualifier()) {
755 case RQ_None:
756 break;
757
758 case RQ_LValue:
759 OS << " &";
760 break;
761
762 case RQ_RValue:
763 OS << " &&";
764 break;
765 }
766 T->printExceptionSpecification(OS, Policy);
767
768 if (T->hasTrailingReturn()) {
769 OS << " -> ";
770 print(T->getReturnType(), OS, StringRef());
771 } else
772 printAfter(T->getReturnType(), OS);
773 }
774
printFunctionNoProtoBefore(const FunctionNoProtoType * T,raw_ostream & OS)775 void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T,
776 raw_ostream &OS) {
777 // If needed for precedence reasons, wrap the inner part in grouping parens.
778 SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder, false);
779 printBefore(T->getReturnType(), OS);
780 if (!PrevPHIsEmpty.get())
781 OS << '(';
782 }
printFunctionNoProtoAfter(const FunctionNoProtoType * T,raw_ostream & OS)783 void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,
784 raw_ostream &OS) {
785 // If needed for precedence reasons, wrap the inner part in grouping parens.
786 if (!HasEmptyPlaceHolder)
787 OS << ')';
788 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
789
790 OS << "()";
791 if (T->getNoReturnAttr())
792 OS << " __attribute__((noreturn))";
793 printAfter(T->getReturnType(), OS);
794 }
795
printTypeSpec(const NamedDecl * D,raw_ostream & OS)796 void TypePrinter::printTypeSpec(const NamedDecl *D, raw_ostream &OS) {
797 IdentifierInfo *II = D->getIdentifier();
798 OS << II->getName();
799 spaceBeforePlaceHolder(OS);
800 }
801
printUnresolvedUsingBefore(const UnresolvedUsingType * T,raw_ostream & OS)802 void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,
803 raw_ostream &OS) {
804 printTypeSpec(T->getDecl(), OS);
805 }
printUnresolvedUsingAfter(const UnresolvedUsingType * T,raw_ostream & OS)806 void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,
807 raw_ostream &OS) { }
808
printTypedefBefore(const TypedefType * T,raw_ostream & OS)809 void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
810 printTypeSpec(T->getDecl(), OS);
811 }
printTypedefAfter(const TypedefType * T,raw_ostream & OS)812 void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) { }
813
printTypeOfExprBefore(const TypeOfExprType * T,raw_ostream & OS)814 void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
815 raw_ostream &OS) {
816 OS << "typeof ";
817 if (T->getUnderlyingExpr())
818 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
819 spaceBeforePlaceHolder(OS);
820 }
printTypeOfExprAfter(const TypeOfExprType * T,raw_ostream & OS)821 void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
822 raw_ostream &OS) { }
823
printTypeOfBefore(const TypeOfType * T,raw_ostream & OS)824 void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) {
825 OS << "typeof(";
826 print(T->getUnderlyingType(), OS, StringRef());
827 OS << ')';
828 spaceBeforePlaceHolder(OS);
829 }
printTypeOfAfter(const TypeOfType * T,raw_ostream & OS)830 void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) { }
831
printDecltypeBefore(const DecltypeType * T,raw_ostream & OS)832 void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {
833 OS << "decltype(";
834 if (T->getUnderlyingExpr())
835 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
836 OS << ')';
837 spaceBeforePlaceHolder(OS);
838 }
printDecltypeAfter(const DecltypeType * T,raw_ostream & OS)839 void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) { }
840
printUnaryTransformBefore(const UnaryTransformType * T,raw_ostream & OS)841 void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,
842 raw_ostream &OS) {
843 IncludeStrongLifetimeRAII Strong(Policy);
844
845 switch (T->getUTTKind()) {
846 case UnaryTransformType::EnumUnderlyingType:
847 OS << "__underlying_type(";
848 print(T->getBaseType(), OS, StringRef());
849 OS << ')';
850 spaceBeforePlaceHolder(OS);
851 return;
852 }
853
854 printBefore(T->getBaseType(), OS);
855 }
printUnaryTransformAfter(const UnaryTransformType * T,raw_ostream & OS)856 void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,
857 raw_ostream &OS) {
858 IncludeStrongLifetimeRAII Strong(Policy);
859
860 switch (T->getUTTKind()) {
861 case UnaryTransformType::EnumUnderlyingType:
862 return;
863 }
864
865 printAfter(T->getBaseType(), OS);
866 }
867
printAutoBefore(const AutoType * T,raw_ostream & OS)868 void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
869 // If the type has been deduced, do not print 'auto'.
870 if (!T->getDeducedType().isNull()) {
871 printBefore(T->getDeducedType(), OS);
872 } else {
873 switch (T->getKeyword()) {
874 case AutoTypeKeyword::Auto: OS << "auto"; break;
875 case AutoTypeKeyword::DecltypeAuto: OS << "decltype(auto)"; break;
876 case AutoTypeKeyword::GNUAutoType: OS << "__auto_type"; break;
877 }
878 spaceBeforePlaceHolder(OS);
879 }
880 }
printAutoAfter(const AutoType * T,raw_ostream & OS)881 void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {
882 // If the type has been deduced, do not print 'auto'.
883 if (!T->getDeducedType().isNull())
884 printAfter(T->getDeducedType(), OS);
885 }
886
printAtomicBefore(const AtomicType * T,raw_ostream & OS)887 void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {
888 IncludeStrongLifetimeRAII Strong(Policy);
889
890 OS << "_Atomic(";
891 print(T->getValueType(), OS, StringRef());
892 OS << ')';
893 spaceBeforePlaceHolder(OS);
894 }
printAtomicAfter(const AtomicType * T,raw_ostream & OS)895 void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) { }
896
printPipeBefore(const PipeType * T,raw_ostream & OS)897 void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) {
898 IncludeStrongLifetimeRAII Strong(Policy);
899
900 OS << "pipe ";
901 print(T->getElementType(), OS, StringRef());
902 spaceBeforePlaceHolder(OS);
903 }
904
printPipeAfter(const PipeType * T,raw_ostream & OS)905 void TypePrinter::printPipeAfter(const PipeType *T, raw_ostream &OS) {
906 }
907 /// Appends the given scope to the end of a string.
AppendScope(DeclContext * DC,raw_ostream & OS)908 void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS) {
909 if (DC->isTranslationUnit()) return;
910 if (DC->isFunctionOrMethod()) return;
911 AppendScope(DC->getParent(), OS);
912
913 if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
914 if (Policy.SuppressUnwrittenScope &&
915 (NS->isAnonymousNamespace() || NS->isInline()))
916 return;
917 if (NS->getIdentifier())
918 OS << NS->getName() << "::";
919 else
920 OS << "(anonymous namespace)::";
921 } else if (ClassTemplateSpecializationDecl *Spec
922 = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
923 IncludeStrongLifetimeRAII Strong(Policy);
924 OS << Spec->getIdentifier()->getName();
925 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
926 TemplateSpecializationType::PrintTemplateArgumentList(
927 OS, TemplateArgs.asArray(), Policy);
928 OS << "::";
929 } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
930 if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl())
931 OS << Typedef->getIdentifier()->getName() << "::";
932 else if (Tag->getIdentifier())
933 OS << Tag->getIdentifier()->getName() << "::";
934 else
935 return;
936 }
937 }
938
printTag(TagDecl * D,raw_ostream & OS)939 void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {
940 if (Policy.IncludeTagDefinition) {
941 PrintingPolicy SubPolicy = Policy;
942 SubPolicy.IncludeTagDefinition = false;
943 D->print(OS, SubPolicy, Indentation);
944 spaceBeforePlaceHolder(OS);
945 return;
946 }
947
948 bool HasKindDecoration = false;
949
950 // We don't print tags unless this is an elaborated type.
951 // In C, we just assume every RecordType is an elaborated type.
952 if (!Policy.SuppressTagKeyword && !D->getTypedefNameForAnonDecl()) {
953 HasKindDecoration = true;
954 OS << D->getKindName();
955 OS << ' ';
956 }
957
958 // Compute the full nested-name-specifier for this type.
959 // In C, this will always be empty except when the type
960 // being printed is anonymous within other Record.
961 if (!Policy.SuppressScope)
962 AppendScope(D->getDeclContext(), OS);
963
964 if (const IdentifierInfo *II = D->getIdentifier())
965 OS << II->getName();
966 else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) {
967 assert(Typedef->getIdentifier() && "Typedef without identifier?");
968 OS << Typedef->getIdentifier()->getName();
969 } else {
970 // Make an unambiguous representation for anonymous types, e.g.
971 // (anonymous enum at /usr/include/string.h:120:9)
972 OS << (Policy.MSVCFormatting ? '`' : '(');
973
974 if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
975 OS << "lambda";
976 HasKindDecoration = true;
977 } else {
978 OS << "anonymous";
979 }
980
981 if (Policy.AnonymousTagLocations) {
982 // Suppress the redundant tag keyword if we just printed one.
983 // We don't have to worry about ElaboratedTypes here because you can't
984 // refer to an anonymous type with one.
985 if (!HasKindDecoration)
986 OS << " " << D->getKindName();
987
988 PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc(
989 D->getLocation());
990 if (PLoc.isValid()) {
991 OS << " at " << PLoc.getFilename()
992 << ':' << PLoc.getLine()
993 << ':' << PLoc.getColumn();
994 }
995 }
996
997 OS << (Policy.MSVCFormatting ? '\'' : ')');
998 }
999
1000 // If this is a class template specialization, print the template
1001 // arguments.
1002 if (ClassTemplateSpecializationDecl *Spec
1003 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1004 ArrayRef<TemplateArgument> Args;
1005 if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) {
1006 const TemplateSpecializationType *TST =
1007 cast<TemplateSpecializationType>(TAW->getType());
1008 Args = TST->template_arguments();
1009 } else {
1010 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
1011 Args = TemplateArgs.asArray();
1012 }
1013 IncludeStrongLifetimeRAII Strong(Policy);
1014 TemplateSpecializationType::PrintTemplateArgumentList(OS, Args, Policy);
1015 }
1016
1017 spaceBeforePlaceHolder(OS);
1018 }
1019
printRecordBefore(const RecordType * T,raw_ostream & OS)1020 void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
1021 printTag(T->getDecl(), OS);
1022 }
printRecordAfter(const RecordType * T,raw_ostream & OS)1023 void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) { }
1024
printEnumBefore(const EnumType * T,raw_ostream & OS)1025 void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {
1026 printTag(T->getDecl(), OS);
1027 }
printEnumAfter(const EnumType * T,raw_ostream & OS)1028 void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) { }
1029
printTemplateTypeParmBefore(const TemplateTypeParmType * T,raw_ostream & OS)1030 void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
1031 raw_ostream &OS) {
1032 if (IdentifierInfo *Id = T->getIdentifier())
1033 OS << Id->getName();
1034 else
1035 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
1036 spaceBeforePlaceHolder(OS);
1037 }
printTemplateTypeParmAfter(const TemplateTypeParmType * T,raw_ostream & OS)1038 void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,
1039 raw_ostream &OS) { }
1040
printSubstTemplateTypeParmBefore(const SubstTemplateTypeParmType * T,raw_ostream & OS)1041 void TypePrinter::printSubstTemplateTypeParmBefore(
1042 const SubstTemplateTypeParmType *T,
1043 raw_ostream &OS) {
1044 IncludeStrongLifetimeRAII Strong(Policy);
1045 printBefore(T->getReplacementType(), OS);
1046 }
printSubstTemplateTypeParmAfter(const SubstTemplateTypeParmType * T,raw_ostream & OS)1047 void TypePrinter::printSubstTemplateTypeParmAfter(
1048 const SubstTemplateTypeParmType *T,
1049 raw_ostream &OS) {
1050 IncludeStrongLifetimeRAII Strong(Policy);
1051 printAfter(T->getReplacementType(), OS);
1052 }
1053
printSubstTemplateTypeParmPackBefore(const SubstTemplateTypeParmPackType * T,raw_ostream & OS)1054 void TypePrinter::printSubstTemplateTypeParmPackBefore(
1055 const SubstTemplateTypeParmPackType *T,
1056 raw_ostream &OS) {
1057 IncludeStrongLifetimeRAII Strong(Policy);
1058 printTemplateTypeParmBefore(T->getReplacedParameter(), OS);
1059 }
printSubstTemplateTypeParmPackAfter(const SubstTemplateTypeParmPackType * T,raw_ostream & OS)1060 void TypePrinter::printSubstTemplateTypeParmPackAfter(
1061 const SubstTemplateTypeParmPackType *T,
1062 raw_ostream &OS) {
1063 IncludeStrongLifetimeRAII Strong(Policy);
1064 printTemplateTypeParmAfter(T->getReplacedParameter(), OS);
1065 }
1066
printTemplateSpecializationBefore(const TemplateSpecializationType * T,raw_ostream & OS)1067 void TypePrinter::printTemplateSpecializationBefore(
1068 const TemplateSpecializationType *T,
1069 raw_ostream &OS) {
1070 IncludeStrongLifetimeRAII Strong(Policy);
1071 T->getTemplateName().print(OS, Policy);
1072
1073 TemplateSpecializationType::PrintTemplateArgumentList(
1074 OS, T->template_arguments(), Policy);
1075 spaceBeforePlaceHolder(OS);
1076 }
printTemplateSpecializationAfter(const TemplateSpecializationType * T,raw_ostream & OS)1077 void TypePrinter::printTemplateSpecializationAfter(
1078 const TemplateSpecializationType *T,
1079 raw_ostream &OS) { }
1080
printInjectedClassNameBefore(const InjectedClassNameType * T,raw_ostream & OS)1081 void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
1082 raw_ostream &OS) {
1083 printTemplateSpecializationBefore(T->getInjectedTST(), OS);
1084 }
printInjectedClassNameAfter(const InjectedClassNameType * T,raw_ostream & OS)1085 void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
1086 raw_ostream &OS) { }
1087
printElaboratedBefore(const ElaboratedType * T,raw_ostream & OS)1088 void TypePrinter::printElaboratedBefore(const ElaboratedType *T,
1089 raw_ostream &OS) {
1090 // The tag definition will take care of these.
1091 if (!Policy.IncludeTagDefinition)
1092 {
1093 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1094 if (T->getKeyword() != ETK_None)
1095 OS << " ";
1096 NestedNameSpecifier* Qualifier = T->getQualifier();
1097 if (Qualifier)
1098 Qualifier->print(OS, Policy);
1099 }
1100
1101 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1102 printBefore(T->getNamedType(), OS);
1103 }
printElaboratedAfter(const ElaboratedType * T,raw_ostream & OS)1104 void TypePrinter::printElaboratedAfter(const ElaboratedType *T,
1105 raw_ostream &OS) {
1106 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1107 printAfter(T->getNamedType(), OS);
1108 }
1109
printParenBefore(const ParenType * T,raw_ostream & OS)1110 void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {
1111 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1112 printBefore(T->getInnerType(), OS);
1113 OS << '(';
1114 } else
1115 printBefore(T->getInnerType(), OS);
1116 }
printParenAfter(const ParenType * T,raw_ostream & OS)1117 void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {
1118 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1119 OS << ')';
1120 printAfter(T->getInnerType(), OS);
1121 } else
1122 printAfter(T->getInnerType(), OS);
1123 }
1124
printDependentNameBefore(const DependentNameType * T,raw_ostream & OS)1125 void TypePrinter::printDependentNameBefore(const DependentNameType *T,
1126 raw_ostream &OS) {
1127 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1128 if (T->getKeyword() != ETK_None)
1129 OS << " ";
1130
1131 T->getQualifier()->print(OS, Policy);
1132
1133 OS << T->getIdentifier()->getName();
1134 spaceBeforePlaceHolder(OS);
1135 }
printDependentNameAfter(const DependentNameType * T,raw_ostream & OS)1136 void TypePrinter::printDependentNameAfter(const DependentNameType *T,
1137 raw_ostream &OS) { }
1138
printDependentTemplateSpecializationBefore(const DependentTemplateSpecializationType * T,raw_ostream & OS)1139 void TypePrinter::printDependentTemplateSpecializationBefore(
1140 const DependentTemplateSpecializationType *T, raw_ostream &OS) {
1141 IncludeStrongLifetimeRAII Strong(Policy);
1142
1143 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1144 if (T->getKeyword() != ETK_None)
1145 OS << " ";
1146
1147 if (T->getQualifier())
1148 T->getQualifier()->print(OS, Policy);
1149 OS << T->getIdentifier()->getName();
1150 TemplateSpecializationType::PrintTemplateArgumentList(OS,
1151 T->template_arguments(),
1152 Policy);
1153 spaceBeforePlaceHolder(OS);
1154 }
printDependentTemplateSpecializationAfter(const DependentTemplateSpecializationType * T,raw_ostream & OS)1155 void TypePrinter::printDependentTemplateSpecializationAfter(
1156 const DependentTemplateSpecializationType *T, raw_ostream &OS) { }
1157
printPackExpansionBefore(const PackExpansionType * T,raw_ostream & OS)1158 void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,
1159 raw_ostream &OS) {
1160 printBefore(T->getPattern(), OS);
1161 }
printPackExpansionAfter(const PackExpansionType * T,raw_ostream & OS)1162 void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
1163 raw_ostream &OS) {
1164 printAfter(T->getPattern(), OS);
1165 OS << "...";
1166 }
1167
printAttributedBefore(const AttributedType * T,raw_ostream & OS)1168 void TypePrinter::printAttributedBefore(const AttributedType *T,
1169 raw_ostream &OS) {
1170 // Prefer the macro forms of the GC and ownership qualifiers.
1171 if (T->getAttrKind() == AttributedType::attr_objc_gc ||
1172 T->getAttrKind() == AttributedType::attr_objc_ownership)
1173 return printBefore(T->getEquivalentType(), OS);
1174
1175 if (T->getAttrKind() == AttributedType::attr_objc_kindof)
1176 OS << "__kindof ";
1177
1178 printBefore(T->getModifiedType(), OS);
1179
1180 if (T->isMSTypeSpec()) {
1181 switch (T->getAttrKind()) {
1182 default: return;
1183 case AttributedType::attr_ptr32: OS << " __ptr32"; break;
1184 case AttributedType::attr_ptr64: OS << " __ptr64"; break;
1185 case AttributedType::attr_sptr: OS << " __sptr"; break;
1186 case AttributedType::attr_uptr: OS << " __uptr"; break;
1187 }
1188 spaceBeforePlaceHolder(OS);
1189 }
1190
1191 // Print nullability type specifiers.
1192 if (T->getAttrKind() == AttributedType::attr_nonnull ||
1193 T->getAttrKind() == AttributedType::attr_nullable ||
1194 T->getAttrKind() == AttributedType::attr_null_unspecified) {
1195 if (T->getAttrKind() == AttributedType::attr_nonnull)
1196 OS << " _Nonnull";
1197 else if (T->getAttrKind() == AttributedType::attr_nullable)
1198 OS << " _Nullable";
1199 else if (T->getAttrKind() == AttributedType::attr_null_unspecified)
1200 OS << " _Null_unspecified";
1201 else
1202 llvm_unreachable("unhandled nullability");
1203 spaceBeforePlaceHolder(OS);
1204 }
1205 }
1206
printAttributedAfter(const AttributedType * T,raw_ostream & OS)1207 void TypePrinter::printAttributedAfter(const AttributedType *T,
1208 raw_ostream &OS) {
1209 // Prefer the macro forms of the GC and ownership qualifiers.
1210 if (T->getAttrKind() == AttributedType::attr_objc_gc ||
1211 T->getAttrKind() == AttributedType::attr_objc_ownership)
1212 return printAfter(T->getEquivalentType(), OS);
1213
1214 if (T->getAttrKind() == AttributedType::attr_objc_kindof)
1215 return;
1216
1217 // TODO: not all attributes are GCC-style attributes.
1218 if (T->isMSTypeSpec())
1219 return;
1220
1221 // Nothing to print after.
1222 if (T->getAttrKind() == AttributedType::attr_nonnull ||
1223 T->getAttrKind() == AttributedType::attr_nullable ||
1224 T->getAttrKind() == AttributedType::attr_null_unspecified)
1225 return printAfter(T->getModifiedType(), OS);
1226
1227 // If this is a calling convention attribute, don't print the implicit CC from
1228 // the modified type.
1229 SaveAndRestore<bool> MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());
1230
1231 printAfter(T->getModifiedType(), OS);
1232
1233 // Don't print the inert __unsafe_unretained attribute at all.
1234 if (T->getAttrKind() == AttributedType::attr_objc_inert_unsafe_unretained)
1235 return;
1236
1237 // Print nullability type specifiers that occur after
1238 if (T->getAttrKind() == AttributedType::attr_nonnull ||
1239 T->getAttrKind() == AttributedType::attr_nullable ||
1240 T->getAttrKind() == AttributedType::attr_null_unspecified) {
1241 if (T->getAttrKind() == AttributedType::attr_nonnull)
1242 OS << " _Nonnull";
1243 else if (T->getAttrKind() == AttributedType::attr_nullable)
1244 OS << " _Nullable";
1245 else if (T->getAttrKind() == AttributedType::attr_null_unspecified)
1246 OS << " _Null_unspecified";
1247 else
1248 llvm_unreachable("unhandled nullability");
1249
1250 return;
1251 }
1252
1253 OS << " __attribute__((";
1254 switch (T->getAttrKind()) {
1255 default: llvm_unreachable("This attribute should have been handled already");
1256 case AttributedType::attr_address_space:
1257 OS << "address_space(";
1258 OS << T->getEquivalentType().getAddressSpace();
1259 OS << ')';
1260 break;
1261
1262 case AttributedType::attr_vector_size: {
1263 OS << "__vector_size__(";
1264 if (const VectorType *vector =T->getEquivalentType()->getAs<VectorType>()) {
1265 OS << vector->getNumElements();
1266 OS << " * sizeof(";
1267 print(vector->getElementType(), OS, StringRef());
1268 OS << ')';
1269 }
1270 OS << ')';
1271 break;
1272 }
1273
1274 case AttributedType::attr_neon_vector_type:
1275 case AttributedType::attr_neon_polyvector_type: {
1276 if (T->getAttrKind() == AttributedType::attr_neon_vector_type)
1277 OS << "neon_vector_type(";
1278 else
1279 OS << "neon_polyvector_type(";
1280 const VectorType *vector = T->getEquivalentType()->getAs<VectorType>();
1281 OS << vector->getNumElements();
1282 OS << ')';
1283 break;
1284 }
1285
1286 case AttributedType::attr_regparm: {
1287 // FIXME: When Sema learns to form this AttributedType, avoid printing the
1288 // attribute again in printFunctionProtoAfter.
1289 OS << "regparm(";
1290 QualType t = T->getEquivalentType();
1291 while (!t->isFunctionType())
1292 t = t->getPointeeType();
1293 OS << t->getAs<FunctionType>()->getRegParmType();
1294 OS << ')';
1295 break;
1296 }
1297
1298 case AttributedType::attr_objc_gc: {
1299 OS << "objc_gc(";
1300
1301 QualType tmp = T->getEquivalentType();
1302 while (tmp.getObjCGCAttr() == Qualifiers::GCNone) {
1303 QualType next = tmp->getPointeeType();
1304 if (next == tmp) break;
1305 tmp = next;
1306 }
1307
1308 if (tmp.isObjCGCWeak())
1309 OS << "weak";
1310 else
1311 OS << "strong";
1312 OS << ')';
1313 break;
1314 }
1315
1316 case AttributedType::attr_objc_ownership:
1317 OS << "objc_ownership(";
1318 switch (T->getEquivalentType().getObjCLifetime()) {
1319 case Qualifiers::OCL_None: llvm_unreachable("no ownership!");
1320 case Qualifiers::OCL_ExplicitNone: OS << "none"; break;
1321 case Qualifiers::OCL_Strong: OS << "strong"; break;
1322 case Qualifiers::OCL_Weak: OS << "weak"; break;
1323 case Qualifiers::OCL_Autoreleasing: OS << "autoreleasing"; break;
1324 }
1325 OS << ')';
1326 break;
1327
1328 // FIXME: When Sema learns to form this AttributedType, avoid printing the
1329 // attribute again in printFunctionProtoAfter.
1330 case AttributedType::attr_noreturn: OS << "noreturn"; break;
1331
1332 case AttributedType::attr_cdecl: OS << "cdecl"; break;
1333 case AttributedType::attr_fastcall: OS << "fastcall"; break;
1334 case AttributedType::attr_stdcall: OS << "stdcall"; break;
1335 case AttributedType::attr_thiscall: OS << "thiscall"; break;
1336 case AttributedType::attr_swiftcall: OS << "swiftcall"; break;
1337 case AttributedType::attr_vectorcall: OS << "vectorcall"; break;
1338 case AttributedType::attr_pascal: OS << "pascal"; break;
1339 case AttributedType::attr_ms_abi: OS << "ms_abi"; break;
1340 case AttributedType::attr_sysv_abi: OS << "sysv_abi"; break;
1341 case AttributedType::attr_pcs:
1342 case AttributedType::attr_pcs_vfp: {
1343 OS << "pcs(";
1344 QualType t = T->getEquivalentType();
1345 while (!t->isFunctionType())
1346 t = t->getPointeeType();
1347 OS << (t->getAs<FunctionType>()->getCallConv() == CC_AAPCS ?
1348 "\"aapcs\"" : "\"aapcs-vfp\"");
1349 OS << ')';
1350 break;
1351 }
1352 case AttributedType::attr_inteloclbicc: OS << "inteloclbicc"; break;
1353 case AttributedType::attr_preserve_most:
1354 OS << "preserve_most";
1355 break;
1356 case AttributedType::attr_preserve_all:
1357 OS << "preserve_all";
1358 break;
1359 }
1360 OS << "))";
1361 }
1362
printObjCInterfaceBefore(const ObjCInterfaceType * T,raw_ostream & OS)1363 void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
1364 raw_ostream &OS) {
1365 OS << T->getDecl()->getName();
1366 spaceBeforePlaceHolder(OS);
1367 }
printObjCInterfaceAfter(const ObjCInterfaceType * T,raw_ostream & OS)1368 void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
1369 raw_ostream &OS) { }
1370
printObjCObjectBefore(const ObjCObjectType * T,raw_ostream & OS)1371 void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
1372 raw_ostream &OS) {
1373 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
1374 !T->isKindOfTypeAsWritten())
1375 return printBefore(T->getBaseType(), OS);
1376
1377 if (T->isKindOfTypeAsWritten())
1378 OS << "__kindof ";
1379
1380 print(T->getBaseType(), OS, StringRef());
1381
1382 if (T->isSpecializedAsWritten()) {
1383 bool isFirst = true;
1384 OS << '<';
1385 for (auto typeArg : T->getTypeArgsAsWritten()) {
1386 if (isFirst)
1387 isFirst = false;
1388 else
1389 OS << ",";
1390
1391 print(typeArg, OS, StringRef());
1392 }
1393 OS << '>';
1394 }
1395
1396 if (!T->qual_empty()) {
1397 bool isFirst = true;
1398 OS << '<';
1399 for (const auto *I : T->quals()) {
1400 if (isFirst)
1401 isFirst = false;
1402 else
1403 OS << ',';
1404 OS << I->getName();
1405 }
1406 OS << '>';
1407 }
1408
1409 spaceBeforePlaceHolder(OS);
1410 }
printObjCObjectAfter(const ObjCObjectType * T,raw_ostream & OS)1411 void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
1412 raw_ostream &OS) {
1413 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
1414 !T->isKindOfTypeAsWritten())
1415 return printAfter(T->getBaseType(), OS);
1416 }
1417
printObjCObjectPointerBefore(const ObjCObjectPointerType * T,raw_ostream & OS)1418 void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
1419 raw_ostream &OS) {
1420 printBefore(T->getPointeeType(), OS);
1421
1422 // If we need to print the pointer, print it now.
1423 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&
1424 !T->isObjCClassType() && !T->isObjCQualifiedClassType()) {
1425 if (HasEmptyPlaceHolder)
1426 OS << ' ';
1427 OS << '*';
1428 }
1429 }
printObjCObjectPointerAfter(const ObjCObjectPointerType * T,raw_ostream & OS)1430 void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
1431 raw_ostream &OS) { }
1432
1433 void TemplateSpecializationType::
PrintTemplateArgumentList(raw_ostream & OS,const TemplateArgumentListInfo & Args,const PrintingPolicy & Policy)1434 PrintTemplateArgumentList(raw_ostream &OS,
1435 const TemplateArgumentListInfo &Args,
1436 const PrintingPolicy &Policy) {
1437 return PrintTemplateArgumentList(OS,
1438 Args.arguments(),
1439 Policy);
1440 }
1441
PrintTemplateArgumentList(raw_ostream & OS,ArrayRef<TemplateArgument> Args,const PrintingPolicy & Policy,bool SkipBrackets)1442 void TemplateSpecializationType::PrintTemplateArgumentList(
1443 raw_ostream &OS, ArrayRef<TemplateArgument> Args,
1444 const PrintingPolicy &Policy, bool SkipBrackets) {
1445 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
1446 if (!SkipBrackets)
1447 OS << '<';
1448
1449 bool needSpace = false;
1450 bool FirstArg = true;
1451 for (const TemplateArgument &Arg : Args) {
1452 // Print the argument into a string.
1453 SmallString<128> Buf;
1454 llvm::raw_svector_ostream ArgOS(Buf);
1455 if (Arg.getKind() == TemplateArgument::Pack) {
1456 if (Arg.pack_size() && !FirstArg)
1457 OS << Comma;
1458 PrintTemplateArgumentList(ArgOS,
1459 Arg.getPackAsArray(),
1460 Policy, true);
1461 } else {
1462 if (!FirstArg)
1463 OS << Comma;
1464 Arg.print(Policy, ArgOS);
1465 }
1466 StringRef ArgString = ArgOS.str();
1467
1468 // If this is the first argument and its string representation
1469 // begins with the global scope specifier ('::foo'), add a space
1470 // to avoid printing the diagraph '<:'.
1471 if (FirstArg && !ArgString.empty() && ArgString[0] == ':')
1472 OS << ' ';
1473
1474 OS << ArgString;
1475
1476 needSpace = (!ArgString.empty() && ArgString.back() == '>');
1477 FirstArg = false;
1478 }
1479
1480 // If the last character of our string is '>', add another space to
1481 // keep the two '>''s separate tokens. We don't *have* to do this in
1482 // C++0x, but it's still good hygiene.
1483 if (needSpace)
1484 OS << ' ';
1485
1486 if (!SkipBrackets)
1487 OS << '>';
1488 }
1489
1490 // Sadly, repeat all that with TemplateArgLoc.
1491 void TemplateSpecializationType::
PrintTemplateArgumentList(raw_ostream & OS,ArrayRef<TemplateArgumentLoc> Args,const PrintingPolicy & Policy)1492 PrintTemplateArgumentList(raw_ostream &OS,
1493 ArrayRef<TemplateArgumentLoc> Args,
1494 const PrintingPolicy &Policy) {
1495 OS << '<';
1496 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
1497
1498 bool needSpace = false;
1499 bool FirstArg = true;
1500 for (const TemplateArgumentLoc &Arg : Args) {
1501 if (!FirstArg)
1502 OS << Comma;
1503
1504 // Print the argument into a string.
1505 SmallString<128> Buf;
1506 llvm::raw_svector_ostream ArgOS(Buf);
1507 if (Arg.getArgument().getKind() == TemplateArgument::Pack) {
1508 PrintTemplateArgumentList(ArgOS,
1509 Arg.getArgument().getPackAsArray(),
1510 Policy, true);
1511 } else {
1512 Arg.getArgument().print(Policy, ArgOS);
1513 }
1514 StringRef ArgString = ArgOS.str();
1515
1516 // If this is the first argument and its string representation
1517 // begins with the global scope specifier ('::foo'), add a space
1518 // to avoid printing the diagraph '<:'.
1519 if (FirstArg && !ArgString.empty() && ArgString[0] == ':')
1520 OS << ' ';
1521
1522 OS << ArgString;
1523
1524 needSpace = (!ArgString.empty() && ArgString.back() == '>');
1525 FirstArg = false;
1526 }
1527
1528 // If the last character of our string is '>', add another space to
1529 // keep the two '>''s separate tokens. We don't *have* to do this in
1530 // C++0x, but it's still good hygiene.
1531 if (needSpace)
1532 OS << ' ';
1533
1534 OS << '>';
1535 }
1536
getAsString() const1537 std::string Qualifiers::getAsString() const {
1538 LangOptions LO;
1539 return getAsString(PrintingPolicy(LO));
1540 }
1541
1542 // Appends qualifiers to the given string, separated by spaces. Will
1543 // prefix a space if the string is non-empty. Will not append a final
1544 // space.
getAsString(const PrintingPolicy & Policy) const1545 std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {
1546 SmallString<64> Buf;
1547 llvm::raw_svector_ostream StrOS(Buf);
1548 print(StrOS, Policy);
1549 return StrOS.str();
1550 }
1551
isEmptyWhenPrinted(const PrintingPolicy & Policy) const1552 bool Qualifiers::isEmptyWhenPrinted(const PrintingPolicy &Policy) const {
1553 if (getCVRQualifiers())
1554 return false;
1555
1556 if (getAddressSpace())
1557 return false;
1558
1559 if (getObjCGCAttr())
1560 return false;
1561
1562 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime())
1563 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
1564 return false;
1565
1566 return true;
1567 }
1568
1569 // Appends qualifiers to the given string, separated by spaces. Will
1570 // prefix a space if the string is non-empty. Will not append a final
1571 // space.
print(raw_ostream & OS,const PrintingPolicy & Policy,bool appendSpaceIfNonEmpty) const1572 void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
1573 bool appendSpaceIfNonEmpty) const {
1574 bool addSpace = false;
1575
1576 unsigned quals = getCVRQualifiers();
1577 if (quals) {
1578 AppendTypeQualList(OS, quals, Policy.Restrict);
1579 addSpace = true;
1580 }
1581 if (hasUnaligned()) {
1582 if (addSpace)
1583 OS << ' ';
1584 OS << "__unaligned";
1585 addSpace = true;
1586 }
1587 if (unsigned addrspace = getAddressSpace()) {
1588 if (addSpace)
1589 OS << ' ';
1590 addSpace = true;
1591 switch (addrspace) {
1592 case LangAS::opencl_global:
1593 OS << "__global";
1594 break;
1595 case LangAS::opencl_local:
1596 OS << "__local";
1597 break;
1598 case LangAS::opencl_constant:
1599 OS << "__constant";
1600 break;
1601 case LangAS::opencl_generic:
1602 OS << "__generic";
1603 break;
1604 default:
1605 OS << "__attribute__((address_space(";
1606 OS << addrspace;
1607 OS << ")))";
1608 }
1609 }
1610 if (Qualifiers::GC gc = getObjCGCAttr()) {
1611 if (addSpace)
1612 OS << ' ';
1613 addSpace = true;
1614 if (gc == Qualifiers::Weak)
1615 OS << "__weak";
1616 else
1617 OS << "__strong";
1618 }
1619 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
1620 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
1621 if (addSpace)
1622 OS << ' ';
1623 addSpace = true;
1624 }
1625
1626 switch (lifetime) {
1627 case Qualifiers::OCL_None: llvm_unreachable("none but true");
1628 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;
1629 case Qualifiers::OCL_Strong:
1630 if (!Policy.SuppressStrongLifetime)
1631 OS << "__strong";
1632 break;
1633
1634 case Qualifiers::OCL_Weak: OS << "__weak"; break;
1635 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
1636 }
1637 }
1638
1639 if (appendSpaceIfNonEmpty && addSpace)
1640 OS << ' ';
1641 }
1642
getAsString(const PrintingPolicy & Policy) const1643 std::string QualType::getAsString(const PrintingPolicy &Policy) const {
1644 std::string S;
1645 getAsStringInternal(S, Policy);
1646 return S;
1647 }
1648
getAsString(const Type * ty,Qualifiers qs)1649 std::string QualType::getAsString(const Type *ty, Qualifiers qs) {
1650 std::string buffer;
1651 LangOptions options;
1652 getAsStringInternal(ty, qs, buffer, PrintingPolicy(options));
1653 return buffer;
1654 }
1655
print(const Type * ty,Qualifiers qs,raw_ostream & OS,const PrintingPolicy & policy,const Twine & PlaceHolder,unsigned Indentation)1656 void QualType::print(const Type *ty, Qualifiers qs,
1657 raw_ostream &OS, const PrintingPolicy &policy,
1658 const Twine &PlaceHolder, unsigned Indentation) {
1659 SmallString<128> PHBuf;
1660 StringRef PH = PlaceHolder.toStringRef(PHBuf);
1661
1662 TypePrinter(policy, Indentation).print(ty, qs, OS, PH);
1663 }
1664
getAsStringInternal(const Type * ty,Qualifiers qs,std::string & buffer,const PrintingPolicy & policy)1665 void QualType::getAsStringInternal(const Type *ty, Qualifiers qs,
1666 std::string &buffer,
1667 const PrintingPolicy &policy) {
1668 SmallString<256> Buf;
1669 llvm::raw_svector_ostream StrOS(Buf);
1670 TypePrinter(policy).print(ty, qs, StrOS, buffer);
1671 std::string str = StrOS.str();
1672 buffer.swap(str);
1673 }
1674