diff options
author | Douglas Gregor <dgregor@apple.com> | 2015-07-07 03:57:35 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2015-07-07 03:57:35 +0000 |
commit | e9d95f1ecc98ced831cace8b4b78cb7cc380f4aa (patch) | |
tree | 73962adb18c3f8c191701021f69a14b4121676e6 /clang/lib/Parse/ParseDecl.cpp | |
parent | 85f3f9513dbc88b9898d022a1a55a03d55612721 (diff) | |
download | bcm5719-llvm-e9d95f1ecc98ced831cace8b4b78cb7cc380f4aa.tar.gz bcm5719-llvm-e9d95f1ecc98ced831cace8b4b78cb7cc380f4aa.zip |
Handle Objective-C type arguments.
Objective-C type arguments can be provided in angle brackets following
an Objective-C interface type. Syntactically, this is the same
position as one would provide protocol qualifiers (e.g.,
id<NSCopying>), so parse both together and let Sema sort out the
ambiguous cases. This applies both when parsing types and when parsing
the superclass of an Objective-C class, which can now be a specialized
type (e.g., NSMutableArray<T> inherits from NSArray<T>).
Check Objective-C type arguments against the type parameters of the
corresponding class. Verify the length of the type argument list and
that each type argument satisfies the corresponding bound.
Specializations of parameterized Objective-C classes are represented
in the type system as distinct types. Both specialized types (e.g.,
NSArray<NSString *> *) and unspecialized types (NSArray *) are
represented, separately.
llvm-svn: 241542
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index d843e801b63..fdd10522ee5 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -2886,11 +2886,26 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, DS.SetRangeEnd(Tok.getAnnotationEndLoc()); ConsumeToken(); // The typename - // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id' - // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an - // Objective-C interface. - if (Tok.is(tok::less) && getLangOpts().ObjC1) - ParseObjCProtocolQualifiers(DS); + // Objective-C supports type arguments and protocol references + // 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); + } + } + } continue; } @@ -2997,11 +3012,26 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, DS.SetRangeEnd(Tok.getLocation()); ConsumeToken(); // The identifier - // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id' - // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an - // Objective-C interface. - if (Tok.is(tok::less) && getLangOpts().ObjC1) - ParseObjCProtocolQualifiers(DS); + // Objective-C supports type arguments and protocol references + // 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); + } + } + } // Need to support trailing type qualifiers (e.g. "id<p> const"). // If a type specifier follows, it will be diagnosed elsewhere. |