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 << '[' << T->getSize().getZExtValue() << ']';
434 printAfter(T->getElementType(), OS);
435 }
436
printIncompleteArrayBefore(const IncompleteArrayType * T,raw_ostream & OS)437 void TypePrinter::printIncompleteArrayBefore(const IncompleteArrayType *T,
438 raw_ostream &OS) {
439 IncludeStrongLifetimeRAII Strong(Policy);
440 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
441 printBefore(T->getElementType(), OS);
442 }
printIncompleteArrayAfter(const IncompleteArrayType * T,raw_ostream & OS)443 void TypePrinter::printIncompleteArrayAfter(const IncompleteArrayType *T,
444 raw_ostream &OS) {
445 OS << "[]";
446 printAfter(T->getElementType(), OS);
447 }
448
printVariableArrayBefore(const VariableArrayType * T,raw_ostream & OS)449 void TypePrinter::printVariableArrayBefore(const VariableArrayType *T,
450 raw_ostream &OS) {
451 IncludeStrongLifetimeRAII Strong(Policy);
452 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
453 printBefore(T->getElementType(), OS);
454 }
printVariableArrayAfter(const VariableArrayType * T,raw_ostream & OS)455 void TypePrinter::printVariableArrayAfter(const VariableArrayType *T,
456 raw_ostream &OS) {
457 OS << '[';
458 if (T->getIndexTypeQualifiers().hasQualifiers()) {
459 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers());
460 OS << ' ';
461 }
462
463 if (T->getSizeModifier() == VariableArrayType::Static)
464 OS << "static";
465 else if (T->getSizeModifier() == VariableArrayType::Star)
466 OS << '*';
467
468 if (T->getSizeExpr())
469 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
470 OS << ']';
471
472 printAfter(T->getElementType(), OS);
473 }
474
printAdjustedBefore(const AdjustedType * T,raw_ostream & OS)475 void TypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream &OS) {
476 // Print the adjusted representation, otherwise the adjustment will be
477 // invisible.
478 printBefore(T->getAdjustedType(), OS);
479 }
printAdjustedAfter(const AdjustedType * T,raw_ostream & OS)480 void TypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) {
481 printAfter(T->getAdjustedType(), OS);
482 }
483
printDecayedBefore(const DecayedType * T,raw_ostream & OS)484 void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {
485 // Print as though it's a pointer.
486 printAdjustedBefore(T, OS);
487 }
printDecayedAfter(const DecayedType * T,raw_ostream & OS)488 void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {
489 printAdjustedAfter(T, OS);
490 }
491
printDependentSizedArrayBefore(const DependentSizedArrayType * T,raw_ostream & OS)492 void TypePrinter::printDependentSizedArrayBefore(
493 const DependentSizedArrayType *T,
494 raw_ostream &OS) {
495 IncludeStrongLifetimeRAII Strong(Policy);
496 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
497 printBefore(T->getElementType(), OS);
498 }
printDependentSizedArrayAfter(const DependentSizedArrayType * T,raw_ostream & OS)499 void TypePrinter::printDependentSizedArrayAfter(
500 const DependentSizedArrayType *T,
501 raw_ostream &OS) {
502 OS << '[';
503 if (T->getSizeExpr())
504 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
505 OS << ']';
506 printAfter(T->getElementType(), OS);
507 }
508
printDependentSizedExtVectorBefore(const DependentSizedExtVectorType * T,raw_ostream & OS)509 void TypePrinter::printDependentSizedExtVectorBefore(
510 const DependentSizedExtVectorType *T,
511 raw_ostream &OS) {
512 printBefore(T->getElementType(), OS);
513 }
printDependentSizedExtVectorAfter(const DependentSizedExtVectorType * T,raw_ostream & OS)514 void TypePrinter::printDependentSizedExtVectorAfter(
515 const DependentSizedExtVectorType *T,
516 raw_ostream &OS) {
517 OS << " __attribute__((ext_vector_type(";
518 if (T->getSizeExpr())
519 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
520 OS << ")))";
521 printAfter(T->getElementType(), OS);
522 }
523
printVectorBefore(const VectorType * T,raw_ostream & OS)524 void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {
525 switch (T->getVectorKind()) {
526 case VectorType::AltiVecPixel:
527 OS << "__vector __pixel ";
528 break;
529 case VectorType::AltiVecBool:
530 OS << "__vector __bool ";
531 printBefore(T->getElementType(), OS);
532 break;
533 case VectorType::AltiVecVector:
534 OS << "__vector ";
535 printBefore(T->getElementType(), OS);
536 break;
537 case VectorType::NeonVector:
538 OS << "__attribute__((neon_vector_type("
539 << T->getNumElements() << "))) ";
540 printBefore(T->getElementType(), OS);
541 break;
542 case VectorType::NeonPolyVector:
543 OS << "__attribute__((neon_polyvector_type(" <<
544 T->getNumElements() << "))) ";
545 printBefore(T->getElementType(), OS);
546 break;
547 case VectorType::GenericVector: {
548 // FIXME: We prefer to print the size directly here, but have no way
549 // to get the size of the type.
550 OS << "__attribute__((__vector_size__("
551 << T->getNumElements()
552 << " * sizeof(";
553 print(T->getElementType(), OS, StringRef());
554 OS << ")))) ";
555 printBefore(T->getElementType(), OS);
556 break;
557 }
558 }
559 }
printVectorAfter(const VectorType * T,raw_ostream & OS)560 void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) {
561 printAfter(T->getElementType(), OS);
562 }
563
printExtVectorBefore(const ExtVectorType * T,raw_ostream & OS)564 void TypePrinter::printExtVectorBefore(const ExtVectorType *T,
565 raw_ostream &OS) {
566 printBefore(T->getElementType(), OS);
567 }
printExtVectorAfter(const ExtVectorType * T,raw_ostream & OS)568 void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) {
569 printAfter(T->getElementType(), OS);
570 OS << " __attribute__((ext_vector_type(";
571 OS << T->getNumElements();
572 OS << ")))";
573 }
574
575 void
printExceptionSpecification(raw_ostream & OS,const PrintingPolicy & Policy) const576 FunctionProtoType::printExceptionSpecification(raw_ostream &OS,
577 const PrintingPolicy &Policy)
578 const {
579
580 if (hasDynamicExceptionSpec()) {
581 OS << " throw(";
582 if (getExceptionSpecType() == EST_MSAny)
583 OS << "...";
584 else
585 for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) {
586 if (I)
587 OS << ", ";
588
589 OS << getExceptionType(I).stream(Policy);
590 }
591 OS << ')';
592 } else if (isNoexceptExceptionSpec(getExceptionSpecType())) {
593 OS << " noexcept";
594 if (getExceptionSpecType() == EST_ComputedNoexcept) {
595 OS << '(';
596 if (getNoexceptExpr())
597 getNoexceptExpr()->printPretty(OS, nullptr, Policy);
598 OS << ')';
599 }
600 }
601 }
602
printFunctionProtoBefore(const FunctionProtoType * T,raw_ostream & OS)603 void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,
604 raw_ostream &OS) {
605 if (T->hasTrailingReturn()) {
606 OS << "auto ";
607 if (!HasEmptyPlaceHolder)
608 OS << '(';
609 } else {
610 // If needed for precedence reasons, wrap the inner part in grouping parens.
611 SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder, false);
612 printBefore(T->getReturnType(), OS);
613 if (!PrevPHIsEmpty.get())
614 OS << '(';
615 }
616 }
617
printFunctionProtoAfter(const FunctionProtoType * T,raw_ostream & OS)618 void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
619 raw_ostream &OS) {
620 // If needed for precedence reasons, wrap the inner part in grouping parens.
621 if (!HasEmptyPlaceHolder)
622 OS << ')';
623 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
624
625 OS << '(';
626 {
627 ParamPolicyRAII ParamPolicy(Policy);
628 for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {
629 if (i) OS << ", ";
630 print(T->getParamType(i), OS, StringRef());
631 }
632 }
633
634 if (T->isVariadic()) {
635 if (T->getNumParams())
636 OS << ", ";
637 OS << "...";
638 } else if (T->getNumParams() == 0 && !Policy.LangOpts.CPlusPlus) {
639 // Do not emit int() if we have a proto, emit 'int(void)'.
640 OS << "void";
641 }
642
643 OS << ')';
644
645 FunctionType::ExtInfo Info = T->getExtInfo();
646
647 if (!InsideCCAttribute) {
648 switch (Info.getCC()) {
649 case CC_C:
650 // The C calling convention is the default on the vast majority of platforms
651 // we support. If the user wrote it explicitly, it will usually be printed
652 // while traversing the AttributedType. If the type has been desugared, let
653 // the canonical spelling be the implicit calling convention.
654 // FIXME: It would be better to be explicit in certain contexts, such as a
655 // cdecl function typedef used to declare a member function with the
656 // Microsoft C++ ABI.
657 break;
658 case CC_X86StdCall:
659 OS << " __attribute__((stdcall))";
660 break;
661 case CC_X86FastCall:
662 OS << " __attribute__((fastcall))";
663 break;
664 case CC_X86ThisCall:
665 OS << " __attribute__((thiscall))";
666 break;
667 case CC_X86Pascal:
668 OS << " __attribute__((pascal))";
669 break;
670 case CC_AAPCS:
671 OS << " __attribute__((pcs(\"aapcs\")))";
672 break;
673 case CC_AAPCS_VFP:
674 OS << " __attribute__((pcs(\"aapcs-vfp\")))";
675 break;
676 case CC_PnaclCall:
677 OS << " __attribute__((pnaclcall))";
678 break;
679 case CC_IntelOclBicc:
680 OS << " __attribute__((intel_ocl_bicc))";
681 break;
682 case CC_X86_64Win64:
683 OS << " __attribute__((ms_abi))";
684 break;
685 case CC_X86_64SysV:
686 OS << " __attribute__((sysv_abi))";
687 break;
688 }
689 }
690
691 if (Info.getNoReturn())
692 OS << " __attribute__((noreturn))";
693 if (Info.getRegParm())
694 OS << " __attribute__((regparm ("
695 << Info.getRegParm() << ")))";
696
697 if (unsigned quals = T->getTypeQuals()) {
698 OS << ' ';
699 AppendTypeQualList(OS, quals);
700 }
701
702 switch (T->getRefQualifier()) {
703 case RQ_None:
704 break;
705
706 case RQ_LValue:
707 OS << " &";
708 break;
709
710 case RQ_RValue:
711 OS << " &&";
712 break;
713 }
714 T->printExceptionSpecification(OS, Policy);
715
716 if (T->hasTrailingReturn()) {
717 OS << " -> ";
718 print(T->getReturnType(), OS, StringRef());
719 } else
720 printAfter(T->getReturnType(), OS);
721 }
722
printFunctionNoProtoBefore(const FunctionNoProtoType * T,raw_ostream & OS)723 void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T,
724 raw_ostream &OS) {
725 // If needed for precedence reasons, wrap the inner part in grouping parens.
726 SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder, false);
727 printBefore(T->getReturnType(), OS);
728 if (!PrevPHIsEmpty.get())
729 OS << '(';
730 }
printFunctionNoProtoAfter(const FunctionNoProtoType * T,raw_ostream & OS)731 void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,
732 raw_ostream &OS) {
733 // If needed for precedence reasons, wrap the inner part in grouping parens.
734 if (!HasEmptyPlaceHolder)
735 OS << ')';
736 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
737
738 OS << "()";
739 if (T->getNoReturnAttr())
740 OS << " __attribute__((noreturn))";
741 printAfter(T->getReturnType(), OS);
742 }
743
printTypeSpec(const NamedDecl * D,raw_ostream & OS)744 void TypePrinter::printTypeSpec(const NamedDecl *D, raw_ostream &OS) {
745 IdentifierInfo *II = D->getIdentifier();
746 OS << II->getName();
747 spaceBeforePlaceHolder(OS);
748 }
749
printUnresolvedUsingBefore(const UnresolvedUsingType * T,raw_ostream & OS)750 void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,
751 raw_ostream &OS) {
752 printTypeSpec(T->getDecl(), OS);
753 }
printUnresolvedUsingAfter(const UnresolvedUsingType * T,raw_ostream & OS)754 void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,
755 raw_ostream &OS) { }
756
printTypedefBefore(const TypedefType * T,raw_ostream & OS)757 void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
758 printTypeSpec(T->getDecl(), OS);
759 }
printTypedefAfter(const TypedefType * T,raw_ostream & OS)760 void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) { }
761
printTypeOfExprBefore(const TypeOfExprType * T,raw_ostream & OS)762 void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
763 raw_ostream &OS) {
764 OS << "typeof ";
765 if (T->getUnderlyingExpr())
766 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
767 spaceBeforePlaceHolder(OS);
768 }
printTypeOfExprAfter(const TypeOfExprType * T,raw_ostream & OS)769 void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
770 raw_ostream &OS) { }
771
printTypeOfBefore(const TypeOfType * T,raw_ostream & OS)772 void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) {
773 OS << "typeof(";
774 print(T->getUnderlyingType(), OS, StringRef());
775 OS << ')';
776 spaceBeforePlaceHolder(OS);
777 }
printTypeOfAfter(const TypeOfType * T,raw_ostream & OS)778 void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) { }
779
printDecltypeBefore(const DecltypeType * T,raw_ostream & OS)780 void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {
781 OS << "decltype(";
782 if (T->getUnderlyingExpr())
783 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
784 OS << ')';
785 spaceBeforePlaceHolder(OS);
786 }
printDecltypeAfter(const DecltypeType * T,raw_ostream & OS)787 void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) { }
788
printUnaryTransformBefore(const UnaryTransformType * T,raw_ostream & OS)789 void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,
790 raw_ostream &OS) {
791 IncludeStrongLifetimeRAII Strong(Policy);
792
793 switch (T->getUTTKind()) {
794 case UnaryTransformType::EnumUnderlyingType:
795 OS << "__underlying_type(";
796 print(T->getBaseType(), OS, StringRef());
797 OS << ')';
798 spaceBeforePlaceHolder(OS);
799 return;
800 }
801
802 printBefore(T->getBaseType(), OS);
803 }
printUnaryTransformAfter(const UnaryTransformType * T,raw_ostream & OS)804 void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,
805 raw_ostream &OS) {
806 IncludeStrongLifetimeRAII Strong(Policy);
807
808 switch (T->getUTTKind()) {
809 case UnaryTransformType::EnumUnderlyingType:
810 return;
811 }
812
813 printAfter(T->getBaseType(), OS);
814 }
815
printAutoBefore(const AutoType * T,raw_ostream & OS)816 void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
817 // If the type has been deduced, do not print 'auto'.
818 if (!T->getDeducedType().isNull()) {
819 printBefore(T->getDeducedType(), OS);
820 } else {
821 OS << (T->isDecltypeAuto() ? "decltype(auto)" : "auto");
822 spaceBeforePlaceHolder(OS);
823 }
824 }
printAutoAfter(const AutoType * T,raw_ostream & OS)825 void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {
826 // If the type has been deduced, do not print 'auto'.
827 if (!T->getDeducedType().isNull())
828 printAfter(T->getDeducedType(), OS);
829 }
830
printAtomicBefore(const AtomicType * T,raw_ostream & OS)831 void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {
832 IncludeStrongLifetimeRAII Strong(Policy);
833
834 OS << "_Atomic(";
835 print(T->getValueType(), OS, StringRef());
836 OS << ')';
837 spaceBeforePlaceHolder(OS);
838 }
printAtomicAfter(const AtomicType * T,raw_ostream & OS)839 void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) { }
840
841 /// Appends the given scope to the end of a string.
AppendScope(DeclContext * DC,raw_ostream & OS)842 void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS) {
843 if (DC->isTranslationUnit()) return;
844 if (DC->isFunctionOrMethod()) return;
845 AppendScope(DC->getParent(), OS);
846
847 if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
848 if (Policy.SuppressUnwrittenScope &&
849 (NS->isAnonymousNamespace() || NS->isInline()))
850 return;
851 if (NS->getIdentifier())
852 OS << NS->getName() << "::";
853 else
854 OS << "(anonymous namespace)::";
855 } else if (ClassTemplateSpecializationDecl *Spec
856 = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
857 IncludeStrongLifetimeRAII Strong(Policy);
858 OS << Spec->getIdentifier()->getName();
859 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
860 TemplateSpecializationType::PrintTemplateArgumentList(OS,
861 TemplateArgs.data(),
862 TemplateArgs.size(),
863 Policy);
864 OS << "::";
865 } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
866 if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl())
867 OS << Typedef->getIdentifier()->getName() << "::";
868 else if (Tag->getIdentifier())
869 OS << Tag->getIdentifier()->getName() << "::";
870 else
871 return;
872 }
873 }
874
printTag(TagDecl * D,raw_ostream & OS)875 void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {
876 if (Policy.SuppressTag)
877 return;
878
879 bool HasKindDecoration = false;
880
881 // bool SuppressTagKeyword
882 // = Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword;
883
884 // We don't print tags unless this is an elaborated type.
885 // In C, we just assume every RecordType is an elaborated type.
886 if (!(Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword ||
887 D->getTypedefNameForAnonDecl())) {
888 HasKindDecoration = true;
889 OS << D->getKindName();
890 OS << ' ';
891 }
892
893 // Compute the full nested-name-specifier for this type.
894 // In C, this will always be empty except when the type
895 // being printed is anonymous within other Record.
896 if (!Policy.SuppressScope)
897 AppendScope(D->getDeclContext(), OS);
898
899 if (const IdentifierInfo *II = D->getIdentifier())
900 OS << II->getName();
901 else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) {
902 assert(Typedef->getIdentifier() && "Typedef without identifier?");
903 OS << Typedef->getIdentifier()->getName();
904 } else {
905 // Make an unambiguous representation for anonymous types, e.g.
906 // (anonymous enum at /usr/include/string.h:120:9)
907
908 if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
909 OS << "(lambda";
910 HasKindDecoration = true;
911 } else {
912 OS << "(anonymous";
913 }
914
915 if (Policy.AnonymousTagLocations) {
916 // Suppress the redundant tag keyword if we just printed one.
917 // We don't have to worry about ElaboratedTypes here because you can't
918 // refer to an anonymous type with one.
919 if (!HasKindDecoration)
920 OS << " " << D->getKindName();
921
922 PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc(
923 D->getLocation());
924 if (PLoc.isValid()) {
925 OS << " at " << PLoc.getFilename()
926 << ':' << PLoc.getLine()
927 << ':' << PLoc.getColumn();
928 }
929 }
930
931 OS << ')';
932 }
933
934 // If this is a class template specialization, print the template
935 // arguments.
936 if (ClassTemplateSpecializationDecl *Spec
937 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
938 const TemplateArgument *Args;
939 unsigned NumArgs;
940 if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) {
941 const TemplateSpecializationType *TST =
942 cast<TemplateSpecializationType>(TAW->getType());
943 Args = TST->getArgs();
944 NumArgs = TST->getNumArgs();
945 } else {
946 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
947 Args = TemplateArgs.data();
948 NumArgs = TemplateArgs.size();
949 }
950 IncludeStrongLifetimeRAII Strong(Policy);
951 TemplateSpecializationType::PrintTemplateArgumentList(OS,
952 Args, NumArgs,
953 Policy);
954 }
955
956 spaceBeforePlaceHolder(OS);
957 }
958
printRecordBefore(const RecordType * T,raw_ostream & OS)959 void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
960 printTag(T->getDecl(), OS);
961 }
printRecordAfter(const RecordType * T,raw_ostream & OS)962 void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) { }
963
printEnumBefore(const EnumType * T,raw_ostream & OS)964 void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {
965 printTag(T->getDecl(), OS);
966 }
printEnumAfter(const EnumType * T,raw_ostream & OS)967 void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) { }
968
printTemplateTypeParmBefore(const TemplateTypeParmType * T,raw_ostream & OS)969 void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
970 raw_ostream &OS) {
971 if (IdentifierInfo *Id = T->getIdentifier())
972 OS << Id->getName();
973 else
974 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
975 spaceBeforePlaceHolder(OS);
976 }
printTemplateTypeParmAfter(const TemplateTypeParmType * T,raw_ostream & OS)977 void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,
978 raw_ostream &OS) { }
979
printSubstTemplateTypeParmBefore(const SubstTemplateTypeParmType * T,raw_ostream & OS)980 void TypePrinter::printSubstTemplateTypeParmBefore(
981 const SubstTemplateTypeParmType *T,
982 raw_ostream &OS) {
983 IncludeStrongLifetimeRAII Strong(Policy);
984 printBefore(T->getReplacementType(), OS);
985 }
printSubstTemplateTypeParmAfter(const SubstTemplateTypeParmType * T,raw_ostream & OS)986 void TypePrinter::printSubstTemplateTypeParmAfter(
987 const SubstTemplateTypeParmType *T,
988 raw_ostream &OS) {
989 IncludeStrongLifetimeRAII Strong(Policy);
990 printAfter(T->getReplacementType(), OS);
991 }
992
printSubstTemplateTypeParmPackBefore(const SubstTemplateTypeParmPackType * T,raw_ostream & OS)993 void TypePrinter::printSubstTemplateTypeParmPackBefore(
994 const SubstTemplateTypeParmPackType *T,
995 raw_ostream &OS) {
996 IncludeStrongLifetimeRAII Strong(Policy);
997 printTemplateTypeParmBefore(T->getReplacedParameter(), OS);
998 }
printSubstTemplateTypeParmPackAfter(const SubstTemplateTypeParmPackType * T,raw_ostream & OS)999 void TypePrinter::printSubstTemplateTypeParmPackAfter(
1000 const SubstTemplateTypeParmPackType *T,
1001 raw_ostream &OS) {
1002 IncludeStrongLifetimeRAII Strong(Policy);
1003 printTemplateTypeParmAfter(T->getReplacedParameter(), OS);
1004 }
1005
printTemplateSpecializationBefore(const TemplateSpecializationType * T,raw_ostream & OS)1006 void TypePrinter::printTemplateSpecializationBefore(
1007 const TemplateSpecializationType *T,
1008 raw_ostream &OS) {
1009 IncludeStrongLifetimeRAII Strong(Policy);
1010 T->getTemplateName().print(OS, Policy);
1011
1012 TemplateSpecializationType::PrintTemplateArgumentList(OS,
1013 T->getArgs(),
1014 T->getNumArgs(),
1015 Policy);
1016 spaceBeforePlaceHolder(OS);
1017 }
printTemplateSpecializationAfter(const TemplateSpecializationType * T,raw_ostream & OS)1018 void TypePrinter::printTemplateSpecializationAfter(
1019 const TemplateSpecializationType *T,
1020 raw_ostream &OS) { }
1021
printInjectedClassNameBefore(const InjectedClassNameType * T,raw_ostream & OS)1022 void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
1023 raw_ostream &OS) {
1024 printTemplateSpecializationBefore(T->getInjectedTST(), OS);
1025 }
printInjectedClassNameAfter(const InjectedClassNameType * T,raw_ostream & OS)1026 void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
1027 raw_ostream &OS) { }
1028
printElaboratedBefore(const ElaboratedType * T,raw_ostream & OS)1029 void TypePrinter::printElaboratedBefore(const ElaboratedType *T,
1030 raw_ostream &OS) {
1031 if (Policy.SuppressTag && isa<TagType>(T->getNamedType()))
1032 return;
1033 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1034 if (T->getKeyword() != ETK_None)
1035 OS << " ";
1036 NestedNameSpecifier* Qualifier = T->getQualifier();
1037 if (Qualifier)
1038 Qualifier->print(OS, Policy);
1039
1040 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1041 printBefore(T->getNamedType(), OS);
1042 }
printElaboratedAfter(const ElaboratedType * T,raw_ostream & OS)1043 void TypePrinter::printElaboratedAfter(const ElaboratedType *T,
1044 raw_ostream &OS) {
1045 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1046 printAfter(T->getNamedType(), OS);
1047 }
1048
printParenBefore(const ParenType * T,raw_ostream & OS)1049 void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {
1050 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1051 printBefore(T->getInnerType(), OS);
1052 OS << '(';
1053 } else
1054 printBefore(T->getInnerType(), OS);
1055 }
printParenAfter(const ParenType * T,raw_ostream & OS)1056 void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {
1057 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1058 OS << ')';
1059 printAfter(T->getInnerType(), OS);
1060 } else
1061 printAfter(T->getInnerType(), OS);
1062 }
1063
printDependentNameBefore(const DependentNameType * T,raw_ostream & OS)1064 void TypePrinter::printDependentNameBefore(const DependentNameType *T,
1065 raw_ostream &OS) {
1066 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1067 if (T->getKeyword() != ETK_None)
1068 OS << " ";
1069
1070 T->getQualifier()->print(OS, Policy);
1071
1072 OS << T->getIdentifier()->getName();
1073 spaceBeforePlaceHolder(OS);
1074 }
printDependentNameAfter(const DependentNameType * T,raw_ostream & OS)1075 void TypePrinter::printDependentNameAfter(const DependentNameType *T,
1076 raw_ostream &OS) { }
1077
printDependentTemplateSpecializationBefore(const DependentTemplateSpecializationType * T,raw_ostream & OS)1078 void TypePrinter::printDependentTemplateSpecializationBefore(
1079 const DependentTemplateSpecializationType *T, raw_ostream &OS) {
1080 IncludeStrongLifetimeRAII Strong(Policy);
1081
1082 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1083 if (T->getKeyword() != ETK_None)
1084 OS << " ";
1085
1086 if (T->getQualifier())
1087 T->getQualifier()->print(OS, Policy);
1088 OS << T->getIdentifier()->getName();
1089 TemplateSpecializationType::PrintTemplateArgumentList(OS,
1090 T->getArgs(),
1091 T->getNumArgs(),
1092 Policy);
1093 spaceBeforePlaceHolder(OS);
1094 }
printDependentTemplateSpecializationAfter(const DependentTemplateSpecializationType * T,raw_ostream & OS)1095 void TypePrinter::printDependentTemplateSpecializationAfter(
1096 const DependentTemplateSpecializationType *T, raw_ostream &OS) { }
1097
printPackExpansionBefore(const PackExpansionType * T,raw_ostream & OS)1098 void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,
1099 raw_ostream &OS) {
1100 printBefore(T->getPattern(), OS);
1101 }
printPackExpansionAfter(const PackExpansionType * T,raw_ostream & OS)1102 void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
1103 raw_ostream &OS) {
1104 printAfter(T->getPattern(), OS);
1105 OS << "...";
1106 }
1107
printAttributedBefore(const AttributedType * T,raw_ostream & OS)1108 void TypePrinter::printAttributedBefore(const AttributedType *T,
1109 raw_ostream &OS) {
1110 // Prefer the macro forms of the GC and ownership qualifiers.
1111 if (T->getAttrKind() == AttributedType::attr_objc_gc ||
1112 T->getAttrKind() == AttributedType::attr_objc_ownership)
1113 return printBefore(T->getEquivalentType(), OS);
1114
1115 printBefore(T->getModifiedType(), OS);
1116
1117 if (T->isMSTypeSpec()) {
1118 switch (T->getAttrKind()) {
1119 default: return;
1120 case AttributedType::attr_ptr32: OS << " __ptr32"; break;
1121 case AttributedType::attr_ptr64: OS << " __ptr64"; break;
1122 case AttributedType::attr_sptr: OS << " __sptr"; break;
1123 case AttributedType::attr_uptr: OS << " __uptr"; break;
1124 }
1125 spaceBeforePlaceHolder(OS);
1126 }
1127 }
1128
printAttributedAfter(const AttributedType * T,raw_ostream & OS)1129 void TypePrinter::printAttributedAfter(const AttributedType *T,
1130 raw_ostream &OS) {
1131 // Prefer the macro forms of the GC and ownership qualifiers.
1132 if (T->getAttrKind() == AttributedType::attr_objc_gc ||
1133 T->getAttrKind() == AttributedType::attr_objc_ownership)
1134 return printAfter(T->getEquivalentType(), OS);
1135
1136 // TODO: not all attributes are GCC-style attributes.
1137 if (T->isMSTypeSpec())
1138 return;
1139
1140 // If this is a calling convention attribute, don't print the implicit CC from
1141 // the modified type.
1142 SaveAndRestore<bool> MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());
1143
1144 printAfter(T->getModifiedType(), OS);
1145
1146 OS << " __attribute__((";
1147 switch (T->getAttrKind()) {
1148 default: llvm_unreachable("This attribute should have been handled already");
1149 case AttributedType::attr_address_space:
1150 OS << "address_space(";
1151 OS << T->getEquivalentType().getAddressSpace();
1152 OS << ')';
1153 break;
1154
1155 case AttributedType::attr_vector_size: {
1156 OS << "__vector_size__(";
1157 if (const VectorType *vector =T->getEquivalentType()->getAs<VectorType>()) {
1158 OS << vector->getNumElements();
1159 OS << " * sizeof(";
1160 print(vector->getElementType(), OS, StringRef());
1161 OS << ')';
1162 }
1163 OS << ')';
1164 break;
1165 }
1166
1167 case AttributedType::attr_neon_vector_type:
1168 case AttributedType::attr_neon_polyvector_type: {
1169 if (T->getAttrKind() == AttributedType::attr_neon_vector_type)
1170 OS << "neon_vector_type(";
1171 else
1172 OS << "neon_polyvector_type(";
1173 const VectorType *vector = T->getEquivalentType()->getAs<VectorType>();
1174 OS << vector->getNumElements();
1175 OS << ')';
1176 break;
1177 }
1178
1179 case AttributedType::attr_regparm: {
1180 // FIXME: When Sema learns to form this AttributedType, avoid printing the
1181 // attribute again in printFunctionProtoAfter.
1182 OS << "regparm(";
1183 QualType t = T->getEquivalentType();
1184 while (!t->isFunctionType())
1185 t = t->getPointeeType();
1186 OS << t->getAs<FunctionType>()->getRegParmType();
1187 OS << ')';
1188 break;
1189 }
1190
1191 case AttributedType::attr_objc_gc: {
1192 OS << "objc_gc(";
1193
1194 QualType tmp = T->getEquivalentType();
1195 while (tmp.getObjCGCAttr() == Qualifiers::GCNone) {
1196 QualType next = tmp->getPointeeType();
1197 if (next == tmp) break;
1198 tmp = next;
1199 }
1200
1201 if (tmp.isObjCGCWeak())
1202 OS << "weak";
1203 else
1204 OS << "strong";
1205 OS << ')';
1206 break;
1207 }
1208
1209 case AttributedType::attr_objc_ownership:
1210 OS << "objc_ownership(";
1211 switch (T->getEquivalentType().getObjCLifetime()) {
1212 case Qualifiers::OCL_None: llvm_unreachable("no ownership!");
1213 case Qualifiers::OCL_ExplicitNone: OS << "none"; break;
1214 case Qualifiers::OCL_Strong: OS << "strong"; break;
1215 case Qualifiers::OCL_Weak: OS << "weak"; break;
1216 case Qualifiers::OCL_Autoreleasing: OS << "autoreleasing"; break;
1217 }
1218 OS << ')';
1219 break;
1220
1221 // FIXME: When Sema learns to form this AttributedType, avoid printing the
1222 // attribute again in printFunctionProtoAfter.
1223 case AttributedType::attr_noreturn: OS << "noreturn"; break;
1224
1225 case AttributedType::attr_cdecl: OS << "cdecl"; break;
1226 case AttributedType::attr_fastcall: OS << "fastcall"; break;
1227 case AttributedType::attr_stdcall: OS << "stdcall"; break;
1228 case AttributedType::attr_thiscall: OS << "thiscall"; break;
1229 case AttributedType::attr_pascal: OS << "pascal"; break;
1230 case AttributedType::attr_ms_abi: OS << "ms_abi"; break;
1231 case AttributedType::attr_sysv_abi: OS << "sysv_abi"; break;
1232 case AttributedType::attr_pcs:
1233 case AttributedType::attr_pcs_vfp: {
1234 OS << "pcs(";
1235 QualType t = T->getEquivalentType();
1236 while (!t->isFunctionType())
1237 t = t->getPointeeType();
1238 OS << (t->getAs<FunctionType>()->getCallConv() == CC_AAPCS ?
1239 "\"aapcs\"" : "\"aapcs-vfp\"");
1240 OS << ')';
1241 break;
1242 }
1243 case AttributedType::attr_pnaclcall: OS << "pnaclcall"; break;
1244 case AttributedType::attr_inteloclbicc: OS << "inteloclbicc"; break;
1245 }
1246 OS << "))";
1247 }
1248
printObjCInterfaceBefore(const ObjCInterfaceType * T,raw_ostream & OS)1249 void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
1250 raw_ostream &OS) {
1251 OS << T->getDecl()->getName();
1252 spaceBeforePlaceHolder(OS);
1253 }
printObjCInterfaceAfter(const ObjCInterfaceType * T,raw_ostream & OS)1254 void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
1255 raw_ostream &OS) { }
1256
printObjCObjectBefore(const ObjCObjectType * T,raw_ostream & OS)1257 void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
1258 raw_ostream &OS) {
1259 if (T->qual_empty())
1260 return printBefore(T->getBaseType(), OS);
1261
1262 print(T->getBaseType(), OS, StringRef());
1263 OS << '<';
1264 bool isFirst = true;
1265 for (const auto *I : T->quals()) {
1266 if (isFirst)
1267 isFirst = false;
1268 else
1269 OS << ',';
1270 OS << I->getName();
1271 }
1272 OS << '>';
1273 spaceBeforePlaceHolder(OS);
1274 }
printObjCObjectAfter(const ObjCObjectType * T,raw_ostream & OS)1275 void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
1276 raw_ostream &OS) {
1277 if (T->qual_empty())
1278 return printAfter(T->getBaseType(), OS);
1279 }
1280
printObjCObjectPointerBefore(const ObjCObjectPointerType * T,raw_ostream & OS)1281 void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
1282 raw_ostream &OS) {
1283 T->getPointeeType().getLocalQualifiers().print(OS, Policy,
1284 /*appendSpaceIfNonEmpty=*/true);
1285
1286 assert(!T->isObjCSelType());
1287
1288 if (T->isObjCIdType() || T->isObjCQualifiedIdType())
1289 OS << "id";
1290 else if (T->isObjCClassType() || T->isObjCQualifiedClassType())
1291 OS << "Class";
1292 else
1293 OS << T->getInterfaceDecl()->getName();
1294
1295 if (!T->qual_empty()) {
1296 OS << '<';
1297 for (ObjCObjectPointerType::qual_iterator I = T->qual_begin(),
1298 E = T->qual_end();
1299 I != E; ++I) {
1300 OS << (*I)->getName();
1301 if (I+1 != E)
1302 OS << ',';
1303 }
1304 OS << '>';
1305 }
1306
1307 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&
1308 !T->isObjCClassType() && !T->isObjCQualifiedClassType()) {
1309 OS << " *"; // Don't forget the implicit pointer.
1310 } else {
1311 spaceBeforePlaceHolder(OS);
1312 }
1313 }
printObjCObjectPointerAfter(const ObjCObjectPointerType * T,raw_ostream & OS)1314 void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
1315 raw_ostream &OS) { }
1316
1317 void TemplateSpecializationType::
PrintTemplateArgumentList(raw_ostream & OS,const TemplateArgumentListInfo & Args,const PrintingPolicy & Policy)1318 PrintTemplateArgumentList(raw_ostream &OS,
1319 const TemplateArgumentListInfo &Args,
1320 const PrintingPolicy &Policy) {
1321 return PrintTemplateArgumentList(OS,
1322 Args.getArgumentArray(),
1323 Args.size(),
1324 Policy);
1325 }
1326
1327 void
PrintTemplateArgumentList(raw_ostream & OS,const TemplateArgument * Args,unsigned NumArgs,const PrintingPolicy & Policy,bool SkipBrackets)1328 TemplateSpecializationType::PrintTemplateArgumentList(
1329 raw_ostream &OS,
1330 const TemplateArgument *Args,
1331 unsigned NumArgs,
1332 const PrintingPolicy &Policy,
1333 bool SkipBrackets) {
1334 if (!SkipBrackets)
1335 OS << '<';
1336
1337 bool needSpace = false;
1338 for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
1339 // Print the argument into a string.
1340 SmallString<128> Buf;
1341 llvm::raw_svector_ostream ArgOS(Buf);
1342 if (Args[Arg].getKind() == TemplateArgument::Pack) {
1343 if (Args[Arg].pack_size() && Arg > 0)
1344 OS << ", ";
1345 PrintTemplateArgumentList(ArgOS,
1346 Args[Arg].pack_begin(),
1347 Args[Arg].pack_size(),
1348 Policy, true);
1349 } else {
1350 if (Arg > 0)
1351 OS << ", ";
1352 Args[Arg].print(Policy, ArgOS);
1353 }
1354 StringRef ArgString = ArgOS.str();
1355
1356 // If this is the first argument and its string representation
1357 // begins with the global scope specifier ('::foo'), add a space
1358 // to avoid printing the diagraph '<:'.
1359 if (!Arg && !ArgString.empty() && ArgString[0] == ':')
1360 OS << ' ';
1361
1362 OS << ArgString;
1363
1364 needSpace = (!ArgString.empty() && ArgString.back() == '>');
1365 }
1366
1367 // If the last character of our string is '>', add another space to
1368 // keep the two '>''s separate tokens. We don't *have* to do this in
1369 // C++0x, but it's still good hygiene.
1370 if (needSpace)
1371 OS << ' ';
1372
1373 if (!SkipBrackets)
1374 OS << '>';
1375 }
1376
1377 // Sadly, repeat all that with TemplateArgLoc.
1378 void TemplateSpecializationType::
PrintTemplateArgumentList(raw_ostream & OS,const TemplateArgumentLoc * Args,unsigned NumArgs,const PrintingPolicy & Policy)1379 PrintTemplateArgumentList(raw_ostream &OS,
1380 const TemplateArgumentLoc *Args, unsigned NumArgs,
1381 const PrintingPolicy &Policy) {
1382 OS << '<';
1383
1384 bool needSpace = false;
1385 for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
1386 if (Arg > 0)
1387 OS << ", ";
1388
1389 // Print the argument into a string.
1390 SmallString<128> Buf;
1391 llvm::raw_svector_ostream ArgOS(Buf);
1392 if (Args[Arg].getArgument().getKind() == TemplateArgument::Pack) {
1393 PrintTemplateArgumentList(ArgOS,
1394 Args[Arg].getArgument().pack_begin(),
1395 Args[Arg].getArgument().pack_size(),
1396 Policy, true);
1397 } else {
1398 Args[Arg].getArgument().print(Policy, ArgOS);
1399 }
1400 StringRef ArgString = ArgOS.str();
1401
1402 // If this is the first argument and its string representation
1403 // begins with the global scope specifier ('::foo'), add a space
1404 // to avoid printing the diagraph '<:'.
1405 if (!Arg && !ArgString.empty() && ArgString[0] == ':')
1406 OS << ' ';
1407
1408 OS << ArgString;
1409
1410 needSpace = (!ArgString.empty() && ArgString.back() == '>');
1411 }
1412
1413 // If the last character of our string is '>', add another space to
1414 // keep the two '>''s separate tokens. We don't *have* to do this in
1415 // C++0x, but it's still good hygiene.
1416 if (needSpace)
1417 OS << ' ';
1418
1419 OS << '>';
1420 }
1421
dump(const char * msg) const1422 void QualType::dump(const char *msg) const {
1423 if (msg)
1424 llvm::errs() << msg << ": ";
1425 LangOptions LO;
1426 print(llvm::errs(), PrintingPolicy(LO), "identifier");
1427 llvm::errs() << '\n';
1428 }
1429
dump() const1430 LLVM_DUMP_METHOD void QualType::dump() const { dump(nullptr); }
1431
dump() const1432 LLVM_DUMP_METHOD void Type::dump() const { QualType(this, 0).dump(); }
1433
getAsString() const1434 std::string Qualifiers::getAsString() const {
1435 LangOptions LO;
1436 return getAsString(PrintingPolicy(LO));
1437 }
1438
1439 // Appends qualifiers to the given string, separated by spaces. Will
1440 // prefix a space if the string is non-empty. Will not append a final
1441 // space.
getAsString(const PrintingPolicy & Policy) const1442 std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {
1443 SmallString<64> Buf;
1444 llvm::raw_svector_ostream StrOS(Buf);
1445 print(StrOS, Policy);
1446 return StrOS.str();
1447 }
1448
isEmptyWhenPrinted(const PrintingPolicy & Policy) const1449 bool Qualifiers::isEmptyWhenPrinted(const PrintingPolicy &Policy) const {
1450 if (getCVRQualifiers())
1451 return false;
1452
1453 if (getAddressSpace())
1454 return false;
1455
1456 if (getObjCGCAttr())
1457 return false;
1458
1459 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime())
1460 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
1461 return false;
1462
1463 return true;
1464 }
1465
1466 // Appends qualifiers to the given string, separated by spaces. Will
1467 // prefix a space if the string is non-empty. Will not append a final
1468 // space.
print(raw_ostream & OS,const PrintingPolicy & Policy,bool appendSpaceIfNonEmpty) const1469 void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
1470 bool appendSpaceIfNonEmpty) const {
1471 bool addSpace = false;
1472
1473 unsigned quals = getCVRQualifiers();
1474 if (quals) {
1475 AppendTypeQualList(OS, quals);
1476 addSpace = true;
1477 }
1478 if (unsigned addrspace = getAddressSpace()) {
1479 if (addSpace)
1480 OS << ' ';
1481 addSpace = true;
1482 switch (addrspace) {
1483 case LangAS::opencl_global:
1484 OS << "__global";
1485 break;
1486 case LangAS::opencl_local:
1487 OS << "__local";
1488 break;
1489 case LangAS::opencl_constant:
1490 OS << "__constant";
1491 break;
1492 default:
1493 OS << "__attribute__((address_space(";
1494 OS << addrspace;
1495 OS << ")))";
1496 }
1497 }
1498 if (Qualifiers::GC gc = getObjCGCAttr()) {
1499 if (addSpace)
1500 OS << ' ';
1501 addSpace = true;
1502 if (gc == Qualifiers::Weak)
1503 OS << "__weak";
1504 else
1505 OS << "__strong";
1506 }
1507 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
1508 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
1509 if (addSpace)
1510 OS << ' ';
1511 addSpace = true;
1512 }
1513
1514 switch (lifetime) {
1515 case Qualifiers::OCL_None: llvm_unreachable("none but true");
1516 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;
1517 case Qualifiers::OCL_Strong:
1518 if (!Policy.SuppressStrongLifetime)
1519 OS << "__strong";
1520 break;
1521
1522 case Qualifiers::OCL_Weak: OS << "__weak"; break;
1523 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
1524 }
1525 }
1526
1527 if (appendSpaceIfNonEmpty && addSpace)
1528 OS << ' ';
1529 }
1530
getAsString(const PrintingPolicy & Policy) const1531 std::string QualType::getAsString(const PrintingPolicy &Policy) const {
1532 std::string S;
1533 getAsStringInternal(S, Policy);
1534 return S;
1535 }
1536
getAsString(const Type * ty,Qualifiers qs)1537 std::string QualType::getAsString(const Type *ty, Qualifiers qs) {
1538 std::string buffer;
1539 LangOptions options;
1540 getAsStringInternal(ty, qs, buffer, PrintingPolicy(options));
1541 return buffer;
1542 }
1543
print(const Type * ty,Qualifiers qs,raw_ostream & OS,const PrintingPolicy & policy,const Twine & PlaceHolder)1544 void QualType::print(const Type *ty, Qualifiers qs,
1545 raw_ostream &OS, const PrintingPolicy &policy,
1546 const Twine &PlaceHolder) {
1547 SmallString<128> PHBuf;
1548 StringRef PH = PlaceHolder.toStringRef(PHBuf);
1549
1550 TypePrinter(policy).print(ty, qs, OS, PH);
1551 }
1552
getAsStringInternal(const Type * ty,Qualifiers qs,std::string & buffer,const PrintingPolicy & policy)1553 void QualType::getAsStringInternal(const Type *ty, Qualifiers qs,
1554 std::string &buffer,
1555 const PrintingPolicy &policy) {
1556 SmallString<256> Buf;
1557 llvm::raw_svector_ostream StrOS(Buf);
1558 TypePrinter(policy).print(ty, qs, StrOS, buffer);
1559 std::string str = StrOS.str();
1560 buffer.swap(str);
1561 }
1562