forked from OSchip/llvm-project
Match to do some semantic analysis on objective-c class decl.
1. Detect used of undeclared/forward declared super class. 2. Detect duplicate definition of a class. llvm-svn: 42168
This commit is contained in:
parent
cc7c475705
commit
a8bbc63c1f
|
@ -868,13 +868,30 @@ Sema::DeclTy *Sema::ObjcStartClassInterface(SourceLocation AtInterfaceLoc,
|
|||
IdentifierInfo **ProtocolNames, unsigned NumProtocols,
|
||||
AttributeList *AttrList) {
|
||||
assert(ClassName && "Missing class identifier");
|
||||
ObjcInterfaceDecl *IDecl;
|
||||
|
||||
|
||||
ObjcInterfaceDecl* IDecl;
|
||||
|
||||
if (Context.getObjCInterfaceDecl(ClassName))
|
||||
Diag(AtInterfaceLoc, diag::err_duplicate_class_def, ClassName->getName());
|
||||
|
||||
IDecl = new ObjcInterfaceDecl(AtInterfaceLoc, ClassName);
|
||||
|
||||
// Chain & install the interface decl into the identifier.
|
||||
IDecl->setNext(ClassName->getFETokenInfo<ScopedDecl>());
|
||||
ClassName->setFETokenInfo(IDecl);
|
||||
|
||||
if (SuperName) {
|
||||
const ObjcInterfaceDecl* SuperClassEntry =
|
||||
Context.getObjCInterfaceDecl(SuperName);
|
||||
|
||||
if (!SuperClassEntry) {
|
||||
Diag(AtInterfaceLoc, diag::err_undef_superclass, SuperName->getName(),
|
||||
ClassName->getName());
|
||||
}
|
||||
}
|
||||
|
||||
Context.setObjCInterfaceDecl(ClassName, IDecl);
|
||||
|
||||
return IDecl;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,8 +37,10 @@ class ASTContext {
|
|||
llvm::FoldingSet<FunctionTypeNoProto> FunctionTypeNoProtos;
|
||||
llvm::FoldingSet<FunctionTypeProto> FunctionTypeProtos;
|
||||
llvm::DenseMap<const RecordDecl*, const RecordLayout*> RecordLayoutInfo;
|
||||
llvm::DenseMap<const IdentifierInfo*, const ObjcInterfaceDecl*> ClassNameInfo;
|
||||
RecordDecl *CFConstantStringTypeDecl;
|
||||
public:
|
||||
|
||||
SourceManager &SourceMgr;
|
||||
TargetInfo &Target;
|
||||
IdentifierTable &Idents;
|
||||
|
@ -157,6 +159,12 @@ public:
|
|||
/// position information.
|
||||
const RecordLayout &getRecordLayout(const RecordDecl *D, SourceLocation L);
|
||||
|
||||
const ObjcInterfaceDecl* getObjCInterfaceDecl(const IdentifierInfo* ClassName)
|
||||
{ return ClassNameInfo[ClassName]; }
|
||||
void setObjCInterfaceDecl(const IdentifierInfo* ClassName,
|
||||
const ObjcInterfaceDecl* InterfaceDecl)
|
||||
{ ClassNameInfo[ClassName] = InterfaceDecl; }
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Type Operators
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
|
|
@ -408,6 +408,11 @@ DIAG(err_objc_protocol_optional, ERROR,
|
|||
"@optional may be specified in protocols only")
|
||||
DIAG(err_missing_catch_finally, ERROR,
|
||||
"@try statment without a @catch and @finally clause")
|
||||
DIAG(err_undef_superclass, ERROR,
|
||||
"cannot find interface declaration for '%0', superclass of '%1'")
|
||||
DIAG(err_duplicate_class_def, ERROR,
|
||||
"duplicate interface declaration for class '%0'")
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Semantic Analysis
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
@class SUPER, Y;
|
||||
|
||||
@interface INTF :SUPER // expected-error {{cannot find interface declaration for 'SUPER', superclass of 'INTF'}}
|
||||
@end
|
||||
|
||||
@interface SUPER @end
|
||||
|
||||
@interface INTF1 : SUPER
|
||||
@end
|
||||
|
||||
@interface INTF2 : INTF1
|
||||
@end
|
||||
|
||||
@interface INTF3 : Y // expected-error {{cannot find interface declaration for 'Y', superclass of 'INTF3'}}
|
||||
@end
|
||||
|
||||
@interface INTF1 // expected-error {{duplicate interface declaration for class 'INTF1'}}
|
||||
@end
|
Loading…
Reference in New Issue