[cfe-commits] r63549 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaInit.cpp lib/Sema/SemaLookup.cpp test/Sema/init.c
Douglas Gregor
dgregor at apple.com
Mon Feb 2 13:35:48 PST 2009
Author: dgregor
Date: Mon Feb 2 15:35:47 2009
New Revision: 63549
URL: http://llvm.org/viewvc/llvm-project?rev=63549&view=rev
Log:
Add iterators to LookupResult, allowing one to iterate over the
non-ambiguous name lookup results without allocating any memory, e.g.,
for sets of overloaded functions.
Modified:
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/lib/Sema/SemaLookup.cpp
cfe/trunk/test/Sema/init.c
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=63549&r1=63548&r2=63549&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Feb 2 15:35:47 2009
@@ -735,6 +735,55 @@
Decl* getAsDecl() const;
BasePaths *getBasePaths() const;
+
+ /// \brief Iterate over the results of name lookup.
+ ///
+ /// The @c iterator class provides iteration over the results of a
+ /// non-ambiguous name lookup.
+ class iterator {
+ /// The LookupResult structure we're iterating through.
+ LookupResult *Result;
+
+ /// The current position of this iterator within the sequence of
+ /// results. This value will have the same representation as the
+ /// @c First field in the LookupResult structure.
+ mutable uintptr_t Current;
+
+ public:
+ typedef Decl * value_type;
+ typedef Decl * reference;
+ typedef Decl * pointer;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+
+ iterator() : Result(0), Current(0) { }
+
+ iterator(LookupResult *Res, uintptr_t Cur) : Result(Res), Current(Cur) { }
+
+ reference operator*() const;
+
+ pointer operator->() const { return **this; }
+
+ iterator &operator++();
+
+ iterator operator++(int) {
+ iterator tmp(*this);
+ ++(*this);
+ return tmp;
+ }
+
+ friend inline bool operator==(iterator const& x, iterator const& y) {
+ return x.Current == y.Current;
+ }
+
+ friend inline bool operator!=(iterator const& x, iterator const& y) {
+ return x.Current != y.Current;
+ }
+ };
+ friend class iterator;
+
+ iterator begin();
+ iterator end();
};
/// Determines whether D is a suitable lookup result according to the
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=63549&r1=63548&r2=63549&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Feb 2 15:35:47 2009
@@ -1666,35 +1666,22 @@
<< D.getCXXScopeSpec().getRange();
InvalidDecl = true;
- PrevDecl = LookupQualifiedName(DC, Name, LookupOrdinaryName);
- if (!PrevDecl) {
- // Nothing to suggest.
- } else if (OverloadedFunctionDecl *Ovl
- = dyn_cast<OverloadedFunctionDecl>(PrevDecl)) {
- for (OverloadedFunctionDecl::function_iterator
- Func = Ovl->function_begin(),
- FuncEnd = Ovl->function_end();
- Func != FuncEnd; ++Func) {
- if (isNearlyMatchingMemberFunction(Context, *Func, NewFD))
- Diag((*Func)->getLocation(), diag::note_member_def_close_match);
-
- }
- } else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(PrevDecl)) {
- // Suggest this no matter how mismatched it is; it's the only
- // thing we have.
- unsigned diag;
- if (isNearlyMatchingMemberFunction(Context, Method, NewFD))
- diag = diag::note_member_def_close_match;
- else if (Method->getBody())
- diag = diag::note_previous_definition;
- else
- diag = diag::note_previous_declaration;
- Diag(Method->getLocation(), diag);
+ LookupResult Prev = LookupQualifiedName(DC, Name, LookupOrdinaryName,
+ true);
+ assert(!Prev.isAmbiguous() &&
+ "Cannot have an ambiguity in previous-declaration lookup");
+ for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end();
+ Func != FuncEnd; ++Func) {
+ if (isa<CXXMethodDecl>(*Func) &&
+ isNearlyMatchingMemberFunction(Context, cast<FunctionDecl>(*Func),
+ NewFD))
+ Diag((*Func)->getLocation(), diag::note_member_def_close_match);
}
-
+
PrevDecl = 0;
}
}
+
// Handle attributes. We need to have merged decls when handling attributes
// (for example to check for conflicts, etc).
ProcessDeclAttributes(NewFD, D);
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=63549&r1=63548&r2=63549&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Mon Feb 2 15:35:47 2009
@@ -1342,6 +1342,8 @@
// [...] A program that calls for default-initialization or
// value-initialization of an entity of reference type is
// ill-formed. [...]
+ // FIXME: Once we have code that goes through this path, add an
+ // actual diagnostic :)
}
return false;
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=63549&r1=63548&r2=63549&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Mon Feb 2 15:35:47 2009
@@ -181,6 +181,66 @@
return reinterpret_cast<BasePaths *>(First);
}
+Sema::LookupResult::iterator::reference
+Sema::LookupResult::iterator::operator*() const {
+ switch (Result->StoredKind) {
+ case SingleDecl:
+ return reinterpret_cast<Decl*>(Current);
+
+ case OverloadedDeclFromIdResolver:
+ return *IdentifierResolver::iterator::getFromOpaqueValue(Current);
+
+ case OverloadedDeclFromDeclContext:
+ return *reinterpret_cast<DeclContext::lookup_iterator>(Current);
+
+ case AmbiguousLookup:
+ assert(false && "Cannot look into ambiguous lookup results");
+ break;
+ }
+
+ return 0;
+}
+
+Sema::LookupResult::iterator& Sema::LookupResult::iterator::operator++() {
+ switch (Result->StoredKind) {
+ case SingleDecl:
+ Current = reinterpret_cast<uintptr_t>((Decl*)0);
+ break;
+
+ case OverloadedDeclFromIdResolver: {
+ IdentifierResolver::iterator I
+ = IdentifierResolver::iterator::getFromOpaqueValue(Current);
+ ++I;
+ Current = I.getAsOpaqueValue();
+ break;
+ }
+
+ case OverloadedDeclFromDeclContext: {
+ DeclContext::lookup_iterator I
+ = reinterpret_cast<DeclContext::lookup_iterator>(Current);
+ ++I;
+ Current = reinterpret_cast<uintptr_t>(I);
+ break;
+ }
+
+ case AmbiguousLookup:
+ assert(false && "Cannot look into ambiguous lookup results");
+ break;
+ }
+
+ return *this;
+}
+
+Sema::LookupResult::iterator Sema::LookupResult::begin() {
+ assert(StoredKind != AmbiguousLookup && "Lookup into an ambiguous result");
+ return iterator(this, First);
+}
+
+Sema::LookupResult::iterator Sema::LookupResult::end() {
+ assert(StoredKind != AmbiguousLookup && "Lookup into an ambiguous result");
+ return iterator(this, Last);
+}
+
// Retrieve the set of identifier namespaces that correspond to a
// specific kind of name lookup.
inline unsigned
Modified: cfe/trunk/test/Sema/init.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/init.c?rev=63549&r1=63548&r2=63549&view=diff
==============================================================================
--- cfe/trunk/test/Sema/init.c (original)
+++ cfe/trunk/test/Sema/init.c Mon Feb 2 15:35:47 2009
@@ -96,3 +96,13 @@
int a;
int z[2];
} y = { .z = {} };
+
+int bbb[10];
+
+struct foo2 {
+ unsigned a;
+};
+
+struct foo2 bar2[] = {
+ { (int)bbb }
+};
More information about the cfe-commits
mailing list