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