diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Expr.cpp | 287 | ||||
-rw-r--r-- | lib/AST/ExprCXX.cpp | 202 | ||||
-rw-r--r-- | lib/AST/ExprClassification.cpp | 1 | ||||
-rw-r--r-- | lib/AST/ExprConstant.cpp | 1 | ||||
-rw-r--r-- | lib/AST/ItaniumMangle.cpp | 1 | ||||
-rw-r--r-- | lib/AST/Stmt.cpp | 220 | ||||
-rw-r--r-- | lib/AST/StmtPrinter.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CGStmt.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 8 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/ExprEngine.cpp | 1 |
10 files changed, 113 insertions, 613 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 747f786542..6280d633aa 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -30,8 +30,6 @@ #include <algorithm> using namespace clang; -void Expr::ANCHOR() {} // key function for Expr class. - /// isKnownToHaveBooleanValue - Return true if this is an integer expression /// that is known to return 0 or 1. This happens for _Bool/bool expressions /// but also int expressions which are produced by things like comparisons in @@ -93,6 +91,42 @@ bool Expr::isKnownToHaveBooleanValue() const { return false; } +// Amusing macro metaprogramming hack: check whether a class provides +// a more specific implementation of getExprLoc(). +namespace { + /// This implementation is used when a class provides a custom + /// implementation of getExprLoc. + template <class E, class T> + SourceLocation getExprLocImpl(const Expr *expr, + SourceLocation (T::*v)() const) { + return static_cast<const E*>(expr)->getExprLoc(); + } + + /// This implementation is used when a class doesn't provide + /// a custom implementation of getExprLoc. Overload resolution + /// should pick it over the implementation above because it's + /// more specialized according to function template partial ordering. + template <class E> + SourceLocation getExprLocImpl(const Expr *expr, + SourceLocation (Expr::*v)() const) { + return static_cast<const E*>(expr)->getSourceRange().getBegin(); + } +} + +SourceLocation Expr::getExprLoc() const { + switch (getStmtClass()) { + case Stmt::NoStmtClass: llvm_unreachable("statement without class"); +#define ABSTRACT_STMT(type) +#define STMT(type, base) \ + case Stmt::type##Class: llvm_unreachable(#type " is not an Expr"); break; +#define EXPR(type, base) \ + case Stmt::type##Class: return getExprLocImpl<type>(this, &type::getExprLoc); +#include "clang/AST/StmtNodes.inc" + } + llvm_unreachable("unknown statement kind"); + return SourceLocation(); +} + //===----------------------------------------------------------------------===// // Primary Expressions. //===----------------------------------------------------------------------===// @@ -1560,7 +1594,8 @@ static Expr::CanThrowResult MergeCanThrow(Expr::CanThrowResult CT1, static Expr::CanThrowResult CanSubExprsThrow(ASTContext &C, const Expr *CE) { Expr *E = const_cast<Expr*>(CE); Expr::CanThrowResult R = Expr::CT_Cannot; - for (Expr::child_iterator I = E->child_begin(), IE = E->child_end(); + Expr::child_iterator I, IE; + for (llvm::tie(I, IE) = E->children(); I != IE && R != Expr::CT_Can; ++I) { R = MergeCanThrow(R, cast<Expr>(*I)->CanThrow(C)); } @@ -2735,242 +2770,29 @@ const Expr* ConstExprIterator::operator->() const { return cast<Expr>(*I); } // Child Iterators for iterating over subexpressions/substatements //===----------------------------------------------------------------------===// -// DeclRefExpr -Stmt::child_iterator DeclRefExpr::child_begin() { return child_iterator(); } -Stmt::child_iterator DeclRefExpr::child_end() { return child_iterator(); } - -// ObjCIvarRefExpr -Stmt::child_iterator ObjCIvarRefExpr::child_begin() { return &Base; } -Stmt::child_iterator ObjCIvarRefExpr::child_end() { return &Base+1; } - -// ObjCPropertyRefExpr -Stmt::child_iterator ObjCPropertyRefExpr::child_begin() -{ - if (Receiver.is<Stmt*>()) { - // Hack alert! - return reinterpret_cast<Stmt**> (&Receiver); - } - return child_iterator(); -} - -Stmt::child_iterator ObjCPropertyRefExpr::child_end() -{ return Receiver.is<Stmt*>() ? - reinterpret_cast<Stmt**> (&Receiver)+1 : - child_iterator(); -} - -// ObjCIsaExpr -Stmt::child_iterator ObjCIsaExpr::child_begin() { return &Base; } -Stmt::child_iterator ObjCIsaExpr::child_end() { return &Base+1; } - -// PredefinedExpr -Stmt::child_iterator PredefinedExpr::child_begin() { return child_iterator(); } -Stmt::child_iterator PredefinedExpr::child_end() { return child_iterator(); } - -// IntegerLiteral -Stmt::child_iterator IntegerLiteral::child_begin() { return child_iterator(); } -Stmt::child_iterator IntegerLiteral::child_end() { return child_iterator(); } - -// CharacterLiteral -Stmt::child_iterator CharacterLiteral::child_begin() { return child_iterator();} -Stmt::child_iterator CharacterLiteral::child_end() { return child_iterator(); } - -// FloatingLiteral -Stmt::child_iterator FloatingLiteral::child_begin() { return child_iterator(); } -Stmt::child_iterator FloatingLiteral::child_end() { return child_iterator(); } - -// ImaginaryLiteral -Stmt::child_iterator ImaginaryLiteral::child_begin() { return &Val; } -Stmt::child_iterator ImaginaryLiteral::child_end() { return &Val+1; } - -// StringLiteral -Stmt::child_iterator StringLiteral::child_begin() { return child_iterator(); } -Stmt::child_iterator StringLiteral::child_end() { return child_iterator(); } - -// ParenExpr -Stmt::child_iterator ParenExpr::child_begin() { return &Val; } -Stmt::child_iterator ParenExpr::child_end() { return &Val+1; } - -// UnaryOperator -Stmt::child_iterator UnaryOperator::child_begin() { return &Val; } -Stmt::child_iterator UnaryOperator::child_end() { return &Val+1; } - -// OffsetOfExpr -Stmt::child_iterator OffsetOfExpr::child_begin() { - return reinterpret_cast<Stmt **> (reinterpret_cast<OffsetOfNode *> (this + 1) - + NumComps); -} -Stmt::child_iterator OffsetOfExpr::child_end() { - return child_iterator(&*child_begin() + NumExprs); -} - // SizeOfAlignOfExpr -Stmt::child_iterator SizeOfAlignOfExpr::child_begin() { +Stmt::child_range SizeOfAlignOfExpr::children() { // If this is of a type and the type is a VLA type (and not a typedef), the // size expression of the VLA needs to be treated as an executable expression. // Why isn't this weirdness documented better in StmtIterator? if (isArgumentType()) { if (const VariableArrayType* T = dyn_cast<VariableArrayType>( getArgumentType().getTypePtr())) - return child_iterator(T); - return child_iterator(); + return child_range(child_iterator(T), child_iterator()); + return child_range(); } - return child_iterator(&Argument.Ex); -} -Stmt::child_iterator SizeOfAlignOfExpr::child_end() { - if (isArgumentType()) - return child_iterator(); - return child_iterator(&Argument.Ex + 1); -} - -// ArraySubscriptExpr -Stmt::child_iterator ArraySubscriptExpr::child_begin() { - return &SubExprs[0]; -} -Stmt::child_iterator ArraySubscriptExpr::child_end() { - return &SubExprs[0]+END_EXPR; -} - -// CallExpr -Stmt::child_iterator CallExpr::child_begin() { - return &SubExprs[0]; -} -Stmt::child_iterator CallExpr::child_end() { - return &SubExprs[0]+NumArgs+getNumPreArgs()+PREARGS_START; -} - -// MemberExpr -Stmt::child_iterator MemberExpr::child_begin() { return &Base; } -Stmt::child_iterator MemberExpr::child_end() { return &Base+1; } - -// ExtVectorElementExpr -Stmt::child_iterator ExtVectorElementExpr::child_begin() { return &Base; } -Stmt::child_iterator ExtVectorElementExpr::child_end() { return &Base+1; } - -// CompoundLiteralExpr -Stmt::child_iterator CompoundLiteralExpr::child_begin() { return &Init; } -Stmt::child_iterator CompoundLiteralExpr::child_end() { return &Init+1; } - -// CastExpr -Stmt::child_iterator CastExpr::child_begin() { return &Op; } -Stmt::child_iterator CastExpr::child_end() { return &Op+1; } - -// BinaryOperator -Stmt::child_iterator BinaryOperator::child_begin() { - return &SubExprs[0]; -} -Stmt::child_iterator BinaryOperator::child_end() { - return &SubExprs[0]+END_EXPR; -} - -// ConditionalOperator -Stmt::child_iterator ConditionalOperator::child_begin() { - return &SubExprs[0]; -} -Stmt::child_iterator ConditionalOperator::child_end() { - return &SubExprs[0]+END_EXPR; -} - -// AddrLabelExpr -Stmt::child_iterator AddrLabelExpr::child_begin() { return child_iterator(); } -Stmt::child_iterator AddrLabelExpr::child_end() { return child_iterator(); } - -// StmtExpr -Stmt::child_iterator StmtExpr::child_begin() { return &SubStmt; } -Stmt::child_iterator StmtExpr::child_end() { return &SubStmt+1; } - - -// ChooseExpr -Stmt::child_iterator ChooseExpr::child_begin() { return &SubExprs[0]; } -Stmt::child_iterator ChooseExpr::child_end() { return &SubExprs[0]+END_EXPR; } - -// GNUNullExpr -Stmt::child_iterator GNUNullExpr::child_begin() { return child_iterator(); } -Stmt::child_iterator GNUNullExpr::child_end() { return child_iterator(); } - -// ShuffleVectorExpr -Stmt::child_iterator ShuffleVectorExpr::child_begin() { - return &SubExprs[0]; -} -Stmt::child_iterator ShuffleVectorExpr::child_end() { - return &SubExprs[0]+NumExprs; -} - -// VAArgExpr -Stmt::child_iterator VAArgExpr::child_begin() { return &Val; } -Stmt::child_iterator VAArgExpr::child_end() { return &Val+1; } - -// InitListExpr -Stmt::child_iterator InitListExpr::child_begin() { - return InitExprs.size() ? &InitExprs[0] : 0; -} -Stmt::child_iterator InitListExpr::child_end() { - return InitExprs.size() ? &InitExprs[0] + InitExprs.size() : 0; -} - -// DesignatedInitExpr -Stmt::child_iterator DesignatedInitExpr::child_begin() { - char* Ptr = static_cast<char*>(static_cast<void *>(this)); - Ptr += sizeof(DesignatedInitExpr); - return reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr)); -} -Stmt::child_iterator DesignatedInitExpr::child_end() { - return child_iterator(&*child_begin() + NumSubExprs); -} - -// ImplicitValueInitExpr -Stmt::child_iterator ImplicitValueInitExpr::child_begin() { - return child_iterator(); -} - -Stmt::child_iterator ImplicitValueInitExpr::child_end() { - return child_iterator(); -} - -// ParenListExpr -Stmt::child_iterator ParenListExpr::child_begin() { - return &Exprs[0]; -} -Stmt::child_iterator ParenListExpr::child_end() { - return &Exprs[0]+NumExprs; -} - -// ObjCStringLiteral -Stmt::child_iterator ObjCStringLiteral::child_begin() { - return &String; -} -Stmt::child_iterator ObjCStringLiteral::child_end() { - return &String+1; -} - -// ObjCEncodeExpr -Stmt::child_iterator ObjCEncodeExpr::child_begin() { return child_iterator(); } -Stmt::child_iterator ObjCEncodeExpr::child_end() { return child_iterator(); } - -// ObjCSelectorExpr -Stmt::child_iterator ObjCSelectorExpr::child_begin() { - return child_iterator(); -} -Stmt::child_iterator ObjCSelectorExpr::child_end() { - return child_iterator(); -} - -// ObjCProtocolExpr -Stmt::child_iterator ObjCProtocolExpr::child_begin() { - return child_iterator(); -} -Stmt::child_iterator ObjCProtocolExpr::child_end() { - return child_iterator(); + return child_range(&Argument.Ex, &Argument.Ex + 1); } // ObjCMessageExpr -Stmt::child_iterator ObjCMessageExpr::child_begin() { +Stmt::child_range ObjCMessageExpr::children() { + Stmt **begin; if (getReceiverKind() == Instance) - return reinterpret_cast<Stmt **>(this + 1); - return reinterpret_cast<Stmt **>(getArgs()); -} -Stmt::child_iterator ObjCMessageExpr::child_end() { - return reinterpret_cast<Stmt **>(getArgs() + getNumArgs()); + begin = reinterpret_cast<Stmt **>(this + 1); + else + begin = reinterpret_cast<Stmt **>(getArgs()); + return child_range(begin, + reinterpret_cast<Stmt **>(getArgs() + getNumArgs())); } // Blocks @@ -2988,14 +2810,3 @@ BlockDeclRefExpr::BlockDeclRefExpr(VarDecl *d, QualType t, ExprValueKind VK, ExprBits.ValueDependent = ValueDependent; } -Stmt::child_iterator BlockExpr::child_begin() { return child_iterator(); } -Stmt::child_iterator BlockExpr::child_end() { return child_iterator(); } - -Stmt::child_iterator BlockDeclRefExpr::child_begin() { return child_iterator();} -Stmt::child_iterator BlockDeclRefExpr::child_end() { return child_iterator(); } - -// OpaqueValueExpr -SourceRange OpaqueValueExpr::getSourceRange() const { return Loc; } -Stmt::child_iterator OpaqueValueExpr::child_begin() { return child_iterator(); } -Stmt::child_iterator OpaqueValueExpr::child_end() { return child_iterator(); } - diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index a11d05a3a7..28ff9fb57a 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -29,67 +29,12 @@ QualType CXXTypeidExpr::getTypeOperand() const { .getUnqualifiedType(); } -// CXXTypeidExpr - has child iterators if the operand is an expression -Stmt::child_iterator CXXTypeidExpr::child_begin() { - return isTypeOperand() ? child_iterator() - : reinterpret_cast<Stmt **>(&Operand); -} -Stmt::child_iterator CXXTypeidExpr::child_end() { - return isTypeOperand() ? child_iterator() - : reinterpret_cast<Stmt **>(&Operand) + 1; -} - QualType CXXUuidofExpr::getTypeOperand() const { assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)"); return Operand.get<TypeSourceInfo *>()->getType().getNonReferenceType() .getUnqualifiedType(); } -// CXXUuidofExpr - has child iterators if the operand is an expression -Stmt::child_iterator CXXUuidofExpr::child_begin() { - return isTypeOperand() ? child_iterator() - : reinterpret_cast<Stmt **>(&Operand); -} -Stmt::child_iterator CXXUuidofExpr::child_end() { - return isTypeOperand() ? child_iterator() - : reinterpret_cast<Stmt **>(&Operand) + 1; -} - -// CXXBoolLiteralExpr -Stmt::child_iterator CXXBoolLiteralExpr::child_begin() { - return child_iterator(); -} -Stmt::child_iterator CXXBoolLiteralExpr::child_end() { - return child_iterator(); -} - -// CXXNullPtrLiteralExpr -Stmt::child_iterator CXXNullPtrLiteralExpr::child_begin() { - return child_iterator(); -} -Stmt::child_iterator CXXNullPtrLiteralExpr::child_end() { - return child_iterator(); -} - -// CXXThisExpr -Stmt::child_iterator CXXThisExpr::child_begin() { return child_iterator(); } -Stmt::child_iterator CXXThisExpr::child_end() { return child_iterator(); } - -// CXXThrowExpr -Stmt::child_iterator CXXThrowExpr::child_begin() { return &Op; } -Stmt::child_iterator CXXThrowExpr::child_end() { - // If Op is 0, we are processing throw; which has no children. - return Op ? &Op+1 : &Op; -} - -// CXXDefaultArgExpr -Stmt::child_iterator CXXDefaultArgExpr::child_begin() { - return child_iterator(); -} -Stmt::child_iterator CXXDefaultArgExpr::child_end() { - return child_iterator(); -} - // CXXScalarValueInitExpr SourceRange CXXScalarValueInitExpr::getSourceRange() const { SourceLocation Start = RParenLoc; @@ -98,13 +43,6 @@ SourceRange CXXScalarValueInitExpr::getSourceRange() const { return SourceRange(Start, RParenLoc); } -Stmt::child_iterator CXXScalarValueInitExpr::child_begin() { - return child_iterator(); -} -Stmt::child_iterator CXXScalarValueInitExpr::child_end() { - return child_iterator(); -} - // CXXNewExpr CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew, Expr **placementArgs, unsigned numPlaceArgs, @@ -163,11 +101,6 @@ void CXXNewExpr::AllocateArgsArray(ASTContext &C, bool isArray, } -Stmt::child_iterator CXXNewExpr::child_begin() { return &SubExprs[0]; } -Stmt::child_iterator CXXNewExpr::child_end() { - return &SubExprs[0] + Array + getNumPlacementArgs() + getNumConstructorArgs(); -} - // CXXDeleteExpr QualType CXXDeleteExpr::getDestroyedType() const { const Expr *Arg = getArgument(); @@ -187,15 +120,7 @@ QualType CXXDeleteExpr::getDestroyedType() const { return ArgType->getAs<PointerType>()->getPointeeType(); } -Stmt::child_iterator CXXDeleteExpr::child_begin() { return &Argument; } -Stmt::child_iterator CXXDeleteExpr::child_end() { return &Argument+1; } - // CXXPseudoDestructorExpr -Stmt::child_iterator CXXPseudoDestructorExpr::child_begin() { return &Base; } -Stmt::child_iterator CXXPseudoDestructorExpr::child_end() { - return &Base + 1; -} - PseudoDestructorTypeStorage::PseudoDestructorTypeStorage(TypeSourceInfo *Info) : Type(Info) { @@ -355,28 +280,6 @@ CXXRecordDecl *OverloadExpr::getNamingClass() const { return cast<UnresolvedMemberExpr>(this)->getNamingClass(); } -Stmt::child_iterator UnresolvedLookupExpr::child_begin() { - return child_iterator(); -} -Stmt::child_iterator UnresolvedLookupExpr::child_end() { - return child_iterator(); -} -// UnaryTypeTraitExpr -Stmt::child_iterator UnaryTypeTraitExpr::child_begin() { - return child_iterator(); -} -Stmt::child_iterator UnaryTypeTraitExpr::child_end() { - return child_iterator(); -} - -//BinaryTypeTraitExpr -Stmt::child_iterator BinaryTypeTraitExpr::child_begin() { - return child_iterator(); -} -Stmt::child_iterator BinaryTypeTraitExpr::child_end() { - return child_iterator(); -} - // DependentScopeDeclRefExpr DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(QualType T, NestedNameSpecifier *Qualifier, @@ -431,14 +334,6 @@ DependentScopeDeclRefExpr::CreateEmpty(ASTContext &C, return E; } -StmtIterator DependentScopeDeclRefExpr::child_begin() { - return child_iterator(); -} - -StmtIterator DependentScopeDeclRefExpr::child_end() { - return child_iterator(); -} - SourceRange CXXConstructExpr::getSourceRange() const { if (ParenRange.isValid()) return SourceRange(Loc, ParenRange.getEnd()); @@ -746,32 +641,6 @@ ExprWithCleanups *ExprWithCleanups::Create(ASTContext &C, return new (C) ExprWithCleanups(C, SubExpr, Temps, NumTemps); } -// CXXBindTemporaryExpr -Stmt::child_iterator CXXBindTemporaryExpr::child_begin() { - return &SubExpr; -} - -Stmt::child_iterator CXXBindTemporaryExpr::child_end() { - return &SubExpr + 1; -} - -// CXXConstructExpr -Stmt::child_iterator CXXConstructExpr::child_begin() { - return &Args[0]; -} -Stmt::child_iterator CXXConstructExpr::child_end() { - return &Args[0]+NumArgs; -} - -// ExprWithCleanups -Stmt::child_iterator ExprWithCleanups::child_begin() { - return &SubExpr; -} - -Stmt::child_iterator ExprWithCleanups::child_end() { - return &SubExpr + 1; -} - CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *Type, SourceLocation LParenLoc, Expr **Args, @@ -820,14 +689,6 @@ SourceRange CXXUnresolvedConstructExpr::getSourceRange() const { return SourceRange(Type->getTypeLoc().getBeginLoc(), RParenLoc); } -Stmt::child_iterator CXXUnresolvedConstructExpr::child_begin() { - return child_iterator(reinterpret_cast<Stmt **>(this + 1)); -} - -Stmt::child_iterator CXXUnresolvedConstructExpr::child_end() { - return child_iterator(reinterpret_cast<Stmt **>(this + 1) + NumArgs); -} - CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow, @@ -927,16 +788,6 @@ CXXDependentScopeMemberExpr::CreateEmpty(ASTContext &C, return E; } -Stmt::child_iterator CXXDependentScopeMemberExpr::child_begin() { - return child_iterator(&Base); -} - -Stmt::child_iterator CXXDependentScopeMemberExpr::child_end() { - if (isImplicitAccess()) - return child_iterator(&Base); - return child_iterator(&Base + 1); -} - UnresolvedMemberExpr::UnresolvedMemberExpr(ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, @@ -1025,47 +876,6 @@ CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const { return Record; } -Stmt::child_iterator UnresolvedMemberExpr::child_begin() { - return child_iterator(&Base); -} - -Stmt::child_iterator UnresolvedMemberExpr::child_end() { - if (isImplicitAccess()) - return child_iterator(&Base); - return child_iterator(&Base + 1); -} - -Stmt::child_iterator CXXNoexceptExpr::child_begin() { - return child_iterator(&Operand); -} -Stmt::child_iterator CXXNoexceptExpr::child_end() { - return child_iterator(&Operand + 1); -} - -SourceRange PackExpansionExpr::getSourceRange() const { - return SourceRange(Pattern->getLocStart(), EllipsisLoc); -} - -Stmt::child_iterator PackExpansionExpr::child_begin() { - return child_iterator(&Pattern); -} - -Stmt::child_iterator PackExpansionExpr::child_end() { - return child_iterator(&Pattern + 1); -} - -SourceRange SizeOfPackExpr::getSourceRange() const { - return SourceRange(OperatorLoc, RParenLoc); -} - -Stmt::child_iterator SizeOfPackExpr::child_begin() { - return child_iterator(); -} - -Stmt::child_iterator SizeOfPackExpr::child_end() { - return child_iterator(); -} - SubstNonTypeTemplateParmPackExpr:: SubstNonTypeTemplateParmPackExpr(QualType T, NonTypeTemplateParmDecl *Param, @@ -1080,16 +890,4 @@ TemplateArgument SubstNonTypeTemplateParmPackExpr::getArgumentPack() const { return TemplateArgument(Arguments, NumArguments); } -SourceRange SubstNonTypeTemplateParmPackExpr::getSourceRange() const { - return NameLoc; -} - -Stmt::child_iterator SubstNonTypeTemplateParmPackExpr::child_begin() { - return child_iterator(); -} - -Stmt::child_iterator SubstNonTypeTemplateParmPackExpr::child_end() { - return child_iterator(); -} - diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp index c9f4fa8daa..ba3b88b465 100644 --- a/lib/AST/ExprClassification.cpp +++ b/lib/AST/ExprClassification.cpp @@ -90,6 +90,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { switch (E->getStmtClass()) { // First come the expressions that are always lvalues, unconditionally. case Stmt::NoStmtClass: +#define ABSTRACT_STMT(Kind) #define STMT(Kind, Base) case Expr::Kind##Class: #define EXPR(Kind, Base) #include "clang/AST/StmtNodes.inc" diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 0a7a9d22cf..227c60e564 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -2578,6 +2578,7 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { } switch (E->getStmtClass()) { +#define ABSTRACT_STMT(Node) #define STMT(Node, Base) case Expr::Node##Class: #define EXPR(Node, Base) #include "clang/AST/StmtNodes.inc" diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index a84df1210d..0e050414ee 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -1690,6 +1690,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) { // ::= L <mangled-name> E # external name switch (E->getStmtClass()) { case Expr::NoStmtClass: +#define ABSTRACT_STMT(Type) #define EXPR(Type, Base) #define STMT(Type, Base) \ case Expr::Type##Class: diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index acd77beaca..b4abd05d68 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -84,6 +84,61 @@ bool Stmt::CollectingStats(bool Enable) { return StatSwitch; } +namespace { + struct good {}; + struct bad {}; + static inline good is_good(good); // static inline to suppress unused warning + + typedef Stmt::child_range children_t(); + template <class T> good implements_children(children_t T::*); + static inline bad implements_children(children_t Stmt::*); + + typedef SourceRange getSourceRange_t() const; + template <class T> good implements_getSourceRange(getSourceRange_t T::*); + static inline bad implements_getSourceRange(getSourceRange_t Stmt::*); + +#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); @@ -556,6 +611,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,89 +645,6 @@ 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]+CompoundStmtBits.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 LabelStmt *IndirectGotoStmt::getConstantTarget() { if (AddrLabelExpr *E = @@ -676,17 +653,6 @@ LabelStmt *IndirectGotoStmt::getConstantTarget() { return 0; } -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(); } - // ReturnStmt const Expr* ReturnStmt::getRetValue() const { return cast_or_null<Expr>(RetExpr); @@ -694,69 +660,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; -} diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 2ed2c92750..5d31fd61a5 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -220,10 +220,6 @@ void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) { } } -void StmtPrinter::VisitSwitchCase(SwitchCase*) { - assert(0 && "SwitchCase is an abstract class"); -} - void StmtPrinter::VisitWhileStmt(WhileStmt *Node) { Indent() << "while ("; PrintExpr(Node->getCond()); diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index 60aa7541cf..f782c8004a 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -71,7 +71,6 @@ void CodeGenFunction::EmitStmt(const Stmt *S) { switch (S->getStmtClass()) { case Stmt::NoStmtClass: case Stmt::CXXCatchStmtClass: - case Stmt::SwitchCaseClass: llvm_unreachable("invalid statement class to emit generically"); case Stmt::NullStmtClass: case Stmt::CompoundStmtClass: diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 2a82869786..bd110bd1f6 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -2280,6 +2280,7 @@ StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) { // Transform individual statement nodes #define STMT(Node, Parent) \ case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S)); +#define ABSTRACT_STMT(Node) #define EXPR(Node, Parent) #include "clang/AST/StmtNodes.inc" @@ -4831,13 +4832,6 @@ TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) { template<typename Derived> StmtResult -TreeTransform<Derived>::TransformSwitchCase(SwitchCase *S) { - assert(false && "SwitchCase is abstract and cannot be transformed"); - return SemaRef.Owned(S); -} - -template<typename Derived> -StmtResult |