//===--- PrettyStackTrace.cpp - Swift-specific PrettyStackTraceEntries ----===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// // // This file implements several Swift-specific implementations of // PrettyStackTraceEntry. // //===----------------------------------------------------------------------===// #include "swift/AST/AST.h" #include "swift/AST/PrettyStackTrace.h" #include "swift/AST/TypeVisitor.h" #include "swift/Basic/SourceManager.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/MemoryBuffer.h" using namespace swift; void PrettyStackTraceDecl::print(llvm::raw_ostream &out) const { out << "While " << Action << ' '; if (!TheDecl) { out << "NULL declaration!\n"; return; } printDeclDescription(out, TheDecl, TheDecl->getASTContext()); } void swift::printDeclDescription(llvm::raw_ostream &out, const Decl *D, ASTContext &Context) { bool hasPrintedName = false; if (auto *named = dyn_cast(D)) { if (named->hasName()) { out << '\'' << named->getName() << '\''; hasPrintedName = true; } else if (auto *fn = dyn_cast(named)) { if (auto *ASD = fn->getAccessorStorageDecl()) { if (ASD->hasName()) { switch (fn->getAccessorKind()) { case AccessorKind::NotAccessor: llvm_unreachable("Isn't an accessor?"); case AccessorKind::IsGetter: out << "getter"; break; case AccessorKind::IsSetter: out << "setter"; break; case AccessorKind::IsWillSet: out << "willset"; break; case AccessorKind::IsDidSet: out << "didset"; break; case AccessorKind::IsMaterializeForSet: out << "materializeForSet"; break; case AccessorKind::IsAddressor: out << "addressor"; break; case AccessorKind::IsMutableAddressor: out << "mutableAddressor"; break; } out << " for " << ASD->getFullName(); hasPrintedName = true; } } } } if (!hasPrintedName) out << "declaration " << (const void *)D; out << " at "; D->getStartLoc().print(out, Context.SourceMgr); out << '\n'; } void PrettyStackTraceExpr::print(llvm::raw_ostream &out) const { out << "While " << Action << ' '; if (!TheExpr) { out << "NULL expression!\n"; return; } printExprDescription(out, TheExpr, Context); } void swift::printExprDescription(llvm::raw_ostream &out, Expr *E, ASTContext &Context) { out << "expression at "; E->getSourceRange().print(out, Context.SourceMgr); out << '\n'; } void PrettyStackTraceStmt::print(llvm::raw_ostream &out) const { out << "While " << Action << ' '; if (!TheStmt) { out << "NULL statement!\n"; return; } printStmtDescription(out, TheStmt, Context); } void swift::printStmtDescription(llvm::raw_ostream &out, Stmt *S, ASTContext &Context) { out << "statement at "; S->getSourceRange().print(out, Context.SourceMgr); out << '\n'; } void PrettyStackTracePattern::print(llvm::raw_ostream &out) const { out << "While " << Action << ' '; if (!ThePattern) { out << "NULL pattern!\n"; return; } printPatternDescription(out, ThePattern, Context); } void swift::printPatternDescription(llvm::raw_ostream &out, Pattern *P, ASTContext &Context) { out << "pattern at "; P->getSourceRange().print(out, Context.SourceMgr); out << '\n'; } namespace { /// Map a Type to an interesting declaration whose source range we /// should print. struct InterestingDeclForType : TypeVisitor { Decl *visitType(TypeBase *type) { return nullptr; } Decl *visitUnboundGenericType(UnboundGenericType *type) { return type->getDecl(); } Decl *visitBoundGenericType(BoundGenericType *type) { return type->getDecl(); } Decl *visitNominalType(NominalType *type) { return type->getDecl(); } Decl *visitNameAliasType(NameAliasType *type) { return type->getDecl(); } }; } void PrettyStackTraceType::print(llvm::raw_ostream &out) const { out << "While " << Action << ' '; if (TheType.isNull()) { out << "NULL type!\n"; return; } printTypeDescription(out, TheType, Context); } void swift::printTypeDescription(llvm::raw_ostream &out, Type type, ASTContext &Context) { out << "type '" << type << '\''; if (Decl *decl = InterestingDeclForType().visit(type)) { out << " (declared at "; decl->getSourceRange().print(out, Context.SourceMgr); out << ')'; } out << '\n'; } void PrettyStackTraceTypeRepr::print(llvm::raw_ostream &out) const { out << "While " << Action << " type "; TheType->print(out); if (TheType && TheType->getSourceRange().isValid()) { out << " at "; TheType->getSourceRange().print(out, Context.SourceMgr); } out << '\n'; } void swift::printSourceLocDescription(llvm::raw_ostream &out, SourceLoc loc, ASTContext &ctx) { loc.print(out, ctx.SourceMgr); out << '\n'; } void PrettyStackTraceLocation::print(llvm::raw_ostream &out) const { out << "While " << Action << " starting at "; printSourceLocDescription(out, Loc, Context); }