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:
@@ -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;
|
||||
|
||||
@@ -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')';
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user