diff --git a/src/lib/component/controller/UndoRedoController.cpp b/src/lib/component/controller/UndoRedoController.cpp index dc362ad6..2cf5caed 100644 --- a/src/lib/component/controller/UndoRedoController.cpp +++ b/src/lib/component/controller/UndoRedoController.cpp @@ -493,7 +493,13 @@ void UndoRedoController::replayCommand(std::list::iterator it) for (SearchMatch match : matches) { - match.tokenIds = m_storageAccess->getNodeIdsForNameHierarchies(match.tokenNames); + // TODO: replace duplicate main definition fix with better solution + if (match.nodeType.getType() != NodeType::NODE_FUNCTION || !match.tokenNames.size() || + match.tokenNames[0].getRawName() != L"main") + { + match.tokenIds = m_storageAccess->getNodeIdsForNameHierarchies(match.tokenNames); + } + if (!match.tokenIds.size()) { match.nodeType = NodeType::NODE_SYMBOL; diff --git a/src/lib/data/name/NameElement.cpp b/src/lib/data/name/NameElement.cpp index db8d4a5d..be9889af 100644 --- a/src/lib/data/name/NameElement.cpp +++ b/src/lib/data/name/NameElement.cpp @@ -38,7 +38,7 @@ std::wstring NameElement::Signature::qualifyName(const std::wstring& name) const bool NameElement::Signature::isValid() const { - return ((m_prefix + m_postfix).size() > 0); + return !m_prefix.empty() || !m_postfix.empty(); } const std::wstring& NameElement::Signature::getPrefix() const @@ -53,7 +53,7 @@ const std::wstring& NameElement::Signature::getPostfix() const std::wstring NameElement::Signature::getParameterString() const { - if (m_postfix.size()) + if (!m_postfix.empty()) { return utility::substrBeforeLast(m_postfix, L')') + L')'; } diff --git a/src/lib/data/name/NameHierarchy.cpp b/src/lib/data/name/NameHierarchy.cpp index 167ad435..9a2f84a5 100644 --- a/src/lib/data/name/NameHierarchy.cpp +++ b/src/lib/data/name/NameHierarchy.cpp @@ -89,6 +89,15 @@ NameHierarchy NameHierarchy::deserialize(const std::wstring& serializedName) nameHierarchy.push(NameElement(std::move(name), std::move(prefix), std::move(postfix))); } + // TODO: replace duplicate main definition fix with better solution + if (nameHierarchy.size() == 1 && nameHierarchy.back().hasSignature() && !nameHierarchy.back().getName().empty() && + nameHierarchy.back().getName()[0] == '.' && utility::isPrefix(L".:main:.", nameHierarchy.back().getName())) + { + NameElement::Signature sig = nameHierarchy.back().getSignature(); + nameHierarchy.pop(); + nameHierarchy.push(NameElement(L"main", sig.getPrefix(), sig.getPostfix())); + } + return nameHierarchy; } diff --git a/src/lib_cxx/data/parser/cxx/CanonicalFilePathCache.cpp b/src/lib_cxx/data/parser/cxx/CanonicalFilePathCache.cpp index 5d4d4b78..ffe5fe83 100644 --- a/src/lib_cxx/data/parser/cxx/CanonicalFilePathCache.cpp +++ b/src/lib_cxx/data/parser/cxx/CanonicalFilePathCache.cpp @@ -1,5 +1,7 @@ #include "CanonicalFilePathCache.h" +#include + #include "utilityString.h" #include "utilityClang.h" @@ -118,6 +120,19 @@ Id CanonicalFilePathCache::getFileSymbolId(const std::wstring& path) return 0; } +std::wstring CanonicalFilePathCache::getDeclarationFileName(const clang::Decl* declaration) +{ + const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager(); + const clang::FileID fileId = sourceManager.getFileID(declaration->getBeginLoc()); + const clang::FileEntry* fileEntry = sourceManager.getFileEntryForID(fileId); + if (fileEntry != nullptr && fileEntry->isValid()) + { + return getCanonicalFilePath(fileId, sourceManager).fileName(); + } + return getCanonicalFilePath( + utility::decodeFromUtf8(sourceManager.getPresumedLoc(declaration->getBeginLoc()).getFilename())).fileName(); +} + bool CanonicalFilePathCache::isProjectFile(const clang::FileID& fileId, const clang::SourceManager& sourceManager) { if (!fileId.isValid()) diff --git a/src/lib_cxx/data/parser/cxx/CanonicalFilePathCache.h b/src/lib_cxx/data/parser/cxx/CanonicalFilePathCache.h index 01a3b084..964233c8 100644 --- a/src/lib_cxx/data/parser/cxx/CanonicalFilePathCache.h +++ b/src/lib_cxx/data/parser/cxx/CanonicalFilePathCache.h @@ -5,6 +5,7 @@ #include #include +#include #include #include "FilePath.h" @@ -28,6 +29,8 @@ public: Id getFileSymbolId(const clang::FileEntry* entry); Id getFileSymbolId(const std::wstring& path); + std::wstring getDeclarationFileName(const clang::Decl* declaration); + bool isProjectFile(const clang::FileID& fileId, const clang::SourceManager& sourceManager); private: diff --git a/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.cpp b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.cpp index f84e2864..2e5d09b3 100644 --- a/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.cpp +++ b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.cpp @@ -11,6 +11,7 @@ #include "CxxAstVisitorComponentDeclRefKind.h" #include "CxxAstVisitorComponentTypeRefKind.h" #include "CxxDeclNameResolver.h" +#include "CxxFunctionDeclName.h" #include "CxxTypeNameResolver.h" #include "utilityClang.h" #include "ParserClient.h" @@ -835,6 +836,18 @@ Id CxxAstVisitorComponentIndexer::getOrCreateSymbolId(const clang::NamedDecl* de if (declName) { symbolName = declName->toNameHierarchy(); + + // TODO: replace duplicate main definition fix with better solution + if (dynamic_cast(declName.get()) && symbolName.size() == 1 && symbolName.back().getName() == L"main") + { + NameElement::Signature sig = symbolName.back().getSignature(); + symbolName.pop(); + symbolName.push(NameElement( + L".:main:." + getAstVisitor()->getCanonicalFilePathCache()->getDeclarationFileName(decl), + sig.getPrefix(), + sig.getPostfix() + )); + } } } diff --git a/src/lib_cxx/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp b/src/lib_cxx/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp index 2cb2ffec..5c034e9c 100644 --- a/src/lib_cxx/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp +++ b/src/lib_cxx/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp @@ -382,7 +382,7 @@ std::unique_ptr CxxDeclNameResolver::getDeclName(const clang::Named std::wstring scopeFileName; if (varDecl->getType().isConstQualified()) { - scopeFileName = getDeclarationFileName(declaration); + scopeFileName = getCanonicalFilePathCache()->getDeclarationFileName(declaration); } else { @@ -450,19 +450,6 @@ std::wstring CxxDeclNameResolver::getTranslationUnitMainFileName(const clang::De return getCanonicalFilePathCache()->getCanonicalFilePath(sourceManager.getMainFileID(), sourceManager).fileName(); } -std::wstring CxxDeclNameResolver::getDeclarationFileName(const clang::Decl* declaration) -{ - const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager(); - const clang::FileID fileId = sourceManager.getFileID(declaration->getBeginLoc()); - const clang::FileEntry* fileEntry = sourceManager.getFileEntryForID(fileId); - if (fileEntry != nullptr && fileEntry->isValid()) - { - return getCanonicalFilePathCache()->getCanonicalFilePath(fileId, sourceManager).fileName(); - } - return getCanonicalFilePathCache()->getCanonicalFilePath( - utility::decodeFromUtf8(sourceManager.getPresumedLoc(declaration->getBeginLoc()).getFilename())).fileName(); -} - std::wstring CxxDeclNameResolver::getNameForAnonymousSymbol(const std::wstring& symbolKindName, const clang::Decl* declaration) { const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager(); @@ -471,7 +458,7 @@ std::wstring CxxDeclNameResolver::getNameForAnonymousSymbol(const std::wstring& if (presumedBegin.isValid()) { return L"anonymous " + symbolKindName + - L" (" + getDeclarationFileName(declaration) + L'<' + std::to_wstring(presumedBegin.getLine()) + L':' + + L" (" + getCanonicalFilePathCache()->getDeclarationFileName(declaration) + L'<' + std::to_wstring(presumedBegin.getLine()) + L':' + std::to_wstring(presumedBegin.getColumn()) + L">)"; } return L"anonymous " + symbolKindName; diff --git a/src/lib_cxx/data/parser/cxx/name_resolver/CxxDeclNameResolver.h b/src/lib_cxx/data/parser/cxx/name_resolver/CxxDeclNameResolver.h index 514e55ab..40e6da1d 100644 --- a/src/lib_cxx/data/parser/cxx/name_resolver/CxxDeclNameResolver.h +++ b/src/lib_cxx/data/parser/cxx/name_resolver/CxxDeclNameResolver.h @@ -21,7 +21,6 @@ private: std::unique_ptr getContextName(const clang::DeclContext* declaration); std::unique_ptr getDeclName(const clang::NamedDecl* declaration); std::wstring getTranslationUnitMainFileName(const clang::Decl* declaration); - std::wstring getDeclarationFileName(const clang::Decl* declaration); std::wstring getNameForAnonymousSymbol(const std::wstring& symbolKindName, const clang::Decl* declaration); std::vector getTemplateParameterStrings(const clang::TemplateDecl* templateDecl); template