aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseTentative.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-10-21 23:17:00 +0000
committerDouglas Gregor <dgregor@apple.com>2010-10-21 23:17:00 +0000
commit9bd1d8d174a9d15ae343246c8322299248b9e92a (patch)
tree3d34514eefa6e0da0657c72c9d326bacbbeb2326 /lib/Parse/ParseTentative.cpp
parentd93fae659ca26558c62dd654e24293be024408af (diff)
Teach the C++ simple-type-specifier parser and tentative parses about
protocol-qualified types such as id<Protocol>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117081 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseTentative.cpp')
-rw-r--r--lib/Parse/ParseTentative.cpp75
1 files changed, 68 insertions, 7 deletions
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp
index 731822ecdd..9bd000c323 100644
--- a/lib/Parse/ParseTentative.cpp
+++ b/lib/Parse/ParseTentative.cpp
@@ -139,9 +139,13 @@ Parser::TPResult Parser::TryParseSimpleDeclaration() {
if (Tok.is(tok::kw_typeof))
TryParseTypeofSpecifier();
- else
+ else {
ConsumeToken();
-
+
+ if (getLang().ObjC1 && Tok.is(tok::less))
+ TryParseProtocolQualifiers();
+ }
+
assert(Tok.is(tok::l_paren) && "Expected '('");
TPResult TPR = TryParseInitDeclaratorList();
@@ -242,8 +246,12 @@ bool Parser::isCXXConditionDeclaration() {
// type-specifier-seq
if (Tok.is(tok::kw_typeof))
TryParseTypeofSpecifier();
- else
+ else {
ConsumeToken();
+
+ if (getLang().ObjC1 && Tok.is(tok::less))
+ TryParseProtocolQualifiers();
+ }
assert(Tok.is(tok::l_paren) && "Expected '('");
// declarator
@@ -313,8 +321,13 @@ bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
// type-specifier-seq
if (Tok.is(tok::kw_typeof))
TryParseTypeofSpecifier();
- else
+ else {
ConsumeToken();
+
+ if (getLang().ObjC1 && Tok.is(tok::less))
+ TryParseProtocolQualifiers();
+ }
+
assert(Tok.is(tok::l_paren) && "Expected '('");
// declarator
@@ -808,6 +821,28 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() {
// simple-type-specifier:
+ case tok::annot_typename:
+ case_typename:
+ // In Objective-C, we might have a protocol-qualified type.
+ if (getLang().ObjC1 && NextToken().is(tok::less)) {
+ // Tentatively parse the
+ TentativeParsingAction PA(*this);
+ ConsumeToken(); // The type token
+
+ TPResult TPR = TryParseProtocolQualifiers();
+ bool isFollowedByParen = Tok.is(tok::l_paren);
+
+ PA.Revert();
+
+ if (TPR == TPResult::Error())
+ return TPResult::Error();
+
+ if (isFollowedByParen)
+ return TPResult::Ambiguous();
+
+ return TPResult::True();
+ }
+
case tok::kw_char:
case tok::kw_wchar_t:
case tok::kw_char16_t:
@@ -821,8 +856,6 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() {
case tok::kw_float:
case tok::kw_double:
case tok::kw_void:
- case tok::annot_typename:
- case_typename:
if (NextToken().is(tok::l_paren))
return TPResult::Ambiguous();
@@ -878,6 +911,30 @@ Parser::TPResult Parser::TryParseTypeofSpecifier() {
return TPResult::Ambiguous();
}
+/// [ObjC] protocol-qualifiers:
+//// '<' identifier-list '>'
+Parser::TPResult Parser::TryParseProtocolQualifiers() {
+ assert(Tok.is(tok::less) && "Expected '<' for qualifier list");
+ ConsumeToken();
+ do {
+ if (Tok.isNot(tok::identifier))
+ return TPResult::Error();
+ ConsumeToken();
+
+ if (Tok.is(tok::comma)) {
+ ConsumeToken();
+ continue;
+ }
+
+ if (Tok.is(tok::greater)) {
+ ConsumeToken();
+ return TPResult::Ambiguous();
+ }
+ } while (false);
+
+ return TPResult::Error();
+}
+
Parser::TPResult Parser::TryParseDeclarationSpecifier() {
TPResult TPR = isCXXDeclarationSpecifier();
if (TPR != TPResult::Ambiguous())
@@ -885,8 +942,12 @@ Parser::TPResult Parser::TryParseDeclarationSpecifier() {
if (Tok.is(tok::kw_typeof))
TryParseTypeofSpecifier();
- else
+ else {
ConsumeToken();
+
+ if (getLang().ObjC1 && Tok.is(tok::less))
+ TryParseProtocolQualifiers();
+ }
assert(Tok.is(tok::l_paren) && "Expected '('!");
return TPResult::Ambiguous();