diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST/Stmt.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/Stmt.cpp | 256 |
1 files changed, 87 insertions, 169 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/Stmt.cpp b/contrib/llvm/tools/clang/lib/AST/Stmt.cpp index fc88981..7e73f02 100644 --- a/contrib/llvm/tools/clang/lib/AST/Stmt.cpp +++ b/contrib/llvm/tools/clang/lib/AST/Stmt.cpp @@ -46,7 +46,7 @@ static StmtClassNameTable &getStmtInfoTableEntry(Stmt::StmtClass E) { } const char *Stmt::getStmtClassName() const { - return getStmtInfoTableEntry((StmtClass)sClass).Name; + return getStmtInfoTableEntry((StmtClass) StmtBits.sClass).Name; } void Stmt::PrintStats() { @@ -84,17 +84,84 @@ bool Stmt::CollectingStats(bool Enable) { return StatSwitch; } +namespace { + struct good {}; + struct bad {}; + + // These silly little functions have to be static inline to suppress + // unused warnings, and they have to be defined to suppress other + // warnings. + static inline good is_good(good) { return good(); } + + typedef Stmt::child_range children_t(); + template <class T> good implements_children(children_t T::*) { + return good(); + } + static inline bad implements_children(children_t Stmt::*) { + return bad(); + } + + typedef SourceRange getSourceRange_t() const; + template <class T> good implements_getSourceRange(getSourceRange_t T::*) { + return good(); + } + static inline bad implements_getSourceRange(getSourceRange_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))) +} + +/// Check whether the various Stmt classes implement their member +/// functions. +static inline void check_implementations() { +#define ABSTRACT_STMT(type) +#define STMT(type, base) \ + ASSERT_IMPLEMENTS_children(type); \ + ASSERT_IMPLEMENTS_getSourceRange(type); +#include "clang/AST/StmtNodes.inc" +} + +Stmt::child_range Stmt::children() { + 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<type*>(this)->children(); +#include "clang/AST/StmtNodes.inc" + } + llvm_unreachable("unknown statement kind!"); + return child_range(); +} + +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!"); + return SourceRange(); +} + void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) { if (this->Body) C.Deallocate(Body); - this->NumStmts = NumStmts; + this->CompoundStmtBits.NumStmts = NumStmts; Body = new (C) Stmt*[NumStmts]; memcpy(Body, Stmts, sizeof(Stmt *) * NumStmts); } const char *LabelStmt::getName() const { - return getID()->getNameStart(); + return getDecl()->getIdentifier()->getNameStart(); } // This is defined here to avoid polluting Stmt.h with importing Expr.h @@ -106,7 +173,7 @@ SourceRange ReturnStmt::getSourceRange() const { } bool Stmt::hasImplicitControlFlow() const { - switch (sClass) { + switch (StmtBits.sClass) { default: return false; @@ -416,7 +483,7 @@ ObjCAtTryStmt *ObjCAtTryStmt::Create(ASTContext &Context, Stmt *atFinallyStmt) { unsigned Size = sizeof(ObjCAtTryStmt) + (1 + NumCatchStmts + (atFinallyStmt != 0)) * sizeof(Stmt *); - void *Mem = Context.Allocate(Size, llvm::alignof<ObjCAtTryStmt>()); + void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>()); return new (Mem) ObjCAtTryStmt(atTryLoc, atTryStmt, CatchStmts, NumCatchStmts, atFinallyStmt); } @@ -426,7 +493,7 @@ ObjCAtTryStmt *ObjCAtTryStmt::CreateEmpty(ASTContext &Context, bool HasFinally) { unsigned Size = sizeof(ObjCAtTryStmt) + (1 + NumCatchStmts + HasFinally) * sizeof(Stmt *); - void *Mem = Context.Allocate(Size, llvm::alignof<ObjCAtTryStmt>()); + void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>()); return new (Mem) ObjCAtTryStmt(EmptyShell(), NumCatchStmts, HasFinally); } @@ -448,7 +515,7 @@ CXXTryStmt *CXXTryStmt::Create(ASTContext &C, SourceLocation tryLoc, std::size_t Size = sizeof(CXXTryStmt); Size += ((numHandlers + 1) * sizeof(Stmt)); - void *Mem = C.Allocate(Size, llvm::alignof<CXXTryStmt>()); + void *Mem = C.Allocate(Size, llvm::alignOf<CXXTryStmt>()); return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers, numHandlers); } @@ -457,7 +524,7 @@ CXXTryStmt *CXXTryStmt::Create(ASTContext &C, EmptyShell Empty, std::size_t Size = sizeof(CXXTryStmt); Size += ((numHandlers + 1) * sizeof(Stmt)); - void *Mem = C.Allocate(Size, llvm::alignof<CXXTryStmt>()); + void *Mem = C.Allocate(Size, llvm::alignOf<CXXTryStmt>()); return new (Mem) CXXTryStmt(Empty, numHandlers); } @@ -530,7 +597,7 @@ void ForStmt::setConditionVariable(ASTContext &C, VarDecl *V) { } SwitchStmt::SwitchStmt(ASTContext &C, VarDecl *Var, Expr *cond) - : Stmt(SwitchStmtClass), FirstCase(0) + : Stmt(SwitchStmtClass), FirstCase(0), AllEnumCasesCovered(0) { setConditionVariable(C, Var); SubExprs[COND] = reinterpret_cast<Stmt*>(cond); @@ -556,6 +623,11 @@ void SwitchStmt::setConditionVariable(ASTContext &C, VarDecl *V) { V->getSourceRange().getEnd()); } +Stmt *SwitchCase::getSubStmt() { + if (isa<CaseStmt>(this)) return cast<CaseStmt>(this)->getSubStmt(); + return cast<DefaultStmt>(this)->getSubStmt(); +} + WhileStmt::WhileStmt(ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) @@ -585,101 +657,13 @@ void WhileStmt::setConditionVariable(ASTContext &C, VarDecl *V) { V->getSourceRange().getEnd()); } -//===----------------------------------------------------------------------===// -// Child Iterators for iterating over subexpressions/substatements -//===----------------------------------------------------------------------===// - -// DeclStmt -Stmt::child_iterator DeclStmt::child_begin() { - return StmtIterator(DG.begin(), DG.end()); -} - -Stmt::child_iterator DeclStmt::child_end() { - return StmtIterator(DG.end(), DG.end()); -} - -// NullStmt -Stmt::child_iterator NullStmt::child_begin() { return child_iterator(); } -Stmt::child_iterator NullStmt::child_end() { return child_iterator(); } - -// CompoundStmt -Stmt::child_iterator CompoundStmt::child_begin() { return &Body[0]; } -Stmt::child_iterator CompoundStmt::child_end() { return &Body[0]+NumStmts; } - -// CaseStmt -Stmt::child_iterator CaseStmt::child_begin() { return &SubExprs[0]; } -Stmt::child_iterator CaseStmt::child_end() { return &SubExprs[END_EXPR]; } - -// DefaultStmt -Stmt::child_iterator DefaultStmt::child_begin() { return &SubStmt; } -Stmt::child_iterator DefaultStmt::child_end() { return &SubStmt+1; } - -// LabelStmt -Stmt::child_iterator LabelStmt::child_begin() { return &SubStmt; } -Stmt::child_iterator LabelStmt::child_end() { return &SubStmt+1; } - -// IfStmt -Stmt::child_iterator IfStmt::child_begin() { - return &SubExprs[0]; -} -Stmt::child_iterator IfStmt::child_end() { - return &SubExprs[0]+END_EXPR; -} - -// SwitchStmt -Stmt::child_iterator SwitchStmt::child_begin() { - return &SubExprs[0]; -} -Stmt::child_iterator SwitchStmt::child_end() { - return &SubExprs[0]+END_EXPR; -} - -// WhileStmt -Stmt::child_iterator WhileStmt::child_begin() { - return &SubExprs[0]; -} -Stmt::child_iterator WhileStmt::child_end() { - return &SubExprs[0]+END_EXPR; -} - -// DoStmt -Stmt::child_iterator DoStmt::child_begin() { return &SubExprs[0]; } -Stmt::child_iterator DoStmt::child_end() { return &SubExprs[0]+END_EXPR; } - -// ForStmt -Stmt::child_iterator ForStmt::child_begin() { - return &SubExprs[0]; -} -Stmt::child_iterator ForStmt::child_end() { - return &SubExprs[0]+END_EXPR; -} - -// ObjCForCollectionStmt -Stmt::child_iterator ObjCForCollectionStmt::child_begin() { - return &SubExprs[0]; -} -Stmt::child_iterator ObjCForCollectionStmt::child_end() { - return &SubExprs[0]+END_EXPR; -} - -// GotoStmt -Stmt::child_iterator GotoStmt::child_begin() { return child_iterator(); } -Stmt::child_iterator GotoStmt::child_end() { return child_iterator(); } - // IndirectGotoStmt -Expr* IndirectGotoStmt::getTarget() { return cast<Expr>(Target); } -const Expr* IndirectGotoStmt::getTarget() const { return cast<Expr>(Target); } - -Stmt::child_iterator IndirectGotoStmt::child_begin() { return &Target; } -Stmt::child_iterator IndirectGotoStmt::child_end() { return &Target+1; } - -// ContinueStmt -Stmt::child_iterator ContinueStmt::child_begin() { return child_iterator(); } -Stmt::child_iterator ContinueStmt::child_end() { return child_iterator(); } - -// BreakStmt -Stmt::child_iterator BreakStmt::child_begin() { return child_iterator(); } -Stmt::child_iterator BreakStmt::child_end() { return child_iterator(); } +LabelDecl *IndirectGotoStmt::getConstantTarget() { + if (AddrLabelExpr *E = + dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts())) + return E->getLabel(); + return 0; +} // ReturnStmt const Expr* ReturnStmt::getRetValue() const { @@ -688,69 +672,3 @@ const Expr* ReturnStmt::getRetValue() const { Expr* ReturnStmt::getRetValue() { return cast_or_null<Expr>(RetExpr); } - -Stmt::child_iterator ReturnStmt::child_begin() { - return &RetExpr; -} -Stmt::child_iterator ReturnStmt::child_end() { - return RetExpr ? &RetExpr+1 : &RetExpr; -} - -// AsmStmt -Stmt::child_iterator AsmStmt::child_begin() { - return NumOutputs + NumInputs == 0 ? 0 : &Exprs[0]; -} -Stmt::child_iterator AsmStmt::child_end() { - return NumOutputs + NumInputs == 0 ? 0 : &Exprs[0] + NumOutputs + NumInputs; -} - -// ObjCAtCatchStmt -Stmt::child_iterator ObjCAtCatchStmt::child_begin() { return &Body; } -Stmt::child_iterator ObjCAtCatchStmt::child_end() { return &Body + 1; } - -// ObjCAtFinallyStmt -Stmt::child_iterator ObjCAtFinallyStmt::child_begin() { return &AtFinallyStmt; } -Stmt::child_iterator ObjCAtFinallyStmt::child_end() { return &AtFinallyStmt+1; } - -// ObjCAtTryStmt -Stmt::child_iterator ObjCAtTryStmt::child_begin() { return getStmts(); } - -Stmt::child_iterator ObjCAtTryStmt::child_end() { - return getStmts() + 1 + NumCatchStmts + HasFinally; -} - -// ObjCAtThrowStmt -Stmt::child_iterator ObjCAtThrowStmt::child_begin() { - return &Throw; -} - -Stmt::child_iterator ObjCAtThrowStmt::child_end() { - return &Throw+1; -} - -// ObjCAtSynchronizedStmt -Stmt::child_iterator ObjCAtSynchronizedStmt::child_begin() { - return &SubStmts[0]; -} - -Stmt::child_iterator ObjCAtSynchronizedStmt::child_end() { - return &SubStmts[0]+END_EXPR; -} - -// CXXCatchStmt -Stmt::child_iterator CXXCatchStmt::child_begin() { - return &HandlerBlock; -} - -Stmt::child_iterator CXXCatchStmt::child_end() { - return &HandlerBlock + 1; -} - -// CXXTryStmt -Stmt::child_iterator CXXTryStmt::child_begin() { - return reinterpret_cast<Stmt **>(this + 1); -} - -Stmt::child_iterator CXXTryStmt::child_end() { - return reinterpret_cast<Stmt **>(this + 1) + NumHandlers + 1; -} |