forked from OSchip/llvm-project
Make it an error if an Objective-C declaration is not in the global scope.
llvm-svn: 58705
This commit is contained in:
parent
b8c18fa59a
commit
a6b508a28c
|
@ -696,6 +696,10 @@ DIAG(err_reference_var_requires_init, ERROR,
|
|||
DIAG(err_const_var_requires_init, ERROR,
|
||||
"declaration of const variable '%0' requires an initializer")
|
||||
|
||||
// Objective-C++
|
||||
DIAG(err_objc_decls_may_only_appear_in_global_scope, ERROR,
|
||||
"Objective-C declarations may only appear in global scope")
|
||||
|
||||
// Attributes
|
||||
DIAG(err_attribute_wrong_number_arguments, ERROR,
|
||||
"attribute requires %0 argument(s)")
|
||||
|
|
|
@ -1209,7 +1209,11 @@ private:
|
|||
bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS,
|
||||
bool ForCompare);
|
||||
|
||||
|
||||
/// Checks that the Objective-C declaration is declared in the global scope.
|
||||
/// Emits an error and marks the declaration as invalid if it's not declared
|
||||
/// in the global scope.
|
||||
bool CheckObjCDeclScope(Decl *D);
|
||||
|
||||
void InitBuiltinVaListType();
|
||||
|
||||
// Helper method to turn variable array types into
|
||||
|
|
|
@ -124,6 +124,8 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
|
|||
IDecl->addReferencedProtocols((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs);
|
||||
IDecl->setLocEnd(EndProtoLoc);
|
||||
}
|
||||
|
||||
CheckObjCDeclScope(IDecl);
|
||||
return IDecl;
|
||||
}
|
||||
|
||||
|
@ -163,7 +165,10 @@ Sema::DeclTy *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
|
|||
ObjCCompatibleAliasDecl::Create(Context, AtLoc, AliasName, CDecl);
|
||||
|
||||
ObjCAliasDecls[AliasName] = AliasDecl;
|
||||
TUScope->AddDecl(AliasDecl);
|
||||
|
||||
if (!CheckObjCDeclScope(AliasDecl))
|
||||
TUScope->AddDecl(AliasDecl);
|
||||
|
||||
return AliasDecl;
|
||||
}
|
||||
|
||||
|
@ -201,6 +206,8 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
|
|||
PDecl->addReferencedProtocols((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs);
|
||||
PDecl->setLocEnd(EndProtoLoc);
|
||||
}
|
||||
|
||||
CheckObjCDeclScope(PDecl);
|
||||
return PDecl;
|
||||
}
|
||||
|
||||
|
@ -370,8 +377,13 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
|
|||
|
||||
Protocols.push_back(PDecl);
|
||||
}
|
||||
return ObjCForwardProtocolDecl::Create(Context, AtProtocolLoc,
|
||||
&Protocols[0], Protocols.size());
|
||||
|
||||
ObjCForwardProtocolDecl *PDecl =
|
||||
ObjCForwardProtocolDecl::Create(Context, AtProtocolLoc,
|
||||
&Protocols[0], Protocols.size());
|
||||
|
||||
CheckObjCDeclScope(PDecl);
|
||||
return PDecl;
|
||||
}
|
||||
|
||||
Sema::DeclTy *Sema::
|
||||
|
@ -410,6 +422,8 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
|
|||
CDecl->addReferencedProtocols((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs);
|
||||
CDecl->setLocEnd(EndProtoLoc);
|
||||
}
|
||||
|
||||
CheckObjCDeclScope(CDecl);
|
||||
return CDecl;
|
||||
}
|
||||
|
||||
|
@ -430,6 +444,8 @@ Sema::DeclTy *Sema::ActOnStartCategoryImplementation(
|
|||
/// TODO: Check that CatName, category name, is not used in another
|
||||
// implementation.
|
||||
ObjCCategoryImpls.push_back(CDecl);
|
||||
|
||||
CheckObjCDeclScope(CDecl);
|
||||
return CDecl;
|
||||
}
|
||||
|
||||
|
@ -498,6 +514,9 @@ Sema::DeclTy *Sema::ActOnStartClassImplementation(
|
|||
ObjCImplementationDecl::Create(Context, AtClassImplLoc, ClassName,
|
||||
IDecl, SDecl);
|
||||
|
||||
if (CheckObjCDeclScope(IMPDecl))
|
||||
return IMPDecl;
|
||||
|
||||
// Check that there is no duplicate implementation of this class.
|
||||
if (ObjCImplementations[ClassName])
|
||||
// FIXME: Don't leak everything!
|
||||
|
@ -730,8 +749,12 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
|
|||
Interfaces.push_back(IDecl);
|
||||
}
|
||||
|
||||
return ObjCClassDecl::Create(Context, AtClassLoc,
|
||||
&Interfaces[0], Interfaces.size());
|
||||
ObjCClassDecl *CDecl = ObjCClassDecl::Create(Context, AtClassLoc,
|
||||
&Interfaces[0],
|
||||
Interfaces.size());
|
||||
|
||||
CheckObjCDeclScope(CDecl);
|
||||
return CDecl;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1327,3 +1350,14 @@ Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
|
|||
|
||||
return PIDecl;
|
||||
}
|
||||
|
||||
bool Sema::CheckObjCDeclScope(Decl *D)
|
||||
{
|
||||
if (isa<TranslationUnitDecl>(CurContext))
|
||||
return false;
|
||||
|
||||
Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope);
|
||||
D->setInvalidDecl();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
// RUN: clang -fsyntax-only -verify %s
|
||||
|
||||
namespace C {
|
||||
|
||||
@protocol P; //expected-error{{Objective-C declarations may only appear in global scope}}
|
||||
|
||||
@class Bar; //expected-error{{Objective-C declarations may only appear in global scope}}
|
||||
|
||||
@compatibility_alias Foo Bar; //expected-error{{Objective-C declarations may only appear in global scope}}
|
||||
|
||||
@interface A //expected-error{{Objective-C declarations may only appear in global scope}}
|
||||
@end
|
||||
|
||||
@implementation A //expected-error{{Objective-C declarations may only appear in global scope}}
|
||||
@end
|
||||
|
||||
@protocol P //expected-error{{Objective-C declarations may only appear in global scope}}
|
||||
@end
|
||||
|
||||
@interface A(C) //expected-error{{Objective-C declarations may only appear in global scope}}
|
||||
@end
|
||||
|
||||
@implementation A(C) //expected-error{{Objective-C declarations may only appear in global scope}}
|
||||
@end
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue