Actually distinguish between RecordDecl::field_iterator and RecordDecl::field_const_iterator, propagating the constness down to the FieldDecls.

llvm-svn: 60883
This commit is contained in:
Douglas Gregor 2008-12-11 17:59:21 +00:00
parent 6a344e097c
commit e029561346
6 changed files with 70 additions and 30 deletions

View File

@ -1134,7 +1134,7 @@ void RewriteBlocks::HandleDeclInMainFile(Decl *D) {
}
if (RecordDecl *RD = dyn_cast<RecordDecl>(D)) {
if (RD->isDefinition()) {
for (RecordDecl::field_const_iterator i = RD->field_begin(),
for (RecordDecl::field_iterator i = RD->field_begin(),
e = RD->field_end(); i != e; ++i) {
FieldDecl *FD = *i;
if (isBlockPointerType(FD->getType()))

View File

@ -4438,7 +4438,7 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) {
}
if (RecordDecl *RD = dyn_cast<RecordDecl>(D)) {
if (RD->isDefinition()) {
for (RecordDecl::field_const_iterator i = RD->field_begin(),
for (RecordDecl::field_iterator i = RD->field_begin(),
e = RD->field_end(); i != e; ++i) {
FieldDecl *FD = *i;
if (isBlockPointerType(FD->getType()))

View File

@ -1002,8 +1002,11 @@ public:
return cast_or_null<RecordDecl>(TagDecl::getDefinition(C));
}
// Iterator access to field members.
class field_iterator {
// Iterator access to field members. The field iterator only visits
// the non-static data members of this class, ignoring any static
// data members, functions, constructors, destructors, etc.
class field_const_iterator {
protected:
/// Current - Current position within the sequence of declarations
/// in this record.
DeclContext::decl_iterator Current;
@ -1020,15 +1023,16 @@ public:
}
public:
typedef FieldDecl* value_type;
typedef FieldDecl* reference;
typedef FieldDecl* pointer;
typedef FieldDecl const * value_type;
typedef FieldDecl const * reference;
typedef FieldDecl const * pointer;
typedef std::ptrdiff_t difference_type;
typedef std::forward_iterator_tag iterator_category;
field_iterator() : Current(), End() { }
field_const_iterator() : Current(), End() { }
field_iterator(DeclContext::decl_iterator C, DeclContext::decl_iterator E)
field_const_iterator(DeclContext::decl_iterator C,
DeclContext::decl_iterator E)
: Current(C), End(E) {
SkipToNextField();
}
@ -1037,6 +1041,44 @@ public:
pointer operator->() const { return cast<FieldDecl>(*Current); }
field_const_iterator& operator++() {
++Current;
SkipToNextField();
return *this;
}
field_const_iterator operator++(int) {
field_const_iterator tmp(*this);
++(*this);
return tmp;
}
friend bool
operator==(const field_const_iterator& x, const field_const_iterator& y) {
return x.Current == y.Current;
}
friend bool
operator!=(const field_const_iterator& x, const field_const_iterator& y) {
return x.Current != y.Current;
}
};
class field_iterator : public field_const_iterator {
public:
typedef FieldDecl* value_type;
typedef FieldDecl* reference;
typedef FieldDecl* pointer;
field_iterator() : field_const_iterator() { }
field_iterator(DeclContext::decl_iterator C, DeclContext::decl_iterator E)
: field_const_iterator(C, E) { }
reference operator*() const { return cast<FieldDecl>(*Current); }
pointer operator->() const { return cast<FieldDecl>(*Current); }
field_iterator& operator++() {
++Current;
SkipToNextField();
@ -1048,25 +1090,22 @@ public:
++(*this);
return tmp;
}
friend bool operator==(const field_iterator& x, const field_iterator& y) {
return x.Current == y.Current;
}
friend bool operator!=(const field_iterator& x, const field_iterator& y) {
return x.Current != y.Current;
}
};
typedef field_iterator field_const_iterator;
field_iterator field_begin() const {
field_iterator field_begin() {
return field_iterator(decls_begin(), decls_end());
}
field_iterator field_end() const {
field_iterator field_end() {
return field_iterator(decls_end(), decls_end());
}
field_const_iterator field_begin() const {
return field_const_iterator(decls_begin(), decls_end());
}
field_const_iterator field_end() const {
return field_const_iterator(decls_end(), decls_end());
}
/// completeDefinition - Notes that the definition of this type is
/// now complete.
void completeDefinition(ASTContext& C);

View File

@ -553,8 +553,8 @@ const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D) {
// Layout each field, for now, just sequentially, respecting alignment. In
// the future, this will need to be tweakable by targets.
unsigned FieldIdx = 0;
for (RecordDecl::field_iterator Field = D->field_begin(),
FieldEnd = D->field_end();
for (RecordDecl::field_const_iterator Field = D->field_begin(),
FieldEnd = D->field_end();
Field != FieldEnd; (void)++Field, ++FieldIdx)
NewEntry->LayoutField(*Field, FieldIdx, IsUnion, StructPacking, *this);

View File

@ -191,7 +191,7 @@ llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty,
/// getOrCreateRecordType - get structure or union type.
llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
llvm::DICompileUnit Unit) {
const RecordDecl *Decl = Ty->getDecl();
RecordDecl *Decl = Ty->getDecl();
unsigned Tag;
if (Decl->isStruct())
@ -236,8 +236,9 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
const ASTRecordLayout &RL = M->getContext().getASTRecordLayout(Decl);
unsigned FieldNo = 0;
for (RecordDecl::field_const_iterator I = Decl->field_begin(),
E = Decl->field_end(); I != E; ++I, ++FieldNo) {
for (RecordDecl::field_iterator I = Decl->field_begin(),
E = Decl->field_end();
I != E; ++I, ++FieldNo) {
FieldDecl *Field = *I;
llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);

View File

@ -480,8 +480,8 @@ void RecordOrganizer::layoutStructFields(const ASTRecordLayout &RL) {
std::vector<const llvm::Type*> LLVMFields;
unsigned curField = 0;
for (RecordDecl::field_iterator Field = RD.field_begin(),
FieldEnd = RD.field_end();
for (RecordDecl::field_const_iterator Field = RD.field_begin(),
FieldEnd = RD.field_end();
Field != FieldEnd; ++Field) {
uint64_t offset = RL.getFieldOffset(curField);
const llvm::Type *Ty = CGT.ConvertTypeRecursive(Field->getType());
@ -531,8 +531,8 @@ void RecordOrganizer::layoutStructFields(const ASTRecordLayout &RL) {
/// all fields are added.
void RecordOrganizer::layoutUnionFields(const ASTRecordLayout &RL) {
unsigned curField = 0;
for (RecordDecl::field_iterator Field = RD.field_begin(),
FieldEnd = RD.field_end();
for (RecordDecl::field_const_iterator Field = RD.field_begin(),
FieldEnd = RD.field_end();
Field != FieldEnd; ++Field) {
// The offset should usually be zero, but bitfields could be strange
uint64_t offset = RL.getFieldOffset(curField);