~ubuntu-branches/ubuntu/trusty/llvm-toolchain-snapshot/trusty-201310232150

« back to all changes in this revision

Viewing changes to clang/lib/Parse/ParseExprCXX.cpp

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-27 15:01:57 UTC
  • mfrom: (0.10.1) (0.9.1) (0.8.1) (0.7.1) (0.6.1) (0.5.2)
  • Revision ID: package-import@ubuntu.com-20130527150157-tdkrsjpuvht7v0qx
Tags: 1:3.4~svn182733-1~exp1
* New snapshot release (3.4 release)
* Add a symlink of libLLVM-3.4.so.1 to usr/lib/llvm-3.4/lib/libLLVM-3.4.so
    to fix make the llvm-config-3.4 --libdir work (Closes: #708677)
  * Various packages rename to allow co installations:
    * libclang1 => libclang1-3.4
    * libclang1-dbg => libclang1-3.4-dbg
    * libclang-dev => libclang-3.4-dev
    * libclang-common-dev => libclang-common-3.4-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
583
583
                                   Tok.is(tok::l_paren), isAddressOfOperand);
584
584
}
585
585
 
586
 
/// ParseLambdaExpression - Parse a C++0x lambda expression.
 
586
/// ParseLambdaExpression - Parse a C++11 lambda expression.
587
587
///
588
588
///       lambda-expression:
589
589
///         lambda-introducer lambda-declarator[opt] compound-statement
605
605
///         capture-list ',' capture
606
606
///
607
607
///       capture:
 
608
///         simple-capture
 
609
///         init-capture     [C++1y]
 
610
///
 
611
///       simple-capture:
608
612
///         identifier
609
613
///         '&' identifier
610
614
///         'this'
611
615
///
 
616
///       init-capture:      [C++1y]
 
617
///         identifier initializer
 
618
///         '&' identifier initializer
 
619
///
612
620
///       lambda-declarator:
613
621
///         '(' parameter-declaration-clause ')' attribute-specifier[opt]
614
622
///           'mutable'[opt] exception-specification[opt]
671
679
  return ParseLambdaExpressionAfterIntroducer(Intro);
672
680
}
673
681
 
674
 
/// ParseLambdaExpression - Parse a lambda introducer.
675
 
///
676
 
/// Returns a DiagnosticID if it hit something unexpected.
677
 
Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro) {
 
682
/// \brief Parse a lambda introducer.
 
683
/// \param Intro A LambdaIntroducer filled in with information about the
 
684
///        contents of the lambda-introducer.
 
685
/// \param SkippedInits If non-null, we are disambiguating between an Obj-C
 
686
///        message send and a lambda expression. In this mode, we will
 
687
///        sometimes skip the initializers for init-captures and not fully
 
688
///        populate \p Intro. This flag will be set to \c true if we do so.
 
689
/// \return A DiagnosticID if it hit something unexpected. The location for
 
690
///         for the diagnostic is that of the current token.
 
691
Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
 
692
                                                 bool *SkippedInits) {
678
693
  typedef Optional<unsigned> DiagResult;
679
694
 
680
695
  assert(Tok.is(tok::l_square) && "Lambda expressions begin with '['.");
737
752
    SourceLocation Loc;
738
753
    IdentifierInfo* Id = 0;
739
754
    SourceLocation EllipsisLoc;
 
755
    ExprResult Init;
740
756
    
741
757
    if (Tok.is(tok::kw_this)) {
742
758
      Kind = LCK_This;
757
773
      if (Tok.is(tok::identifier)) {
758
774
        Id = Tok.getIdentifierInfo();
759
775
        Loc = ConsumeToken();
760
 
        
761
 
        if (Tok.is(tok::ellipsis))
762
 
          EllipsisLoc = ConsumeToken();
763
776
      } else if (Tok.is(tok::kw_this)) {
764
777
        // FIXME: If we want to suggest a fixit here, will need to return more
765
778
        // than just DiagnosticID. Perhaps full DiagnosticBuilder that can be
768
781
      } else {
769
782
        return DiagResult(diag::err_expected_capture);
770
783
      }
 
784
 
 
785
      if (Tok.is(tok::l_paren)) {
 
786
        BalancedDelimiterTracker Parens(*this, tok::l_paren);
 
787
        Parens.consumeOpen();
 
788
 
 
789
        ExprVector Exprs;
 
790
        CommaLocsTy Commas;
 
791
        if (SkippedInits) {
 
792
          Parens.skipToEnd();
 
793
          *SkippedInits = true;
 
794
        } else if (ParseExpressionList(Exprs, Commas)) {
 
795
          Parens.skipToEnd();
 
796
          Init = ExprError();
 
797
        } else {
 
798
          Parens.consumeClose();
 
799
          Init = Actions.ActOnParenListExpr(Parens.getOpenLocation(),
 
800
                                            Parens.getCloseLocation(),
 
801
                                            Exprs);
 
802
        }
 
803
      } else if (Tok.is(tok::l_brace) || Tok.is(tok::equal)) {
 
804
        if (Tok.is(tok::equal))
 
805
          ConsumeToken();
 
806
 
 
807
        if (!SkippedInits)
 
808
          Init = ParseInitializer();
 
809
        else if (Tok.is(tok::l_brace)) {
 
810
          BalancedDelimiterTracker Braces(*this, tok::l_brace);
 
811
          Braces.consumeOpen();
 
812
          Braces.skipToEnd();
 
813
          *SkippedInits = true;
 
814
        } else {
 
815
          // We're disambiguating this:
 
816
          //
 
817
          //   [..., x = expr
 
818
          //
 
819
          // We need to find the end of the following expression in order to
 
820
          // determine whether this is an Obj-C message send's receiver, or a
 
821
          // lambda init-capture.
 
822
          //
 
823
          // Parse the expression to find where it ends, and annotate it back
 
824
          // onto the tokens. We would have parsed this expression the same way
 
825
          // in either case: both the RHS of an init-capture and the RHS of an
 
826
          // assignment expression are parsed as an initializer-clause, and in
 
827
          // neither case can anything be added to the scope between the '[' and
 
828
          // here.
 
829
          //
 
830
          // FIXME: This is horrible. Adding a mechanism to skip an expression
 
831
          // would be much cleaner.
 
832
          // FIXME: If there is a ',' before the next ']' or ':', we can skip to
 
833
          // that instead. (And if we see a ':' with no matching '?', we can
 
834
          // classify this as an Obj-C message send.)
 
835
          SourceLocation StartLoc = Tok.getLocation();
 
836
          InMessageExpressionRAIIObject MaybeInMessageExpression(*this, true);
 
837
          Init = ParseInitializer();
 
838
 
 
839
          if (Tok.getLocation() != StartLoc) {
 
840
            // Back out the lexing of the token after the initializer.
 
841
            PP.RevertCachedTokens(1);
 
842
 
 
843
            // Replace the consumed tokens with an appropriate annotation.
 
844
            Tok.setLocation(StartLoc);
 
845
            Tok.setKind(tok::annot_primary_expr);
 
846
            setExprAnnotation(Tok, Init);
 
847
            Tok.setAnnotationEndLoc(PP.getLastCachedTokenLocation());
 
848
            PP.AnnotateCachedTokens(Tok);
 
849
 
 
850
            // Consume the annotated initializer.
 
851
            ConsumeToken();
 
852
          }
 
853
        }
 
854
      } else if (Tok.is(tok::ellipsis))
 
855
        EllipsisLoc = ConsumeToken();
771
856
    }
772
857
 
773
 
    Intro.addCapture(Kind, Loc, Id, EllipsisLoc);
 
858
    Intro.addCapture(Kind, Loc, Id, EllipsisLoc, Init);
774
859
  }
775
860
 
776
861
  T.consumeClose();
785
870
bool Parser::TryParseLambdaIntroducer(LambdaIntroducer &Intro) {
786
871
  TentativeParsingAction PA(*this);
787
872
 
788
 
  Optional<unsigned> DiagID(ParseLambdaIntroducer(Intro));
 
873
  bool SkippedInits = false;
 
874
  Optional<unsigned> DiagID(ParseLambdaIntroducer(Intro, &SkippedInits));
789
875
 
790
876
  if (DiagID) {
791
877
    PA.Revert();
792
878
    return true;
793
879
  }
794
880
 
 
881
  if (SkippedInits) {
 
882
    // Parse it again, but this time parse the init-captures too.
 
883
    PA.Revert();
 
884
    Intro = LambdaIntroducer();
 
885
    DiagID = ParseLambdaIntroducer(Intro);
 
886
    assert(!DiagID && "parsing lambda-introducer failed on reparse");
 
887
    return false;
 
888
  }
 
889
 
795
890
  PA.Commit();
796
891
  return false;
797
892
}
806
901
  PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), LambdaBeginLoc,
807
902
                                "lambda expression parsing");
808
903
 
 
904
  // FIXME: Call into Actions to add any init-capture declarations to the
 
905
  // scope while parsing the lambda-declarator and compound-statement.
 
906
 
809
907
  // Parse lambda-declarator[opt].
810
908
  DeclSpec DS(AttrFactory);
811
909
  Declarator D(DS, Declarator::LambdaExprContext);
1455
1553
 
1456
1554
  if (!InitExpr.isInvalid())
1457
1555
    Actions.AddInitializerToDecl(DeclOut, InitExpr.take(), !CopyInitialization,
1458
 
                                 DS.getTypeSpecType() == DeclSpec::TST_auto);
 
1556
                                 DS.containsPlaceholderType());
 
1557
  else
 
1558
    Actions.ActOnInitializerError(DeclOut);
1459
1559
 
1460
1560
  // FIXME: Build a reference to this declaration? Convert it to bool?
1461
1561
  // (This is currently handled by Sema).
2033
2133
  
2034
2134
  // Parse the conversion-declarator, which is merely a sequence of
2035
2135
  // ptr-operators.
2036
 
  Declarator D(DS, Declarator::TypeNameContext);
 
2136
  Declarator D(DS, Declarator::ConversionIdContext);
2037
2137
  ParseDeclaratorInternal(D, /*DirectDeclParser=*/0);
2038
2138
  
2039
2139
  // Finish up the type.