forked from OSchip/llvm-project
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. llvm-svn: 63549
This commit is contained in:
parent
dd5dbca59c
commit
0e8fc3c773
|
@ -735,6 +735,55 @@ public:
|
|||
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
|
||||
|
|
|
@ -1666,35 +1666,22 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
|||
<< 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);
|
||||
|
|
|
@ -1342,6 +1342,8 @@ bool Sema::CheckValueInitialization(QualType Type, SourceLocation Loc) {
|
|||
// [...] 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;
|
||||
|
|
|
@ -181,6 +181,66 @@ BasePaths *Sema::LookupResult::getBasePaths() const {
|
|||
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
|
||||
|
|
|
@ -96,3 +96,13 @@ struct {
|
|||
int a;
|
||||
int z[2];
|
||||
} y = { .z = {} };
|
||||
|
||||
int bbb[10];
|
||||
|
||||
struct foo2 {
|
||||
unsigned a;
|
||||
};
|
||||
|
||||
struct foo2 bar2[] = {
|
||||
{ (int)bbb }
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue