@@ -336,219 +336,82 @@ static ClangASTMap &GetASTMap() {
336
336
return *g_map_ptr;
337
337
}
338
338
339
- bool ClangASTContext::IsOperator (const char * name,
339
+ bool ClangASTContext::IsOperator (llvm::StringRef name,
340
340
clang::OverloadedOperatorKind &op_kind) {
341
- if (name == nullptr || name[0 ] == ' \0 ' )
341
+ // All operators have to start with "operator".
342
+ if (!name.consume_front (" operator" ))
342
343
return false ;
343
344
344
- #define OPERATOR_PREFIX " operator"
345
- #define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1 )
346
-
347
- const char *post_op_name = nullptr ;
348
-
349
- bool no_space = true ;
350
-
351
- if (::strncmp (name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
352
- return false ;
353
-
354
- post_op_name = name + OPERATOR_PREFIX_LENGTH;
355
-
356
- if (post_op_name[0 ] == ' ' ) {
357
- post_op_name++;
358
- no_space = false ;
359
- }
360
-
361
- #undef OPERATOR_PREFIX
362
- #undef OPERATOR_PREFIX_LENGTH
363
-
364
- // This is an operator, set the overloaded operator kind to invalid in case
365
- // this is a conversion operator...
366
- op_kind = clang::NUM_OVERLOADED_OPERATORS;
367
-
368
- switch (post_op_name[0 ]) {
369
- default :
370
- if (no_space)
371
- return false ;
372
- break ;
373
- case ' n' :
374
- if (no_space)
375
- return false ;
376
- if (strcmp (post_op_name, " new" ) == 0 )
377
- op_kind = clang::OO_New;
378
- else if (strcmp (post_op_name, " new[]" ) == 0 )
379
- op_kind = clang::OO_Array_New;
380
- break ;
381
-
382
- case ' d' :
383
- if (no_space)
384
- return false ;
385
- if (strcmp (post_op_name, " delete" ) == 0 )
386
- op_kind = clang::OO_Delete;
387
- else if (strcmp (post_op_name, " delete[]" ) == 0 )
388
- op_kind = clang::OO_Array_Delete;
389
- break ;
390
-
391
- case ' +' :
392
- if (post_op_name[1 ] == ' \0 ' )
393
- op_kind = clang::OO_Plus;
394
- else if (post_op_name[2 ] == ' \0 ' ) {
395
- if (post_op_name[1 ] == ' =' )
396
- op_kind = clang::OO_PlusEqual;
397
- else if (post_op_name[1 ] == ' +' )
398
- op_kind = clang::OO_PlusPlus;
399
- }
400
- break ;
401
-
402
- case ' -' :
403
- if (post_op_name[1 ] == ' \0 ' )
404
- op_kind = clang::OO_Minus;
405
- else if (post_op_name[2 ] == ' \0 ' ) {
406
- switch (post_op_name[1 ]) {
407
- case ' =' :
408
- op_kind = clang::OO_MinusEqual;
409
- break ;
410
- case ' -' :
411
- op_kind = clang::OO_MinusMinus;
412
- break ;
413
- case ' >' :
414
- op_kind = clang::OO_Arrow;
415
- break ;
416
- }
417
- } else if (post_op_name[3 ] == ' \0 ' ) {
418
- if (post_op_name[2 ] == ' *' )
419
- op_kind = clang::OO_ArrowStar;
420
- break ;
421
- }
422
- break ;
423
-
424
- case ' *' :
425
- if (post_op_name[1 ] == ' \0 ' )
426
- op_kind = clang::OO_Star;
427
- else if (post_op_name[1 ] == ' =' && post_op_name[2 ] == ' \0 ' )
428
- op_kind = clang::OO_StarEqual;
429
- break ;
430
-
431
- case ' /' :
432
- if (post_op_name[1 ] == ' \0 ' )
433
- op_kind = clang::OO_Slash;
434
- else if (post_op_name[1 ] == ' =' && post_op_name[2 ] == ' \0 ' )
435
- op_kind = clang::OO_SlashEqual;
436
- break ;
437
-
438
- case ' %' :
439
- if (post_op_name[1 ] == ' \0 ' )
440
- op_kind = clang::OO_Percent;
441
- else if (post_op_name[1 ] == ' =' && post_op_name[2 ] == ' \0 ' )
442
- op_kind = clang::OO_PercentEqual;
443
- break ;
444
-
445
- case ' ^' :
446
- if (post_op_name[1 ] == ' \0 ' )
447
- op_kind = clang::OO_Caret;
448
- else if (post_op_name[1 ] == ' =' && post_op_name[2 ] == ' \0 ' )
449
- op_kind = clang::OO_CaretEqual;
450
- break ;
451
-
452
- case ' &' :
453
- if (post_op_name[1 ] == ' \0 ' )
454
- op_kind = clang::OO_Amp;
455
- else if (post_op_name[2 ] == ' \0 ' ) {
456
- switch (post_op_name[1 ]) {
457
- case ' =' :
458
- op_kind = clang::OO_AmpEqual;
459
- break ;
460
- case ' &' :
461
- op_kind = clang::OO_AmpAmp;
462
- break ;
463
- }
464
- }
465
- break ;
466
-
467
- case ' |' :
468
- if (post_op_name[1 ] == ' \0 ' )
469
- op_kind = clang::OO_Pipe;
470
- else if (post_op_name[2 ] == ' \0 ' ) {
471
- switch (post_op_name[1 ]) {
472
- case ' =' :
473
- op_kind = clang::OO_PipeEqual;
474
- break ;
475
- case ' |' :
476
- op_kind = clang::OO_PipePipe;
477
- break ;
478
- }
479
- }
480
- break ;
481
-
482
- case ' ~' :
483
- if (post_op_name[1 ] == ' \0 ' )
484
- op_kind = clang::OO_Tilde;
485
- break ;
486
-
487
- case ' !' :
488
- if (post_op_name[1 ] == ' \0 ' )
489
- op_kind = clang::OO_Exclaim;
490
- else if (post_op_name[1 ] == ' =' && post_op_name[2 ] == ' \0 ' )
491
- op_kind = clang::OO_ExclaimEqual;
492
- break ;
493
-
494
- case ' =' :
495
- if (post_op_name[1 ] == ' \0 ' )
496
- op_kind = clang::OO_Equal;
497
- else if (post_op_name[1 ] == ' =' && post_op_name[2 ] == ' \0 ' )
498
- op_kind = clang::OO_EqualEqual;
499
- break ;
500
-
501
- case ' <' :
502
- if (post_op_name[1 ] == ' \0 ' )
503
- op_kind = clang::OO_Less;
504
- else if (post_op_name[2 ] == ' \0 ' ) {
505
- switch (post_op_name[1 ]) {
506
- case ' <' :
507
- op_kind = clang::OO_LessLess;
508
- break ;
509
- case ' =' :
510
- op_kind = clang::OO_LessEqual;
511
- break ;
512
- }
513
- } else if (post_op_name[3 ] == ' \0 ' ) {
514
- if (post_op_name[2 ] == ' =' )
515
- op_kind = clang::OO_LessLessEqual;
516
- }
517
- break ;
518
-
519
- case ' >' :
520
- if (post_op_name[1 ] == ' \0 ' )
521
- op_kind = clang::OO_Greater;
522
- else if (post_op_name[2 ] == ' \0 ' ) {
523
- switch (post_op_name[1 ]) {
524
- case ' >' :
525
- op_kind = clang::OO_GreaterGreater;
526
- break ;
527
- case ' =' :
528
- op_kind = clang::OO_GreaterEqual;
529
- break ;
530
- }
531
- } else if (post_op_name[1 ] == ' >' && post_op_name[2 ] == ' =' &&
532
- post_op_name[3 ] == ' \0 ' ) {
533
- op_kind = clang::OO_GreaterGreaterEqual;
534
- }
535
- break ;
536
-
537
- case ' ,' :
538
- if (post_op_name[1 ] == ' \0 ' )
539
- op_kind = clang::OO_Comma;
540
- break ;
541
-
542
- case ' (' :
543
- if (post_op_name[1 ] == ' )' && post_op_name[2 ] == ' \0 ' )
544
- op_kind = clang::OO_Call;
545
- break ;
345
+ // Remember if there was a space after "operator". This is necessary to
346
+ // check for collisions with strangely named functions like "operatorint()".
347
+ bool space_after_operator = name.consume_front (" " );
348
+
349
+ op_kind = StringSwitch<clang::OverloadedOperatorKind>(name)
350
+ .Case (" +" , clang::OO_Plus)
351
+ .Case (" +=" , clang::OO_PlusEqual)
352
+ .Case (" ++" , clang::OO_PlusPlus)
353
+ .Case (" -" , clang::OO_Minus)
354
+ .Case (" -=" , clang::OO_MinusEqual)
355
+ .Case (" --" , clang::OO_MinusMinus)
356
+ .Case (" ->" , clang::OO_Arrow)
357
+ .Case (" ->*" , clang::OO_ArrowStar)
358
+ .Case (" *" , clang::OO_Star)
359
+ .Case (" *=" , clang::OO_StarEqual)
360
+ .Case (" /" , clang::OO_Slash)
361
+ .Case (" /=" , clang::OO_SlashEqual)
362
+ .Case (" %" , clang::OO_Percent)
363
+ .Case (" %=" , clang::OO_PercentEqual)
364
+ .Case (" ^" , clang::OO_Caret)
365
+ .Case (" ^=" , clang::OO_CaretEqual)
366
+ .Case (" &" , clang::OO_Amp)
367
+ .Case (" &=" , clang::OO_AmpEqual)
368
+ .Case (" &&" , clang::OO_AmpAmp)
369
+ .Case (" |" , clang::OO_Pipe)
370
+ .Case (" |=" , clang::OO_PipeEqual)
371
+ .Case (" ||" , clang::OO_PipePipe)
372
+ .Case (" ~" , clang::OO_Tilde)
373
+ .Case (" !" , clang::OO_Exclaim)
374
+ .Case (" !=" , clang::OO_ExclaimEqual)
375
+ .Case (" =" , clang::OO_Equal)
376
+ .Case (" ==" , clang::OO_EqualEqual)
377
+ .Case (" <" , clang::OO_Less)
378
+ .Case (" <<" , clang::OO_LessLess)
379
+ .Case (" <<=" , clang::OO_LessLessEqual)
380
+ .Case (" <=" , clang::OO_LessEqual)
381
+ .Case (" >" , clang::OO_Greater)
382
+ .Case (" >>" , clang::OO_GreaterGreater)
383
+ .Case (" >>=" , clang::OO_GreaterGreaterEqual)
384
+ .Case (" >=" , clang::OO_GreaterEqual)
385
+ .Case (" ()" , clang::OO_Call)
386
+ .Case (" []" , clang::OO_Subscript)
387
+ .Case (" ," , clang::OO_Comma)
388
+ .Default (clang::NUM_OVERLOADED_OPERATORS);
389
+
390
+ // We found a fitting operator, so we can exit now.
391
+ if (op_kind != clang::NUM_OVERLOADED_OPERATORS)
392
+ return true ;
546
393
547
- case ' [' :
548
- if (post_op_name[1 ] == ' ]' && post_op_name[2 ] == ' \0 ' )
549
- op_kind = clang::OO_Subscript;
550
- break ;
551
- }
394
+ // After the "operator " or "operator" part is something unknown. This means
395
+ // it's either one of the named operators (new/delete), a conversion operator
396
+ // (e.g. operator bool) or a function which name starts with "operator"
397
+ // (e.g. void operatorbool).
398
+
399
+ // If it's a function that starts with operator it can't have a space after
400
+ // "operator" because identifiers can't contain spaces.
401
+ // E.g. "operator int" (conversion operator)
402
+ // vs. "operatorint" (function with colliding name).
403
+ if (!space_after_operator)
404
+ return false ; // not an operator.
405
+
406
+ // Now the operator is either one of the named operators or a conversion
407
+ // operator.
408
+ op_kind = StringSwitch<clang::OverloadedOperatorKind>(name)
409
+ .Case (" new" , clang::OO_New)
410
+ .Case (" new[]" , clang::OO_Array_New)
411
+ .Case (" delete" , clang::OO_Delete)
412
+ .Case (" delete[]" , clang::OO_Array_Delete)
413
+ // conversion operators hit this case.
414
+ .Default (clang::NUM_OVERLOADED_OPERATORS);
552
415
553
416
return true ;
554
417
}
0 commit comments