From: Aaron Ballman Date: Fri, 7 Mar 2014 22:17:20 +0000 (+0000) Subject: In my tests, I'm finding that declaring iterators in terms of ranges can sometimes... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6f69b0ed9a677f8f0c3d303fcd5fadf23bd2d43f;p=clang In my tests, I'm finding that declaring iterators in terms of ranges can sometimes have dangerous side-effects where the range temporary is destroyed, taking the underlying iterators out with it. This changes the iterators so that they are no longer implemented in terms of ranges (so it's a very partial revert of the existing rangification efforts). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@203299 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 081101520f..c4451e73cd 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -1846,14 +1846,20 @@ public: typedef llvm::iterator_range param_range; typedef llvm::iterator_range param_const_range; - param_iterator param_begin() { return params().begin(); } - param_iterator param_end() { return params().end(); } + param_iterator param_begin() { return param_iterator(ParamInfo); } + param_iterator param_end() { + return param_iterator(ParamInfo + param_size()); + } param_range params() { return param_range(ParamInfo, ParamInfo + param_size()); } - param_const_iterator param_begin() const { return params().begin(); } - param_const_iterator param_end() const { return params().end(); } + param_const_iterator param_begin() const { + return param_const_iterator(ParamInfo); + } + param_const_iterator param_end() const { + return param_const_iterator(ParamInfo + param_size()); + } param_const_range params() const { return param_const_range(ParamInfo, ParamInfo + param_size()); } diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 47a3600e9c..4139e28afe 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -780,8 +780,10 @@ public: redecl_iterator()); } - redecl_iterator redecls_begin() const { return redecls().begin(); } - redecl_iterator redecls_end() const { return redecls().end(); } + redecl_iterator redecls_begin() const { + return redecl_iterator(const_cast(this)); + } + redecl_iterator redecls_end() const { return redecl_iterator(); } /// \brief Retrieve the previous declaration that declares the same entity /// as this declaration, or NULL if there is no previous declaration. @@ -1311,16 +1313,16 @@ public: /// decls_begin/decls_end - Iterate over the declarations stored in /// this context. decl_range decls() const; - decl_iterator decls_begin() const { return decls().begin(); } - decl_iterator decls_end() const { return decls().end(); } + decl_iterator decls_begin() const; + decl_iterator decls_end() const { return decl_iterator(); } bool decls_empty() const; /// noload_decls_begin/end - Iterate over the declarations stored in this /// context that are currently loaded; don't attempt to retrieve anything /// from an external source. decl_range noload_decls() const; - decl_iterator noload_decls_begin() const { return noload_decls().begin(); } - decl_iterator noload_decls_end() const { return noload_decls().end(); } + decl_iterator noload_decls_begin() const; + decl_iterator noload_decls_end() const { return decl_iterator(); } /// specific_decl_iterator - Iterates over a subrange of /// declarations stored in a DeclContext, providing only those that diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 309bb12609..6948443d8d 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -352,10 +352,14 @@ public: return param_const_range(getParams(), getParams() + NumParams); } - param_const_iterator param_begin() const { return params().begin(); } - param_const_iterator param_end() const { return params().end(); } - param_iterator param_begin() { return params().begin(); } - param_iterator param_end() { return params().end(); } + param_const_iterator param_begin() const { + return param_const_iterator(getParams()); + } + param_const_iterator param_end() const { + return param_const_iterator(getParams() + NumParams); + } + param_iterator param_begin() { return param_iterator(getParams()); } + param_iterator param_end() { return param_iterator(getParams() + NumParams); } // This method returns and of the parameters which are part of the selector // name mangling requirements. diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h index 1170eda819..25b81c2a80 100644 --- a/include/clang/AST/Redeclarable.h +++ b/include/clang/AST/Redeclarable.h @@ -171,8 +171,11 @@ public: redecl_iterator()); } - redecl_iterator redecls_begin() const { return redecls().begin(); } - redecl_iterator redecls_end() const { return redecls().end(); } + redecl_iterator redecls_begin() const { + return redecl_iterator( + const_cast(static_cast(this))); + } + redecl_iterator redecls_end() const { return redecl_iterator(); } friend class ASTDeclReader; friend class ASTDeclWriter; diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 711946ea00..5797e554a3 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -1080,12 +1080,22 @@ DeclContext::decl_range DeclContext::noload_decls() const { return decl_range(decl_iterator(FirstDecl), decl_iterator()); } +DeclContext::decl_iterator DeclContext::noload_decls_begin() const { + return decl_iterator(FirstDecl); +} + DeclContext::decl_range DeclContext::decls() const { if (hasExternalLexicalStorage()) LoadLexicalDeclsFromExternalStorage(); return decl_range(decl_iterator(FirstDecl), decl_iterator()); } +DeclContext::decl_iterator DeclContext::decls_begin() const { + if (hasExternalLexicalStorage()) + LoadLexicalDeclsFromExternalStorage(); + return decl_iterator(FirstDecl); +} + bool DeclContext::decls_empty() const { if (hasExternalLexicalStorage()) LoadLexicalDeclsFromExternalStorage();