//===--- ASTNode.cpp - Swift Language ASTs --------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2017 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 the ASTNode, which is a union of Stmt, Expr, and Decl. // //===----------------------------------------------------------------------===// #include "swift/AST/ASTNode.h" #include "swift/AST/Decl.h" #include "swift/AST/Expr.h" #include "swift/AST/Stmt.h" #include "swift/Basic/SourceLoc.h" using namespace swift; SourceRange ASTNode::getSourceRange() const { if (const Expr *E = this->dyn_cast()) return E->getSourceRange(); if (const Stmt *S = this->dyn_cast()) return S->getSourceRange(); if (const Decl *D = this->dyn_cast()) return D->getSourceRange(); llvm_unreachable("unsupported AST node"); } /// \brief Return the location of the start of the statement. SourceLoc ASTNode::getStartLoc() const { return getSourceRange().Start; } /// \brief Return the location of the end of the statement. SourceLoc ASTNode::getEndLoc() const { return getSourceRange().End; } DeclContext *ASTNode::getAsDeclContext() const { if (Expr *E = this->dyn_cast()) { if (isa(E)) return static_cast(E); } else if (is()) { return nullptr; } else if (Decl *D = this->dyn_cast()) { if (isa(D)) return cast(D); } else if (getOpaqueValue()) llvm_unreachable("unsupported AST node"); return nullptr; } void ASTNode::walk(ASTWalker &Walker) { if (Expr *E = this->dyn_cast()) E->walk(Walker); else if (Stmt *S = this->dyn_cast()) S->walk(Walker); else if (Decl *D = this->dyn_cast()) D->walk(Walker); else llvm_unreachable("unsupported AST node"); } void ASTNode::walk(SourceEntityWalker &Walker) { if (Expr *E = this->dyn_cast()) Walker.walk(E); else if (Stmt *S = this->dyn_cast()) Walker.walk(S); else if (Decl *D = this->dyn_cast()) Walker.walk(D); else llvm_unreachable("unsupported AST node"); } #define FUNC(T) \ bool ASTNode::is##T(T##Kind Kind) const { \ if (!is()) \ return false; \ return get()->getKind() == Kind; \ } FUNC(Stmt) FUNC(Expr) FUNC(Decl) #undef FUNC