[llvm-branch-commits] [cfe-branch] r119247 - in /cfe/branches/Apple/whitney: include/clang/AST/DeclCXX.h lib/AST/DeclCXX.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriterDecl.cpp test/Index/load-namespaces.cpp tools/libclang/CIndex.cpp
Daniel Dunbar
daniel at zuster.org
Mon Nov 15 13:45:55 PST 2010
Author: ddunbar
Date: Mon Nov 15 15:45:55 2010
New Revision: 119247
URL: http://llvm.org/viewvc/llvm-project?rev=119247&view=rev
Log:
Merge r118674:
--
Author: Argyrios Kyrtzidis <akyrtzi at gmail.com>
Date: Wed Nov 10 05:40:41 2010 +0000
Replace UsingDecl's SmallPtrSet of UsingShadowDecls with a linked list to avoid leaking memory.
Fixes rdar://8649963.
Modified:
cfe/branches/Apple/whitney/include/clang/AST/DeclCXX.h
cfe/branches/Apple/whitney/lib/AST/DeclCXX.cpp
cfe/branches/Apple/whitney/lib/Serialization/ASTReaderDecl.cpp
cfe/branches/Apple/whitney/lib/Serialization/ASTWriterDecl.cpp
cfe/branches/Apple/whitney/test/Index/load-namespaces.cpp
cfe/branches/Apple/whitney/tools/libclang/CIndex.cpp
Modified: cfe/branches/Apple/whitney/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/include/clang/AST/DeclCXX.h?rev=119247&r1=119246&r2=119247&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/include/clang/AST/DeclCXX.h (original)
+++ cfe/branches/Apple/whitney/include/clang/AST/DeclCXX.h Mon Nov 15 15:45:55 2010
@@ -1881,13 +1881,16 @@
/// The referenced declaration.
NamedDecl *Underlying;
- /// The using declaration which introduced this decl.
- UsingDecl *Using;
+ /// \brief The using declaration which introduced this decl or the next using
+ /// shadow declaration contained in the aforementioned using declaration.
+ NamedDecl *UsingOrNextShadow;
+ friend class UsingDecl;
UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using,
NamedDecl *Target)
: NamedDecl(UsingShadow, DC, Loc, DeclarationName()),
- Underlying(Target), Using(Using) {
+ Underlying(Target),
+ UsingOrNextShadow(reinterpret_cast<NamedDecl *>(Using)) {
if (Target) {
setDeclName(Target->getDeclName());
IdentifierNamespace = Target->getIdentifierNamespace();
@@ -1915,15 +1918,20 @@
}
/// \brief Gets the using declaration to which this declaration is tied.
- UsingDecl *getUsingDecl() const { return Using; }
+ UsingDecl *getUsingDecl() const;
- /// \brief Sets the using declaration that introduces this target
- /// declaration.
- void setUsingDecl(UsingDecl* UD) { Using = UD; }
+ /// \brief The next using shadow declaration contained in the shadow decl
+ /// chain of the using declaration which introduced this decl.
+ UsingShadowDecl *getNextUsingShadowDecl() const {
+ return dyn_cast_or_null<UsingShadowDecl>(UsingOrNextShadow);
+ }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UsingShadowDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Decl::UsingShadow; }
+
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
};
/// UsingDecl - Represents a C++ using-declaration. For example:
@@ -1943,10 +1951,9 @@
/// declaration name embedded in the ValueDecl base class.
DeclarationNameLoc DNLoc;
- /// \brief The collection of shadow declarations associated with
- /// this using declaration. This set can change as a class is
- /// processed.
- llvm::SmallPtrSet<UsingShadowDecl*, 8> Shadows;
+ /// \brief The first shadow declaration of the shadow decl chain associated
+ /// with this using declaration.
+ UsingShadowDecl *FirstUsingShadow;
// \brief Has 'typename' keyword.
bool IsTypeName;
@@ -1956,7 +1963,7 @@
const DeclarationNameInfo &NameInfo, bool IsTypeNameArg)
: NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()),
NestedNameRange(NNR), UsingLocation(UL), TargetNestedName(TargetNNS),
- DNLoc(NameInfo.getInfo()), IsTypeName(IsTypeNameArg) {
+ DNLoc(NameInfo.getInfo()), FirstUsingShadow(0),IsTypeName(IsTypeNameArg) {
}
public:
@@ -1994,29 +2001,58 @@
/// \brief Sets whether the using declaration has 'typename'.
void setTypeName(bool TN) { IsTypeName = TN; }
- typedef llvm::SmallPtrSet<UsingShadowDecl*,8>::const_iterator shadow_iterator;
- shadow_iterator shadow_begin() const { return Shadows.begin(); }
- shadow_iterator shadow_end() const { return Shadows.end(); }
-
- void addShadowDecl(UsingShadowDecl *S) {
- assert(S->getUsingDecl() == this);
- if (!Shadows.insert(S)) {
- assert(false && "declaration already in set");
+ /// \brief Iterates through the using shadow declarations assosiated with
+ /// this using declaration.
+ class shadow_iterator {
+ /// \brief The current using shadow declaration.
+ UsingShadowDecl *Current;
+
+ public:
+ typedef UsingShadowDecl* value_type;
+ typedef UsingShadowDecl* reference;
+ typedef UsingShadowDecl* pointer;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef std::ptrdiff_t difference_type;
+
+ shadow_iterator() : Current(0) { }
+ explicit shadow_iterator(UsingShadowDecl *C) : Current(C) { }
+
+ reference operator*() const { return Current; }
+ pointer operator->() const { return Current; }
+
+ shadow_iterator& operator++() {
+ Current = Current->getNextUsingShadowDecl();
+ return *this;
}
- }
- void removeShadowDecl(UsingShadowDecl *S) {
- assert(S->getUsingDecl() == this);
- if (!Shadows.erase(S)) {
- assert(false && "declaration not in set");
+
+ shadow_iterator operator++(int) {
+ shadow_iterator tmp(*this);
+ ++(*this);
+ return tmp;
}
+
+ friend bool operator==(shadow_iterator x, shadow_iterator y) {
+ return x.Current == y.Current;
+ }
+ friend bool operator!=(shadow_iterator x, shadow_iterator y) {
+ return x.Current != y.Current;
+ }
+ };
+
+ shadow_iterator shadow_begin() const {
+ return shadow_iterator(FirstUsingShadow);
}
+ shadow_iterator shadow_end() const { return shadow_iterator(); }
/// \brief Return the number of shadowed declarations associated with this
/// using declaration.
- unsigned getNumShadowDecls() const {
- return Shadows.size();
+ unsigned shadow_size() const {
+ return std::distance(shadow_begin(), shadow_end());
}
+ void addShadowDecl(UsingShadowDecl *S);
+ void removeShadowDecl(UsingShadowDecl *S);
+
static UsingDecl *Create(ASTContext &C, DeclContext *DC,
SourceRange NNR, SourceLocation UsingL,
NestedNameSpecifier* TargetNNS,
Modified: cfe/branches/Apple/whitney/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/lib/AST/DeclCXX.cpp?rev=119247&r1=119246&r2=119247&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/lib/AST/DeclCXX.cpp (original)
+++ cfe/branches/Apple/whitney/lib/AST/DeclCXX.cpp Mon Nov 15 15:45:55 2010
@@ -1276,6 +1276,44 @@
Qualifier, IdentLoc, Namespace);
}
+UsingDecl *UsingShadowDecl::getUsingDecl() const {
+ const UsingShadowDecl *Shadow = this;
+ while (const UsingShadowDecl *NextShadow =
+ dyn_cast<UsingShadowDecl>(Shadow->UsingOrNextShadow))
+ Shadow = NextShadow;
+ return cast<UsingDecl>(Shadow->UsingOrNextShadow);
+}
+
+void UsingDecl::addShadowDecl(UsingShadowDecl *S) {
+ assert(std::find(shadow_begin(), shadow_end(), S) == shadow_end() &&
+ "declaration already in set");
+ assert(S->getUsingDecl() == this);
+
+ if (FirstUsingShadow)
+ S->UsingOrNextShadow = FirstUsingShadow;
+ FirstUsingShadow = S;
+}
+
+void UsingDecl::removeShadowDecl(UsingShadowDecl *S) {
+ assert(std::find(shadow_begin(), shadow_end(), S) != shadow_end() &&
+ "declaration not in set");
+ assert(S->getUsingDecl() == this);
+
+ // Remove S from the shadow decl chain. This is O(n) but hopefully rare.
+
+ if (FirstUsingShadow == S) {
+ FirstUsingShadow = dyn_cast<UsingShadowDecl>(S->UsingOrNextShadow);
+ S->UsingOrNextShadow = this;
+ return;
+ }
+
+ UsingShadowDecl *Prev = FirstUsingShadow;
+ while (Prev->UsingOrNextShadow != S)
+ Prev = cast<UsingShadowDecl>(Prev->UsingOrNextShadow);
+ Prev->UsingOrNextShadow = S->UsingOrNextShadow;
+ S->UsingOrNextShadow = this;
+}
+
UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC,
SourceRange NNR, SourceLocation UL,
NestedNameSpecifier* TargetNNS,
Modified: cfe/branches/Apple/whitney/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/lib/Serialization/ASTReaderDecl.cpp?rev=119247&r1=119246&r2=119247&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/branches/Apple/whitney/lib/Serialization/ASTReaderDecl.cpp Mon Nov 15 15:45:55 2010
@@ -717,16 +717,7 @@
D->setNestedNameRange(ReadSourceRange(Record, Idx));
D->setTargetNestedNameDecl(Reader.ReadNestedNameSpecifier(Record, Idx));
ReadDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record, Idx);
-
- // FIXME: It would probably be more efficient to read these into a vector
- // and then re-cosntruct the shadow decl set over that vector since it
- // would avoid existence checks.
- unsigned NumShadows = Record[Idx++];
- for(unsigned I = 0; I != NumShadows; ++I) {
- // Avoid invariant checking of UsingDecl::addShadowDecl, the decl may still
- // be initializing.
- D->Shadows.insert(cast<UsingShadowDecl>(Reader.GetDecl(Record[Idx++])));
- }
+ D->FirstUsingShadow = cast_or_null<UsingShadowDecl>(Reader.GetDecl(Record[Idx++]));
D->setTypeName(Record[Idx++]);
NamedDecl *Pattern = cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++]));
if (Pattern)
@@ -736,7 +727,7 @@
void ASTDeclReader::VisitUsingShadowDecl(UsingShadowDecl *D) {
VisitNamedDecl(D);
D->setTargetDecl(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));
- D->setUsingDecl(cast<UsingDecl>(Reader.GetDecl(Record[Idx++])));
+ D->UsingOrNextShadow = cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++]));
UsingShadowDecl *Pattern
= cast_or_null<UsingShadowDecl>(Reader.GetDecl(Record[Idx++]));
if (Pattern)
Modified: cfe/branches/Apple/whitney/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/lib/Serialization/ASTWriterDecl.cpp?rev=119247&r1=119246&r2=119247&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/branches/Apple/whitney/lib/Serialization/ASTWriterDecl.cpp Mon Nov 15 15:45:55 2010
@@ -673,10 +673,7 @@
Writer.AddSourceLocation(D->getUsingLocation(), Record);
Writer.AddNestedNameSpecifier(D->getTargetNestedNameDecl(), Record);
Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record);
- Record.push_back(D->getNumShadowDecls());
- for (UsingDecl::shadow_iterator P = D->shadow_begin(),
- PEnd = D->shadow_end(); P != PEnd; ++P)
- Writer.AddDeclRef(*P, Record);
+ Writer.AddDeclRef(D->FirstUsingShadow, Record);
Record.push_back(D->isTypeName());
Writer.AddDeclRef(Context.getInstantiatedFromUsingDecl(D), Record);
Code = serialization::DECL_USING;
@@ -685,7 +682,7 @@
void ASTDeclWriter::VisitUsingShadowDecl(UsingShadowDecl *D) {
VisitNamedDecl(D);
Writer.AddDeclRef(D->getTargetDecl(), Record);
- Writer.AddDeclRef(D->getUsingDecl(), Record);
+ Writer.AddDeclRef(D->UsingOrNextShadow, Record);
Writer.AddDeclRef(Context.getInstantiatedFromUsingShadowDecl(D), Record);
Code = serialization::DECL_USING_SHADOW;
}
Modified: cfe/branches/Apple/whitney/test/Index/load-namespaces.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/test/Index/load-namespaces.cpp?rev=119247&r1=119246&r2=119247&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/test/Index/load-namespaces.cpp (original)
+++ cfe/branches/Apple/whitney/test/Index/load-namespaces.cpp Mon Nov 15 15:45:55 2010
@@ -41,7 +41,7 @@
// CHECK: load-namespaces.cpp:18:11: Namespace=std:18:11 (Definition) Extent=[18:11 - 20:2]
// CHECK: load-namespaces.cpp:19:7: FunctionDecl=g:19:7 Extent=[19:7 - 19:13]
// CHECK: load-namespaces.cpp:19:12: ParmDecl=:19:12 (Definition) Extent=[19:9 - 19:13]
-// CHECK: load-namespaces.cpp:22:12: UsingDeclaration=g[10:8, 19:7] Extent=[22:1 - 22:13]
+// CHECK: load-namespaces.cpp:22:12: UsingDeclaration=g[19:7, 10:8] Extent=[22:1 - 22:13]
// CHECK: load-namespaces.cpp:22:7: NamespaceRef=std:18:11 Extent=[22:7 - 22:10]
// CHECK: load-namespaces.cpp:24:11: FunctionDecl=g:24:11 (Definition) Extent=[24:11 - 25:2]
// CHECK: load-namespaces.cpp:24:6: NamespaceRef=std:18:11 Extent=[24:6 - 24:9]
Modified: cfe/branches/Apple/whitney/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/tools/libclang/CIndex.cpp?rev=119247&r1=119246&r2=119247&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/tools/libclang/CIndex.cpp (original)
+++ cfe/branches/Apple/whitney/tools/libclang/CIndex.cpp Mon Nov 15 15:45:55 2010
@@ -3645,7 +3645,7 @@
Decl *D = Storage.get<Decl*>();
if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
- return Using->getNumShadowDecls();
+ return Using->shadow_size();
if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
return Classes->size();
if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
More information about the llvm-branch-commits
mailing list