|
51 | 51 | #endif
|
52 | 52 |
|
53 | 53 | #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
|
54 |
| -#include "Plugins/Language/ObjC/ObjCLanguage.h" |
55 | 54 |
|
56 | 55 | #include "llvm/ADT/STLExtras.h"
|
57 | 56 | #include "llvm/Support/Compiler.h"
|
@@ -635,101 +634,81 @@ void Module::FindCompileUnits(const FileSpec &path,
|
635 | 634 |
|
636 | 635 | Module::LookupInfo::LookupInfo(ConstString name,
|
637 | 636 | FunctionNameType name_type_mask,
|
638 |
| - LanguageType language) |
639 |
| - : m_name(name), m_lookup_name(), m_language(language), |
| 637 | + LanguageType language_type) |
| 638 | + : m_name(name), m_lookup_name(name), m_language_type(language_type), |
640 | 639 | m_name_type_mask(eFunctionNameTypeNone),
|
641 | 640 | m_match_name_after_lookup(false) {
|
642 |
| - const char *name_cstr = name.GetCString(); |
643 | 641 | llvm::StringRef basename;
|
644 | 642 | llvm::StringRef context;
|
645 | 643 |
|
| 644 | + std::vector<Language *> languages; |
| 645 | + Language::ForEach([&languages](Language *l) { |
| 646 | + languages.push_back(l); |
| 647 | + return true; |
| 648 | + }); |
| 649 | + |
646 | 650 | if (name_type_mask & eFunctionNameTypeAuto) {
|
647 |
| - if (CPlusPlusLanguage::IsCPPMangledName(name_cstr)) |
648 |
| - m_name_type_mask = eFunctionNameTypeFull; |
649 |
| - else if ((language == eLanguageTypeUnknown || |
650 |
| - Language::LanguageIsObjC(language)) && |
651 |
| - ObjCLanguage::IsPossibleObjCMethodName(name_cstr)) |
652 |
| - m_name_type_mask = eFunctionNameTypeFull; |
653 |
| - else if (Language::LanguageIsC(language)) { |
654 |
| - m_name_type_mask = eFunctionNameTypeFull; |
| 651 | + if (language_type == eLanguageTypeUnknown) { |
| 652 | + for (Language *lang : languages) { |
| 653 | + Language::FunctionNameInfo info = lang->GetFunctionNameInfo(name); |
| 654 | + if (info.func_name_type != eFunctionNameTypeNone) { |
| 655 | + m_name_type_mask = info.func_name_type; |
| 656 | + basename = info.basename; |
| 657 | + context = info.context; |
| 658 | + break; |
| 659 | + } |
| 660 | + } |
655 | 661 | } else {
|
656 |
| - if ((language == eLanguageTypeUnknown || |
657 |
| - Language::LanguageIsObjC(language)) && |
658 |
| - ObjCLanguage::IsPossibleObjCSelector(name_cstr)) |
659 |
| - m_name_type_mask |= eFunctionNameTypeSelector; |
660 |
| - |
661 |
| - CPlusPlusLanguage::MethodName cpp_method(name); |
662 |
| - basename = cpp_method.GetBasename(); |
663 |
| - if (basename.empty()) { |
664 |
| - if (CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context, |
665 |
| - basename)) |
666 |
| - m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase); |
667 |
| - else |
668 |
| - m_name_type_mask |= eFunctionNameTypeFull; |
669 |
| - } else { |
670 |
| - m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase); |
| 662 | + if (auto *lang = Language::FindPlugin(language_type)) { |
| 663 | + Language::FunctionNameInfo info = lang->GetFunctionNameInfo(name); |
| 664 | + m_name_type_mask = info.func_name_type; |
| 665 | + basename = info.basename; |
| 666 | + context = info.context; |
671 | 667 | }
|
672 | 668 | }
|
| 669 | + |
| 670 | + // NOTE: There are several ways to get here, but this is a fallback path in |
| 671 | + // case the above does not succeed at extracting any useful information from |
| 672 | + // the loaded language plugins. |
| 673 | + if (m_name_type_mask == eFunctionNameTypeNone) |
| 674 | + m_name_type_mask = eFunctionNameTypeFull; |
| 675 | + |
673 | 676 | } else {
|
674 | 677 | m_name_type_mask = name_type_mask;
|
675 |
| - if (name_type_mask & eFunctionNameTypeMethod || |
676 |
| - name_type_mask & eFunctionNameTypeBase) { |
677 |
| - // If they've asked for a CPP method or function name and it can't be |
678 |
| - // that, we don't even need to search for CPP methods or names. |
679 |
| - CPlusPlusLanguage::MethodName cpp_method(name); |
680 |
| - if (cpp_method.IsValid()) { |
681 |
| - basename = cpp_method.GetBasename(); |
682 |
| - |
683 |
| - if (!cpp_method.GetQualifiers().empty()) { |
684 |
| - // There is a "const" or other qualifier following the end of the |
685 |
| - // function parens, this can't be a eFunctionNameTypeBase |
686 |
| - m_name_type_mask &= ~(eFunctionNameTypeBase); |
687 |
| - if (m_name_type_mask == eFunctionNameTypeNone) |
688 |
| - return; |
| 678 | + if (language_type != eLanguageTypeUnknown) { |
| 679 | + if (auto *lang = Language::FindPlugin(language_type)) { |
| 680 | + Language::FunctionNameInfo info = lang->GetFunctionNameInfo(name); |
| 681 | + if (info.func_name_type & m_name_type_mask) { |
| 682 | + // If the user asked for FunctionNameTypes that aren't possible, |
| 683 | + // then filter those out. (e.g. asking for Selectors on |
| 684 | + // C++ symbols, or even if the symbol given can't be a selector in |
| 685 | + // ObjC) |
| 686 | + m_name_type_mask &= info.func_name_type; |
| 687 | + basename = info.basename; |
| 688 | + context = info.context; |
689 | 689 | }
|
690 |
| - } else { |
691 |
| - // If the CPP method parser didn't manage to chop this up, try to fill |
692 |
| - // in the base name if we can. If a::b::c is passed in, we need to just |
693 |
| - // look up "c", and then we'll filter the result later. |
694 |
| - CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context, |
695 |
| - basename); |
696 |
| - } |
697 |
| - } |
698 |
| - |
699 |
| - if (name_type_mask & eFunctionNameTypeSelector) { |
700 |
| - if (!ObjCLanguage::IsPossibleObjCSelector(name_cstr)) { |
701 |
| - m_name_type_mask &= ~(eFunctionNameTypeSelector); |
702 |
| - if (m_name_type_mask == eFunctionNameTypeNone) |
703 |
| - return; |
704 | 690 | }
|
705 |
| - } |
706 |
| - |
707 |
| - // Still try and get a basename in case someone specifies a name type mask |
708 |
| - // of eFunctionNameTypeFull and a name like "A::func" |
709 |
| - if (basename.empty()) { |
710 |
| - if (name_type_mask & eFunctionNameTypeFull && |
711 |
| - !CPlusPlusLanguage::IsCPPMangledName(name_cstr)) { |
712 |
| - CPlusPlusLanguage::MethodName cpp_method(name); |
713 |
| - basename = cpp_method.GetBasename(); |
714 |
| - if (basename.empty()) |
715 |
| - CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context, |
716 |
| - basename); |
| 691 | + } else { |
| 692 | + for (Language *lang : languages) { |
| 693 | + Language::FunctionNameInfo info = lang->GetFunctionNameInfo(name); |
| 694 | + if (info.func_name_type & m_name_type_mask) { |
| 695 | + m_name_type_mask &= info.func_name_type; |
| 696 | + basename = info.basename; |
| 697 | + context = info.context; |
| 698 | + break; |
| 699 | + } |
717 | 700 | }
|
718 | 701 | }
|
719 | 702 | }
|
720 | 703 |
|
721 | 704 | if (!basename.empty()) {
|
722 |
| - // The name supplied was a partial C++ path like "a::count". In this case |
723 |
| - // we want to do a lookup on the basename "count" and then make sure any |
724 |
| - // matching results contain "a::count" so that it would match "b::a::count" |
725 |
| - // and "a::count". This is why we set "match_name_after_lookup" to true |
| 705 | + // The name supplied was incomplete for lookup purposes. For example, in C++ |
| 706 | + // we may have gotten something like "a::count". In this case, we want to do |
| 707 | + // a lookup on the basename "count" and then make sure any matching results |
| 708 | + // contain "a::count" so that it would match "b::a::count" and "a::count". |
| 709 | + // This is why we set match_name_after_lookup to true. |
726 | 710 | m_lookup_name.SetString(basename);
|
727 | 711 | m_match_name_after_lookup = true;
|
728 |
| - } else { |
729 |
| - // The name is already correct, just use the exact name as supplied, and we |
730 |
| - // won't need to check if any matches contain "name" |
731 |
| - m_lookup_name = name; |
732 |
| - m_match_name_after_lookup = false; |
733 | 712 | }
|
734 | 713 | }
|
735 | 714 |
|
|
0 commit comments