#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 <string>
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<std::forward_iterator_tag,
- Expr *&, ptrdiff_t,
- Expr *&, Expr *&> {
- 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<std::forward_iterator_tag,
- const Expr *&, ptrdiff_t,
- const Expr *&,
- const Expr *&> {
- 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.
//===----------------------------------------------------------------------===//
/// 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, Stmt **,
+ std::random_access_iterator_tag, Expr *> {
+ 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<Expr **>(I);
+ }
+ };
+
+ /// Const iterator for iterating over Stmt * arrays that contain only Expr *
+ struct ConstExprIterator
+ : llvm::iterator_adaptor_base<ConstExprIterator, const Stmt *const *,
+ std::random_access_iterator_tag,
+ const Expr *const> {
+ 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<const Expr *const *>(I);
+ }
+ };
+
private:
/// \brief Whether statistic collection is enabled.
static bool StatisticsEnabled;
}
}
-//===----------------------------------------------------------------------===//
-// ExprIterator.
-//===----------------------------------------------------------------------===//
-
-Expr* ExprIterator::operator[](size_t idx) { return cast<Expr>(I[idx]); }
-Expr* ExprIterator::operator*() const { return cast<Expr>(*I); }
-Expr* ExprIterator::operator->() const { return cast<Expr>(*I); }
-const Expr* ConstExprIterator::operator[](size_t idx) const {
- return cast<Expr>(I[idx]);
-}
-const Expr* ConstExprIterator::operator*() const { return cast<Expr>(*I); }
-const Expr* ConstExprIterator::operator->() const { return cast<Expr>(*I); }
-
//===----------------------------------------------------------------------===//
// Child Iterators for iterating over subexpressions/substatements
//===----------------------------------------------------------------------===//
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 << ", ";
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);
}
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);
}
}
"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);
// 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");
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
.getCanonicalType((*I).getNonReferenceType())
.getTypePtr() ==
getContext()
- .getCanonicalType(Arg->getType())
+ .getCanonicalType((*Arg)->getType())
.getTypePtr())) &&
"type mismatch in call argument!");
ArgTypes.push_back(*I);
CodeGenFunction::RunCleanupsScope Cleanups(CGF);
const auto *FPT = CD->getType()->castAs<FunctionProtoType>();
- 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,