[cfe-commits] r75604 - in /cfe/trunk: include/clang/AST/Decl.h lib/AST/Decl.cpp
Douglas Gregor
dgregor at apple.com
Tue Jul 14 00:11:12 PDT 2009
On Jul 14, 2009, at 5:20 AM, Argiris Kirtzidis wrote:
> Author: akirtzidis
> Date: Mon Jul 13 22:20:21 2009
> New Revision: 75604
>
> URL: http://llvm.org/viewvc/llvm-project?rev=75604&view=rev
> Log:
> Introduce redecl_iterator, used for iterating over the
> redeclarations of a FunctionDecl or VarDecl.
>
> It iterates over all the redeclarations, regardless of the starting
> point. For example:
>
> 1) int f();
> 2) int f();
> 3) int f();
>
> if you have the (2) FunctionDecl and call redecls_begin/redecls_end
> to iterate, you'll get this sequence:
> (2)
> (1)
> (3)
>
> The motivation to introduce this was that, previously, if (3) was a
> function definition,
> and you called getBody() at (2), it would not return it, since
> getBody() iterated over the previous declarations only,
> so it would only check (2) and (1).
Excellent! Solving this problem has been on my TODO list for several
months :)
(Some comments below)
> Modified:
> cfe/trunk/include/clang/AST/Decl.h
> cfe/trunk/lib/AST/Decl.cpp
>
> Modified: cfe/trunk/include/clang/AST/Decl.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=75604&r1=75603&r2=75604&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/include/clang/AST/Decl.h (original)
> +++ cfe/trunk/include/clang/AST/Decl.h Mon Jul 13 22:20:21 2009
> @@ -439,6 +439,54 @@
>
> virtual Decl *getPrimaryDecl() const;
>
> + /// \brief Iterates through all the redeclarations of the same
> var decl.
> + class redecl_iterator {
> + /// Current - The current declaration.
> + VarDecl *Current;
> + VarDecl *Starter;
> +
> + public:
> + typedef VarDecl* value_type;
> + typedef VarDecl* reference;
> + typedef VarDecl* pointer;
> + typedef std::forward_iterator_tag iterator_category;
> + typedef std::ptrdiff_t difference_type;
> +
> + redecl_iterator() : Current(0) { }
> + explicit redecl_iterator(VarDecl *C) : Current(C), Starter(C) { }
> +
> + reference operator*() const { return Current; }
> + pointer operator->() const { return Current; }
> +
> + redecl_iterator& operator++() {
> + assert(Current && "Advancing while iterator has reached end");
> + // Get either previous decl or latest decl.
> + VarDecl *Next = Current->PreviousDeclaration.getPointer();
> + Current = (Next != Starter ? Next : 0);
> + return *this;
> + }
> +
> + redecl_iterator operator++(int) {
> + redecl_iterator tmp(*this);
> + ++(*this);
> + return tmp;
> + }
> +
> + friend bool operator==(redecl_iterator x, redecl_iterator y) {
> + return x.Current == y.Current;
> + }
> + friend bool operator!=(redecl_iterator x, redecl_iterator y) {
> + return x.Current != y.Current;
> + }
> + };
> +
> + /// \brief Returns iterator for all the redeclarations of the
> same variable.
> + /// It will iterate at least once (when this decl is the only one).
> + redecl_iterator redecls_begin() const {
> + return redecl_iterator(const_cast<VarDecl*>(this));
> + }
> + redecl_iterator redecls_end() const { return redecl_iterator(); }
> +
> /// hasLocalStorage - Returns true if a variable with function scope
> /// is a non-static local variable.
> bool hasLocalStorage() const {
> @@ -862,6 +910,54 @@
>
> virtual Decl *getPrimaryDecl() const;
>
> + /// \brief Iterates through all the redeclarations of the same
> function decl.
> + class redecl_iterator {
> + /// Current - The current declaration.
> + FunctionDecl *Current;
> + FunctionDecl *Starter;
> +
> + public:
> + typedef FunctionDecl* value_type;
> + typedef FunctionDecl* reference;
> + typedef FunctionDecl* pointer;
> + typedef std::forward_iterator_tag iterator_category;
> + typedef std::ptrdiff_t difference_type;
> +
> + redecl_iterator() : Current(0) { }
> + explicit redecl_iterator(FunctionDecl *C) : Current(C),
> Starter(C) { }
> +
> + reference operator*() const { return Current; }
> + pointer operator->() const { return Current; }
> +
> + redecl_iterator& operator++() {
> + assert(Current && "Advancing while iterator has reached end");
> + // Get either previous decl or latest decl.
> + FunctionDecl *Next = Current->PreviousDeclaration.getPointer();
> + Current = (Next != Starter ? Next : 0);
> + return *this;
> + }
> +
> + redecl_iterator operator++(int) {
> + redecl_iterator tmp(*this);
> + ++(*this);
> + return tmp;
> + }
> +
> + friend bool operator==(redecl_iterator x, redecl_iterator y) {
> + return x.Current == y.Current;
> + }
> + friend bool operator!=(redecl_iterator x, redecl_iterator y) {
> + return x.Current != y.Current;
> + }
> + };
This is mostly copy-paste-and-modify from VarDecl's redecl_iterator.
Can we extract the common functionality into a template? We'll also
need the same behavior for other kinds of entities that can be
redeclared---tag types and templates, for example.
- Doug
More information about the cfe-commits
mailing list