@@ -392,138 +392,8 @@ void macho::reportPendingDuplicateSymbols() {
392
392
}
393
393
}
394
394
395
- // Check whether the definition name def is a mangled function name that matches
396
- // the reference name ref.
397
- static bool canSuggestExternCForCXX (StringRef ref, StringRef def) {
398
- llvm::ItaniumPartialDemangler d;
399
- std::string name = def.str ();
400
- if (d.partialDemangle (name.c_str ()))
401
- return false ;
402
- char *buf = d.getFunctionName (nullptr , nullptr );
403
- if (!buf)
404
- return false ;
405
- bool ret = ref == buf;
406
- free (buf);
407
- return ret;
408
- }
409
-
410
- // Suggest an alternative spelling of an "undefined symbol" diagnostic. Returns
411
- // the suggested symbol, which is either in the symbol table, or in the same
412
- // file of sym.
413
- static const Symbol *getAlternativeSpelling (const Undefined &sym,
414
- std::string &pre_hint,
415
- std::string &post_hint) {
416
- DenseMap<StringRef, const Symbol *> map;
417
- if (sym.getFile () && sym.getFile ()->kind () == InputFile::ObjKind) {
418
- // Build a map of local defined symbols.
419
- for (const Symbol *s : sym.getFile ()->symbols )
420
- if (auto *defined = dyn_cast<Defined>(s))
421
- if (!defined->isExternal ())
422
- map.try_emplace (s->getName (), s);
423
- }
424
-
425
- auto suggest = [&](StringRef newName) -> const Symbol * {
426
- // If defined locally.
427
- if (const Symbol *s = map.lookup (newName))
428
- return s;
429
-
430
- // If in the symbol table and not undefined.
431
- if (const Symbol *s = symtab->find (newName))
432
- if (dyn_cast<Undefined>(s) == nullptr )
433
- return s;
434
-
435
- return nullptr ;
436
- };
437
-
438
- // This loop enumerates all strings of Levenshtein distance 1 as typo
439
- // correction candidates and suggests the one that exists as a non-undefined
440
- // symbol.
441
- StringRef name = sym.getName ();
442
- for (size_t i = 0 , e = name.size (); i != e + 1 ; ++i) {
443
- // Insert a character before name[i].
444
- std::string newName = (name.substr (0 , i) + " 0" + name.substr (i)).str ();
445
- for (char c = ' 0' ; c <= ' z' ; ++c) {
446
- newName[i] = c;
447
- if (const Symbol *s = suggest (newName))
448
- return s;
449
- }
450
- if (i == e)
451
- break ;
452
-
453
- // Substitute name[i].
454
- newName = std::string (name);
455
- for (char c = ' 0' ; c <= ' z' ; ++c) {
456
- newName[i] = c;
457
- if (const Symbol *s = suggest (newName))
458
- return s;
459
- }
460
-
461
- // Transpose name[i] and name[i+1]. This is of edit distance 2 but it is
462
- // common.
463
- if (i + 1 < e) {
464
- newName[i] = name[i + 1 ];
465
- newName[i + 1 ] = name[i];
466
- if (const Symbol *s = suggest (newName))
467
- return s;
468
- }
469
-
470
- // Delete name[i].
471
- newName = (name.substr (0 , i) + name.substr (i + 1 )).str ();
472
- if (const Symbol *s = suggest (newName))
473
- return s;
474
- }
475
-
476
- // Case mismatch, e.g. Foo vs FOO.
477
- for (auto &it : map)
478
- if (name.equals_insensitive (it.first ))
479
- return it.second ;
480
- for (Symbol *sym : symtab->getSymbols ())
481
- if (dyn_cast<Undefined>(sym) == nullptr &&
482
- name.equals_insensitive (sym->getName ()))
483
- return sym;
484
-
485
- // The reference may be a mangled name while the definition is not. Suggest a
486
- // missing extern "C".
487
- if (name.startswith (" __Z" )) {
488
- std::string buf = name.str ();
489
- llvm::ItaniumPartialDemangler d;
490
- if (!d.partialDemangle (buf.c_str ()))
491
- if (char *buf = d.getFunctionName (nullptr , nullptr )) {
492
- const Symbol *s = suggest ((Twine (" _" ) + buf).str ());
493
- free (buf);
494
- if (s) {
495
- pre_hint = " : extern \" C\" " ;
496
- return s;
497
- }
498
- }
499
- } else {
500
- StringRef name_without_underscore = name;
501
- name_without_underscore.consume_front (" _" );
502
- const Symbol *s = nullptr ;
503
- for (auto &it : map)
504
- if (canSuggestExternCForCXX (name_without_underscore, it.first )) {
505
- s = it.second ;
506
- break ;
507
- }
508
- if (!s)
509
- for (Symbol *sym : symtab->getSymbols ())
510
- if (canSuggestExternCForCXX (name_without_underscore, sym->getName ())) {
511
- s = sym;
512
- break ;
513
- }
514
- if (s) {
515
- pre_hint = " to declare " ;
516
- post_hint = " as extern \" C\" ?" ;
517
- return s;
518
- }
519
- }
520
-
521
- return nullptr ;
522
- }
523
-
524
395
static void reportUndefinedSymbol (const Undefined &sym,
525
- const UndefinedDiag &locations,
526
- bool correctSpelling) {
396
+ const UndefinedDiag &locations) {
527
397
std::string message = " undefined symbol" ;
528
398
if (config->archMultiple )
529
399
message += (" for arch " + getArchitectureName (config->arch ())).str ();
@@ -556,17 +426,6 @@ static void reportUndefinedSymbol(const Undefined &sym,
556
426
(" \n >>> referenced " + Twine (totalReferences - i) + " more times" )
557
427
.str ();
558
428
559
- if (correctSpelling) {
560
- std::string pre_hint = " : " , post_hint;
561
- if (const Symbol *corrected =
562
- getAlternativeSpelling (sym, pre_hint, post_hint)) {
563
- message +=
564
- " \n >>> did you mean" + pre_hint + toString (*corrected) + post_hint;
565
- if (corrected->getFile ())
566
- message += " \n >>> defined in: " + toString (corrected->getFile ());
567
- }
568
- }
569
-
570
429
if (config->undefinedSymbolTreatment == UndefinedSymbolTreatment::error)
571
430
error (message);
572
431
else if (config->undefinedSymbolTreatment ==
@@ -577,9 +436,8 @@ static void reportUndefinedSymbol(const Undefined &sym,
577
436
}
578
437
579
438
void macho::reportPendingUndefinedSymbols () {
580
- // Enable spell corrector for the first 2 diagnostics.
581
- for (const auto &[i, undef] : llvm::enumerate (undefs))
582
- reportUndefinedSymbol (*undef.first , undef.second , i < 2 );
439
+ for (const auto &undef : undefs)
440
+ reportUndefinedSymbol (*undef.first , undef.second );
583
441
584
442
// This function is called multiple times during execution. Clear the printed
585
443
// diagnostics to avoid printing the same things again the next time.
0 commit comments