summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Parse')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp32
-rw-r--r--clang/lib/Parse/ParseInit.cpp25
-rw-r--r--clang/lib/Parse/ParseObjc.cpp54
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);
OpenPOWER on IntegriCloud