зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
e620ecdd41
Коммит
4c921ae760
|
@ -225,14 +225,9 @@ void IdentifierResolver::RemoveDecl(NamedDecl *D) {
|
|||
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 @@ IdentifierResolver::begin(DeclarationName Name, const DeclContext *Ctx,
|
|||
|
||||
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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -136,19 +136,12 @@ public:
|
|||
}
|
||||
/// 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 @@ public:
|
|||
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() {
|
||||
|
|
123
lib/Sema/Sema.h
123
lib/Sema/Sema.h
|
@ -559,7 +559,7 @@ public:
|
|||
/// 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 @@ public:
|
|||
/// 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 @@ public:
|
|||
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());
|
||||
|
|
|
@ -36,10 +36,7 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
|
|||
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 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
|
|||
// 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;
|
||||
|
|
|
@ -32,18 +32,8 @@ using namespace clang;
|
|||
|
||||
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 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S) {
|
|||
// 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 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S) {
|
|||
// 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 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
|
|||
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 @@ Scope *Sema::getNonFieldDeclScope(Scope *S) {
|
|||
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 @@ NamespaceDecl *Sema::GetStdNamespace() {
|
|||
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 @@ void Sema::CheckForFileScopedRedefinitions(Scope *S, VarDecl *VD) {
|
|||
|
||||
// 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 @@ bool Sema::InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner,
|
|||
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 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl,
|
|||
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 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
|||
<< 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 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
|
|||
// 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 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK,
|
|||
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 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK,
|
|||
} 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 @@ CreateNewDecl:
|
|||
// 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 @@ Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *TagD,
|
|||
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 @@ Sema::DeclTy *Sema::ActOnIvar(Scope *S,
|
|||
(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 @@ Sema::DeclTy *Sema::ActOnEnumConstant(Scope *S, DeclTy *theEnumDecl,
|
|||
|
||||
// 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);
|
||||
|
|
|
@ -1375,8 +1375,8 @@ Sema::DeclTy *Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
|
|||
// 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 @@ Sema::DeclTy *Sema::ActOnUsingDirective(Scope *S,
|
|||
// 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 @@ Sema::DeclTy *Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D)
|
|||
// 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));
|
||||
|
|
|
@ -64,7 +64,7 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
|
|||
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 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
|
|||
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 @@ Sema::DeclTy *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
|
|||
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 @@ Sema::DeclTy *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
|
|||
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 @@ Sema::DeclTy *Sema::ActOnStartClassImplementation(
|
|||
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 @@ Sema::DeclTy *Sema::ActOnStartClassImplementation(
|
|||
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 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
|
|||
|
||||
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);
|
||||
|
|
|
@ -555,14 +555,9 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
|
|||
|
||||
// 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 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
|
|||
// 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 @@ Sema::ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
|
|||
// 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);
|
||||
|
|
|
@ -55,12 +55,12 @@ Sema::ActOnCXXOperatorFunctionIdExpr(Scope *S, SourceLocation OperatorLoc,
|
|||
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);
|
||||
|
|
|
@ -52,7 +52,7 @@ Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
|
|||
// 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 @@ Sema::ExprResult Sema::ActOnClassMessage(
|
|||
} 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 @@ Sema::ExprResult Sema::ActOnClassMessage(
|
|||
//
|
||||
// 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();
|
||||
|
|
|
@ -153,7 +153,8 @@ bool Sema::LookupInBases(CXXRecordDecl *Class,
|
|||
} 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;
|
||||
}
|
||||
|
|
|
@ -193,8 +193,9 @@ namespace clang {
|
|||
/// 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 @@ namespace clang {
|
|||
/// 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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -31,8 +31,8 @@ using namespace clang;
|
|||
/// 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 @@ MaybeConstructOverloadSet(ASTContext &Context,
|
|||
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 @@ BasePaths *Sema::LookupResult::getBasePaths() const {
|
|||
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 @@ BasePaths *Sema::LookupResult::getBasePaths() const {
|
|||
/// 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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// 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 @@ Sema::LookupName(Scope *S, DeclarationName Name, LookupCriteria Criteria) {
|
|||
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 @@ Sema::LookupName(Scope *S, DeclarationName Name, LookupCriteria Criteria) {
|
|||
// 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 @@ Sema::LookupName(Scope *S, DeclarationName Name, LookupCriteria Criteria) {
|
|||
/// 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 @@ Sema::LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name,
|
|||
|
||||
// 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 @@ Sema::LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name,
|
|||
/// @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
|
||||
|
|
|
@ -2279,9 +2279,8 @@ void Sema::AddOperatorCandidates(OverloadedOperatorKind Op, Scope *S,
|
|||
// 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.
|
||||
|
|
|
@ -32,9 +32,7 @@ Sema::DeclTy *Sema::isTemplateName(IdentifierInfo &II, Scope *S,
|
|||
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 @@ Sema::DeclTy *Sema::ActOnTypeParameter(Scope *S, bool Typename,
|
|||
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 @@ Sema::DeclTy *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
|
|||
|
||||
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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче