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