diff options
Diffstat (limited to 'lib/AST/Stmt.cpp')
-rw-r--r-- | lib/AST/Stmt.cpp | 107 |
1 files changed, 45 insertions, 62 deletions
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index ddb1560723..1ef80c95c4 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -142,18 +142,28 @@ namespace { return bad(); } - typedef SourceRange getSourceRange_t() const; - template <class T> good implements_getSourceRange(getSourceRange_t T::*) { + typedef SourceLocation getLocStart_t() const; + template <class T> good implements_getLocStart(getLocStart_t T::*) { return good(); } - static inline bad implements_getSourceRange(getSourceRange_t Stmt::*) { + static inline bad implements_getLocStart(getLocStart_t Stmt::*) { + return bad(); + } + + typedef SourceLocation getLocEnd_t() const; + template <class T> good implements_getLocEnd(getLocEnd_t T::*) { + return good(); + } + static inline bad implements_getLocEnd(getLocEnd_t Stmt::*) { return bad(); } #define ASSERT_IMPLEMENTS_children(type) \ (void) sizeof(is_good(implements_children(&type::children))) -#define ASSERT_IMPLEMENTS_getSourceRange(type) \ - (void) sizeof(is_good(implements_getSourceRange(&type::getSourceRange))) +#define ASSERT_IMPLEMENTS_getLocStart(type) \ + (void) sizeof(is_good(implements_getLocStart(&type::getLocStart))) +#define ASSERT_IMPLEMENTS_getLocEnd(type) \ + (void) sizeof(is_good(implements_getLocEnd(&type::getLocEnd))) } /// Check whether the various Stmt classes implement their member @@ -162,7 +172,8 @@ static inline void check_implementations() { #define ABSTRACT_STMT(type) #define STMT(type, base) \ ASSERT_IMPLEMENTS_children(type); \ - ASSERT_IMPLEMENTS_getSourceRange(type); + ASSERT_IMPLEMENTS_getLocStart(type); \ + ASSERT_IMPLEMENTS_getLocEnd(type); #include "clang/AST/StmtNodes.inc" } @@ -178,67 +189,51 @@ Stmt::child_range Stmt::children() { llvm_unreachable("unknown statement kind!"); } -SourceRange Stmt::getSourceRange() const { - switch (getStmtClass()) { - case Stmt::NoStmtClass: llvm_unreachable("statement without class"); -#define ABSTRACT_STMT(type) -#define STMT(type, base) \ - case Stmt::type##Class: \ - return static_cast<const type*>(this)->getSourceRange(); -#include "clang/AST/StmtNodes.inc" - } - llvm_unreachable("unknown statement kind!"); -} - // Amusing macro metaprogramming hack: check whether a class provides -// a more specific implementation of getLocStart() and getLocEnd(). +// a more specific implementation of getSourceRange. // // See also Expr.cpp:getExprLoc(). namespace { /// This implementation is used when a class provides a custom - /// implementation of getLocStart. + /// implementation of getSourceRange. template <class S, class T> - SourceLocation getLocStartImpl(const Stmt *stmt, - SourceLocation (T::*v)() const) { - return static_cast<const S*>(stmt)->getLocStart(); + SourceRange getSourceRangeImpl(const Stmt *stmt, + SourceRange (T::*v)() const) { + return static_cast<const S*>(stmt)->getSourceRange(); } /// This implementation is used when a class doesn't provide a custom - /// implementation of getLocStart. Overload resolution should pick it over + /// implementation of getSourceRange. Overload resolution should pick it over /// the implementation above because it's more specialized according to /// function template partial ordering. template <class S> - SourceLocation getLocStartImpl(const Stmt *stmt, - SourceLocation (Stmt::*v)() const) { - return static_cast<const S*>(stmt)->getSourceRange().getBegin(); - } - - /// This implementation is used when a class provides a custom - /// implementation of getLocEnd. - template <class S, class T> - SourceLocation getLocEndImpl(const Stmt *stmt, - SourceLocation (T::*v)() const) { - return static_cast<const S*>(stmt)->getLocEnd(); + SourceRange getSourceRangeImpl(const Stmt *stmt, + SourceRange (Stmt::*v)() const) { + return SourceRange(static_cast<const S*>(stmt)->getLocStart(), + static_cast<const S*>(stmt)->getLocEnd()); } +} - /// This implementation is used when a class doesn't provide a custom - /// implementation of getLocEnd. Overload resolution should pick it over - /// the implementation above because it's more specialized according to - /// function template partial ordering. - template <class S> - SourceLocation getLocEndImpl(const Stmt *stmt, - SourceLocation (Stmt::*v)() const) { - return static_cast<const S*>(stmt)->getSourceRange().getEnd(); +SourceRange Stmt::getSourceRange() const { + switch (getStmtClass()) { + case Stmt::NoStmtClass: llvm_unreachable("statement without class"); +#define ABSTRACT_STMT(type) +#define STMT(type, base) \ + case Stmt::type##Class: \ + return getSourceRangeImpl<type>(this, &type::getSourceRange); +#include "clang/AST/StmtNodes.inc" } + llvm_unreachable("unknown statement kind!"); } SourceLocation Stmt::getLocStart() const { +// llvm::errs() << "getLocStart() for " << getStmtClassName() << "\n"; switch (getStmtClass()) { case Stmt::NoStmtClass: llvm_unreachable("statement without class"); #define ABSTRACT_STMT(type) #define STMT(type, base) \ case Stmt::type##Class: \ - return getLocStartImpl<type>(this, &type::getLocStart); + return static_cast<const type*>(this)->getLocStart(); #include "clang/AST/StmtNodes.inc" } llvm_unreachable("unknown statement kind"); @@ -250,7 +245,7 @@ SourceLocation Stmt::getLocEnd() const { #define ABSTRACT_STMT(type) #define STMT(type, base) \ case Stmt::type##Class: \ - return getLocEndImpl<type>(this, &type::getLocEnd); + return static_cast<const type*>(this)->getLocEnd(); #include "clang/AST/StmtNodes.inc" } llvm_unreachable("unknown statement kind"); @@ -302,14 +297,6 @@ AttributedStmt *AttributedStmt::CreateEmpty(ASTContext &C, unsigned NumAttrs) { return new (Mem) AttributedStmt(EmptyShell(), NumAttrs); } -// This is defined here to avoid polluting Stmt.h with importing Expr.h -SourceRange ReturnStmt::getSourceRange() const { - if (RetExpr) - return SourceRange(RetLoc, RetExpr->getLocEnd()); - else - return SourceRange(RetLoc); -} - bool Stmt::hasImplicitControlFlow() const { switch (StmtBits.sClass) { default: @@ -773,16 +760,12 @@ ObjCAtTryStmt *ObjCAtTryStmt::CreateEmpty(ASTContext &Context, return new (Mem) ObjCAtTryStmt(EmptyShell(), NumCatchStmts, HasFinally); } -SourceRange ObjCAtTryStmt::getSourceRange() const { - SourceLocation EndLoc; +SourceLocation ObjCAtTryStmt::getLocEnd() const { if (HasFinally) - EndLoc = getFinallyStmt()->getLocEnd(); - else if (NumCatchStmts) - EndLoc = getCatchStmt(NumCatchStmts - 1)->getLocEnd(); - else - EndLoc = getTryBody()->getLocEnd(); - - return SourceRange(AtTryLoc, EndLoc); + return getFinallyStmt()->getLocEnd(); + if (NumCatchStmts) + return getCatchStmt(NumCatchStmts - 1)->getLocEnd(); + return getTryBody()->getLocEnd(); } CXXTryStmt *CXXTryStmt::Create(ASTContext &C, SourceLocation tryLoc, |