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,
|
IdentifierInfo **ProtocolNames, unsigned NumProtocols,
|
||||||
AttributeList *AttrList) {
|
AttributeList *AttrList) {
|
||||||
assert(ClassName && "Missing class identifier");
|
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);
|
IDecl = new ObjcInterfaceDecl(AtInterfaceLoc, ClassName);
|
||||||
|
|
||||||
// Chain & install the interface decl into the identifier.
|
// Chain & install the interface decl into the identifier.
|
||||||
IDecl->setNext(ClassName->getFETokenInfo<ScopedDecl>());
|
IDecl->setNext(ClassName->getFETokenInfo<ScopedDecl>());
|
||||||
ClassName->setFETokenInfo(IDecl);
|
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;
|
return IDecl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,8 +37,10 @@ class ASTContext {
|
||||||
llvm::FoldingSet<FunctionTypeNoProto> FunctionTypeNoProtos;
|
llvm::FoldingSet<FunctionTypeNoProto> FunctionTypeNoProtos;
|
||||||
llvm::FoldingSet<FunctionTypeProto> FunctionTypeProtos;
|
llvm::FoldingSet<FunctionTypeProto> FunctionTypeProtos;
|
||||||
llvm::DenseMap<const RecordDecl*, const RecordLayout*> RecordLayoutInfo;
|
llvm::DenseMap<const RecordDecl*, const RecordLayout*> RecordLayoutInfo;
|
||||||
|
llvm::DenseMap<const IdentifierInfo*, const ObjcInterfaceDecl*> ClassNameInfo;
|
||||||
RecordDecl *CFConstantStringTypeDecl;
|
RecordDecl *CFConstantStringTypeDecl;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SourceManager &SourceMgr;
|
SourceManager &SourceMgr;
|
||||||
TargetInfo &Target;
|
TargetInfo &Target;
|
||||||
IdentifierTable &Idents;
|
IdentifierTable &Idents;
|
||||||
|
@ -157,6 +159,12 @@ public:
|
||||||
/// position information.
|
/// position information.
|
||||||
const RecordLayout &getRecordLayout(const RecordDecl *D, SourceLocation L);
|
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
|
// Type Operators
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
|
|
@ -408,6 +408,11 @@ DIAG(err_objc_protocol_optional, ERROR,
|
||||||
"@optional may be specified in protocols only")
|
"@optional may be specified in protocols only")
|
||||||
DIAG(err_missing_catch_finally, ERROR,
|
DIAG(err_missing_catch_finally, ERROR,
|
||||||
"@try statment without a @catch and @finally clause")
|
"@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
|
// 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