summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2015-07-07 03:58:14 +0000
committerDouglas Gregor <dgregor@apple.com>2015-07-07 03:58:14 +0000
commit9bda6cff20276f67c02d0d2814ef44c2d62ecd89 (patch)
tree42cdccf290e6507ad745f4b0a838e76a6f8e32d0 /clang/lib/Parse/ParseDecl.cpp
parentc5e07f5c115ed486f57db957447086c1b0023385 (diff)
downloadbcm5719-llvm-9bda6cff20276f67c02d0d2814ef44c2d62ecd89.tar.gz
bcm5719-llvm-9bda6cff20276f67c02d0d2814ef44c2d62ecd89.zip
C++ support for Objective-C lightweight generics.
Teach C++'s tentative parsing to handle specializations of Objective-C class types (e.g., NSArray<NSString *>) as well as Objective-C protocol qualifiers (id<NSCopying>) by extending type-annotation tokens to handle this case. As part of this, remove Objective-C protocol qualifiers from the declaration specifiers, which never really made sense: instead, provide Sema entry points to make them part of the type annotation token. Among other things, this properly diagnoses bogus types such as "<NSCopying> id" which should have been written as "id <NSCopying>". Implements template instantiation support for, e.g., NSArray<T>* in C++. Note that parameterized classes are not templates in the C++ sense, so that cannot (for example) be used as a template argument for a template template parameter. Part of rdar://problem/6294649. llvm-svn: 241545
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp40
1 files changed, 24 insertions, 16 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 231f6d4d97a..9c12abab39d 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -2144,8 +2144,7 @@ void Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS,
if (isTypeSpecifier(DSC) && !DS.hasTypeSpecifier()) {
Diag(Tok, diag::err_expected_type);
DS.SetTypeSpecError();
- } else if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() &&
- !DS.hasAttributes()) {
+ } else if (Specs == DeclSpec::PQ_None && !DS.hasAttributes()) {
Diag(Tok, diag::err_typename_requires_specqual);
if (!DS.hasTypeSpecifier())
DS.SetTypeSpecError();
@@ -2886,13 +2885,6 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
DS.SetRangeEnd(Tok.getAnnotationEndLoc());
ConsumeToken(); // The typename
- // 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) {
- ParseObjCTypeArgsAndProtocolQualifiers(DS);
- }
-
continue;
}
@@ -2999,10 +2991,17 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
ConsumeToken(); // The identifier
// Objective-C supports type arguments and protocol references
- // following an Objective-C object pointer type. Handle either
- // one of them.
+ // following an Objective-C object or object pointer
+ // type. Handle either one of them.
if (Tok.is(tok::less) && getLangOpts().ObjC1) {
- ParseObjCTypeArgsAndProtocolQualifiers(DS);
+ SourceLocation NewEndLoc;
+ TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
+ Loc, TypeRep, /*consumeLastToken=*/true,
+ NewEndLoc);
+ if (NewTypeRep.isUsable()) {
+ DS.UpdateTypeRep(NewTypeRep.get());
+ DS.SetRangeEnd(NewEndLoc);
+ }
}
// Need to support trailing type qualifiers (e.g. "id<p> const").
@@ -3420,10 +3419,19 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
if (DS.hasTypeSpecifier() || !getLangOpts().ObjC1)
goto DoneWithDeclSpec;
- if (!ParseObjCProtocolQualifiers(DS))
- Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id)
- << FixItHint::CreateInsertion(Loc, "id")
- << SourceRange(Loc, DS.getSourceRange().getEnd());
+ SourceLocation StartLoc = Tok.getLocation();
+ SourceLocation EndLoc;
+ TypeResult Type = parseObjCProtocolQualifierType(EndLoc);
+ if (Type.isUsable()) {
+ if (DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc, StartLoc,
+ PrevSpec, DiagID, Type.get(),
+ Actions.getASTContext().getPrintingPolicy()))
+ Diag(StartLoc, DiagID) << PrevSpec;
+
+ DS.SetRangeEnd(EndLoc);
+ } else {
+ DS.SetTypeSpecError();
+ }
// Need to support trailing type qualifiers (e.g. "id<p> const").
// If a type specifier follows, it will be diagnosed elsewhere.
OpenPOWER on IntegriCloud