diff --git a/clang/AST/Decl.cpp b/clang/AST/Decl.cpp index 30ca5e6e1ba2..804e9ccabfef 100644 --- a/clang/AST/Decl.cpp +++ b/clang/AST/Decl.cpp @@ -293,13 +293,15 @@ ObjcMethodDecl::~ObjcMethodDecl() { /// ObjcAddInstanceVariablesToClass - Inserts instance variables /// into ObjcInterfaceDecl's fields. /// -void ObjcInterfaceDecl::ObjcAddInstanceVariablesToClass(ObjcIvarDecl **ivars, - unsigned numIvars) { +void ObjcInterfaceDecl::addInstanceVariablesToClass(ObjcIvarDecl **ivars, + unsigned numIvars, + SourceLocation RB) { NumIvars = numIvars; if (numIvars) { Ivars = new ObjcIvarDecl*[numIvars]; memcpy(Ivars, ivars, numIvars*sizeof(ObjcIvarDecl*)); } + RBracLoc = RB; } /// ObjcAddInstanceVariablesToClassImpl - Checks for correctness of Instance @@ -315,13 +317,14 @@ void ObjcImplementationDecl::ObjcAddInstanceVariablesToClassImpl( } } -/// addObjcMethods - Insert instance and methods declarations into +/// addMethods - Insert instance and methods declarations into /// ObjcInterfaceDecl's InsMethods and ClsMethods fields. /// -void ObjcInterfaceDecl::ObjcAddMethods(ObjcMethodDecl **insMethods, - unsigned numInsMembers, - ObjcMethodDecl **clsMethods, - unsigned numClsMembers) { +void ObjcInterfaceDecl::addMethods(ObjcMethodDecl **insMethods, + unsigned numInsMembers, + ObjcMethodDecl **clsMethods, + unsigned numClsMembers, + SourceLocation endLoc) { NumInstanceMethods = numInsMembers; if (numInsMembers) { InstanceMethods = new ObjcMethodDecl*[numInsMembers]; @@ -332,15 +335,17 @@ void ObjcInterfaceDecl::ObjcAddMethods(ObjcMethodDecl **insMethods, ClassMethods = new ObjcMethodDecl*[numClsMembers]; memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjcMethodDecl*)); } + EndLoc = endLoc; } -/// ObjcAddProtoMethods - Insert instance and methods declarations into +/// addMethods - Insert instance and methods declarations into /// ObjcProtocolDecl's ProtoInsMethods and ProtoClsMethods fields. /// -void ObjcProtocolDecl::ObjcAddProtoMethods(ObjcMethodDecl **insMethods, - unsigned numInsMembers, - ObjcMethodDecl **clsMethods, - unsigned numClsMembers) { +void ObjcProtocolDecl::addMethods(ObjcMethodDecl **insMethods, + unsigned numInsMembers, + ObjcMethodDecl **clsMethods, + unsigned numClsMembers, + SourceLocation AtEndLoc) { NumInstanceMethods = numInsMembers; if (numInsMembers) { InstanceMethods = new ObjcMethodDecl*[numInsMembers]; @@ -353,13 +358,14 @@ void ObjcProtocolDecl::ObjcAddProtoMethods(ObjcMethodDecl **insMethods, } } -/// ObjcAddCat - Insert instance and methods declarations into +/// addMethods - Insert instance and methods declarations into /// ObjcCategoryDecl's CatInsMethods and CatClsMethods fields. /// -void ObjcCategoryDecl::ObjcAddCatMethods(ObjcMethodDecl **insMethods, - unsigned numInsMembers, - ObjcMethodDecl **clsMethods, - unsigned numClsMembers) { +void ObjcCategoryDecl::addMethods(ObjcMethodDecl **insMethods, + unsigned numInsMembers, + ObjcMethodDecl **clsMethods, + unsigned numClsMembers, + SourceLocation AtEndLoc) { NumInstanceMethods = numInsMembers; if (numInsMembers) { InstanceMethods = new ObjcMethodDecl*[numInsMembers]; @@ -372,13 +378,14 @@ void ObjcCategoryDecl::ObjcAddCatMethods(ObjcMethodDecl **insMethods, } } -/// ObjcAddCatImplMethods - Insert instance and methods declarations into +/// addMethods - Insert instance and methods declarations into /// ObjcCategoryImplDecl's CatInsMethods and CatClsMethods fields. /// -void ObjcCategoryImplDecl::ObjcAddCatImplMethods(ObjcMethodDecl **insMethods, - unsigned numInsMembers, - ObjcMethodDecl **clsMethods, - unsigned numClsMembers) { +void ObjcCategoryImplDecl::addMethods(ObjcMethodDecl **insMethods, + unsigned numInsMembers, + ObjcMethodDecl **clsMethods, + unsigned numClsMembers, + SourceLocation AtEndLoc) { NumInstanceMethods = numInsMembers; if (numInsMembers) { InstanceMethods = new ObjcMethodDecl*[numInsMembers]; @@ -394,10 +401,11 @@ void ObjcCategoryImplDecl::ObjcAddCatImplMethods(ObjcMethodDecl **insMethods, /// ObjcAddImplMethods - Insert instance and methods declarations into /// ObjcImplementationDecl's InsMethods and ClsMethods fields. /// -void ObjcImplementationDecl::ObjcAddImplMethods(ObjcMethodDecl **insMethods, - unsigned numInsMembers, - ObjcMethodDecl **clsMethods, - unsigned numClsMembers) { +void ObjcImplementationDecl::addMethods(ObjcMethodDecl **insMethods, + unsigned numInsMembers, + ObjcMethodDecl **clsMethods, + unsigned numClsMembers, + SourceLocation AtEndLoc) { NumInstanceMethods = numInsMembers; if (numInsMembers) { InstanceMethods = new ObjcMethodDecl*[numInsMembers]; diff --git a/clang/Parse/ParseDecl.cpp b/clang/Parse/ParseDecl.cpp index a525792ff80d..1e786da43599 100644 --- a/clang/Parse/ParseDecl.cpp +++ b/clang/Parse/ParseDecl.cpp @@ -758,10 +758,11 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, } } - MatchRHSPunctuation(tok::r_brace, LBraceLoc); + SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc); Actions.ActOnFields(CurScope, - RecordLoc,TagDecl,&FieldDecls[0],FieldDecls.size()); + RecordLoc,TagDecl,&FieldDecls[0],FieldDecls.size(), + LBraceLoc, RBraceLoc); AttributeList *AttrList = 0; // If attributes exist after struct contents, parse them. diff --git a/clang/Parse/ParseObjc.cpp b/clang/Parse/ParseObjc.cpp index 4abf8fd43dd5..c628f4d8fceb 100644 --- a/clang/Parse/ParseObjc.cpp +++ b/clang/Parse/ParseObjc.cpp @@ -193,7 +193,7 @@ Parser::DeclTy *Parser::ParseObjCAtInterfaceDeclaration( ProtocolRefs.size(), attrList); if (Tok.is(tok::l_brace)) - ParseObjCClassInstanceVariables(ClsType); + ParseObjCClassInstanceVariables(ClsType, atLoc); ParseObjCInterfaceDeclList(ClsType, tok::objc_interface); @@ -222,12 +222,15 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, tok::ObjCKeywordKind contextKey) { llvm::SmallVector allMethods; tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword; + SourceLocation AtEndLoc; + while (1) { if (Tok.is(tok::at)) { SourceLocation AtLoc = ConsumeToken(); // the "@" tok::ObjCKeywordKind ocKind = Tok.getObjCKeywordID(); if (ocKind == tok::objc_end) { // terminate list + AtEndLoc = AtLoc; break; } else if (ocKind == tok::objc_required) { // protocols only ConsumeToken(); @@ -268,8 +271,8 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, } if (allMethods.size()) /// Insert collected methods declarations into the @interface object. - Actions.ActOnAddMethodsToObjcDecl(CurScope, interfaceDecl, - &allMethods[0], allMethods.size()); + Actions.ActOnAddMethodsToObjcDecl(CurScope, interfaceDecl, &allMethods[0], + allMethods.size(), AtEndLoc); } /// Parse property attribute declarations. @@ -683,7 +686,8 @@ bool Parser::ParseObjCProtocolReferences( /// objc-instance-variable-decl: /// struct-declaration /// -void Parser::ParseObjCClassInstanceVariables(DeclTy *interfaceDecl) { +void Parser::ParseObjCClassInstanceVariables(DeclTy *interfaceDecl, + SourceLocation atLoc) { assert(Tok.is(tok::l_brace) && "expected {"); llvm::SmallVector IvarDecls; llvm::SmallVector AllIvarDecls; @@ -737,12 +741,12 @@ void Parser::ParseObjCClassInstanceVariables(DeclTy *interfaceDecl) { SkipUntil(tok::r_brace, true, true); } } + SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc); if (AllIvarDecls.size()) { // Check for {} - no ivars in braces - Actions.ActOnFields(CurScope, LBraceLoc, interfaceDecl, + Actions.ActOnFields(CurScope, atLoc, interfaceDecl, &AllIvarDecls[0], AllIvarDecls.size(), - &AllVisibilities[0]); + LBraceLoc, RBraceLoc, &AllVisibilities[0]); } - MatchRHSPunctuation(tok::r_brace, LBraceLoc); return; } @@ -893,11 +897,12 @@ Parser::DeclTy *Parser::ParseObjCAtImplementationDeclaration( atLoc, nameId, nameLoc, superClassId, superClassLoc); - if (Tok.is(tok::l_brace)) - ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/); // we have ivars + if (Tok.is(tok::l_brace)) // we have ivars + ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/, atLoc); return ImplClsType; } + Parser::DeclTy *Parser::ParseObjCAtEndDeclaration(SourceLocation atLoc) { assert(Tok.isObjCAtKeyword(tok::objc_end) && "ParseObjCAtEndDeclaration(): Expected @end"); @@ -908,7 +913,8 @@ Parser::DeclTy *Parser::ParseObjCAtEndDeclaration(SourceLocation atLoc) { // could be 0. /// Insert collected methods declarations into the @interface object. Actions.ActOnAddMethodsToObjcDecl(CurScope, ObjcImpDecl, - &AllImplMethods[0],AllImplMethods.size()); + &AllImplMethods[0], AllImplMethods.size(), + atLoc); ObjcImpDecl = 0; AllImplMethods.clear(); } diff --git a/clang/Sema/Sema.h b/clang/Sema/Sema.h index f553356657e5..dcf024ec0c60 100644 --- a/clang/Sema/Sema.h +++ b/clang/Sema/Sema.h @@ -203,9 +203,10 @@ private: // This is used for both record definitions and ObjC interface declarations. virtual void ActOnFields(Scope* S, - SourceLocation RecLoc, DeclTy *TagDecl, - DeclTy **Fields, unsigned NumFields, - tok::ObjCKeywordKind *visibility = 0); + SourceLocation RecLoc, DeclTy *TagDecl, + DeclTy **Fields, unsigned NumFields, + SourceLocation LBrac, SourceLocation RBrac, + tok::ObjCKeywordKind *visibility = 0); virtual DeclTy *ActOnEnumConstant(Scope *S, DeclTy *EnumDecl, DeclTy *LastEnumConstant, SourceLocation IdLoc, IdentifierInfo *Id, @@ -517,7 +518,8 @@ public: Protocols); virtual void ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *ClassDecl, - DeclTy **allMethods, unsigned allNum); + DeclTy **allMethods, unsigned allNum, + SourceLocation AtEndLoc); virtual DeclTy *ActOnMethodDeclaration( SourceLocation BeginLoc, // location of the + or -. diff --git a/clang/Sema/SemaDecl.cpp b/clang/Sema/SemaDecl.cpp index 12efd458b22d..1ec54d511cb4 100644 --- a/clang/Sema/SemaDecl.cpp +++ b/clang/Sema/SemaDecl.cpp @@ -1263,7 +1263,7 @@ void Sema::CheckImplementationIvars(ObjcImplementationDecl *ImpDecl, /// (legacy objective-c @implementation decl without an @interface decl). /// Add implementations's ivar to the synthesize class's ivar list. if (IDecl->ImplicitInterfaceDecl()) { - IDecl->ObjcAddInstanceVariablesToClass(ivars, numIvars); + IDecl->addInstanceVariablesToClass(ivars, numIvars, SourceLocation()); return; } @@ -1631,6 +1631,7 @@ TranslateIvarVisibility(tok::ObjCKeywordKind ivarVisibility) { void Sema::ActOnFields(Scope* S, SourceLocation RecLoc, DeclTy *RecDecl, DeclTy **Fields, unsigned NumFields, + SourceLocation LBrac, SourceLocation RBrac, tok::ObjCKeywordKind *visibility) { Decl *EnclosingDecl = static_cast(RecDecl); assert(EnclosingDecl && "missing record or interface decl"); @@ -1769,7 +1770,7 @@ void Sema::ActOnFields(Scope* S, reinterpret_cast(&RecFields[0]); if (isa(static_cast(RecDecl))) cast(static_cast(RecDecl))-> - ObjcAddInstanceVariablesToClass(ClsFields, RecFields.size()); + addInstanceVariablesToClass(ClsFields, RecFields.size(), RBrac); else if (isa(static_cast(RecDecl))) { ObjcImplementationDecl* IMPDecl = cast(static_cast(RecDecl)); @@ -1844,7 +1845,8 @@ void Sema::AddFactoryMethodToGlobalPool(ObjcMethodDecl *Method) { } void Sema::ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *classDecl, - DeclTy **allMethods, unsigned allNum) { + DeclTy **allMethods, unsigned allNum, + SourceLocation AtEndLoc) { Decl *ClassDecl = static_cast(classDecl); // FIXME: If we don't have a ClassDecl, we have an error. I (snaroff) would @@ -1906,26 +1908,26 @@ void Sema::ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *classDecl, } if (ObjcInterfaceDecl *I = dyn_cast(ClassDecl)) { - I->ObjcAddMethods(&insMethods[0], insMethods.size(), - &clsMethods[0], clsMethods.size()); + I->addMethods(&insMethods[0], insMethods.size(), + &clsMethods[0], clsMethods.size(), AtEndLoc); } else if (ObjcProtocolDecl *P = dyn_cast(ClassDecl)) { - P->ObjcAddProtoMethods(&insMethods[0], insMethods.size(), - &clsMethods[0], clsMethods.size()); + P->addMethods(&insMethods[0], insMethods.size(), + &clsMethods[0], clsMethods.size(), AtEndLoc); } else if (ObjcCategoryDecl *C = dyn_cast(ClassDecl)) { - C->ObjcAddCatMethods(&insMethods[0], insMethods.size(), - &clsMethods[0], clsMethods.size()); + C->addMethods(&insMethods[0], insMethods.size(), + &clsMethods[0], clsMethods.size(), AtEndLoc); } else if (ObjcImplementationDecl *IC = dyn_cast(ClassDecl)) { - IC->ObjcAddImplMethods(&insMethods[0], insMethods.size(), - &clsMethods[0], clsMethods.size()); + IC->addMethods(&insMethods[0], insMethods.size(), + &clsMethods[0], clsMethods.size(), AtEndLoc); if (ObjcInterfaceDecl* IDecl = getObjCInterfaceDecl(IC->getIdentifier())) ImplMethodsVsClassMethods(IC, IDecl); } else { ObjcCategoryImplDecl* CatImplClass = cast(ClassDecl); - CatImplClass->ObjcAddCatImplMethods(&insMethods[0], insMethods.size(), - &clsMethods[0], clsMethods.size()); + CatImplClass->addMethods(&insMethods[0], insMethods.size(), + &clsMethods[0], clsMethods.size(), AtEndLoc); ObjcInterfaceDecl* IDecl = CatImplClass->getClassInterface(); // Find category interface decl and then check that all methods declared // in this interface is implemented in the category @implementation. diff --git a/clang/clang.xcodeproj/project.pbxproj b/clang/clang.xcodeproj/project.pbxproj index fe4cf8d85be8..de41b4628d0c 100644 --- a/clang/clang.xcodeproj/project.pbxproj +++ b/clang/clang.xcodeproj/project.pbxproj @@ -756,7 +756,6 @@ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */; - compatibilityVersion = "Xcode 2.4"; hasScannedForEncodings = 1; mainGroup = 08FB7794FE84155DC02AAC07 /* clang */; projectDirPath = ""; diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index 615718740572..e5d6fb8a7c41 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -73,10 +73,13 @@ class ObjcInterfaceDecl : public TypeDecl { ObjcCategoryDecl *CategoryList; bool ForwardDecl; // declared with @class. + + SourceLocation RBracLoc; // marks the end of the instance variables. + SourceLocation EndLoc; // marks the end of the entire interface. public: - ObjcInterfaceDecl(SourceLocation L, unsigned numRefProtos, + ObjcInterfaceDecl(SourceLocation atLoc, unsigned numRefProtos, IdentifierInfo *Id, bool FD = false) - : TypeDecl(ObjcInterface, L, Id, 0), SuperClass(0), + : TypeDecl(ObjcInterface, atLoc, Id, 0), SuperClass(0), ReferencedProtocols(0), NumReferencedProtocols(-1), Ivars(0), NumIvars(-1), InstanceMethods(0), NumInstanceMethods(-1), @@ -109,11 +112,12 @@ public: ObjcMethodDecl** getClassMethods() const { return ClassMethods; } int getNumClassMethods() const { return NumClassMethods; } - void ObjcAddInstanceVariablesToClass(ObjcIvarDecl **ivars, - unsigned numIvars); + void addInstanceVariablesToClass(ObjcIvarDecl **ivars, unsigned numIvars, + SourceLocation RBracLoc); - void ObjcAddMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers, - ObjcMethodDecl **clsMethods, unsigned numClsMembers); + void addMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers, + ObjcMethodDecl **clsMethods, unsigned numClsMembers, + SourceLocation AtEnd); bool isForwardDecl() const { return ForwardDecl; } void setForwardDecl(bool val) { ForwardDecl = val; } @@ -132,6 +136,14 @@ public: } ObjcMethodDecl *lookupInstanceMethod(Selector &Sel); ObjcMethodDecl *lookupClassMethod(Selector &Sel); + + // Location information, modeled after the Stmt API. For interfaces, + // which are fairly course grain, the end refers to the '}' token. + SourceLocation getLocStart() const { return getLocation(); } // '@'interface + SourceLocation getLocEnd() const { return RBracLoc; } + + // We also need to record the @end location. + SourceLocation getAtEndLoc() const { return EndLoc; } /// ImplicitInterfaceDecl - check that this is an implicitely declared /// ObjcInterfaceDecl node. This is for legacy objective-c @implementation @@ -313,8 +325,9 @@ public: NumReferencedProtocols = numRefProtos; } } - void ObjcAddProtoMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers, - ObjcMethodDecl **clsMethods, unsigned numClsMembers); + void addMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers, + ObjcMethodDecl **clsMethods, unsigned numClsMembers, + SourceLocation AtEndLoc); void setReferencedProtocols(int idx, ObjcProtocolDecl *OID) { assert((idx < NumReferencedProtocols) && "index out of range"); @@ -480,8 +493,9 @@ public: ObjcMethodDecl **getClassMethods() const { return ClassMethods; } int getNumClassMethods() const { return NumClassMethods; } - void ObjcAddCatMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers, - ObjcMethodDecl **clsMethods, unsigned numClsMembers); + void addMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers, + ObjcMethodDecl **clsMethods, unsigned numClsMembers, + SourceLocation AtEndLoc); ObjcCategoryDecl *getNextClassCategory() const { return NextClassCategory; } void insertNextClassCategory() { @@ -525,9 +539,9 @@ class ObjcCategoryImplDecl : public NamedDecl { ObjcMethodDecl **getClassMethods() const { return ClassMethods; } int getNumClassMethods() const { return NumClassMethods; } - void ObjcAddCatImplMethods( - ObjcMethodDecl **insMethods, unsigned numInsMembers, - ObjcMethodDecl **clsMethods, unsigned numClsMembers); + void addMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers, + ObjcMethodDecl **clsMethods, unsigned numClsMembers, + SourceLocation AtEndLoc); static bool classof(const Decl *D) { return D->getKind() == ObjcCategoryImpl;} static bool classof(const ObjcCategoryImplDecl *D) { return true; } @@ -581,8 +595,9 @@ public: void ObjcAddInstanceVariablesToClassImpl(ObjcIvarDecl **ivars, unsigned numIvars); - void ObjcAddImplMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers, - ObjcMethodDecl **clsMethods, unsigned numClsMembers); + void addMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers, + ObjcMethodDecl **clsMethods, unsigned numClsMembers, + SourceLocation AtEndLoc); ObjcInterfaceDecl *getClassInterface() const { return ClassInterface; } ObjcInterfaceDecl *getSuperClass() const { return SuperClass; } diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index a237bf3c2704..a80fb081841d 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -180,10 +180,10 @@ public: Declarator &D, ExprTy *BitfieldWidth) { return 0; } - virtual void ActOnFields(Scope* S, - SourceLocation RecLoc, DeclTy *TagDecl, - DeclTy **Fields, unsigned NumFields, - tok::ObjCKeywordKind *visibility = 0) {} + virtual void ActOnFields(Scope* S, SourceLocation RecLoc, DeclTy *TagDecl, + DeclTy **Fields, unsigned NumFields, + SourceLocation LBrac, SourceLocation RBrac, + tok::ObjCKeywordKind *visibility = 0) {} virtual DeclTy *ActOnEnumConstant(Scope *S, DeclTy *EnumDecl, DeclTy *LastEnumConstant, SourceLocation IdLoc, IdentifierInfo *Id, @@ -541,7 +541,8 @@ public: Scope* S, DeclTy *ClassDecl, DeclTy **allMethods, - unsigned allNum) { + unsigned allNum, + SourceLocation AtEndLoc) { return; } // ActOnClassMessage - used for both unary and keyword messages. diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index a41d357215be..0ca6eaf09667 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -258,7 +258,8 @@ private: DeclTy *ParseObjCAtClassDeclaration(SourceLocation atLoc); DeclTy *ParseObjCAtInterfaceDeclaration(SourceLocation atLoc, AttributeList *prefixAttrs = 0); - void ParseObjCClassInstanceVariables(DeclTy *interfaceDecl); + void ParseObjCClassInstanceVariables(DeclTy *interfaceDecl, + SourceLocation atLoc); bool ParseObjCProtocolReferences(llvm::SmallVectorImpl &); void ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, tok::ObjCKeywordKind contextKey);