[cfe-commits] r76298 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/AST/DeclBase.h lib/AST/Decl.cpp tools/index-test/index-test.cpp

Argiris Kirtzidis akyrtzi at gmail.com
Sat Jul 18 01:50:36 PDT 2009


Author: akirtzidis
Date: Sat Jul 18 03:50:35 2009
New Revision: 76298

URL: http://llvm.org/viewvc/llvm-project?rev=76298&view=rev
Log:
Introduce a redecl_iterator in Decl class, so that we can do a "iterate over all declarations of the same decl" without knowing the exact type.

Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/DeclBase.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/tools/index-test/index-test.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=76298&r1=76297&r2=76298&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Sat Jul 18 03:50:35 2009
@@ -259,7 +259,19 @@
       DeclaredInCondition(false), TypeSpecStartLoc(TSSL) { 
     SClass = SC; 
   }
+
+  typedef Redeclarable<VarDecl> redeclarable_base;
+  virtual VarDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
+
 public:
+  typedef redeclarable_base::redecl_iterator redecl_iterator;
+  redecl_iterator redecls_begin() const {
+    return redeclarable_base::redecls_begin();
+  } 
+  redecl_iterator redecls_end() const {
+    return redeclarable_base::redecls_end();
+  }
+
   static VarDecl *Create(ASTContext &C, DeclContext *DC,
                          SourceLocation L, IdentifierInfo *Id,
                          QualType T, StorageClass S,
@@ -683,7 +695,18 @@
   virtual ~FunctionDecl() {}
   virtual void Destroy(ASTContext& C);
 
+  typedef Redeclarable<FunctionDecl> redeclarable_base;
+  virtual FunctionDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
+
 public:
+  typedef redeclarable_base::redecl_iterator redecl_iterator;
+  redecl_iterator redecls_begin() const {
+    return redeclarable_base::redecls_begin();
+  } 
+  redecl_iterator redecls_end() const {
+    return redeclarable_base::redecls_end();
+  }
+
   static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
                               DeclarationName N, QualType T, 
                               StorageClass S = None, bool isInline = false,

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=76298&r1=76297&r2=76298&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Sat Jul 18 03:50:35 2009
@@ -320,6 +320,62 @@
 
   /// \brief Whether this particular Decl is a primary one.
   bool isCanonicalDecl() const { return getCanonicalDecl() == this; }
+  
+protected:
+  /// \brief Returns the next redeclaration or itself if this is the only decl.
+  ///
+  /// Decl subclasses that can be redeclared should override this method so that
+  /// Decl::redecl_iterator can iterate over them.
+  virtual Decl *getNextRedeclaration() { return this; }
+
+public:
+  /// \brief Iterates through all the redeclarations of the same decl.
+  class redecl_iterator {
+    /// Current - The current declaration.
+    Decl *Current;
+    Decl *Starter;
+
+  public:
+    typedef Decl*                     value_type;
+    typedef Decl*                     reference;
+    typedef Decl*                     pointer;
+    typedef std::forward_iterator_tag iterator_category;
+    typedef std::ptrdiff_t            difference_type;
+
+    redecl_iterator() : Current(0) { }
+    explicit redecl_iterator(Decl *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.
+      Decl *Next = Current->getNextRedeclaration();
+      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 decl.
+  /// It will iterate at least once (when this decl is the only one).
+  redecl_iterator redecls_begin() const {
+    return redecl_iterator(const_cast<Decl*>(this));
+  }
+  redecl_iterator redecls_end() const { return redecl_iterator(); }
 
   /// getBody - If this Decl represents a declaration for a body of code,
   ///  such as a function or method definition, this method returns the

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=76298&r1=76297&r2=76298&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Sat Jul 18 03:50:35 2009
@@ -565,7 +565,7 @@
 
 void 
 FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) {
-  Redeclarable<FunctionDecl>::setPreviousDeclaration(PrevDecl);
+  redeclarable_base::setPreviousDeclaration(PrevDecl);
 
   if (FunctionTemplateDecl *FunTmpl = getDescribedFunctionTemplate()) {
     FunctionTemplateDecl *PrevFunTmpl 

Modified: cfe/trunk/tools/index-test/index-test.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/index-test/index-test.cpp?rev=76298&r1=76297&r2=76298&view=diff

==============================================================================
--- cfe/trunk/tools/index-test/index-test.cpp (original)
+++ cfe/trunk/tools/index-test/index-test.cpp Sat Jul 18 03:50:35 2009
@@ -133,16 +133,9 @@
   }
   
   case PrintDecls :
-    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-      for (FunctionDecl::redecl_iterator I = FD->redecls_begin(),
-                                         E = FD->redecls_end(); I != E; ++I)
-        ASTLocation(*I).print(OS);
-    } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
-      for (VarDecl::redecl_iterator I = VD->redecls_begin(),
-                                    E = VD->redecls_end(); I != E; ++I)
-        ASTLocation(*I).print(OS);
-    } else
-      ASTLocation(D).print(OS);
+    for (Decl::redecl_iterator I = D->redecls_begin(),
+                               E = D->redecls_end(); I != E; ++I)
+      ASTLocation(*I).print(OS);
     break;
     
   }





More information about the cfe-commits mailing list