Eliminated LookupCriteria, whose creation was causing a bottleneck for
LookupName et al. Instead, use an enum and a bool to describe its
contents.
Optimized the C/Objective-C path through LookupName, eliminating any
unnecessarily C++isms. Simplify IdentifierResolver::iterator, removing
some code and arguments that are no longer used.
Eliminated LookupDeclInScope/LookupDeclInContext, moving all callers
over to LookupName, LookupQualifiedName, or LookupParsedName, as
appropriate.
All together, I'm seeing a 0.2% speedup on Cocoa.h with PTH and
-disable-free. Plus, we're down to three name-lookup routines.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63354 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/IdentifierResolver.cpp b/lib/Sema/IdentifierResolver.cpp
index 4e9d085..781d89a 100644
--- a/lib/Sema/IdentifierResolver.cpp
+++ b/lib/Sema/IdentifierResolver.cpp
@@ -225,14 +225,9 @@
return toIdDeclInfo(Ptr)->RemoveDecl(D);
}
-/// begin - Returns an iterator for decls with name 'Name', starting at
-/// declaration context 'Ctx'. If 'LookInParentCtx' is true, it will walk the
-/// decls of parent declaration contexts too.
+/// begin - Returns an iterator for decls with name 'Name'.
IdentifierResolver::iterator
-IdentifierResolver::begin(DeclarationName Name, const DeclContext *Ctx,
- bool LookInParentCtx) {
- assert(Ctx && "null param passed");
-
+IdentifierResolver::begin(DeclarationName Name) {
void *Ptr = Name.getFETokenInfo<void>();
if (!Ptr) return end();
@@ -245,26 +240,11 @@
IdDeclInfo::DeclsTy::iterator I = IDI->decls_end();
if (I != IDI->decls_begin())
- return iterator(I-1, LookInParentCtx);
+ return iterator(I-1);
else // No decls found.
return end();
}
-/// PreIncIter - Do a preincrement when 'Ptr' is a BaseIter.
-void IdentifierResolver::iterator::PreIncIter() {
- NamedDecl *D = **this;
- void *InfoPtr = D->getDeclName().getFETokenInfo<void>();
- assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");
- IdDeclInfo *Info = toIdDeclInfo(InfoPtr);
-
- BaseIter I = getIterator();
- if (I != Info->decls_begin())
- *this = iterator(I-1, LookInParentCtx());
- else // No more decls.
- *this = end();
-}
-
-
//===----------------------------------------------------------------------===//
// IdDeclInfoMap Implementation
//===----------------------------------------------------------------------===//
diff --git a/lib/Sema/IdentifierResolver.h b/lib/Sema/IdentifierResolver.h
index a44323e..50b894a 100644
--- a/lib/Sema/IdentifierResolver.h
+++ b/lib/Sema/IdentifierResolver.h
@@ -136,19 +136,12 @@
}
/// A IdDeclInfo::DeclsTy::iterator that walks or not the parent declaration
/// contexts depending on 'LookInParentCtx'.
- iterator(BaseIter I, bool LookInParentCtx) {
+ iterator(BaseIter I) {
Ptr = reinterpret_cast<uintptr_t>(I) | 0x1;
- assert((Ptr & 0x2) == 0 && "Invalid Ptr!");
- if (LookInParentCtx) Ptr |= 0x2;
}
bool isIterator() const { return (Ptr & 0x1); }
- bool LookInParentCtx() const {
- assert(isIterator() && "Ptr not an iterator!");
- return (Ptr & 0x2) != 0;
- }
-
BaseIter getIterator() const {
assert(isIterator() && "Ptr not an iterator!");
return reinterpret_cast<BaseIter>(Ptr & ~0x3);
@@ -176,29 +169,32 @@
iterator& operator++() {
if (!isIterator()) // common case.
Ptr = 0;
- else
- PreIncIter();
+ else {
+ NamedDecl *D = **this;
+ void *InfoPtr = D->getDeclName().getFETokenInfo<void>();
+ assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");
+ IdDeclInfo *Info = toIdDeclInfo(InfoPtr);
+
+ BaseIter I = getIterator();
+ if (I != Info->decls_begin())
+ *this = iterator(I-1);
+ else // No more decls.
+ *this = iterator();
+ }
return *this;
}
uintptr_t getAsOpaqueValue() const { return Ptr; }
static iterator getFromOpaqueValue(uintptr_t P) {
- iterator Result(0);
+ iterator Result;
Result.Ptr = P;
return Result;
}
-
- private:
- void PreIncIter();
};
- /// begin - Returns an iterator for decls with the name 'Name', starting at
- /// declaration context 'Ctx'. If 'LookInParentCtx' is true, it will walk the
- /// decls of parent declaration contexts too.
- /// Default for 'LookInParentCtx is true.
- static iterator begin(DeclarationName Name, const DeclContext *Ctx,
- bool LookInParentCtx = true);
+ /// begin - Returns an iterator for decls with the name 'Name'.
+ static iterator begin(DeclarationName Name);
/// end - Returns an iterator that has 'finished'.
static iterator end() {
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index fe2b9de..6e3a552 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -559,7 +559,7 @@
/// for capturing language semantics (certain lookups will ignore
/// certain names, for example) and for performance, since name
/// lookup is often a bottleneck in the compilation of C++. Name
- /// lookup criteria is specified via the LookupCriteria class.
+ /// lookup criteria is specified via the LookupCriteria enumeration.
///
/// The results of name lookup can vary based on the kind of name
/// lookup performed, the current language, and the translation
@@ -571,65 +571,26 @@
/// the ability to distinguish among them.
//@{
- /// @brief Describes the criteria by which name lookup will
- /// determine whether a given name will be found.
- ///
- /// The LookupCriteria class captures the information required to
- /// direct name lookup to find the appropriate kind of name. It
- /// includes information about which kinds of names to consider
- /// (ordinary names, tag names, class/struct/union member names,
- /// namespace names, etc.) and where to look for those
- /// names. LookupCriteria is used throughout semantic analysis to
- /// specify how to search for a name, e.g., with the LookupName and
- /// LookupQualifiedName functions.
- struct LookupCriteria {
- /// NameKind - The kinds of names that we are looking for.
- enum NameKind {
- /// Ordinary - Ordinary name lookup, which finds ordinary names
- /// (functions, variables, typedefs, etc.) in C and most kinds
- /// of names (functions, variables, members, types, etc.) in
- /// C++.
- Ordinary,
- /// Tag - Tag name lookup, which finds the names of enums,
- /// classes, structs, and unions.
- Tag,
- /// Member - Member name lookup, which finds the names of
- /// class/struct/union members.
- Member,
- /// NestedNameSpecifier - Look up of a name that precedes the
- /// '::' scope resolution operator in C++. This lookup
- /// completely ignores operator, function, and enumerator names
- /// (C++ [basic.lookup.qual]p1).
- NestedNameSpecifier,
- /// Namespace - Look up a namespace name within a C++
- /// using directive or namespace alias definition, ignoring
- /// non-namespace names (C++ [basic.lookup.udir]p1).
- Namespace
- } Kind;
-
- /// AllowLazyBuiltinCreation - If true, permits name lookup to
- /// lazily build declarations for built-in names, e.g.,
- /// __builtin_expect.
- bool AllowLazyBuiltinCreation;
-
- /// RedeclarationOnly - If true, the lookup will only
- /// consider entities within the scope where the lookup
- /// began. Entities that might otherwise meet the lookup criteria
- /// but are not within the original lookup scope will be ignored.
- bool RedeclarationOnly;
-
- /// IDNS - Bitwise OR of the appropriate Decl::IDNS_* flags that
- /// describe the namespaces where we should look for names. This
- /// field is determined by the kind of name we're searching for.
- unsigned IDNS;
-
- LookupCriteria()
- : Kind(Ordinary), AllowLazyBuiltinCreation(true),
- RedeclarationOnly(false), IDNS(Decl::IDNS_Ordinary) { }
-
- LookupCriteria(NameKind K, bool RedeclarationOnly, bool CPlusPlus);
-
- bool isLookupResult(Decl *D) const;
+ /// @brief Describes the kind of name lookup to perform.
+ enum LookupNameKind {
+ /// Ordinary name lookup, which finds ordinary names (functions,
+ /// variables, typedefs, etc.) in C and most kinds of names
+ /// (functions, variables, members, types, etc.) in C++.
+ LookupOrdinaryName = 0,
+ /// Tag name lookup, which finds the names of enums, classes,
+ /// structs, and unions.
+ LookupTagName,
+ /// Member name lookup, which finds the names of
+ /// class/struct/union members.
+ LookupMemberName,
+ /// Look up of a name that precedes the '::' scope resolution
+ /// operator in C++. This lookup completely ignores operator,
+ /// function, and enumerator names (C++ [basic.lookup.qual]p1).
+ LookupNestedNameSpecifierName,
+ /// Look up a namespace name within a C++ using directive or
+ /// namespace alias definition, ignoring non-namespace names (C++
+ /// [basic.lookup.udir]p1).
+ LookupNamespaceName
};
/// @brief Represents the results of name lookup.
@@ -775,18 +736,38 @@
BasePaths *getBasePaths() const;
};
- LookupResult LookupName(Scope *S, DeclarationName Name,
- LookupCriteria Criteria);
- LookupResult LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name,
- LookupCriteria Criteria);
- LookupResult LookupParsedName(Scope *S, const CXXScopeSpec &SS,
- DeclarationName Name, LookupCriteria Criteria);
- LookupResult LookupDeclInScope(DeclarationName Name, unsigned NSI, Scope *S,
- bool LookInParent = true);
- LookupResult LookupDeclInContext(DeclarationName Name, unsigned NSI,
- const DeclContext *LookupCtx,
- bool LookInParent = true);
+ /// Determines whether D is a suitable lookup result according to the
+ /// lookup criteria.
+ bool isAcceptableLookupResult(Decl *D, LookupNameKind NameKind,
+ unsigned IDNS) const {
+ switch (NameKind) {
+ case Sema::LookupOrdinaryName:
+ case Sema::LookupTagName:
+ case Sema::LookupMemberName:
+ return D->isInIdentifierNamespace(IDNS);
+
+ case Sema::LookupNestedNameSpecifierName:
+ return isa<TypedefDecl>(D) || D->isInIdentifierNamespace(Decl::IDNS_Tag);
+
+ case Sema::LookupNamespaceName:
+ return isa<NamespaceDecl>(D);
+ }
+
+ assert(false &&
+ "isNameAcceptableLookupResult always returns before this point");
+ return false;
+ }
+ LookupResult LookupName(Scope *S, DeclarationName Name,
+ LookupNameKind NameKind,
+ bool RedeclarationOnly = false);
+ LookupResult LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name,
+ LookupNameKind NameKind,
+ bool RedeclarationOnly = false);
+ LookupResult LookupParsedName(Scope *S, const CXXScopeSpec *SS,
+ DeclarationName Name,
+ LookupNameKind NameKind,
+ bool RedeclarationOnly = false);
bool DiagnoseAmbiguousLookup(LookupResult &Result, DeclarationName Name,
SourceLocation NameLoc,
SourceRange LookupRange = SourceRange());
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index cf93571..c77325f 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -36,10 +36,7 @@
SourceLocation IdLoc,
SourceLocation CCLoc,
IdentifierInfo &II) {
- Decl *SD = LookupParsedName(S, SS, &II,
- LookupCriteria(LookupCriteria::NestedNameSpecifier,
- /*RedeclarationOnly=*/false,
- /*CPlusPlus=*/true));
+ Decl *SD = LookupParsedName(S, &SS, &II, LookupNestedNameSpecifierName);
if (SD) {
if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {
@@ -60,10 +57,7 @@
// ordinary name lookup, which can help us produce better error
// messages.
if (!SD)
- SD = LookupParsedName(S, SS, &II,
- LookupCriteria(LookupCriteria::Ordinary,
- /*RedeclarationOnly=*/false,
- /*CPlusPlus=*/true));
+ SD = LookupParsedName(S, &SS, &II, LookupOrdinaryName);
unsigned DiagID;
if (SD)
DiagID = diag::err_expected_class_or_namespace;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index cf71d39..ad6a719 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -32,18 +32,8 @@
Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, Scope *S,
const CXXScopeSpec *SS) {
- DeclContext *DC = 0;
-
- if (SS) {
- if (SS->isInvalid())
- return 0;
- DC = static_cast<DeclContext*>(SS->getScopeRep());
- }
Decl *IIDecl = 0;
-
- LookupResult Result = DC ? LookupDeclInContext(&II, Decl::IDNS_Ordinary, DC) :
- LookupDeclInScope(&II, Decl::IDNS_Ordinary, S);
-
+ LookupResult Result = LookupParsedName(S, SS, &II, LookupOrdinaryName, false);
switch (Result.getKind()) {
case LookupResult::NotFound:
case LookupResult::FoundOverloaded:
@@ -139,8 +129,7 @@
// We're pushing the tag into the current context, which might
// require some reshuffling in the identifier resolver.
IdentifierResolver::iterator
- I = IdResolver.begin(TD->getDeclName(), CurContext,
- false/*LookInParentCtx*/),
+ I = IdResolver.begin(TD->getDeclName()),
IEnd = IdResolver.end();
if (I != IEnd && isDeclInScope(*I, CurContext, S)) {
NamedDecl *PrevDecl = *I;
@@ -175,10 +164,8 @@
// We are pushing the name of a function, which might be an
// overloaded name.
FunctionDecl *FD = cast<FunctionDecl>(D);
- DeclContext *DC = FD->getDeclContext()->getLookupContext();
IdentifierResolver::iterator Redecl
- = std::find_if(IdResolver.begin(FD->getDeclName(), DC,
- false/*LookInParentCtx*/),
+ = std::find_if(IdResolver.begin(FD->getDeclName()),
IdResolver.end(),
std::bind1st(std::mem_fun(&NamedDecl::declarationReplaces),
FD));
@@ -218,7 +205,7 @@
ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) {
// The third "scope" argument is 0 since we aren't enabling lazy built-in
// creation from this context.
- Decl *IDecl = LookupDeclInScope(Id, Decl::IDNS_Ordinary, 0);
+ Decl *IDecl = LookupName(TUScope, Id, LookupOrdinaryName);
return dyn_cast_or_null<ObjCInterfaceDecl>(IDecl);
}
@@ -255,123 +242,12 @@
return S;
}
-/// LookupDeclInScope - Look up the inner-most declaration in the specified
-/// namespace. NamespaceNameOnly - during lookup only namespace names
-/// are considered as required in C++ [basic.lookup.udir] 3.4.6.p1
-/// 'When looking up a namespace-name in a using-directive or
-/// namespace-alias-definition, only namespace names are considered.'
-///
-/// Note: The use of this routine is deprecated. Please use
-/// LookupName, LookupQualifiedName, or LookupParsedName instead.
-Sema::LookupResult
-Sema::LookupDeclInScope(DeclarationName Name, unsigned NSI, Scope *S,
- bool LookInParent) {
- if (getLangOptions().CPlusPlus) {
- LookupCriteria::NameKind Kind;
- if (NSI == Decl::IDNS_Ordinary) {
- Kind = LookupCriteria::Ordinary;
- } else if (NSI == Decl::IDNS_Tag)
- Kind = LookupCriteria::Tag;
- else {
- assert(NSI == Decl::IDNS_Member &&"Unable to grok LookupDecl NSI argument");
- Kind = LookupCriteria::Member;
- }
- // Unqualified lookup
- return LookupName(S, Name,
- LookupCriteria(Kind, !LookInParent,
- getLangOptions().CPlusPlus));
- }
- // Fast path for C/ObjC.
-
- // Unqualified name lookup in C/Objective-C is purely lexical, so
- // search in the declarations attached to the name.
-
- // For the purposes of unqualified name lookup, structs and unions
- // don't have scopes at all. For example:
- //
- // struct X {
- // struct T { int i; } x;
- // };
- //
- // void f() {
- // struct T t; // okay: T is defined lexically within X, but
- // // semantically at global scope
- // };
- //
- // FIXME: Is there a better way to deal with this?
- DeclContext *SearchCtx = CurContext;
- while (isa<RecordDecl>(SearchCtx) || isa<EnumDecl>(SearchCtx))
- SearchCtx = SearchCtx->getParent();
- IdentifierResolver::iterator I
- = IdResolver.begin(Name, SearchCtx, LookInParent);
-
- // Scan up the scope chain looking for a decl that matches this
- // identifier that is in the appropriate namespace. This search
- // should not take long, as shadowing of names is uncommon, and
- // deep shadowing is extremely uncommon.
- for (; I != IdResolver.end(); ++I) {
- switch (NSI) {
- case Decl::IDNS_Ordinary:
- case Decl::IDNS_Tag:
- case Decl::IDNS_Member:
- if ((*I)->isInIdentifierNamespace(NSI))
- return LookupResult::CreateLookupResult(Context, *I);
- break;
- default:
- assert(0 && "Unable to grok LookupDecl NSI argument");
- }
- }
- if (NSI == Decl::IDNS_Ordinary) {
- IdentifierInfo *II = Name.getAsIdentifierInfo();
- if (II) {
- // If this is a builtin on this (or all) targets, create the decl.
- if (unsigned BuiltinID = II->getBuiltinID())
- return LookupResult::CreateLookupResult(Context,
- LazilyCreateBuiltin((IdentifierInfo *)II, BuiltinID,
- S));
- }
- if (getLangOptions().ObjC1 && II) {
- // @interface and @compatibility_alias introduce typedef-like names.
- // Unlike typedef's, they can only be introduced at file-scope (and are
- // therefore not scoped decls). They can, however, be shadowed by
- // other names in IDNS_Ordinary.
- ObjCInterfaceDeclsTy::iterator IDI = ObjCInterfaceDecls.find(II);
- if (IDI != ObjCInterfaceDecls.end())
- return LookupResult::CreateLookupResult(Context, IDI->second);
- ObjCAliasTy::iterator I = ObjCAliasDecls.find(II);
- if (I != ObjCAliasDecls.end())
- return LookupResult::CreateLookupResult(Context,
- I->second->getClassInterface());
- }
- }
- return LookupResult::CreateLookupResult(Context, 0);
-}
-
-Sema::LookupResult
-Sema::LookupDeclInContext(DeclarationName Name, unsigned NSI,
- const DeclContext *LookupCtx,
- bool LookInParent) {
- assert(LookupCtx && "LookupDeclInContext(): Missing DeclContext");
- LookupCriteria::NameKind Kind;
- if (NSI == Decl::IDNS_Ordinary) {
- Kind = LookupCriteria::Ordinary;
- } else if (NSI == Decl::IDNS_Tag)
- Kind = LookupCriteria::Tag;
- else {
- assert(NSI == Decl::IDNS_Member &&"Unable to grok LookupDecl NSI argument");
- Kind = LookupCriteria::Member;
- }
- return LookupQualifiedName(const_cast<DeclContext *>(LookupCtx), Name,
- LookupCriteria(Kind, !LookInParent,
- getLangOptions().CPlusPlus));
-}
-
void Sema::InitBuiltinVaListType() {
if (!Context.getBuiltinVaListType().isNull())
return;
IdentifierInfo *VaIdent = &Context.Idents.get("__builtin_va_list");
- Decl *VaDecl = LookupDeclInScope(VaIdent, Decl::IDNS_Ordinary, TUScope);
+ Decl *VaDecl = LookupName(TUScope, VaIdent, LookupOrdinaryName);
TypedefDecl *VaTypedef = cast<TypedefDecl>(VaDecl);
Context.setBuiltinVaListType(Context.getTypedefType(VaTypedef));
}
@@ -420,7 +296,7 @@
if (!StdNamespace) {
IdentifierInfo *StdIdent = &PP.getIdentifierTable().get("std");
DeclContext *Global = Context.getTranslationUnitDecl();
- Decl *Std = LookupDeclInContext(StdIdent, Decl::IDNS_Ordinary, Global);
+ Decl *Std = LookupQualifiedName(Global, StdIdent, LookupNamespaceName);
StdNamespace = dyn_cast_or_null<NamespaceDecl>(Std);
}
return StdNamespace;
@@ -689,10 +565,9 @@
// FIXME: I don't think this will actually see all of the
// redefinitions. Can't we check this property on-the-fly?
- for (IdentifierResolver::iterator
- I = IdResolver.begin(VD->getIdentifier(),
- VD->getDeclContext(), false/*LookInParentCtx*/),
- E = IdResolver.end(); I != E; ++I) {
+ for (IdentifierResolver::iterator I = IdResolver.begin(VD->getIdentifier()),
+ E = IdResolver.end();
+ I != E; ++I) {
if (*I != VD && isDeclInScope(*I, VD->getDeclContext(), S)) {
VarDecl *OldDecl = dyn_cast<VarDecl>(*I);
@@ -864,8 +739,8 @@
FEnd = AnonRecord->field_end();
F != FEnd; ++F) {
if ((*F)->getDeclName()) {
- Decl *PrevDecl = LookupDeclInContext((*F)->getDeclName(),
- Decl::IDNS_Ordinary, Owner, false);
+ Decl *PrevDecl = LookupQualifiedName(Owner, (*F)->getDeclName(),
+ LookupOrdinaryName, true);
if (PrevDecl && !isa<TagDecl>(PrevDecl)) {
// C++ [class.union]p2:
// The names of the members of an anonymous union shall be
@@ -1312,13 +1187,12 @@
bool InvalidDecl = false;
// See if this is a redefinition of a variable in the same scope.
- if (!D.getCXXScopeSpec().isSet()) {
+ if (!D.getCXXScopeSpec().isSet() && !D.getCXXScopeSpec().isInvalid()) {
DC = CurContext;
- PrevDecl = LookupDeclInScope(Name, Decl::IDNS_Ordinary, S);
+ PrevDecl = LookupName(S, Name, LookupOrdinaryName);
} else { // Something like "int foo::x;"
DC = static_cast<DeclContext*>(D.getCXXScopeSpec().getScopeRep());
- PrevDecl = DC ? LookupDeclInContext(Name, Decl::IDNS_Ordinary, DC)
- : LookupDeclInScope(Name, Decl::IDNS_Ordinary, S);
+ PrevDecl = LookupQualifiedName(DC, Name, LookupOrdinaryName);
// C++ 7.3.1.2p2:
// Members (including explicit specializations of templates) of a named
@@ -1807,7 +1681,7 @@
<< D.getCXXScopeSpec().getRange();
InvalidDecl = true;
- PrevDecl = LookupDeclInContext(Name, Decl::IDNS_Ordinary, DC);
+ PrevDecl = LookupQualifiedName(DC, Name, LookupOrdinaryName);
if (!PrevDecl) {
// Nothing to suggest.
} else if (OverloadedFunctionDecl *Ovl
@@ -2662,7 +2536,7 @@
// among each other. Here they can only shadow globals, which is ok.
IdentifierInfo *II = D.getIdentifier();
if (II) {
- if (Decl *PrevDecl = LookupDeclInScope(II, Decl::IDNS_Ordinary, S)) {
+ if (Decl *PrevDecl = LookupName(S, II, LookupOrdinaryName)) {
if (PrevDecl->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter.
DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
@@ -2954,7 +2828,7 @@
DC = static_cast<DeclContext*>(SS.getScopeRep());
// Look-up name inside 'foo::'.
PrevDecl = dyn_cast_or_null<TagDecl>(
- LookupDeclInContext(Name, Decl::IDNS_Tag, DC).getAsDecl());
+ LookupQualifiedName(DC, Name, LookupTagName).getAsDecl());
// A tag 'foo::bar' must already exist.
if (PrevDecl == 0) {
@@ -2965,14 +2839,14 @@
} else if (Name) {
// If this is a named struct, check to see if there was a previous forward
// declaration or definition.
- Decl *D = LookupDeclInScope(Name, Decl::IDNS_Tag, S);
+ Decl *D = LookupName(S, Name, LookupTagName);
PrevDecl = dyn_cast_or_null<NamedDecl>(D);
if (!getLangOptions().CPlusPlus && TK != TK_Reference) {
// FIXME: This makes sure that we ignore the contexts associated
// with C structs, unions, and enums when looking for a matching
// tag declaration or definition. See the similar lookup tweak
- // in Sema::LookupDecl; is there a better way to deal with this?
+ // in Sema::LookupName; is there a better way to deal with this?
while (isa<RecordDecl>(SearchDC) || isa<EnumDecl>(SearchDC))
SearchDC = SearchDC->getParent();
}
@@ -3158,9 +3032,7 @@
// shall not be declared with the same name as a typedef-name
// that is declared in that scope and refers to a type other
// than the class or enumeration itself.
- LookupResult Lookup = LookupName(S, Name,
- LookupCriteria(LookupCriteria::Ordinary,
- true, true));
+ LookupResult Lookup = LookupName(S, Name, LookupOrdinaryName, true);
TypedefDecl *PrevTypedef = 0;
if (Lookup.getKind() == LookupResult::Found)
PrevTypedef = dyn_cast<TypedefDecl>(Lookup.getAsDecl());
@@ -3352,8 +3224,7 @@
DeclSpec::SCS_mutable);
if (II) {
- Decl *PrevDecl
- = LookupDeclInScope(II, Decl::IDNS_Member, S, false);
+ Decl *PrevDecl = LookupName(S, II, LookupMemberName, true);
if (PrevDecl && isDeclInScope(PrevDecl, CurContext, S)
&& !isa<TagDecl>(PrevDecl)) {
Diag(Loc, diag::err_duplicate_member) << II;
@@ -3445,7 +3316,7 @@
(Expr *)BitfieldWidth);
if (II) {
- Decl *PrevDecl = LookupDeclInScope(II, Decl::IDNS_Member, S, false);
+ Decl *PrevDecl = LookupName(S, II, LookupMemberName, true);
if (PrevDecl && isDeclInScope(PrevDecl, CurContext, S)
&& !isa<TagDecl>(PrevDecl)) {
Diag(Loc, diag::err_duplicate_member) << II;
@@ -3621,7 +3492,7 @@
// Verify that there isn't already something declared with this name in this
// scope.
- Decl *PrevDecl = LookupDeclInScope(Id, Decl::IDNS_Ordinary, S);
+ Decl *PrevDecl = LookupName(S, Id, LookupOrdinaryName);
if (PrevDecl && PrevDecl->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter.
DiagnoseTemplateParameterShadow(IdLoc, PrevDecl);
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 1870a8f..24f7531 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1375,8 +1375,8 @@
// original-namespace-definition is the name of the namespace. Subsequently
// in that declarative region, it is treated as an original-namespace-name.
- Decl *PrevDecl = LookupDeclInScope(II, Decl::IDNS_Ordinary, DeclRegionScope,
- /*LookupInParent=*/false);
+ Decl *PrevDecl = LookupName(DeclRegionScope, II, LookupOrdinaryName,
+ true);
if (NamespaceDecl *OrigNS = dyn_cast_or_null<NamespaceDecl>(PrevDecl)) {
// This is an extended namespace definition.
@@ -1437,14 +1437,7 @@
// FIXME: This still requires lot more checks, and AST support.
// Lookup namespace name.
- LookupCriteria Criteria(LookupCriteria::Namespace, /*RedeclarationOnly=*/false,
- /*CPlusPlus=*/true);
- Decl *NS = 0;
- if (SS.isSet())
- NS = LookupQualifiedName(static_cast<DeclContext*>(SS.getScopeRep()),
- NamespcName, Criteria);
- else
- NS = LookupName(S, NamespcName, Criteria);
+ Decl *NS = LookupParsedName(S, &SS, NamespcName, LookupNamespaceName, false);
if (NS) {
assert(isa<NamespaceDecl>(NS) && "expected namespace decl");
@@ -2179,7 +2172,7 @@
// FIXME: Need to check for abstract classes.
IdentifierInfo *II = D.getIdentifier();
- if (Decl *PrevDecl = LookupDeclInScope(II, Decl::IDNS_Ordinary, S)) {
+ if (Decl *PrevDecl = LookupName(S, II, LookupOrdinaryName)) {
// The scope should be freshly made just for us. There is just no way
// it contains any previous declaration.
assert(!S->isDeclScope(PrevDecl));
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 3371e3e..c3519f8 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -64,7 +64,7 @@
assert(ClassName && "Missing class identifier");
// Check for another declaration kind with the same name.
- Decl *PrevDecl = LookupDeclInScope(ClassName, Decl::IDNS_Ordinary, TUScope);
+ Decl *PrevDecl = LookupName(TUScope, ClassName, LookupOrdinaryName);
if (PrevDecl && PrevDecl->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter.
DiagnoseTemplateParameterShadow(ClassLoc, PrevDecl);
@@ -107,7 +107,7 @@
if (SuperName) {
ObjCInterfaceDecl* SuperClassEntry = 0;
// Check if a different kind of symbol declared in this scope.
- PrevDecl = LookupDeclInScope(SuperName, Decl::IDNS_Ordinary, TUScope);
+ PrevDecl = LookupName(TUScope, SuperName, LookupOrdinaryName);
if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
@@ -149,7 +149,7 @@
IdentifierInfo *ClassName,
SourceLocation ClassLocation) {
// Look for previous declaration of alias name
- Decl *ADecl = LookupDeclInScope(AliasName, Decl::IDNS_Ordinary, TUScope);
+ Decl *ADecl = LookupName(TUScope, AliasName, LookupOrdinaryName);
if (ADecl) {
if (isa<ObjCCompatibleAliasDecl>(ADecl))
Diag(AliasLocation, diag::warn_previous_alias_decl);
@@ -159,13 +159,13 @@
return 0;
}
// Check for class declaration
- Decl *CDeclU = LookupDeclInScope(ClassName, Decl::IDNS_Ordinary, TUScope);
+ Decl *CDeclU = LookupName(TUScope, ClassName, LookupOrdinaryName);
if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(CDeclU)) {
QualType T = TDecl->getUnderlyingType();
if (T->isObjCInterfaceType()) {
if (NamedDecl *IDecl = T->getAsObjCInterfaceType()->getDecl()) {
ClassName = IDecl->getIdentifier();
- CDeclU = LookupDeclInScope(ClassName, Decl::IDNS_Ordinary, TUScope);
+ CDeclU = LookupName(TUScope, ClassName, LookupOrdinaryName);
}
}
}
@@ -535,7 +535,7 @@
SourceLocation SuperClassLoc) {
ObjCInterfaceDecl* IDecl = 0;
// Check for another declaration kind with the same name.
- Decl *PrevDecl = LookupDeclInScope(ClassName, Decl::IDNS_Ordinary, TUScope);
+ Decl *PrevDecl = LookupName(TUScope, ClassName, LookupOrdinaryName);
if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
@@ -551,7 +551,7 @@
ObjCInterfaceDecl* SDecl = 0;
if (SuperClassname) {
// Check if a different kind of symbol declared in this scope.
- PrevDecl = LookupDeclInScope(SuperClassname, Decl::IDNS_Ordinary, TUScope);
+ PrevDecl = LookupName(TUScope, SuperClassname, LookupOrdinaryName);
if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Diag(SuperClassLoc, diag::err_redefinition_different_kind)
<< SuperClassname;
@@ -909,7 +909,7 @@
for (unsigned i = 0; i != NumElts; ++i) {
// Check for another declaration kind with the same name.
- Decl *PrevDecl = LookupDeclInScope(IdentList[i], Decl::IDNS_Ordinary, TUScope);
+ Decl *PrevDecl = LookupName(TUScope, IdentList[i], LookupOrdinaryName);
if (PrevDecl && PrevDecl->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter.
DiagnoseTemplateParameterShadow(AtClassLoc, PrevDecl);
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 5ebec02..129967a 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -555,14 +555,9 @@
// Could be enum-constant, value decl, instance variable, etc.
Decl *D = 0;
- LookupResult Lookup;
- if (SS && !SS->isEmpty()) {
- DeclContext *DC = static_cast<DeclContext*>(SS->getScopeRep());
- if (DC == 0)
- return ExprError();
- Lookup = LookupDeclInContext(Name, Decl::IDNS_Ordinary, DC);
- } else
- Lookup = LookupDeclInScope(Name, Decl::IDNS_Ordinary, S);
+ if (SS && SS->isInvalid())
+ return ExprError();
+ LookupResult Lookup = LookupParsedName(S, SS, Name, LookupOrdinaryName);
if (Lookup.isAmbiguous()) {
DiagnoseAmbiguousLookup(Lookup, Name, Loc,
@@ -1519,9 +1514,7 @@
// than this.
LookupResult Result
= LookupQualifiedName(RDecl, DeclarationName(&Member),
- LookupCriteria(LookupCriteria::Member,
- /*RedeclarationOnly=*/false,
- getLangOptions().CPlusPlus));
+ LookupMemberName, false);
Decl *MemberDecl = 0;
if (!Result)
@@ -4030,9 +4023,9 @@
// Get the decl corresponding to this.
RecordDecl *RD = RC->getDecl();
FieldDecl *MemberDecl
- = dyn_cast_or_null<FieldDecl>(LookupDeclInContext(OC.U.IdentInfo,
- Decl::IDNS_Ordinary,
- RD, false).getAsDecl());
+ = dyn_cast_or_null<FieldDecl>(LookupQualifiedName(RD, OC.U.IdentInfo,
+ LookupMemberName)
+ .getAsDecl());
if (!MemberDecl)
return Diag(BuiltinLoc, diag::err_typecheck_no_member)
<< OC.U.IdentInfo << SourceRange(OC.LocStart, OC.LocEnd);
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index d0ceb97..3c8184d 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -55,12 +55,12 @@
Action::ExprResult
Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
bool isType, void *TyOrExpr, SourceLocation RParenLoc) {
- const NamespaceDecl *StdNs = GetStdNamespace();
+ NamespaceDecl *StdNs = GetStdNamespace();
if (!StdNs)
return Diag(OpLoc, diag::err_need_header_before_typeid);
IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info");
- Decl *TypeInfoDecl = LookupDeclInContext(TypeInfoII, Decl::IDNS_Tag, StdNs);
+ Decl *TypeInfoDecl = LookupQualifiedName(StdNs, TypeInfoII, LookupTagName);
RecordDecl *TypeInfoRecordDecl = dyn_cast_or_null<RecordDecl>(TypeInfoDecl);
if (!TypeInfoRecordDecl)
return Diag(OpLoc, diag::err_need_header_before_typeid);
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index f436e61..f893f1e 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -52,7 +52,7 @@
// Initialize the constant string interface lazily. This assumes
// the NSConstantString interface is seen in this translation unit.
IdentifierInfo *NSIdent = &Context.Idents.get("NSConstantString");
- Decl *IFace = LookupDeclInScope(NSIdent, Decl::IDNS_Ordinary, TUScope);
+ Decl *IFace = LookupName(TUScope, NSIdent, LookupOrdinaryName);
ObjCInterfaceDecl *strIFace = dyn_cast_or_null<ObjCInterfaceDecl>(IFace);
if (strIFace)
Context.setObjCConstantStringInterface(strIFace);
@@ -209,7 +209,7 @@
} else {
// 'super' has been used outside a method context. If a variable named
// 'super' has been declared, redirect. If not, produce a diagnostic.
- Decl *SuperDecl = LookupDeclInScope(receiverName, Decl::IDNS_Ordinary, S);
+ Decl *SuperDecl = LookupName(S, receiverName, LookupOrdinaryName);
ValueDecl *VD = dyn_cast_or_null<ValueDecl>(SuperDecl);
if (VD) {
ExprResult ReceiverExpr = new DeclRefExpr(VD, VD->getType(),
@@ -234,7 +234,7 @@
//
// If necessary, the following lookup could move to getObjCInterfaceDecl().
if (!ClassDecl) {
- Decl *IDecl = LookupDeclInScope(receiverName, Decl::IDNS_Ordinary, 0);
+ Decl *IDecl = LookupName(TUScope, receiverName, LookupOrdinaryName);
if (TypedefDecl *OCTD = dyn_cast_or_null<TypedefDecl>(IDecl)) {
const ObjCInterfaceType *OCIT;
OCIT = OCTD->getUnderlyingType()->getAsObjCInterfaceType();
diff --git a/lib/Sema/SemaInherit.cpp b/lib/Sema/SemaInherit.cpp
index cb58063..0772bc3 100644
--- a/lib/Sema/SemaInherit.cpp
+++ b/lib/Sema/SemaInherit.cpp
@@ -153,7 +153,8 @@
} else {
Paths.ScratchPath.Decls = BaseRecord->lookup(Criteria.Name);
while (Paths.ScratchPath.Decls.first != Paths.ScratchPath.Decls.second) {
- if (Criteria.Criteria.isLookupResult(*Paths.ScratchPath.Decls.first)) {
+ if (isAcceptableLookupResult(*Paths.ScratchPath.Decls.first,
+ Criteria.NameKind, Criteria.IDNS)) {
FoundPathToThisBase = true;
break;
}
diff --git a/lib/Sema/SemaInherit.h b/lib/Sema/SemaInherit.h
index 87a4a66..eb169a2 100644
--- a/lib/Sema/SemaInherit.h
+++ b/lib/Sema/SemaInherit.h
@@ -193,8 +193,9 @@
/// MemberLookupCriteria - Constructs member lookup criteria to
/// search for a class member with the given Name.
explicit MemberLookupCriteria(DeclarationName Name,
- Sema::LookupCriteria Criteria)
- : LookupBase(false), Name(Name), Criteria(Criteria) { }
+ Sema::LookupNameKind NameKind,
+ unsigned IDNS)
+ : LookupBase(false), Name(Name), NameKind(NameKind), IDNS(IDNS) { }
/// LookupBase - True if we are looking for a base class (whose
/// type is Base). If false, we are looking for a named member of
@@ -209,9 +210,8 @@
/// LookupBase is false.
DeclarationName Name;
- /// Criteria - The criteria by which we evaluate a named member,
- /// if LookupBase is false.
- Sema::LookupCriteria Criteria;
+ Sema::LookupNameKind NameKind;
+ unsigned IDNS;
};
}
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 7353bc3..abb265d 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -31,8 +31,8 @@
/// OverloadeFunctionDecl that represents the overloaded functions in
/// [I, IEnd).
///
-/// The existance of this routine is temporary; LookupDecl should
-/// probably be able to return multiple results, to deal with cases of
+/// The existance of this routine is temporary; users of LookupResult
+/// should be able to handle multiple results, to deal with cases of
/// ambiguity and overloaded functions without needing to create a
/// Decl node.
template<typename DeclIterator>
@@ -69,64 +69,6 @@
return *I;
}
-/// @brief Constructs name lookup criteria.
-///
-/// @param K The kind of name that we're searching for.
-///
-/// @param RedeclarationOnly If true, then name lookup will only look
-/// into the current scope for names, not in parent scopes. This
-/// option should be set when we're looking to introduce a new
-/// declaration into scope.
-///
-/// @param CPlusPlus Whether we are performing C++ name lookup or not.
-Sema::LookupCriteria::LookupCriteria(NameKind K, bool RedeclarationOnly,
- bool CPlusPlus)
- : Kind(K), AllowLazyBuiltinCreation(K == Ordinary),
- RedeclarationOnly(RedeclarationOnly) {
- switch (Kind) {
- case Ordinary:
- IDNS = Decl::IDNS_Ordinary;
- if (CPlusPlus)
- IDNS |= Decl::IDNS_Tag | Decl::IDNS_Member;
- break;
-
- case Tag:
- IDNS = Decl::IDNS_Tag;
- break;
-
- case Member:
- IDNS = Decl::IDNS_Member;
- if (CPlusPlus)
- IDNS |= Decl::IDNS_Tag | Decl::IDNS_Ordinary;
- break;
-
- case NestedNameSpecifier:
- case Namespace:
- IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Member;
- break;
- }
-}
-
-/// isLookupResult - Determines whether D is a suitable lookup result
-/// according to the lookup criteria.
-bool Sema::LookupCriteria::isLookupResult(Decl *D) const {
- switch (Kind) {
- case Ordinary:
- case Tag:
- case Member:
- return D->isInIdentifierNamespace(IDNS);
-
- case NestedNameSpecifier:
- return isa<TypedefDecl>(D) || D->isInIdentifierNamespace(Decl::IDNS_Tag);
-
- case Namespace:
- return isa<NamespaceDecl>(D);
- }
-
- assert(false && "isLookupResult always returns before this point");
- return false;
-}
-
/// @brief Moves the name-lookup results from Other to this LookupResult.
Sema::LookupResult
Sema::LookupResult::CreateLookupResult(ASTContext &Context,
@@ -239,6 +181,37 @@
return reinterpret_cast<BasePaths *>(First);
}
+// Retrieve the set of identifier namespaces that correspond to a
+// specific kind of name lookup.
+inline unsigned
+getIdentifierNamespacesFromLookupNameKind(Sema::LookupNameKind NameKind,
+ bool CPlusPlus) {
+ unsigned IDNS = 0;
+ switch (NameKind) {
+ case Sema::LookupOrdinaryName:
+ IDNS = Decl::IDNS_Ordinary;
+ if (CPlusPlus)
+ IDNS |= Decl::IDNS_Tag | Decl::IDNS_Member;
+ break;
+
+ case Sema::LookupTagName:
+ IDNS = Decl::IDNS_Tag;
+ break;
+
+ case Sema::LookupMemberName:
+ IDNS = Decl::IDNS_Member;
+ if (CPlusPlus)
+ IDNS |= Decl::IDNS_Tag | Decl::IDNS_Ordinary;
+ break;
+
+ case Sema::LookupNestedNameSpecifierName:
+ case Sema::LookupNamespaceName:
+ IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Member;
+ break;
+ }
+ return IDNS;
+}
+
/// @brief Perform unqualified name lookup starting from a given
/// scope.
///
@@ -276,52 +249,58 @@
/// declarations and possibly additional information used to diagnose
/// ambiguities.
Sema::LookupResult
-Sema::LookupName(Scope *S, DeclarationName Name, LookupCriteria Criteria) {
+Sema::LookupName(Scope *S, DeclarationName Name, LookupNameKind NameKind,
+ bool RedeclarationOnly) {
if (!Name) return LookupResult::CreateLookupResult(Context, 0);
if (!getLangOptions().CPlusPlus) {
// Unqualified name lookup in C/Objective-C is purely lexical, so
// search in the declarations attached to the name.
+ unsigned IDNS = 0;
+ switch (NameKind) {
+ case Sema::LookupOrdinaryName:
+ IDNS = Decl::IDNS_Ordinary;
+ break;
- // For the purposes of unqualified name lookup, structs and unions
- // don't have scopes at all. For example:
- //
- // struct X {
- // struct T { int i; } x;
- // };
- //
- // void f() {
- // struct T t; // okay: T is defined lexically within X, but
- // // semantically at global scope
- // };
- //
- // FIXME: Is there a better way to deal with this?
- DeclContext *SearchCtx = CurContext;
- while (isa<RecordDecl>(SearchCtx) || isa<EnumDecl>(SearchCtx))
- SearchCtx = SearchCtx->getParent();
- IdentifierResolver::iterator I
- = IdResolver.begin(Name, SearchCtx, !Criteria.RedeclarationOnly);
-
+ case Sema::LookupTagName:
+ IDNS = Decl::IDNS_Tag;
+ break;
+
+ case Sema::LookupMemberName:
+ IDNS = Decl::IDNS_Member;
+ break;
+
+ case Sema::LookupNestedNameSpecifierName:
+ case Sema::LookupNamespaceName:
+ assert(false && "C does not perform these kinds of name lookup");
+ break;
+ }
+
// Scan up the scope chain looking for a decl that matches this
// identifier that is in the appropriate namespace. This search
// should not take long, as shadowing of names is uncommon, and
// deep shadowing is extremely uncommon.
- for (; I != IdResolver.end(); ++I)
- if (Criteria.isLookupResult(*I))
+ for (IdentifierResolver::iterator I = IdResolver.begin(Name),
+ IEnd = IdResolver.end();
+ I != IEnd; ++I)
+ if ((*I)->isInIdentifierNamespace(IDNS))
return LookupResult::CreateLookupResult(Context, *I);
} else {
+ unsigned IDNS
+ = getIdentifierNamespacesFromLookupNameKind(NameKind,
+ getLangOptions().CPlusPlus);
+
// Unqualified name lookup in C++ requires looking into scopes
// that aren't strictly lexical, and therefore we walk through the
// context as well as walking through the scopes.
// FIXME: does "true" for LookInParentCtx actually make sense?
- IdentifierResolver::iterator
- I = IdResolver.begin(Name, CurContext, true/*LookInParentCtx*/),
- IEnd = IdResolver.end();
+ IdentifierResolver::iterator I = IdResolver.begin(Name),
+ IEnd = IdResolver.end();
for (; S; S = S->getParent()) {
// Check whether the IdResolver has anything in this scope.
for (; I != IEnd && S->isDeclScope(*I); ++I) {
- if (Criteria.isLookupResult(*I)) {
+ if (isAcceptableLookupResult(*I, NameKind, IDNS)) {
// We found something. Look for anything else in our scope
// with this same name and in an acceptable identifier
// namespace, so that we can construct an overload set if we
@@ -356,10 +335,11 @@
Ctx = Ctx->getParent();
while (Ctx && (Ctx->isNamespace() || Ctx->isRecord())) {
// Look for declarations of this name in this scope.
- if (LookupResult Result = LookupQualifiedName(Ctx, Name, Criteria))
+ if (LookupResult Result = LookupQualifiedName(Ctx, Name, NameKind,
+ RedeclarationOnly))
return Result;
- if (Criteria.RedeclarationOnly && !Ctx->isTransparentContext())
+ if (RedeclarationOnly && !Ctx->isTransparentContext())
return LookupResult::CreateLookupResult(Context, 0);
Ctx = Ctx->getParent();
@@ -370,9 +350,9 @@
// If we didn't find a use of this identifier, and if the identifier
// corresponds to a compiler builtin, create the decl object for the builtin
// now, injecting it into translation unit scope, and return it.
- if (Criteria.Kind == LookupCriteria::Ordinary) {
+ if (NameKind == LookupOrdinaryName) {
IdentifierInfo *II = Name.getAsIdentifierInfo();
- if (Criteria.AllowLazyBuiltinCreation && II) {
+ if (II) {
// If this is a builtin on this (or all) targets, create the decl.
if (unsigned BuiltinID = II->getBuiltinID())
return LookupResult::CreateLookupResult(Context,
@@ -428,25 +408,28 @@
/// ambiguities.
Sema::LookupResult
Sema::LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name,
- LookupCriteria Criteria) {
+ LookupNameKind NameKind, bool RedeclarationOnly) {
assert(LookupCtx && "Sema::LookupQualifiedName requires a lookup context");
if (!Name) return LookupResult::CreateLookupResult(Context, 0);
// If we're performing qualified name lookup (e.g., lookup into a
// struct), find fields as part of ordinary name lookup.
- if (Criteria.Kind == LookupCriteria::Ordinary)
- Criteria.IDNS |= Decl::IDNS_Member;
+ unsigned IDNS
+ = getIdentifierNamespacesFromLookupNameKind(NameKind,
+ getLangOptions().CPlusPlus);
+ if (NameKind == LookupOrdinaryName)
+ IDNS |= Decl::IDNS_Member;
// Perform qualified name lookup into the LookupCtx.
DeclContext::lookup_iterator I, E;
for (llvm::tie(I, E) = LookupCtx->lookup(Name); I != E; ++I)
- if (Criteria.isLookupResult(*I))
+ if (isAcceptableLookupResult(*I, NameKind, IDNS))
return LookupResult::CreateLookupResult(Context, I, E);
// If this isn't a C++ class or we aren't allowed to look into base
// classes, we're done.
- if (Criteria.RedeclarationOnly || !isa<CXXRecordDecl>(LookupCtx))
+ if (RedeclarationOnly || !isa<CXXRecordDecl>(LookupCtx))
return LookupResult::CreateLookupResult(Context, 0);
// Perform lookup into our base classes.
@@ -455,7 +438,7 @@
// Look for this member in our base classes
if (!LookupInBases(cast<CXXRecordDecl>(LookupCtx),
- MemberLookupCriteria(Name, Criteria), Paths))
+ MemberLookupCriteria(Name, NameKind, IDNS), Paths))
return LookupResult::CreateLookupResult(Context, 0);
// C++ [class.member.lookup]p2:
@@ -552,18 +535,21 @@
/// @param Name The name of the entity that name lookup will
/// search for.
///
-/// @param Criteria The criteria that will determine which entities
-/// are visible to name lookup.
-///
/// @returns The result of qualified or unqualified name lookup.
Sema::LookupResult
-Sema::LookupParsedName(Scope *S, const CXXScopeSpec &SS,
- DeclarationName Name, LookupCriteria Criteria) {
- if (SS.isSet())
- return LookupQualifiedName(static_cast<DeclContext *>(SS.getScopeRep()),
- Name, Criteria);
+Sema::LookupParsedName(Scope *S, const CXXScopeSpec *SS,
+ DeclarationName Name, LookupNameKind NameKind,
+ bool RedeclarationOnly) {
+ if (SS) {
+ if (SS->isInvalid())
+ return LookupResult::CreateLookupResult(Context, 0);
- return LookupName(S, Name, Criteria);
+ if (SS->isSet())
+ return LookupQualifiedName(static_cast<DeclContext *>(SS->getScopeRep()),
+ Name, NameKind, RedeclarationOnly);
+ }
+
+ return LookupName(S, Name, NameKind, RedeclarationOnly);
}
/// @brief Produce a diagnostic describing the ambiguity that resulted
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 0f9f0cf..17ad387 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -2279,9 +2279,8 @@
// of type T2 or “reference to (possibly cv-qualified) T2”,
// when T2 is an enumeration type, are candidate functions.
{
- IdentifierResolver::iterator
- I = IdResolver.begin(OpName, CurContext, true/*LookInParentCtx*/),
- IEnd = IdResolver.end();
+ IdentifierResolver::iterator I = IdResolver.begin(OpName),
+ IEnd = IdResolver.end();
for (; I != IEnd; ++I) {
// We don't need to check the identifier namespace, because
// operator names can only be ordinary identifiers.
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 7ecac00..f1b8617 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -32,9 +32,7 @@
return 0;
DC = static_cast<DeclContext*>(SS->getScopeRep());
}
- Decl *IIDecl = DC ?
- LookupDeclInContext(&II, Decl::IDNS_Ordinary, DC, false) :
- LookupDeclInScope(&II, Decl::IDNS_Ordinary, S, false);
+ Decl *IIDecl = LookupParsedName(S, SS, &II, LookupOrdinaryName);
if (IIDecl) {
// FIXME: We need to represent templates via some kind of
@@ -96,7 +94,7 @@
bool Invalid = false;
if (ParamName) {
- Decl *PrevDecl = LookupDeclInScope(ParamName, Decl::IDNS_Tag, S);
+ Decl *PrevDecl = LookupName(S, ParamName, LookupTagName);
if (PrevDecl && PrevDecl->isTemplateParameter())
Invalid = Invalid || DiagnoseTemplateParameterShadow(ParamNameLoc,
PrevDecl);
@@ -132,7 +130,7 @@
IdentifierInfo *ParamName = D.getIdentifier();
if (ParamName) {
- Decl *PrevDecl = LookupDeclInScope(ParamName, Decl::IDNS_Tag, S);
+ Decl *PrevDecl = LookupName(S, ParamName, LookupTagName);
if (PrevDecl && PrevDecl->isTemplateParameter())
Invalid = Invalid || DiagnoseTemplateParameterShadow(D.getIdentifierLoc(),
PrevDecl);