forked from OSchip/llvm-project
[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. llvm-svn: 242608
This commit is contained in:
parent
3204a105e3
commit
f48ee4482a
|
@ -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 <string>
|
||||
|
@ -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<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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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, 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;
|
||||
|
|
|
@ -4162,19 +4162,6 @@ PseudoObjectExpr::PseudoObjectExpr(QualType type, ExprValueKind VK,
|
|||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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 << ", ";
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -3803,9 +3803,8 @@ MicrosoftCXXABI::getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD,
|
|||
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,
|
||||
|
|
Loading…
Reference in New Issue