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