ParseExprCXX.cpp revision e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1
1//===--- ParseExprCXX.cpp - C++ Expression Parsing ------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Expression parsing implementation for C++.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Parse/ParseDiagnostic.h"
15#include "clang/Parse/Parser.h"
16#include "clang/Parse/DeclSpec.h"
17#include "AstGuard.h"
18using namespace clang;
19
20/// ParseOptionalCXXScopeSpecifier - Parse global scope or
21/// nested-name-specifier if present.  Returns true if a nested-name-specifier
22/// was parsed from the token stream.  Note that this routine will not parse
23/// ::new or ::delete, it will just leave them in the token stream.
24///
25///       '::'[opt] nested-name-specifier
26///       '::'
27///
28///       nested-name-specifier:
29///         type-name '::'
30///         namespace-name '::'
31///         nested-name-specifier identifier '::'
32///         nested-name-specifier 'template'[opt] simple-template-id '::' [TODO]
33///
34bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) {
35  assert(getLang().CPlusPlus &&
36         "Call sites of this function should be guarded by checking for C++");
37
38  if (Tok.is(tok::annot_cxxscope)) {
39    SS.setFromAnnotationData(Tok.getAnnotationValue());
40    CXXScopeSpec::freeAnnotationData(Tok.getAnnotationValue());
41    SS.setRange(Tok.getAnnotationRange());
42    ConsumeToken();
43    return true;
44  }
45
46  bool HasScopeSpecifier = false;
47
48  if (Tok.is(tok::coloncolon)) {
49    // ::new and ::delete aren't nested-name-specifiers.
50    tok::TokenKind NextKind = NextToken().getKind();
51    if (NextKind == tok::kw_new || NextKind == tok::kw_delete)
52      return false;
53
54    // '::' - Global scope qualifier.
55    SourceLocation CCLoc = ConsumeToken();
56    SS.setBeginLoc(CCLoc);
57    SS.addScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc));
58    SS.setEndLoc(CCLoc);
59    HasScopeSpecifier = true;
60  }
61
62  while (true) {
63    // nested-name-specifier:
64    //   type-name '::'
65    //   namespace-name '::'
66    //   nested-name-specifier identifier '::'
67    if (Tok.is(tok::identifier) && NextToken().is(tok::coloncolon)) {
68      // We have an identifier followed by a '::'. Lookup this name
69      // as the name in a nested-name-specifier.
70      IdentifierInfo *II = Tok.getIdentifierInfo();
71      SourceLocation IdLoc = ConsumeToken();
72      assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
73      SourceLocation CCLoc = ConsumeToken();
74
75      if (!HasScopeSpecifier) {
76        SS.setBeginLoc(IdLoc);
77        HasScopeSpecifier = true;
78      }
79
80      if (SS.isInvalid())
81        continue;
82
83      SS.addScopeRep(
84        Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, *II));
85      SS.setEndLoc(CCLoc);
86      continue;
87    }
88
89    // nested-name-specifier:
90    //   type-name '::'
91    //   nested-name-specifier 'template'[opt] simple-template-id '::'
92    if ((Tok.is(tok::identifier) && NextToken().is(tok::less)) ||
93        Tok.is(tok::kw_template)) {
94      // Parse the optional 'template' keyword, then make sure we have
95      // 'identifier <' after it.
96      SourceLocation TemplateKWLoc;
97      if (Tok.is(tok::kw_template)) {
98        TemplateKWLoc = ConsumeToken();
99
100        if (Tok.isNot(tok::identifier)) {
101          Diag(Tok.getLocation(),
102               diag::err_id_after_template_in_nested_name_spec)
103            << SourceRange(TemplateKWLoc);
104          break;
105        }
106
107        if (NextToken().isNot(tok::less)) {
108          Diag(NextToken().getLocation(),
109               diag::err_less_after_template_name_in_nested_name_spec)
110            << Tok.getIdentifierInfo()->getName()
111            << SourceRange(TemplateKWLoc, Tok.getLocation());
112          break;
113        }
114      }
115      else {
116        // FIXME: If the nested-name-specifier thus far is dependent,
117        // we need to break out of here, because this '<' is taken as
118        // an operator and not as part of a simple-template-id.
119      }
120
121      DeclTy *Template = 0;
122      TemplateNameKind TNK = TNK_Non_template;
123      // FIXME: If the nested-name-specifier thus far is dependent,
124      // set TNK = TNK_Dependent_template_name and skip the
125      // "isTemplateName" check.
126      TNK = Actions.isTemplateName(*Tok.getIdentifierInfo(),
127                                   CurScope, Template, &SS);
128      if (TNK) {
129        // We have found a template name, so annotate this this token
130        // with a template-id annotation. We do not permit the
131        // template-id to be translated into a type annotation,
132        // because some clients (e.g., the parsing of class template
133        // specializations) still want to see the original template-id
134        // token.
135        AnnotateTemplateIdToken(Template, TNK, &SS, TemplateKWLoc, false);
136        continue;
137      }
138    }
139
140    if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) {
141      // We have
142      //
143      //   simple-template-id '::'
144      //
145      // So we need to check whether the simple-template-id is of the
146      // right kind (it should name a type), and then convert it into
147      // a type within the nested-name-specifier.
148      TemplateIdAnnotation *TemplateId
149        = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
150
151      if (TemplateId->Kind == TNK_Class_template) {
152        if (AnnotateTemplateIdTokenAsType(&SS))
153          SS.clear();
154
155        assert(Tok.is(tok::annot_typename) &&
156               "AnnotateTemplateIdTokenAsType isn't working");
157
158        Token TypeToken = Tok;
159        ConsumeToken();
160        assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
161        SourceLocation CCLoc = ConsumeToken();
162
163        if (!HasScopeSpecifier) {
164          SS.setBeginLoc(TypeToken.getLocation());
165          HasScopeSpecifier = true;
166        }
167
168        SS.addScopeRep(
169          Actions.ActOnCXXNestedNameSpecifier(CurScope, SS,
170                                              TypeToken.getAnnotationValue(),
171                                              TypeToken.getAnnotationRange(),
172                                              CCLoc));
173        SS.setEndLoc(CCLoc);
174        continue;
175      } else
176        assert(false && "FIXME: Only class template names supported here");
177    }
178
179    // We don't have any tokens that form the beginning of a
180    // nested-name-specifier, so we're done.
181    break;
182  }
183
184  return HasScopeSpecifier;
185}
186
187/// ParseCXXIdExpression - Handle id-expression.
188///
189///       id-expression:
190///         unqualified-id
191///         qualified-id
192///
193///       unqualified-id:
194///         identifier
195///         operator-function-id
196///         conversion-function-id                [TODO]
197///         '~' class-name                        [TODO]
198///         template-id                           [TODO]
199///
200///       qualified-id:
201///         '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
202///         '::' identifier
203///         '::' operator-function-id
204///         '::' template-id                      [TODO]
205///
206///       nested-name-specifier:
207///         type-name '::'
208///         namespace-name '::'
209///         nested-name-specifier identifier '::'
210///         nested-name-specifier 'template'[opt] simple-template-id '::' [TODO]
211///
212/// NOTE: The standard specifies that, for qualified-id, the parser does not
213/// expect:
214///
215///   '::' conversion-function-id
216///   '::' '~' class-name
217///
218/// This may cause a slight inconsistency on diagnostics:
219///
220/// class C {};
221/// namespace A {}
222/// void f() {
223///   :: A :: ~ C(); // Some Sema error about using destructor with a
224///                  // namespace.
225///   :: ~ C(); // Some Parser error like 'unexpected ~'.
226/// }
227///
228/// We simplify the parser a bit and make it work like:
229///
230///       qualified-id:
231///         '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
232///         '::' unqualified-id
233///
234/// That way Sema can handle and report similar errors for namespaces and the
235/// global scope.
236///
237/// The isAddressOfOperand parameter indicates that this id-expression is a
238/// direct operand of the address-of operator. This is, besides member contexts,
239/// the only place where a qualified-id naming a non-static class member may
240/// appear.
241///
242Parser::OwningExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
243  // qualified-id:
244  //   '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
245  //   '::' unqualified-id
246  //
247  CXXScopeSpec SS;
248  ParseOptionalCXXScopeSpecifier(SS);
249
250  // unqualified-id:
251  //   identifier
252  //   operator-function-id
253  //   conversion-function-id
254  //   '~' class-name                        [TODO]
255  //   template-id                           [TODO]
256  //
257  switch (Tok.getKind()) {
258  default:
259    return ExprError(Diag(Tok, diag::err_expected_unqualified_id));
260
261  case tok::identifier: {
262    // Consume the identifier so that we can see if it is followed by a '('.
263    IdentifierInfo &II = *Tok.getIdentifierInfo();
264    SourceLocation L = ConsumeToken();
265    return Actions.ActOnIdentifierExpr(CurScope, L, II, Tok.is(tok::l_paren),
266                                       &SS, isAddressOfOperand);
267  }
268
269  case tok::kw_operator: {
270    SourceLocation OperatorLoc = Tok.getLocation();
271    if (OverloadedOperatorKind Op = TryParseOperatorFunctionId())
272      return Actions.ActOnCXXOperatorFunctionIdExpr(
273                       CurScope, OperatorLoc, Op, Tok.is(tok::l_paren), SS,
274                       isAddressOfOperand);
275    if (TypeTy *Type = ParseConversionFunctionId())
276      return Actions.ActOnCXXConversionFunctionExpr(CurScope, OperatorLoc, Type,
277                                                    Tok.is(tok::l_paren), SS,
278                                                    isAddressOfOperand);
279
280    // We already complained about a bad conversion-function-id,
281    // above.
282    return ExprError();
283  }
284
285  } // switch.
286
287  assert(0 && "The switch was supposed to take care everything.");
288}
289
290/// ParseCXXCasts - This handles the various ways to cast expressions to another
291/// type.
292///
293///       postfix-expression: [C++ 5.2p1]
294///         'dynamic_cast' '<' type-name '>' '(' expression ')'
295///         'static_cast' '<' type-name '>' '(' expression ')'
296///         'reinterpret_cast' '<' type-name '>' '(' expression ')'
297///         'const_cast' '<' type-name '>' '(' expression ')'
298///
299Parser::OwningExprResult Parser::ParseCXXCasts() {
300  tok::TokenKind Kind = Tok.getKind();
301  const char *CastName = 0;     // For error messages
302
303  switch (Kind) {
304  default: assert(0 && "Unknown C++ cast!"); abort();
305  case tok::kw_const_cast:       CastName = "const_cast";       break;
306  case tok::kw_dynamic_cast:     CastName = "dynamic_cast";     break;
307  case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break;
308  case tok::kw_static_cast:      CastName = "static_cast";      break;
309  }
310
311  SourceLocation OpLoc = ConsumeToken();
312  SourceLocation LAngleBracketLoc = Tok.getLocation();
313
314  if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName))
315    return ExprError();
316
317  TypeResult CastTy = ParseTypeName();
318  SourceLocation RAngleBracketLoc = Tok.getLocation();
319
320  if (ExpectAndConsume(tok::greater, diag::err_expected_greater))
321    return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << "<");
322
323  SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
324
325  if (Tok.isNot(tok::l_paren))
326    return ExprError(Diag(Tok, diag::err_expected_lparen_after) << CastName);
327
328  OwningExprResult Result(ParseSimpleParenExpression(RParenLoc));
329
330  if (!Result.isInvalid() && !CastTy.isInvalid())
331    Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,
332                                       LAngleBracketLoc, CastTy.get(),
333                                       RAngleBracketLoc,
334                                       LParenLoc, move(Result), RParenLoc);
335
336  return move(Result);
337}
338
339/// ParseCXXTypeid - This handles the C++ typeid expression.
340///
341///       postfix-expression: [C++ 5.2p1]
342///         'typeid' '(' expression ')'
343///         'typeid' '(' type-id ')'
344///
345Parser::OwningExprResult Parser::ParseCXXTypeid() {
346  assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!");
347
348  SourceLocation OpLoc = ConsumeToken();
349  SourceLocation LParenLoc = Tok.getLocation();
350  SourceLocation RParenLoc;
351
352  // typeid expressions are always parenthesized.
353  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
354      "typeid"))
355    return ExprError();
356
357  OwningExprResult Result(Actions);
358
359  if (isTypeIdInParens()) {
360    TypeResult Ty = ParseTypeName();
361
362    // Match the ')'.
363    MatchRHSPunctuation(tok::r_paren, LParenLoc);
364
365    if (Ty.isInvalid())
366      return ExprError();
367
368    Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true,
369                                    Ty.get(), RParenLoc);
370  } else {
371    Result = ParseExpression();
372
373    // Match the ')'.
374    if (Result.isInvalid())
375      SkipUntil(tok::r_paren);
376    else {
377      MatchRHSPunctuation(tok::r_paren, LParenLoc);
378
379      Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false,
380                                      Result.release(), RParenLoc);
381    }
382  }
383
384  return move(Result);
385}
386
387/// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
388///
389///       boolean-literal: [C++ 2.13.5]
390///         'true'
391///         'false'
392Parser::OwningExprResult Parser::ParseCXXBoolLiteral() {
393  tok::TokenKind Kind = Tok.getKind();
394  return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind);
395}
396
397/// ParseThrowExpression - This handles the C++ throw expression.
398///
399///       throw-expression: [C++ 15]
400///         'throw' assignment-expression[opt]
401Parser::OwningExprResult Parser::ParseThrowExpression() {
402  assert(Tok.is(tok::kw_throw) && "Not throw!");
403  SourceLocation ThrowLoc = ConsumeToken();           // Eat the throw token.
404
405  // If the current token isn't the start of an assignment-expression,
406  // then the expression is not present.  This handles things like:
407  //   "C ? throw : (void)42", which is crazy but legal.
408  switch (Tok.getKind()) {  // FIXME: move this predicate somewhere common.
409  case tok::semi:
410  case tok::r_paren:
411  case tok::r_square:
412  case tok::r_brace:
413  case tok::colon:
414  case tok::comma:
415    return Actions.ActOnCXXThrow(ThrowLoc, ExprArg(Actions));
416
417  default:
418    OwningExprResult Expr(ParseAssignmentExpression());
419    if (Expr.isInvalid()) return move(Expr);
420    return Actions.ActOnCXXThrow(ThrowLoc, move(Expr));
421  }
422}
423
424/// ParseCXXThis - This handles the C++ 'this' pointer.
425///
426/// C++ 9.3.2: In the body of a non-static member function, the keyword this is
427/// a non-lvalue expression whose value is the address of the object for which
428/// the function is called.
429Parser::OwningExprResult Parser::ParseCXXThis() {
430  assert(Tok.is(tok::kw_this) && "Not 'this'!");
431  SourceLocation ThisLoc = ConsumeToken();
432  return Actions.ActOnCXXThis(ThisLoc);
433}
434
435/// ParseCXXTypeConstructExpression - Parse construction of a specified type.
436/// Can be interpreted either as function-style casting ("int(x)")
437/// or class type construction ("ClassType(x,y,z)")
438/// or creation of a value-initialized type ("int()").
439///
440///       postfix-expression: [C++ 5.2p1]
441///         simple-type-specifier '(' expression-list[opt] ')'      [C++ 5.2.3]
442///         typename-specifier '(' expression-list[opt] ')'         [TODO]
443///
444Parser::OwningExprResult
445Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
446  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
447  TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).get();
448
449  assert(Tok.is(tok::l_paren) && "Expected '('!");
450  SourceLocation LParenLoc = ConsumeParen();
451
452  ExprVector Exprs(Actions);
453  CommaLocsTy CommaLocs;
454
455  if (Tok.isNot(tok::r_paren)) {
456    if (ParseExpressionList(Exprs, CommaLocs)) {
457      SkipUntil(tok::r_paren);
458      return ExprError();
459    }
460  }
461
462  // Match the ')'.
463  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
464
465  assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&&
466         "Unexpected number of commas!");
467  return Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep,
468                                           LParenLoc, move_arg(Exprs),
469                                           &CommaLocs[0], RParenLoc);
470}
471
472/// ParseCXXCondition - if/switch/while/for condition expression.
473///
474///       condition:
475///         expression
476///         type-specifier-seq declarator '=' assignment-expression
477/// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
478///             '=' assignment-expression
479///
480Parser::OwningExprResult Parser::ParseCXXCondition() {
481  if (!isCXXConditionDeclaration())
482    return ParseExpression(); // expression
483
484  SourceLocation StartLoc = Tok.getLocation();
485
486  // type-specifier-seq
487  DeclSpec DS;
488  ParseSpecifierQualifierList(DS);
489
490  // declarator
491  Declarator DeclaratorInfo(DS, Declarator::ConditionContext);
492  ParseDeclarator(DeclaratorInfo);
493
494  // simple-asm-expr[opt]
495  if (Tok.is(tok::kw_asm)) {
496    SourceLocation Loc;
497    OwningExprResult AsmLabel(ParseSimpleAsm(&Loc));
498    if (AsmLabel.isInvalid()) {
499      SkipUntil(tok::semi);
500      return ExprError();
501    }
502    DeclaratorInfo.setAsmLabel(AsmLabel.release());
503    DeclaratorInfo.SetRangeEnd(Loc);
504  }
505
506  // If attributes are present, parse them.
507  if (Tok.is(tok::kw___attribute)) {
508    SourceLocation Loc;
509    AttributeList *AttrList = ParseAttributes(&Loc);
510    DeclaratorInfo.AddAttributes(AttrList, Loc);
511  }
512
513  // '=' assignment-expression
514  if (Tok.isNot(tok::equal))
515    return ExprError(Diag(Tok, diag::err_expected_equal_after_declarator));
516  SourceLocation EqualLoc = ConsumeToken();
517  OwningExprResult AssignExpr(ParseAssignmentExpression());
518  if (AssignExpr.isInvalid())
519    return ExprError();
520
521  return Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc,
522                                                  DeclaratorInfo,EqualLoc,
523                                                  move(AssignExpr));
524}
525
526/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
527/// This should only be called when the current token is known to be part of
528/// simple-type-specifier.
529///
530///       simple-type-specifier:
531///         '::'[opt] nested-name-specifier[opt] type-name
532///         '::'[opt] nested-name-specifier 'template' simple-template-id [TODO]
533///         char
534///         wchar_t
535///         bool
536///         short
537///         int
538///         long
539///         signed
540///         unsigned
541///         float
542///         double
543///         void
544/// [GNU]   typeof-specifier
545/// [C++0x] auto               [TODO]
546///
547///       type-name:
548///         class-name
549///         enum-name
550///         typedef-name
551///
552void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
553  DS.SetRangeStart(Tok.getLocation());
554  const char *PrevSpec;
555  SourceLocation Loc = Tok.getLocation();
556
557  switch (Tok.getKind()) {
558  case tok::identifier:   // foo::bar
559  case tok::coloncolon:   // ::foo::bar
560    assert(0 && "Annotation token should already be formed!");
561  default:
562    assert(0 && "Not a simple-type-specifier token!");
563    abort();
564
565  // type-name
566  case tok::annot_typename: {
567    DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
568                       Tok.getAnnotationValue());
569    break;
570  }
571
572  // builtin types
573  case tok::kw_short:
574    DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec);
575    break;
576  case tok::kw_long:
577    DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec);
578    break;
579  case tok::kw_signed:
580    DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec);
581    break;
582  case tok::kw_unsigned:
583    DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec);
584    break;
585  case tok::kw_void:
586    DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec);
587    break;
588  case tok::kw_char:
589    DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec);
590    break;
591  case tok::kw_int:
592    DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec);
593    break;
594  case tok::kw_float:
595    DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec);
596    break;
597  case tok::kw_double:
598    DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec);
599    break;
600  case tok::kw_wchar_t:
601    DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec);
602    break;
603  case tok::kw_bool:
604    DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
605    break;
606
607  // GNU typeof support.
608  case tok::kw_typeof:
609    ParseTypeofSpecifier(DS);
610    DS.Finish(Diags, PP.getSourceManager(), getLang());
611    return;
612  }
613  if (Tok.is(tok::annot_typename))
614    DS.SetRangeEnd(Tok.getAnnotationEndLoc());
615  else
616    DS.SetRangeEnd(Tok.getLocation());
617  ConsumeToken();
618  DS.Finish(Diags, PP.getSourceManager(), getLang());
619}
620
621/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++
622/// [dcl.name]), which is a non-empty sequence of type-specifiers,
623/// e.g., "const short int". Note that the DeclSpec is *not* finished
624/// by parsing the type-specifier-seq, because these sequences are
625/// typically followed by some form of declarator. Returns true and
626/// emits diagnostics if this is not a type-specifier-seq, false
627/// otherwise.
628///
629///   type-specifier-seq: [C++ 8.1]
630///     type-specifier type-specifier-seq[opt]
631///
632bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) {
633  DS.SetRangeStart(Tok.getLocation());
634  const char *PrevSpec = 0;
635  int isInvalid = 0;
636
637  // Parse one or more of the type specifiers.
638  if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec)) {
639    Diag(Tok, diag::err_operator_missing_type_specifier);
640    return true;
641  }
642
643  while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec)) ;
644
645  return false;
646}
647
648/// TryParseOperatorFunctionId - Attempts to parse a C++ overloaded
649/// operator name (C++ [over.oper]). If successful, returns the
650/// predefined identifier that corresponds to that overloaded
651/// operator. Otherwise, returns NULL and does not consume any tokens.
652///
653///       operator-function-id: [C++ 13.5]
654///         'operator' operator
655///
656/// operator: one of
657///            new   delete  new[]   delete[]
658///            +     -    *  /    %  ^    &   |   ~
659///            !     =    <  >    += -=   *=  /=  %=
660///            ^=    &=   |= <<   >> >>= <<=  ==  !=
661///            <=    >=   && ||   ++ --   ,   ->* ->
662///            ()    []
663OverloadedOperatorKind
664Parser::TryParseOperatorFunctionId(SourceLocation *EndLoc) {
665  assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
666  SourceLocation Loc;
667
668  OverloadedOperatorKind Op = OO_None;
669  switch (NextToken().getKind()) {
670  case tok::kw_new:
671    ConsumeToken(); // 'operator'
672    Loc = ConsumeToken(); // 'new'
673    if (Tok.is(tok::l_square)) {
674      ConsumeBracket(); // '['
675      Loc = Tok.getLocation();
676      ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
677      Op = OO_Array_New;
678    } else {
679      Op = OO_New;
680    }
681    if (EndLoc)
682      *EndLoc = Loc;
683    return Op;
684
685  case tok::kw_delete:
686    ConsumeToken(); // 'operator'
687    Loc = ConsumeToken(); // 'delete'
688    if (Tok.is(tok::l_square)) {
689      ConsumeBracket(); // '['
690      Loc = Tok.getLocation();
691      ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
692      Op = OO_Array_Delete;
693    } else {
694      Op = OO_Delete;
695    }
696    if (EndLoc)
697      *EndLoc = Loc;
698    return Op;
699
700#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly)  \
701    case tok::Token:  Op = OO_##Name; break;
702#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
703#include "clang/Basic/OperatorKinds.def"
704
705  case tok::l_paren:
706    ConsumeToken(); // 'operator'
707    ConsumeParen(); // '('
708    Loc = Tok.getLocation();
709    ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); // ')'
710    if (EndLoc)
711      *EndLoc = Loc;
712    return OO_Call;
713
714  case tok::l_square:
715    ConsumeToken(); // 'operator'
716    ConsumeBracket(); // '['
717    Loc = Tok.getLocation();
718    ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
719    if (EndLoc)
720      *EndLoc = Loc;
721    return OO_Subscript;
722
723  default:
724    return OO_None;
725  }
726
727  ConsumeToken(); // 'operator'
728  Loc = ConsumeAnyToken(); // the operator itself
729  if (EndLoc)
730    *EndLoc = Loc;
731  return Op;
732}
733
734/// ParseConversionFunctionId - Parse a C++ conversion-function-id,
735/// which expresses the name of a user-defined conversion operator
736/// (C++ [class.conv.fct]p1). Returns the type that this operator is
737/// specifying a conversion for, or NULL if there was an error.
738///
739///        conversion-function-id: [C++ 12.3.2]
740///                   operator conversion-type-id
741///
742///        conversion-type-id:
743///                   type-specifier-seq conversion-declarator[opt]
744///
745///        conversion-declarator:
746///                   ptr-operator conversion-declarator[opt]
747Parser::TypeTy *Parser::ParseConversionFunctionId(SourceLocation *EndLoc) {
748  assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
749  ConsumeToken(); // 'operator'
750
751  // Parse the type-specifier-seq.
752  DeclSpec DS;
753  if (ParseCXXTypeSpecifierSeq(DS))
754    return 0;
755
756  // Parse the conversion-declarator, which is merely a sequence of
757  // ptr-operators.
758  Declarator D(DS, Declarator::TypeNameContext);
759  ParseDeclaratorInternal(D, /*DirectDeclParser=*/0);
760  if (EndLoc)
761    *EndLoc = D.getSourceRange().getEnd();
762
763  // Finish up the type.
764  Action::TypeResult Result = Actions.ActOnTypeName(CurScope, D);
765  if (Result.isInvalid())
766    return 0;
767  else
768    return Result.get();
769}
770
771/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate
772/// memory in a typesafe manner and call constructors.
773///
774/// This method is called to parse the new expression after the optional :: has
775/// been already parsed.  If the :: was present, "UseGlobal" is true and "Start"
776/// is its location.  Otherwise, "Start" is the location of the 'new' token.
777///
778///        new-expression:
779///                   '::'[opt] 'new' new-placement[opt] new-type-id
780///                                     new-initializer[opt]
781///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
782///                                     new-initializer[opt]
783///
784///        new-placement:
785///                   '(' expression-list ')'
786///
787///        new-type-id:
788///                   type-specifier-seq new-declarator[opt]
789///
790///        new-declarator:
791///                   ptr-operator new-declarator[opt]
792///                   direct-new-declarator
793///
794///        new-initializer:
795///                   '(' expression-list[opt] ')'
796/// [C++0x]           braced-init-list                                   [TODO]
797///
798Parser::OwningExprResult
799Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
800  assert(Tok.is(tok::kw_new) && "expected 'new' token");
801  ConsumeToken();   // Consume 'new'
802
803  // A '(' now can be a new-placement or the '(' wrapping the type-id in the
804  // second form of new-expression. It can't be a new-type-id.
805
806  ExprVector PlacementArgs(Actions);
807  SourceLocation PlacementLParen, PlacementRParen;
808
809  bool ParenTypeId;
810  DeclSpec DS;
811  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
812  if (Tok.is(tok::l_paren)) {
813    // If it turns out to be a placement, we change the type location.
814    PlacementLParen = ConsumeParen();
815    if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) {
816      SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
817      return ExprError();
818    }
819
820    PlacementRParen = MatchRHSPunctuation(tok::r_paren, PlacementLParen);
821    if (PlacementRParen.isInvalid()) {
822      SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
823      return ExprError();
824    }
825
826    if (PlacementArgs.empty()) {
827      // Reset the placement locations. There was no placement.
828      PlacementLParen = PlacementRParen = SourceLocation();
829      ParenTypeId = true;
830    } else {
831      // We still need the type.
832      if (Tok.is(tok::l_paren)) {
833        SourceLocation LParen = ConsumeParen();
834        ParseSpecifierQualifierList(DS);
835        DeclaratorInfo.SetSourceRange(DS.getSourceRange());
836        ParseDeclarator(DeclaratorInfo);
837        MatchRHSPunctuation(tok::r_paren, LParen);
838        ParenTypeId = true;
839      } else {
840        if (ParseCXXTypeSpecifierSeq(DS))
841          DeclaratorInfo.setInvalidType(true);
842        else {
843          DeclaratorInfo.SetSourceRange(DS.getSourceRange());
844          ParseDeclaratorInternal(DeclaratorInfo,
845                                  &Parser::ParseDirectNewDeclarator);
846        }
847        ParenTypeId = false;
848      }
849    }
850  } else {
851    // A new-type-id is a simplified type-id, where essentially the
852    // direct-declarator is replaced by a direct-new-declarator.
853    if (ParseCXXTypeSpecifierSeq(DS))
854      DeclaratorInfo.setInvalidType(true);
855    else {
856      DeclaratorInfo.SetSourceRange(DS.getSourceRange());
857      ParseDeclaratorInternal(DeclaratorInfo,
858                              &Parser::ParseDirectNewDeclarator);
859    }
860    ParenTypeId = false;
861  }
862  if (DeclaratorInfo.getInvalidType()) {
863    SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
864    return ExprError();
865  }
866
867  ExprVector ConstructorArgs(Actions);
868  SourceLocation ConstructorLParen, ConstructorRParen;
869
870  if (Tok.is(tok::l_paren)) {
871    ConstructorLParen = ConsumeParen();
872    if (Tok.isNot(tok::r_paren)) {
873      CommaLocsTy CommaLocs;
874      if (ParseExpressionList(ConstructorArgs, CommaLocs)) {
875        SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
876        return ExprError();
877      }
878    }
879    ConstructorRParen = MatchRHSPunctuation(tok::r_paren, ConstructorLParen);
880    if (ConstructorRParen.isInvalid()) {
881      SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
882      return ExprError();
883    }
884  }
885
886  return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,
887                             move_arg(PlacementArgs), PlacementRParen,
888                             ParenTypeId, DeclaratorInfo, ConstructorLParen,
889                             move_arg(ConstructorArgs), ConstructorRParen);
890}
891
892/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be
893/// passed to ParseDeclaratorInternal.
894///
895///        direct-new-declarator:
896///                   '[' expression ']'
897///                   direct-new-declarator '[' constant-expression ']'
898///
899void Parser::ParseDirectNewDeclarator(Declarator &D) {
900  // Parse the array dimensions.
901  bool first = true;
902  while (Tok.is(tok::l_square)) {
903    SourceLocation LLoc = ConsumeBracket();
904    OwningExprResult Size(first ? ParseExpression()
905                                : ParseConstantExpression());
906    if (Size.isInvalid()) {
907      // Recover
908      SkipUntil(tok::r_square);
909      return;
910    }
911    first = false;
912
913    SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc);
914    D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false,
915                                            Size.release(), LLoc),
916                  RLoc);
917
918    if (RLoc.isInvalid())
919      return;
920  }
921}
922
923/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id.
924/// This ambiguity appears in the syntax of the C++ new operator.
925///
926///        new-expression:
927///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
928///                                     new-initializer[opt]
929///
930///        new-placement:
931///                   '(' expression-list ')'
932///
933bool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs,
934                                         Declarator &D) {
935  // The '(' was already consumed.
936  if (isTypeIdInParens()) {
937    ParseSpecifierQualifierList(D.getMutableDeclSpec());
938    D.SetSourceRange(D.getDeclSpec().getSourceRange());
939    ParseDeclarator(D);
940    return D.getInvalidType();
941  }
942
943  // It's not a type, it has to be an expression list.
944  // Discard the comma locations - ActOnCXXNew has enough parameters.
945  CommaLocsTy CommaLocs;
946  return ParseExpressionList(PlacementArgs, CommaLocs);
947}
948
949/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used
950/// to free memory allocated by new.
951///
952/// This method is called to parse the 'delete' expression after the optional
953/// '::' has been already parsed.  If the '::' was present, "UseGlobal" is true
954/// and "Start" is its location.  Otherwise, "Start" is the location of the
955/// 'delete' token.
956///
957///        delete-expression:
958///                   '::'[opt] 'delete' cast-expression
959///                   '::'[opt] 'delete' '[' ']' cast-expression
960Parser::OwningExprResult
961Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) {
962  assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword");
963  ConsumeToken(); // Consume 'delete'
964
965  // Array delete?
966  bool ArrayDelete = false;
967  if (Tok.is(tok::l_square)) {
968    ArrayDelete = true;
969    SourceLocation LHS = ConsumeBracket();
970    SourceLocation RHS = MatchRHSPunctuation(tok::r_square, LHS);
971    if (RHS.isInvalid())
972      return ExprError();
973  }
974
975  OwningExprResult Operand(ParseCastExpression(false));
976  if (Operand.isInvalid())
977    return move(Operand);
978
979  return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, move(Operand));
980}
981
982static UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind)
983{
984  switch(kind) {
985  default: assert(false && "Not a known unary type trait.");
986  case tok::kw___has_nothrow_assign:      return UTT_HasNothrowAssign;
987  case tok::kw___has_nothrow_copy:        return UTT_HasNothrowCopy;
988  case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor;
989  case tok::kw___has_trivial_assign:      return UTT_HasTrivialAssign;
990  case tok::kw___has_trivial_copy:        return UTT_HasTrivialCopy;
991  case tok::kw___has_trivial_constructor: return UTT_HasTrivialConstructor;
992  case tok::kw___has_trivial_destructor:  return UTT_HasTrivialDestructor;
993  case tok::kw___has_virtual_destructor:  return UTT_HasVirtualDestructor;
994  case tok::kw___is_abstract:             return UTT_IsAbstract;
995  case tok::kw___is_class:                return UTT_IsClass;
996  case tok::kw___is_empty:                return UTT_IsEmpty;
997  case tok::kw___is_enum:                 return UTT_IsEnum;
998  case tok::kw___is_pod:                  return UTT_IsPOD;
999  case tok::kw___is_polymorphic:          return UTT_IsPolymorphic;
1000  case tok::kw___is_union:                return UTT_IsUnion;
1001  }
1002}
1003
1004/// ParseUnaryTypeTrait - Parse the built-in unary type-trait
1005/// pseudo-functions that allow implementation of the TR1/C++0x type traits
1006/// templates.
1007///
1008///       primary-expression:
1009/// [GNU]             unary-type-trait '(' type-id ')'
1010///
1011Parser::OwningExprResult Parser::ParseUnaryTypeTrait()
1012{
1013  UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind());
1014  SourceLocation Loc = ConsumeToken();
1015
1016  SourceLocation LParen = Tok.getLocation();
1017  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen))
1018    return ExprError();
1019
1020  // FIXME: Error reporting absolutely sucks! If the this fails to parse a type
1021  // there will be cryptic errors about mismatched parentheses and missing
1022  // specifiers.
1023  TypeResult Ty = ParseTypeName();
1024
1025  SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen);
1026
1027  if (Ty.isInvalid())
1028    return ExprError();
1029
1030  return Actions.ActOnUnaryTypeTrait(UTT, Loc, LParen, Ty.get(), RParen);
1031}
1032