[cfe-commits] r63320 - in /cfe/trunk/lib/Sema: Sema.h SemaDecl.cpp
Steve Naroff
snaroff at apple.com
Thu Jan 29 10:09:31 PST 2009
Author: snaroff
Date: Thu Jan 29 12:09:31 2009
New Revision: 63320
URL: http://llvm.org/viewvc/llvm-project?rev=63320&view=rev
Log:
Hack Sema::LookupDeclInScope() to avoid calling Sema::LookupName() when parsing C/ObjC.
This results in a 1.7% improvement for "Cocoa.h". If we can figure out how to return a "Decl *", rather than a Sema::LookupResult(), we will likely bump the speedup from 1.7%->2.5%. I verified this, however couldn't get it to work without breaking a fair number of C++ test cases. Will discuss with Doug offline.
Modified:
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=63320&r1=63319&r2=63320&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Thu Jan 29 12:09:31 2009
@@ -782,7 +782,7 @@
LookupResult LookupParsedName(Scope *S, const CXXScopeSpec &SS,
DeclarationName Name, LookupCriteria Criteria);
LookupResult LookupDeclInScope(DeclarationName Name, unsigned NSI, Scope *S,
- bool LookInParent = true);
+ bool LookInParent = true);
LookupResult LookupDeclInContext(DeclarationName Name, unsigned NSI,
const DeclContext *LookupCtx,
bool LookInParent = true);
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=63320&r1=63319&r2=63320&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Jan 29 12:09:31 2009
@@ -39,31 +39,32 @@
return 0;
DC = static_cast<DeclContext*>(SS->getScopeRep());
}
- LookupResult Result = DC ?
- LookupDeclInContext(&II, Decl::IDNS_Ordinary, DC) :
- LookupDeclInScope(&II, Decl::IDNS_Ordinary, S);
-
Decl *IIDecl = 0;
+
+ LookupResult Result = DC ? LookupDeclInContext(&II, Decl::IDNS_Ordinary, DC) :
+ LookupDeclInScope(&II, Decl::IDNS_Ordinary, S);
+
switch (Result.getKind()) {
- case LookupResult::NotFound:
- case LookupResult::FoundOverloaded:
- case LookupResult::AmbiguousBaseSubobjectTypes:
- case LookupResult::AmbiguousBaseSubobjects:
- // FIXME: In the event of an ambiguous lookup, we could visit all of
- // the entities found to determine whether they are all types. This
- // might provide better diagnostics.
- return 0;
-
- case LookupResult::Found:
- IIDecl = Result.getAsDecl();
- break;
+ case LookupResult::NotFound:
+ case LookupResult::FoundOverloaded:
+ case LookupResult::AmbiguousBaseSubobjectTypes:
+ case LookupResult::AmbiguousBaseSubobjects:
+ // FIXME: In the event of an ambiguous lookup, we could visit all of
+ // the entities found to determine whether they are all types. This
+ // might provide better diagnostics.
+ return 0;
+ case LookupResult::Found:
+ IIDecl = Result.getAsDecl();
+ break;
}
- if (isa<TypedefDecl>(IIDecl) ||
- isa<ObjCInterfaceDecl>(IIDecl) ||
- isa<TagDecl>(IIDecl) ||
- isa<TemplateTypeParmDecl>(IIDecl))
- return IIDecl;
+ if (IIDecl) {
+ if (isa<TypedefDecl>(IIDecl) ||
+ isa<ObjCInterfaceDecl>(IIDecl) ||
+ isa<TagDecl>(IIDecl) ||
+ isa<TemplateTypeParmDecl>(IIDecl))
+ return IIDecl;
+ }
return 0;
}
@@ -265,19 +266,85 @@
Sema::LookupResult
Sema::LookupDeclInScope(DeclarationName Name, unsigned NSI, Scope *S,
bool LookInParent) {
- LookupCriteria::NameKind Kind;
+ 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) {
- 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;
+ 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());
+ }
}
- // Unqualified lookup
- return LookupName(S, Name,
- LookupCriteria(Kind, !LookInParent,
- getLangOptions().CPlusPlus));
+ return LookupResult::CreateLookupResult(Context, 0);
}
Sema::LookupResult
@@ -2898,9 +2965,8 @@
} else if (Name) {
// If this is a named struct, check to see if there was a previous forward
// declaration or definition.
- PrevDecl = dyn_cast_or_null<NamedDecl>(LookupDeclInScope(Name,
- Decl::IDNS_Tag,S)
- .getAsDecl());
+ Decl *D = LookupDeclInScope(Name, Decl::IDNS_Tag, S);
+ PrevDecl = dyn_cast_or_null<NamedDecl>(D);
if (!getLangOptions().CPlusPlus && TK != TK_Reference) {
// FIXME: This makes sure that we ignore the contexts associated
More information about the cfe-commits
mailing list