Eliminate the oddly-named Sema::ComparePropertiesInBaseAndSuper, which

did a redundant traversal of the lexical declarations in the
superclass. Instead, when we declare a new property, look into the
superclass to see whether we're redeclaring the property. Goot for 1%
of -fsyntax-only time on Cocoa.h and a little less than 3% on my
modules test case.

llvm-svn: 173073
This commit is contained in:
Douglas Gregor 2013-01-21 19:05:22 +00:00
parent bba95c08e4
commit 90d3442784
3 changed files with 41 additions and 60 deletions

View File

@ -2406,19 +2406,19 @@ public:
/// Called by ActOnProperty to handle \@property declarations in /// Called by ActOnProperty to handle \@property declarations in
/// class extensions. /// class extensions.
Decl *HandlePropertyInClassExtension(Scope *S, ObjCPropertyDecl *HandlePropertyInClassExtension(Scope *S,
SourceLocation AtLoc, SourceLocation AtLoc,
SourceLocation LParenLoc, SourceLocation LParenLoc,
FieldDeclarator &FD, FieldDeclarator &FD,
Selector GetterSel, Selector GetterSel,
Selector SetterSel, Selector SetterSel,
const bool isAssign, const bool isAssign,
const bool isReadWrite, const bool isReadWrite,
const unsigned Attributes, const unsigned Attributes,
const unsigned AttributesAsWritten, const unsigned AttributesAsWritten,
bool *isOverridingProperty, bool *isOverridingProperty,
TypeSourceInfo *T, TypeSourceInfo *T,
tok::ObjCKeywordKind MethodImplKind); tok::ObjCKeywordKind MethodImplKind);
/// Called by ActOnProperty and HandlePropertyInClassExtension to /// Called by ActOnProperty and HandlePropertyInClassExtension to
/// handle creating the ObjcPropertyDecl for a category or \@interface. /// handle creating the ObjcPropertyDecl for a category or \@interface.
@ -6212,7 +6212,6 @@ public:
void DiagnosePropertyMismatch(ObjCPropertyDecl *Property, void DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
ObjCPropertyDecl *SuperProperty, ObjCPropertyDecl *SuperProperty,
const IdentifierInfo *Name); const IdentifierInfo *Name);
void ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl);
void CompareProperties(Decl *CDecl, Decl *MergeProtocols); void CompareProperties(Decl *CDecl, Decl *MergeProtocols);

View File

@ -2383,7 +2383,6 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) { if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
// Compares properties declared in this class to those of its // Compares properties declared in this class to those of its
// super class. // super class.
ComparePropertiesInBaseAndSuper(I);
CompareProperties(I, I); CompareProperties(I, I);
} else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) { } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
// Categories are used to extend the class by declaring new methods. // Categories are used to extend the class by declaring new methods.

View File

@ -139,34 +139,31 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
!(Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) && !(Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) &&
!(Attributes & ObjCDeclSpec::DQ_PR_weak))); !(Attributes & ObjCDeclSpec::DQ_PR_weak)));
// Proceed with constructing the ObjCPropertDecls. // Proceed with constructing the ObjCPropertyDecls.
ObjCContainerDecl *ClassDecl = cast<ObjCContainerDecl>(CurContext); ObjCContainerDecl *ClassDecl = cast<ObjCContainerDecl>(CurContext);
if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) ObjCPropertyDecl *Res = 0;
if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
if (CDecl->IsClassExtension()) { if (CDecl->IsClassExtension()) {
Decl *Res = HandlePropertyInClassExtension(S, AtLoc, LParenLoc, Res = HandlePropertyInClassExtension(S, AtLoc, LParenLoc,
FD, GetterSel, SetterSel, FD, GetterSel, SetterSel,
isAssign, isReadWrite, isAssign, isReadWrite,
Attributes, Attributes,
ODS.getPropertyAttributes(), ODS.getPropertyAttributes(),
isOverridingProperty, TSI, isOverridingProperty, TSI,
MethodImplKind); MethodImplKind);
if (Res) { if (!Res)
CheckObjCPropertyAttributes(Res, AtLoc, Attributes, false); return 0;
if (getLangOpts().ObjCAutoRefCount)
checkARCPropertyDecl(*this, cast<ObjCPropertyDecl>(Res));
}
ActOnDocumentableDecl(Res);
return Res;
} }
}
ObjCPropertyDecl *Res = CreatePropertyDecl(S, ClassDecl, AtLoc, LParenLoc, FD, if (!Res) {
GetterSel, SetterSel, Res = CreatePropertyDecl(S, ClassDecl, AtLoc, LParenLoc, FD,
isAssign, isReadWrite, GetterSel, SetterSel, isAssign, isReadWrite,
Attributes, Attributes, ODS.getPropertyAttributes(),
ODS.getPropertyAttributes(), TSI, MethodImplKind);
TSI, MethodImplKind); if (lexicalDC)
if (lexicalDC) Res->setLexicalDeclContext(lexicalDC);
Res->setLexicalDeclContext(lexicalDC); }
// Validate the attributes on the @property. // Validate the attributes on the @property.
CheckObjCPropertyAttributes(Res, AtLoc, Attributes, CheckObjCPropertyAttributes(Res, AtLoc, Attributes,
@ -176,6 +173,16 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
if (getLangOpts().ObjCAutoRefCount) if (getLangOpts().ObjCAutoRefCount)
checkARCPropertyDecl(*this, Res); checkARCPropertyDecl(*this, Res);
// Compare this property against the property in our superclass.
if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
if (ObjCInterfaceDecl *Super = IFace->getSuperClass()) {
DeclContext::lookup_result R = Super->lookup(Res->getDeclName());
for (unsigned I = 0, N = R.size(); I != N; ++I)
if (ObjCPropertyDecl *SuperProp = dyn_cast<ObjCPropertyDecl>(R[I]))
DiagnosePropertyMismatch(Res, SuperProp, Super->getIdentifier());
}
}
ActOnDocumentableDecl(Res); ActOnDocumentableDecl(Res);
return Res; return Res;
} }
@ -251,7 +258,7 @@ static unsigned getOwnershipRule(unsigned attr) {
ObjCPropertyDecl::OBJC_PR_unsafe_unretained); ObjCPropertyDecl::OBJC_PR_unsafe_unretained);
} }
Decl * ObjCPropertyDecl *
Sema::HandlePropertyInClassExtension(Scope *S, Sema::HandlePropertyInClassExtension(Scope *S,
SourceLocation AtLoc, SourceLocation AtLoc,
SourceLocation LParenLoc, SourceLocation LParenLoc,
@ -1276,30 +1283,6 @@ bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property,
return false; return false;
} }
/// ComparePropertiesInBaseAndSuper - This routine compares property
/// declarations in base and its super class, if any, and issues
/// diagnostics in a variety of inconsistent situations.
///
void Sema::ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl) {
ObjCInterfaceDecl *SDecl = IDecl->getSuperClass();
if (!SDecl)
return;
// FIXME: We should perform this check when the property in the subclass
// is declared.
for (ObjCInterfaceDecl::prop_iterator S = SDecl->prop_begin(),
E = SDecl->prop_end(); S != E; ++S) {
ObjCPropertyDecl *SuperPDecl = *S;
DeclContext::lookup_result Results
= IDecl->lookup(SuperPDecl->getDeclName());
for (unsigned I = 0, N = Results.size(); I != N; ++I) {
if (ObjCPropertyDecl *PDecl = dyn_cast<ObjCPropertyDecl>(Results[I])) {
DiagnosePropertyMismatch(PDecl, SuperPDecl,
SDecl->getIdentifier());
}
}
}
}
/// MatchOneProtocolPropertiesInClass - This routine goes thru the list /// MatchOneProtocolPropertiesInClass - This routine goes thru the list
/// of properties declared in a protocol and compares their attribute against /// of properties declared in a protocol and compares their attribute against
/// the same property declared in the class or category. /// the same property declared in the class or category.
@ -1340,7 +1323,7 @@ Sema::MatchOneProtocolPropertiesInClass(Decl *CDecl, ObjCProtocolDecl *PDecl) {
E = PDecl->prop_end(); P != E; ++P) { E = PDecl->prop_end(); P != E; ++P) {
ObjCPropertyDecl *ProtoProp = *P; ObjCPropertyDecl *ProtoProp = *P;
DeclContext::lookup_result R DeclContext::lookup_result R
= IDecl->lookup(ProtoProp->getDeclName()); = IDecl->lookup(ProtoProp->getDeclName());
for (unsigned I = 0, N = R.size(); I != N; ++I) { for (unsigned I = 0, N = R.size(); I != N; ++I) {
if (ObjCPropertyDecl *ClassProp = dyn_cast<ObjCPropertyDecl>(R[I])) { if (ObjCPropertyDecl *ClassProp = dyn_cast<ObjCPropertyDecl>(R[I])) {
if (ClassProp != ProtoProp) { if (ClassProp != ProtoProp) {