[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