Extend warnings for missing '@end'.

Fixes PR2709.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145928 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Erik Verbruggen 2011-12-06 09:25:23 +00:00
Родитель 26b45d8608
Коммит d64251fd56
14 изменённых файлов: 128 добавлений и 62 удалений

Просмотреть файл

@ -35,7 +35,7 @@ namespace clang {
DIAG_START_FRONTEND = DIAG_START_DRIVER + 100, DIAG_START_FRONTEND = DIAG_START_DRIVER + 100,
DIAG_START_LEX = DIAG_START_FRONTEND + 120, DIAG_START_LEX = DIAG_START_FRONTEND + 120,
DIAG_START_PARSE = DIAG_START_LEX + 300, DIAG_START_PARSE = DIAG_START_LEX + 300,
DIAG_START_AST = DIAG_START_PARSE + 300, DIAG_START_AST = DIAG_START_PARSE + 350,
DIAG_START_SEMA = DIAG_START_AST + 100, DIAG_START_SEMA = DIAG_START_AST + 100,
DIAG_START_ANALYSIS = DIAG_START_SEMA + 3000, DIAG_START_ANALYSIS = DIAG_START_SEMA + 3000,
DIAG_UPPER_LIMIT = DIAG_START_ANALYSIS + 100 DIAG_UPPER_LIMIT = DIAG_START_ANALYSIS + 100

Просмотреть файл

@ -313,7 +313,10 @@ def err_expected_minus_or_plus : Error<
"method type specifier must start with '-' or '+'">; "method type specifier must start with '-' or '+'">;
def err_objc_no_attributes_on_category : Error< def err_objc_no_attributes_on_category : Error<
"attributes may not be specified on a category">; "attributes may not be specified on a category">;
def err_objc_missing_end : Error<"missing @end">; def err_objc_missing_end : Error<"missing '@end'">;
def note_objc_container_start : Note<
"%select{class|protocol|category|class extension|implementation"
"|category implementation}0 started here">;
def warn_objc_protocol_qualifier_missing_id : Warning< def warn_objc_protocol_qualifier_missing_id : Warning<
"protocol qualifiers without 'id' is archaic">; "protocol qualifiers without 'id' is archaic">;
def err_objc_unknown_at : Error<"expected an Objective-C directive after '@'">; def err_objc_unknown_at : Error<"expected an Objective-C directive after '@'">;
@ -352,8 +355,8 @@ def err_missing_id_definition : Error<"cannot find definition of 'id'">;
def err_missing_proto_definition : Error< def err_missing_proto_definition : Error<
"cannot find definition of 'Protocol'">; "cannot find definition of 'Protocol'">;
def err_missing_class_definition : Error<"cannot find definition of 'Class'">; def err_missing_class_definition : Error<"cannot find definition of 'Class'">;
def err_expected_implementation : Error< def err_expected_objc_container : Error<
"@end must appear in an @implementation context">; "'@end' must appear in an Objective-C context">;
def error_property_ivar_decl : Error< def error_property_ivar_decl : Error<
"property synthesize requires specification of an ivar">; "property synthesize requires specification of an ivar">;
def err_synthesized_property_name : Error< def err_synthesized_property_name : Error<

Просмотреть файл

@ -488,7 +488,6 @@ def note_declared_at : Note<"declared here">;
def note_method_declared_at : Note<"method declared here">; def note_method_declared_at : Note<"method declared here">;
def err_setter_type_void : Error<"type of setter must be void">; def err_setter_type_void : Error<"type of setter must be void">;
def err_duplicate_method_decl : Error<"duplicate declaration of method %0">; def err_duplicate_method_decl : Error<"duplicate declaration of method %0">;
def err_missing_atend : Error<"'@end' is missing in implementation context">;
def err_objc_var_decl_inclass : def err_objc_var_decl_inclass :
Error<"cannot declare variable inside @interface or @protocol">; Error<"cannot declare variable inside @interface or @protocol">;
def error_missing_method_context : Error< def error_missing_method_context : Error<

Просмотреть файл

@ -716,6 +716,7 @@ public:
private: private:
void SuggestParentheses(SourceLocation Loc, unsigned DK, void SuggestParentheses(SourceLocation Loc, unsigned DK,
SourceRange ParenRange); SourceRange ParenRange);
void CheckNestedObjCContexts(SourceLocation AtLoc);
/// SkipUntil - Read tokens until we get to the specified token, then consume /// SkipUntil - Read tokens until we get to the specified token, then consume
/// it (unless DontConsume is true). Because we cannot guarantee that the /// it (unless DontConsume is true). Because we cannot guarantee that the
@ -1204,7 +1205,7 @@ private:
// Objective-C External Declarations // Objective-C External Declarations
Parser::DeclGroupPtrTy ParseObjCAtDirectives(); Parser::DeclGroupPtrTy ParseObjCAtDirectives();
Parser::DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc); Parser::DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc);
Decl *ParseObjCAtInterfaceDeclaration(SourceLocation atLoc, Decl *ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
ParsedAttributes &prefixAttrs); ParsedAttributes &prefixAttrs);
void ParseObjCClassInstanceVariables(Decl *interfaceDecl, void ParseObjCClassInstanceVariables(Decl *interfaceDecl,
tok::ObjCKeywordKind visibility, tok::ObjCKeywordKind visibility,
@ -1225,7 +1226,7 @@ private:
typedef SmallVector<LexedMethod*, 2> LateParsedObjCMethodContainer; typedef SmallVector<LexedMethod*, 2> LateParsedObjCMethodContainer;
LateParsedObjCMethodContainer LateParsedObjCMethods; LateParsedObjCMethodContainer LateParsedObjCMethods;
Decl *ParseObjCAtImplementationDeclaration(SourceLocation atLoc); Decl *ParseObjCAtImplementationDeclaration(SourceLocation AtLoc);
DeclGroupPtrTy ParseObjCAtEndDeclaration(SourceRange atEnd); DeclGroupPtrTy ParseObjCAtEndDeclaration(SourceRange atEnd);
Decl *ParseObjCAtAliasDeclaration(SourceLocation atLoc); Decl *ParseObjCAtAliasDeclaration(SourceLocation atLoc);
Decl *ParseObjCPropertySynthesize(SourceLocation atLoc); Decl *ParseObjCPropertySynthesize(SourceLocation atLoc);

Просмотреть файл

@ -5173,6 +5173,17 @@ public:
const MultiLevelTemplateArgumentList &TemplateArgs); const MultiLevelTemplateArgumentList &TemplateArgs);
// Objective-C declarations. // Objective-C declarations.
enum ObjCContainerKind {
OCK_None = -1,
OCK_Interface = 0,
OCK_Protocol,
OCK_Category,
OCK_ClassExtension,
OCK_Implementation,
OCK_CategoryImplementation
};
ObjCContainerKind getObjCContainerKind() const;
Decl *ActOnStartClassInterface(SourceLocation AtInterfaceLoc, Decl *ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
IdentifierInfo *ClassName, IdentifierInfo *ClassName,
SourceLocation ClassLoc, SourceLocation ClassLoc,
@ -5275,10 +5286,10 @@ public:
void MatchOneProtocolPropertiesInClass(Decl *CDecl, void MatchOneProtocolPropertiesInClass(Decl *CDecl,
ObjCProtocolDecl *PDecl); ObjCProtocolDecl *PDecl);
void ActOnAtEnd(Scope *S, SourceRange AtEnd, Decl *ActOnAtEnd(Scope *S, SourceRange AtEnd,
Decl **allMethods = 0, unsigned allNum = 0, Decl **allMethods = 0, unsigned allNum = 0,
Decl **allProperties = 0, unsigned pNum = 0, Decl **allProperties = 0, unsigned pNum = 0,
DeclGroupPtrTy *allTUVars = 0, unsigned tuvNum = 0); DeclGroupPtrTy *allTUVars = 0, unsigned tuvNum = 0);
Decl *ActOnProperty(Scope *S, SourceLocation AtLoc, Decl *ActOnProperty(Scope *S, SourceLocation AtLoc,
FieldDeclarator &FD, ObjCDeclSpec &ODS, FieldDeclarator &FD, ObjCDeclSpec &ODS,

Просмотреть файл

@ -113,6 +113,23 @@ Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {
ClassNames.size()); ClassNames.size());
} }
void Parser::CheckNestedObjCContexts(SourceLocation AtLoc)
{
Sema::ObjCContainerKind ock = Actions.getObjCContainerKind();
if (ock == Sema::OCK_None)
return;
Decl *Decl = Actions.ActOnAtEnd(getCurScope(), AtLoc);
Diag(AtLoc, diag::err_objc_missing_end)
<< FixItHint::CreateInsertion(AtLoc, "@end\n");
if (Decl)
Diag(Decl->getLocStart(), diag::note_objc_container_start)
<< (int) ock;
if (!PendingObjCImpDecl.empty())
PendingObjCImpDecl.pop_back();
ObjCImpDecl = 0;
}
/// ///
/// objc-interface: /// objc-interface:
/// objc-class-interface-attributes[opt] objc-class-interface /// objc-class-interface-attributes[opt] objc-class-interface
@ -141,10 +158,11 @@ Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {
/// __attribute__((unavailable)) /// __attribute__((unavailable))
/// __attribute__((objc_exception)) - used by NSException on 64-bit /// __attribute__((objc_exception)) - used by NSException on 64-bit
/// ///
Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation atLoc, Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
ParsedAttributes &attrs) { ParsedAttributes &attrs) {
assert(Tok.isObjCAtKeyword(tok::objc_interface) && assert(Tok.isObjCAtKeyword(tok::objc_interface) &&
"ParseObjCAtInterfaceDeclaration(): Expected @interface"); "ParseObjCAtInterfaceDeclaration(): Expected @interface");
CheckNestedObjCContexts(AtLoc);
ConsumeToken(); // the "interface" identifier ConsumeToken(); // the "interface" identifier
// Code completion after '@interface'. // Code completion after '@interface'.
@ -205,7 +223,7 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
return 0; return 0;
Decl *CategoryType = Decl *CategoryType =
Actions.ActOnStartCategoryInterface(atLoc, Actions.ActOnStartCategoryInterface(AtLoc,
nameId, nameLoc, nameId, nameLoc,
categoryId, categoryLoc, categoryId, categoryLoc,
ProtocolRefs.data(), ProtocolRefs.data(),
@ -214,7 +232,7 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
EndProtoLoc); EndProtoLoc);
if (Tok.is(tok::l_brace)) if (Tok.is(tok::l_brace))
ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, atLoc); ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, AtLoc);
ParseObjCInterfaceDeclList(tok::objc_not_keyword, CategoryType); ParseObjCInterfaceDeclList(tok::objc_not_keyword, CategoryType);
return CategoryType; return CategoryType;
@ -250,14 +268,14 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
return 0; return 0;
Decl *ClsType = Decl *ClsType =
Actions.ActOnStartClassInterface(atLoc, nameId, nameLoc, Actions.ActOnStartClassInterface(AtLoc, nameId, nameLoc,
superClassId, superClassLoc, superClassId, superClassLoc,
ProtocolRefs.data(), ProtocolRefs.size(), ProtocolRefs.data(), ProtocolRefs.size(),
ProtocolLocs.data(), ProtocolLocs.data(),
EndProtoLoc, attrs.getList()); EndProtoLoc, attrs.getList());
if (Tok.is(tok::l_brace)) if (Tok.is(tok::l_brace))
ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, atLoc); ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, AtLoc);
ParseObjCInterfaceDeclList(tok::objc_interface, ClsType); ParseObjCInterfaceDeclList(tok::objc_interface, ClsType);
return ClsType; return ClsType;
@ -425,7 +443,10 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
case tok::objc_implementation: case tok::objc_implementation:
case tok::objc_interface: case tok::objc_interface:
Diag(Tok, diag::err_objc_missing_end); Diag(AtLoc, diag::err_objc_missing_end)
<< FixItHint::CreateInsertion(AtLoc, "@end\n");
Diag(CDecl->getLocStart(), diag::note_objc_container_start)
<< (int) Actions.getObjCContainerKind();
ConsumeToken(); ConsumeToken();
break; break;
@ -465,10 +486,16 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
if (Tok.is(tok::code_completion)) { if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteObjCAtDirective(getCurScope()); Actions.CodeCompleteObjCAtDirective(getCurScope());
return cutOffParsing(); return cutOffParsing();
} else if (Tok.isObjCAtKeyword(tok::objc_end)) } else if (Tok.isObjCAtKeyword(tok::objc_end)) {
ConsumeToken(); // the "end" identifier ConsumeToken(); // the "end" identifier
else } else {
Diag(Tok, diag::err_objc_missing_end); Diag(Tok, diag::err_objc_missing_end)
<< FixItHint::CreateInsertion(Tok.getLocation(), "\n@end\n");
Diag(CDecl->getLocStart(), diag::note_objc_container_start)
<< (int) Actions.getObjCContainerKind();
AtEnd.setBegin(Tok.getLocation());
AtEnd.setEnd(Tok.getLocation());
}
// Insert collected methods declarations into the @interface object. // Insert collected methods declarations into the @interface object.
// This passes in an invalid SourceLocation for AtEndLoc when EOF is hit. // This passes in an invalid SourceLocation for AtEndLoc when EOF is hit.
@ -1316,6 +1343,7 @@ Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
ParsedAttributes &attrs) { ParsedAttributes &attrs) {
assert(Tok.isObjCAtKeyword(tok::objc_protocol) && assert(Tok.isObjCAtKeyword(tok::objc_protocol) &&
"ParseObjCAtProtocolDeclaration(): Expected @protocol"); "ParseObjCAtProtocolDeclaration(): Expected @protocol");
CheckNestedObjCContexts(AtLoc);
ConsumeToken(); // the "protocol" identifier ConsumeToken(); // the "protocol" identifier
if (Tok.is(tok::code_completion)) { if (Tok.is(tok::code_completion)) {
@ -1399,10 +1427,10 @@ Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
/// ///
/// objc-category-implementation-prologue: /// objc-category-implementation-prologue:
/// @implementation identifier ( identifier ) /// @implementation identifier ( identifier )
Decl *Parser::ParseObjCAtImplementationDeclaration( Decl *Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc) {
SourceLocation atLoc) {
assert(Tok.isObjCAtKeyword(tok::objc_implementation) && assert(Tok.isObjCAtKeyword(tok::objc_implementation) &&
"ParseObjCAtImplementationDeclaration(): Expected @implementation"); "ParseObjCAtImplementationDeclaration(): Expected @implementation");
CheckNestedObjCContexts(AtLoc);
ConsumeToken(); // the "implementation" identifier ConsumeToken(); // the "implementation" identifier
// Code completion after '@implementation'. // Code completion after '@implementation'.
@ -1446,7 +1474,7 @@ Decl *Parser::ParseObjCAtImplementationDeclaration(
} }
rparenLoc = ConsumeParen(); rparenLoc = ConsumeParen();
Decl *ImplCatType = Actions.ActOnStartCategoryImplementation( Decl *ImplCatType = Actions.ActOnStartCategoryImplementation(
atLoc, nameId, nameLoc, categoryId, AtLoc, nameId, nameLoc, categoryId,
categoryLoc); categoryLoc);
ObjCImpDecl = ImplCatType; ObjCImpDecl = ImplCatType;
@ -1467,11 +1495,11 @@ Decl *Parser::ParseObjCAtImplementationDeclaration(
superClassLoc = ConsumeToken(); // Consume super class name superClassLoc = ConsumeToken(); // Consume super class name
} }
Decl *ImplClsType = Actions.ActOnStartClassImplementation( Decl *ImplClsType = Actions.ActOnStartClassImplementation(
atLoc, nameId, nameLoc, AtLoc, nameId, nameLoc,
superClassId, superClassLoc); superClassId, superClassLoc);
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);
ObjCImpDecl = ImplClsType; ObjCImpDecl = ImplClsType;
PendingObjCImpDecl.push_back(ObjCImpDecl); PendingObjCImpDecl.push_back(ObjCImpDecl);
@ -1498,7 +1526,7 @@ Parser::ParseObjCAtEndDeclaration(SourceRange atEnd) {
} }
else else
// missing @implementation // missing @implementation
Diag(atEnd.getBegin(), diag::err_expected_implementation); Diag(atEnd.getBegin(), diag::err_expected_objc_container);
clearLateParsedObjCMethods(); clearLateParsedObjCMethods();
ObjCImpDecl = 0; ObjCImpDecl = 0;
@ -1510,8 +1538,15 @@ Parser::DeclGroupPtrTy Parser::FinishPendingObjCActions() {
Actions.DiagnoseUseOfUnimplementedSelectors(); Actions.DiagnoseUseOfUnimplementedSelectors();
if (PendingObjCImpDecl.empty()) if (PendingObjCImpDecl.empty())
return Actions.ConvertDeclToDeclGroup(0); return Actions.ConvertDeclToDeclGroup(0);
Decl *ImpDecl = PendingObjCImpDecl.pop_back_val(); Decl *ImpDecl = PendingObjCImpDecl.pop_back_val();
Actions.ActOnAtEnd(getCurScope(), SourceRange()); Actions.ActOnAtEnd(getCurScope(), SourceRange(Tok.getLocation()));
Diag(Tok, diag::err_objc_missing_end)
<< FixItHint::CreateInsertion(Tok.getLocation(), "\n@end\n");
if (ImpDecl)
Diag(ImpDecl->getLocStart(), diag::note_objc_container_start)
<< Sema::OCK_Implementation;
return Actions.ConvertDeclToDeclGroup(ImpDecl); return Actions.ConvertDeclToDeclGroup(ImpDecl);
} }

Просмотреть файл

@ -2148,15 +2148,39 @@ void Sema::DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID,
} }
} }
Sema::ObjCContainerKind Sema::getObjCContainerKind() const {
switch (CurContext->getDeclKind()) {
case Decl::ObjCInterface:
return Sema::OCK_Interface;
case Decl::ObjCProtocol:
return Sema::OCK_Protocol;
case Decl::ObjCCategory:
if (dyn_cast<ObjCCategoryDecl>(CurContext)->IsClassExtension())
return Sema::OCK_ClassExtension;
else
return Sema::OCK_Category;
case Decl::ObjCImplementation:
return Sema::OCK_Implementation;
case Decl::ObjCCategoryImpl:
return Sema::OCK_CategoryImplementation;
default:
return Sema::OCK_None;
}
}
// Note: For class/category implemenations, allMethods/allProperties is // Note: For class/category implemenations, allMethods/allProperties is
// always null. // always null.
void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
Decl **allMethods, unsigned allNum, Decl **allMethods, unsigned allNum,
Decl **allProperties, unsigned pNum, Decl **allProperties, unsigned pNum,
DeclGroupPtrTy *allTUVars, unsigned tuvNum) { DeclGroupPtrTy *allTUVars, unsigned tuvNum) {
if (getObjCContainerKind() == Sema::OCK_None)
return 0;
assert(AtEnd.isValid() && "Invalid location for '@end'");
if (!CurContext->isObjCContainer())
return;
ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext); ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext);
Decl *ClassDecl = cast<Decl>(OCD); Decl *ClassDecl = cast<Decl>(OCD);
@ -2165,15 +2189,6 @@ void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
|| isa<ObjCProtocolDecl>(ClassDecl); || isa<ObjCProtocolDecl>(ClassDecl);
bool checkIdenticalMethods = isa<ObjCImplementationDecl>(ClassDecl); bool checkIdenticalMethods = isa<ObjCImplementationDecl>(ClassDecl);
if (!isInterfaceDeclKind && AtEnd.isInvalid()) {
// FIXME: This is wrong. We shouldn't be pretending that there is
// an '@end' in the declaration.
SourceLocation L = OCD->getAtStartLoc();
AtEnd.setBegin(L);
AtEnd.setEnd(L);
Diag(L, diag::err_missing_atend);
}
// FIXME: Remove these and use the ObjCContainerDecl/DeclContext. // FIXME: Remove these and use the ObjCContainerDecl/DeclContext.
llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap; llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap;
llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap; llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap;
@ -2335,6 +2350,8 @@ void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
(*I)->setTopLevelDeclInObjCContainer(); (*I)->setTopLevelDeclInObjCContainer();
Consumer.HandleTopLevelDeclInObjCContainer(DG); Consumer.HandleTopLevelDeclInObjCContainer(DG);
} }
return ClassDecl;
} }

Просмотреть файл

@ -4,4 +4,4 @@
@interface Rdar8452791 () - (void)rdar8452791; @interface Rdar8452791 () - (void)rdar8452791;
// CHECK: error: cannot find interface declaration for 'Rdar8452791' // CHECK: error: cannot find interface declaration for 'Rdar8452791'
// CHECK: missing @end // CHECK: missing '@end'

Просмотреть файл

@ -1,19 +1,19 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s // RUN: %clang_cc1 -fsyntax-only -verify %s
// rdar: //7824372 // rdar: //7824372
@interface A @interface A // expected-note {{class started here}}
-(void) im0; -(void) im0;
@implementation A // expected-error {{missing @end}} @implementation A // expected-error {{missing '@end'}}
@end @end
@interface B { @interface B { // expected-note {{class started here}}
} }
@implementation B // expected-error {{missing @end}} @implementation B // expected-error {{missing '@end'}}
@end @end
@interface C @interface C // expected-note 2 {{class started here}}
@property int P; @property int P;
@implementation C // expected-error 2 {{missing @end}} @implementation C // expected-error 2 {{missing '@end'}}

Просмотреть файл

@ -1,10 +1,10 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s // RUN: %clang_cc1 -fsyntax-only -verify %s
// rdar://8283484 // rdar://8283484
@interface blah { @interface blah { // expected-note {{class started here}}
@private @private
} }
// since I forgot the @end here it should say something // since I forgot the @end here it should say something
@interface blah // expected-error {{missing @end}} @interface blah // expected-error {{missing '@end'}}
@end // and Unknown type name 'end' here @end // and Unknown type name 'end' here

Просмотреть файл

@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s // RUN: %clang_cc1 -fsyntax-only -verify %s
@interface AAA @interface AAA // expected-note {{class started here}}
{ {
} }
@ x// expected-error{{expected an Objective-C directive after '@'}} @ x// expected-error{{expected an Objective-C directive after '@'}}
// expected-error{{missing @end}} // expected-error{{missing '@end'}}

Просмотреть файл

@ -1,2 +1,2 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s // RUN: %clang_cc1 -fsyntax-only -verify %s
@end // expected-error {{@end must appear in an @implementation context}} @end // expected-error {{'@end' must appear in an Objective-C context}}

Просмотреть файл

@ -5,8 +5,8 @@ int @"s" = 5; // expected-error {{prefix attribute must be}}
// rdar://6480479 // rdar://6480479
@interface A @interface A // expected-note {{class started here}}
}; // expected-error {{missing @end}} \ }; // expected-error {{missing '@end'}} \
// expected-error {{expected external declaration}} \ // expected-error {{expected external declaration}} \
// expected-warning{{extra ';' outside of a function}} // expected-warning{{extra ';' outside of a function}}

Просмотреть файл

@ -3,20 +3,20 @@
@interface I0 @interface I0
@end @end
@implementation I0 // expected-error {{'@end' is missing in implementation context}} @implementation I0 // expected-note {{implementation started here}}
- meth { return 0; } - meth { return 0; }
@interface I1 : I0 @interface I1 : I0 // expected-error {{missing '@end'}}
@end @end
@implementation I1 // expected-error {{'@end' is missing in implementation context}} @implementation I1 // expected-note {{implementation started here}}
-(void) im0 { self = [super init]; } -(void) im0 { self = [super init]; }
@interface I2 : I0 @interface I2 : I0 // expected-error {{missing '@end'}}
- I2meth; - I2meth;
@end @end
@implementation I2 // expected-error {{'@end' is missing in implementation context}} @implementation I2 // expected-note {{implementation started here}}
- I2meth { return 0; } - I2meth { return 0; }
@implementation I2(CAT) // expected-error {{'@end' is missing in implementation context}} @implementation I2(CAT) // expected-error 2 {{missing '@end'}} expected-note {{implementation started here}}