//===--- ASTPrinter.cpp - Swift Language AST Printer ----------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
//  This file implements printing for the Swift ASTs.
//
//===----------------------------------------------------------------------===//

#include "swift/AST/ASTPrinter.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/ASTVisitor.h"
#include "swift/AST/Attr.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Expr.h"
#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/Module.h"
#include "swift/AST/NameLookup.h"
#include "swift/AST/ParameterList.h"
#include "swift/AST/PrintOptions.h"
#include "swift/AST/ProtocolConformance.h"
#include "swift/AST/Stmt.h"
#include "swift/AST/TypeVisitor.h"
#include "swift/AST/TypeWalker.h"
#include "swift/AST/Types.h"
#include "swift/Basic/Defer.h"
#include "swift/Basic/PrimitiveParsing.h"
#include "swift/Basic/QuotedString.h"
#include "swift/Basic/STLExtras.h"
#include "swift/Basic/StringExtras.h"
#include "swift/Config.h"
#include "swift/Parse/Lexer.h"
#include "swift/Strings.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
#include "clang/Basic/Module.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <queue>

using namespace swift;

void PrintOptions::setBaseType(Type T) {
  TransformContext = TypeTransformContext(T);
}

void PrintOptions::initForSynthesizedExtension(TypeOrExtensionDecl D) {
  TransformContext = TypeTransformContext(D);
}

void PrintOptions::clearSynthesizedExtension() {
  TransformContext.reset();
}

static bool isPublicOrUsableFromInline(const ValueDecl *VD) {
  AccessScope scope =
      VD->getFormalAccessScope(/*useDC*/nullptr,
                               /*treatUsableFromInlineAsPublic*/true);
  return scope.isPublic();
}

static bool isPublicOrUsableFromInline(Type ty) {
  // Note the double negative here: we're looking for any referenced decls that
  // are *not* public-or-usableFromInline.
  return !ty.findIf([](Type typePart) -> bool {
    // FIXME: If we have an internal typealias for a non-internal type, we ought
    // to be able to print it by desugaring.
    if (auto *aliasTy = dyn_cast<NameAliasType>(typePart.getPointer()))
      return !isPublicOrUsableFromInline(aliasTy->getDecl());
    if (auto *nominal = typePart->getAnyNominal())
      return !isPublicOrUsableFromInline(nominal);
    return false;
  });
}

static bool contributesToParentTypeStorage(const AbstractStorageDecl *ASD) {
  auto *DC = ASD->getDeclContext()->getAsDecl();
  if (!DC) return false;
  auto *ND = dyn_cast<NominalTypeDecl>(DC);
  if (!ND) return false;
  return !ND->isResilient() && ASD->hasStorage() && !ASD->isStatic();
}

PrintOptions PrintOptions::printParseableInterfaceFile() {
  PrintOptions result;
  result.PrintLongAttrsOnSeparateLines = true;
  result.TypeDefinitions = true;
  result.PrintIfConfig = false;
  result.FullyQualifiedTypes = true;
  result.AllowNullTypes = false;
  result.SkipImports = true;
  result.OmitNameOfInaccessibleProperties = true;
  result.FunctionDefinitions = true;
  result.CollapseSingleGetterProperty = false;
  result.VarInitializers = true;

  result.FunctionBody = [](const ValueDecl *decl, ASTPrinter &printer) {
    auto AFD = dyn_cast<AbstractFunctionDecl>(decl);
    if (!AFD || !AFD->hasInlinableBodyText()) return;
    if (AFD->getResilienceExpansion() != ResilienceExpansion::Minimal)
      return;
    SmallString<128> scratch;
    printer << " " << AFD->getInlinableBodyText(scratch);
  };

  class ShouldPrintForParseableInterface : public ShouldPrintChecker {
    bool shouldPrint(const Decl *D, const PrintOptions &options) override {
      // Skip anything that isn't 'public' or '@usableFromInline'.
      if (auto *VD = dyn_cast<ValueDecl>(D)) {
        if (!isPublicOrUsableFromInline(VD)) {
          // We do want to print private stored properties, without their
          // original names present.
          if (auto *ASD = dyn_cast<AbstractStorageDecl>(VD))
            if (contributesToParentTypeStorage(ASD))
              return true;
          return false;
        }
      }

      // Skip extensions that extend things we wouldn't print.
      if (auto *ED = dyn_cast<ExtensionDecl>(D)) {
        if (!shouldPrint(ED->getExtendedNominal(), options))
          return false;
        for (const Requirement &req : ED->getGenericRequirements()) {
          if (!isPublicOrUsableFromInline(req.getFirstType()))
            return false;

          switch (req.getKind()) {
          case RequirementKind::Conformance:
          case RequirementKind::Superclass:
          case RequirementKind::SameType:
            if (!isPublicOrUsableFromInline(req.getSecondType()))
              return false;
            break;
          case RequirementKind::Layout:
            break;
          }
        }
      }

      // Skip typealiases that just redeclare generic parameters.
      if (auto *alias = dyn_cast<TypeAliasDecl>(D)) {
        if (alias->isImplicit()) {
          const Decl *parent =
              D->getDeclContext()->getAsDecl();
          if (auto *genericCtx = parent->getAsGenericContext()) {
            bool matchesGenericParam =
                llvm::any_of(genericCtx->getInnermostGenericParamTypes(),
                             [alias](const GenericTypeParamType *param) {
              return param->getName() == alias->getName();
            });
            if (matchesGenericParam)
              return false;
          }
        }
      }

      return ShouldPrintChecker::shouldPrint(D, options);
    }
  };
  result.CurrentPrintabilityChecker =
      std::make_shared<ShouldPrintForParseableInterface>();

  // FIXME: We don't really need 'public' on everything; we could just change
  // the default to 'public' and mark the 'internal' things.
  result.PrintAccess = true;

  result.ExcludeAttrList = {DAK_ImplicitlyUnwrappedOptional, DAK_AccessControl,
                            DAK_SetterAccess};

  return result;
}

TypeTransformContext::TypeTransformContext(Type T)
    : BaseType(T.getPointer()) {
  assert(T->mayHaveMembers());
}

TypeTransformContext::TypeTransformContext(TypeOrExtensionDecl D)
    : BaseType(nullptr), Decl(D) {
  if (auto NTD = Decl.Decl.dyn_cast<NominalTypeDecl *>())
    BaseType = NTD->getDeclaredTypeInContext().getPointer();
  else {
    auto *ED = Decl.Decl.get<ExtensionDecl *>();
    BaseType = ED->getDeclaredTypeInContext().getPointer();
  }
}

TypeOrExtensionDecl TypeTransformContext::getDecl() const { return Decl; }

DeclContext *TypeTransformContext::getDeclContext() const {
  return Decl.getAsDecl()->getDeclContext();
}

Type TypeTransformContext::getBaseType() const {
  return Type(BaseType);
}

bool TypeTransformContext::isPrintingSynthesizedExtension() const {
  return !Decl.isNull();
}

std::string ASTPrinter::sanitizeUtf8(StringRef Text) {
  llvm::SmallString<256> Builder;
  Builder.reserve(Text.size());
  const llvm::UTF8* Data = reinterpret_cast<const llvm::UTF8*>(Text.begin());
  const llvm::UTF8* End = reinterpret_cast<const llvm::UTF8*>(Text.end());
  StringRef Replacement = u8"\ufffd";
  while (Data < End) {
    auto Step = llvm::getNumBytesForUTF8(*Data);
    if (Data + Step > End) {
      Builder.append(Replacement);
      break;
    }

    if (llvm::isLegalUTF8Sequence(Data, Data + Step)) {
      Builder.append(Data, Data + Step);
    } else {

      // If malformed, add replacement characters.
      Builder.append(Replacement);
    }
    Data += Step;
  }
  return Builder.str();
}

ValueDecl* ASTPrinter::findConformancesWithDocComment(ValueDecl *VD) {
  assert(VD->getRawComment().isEmpty());
  std::queue<ValueDecl*> AllConformances;
  AllConformances.push(VD);
  while (!AllConformances.empty()) {
    auto *VD = AllConformances.front();
    AllConformances.pop();
    if (VD->getRawComment().isEmpty()) {
      for (auto *Req : VD->getSatisfiedProtocolRequirements()) {
        AllConformances.push(Req);
      }
    } else {
      return VD;
    }
  }
  return nullptr;
}

void ASTPrinter::anchor() {}

void ASTPrinter::printIndent() {
  llvm::SmallString<16> Str;
  for (unsigned i = 0; i != CurrentIndentation; ++i)
    Str += ' ';

  printText(Str);
}

void ASTPrinter::printTextImpl(StringRef Text) {
  forceNewlines();
  printText(Text);
}

void ASTPrinter::printTypeRef(Type T, const TypeDecl *RefTo, Identifier Name) {
  PrintNameContext Context = PrintNameContext::Normal;
  if (isa<GenericTypeParamDecl>(RefTo)) {
    Context = PrintNameContext::GenericParameter;
  } else if (T && T->is<DynamicSelfType>()) {
    assert(T->castTo<DynamicSelfType>()->getSelfType()->getAnyNominal() &&
           "protocol Self handled as GenericTypeParamDecl");
    Context = PrintNameContext::ClassDynamicSelf;
  }

  printName(Name, Context);
}

void ASTPrinter::printModuleRef(ModuleEntity Mod, Identifier Name) {
  printName(Name);
}

void ASTPrinter::callPrintDeclPre(const Decl *D,
                                  Optional<BracketOptions> Bracket) {
  forceNewlines();

  if (SynthesizeTarget && isa<ExtensionDecl>(D))
    printSynthesizedExtensionPre(cast<ExtensionDecl>(D), SynthesizeTarget, Bracket);
  else
    printDeclPre(D, Bracket);
}

ASTPrinter &ASTPrinter::operator<<(unsigned long long N) {
  llvm::SmallString<32> Str;
  llvm::raw_svector_ostream OS(Str);
  OS << N;
  printTextImpl(OS.str());
  return *this;
}

ASTPrinter &ASTPrinter::operator<<(UUID UU) {
  llvm::SmallString<UUID::StringBufferSize> Str;
  UU.toString(Str);
  printTextImpl(Str);
  return *this;
}

ASTPrinter &ASTPrinter::operator<<(DeclName name) {
  llvm::SmallString<32> str;
  llvm::raw_svector_ostream os(str);
  name.print(os);
  printTextImpl(os.str());
  return *this;
}

llvm::raw_ostream &swift::
operator<<(llvm::raw_ostream &OS, tok keyword) {
  switch (keyword) {
#define KEYWORD(KW) case tok::kw_##KW: OS << #KW; break;
#define POUND_KEYWORD(KW) case tok::pound_##KW: OS << "#"#KW; break;
#define PUNCTUATOR(PUN, TEXT) case tok::PUN: OS << TEXT; break;
#include "swift/Syntax/TokenKinds.def"
  default:
    llvm_unreachable("unexpected keyword or punctuator kind");
  }
  return OS;
}

uint8_t swift::getKeywordLen(tok keyword) {
  switch (keyword) {
#define KEYWORD(KW) case tok::kw_##KW: return StringRef(#KW).size();
#define POUND_KEYWORD(KW) case tok::pound_##KW: return StringRef("#"#KW).size();
#define PUNCTUATOR(PUN, TEXT) case tok::PUN: return StringRef(TEXT).size();
#include "swift/Syntax/TokenKinds.def"
  default:
    llvm_unreachable("unexpected keyword or punctuator kind");
  }
}

StringRef swift::getCodePlaceholder() { return "<#code#>"; }

ASTPrinter &operator<<(ASTPrinter &printer, tok keyword) {
  SmallString<16> Buffer;
  llvm::raw_svector_ostream OS(Buffer);
  OS << keyword;
  printer.printKeyword(Buffer.str());
  return printer;
}

/// Determine whether to escape the given keyword in the given context.
static bool escapeKeywordInContext(StringRef keyword, PrintNameContext context){
  switch (context) {
  case PrintNameContext::Normal:
  case PrintNameContext::Attribute:
    return true;
  case PrintNameContext::Keyword:
    return false;

  case PrintNameContext::ClassDynamicSelf:
  case PrintNameContext::GenericParameter:
    return keyword != "Self";

  case PrintNameContext::FunctionParameterExternal:
  case PrintNameContext::FunctionParameterLocal:
  case PrintNameContext::TupleElement:
    return !canBeArgumentLabel(keyword);
  }

  llvm_unreachable("Unhandled PrintNameContext in switch.");
}

void ASTPrinter::printName(Identifier Name, PrintNameContext Context) {
  callPrintNamePre(Context);

  if (Name.empty()) {
    *this << "_";
    printNamePost(Context);
    return;
  }
  bool IsKeyword = llvm::StringSwitch<bool>(Name.str())
#define KEYWORD(KW) \
      .Case(#KW, true)
#include "swift/Syntax/TokenKinds.def"
      .Default(false);

  if (IsKeyword)
    IsKeyword = escapeKeywordInContext(Name.str(), Context);

  if (IsKeyword)
    *this << "`";
  *this << Name.str();
  if (IsKeyword)
    *this << "`";

  printNamePost(Context);
}

void StreamPrinter::printText(StringRef Text) {
  OS << Text;
}

/// Whether we will be printing a TypeLoc by using the TypeRepr printer
static bool willUseTypeReprPrinting(TypeLoc tyLoc,
                                    Type currentType,
                                    PrintOptions options) {
  // Special case for when transforming archetypes
  if (currentType && tyLoc.getType())
    return false;

  return ((options.PreferTypeRepr && tyLoc.hasLocation()) ||
          (tyLoc.getType().isNull() && tyLoc.getTypeRepr()));
}

namespace {
/// \brief AST pretty-printer.
class PrintAST : public ASTVisitor<PrintAST> {
  ASTPrinter &Printer;
  PrintOptions Options;
  unsigned IndentLevel = 0;
  Decl *Current = nullptr;
  Type CurrentType;

  friend DeclVisitor<PrintAST>;

  /// \brief RAII object that increases the indentation level.
  class IndentRAII {
    PrintAST &Self;
    bool DoIndent;

  public:
    IndentRAII(PrintAST &self, bool DoIndent = true)
        : Self(self), DoIndent(DoIndent) {
      if (DoIndent)
        Self.IndentLevel += Self.Options.Indent;
    }

    ~IndentRAII() {
      if (DoIndent)
        Self.IndentLevel -= Self.Options.Indent;
    }
  };

  /// \brief Indent the current number of indentation spaces.
  void indent() {
    Printer.setIndent(IndentLevel);
  }

  /// \brief Record the location of this declaration, which is about to
  /// be printed, marking the name and signature end locations.
  template<typename FnTy>
  void recordDeclLoc(Decl *decl, const FnTy &NameFn,
                     llvm::function_ref<void()> ParamFn = []{}) {
    Printer.callPrintDeclLoc(decl);
    NameFn();
    Printer.printDeclNameEndLoc(decl);
    ParamFn();
    Printer.printDeclNameOrSignatureEndLoc(decl);
  }

  void printSourceRange(CharSourceRange Range, ASTContext &Ctx) {
    Printer << Ctx.SourceMgr.extractText(Range);
  }

  void printClangDocumentationComment(const clang::Decl *D) {
    const auto &ClangContext = D->getASTContext();
    const clang::RawComment *RC = ClangContext.getRawCommentForAnyRedecl(D);
    if (!RC)
      return;

    bool Invalid;
    unsigned StartLocCol =
        ClangContext.getSourceManager().getSpellingColumnNumber(
            RC->getLocStart(), &Invalid);
    if (Invalid)
      StartLocCol = 0;

    unsigned WhitespaceToTrim = StartLocCol ? StartLocCol - 1 : 0;

    SmallVector<StringRef, 8> Lines;

    StringRef RawText =
        RC->getRawText(ClangContext.getSourceManager()).rtrim("\n\r");
    trimLeadingWhitespaceFromLines(RawText, WhitespaceToTrim, Lines);

    for (auto Line : Lines) {
      Printer << ASTPrinter::sanitizeUtf8(Line);
      Printer.printNewline();
    }
  }

  void printRawComment(RawComment RC) {
    indent();

    SmallVector<StringRef, 8> Lines;
    for (const auto &SRC : RC.Comments) {
      Lines.clear();

      StringRef RawText = SRC.RawText.rtrim("\n\r");
      unsigned WhitespaceToTrim = SRC.StartColumn - 1;
      trimLeadingWhitespaceFromLines(RawText, WhitespaceToTrim, Lines);

      for (auto Line : Lines) {
        Printer << Line;
        Printer.printNewline();
      }
    }
  }

  void printSwiftDocumentationComment(const Decl *D) {
    auto RC = D->getRawComment();
    if (RC.isEmpty() && !Options.ElevateDocCommentFromConformance)
      return;

    if (RC.isEmpty()) {
      if (auto *VD = dyn_cast<ValueDecl>(D)) {
        if (auto *Req = ASTPrinter::findConformancesWithDocComment(
            const_cast<ValueDecl*>(VD))) {
          printRawComment(Req->getRawComment());
        }
      }
    } else {
      printRawComment(RC);
    }
  }

  void printDocumentationComment(const Decl *D) {
    if (!Options.PrintDocumentationComments)
      return;

    // Try to print a comment from Clang.
    auto MaybeClangNode = D->getClangNode();
    if (MaybeClangNode) {
      if (auto *CD = MaybeClangNode.getAsDecl())
        printClangDocumentationComment(CD);
      return;
    }

    printSwiftDocumentationComment(D);
  }

  void printStaticKeyword(StaticSpellingKind StaticSpelling) {
    switch (StaticSpelling) {
    case StaticSpellingKind::None:
      llvm_unreachable("should not be called for non-static decls");
    case StaticSpellingKind::KeywordStatic:
      Printer << tok::kw_static << " ";
      break;
    case StaticSpellingKind::KeywordClass:
      Printer << tok::kw_class << " ";
      break;
    }
  }

  void printAccess(AccessLevel access, StringRef suffix = "") {
    switch (access) {
    case AccessLevel::Private:
      Printer << tok::kw_private;
      break;
    case AccessLevel::FilePrivate:
      Printer << tok::kw_fileprivate;
      break;
    case AccessLevel::Internal:
      if (!Options.PrintInternalAccessKeyword)
        return;
      Printer << tok::kw_internal;
      break;
    case AccessLevel::Public:
      Printer << tok::kw_public;
      break;
    case AccessLevel::Open:
      Printer.printKeyword("open");
      break;
    }
    Printer << suffix << " ";
  }

  void printAccess(const ValueDecl *D) {
    assert(!llvm::is_contained(Options.ExcludeAttrList, DAK_AccessControl) ||
           llvm::is_contained(Options.ExcludeAttrList, DAK_SetterAccess));

    if (!Options.PrintAccess || isa<ProtocolDecl>(D->getDeclContext()))
      return;
    if (D->getAttrs().hasAttribute<AccessControlAttr>() &&
        !llvm::is_contained(Options.ExcludeAttrList, DAK_AccessControl))
      return;

    printAccess(D->getFormalAccess());
    bool shouldSkipSetterAccess =
      llvm::is_contained(Options.ExcludeAttrList, DAK_SetterAccess);

    if (auto storageDecl = dyn_cast<AbstractStorageDecl>(D)) {
      if (auto setter = storageDecl->getSetter()) {
        AccessLevel setterAccess = setter->getFormalAccess();
        if (setterAccess != D->getFormalAccess() && !shouldSkipSetterAccess)
          printAccess(setterAccess, "(set)");
      }
    }
  }

  void printTypeWithOptions(Type T, PrintOptions options) {
    if (options.TransformContext) {
      // FIXME: it's not clear exactly what we want to keep from the existing
      // options, and what we want to discard.
      PrintOptions FreshOptions;
      FreshOptions.ExcludeAttrList = options.ExcludeAttrList;
      FreshOptions.ExclusiveAttrList = options.ExclusiveAttrList;
      FreshOptions.PrintOptionalAsImplicitlyUnwrapped = options.PrintOptionalAsImplicitlyUnwrapped;
      T.print(Printer, FreshOptions);
      return;
    }

    T.print(Printer, options);
  }

  void printType(Type T) { printTypeWithOptions(T, Options); }

  void printTransformedTypeWithOptions(Type T, PrintOptions options) {
    if (CurrentType) {
      if (T->hasArchetype()) {
        // Get the interface type, since TypeLocs still have
        // contextual types in them.
        T = T->mapTypeOutOfContext();
      }

      auto *M = Current->getDeclContext()->getParentModule();
      SubstitutionMap subMap;

      if (auto *NTD = dyn_cast<NominalTypeDecl>(Current))
        subMap = CurrentType->getContextSubstitutionMap(M, NTD);
      else if (auto *ED = dyn_cast<ExtensionDecl>(Current))
        subMap = CurrentType->getContextSubstitutionMap(M, ED);
      else {
        subMap = CurrentType->getMemberSubstitutionMap(
          M, cast<ValueDecl>(Current));
      }

      T = T.subst(subMap,
                  SubstFlags::DesugarMemberTypes | SubstFlags::UseErrorType);
    }

    printTypeWithOptions(T, options);
  }

  void printTransformedType(Type T) {
    printTransformedTypeWithOptions(T, Options);
  }

  void printTypeLocWithOptions(const TypeLoc &TL, PrintOptions options) {
    if (CurrentType && TL.getType()) {
      printTransformedTypeWithOptions(TL.getType(), options);
      return;
    }

    // Print a TypeRepr if instructed to do so by options, or if the type
    // is null.
    if (willUseTypeReprPrinting(TL, CurrentType, options)) {
      if (auto repr = TL.getTypeRepr())
        repr->print(Printer, options);
      return;
    }

    TL.getType().print(Printer, options);
  }

  void printTypeLoc(const TypeLoc &TL) { printTypeLocWithOptions(TL, Options); }

  void printTypeLocForImplicitlyUnwrappedOptional(TypeLoc TL) {
    PrintOptions options = Options;
    options.PrintOptionalAsImplicitlyUnwrapped = true;
    printTypeLocWithOptions(TL, options);
  }

  void printContextIfNeeded(const Decl *decl) {
    if (IndentLevel > 0)
      return;

    switch (Options.ShouldQualifyNestedDeclarations) {
    case PrintOptions::QualifyNestedDeclarations::Never:
      return;
    case PrintOptions::QualifyNestedDeclarations::TypesOnly:
      if (!isa<TypeDecl>(decl))
        return;
      break;
    case PrintOptions::QualifyNestedDeclarations::Always:
      break;
    }

    auto *container = dyn_cast<NominalTypeDecl>(decl->getDeclContext());
    if (!container)
      return;
    printType(container->getDeclaredInterfaceType());
    Printer << ".";
  }

  void printAttributes(const Decl *D);
  void printTypedPattern(const TypedPattern *TP);
  void printBraceStmt(const BraceStmt *stmt, bool newlineIfEmpty = true);
  void printAccessorDecl(const AccessorDecl *decl);

public:
  void printPattern(const Pattern *pattern);

  enum GenericSignatureFlags {
    PrintParams = 1,
    PrintRequirements = 2,
    InnermostOnly = 4,
    SwapSelfAndDependentMemberType = 8,
    PrintInherited = 16,
  };

  void printInheritedFromRequirementSignature(ProtocolDecl *proto,
                                              Decl *attachingTo);
  void printWhereClauseFromRequirementSignature(ProtocolDecl *proto,
                                                Decl *attachingTo);
  void printTrailingWhereClause(TrailingWhereClause *whereClause);

  void printGenericSignature(const GenericSignature *genericSig,
                             unsigned flags);
  void
  printGenericSignature(const GenericSignature *genericSig, unsigned flags,
                        llvm::function_ref<bool(const Requirement &)> filter);
  void printSingleDepthOfGenericSignature(
      TypeArrayView<GenericTypeParamType> genericParams,
      ArrayRef<Requirement> requirements, unsigned flags,
      llvm::function_ref<bool(const Requirement &)> filter);
  void printRequirement(const Requirement &req);

private:
  bool shouldPrint(const Decl *D, bool Notify = false);
  bool shouldPrintPattern(const Pattern *P);
  void printPatternType(const Pattern *P);
  void printAccessors(const AbstractStorageDecl *ASD);
  void printMutatingModifiersIfNeeded(const AccessorDecl *accessor);
  void printMembersOfDecl(Decl * NTD, bool needComma = false,
                          bool openBracket = true, bool closeBracket = true);
  void printMembers(ArrayRef<Decl *> members, bool needComma = false,
                    bool openBracket = true, bool closeBracket = true);
  void printGenericDeclGenericParams(GenericContext *decl);
  void printGenericDeclGenericRequirements(GenericContext *decl);
  void printInherited(const Decl *decl);
  void printBodyIfNecessary(const AbstractFunctionDecl *decl);

  void printEnumElement(EnumElementDecl *elt);

  /// \returns true if anything was printed.
  bool printASTNodes(const ArrayRef<ASTNode> &Elements, bool NeedIndent = true);

  void printOneParameter(const ParamDecl *param, ParameterTypeFlags paramFlags,
                         bool ArgNameIsAPIByDefault);

  void printParameterList(ParameterList *PL,
                          ArrayRef<AnyFunctionType::Param> params,
                          bool isAPINameByDefault);

  /// \brief Print the function parameters in curried or selector style,
  /// to match the original function declaration.
  void printFunctionParameters(AbstractFunctionDecl *AFD);

#define DECL(Name,Parent) void visit##Name##Decl(Name##Decl *decl);
#define ABSTRACT_DECL(Name, Parent)
#define DECL_RANGE(Name,Start,End)
#include "swift/AST/DeclNodes.def"

#define STMT(Name, Parent) void visit##Name##Stmt(Name##Stmt *stmt);
#include "swift/AST/StmtNodes.def"

  void printSynthesizedExtension(Type ExtendedType, ExtensionDecl *ExtDecl);

  void printExtension(ExtensionDecl* ExtDecl);

public:
  PrintAST(ASTPrinter &Printer, const PrintOptions &Options)
      : Printer(Printer), Options(Options) {
    if (Options.TransformContext)
      CurrentType = Options.TransformContext->getBaseType();
  }

  using ASTVisitor::visit;

  bool visit(Decl *D) {
    if (!shouldPrint(D, true))
      return false;

    Decl *Old = Current;
    Current = D;
    SWIFT_DEFER { Current = Old; };

    Type OldType = CurrentType;
    if (CurrentType && (Old != nullptr || Options.PrintAsMember)) {
      if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
        auto Subs = CurrentType->getContextSubstitutionMap(
          Options.CurrentModule, NTD->getDeclContext());
        CurrentType = NTD->getDeclaredInterfaceType().subst(Subs);
      }
    }

    SWIFT_DEFER { CurrentType = OldType; };

    bool Synthesize =
        Options.TransformContext &&
        Options.TransformContext->isPrintingSynthesizedExtension() &&
        isa<ExtensionDecl>(D);
    if (Synthesize) {
      Printer.setSynthesizedTarget(Options.TransformContext->getDecl());
    }

    // We want to print a newline before doc comments.  Swift code already
    // handles this, but we need to insert it for clang doc comments when not
    // printing other clang comments. Do it now so the printDeclPre callback
    // happens after the newline.
    if (Options.PrintDocumentationComments &&
        !Options.PrintRegularClangComments &&
        D->hasClangNode()) {
      auto clangNode = D->getClangNode();
      auto clangDecl = clangNode.getAsDecl();
      if (clangDecl &&
          clangDecl->getASTContext().getRawCommentForAnyRedecl(clangDecl)) {
        Printer.printNewline();
        indent();
      }
    }

    Printer.callPrintDeclPre(D, Options.BracketOptions);

    ASTVisitor::visit(D);

    if (Synthesize) {
      Printer.setSynthesizedTarget({});
      Printer.printSynthesizedExtensionPost(cast<ExtensionDecl>(D),
                                            Options.TransformContext->getDecl(),
                                            Options.BracketOptions);
    } else {
      Printer.callPrintDeclPost(D, Options.BracketOptions);
    }

    return true;
  }

};
} // unnamed namespace

static StaticSpellingKind getCorrectStaticSpelling(const Decl *D) {
  if (auto *VD = dyn_cast<VarDecl>(D)) {
    return VD->getCorrectStaticSpelling();
  } else if (auto *PBD = dyn_cast<PatternBindingDecl>(D)) {
    return PBD->getCorrectStaticSpelling();
  } else if (auto *FD = dyn_cast<FuncDecl>(D)) {
    return FD->getCorrectStaticSpelling();
  } else {
    return StaticSpellingKind::None;
  }
}

static bool hasMutatingGetter(const AbstractStorageDecl *ASD) {
  return ASD->getGetter() && ASD->isGetterMutating();
}

static bool hasNonMutatingSetter(const AbstractStorageDecl *ASD) {
  if (!ASD->isSettable(nullptr)) return false;
  auto setter = ASD->getSetter();
  return setter && setter->isExplicitNonMutating();
}

static bool hasLessAccessibleSetter(const AbstractStorageDecl *ASD) {
  return ASD->getSetterFormalAccess() < ASD->getFormalAccess();
}

void PrintAST::printAttributes(const Decl *D) {
  if (Options.SkipAttributes)
    return;

  // Save the current number of exclude attrs to restore once we're done.
  unsigned originalExcludeAttrCount = Options.ExcludeAttrList.size();

  if (Options.PrintImplicitAttrs) {

    // Don't print a redundant 'final' if we are printing a 'static' decl.
    if (D->getDeclContext()->getSelfClassDecl() &&
        getCorrectStaticSpelling(D) == StaticSpellingKind::KeywordStatic) {
      Options.ExcludeAttrList.push_back(DAK_Final);
    }

    if (auto vd = dyn_cast<VarDecl>(D)) {
      // Don't print @_hasInitialValue if we're printing an initializer
      // expression.
      if (vd->isInitExposedToClients())
        Options.ExcludeAttrList.push_back(DAK_HasInitialValue);

      if (!Options.PrintForSIL) {
        // Don't print @_hasStorage if the value is simply stored, or the
        // decl is resilient.
        if (vd->isResilient() ||
            (vd->getImplInfo().isSimpleStored() &&
             !hasLessAccessibleSetter(vd)))
          Options.ExcludeAttrList.push_back(DAK_HasStorage);
      }
    }

    // Don't print any contextual decl modifiers.
    // We will handle 'mutating' and 'nonmutating' separately.
    if (isa<AccessorDecl>(D)) {
#define EXCLUDE_ATTR(Class) Options.ExcludeAttrList.push_back(DAK_##Class);
#define CONTEXTUAL_DECL_ATTR(X, Class, Y, Z) EXCLUDE_ATTR(Class)
#define CONTEXTUAL_SIMPLE_DECL_ATTR(X, Class, Y, Z) EXCLUDE_ATTR(Class)
#define CONTEXTUAL_DECL_ATTR_ALIAS(X, Class) EXCLUDE_ATTR(Class)
#include "swift/AST/Attr.def"
    }

    // If the declaration is implicitly @objc, print the attribute now.
    if (auto VD = dyn_cast<ValueDecl>(D)) {
      if (VD->isObjC() && !VD->getAttrs().hasAttribute<ObjCAttr>()) {
        Printer.printAttrName("@objc");
        Printer << " ";
      }
    }
  }

  D->getAttrs().print(Printer, Options, D);

  // Explicitly print 'mutating' and 'nonmutating' before getters and setters
  // for which that is true.
  if (auto accessor = dyn_cast<AccessorDecl>(D)) {
    printMutatingModifiersIfNeeded(accessor);
  }

  Options.ExcludeAttrList.resize(originalExcludeAttrCount);
}

void PrintAST::printTypedPattern(const TypedPattern *TP) {
  printPattern(TP->getSubPattern());
  Printer << ": ";
  printTypeLoc(TP->getTypeLoc());
}

void PrintAST::printPattern(const Pattern *pattern) {
  switch (pattern->getKind()) {
  case PatternKind::Any:
    Printer << "_";
    break;

  case PatternKind::Named: {
    auto named = cast<NamedPattern>(pattern);
    auto decl = named->getDecl();
    recordDeclLoc(decl, [&]{
      if (Options.OmitNameOfInaccessibleProperties &&
          contributesToParentTypeStorage(decl) &&
          !isPublicOrUsableFromInline(decl) &&
          // FIXME: We need to figure out a way to generate an entry point
          //        for the initializer expression without revealing the name.
          !decl->hasInitialValue())
        Printer << "_";
      else
        Printer.printName(named->getBoundName());
      });
    break;
  }

  case PatternKind::Paren:
    Printer << "(";
    printPattern(cast<ParenPattern>(pattern)->getSubPattern());
    Printer << ")";
    break;

  case PatternKind::Tuple: {
    Printer << "(";
    auto TP = cast<TuplePattern>(pattern);
    auto Fields = TP->getElements();
    for (unsigned i = 0, e = Fields.size(); i != e; ++i) {
      const auto &Elt = Fields[i];
      if (i != 0)
        Printer << ", ";

      printPattern(Elt.getPattern());
    }
    Printer << ")";
    break;
  }

  case PatternKind::Typed:
    printTypedPattern(cast<TypedPattern>(pattern));
    break;

  case PatternKind::Is: {
    auto isa = cast<IsPattern>(pattern);
    Printer << tok::kw_is << " ";
    isa->getCastTypeLoc().getType().print(Printer, Options);
    break;
  }

  case PatternKind::EnumElement: {
    auto elt = cast<EnumElementPattern>(pattern);
    // FIXME: Print element expr.
    if (elt->hasSubPattern())
      printPattern(elt->getSubPattern());
    break;
  }

  case PatternKind::OptionalSome:
    printPattern(cast<OptionalSomePattern>(pattern)->getSubPattern());
    Printer << '?';
    break;

  case PatternKind::Bool:
    Printer << (cast<BoolPattern>(pattern)->getValue() ? tok::kw_true
                                                       : tok::kw_false);
    break;

  case PatternKind::Expr:
    // FIXME: Print expr.
    break;

  case PatternKind::Var:
    if (!Options.SkipIntroducerKeywords)
      Printer << (cast<VarPattern>(pattern)->isLet() ? tok::kw_let
                                                     : tok::kw_var)
              << " ";
    printPattern(cast<VarPattern>(pattern)->getSubPattern());
  }
}

/// If we can't find the depth of a type, return ErrorDepth.
static const unsigned ErrorDepth = ~0U;
/// A helper function to return the depth of a type.
static unsigned getDepthOfType(Type ty) {
  unsigned depth = ErrorDepth;

  auto combineDepth = [&depth](unsigned newDepth) -> bool {
    // If there is no current depth (depth == ErrorDepth), then assign to
    // newDepth; otherwise, choose the deeper of the current and new depth.

    // Since ErrorDepth == ~0U, ErrorDepth + 1 == 0, which is smaller than any
    // valid depth + 1.
    depth = std::max(depth+1U, newDepth+1U) - 1U;
    return false;
  };

  ty.findIf([combineDepth](Type t) -> bool {
    if (auto paramTy = t->getAs<GenericTypeParamType>())
      return combineDepth(paramTy->getDepth());

    if (auto depMemTy = dyn_cast<DependentMemberType>(t->getCanonicalType())) {
      CanType rootTy;
      do {
        rootTy = depMemTy.getBase();
      } while ((depMemTy = dyn_cast<DependentMemberType>(rootTy)));
      if (auto rootParamTy = dyn_cast<GenericTypeParamType>(rootTy))
        return combineDepth(rootParamTy->getDepth());
    }

    return false;
  });

  return depth;
}

namespace {
struct RequirementPrintLocation {
  /// The Decl where the requirement should be attached (whether inherited or in
  /// a where clause)
  Decl *AttachedTo;
  /// Whether the requirement needs to be in a where clause.
  bool InWhereClause;
};
} // end anonymous namespace

/// Heuristically work out a good place for \c req to be printed inside \c
/// proto.
///
/// This depends only on the protocol so that we make the same decisions for all
/// requirements in all associated types, guaranteeing that all of them will be
/// printed somewhere. That is, taking an AssociatedTypeDecl as an argument and
/// asking "should this requirement be printed on this ATD?" seems more likely
/// to result in inconsistencies in what is printed where, versus what this
/// function does: asking "where should this requirement be printed?" and then
/// callers check if the location is the ATD.
static RequirementPrintLocation
bestRequirementPrintLocation(ProtocolDecl *proto, const Requirement &req) {
  auto protoSelf = proto->getProtocolSelfType();
  // Returns the most relevant decl within proto connected to outerType (or null
  // if one doesn't exist), and whether the type is an "direct use",
  // i.e. outerType itself is Self or Self.T, but not, say, Self.T.U, or
  // Array<Self.T>. (The first's decl will be proto, while the other three will
  // be Self.T.)
  auto findRelevantDeclAndDirectUse = [&](Type outerType) {
    TypeDecl *relevantDecl = nullptr;
    Type foundType;
    (void)outerType.findIf([&](Type t) {
      if (t->isEqual(protoSelf)) {
        relevantDecl = proto;
        foundType = t;
        return true;
      } else if (auto DMT = t->getAs<DependentMemberType>()) {
        auto assocType = DMT->getAssocType();
        if (assocType && assocType->getProtocol() == proto) {
          relevantDecl = assocType;
          foundType = t;
          return true;
        }
      }

      // not here, so let's keep looking.
      return false;
    });

    // If we didn't find anything, relevantDecl and foundType will be null, as
    // desired.
    auto directUse = foundType && outerType->isEqual(foundType);
    return std::make_pair(relevantDecl, directUse);
  };

  Decl *bestDecl;
  bool inWhereClause;

  switch (req.getKind()) {
  case RequirementKind::Conformance:
  case RequirementKind::Superclass:
  case RequirementKind::Layout: {
    auto subject = req.getFirstType();
    auto result = findRelevantDeclAndDirectUse(subject);

    bestDecl = result.first;
    inWhereClause = !bestDecl || !result.second;
    break;
  }
  case RequirementKind::SameType: {
    auto lhs = req.getFirstType();
    auto rhs = req.getSecondType();

    auto lhsResult = findRelevantDeclAndDirectUse(lhs);
    auto rhsResult = findRelevantDeclAndDirectUse(rhs);

    // Default to using the left type's decl.
    bestDecl = lhsResult.first;

    // But maybe the right type's one is "obviously" better!
    // e.g. Int == Self.T
    auto lhsDoesntExist = !lhsResult.first;
    // e.g. Self.T.U == Self.V should go on V (first two conditions), but
    // Self.T.U == Self should go on T (third condition).
    auto rhsBetterDirect =
        !lhsResult.second && rhsResult.second && rhsResult.first != proto;
    auto rhsOfSelfToAssoc = lhsResult.first == proto && rhsResult.first;
    // e.g. Self == Self.T.U
    if (lhsDoesntExist || rhsBetterDirect || rhsOfSelfToAssoc)
      bestDecl = rhsResult.first;

    // Same-type requirements can only occur in where clauses
    inWhereClause = true;
    break;
  }
  }
  // Didn't find anything that we think is relevant, so let's default to a where
  // clause on the protocol.
  if (!bestDecl) {
    bestDecl = proto;
    inWhereClause = true;
  }

  return {/*AttachedTo=*/bestDecl, inWhereClause};
}

void PrintAST::printInheritedFromRequirementSignature(ProtocolDecl *proto,
                                                      Decl *attachingTo) {
  assert(proto->isRequirementSignatureComputed());
  printGenericSignature(
      GenericSignature::get({proto->getProtocolSelfType()} ,
                            proto->getRequirementSignature()),
      PrintInherited,
      [&](const Requirement &req) {
        auto location = bestRequirementPrintLocation(proto, req);
        return location.AttachedTo == attachingTo && !location.InWhereClause;
      });
}

void PrintAST::printWhereClauseFromRequirementSignature(ProtocolDecl *proto,
                                                        Decl *attachingTo) {
  assert(proto->isRequirementSignatureComputed());
  unsigned flags = PrintRequirements;
  if (isa<AssociatedTypeDecl>(attachingTo))
    flags |= SwapSelfAndDependentMemberType;
  printGenericSignature(
      GenericSignature::get({proto->getProtocolSelfType()} ,
                            proto->getRequirementSignature()),
      flags,
      [&](const Requirement &req) {
        auto location = bestRequirementPrintLocation(proto, req);
        return location.AttachedTo == attachingTo && location.InWhereClause;
      });
}

void PrintAST::printTrailingWhereClause(TrailingWhereClause *whereClause) {
  Printer << " " << tok::kw_where << " ";
  interleave(
      whereClause->getRequirements(),
      [&](const RequirementRepr &req) {
        Printer.callPrintStructurePre(PrintStructureKind::GenericRequirement);
        req.print(Printer);
        Printer.printStructurePost(PrintStructureKind::GenericRequirement);
      },
      [&] { Printer << ", "; });
}

/// A helper function to return the depth of a requirement.
static unsigned getDepthOfRequirement(const Requirement &req) {
  switch (req.getKind()) {
  case RequirementKind::Conformance:
  case RequirementKind::Layout:
    return getDepthOfType(req.getFirstType());

  case RequirementKind::Superclass:
  case RequirementKind::SameType: {
    // Return the max valid depth of firstType and secondType.
    unsigned firstDepth = getDepthOfType(req.getFirstType());
    unsigned secondDepth = getDepthOfType(req.getSecondType());

    unsigned maxDepth;
    if (firstDepth == ErrorDepth && secondDepth != ErrorDepth)
      maxDepth = secondDepth;
    else if (firstDepth != ErrorDepth && secondDepth == ErrorDepth)
      maxDepth = firstDepth;
    else
      maxDepth = std::max(firstDepth, secondDepth);

    return maxDepth;
  }
  }
  llvm_unreachable("bad RequirementKind");
}

static void getRequirementsAtDepth(const GenericSignature *genericSig,
                                   unsigned depth,
                                   SmallVectorImpl<Requirement> &result) {
  for (auto reqt : genericSig->getRequirements()) {
    unsigned currentDepth = getDepthOfRequirement(reqt);
    assert(currentDepth != ErrorDepth);
    if (currentDepth == depth)
      result.push_back(reqt);
  }
}

void PrintAST::printGenericSignature(const GenericSignature *genericSig,
                                     unsigned flags) {
  printGenericSignature(genericSig, flags,
                        // print everything
                        [&](const Requirement &) { return true; });
}
void PrintAST::printGenericSignature(
    const GenericSignature *genericSig, unsigned flags,
    llvm::function_ref<bool(const Requirement &)> filter) {
  if (flags & InnermostOnly) {
    auto genericParams = genericSig->getInnermostGenericParams();
    unsigned depth = genericParams[0]->getDepth();
    SmallVector<Requirement, 2> requirementsAtDepth;
    getRequirementsAtDepth(genericSig, depth, requirementsAtDepth);

    printSingleDepthOfGenericSignature(genericParams, requirementsAtDepth,
                                       flags, filter);
    return;
  }

  auto genericParams = genericSig->getGenericParams();
  auto requirements = genericSig->getRequirements();

  if (!Options.PrintInSILBody) {
    printSingleDepthOfGenericSignature(genericParams, requirements, flags,
                                       filter);
    return;
  }

  // In order to recover the nested GenericParamLists, we divide genericParams
  // and requirements according to depth.
  unsigned paramIdx = 0, numParam = genericParams.size();
  while (paramIdx < numParam) {
    unsigned depth = genericParams[paramIdx]->getDepth();

    // Move index to genericParams.
    unsigned lastParamIdx = paramIdx;
    do {
      lastParamIdx++;
    } while (lastParamIdx < numParam &&
             genericParams[lastParamIdx]->getDepth() == depth);

    // Collect requirements for this level.
    SmallVector<Requirement, 2> requirementsAtDepth;
    getRequirementsAtDepth(genericSig, depth, requirementsAtDepth);

    printSingleDepthOfGenericSignature(
        genericParams.slice(paramIdx, lastParamIdx - paramIdx),
        requirementsAtDepth, flags, filter);

    paramIdx = lastParamIdx;
  }
}

void PrintAST::printSingleDepthOfGenericSignature(
    TypeArrayView<GenericTypeParamType> genericParams,
    ArrayRef<Requirement> requirements, unsigned flags,
    llvm::function_ref<bool(const Requirement &)> filter) {
  bool printParams = (flags & PrintParams);
  bool printRequirements = (flags & PrintRequirements);
  bool printInherited = (flags & PrintInherited);
  bool swapSelfAndDependentMemberType =
    (flags & SwapSelfAndDependentMemberType);

  SubstitutionMap subMap;
  if (CurrentType) {
    if (!CurrentType->isExistentialType()) {
      auto *DC = Current->getInnermostDeclContext()->getInnermostTypeContext();
      auto *M = DC->getParentModule();
      subMap = CurrentType->getContextSubstitutionMap(M, DC);
    }
  }

  auto substParam = [&](Type param) -> Type {
    return param.subst(subMap);
  };

  if (printParams) {
    // Print the generic parameters.
    Printer << "<";
    interleave(genericParams,
               [&](GenericTypeParamType *param) {
                 if (!subMap.empty()) {
                   if (auto argTy = substParam(param))
                     printType(argTy);
                   else
                     printType(param);
                 } else if (auto *GP = param->getDecl()) {
                   Printer.callPrintStructurePre(
                       PrintStructureKind::GenericParameter, GP);
                   Printer.printName(GP->getName(),
                                     PrintNameContext::GenericParameter);
                   Printer.printStructurePost(
                       PrintStructureKind::GenericParameter, GP);
                 } else {
                   printType(param);
                 }
               },
               [&] { Printer << ", "; });
  }

  if (printRequirements || printInherited) {
    bool isFirstReq = true;
    for (const auto &req : requirements) {
      if (!filter(req))
        continue;

      auto first = req.getFirstType();
      Type second;

      if (req.getKind() != RequirementKind::Layout)
        second = req.getSecondType();

      if (!subMap.empty()) {
        if (Type subFirst = substParam(first))
          first = subFirst;
        if (second) {
          if (Type subSecond = substParam(second))
            second = subSecond;
          if (!(first->is<ArchetypeType>() || first->isTypeParameter()) &&
              !(second->is<ArchetypeType>() || second->isTypeParameter()))
            continue;
        }
      }

      if (isFirstReq) {
        if (printRequirements)
          Printer << " " << tok::kw_where << " ";
        else
          Printer << " : ";

        isFirstReq = false;
      } else {
        Printer << ", ";
      }

      // Swap the order of Self == Self.A requirements if requested.
      if (swapSelfAndDependentMemberType &&
          req.getKind() == RequirementKind::SameType &&
          first->is<GenericTypeParamType>() &&
          second->is<DependentMemberType>())
        std::swap(first, second);

      if (printInherited) {
        // We only print the second part of a requirement in the "inherited"
        // clause.
        switch (req.getKind()) {
        case RequirementKind::Layout:
          req.getLayoutConstraint()->print(Printer, Options);
          break;

        case RequirementKind::Conformance:
        case RequirementKind::Superclass:
          printType(second);
          break;

        case RequirementKind::SameType:
          llvm_unreachable("same-type constraints belong in the where clause");
          break;
        }
      } else {
        Printer.callPrintStructurePre(PrintStructureKind::GenericRequirement);

        // We don't substitute type for the printed requirement so that the
        // printed requirement agrees with separately reported generic parameters.
        printRequirement(req);
        Printer.printStructurePost(PrintStructureKind::GenericRequirement);
      }
    }
  }

  if (printParams)
    Printer << ">";
}

void PrintAST::printRequirement(const Requirement &req) {
  printType(req.getFirstType());
  switch (req.getKind()) {
  case RequirementKind::Layout:
    Printer << " : ";
    req.getLayoutConstraint()->print(Printer, Options);
    return;
  case RequirementKind::Conformance:
  case RequirementKind::Superclass:
    Printer << " : ";
    break;
  case RequirementKind::SameType:
    Printer << " == ";
    break;
  }
  printType(req.getSecondType());
}

bool PrintAST::shouldPrintPattern(const Pattern *P) {
  return Options.shouldPrint(P);
}

void PrintAST::printPatternType(const Pattern *P) {
  if (P->hasType()) {
    Printer << ": ";
    printType(P->getType());
  }
}

bool ShouldPrintChecker::shouldPrint(const Pattern *P,
                                     const PrintOptions &Options) {
  bool ShouldPrint = false;
  P->forEachVariable([&](const VarDecl *VD) {
    ShouldPrint |= shouldPrint(VD, Options);
  });
  return ShouldPrint;
}

bool ShouldPrintChecker::shouldPrint(const Decl *D,
                                     const PrintOptions &Options) {
  if (auto *ED= dyn_cast<ExtensionDecl>(D)) {
    if (Options.printExtensionContentAsMembers(ED))
      return false;
  }

  if (Options.SkipMissingMemberPlaceholders && isa<MissingMemberDecl>(D))
    return false;

  if (Options.SkipDeinit && isa<DestructorDecl>(D)) {
    return false;
  }

  if (Options.SkipImports && isa<ImportDecl>(D)) {
    return false;
  }

  if (Options.SkipImplicit && D->isImplicit())
    return false;

  if (Options.SkipUnavailable &&
      D->getAttrs().isUnavailable(D->getASTContext()))
    return false;

  if (Options.ExplodeEnumCaseDecls) {
    if (isa<EnumElementDecl>(D))
      return true;
    if (isa<EnumCaseDecl>(D))
      return false;
  } else if (auto *EED = dyn_cast<EnumElementDecl>(D)) {
    // Enum elements are printed as part of the EnumCaseDecl, unless they were
    // imported without source info.
    return !EED->getSourceRange().isValid();
  }

  if (auto *ASD = dyn_cast<AbstractStorageDecl>(D)) {
    if (Options.OmitNameOfInaccessibleProperties &&
        contributesToParentTypeStorage(ASD))
      return true;
  }

  // Skip declarations that are not accessible.
  if (auto *VD = dyn_cast<ValueDecl>(D)) {
    if (Options.AccessFilter > AccessLevel::Private &&
        VD->getFormalAccess() < Options.AccessFilter)
      return false;
  }

  if (Options.SkipPrivateStdlibDecls &&
      D->isPrivateStdlibDecl(!Options.SkipUnderscoredStdlibProtocols))
    return false;

  if (Options.SkipEmptyExtensionDecls && isa<ExtensionDecl>(D)) {
    auto Ext = cast<ExtensionDecl>(D);
    // If the extension doesn't add protocols or has no members that we should
    // print then skip printing it.
    if (Ext->getLocalProtocols().empty()) {
      bool HasMemberToPrint = false;
      for (auto Member : Ext->getMembers()) {
        if (shouldPrint(Member, Options)) {
          HasMemberToPrint = true;
          break;
        }
      }
      if (!HasMemberToPrint)
        return false;
    }
  }

  // If asked to skip overrides and witnesses, do so.
  if (Options.SkipOverrides) {
    if (auto *VD = dyn_cast<ValueDecl>(D)) {
      if (VD->getOverriddenDecl()) return false;
      if (!VD->getSatisfiedProtocolRequirements().empty()) return false;

      if (auto clangDecl = VD->getClangDecl()) {
        // If the Clang declaration is from a protocol but was mirrored into
        // class or extension thereof, treat it as an override.
        if (isa<clang::ObjCProtocolDecl>(clangDecl->getDeclContext()) &&
            VD->getDeclContext()->getSelfClassDecl())
          return false;

        // Check whether Clang considers it an override.
        if (auto objcMethod = dyn_cast<clang::ObjCMethodDecl>(clangDecl)) {
          SmallVector<const clang::ObjCMethodDecl *, 4> overriddenMethods;
          objcMethod->getOverriddenMethods(overriddenMethods);
          if (!overriddenMethods.empty()) return false;
        } else if (auto objcProperty
                     = dyn_cast<clang::ObjCPropertyDecl>(clangDecl)) {
          if (auto getter = objcProperty->getGetterMethodDecl()) {
            SmallVector<const clang::ObjCMethodDecl *, 4> overriddenMethods;
            getter->getOverriddenMethods(overriddenMethods);
            if (!overriddenMethods.empty()) return false;
          }
        }
      }
    }
  }

  // We need to handle PatternBindingDecl as a special case here because its
  // attributes can only be retrieved from the inside VarDecls.
  if (auto *PD = dyn_cast<PatternBindingDecl>(D)) {
    auto ShouldPrint = false;
    for (auto entry : PD->getPatternList()) {
      ShouldPrint |= shouldPrint(entry.getPattern(), Options);
      if (ShouldPrint)
        return true;
    }
    return false;
  }
  return true;
}

bool PrintAST::shouldPrint(const Decl *D, bool Notify) {
  auto Result = Options.shouldPrint(D);
  if (!Result && Notify)
    Printer.callAvoidPrintDeclPost(D);
  return Result;
}

void PrintAST::printBraceStmt(const BraceStmt *stmt, bool newlineIfEmpty) {
  Printer << "{";
  if (printASTNodes(stmt->getElements()) || newlineIfEmpty) {
    Printer.printNewline();
    indent();
  }
  Printer << "}";
}

void PrintAST::printBodyIfNecessary(const AbstractFunctionDecl *decl) {
  if (auto BodyFunc = Options.FunctionBody) {
    BodyFunc(decl, Printer);
    indent();
    return;
  }

  if (!Options.FunctionDefinitions || !decl->getBody())
    return;

  Printer << " ";
  printBraceStmt(decl->getBody(), /*newlineIfEmpty*/!isa<AccessorDecl>(decl));
}

static StringRef getAccessorLabel(AccessorDecl *accessor) {
  switch (accessor->getAccessorKind()) {
#define SINGLETON_ACCESSOR(ID, KEYWORD) \
  case AccessorKind::ID: return #KEYWORD;
#define ACCESSOR(ID)
#include "swift/AST/AccessorKinds.def"
  }
  llvm_unreachable("bad accessor kind");
}

void PrintAST::printMutatingModifiersIfNeeded(const AccessorDecl *accessor) {
  if (accessor->isAssumedNonMutating() && accessor->isMutating()) {
    Printer.printKeyword("mutating");
    Printer << " ";
  } else if (accessor->isExplicitNonMutating()) {
    Printer.printKeyword("nonmutating");
    Printer << " ";
  }
}

void PrintAST::printAccessors(const AbstractStorageDecl *ASD) {
  if (isa<VarDecl>(ASD) && !Options.PrintPropertyAccessors)
    return;

  auto impl = ASD->getImplInfo();

  // Don't print accessors for trivially stored properties...
  if (impl.isSimpleStored()) {
    // ...unless we're printing for SIL, which expects a { get set? } on
    //    trivial properties
    if (Options.PrintForSIL) {
      Printer << " { get " << (impl.supportsMutation() ? "set }" : "}");
    }
    // ...or you're private/internal(set), at which point we'll print
    //    @_hasStorage var x: T { get }
    else if (ASD->isSettable(nullptr) && hasLessAccessibleSetter(ASD)) {
      Printer << " {";
      {
        IndentRAII indentMore(*this);
        indent();
        Printer.printNewline();
        Printer << "get";
        Printer.printNewline();
      }
      Printer << "}";
    }
    return;
  }

  // AbstractAccessors is suppressed by FunctionDefinitions.
  bool PrintAbstract =
    Options.AbstractAccessors && !Options.FunctionDefinitions;

  // We sometimes want to print the accessors abstractly
  // instead of listing out how they're actually implemented.
  bool inProtocol = isa<ProtocolDecl>(ASD->getDeclContext());
  if ((inProtocol && !Options.PrintAccessorBodiesInProtocols) ||
      PrintAbstract) {
    bool settable = ASD->isSettable(nullptr);
    bool mutatingGetter = hasMutatingGetter(ASD);
    bool nonmutatingSetter = hasNonMutatingSetter(ASD);

    // We're about to print something like this:
    //   { mutating? get (nonmutating? set)? }
    // But don't print "{ get set }" if we don't have to.
    if (!inProtocol && !Options.PrintGetSetOnRWProperties &&
        settable && !mutatingGetter && !nonmutatingSetter) {
      return;
    }

    Printer << " {";
    if (mutatingGetter) {
      Printer << " ";
      Printer.printKeyword("mutating");
    }
    Printer << " ";
    Printer.printKeyword("get");
    if (settable) {
      if (nonmutatingSetter) {
        Printer << " ";
        Printer.printKeyword("nonmutating");
      }
      Printer << " ";
      Printer.printKeyword("set");
    }
    Printer << " }";
    return;
  }

  // Should we print the 'modify' accessor?
  auto shouldHideModifyAccessor = [&] {
    if (impl.getReadWriteImpl() != ReadWriteImplKind::Modify)
      return true;
    // Always hide in a protocol.
    return isa<ProtocolDecl>(ASD->getDeclContext());
  };

  auto isGetSetImpl = [&] {
    return ((impl.getReadImpl() == ReadImplKind::Stored ||
             impl.getReadImpl() == ReadImplKind::Get) &&
            (impl.getWriteImpl() == WriteImplKind::Stored ||
             impl.getWriteImpl() == WriteImplKind::Set) &&
            (shouldHideModifyAccessor()));
  };

  // Honor !Options.PrintGetSetOnRWProperties in the only remaining
  // case where we could end up printing { get set }.
  if ((PrintAbstract || isGetSetImpl()) &&
      !Options.PrintGetSetOnRWProperties &&
      !Options.FunctionDefinitions &&
      !ASD->getGetter()->isMutating() &&
      !ASD->getSetter()->isExplicitNonMutating()) {
    return;
  }

  // Otherwise, print all the concrete defining accessors.
  bool PrintAccessorBody = Options.FunctionDefinitions;

  // Helper to print an accessor. Returns true if the
  // accessor was present but skipped.
  auto PrintAccessor = [&](AccessorDecl *Accessor) -> bool {
    if (!Accessor || !shouldPrint(Accessor))
      return true;
    if (!PrintAccessorBody) {
      Printer << " ";
      printMutatingModifiersIfNeeded(Accessor);
      Printer.printKeyword(getAccessorLabel(Accessor));
    } else {
      {
        IndentRAII IndentMore(*this);
        indent();
        visit(Accessor);
      }
      indent();
      Printer.printNewline();
    }
    return false;
  };

  // Determine if we should print the getter without the 'get { ... }'
  // block around it.
  bool isOnlyGetter = impl.getReadImpl() == ReadImplKind::Get &&
                      ASD->getGetter();
  bool isGetterMutating = ASD->supportsMutation() || ASD->isGetterMutating();
  if (isOnlyGetter && !isGetterMutating && PrintAccessorBody &&
      Options.FunctionBody && Options.CollapseSingleGetterProperty) {
    Options.FunctionBody(ASD->getGetter(), Printer);
    indent();
    return;
  }

  Printer << " {";

  if (PrintAccessorBody)
    Printer.printNewline();

  if (PrintAbstract) {
    PrintAccessor(ASD->getGetter());
    if (ASD->supportsMutation())
      PrintAccessor(ASD->getSetter());
  } else {
    switch (impl.getReadImpl()) {
    case ReadImplKind::Stored:
    case ReadImplKind::Inherited:
      break;
    case ReadImplKind::Get:
      PrintAccessor(ASD->getGetter());
      break;
    case ReadImplKind::Address:
      PrintAccessor(ASD->getAddressor());
      break;
    case ReadImplKind::Read:
      PrintAccessor(ASD->getReadCoroutine());
      break;
    }
    switch (impl.getWriteImpl()) {
    case WriteImplKind::Immutable:
      break;
    case WriteImplKind::Stored:
      llvm_unreachable("simply-stored variable should have been filtered out");
    case WriteImplKind::StoredWithObservers:
    case WriteImplKind::InheritedWithObservers: {
      PrintAccessor(ASD->getGetter());
      PrintAccessor(ASD->getSetter());
      break;
    }
    case WriteImplKind::Set:
      PrintAccessor(ASD->getSetter());
      if (!shouldHideModifyAccessor())
        PrintAccessor(ASD->getModifyCoroutine());
      break;
    case WriteImplKind::MutableAddress:
      PrintAccessor(ASD->getMutableAddressor());
      PrintAccessor(ASD->getWillSetFunc());
      PrintAccessor(ASD->getDidSetFunc());
      break;
    case WriteImplKind::Modify:
      PrintAccessor(ASD->getModifyCoroutine());
      break;
    }
  }

  if (!PrintAccessorBody)
    Printer << " ";

  Printer << "}";

  indent();
}

void PrintAST::printMembersOfDecl(Decl *D, bool needComma,
                                  bool openBracket,
                                  bool closeBracket) {
  llvm::SmallVector<Decl *, 3> Members;
  auto AddDeclFunc = [&](DeclRange Range) {
    for (auto RD : Range)
      Members.push_back(RD);
  };

  if (auto Ext = dyn_cast<ExtensionDecl>(D)) {
    AddDeclFunc(Ext->getMembers());
  } else if (auto NTD = dyn_cast<NominalTypeDecl>(D)) {
    AddDeclFunc(NTD->getMembers());
    for (auto Ext : NTD->getExtensions()) {
      if (Options.printExtensionContentAsMembers(Ext))
        AddDeclFunc(Ext->getMembers());
    }
    if (Options.PrintExtensionFromConformingProtocols) {
      for (auto Conf : NTD->getAllConformances()) {
        for (auto Ext : Conf->getProtocol()->getExtensions()) {
          if (Options.printExtensionContentAsMembers(Ext))
            AddDeclFunc(Ext->getMembers());
        }
      }
    }
  }
  printMembers(Members, needComma, openBracket, closeBracket);
}

void PrintAST::printMembers(ArrayRef<Decl *> members, bool needComma,
                            bool openBracket, bool closeBracket) {
  if (openBracket) {
    Printer << " {";
    Printer.printNewline();
  }
  {
    IndentRAII indentMore(*this);
    for (auto i = members.begin(), iEnd = members.end(); i != iEnd; ++i) {
      auto member = *i;

      if (!shouldPrint(member, true))
        continue;

      if (!member->shouldPrintInContext(Options))
        continue;

      if (Options.EmptyLineBetweenMembers)
        Printer.printNewline();
      indent();
      visit(member);
      if (needComma && std::next(i) != iEnd)
        Printer << ",";
      Printer.printNewline();
    }
  }
  indent();
  if (closeBracket)
    Printer << "}";
}

void PrintAST::printGenericDeclGenericParams(GenericContext *decl) {
  if (decl->getGenericParams())
    if (auto GenericSig = decl->getGenericSignature())
      printGenericSignature(GenericSig, PrintParams | InnermostOnly);
}

void PrintAST::printGenericDeclGenericRequirements(GenericContext *decl) {
  if (decl->getGenericParams())
    if (auto GenericSig = decl->getGenericSignature())
      printGenericSignature(GenericSig, PrintRequirements | InnermostOnly);
}

void PrintAST::printInherited(const Decl *decl) {
  SmallVector<TypeLoc, 6> TypesToPrint;
  getInheritedForPrinting(decl, [this](const Decl* D) { return shouldPrint(D); },
                          TypesToPrint);
  if (TypesToPrint.empty())
    return;

  Printer << " : ";

  interleave(TypesToPrint, [&](TypeLoc TL) {
    printTypeLoc(TL);
  }, [&]() {
    Printer << ", ";
  });
}

static void getModuleEntities(const clang::Module *ClangMod,
                              SmallVectorImpl<ModuleEntity> &ModuleEnts) {
  if (!ClangMod)
    return;

  getModuleEntities(ClangMod->Parent, ModuleEnts);
  ModuleEnts.push_back(ClangMod);
}

static void getModuleEntities(ImportDecl *Import,
                              SmallVectorImpl<ModuleEntity> &ModuleEnts) {
  if (auto *ClangMod = Import->getClangModule()) {
    getModuleEntities(ClangMod, ModuleEnts);
    return;
  }

  auto Mod = Import->getModule();
  if (!Mod)
    return;

  if (auto *ClangMod = Mod->findUnderlyingClangModule()) {
    getModuleEntities(ClangMod, ModuleEnts);
  } else {
    ModuleEnts.push_back(Mod);
  }
}

void PrintAST::visitImportDecl(ImportDecl *decl) {
  printAttributes(decl);
  Printer << tok::kw_import << " ";

  switch (decl->getImportKind()) {
  case ImportKind::Module:
    break;
  case ImportKind::Type:
    Printer << tok::kw_typealias << " ";
    break;
  case ImportKind::Struct:
    Printer << tok::kw_struct << " ";
    break;
  case ImportKind::Class:
    Printer << tok::kw_class << " ";
    break;
  case ImportKind::Enum:
    Printer << tok::kw_enum << " ";
    break;
  case ImportKind::Protocol:
    Printer << tok::kw_protocol << " ";
    break;
  case ImportKind::Var:
    Printer << tok::kw_var << " ";
    break;
  case ImportKind::Func:
    Printer << tok::kw_func << " ";
    break;
  }

  SmallVector<ModuleEntity, 4> ModuleEnts;
  getModuleEntities(decl, ModuleEnts);

  ArrayRef<ModuleEntity> Mods = ModuleEnts;
  interleave(decl->getFullAccessPath(),
             [&](const ImportDecl::AccessPathElement &Elem) {
               if (!Mods.empty()) {
                 Printer.printModuleRef(Mods.front(), Elem.first);
                 Mods = Mods.slice(1);
               } else {
                 Printer << Elem.first.str();
               }
             },
             [&] { Printer << "."; });
}

static void printExtendedTypeName(Type ExtendedType, ASTPrinter &Printer,
                                  PrintOptions Options) {
  Options.FullyQualifiedTypes = false;
  Options.FullyQualifiedTypesIfAmbiguous = false;

  // Strip off generic arguments, if any.
  auto Ty = ExtendedType->getAnyNominal()->getDeclaredType();

  Ty->print(Printer, Options);
}

void PrintAST::printSynthesizedExtension(Type ExtendedType,
                                         ExtensionDecl *ExtDecl) {
  if (Options.BracketOptions.shouldOpenExtension(ExtDecl)) {
    printDocumentationComment(ExtDecl);
    printAttributes(ExtDecl);
    Printer << tok::kw_extension << " ";

    printExtendedTypeName(ExtendedType, Printer, Options);
    printInherited(ExtDecl);
    printGenericDeclGenericRequirements(ExtDecl);
  }
  if (Options.TypeDefinitions) {
    printMembersOfDecl(ExtDecl, false,
                       Options.BracketOptions.shouldOpenExtension(ExtDecl),
                       Options.BracketOptions.shouldCloseExtension(ExtDecl));
  }
}

void PrintAST::printExtension(ExtensionDecl *decl) {
  if (Options.BracketOptions.shouldOpenExtension(decl)) {
    printDocumentationComment(decl);
    printAttributes(decl);
    Printer << "extension ";
    recordDeclLoc(decl, [&]{
      // We cannot extend sugared types.
      Type extendedType = decl->getExtendedType();
      if (!extendedType || !extendedType->getAnyNominal()) {
        // Fallback to TypeRepr.
        printTypeLoc(decl->getExtendedTypeLoc());
        return;
      }
      printExtendedTypeName(extendedType, Printer, Options);
    });
    printInherited(decl);

    if (auto *genericSig = decl->getGenericSignature()) {
      auto *baseGenericSig = decl->getExtendedNominal()->getGenericSignature();
      assert(baseGenericSig &&
             "an extension can't be generic if the base type isn't");
      printGenericSignature(genericSig, PrintRequirements | InnermostOnly,
                            [baseGenericSig](const Requirement &req) -> bool {
        // Only include constraints that are not satisfied by the base type.
        return !baseGenericSig->isRequirementSatisfied(req);
      });
    }
  }
  if (Options.TypeDefinitions) {
    printMembersOfDecl(decl, false,
                       Options.BracketOptions.shouldOpenExtension(decl),
                       Options.BracketOptions.shouldCloseExtension(decl));
  }
}

void PrintAST::visitExtensionDecl(ExtensionDecl *decl) {
  if (Options.TransformContext &&
      Options.TransformContext->isPrintingSynthesizedExtension()) {
    auto extendedType = Options.TransformContext->getBaseType();
    if (extendedType->hasArchetype())
      extendedType = extendedType->mapTypeOutOfContext();
    printSynthesizedExtension(extendedType, decl);
  } else
    printExtension(decl);
}

void PrintAST::visitPatternBindingDecl(PatternBindingDecl *decl) {
  // FIXME: We're not printing proper "{ get set }" annotations in pattern
  // binding decls.  As a hack, scan the decl to find out if any of the
  // variables are immutable, and if so, we print as 'let'.  This allows us to
  // handle the 'let x = 4' case properly at least.
  const VarDecl *anyVar = nullptr;
  for (auto entry : decl->getPatternList()) {
    entry.getPattern()->forEachVariable([&](VarDecl *V) {
      anyVar = V;
    });
    if (anyVar) break;
  }

  if (anyVar)
    printDocumentationComment(anyVar);

  // FIXME: PatternBindingDecls don't have attributes themselves, so just assume
  // the variables all have the same attributes. This isn't exactly true
  // after type-checking, but it's close enough for now.
  if (anyVar) {
    printAttributes(anyVar);
    printAccess(anyVar);
  }

  if (decl->isStatic())
    printStaticKeyword(decl->getCorrectStaticSpelling());

  if (anyVar) {
    Printer << (anyVar->isSettable(anyVar->getDeclContext()) ? "var " : "let ");
  } else {
    Printer << "let ";
  }

  bool isFirst = true;
  for (auto &entry : decl->getPatternList()) {
    if (!shouldPrintPattern(entry.getPattern()))
      continue;
    if (isFirst)
      isFirst = false;
    else
      Printer << ", ";

    printPattern(entry.getPattern());

    // We also try to print type for named patterns, e.g. var Field = 10;
    // and tuple patterns, e.g. var (T1, T2) = (10, 10)
    if (isa<NamedPattern>(entry.getPattern()) ||
        isa<TuplePattern>(entry.getPattern())) {
      printPatternType(entry.getPattern());
    }

    if (Options.VarInitializers) {
      auto vd = entry.getAnchoringVarDecl();
      if (entry.hasInitStringRepresentation() &&
          vd->isInitExposedToClients()) {
        SmallString<128> scratch;
        Printer << " = " << entry.getInitStringRepresentation(scratch);
      }
    }

    // If we're just printing a single pattern and it has accessors,
    // print the accessors here. It is an error to add accessors to a
    // pattern binding with multiple entries.
    if (auto var = decl->getSingleVar()) {
      printAccessors(var);
    }
  }
}

void PrintAST::visitTopLevelCodeDecl(TopLevelCodeDecl *decl) {
  printASTNodes(decl->getBody()->getElements(), /*NeedIndent=*/false);
}

void PrintAST::visitIfConfigDecl(IfConfigDecl *ICD) {
  if (!Options.PrintIfConfig)
    return;

  for (auto &Clause : ICD->getClauses()) {
    if (&Clause == &*ICD->getClauses().begin())
      Printer << tok::pound_if << " /* condition */"; // FIXME: print condition
    else if (Clause.Cond)
      Printer << tok::pound_elseif << " /* condition */"; // FIXME: print condition
    else
      Printer << tok::pound_else;
    printASTNodes(Clause.Elements);
    Printer.printNewline();
    indent();
  }
  Printer << tok::pound_endif;
}

void PrintAST::visitPoundDiagnosticDecl(PoundDiagnosticDecl *PDD) {
  /// TODO: Should we even print #error/#warning?
  if (PDD->isError()) {
    Printer << tok::pound_error;
  } else {
    Printer << tok::pound_warning; 
  }

  Printer << "(\"" << PDD->getMessage()->getValue() << "\")";
}

void PrintAST::visitTypeAliasDecl(TypeAliasDecl *decl) {
  printDocumentationComment(decl);
  printAttributes(decl);
  printAccess(decl);
  if (!Options.SkipIntroducerKeywords)
    Printer << tok::kw_typealias << " ";
  printContextIfNeeded(decl);
  recordDeclLoc(decl,
    [&]{
      Printer.printName(decl->getName());
    }, [&]{ // Signature
      printGenericDeclGenericParams(decl);
    });
  bool ShouldPrint = true;
  Type Ty = decl->getUnderlyingTypeLoc().getType();

  // If the underlying type is private, don't print it.
  if (Options.SkipPrivateStdlibDecls && Ty && Ty.isPrivateStdlibType())
    ShouldPrint = false;

  if (ShouldPrint) {
    Printer << " = ";
    printTypeLoc(decl->getUnderlyingTypeLoc());
    printGenericDeclGenericRequirements(decl);
  }
}

void PrintAST::visitGenericTypeParamDecl(GenericTypeParamDecl *decl) {
  recordDeclLoc(decl, [&] {
    Printer.printName(decl->getName(), PrintNameContext::GenericParameter);
  });

  printInherited(decl);
}

void PrintAST::visitAssociatedTypeDecl(AssociatedTypeDecl *decl) {
  printDocumentationComment(decl);
  printAttributes(decl);
  if (!Options.SkipIntroducerKeywords)
    Printer << tok::kw_associatedtype << " ";
  recordDeclLoc(decl,
    [&]{
      Printer.printName(decl->getName());
    });

  auto proto = decl->getProtocol();
  if (proto->isRequirementSignatureComputed()) {
    printInheritedFromRequirementSignature(proto, decl);
  } else {
    printInherited(decl);
  }

  if (!decl->getDefaultDefinitionLoc().isNull()) {
    Printer << " = ";
    decl->getDefaultDefinitionLoc().getType().print(Printer, Options);
  }

  // As with protocol's trailing where clauses, use the requirement signature
  // when available.
  if (proto->isRequirementSignatureComputed()) {
    printWhereClauseFromRequirementSignature(proto, decl);
  } else {
    if (auto trailingWhere = decl->getTrailingWhereClause()) {
      printTrailingWhereClause(trailingWhere);
    }
  }
}

void PrintAST::visitEnumDecl(EnumDecl *decl) {
  printDocumentationComment(decl);
  printAttributes(decl);
  printAccess(decl);

  if (Options.PrintOriginalSourceText && decl->getStartLoc().isValid()) {
    ASTContext &Ctx = decl->getASTContext();
    printSourceRange(CharSourceRange(Ctx.SourceMgr, decl->getStartLoc(),
                              decl->getBraces().Start.getAdvancedLoc(-1)), Ctx);
  } else {
    if (!Options.SkipIntroducerKeywords)
      Printer << tok::kw_enum << " ";
    printContextIfNeeded(decl);
    recordDeclLoc(decl,
      [&]{
        Printer.printName(decl->getName());
      }, [&]{ // Signature
        printGenericDeclGenericParams(decl);
      });
    printInherited(decl);
    printGenericDeclGenericRequirements(decl);
  }
  if (Options.TypeDefinitions) {
    printMembersOfDecl(decl, false, true,
                       Options.BracketOptions.shouldCloseNominal(decl));
  }
}

void PrintAST::visitStructDecl(StructDecl *decl) {
  printDocumentationComment(decl);
  printAttributes(decl);
  printAccess(decl);

  if (Options.PrintOriginalSourceText && decl->getStartLoc().isValid()) {
    ASTContext &Ctx = decl->getASTContext();
    printSourceRange(CharSourceRange(Ctx.SourceMgr, decl->getStartLoc(),
                              decl->getBraces().Start.getAdvancedLoc(-1)), Ctx);
  } else {
    if (!Options.SkipIntroducerKeywords)
      Printer << tok::kw_struct << " ";
    printContextIfNeeded(decl);
    recordDeclLoc(decl,
      [&]{
        Printer.printName(decl->getName());
      }, [&]{ // Signature
        printGenericDeclGenericParams(decl);
      });
    printInherited(decl);
    printGenericDeclGenericRequirements(decl);
  }
  if (Options.TypeDefinitions) {
    printMembersOfDecl(decl, false, true,
                       Options.BracketOptions.shouldCloseNominal(decl));
  }
}

void PrintAST::visitClassDecl(ClassDecl *decl) {
  printDocumentationComment(decl);
  printAttributes(decl);
  printAccess(decl);

  if (Options.PrintOriginalSourceText && decl->getStartLoc().isValid()) {
    ASTContext &Ctx = decl->getASTContext();
    printSourceRange(CharSourceRange(Ctx.SourceMgr, decl->getStartLoc(),
                              decl->getBraces().Start.getAdvancedLoc(-1)), Ctx);
  } else {
    if (!Options.SkipIntroducerKeywords)
      Printer << tok::kw_class << " ";
    printContextIfNeeded(decl);
    recordDeclLoc(decl,
      [&]{
        Printer.printName(decl->getName());
      }, [&]{ // Signature
        printGenericDeclGenericParams(decl);
      });

    printInherited(decl);
    printGenericDeclGenericRequirements(decl);
  }

  if (Options.TypeDefinitions) {
    printMembersOfDecl(decl, false, true,
                       Options.BracketOptions.shouldCloseNominal(decl));
  }
}

void PrintAST::visitProtocolDecl(ProtocolDecl *decl) {
  printDocumentationComment(decl);
  printAttributes(decl);
  printAccess(decl);

  if (Options.PrintOriginalSourceText && decl->getStartLoc().isValid()) {
    ASTContext &Ctx = decl->getASTContext();
    printSourceRange(CharSourceRange(Ctx.SourceMgr, decl->getStartLoc(),
                              decl->getBraces().Start.getAdvancedLoc(-1)), Ctx);
  } else {
    if (!Options.SkipIntroducerKeywords)
      Printer << tok::kw_protocol << " ";
    printContextIfNeeded(decl);
    recordDeclLoc(decl,
      [&]{
        Printer.printName(decl->getName());
      });

    if (decl->isRequirementSignatureComputed()) {
      printInheritedFromRequirementSignature(decl, decl);
    } else {
      printInherited(decl);
    }

    // The trailing where clause is a syntactic thing, which isn't serialized
    // (etc.) and thus isn't available for printing things out of
    // already-compiled SIL modules. The requirement signature is available in
    // such cases, so let's go with that when we can.
    if (decl->isRequirementSignatureComputed()) {
      printWhereClauseFromRequirementSignature(decl, decl);
    } else {
      if (auto trailingWhere = decl->getTrailingWhereClause()) {
        printTrailingWhereClause(trailingWhere);
      }
    }
  }
  if (Options.TypeDefinitions) {
    printMembersOfDecl(decl, false, true,
                       Options.BracketOptions.shouldCloseNominal(decl));
  }
}
static bool isStructOrClassContext(DeclContext *dc) {
  auto *nominal = dc->getSelfNominalTypeDecl();
  if (nominal == nullptr)
    return false;
  return isa<ClassDecl>(nominal) || isa<StructDecl>(nominal);
}

static void printParameterFlags(ASTPrinter &printer, PrintOptions options,
                                ParameterTypeFlags flags) {
  if (!options.excludeAttrKind(TAK_autoclosure) && flags.isAutoClosure())
    printer << "@autoclosure ";
  if (!options.excludeAttrKind(TAK_escaping) && flags.isEscaping())
    printer << "@escaping ";

  switch (flags.getValueOwnership()) {
  case ValueOwnership::Default:
    /* nothing */
    break;
  case ValueOwnership::InOut:
    printer << "inout ";
    break;
  case ValueOwnership::Shared:
    printer << "__shared ";
    break;
  case ValueOwnership::Owned:
    printer << "__owned ";
    break;
  }
}

void PrintAST::visitVarDecl(VarDecl *decl) {
  printDocumentationComment(decl);
  // Print @_hasStorage when the attribute is not already
  // on, decl has storage and it is on a class.
  if (Options.PrintForSIL && decl->hasStorage() &&
      isStructOrClassContext(decl->getDeclContext()) &&
      !decl->getAttrs().hasAttribute<HasStorageAttr>())
    Printer << "@_hasStorage ";
  printAttributes(decl);
  printAccess(decl);
  if (!Options.SkipIntroducerKeywords) {
    if (decl->isStatic())
      printStaticKeyword(decl->getCorrectStaticSpelling());
    if (decl->getKind() == DeclKind::Var
        || Options.PrintParameterSpecifiers) {
      // Map all non-let specifiers to 'var'.  This is not correct, but
      // SourceKit relies on this for info about parameter decls.
      switch (decl->getSpecifier()) {
      case VarDecl::Specifier::Let:
        Printer << tok::kw_let;
        break;
      case VarDecl::Specifier::Var:
      case VarDecl::Specifier::InOut:
      case VarDecl::Specifier::Shared:
      case VarDecl::Specifier::Owned:
        Printer << tok::kw_var;
        break;
      }
      Printer << " ";
    }
  }
  printContextIfNeeded(decl);
  recordDeclLoc(decl,
    [&]{
      Printer.printName(decl->getName());
    });
  if (decl->hasInterfaceType()) {
    Printer << ": ";
    auto tyLoc = decl->getTypeLoc();
    if (!tyLoc.getTypeRepr())
      tyLoc = TypeLoc::withoutLoc(decl->getInterfaceType());

    if (decl->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
      printTypeLocForImplicitlyUnwrappedOptional(tyLoc);
    else
      printTypeLoc(tyLoc);
  }

  printAccessors(decl);
}

void PrintAST::visitParamDecl(ParamDecl *decl) {
  visitVarDecl(decl);
}

void PrintAST::printOneParameter(const ParamDecl *param,
                                 ParameterTypeFlags paramFlags,
                                 bool ArgNameIsAPIByDefault) {
  Printer.callPrintStructurePre(PrintStructureKind::FunctionParameter, param);
  SWIFT_DEFER {
    Printer.printStructurePost(PrintStructureKind::FunctionParameter, param);
  };

  auto printArgName = [&]() {
    // Print argument name.
    auto ArgName = param->getArgumentName();
    auto BodyName = param->getName();
    switch (Options.ArgAndParamPrinting) {
    case PrintOptions::ArgAndParamPrintingMode::EnumElement:
      if (ArgName.empty() && BodyName.empty() && !param->getDefaultValue()) {
        // Don't print anything, in the style of a tuple element.
        return;
      }
      // Else, print the argument only.
      LLVM_FALLTHROUGH;
    case PrintOptions::ArgAndParamPrintingMode::ArgumentOnly:
      Printer.printName(ArgName, PrintNameContext::FunctionParameterExternal);

      if (!ArgNameIsAPIByDefault && !ArgName.empty())
        Printer << " _";
      break;
    case PrintOptions::ArgAndParamPrintingMode::MatchSource:
      if (ArgName == BodyName && ArgNameIsAPIByDefault) {
        Printer.printName(ArgName, PrintNameContext::FunctionParameterExternal);
        break;
      }
      if (ArgName.empty() && !ArgNameIsAPIByDefault) {
        Printer.printName(BodyName, PrintNameContext::FunctionParameterLocal);
        break;
      }
      LLVM_FALLTHROUGH;
    case PrintOptions::ArgAndParamPrintingMode::BothAlways:
      Printer.printName(ArgName, PrintNameContext::FunctionParameterExternal);
      Printer << " ";
      Printer.printName(BodyName, PrintNameContext::FunctionParameterLocal);
      break;
    }
    Printer << ": ";
  };

  auto TheTypeLoc = param->getTypeLoc();

  printArgName();

  if (!TheTypeLoc.getTypeRepr() && param->hasInterfaceType())
    TheTypeLoc = TypeLoc::withoutLoc(param->getInterfaceType());

  // If the parameter is variadic, we will print the "..." after it, but we have
  // to strip off the added array type.
  if (param->isVariadic() && TheTypeLoc.getType()) {
    if (auto *BGT = TheTypeLoc.getType()->getAs<BoundGenericType>())
      TheTypeLoc.setType(BGT->getGenericArgs()[0]);
  }

  // Special case, if we're not going to use the type repr printing, peek
  // through the paren types so that we don't print excessive @escapings.
  unsigned numParens = 0;
  if (!willUseTypeReprPrinting(TheTypeLoc, CurrentType, Options)) {
    auto type = TheTypeLoc.getType();

    printParameterFlags(Printer, Options, paramFlags);
    while (auto parenTy = dyn_cast<ParenType>(type.getPointer())) {
      ++numParens;
      type = parenTy->getUnderlyingType();
    }

    TheTypeLoc = TypeLoc::withoutLoc(type);
  }

  for (unsigned i = 0; i < numParens; ++i)
    Printer << "(";
  if (param->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
    printTypeLocForImplicitlyUnwrappedOptional(TheTypeLoc);
  else
    printTypeLoc(TheTypeLoc);
  for (unsigned i = 0; i < numParens; ++i)
    Printer << ")";

  if (param->isVariadic())
    Printer << "...";

  if (param->isDefaultArgument()) {
    SmallString<128> scratch;
    auto defaultArgStr = param->getDefaultValueStringRepresentation(scratch);

    assert(!defaultArgStr.empty() && "empty default argument?");
    Printer << " = ";

    switch (param->getDefaultArgumentKind()) {
    case DefaultArgumentKind::File:
    case DefaultArgumentKind::Line:
    case DefaultArgumentKind::Column:
    case DefaultArgumentKind::Function:
    case DefaultArgumentKind::DSOHandle:
    case DefaultArgumentKind::NilLiteral:
      Printer.printKeyword(defaultArgStr);
      break;
    default:
      Printer << defaultArgStr;
      break;
    }
  }
}

void PrintAST::printParameterList(ParameterList *PL,
                                  ArrayRef<AnyFunctionType::Param> params,
                                  bool isAPINameByDefault) {
  Printer << "(";
  const unsigned paramSize = params.size();
  for (unsigned i = 0, e = PL->size(); i != e; ++i) {
    if (i > 0)
      Printer << ", ";
    auto paramFlags = (i < paramSize)
                    ? params[i].getParameterFlags()
                    : ParameterTypeFlags();
    printOneParameter(PL->get(i), paramFlags,
                      isAPINameByDefault);
  }
  Printer << ")";
}

void PrintAST::printFunctionParameters(AbstractFunctionDecl *AFD) {
  auto BodyParams = AFD->getParameters();
  auto curTy = AFD->hasInterfaceType() ? AFD->getInterfaceType() : nullptr;

  // Skip over the implicit 'self'.
  if (AFD->hasImplicitSelfDecl()) {
    if (curTy)
      if (auto funTy = curTy->getAs<AnyFunctionType>())
        curTy = funTy->getResult();
  }

  ArrayRef<AnyFunctionType::Param> parameterListTypes;
  if (curTy) {
    if (auto funTy = curTy->getAs<AnyFunctionType>()) {
      parameterListTypes = funTy->getParams();
    }
  }

  printParameterList(BodyParams, parameterListTypes,
                     AFD->argumentNameIsAPIByDefault());

  if (AFD->hasThrows()) {
    if (AFD->getAttrs().hasAttribute<RethrowsAttr>())
      Printer << " " << tok::kw_rethrows;
    else
      Printer << " " << tok::kw_throws;
  }
}

bool PrintAST::printASTNodes(const ArrayRef<ASTNode> &Elements,
                             bool NeedIndent) {
  IndentRAII IndentMore(*this, NeedIndent);
  bool PrintedSomething = false;
  for (auto element : Elements) {
    PrintedSomething = true;
    Printer.printNewline();
    indent();
    if (auto decl = element.dyn_cast<Decl*>()) {
      if (decl->shouldPrintInContext(Options))
        visit(decl);
    } else if (auto stmt = element.dyn_cast<Stmt*>()) {
      visit(stmt);
    } else {
      // FIXME: print expression
      // visit(element.get<Expr*>());
    }
  }
  return PrintedSomething;
}

void PrintAST::visitAccessorDecl(AccessorDecl *decl) {
  printDocumentationComment(decl);
  printAttributes(decl);
  switch (auto kind = decl->getAccessorKind()) {
  case AccessorKind::Get:
  case AccessorKind::Address:
  case AccessorKind::Read:
  case AccessorKind::Modify:
  case AccessorKind::DidSet:
  case AccessorKind::MutableAddress:
    recordDeclLoc(decl,
      [&]{
        Printer << getAccessorLabel(decl);
      });
    break;
  case AccessorKind::Set:
  case AccessorKind::WillSet:
    recordDeclLoc(decl,
      [&]{
        Printer << getAccessorLabel(decl);

        auto params = decl->getParameters();
        if (params->size() != 0 && !params->get(0)->isImplicit()) {
          auto Name = params->get(0)->getName();
          if (!Name.empty()) {
            Printer << "(";
            Printer.printName(Name);
            Printer << ")";
          }
        }
      });
  }

  printBodyIfNecessary(decl);
}

void PrintAST::visitFuncDecl(FuncDecl *decl) {
  printDocumentationComment(decl);
  printAttributes(decl);
  printAccess(decl);

  if (Options.PrintOriginalSourceText && decl->getStartLoc().isValid()) {
    ASTContext &Ctx = decl->getASTContext();
    SourceLoc StartLoc = decl->getStartLoc();
    SourceLoc EndLoc;
    if (!decl->getBodyResultTypeLoc().isNull()) {
      EndLoc = decl->getBodyResultTypeLoc().getSourceRange().End;
    } else {
      EndLoc = decl->getSignatureSourceRange().End;
    }
    CharSourceRange Range =
      Lexer::getCharSourceRangeFromSourceRange(Ctx.SourceMgr,
                                               SourceRange(StartLoc, EndLoc));
    printSourceRange(Range, Ctx);
  } else {
    if (!Options.SkipIntroducerKeywords) {
      if (decl->isStatic())
        printStaticKeyword(decl->getCorrectStaticSpelling());
      if (decl->isMutating() && !decl->getAttrs().hasAttribute<MutatingAttr>()) {
        Printer.printKeyword("mutating");
        Printer << " ";
      } else if (decl->isConsuming() && !decl->getAttrs().hasAttribute<ConsumingAttr>()) {
        Printer.printKeyword("__consuming");
        Printer << " ";
      }
      Printer << tok::kw_func << " ";
    }
    printContextIfNeeded(decl);
    recordDeclLoc(decl,
      [&]{ // Name
        if (!decl->hasName()) {
          Printer << "<anonymous>";
        } else {
          Printer.printName(decl->getName());
          if (decl->isOperator())
            Printer << " ";
        }
      }, [&] { // Parameters
        printGenericDeclGenericParams(decl);
        printFunctionParameters(decl);
      });

    Type ResultTy = decl->getResultInterfaceType();
    if (ResultTy && !ResultTy->isVoid()) {
      TypeLoc ResultTyLoc = decl->getBodyResultTypeLoc();
      if (!ResultTyLoc.getTypeRepr())
        ResultTyLoc = TypeLoc::withoutLoc(ResultTy);
      // FIXME: Hacky way to workaround the fact that 'Self' as return
      // TypeRepr is not getting 'typechecked'. See
      // \c resolveTopLevelIdentTypeComponent function in TypeCheckType.cpp.
      if (auto *simId = dyn_cast_or_null<SimpleIdentTypeRepr>(ResultTyLoc.getTypeRepr())) {
        if (simId->getIdentifier().str() == "Self")
          ResultTyLoc = TypeLoc::withoutLoc(ResultTy);
      }
      Printer << " -> ";
      Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType);
      if (decl->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
        printTypeLocForImplicitlyUnwrappedOptional(ResultTyLoc);
      else
        printTypeLoc(ResultTyLoc);
      Printer.printStructurePost(PrintStructureKind::FunctionReturnType);
    }
    printGenericDeclGenericRequirements(decl);
  }

  printBodyIfNecessary(decl);
}

void PrintAST::printEnumElement(EnumElementDecl *elt) {
  recordDeclLoc(elt,
    [&]{
      Printer.printName(elt->getName());
    });

  if (auto *PL = elt->getParameterList()) {
    llvm::SaveAndRestore<PrintOptions::ArgAndParamPrintingMode>
      mode(Options.ArgAndParamPrinting,
           PrintOptions::ArgAndParamPrintingMode::EnumElement);


    auto params = ArrayRef<AnyFunctionType::Param>();
    if (elt->hasInterfaceType() && !elt->getInterfaceType()->hasError()) {
      // Walk to the params of the associated values.
      // (EnumMetaType) -> (AssocValues) -> Enum
      params = elt->getInterfaceType()->castTo<AnyFunctionType>()
                                      ->getResult()
                                      ->castTo<AnyFunctionType>()
                                      ->getParams();
    }
    printParameterList(PL, params,
                       /*isAPINameByDefault*/true);
  }

  auto *raw = elt->getRawValueExpr();
  if (!Options.EnumRawValues || !raw || raw->isImplicit())
    return;

  // Print the explicit raw value expression.
  Printer << " = ";
  switch (raw->getKind()) {
  case ExprKind::IntegerLiteral:
  case ExprKind::FloatLiteral: {
    auto *numLiteral = cast<NumberLiteralExpr>(raw);
    Printer.callPrintStructurePre(PrintStructureKind::NumberLiteral);
    if (numLiteral->isNegative())
      Printer << "-";
    Printer << numLiteral->getDigitsText();
    Printer.printStructurePost(PrintStructureKind::NumberLiteral);
    break;
  }
  case ExprKind::StringLiteral: {
    Printer.callPrintStructurePre(PrintStructureKind::StringLiteral);
    llvm::SmallString<32> str;
    llvm::raw_svector_ostream os(str);
    os << QuotedString(cast<StringLiteralExpr>(raw)->getValue());
    Printer << str;
    Printer.printStructurePost(PrintStructureKind::StringLiteral);
    break;
  }
  default:
    break; // Incorrect raw value; skip it for error recovery.
  }
}

void PrintAST::visitEnumCaseDecl(EnumCaseDecl *decl) {
  auto elems = decl->getElements();
  if (!elems.empty()) {
    // Documentation comments over the case are attached to the enum elements.
    printDocumentationComment(elems[0]);
  }
  printAttributes(decl);
  Printer << tok::kw_case << " ";

  interleave(elems.begin(), elems.end(),
    [&](EnumElementDecl *elt) {
      printEnumElement(elt);
    },
    [&] { Printer << ", "; });
}

void PrintAST::visitEnumElementDecl(EnumElementDecl *decl) {
  printDocumentationComment(decl);
  // In cases where there is no parent EnumCaseDecl (such as imported or
  // deserialized elements), print the element independently.
  printAttributes(decl);
  Printer << tok::kw_case << " ";
  printEnumElement(decl);
}

void PrintAST::visitSubscriptDecl(SubscriptDecl *decl) {
  printDocumentationComment(decl);
  printAttributes(decl);
  printAccess(decl);
  printContextIfNeeded(decl);
  recordDeclLoc(decl, [&]{
    Printer << "subscript";
  }, [&] { // Parameters
    printGenericDeclGenericParams(decl);
    auto params = ArrayRef<AnyFunctionType::Param>();
    if (decl->hasInterfaceType() && !decl->getInterfaceType()->hasError()) {
      // Walk to the params of the subscript's indices.
      params = decl->getInterfaceType()->castTo<AnyFunctionType>()->getParams();
    }
    printParameterList(decl->getIndices(), params,
                       /*isAPINameByDefault*/false);
  });
  Printer << " -> ";

  Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType);
  TypeLoc elementTy = decl->getElementTypeLoc();
  if (!elementTy.getTypeRepr())
    elementTy = TypeLoc::withoutLoc(decl->getElementInterfaceType());
  if (decl->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
    printTypeLocForImplicitlyUnwrappedOptional(elementTy);
  else
    printTypeLoc(elementTy);
  Printer.printStructurePost(PrintStructureKind::FunctionReturnType);
  printGenericDeclGenericRequirements(decl);
  printAccessors(decl);
}

void PrintAST::visitConstructorDecl(ConstructorDecl *decl) {
  printDocumentationComment(decl);
  printAttributes(decl);
  printAccess(decl);

  if ((decl->getInitKind() == CtorInitializerKind::Convenience ||
       decl->getInitKind() == CtorInitializerKind::ConvenienceFactory) &&
      !decl->getAttrs().hasAttribute<ConvenienceAttr>()) {
    // Protocol extension initializers are modeled as convenience initializers,
    // but they're not written that way in source. Check if we're actually
    // printing onto a class.
    bool isClassContext;
    if (CurrentType) {
      isClassContext = CurrentType->getClassOrBoundGenericClass() != nullptr;
    } else {
      const DeclContext *dc = decl->getDeclContext();
      isClassContext = dc->getSelfClassDecl() != nullptr;
    }
    if (isClassContext) {
      Printer.printKeyword("convenience");
      Printer << " ";
    } else {
      assert(decl->getDeclContext()->getExtendedProtocolDecl() &&
             "unexpected convenience initializer");
    }
  } else if (decl->getInitKind() == CtorInitializerKind::Factory) {
    Printer << "/*not inherited*/ ";
  }

  printContextIfNeeded(decl);
  recordDeclLoc(decl,
    [&]{
      Printer << "init";
    }, [&] { // Signature
      switch (decl->getFailability()) {
      case OTK_None:
        break;

      case OTK_Optional:
        Printer << "?";
        break;

      case OTK_ImplicitlyUnwrappedOptional:
        Printer << "!";
        break;
      }

      printGenericDeclGenericParams(decl);
      printFunctionParameters(decl);
    });

  printGenericDeclGenericRequirements(decl);

  printBodyIfNecessary(decl);
}

void PrintAST::visitDestructorDecl(DestructorDecl *decl) {
  printDocumentationComment(decl);
  printAttributes(decl);
  printContextIfNeeded(decl);
  recordDeclLoc(decl,
    [&]{
      Printer << "deinit";
    });

  printBodyIfNecessary(decl);
}

void PrintAST::visitInfixOperatorDecl(InfixOperatorDecl *decl) {
  Printer.printKeyword("infix");
  Printer << " " << tok::kw_operator << " ";
  recordDeclLoc(decl,
    [&]{
      Printer.printName(decl->getName());
    });
  if (auto *group = decl->getPrecedenceGroup())
    Printer << " : " << group->getName();
  auto designatedNominalTypes = decl->getDesignatedNominalTypes();
  auto first = true;
  for (auto typeDecl : designatedNominalTypes) {
    if (first && !decl->getPrecedenceGroup())
      Printer << " : " << typeDecl->getName();
    else
      Printer << ", " << typeDecl->getName();
    first = false;
  }
}

void PrintAST::visitPrecedenceGroupDecl(PrecedenceGroupDecl *decl) {
  Printer << tok::kw_precedencegroup << " ";
  recordDeclLoc(decl,
    [&]{
      Printer.printName(decl->getName());
    });
  Printer << " {";
  Printer.printNewline();
  {
    IndentRAII indentMore(*this);
    if (!decl->isAssociativityImplicit() ||
        !decl->isNonAssociative()) {
      indent();
      Printer.printKeyword("associativity");
      Printer << ": ";
      switch (decl->getAssociativity()) {
      case Associativity::None:
        Printer.printKeyword("none");
        break;
      case Associativity::Left:
        Printer.printKeyword("left");
        break;
      case Associativity::Right:
        Printer.printKeyword("right");
        break;
      }
      Printer.printNewline();
    }
    if (!decl->isAssignmentImplicit() ||
        decl->isAssignment()) {
      indent();
      Printer.printKeyword("assignment");
      Printer << ": ";
      Printer.printKeyword(decl->isAssignment() ? "true" : "false");
      Printer.printNewline();
    }
    if (!decl->getHigherThan().empty()) {
      indent();
      Printer.printKeyword("higherThan");
      Printer << ": ";
      if (!decl->getHigherThan().empty()) {
        Printer << decl->getHigherThan()[0].Name;
        for (auto &rel : decl->getHigherThan().slice(1))
          Printer << ", " << rel.Name;
      }
      Printer.printNewline();
    }
    if (!decl->getLowerThan().empty()) {
      indent();
      Printer.printKeyword("lowerThan");
      Printer << ": ";
      if (!decl->getLowerThan().empty()) {
        Printer << decl->getLowerThan()[0].Name;
        for (auto &rel : decl->getLowerThan().slice(1))
          Printer << ", " << rel.Name;
      }
      Printer.printNewline();
    }
  }
  indent();
  Printer << "}";
}

void PrintAST::visitPrefixOperatorDecl(PrefixOperatorDecl *decl) {
  Printer.printKeyword("prefix");
  Printer << " " << tok::kw_operator << " ";
  recordDeclLoc(decl,
    [&]{
      Printer.printName(decl->getName());
    });
  auto designatedNominalTypes = decl->getDesignatedNominalTypes();
  auto first = true;
  for (auto typeDecl : designatedNominalTypes) {
    if (first)
      Printer << " : " << typeDecl->getName();
    else
      Printer << ", " << typeDecl->getName();
    first = false;
  }
}

void PrintAST::visitPostfixOperatorDecl(PostfixOperatorDecl *decl) {
  Printer.printKeyword("postfix");
  Printer << " " << tok::kw_operator << " ";
  recordDeclLoc(decl,
    [&]{
      Printer.printName(decl->getName());
    });
  auto designatedNominalTypes = decl->getDesignatedNominalTypes();
  auto first = true;
  for (auto typeDecl : designatedNominalTypes) {
    if (first)
      Printer << " : " << typeDecl->getName();
    else
      Printer << ", " << typeDecl->getName();
    first = false;
  }
}

void PrintAST::visitModuleDecl(ModuleDecl *decl) { }

void PrintAST::visitMissingMemberDecl(MissingMemberDecl *decl) {
  Printer << "/* placeholder for ";
  recordDeclLoc(decl, [&]{ Printer << decl->getFullName(); });
  Printer << " */";
}

void PrintAST::visitBraceStmt(BraceStmt *stmt) {
  printBraceStmt(stmt);
}

void PrintAST::visitReturnStmt(ReturnStmt *stmt) {
  Printer << tok::kw_return;
  if (stmt->hasResult()) {
    Printer << " ";
    // FIXME: print expression.
  }
}

void PrintAST::visitYieldStmt(YieldStmt *stmt) {
  Printer.printKeyword("yield");
  Printer << " ";
  bool parens = (stmt->getYields().size() != 1
                 || stmt->getLParenLoc().isValid());
  if (parens) Printer << "(";
  bool first = true;
  for (auto yield : stmt->getYields()) {
    if (first) {
      first = false;
    } else {
      Printer << ", ";
    }

    // FIXME: print expression.
    (void) yield;
  }
  if (parens) Printer << ")";
}

void PrintAST::visitThrowStmt(ThrowStmt *stmt) {
  Printer << tok::kw_throw << " ";
  // FIXME: print expression.
}

void PrintAST::visitPoundAssertStmt(PoundAssertStmt *stmt) {
  Printer << tok::pound_assert << " ";
  // FIXME: print expression.
}

void PrintAST::visitDeferStmt(DeferStmt *stmt) {
  Printer << tok::kw_defer << " ";
  visit(stmt->getBodyAsWritten());
}

void PrintAST::visitIfStmt(IfStmt *stmt) {
  Printer << tok::kw_if << " ";
  // FIXME: print condition
  Printer << " ";
  visit(stmt->getThenStmt());
  if (auto elseStmt = stmt->getElseStmt()) {
    Printer << " " << tok::kw_else << " ";
    visit(elseStmt);
  }
}
void PrintAST::visitGuardStmt(GuardStmt *stmt) {
  Printer << tok::kw_guard << " ";
  // FIXME: print condition
  Printer << " ";
  visit(stmt->getBody());
}

void PrintAST::visitWhileStmt(WhileStmt *stmt) {
  Printer << tok::kw_while << " ";
  // FIXME: print condition
  Printer << " ";
  visit(stmt->getBody());
}

void PrintAST::visitRepeatWhileStmt(RepeatWhileStmt *stmt) {
  Printer << tok::kw_do << " ";
  visit(stmt->getBody());
  Printer << " " << tok::kw_while << " ";
  // FIXME: print condition
}

void PrintAST::visitDoStmt(DoStmt *stmt) {
  Printer << tok::kw_do << " ";
  visit(stmt->getBody());
}

void PrintAST::visitDoCatchStmt(DoCatchStmt *stmt) {
  Printer << tok::kw_do << " ";
  visit(stmt->getBody());
  for (auto clause : stmt->getCatches()) {
    visitCatchStmt(clause);
  }
}

void PrintAST::visitCatchStmt(CatchStmt *stmt) {
  Printer << tok::kw_catch << " ";
  printPattern(stmt->getErrorPattern());
  if (auto guard = stmt->getGuardExpr()) {
    Printer << " " << tok::kw_where << " ";
    // FIXME: print guard expression
    (void) guard;
  }
  Printer << ' ';
  visit(stmt->getBody());
}

void PrintAST::visitForEachStmt(ForEachStmt *stmt) {
  Printer << tok::kw_for << " ";
  printPattern(stmt->getPattern());
  Printer << " " << tok::kw_in << " ";
  // FIXME: print container
  Printer << " ";
  visit(stmt->getBody());
}

void PrintAST::visitBreakStmt(BreakStmt *stmt) {
  Printer << tok::kw_break;
}

void PrintAST::visitContinueStmt(ContinueStmt *stmt) {
  Printer << tok::kw_continue;
}

void PrintAST::visitFallthroughStmt(FallthroughStmt *stmt) {
  Printer << tok::kw_fallthrough;
}

void PrintAST::visitSwitchStmt(SwitchStmt *stmt) {
  Printer << tok::kw_switch << " ";
  // FIXME: print subject
  Printer << "{";
  Printer.printNewline();
  for (auto N : stmt->getRawCases()) {
    if (N.is<Stmt*>())
      visit(cast<CaseStmt>(N.get<Stmt*>()));
    else
      visit(cast<IfConfigDecl>(N.get<Decl*>()));
  }
  Printer.printNewline();
  indent();
  Printer << "}";
}

void PrintAST::visitCaseStmt(CaseStmt *CS) {
  if (CS->hasUnknownAttr())
    Printer << "@unknown ";

  if (CS->isDefault()) {
    Printer << tok::kw_default;
  } else {
    auto PrintCaseLabelItem = [&](const CaseLabelItem &CLI) {
      if (auto *P = CLI.getPattern())
        printPattern(P);
      if (CLI.getGuardExpr()) {
        Printer << " " << tok::kw_where << " ";
        // FIXME: print guard expr
      }
    };
    Printer << tok::kw_case << " ";
    interleave(CS->getCaseLabelItems(), PrintCaseLabelItem,
               [&] { Printer << ", "; });
  }
  Printer << ":";
  Printer.printNewline();

  printASTNodes((cast<BraceStmt>(CS->getBody())->getElements()));
}

void PrintAST::visitFailStmt(FailStmt *stmt) {
  Printer << tok::kw_return << " " << tok::kw_nil;
}

void Decl::print(raw_ostream &os) const {
  PrintOptions options;
  options.FunctionDefinitions = true;
  options.TypeDefinitions = true;
  options.VarInitializers = true;
  // FIXME: Move all places where SIL printing is happening to explicit options.
  // For example, see \c ProjectionPath::print.
  options.PreferTypeRepr = false;

  print(os, options);
}

void Decl::print(raw_ostream &OS, const PrintOptions &Opts) const {
  StreamPrinter Printer(OS);
  print(Printer, Opts);
}

bool Decl::print(ASTPrinter &Printer, const PrintOptions &Opts) const {
  PrintAST printer(Printer, Opts);
  return printer.visit(const_cast<Decl *>(this));
}

bool Decl::shouldPrintInContext(const PrintOptions &PO) const {
  // Skip getters/setters. They are part of the variable or subscript.
  if (isa<AccessorDecl>(this))
    return false;

  if (PO.ExplodePatternBindingDecls) {
    if (isa<VarDecl>(this))
      return true;
    if (isa<PatternBindingDecl>(this))
      return false;
  } else {
    // Try to preserve the PatternBindingDecl structure.

    // Skip stored variables, unless they came from a Clang module.
    // Stored variables in Swift source will be picked up by the
    // PatternBindingDecl.
    if (auto *VD = dyn_cast<VarDecl>(this)) {
      if (!VD->hasClangNode() && VD->hasStorage())
        return false;
    }

    // Skip pattern bindings that consist of just one variable with
    // interesting accessors.
    if (auto pbd = dyn_cast<PatternBindingDecl>(this)) {
      if (pbd->getPatternList().size() == 1) {
        auto pattern =
          pbd->getPatternList()[0].getPattern()->getSemanticsProvidingPattern();
        if (auto named = dyn_cast<NamedPattern>(pattern)) {
          if (!named->getDecl()->hasStorage())
            return false;
        }
      }
    }
  }

  if (isa<IfConfigDecl>(this)) {
    return PO.PrintIfConfig;
  }

  // Print everything else.
  return true;
}

void Pattern::print(llvm::raw_ostream &OS, const PrintOptions &Options) const {
  StreamPrinter StreamPrinter(OS);
  PrintAST Printer(StreamPrinter, Options);
  Printer.printPattern(this);
}

//===----------------------------------------------------------------------===//
//  Type Printing
//===----------------------------------------------------------------------===//

namespace {
class TypePrinter : public TypeVisitor<TypePrinter> {
  using super = TypeVisitor;

  ASTPrinter &Printer;
  const PrintOptions &Options;

  void printGenericArgs(ArrayRef<Type> Args) {
    if (Args.empty())
      return;

    Printer << "<";
    interleave(Args, [&](Type Arg) { visit(Arg); }, [&] { Printer << ", "; });
    Printer << ">";
  }

  /// Helper function for printing a type that is embedded within a larger type.
  ///
  /// This is necessary whenever the inner type may not normally be represented
  /// as a 'type-simple' production in the type grammar.
  void printWithParensIfNotSimple(Type T) {
    if (T.isNull()) {
      visit(T);
      return;
    }

    if (T->hasSimpleTypeRepr()) {
      visit(T);
    } else {
      Printer << "(";
      visit(T);
      Printer << ")";
    }
  }

  template <typename T>
  void printModuleContext(T *Ty) {
    ModuleDecl *Mod = Ty->getDecl()->getModuleContext();
    Printer.printModuleRef(Mod, Mod->getName());
    Printer << ".";
  }

  template <typename T>
  void printTypeDeclName(T *Ty) {
    TypeDecl *TD = Ty->getDecl();
    Printer.printTypeRef(Ty, TD, TD->getName());
  }

  // FIXME: we should have a callback that would tell us
  // whether it's kosher to print a module name or not
  bool isLLDBExpressionModule(ModuleDecl *M) {
    if (!M)
      return false;
    return M->getName().str().startswith(LLDB_EXPRESSIONS_MODULE_NAME_PREFIX);
  }

  bool shouldPrintFullyQualified(TypeBase *T) {
    if (Options.FullyQualifiedTypes)
      return true;

    if (!Options.FullyQualifiedTypesIfAmbiguous)
      return false;

    Decl *D = T->getAnyGeneric();

    // If we cannot find the declaration, be extra careful and print
    // the type qualified.
    if (!D)
      return true;

    ModuleDecl *M = D->getDeclContext()->getParentModule();

    if (Options.CurrentModule && M == Options.CurrentModule) {
      return false;
    }

    // Don't print qualifiers for types from the standard library.
    if (M->isStdlibModule() ||
        M->getName() == M->getASTContext().Id_ObjectiveC ||
        M->isSystemModule() ||
        isLLDBExpressionModule(M))
      return false;

    // Don't print qualifiers for imported types.
    for (auto File : M->getFiles()) {
      if (File->getKind() == FileUnitKind::ClangModule)
        return false;
    }

    return true;
  }

public:
  TypePrinter(ASTPrinter &Printer, const PrintOptions &PO)
      : Printer(Printer), Options(PO) {}

  void visit(Type T) {
    Printer.printTypePre(TypeLoc::withoutLoc(T));
    SWIFT_DEFER { Printer.printTypePost(TypeLoc::withoutLoc(T)); };

    super::visit(T);
  }

  void visitErrorType(ErrorType *T) {
    if (auto originalType = T->getOriginalType())
      visit(originalType);
    else
      Printer << "<<error type>>";
  }

  void visitUnresolvedType(UnresolvedType *T) {
    if (T->getASTContext().LangOpts.DebugConstraintSolver)
      Printer << "<<unresolvedtype>>";
    else
      Printer << "_";
  }

  void visitBuiltinRawPointerType(BuiltinRawPointerType *T) {
    Printer << BUILTIN_TYPE_NAME_RAWPOINTER;
  }

  void visitBuiltinNativeObjectType(BuiltinNativeObjectType *T) {
    Printer << BUILTIN_TYPE_NAME_NATIVEOBJECT;
  }

  void visitBuiltinUnknownObjectType(BuiltinUnknownObjectType *T) {
    Printer << BUILTIN_TYPE_NAME_UNKNOWNOBJECT;
  }

  void visitBuiltinBridgeObjectType(BuiltinBridgeObjectType *T) {
    Printer << BUILTIN_TYPE_NAME_BRIDGEOBJECT;
  }

  void visitBuiltinUnsafeValueBufferType(BuiltinUnsafeValueBufferType *T) {
    Printer << BUILTIN_TYPE_NAME_UNSAFEVALUEBUFFER;
  }

  void visitBuiltinIntegerLiteralType(BuiltinIntegerLiteralType *T) {
    Printer << BUILTIN_TYPE_NAME_INTLITERAL;
  }

  void visitBuiltinVectorType(BuiltinVectorType *T) {
    llvm::SmallString<32> UnderlyingStrVec;
    StringRef UnderlyingStr;
    {
      // FIXME: Ugly hack: remove the .Builtin from the element type.
      {
        llvm::raw_svector_ostream UnderlyingOS(UnderlyingStrVec);
        T->getElementType().print(UnderlyingOS);
      }
      if (UnderlyingStrVec.startswith(BUILTIN_TYPE_NAME_PREFIX))
        UnderlyingStr = UnderlyingStrVec.substr(8);
      else
        UnderlyingStr = UnderlyingStrVec;
    }

    Printer << BUILTIN_TYPE_NAME_VEC << T->getNumElements() << "x" << UnderlyingStr;
  }

  void visitBuiltinIntegerType(BuiltinIntegerType *T) {
    auto width = T->getWidth();
    if (width.isFixedWidth()) {
      Printer << BUILTIN_TYPE_NAME_INT << width.getFixedWidth();
    } else if (width.isPointerWidth()) {
      Printer << BUILTIN_TYPE_NAME_WORD;
    } else {
      llvm_unreachable("impossible bit width");
    }
  }

  void visitBuiltinFloatType(BuiltinFloatType *T) {
    switch (T->getFPKind()) {
    case BuiltinFloatType::IEEE16:  Printer << "Builtin.FPIEEE16"; return;
    case BuiltinFloatType::IEEE32:  Printer << "Builtin.FPIEEE32"; return;
    case BuiltinFloatType::IEEE64:  Printer << "Builtin.FPIEEE64"; return;
    case BuiltinFloatType::IEEE80:  Printer << "Builtin.FPIEEE80"; return;
    case BuiltinFloatType::IEEE128: Printer << "Builtin.FPIEEE128"; return;
    case BuiltinFloatType::PPC128:  Printer << "Builtin.FPPPC128"; return;
    }
  }

  void visitSILTokenType(SILTokenType *T) {
    Printer << BUILTIN_TYPE_NAME_SILTOKEN;
  }

  void visitNameAliasType(NameAliasType *T) {
    if (Options.PrintForSIL || Options.PrintNameAliasUnderlyingType) {
      visit(T->getSinglyDesugaredType());
      return;
    }

    if (auto parent = T->getParent()) {
      visit(parent);
      Printer << ".";
    }

    printTypeDeclName(T);
    printGenericArgs(T->getInnermostGenericArgs());
  }

  void visitParenType(ParenType *T) {
    Printer << "(";
    printParameterFlags(Printer, Options, T->getParameterFlags());
    visit(T->getUnderlyingType()->getInOutObjectType());
    Printer << ")";
  }

  void visitTupleType(TupleType *T) {
    Printer.callPrintStructurePre(PrintStructureKind::TupleType);
    SWIFT_DEFER { Printer.printStructurePost(PrintStructureKind::TupleType); };

    Printer << "(";

    auto Fields = T->getElements();
    for (unsigned i = 0, e = Fields.size(); i != e; ++i) {
      if (i)
        Printer << ", ";
      const TupleTypeElt &TD = Fields[i];
      Type EltType = TD.getRawType();

      Printer.callPrintStructurePre(PrintStructureKind::TupleElement);
      SWIFT_DEFER {
        Printer.printStructurePost(PrintStructureKind::TupleElement);
      };

      if (TD.hasName()) {
        Printer.printName(TD.getName(), PrintNameContext::TupleElement);
        Printer << ": ";
      }
      if (TD.isVararg()) {
        visit(TD.getVarargBaseTy());
        Printer << "...";
      } else {
        printParameterFlags(Printer, Options, TD.getParameterFlags());
        visit(EltType);
      }
    }
    Printer << ")";
  }

  void visitUnboundGenericType(UnboundGenericType *T) {
    if (auto ParentType = T->getParent()) {
      visit(ParentType);
      Printer << ".";
    } else if (shouldPrintFullyQualified(T)) {
      printModuleContext(T);
    }
    printTypeDeclName(T);
  }

  void visitBoundGenericType(BoundGenericType *T) {
    if (Options.SynthesizeSugarOnTypes) {
      auto *NT = T->getDecl();
      auto &Ctx = T->getASTContext();
      if (NT == Ctx.getArrayDecl()) {
        Printer << "[";
        visit(T->getGenericArgs()[0]);
        Printer << "]";
        return;
      }
      if (NT == Ctx.getDictionaryDecl()) {
        Printer << "[";
        visit(T->getGenericArgs()[0]);
        Printer << " : ";
        visit(T->getGenericArgs()[1]);
        Printer << "]";
        return;
      }
      if (NT == Ctx.getOptionalDecl()) {
        printWithParensIfNotSimple(T->getGenericArgs()[0]);
        Printer << "?";
        return;
      }
    }
    if (auto ParentType = T->getParent()) {
      visit(ParentType);
      Printer << ".";
    } else if (shouldPrintFullyQualified(T)) {
      printModuleContext(T);
    }

    printTypeDeclName(T);
    printGenericArgs(T->getGenericArgs());
  }

  void visitParentType(Type T) {
    PrintOptions innerOptions = Options;
    innerOptions.SynthesizeSugarOnTypes = false;

    if (auto sugarType = dyn_cast<SyntaxSugarType>(T.getPointer()))
      T = sugarType->getImplementationType();

    TypePrinter(Printer, innerOptions).visit(T);
  }

  void visitEnumType(EnumType *T) {
    if (auto ParentType = T->getParent()) {
      visitParentType(ParentType);
      Printer << ".";
    } else if (shouldPrintFullyQualified(T)) {
      printModuleContext(T);
    }

    printTypeDeclName(T);
  }

  void visitStructType(StructType *T) {
    if (auto ParentType = T->getParent()) {
      visitParentType(ParentType);
      Printer << ".";
    } else if (shouldPrintFullyQualified(T)) {
      printModuleContext(T);
    }

    printTypeDeclName(T);
  }

  void visitClassType(ClassType *T) {
    if (auto ParentType = T->getParent()) {
      visitParentType(ParentType);
      Printer << ".";
    } else if (shouldPrintFullyQualified(T)) {
      printModuleContext(T);
    }

    printTypeDeclName(T);
  }

  void visitAnyMetatypeType(AnyMetatypeType *T) {
    if (T->hasRepresentation()) {
      switch (T->getRepresentation()) {
      case MetatypeRepresentation::Thin:  Printer << "@thin ";  break;
      case MetatypeRepresentation::Thick: Printer << "@thick "; break;
      case MetatypeRepresentation::ObjC:  Printer << "@objc_metatype "; break;
      }
    }
    printWithParensIfNotSimple(T->getInstanceType());

    // We spell normal metatypes of existential types as .Protocol.
    if (isa<MetatypeType>(T) &&
        T->getInstanceType()->isAnyExistentialType()) {
      Printer << ".Protocol";
    } else {
      Printer << ".Type";
    }
  }

  void visitModuleType(ModuleType *T) {
    Printer << "module<";
    Printer.printModuleRef(T->getModule(), T->getModule()->getName());
    Printer << ">";
  }

  void visitDynamicSelfType(DynamicSelfType *T) {
    if (Options.PrintInSILBody) {
      Printer << "@dynamic_self ";
      visit(T->getSelfType());
      return;
    }

    // Try to print as a reference to the static type so that we will get a USR,
    // in cursor info.
    auto staticSelfT = T->getSelfType();

    if (auto *NTD = staticSelfT->getAnyNominal()) {
      if (isa<ClassDecl>(NTD)) {
        auto Name = T->getASTContext().Id_Self;
        Printer.printTypeRef(T, NTD, Name);
        return;
      }
    }

    visit(staticSelfT);
  }

  void printFunctionExtInfo(AnyFunctionType::ExtInfo info) {
    if (Options.SkipAttributes)
      return;


    if (Options.PrintFunctionRepresentationAttrs &&
        !Options.excludeAttrKind(TAK_convention) &&
        info.getSILRepresentation() != SILFunctionType::Representation::Thick) {
      Printer.callPrintStructurePre(PrintStructureKind::BuiltinAttribute);
      Printer.printAttrName("@convention");
      Printer << "(";
      // TODO: coalesce into a single convention attribute.
      switch (info.getSILRepresentation()) {
      case SILFunctionType::Representation::Thick:
        llvm_unreachable("thick is not printed");
      case SILFunctionType::Representation::Thin:
        Printer << "thin";
        break;
      case SILFunctionType::Representation::Block:
        Printer << "block";
        break;
      case SILFunctionType::Representation::CFunctionPointer:
        Printer << "c";
        break;
      case SILFunctionType::Representation::Method:
        Printer << "method";
        break;
      case SILFunctionType::Representation::ObjCMethod:
        Printer << "objc_method";
        break;
      case SILFunctionType::Representation::WitnessMethod:
        Printer << "witness_method";
        break;
      case SILFunctionType::Representation::Closure:
        Printer << "closure";
        break;
      }
      Printer << ")";
      Printer.printStructurePost(PrintStructureKind::BuiltinAttribute);
      Printer << " ";
    }
  }

  void printFunctionExtInfo(
      SILFunctionType::ExtInfo info,
      Optional<ProtocolConformanceRef> witnessMethodConformance) {
    if (Options.SkipAttributes)
      return;

    if (Options.PrintFunctionRepresentationAttrs &&
        !Options.excludeAttrKind(TAK_convention) &&
        info.getRepresentation() != SILFunctionType::Representation::Thick) {
      Printer.callPrintStructurePre(PrintStructureKind::BuiltinAttribute);
      Printer.printAttrName("@convention");
      Printer << "(";
      switch (info.getRepresentation()) {
      case SILFunctionType::Representation::Thick:
        llvm_unreachable("thick is not printed");
      case SILFunctionType::Representation::Thin:
        Printer << "thin";
        break;
      case SILFunctionType::Representation::Block:
        Printer << "block";
        break;
      case SILFunctionType::Representation::CFunctionPointer:
        Printer << "c";
        break;
      case SILFunctionType::Representation::Method:
        Printer << "method";
        break;
      case SILFunctionType::Representation::ObjCMethod:
        Printer << "objc_method";
        break;
      case SILFunctionType::Representation::WitnessMethod:
        Printer << "witness_method: ";
        printTypeDeclName(
            witnessMethodConformance->getRequirement()->getDeclaredType());
        break;
      case SILFunctionType::Representation::Closure:
        Printer << "closure";
        break;
      }
      Printer << ")";
      Printer.printStructurePost(PrintStructureKind::BuiltinAttribute);
      Printer << " ";
    }

    if (info.isPseudogeneric()) {
      Printer.printSimpleAttr("@pseudogeneric") << " ";
    }
    if (info.isNoEscape()) {
      Printer.printSimpleAttr("@noescape") << " ";
    }
  }

  void visitAnyFunctionTypeParams(ArrayRef<AnyFunctionType::Param> Params,
                                  bool printLabels) {
    Printer << "(";

    for (unsigned i = 0, e = Params.size(); i != e; ++i) {
      if (i)
        Printer << ", ";
      const AnyFunctionType::Param &Param = Params[i];

      Printer.callPrintStructurePre(PrintStructureKind::FunctionParameter);
      SWIFT_DEFER {
        Printer.printStructurePost(PrintStructureKind::FunctionParameter);
      };

      if (printLabels && Param.hasLabel()) {
        Printer.printName(Param.getLabel(),
                          PrintNameContext::FunctionParameterExternal);
        Printer << ": ";
      }

      printParameterFlags(Printer, Options, Param.getParameterFlags());
      visit(Param.getPlainType());
      if (Param.isVariadic())
        Printer << "...";
    }

    Printer << ")";
  }

  void visitFunctionType(FunctionType *T) {
    Printer.callPrintStructurePre(PrintStructureKind::FunctionType);
    SWIFT_DEFER {
      Printer.printStructurePost(PrintStructureKind::FunctionType);
    };

    printFunctionExtInfo(T->getExtInfo());

    // If we're stripping argument labels from types, do it when printing.
    visitAnyFunctionTypeParams(T->getParams(), /*printLabels*/false);

    if (T->throws())
      Printer << " " << tok::kw_throws;

    Printer << " -> ";

    Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType);
    T->getResult().print(Printer, Options);
    Printer.printStructurePost(PrintStructureKind::FunctionReturnType);
  }

  void printGenericSignature(const GenericSignature *genericSig,
                             unsigned flags) {
    PrintAST(Printer, Options).printGenericSignature(genericSig, flags);
  }

  void visitGenericFunctionType(GenericFunctionType *T) {
    Printer.callPrintStructurePre(PrintStructureKind::FunctionType);
    SWIFT_DEFER {
      Printer.printStructurePost(PrintStructureKind::FunctionType);
    };

    printFunctionExtInfo(T->getExtInfo());
    printGenericSignature(T->getGenericSignature(),
                          PrintAST::PrintParams |
                          PrintAST::PrintRequirements);
    Printer << " ";

   visitAnyFunctionTypeParams(T->getParams(), /*printLabels*/true);

    if (T->throws())
      Printer << " " << tok::kw_throws;

    Printer << " -> ";
    Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType);
    T->getResult().print(Printer, Options);
    Printer.printStructurePost(PrintStructureKind::FunctionReturnType);
  }

  void printSILCoroutineKind(SILCoroutineKind kind) {
    switch (kind) {
    case SILCoroutineKind::None:
      return;
    case SILCoroutineKind::YieldOnce:
      Printer << "@yield_once ";
      return;
    case SILCoroutineKind::YieldMany:
      Printer << "@yield_many ";
      return;
    }
    llvm_unreachable("bad convention");
  }

  void printCalleeConvention(ParameterConvention conv) {
    switch (conv) {
    case ParameterConvention::Direct_Unowned:
      return;
    case ParameterConvention::Direct_Owned:
      Printer << "@callee_owned ";
      return;
    case ParameterConvention::Direct_Guaranteed:
      Printer << "@callee_guaranteed ";
      return;
    case ParameterConvention::Indirect_In:
    case ParameterConvention::Indirect_In_Constant:
    case ParameterConvention::Indirect_Inout:
    case ParameterConvention::Indirect_InoutAliasable:
    case ParameterConvention::Indirect_In_Guaranteed:
      llvm_unreachable("callee convention cannot be indirect");
    }
    llvm_unreachable("bad convention");
  }

  void visitSILFunctionType(SILFunctionType *T) {
    printSILCoroutineKind(T->getCoroutineKind());
    printFunctionExtInfo(T->getExtInfo(),
                         T->getWitnessMethodConformanceOrNone());
    printCalleeConvention(T->getCalleeConvention());
    if (auto sig = T->getGenericSignature()) {
      printGenericSignature(sig,
                            PrintAST::PrintParams |
                            PrintAST::PrintRequirements);
      Printer << " ";
    }

    Printer << "(";
    bool first = true;
    for (auto param : T->getParameters()) {
      Printer.printSeparator(first, ", ");
      param.print(Printer, Options);
    }
    Printer << ") -> ";

    unsigned totalResults =
      T->getNumYields() + T->getNumResults() + unsigned(T->hasErrorResult());

    if (totalResults != 1) Printer << "(";

    first = true;

    for (auto yield : T->getYields()) {
      Printer.printSeparator(first, ", ");
      Printer << "@yields ";
      yield.print(Printer, Options);
    }

    for (auto result : T->getResults()) {
      Printer.printSeparator(first, ", ");
      result.print(Printer, Options);
    }

    if (T->hasErrorResult()) {
      // The error result is implicitly @owned; don't print that.
      assert(T->getErrorResult().getConvention() == ResultConvention::Owned);
      Printer.printSeparator(first, ", ");
      Printer << "@error ";
      T->getErrorResult().getType().print(Printer, Options);
    }

    if (totalResults != 1) Printer << ")";
  }

  void visitSILBlockStorageType(SILBlockStorageType *T) {
    Printer << "@block_storage ";
    printWithParensIfNotSimple(T->getCaptureType());
  }

  void visitSILBoxType(SILBoxType *T) {
    {
      // A box layout has its own independent generic environment. Don't try
      // to print it with the environment's generic params.
      PrintOptions subOptions = Options;
      subOptions.GenericEnv = nullptr;
      TypePrinter sub(Printer, subOptions);

      // Capture list used here to ensure we don't print anything using `this`
      // printer, but only the sub-Printer.
      [&sub, T]{
        if (auto sig = T->getLayout()->getGenericSignature()) {
          sub.printGenericSignature(sig,
                            PrintAST::PrintParams | PrintAST::PrintRequirements);
          sub.Printer << " ";
        }
        sub.Printer << "{";
        interleave(T->getLayout()->getFields(),
                   [&](const SILField &field) {
                     sub.Printer <<
                       (field.isMutable() ? " var " : " let ");
                     sub.visit(field.getLoweredType());
                   },
                   [&]{
                     sub.Printer << ",";
                   });
        sub.Printer << " }";
      }();
    }

    // The arguments to the layout, if any, do come from the outer environment.
    if (auto subMap = T->getSubstitutions()) {
      Printer << " <";
      interleave(subMap.getReplacementTypes(),
                 [&](Type type) {
                   visit(type);
                 }, [&]{
                   Printer << ", ";
                 });
      Printer << ">";
    }
  }

  void visitArraySliceType(ArraySliceType *T) {
    Printer << "[";
    visit(T->getBaseType());
    Printer << "]";
  }

  void visitDictionaryType(DictionaryType *T) {
    Printer << "[";
    visit(T->getKeyType());
    Printer << " : ";
    visit(T->getValueType());
    Printer << "]";
  }

  void visitOptionalType(OptionalType *T) {
    auto printAsIUO = Options.PrintOptionalAsImplicitlyUnwrapped;

    // Printing optionals with a trailing '!' applies only to
    // top-level optionals, not to any nested within.
    const_cast<PrintOptions &>(Options).PrintOptionalAsImplicitlyUnwrapped =
        false;
    printWithParensIfNotSimple(T->getBaseType());
    const_cast<PrintOptions &>(Options).PrintOptionalAsImplicitlyUnwrapped =
        printAsIUO;

    if (printAsIUO)
      Printer << "!";
    else
      Printer << "?";
  }

  void visitProtocolType(ProtocolType *T) {
    printTypeDeclName(T);
  }

  void visitProtocolCompositionType(ProtocolCompositionType *T) {
    if (T->getMembers().empty()) {
      if (T->hasExplicitAnyObject())
        Printer << "AnyObject";
      else
        Printer << "Any";
    } else {
      interleave(T->getMembers(), [&](Type Ty) { visit(Ty); },
                 [&] { Printer << " & "; });
      if (T->hasExplicitAnyObject())
        Printer << " & AnyObject";
    }
  }

  void visitLValueType(LValueType *T) {
    Printer << "@lvalue ";
    visit(T->getObjectType());
  }

  void visitInOutType(InOutType *T) {
    Printer << tok::kw_inout << " ";
    visit(T->getObjectType());
  }

  void visitArchetypeType(ArchetypeType *T) {
    if (auto existentialTy = T->getOpenedExistentialType()) {
      if (Options.PrintForSIL)
        Printer << "@opened(\"" << T->getOpenedExistentialID() << "\") ";
      visit(existentialTy);
    } else {
      if (auto parent = T->getParent()) {
        visit(parent);
        Printer << ".";
      }

      if (Options.AlternativeTypeNames) {
        auto found = Options.AlternativeTypeNames->find(T->getCanonicalType());
        if (found != Options.AlternativeTypeNames->end()) {
          Printer << found->second.str();
          return;
        }
      }

      auto Name = T->getName();
      if (Name.empty())
        Printer << "<anonymous>";
      else {
        PrintNameContext context = PrintNameContext::Normal;
        if (Name == T->getASTContext().Id_Self)
          context = PrintNameContext::GenericParameter;
        Printer.printName(Name, context);
      }
    }
  }

  void visitGenericTypeParamType(GenericTypeParamType *T) {
    if (T->getDecl() == nullptr) {
      // If we have an alternate name for this type, use it.
      if (Options.AlternativeTypeNames) {
        auto found = Options.AlternativeTypeNames->find(T->getCanonicalType());
        if (found != Options.AlternativeTypeNames->end()) {
          Printer << found->second.str();
          return;
        }
      }

      // When printing SIL types, use a generic environment to map them from
      // canonical types to sugared types.
      if (Options.GenericEnv)
        T = Options.GenericEnv->getSugaredType(T);
    }

    auto Name = T->getName();
    if (Name.empty())
      Printer << "<anonymous>";
    else {
      if (T->getDecl() &&
          T->getDecl()->getDeclContext()->getSelfProtocolDecl()) {
        Printer.printTypeRef(T, T->getDecl(), Name);
        return;
      }

      PrintNameContext context = PrintNameContext::Normal;
      if (Name == T->getASTContext().Id_Self)
        context = PrintNameContext::GenericParameter;
      Printer.printName(Name, context);
    }
  }

  void visitDependentMemberType(DependentMemberType *T) {
    visitParentType(T->getBase());
    Printer << ".";
    Printer.printName(T->getName());
  }

#define REF_STORAGE(Name, name, ...) \
  void visit##Name##StorageType(Name##StorageType *T) { \
    if (Options.PrintStorageRepresentationAttrs) \
      Printer << "@sil_" #name " "; \
    visit(T->getReferentType()); \
  }
#include "swift/AST/ReferenceStorage.def"

  void visitTypeVariableType(TypeVariableType *T) {
    if (T->getASTContext().LangOpts.DebugConstraintSolver) {
      Printer << "$T" << T->getID();
      return;
    }

    Printer << "_";
  }
};
} // unnamed namespace

void Type::print(raw_ostream &OS, const PrintOptions &PO) const {
  StreamPrinter Printer(OS);
  print(Printer, PO);
}
void Type::print(ASTPrinter &Printer, const PrintOptions &PO) const {
  if (isNull()) {
    if (!PO.AllowNullTypes) {
      // Use report_fatal_error instead of assert to trap in release builds too.
      llvm::report_fatal_error("Cannot pretty-print a null type");
    }
    Printer << "<null>";
    return;
  }
  TypePrinter(Printer, PO).visit(*this);
}

void AnyFunctionType::printParams(raw_ostream &OS, const
                                  PrintOptions &PO) const {
  StreamPrinter Printer(OS);
  printParams(Printer, PO);
}
void AnyFunctionType::printParams(ASTPrinter &Printer,
                                  const PrintOptions &PO) const {
  TypePrinter(Printer, PO).visitAnyFunctionTypeParams(getParams(),
                                                      /*printLabels*/true);
}

void LayoutConstraintInfo::print(raw_ostream &OS,
                                 const PrintOptions &PO) const {
  StreamPrinter Printer(OS);
  print(Printer, PO);
}

void LayoutConstraint::print(raw_ostream &OS,
                             const PrintOptions &PO) const {
  assert(*this);
  getPointer()->print(OS, PO);
}

void LayoutConstraintInfo::print(ASTPrinter &Printer,
                                 const PrintOptions &PO) const {
  Printer << getName();
  switch (getKind()) {
  case LayoutConstraintKind::UnknownLayout:
  case LayoutConstraintKind::RefCountedObject:
  case LayoutConstraintKind::NativeRefCountedObject:
  case LayoutConstraintKind::Class:
  case LayoutConstraintKind::NativeClass:
  case LayoutConstraintKind::Trivial:
    return;
  case LayoutConstraintKind::TrivialOfAtMostSize:
  case LayoutConstraintKind::TrivialOfExactSize:
    Printer << "(";
    Printer << SizeInBits;
    if (Alignment)
      Printer << ", " << Alignment;
    Printer << ")";
    break;
  }
}

void GenericSignature::print(raw_ostream &OS, PrintOptions Opts) const {
  StreamPrinter Printer(OS);
  print(Printer, Opts);
}

void GenericSignature::print(ASTPrinter &Printer, PrintOptions Opts) const {
  PrintAST(Printer, Opts).printGenericSignature(this,
                                                PrintAST::PrintParams |
                                                PrintAST::PrintRequirements);
}

void GenericSignature::dump() const {
  print(llvm::errs());
  llvm::errs() << '\n';
}

void Requirement::dump() const {
  dump(llvm::errs());
  llvm::errs() << '\n';
}
void Requirement::dump(raw_ostream &out) const {
  switch (getKind()) {
  case RequirementKind::Conformance:
    out << "conforms_to: ";
    break;
  case RequirementKind::Layout:
    out << "layout: ";
    break;
  case RequirementKind::Superclass:
    out << "superclass: ";
    break;
  case RequirementKind::SameType:
    out << "same_type: ";
    break;
  }

  if (getFirstType())
    out << getFirstType() << " ";
  if (getKind() != RequirementKind::Layout && getSecondType())
    out << getSecondType();
  else if (getLayoutConstraint())
    out << getLayoutConstraint();
}

void Requirement::print(raw_ostream &os, const PrintOptions &opts) const {
  StreamPrinter printer(os);
  PrintAST(printer, opts).printRequirement(*this);
}

void Requirement::print(ASTPrinter &printer, const PrintOptions &opts) const {
  PrintAST(printer, opts).printRequirement(*this);
}

std::string GenericSignature::getAsString() const {
  std::string result;
  llvm::raw_string_ostream out(result);
  print(out);
  return out.str();
}

static StringRef getStringForParameterConvention(ParameterConvention conv) {
  switch (conv) {
  case ParameterConvention::Indirect_In: return "@in ";
  case ParameterConvention::Indirect_In_Constant:
    return "@in_constant ";
  case ParameterConvention::Indirect_In_Guaranteed:  return "@in_guaranteed ";
  case ParameterConvention::Indirect_Inout: return "@inout ";
  case ParameterConvention::Indirect_InoutAliasable: return "@inout_aliasable ";
  case ParameterConvention::Direct_Owned: return "@owned ";
  case ParameterConvention::Direct_Unowned: return "";
  case ParameterConvention::Direct_Guaranteed: return "@guaranteed ";
  }
  llvm_unreachable("bad parameter convention");
}

StringRef swift::getCheckedCastKindName(CheckedCastKind kind) {
  switch (kind) {
  case CheckedCastKind::Unresolved:
    return "unresolved";
  case CheckedCastKind::Coercion:
    return "coercion";
  case CheckedCastKind::ValueCast:
    return "value_cast";
  case CheckedCastKind::ArrayDowncast:
    return "array_downcast";
  case CheckedCastKind::DictionaryDowncast:
    return "dictionary_downcast";
  case CheckedCastKind::SetDowncast:
    return "set_downcast";
  case CheckedCastKind::BridgingCoercion:
    return "bridging_coercion";
  }
  llvm_unreachable("bad checked cast name");
}

void SILParameterInfo::dump() const {
  print(llvm::errs());
  llvm::errs() << '\n';
}
void SILParameterInfo::print(raw_ostream &OS, const PrintOptions &Opts) const {
  StreamPrinter Printer(OS);
  print(Printer, Opts);
}
void SILParameterInfo::print(ASTPrinter &Printer,
                             const PrintOptions &Opts) const {
  Printer << getStringForParameterConvention(getConvention());
  getType().print(Printer, Opts);
}

static StringRef getStringForResultConvention(ResultConvention conv) {
  switch (conv) {
  case ResultConvention::Indirect: return "@out ";
  case ResultConvention::Owned: return "@owned ";
  case ResultConvention::Unowned: return "";
  case ResultConvention::UnownedInnerPointer: return "@unowned_inner_pointer ";
  case ResultConvention::Autoreleased: return "@autoreleased ";
  }
  llvm_unreachable("bad result convention");
}

void SILResultInfo::dump() const {
  print(llvm::errs());
  llvm::errs() << '\n';
}
void SILResultInfo::print(raw_ostream &OS, const PrintOptions &Opts) const {
  StreamPrinter Printer(OS);
  print(Printer, Opts);
}
void SILResultInfo::print(ASTPrinter &Printer, const PrintOptions &Opts) const {
  Printer << getStringForResultConvention(getConvention());
  getType().print(Printer, Opts);
}

std::string Type::getString(const PrintOptions &PO) const {
  std::string Result;
  llvm::raw_string_ostream OS(Result);
  print(OS, PO);
  return OS.str();
}

std::string TypeBase::getString(const PrintOptions &PO) const {
  std::string Result;
  llvm::raw_string_ostream OS(Result);
  print(OS, PO);
  return OS.str();
}

std::string Type::getStringAsComponent(const PrintOptions &PO) const {
  std::string Result;
  llvm::raw_string_ostream OS(Result);

  if (getPointer()->hasSimpleTypeRepr()) {
    print(OS, PO);
  } else {
    OS << "(";
    print(OS, PO);
    OS << ")";
  }

  return OS.str();
}

std::string TypeBase::getStringAsComponent(const PrintOptions &PO) const {
  std::string Result;
  llvm::raw_string_ostream OS(Result);

  if (hasSimpleTypeRepr()) {
    print(OS, PO);
  } else {
    OS << "(";
    print(OS, PO);
    OS << ")";
  }

  return OS.str();
}

void TypeBase::dumpPrint() const {
  print(llvm::errs());
  llvm::errs() << '\n';
}
void TypeBase::print(raw_ostream &OS, const PrintOptions &PO) const {
  Type(const_cast<TypeBase *>(this)).print(OS, PO);
}
void TypeBase::print(ASTPrinter &Printer, const PrintOptions &PO) const {
  Type(const_cast<TypeBase *>(this)).print(Printer, PO);
}

std::string LayoutConstraint::getString(const PrintOptions &PO) const {
  std::string Result;
  llvm::raw_string_ostream OS(Result);
  print(OS, PO);
  return OS.str();
}

std::string LayoutConstraintInfo::getString(const PrintOptions &PO) const {
  std::string Result;
  llvm::raw_string_ostream OS(Result);
  print(OS, PO);
  return OS.str();
}

void ProtocolConformance::printName(llvm::raw_ostream &os,
                                    const PrintOptions &PO) const {
  if (getKind() == ProtocolConformanceKind::Normal) {
    if (auto genericSig = getGenericSignature()) {
      StreamPrinter sPrinter(os);
      TypePrinter typePrinter(sPrinter, PO);
      typePrinter
          .printGenericSignature(genericSig,
                                 PrintAST::PrintParams |
                                 PrintAST::PrintRequirements);
      os << ' ';
    }
  }

  getType()->print(os, PO);
  os << ": ";

  switch (getKind()) {
  case ProtocolConformanceKind::Normal: {
    auto normal = cast<NormalProtocolConformance>(this);
    os << normal->getProtocol()->getName()
       << " module " << normal->getDeclContext()->getParentModule()->getName();
    break;
  }
  case ProtocolConformanceKind::Self: {
    auto self = cast<SelfProtocolConformance>(this);
    os << self->getProtocol()->getName()
       << " module " << self->getDeclContext()->getParentModule()->getName();
    break;
  }
  case ProtocolConformanceKind::Specialized: {
    auto spec = cast<SpecializedProtocolConformance>(this);
    os << "specialize <";
    interleave(spec->getSubstitutionMap().getReplacementTypes(),
               [&](Type type) { type.print(os, PO); },
               [&] { os << ", "; });

    os << "> (";
    spec->getGenericConformance()->printName(os, PO);
    os << ")";
    break;
  }
  case ProtocolConformanceKind::Inherited: {
    auto inherited = cast<InheritedProtocolConformance>(this);
    os << "inherit (";
    inherited->getInheritedConformance()->printName(os, PO);
    os << ")";
    break;
  }
  }
}

void swift::printEnumElementsAsCases(
    llvm::DenseSet<EnumElementDecl *> &UnhandledElements,
    llvm::raw_ostream &OS) {
  // Sort the missing elements to a vector because set does not guarantee
  // orders.
  SmallVector<EnumElementDecl *, 4> SortedElements;
  SortedElements.insert(SortedElements.begin(), UnhandledElements.begin(),
                        UnhandledElements.end());
  std::sort(SortedElements.begin(), SortedElements.end(),
            [](EnumElementDecl *LHS, EnumElementDecl *RHS) {
              return LHS->getNameStr().compare(RHS->getNameStr()) < 0;
            });

  auto printPayloads = [](ParameterList *PL, llvm::raw_ostream &OS) {
    // If the enum element has no payloads, return.
    if (!PL)
      return;
    OS << "(";
    // Print each element in the pattern match.
    for (auto i = PL->begin(); i != PL->end(); ++i) {
      auto *param = *i;
      if (param->hasName()) {
        OS << tok::kw_let << " " << param->getName().str();
      } else {
        OS << "_";
      }
      if (i + 1 != PL->end()) {
        OS << ", ";
      }
    }
    OS << ")";
  };

  // Print each enum element name.
  std::for_each(SortedElements.begin(), SortedElements.end(),
                [&](EnumElementDecl *EE) {
                  OS << tok::kw_case << " ." << EE->getNameStr();
                  printPayloads(EE->getParameterList(), OS);
                  OS << ": " << getCodePlaceholder() << "\n";
                });
}

void
swift::getInheritedForPrinting(const Decl *decl,
                               llvm::function_ref<bool(const Decl*)> shouldPrint,
                               llvm::SmallVectorImpl<TypeLoc> &Results) {
  ArrayRef<TypeLoc> inherited;
  if (auto td = dyn_cast<TypeDecl>(decl)) {
    inherited = td->getInherited();
  } else if (auto ed = dyn_cast<ExtensionDecl>(decl)) {
    inherited = ed->getInherited();
  }

  // Collect explicit inherited types.
  for (auto TL: inherited) {
    if (auto ty = TL.getType()) {
      bool foundUnprintable = ty.findIf([shouldPrint](Type subTy) {
        if (auto aliasTy = dyn_cast<NameAliasType>(subTy.getPointer()))
          return !shouldPrint(aliasTy->getDecl());
        if (auto NTD = subTy->getAnyNominal())
          return !shouldPrint(NTD);
        return false;
      });
      if (foundUnprintable)
        continue;
    }
    Results.push_back(TL);
  }

  // Collect synthesized conformances.
  auto &ctx = decl->getASTContext();
  for (auto attr : decl->getAttrs().getAttributes<SynthesizedProtocolAttr>()) {
    if (auto *proto = ctx.getProtocol(attr->getProtocolKind())) {
      if (!shouldPrint(proto))
        continue;
      if (attr->getProtocolKind() == KnownProtocolKind::RawRepresentable &&
          isa<EnumDecl>(decl) &&
          cast<EnumDecl>(decl)->hasRawType())
        continue;
      Results.push_back(TypeLoc::withoutLoc(proto->getDeclaredType()));
    }
  }
}
