data: Added intermediate fix to handle multiple definitions of main() in C/C++ (issue #233)

* record main definition as .:main:.<filename>
* restore original name in name deserialization
* don't look up id when undoing main activation
This commit is contained in:
Eberhard Graether
2019-04-30 13:04:57 +02:00
parent ee1fd9c38b
commit af70d684a5
8 changed files with 51 additions and 19 deletions
@@ -493,7 +493,13 @@ void UndoRedoController::replayCommand(std::list<Command>::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;
+2 -2
View File
@@ -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')';
}
+9
View File
@@ -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<std::wstring>(L".:main:.", nameHierarchy.back().getName()))
{
NameElement::Signature sig = nameHierarchy.back().getSignature();
nameHierarchy.pop();
nameHierarchy.push(NameElement(L"main", sig.getPrefix(), sig.getPostfix()));
}
return nameHierarchy;
}
@@ -1,5 +1,7 @@
#include "CanonicalFilePathCache.h"
#include <clang/AST/ASTContext.h>
#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())
@@ -5,6 +5,7 @@
#include <string>
#include <unordered_map>
#include <clang/AST/Decl.h>
#include <clang/Basic/SourceManager.h>
#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:
@@ -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<CxxFunctionDeclName*>(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()
));
}
}
}
@@ -382,7 +382,7 @@ std::unique_ptr<CxxDeclName> 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;
@@ -21,7 +21,6 @@ private:
std::unique_ptr<CxxName> getContextName(const clang::DeclContext* declaration);
std::unique_ptr<CxxDeclName> 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<std::wstring> getTemplateParameterStrings(const clang::TemplateDecl* templateDecl);
template <typename T>