From a4c46df1cd63e06af2a094b68b902a3eb232f056 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 11 Dec 2008 17:59:21 +0000 Subject: [PATCH] Actually distinguish between RecordDecl::field_iterator and RecordDecl::field_const_iterator, propagating the constness down to the FieldDecls. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60883 91177308-0d34-0410-b5e6-96231b3b80d8 --- Driver/RewriteBlocks.cpp | 2 +- Driver/RewriteObjC.cpp | 2 +- include/clang/AST/Decl.h | 77 +++++++++++++++++++++++++++--------- lib/AST/ASTContext.cpp | 4 +- lib/CodeGen/CGDebugInfo.cpp | 7 ++-- lib/CodeGen/CodeGenTypes.cpp | 8 ++-- 6 files changed, 70 insertions(+), 30 deletions(-) diff --git a/Driver/RewriteBlocks.cpp b/Driver/RewriteBlocks.cpp index 5b6e1a988d..1e7a6af91d 100644 --- a/Driver/RewriteBlocks.cpp +++ b/Driver/RewriteBlocks.cpp @@ -1134,7 +1134,7 @@ void RewriteBlocks::HandleDeclInMainFile(Decl *D) { } if (RecordDecl *RD = dyn_cast(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())) diff --git a/Driver/RewriteObjC.cpp b/Driver/RewriteObjC.cpp index 290a668563..2487d23759 100644 --- a/Driver/RewriteObjC.cpp +++ b/Driver/RewriteObjC.cpp @@ -4438,7 +4438,7 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) { } if (RecordDecl *RD = dyn_cast(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())) diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 3b0eb551bb..3f7b53dfdc 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -1002,8 +1002,11 @@ public: return cast_or_null(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(*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(*Current); } + + pointer operator->() const { return cast(*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); diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 3455504fdb..e62920f631 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -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); diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 67c60aae07..d6a1c6b8b3 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -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); diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp index 8918671332..d9c9cb1336 100644 --- a/lib/CodeGen/CodeGenTypes.cpp +++ b/lib/CodeGen/CodeGenTypes.cpp @@ -480,8 +480,8 @@ void RecordOrganizer::layoutStructFields(const ASTRecordLayout &RL) { std::vector 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);