diff options
Diffstat (limited to 'lib/Parse/ParseObjc.cpp')
-rw-r--r-- | lib/Parse/ParseObjc.cpp | 197 |
1 files changed, 91 insertions, 106 deletions
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index fb8624a324b9..5c5b3cdfcf33 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -13,11 +13,11 @@ #include "clang/Parse/Parser.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/PrettyDeclStackTrace.h" #include "clang/Basic/CharInfo.h" #include "clang/Parse/ParseDiagnostic.h" #include "clang/Parse/RAIIObjectsForParser.h" #include "clang/Sema/DeclSpec.h" -#include "clang/Sema/PrettyDeclStackTrace.h" #include "clang/Sema/Scope.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" @@ -45,7 +45,8 @@ void Parser::MaybeSkipAttributes(tok::ObjCKeywordKind Kind) { /// [OBJC] objc-protocol-definition /// [OBJC] objc-method-definition /// [OBJC] '@' 'end' -Parser::DeclGroupPtrTy Parser::ParseObjCAtDirectives() { +Parser::DeclGroupPtrTy +Parser::ParseObjCAtDirectives(ParsedAttributesWithRange &Attrs) { SourceLocation AtLoc = ConsumeToken(); // the "@" if (Tok.is(tok::code_completion)) { @@ -58,15 +59,11 @@ Parser::DeclGroupPtrTy Parser::ParseObjCAtDirectives() { switch (Tok.getObjCKeywordID()) { case tok::objc_class: return ParseObjCAtClassDeclaration(AtLoc); - case tok::objc_interface: { - ParsedAttributes attrs(AttrFactory); - SingleDecl = ParseObjCAtInterfaceDeclaration(AtLoc, attrs); + case tok::objc_interface: + SingleDecl = ParseObjCAtInterfaceDeclaration(AtLoc, Attrs); break; - } - case tok::objc_protocol: { - ParsedAttributes attrs(AttrFactory); - return ParseObjCAtProtocolDeclaration(AtLoc, attrs); - } + case tok::objc_protocol: + return ParseObjCAtProtocolDeclaration(AtLoc, Attrs); case tok::objc_implementation: return ParseObjCAtImplementationDeclaration(AtLoc); case tok::objc_end: @@ -290,7 +287,7 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc, Decl *CategoryType = Actions.ActOnStartCategoryInterface( AtLoc, nameId, nameLoc, typeParameterList, categoryId, categoryLoc, ProtocolRefs.data(), ProtocolRefs.size(), ProtocolLocs.data(), - EndProtoLoc, attrs.getList()); + EndProtoLoc, attrs); if (Tok.is(tok::l_brace)) ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, AtLoc); @@ -356,17 +353,12 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc, if (Tok.isNot(tok::less)) Actions.ActOnTypedefedProtocols(protocols, protocolLocs, superClassId, superClassLoc); - - Decl *ClsType = - Actions.ActOnStartClassInterface(getCurScope(), AtLoc, nameId, nameLoc, - typeParameterList, superClassId, - superClassLoc, - typeArgs, - SourceRange(typeArgsLAngleLoc, - typeArgsRAngleLoc), - protocols.data(), protocols.size(), - protocolLocs.data(), - EndProtoLoc, attrs.getList()); + + Decl *ClsType = Actions.ActOnStartClassInterface( + getCurScope(), AtLoc, nameId, nameLoc, typeParameterList, superClassId, + superClassLoc, typeArgs, + SourceRange(typeArgsLAngleLoc, typeArgsRAngleLoc), protocols.data(), + protocols.size(), protocolLocs.data(), EndProtoLoc, attrs); if (Tok.is(tok::l_brace)) ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, AtLoc); @@ -384,25 +376,21 @@ static void addContextSensitiveTypeNullability(Parser &P, SourceLocation nullabilityLoc, bool &addedToDeclSpec) { // Create the attribute. - auto getNullabilityAttr = [&]() -> AttributeList * { - return D.getAttributePool().create( - P.getNullabilityKeyword(nullability), - SourceRange(nullabilityLoc), - nullptr, SourceLocation(), - nullptr, 0, - AttributeList::AS_ContextSensitiveKeyword); + auto getNullabilityAttr = [&](AttributePool &Pool) -> ParsedAttr * { + return Pool.create(P.getNullabilityKeyword(nullability), + SourceRange(nullabilityLoc), nullptr, SourceLocation(), + nullptr, 0, ParsedAttr::AS_ContextSensitiveKeyword); }; if (D.getNumTypeObjects() > 0) { // Add the attribute to the declarator chunk nearest the declarator. - auto nullabilityAttr = getNullabilityAttr(); - DeclaratorChunk &chunk = D.getTypeObject(0); - nullabilityAttr->setNext(chunk.getAttrListRef()); - chunk.getAttrListRef() = nullabilityAttr; + D.getTypeObject(0).getAttrs().addAtStart( + getNullabilityAttr(D.getAttributePool())); } else if (!addedToDeclSpec) { // Otherwise, just put it on the declaration specifiers (if one // isn't there already). - D.getMutableDeclSpec().addAttributes(getNullabilityAttr()); + D.getMutableDeclSpec().getAttributes().addAtStart( + getNullabilityAttr(D.getMutableDeclSpec().getAttributes().getPool())); addedToDeclSpec = true; } } @@ -1140,14 +1128,14 @@ bool Parser::isTokIdentifier_in() const { /// 'null_unspecified' /// void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS, - Declarator::TheContext Context) { - assert(Context == Declarator::ObjCParameterContext || - Context == Declarator::ObjCResultContext); + DeclaratorContext Context) { + assert(Context == DeclaratorContext::ObjCParameterContext || + Context == DeclaratorContext::ObjCResultContext); while (1) { if (Tok.is(tok::code_completion)) { Actions.CodeCompleteObjCPassingType(getCurScope(), DS, - Context == Declarator::ObjCParameterContext); + Context == DeclaratorContext::ObjCParameterContext); return cutOffParsing(); } @@ -1205,18 +1193,12 @@ void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS, /// Take all the decl attributes out of the given list and add /// them to the given attribute set. -static void takeDeclAttributes(ParsedAttributes &attrs, - AttributeList *list) { - while (list) { - AttributeList *cur = list; - list = cur->getNext(); - - if (!cur->isUsedAsTypeAttr()) { - // Clear out the next pointer. We're really completely - // destroying the internal invariants of the declarator here, - // but it doesn't matter because we're done with it. - cur->setNext(nullptr); - attrs.add(cur); +static void takeDeclAttributes(ParsedAttributesView &attrs, + ParsedAttributesView &from) { + for (auto &AL : llvm::reverse(from)) { + if (!AL.isUsedAsTypeAttr()) { + from.remove(&AL); + attrs.addAtStart(&AL); } } } @@ -1230,11 +1212,10 @@ static void takeDeclAttributes(ParsedAttributes &attrs, attrs.getPool().takeAllFrom(D.getDeclSpec().getAttributePool()); // Now actually move the attributes over. - takeDeclAttributes(attrs, D.getDeclSpec().getAttributes().getList()); + takeDeclAttributes(attrs, D.getMutableDeclSpec().getAttributes()); takeDeclAttributes(attrs, D.getAttributes()); for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) - takeDeclAttributes(attrs, - const_cast<AttributeList*>(D.getTypeObject(i).getAttrs())); + takeDeclAttributes(attrs, D.getTypeObject(i).getAttrs()); } /// objc-type-name: @@ -1242,12 +1223,12 @@ static void takeDeclAttributes(ParsedAttributes &attrs, /// '(' objc-type-qualifiers[opt] ')' /// ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS, - Declarator::TheContext context, + DeclaratorContext context, ParsedAttributes *paramAttrs) { - assert(context == Declarator::ObjCParameterContext || - context == Declarator::ObjCResultContext); + assert(context == DeclaratorContext::ObjCParameterContext || + context == DeclaratorContext::ObjCResultContext); assert((paramAttrs != nullptr) == - (context == Declarator::ObjCParameterContext)); + (context == DeclaratorContext::ObjCParameterContext)); assert(Tok.is(tok::l_paren) && "expected ("); @@ -1265,9 +1246,9 @@ ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS, // Parse an abstract declarator. DeclSpec declSpec(AttrFactory); declSpec.setObjCQualifiers(&DS); - DeclSpecContext dsContext = DSC_normal; - if (context == Declarator::ObjCResultContext) - dsContext = DSC_objc_method_result; + DeclSpecContext dsContext = DeclSpecContext::DSC_normal; + if (context == DeclaratorContext::ObjCResultContext) + dsContext = DeclSpecContext::DSC_objc_method_result; ParseSpecifierQualifierList(declSpec, AS_none, dsContext); Declarator declarator(declSpec, context); ParseDeclarator(declarator); @@ -1288,7 +1269,7 @@ ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS, // If we're parsing a parameter, steal all the decl attributes // and add them to the decl spec. - if (context == Declarator::ObjCParameterContext) + if (context == DeclaratorContext::ObjCParameterContext) takeDeclAttributes(*paramAttrs, declarator); } } @@ -1352,13 +1333,14 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, ParsedType ReturnType; ObjCDeclSpec DSRet; if (Tok.is(tok::l_paren)) - ReturnType = ParseObjCTypeName(DSRet, Declarator::ObjCResultContext, + ReturnType = ParseObjCTypeName(DSRet, DeclaratorContext::ObjCResultContext, nullptr); // If attributes exist before the method, parse them. ParsedAttributes methodAttrs(AttrFactory); if (getLangOpts().ObjC2) MaybeParseGNUAttributes(methodAttrs); + MaybeParseCXX11Attributes(methodAttrs); if (Tok.is(tok::code_completion)) { Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, @@ -1385,15 +1367,13 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, // If attributes exist after the method, parse them. if (getLangOpts().ObjC2) MaybeParseGNUAttributes(methodAttrs); + MaybeParseCXX11Attributes(methodAttrs); Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent); - Decl *Result - = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(), - mType, DSRet, ReturnType, - selLoc, Sel, nullptr, - CParamInfo.data(), CParamInfo.size(), - methodAttrs.getList(), MethodImplKind, - false, MethodDefinition); + Decl *Result = Actions.ActOnMethodDeclaration( + getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType, + selLoc, Sel, nullptr, CParamInfo.data(), CParamInfo.size(), methodAttrs, + MethodImplKind, false, MethodDefinition); PD.complete(Result); return Result; } @@ -1416,16 +1396,15 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, ArgInfo.Type = nullptr; if (Tok.is(tok::l_paren)) // Parse the argument type if present. ArgInfo.Type = ParseObjCTypeName(ArgInfo.DeclSpec, - Declarator::ObjCParameterContext, + DeclaratorContext::ObjCParameterContext, ¶mAttrs); // If attributes exist before the argument name, parse them. // Regardless, collect all the attributes we've parsed so far. - ArgInfo.ArgAttrs = nullptr; - if (getLangOpts().ObjC2) { + if (getLangOpts().ObjC2) MaybeParseGNUAttributes(paramAttrs); - ArgInfo.ArgAttrs = paramAttrs.getList(); - } + MaybeParseCXX11Attributes(paramAttrs); + ArgInfo.ArgAttrs = paramAttrs; // Code completion for the next piece of the selector. if (Tok.is(tok::code_completion)) { @@ -1494,7 +1473,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, DeclSpec DS(AttrFactory); ParseDeclarationSpecifiers(DS); // Parse the declarator. - Declarator ParmDecl(DS, Declarator::PrototypeContext); + Declarator ParmDecl(DS, DeclaratorContext::PrototypeContext); ParseDeclarator(ParmDecl); IdentifierInfo *ParmII = ParmDecl.getIdentifier(); Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl); @@ -1508,20 +1487,18 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, // If attributes exist after the method, parse them. if (getLangOpts().ObjC2) MaybeParseGNUAttributes(methodAttrs); - + MaybeParseCXX11Attributes(methodAttrs); + if (KeyIdents.size() == 0) return nullptr; Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(), &KeyIdents[0]); - Decl *Result - = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(), - mType, DSRet, ReturnType, - KeyLocs, Sel, &ArgInfos[0], - CParamInfo.data(), CParamInfo.size(), - methodAttrs.getList(), - MethodImplKind, isVariadic, MethodDefinition); - + Decl *Result = Actions.ActOnMethodDeclaration( + getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType, KeyLocs, + Sel, &ArgInfos[0], CParamInfo.data(), CParamInfo.size(), methodAttrs, + MethodImplKind, isVariadic, MethodDefinition); + PD.complete(Result); return Result; } @@ -1703,7 +1680,7 @@ void Parser::parseObjCTypeArgsOrProtocolQualifiers( typeArg, Actions.getASTContext().getPrintingPolicy()); // Form a declarator to turn this into a type. - Declarator D(DS, Declarator::TypeNameContext); + Declarator D(DS, DeclaratorContext::TypeNameContext); TypeResult fullTypeArg = Actions.ActOnTypeName(getCurScope(), D); if (fullTypeArg.isUsable()) { typeArgs.push_back(fullTypeArg.get()); @@ -1886,9 +1863,9 @@ void Parser::HelperActionsForIvarDeclarations(Decl *interfaceDecl, SourceLocatio Actions.ActOnObjCContainerFinishDefinition(); // 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, - AllIvarDecls, - T.getOpenLocation(), T.getCloseLocation(), nullptr); + Actions.ActOnFields(getCurScope(), atLoc, interfaceDecl, AllIvarDecls, + T.getOpenLocation(), T.getCloseLocation(), + ParsedAttributesView()); } /// objc-class-instance-variables: @@ -2038,8 +2015,7 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, if (TryConsumeToken(tok::semi)) { // forward declaration of one protocol. IdentifierLocPair ProtoInfo(protocolName, nameLoc); - return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtoInfo, - attrs.getList()); + return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtoInfo, attrs); } CheckNestedObjCContexts(AtLoc); @@ -2066,8 +2042,7 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@protocol")) return nullptr; - return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtocolRefs, - attrs.getList()); + return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtocolRefs, attrs); } // Last, and definitely not least, parse a protocol declaration. @@ -2081,12 +2056,9 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, /*consumeLastToken=*/true)) return nullptr; - Decl *ProtoType = - Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc, - ProtocolRefs.data(), - ProtocolRefs.size(), - ProtocolLocs.data(), - EndProtoLoc, attrs.getList()); + Decl *ProtoType = Actions.ActOnStartProtocolInterface( + AtLoc, protocolName, nameLoc, ProtocolRefs.data(), ProtocolRefs.size(), + ProtocolLocs.data(), EndProtoLoc, attrs); ParseObjCInterfaceDeclList(tok::objc_protocol, ProtoType); return Actions.ConvertDeclToDeclGroup(ProtoType); @@ -2273,7 +2245,7 @@ void Parser::ObjCImplParsingDataRAII::finish(SourceRange AtEnd) { P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i], false/*c-functions*/); - /// \brief Clear and free the cached objc methods. + /// Clear and free the cached objc methods. for (LateParsedObjCMethodContainer::iterator I = LateParsedObjCMethods.begin(), E = LateParsedObjCMethods.end(); I != E; ++I) @@ -2543,7 +2515,7 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { if (Tok.isNot(tok::ellipsis)) { DeclSpec DS(AttrFactory); ParseDeclarationSpecifiers(DS); - Declarator ParmDecl(DS, Declarator::ObjCCatchContext); + Declarator ParmDecl(DS, DeclaratorContext::ObjCCatchContext); ParseDeclarator(ParmDecl); // Inform the actions module about the declarator, so it @@ -2586,13 +2558,26 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { ParseScope FinallyScope(this, Scope::DeclScope | Scope::CompoundStmtScope); + bool ShouldCapture = + getTargetInfo().getTriple().isWindowsMSVCEnvironment(); + if (ShouldCapture) + Actions.ActOnCapturedRegionStart(Tok.getLocation(), getCurScope(), + CR_ObjCAtFinally, 1); + StmtResult FinallyBody(true); if (Tok.is(tok::l_brace)) FinallyBody = ParseCompoundStatementBody(); else Diag(Tok, diag::err_expected) << tok::l_brace; - if (FinallyBody.isInvalid()) + + if (FinallyBody.isInvalid()) { FinallyBody = Actions.ActOnNullStmt(Tok.getLocation()); + if (ShouldCapture) + Actions.ActOnCapturedRegionError(); + } else if (ShouldCapture) { + FinallyBody = Actions.ActOnCapturedRegionEnd(FinallyBody.get()); + } + FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc, FinallyBody.get()); catch_or_finally_seen = true; @@ -2681,7 +2666,7 @@ void Parser::StashAwayMethodOrFunctionBodyTokens(Decl *MDecl) { Decl *Parser::ParseObjCMethodDefinition() { Decl *MDecl = ParseObjCMethodPrototype(); - PrettyDeclStackTraceEntry CrashInfo(Actions, MDecl, Tok.getLocation(), + PrettyDeclStackTraceEntry CrashInfo(Actions.Context, MDecl, Tok.getLocation(), "parsing Objective-C method"); // parse optional ';' @@ -2865,7 +2850,7 @@ ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { } } -/// \brief Parse the receiver of an Objective-C++ message send. +/// Parse the receiver of an Objective-C++ message send. /// /// This routine parses the receiver of a message send in /// Objective-C++ either as a type or as an expression. Note that this @@ -2945,7 +2930,7 @@ bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) { // We have a class message. Turn the simple-type-specifier or // typename-specifier we parsed into a type and parse the // remainder of the class message. - Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); + Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext); TypeResult Type = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); if (Type.isInvalid()) return true; @@ -2955,7 +2940,7 @@ bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) { return false; } -/// \brief Determine whether the parser is currently referring to a an +/// Determine whether the parser is currently referring to a an /// Objective-C message send, using a simplified heuristic to avoid overhead. /// /// This routine will only return true for a subset of valid message-send @@ -3100,7 +3085,7 @@ ExprResult Parser::ParseObjCMessageExpression() { Res.get()); } -/// \brief Parse the remainder of an Objective-C message following the +/// Parse the remainder of an Objective-C message following the /// '[' objc-receiver. /// /// This routine handles sends to super, class messages (sent to a |