diff options
Diffstat (limited to 'clang/lib/Parse')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 32 | ||||
-rw-r--r-- | clang/lib/Parse/ParseInit.cpp | 25 | ||||
-rw-r--r-- | clang/lib/Parse/ParseObjc.cpp | 54 |
3 files changed, 75 insertions, 36 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index fdd10522ee5..231f6d4d97a 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -2890,21 +2890,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // following an Objective-C object pointer type. Handle either // one of them. if (Tok.is(tok::less) && getLangOpts().ObjC1) { - ParseObjCTypeArgsOrProtocolQualifiers( - DS, /*warnOnIncompleteProtocols=*/false); - - // An Objective-C object pointer followed by type arguments - // can then be followed again by a set of protocol references, e.g., - // \c NSArray<NSView><NSTextDelegate> - if (Tok.is(tok::less)) { - if (DS.getProtocolQualifiers()) { - Diag(Tok, diag::err_objc_type_args_after_protocols) - << SourceRange(DS.getProtocolLAngleLoc(), DS.getLocEnd()); - SkipUntil(tok::greater, tok::greatergreater); - } else { - ParseObjCProtocolQualifiers(DS); - } - } + ParseObjCTypeArgsAndProtocolQualifiers(DS); } continue; @@ -3016,21 +3002,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // following an Objective-C object pointer type. Handle either // one of them. if (Tok.is(tok::less) && getLangOpts().ObjC1) { - ParseObjCTypeArgsOrProtocolQualifiers( - DS, /*warnOnIncompleteProtocols=*/false); - - // An Objective-C object pointer followed by type arguments - // can then be followed again by a set of protocol references, e.g., - // \c NSArray<NSView><NSTextDelegate> - if (Tok.is(tok::less)) { - if (DS.getProtocolQualifiers()) { - Diag(Tok, diag::err_objc_type_args_after_protocols) - << SourceRange(DS.getProtocolLAngleLoc(), DS.getLocEnd()); - SkipUntil(tok::greater, tok::greatergreater); - } else { - ParseObjCProtocolQualifiers(DS); - } - } + ParseObjCTypeArgsAndProtocolQualifiers(DS); } // Need to support trailing type qualifiers (e.g. "id<p> const"). diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp index 42287d68b33..f62c8be0769 100644 --- a/clang/lib/Parse/ParseInit.cpp +++ b/clang/lib/Parse/ParseInit.cpp @@ -258,20 +258,33 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator() { NextToken().is(tok::period), ReceiverType)) { case Sema::ObjCSuperMessage: + CheckArrayDesignatorSyntax(*this, StartLoc, Desig); + return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, + ConsumeToken(), + ParsedType(), + nullptr); + case Sema::ObjCClassMessage: CheckArrayDesignatorSyntax(*this, StartLoc, Desig); - if (Kind == Sema::ObjCSuperMessage) - return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, - ConsumeToken(), - ParsedType(), - nullptr); ConsumeToken(); // the identifier if (!ReceiverType) { SkipUntil(tok::r_square, StopAtSemi); return ExprError(); } - return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, + // Parse type arguments and protocol qualifiers. + if (Tok.is(tok::less)) { + TypeResult NewReceiverType + = ParseObjCTypeArgsAndProtocolQualifiers(IILoc, ReceiverType); + if (!NewReceiverType.isUsable()) { + SkipUntil(tok::r_square, StopAtSemi); + return ExprError(); + } + + ReceiverType = NewReceiverType.get(); + } + + return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, SourceLocation(), ReceiverType, nullptr); diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 0e4574056b0..669c0653df8 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -438,8 +438,10 @@ ObjCTypeParamList *Parser::parseObjCTypeParamListOrProtocolRefs( // type parameters. SmallVector<Decl *, 4> typeParams; auto makeProtocolIdentsIntoTypeParameters = [&]() { + unsigned index = 0; for (const auto &pair : protocolIdents) { DeclResult typeParam = Actions.actOnObjCTypeParam(getCurScope(), + index++, pair.first, pair.second, SourceLocation(), @@ -502,6 +504,7 @@ ObjCTypeParamList *Parser::parseObjCTypeParamListOrProtocolRefs( // Create the type parameter. DeclResult typeParam = Actions.actOnObjCTypeParam(getCurScope(), + typeParams.size(), paramName, paramLoc, colonLoc, @@ -1675,6 +1678,45 @@ void Parser::ParseObjCTypeArgsOrProtocolQualifiers( DS.setObjCTypeArgs(lAngleLoc, typeArgs, rAngleLoc); } +void Parser::ParseObjCTypeArgsAndProtocolQualifiers(DeclSpec &DS) { + assert(Tok.is(tok::less)); + + ParseObjCTypeArgsOrProtocolQualifiers(DS, + /*warnOnIncompleteProtocols=*/false); + + // An Objective-C object pointer followed by type arguments + // can then be followed again by a set of protocol references, e.g., + // \c NSArray<NSView><NSTextDelegate> + if (Tok.is(tok::less)) { + if (DS.getProtocolQualifiers()) { + Diag(Tok, diag::err_objc_type_args_after_protocols) + << SourceRange(DS.getProtocolLAngleLoc(), DS.getLocEnd()); + SkipUntil(tok::greater, tok::greatergreater); + } else { + ParseObjCProtocolQualifiers(DS); + } + } +} + +TypeResult Parser::ParseObjCTypeArgsAndProtocolQualifiers(SourceLocation loc, + ParsedType type) { + assert(Tok.is(tok::less)); + + // Create declaration specifiers and set the type as the type specifier. + DeclSpec DS(AttrFactory); + const char *prevSpec = nullptr; + unsigned diagID; + DS.SetTypeSpecType(TST_typename, loc, prevSpec, diagID, type, + Actions.getASTContext().getPrintingPolicy()); + + // Parse type arguments and protocol qualifiers. + ParseObjCTypeArgsAndProtocolQualifiers(DS); + + // Form a declarator to turn this into a type. + Declarator D(DS, Declarator::TypeNameContext); + return Actions.ActOnTypeName(getCurScope(), D); +} + void Parser::HelperActionsForIvarDeclarations(Decl *interfaceDecl, SourceLocation atLoc, BalancedDelimiterTracker &T, SmallVectorImpl<Decl *> &AllIvarDecls, @@ -2829,6 +2871,18 @@ ExprResult Parser::ParseObjCMessageExpression() { ConsumeToken(); // the type name + // Parse type arguments and protocol qualifiers. + if (Tok.is(tok::less)) { + TypeResult NewReceiverType + = ParseObjCTypeArgsAndProtocolQualifiers(NameLoc, ReceiverType); + if (!NewReceiverType.isUsable()) { + SkipUntil(tok::r_square, StopAtSemi); + return ExprError(); + } + + ReceiverType = NewReceiverType.get(); + } + return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), ReceiverType, nullptr); |