ParseExprCXX.cpp revision f58f45e6d76792df8c643ce1c6d364dce5db4826
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    Result = ParseExpression();
381
382    // Match the ')'.
383    if (Result.isInvalid())
384      SkipUntil(tok::r_paren);
385    else {
386      MatchRHSPunctuation(tok::r_paren, LParenLoc);
387
388      Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false,
389                                      Result.release(), RParenLoc);
390    }
391  }
392
393  return move(Result);
394}
395
396/// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
397///
398///       boolean-literal: [C++ 2.13.5]
399///         'true'
400///         'false'
401Parser::OwningExprResult Parser::ParseCXXBoolLiteral() {
402  tok::TokenKind Kind = Tok.getKind();
403  return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind);
404}
405
406/// ParseThrowExpression - This handles the C++ throw expression.
407///
408///       throw-expression: [C++ 15]
409///         'throw' assignment-expression[opt]
410Parser::OwningExprResult Parser::ParseThrowExpression() {
411  assert(Tok.is(tok::kw_throw) && "Not throw!");
412  SourceLocation ThrowLoc = ConsumeToken();           // Eat the throw token.
413
414  // If the current token isn't the start of an assignment-expression,
415  // then the expression is not present.  This handles things like:
416  //   "C ? throw : (void)42", which is crazy but legal.
417  switch (Tok.getKind()) {  // FIXME: move this predicate somewhere common.
418  case tok::semi:
419  case tok::r_paren:
420  case tok::r_square:
421  case tok::r_brace:
422  case tok::colon:
423  case tok::comma:
424    return Actions.ActOnCXXThrow(ThrowLoc, ExprArg(Actions));
425
426  default:
427    OwningExprResult Expr(ParseAssignmentExpression());
428    if (Expr.isInvalid()) return move(Expr);
429    return Actions.ActOnCXXThrow(ThrowLoc, move(Expr));
430  }
431}
432
433/// ParseCXXThis - This handles the C++ 'this' pointer.
434///
435/// C++ 9.3.2: In the body of a non-static member function, the keyword this is
436/// a non-lvalue expression whose value is the address of the object for which
437/// the function is called.
438Parser::OwningExprResult Parser::ParseCXXThis() {
439  assert(Tok.is(tok::kw_this) && "Not 'this'!");
440  SourceLocation ThisLoc = ConsumeToken();
441  return Actions.ActOnCXXThis(ThisLoc);
442}
443
444/// ParseCXXTypeConstructExpression - Parse construction of a specified type.
445/// Can be interpreted either as function-style casting ("int(x)")
446/// or class type construction ("ClassType(x,y,z)")
447/// or creation of a value-initialized type ("int()").
448///
449///       postfix-expression: [C++ 5.2p1]
450///         simple-type-specifier '(' expression-list[opt] ')'      [C++ 5.2.3]
451///         typename-specifier '(' expression-list[opt] ')'         [TODO]
452///
453Parser::OwningExprResult
454Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
455  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
456  TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).get();
457
458  assert(Tok.is(tok::l_paren) && "Expected '('!");
459  SourceLocation LParenLoc = ConsumeParen();
460
461  ExprVector Exprs(Actions);
462  CommaLocsTy CommaLocs;
463
464  if (Tok.isNot(tok::r_paren)) {
465    if (ParseExpressionList(Exprs, CommaLocs)) {
466      SkipUntil(tok::r_paren);
467      return ExprError();
468    }
469  }
470
471  // Match the ')'.
472  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
473
474  assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&&
475         "Unexpected number of commas!");
476  return Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep,
477                                           LParenLoc, move_arg(Exprs),
478                                           CommaLocs.data(), RParenLoc);
479}
480
481/// ParseCXXCondition - if/switch/while/for condition expression.
482///
483///       condition:
484///         expression
485///         type-specifier-seq declarator '=' assignment-expression
486/// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
487///             '=' assignment-expression
488///
489Parser::OwningExprResult Parser::ParseCXXCondition() {
490  if (!isCXXConditionDeclaration())
491    return ParseExpression(); // expression
492
493  SourceLocation StartLoc = Tok.getLocation();
494
495  // type-specifier-seq
496  DeclSpec DS;
497  ParseSpecifierQualifierList(DS);
498
499  // declarator
500  Declarator DeclaratorInfo(DS, Declarator::ConditionContext);
501  ParseDeclarator(DeclaratorInfo);
502
503  // simple-asm-expr[opt]
504  if (Tok.is(tok::kw_asm)) {
505    SourceLocation Loc;
506    OwningExprResult AsmLabel(ParseSimpleAsm(&Loc));
507    if (AsmLabel.isInvalid()) {
508      SkipUntil(tok::semi);
509      return ExprError();
510    }
511    DeclaratorInfo.setAsmLabel(AsmLabel.release());
512    DeclaratorInfo.SetRangeEnd(Loc);
513  }
514
515  // If attributes are present, parse them.
516  if (Tok.is(tok::kw___attribute)) {
517    SourceLocation Loc;
518    AttributeList *AttrList = ParseAttributes(&Loc);
519    DeclaratorInfo.AddAttributes(AttrList, Loc);
520  }
521
522  // '=' assignment-expression
523  if (Tok.isNot(tok::equal))
524    return ExprError(Diag(Tok, diag::err_expected_equal_after_declarator));
525  SourceLocation EqualLoc = ConsumeToken();
526  OwningExprResult AssignExpr(ParseAssignmentExpression());
527  if (AssignExpr.isInvalid())
528    return ExprError();
529
530  return Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc,
531                                                  DeclaratorInfo,EqualLoc,
532                                                  move(AssignExpr));
533}
534
535/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
536/// This should only be called when the current token is known to be part of
537/// simple-type-specifier.
538///
539///       simple-type-specifier:
540///         '::'[opt] nested-name-specifier[opt] type-name
541///         '::'[opt] nested-name-specifier 'template' simple-template-id [TODO]
542///         char
543///         wchar_t
544///         bool
545///         short
546///         int
547///         long
548///         signed
549///         unsigned
550///         float
551///         double
552///         void
553/// [GNU]   typeof-specifier
554/// [C++0x] auto               [TODO]
555///
556///       type-name:
557///         class-name
558///         enum-name
559///         typedef-name
560///
561void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
562  DS.SetRangeStart(Tok.getLocation());
563  const char *PrevSpec;
564  SourceLocation Loc = Tok.getLocation();
565
566  switch (Tok.getKind()) {
567  case tok::identifier:   // foo::bar
568  case tok::coloncolon:   // ::foo::bar
569    assert(0 && "Annotation token should already be formed!");
570  default:
571    assert(0 && "Not a simple-type-specifier token!");
572    abort();
573
574  // type-name
575  case tok::annot_typename: {
576    DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
577                       Tok.getAnnotationValue());
578    break;
579  }
580
581  // builtin types
582  case tok::kw_short:
583    DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec);
584    break;
585  case tok::kw_long:
586    DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec);
587    break;
588  case tok::kw_signed:
589    DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec);
590    break;
591  case tok::kw_unsigned:
592    DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec);
593    break;
594  case tok::kw_void:
595    DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec);
596    break;
597  case tok::kw_char:
598    DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec);
599    break;
600  case tok::kw_int:
601    DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec);
602    break;
603  case tok::kw_float:
604    DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec);
605    break;
606  case tok::kw_double:
607    DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec);
608    break;
609  case tok::kw_wchar_t:
610    DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec);
611    break;
612  case tok::kw_bool:
613    DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
614    break;
615
616  // GNU typeof support.
617  case tok::kw_typeof:
618    ParseTypeofSpecifier(DS);
619    DS.Finish(Diags, PP);
620    return;
621  }
622  if (Tok.is(tok::annot_typename))
623    DS.SetRangeEnd(Tok.getAnnotationEndLoc());
624  else
625    DS.SetRangeEnd(Tok.getLocation());
626  ConsumeToken();
627  DS.Finish(Diags, PP);
628}
629
630/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++
631/// [dcl.name]), which is a non-empty sequence of type-specifiers,
632/// e.g., "const short int". Note that the DeclSpec is *not* finished
633/// by parsing the type-specifier-seq, because these sequences are
634/// typically followed by some form of declarator. Returns true and
635/// emits diagnostics if this is not a type-specifier-seq, false
636/// otherwise.
637///
638///   type-specifier-seq: [C++ 8.1]
639///     type-specifier type-specifier-seq[opt]
640///
641bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) {
642  DS.SetRangeStart(Tok.getLocation());
643  const char *PrevSpec = 0;
644  int isInvalid = 0;
645
646  // Parse one or more of the type specifiers.
647  if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec)) {
648    Diag(Tok, diag::err_operator_missing_type_specifier);
649    return true;
650  }
651
652  while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec)) ;
653
654  return false;
655}
656
657/// TryParseOperatorFunctionId - Attempts to parse a C++ overloaded
658/// operator name (C++ [over.oper]). If successful, returns the
659/// predefined identifier that corresponds to that overloaded
660/// operator. Otherwise, returns NULL and does not consume any tokens.
661///
662///       operator-function-id: [C++ 13.5]
663///         'operator' operator
664///
665/// operator: one of
666///            new   delete  new[]   delete[]
667///            +     -    *  /    %  ^    &   |   ~
668///            !     =    <  >    += -=   *=  /=  %=
669///            ^=    &=   |= <<   >> >>= <<=  ==  !=
670///            <=    >=   && ||   ++ --   ,   ->* ->
671///            ()    []
672OverloadedOperatorKind
673Parser::TryParseOperatorFunctionId(SourceLocation *EndLoc) {
674  assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
675  SourceLocation Loc;
676
677  OverloadedOperatorKind Op = OO_None;
678  switch (NextToken().getKind()) {
679  case tok::kw_new:
680    ConsumeToken(); // 'operator'
681    Loc = ConsumeToken(); // 'new'
682    if (Tok.is(tok::l_square)) {
683      ConsumeBracket(); // '['
684      Loc = Tok.getLocation();
685      ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
686      Op = OO_Array_New;
687    } else {
688      Op = OO_New;
689    }
690    if (EndLoc)
691      *EndLoc = Loc;
692    return Op;
693
694  case tok::kw_delete:
695    ConsumeToken(); // 'operator'
696    Loc = ConsumeToken(); // 'delete'
697    if (Tok.is(tok::l_square)) {
698      ConsumeBracket(); // '['
699      Loc = Tok.getLocation();
700      ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
701      Op = OO_Array_Delete;
702    } else {
703      Op = OO_Delete;
704    }
705    if (EndLoc)
706      *EndLoc = Loc;
707    return Op;
708
709#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly)  \
710    case tok::Token:  Op = OO_##Name; break;
711#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
712#include "clang/Basic/OperatorKinds.def"
713
714  case tok::l_paren:
715    ConsumeToken(); // 'operator'
716    ConsumeParen(); // '('
717    Loc = Tok.getLocation();
718    ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); // ')'
719    if (EndLoc)
720      *EndLoc = Loc;
721    return OO_Call;
722
723  case tok::l_square:
724    ConsumeToken(); // 'operator'
725    ConsumeBracket(); // '['
726    Loc = Tok.getLocation();
727    ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
728    if (EndLoc)
729      *EndLoc = Loc;
730    return OO_Subscript;
731
732  default:
733    return OO_None;
734  }
735
736  ConsumeToken(); // 'operator'
737  Loc = ConsumeAnyToken(); // the operator itself
738  if (EndLoc)
739    *EndLoc = Loc;
740  return Op;
741}
742
743/// ParseConversionFunctionId - Parse a C++ conversion-function-id,
744/// which expresses the name of a user-defined conversion operator
745/// (C++ [class.conv.fct]p1). Returns the type that this operator is
746/// specifying a conversion for, or NULL if there was an error.
747///
748///        conversion-function-id: [C++ 12.3.2]
749///                   operator conversion-type-id
750///
751///        conversion-type-id:
752///                   type-specifier-seq conversion-declarator[opt]
753///
754///        conversion-declarator:
755///                   ptr-operator conversion-declarator[opt]
756Parser::TypeTy *Parser::ParseConversionFunctionId(SourceLocation *EndLoc) {
757  assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
758  ConsumeToken(); // 'operator'
759
760  // Parse the type-specifier-seq.
761  DeclSpec DS;
762  if (ParseCXXTypeSpecifierSeq(DS))
763    return 0;
764
765  // Parse the conversion-declarator, which is merely a sequence of
766  // ptr-operators.
767  Declarator D(DS, Declarator::TypeNameContext);
768  ParseDeclaratorInternal(D, /*DirectDeclParser=*/0);
769  if (EndLoc)
770    *EndLoc = D.getSourceRange().getEnd();
771
772  // Finish up the type.
773  Action::TypeResult Result = Actions.ActOnTypeName(CurScope, D);
774  if (Result.isInvalid())
775    return 0;
776  else
777    return Result.get();
778}
779
780/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate
781/// memory in a typesafe manner and call constructors.
782///
783/// This method is called to parse the new expression after the optional :: has
784/// been already parsed.  If the :: was present, "UseGlobal" is true and "Start"
785/// is its location.  Otherwise, "Start" is the location of the 'new' token.
786///
787///        new-expression:
788///                   '::'[opt] 'new' new-placement[opt] new-type-id
789///                                     new-initializer[opt]
790///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
791///                                     new-initializer[opt]
792///
793///        new-placement:
794///                   '(' expression-list ')'
795///
796///        new-type-id:
797///                   type-specifier-seq new-declarator[opt]
798///
799///        new-declarator:
800///                   ptr-operator new-declarator[opt]
801///                   direct-new-declarator
802///
803///        new-initializer:
804///                   '(' expression-list[opt] ')'
805/// [C++0x]           braced-init-list                                   [TODO]
806///
807Parser::OwningExprResult
808Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
809  assert(Tok.is(tok::kw_new) && "expected 'new' token");
810  ConsumeToken();   // Consume 'new'
811
812  // A '(' now can be a new-placement or the '(' wrapping the type-id in the
813  // second form of new-expression. It can't be a new-type-id.
814
815  ExprVector PlacementArgs(Actions);
816  SourceLocation PlacementLParen, PlacementRParen;
817
818  bool ParenTypeId;
819  DeclSpec DS;
820  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
821  if (Tok.is(tok::l_paren)) {
822    // If it turns out to be a placement, we change the type location.
823    PlacementLParen = ConsumeParen();
824    if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) {
825      SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
826      return ExprError();
827    }
828
829    PlacementRParen = MatchRHSPunctuation(tok::r_paren, PlacementLParen);
830    if (PlacementRParen.isInvalid()) {
831      SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
832      return ExprError();
833    }
834
835    if (PlacementArgs.empty()) {
836      // Reset the placement locations. There was no placement.
837      PlacementLParen = PlacementRParen = SourceLocation();
838      ParenTypeId = true;
839    } else {
840      // We still need the type.
841      if (Tok.is(tok::l_paren)) {
842        SourceLocation LParen = ConsumeParen();
843        ParseSpecifierQualifierList(DS);
844        DeclaratorInfo.SetSourceRange(DS.getSourceRange());
845        ParseDeclarator(DeclaratorInfo);
846        MatchRHSPunctuation(tok::r_paren, LParen);
847        ParenTypeId = true;
848      } else {
849        if (ParseCXXTypeSpecifierSeq(DS))
850          DeclaratorInfo.setInvalidType(true);
851        else {
852          DeclaratorInfo.SetSourceRange(DS.getSourceRange());
853          ParseDeclaratorInternal(DeclaratorInfo,
854                                  &Parser::ParseDirectNewDeclarator);
855        }
856        ParenTypeId = false;
857      }
858    }
859  } else {
860    // A new-type-id is a simplified type-id, where essentially the
861    // direct-declarator is replaced by a direct-new-declarator.
862    if (ParseCXXTypeSpecifierSeq(DS))
863      DeclaratorInfo.setInvalidType(true);
864    else {
865      DeclaratorInfo.SetSourceRange(DS.getSourceRange());
866      ParseDeclaratorInternal(DeclaratorInfo,
867                              &Parser::ParseDirectNewDeclarator);
868    }
869    ParenTypeId = false;
870  }
871  if (DeclaratorInfo.isInvalidType()) {
872    SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
873    return ExprError();
874  }
875
876  ExprVector ConstructorArgs(Actions);
877  SourceLocation ConstructorLParen, ConstructorRParen;
878
879  if (Tok.is(tok::l_paren)) {
880    ConstructorLParen = ConsumeParen();
881    if (Tok.isNot(tok::r_paren)) {
882      CommaLocsTy CommaLocs;
883      if (ParseExpressionList(ConstructorArgs, CommaLocs)) {
884        SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
885        return ExprError();
886      }
887    }
888    ConstructorRParen = MatchRHSPunctuation(tok::r_paren, ConstructorLParen);
889    if (ConstructorRParen.isInvalid()) {
890      SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
891      return ExprError();
892    }
893  }
894
895  return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,
896                             move_arg(PlacementArgs), PlacementRParen,
897                             ParenTypeId, DeclaratorInfo, ConstructorLParen,
898                             move_arg(ConstructorArgs), ConstructorRParen);
899}
900
901/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be
902/// passed to ParseDeclaratorInternal.
903///
904///        direct-new-declarator:
905///                   '[' expression ']'
906///                   direct-new-declarator '[' constant-expression ']'
907///
908void Parser::ParseDirectNewDeclarator(Declarator &D) {
909  // Parse the array dimensions.
910  bool first = true;
911  while (Tok.is(tok::l_square)) {
912    SourceLocation LLoc = ConsumeBracket();
913    OwningExprResult Size(first ? ParseExpression()
914                                : ParseConstantExpression());
915    if (Size.isInvalid()) {
916      // Recover
917      SkipUntil(tok::r_square);
918      return;
919    }
920    first = false;
921
922    SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc);
923    D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false,
924                                            Size.release(), LLoc),
925                  RLoc);
926
927    if (RLoc.isInvalid())
928      return;
929  }
930}
931
932/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id.
933/// This ambiguity appears in the syntax of the C++ new operator.
934///
935///        new-expression:
936///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
937///                                     new-initializer[opt]
938///
939///        new-placement:
940///                   '(' expression-list ')'
941///
942bool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs,
943                                         Declarator &D) {
944  // The '(' was already consumed.
945  if (isTypeIdInParens()) {
946    ParseSpecifierQualifierList(D.getMutableDeclSpec());
947    D.SetSourceRange(D.getDeclSpec().getSourceRange());
948    ParseDeclarator(D);
949    return D.isInvalidType();
950  }
951
952  // It's not a type, it has to be an expression list.
953  // Discard the comma locations - ActOnCXXNew has enough parameters.
954  CommaLocsTy CommaLocs;
955  return ParseExpressionList(PlacementArgs, CommaLocs);
956}
957
958/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used
959/// to free memory allocated by new.
960///
961/// This method is called to parse the 'delete' expression after the optional
962/// '::' has been already parsed.  If the '::' was present, "UseGlobal" is true
963/// and "Start" is its location.  Otherwise, "Start" is the location of the
964/// 'delete' token.
965///
966///        delete-expression:
967///                   '::'[opt] 'delete' cast-expression
968///                   '::'[opt] 'delete' '[' ']' cast-expression
969Parser::OwningExprResult
970Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) {
971  assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword");
972  ConsumeToken(); // Consume 'delete'
973
974  // Array delete?
975  bool ArrayDelete = false;
976  if (Tok.is(tok::l_square)) {
977    ArrayDelete = true;
978    SourceLocation LHS = ConsumeBracket();
979    SourceLocation RHS = MatchRHSPunctuation(tok::r_square, LHS);
980    if (RHS.isInvalid())
981      return ExprError();
982  }
983
984  OwningExprResult Operand(ParseCastExpression(false));
985  if (Operand.isInvalid())
986    return move(Operand);
987
988  return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, move(Operand));
989}
990
991static UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind)
992{
993  switch(kind) {
994  default: assert(false && "Not a known unary type trait.");
995  case tok::kw___has_nothrow_assign:      return UTT_HasNothrowAssign;
996  case tok::kw___has_nothrow_copy:        return UTT_HasNothrowCopy;
997  case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor;
998  case tok::kw___has_trivial_assign:      return UTT_HasTrivialAssign;
999  case tok::kw___has_trivial_copy:        return UTT_HasTrivialCopy;
1000  case tok::kw___has_trivial_constructor: return UTT_HasTrivialConstructor;
1001  case tok::kw___has_trivial_destructor:  return UTT_HasTrivialDestructor;
1002  case tok::kw___has_virtual_destructor:  return UTT_HasVirtualDestructor;
1003  case tok::kw___is_abstract:             return UTT_IsAbstract;
1004  case tok::kw___is_class:                return UTT_IsClass;
1005  case tok::kw___is_empty:                return UTT_IsEmpty;
1006  case tok::kw___is_enum:                 return UTT_IsEnum;
1007  case tok::kw___is_pod:                  return UTT_IsPOD;
1008  case tok::kw___is_polymorphic:          return UTT_IsPolymorphic;
1009  case tok::kw___is_union:                return UTT_IsUnion;
1010  }
1011}
1012
1013/// ParseUnaryTypeTrait - Parse the built-in unary type-trait
1014/// pseudo-functions that allow implementation of the TR1/C++0x type traits
1015/// templates.
1016///
1017///       primary-expression:
1018/// [GNU]             unary-type-trait '(' type-id ')'
1019///
1020Parser::OwningExprResult Parser::ParseUnaryTypeTrait()
1021{
1022  UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind());
1023  SourceLocation Loc = ConsumeToken();
1024
1025  SourceLocation LParen = Tok.getLocation();
1026  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen))
1027    return ExprError();
1028
1029  // FIXME: Error reporting absolutely sucks! If the this fails to parse a type
1030  // there will be cryptic errors about mismatched parentheses and missing
1031  // specifiers.
1032  TypeResult Ty = ParseTypeName();
1033
1034  SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen);
1035
1036  if (Ty.isInvalid())
1037    return ExprError();
1038
1039  return Actions.ActOnUnaryTypeTrait(UTT, Loc, LParen, Ty.get(), RParen);
1040}
1041
1042/// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a
1043/// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate
1044/// based on the context past the parens.
1045Parser::OwningExprResult
1046Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
1047                                         TypeTy *&CastTy,
1048                                         SourceLocation LParenLoc,
1049                                         SourceLocation &RParenLoc) {
1050  assert(getLang().CPlusPlus && "Should only be called for C++!");
1051  assert(ExprType == CastExpr && "Compound literals are not ambiguous!");
1052  assert(isTypeIdInParens() && "Not a type-id!");
1053
1054  OwningExprResult Result(Actions, true);
1055  CastTy = 0;
1056
1057  // We need to disambiguate a very ugly part of the C++ syntax:
1058  //
1059  // (T())x;  - type-id
1060  // (T())*x; - type-id
1061  // (T())/x; - expression
1062  // (T());   - expression
1063  //
1064  // The bad news is that we cannot use the specialized tentative parser, since
1065  // it can only verify that the thing inside the parens can be parsed as
1066  // type-id, it is not useful for determining the context past the parens.
1067  //
1068  // The good news is that the parser can disambiguate this part without
1069  // making any unnecessary Action calls (apart from isTypeName).
1070
1071  // Start tentantive parsing.
1072  TentativeParsingAction PA(*this);
1073
1074  // Parse the type-id but don't create a type with ActOnTypeName yet.
1075  DeclSpec DS;
1076  ParseSpecifierQualifierList(DS);
1077
1078  // Parse the abstract-declarator, if present.
1079  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
1080  ParseDeclarator(DeclaratorInfo);
1081
1082  if (!Tok.is(tok::r_paren)) {
1083    PA.Commit();
1084    MatchRHSPunctuation(tok::r_paren, LParenLoc);
1085    return ExprError();
1086  }
1087
1088  RParenLoc = ConsumeParen();
1089
1090  if (Tok.is(tok::l_brace)) {
1091    // Compound literal. Ok, we can commit the parsed tokens and continue
1092    // normal parsing.
1093    ExprType = CompoundLiteral;
1094    PA.Commit();
1095    TypeResult Ty = true;
1096    if (!DeclaratorInfo.isInvalidType())
1097      Ty = Actions.ActOnTypeName(CurScope, DeclaratorInfo);
1098    return ParseCompoundLiteralExpression(Ty.get(), LParenLoc, RParenLoc);
1099  }
1100
1101  // We parsed '(' type-name ')' and the thing after it wasn't a '{'.
1102
1103  if (DeclaratorInfo.isInvalidType()) {
1104    PA.Commit();
1105    return ExprError();
1106  }
1107
1108  bool NotCastExpr;
1109  // Parse the cast-expression that follows it next.
1110  Result = ParseCastExpression(false/*isUnaryExpression*/,
1111                               false/*isAddressofOperand*/,
1112                               NotCastExpr);
1113
1114  if (NotCastExpr == false) {
1115    // We parsed a cast-expression. That means it's really a type-id, so commit
1116    // the parsed tokens and continue normal parsing.
1117    PA.Commit();
1118    TypeResult Ty = Actions.ActOnTypeName(CurScope, DeclaratorInfo);
1119    CastTy = Ty.get();
1120    if (!Result.isInvalid())
1121      Result = Actions.ActOnCastExpr(LParenLoc, CastTy, RParenLoc,move(Result));
1122    return move(Result);
1123  }
1124
1125  // If we get here, it means the things after the parens are not the start of
1126  // a cast-expression. This means we must actually parse the tokens inside
1127  // the parens as an expression.
1128  PA.Revert();
1129
1130  Result = ParseExpression();
1131  ExprType = SimpleExpr;
1132  if (!Result.isInvalid() && Tok.is(tok::r_paren))
1133    Result = Actions.ActOnParenExpr(LParenLoc, Tok.getLocation(), move(Result));
1134
1135  // Match the ')'.
1136  if (Result.isInvalid()) {
1137    SkipUntil(tok::r_paren);
1138    return ExprError();
1139  }
1140
1141  if (Tok.is(tok::r_paren))
1142    RParenLoc = ConsumeParen();
1143  else
1144    MatchRHSPunctuation(tok::r_paren, LParenLoc);
1145
1146  return move(Result);
1147}
1148