mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
198 lines
5.7 KiB
C++
198 lines
5.7 KiB
C++
//===--- 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<ValueDecl>(D)) {
|
|
if (named->hasName()) {
|
|
out << '\'' << named->getName() << '\'';
|
|
hasPrintedName = true;
|
|
} else if (auto *fn = dyn_cast<FuncDecl>(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<InterestingDeclForType, Decl*> {
|
|
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);
|
|
}
|