зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
8f74476413
Коммит
4cabdfc51c
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче