Clang Project

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