ParseExprCXX.cpp revision 194613
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"
17using namespace clang;
18
19/// ParseOptionalCXXScopeSpecifier - Parse global scope or
20/// nested-name-specifier if present.  Returns true if a nested-name-specifier
21/// was parsed from the token stream.  Note that this routine will not parse
22/// ::new or ::delete, it will just leave them in the token stream.
23///
24///       '::'[opt] nested-name-specifier
25///       '::'
26///
27///       nested-name-specifier:
28///         type-name '::'
29///         namespace-name '::'
30///         nested-name-specifier identifier '::'
31///         nested-name-specifier 'template'[opt] simple-template-id '::' [TODO]
32///
33bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) {
34  assert(getLang().CPlusPlus &&
35         "Call sites of this function should be guarded by checking for C++");
36
37  if (Tok.is(tok::annot_cxxscope)) {
38    SS.setScopeRep(Tok.getAnnotationValue());
39    SS.setRange(Tok.getAnnotationRange());
40    ConsumeToken();
41    return true;
42  }
43
44  bool HasScopeSpecifier = false;
45
46  if (Tok.is(tok::coloncolon)) {
47    // ::new and ::delete aren't nested-name-specifiers.
48    tok::TokenKind NextKind = NextToken().getKind();
49    if (NextKind == tok::kw_new || NextKind == tok::kw_delete)
50      return false;
51
52    // '::' - Global scope qualifier.
53    SourceLocation CCLoc = ConsumeToken();
54    SS.setBeginLoc(CCLoc);
55    SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc));
56    SS.setEndLoc(CCLoc);
57    HasScopeSpecifier = true;
58  }
59
60  while (true) {
61    // nested-name-specifier:
62    //   type-name '::'
63    //   namespace-name '::'
64    //   nested-name-specifier identifier '::'
65    if (Tok.is(tok::identifier) && NextToken().is(tok::coloncolon)) {
66      // We have an identifier followed by a '::'. Lookup this name
67      // as the name in a nested-name-specifier.
68      IdentifierInfo *II = Tok.getIdentifierInfo();
69      SourceLocation IdLoc = ConsumeToken();
70      assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
71      SourceLocation CCLoc = ConsumeToken();
72
73      if (!HasScopeSpecifier) {
74        SS.setBeginLoc(IdLoc);
75        HasScopeSpecifier = true;
76      }
77
78      if (SS.isInvalid())
79        continue;
80
81      SS.setScopeRep(
82        Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, *II));
83      SS.setEndLoc(CCLoc);
84      continue;
85    }
86
87    // nested-name-specifier:
88    //   type-name '::'
89    //   nested-name-specifier 'template'[opt] simple-template-id '::'
90    if ((Tok.is(tok::identifier) && NextToken().is(tok::less)) ||
91        Tok.is(tok::kw_template)) {
92      // Parse the optional 'template' keyword, then make sure we have
93      // 'identifier <' after it.
94      if (Tok.is(tok::kw_template)) {
95        SourceLocation TemplateKWLoc = ConsumeToken();
96
97        if (Tok.isNot(tok::identifier)) {
98          Diag(Tok.getLocation(),
99               diag::err_id_after_template_in_nested_name_spec)
100            << SourceRange(TemplateKWLoc);
101          break;
102        }
103
104        if (NextToken().isNot(tok::less)) {
105          Diag(NextToken().getLocation(),
106               diag::err_less_after_template_name_in_nested_name_spec)
107            << Tok.getIdentifierInfo()->getName()
108            << SourceRange(TemplateKWLoc, Tok.getLocation());
109          break;
110        }
111
112        TemplateTy Template
113          = Actions.ActOnDependentTemplateName(TemplateKWLoc,
114                                               *Tok.getIdentifierInfo(),
115                                               Tok.getLocation(),
116                                               SS);
117        AnnotateTemplateIdToken(Template, TNK_Dependent_template_name,
118                                &SS, TemplateKWLoc, false);
119        continue;
120      }
121
122      TemplateTy Template;
123      TemplateNameKind TNK = Actions.isTemplateName(*Tok.getIdentifierInfo(),
124                                                    CurScope, Template, &SS);
125      if (TNK) {
126        // We have found a template name, so annotate this this token
127        // with a template-id annotation. We do not permit the
128        // template-id to be translated into a type annotation,
129        // because some clients (e.g., the parsing of class template
130        // specializations) still want to see the original template-id
131        // token.
132        AnnotateTemplateIdToken(Template, TNK, &SS, SourceLocation(), false);
133        continue;
134      }
135    }
136
137    if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) {
138      // We have
139      //
140      //   simple-template-id '::'
141      //
142      // So we need to check whether the simple-template-id is of the
143      // right kind (it should name a type or be dependent), and then
144      // convert it into a type within the nested-name-specifier.
145      TemplateIdAnnotation *TemplateId
146        = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
147
148      if (TemplateId->Kind == TNK_Type_template ||
149          TemplateId->Kind == TNK_Dependent_template_name) {
150        AnnotateTemplateIdTokenAsType(&SS);
151        SS.setScopeRep(0);
152
153        assert(Tok.is(tok::annot_typename) &&
154               "AnnotateTemplateIdTokenAsType isn't working");
155        Token TypeToken = Tok;
156        ConsumeToken();
157        assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
158        SourceLocation CCLoc = ConsumeToken();
159
160        if (!HasScopeSpecifier) {
161          SS.setBeginLoc(TypeToken.getLocation());
162          HasScopeSpecifier = true;
163        }
164
165        if (TypeToken.getAnnotationValue())
166          SS.setScopeRep(
167            Actions.ActOnCXXNestedNameSpecifier(CurScope, SS,
168                                                TypeToken.getAnnotationValue(),
169                                                TypeToken.getAnnotationRange(),
170                                                CCLoc));
171        else
172          SS.setScopeRep(0);
173        SS.setEndLoc(CCLoc);
174        continue;
175      } else
176        assert(false && "FIXME: Only type 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 (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, CastName))
326    return ExprError();
327
328  OwningExprResult Result = ParseExpression();
329
330  // Match the ')'.
331  if (Result.isInvalid())
332    SkipUntil(tok::r_paren);
333
334  if (Tok.is(tok::r_paren))
335    RParenLoc = ConsumeParen();
336  else
337    MatchRHSPunctuation(tok::r_paren, LParenLoc);
338
339  if (!Result.isInvalid() && !CastTy.isInvalid())
340    Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,
341                                       LAngleBracketLoc, CastTy.get(),
342                                       RAngleBracketLoc,
343                                       LParenLoc, move(Result), RParenLoc);
344
345  return move(Result);
346}
347
348/// ParseCXXTypeid - This handles the C++ typeid expression.
349///
350///       postfix-expression: [C++ 5.2p1]
351///         'typeid' '(' expression ')'
352///         'typeid' '(' type-id ')'
353///
354Parser::OwningExprResult Parser::ParseCXXTypeid() {
355  assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!");
356
357  SourceLocation OpLoc = ConsumeToken();
358  SourceLocation LParenLoc = Tok.getLocation();
359  SourceLocation RParenLoc;
360
361  // typeid expressions are always parenthesized.
362  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
363      "typeid"))
364    return ExprError();
365
366  OwningExprResult Result(Actions);
367
368  if (isTypeIdInParens()) {
369    TypeResult Ty = ParseTypeName();
370
371    // Match the ')'.
372    MatchRHSPunctuation(tok::r_paren, LParenLoc);
373
374    if (Ty.isInvalid())
375      return ExprError();
376
377    Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true,
378                                    Ty.get(), RParenLoc);
379  } else {
380    // C++0x [expr.typeid]p3:
381    //   When typeid is applied to an expression other than an lvalue of a
382    //   polymorphic class type [...] The expression is an unevaluated
383    //   operand (Clause 5).
384    //
385    // Note that we can't tell whether the expression is an lvalue of a
386    // polymorphic class type until after we've parsed the expression, so
387    // we treat the expression as an unevaluated operand and let semantic
388    // analysis cope with case where the expression is not an unevaluated
389    // operand.
390    EnterUnevaluatedOperand Unevaluated(Actions);
391    Result = ParseExpression();
392
393    // Match the ')'.
394    if (Result.isInvalid())
395      SkipUntil(tok::r_paren);
396    else {
397      MatchRHSPunctuation(tok::r_paren, LParenLoc);
398
399      Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false,
400                                      Result.release(), RParenLoc);
401    }
402  }
403
404  return move(Result);
405}
406
407/// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
408///
409///       boolean-literal: [C++ 2.13.5]
410///         'true'
411///         'false'
412Parser::OwningExprResult Parser::ParseCXXBoolLiteral() {
413  tok::TokenKind Kind = Tok.getKind();
414  return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind);
415}
416
417/// ParseThrowExpression - This handles the C++ throw expression.
418///
419///       throw-expression: [C++ 15]
420///         'throw' assignment-expression[opt]
421Parser::OwningExprResult Parser::ParseThrowExpression() {
422  assert(Tok.is(tok::kw_throw) && "Not throw!");
423  SourceLocation ThrowLoc = ConsumeToken();           // Eat the throw token.
424
425  // If the current token isn't the start of an assignment-expression,
426  // then the expression is not present.  This handles things like:
427  //   "C ? throw : (void)42", which is crazy but legal.
428  switch (Tok.getKind()) {  // FIXME: move this predicate somewhere common.
429  case tok::semi:
430  case tok::r_paren:
431  case tok::r_square:
432  case tok::r_brace:
433  case tok::colon:
434  case tok::comma:
435    return Actions.ActOnCXXThrow(ThrowLoc, ExprArg(Actions));
436
437  default:
438    OwningExprResult Expr(ParseAssignmentExpression());
439    if (Expr.isInvalid()) return move(Expr);
440    return Actions.ActOnCXXThrow(ThrowLoc, move(Expr));
441  }
442}
443
444/// ParseCXXThis - This handles the C++ 'this' pointer.
445///
446/// C++ 9.3.2: In the body of a non-static member function, the keyword this is
447/// a non-lvalue expression whose value is the address of the object for which
448/// the function is called.
449Parser::OwningExprResult Parser::ParseCXXThis() {
450  assert(Tok.is(tok::kw_this) && "Not 'this'!");
451  SourceLocation ThisLoc = ConsumeToken();
452  return Actions.ActOnCXXThis(ThisLoc);
453}
454
455/// ParseCXXTypeConstructExpression - Parse construction of a specified type.
456/// Can be interpreted either as function-style casting ("int(x)")
457/// or class type construction ("ClassType(x,y,z)")
458/// or creation of a value-initialized type ("int()").
459///
460///       postfix-expression: [C++ 5.2p1]
461///         simple-type-specifier '(' expression-list[opt] ')'      [C++ 5.2.3]
462///         typename-specifier '(' expression-list[opt] ')'         [TODO]
463///
464Parser::OwningExprResult
465Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
466  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
467  TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).get();
468
469  assert(Tok.is(tok::l_paren) && "Expected '('!");
470  SourceLocation LParenLoc = ConsumeParen();
471
472  ExprVector Exprs(Actions);
473  CommaLocsTy CommaLocs;
474
475  if (Tok.isNot(tok::r_paren)) {
476    if (ParseExpressionList(Exprs, CommaLocs)) {
477      SkipUntil(tok::r_paren);
478      return ExprError();
479    }
480  }
481
482  // Match the ')'.
483  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
484
485  assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&&
486         "Unexpected number of commas!");
487  return Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep,
488                                           LParenLoc, move_arg(Exprs),
489                                           CommaLocs.data(), RParenLoc);
490}
491
492/// ParseCXXCondition - if/switch/while/for condition expression.
493///
494///       condition:
495///         expression
496///         type-specifier-seq declarator '=' assignment-expression
497/// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
498///             '=' assignment-expression
499///
500Parser::OwningExprResult Parser::ParseCXXCondition() {
501  if (!isCXXConditionDeclaration())
502    return ParseExpression(); // expression
503
504  SourceLocation StartLoc = Tok.getLocation();
505
506  // type-specifier-seq
507  DeclSpec DS;
508  ParseSpecifierQualifierList(DS);
509
510  // declarator
511  Declarator DeclaratorInfo(DS, Declarator::ConditionContext);
512  ParseDeclarator(DeclaratorInfo);
513
514  // simple-asm-expr[opt]
515  if (Tok.is(tok::kw_asm)) {
516    SourceLocation Loc;
517    OwningExprResult AsmLabel(ParseSimpleAsm(&Loc));
518    if (AsmLabel.isInvalid()) {
519      SkipUntil(tok::semi);
520      return ExprError();
521    }
522    DeclaratorInfo.setAsmLabel(AsmLabel.release());
523    DeclaratorInfo.SetRangeEnd(Loc);
524  }
525
526  // If attributes are present, parse them.
527  if (Tok.is(tok::kw___attribute)) {
528    SourceLocation Loc;
529    AttributeList *AttrList = ParseAttributes(&Loc);
530    DeclaratorInfo.AddAttributes(AttrList, Loc);
531  }
532
533  // '=' assignment-expression
534  if (Tok.isNot(tok::equal))
535    return ExprError(Diag(Tok, diag::err_expected_equal_after_declarator));
536  SourceLocation EqualLoc = ConsumeToken();
537  OwningExprResult AssignExpr(ParseAssignmentExpression());
538  if (AssignExpr.isInvalid())
539    return ExprError();
540
541  return Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc,
542                                                  DeclaratorInfo,EqualLoc,
543                                                  move(AssignExpr));
544}
545
546/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
547/// This should only be called when the current token is known to be part of
548/// simple-type-specifier.
549///
550///       simple-type-specifier:
551///         '::'[opt] nested-name-specifier[opt] type-name
552///         '::'[opt] nested-name-specifier 'template' simple-template-id [TODO]
553///         char
554///         wchar_t
555///         bool
556///         short
557///         int
558///         long
559///         signed
560///         unsigned
561///         float
562///         double
563///         void
564/// [GNU]   typeof-specifier
565/// [C++0x] auto               [TODO]
566///
567///       type-name:
568///         class-name
569///         enum-name
570///         typedef-name
571///
572void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
573  DS.SetRangeStart(Tok.getLocation());
574  const char *PrevSpec;
575  SourceLocation Loc = Tok.getLocation();
576
577  switch (Tok.getKind()) {
578  case tok::identifier:   // foo::bar
579  case tok::coloncolon:   // ::foo::bar
580    assert(0 && "Annotation token should already be formed!");
581  default:
582    assert(0 && "Not a simple-type-specifier token!");
583    abort();
584
585  // type-name
586  case tok::annot_typename: {
587    DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
588                       Tok.getAnnotationValue());
589    break;
590  }
591
592  // builtin types
593  case tok::kw_short:
594    DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec);
595    break;
596  case tok::kw_long:
597    DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec);
598    break;
599  case tok::kw_signed:
600    DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec);
601    break;
602  case tok::kw_unsigned:
603    DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec);
604    break;
605  case tok::kw_void:
606    DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec);
607    break;
608  case tok::kw_char:
609    DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec);
610    break;
611  case tok::kw_int:
612    DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec);
613    break;
614  case tok::kw_float:
615    DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec);
616    break;
617  case tok::kw_double:
618    DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec);
619    break;
620  case tok::kw_wchar_t:
621    DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec);
622    break;
623  case tok::kw_bool:
624    DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
625    break;
626
627  // GNU typeof support.
628  case tok::kw_typeof:
629    ParseTypeofSpecifier(DS);
630    DS.Finish(Diags, PP);
631    return;
632  }
633  if (Tok.is(tok::annot_typename))
634    DS.SetRangeEnd(Tok.getAnnotationEndLoc());
635  else
636    DS.SetRangeEnd(Tok.getLocation());
637  ConsumeToken();
638  DS.Finish(Diags, PP);
639}
640
641/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++
642/// [dcl.name]), which is a non-empty sequence of type-specifiers,
643/// e.g., "const short int". Note that the DeclSpec is *not* finished
644/// by parsing the type-specifier-seq, because these sequences are
645/// typically followed by some form of declarator. Returns true and
646/// emits diagnostics if this is not a type-specifier-seq, false
647/// otherwise.
648///
649///   type-specifier-seq: [C++ 8.1]
650///     type-specifier type-specifier-seq[opt]
651///
652bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) {
653  DS.SetRangeStart(Tok.getLocation());
654  const char *PrevSpec = 0;
655  int isInvalid = 0;
656
657  // Parse one or more of the type specifiers.
658  if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec)) {
659    Diag(Tok, diag::err_operator_missing_type_specifier);
660    return true;
661  }
662
663  while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec)) ;
664
665  return false;
666}
667
668/// TryParseOperatorFunctionId - Attempts to parse a C++ overloaded
669/// operator name (C++ [over.oper]). If successful, returns the
670/// predefined identifier that corresponds to that overloaded
671/// operator. Otherwise, returns NULL and does not consume any tokens.
672///
673///       operator-function-id: [C++ 13.5]
674///         'operator' operator
675///
676/// operator: one of
677///            new   delete  new[]   delete[]
678///            +     -    *  /    %  ^    &   |   ~
679///            !     =    <  >    += -=   *=  /=  %=
680///            ^=    &=   |= <<   >> >>= <<=  ==  !=
681///            <=    >=   && ||   ++ --   ,   ->* ->
682///            ()    []
683OverloadedOperatorKind
684Parser::TryParseOperatorFunctionId(SourceLocation *EndLoc) {
685  assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
686  SourceLocation Loc;
687
688  OverloadedOperatorKind Op = OO_None;
689  switch (NextToken().getKind()) {
690  case tok::kw_new:
691    ConsumeToken(); // 'operator'
692    Loc = ConsumeToken(); // 'new'
693    if (Tok.is(tok::l_square)) {
694      ConsumeBracket(); // '['
695      Loc = Tok.getLocation();
696      ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
697      Op = OO_Array_New;
698    } else {
699      Op = OO_New;
700    }
701    if (EndLoc)
702      *EndLoc = Loc;
703    return Op;
704
705  case tok::kw_delete:
706    ConsumeToken(); // 'operator'
707    Loc = ConsumeToken(); // 'delete'
708    if (Tok.is(tok::l_square)) {
709      ConsumeBracket(); // '['
710      Loc = Tok.getLocation();
711      ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
712      Op = OO_Array_Delete;
713    } else {
714      Op = OO_Delete;
715    }
716    if (EndLoc)
717      *EndLoc = Loc;
718    return Op;
719
720#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly)  \
721    case tok::Token:  Op = OO_##Name; break;
722#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
723#include "clang/Basic/OperatorKinds.def"
724
725  case tok::l_paren:
726    ConsumeToken(); // 'operator'
727    ConsumeParen(); // '('
728    Loc = Tok.getLocation();
729    ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); // ')'
730    if (EndLoc)
731      *EndLoc = Loc;
732    return OO_Call;
733
734  case tok::l_square:
735    ConsumeToken(); // 'operator'
736    ConsumeBracket(); // '['
737    Loc = Tok.getLocation();
738    ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
739    if (EndLoc)
740      *EndLoc = Loc;
741    return OO_Subscript;
742
743  default:
744    return OO_None;
745  }
746
747  ConsumeToken(); // 'operator'
748  Loc = ConsumeAnyToken(); // the operator itself
749  if (EndLoc)
750    *EndLoc = Loc;
751  return Op;
752}
753
754/// ParseConversionFunctionId - Parse a C++ conversion-function-id,
755/// which expresses the name of a user-defined conversion operator
756/// (C++ [class.conv.fct]p1). Returns the type that this operator is
757/// specifying a conversion for, or NULL if there was an error.
758///
759///        conversion-function-id: [C++ 12.3.2]
760///                   operator conversion-type-id
761///
762///        conversion-type-id:
763///                   type-specifier-seq conversion-declarator[opt]
764///
765///        conversion-declarator:
766///                   ptr-operator conversion-declarator[opt]
767Parser::TypeTy *Parser::ParseConversionFunctionId(SourceLocation *EndLoc) {
768  assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
769  ConsumeToken(); // 'operator'
770
771  // Parse the type-specifier-seq.
772  DeclSpec DS;
773  if (ParseCXXTypeSpecifierSeq(DS))
774    return 0;
775
776  // Parse the conversion-declarator, which is merely a sequence of
777  // ptr-operators.
778  Declarator D(DS, Declarator::TypeNameContext);
779  ParseDeclaratorInternal(D, /*DirectDeclParser=*/0);
780  if (EndLoc)
781    *EndLoc = D.getSourceRange().getEnd();
782
783  // Finish up the type.
784  Action::TypeResult Result = Actions.ActOnTypeName(CurScope, D);
785  if (Result.isInvalid())
786    return 0;
787  else
788    return Result.get();
789}
790
791/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate
792/// memory in a typesafe manner and call constructors.
793///
794/// This method is called to parse the new expression after the optional :: has
795/// been already parsed.  If the :: was present, "UseGlobal" is true and "Start"
796/// is its location.  Otherwise, "Start" is the location of the 'new' token.
797///
798///        new-expression:
799///                   '::'[opt] 'new' new-placement[opt] new-type-id
800///                                     new-initializer[opt]
801///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
802///                                     new-initializer[opt]
803///
804///        new-placement:
805///                   '(' expression-list ')'
806///
807///        new-type-id:
808///                   type-specifier-seq new-declarator[opt]
809///
810///        new-declarator:
811///                   ptr-operator new-declarator[opt]
812///                   direct-new-declarator
813///
814///        new-initializer:
815///                   '(' expression-list[opt] ')'
816/// [C++0x]           braced-init-list                                   [TODO]
817///
818Parser::OwningExprResult
819Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
820  assert(Tok.is(tok::kw_new) && "expected 'new' token");
821  ConsumeToken();   // Consume 'new'
822
823  // A '(' now can be a new-placement or the '(' wrapping the type-id in the
824  // second form of new-expression. It can't be a new-type-id.
825
826  ExprVector PlacementArgs(Actions);
827  SourceLocation PlacementLParen, PlacementRParen;
828
829  bool ParenTypeId;
830  DeclSpec DS;
831  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
832  if (Tok.is(tok::l_paren)) {
833    // If it turns out to be a placement, we change the type location.
834    PlacementLParen = ConsumeParen();
835    if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) {
836      SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
837      return ExprError();
838    }
839
840    PlacementRParen = MatchRHSPunctuation(tok::r_paren, PlacementLParen);
841    if (PlacementRParen.isInvalid()) {
842      SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
843      return ExprError();
844    }
845
846    if (PlacementArgs.empty()) {
847      // Reset the placement locations. There was no placement.
848      PlacementLParen = PlacementRParen = SourceLocation();
849      ParenTypeId = true;
850    } else {
851      // We still need the type.
852      if (Tok.is(tok::l_paren)) {
853        SourceLocation LParen = ConsumeParen();
854        ParseSpecifierQualifierList(DS);
855        DeclaratorInfo.SetSourceRange(DS.getSourceRange());
856        ParseDeclarator(DeclaratorInfo);
857        MatchRHSPunctuation(tok::r_paren, LParen);
858        ParenTypeId = true;
859      } else {
860        if (ParseCXXTypeSpecifierSeq(DS))
861          DeclaratorInfo.setInvalidType(true);
862        else {
863          DeclaratorInfo.SetSourceRange(DS.getSourceRange());
864          ParseDeclaratorInternal(DeclaratorInfo,
865                                  &Parser::ParseDirectNewDeclarator);
866        }
867        ParenTypeId = false;
868      }
869    }
870  } else {
871    // A new-type-id is a simplified type-id, where essentially the
872    // direct-declarator is replaced by a direct-new-declarator.
873    if (ParseCXXTypeSpecifierSeq(DS))
874      DeclaratorInfo.setInvalidType(true);
875    else {
876      DeclaratorInfo.SetSourceRange(DS.getSourceRange());
877      ParseDeclaratorInternal(DeclaratorInfo,
878                              &Parser::ParseDirectNewDeclarator);
879    }
880    ParenTypeId = false;
881  }
882  if (DeclaratorInfo.isInvalidType()) {
883    SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
884    return ExprError();
885  }
886
887  ExprVector ConstructorArgs(Actions);
888  SourceLocation ConstructorLParen, ConstructorRParen;
889
890  if (Tok.is(tok::l_paren)) {
891    ConstructorLParen = ConsumeParen();
892    if (Tok.isNot(tok::r_paren)) {
893      CommaLocsTy CommaLocs;
894      if (ParseExpressionList(ConstructorArgs, CommaLocs)) {
895        SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
896        return ExprError();
897      }
898    }
899    ConstructorRParen = MatchRHSPunctuation(tok::r_paren, ConstructorLParen);
900    if (ConstructorRParen.isInvalid()) {
901      SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
902      return ExprError();
903    }
904  }
905
906  return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,
907                             move_arg(PlacementArgs), PlacementRParen,
908                             ParenTypeId, DeclaratorInfo, ConstructorLParen,
909                             move_arg(ConstructorArgs), ConstructorRParen);
910}
911
912/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be
913/// passed to ParseDeclaratorInternal.
914///
915///        direct-new-declarator:
916///                   '[' expression ']'
917///                   direct-new-declarator '[' constant-expression ']'
918///
919void Parser::ParseDirectNewDeclarator(Declarator &D) {
920  // Parse the array dimensions.
921  bool first = true;
922  while (Tok.is(tok::l_square)) {
923    SourceLocation LLoc = ConsumeBracket();
924    OwningExprResult Size(first ? ParseExpression()
925                                : ParseConstantExpression());
926    if (Size.isInvalid()) {
927      // Recover
928      SkipUntil(tok::r_square);
929      return;
930    }
931    first = false;
932
933    SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc);
934    D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false,
935                                            Size.release(), LLoc),
936                  RLoc);
937
938    if (RLoc.isInvalid())
939      return;
940  }
941}
942
943/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id.
944/// This ambiguity appears in the syntax of the C++ new operator.
945///
946///        new-expression:
947///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
948///                                     new-initializer[opt]
949///
950///        new-placement:
951///                   '(' expression-list ')'
952///
953bool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs,
954                                         Declarator &D) {
955  // The '(' was already consumed.
956  if (isTypeIdInParens()) {
957    ParseSpecifierQualifierList(D.getMutableDeclSpec());
958    D.SetSourceRange(D.getDeclSpec().getSourceRange());
959    ParseDeclarator(D);
960    return D.isInvalidType();
961  }
962
963  // It's not a type, it has to be an expression list.
964  // Discard the comma locations - ActOnCXXNew has enough parameters.
965  CommaLocsTy CommaLocs;
966  return ParseExpressionList(PlacementArgs, CommaLocs);
967}
968
969/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used
970/// to free memory allocated by new.
971///
972/// This method is called to parse the 'delete' expression after the optional
973/// '::' has been already parsed.  If the '::' was present, "UseGlobal" is true
974/// and "Start" is its location.  Otherwise, "Start" is the location of the
975/// 'delete' token.
976///
977///        delete-expression:
978///                   '::'[opt] 'delete' cast-expression
979///                   '::'[opt] 'delete' '[' ']' cast-expression
980Parser::OwningExprResult
981Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) {
982  assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword");
983  ConsumeToken(); // Consume 'delete'
984
985  // Array delete?
986  bool ArrayDelete = false;
987  if (Tok.is(tok::l_square)) {
988    ArrayDelete = true;
989    SourceLocation LHS = ConsumeBracket();
990    SourceLocation RHS = MatchRHSPunctuation(tok::r_square, LHS);
991    if (RHS.isInvalid())
992      return ExprError();
993  }
994
995  OwningExprResult Operand(ParseCastExpression(false));
996  if (Operand.isInvalid())
997    return move(Operand);
998
999  return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, move(Operand));
1000}
1001
1002static UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind)
1003{
1004  switch(kind) {
1005  default: assert(false && "Not a known unary type trait.");
1006  case tok::kw___has_nothrow_assign:      return UTT_HasNothrowAssign;
1007  case tok::kw___has_nothrow_copy:        return UTT_HasNothrowCopy;
1008  case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor;
1009  case tok::kw___has_trivial_assign:      return UTT_HasTrivialAssign;
1010  case tok::kw___has_trivial_copy:        return UTT_HasTrivialCopy;
1011  case tok::kw___has_trivial_constructor: return UTT_HasTrivialConstructor;
1012  case tok::kw___has_trivial_destructor:  return UTT_HasTrivialDestructor;
1013  case tok::kw___has_virtual_destructor:  return UTT_HasVirtualDestructor;
1014  case tok::kw___is_abstract:             return UTT_IsAbstract;
1015  case tok::kw___is_class:                return UTT_IsClass;
1016  case tok::kw___is_empty:                return UTT_IsEmpty;
1017  case tok::kw___is_enum:                 return UTT_IsEnum;
1018  case tok::kw___is_pod:                  return UTT_IsPOD;
1019  case tok::kw___is_polymorphic:          return UTT_IsPolymorphic;
1020  case tok::kw___is_union:                return UTT_IsUnion;
1021  }
1022}
1023
1024/// ParseUnaryTypeTrait - Parse the built-in unary type-trait
1025/// pseudo-functions that allow implementation of the TR1/C++0x type traits
1026/// templates.
1027///
1028///       primary-expression:
1029/// [GNU]             unary-type-trait '(' type-id ')'
1030///
1031Parser::OwningExprResult Parser::ParseUnaryTypeTrait()
1032{
1033  UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind());
1034  SourceLocation Loc = ConsumeToken();
1035
1036  SourceLocation LParen = Tok.getLocation();
1037  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen))
1038    return ExprError();
1039
1040  // FIXME: Error reporting absolutely sucks! If the this fails to parse a type
1041  // there will be cryptic errors about mismatched parentheses and missing
1042  // specifiers.
1043  TypeResult Ty = ParseTypeName();
1044
1045  SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen);
1046
1047  if (Ty.isInvalid())
1048    return ExprError();
1049
1050  return Actions.ActOnUnaryTypeTrait(UTT, Loc, LParen, Ty.get(), RParen);
1051}
1052
1053/// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a
1054/// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate
1055/// based on the context past the parens.
1056Parser::OwningExprResult
1057Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
1058                                         TypeTy *&CastTy,
1059                                         SourceLocation LParenLoc,
1060                                         SourceLocation &RParenLoc) {
1061  assert(getLang().CPlusPlus && "Should only be called for C++!");
1062  assert(ExprType == CastExpr && "Compound literals are not ambiguous!");
1063  assert(isTypeIdInParens() && "Not a type-id!");
1064
1065  OwningExprResult Result(Actions, true);
1066  CastTy = 0;
1067
1068  // We need to disambiguate a very ugly part of the C++ syntax:
1069  //
1070  // (T())x;  - type-id
1071  // (T())*x; - type-id
1072  // (T())/x; - expression
1073  // (T());   - expression
1074  //
1075  // The bad news is that we cannot use the specialized tentative parser, since
1076  // it can only verify that the thing inside the parens can be parsed as
1077  // type-id, it is not useful for determining the context past the parens.
1078  //
1079  // The good news is that the parser can disambiguate this part without
1080  // making any unnecessary Action calls.
1081  //
1082  // It uses a scheme similar to parsing inline methods. The parenthesized
1083  // tokens are cached, the context that follows is determined (possibly by
1084  // parsing a cast-expression), and then we re-introduce the cached tokens
1085  // into the token stream and parse them appropriately.
1086
1087  ParenParseOption ParseAs;
1088  CachedTokens Toks;
1089
1090  // Store the tokens of the parentheses. We will parse them after we determine
1091  // the context that follows them.
1092  if (!ConsumeAndStoreUntil(tok::r_paren, tok::unknown, Toks, tok::semi)) {
1093    // We didn't find the ')' we expected.
1094    MatchRHSPunctuation(tok::r_paren, LParenLoc);
1095    return ExprError();
1096  }
1097
1098  if (Tok.is(tok::l_brace)) {
1099    ParseAs = CompoundLiteral;
1100  } else {
1101    bool NotCastExpr;
1102    // FIXME: Special-case ++ and --: "(S())++;" is not a cast-expression
1103    if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) {
1104      NotCastExpr = true;
1105    } else {
1106      // Try parsing the cast-expression that may follow.
1107      // If it is not a cast-expression, NotCastExpr will be true and no token
1108      // will be consumed.
1109      Result = ParseCastExpression(false/*isUnaryExpression*/,
1110                                   false/*isAddressofOperand*/,
1111                                   NotCastExpr);
1112    }
1113
1114    // If we parsed a cast-expression, it's really a type-id, otherwise it's
1115    // an expression.
1116    ParseAs = NotCastExpr ? SimpleExpr : CastExpr;
1117  }
1118
1119  // The current token should go after the cached tokens.
1120  Toks.push_back(Tok);
1121  // Re-enter the stored parenthesized tokens into the token stream, so we may
1122  // parse them now.
1123  PP.EnterTokenStream(Toks.data(), Toks.size(),
1124                      true/*DisableMacroExpansion*/, false/*OwnsTokens*/);
1125  // Drop the current token and bring the first cached one. It's the same token
1126  // as when we entered this function.
1127  ConsumeAnyToken();
1128
1129  if (ParseAs >= CompoundLiteral) {
1130    TypeResult Ty = ParseTypeName();
1131
1132    // Match the ')'.
1133    if (Tok.is(tok::r_paren))
1134      RParenLoc = ConsumeParen();
1135    else
1136      MatchRHSPunctuation(tok::r_paren, LParenLoc);
1137
1138    if (ParseAs == CompoundLiteral) {
1139      ExprType = CompoundLiteral;
1140      return ParseCompoundLiteralExpression(Ty.get(), LParenLoc, RParenLoc);
1141    }
1142
1143    // We parsed '(' type-id ')' and the thing after it wasn't a '{'.
1144    assert(ParseAs == CastExpr);
1145
1146    if (Ty.isInvalid())
1147      return ExprError();
1148
1149    CastTy = Ty.get();
1150
1151    // Result is what ParseCastExpression returned earlier.
1152    if (!Result.isInvalid())
1153      Result = Actions.ActOnCastExpr(LParenLoc, CastTy, RParenLoc,move(Result));
1154    return move(Result);
1155  }
1156
1157  // Not a compound literal, and not followed by a cast-expression.
1158  assert(ParseAs == SimpleExpr);
1159
1160  ExprType = SimpleExpr;
1161  Result = ParseExpression();
1162  if (!Result.isInvalid() && Tok.is(tok::r_paren))
1163    Result = Actions.ActOnParenExpr(LParenLoc, Tok.getLocation(), move(Result));
1164
1165  // Match the ')'.
1166  if (Result.isInvalid()) {
1167    SkipUntil(tok::r_paren);
1168    return ExprError();
1169  }
1170
1171  if (Tok.is(tok::r_paren))
1172    RParenLoc = ConsumeParen();
1173  else
1174    MatchRHSPunctuation(tok::r_paren, LParenLoc);
1175
1176  return move(Result);
1177}
1178