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

« back to all changes in this revision

Viewing changes to clang/lib/Format/TokenAnnotator.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:
101
101
        return true;
102
102
      }
103
103
      if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace,
104
 
                                tok::pipepipe, tok::ampamp, tok::question,
105
 
                                tok::colon))
 
104
                                tok::question, tok::colon))
 
105
        return false;
 
106
      if (CurrentToken->isOneOf(tok::pipepipe, tok::ampamp) &&
 
107
          Line.First.isNot(tok::kw_template))
106
108
        return false;
107
109
      updateParameterCount(Left, CurrentToken);
108
110
      if (!consumeToken())
155
157
      }
156
158
 
157
159
      if (CurrentToken->is(tok::r_paren)) {
 
160
        if (CurrentToken->Children.empty() ||
 
161
            !CurrentToken->Children[0].isOneOf(tok::l_paren, tok::l_square))
 
162
          Left->DefinesFunctionType = false;
158
163
        Left->MatchingParen = CurrentToken;
159
164
        CurrentToken->MatchingParen = Left;
160
165
 
171
176
      }
172
177
      if (CurrentToken->isOneOf(tok::r_square, tok::r_brace))
173
178
        return false;
 
179
      if (CurrentToken->Parent->Type == TT_PointerOrReference &&
 
180
          CurrentToken->Parent->Parent->isOneOf(tok::l_paren, tok::coloncolon))
 
181
        Left->DefinesFunctionType = true;
174
182
      updateParameterCount(Left, CurrentToken);
175
183
      if (!consumeToken())
176
184
        return false;
243
251
  }
244
252
 
245
253
  bool parseBrace() {
246
 
    // Lines are fine to end with '{'.
247
 
    if (CurrentToken == NULL)
248
 
      return true;
249
 
    ScopedContextCreator ContextCreator(*this, tok::l_brace, 1);
250
 
    AnnotatedToken *Left = CurrentToken->Parent;
251
 
    while (CurrentToken != NULL) {
252
 
      if (CurrentToken->is(tok::r_brace)) {
253
 
        Left->MatchingParen = CurrentToken;
254
 
        CurrentToken->MatchingParen = Left;
255
 
        next();
256
 
        return true;
257
 
      }
258
 
      if (CurrentToken->isOneOf(tok::r_paren, tok::r_square))
259
 
        return false;
260
 
      updateParameterCount(Left, CurrentToken);
261
 
      if (!consumeToken())
262
 
        return false;
 
254
    if (CurrentToken != NULL) {
 
255
      ScopedContextCreator ContextCreator(*this, tok::l_brace, 1);
 
256
      AnnotatedToken *Left = CurrentToken->Parent;
 
257
 
 
258
      AnnotatedToken *Parent = Left->getPreviousNoneComment();
 
259
      bool StartsObjCDictLiteral = Parent && Parent->is(tok::at);
 
260
      if (StartsObjCDictLiteral) {
 
261
        Contexts.back().ColonIsObjCDictLiteral = true;
 
262
        Left->Type = TT_ObjCDictLiteral;
 
263
      }
 
264
 
 
265
      while (CurrentToken != NULL) {
 
266
        if (CurrentToken->is(tok::r_brace)) {
 
267
          if (StartsObjCDictLiteral)
 
268
            CurrentToken->Type = TT_ObjCDictLiteral;
 
269
          Left->MatchingParen = CurrentToken;
 
270
          CurrentToken->MatchingParen = Left;
 
271
          next();
 
272
          return true;
 
273
        }
 
274
        if (CurrentToken->isOneOf(tok::r_paren, tok::r_square))
 
275
          return false;
 
276
        updateParameterCount(Left, CurrentToken);
 
277
        if (!consumeToken())
 
278
          return false;
 
279
      }
263
280
    }
 
281
    // No closing "}" found, this probably starts a definition.
 
282
    Line.StartsDefinition = true;
264
283
    return true;
265
284
  }
266
285
 
312
331
      // Colons from ?: are handled in parseConditional().
313
332
      if (Tok->Parent->is(tok::r_paren) && Contexts.size() == 1) {
314
333
        Tok->Type = TT_CtorInitializerColon;
 
334
      } else if (Contexts.back().ColonIsObjCDictLiteral) {
 
335
        Tok->Type = TT_ObjCDictLiteral;
315
336
      } else if (Contexts.back().ColonIsObjCMethodExpr ||
316
337
                 Line.First.Type == TT_ObjCMethodSpecifier) {
317
338
        Tok->Type = TT_ObjCMethodExpr;
318
339
        Tok->Parent->Type = TT_ObjCSelectorName;
319
340
        if (Tok->Parent->FormatTok.TokenLength >
320
 
                Contexts.back().LongestObjCSelectorName)
 
341
            Contexts.back().LongestObjCSelectorName)
321
342
          Contexts.back().LongestObjCSelectorName =
322
343
              Tok->Parent->FormatTok.TokenLength;
323
344
        if (Contexts.back().FirstObjCSelectorName == NULL)
384
405
          CurrentToken->Type = TT_PointerOrReference;
385
406
        consumeToken();
386
407
      }
387
 
      if (CurrentToken)
 
408
      if (CurrentToken) {
388
409
        CurrentToken->Type = TT_OverloadedOperatorLParen;
 
410
        if (CurrentToken->Parent->Type == TT_BinaryOperator)
 
411
          CurrentToken->Parent->Type = TT_OverloadedOperator;
 
412
      }
389
413
      break;
390
414
    case tok::question:
391
415
      parseConditional();
457
481
    case tok::pp_warning:
458
482
      parseWarningOrError();
459
483
      break;
 
484
    case tok::pp_if:
 
485
    case tok::pp_elif:
 
486
      parseLine();
 
487
      break;
460
488
    default:
461
489
      break;
462
490
    }
531
559
            bool IsExpression)
532
560
        : ContextKind(ContextKind), BindingStrength(BindingStrength),
533
561
          LongestObjCSelectorName(0), ColonIsForRangeExpr(false),
534
 
          ColonIsObjCMethodExpr(false), FirstObjCSelectorName(NULL),
535
 
          FirstStartOfName(NULL), IsExpression(IsExpression),
536
 
          CanBeExpression(true) {}
 
562
          ColonIsObjCDictLiteral(false), ColonIsObjCMethodExpr(false),
 
563
          FirstObjCSelectorName(NULL), FirstStartOfName(NULL),
 
564
          IsExpression(IsExpression), CanBeExpression(true) {}
537
565
 
538
566
    tok::TokenKind ContextKind;
539
567
    unsigned BindingStrength;
540
568
    unsigned LongestObjCSelectorName;
541
569
    bool ColonIsForRangeExpr;
 
570
    bool ColonIsObjCDictLiteral;
542
571
    bool ColonIsObjCMethodExpr;
543
572
    AnnotatedToken *FirstObjCSelectorName;
544
573
    AnnotatedToken *FirstStartOfName;
578
607
      }
579
608
    } else if (Current.isOneOf(tok::kw_return, tok::kw_throw) ||
580
609
               (Current.is(tok::l_paren) && !Line.MustBeDeclaration &&
 
610
                !Line.InPPDirective &&
581
611
                (!Current.Parent || Current.Parent->isNot(tok::kw_for)))) {
582
612
      Contexts.back().IsExpression = true;
583
613
    } else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {
590
620
      Contexts.back().IsExpression = true;
591
621
    } else if (Current.is(tok::kw_new)) {
592
622
      Contexts.back().CanBeExpression = false;
 
623
    } else if (Current.is(tok::semi)) {
 
624
      // This should be the condition or increment in a for-loop.
 
625
      Contexts.back().IsExpression = true;
593
626
    }
594
627
 
595
628
    if (Current.Type == TT_Unknown) {
596
629
      if (Current.Parent && Current.is(tok::identifier) &&
597
630
          ((Current.Parent->is(tok::identifier) &&
598
631
            Current.Parent->FormatTok.Tok.getIdentifierInfo()
599
 
                ->getPPKeywordID() == tok::pp_not_keyword) ||
 
632
                    ->getPPKeywordID() ==
 
633
                tok::pp_not_keyword) ||
600
634
           isSimpleTypeSpecifier(*Current.Parent) ||
601
635
           Current.Parent->Type == TT_PointerOrReference ||
602
636
           Current.Parent->Type == TT_TemplateCloser)) {
622
656
        else
623
657
          Current.Type = TT_BlockComment;
624
658
      } else if (Current.is(tok::r_paren)) {
625
 
        bool ParensNotExpr = !Current.Parent ||
626
 
                             Current.Parent->Type == TT_PointerOrReference ||
627
 
                             Current.Parent->Type == TT_TemplateCloser;
 
659
        bool ParensNotExpr =
 
660
            !Current.Parent || Current.Parent->Type == TT_PointerOrReference ||
 
661
            Current.Parent->Type == TT_TemplateCloser;
628
662
        bool ParensCouldEndDecl =
629
663
            !Current.Children.empty() &&
630
664
            Current.Children[0].isOneOf(tok::equal, tok::semi, tok::l_brace);
654
688
  }
655
689
 
656
690
  /// \brief Return the type of the given token assuming it is * or &.
657
 
  TokenType
658
 
  determineStarAmpUsage(const AnnotatedToken &Tok, bool IsExpression) {
 
691
  TokenType determineStarAmpUsage(const AnnotatedToken &Tok,
 
692
                                  bool IsExpression) {
659
693
    const AnnotatedToken *PrevToken = Tok.getPreviousNoneComment();
660
694
    if (PrevToken == NULL)
661
695
      return TT_UnaryOperator;
669
703
 
670
704
    if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace,
671
705
                           tok::comma, tok::semi, tok::kw_return, tok::colon,
672
 
                           tok::equal) ||
 
706
                           tok::equal, tok::kw_delete) ||
673
707
        PrevToken->Type == TT_BinaryOperator ||
674
708
        PrevToken->Type == TT_UnaryOperator || PrevToken->Type == TT_CastRParen)
675
709
      return TT_UnaryOperator;
854
888
  Line.First.SpacesRequiredBefore = 1;
855
889
  Line.First.MustBreakBefore = Line.First.FormatTok.MustBreakBefore;
856
890
  Line.First.CanBreakBefore = Line.First.MustBreakBefore;
857
 
 
858
 
  Line.First.TotalLength = Line.First.FormatTok.TokenLength;
859
891
}
860
892
 
861
893
void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) {
901
933
    Current = Current->Children.empty() ? NULL : &Current->Children[0];
902
934
  }
903
935
 
 
936
  calculateUnbreakableTailLengths(Line);
904
937
  DEBUG({
905
938
    printDebugInfo(Line);
906
939
  });
907
940
}
908
941
 
 
942
void TokenAnnotator::calculateUnbreakableTailLengths(AnnotatedLine &Line) {
 
943
  unsigned UnbreakableTailLength = 0;
 
944
  AnnotatedToken *Current = Line.Last;
 
945
  while (Current != NULL) {
 
946
    Current->UnbreakableTailLength = UnbreakableTailLength;
 
947
    if (Current->CanBreakBefore ||
 
948
        Current->isOneOf(tok::comment, tok::string_literal)) {
 
949
      UnbreakableTailLength = 0;
 
950
    } else {
 
951
      UnbreakableTailLength +=
 
952
          Current->FormatTok.TokenLength + Current->SpacesRequiredBefore;
 
953
    }
 
954
    Current = Current->Parent;
 
955
  }
 
956
}
 
957
 
909
958
unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
910
959
                                      const AnnotatedToken &Tok) {
911
960
  const AnnotatedToken &Left = *Tok.Parent;
940
989
    return 150;
941
990
  }
942
991
 
 
992
  // Breaking before a trailing 'const' is bad.
 
993
  if (Left.is(tok::r_paren) && Right.is(tok::kw_const))
 
994
    return 150;
 
995
 
943
996
  // In for-loops, prefer breaking at ',' and ';'.
944
997
  if (Line.First.is(tok::kw_for) && Left.is(tok::equal))
945
998
    return 4;
968
1021
      Content = Content.drop_back(1).drop_front(1).trim();
969
1022
      if (Content.size() > 1 &&
970
1023
          (Content.back() == ':' || Content.back() == '='))
971
 
        return 100;
 
1024
        return 20;
972
1025
    }
973
1026
    return prec::Shift;
974
1027
  }
1014
1067
    return Left.FormatTok.Tok.isLiteral() ||
1015
1068
           ((Left.Type != TT_PointerOrReference) && Left.isNot(tok::l_paren) &&
1016
1069
            !Style.PointerBindsToType);
 
1070
  if (Right.DefinesFunctionType &&
 
1071
      (Left.Type != TT_PointerOrReference || Style.PointerBindsToType))
 
1072
    return true;
1017
1073
  if (Left.Type == TT_PointerOrReference)
1018
1074
    return Right.FormatTok.Tok.isLiteral() ||
1019
1075
           ((Right.Type != TT_PointerOrReference) &&
1020
1076
            Right.isNot(tok::l_paren) && Style.PointerBindsToType &&
1021
 
            Left.Parent && Left.Parent->isNot(tok::l_paren));
 
1077
            Left.Parent &&
 
1078
            !Left.Parent->isOneOf(tok::l_paren, tok::coloncolon));
1022
1079
  if (Right.is(tok::star) && Left.is(tok::l_paren))
1023
1080
    return false;
1024
1081
  if (Left.is(tok::l_square))
1039
1096
    return Line.Type == LT_ObjCDecl ||
1040
1097
           Left.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch,
1041
1098
                        tok::kw_return, tok::kw_catch, tok::kw_new,
1042
 
                        tok::kw_delete);
 
1099
                        tok::kw_delete, tok::semi);
1043
1100
  }
1044
1101
  if (Left.is(tok::at) &&
1045
1102
      Right.FormatTok.Tok.getObjCKeywordID() != tok::objc_not_keyword)
1046
1103
    return false;
1047
1104
  if (Left.is(tok::l_brace) && Right.is(tok::r_brace))
 
1105
    return false; // No spaces in "{}".
 
1106
  if (Left.is(tok::l_brace) || Right.is(tok::r_brace))
 
1107
    return Style.SpacesInBracedLists;
 
1108
  if (Right.Type == TT_UnaryOperator)
 
1109
    return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) &&
 
1110
           (Left.isNot(tok::colon) || Left.Type != TT_ObjCMethodExpr);
 
1111
  if (Left.isOneOf(tok::identifier, tok::greater, tok::r_square) &&
 
1112
      Right.is(tok::l_brace) && Right.getNextNoneComment())
 
1113
    return false;
 
1114
  if (Right.is(tok::ellipsis))
1048
1115
    return false;
1049
1116
  return true;
1050
1117
}
1078
1145
  if (Tok.is(tok::colon))
1079
1146
    return !Line.First.isOneOf(tok::kw_case, tok::kw_default) &&
1080
1147
           Tok.getNextNoneComment() != NULL && Tok.Type != TT_ObjCMethodExpr;
1081
 
  if (Tok.is(tok::l_paren) && !Tok.Children.empty() &&
1082
 
      Tok.Children[0].Type == TT_PointerOrReference &&
1083
 
      !Tok.Children[0].Children.empty() &&
1084
 
      Tok.Children[0].Children[0].isNot(tok::r_paren) &&
1085
 
      Tok.Parent->isNot(tok::l_paren) &&
1086
 
      (Tok.Parent->Type != TT_PointerOrReference || Style.PointerBindsToType))
1087
 
    return true;
1088
1148
  if (Tok.Parent->Type == TT_UnaryOperator || Tok.Parent->Type == TT_CastRParen)
1089
1149
    return false;
1090
 
  if (Tok.Type == TT_UnaryOperator)
1091
 
    return !Tok.Parent->isOneOf(tok::l_paren, tok::l_square, tok::at) &&
1092
 
           (Tok.Parent->isNot(tok::colon) ||
1093
 
            Tok.Parent->Type != TT_ObjCMethodExpr);
1094
1150
  if (Tok.Parent->is(tok::greater) && Tok.is(tok::greater)) {
1095
1151
    return Tok.Type == TT_TemplateCloser &&
1096
1152
           Tok.Parent->Type == TT_TemplateCloser &&
1115
1171
  const AnnotatedToken &Left = *Right.Parent;
1116
1172
  if (Right.Type == TT_StartOfName)
1117
1173
    return true;
1118
 
  if (Right.is(tok::colon) && Right.Type == TT_ObjCMethodExpr)
 
1174
  if (Right.is(tok::colon) &&
 
1175
      (Right.Type == TT_ObjCDictLiteral || Right.Type == TT_ObjCMethodExpr))
1119
1176
    return false;
1120
 
  if (Left.is(tok::colon) && Left.Type == TT_ObjCMethodExpr)
 
1177
  if (Left.is(tok::colon) &&
 
1178
      (Left.Type == TT_ObjCDictLiteral || Left.Type == TT_ObjCMethodExpr))
1121
1179
    return true;
1122
1180
  if (Right.Type == TT_ObjCSelectorName)
1123
1181
    return true;
1126
1184
  if (Right.Type == TT_ConditionalExpr || Right.is(tok::question))
1127
1185
    return true;
1128
1186
  if (Right.Type == TT_RangeBasedForLoopColon ||
1129
 
      Right.Type == TT_InheritanceColon ||
1130
1187
      Right.Type == TT_OverloadedOperatorLParen)
1131
1188
    return false;
1132
 
  if (Left.Type == TT_RangeBasedForLoopColon ||
1133
 
      Left.Type == TT_InheritanceColon)
 
1189
  if (Left.Type == TT_RangeBasedForLoopColon)
1134
1190
    return true;
1135
1191
  if (Right.Type == TT_RangeBasedForLoopColon)
1136
1192
    return false;
1149
1205
    // change the "binding" behavior of a comment.
1150
1206
    return false;
1151
1207
 
 
1208
  // We only break before r_brace if there was a corresponding break before
 
1209
  // the l_brace, which is tracked by BreakBeforeClosingBrace.
 
1210
  if (Right.isOneOf(tok::r_brace, tok::r_paren, tok::greater))
 
1211
    return false;
 
1212
 
1152
1213
  // Allow breaking after a trailing 'const', e.g. after a method declaration,
1153
1214
  // unless it is follow by ';', '{' or '='.
1154
1215
  if (Left.is(tok::kw_const) && Left.Parent != NULL &&
1158
1219
  if (Right.is(tok::kw___attribute))
1159
1220
    return true;
1160
1221
 
1161
 
  // We only break before r_brace if there was a corresponding break before
1162
 
  // the l_brace, which is tracked by BreakBeforeClosingBrace.
1163
 
  if (Right.isOneOf(tok::r_brace, tok::r_paren, tok::greater))
1164
 
    return false;
1165
1222
  if (Left.is(tok::identifier) && Right.is(tok::string_literal))
1166
1223
    return true;
1167
1224
  return (Left.isBinaryOperator() && Left.isNot(tok::lessless)) ||
1169
1226
                      tok::kw_class, tok::kw_struct) ||
1170
1227
         Right.isOneOf(tok::lessless, tok::arrow, tok::period, tok::colon) ||
1171
1228
         (Left.is(tok::r_paren) && Left.Type != TT_CastRParen &&
1172
 
          Right.isOneOf(tok::identifier, tok::kw___attribute)) ||
 
1229
          Right.isOneOf(tok::identifier, tok::kw_const, tok::kw___attribute)) ||
1173
1230
         (Left.is(tok::l_paren) && !Right.is(tok::r_paren)) ||
1174
1231
         (Left.is(tok::l_square) && !Right.is(tok::r_square));
1175
1232
}
1181
1238
    llvm::errs() << " M=" << Tok->MustBreakBefore
1182
1239
                 << " C=" << Tok->CanBreakBefore << " T=" << Tok->Type
1183
1240
                 << " S=" << Tok->SpacesRequiredBefore
 
1241
                 << " P=" << Tok->SplitPenalty
1184
1242
                 << " Name=" << Tok->FormatTok.Tok.getName() << " FakeLParens=";
1185
1243
    for (unsigned i = 0, e = Tok->FakeLParens.size(); i != e; ++i)
1186
1244
      llvm::errs() << Tok->FakeLParens[i] << "/";