Fixed a @compatible_alias bug. In the process, discovered unnecessary 2ndry lookup

ok class names and streamlined this logic to do the lookup once.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42926 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Fariborz Jahanian 2007-10-12 19:38:20 +00:00
Родитель 8f74476413
Коммит 4cabdfc51c
3 изменённых файлов: 52 добавлений и 30 удалений

Просмотреть файл

@ -208,7 +208,8 @@ private:
ParmVarDecl *ParseParamDeclarator(DeclaratorChunk &FI, unsigned ArgNo, ParmVarDecl *ParseParamDeclarator(DeclaratorChunk &FI, unsigned ArgNo,
Scope *FnBodyScope); Scope *FnBodyScope);
ScopedDecl *LookupScopedDecl(IdentifierInfo *II, unsigned NSI, ScopedDecl *LookupScopedDecl(IdentifierInfo *II, unsigned NSI,
SourceLocation IdLoc, Scope *S); SourceLocation IdLoc, Scope *S);
ScopedDecl *LookupInterfaceDecl(IdentifierInfo *II);
ObjcInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *Id); ObjcInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *Id);
ScopedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, Scope *S); ScopedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, Scope *S);
ScopedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II, ScopedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II,

Просмотреть файл

@ -86,23 +86,30 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
} }
} }
/// LookupInterfaceDecl - Lookup interface declaration in the scope chain.
/// Return the first declaration found (which may or may not be a class
/// declaration. Caller is respopnsible for handling the none-class case.
/// Bypassing the alias of a class by returning the aliased class.
ScopedDecl *Sema::LookupInterfaceDecl(IdentifierInfo *ClassName) {
ScopedDecl *IDecl;
// Scan up the scope chain looking for a decl that matches this identifier
// that is in the appropriate namespace.
for (IDecl = ClassName->getFETokenInfo<ScopedDecl>(); IDecl;
IDecl = IDecl->getNext())
if (IDecl->getIdentifierNamespace() == Decl::IDNS_Ordinary)
break;
if (ObjcCompatibleAliasDecl *ADecl =
dyn_cast_or_null<ObjcCompatibleAliasDecl>(IDecl))
return ADecl->getClassInterface();
return IDecl;
}
/// getObjcInterfaceDecl - Look up a for a class declaration in the scope. /// getObjcInterfaceDecl - Look up a for a class declaration in the scope.
/// return 0 if one not found. /// return 0 if one not found.
ObjcInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) { ObjcInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) {
ScopedDecl *IdDecl = LookupInterfaceDecl(Id);
// Scan up the scope chain looking for a decl that matches this identifier return cast_or_null<ObjcInterfaceDecl>(IdDecl);
// that is in the appropriate namespace. This search should not take long, as
// shadowing of names is uncommon, and deep shadowing is extremely uncommon.
ScopedDecl *IdDecl = NULL;
for (ScopedDecl *D = Id->getFETokenInfo<ScopedDecl>(); D; D = D->getNext()) {
if (D->getIdentifierNamespace() == Decl::IDNS_Ordinary) {
IdDecl = D;
break;
}
}
if (IdDecl && !isa<ObjcInterfaceDecl>(IdDecl))
IdDecl = 0;
return cast_or_null<ObjcInterfaceDecl>(static_cast<Decl*>(IdDecl));
} }
/// LookupScopedDecl - Look up the inner-most declaration in the specified /// LookupScopedDecl - Look up the inner-most declaration in the specified
@ -908,19 +915,18 @@ Sema::DeclTy *Sema::ActOnStartClassInterface(
assert(ClassName && "Missing class identifier"); assert(ClassName && "Missing class identifier");
// Check for another declaration kind with the same name. // Check for another declaration kind with the same name.
ScopedDecl *PrevDecl = LookupScopedDecl(ClassName, Decl::IDNS_Ordinary, ScopedDecl *PrevDecl = LookupInterfaceDecl(ClassName);
ClassLoc, TUScope);
if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl)) { if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl)) {
Diag(ClassLoc, diag::err_redefinition_different_kind, Diag(ClassLoc, diag::err_redefinition_different_kind,
ClassName->getName()); ClassName->getName());
Diag(PrevDecl->getLocation(), diag::err_previous_definition); Diag(PrevDecl->getLocation(), diag::err_previous_definition);
} }
ObjcInterfaceDecl* IDecl = getObjCInterfaceDecl(ClassName); ObjcInterfaceDecl* IDecl = dyn_cast_or_null<ObjcInterfaceDecl>(PrevDecl);
if (IDecl) { if (IDecl) {
// Class already seen. Is it a forward declaration? // Class already seen. Is it a forward declaration?
if (!IDecl->isForwardDecl()) if (!IDecl->isForwardDecl())
Diag(AtInterfaceLoc, diag::err_duplicate_class_def, ClassName->getName()); Diag(AtInterfaceLoc, diag::err_duplicate_class_def, IDecl->getName());
else { else {
IDecl->setForwardDecl(false); IDecl->setForwardDecl(false);
IDecl->AllocIntfRefProtocols(NumProtocols); IDecl->AllocIntfRefProtocols(NumProtocols);
@ -937,8 +943,7 @@ Sema::DeclTy *Sema::ActOnStartClassInterface(
if (SuperName) { if (SuperName) {
ObjcInterfaceDecl* SuperClassEntry = 0; ObjcInterfaceDecl* SuperClassEntry = 0;
// Check if a different kind of symbol declared in this scope. // Check if a different kind of symbol declared in this scope.
PrevDecl = LookupScopedDecl(SuperName, Decl::IDNS_Ordinary, PrevDecl = LookupInterfaceDecl(SuperName);
SuperLoc, TUScope);
if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl)) { if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl)) {
Diag(SuperLoc, diag::err_redefinition_different_kind, Diag(SuperLoc, diag::err_redefinition_different_kind,
SuperName->getName()); SuperName->getName());
@ -946,10 +951,12 @@ Sema::DeclTy *Sema::ActOnStartClassInterface(
} }
else { else {
// Check that super class is previously defined // Check that super class is previously defined
SuperClassEntry = getObjCInterfaceDecl(SuperName); SuperClassEntry = dyn_cast_or_null<ObjcInterfaceDecl>(PrevDecl);
if (!SuperClassEntry || SuperClassEntry->isForwardDecl()) { if (!SuperClassEntry || SuperClassEntry->isForwardDecl()) {
Diag(AtInterfaceLoc, diag::err_undef_superclass, SuperName->getName(), Diag(AtInterfaceLoc, diag::err_undef_superclass,
SuperClassEntry ? SuperClassEntry->getName()
: SuperName->getName(),
ClassName->getName()); ClassName->getName());
} }
} }
@ -1153,8 +1160,7 @@ Sema::DeclTy *Sema::ActOnStartClassImplementation(
SourceLocation SuperClassLoc) { SourceLocation SuperClassLoc) {
ObjcInterfaceDecl* IDecl = 0; ObjcInterfaceDecl* IDecl = 0;
// Check for another declaration kind with the same name. // Check for another declaration kind with the same name.
ScopedDecl *PrevDecl = LookupScopedDecl(ClassName, Decl::IDNS_Ordinary, ScopedDecl *PrevDecl = LookupInterfaceDecl(ClassName);
ClassLoc, TUScope);
if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl)) { if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl)) {
Diag(ClassLoc, diag::err_redefinition_different_kind, Diag(ClassLoc, diag::err_redefinition_different_kind,
ClassName->getName()); ClassName->getName());
@ -1162,7 +1168,7 @@ Sema::DeclTy *Sema::ActOnStartClassImplementation(
} }
else { else {
// Is there an interface declaration of this class; if not, warn! // Is there an interface declaration of this class; if not, warn!
IDecl = getObjCInterfaceDecl(ClassName); IDecl = dyn_cast_or_null<ObjcInterfaceDecl>(PrevDecl);
if (!IDecl) if (!IDecl)
Diag(ClassLoc, diag::warn_undef_interface, ClassName->getName()); Diag(ClassLoc, diag::warn_undef_interface, ClassName->getName());
} }
@ -1171,15 +1177,14 @@ Sema::DeclTy *Sema::ActOnStartClassImplementation(
ObjcInterfaceDecl* SDecl = 0; ObjcInterfaceDecl* SDecl = 0;
if (SuperClassname) { if (SuperClassname) {
// Check if a different kind of symbol declared in this scope. // Check if a different kind of symbol declared in this scope.
PrevDecl = LookupScopedDecl(SuperClassname, Decl::IDNS_Ordinary, PrevDecl = LookupInterfaceDecl(SuperClassname);
SuperClassLoc, TUScope);
if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl)) { if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl)) {
Diag(SuperClassLoc, diag::err_redefinition_different_kind, Diag(SuperClassLoc, diag::err_redefinition_different_kind,
SuperClassname->getName()); SuperClassname->getName());
Diag(PrevDecl->getLocation(), diag::err_previous_definition); Diag(PrevDecl->getLocation(), diag::err_previous_definition);
} }
else { else {
SDecl = getObjCInterfaceDecl(SuperClassname); SDecl = dyn_cast_or_null<ObjcInterfaceDecl>(PrevDecl);
if (!SDecl) if (!SDecl)
Diag(SuperClassLoc, diag::err_undef_superclass, Diag(SuperClassLoc, diag::err_undef_superclass,
SuperClassname->getName(), ClassName->getName()); SuperClassname->getName(), ClassName->getName());
@ -1187,7 +1192,7 @@ Sema::DeclTy *Sema::ActOnStartClassImplementation(
// This implementation and its interface do not have the same // This implementation and its interface do not have the same
// super class. // super class.
Diag(SuperClassLoc, diag::err_conflicting_super_class, Diag(SuperClassLoc, diag::err_conflicting_super_class,
SuperClassname->getName()); SDecl->getName());
Diag(SDecl->getLocation(), diag::err_previous_definition); Diag(SDecl->getLocation(), diag::err_previous_definition);
} }
} }

16
test/Sema/alias-test-2.m Normal file
Просмотреть файл

@ -0,0 +1,16 @@
// RUN: clang -fsyntax-only -verify %s
@interface Super @end
@interface MyWpModule @end
@compatibility_alias MyAlias MyWpModule;
@compatibility_alias AliasForSuper Super;
@interface MyAlias : AliasForSuper // expected-error {{duplicate interface declaration for class 'MyWpModule'}}
@end
@implementation MyAlias : AliasForSuper
@end