diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2011-08-22 15:54:49 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2011-08-22 15:54:49 +0000 |
commit | a28948f34817476d02412fa204cae038e228c827 (patch) | |
tree | 3aab4757cbcd4cf2b320a93fec061b4f0497343a /lib | |
parent | ec5bc81fd55bfcc26fc4bde6d5e33113d94c2209 (diff) |
Restore patch I reversed in r138040. Known buildbot
failures are resolved.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138234 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 1 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 33 | ||||
-rw-r--r-- | lib/Parse/ParseObjc.cpp | 118 | ||||
-rw-r--r-- | lib/Parse/ParseTemplate.cpp | 19 | ||||
-rw-r--r-- | lib/Parse/Parser.cpp | 11 | ||||
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 37 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 34 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 24 | ||||
-rw-r--r-- | lib/Sema/SemaObjCProperty.cpp | 27 |
9 files changed, 185 insertions, 119 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 9023b34fa9..2316590afe 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -2319,6 +2319,7 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid, /// void Parser:: ParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) { + if (Tok.is(tok::kw___extension__)) { // __extension__ silences extension warnings in the subexpression. ExtensionRAIIObject O(Diags); // Use RAII to do this. diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 7c38857f5a..f6a79e5967 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -52,7 +52,10 @@ Decl *Parser::ParseNamespace(unsigned Context, SourceLocation InlineLoc) { assert(Tok.is(tok::kw_namespace) && "Not a namespace!"); SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'. - + Decl *DC = getObjCDeclContext(); + if (DC) + Actions.ActOnObjCContainerFinishDefinition(DC); + if (Tok.is(tok::code_completion)) { Actions.CodeCompleteNamespaceDecl(getCurScope()); ConsumeCodeCompletionToken(); @@ -89,8 +92,10 @@ Decl *Parser::ParseNamespace(unsigned Context, if (InlineLoc.isValid()) Diag(InlineLoc, diag::err_inline_namespace_alias) << FixItHint::CreateRemoval(InlineLoc); - - return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd); + Decl *Res = ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd); + if (DC) + Actions.ActOnObjCContainerStartDefinition(DC); + return Res; } @@ -101,6 +106,8 @@ Decl *Parser::ParseNamespace(unsigned Context, } Diag(Tok, Ident ? diag::err_expected_lbrace : diag::err_expected_ident_lbrace); + if (DC) + Actions.ActOnObjCContainerStartDefinition(DC); return 0; } @@ -115,6 +122,8 @@ Decl *Parser::ParseNamespace(unsigned Context, } Diag(LBrace, diag::err_namespace_nonnamespace_scope); SkipUntil(tok::r_brace, false); + if (DC) + Actions.ActOnObjCContainerStartDefinition(DC); return 0; } @@ -173,6 +182,8 @@ Decl *Parser::ParseNamespace(unsigned Context, Actions.ActOnFinishNamespaceDef(NamespcDecl, RBraceLoc); DeclEnd = RBraceLoc; + if (DC) + Actions.ActOnObjCContainerStartDefinition(DC); return NamespcDecl; } @@ -317,7 +328,9 @@ Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context, ParsedAttributesWithRange &attrs, Decl **OwnedType) { assert(Tok.is(tok::kw_using) && "Not using token"); - + Decl *DC = getObjCDeclContext(); + if (DC) + Actions.ActOnObjCContainerFinishDefinition(DC); // Eat 'using'. SourceLocation UsingLoc = ConsumeToken(); @@ -335,7 +348,10 @@ Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context, << R << FixItHint::CreateRemoval(R); } - return ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs); + Decl *Res = ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs); + if (DC) + Actions.ActOnObjCContainerStartDefinition(DC); + return Res; } // Otherwise, it must be a using-declaration or an alias-declaration. @@ -343,8 +359,11 @@ Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context, // Using declarations can't have attributes. ProhibitAttributes(attrs); - return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd, - AS_none, OwnedType); + Decl *Res = ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd, + AS_none, OwnedType); + if (DC) + Actions.ActOnObjCContainerStartDefinition(DC); + return Res; } /// ParseUsingDirective - Parse C++ using-directive, assumes diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index c8b2a09d5e..f5471e5a6f 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -33,7 +33,7 @@ Decl *Parser::ParseObjCAtDirectives() { SourceLocation AtLoc = ConsumeToken(); // the "@" if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCAtDirective(getCurScope(), ObjCImpDecl, false); + Actions.CodeCompleteObjCAtDirective(getCurScope()); ConsumeCodeCompletionToken(); } @@ -195,11 +195,13 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation atLoc, ProtocolRefs.size(), ProtocolLocs.data(), EndProtoLoc); - if (Tok.is(tok::l_brace)) - ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, - atLoc); - ParseObjCInterfaceDeclList(CategoryType, tok::objc_not_keyword); + if (Tok.is(tok::l_brace)) + ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, atLoc); + + Actions.ActOnObjCContainerStartDefinition(CategoryType); + ParseObjCInterfaceDeclList(tok::objc_not_keyword); + Actions.ActOnObjCContainerFinishDefinition(CategoryType); return CategoryType; } // Parse a class interface. @@ -241,7 +243,9 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation atLoc, if (Tok.is(tok::l_brace)) ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, atLoc); - ParseObjCInterfaceDeclList(ClsType, tok::objc_interface); + Actions.ActOnObjCContainerStartDefinition(ClsType); + ParseObjCInterfaceDeclList(tok::objc_interface); + Actions.ActOnObjCContainerFinishDefinition(ClsType); return ClsType; } @@ -249,17 +253,16 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation atLoc, /// it's used, but instead it's been lifted to here to support VS2005. struct Parser::ObjCPropertyCallback : FieldCallback { Parser &P; - Decl *IDecl; SmallVectorImpl<Decl *> &Props; ObjCDeclSpec &OCDS; SourceLocation AtLoc; tok::ObjCKeywordKind MethodImplKind; - ObjCPropertyCallback(Parser &P, Decl *IDecl, + ObjCPropertyCallback(Parser &P, SmallVectorImpl<Decl *> &Props, ObjCDeclSpec &OCDS, SourceLocation AtLoc, tok::ObjCKeywordKind MethodImplKind) : - P(P), IDecl(IDecl), Props(Props), OCDS(OCDS), AtLoc(AtLoc), + P(P), Props(Props), OCDS(OCDS), AtLoc(AtLoc), MethodImplKind(MethodImplKind) { } @@ -292,7 +295,7 @@ struct Parser::ObjCPropertyCallback : FieldCallback { bool isOverridingProperty = false; Decl *Property = P.Actions.ActOnProperty(P.getCurScope(), AtLoc, FD, OCDS, - GetterSel, SetterSel, IDecl, + GetterSel, SetterSel, &isOverridingProperty, MethodImplKind); if (!isOverridingProperty) @@ -314,8 +317,7 @@ struct Parser::ObjCPropertyCallback : FieldCallback { /// @required /// @optional /// -void Parser::ParseObjCInterfaceDeclList(Decl *interfaceDecl, - tok::ObjCKeywordKind contextKey) { +void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey) { SmallVector<Decl *, 32> allMethods; SmallVector<Decl *, 16> allProperties; SmallVector<DeclGroupPtrTy, 8> allTUVariables; @@ -327,7 +329,7 @@ void Parser::ParseObjCInterfaceDeclList(Decl *interfaceDecl, // If this is a method prototype, parse it. if (Tok.is(tok::minus) || Tok.is(tok::plus)) { Decl *methodPrototype = - ParseObjCMethodPrototype(interfaceDecl, MethodImplKind, false); + ParseObjCMethodPrototype(MethodImplKind, false); allMethods.push_back(methodPrototype); // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for // method definitions. @@ -339,7 +341,6 @@ void Parser::ParseObjCInterfaceDeclList(Decl *interfaceDecl, Diag(Tok, diag::err_expected_minus_or_plus); ParseObjCMethodDecl(Tok.getLocation(), tok::minus, - interfaceDecl, MethodImplKind, false); continue; } @@ -368,9 +369,6 @@ void Parser::ParseObjCInterfaceDeclList(Decl *interfaceDecl, // erroneous r_brace would cause an infinite loop if not handled here. if (Tok.is(tok::r_brace)) break; - - // FIXME: as the name implies, this rule allows function definitions. - // We could pass a flag or check for functions during semantic analysis. ParsedAttributes attrs(AttrFactory); allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(attrs)); continue; @@ -379,7 +377,7 @@ void Parser::ParseObjCInterfaceDeclList(Decl *interfaceDecl, // Otherwise, we have an @ directive, eat the @. SourceLocation AtLoc = ConsumeToken(); // the "@" if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCAtDirective(getCurScope(), ObjCImpDecl, true); + Actions.CodeCompleteObjCAtDirective(getCurScope()); ConsumeCodeCompletionToken(); break; } @@ -433,9 +431,9 @@ void Parser::ParseObjCInterfaceDeclList(Decl *interfaceDecl, ObjCDeclSpec OCDS; // Parse property attribute list, if any. if (Tok.is(tok::l_paren)) - ParseObjCPropertyAttribute(OCDS, interfaceDecl); + ParseObjCPropertyAttribute(OCDS); - ObjCPropertyCallback Callback(*this, interfaceDecl, allProperties, + ObjCPropertyCallback Callback(*this, allProperties, OCDS, AtLoc, MethodImplKind); // Parse all the comma separated declarators. @@ -450,7 +448,7 @@ void Parser::ParseObjCInterfaceDeclList(Decl *interfaceDecl, // We break out of the big loop in two cases: when we see @end or when we see // EOF. In the former case, eat the @end. In the later case, emit an error. if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCAtDirective(getCurScope(), ObjCImpDecl, true); + Actions.CodeCompleteObjCAtDirective(getCurScope()); ConsumeCodeCompletionToken(); } else if (Tok.isObjCAtKeyword(tok::objc_end)) ConsumeToken(); // the "end" identifier @@ -459,7 +457,7 @@ void Parser::ParseObjCInterfaceDeclList(Decl *interfaceDecl, // Insert collected methods declarations into the @interface object. // This passes in an invalid SourceLocation for AtEndLoc when EOF is hit. - Actions.ActOnAtEnd(getCurScope(), AtEnd, interfaceDecl, + Actions.ActOnAtEnd(getCurScope(), AtEnd, allMethods.data(), allMethods.size(), allProperties.data(), allProperties.size(), allTUVariables.data(), allTUVariables.size()); @@ -485,7 +483,7 @@ void Parser::ParseObjCInterfaceDeclList(Decl *interfaceDecl, /// weak /// unsafe_unretained /// -void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS, Decl *ClassDecl) { +void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) { assert(Tok.getKind() == tok::l_paren); SourceLocation LHSLoc = ConsumeParen(); // consume '(' @@ -536,9 +534,9 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS, Decl *ClassDecl) { if (Tok.is(tok::code_completion)) { if (IsSetter) - Actions.CodeCompleteObjCPropertySetter(getCurScope(), ClassDecl); + Actions.CodeCompleteObjCPropertySetter(getCurScope()); else - Actions.CodeCompleteObjCPropertyGetter(getCurScope(), ClassDecl); + Actions.CodeCompleteObjCPropertyGetter(getCurScope()); ConsumeCodeCompletionToken(); } @@ -590,14 +588,13 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS, Decl *ClassDecl) { /// objc-method-attributes: [OBJC2] /// __attribute__((deprecated)) /// -Decl *Parser::ParseObjCMethodPrototype(Decl *IDecl, - tok::ObjCKeywordKind MethodImplKind, +Decl *Parser::ParseObjCMethodPrototype(tok::ObjCKeywordKind MethodImplKind, bool MethodDefinition) { assert((Tok.is(tok::minus) || Tok.is(tok::plus)) && "expected +/-"); tok::TokenKind methodType = Tok.getKind(); SourceLocation mLoc = ConsumeToken(); - Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, IDecl,MethodImplKind, + Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, MethodImplKind, MethodDefinition); // Since this rule is used for both method declarations and definitions, // the caller is (optionally) responsible for consuming the ';'. @@ -779,7 +776,9 @@ ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS, SourceLocation LParenLoc = ConsumeParen(); SourceLocation TypeStartLoc = Tok.getLocation(); - + Decl *DC = getObjCDeclContext(); + if (DC) + Actions.ActOnObjCContainerFinishDefinition(DC); // Parse type qualifiers, in, inout, etc. ParseObjCTypeQualifierList(DS, Context); @@ -802,6 +801,8 @@ ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS, // place. Emit an error then return what we have as the type. MatchRHSPunctuation(tok::r_paren, LParenLoc); } + if (DC) + Actions.ActOnObjCContainerStartDefinition(DC); return Ty; } @@ -835,14 +836,13 @@ ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS, /// Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType, - Decl *IDecl, tok::ObjCKeywordKind MethodImplKind, bool MethodDefinition) { ParsingDeclRAIIObject PD(*this); if (Tok.is(tok::code_completion)) { Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, - /*ReturnType=*/ ParsedType(), IDecl); + /*ReturnType=*/ ParsedType()); ConsumeCodeCompletionToken(); } @@ -859,7 +859,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, if (Tok.is(tok::code_completion)) { Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, - ReturnType, IDecl); + ReturnType); ConsumeCodeCompletionToken(); } @@ -885,7 +885,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent); Decl *Result = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(), - mType, IDecl, DSRet, ReturnType, + mType, DSRet, ReturnType, selLoc, Sel, 0, CParamInfo.data(), CParamInfo.size(), methodAttrs.getList(), MethodImplKind, @@ -1001,23 +1001,18 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, if (getLang().ObjC2) MaybeParseGNUAttributes(methodAttrs); - if (KeyIdents.size() == 0) { - // Leave prototype scope. - PrototypeScope.Exit(); + if (KeyIdents.size() == 0) return 0; - } Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(), &KeyIdents[0]); Decl *Result = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(), - mType, IDecl, DSRet, ReturnType, + mType, DSRet, ReturnType, selLoc, Sel, &ArgInfos[0], CParamInfo.data(), CParamInfo.size(), methodAttrs.getList(), MethodImplKind, isVariadic, MethodDefinition); - // Leave prototype scope. - PrototypeScope.Exit(); PD.complete(Result); return Result; @@ -1117,7 +1112,7 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl, SourceLocation atLoc) { assert(Tok.is(tok::l_brace) && "expected {"); SmallVector<Decl *, 32> AllIvarDecls; - + ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope); SourceLocation LBraceLoc = ConsumeBrace(); // the "{" @@ -1175,11 +1170,13 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl, } Decl *invoke(FieldDeclarator &FD) { + P.Actions.ActOnObjCContainerStartDefinition(IDecl); // Install the declarator into the interface decl. Decl *Field = P.Actions.ActOnIvar(P.getCurScope(), FD.D.getDeclSpec().getSourceRange().getBegin(), - IDecl, FD.D, FD.BitfieldSize, visibility); + FD.D, FD.BitfieldSize, visibility); + P.Actions.ActOnObjCContainerFinishDefinition(IDecl); if (Field) AllIvarDecls.push_back(Field); return Field; @@ -1199,7 +1196,9 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl, } } SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc); - Actions.ActOnLastBitfield(RBraceLoc, interfaceDecl, AllIvarDecls); + Actions.ActOnObjCContainerStartDefinition(interfaceDecl); + Actions.ActOnLastBitfield(RBraceLoc, AllIvarDecls); + Actions.ActOnObjCContainerFinishDefinition(interfaceDecl); // Call ActOnFields() even if we don't have any decls. This is useful // for code rewriting tools that need to be aware of the empty list. Actions.ActOnFields(getCurScope(), atLoc, interfaceDecl, @@ -1295,7 +1294,11 @@ Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, ProtocolRefs.size(), ProtocolLocs.data(), EndProtoLoc, attrs.getList()); - ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol); + + + Actions.ActOnObjCContainerStartDefinition(ProtoType); + ParseObjCInterfaceDeclList(tok::objc_protocol); + Actions.ActOnObjCContainerFinishDefinition(ProtoType); return ProtoType; } @@ -1356,6 +1359,8 @@ Decl *Parser::ParseObjCAtImplementationDeclaration( Decl *ImplCatType = Actions.ActOnStartCategoryImplementation( atLoc, nameId, nameLoc, categoryId, categoryLoc); + + Actions.ActOnObjCContainerStartDefinition(ImplCatType); ObjCImpDecl = ImplCatType; PendingObjCImpDecl.push_back(ObjCImpDecl); return 0; @@ -1378,11 +1383,11 @@ Decl *Parser::ParseObjCAtImplementationDeclaration( superClassId, superClassLoc); if (Tok.is(tok::l_brace)) // we have ivars - ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/, - tok::objc_private, atLoc); + ParseObjCClassInstanceVariables(ImplClsType, tok::objc_private, atLoc); + + Actions.ActOnObjCContainerStartDefinition(ImplClsType); ObjCImpDecl = ImplClsType; PendingObjCImpDecl.push_back(ObjCImpDecl); - return 0; } @@ -1392,7 +1397,8 @@ Decl *Parser::ParseObjCAtEndDeclaration(SourceRange atEnd) { Decl *Result = ObjCImpDecl; ConsumeToken(); // the "end" identifier if (ObjCImpDecl) { - Actions.ActOnAtEnd(getCurScope(), atEnd, ObjCImpDecl); + Actions.ActOnAtEnd(getCurScope(), atEnd); + Actions.ActOnObjCContainerFinishDefinition(ObjCImpDecl); ObjCImpDecl = 0; PendingObjCImpDecl.pop_back(); } @@ -1408,7 +1414,8 @@ Parser::DeclGroupPtrTy Parser::FinishPendingObjCActions() { if (PendingObjCImpDecl.empty()) return Actions.ConvertDeclToDeclGroup(0); Decl *ImpDecl = PendingObjCImpDecl.pop_back_val(); - Actions.ActOnAtEnd(getCurScope(), SourceRange(), ImpDecl); + Actions.ActOnAtEnd(getCurScope(), SourceRange()); + Actions.ActOnObjCContainerFinishDefinition(ImpDecl); return Actions.ConvertDeclToDeclGroup(ImpDecl); } @@ -1455,7 +1462,7 @@ Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) { while (true) { if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCPropertyDefinition(getCurScope(), ObjCImpDecl); + Actions.CodeCompleteObjCPropertyDefinition(getCurScope()); ConsumeCodeCompletionToken(); } @@ -1474,8 +1481,7 @@ Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) { ConsumeToken(); // consume '=' if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId, - ObjCImpDecl); + Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId); ConsumeCodeCompletionToken(); } @@ -1486,7 +1492,7 @@ Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) { propertyIvar = Tok.getIdentifierInfo(); propertyIvarLoc = ConsumeToken(); // consume ivar-name } - Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, true, ObjCImpDecl, + Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, true, propertyId, propertyIvar, propertyIvarLoc); if (Tok.isNot(tok::comma)) break; @@ -1509,7 +1515,7 @@ Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) { ConsumeToken(); // consume dynamic while (true) { if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteObjCPropertyDefinition(getCurScope(), ObjCImpDecl); + Actions.CodeCompleteObjCPropertyDefinition(getCurScope()); ConsumeCodeCompletionToken(); } @@ -1521,7 +1527,7 @@ Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) { IdentifierInfo *propertyId = Tok.getIdentifierInfo(); SourceLocation propertyLoc = ConsumeToken(); // consume property name - Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, false, ObjCImpDecl, + Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, false, propertyId, 0, SourceLocation()); if (Tok.isNot(tok::comma)) @@ -1739,7 +1745,7 @@ Parser::ParseObjCAutoreleasePoolStmt(SourceLocation atLoc) { /// objc-method-def: objc-method-proto ';'[opt] '{' body '}' /// Decl *Parser::ParseObjCMethodDefinition() { - Decl *MDecl = ParseObjCMethodPrototype(ObjCImpDecl); + Decl *MDecl = ParseObjCMethodPrototype(); PrettyDeclStackTraceEntry CrashInfo(Actions, MDecl, Tok.getLocation(), "parsing Objective-C method"); diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index 05fabebed2..d0e63496b5 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/lib/Parse/ParseTemplate.cpp @@ -27,11 +27,20 @@ Decl * Parser::ParseDeclarationStartingWithTemplate(unsigned Context, SourceLocation &DeclEnd, AccessSpecifier AS) { - if (Tok.is(tok::kw_template) && NextToken().isNot(tok::less)) - return ParseExplicitInstantiation(SourceLocation(), ConsumeToken(), - DeclEnd); - - return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AS); + Decl *DC = getObjCDeclContext(); + if (DC) + Actions.ActOnObjCContainerFinishDefinition(DC); + if (Tok.is(tok::kw_template) && NextToken().isNot(tok::less)) { + Decl *Res = ParseExplicitInstantiation(SourceLocation(), ConsumeToken(), + DeclEnd); + if (DC) + Actions.ActOnObjCContainerStartDefinition(DC); + return Res; + } + Decl *Res = ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AS); + if (DC) + Actions.ActOnObjCContainerStartDefinition(DC); + return Res; } /// \brief RAII class that manages the template parameter depth. diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 5bb4165fbb..d7e7d4b081 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -811,7 +811,16 @@ Parser::ParseDeclarationOrFunctionDefinition(ParsedAttributes &attrs, AccessSpecifier AS) { ParsingDeclSpec DS(*this); DS.takeAttributesFrom(attrs); - return ParseDeclarationOrFunctionDefinition(DS, AS); + Decl *DC = getObjCDeclContext(); + if (DC) + // Must temporarily exit the objective-c container scope for + // parsing c constructs and re-enter objc container scope + // afterwards. + Actions.ActOnObjCContainerFinishDefinition(DC); + DeclGroupPtrTy resPtrTy = ParseDeclarationOrFunctionDefinition(DS, AS); + if (DC) + Actions.ActOnObjCContainerStartDefinition(DC); + return resPtrTy; } /// ParseFunctionDefinition - We parsed and verified that the specified diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 858a001d43..ef54fbcad8 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -4141,15 +4141,14 @@ static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) { Results.AddResult(Result(Builder.TakeString())); } -void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl, - bool InInterface) { +void Sema::CodeCompleteObjCAtDirective(Scope *S) { typedef CodeCompletionResult Result; ResultBuilder Results(*this, CodeCompleter->getAllocator(), CodeCompletionContext::CCC_Other); Results.EnterNewScope(); - if (ObjCImpDecl) + if (isa<ObjCImplDecl>(CurContext)) AddObjCImplementationResults(getLangOptions(), Results, false); - else if (InInterface) + else if (CurContext->isObjCContainer()) AddObjCInterfaceResults(getLangOptions(), Results, false); else AddObjCTopLevelResults(Results, false); @@ -4521,14 +4520,14 @@ static void AddObjCMethods(ObjCContainerDecl *Container, } -void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl) { +void Sema::CodeCompleteObjCPropertyGetter(Scope *S) { typedef CodeCompletionResult Result; // Try to find the interface where getters might live. - ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl); + ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurContext); if (!Class) { if (ObjCCategoryDecl *Category - = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl)) + = dyn_cast_or_null<ObjCCategoryDecl>(CurContext)) Class = Category->getClassInterface(); if (!Class) @@ -4549,15 +4548,15 @@ void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl) { Results.data(),Results.size()); } -void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl) { +void Sema::CodeCompleteObjCPropertySetter(Scope *S) { typedef CodeCompletionResult Result; // Try to find the interface where setters might live. ObjCInterfaceDecl *Class - = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl); + = dyn_cast_or_null<ObjCInterfaceDecl>(CurContext); if (!Class) { if (ObjCCategoryDecl *Category - = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl)) + = dyn_cast_or_null<ObjCCategoryDecl>(CurContext)) Class = Category->getClassInterface(); if (!Class) @@ -5551,14 +5550,14 @@ void Sema::CodeCompleteObjCImplementationCategory(Scope *S, Results.data(),Results.size()); } -void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) { +void Sema::CodeCompleteObjCPropertyDefinition(Scope *S) { typedef CodeCompletionResult Result; ResultBuilder Results(*this, CodeCompleter->getAllocator(), CodeCompletionContext::CCC_Other); // Figure out where this @synthesize lives. ObjCContainerDecl *Container - = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl); + = dyn_cast_or_null<ObjCContainerDecl>(CurContext); if (!Container || (!isa<ObjCImplementationDecl>(Container) && !isa<ObjCCategoryImplDecl>(Container))) @@ -5591,15 +5590,14 @@ void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) { } void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S, - IdentifierInfo *PropertyName, - Decl *ObjCImpDecl) { + IdentifierInfo *PropertyName) { typedef CodeCompletionResult Result; ResultBuilder Results(*this, CodeCompleter->getAllocator(), CodeCompletionContext::CCC_Other); // Figure out where this @synthesize lives. ObjCContainerDecl *Container - = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl); + = dyn_cast_or_null<ObjCContainerDecl>(CurContext); if (!Container || (!isa<ObjCImplementationDecl>(Container) && !isa<ObjCCategoryImplDecl>(Container))) @@ -6412,12 +6410,15 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, void Sema::CodeCompleteObjCMethodDecl(Scope *S, bool IsInstanceMethod, - ParsedType ReturnTy, - Decl *IDecl) { + ParsedType ReturnTy) { // Determine the return type of the method we're declaring, if // provided. QualType ReturnType = GetTypeFromParser(ReturnTy); - + Decl *IDecl = 0; + if (CurContext->isObjCContainer()) { + ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext); + IDecl = cast<Decl>(OCD); + } // Determine where we should start searching for methods. ObjCContainerDecl *SearchDecl = 0; bool IsInImplementation = false; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index b45b7ae5dc..26af6ef97d 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -737,11 +737,6 @@ DeclContext *Sema::getContainingDC(DeclContext *DC) { return DC; } - // ObjCMethodDecls are parsed (for some reason) outside the context - // of the class. - if (isa<ObjCMethodDecl>(DC)) - return DC->getLexicalParent()->getLexicalParent(); - return DC->getLexicalParent(); } @@ -7732,6 +7727,15 @@ void Sema::ActOnTagStartDefinition(Scope *S, Decl *TagD) { PushDeclContext(S, Tag); } +void Sema::ActOnObjCContainerStartDefinition(Decl *IDecl) { + assert(isa<ObjCContainerDecl>(IDecl) && + "ActOnObjCContainerStartDefinition - Not ObjCContainerDecl"); + DeclContext *OCD = cast<DeclContext>(IDecl); + assert(getContainingDC(OCD) == CurContext && + "The next DeclContext should be lexically contained in the current one."); + CurContext = OCD; +} + void Sema::ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagD, SourceLocation FinalLoc, SourceLocation LBraceLoc) { @@ -7783,6 +7787,11 @@ void Sema::ActOnTagFinishDefinition(Scope *S, Decl *TagD, Consumer.HandleTagDeclDefinition(Tag); } +void Sema::ActOnObjCContainerFinishDefinition(Decl *IDecl) { + // Exit this scope of this interface definition. + PopDeclContext(); +} + void Sema::ActOnTagDefinitionError(Scope *S, Decl *TagD) { AdjustDeclIfTemplate(TagD); TagDecl *Tag = cast<TagDecl>(TagD); @@ -8327,7 +8336,6 @@ TranslateIvarVisibility(tok::ObjCKeywordKind ivarVisibility) { /// in order to create an IvarDecl object for it. Decl *Sema::ActOnIvar(Scope *S, SourceLocation DeclStart, - Decl *IntfDecl, Declarator &D, ExprTy *BitfieldWidth, tok::ObjCKeywordKind Visibility) { @@ -8370,7 +8378,7 @@ Decl *Sema::ActOnIvar(Scope *S, Visibility != tok::objc_not_keyword ? TranslateIvarVisibility(Visibility) : ObjCIvarDecl::None; // Must set ivar's DeclContext to its enclosing interface. - ObjCContainerDecl *EnclosingDecl = cast<ObjCContainerDecl>(IntfDecl); + ObjCContainerDecl *EnclosingDecl = cast<ObjCContainerDecl>(CurContext); ObjCContainerDecl *EnclosingContext; if (ObjCImplementationDecl *IMPDecl = dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) { @@ -8432,7 +8440,7 @@ Decl *Sema::ActOnIvar(Scope *S, /// class and class extensions. For every class @interface and class /// extension @interface, if the last ivar is a bitfield of any type, /// then add an implicit `char :0` ivar to the end of that interface. -void Sema::ActOnLastBitfield(SourceLocation DeclLoc, Decl *EnclosingDecl, +void Sema::ActOnLastBitfield(SourceLocation DeclLoc, SmallVectorImpl<Decl *> &AllIvarDecls) { if (!LangOpts.ObjCNonFragileABI2 || AllIvarDecls.empty()) return; @@ -8446,9 +8454,9 @@ void Sema::ActOnLastBitfield(SourceLocation DeclLoc, Decl *EnclosingDecl, Ivar->getBitWidth()->EvaluateAsInt(Context).getZExtValue(); if (BitFieldSize == 0) return; - ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(EnclosingDecl); + ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CurContext); if (!ID) { - if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(EnclosingDecl)) { + if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CurContext)) { if (!CD->IsClassExtension()) return; } @@ -8460,7 +8468,7 @@ void Sema::ActOnLastBitfield(SourceLocation DeclLoc, Decl *EnclosingDecl, llvm::APInt Zero(Context.getTypeSize(Context.IntTy), 0); Expr * BW = IntegerLiteral::Create(Context, Zero, Context.IntTy, DeclLoc); - Ivar = ObjCIvarDecl::Create(Context, cast<ObjCContainerDecl>(EnclosingDecl), + Ivar = ObjCIvarDecl::Create(Context, cast<ObjCContainerDecl>(CurContext), DeclLoc, DeclLoc, 0, Context.CharTy, Context.getTrivialTypeSourceInfo(Context.CharTy, @@ -9332,3 +9340,7 @@ void Sema::ActOnPragmaWeakAlias(IdentifierInfo* Name, std::pair<IdentifierInfo*,WeakInfo>(AliasName, W)); } } + +Decl *Sema::getObjCDeclContext() const { + return (dyn_cast_or_null<ObjCContainerDecl>(CurContext)); +} diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 3c3c7cb232..d255a3686f 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -2052,15 +2052,14 @@ void Sema::DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, // Note: For class/category implemenations, allMethods/allProperties is // always null. void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, - Decl *ClassDecl, Decl **allMethods, unsigned allNum, Decl **allProperties, unsigned pNum, DeclGroupPtrTy *allTUVars, unsigned tuvNum) { - // FIXME: If we don't have a ClassDecl, we have an error. We should consider - // always passing in a decl. If the decl has an error, isInvalidDecl() - // should be true. - if (!ClassDecl) + + if (!CurContext->isObjCContainer()) return; + ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext); + Decl *ClassDecl = cast<Decl>(OCD); bool isInterfaceDeclKind = isa<ObjCInterfaceDecl>(ClassDecl) || isa<ObjCCategoryDecl>(Class |