From b5363ea12917cc34b87eec96d869961f59aab4a5 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sat, 18 Jul 2015 14:35:53 +0000 Subject: [PATCH] [AST] Cleanup ExprIterator. - Make it a proper random access iterator with a little help from iterator_adaptor_base - Clean up users of magic dereferencing. The iterator should behave like an Expr **. - Make it an implementation detail of Stmt. This allows inlining of the assertions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@242608 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Stmt.h | 85 +++++++++++++-------------------- lib/AST/Expr.cpp | 13 ----- lib/AST/StmtPrinter.cpp | 2 +- lib/CodeGen/CGCall.cpp | 4 +- lib/CodeGen/CGClass.cpp | 2 +- lib/CodeGen/CGExprCXX.cpp | 5 +- lib/CodeGen/CodeGenFunction.h | 2 +- lib/CodeGen/MicrosoftCXXABI.cpp | 5 +- 8 files changed, 43 insertions(+), 75 deletions(-) diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 5104235706..7ab698b4bd 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -22,6 +22,7 @@ #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/iterator.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include @@ -49,57 +50,6 @@ namespace clang { class Token; class VarDecl; - //===--------------------------------------------------------------------===// - // ExprIterator - Iterators for iterating over Stmt* arrays that contain - // only Expr*. This is needed because AST nodes use Stmt* arrays to store - // references to children (to be compatible with StmtIterator). - //===--------------------------------------------------------------------===// - - class Stmt; - class Expr; - - class ExprIterator : public std::iterator { - Stmt** I; - public: - ExprIterator(Stmt** i) : I(i) {} - ExprIterator() : I(nullptr) {} - ExprIterator& operator++() { ++I; return *this; } - ExprIterator operator-(size_t i) { return I-i; } - ExprIterator operator+(size_t i) { return I+i; } - Expr* operator[](size_t idx); - // FIXME: Verify that this will correctly return a signed distance. - signed operator-(const ExprIterator& R) const { return I - R.I; } - Expr* operator*() const; - Expr* operator->() const; - bool operator==(const ExprIterator& R) const { return I == R.I; } - bool operator!=(const ExprIterator& R) const { return I != R.I; } - bool operator>(const ExprIterator& R) const { return I > R.I; } - bool operator>=(const ExprIterator& R) const { return I >= R.I; } - }; - - class ConstExprIterator : public std::iterator { - const Stmt * const *I; - public: - ConstExprIterator(const Stmt * const *i) : I(i) {} - ConstExprIterator() : I(nullptr) {} - ConstExprIterator& operator++() { ++I; return *this; } - ConstExprIterator operator+(size_t i) const { return I+i; } - ConstExprIterator operator-(size_t i) const { return I-i; } - const Expr * operator[](size_t idx) const; - signed operator-(const ConstExprIterator& R) const { return I - R.I; } - const Expr * operator*() const; - const Expr * operator->() const; - bool operator==(const ConstExprIterator& R) const { return I == R.I; } - bool operator!=(const ConstExprIterator& R) const { return I != R.I; } - bool operator>(const ConstExprIterator& R) const { return I > R.I; } - bool operator>=(const ConstExprIterator& R) const { return I >= R.I; } - }; - //===----------------------------------------------------------------------===// // AST classes for statements. //===----------------------------------------------------------------------===// @@ -337,6 +287,39 @@ public: /// de-serialization). struct EmptyShell { }; +protected: + /// Iterator for iterating over Stmt * arrays that contain only Expr * + /// + /// This is needed because AST nodes use Stmt* arrays to store + /// references to children (to be compatible with StmtIterator). + struct ExprIterator + : llvm::iterator_adaptor_base { + ExprIterator() : iterator_adaptor_base(nullptr) {} + ExprIterator(Stmt **I) : iterator_adaptor_base(I) {} + + reference operator*() const { + assert((*I)->getStmtClass() >= firstExprConstant && + (*I)->getStmtClass() <= lastExprConstant); + return *reinterpret_cast(I); + } + }; + + /// Const iterator for iterating over Stmt * arrays that contain only Expr * + struct ConstExprIterator + : llvm::iterator_adaptor_base { + ConstExprIterator() : iterator_adaptor_base(nullptr) {} + ConstExprIterator(const Stmt *const *I) : iterator_adaptor_base(I) {} + + reference operator*() const { + assert((*I)->getStmtClass() >= firstExprConstant && + (*I)->getStmtClass() <= lastExprConstant); + return *reinterpret_cast(I); + } + }; + private: /// \brief Whether statistic collection is enabled. static bool StatisticsEnabled; diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 6c048f96d4..5ee06b3666 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -4162,19 +4162,6 @@ PseudoObjectExpr::PseudoObjectExpr(QualType type, ExprValueKind VK, } } -//===----------------------------------------------------------------------===// -// ExprIterator. -//===----------------------------------------------------------------------===// - -Expr* ExprIterator::operator[](size_t idx) { return cast(I[idx]); } -Expr* ExprIterator::operator*() const { return cast(*I); } -Expr* ExprIterator::operator->() const { return cast(*I); } -const Expr* ConstExprIterator::operator[](size_t idx) const { - return cast(I[idx]); -} -const Expr* ConstExprIterator::operator*() const { return cast(*I); } -const Expr* ConstExprIterator::operator->() const { return cast(*I); } - //===----------------------------------------------------------------------===// // Child Iterators for iterating over subexpressions/substatements //===----------------------------------------------------------------------===// diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 79600773f5..8870c67c74 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -1768,7 +1768,7 @@ void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) { for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(), ArgEnd = Node->arg_end(); Arg != ArgEnd; ++Arg) { - if (Arg->isDefaultArgument()) + if ((*Arg)->isDefaultArgument()) break; if (Arg != Node->arg_begin()) OS << ", "; diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 3e4d7f323d..2dc94d06f3 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -2829,7 +2829,7 @@ void CodeGenFunction::EmitCallArgs(CallArgList &Args, for (int I = ArgTypes.size() - 1; I >= 0; --I) { CallExpr::const_arg_iterator Arg = ArgBeg + I; EmitCallArg(Args, *Arg, ArgTypes[I]); - EmitNonNullArgCheck(Args.back().RV, ArgTypes[I], Arg->getExprLoc(), + EmitNonNullArgCheck(Args.back().RV, ArgTypes[I], (*Arg)->getExprLoc(), CalleeDecl, ParamsToSkip + I); } @@ -2843,7 +2843,7 @@ void CodeGenFunction::EmitCallArgs(CallArgList &Args, CallExpr::const_arg_iterator Arg = ArgBeg + I; assert(Arg != ArgEnd); EmitCallArg(Args, *Arg, ArgTypes[I]); - EmitNonNullArgCheck(Args.back().RV, ArgTypes[I], Arg->getExprLoc(), + EmitNonNullArgCheck(Args.back().RV, ArgTypes[I], (*Arg)->getExprLoc(), CalleeDecl, ParamsToSkip + I); } } diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 9c18b86092..52aac0be3d 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -1832,7 +1832,7 @@ CodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, "trivial 1-arg ctor not a copy/move ctor"); EmitAggregateCopyCtor(This, Src, getContext().getTypeDeclType(D->getParent()), - E->arg_begin()->getType()); + (*E->arg_begin())->getType()); return; } llvm::Value *Callee = CGM.getAddrOfCXXStructor(D, StructorType::Complete); diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index 371f44fcc9..2a6ed30a86 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -196,7 +196,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr( // Trivial move and copy ctor are the same. assert(CE->getNumArgs() == 1 && "unexpected argcount for trivial ctor"); llvm::Value *RHS = EmitLValue(*CE->arg_begin()).getAddress(); - EmitAggregateCopy(This, RHS, CE->arg_begin()->getType()); + EmitAggregateCopy(This, RHS, (*CE->arg_begin())->getType()); return RValue::get(This); } llvm_unreachable("unknown trivial member function"); @@ -1089,8 +1089,7 @@ RValue CodeGenFunction::EmitBuiltinNewDeleteCall(const FunctionProtoType *Type, bool IsDelete) { CallArgList Args; const Stmt *ArgS = Arg; - EmitCallArgs(Args, *Type->param_type_begin(), - ConstExprIterator(&ArgS), ConstExprIterator(&ArgS + 1)); + EmitCallArgs(Args, *Type->param_type_begin(), &ArgS, &ArgS + 1); // Find the allocation or deallocation function that we're calling. ASTContext &Ctx = getContext(); DeclarationName Name = Ctx.DeclarationNames diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index f2bc402f8b..b8e97ac261 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -2992,7 +2992,7 @@ public: .getCanonicalType((*I).getNonReferenceType()) .getTypePtr() == getContext() - .getCanonicalType(Arg->getType()) + .getCanonicalType((*Arg)->getType()) .getTypePtr())) && "type mismatch in call argument!"); ArgTypes.push_back(*I); diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp index 3433990e12..7e33b85c39 100644 --- a/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/lib/CodeGen/MicrosoftCXXABI.cpp @@ -3803,9 +3803,8 @@ MicrosoftCXXABI::getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD, CodeGenFunction::RunCleanupsScope Cleanups(CGF); const auto *FPT = CD->getType()->castAs(); - ConstExprIterator ArgBegin(ArgVec.data()), - ArgEnd(ArgVec.data() + ArgVec.size()); - CGF.EmitCallArgs(Args, FPT, ArgBegin, ArgEnd, CD, IsCopy ? 1 : 0); + CGF.EmitCallArgs(Args, FPT, &*ArgVec.begin(), &*ArgVec.end(), CD, + IsCopy ? 1 : 0); // Insert any ABI-specific implicit constructor arguments. unsigned ExtraArgs = addImplicitConstructorArgs(CGF, CD, Ctor_Complete, -- 2.40.0