forked from OSchip/llvm-project
When using an unavailable/deprecated interface Foo inside Foo's interface/implementation
don't emit unavailable errors. llvm-svn: 141334
This commit is contained in:
parent
1456cd20b4
commit
9321ad3f97
|
@ -520,11 +520,11 @@ private:
|
||||||
explicit ObjCDeclContextSwitch(Parser &p) : P(p),
|
explicit ObjCDeclContextSwitch(Parser &p) : P(p),
|
||||||
DC(p.getObjCDeclContext()) {
|
DC(p.getObjCDeclContext()) {
|
||||||
if (DC)
|
if (DC)
|
||||||
P.Actions.ActOnObjCContainerFinishDefinition();
|
P.Actions.ActOnObjCTemporaryExitContainerContext();
|
||||||
}
|
}
|
||||||
~ObjCDeclContextSwitch() {
|
~ObjCDeclContextSwitch() {
|
||||||
if (DC)
|
if (DC)
|
||||||
P.Actions.ActOnObjCContainerStartDefinition(DC);
|
P.Actions.ActOnObjCReenterContainerContext();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -202,6 +202,10 @@ public:
|
||||||
/// CurContext - This is the current declaration context of parsing.
|
/// CurContext - This is the current declaration context of parsing.
|
||||||
DeclContext *CurContext;
|
DeclContext *CurContext;
|
||||||
|
|
||||||
|
/// \brief Generally null except when we temporarily switch decl contexts,
|
||||||
|
/// like in \see ActOnObjCTemporaryExitContainerContext.
|
||||||
|
DeclContext *OriginalLexicalContext;
|
||||||
|
|
||||||
/// VAListTagName - The declaration name corresponding to __va_list_tag.
|
/// VAListTagName - The declaration name corresponding to __va_list_tag.
|
||||||
/// This is used as part of a hack to omit that class from ADL results.
|
/// This is used as part of a hack to omit that class from ADL results.
|
||||||
DeclarationName VAListTagName;
|
DeclarationName VAListTagName;
|
||||||
|
@ -1224,7 +1228,7 @@ public:
|
||||||
/// struct, or union).
|
/// struct, or union).
|
||||||
void ActOnTagStartDefinition(Scope *S, Decl *TagDecl);
|
void ActOnTagStartDefinition(Scope *S, Decl *TagDecl);
|
||||||
|
|
||||||
void ActOnObjCContainerStartDefinition(Decl *IDecl);
|
Decl *ActOnObjCContainerStartDefinition(Decl *IDecl);
|
||||||
|
|
||||||
/// ActOnStartCXXMemberDeclarations - Invoked when we have parsed a
|
/// ActOnStartCXXMemberDeclarations - Invoked when we have parsed a
|
||||||
/// C++ record definition's base-specifiers clause and are starting its
|
/// C++ record definition's base-specifiers clause and are starting its
|
||||||
|
@ -1240,6 +1244,13 @@ public:
|
||||||
|
|
||||||
void ActOnObjCContainerFinishDefinition();
|
void ActOnObjCContainerFinishDefinition();
|
||||||
|
|
||||||
|
/// \brief Invoked when we must temporarily exit the objective-c container
|
||||||
|
/// scope for parsing/looking-up C constructs.
|
||||||
|
///
|
||||||
|
/// Must be followed by a call to \see ActOnObjCReenterContainerContext
|
||||||
|
void ActOnObjCTemporaryExitContainerContext();
|
||||||
|
void ActOnObjCReenterContainerContext();
|
||||||
|
|
||||||
/// ActOnTagDefinitionError - Invoked when there was an unrecoverable
|
/// ActOnTagDefinitionError - Invoked when there was an unrecoverable
|
||||||
/// error parsing the definition of a tag.
|
/// error parsing the definition of a tag.
|
||||||
void ActOnTagDefinitionError(Scope *S, Decl *TagDecl);
|
void ActOnTagDefinitionError(Scope *S, Decl *TagDecl);
|
||||||
|
@ -6150,6 +6161,10 @@ public:
|
||||||
Scope *getCurScope() const { return CurScope; }
|
Scope *getCurScope() const { return CurScope; }
|
||||||
|
|
||||||
Decl *getObjCDeclContext() const;
|
Decl *getObjCDeclContext() const;
|
||||||
|
|
||||||
|
DeclContext *getCurLexicalContext() const {
|
||||||
|
return OriginalLexicalContext ? OriginalLexicalContext : CurContext;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief RAII object that enters a new expression evaluation context.
|
/// \brief RAII object that enters a new expression evaluation context.
|
||||||
|
|
|
@ -336,7 +336,6 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
|
||||||
tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword;
|
tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword;
|
||||||
|
|
||||||
SourceRange AtEnd;
|
SourceRange AtEnd;
|
||||||
Actions.ActOnObjCContainerStartDefinition(CDecl);
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
// If this is a method prototype, parse it.
|
// If this is a method prototype, parse it.
|
||||||
|
@ -1195,6 +1194,7 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
|
||||||
SmallVector<Decl *, 32> AllIvarDecls;
|
SmallVector<Decl *, 32> AllIvarDecls;
|
||||||
|
|
||||||
ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope);
|
ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope);
|
||||||
|
ObjCDeclContextSwitch ObjCDC(*this);
|
||||||
|
|
||||||
SourceLocation LBraceLoc = ConsumeBrace(); // the "{"
|
SourceLocation LBraceLoc = ConsumeBrace(); // the "{"
|
||||||
|
|
||||||
|
@ -1441,7 +1441,6 @@ Decl *Parser::ParseObjCAtImplementationDeclaration(
|
||||||
atLoc, nameId, nameLoc, categoryId,
|
atLoc, nameId, nameLoc, categoryId,
|
||||||
categoryLoc);
|
categoryLoc);
|
||||||
|
|
||||||
Actions.ActOnObjCContainerStartDefinition(ImplCatType);
|
|
||||||
ObjCImpDecl = ImplCatType;
|
ObjCImpDecl = ImplCatType;
|
||||||
PendingObjCImpDecl.push_back(ObjCImpDecl);
|
PendingObjCImpDecl.push_back(ObjCImpDecl);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1466,7 +1465,6 @@ Decl *Parser::ParseObjCAtImplementationDeclaration(
|
||||||
if (Tok.is(tok::l_brace)) // we have ivars
|
if (Tok.is(tok::l_brace)) // we have ivars
|
||||||
ParseObjCClassInstanceVariables(ImplClsType, tok::objc_private, atLoc);
|
ParseObjCClassInstanceVariables(ImplClsType, tok::objc_private, atLoc);
|
||||||
|
|
||||||
Actions.ActOnObjCContainerStartDefinition(ImplClsType);
|
|
||||||
ObjCImpDecl = ImplClsType;
|
ObjCImpDecl = ImplClsType;
|
||||||
PendingObjCImpDecl.push_back(ObjCImpDecl);
|
PendingObjCImpDecl.push_back(ObjCImpDecl);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -95,7 +95,8 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
|
||||||
LangOpts(pp.getLangOptions()), PP(pp), Context(ctxt), Consumer(consumer),
|
LangOpts(pp.getLangOptions()), PP(pp), Context(ctxt), Consumer(consumer),
|
||||||
Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
|
Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
|
||||||
CollectStats(false), ExternalSource(0), CodeCompleter(CodeCompleter),
|
CollectStats(false), ExternalSource(0), CodeCompleter(CodeCompleter),
|
||||||
CurContext(0), PackContext(0), MSStructPragmaOn(false), VisContext(0),
|
CurContext(0), OriginalLexicalContext(0),
|
||||||
|
PackContext(0), MSStructPragmaOn(false), VisContext(0),
|
||||||
ExprNeedsCleanups(0), LateTemplateParser(0), OpaqueParser(0),
|
ExprNeedsCleanups(0), LateTemplateParser(0), OpaqueParser(0),
|
||||||
IdResolver(pp.getLangOptions()), CXXTypeInfoDecl(0), MSVCGuidDecl(0),
|
IdResolver(pp.getLangOptions()), CXXTypeInfoDecl(0), MSVCGuidDecl(0),
|
||||||
GlobalNewDeleteDeclared(false),
|
GlobalNewDeleteDeclared(false),
|
||||||
|
|
|
@ -8004,13 +8004,14 @@ void Sema::ActOnTagStartDefinition(Scope *S, Decl *TagD) {
|
||||||
PushDeclContext(S, Tag);
|
PushDeclContext(S, Tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sema::ActOnObjCContainerStartDefinition(Decl *IDecl) {
|
Decl *Sema::ActOnObjCContainerStartDefinition(Decl *IDecl) {
|
||||||
assert(isa<ObjCContainerDecl>(IDecl) &&
|
assert(isa<ObjCContainerDecl>(IDecl) &&
|
||||||
"ActOnObjCContainerStartDefinition - Not ObjCContainerDecl");
|
"ActOnObjCContainerStartDefinition - Not ObjCContainerDecl");
|
||||||
DeclContext *OCD = cast<DeclContext>(IDecl);
|
DeclContext *OCD = cast<DeclContext>(IDecl);
|
||||||
assert(getContainingDC(OCD) == CurContext &&
|
assert(getContainingDC(OCD) == CurContext &&
|
||||||
"The next DeclContext should be lexically contained in the current one.");
|
"The next DeclContext should be lexically contained in the current one.");
|
||||||
CurContext = OCD;
|
CurContext = OCD;
|
||||||
|
return IDecl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sema::ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagD,
|
void Sema::ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagD,
|
||||||
|
@ -8069,6 +8070,16 @@ void Sema::ActOnObjCContainerFinishDefinition() {
|
||||||
PopDeclContext();
|
PopDeclContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sema::ActOnObjCTemporaryExitContainerContext() {
|
||||||
|
OriginalLexicalContext = CurContext;
|
||||||
|
ActOnObjCContainerFinishDefinition();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sema::ActOnObjCReenterContainerContext() {
|
||||||
|
ActOnObjCContainerStartDefinition(cast<Decl>(OriginalLexicalContext));
|
||||||
|
OriginalLexicalContext = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void Sema::ActOnTagDefinitionError(Scope *S, Decl *TagD) {
|
void Sema::ActOnTagDefinitionError(Scope *S, Decl *TagD) {
|
||||||
AdjustDeclIfTemplate(TagD);
|
AdjustDeclIfTemplate(TagD);
|
||||||
TagDecl *Tag = cast<TagDecl>(TagD);
|
TagDecl *Tag = cast<TagDecl>(TagD);
|
||||||
|
|
|
@ -4031,7 +4031,7 @@ void Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, don't warn if our current context is deprecated.
|
// Otherwise, don't warn if our current context is deprecated.
|
||||||
if (isDeclDeprecated(cast<Decl>(CurContext)))
|
if (isDeclDeprecated(cast<Decl>(getCurLexicalContext())))
|
||||||
return;
|
return;
|
||||||
if (!Message.empty())
|
if (!Message.empty())
|
||||||
Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
|
Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
|
||||||
|
|
|
@ -374,7 +374,7 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
|
||||||
|
|
||||||
// Return the previous class interface.
|
// Return the previous class interface.
|
||||||
// FIXME: don't leak the objects passed in!
|
// FIXME: don't leak the objects passed in!
|
||||||
return IDecl;
|
return ActOnObjCContainerStartDefinition(IDecl);
|
||||||
} else {
|
} else {
|
||||||
IDecl->setLocation(ClassLoc);
|
IDecl->setLocation(ClassLoc);
|
||||||
IDecl->setForwardDecl(false);
|
IDecl->setForwardDecl(false);
|
||||||
|
@ -482,7 +482,7 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckObjCDeclScope(IDecl);
|
CheckObjCDeclScope(IDecl);
|
||||||
return IDecl;
|
return ActOnObjCContainerStartDefinition(IDecl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ActOnCompatiblityAlias - this action is called after complete parsing of
|
/// ActOnCompatiblityAlias - this action is called after complete parsing of
|
||||||
|
@ -578,7 +578,7 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
|
||||||
Diag(PDecl->getLocation(), diag::note_previous_definition);
|
Diag(PDecl->getLocation(), diag::note_previous_definition);
|
||||||
// Just return the protocol we already had.
|
// Just return the protocol we already had.
|
||||||
// FIXME: don't leak the objects passed in!
|
// FIXME: don't leak the objects passed in!
|
||||||
return PDecl;
|
return ActOnObjCContainerStartDefinition(PDecl);
|
||||||
}
|
}
|
||||||
ObjCList<ObjCProtocolDecl> PList;
|
ObjCList<ObjCProtocolDecl> PList;
|
||||||
PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context);
|
PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context);
|
||||||
|
@ -611,7 +611,7 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckObjCDeclScope(PDecl);
|
CheckObjCDeclScope(PDecl);
|
||||||
return PDecl;
|
return ActOnObjCContainerStartDefinition(PDecl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// FindProtocolDeclaration - This routine looks up protocols and
|
/// FindProtocolDeclaration - This routine looks up protocols and
|
||||||
|
@ -741,7 +741,7 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
|
||||||
ClassLoc, CategoryLoc, CategoryName,IDecl);
|
ClassLoc, CategoryLoc, CategoryName,IDecl);
|
||||||
CDecl->setInvalidDecl();
|
CDecl->setInvalidDecl();
|
||||||
Diag(ClassLoc, diag::err_undef_interface) << ClassName;
|
Diag(ClassLoc, diag::err_undef_interface) << ClassName;
|
||||||
return CDecl;
|
return ActOnObjCContainerStartDefinition(CDecl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CategoryName && IDecl->getImplementation()) {
|
if (!CategoryName && IDecl->getImplementation()) {
|
||||||
|
@ -783,7 +783,7 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckObjCDeclScope(CDecl);
|
CheckObjCDeclScope(CDecl);
|
||||||
return CDecl;
|
return ActOnObjCContainerStartDefinition(CDecl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ActOnStartCategoryImplementation - Perform semantic checks on the
|
/// ActOnStartCategoryImplementation - Perform semantic checks on the
|
||||||
|
@ -836,7 +836,7 @@ Decl *Sema::ActOnStartCategoryImplementation(
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckObjCDeclScope(CDecl);
|
CheckObjCDeclScope(CDecl);
|
||||||
return CDecl;
|
return ActOnObjCContainerStartDefinition(CDecl);
|
||||||
}
|
}
|
||||||
|
|
||||||
Decl *Sema::ActOnStartClassImplementation(
|
Decl *Sema::ActOnStartClassImplementation(
|
||||||
|
@ -930,7 +930,7 @@ Decl *Sema::ActOnStartClassImplementation(
|
||||||
ClassLoc, AtClassImplLoc);
|
ClassLoc, AtClassImplLoc);
|
||||||
|
|
||||||
if (CheckObjCDeclScope(IMPDecl))
|
if (CheckObjCDeclScope(IMPDecl))
|
||||||
return IMPDecl;
|
return ActOnObjCContainerStartDefinition(IMPDecl);
|
||||||
|
|
||||||
// Check that there is no duplicate implementation of this class.
|
// Check that there is no duplicate implementation of this class.
|
||||||
if (IDecl->getImplementation()) {
|
if (IDecl->getImplementation()) {
|
||||||
|
@ -947,7 +947,7 @@ Decl *Sema::ActOnStartClassImplementation(
|
||||||
dyn_cast<NamedDecl>(IDecl),
|
dyn_cast<NamedDecl>(IDecl),
|
||||||
IMPDecl->getLocation(), 1);
|
IMPDecl->getLocation(), 1);
|
||||||
}
|
}
|
||||||
return IMPDecl;
|
return ActOnObjCContainerStartDefinition(IMPDecl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
|
void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
|
||||||
|
|
|
@ -72,7 +72,8 @@ static AvailabilityResult DiagnoseAvailabilityOfDecl(Sema &S,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AR_Unavailable:
|
case AR_Unavailable:
|
||||||
if (cast<Decl>(S.CurContext)->getAvailability() != AR_Unavailable) {
|
if (cast<Decl>(S.getCurLexicalContext())->getAvailability() !=
|
||||||
|
AR_Unavailable) {
|
||||||
if (Message.empty()) {
|
if (Message.empty()) {
|
||||||
if (!UnknownObjCClass)
|
if (!UnknownObjCClass)
|
||||||
S.Diag(Loc, diag::err_unavailable) << D->getDeclName();
|
S.Diag(Loc, diag::err_unavailable) << D->getDeclName();
|
||||||
|
|
|
@ -85,8 +85,10 @@ int t5() {
|
||||||
__attribute ((deprecated))
|
__attribute ((deprecated))
|
||||||
@interface DEPRECATED {
|
@interface DEPRECATED {
|
||||||
@public int ivar;
|
@public int ivar;
|
||||||
|
DEPRECATED *ivar2; // no warning.
|
||||||
}
|
}
|
||||||
- (int) instancemethod;
|
- (int) instancemethod;
|
||||||
|
- (DEPRECATED *) meth; // no warning.
|
||||||
@property int prop;
|
@property int prop;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -2,17 +2,25 @@
|
||||||
// rdar://9092208
|
// rdar://9092208
|
||||||
|
|
||||||
__attribute__((unavailable("not available")))
|
__attribute__((unavailable("not available")))
|
||||||
@interface MyClass { // expected-note 5 {{declaration has been explicitly marked unavailable here}}
|
@interface MyClass { // expected-note 7 {{declaration has been explicitly marked unavailable here}}
|
||||||
@public
|
@public
|
||||||
void *_test;
|
void *_test;
|
||||||
|
MyClass *ivar; // no error.
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)self;
|
- (id)self;
|
||||||
- new;
|
- new;
|
||||||
+ (void)addObject:(id)anObject;
|
+ (void)addObject:(id)anObject;
|
||||||
|
- (MyClass *)meth; // no error.
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@interface Foo {
|
||||||
|
MyClass *ivar; // expected-error {{unavailable}}
|
||||||
|
}
|
||||||
|
- (MyClass *)meth; // expected-error {{unavailable}}
|
||||||
|
@end
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
[MyClass new]; // expected-error {{'MyClass' is unavailable: not available}}
|
[MyClass new]; // expected-error {{'MyClass' is unavailable: not available}}
|
||||||
[MyClass self]; // expected-error {{'MyClass' is unavailable: not available}}
|
[MyClass self]; // expected-error {{'MyClass' is unavailable: not available}}
|
||||||
|
|
Loading…
Reference in New Issue