[cfe-commits] r62001 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/AST/DeclBase.h include/clang/Basic/DiagnosticKinds.def lib/AST/DeclBase.cpp lib/AST/DeclSerialization.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclObjC.cpp test/Sema/typedef-redef.c
Douglas Gregor
dgregor at apple.com
Fri Jan 9 11:42:16 PST 2009
Author: dgregor
Date: Fri Jan 9 13:42:16 2009
New Revision: 62001
URL: http://llvm.org/viewvc/llvm-project?rev=62001&view=rev
Log:
Replace DeclContext's vector of ScopedDecl pointers with a linked list
of ScopedDecls (using the new ScopedDecl::NextDeclInScope
pointer). Performance-wise:
- It's a net win in memory utilization, since DeclContext is now one
pointer smaller than it used to be (std::vectors are typically 3
pointers; we now use 2 pointers) and
- Parsing Cocoa.h with -fsyntax-only (with a Release-Asserts Clang)
is about 1.9% faster than before, most likely because we no longer
have the memory allocations and copying associated with the
std::vector.
I'll re-enable serialization of DeclContexts once I've sorted out the
NextDeclarator/NextDeclInScope question.
Modified:
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/include/clang/AST/DeclBase.h
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/trunk/lib/AST/DeclBase.cpp
cfe/trunk/lib/AST/DeclSerialization.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclObjC.cpp
cfe/trunk/test/Sema/typedef-redef.c
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=62001&r1=62000&r2=62001&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Fri Jan 9 13:42:16 2009
@@ -115,6 +115,17 @@
/// such as "int X, Y, *Z;" this indicates Decl for the next declarator.
ScopedDecl *NextDeclarator;
+ /// NextDeclInScope - The next declaration within the same lexical
+ /// DeclContext. These pointers form the linked list that is
+ /// traversed via DeclContext's decls_begin()/decls_end().
+ /// FIXME: If NextDeclarator is non-NULL, will it always be the same
+ /// as NextDeclInScope? If so, we can use a
+ /// PointerIntPair<ScopedDecl*, 1> to make ScopedDecl smaller.
+ ScopedDecl *NextDeclInScope;
+
+ friend class DeclContext;
+ friend class DeclContext::decl_iterator;
+
/// DeclCtx - Holds either a DeclContext* or a MultipleDC*.
/// For declarations that don't contain C++ scope specifiers, it contains
/// the DeclContext where the ScopedDecl was declared.
@@ -144,7 +155,7 @@
protected:
ScopedDecl(Kind DK, DeclContext *DC, SourceLocation L,
DeclarationName N, ScopedDecl *PrevDecl = 0)
- : NamedDecl(DK, L, N), NextDeclarator(PrevDecl),
+ : NamedDecl(DK, L, N), NextDeclarator(PrevDecl), NextDeclInScope(0),
DeclCtx(reinterpret_cast<uintptr_t>(DC)) {}
virtual ~ScopedDecl();
@@ -1215,6 +1226,11 @@
friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
};
+inline DeclContext::decl_iterator& DeclContext::decl_iterator::operator++() {
+ Current = Current->NextDeclInScope;
+ return *this;
+}
+
} // end namespace clang
#endif
Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=62001&r1=62000&r2=62001&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Fri Jan 9 13:42:16 2009
@@ -18,7 +18,6 @@
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/PointerIntPair.h"
-#include <vector>
namespace clang {
class DeclContext;
@@ -307,9 +306,15 @@
/// FIXME: We need a better data structure for this.
llvm::PointerIntPair<void*, 3> LookupPtr;
- /// Decls - Contains all of the declarations that are defined inside
- /// this declaration context.
- std::vector<ScopedDecl*> Decls;
+ /// FirstDecl - The first declaration stored within this declaration
+ /// context.
+ ScopedDecl *FirstDecl;
+
+ /// LastDecl - The last declaration stored within this declaration
+ /// context. FIXME: We could probably cache this value somewhere
+ /// outside of the DeclContext, to reduce the size of DeclContext by
+ /// another pointer.
+ ScopedDecl *LastDecl;
// Used in the CastTo template to get the DeclKind
// from a Decl or a DeclContext. DeclContext doesn't have a getKind() method
@@ -363,8 +368,8 @@
bool isLookupMap() const { return LookupPtr.getInt() == LookupIsMap; }
protected:
- DeclContext(Decl::Kind K) : DeclKind(K), LookupPtr() {
- }
+ DeclContext(Decl::Kind K)
+ : DeclKind(K), LookupPtr(), FirstDecl(0), LastDecl(0) { }
void DestroyDecls(ASTContext &C);
@@ -483,12 +488,43 @@
/// decl_iterator - Iterates through the declarations stored
/// within this context.
- typedef std::vector<ScopedDecl*>::const_iterator decl_iterator;
+ class decl_iterator {
+ /// Current - The current declaration.
+ ScopedDecl *Current;
+
+ public:
+ typedef ScopedDecl* value_type;
+ typedef ScopedDecl* reference;
+ typedef ScopedDecl* pointer;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef std::ptrdiff_t difference_type;
+
+ decl_iterator() : Current(0) { }
+ explicit decl_iterator(ScopedDecl *C) : Current(C) { }
+
+ reference operator*() const { return Current; }
+ pointer operator->() const { return Current; }
+
+ decl_iterator& operator++();
+
+ decl_iterator operator++(int) {
+ decl_iterator tmp(*this);
+ ++(*this);
+ return tmp;
+ }
+
+ friend bool operator==(decl_iterator x, decl_iterator y) {
+ return x.Current == y.Current;
+ }
+ friend bool operator!=(decl_iterator x, decl_iterator y) {
+ return x.Current != y.Current;
+ }
+ };
/// decls_begin/decls_end - Iterate over the declarations stored in
/// this context.
- decl_iterator decls_begin() const { return Decls.begin(); }
- decl_iterator decls_end() const { return Decls.end(); }
+ decl_iterator decls_begin() const { return decl_iterator(FirstDecl); }
+ decl_iterator decls_end() const { return decl_iterator(); }
/// specific_decl_iterator - Iterates over a subrange of
/// declarations stored in a DeclContext, providing only those that
@@ -548,8 +584,8 @@
SkipToNextDecl();
}
- reference operator*() { return cast<SpecificDecl>(*Current); }
- pointer operator->() { return cast<SpecificDecl>(*Current); }
+ reference operator*() const { return cast<SpecificDecl>(*Current); }
+ pointer operator->() const { return cast<SpecificDecl>(*Current); }
specific_decl_iterator& operator++() {
++Current;
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=62001&r1=62000&r2=62001&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Fri Jan 9 13:42:16 2009
@@ -1003,6 +1003,8 @@
"static declaration of %0 follows non-static declaration")
DIAG(err_non_static_static, ERROR,
"non-static declaration of %0 follows static declaration")
+DIAG(err_redefinition_different_type, ERROR,
+ "redefinition of %0 with a different type")
DIAG(err_redefinition_different_kind, ERROR,
"redefinition of %0 as different kind of symbol")
DIAG(err_redefinition_different_typedef, ERROR,
Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=62001&r1=62000&r2=62001&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Fri Jan 9 13:42:16 2009
@@ -401,7 +401,8 @@
}
void DeclContext::DestroyDecls(ASTContext &C) {
- for (decl_iterator D = Decls.begin(); D != Decls.end(); ++D) {
+ for (decl_iterator D = decls_begin(); D != decls_end(); ++D) {
+ // FIXME: assert that this condition holds.
if ((*D)->getLexicalDeclContext() == this)
(*D)->Destroy(C);
}
@@ -515,7 +516,15 @@
void DeclContext::addDecl(ASTContext &Context, ScopedDecl *D, bool AllowLookup) {
assert(D->getLexicalDeclContext() == this && "Decl inserted into wrong lexical context");
- Decls.push_back(D);
+ assert(!D->NextDeclInScope && D != LastDecl &&
+ "Decl already inserted into a DeclContext");
+
+ if (FirstDecl) {
+ LastDecl->NextDeclInScope = D;
+ LastDecl = D;
+ } else {
+ FirstDecl = LastDecl = D;
+ }
if (AllowLookup)
D->getDeclContext()->insert(Context, D);
}
Modified: cfe/trunk/lib/AST/DeclSerialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclSerialization.cpp?rev=62001&r1=62000&r2=62001&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclSerialization.cpp (original)
+++ cfe/trunk/lib/AST/DeclSerialization.cpp Fri Jan 9 13:42:16 2009
@@ -124,6 +124,9 @@
//===----------------------------------------------------------------------===//
void DeclContext::EmitOutRec(Serializer& S) const {
+#if 0
+ // FIXME: it would be far easier to just serialize FirstDecl and let
+ // ScopedDecl do the work of serializing NextDeclInScope.
S.EmitInt(Decls.size());
for (decl_iterator D = decls_begin(); D != decls_end(); ++D) {
bool Owned = ((*D)->getLexicalDeclContext() == this &&
@@ -135,9 +138,12 @@
else
S.EmitPtr(*D);
}
+#endif
}
void DeclContext::ReadOutRec(Deserializer& D, ASTContext& C) {
+#if 0
+ // FIXME: See comment in DeclContext::EmitOutRec
unsigned NumDecls = D.ReadInt();
Decls.resize(NumDecls);
for (unsigned Idx = 0; Idx < NumDecls; ++Idx) {
@@ -147,6 +153,7 @@
else
D.ReadPtr<ScopedDecl>(Decls[Idx]);
}
+#endif
}
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=62001&r1=62000&r2=62001&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Jan 9 13:42:16 2009
@@ -515,7 +515,7 @@
Diag(New->getLocation(), diag::err_redefinition_different_typedef)
<< New->getUnderlyingType() << Old->getUnderlyingType();
Diag(Old->getLocation(), diag::note_previous_definition);
- return Old;
+ return New;
}
if (getLangOptions().Microsoft) return New;
@@ -768,7 +768,8 @@
QualType OldCType = Context.getCanonicalType(Old->getType());
QualType NewCType = Context.getCanonicalType(New->getType());
if (OldCType != NewCType && !Context.typesAreCompatible(OldCType, NewCType)) {
- Diag(New->getLocation(), diag::err_redefinition) << New->getDeclName();
+ Diag(New->getLocation(), diag::err_redefinition_different_type)
+ << New->getDeclName();
Diag(Old->getLocation(), diag::note_previous_definition);
return New;
}
Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=62001&r1=62000&r2=62001&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Fri Jan 9 13:42:16 2009
@@ -1078,6 +1078,7 @@
ObjCPropertyDecl::Optional) ?
ObjCMethodDecl::Optional :
ObjCMethodDecl::Required);
+ CD->addDecl(Context, GetterMethod);
} else
// A user declared getter will be synthesize when @synthesize of
// the property with the same name is seen in the @implementation
@@ -1108,6 +1109,7 @@
VarDecl::None,
0, 0);
SetterMethod->setMethodParams(&Argument, 1);
+ CD->addDecl(Context, SetterMethod);
} else
// A user declared setter will be synthesize when @synthesize of
// the property with the same name is seen in the @implementation
@@ -1126,14 +1128,10 @@
// double bar = [foo bar];
// }
//
- if (GetterMethod) {
- CD->addDecl(Context, GetterMethod);
+ if (GetterMethod)
AddInstanceMethodToGlobalPool(GetterMethod);
- }
- if (SetterMethod) {
- CD->addDecl(Context, SetterMethod);
+ if (SetterMethod)
AddInstanceMethodToGlobalPool(SetterMethod);
- }
}
// Note: For class/category implemenations, allMethods/allProperties is
Modified: cfe/trunk/test/Sema/typedef-redef.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/typedef-redef.c?rev=62001&r1=62000&r2=62001&view=diff
==============================================================================
--- cfe/trunk/test/Sema/typedef-redef.c (original)
+++ cfe/trunk/test/Sema/typedef-redef.c Fri Jan 9 13:42:16 2009
@@ -7,7 +7,7 @@
typedef const int x; // expected-note {{previous definition is here}}
-extern x a;
+extern x a; // expected-note {{previous definition is here}}
typedef int x; // expected-error {{typedef redefinition with different types}}
-extern x a;
+extern x a; // expected-error{{redefinition of 'a' with a different type}}
More information about the cfe-commits
mailing list