[cfe-commits] r76297 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/AST/Redeclarable.h lib/AST/Decl.cpp

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


Author: akirtzidis
Date: Sat Jul 18 03:50:13 2009
New Revision: 76297

URL: http://llvm.org/viewvc/llvm-project?rev=76297&view=rev
Log:
Introduce the Redeclarable template class, which serves as a base type defining the common interface for Decls that can be redeclared.
Make FunctionDecl and VarDecl use it.

Added:
    cfe/trunk/include/clang/AST/Redeclarable.h
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=76297&r1=76296&r2=76297&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Sat Jul 18 03:50:13 2009
@@ -16,6 +16,7 @@
 
 #include "clang/AST/APValue.h"
 #include "clang/AST/DeclBase.h"
+#include "clang/AST/Redeclarable.h"
 #include "clang/AST/DeclarationName.h"
 #include "clang/AST/ExternalASTSource.h"
 
@@ -224,7 +225,7 @@
 
 /// VarDecl - An instance of this class is created to represent a variable
 /// declaration or definition.
-class VarDecl : public ValueDecl {
+class VarDecl : public ValueDecl, public Redeclarable<VarDecl> {
 public:
   enum StorageClass {
     None, Auto, Register, Extern, Static, PrivateExtern
@@ -247,13 +248,6 @@
   /// condition, e.g., if (int x = foo()) { ... }.
   bool DeclaredInCondition : 1;
 
-  /// \brief The previous declaration of this variable.
-  ///
-  /// If the int part is 0, this is a link to the previous declaration.
-  /// If the int part is 1, this is the first declaration and
-  /// PreviousDeclaration points to the latest declaration.
-  llvm::PointerIntPair<VarDecl *, 1> PreviousDeclaration;
-
   // Move to DeclGroup when it is implemented.
   SourceLocation TypeSpecStartLoc;
   friend class StmtIteratorBase;
@@ -262,8 +256,7 @@
           QualType T, StorageClass SC, SourceLocation TSSL = SourceLocation())
     : ValueDecl(DK, DC, L, Id, T), Init(),
       ThreadSpecified(false), HasCXXDirectInit(false),
-      DeclaredInCondition(false), PreviousDeclaration(this, 1), 
-      TypeSpecStartLoc(TSSL) { 
+      DeclaredInCondition(false), TypeSpecStartLoc(TSSL) { 
     SClass = SC; 
   }
 public:
@@ -409,69 +402,8 @@
     DeclaredInCondition = InCondition; 
   }
 
-  /// getPreviousDeclaration - Return the previous declaration of this
-  /// variable or NULL if this is the first declaration.
-  VarDecl *getPreviousDeclaration() {
-    if (PreviousDeclaration.getInt() == 0)
-      return PreviousDeclaration.getPointer();
-    return 0;
-  }
-  const VarDecl *getPreviousDeclaration() const {
-    return const_cast<VarDecl *>(this)->getPreviousDeclaration();
-  }
-
-  void setPreviousDeclaration(VarDecl *PrevDecl);
-
   virtual VarDecl *getCanonicalDecl();
 
-  /// \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 {
@@ -681,7 +613,8 @@
 /// contains all of the information known about the function. Other,
 /// previous declarations of the function are available via the
 /// getPreviousDeclaration() chain. 
-class FunctionDecl : public ValueDecl, public DeclContext {
+class FunctionDecl : public ValueDecl, public DeclContext,
+                     public Redeclarable<FunctionDecl> {
 public:
   enum StorageClass {
     None, Extern, Static, PrivateExtern
@@ -694,20 +627,6 @@
   ParmVarDecl **ParamInfo;
   
   LazyDeclStmtPtr Body;
-  
-  /// PreviousDeclaration - If the int part is 0, this is a link to the previous
-  /// declaration of this same function. If the int part is 1, this is the first
-  /// declaration and PreviousDeclaration points to the latest declaration. For
-  /// example, in the following code, the PreviousDeclaration can be
-  /// traversed several times to see all three declarations of the
-  /// function "f", the last of which is also a definition.
-  ///
-  ///  #1 int f(int x, int y = 1); // <pointer to #3, 1>
-  ///  #2 int f(int x = 0, int y); // <pointer to #1, 0>
-  ///  #3 int f(int x, int y) { return x + y; } // <pointer to #2, 0>
-  ///
-  /// If there is only one declaration, it is <pointer to self, 1>
-  llvm::PointerIntPair<FunctionDecl *, 1> PreviousDeclaration;
 
   // FIXME: This can be packed into the bitfields in Decl.
   // NOTE: VC++ treats enums as signed, avoid using the StorageClass enum
@@ -755,7 +674,7 @@
                SourceLocation TSSL = SourceLocation())
     : ValueDecl(DK, DC, L, N, T), 
       DeclContext(DK),
-      ParamInfo(0), Body(), PreviousDeclaration(this, 1),
+      ParamInfo(0), Body(),
       SClass(S), IsInline(isInline), C99InlineDefinition(false), 
       IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false), 
       HasWrittenPrototype(true), IsDeleted(false), TypeSpecStartLoc(TSSL),
@@ -865,69 +784,10 @@
   /// \brief Determines whether this is a global function.
   bool isGlobal() const;
 
-  /// getPreviousDeclaration - Return the previous declaration of this
-  /// function or NULL if this is the first declaration.
-  FunctionDecl *getPreviousDeclaration() {
-    if (PreviousDeclaration.getInt() == 0)
-      return PreviousDeclaration.getPointer();
-    return 0;
-  }
-  const FunctionDecl *getPreviousDeclaration() const {
-    return const_cast<FunctionDecl *>(this)->getPreviousDeclaration();
-  }
-
   void setPreviousDeclaration(FunctionDecl * PrevDecl);
 
   virtual FunctionDecl *getCanonicalDecl();
 
-  /// \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;
-    }
-  };
-
-  /// \brief Returns iterator for all the redeclarations of the same function
-  /// decl. It will iterate at least once (when this decl is the only one).
-  redecl_iterator redecls_begin() const {
-    return redecl_iterator(const_cast<FunctionDecl*>(this));
-  }
-  redecl_iterator redecls_end() const { return redecl_iterator(); }
-
   unsigned getBuiltinID(ASTContext &Context) const;
 
   unsigned getNumParmVarDeclsFromType() const;

Added: cfe/trunk/include/clang/AST/Redeclarable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Redeclarable.h?rev=76297&view=auto

==============================================================================
--- cfe/trunk/include/clang/AST/Redeclarable.h (added)
+++ cfe/trunk/include/clang/AST/Redeclarable.h Sat Jul 18 03:50:13 2009
@@ -0,0 +1,153 @@
+//===-- Redeclarable.h - Base for Decls that can be redeclared -*- C++ -*-====//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Redeclarable interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_REDECLARABLE_H
+#define LLVM_CLANG_AST_REDECLARABLE_H
+
+#include "llvm/ADT/PointerIntPair.h"
+
+namespace clang {
+
+/// \brief Provides common interface for the Decls that can be redeclared.
+template<typename decl_type>
+class Redeclarable {
+
+protected:
+  struct DeclLink : public llvm::PointerIntPair<decl_type *, 1, bool> {
+    DeclLink(decl_type *D, bool isLatest)
+      : llvm::PointerIntPair<decl_type *, 1, bool>(D, isLatest) { }
+    
+    typedef llvm::PointerIntPair<decl_type *, 1, bool> base_type;
+
+    bool NextIsPrevious() const { return base_type::getInt() == false; }         
+    bool NextIsLatest() const { return base_type::getInt() == true; }
+    decl_type *getNext() const { return base_type::getPointer(); }
+  };
+
+  struct PreviousDeclLink : public DeclLink {
+    PreviousDeclLink(decl_type *D) : DeclLink(D, false) { }
+  };
+
+  struct LatestDeclLink : public DeclLink {
+    LatestDeclLink(decl_type *D) : DeclLink(D, true) { }
+  };
+
+  /// \brief Points to the next redeclaration in the chain.
+  ///
+  /// If NextIsPrevious() is true, this is a link to the previous declaration
+  /// of this same Decl. If NextIsLatest() is true, this is the first
+  /// declaration and Link points to the latest declaration. For example:
+  ///
+  ///  #1 int f(int x, int y = 1); // <pointer to #3, true>
+  ///  #2 int f(int x = 0, int y); // <pointer to #1, false>
+  ///  #3 int f(int x, int y) { return x + y; } // <pointer to #2, false>
+  ///
+  /// If there is only one declaration, it is <pointer to self, true>
+  DeclLink RedeclLink;
+
+public:
+  Redeclarable() : RedeclLink(LatestDeclLink(static_cast<decl_type*>(this))) { }
+
+  /// \brief Return the previous declaration of this declaration or NULL if this
+  /// is the first declaration.
+  decl_type *getPreviousDeclaration() {
+    if (RedeclLink.NextIsPrevious())
+      return RedeclLink.getNext();
+    return 0;
+  }
+  const decl_type *getPreviousDeclaration() const {
+    return const_cast<decl_type *>(
+                 static_cast<const decl_type*>(this))->getPreviousDeclaration();
+  }
+  
+  /// \brief Return the first declaration of this declaration or itself if this
+  /// is the only declaration.
+  decl_type *getFirstDeclaration() {
+    decl_type *D = static_cast<decl_type*>(this);
+    while (D->getPreviousDeclaration())
+      D = D->getPreviousDeclaration();
+    return D;
+  }
+
+  /// \brief Set the previous declaration. If PrevDecl is NULL, set this as the
+  /// first and only declaration.
+  void setPreviousDeclaration(decl_type *PrevDecl) {
+    decl_type *First;
+
+    if (PrevDecl) {
+      // Point to previous.
+      RedeclLink = PreviousDeclLink(PrevDecl);
+      First = PrevDecl->getFirstDeclaration();
+      assert(First->RedeclLink.NextIsLatest() && "Expected first");
+    } else {
+      // Make this first.
+      First = static_cast<decl_type*>(this); 
+    }
+
+    // First one will point to this one as latest.
+    First->RedeclLink = LatestDeclLink(static_cast<decl_type*>(this));
+  }
+
+  /// \brief Iterates through all the redeclarations of the same decl.
+  class redecl_iterator {
+    /// Current - The current declaration.
+    decl_type *Current;
+    decl_type *Starter;
+
+  public:
+    typedef decl_type*                value_type;
+    typedef decl_type*                reference;
+    typedef decl_type*                pointer;
+    typedef std::forward_iterator_tag iterator_category;
+    typedef std::ptrdiff_t            difference_type;
+
+    redecl_iterator() : Current(0) { }
+    explicit redecl_iterator(decl_type *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_type *Next = Current->RedeclLink.getNext();
+      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_type*>(
+                                          static_cast<const decl_type*>(this)));
+  }
+  redecl_iterator redecls_end() const { return redecl_iterator(); }
+};
+
+}
+
+#endif

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

==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Sat Jul 18 03:50:13 2009
@@ -362,29 +362,8 @@
   return 0;
 }
 
-void VarDecl::setPreviousDeclaration(VarDecl *PrevDecl) {
-  if (PrevDecl) {
-    // Point to previous.
-    PreviousDeclaration.setPointer(PrevDecl);
-    PreviousDeclaration.setInt(0);
-    
-    // First one will point to this one as latest.
-    // getCanonicalDecl returns the first one.
-    VarDecl *First = PrevDecl->getCanonicalDecl();
-    assert(First->PreviousDeclaration.getInt() == 1 && "Expected first");
-    First->PreviousDeclaration.setPointer(this);
-  } else {
-    // This is first.
-    PreviousDeclaration.setPointer(this);
-    PreviousDeclaration.setInt(1);
-  }
-}
-
 VarDecl *VarDecl::getCanonicalDecl() {
-  VarDecl *Var = this;
-  while (Var->getPreviousDeclaration())
-    Var = Var->getPreviousDeclaration();
-  return Var;
+  return getFirstDeclaration();
 }
 
 //===----------------------------------------------------------------------===//
@@ -586,22 +565,8 @@
 
 void 
 FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) {
-  if (PrevDecl) {
-    // Point to previous.
-    PreviousDeclaration.setPointer(PrevDecl);
-    PreviousDeclaration.setInt(0);
-    
-    // First one will point to this one as latest.
-    // getCanonicalDecl returns the first one.
-    FunctionDecl *First = PrevDecl->getCanonicalDecl();
-    assert(First->PreviousDeclaration.getInt() == 1 && "Expected first");
-    First->PreviousDeclaration.setPointer(this);
-  } else {
-    // This is first.
-    PreviousDeclaration.setPointer(this);
-    PreviousDeclaration.setInt(1);
-  }
-  
+  Redeclarable<FunctionDecl>::setPreviousDeclaration(PrevDecl);
+
   if (FunctionTemplateDecl *FunTmpl = getDescribedFunctionTemplate()) {
     FunctionTemplateDecl *PrevFunTmpl 
       = PrevDecl? PrevDecl->getDescribedFunctionTemplate() : 0;
@@ -611,10 +576,7 @@
 }
 
 FunctionDecl *FunctionDecl::getCanonicalDecl() {
-  FunctionDecl *FD = this;
-  while (FD->getPreviousDeclaration())
-    FD = FD->getPreviousDeclaration();
-  return FD;
+  return getFirstDeclaration();
 }
 
 /// getOverloadedOperator - Which C++ overloaded operator this





More information about the cfe-commits mailing list