summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libs/clangbackendipc/clangbackendipc-lib.pri1
-rw-r--r--src/libs/clangbackendipc/filepath.h66
-rw-r--r--src/libs/clangbackendipc/sourcefilepathcontainerbase.h9
-rw-r--r--src/libs/clangbackendipc/sourcelocationcontainerv2.cpp4
-rw-r--r--src/libs/clangbackendipc/sourcerangewithtextcontainer.h2
-rw-r--r--src/libs/clangbackendipc/stringcache.h (renamed from src/tools/clangpchmanagerbackend/source/stringcache.h)25
-rw-r--r--src/libs/utils/smallstringio.h4
-rw-r--r--src/libs/utils/smallstringview.h5
-rw-r--r--src/plugins/clangrefactoring/refactoringclient.cpp15
-rw-r--r--src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri1
-rw-r--r--src/tools/clangrefactoringbackend/source/clangquery.cpp23
-rw-r--r--src/tools/clangrefactoringbackend/source/clangquery.h5
-rw-r--r--src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp13
-rw-r--r--src/tools/clangrefactoringbackend/source/clangquerygatherer.h10
-rw-r--r--src/tools/clangrefactoringbackend/source/clangtool.cpp16
-rw-r--r--src/tools/clangrefactoringbackend/source/clangtool.h4
-rw-r--r--src/tools/clangrefactoringbackend/source/refactoringserver.cpp3
-rw-r--r--src/tools/clangrefactoringbackend/source/refactoringserver.h6
-rw-r--r--src/tools/clangrefactoringbackend/source/sourcelocationsutils.h12
-rw-r--r--src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp41
-rw-r--r--src/tools/clangrefactoringbackend/source/sourcerangeextractor.h17
-rw-r--r--tests/unit/unittest/clangquery-test.cpp12
-rw-r--r--tests/unit/unittest/clangquerygatherer-test.cpp12
-rw-r--r--tests/unit/unittest/filepath-test.cpp56
-rw-r--r--tests/unit/unittest/pchcreator-test.cpp2
-rw-r--r--tests/unit/unittest/sourcerangeextractor-test.cpp20
-rw-r--r--tests/unit/unittest/unittest.pro2
27 files changed, 229 insertions, 157 deletions
diff --git a/src/libs/clangbackendipc/clangbackendipc-lib.pri b/src/libs/clangbackendipc/clangbackendipc-lib.pri
index 36afd9ae70..9664775dd1 100644
--- a/src/libs/clangbackendipc/clangbackendipc-lib.pri
+++ b/src/libs/clangbackendipc/clangbackendipc-lib.pri
@@ -155,6 +155,7 @@ HEADERS += \
$$PWD/pchmanagerclientproxy.h \
$$PWD/projectpartpch.h \
$$PWD/precompiledheadersupdatedmessage.h \
+ $$PWD/stringcache.h \
$$PWD/removepchprojectpartsmessage.h \
$$PWD/clangcodemodelclientmessages.h \
$$PWD/clangcodemodelservermessages.h \
diff --git a/src/libs/clangbackendipc/filepath.h b/src/libs/clangbackendipc/filepath.h
index d435441a13..717d020790 100644
--- a/src/libs/clangbackendipc/filepath.h
+++ b/src/libs/clangbackendipc/filepath.h
@@ -37,66 +37,62 @@ class FilePath
{
public:
FilePath() = default;
- explicit FilePath(Utils::SmallString &&filePath)
+ explicit FilePath(Utils::PathString &&filePath)
+ : m_path(std::move(filePath))
{
- auto foundReverse = std::find(filePath.rbegin(), filePath.rend(), '/');
+ auto foundReverse = std::find(m_path.rbegin(), m_path.rend(), '/');
auto found = foundReverse.base();
+ --found;
- Utils::SmallString fileName(found, filePath.end());
- if (foundReverse != filePath.rend())
- filePath.resize(std::size_t(std::distance(filePath.begin(), --found)));
-
- directory_ = std::move(filePath);
- name_ = std::move(fileName);
+ m_slashIndex = std::size_t(std::distance(m_path.begin(), found));
}
- explicit FilePath(const QString &filePath)
- : FilePath(Utils::SmallString(filePath))
+ explicit FilePath(const Utils::PathString &filePath)
+ : FilePath(filePath.clone())
{
}
- FilePath(Utils::SmallString &&directory, Utils::SmallString &&name)
- : directory_(std::move(directory)),
- name_(std::move(name))
- {}
-
- const Utils::SmallString &directory() const
+ explicit FilePath(Utils::PathString &&filePath, std::size_t slashIndex)
+ : m_path(std::move(filePath)),
+ m_slashIndex(slashIndex)
{
- return directory_;
}
- Utils::SmallString takeDirectory()
+ explicit FilePath(const QString &filePath)
+ : FilePath(Utils::PathString(filePath))
{
- return std::move(directory_);
}
- const Utils::SmallString &name() const
+ FilePath(const Utils::PathString &directory, const Utils::PathString &name)
+ : m_path({std::move(directory), "/", std::move(name)}),
+ m_slashIndex(directory.size())
+ {}
+
+ Utils::SmallStringView directory() const
{
- return name_;
+ return m_path.mid(0, m_slashIndex);
}
- Utils::SmallString takeName()
+ Utils::SmallStringView name() const
{
- return std::move(name_);
+ return m_path.mid(m_slashIndex + 1, m_path.size() - m_slashIndex - 1);
}
- Utils::PathString path() const
+ const Utils::PathString &path() const
{
- return {directory_, "/", name_};
+ return m_path;
}
friend QDataStream &operator<<(QDataStream &out, const FilePath &filePath)
{
- out << filePath.directory_;
- out << filePath.name_;
+ out << filePath.m_path;
return out;
}
friend QDataStream &operator>>(QDataStream &in, FilePath &filePath)
{
- in >> filePath.directory_;
- in >> filePath.name_;
+ in >> filePath.m_path;
return in;
}
@@ -110,24 +106,22 @@ public:
friend bool operator==(const FilePath &first, const FilePath &second)
{
- return first.name_ == second.name_
- && first.directory_ == second.directory_;
+ return first.m_path == second.m_path;
}
friend bool operator<(const FilePath &first, const FilePath &second)
{
- return std::tie(first.name_, first.directory_)
- < std::tie(second.name_, second.directory_);
+ return first.m_path < second.m_path;
}
FilePath clone() const
{
- return FilePath(directory_.clone(), name_.clone());
+ return FilePath(m_path.clone(), m_slashIndex);
}
private:
- Utils::SmallString directory_;
- Utils::SmallString name_;
+ Utils::PathString m_path = "/";
+ std::size_t m_slashIndex = 0;
};
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const FilePath &filePath);
diff --git a/src/libs/clangbackendipc/sourcefilepathcontainerbase.h b/src/libs/clangbackendipc/sourcefilepathcontainerbase.h
index af5f8b570c..ec5b78e9a7 100644
--- a/src/libs/clangbackendipc/sourcefilepathcontainerbase.h
+++ b/src/libs/clangbackendipc/sourcefilepathcontainerbase.h
@@ -42,13 +42,10 @@ public:
{
}
- void insertFilePath(uint fileId, Utils::SmallString &&fileDirectory, Utils::SmallString &&fileName)
+ void insertFilePath(uint fileId, Utils::PathString &&filePath)
{
- if (m_filePathHash.find(fileId) == m_filePathHash.end()) {
- m_filePathHash.emplace(std::piecewise_construct,
- std::forward_as_tuple(fileId),
- std::forward_as_tuple(std::move(fileDirectory), std::move(fileName)));
- }
+ if (m_filePathHash.find(fileId) == m_filePathHash.end())
+ m_filePathHash.emplace(fileId, std::move(filePath));
}
void reserve(std::size_t size)
diff --git a/src/libs/clangbackendipc/sourcelocationcontainerv2.cpp b/src/libs/clangbackendipc/sourcelocationcontainerv2.cpp
index b65803e7c6..3206daf2b5 100644
--- a/src/libs/clangbackendipc/sourcelocationcontainerv2.cpp
+++ b/src/libs/clangbackendipc/sourcelocationcontainerv2.cpp
@@ -46,10 +46,10 @@ QDebug operator<<(QDebug debug, const SourceLocationContainer &container)
std::ostream &operator<<(std::ostream &os, const SourceLocationContainer &container)
{
os << "("
+ << container.fileHash() << ", "
<< container.line() << ", "
<< container.column() << ", "
- << container.offset() << ", "
- << container.fileHash()
+ << container.offset()
<< ")";
return os;
diff --git a/src/libs/clangbackendipc/sourcerangewithtextcontainer.h b/src/libs/clangbackendipc/sourcerangewithtextcontainer.h
index 12b25084c3..82d17f884a 100644
--- a/src/libs/clangbackendipc/sourcerangewithtextcontainer.h
+++ b/src/libs/clangbackendipc/sourcerangewithtextcontainer.h
@@ -110,6 +110,8 @@ private:
Utils::SmallString m_text;
};
+using SourceRangeWithTextContainers = std::vector<SourceRangeWithTextContainer>;
+
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const SourceRangeWithTextContainer &container);
std::ostream &operator<<(std::ostream &os, const SourceRangeWithTextContainer &container);
} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/stringcache.h b/src/libs/clangbackendipc/stringcache.h
index a85c314700..7b4230b577 100644
--- a/src/tools/clangpchmanagerbackend/source/stringcache.h
+++ b/src/libs/clangbackendipc/stringcache.h
@@ -25,16 +25,26 @@
#pragma once
-#include "clangpchmanagerbackend_global.h"
-
#include <utils/smallstringview.h>
#include <algorithm>
+#include <mutex>
#include <vector>
namespace ClangBackEnd {
-template <typename StringType>
+class NonLockingMutex
+{
+public:
+ constexpr NonLockingMutex() noexcept {}
+ NonLockingMutex(const NonLockingMutex&) = delete;
+ NonLockingMutex& operator=(const NonLockingMutex&) = delete;
+ void lock() {}
+ void unlock() {}
+};
+
+template <typename StringType,
+ typename Mutex = NonLockingMutex>
class StringCache
{
class StringCacheEntry
@@ -79,6 +89,8 @@ public:
uint stringId(Utils::SmallStringView stringView)
{
+ std::lock_guard<Mutex> lock(m_mutex);
+
Found found = find(stringView);
if (!found.wasFound)
@@ -89,6 +101,8 @@ public:
std::vector<uint> stringIds(const std::vector<StringType> &strings)
{
+ std::lock_guard<Mutex> lock(m_mutex);
+
std::vector<uint> ids;
ids.reserve(strings.size());
@@ -102,11 +116,15 @@ public:
const StringType &string(uint id) const
{
+ std::lock_guard<Mutex> lock(m_mutex);
+
return m_strings.at(m_indices.at(id)).string;
}
std::vector<StringType> strings(const std::vector<uint> &ids) const
{
+ std::lock_guard<Mutex> lock(m_mutex);
+
std::vector<StringType> strings;
strings.reserve(ids.size());
@@ -155,6 +173,7 @@ private:
private:
StringCacheEntries m_strings;
std::vector<uint> m_indices;
+ mutable Mutex m_mutex;
};
} // namespace ClangBackEnd
diff --git a/src/libs/utils/smallstringio.h b/src/libs/utils/smallstringio.h
index 26424b22fe..8dabbcc4d0 100644
--- a/src/libs/utils/smallstringio.h
+++ b/src/libs/utils/smallstringio.h
@@ -68,8 +68,8 @@ QDataStream &operator>>(QDataStream &in, BasicSmallString<Size> &string)
return in;
}
-inline
-QDebug &operator<<(QDebug &debug, const SmallString &string)
+template <typename String>
+QDebug &operator<<(QDebug &debug, const String &string)
{
using QT_PREPEND_NAMESPACE(operator<<);
diff --git a/src/libs/utils/smallstringview.h b/src/libs/utils/smallstringview.h
index 2d445501c2..3e11497ed3 100644
--- a/src/libs/utils/smallstringview.h
+++ b/src/libs/utils/smallstringview.h
@@ -104,6 +104,11 @@ public:
return const_reverse_iterator(begin() - static_cast<std::size_t>(1));
}
+ operator std::string() const
+ {
+ return std::string(data(), size());
+ }
+
private:
const char *m_pointer;
size_type m_size;
diff --git a/src/plugins/clangrefactoring/refactoringclient.cpp b/src/plugins/clangrefactoring/refactoringclient.cpp
index 83b058d626..4cb954e231 100644
--- a/src/plugins/clangrefactoring/refactoringclient.cpp
+++ b/src/plugins/clangrefactoring/refactoringclient.cpp
@@ -104,19 +104,6 @@ void RefactoringClient::setRefactoringConnectionClient(
this->connectionClient = connectionClient;
}
-namespace {
-
-Utils::SmallString concatenateFilePath(const ClangBackEnd::FilePath &filePath)
-{
- Utils::SmallString concatenatedFilePath = filePath.directory().clone();
- concatenatedFilePath.append("/");
- concatenatedFilePath.append(filePath.name().clone());
-
- return concatenatedFilePath;
-}
-
-}
-
std::unordered_map<uint, QString> RefactoringClient::convertFilePaths(
const ClangBackEnd::FilePathDict &filePaths)
{
@@ -126,7 +113,7 @@ std::unordered_map<uint, QString> RefactoringClient::convertFilePaths(
auto convertFilePath = [] (const ClangBackEnd::FilePathDict::value_type &dictonaryEntry) {
return std::make_pair(dictonaryEntry.first,
- concatenateFilePath(dictonaryEntry.second).toQString());
+ dictonaryEntry.second.path().toQString());
};
std::transform(filePaths.begin(),
diff --git a/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri b/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri
index 2bb0d0ab7b..926280a5fa 100644
--- a/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri
+++ b/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri
@@ -19,7 +19,6 @@ HEADERS += \
$$PWD/environment.h \
$$PWD/clangpathwatcher.h \
$$PWD/projectparts.h \
- $$PWD/stringcache.h \
$$PWD/idpaths.h \
$$PWD/pchcreatorinterface.h \
$$PWD/clangpathwatcherinterface.h \
diff --git a/src/tools/clangrefactoringbackend/source/clangquery.cpp b/src/tools/clangrefactoringbackend/source/clangquery.cpp
index d24b981f45..be93b61a1a 100644
--- a/src/tools/clangrefactoringbackend/source/clangquery.cpp
+++ b/src/tools/clangrefactoringbackend/source/clangquery.cpp
@@ -30,27 +30,15 @@
#include <sourcerangescontainer.h>
-#include <QTime>
+#include <stringcache.h>
-#if defined(__GNUC__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wunused-parameter"
-#elif defined(_MSC_VER)
-# pragma warning(push)
-# pragma warning( disable : 4100 )
-#endif
+#include <QTime>
#include <clang/ASTMatchers/ASTMatchers.h>
#include <clang/ASTMatchers/ASTMatchFinder.h>
#include <clang/ASTMatchers/Dynamic/Diagnostics.h>
#include <clang/ASTMatchers/Dynamic/Parser.h>
-#if defined(__GNUC__)
-# pragma GCC diagnostic pop
-#elif defined(_MSC_VER)
-# pragma warning(pop)
-#endif
-
using clang::ast_matchers::dynamic::Diagnostics;
using clang::ast_matchers::dynamic::Parser;
using clang::ast_matchers::BoundNodes;
@@ -66,8 +54,10 @@ struct CollectBoundNodes : MatchFinder::MatchCallback {
}
};
-ClangQuery::ClangQuery(Utils::SmallString &&query)
- : query(std::move(query))
+ClangQuery::ClangQuery(StringCache<Utils::PathString, std::mutex> &filePathCache,
+ Utils::SmallString &&query)
+ : query(std::move(query)),
+ filePathCache(filePathCache)
{
}
@@ -226,6 +216,7 @@ void ClangQuery::matchLocation(
SourceRangeExtractor extractor(ast->getSourceManager(),
ast->getLangOpts(),
+ filePathCache,
sourceRangesContainer);
extractor.addSourceRanges(sourceRanges);
diff --git a/src/tools/clangrefactoringbackend/source/clangquery.h b/src/tools/clangrefactoringbackend/source/clangquery.h
index 93190449a5..20b38a7ab1 100644
--- a/src/tools/clangrefactoringbackend/source/clangquery.h
+++ b/src/tools/clangrefactoringbackend/source/clangquery.h
@@ -30,6 +30,8 @@
#include <sourcerangescontainer.h>
#include <dynamicastmatcherdiagnosticcontainer.h>
+#include <stringcache.h>
+
namespace clang {
namespace ast_matchers {
namespace dynamic {
@@ -49,7 +51,7 @@ namespace ClangBackEnd {
class ClangQuery : public ClangTool
{
public:
- ClangQuery(Utils::SmallString &&query={});
+ ClangQuery(StringCache<Utils::PathString, std::mutex> &filePathCache, Utils::SmallString &&query={});
void setQuery(Utils::SmallString &&query);
@@ -67,6 +69,7 @@ private:
SourceRangesContainer sourceRangesContainer;
Utils::SmallString query;
std::vector<DynamicASTMatcherDiagnosticContainer> diagnosticContainers_;
+ StringCache<Utils::PathString, std::mutex> &filePathCache;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp b/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp
index cbf9a9c70c..09c96a69b5 100644
--- a/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp
+++ b/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp
@@ -29,10 +29,12 @@
namespace ClangBackEnd {
-ClangQueryGatherer::ClangQueryGatherer(std::vector<V2::FileContainer> &&sources,
+ClangQueryGatherer::ClangQueryGatherer(StringCache<Utils::PathString, std::mutex> *filePathCache,
+ std::vector<V2::FileContainer> &&sources,
std::vector<V2::FileContainer> &&unsaved,
Utils::SmallString &&query)
- : m_sources(std::move(sources)),
+ : m_filePathCache(filePathCache),
+ m_sources(std::move(sources)),
m_unsaved(std::move(unsaved)),
m_query(std::move(query))
{
@@ -40,11 +42,12 @@ ClangQueryGatherer::ClangQueryGatherer(std::vector<V2::FileContainer> &&sources,
SourceRangesAndDiagnosticsForQueryMessage
ClangQueryGatherer::createSourceRangesAndDiagnosticsForSource(
+ StringCache<Utils::PathString, std::mutex> *filePathCache,
V2::FileContainer &&source,
const std::vector<V2::FileContainer> &unsaved,
Utils::SmallString &&query)
{
- ClangQuery clangQuery(std::move(query));
+ ClangQuery clangQuery(*filePathCache, std::move(query));
clangQuery.addFile(source.filePath().directory(),
source.filePath().name(),
@@ -65,7 +68,8 @@ bool ClangQueryGatherer::canCreateSourceRangesAndDiagnostics() const
SourceRangesAndDiagnosticsForQueryMessage ClangQueryGatherer::createNextSourceRangesAndDiagnostics()
{
- auto message = createSourceRangesAndDiagnosticsForSource(std::move(m_sources.back()),
+ auto message = createSourceRangesAndDiagnosticsForSource(m_filePathCache,
+ std::move(m_sources.back()),
m_unsaved,
m_query.clone());
m_sources.pop_back();
@@ -77,6 +81,7 @@ ClangQueryGatherer::Future ClangQueryGatherer::startCreateNextSourceRangesAndDia
{
Future future = std::async(std::launch::async,
createSourceRangesAndDiagnosticsForSource,
+ m_filePathCache,
std::move(m_sources.back()),
m_unsaved,
m_query.clone());
diff --git a/src/tools/clangrefactoringbackend/source/clangquerygatherer.h b/src/tools/clangrefactoringbackend/source/clangquerygatherer.h
index a7ba8fac79..b937056379 100644
--- a/src/tools/clangrefactoringbackend/source/clangquerygatherer.h
+++ b/src/tools/clangrefactoringbackend/source/clangquerygatherer.h
@@ -27,6 +27,7 @@
#include <sourcerangesanddiagnosticsforquerymessage.h>
#include <filecontainerv2.h>
+#include <stringcache.h>
#include <future>
@@ -38,16 +39,16 @@ public:
using Future = std::future<SourceRangesAndDiagnosticsForQueryMessage>;
ClangQueryGatherer() = default;
- ClangQueryGatherer(std::vector<V2::FileContainer> &&sources,
+ ClangQueryGatherer(StringCache<Utils::PathString, std::mutex> *filePathCache,
+ std::vector<V2::FileContainer> &&sources,
std::vector<V2::FileContainer> &&unsaved,
Utils::SmallString &&query);
- static
- SourceRangesAndDiagnosticsForQueryMessage createSourceRangesAndDiagnosticsForSource(
+ static SourceRangesAndDiagnosticsForQueryMessage createSourceRangesAndDiagnosticsForSource(
+ StringCache<Utils::PathString, std::mutex> *filePathCache,
V2::FileContainer &&source,
const std::vector<V2::FileContainer> &unsaved,
Utils::SmallString &&query);
-
bool canCreateSourceRangesAndDiagnostics() const;
SourceRangesAndDiagnosticsForQueryMessage createNextSourceRangesAndDiagnostics();
Future startCreateNextSourceRangesAndDiagnosticsMessage();
@@ -66,6 +67,7 @@ protected:
std::vector<Future> finishedFutures();
private:
+ StringCache<Utils::PathString, std::mutex> *m_filePathCache = nullptr;
std::vector<V2::FileContainer> m_sources;
std::vector<V2::FileContainer> m_unsaved;
Utils::SmallString m_query;
diff --git a/src/tools/clangrefactoringbackend/source/clangtool.cpp b/src/tools/clangrefactoringbackend/source/clangtool.cpp
index dd4b6c57a3..2ffad73965 100644
--- a/src/tools/clangrefactoringbackend/source/clangtool.cpp
+++ b/src/tools/clangrefactoringbackend/source/clangtool.cpp
@@ -84,23 +84,12 @@ template
void ClangTool::addFiles<Utils::PathStringVector>(const Utils::PathStringVector &filePaths,
const Utils::SmallStringVector &arguments);
-namespace {
-Utils::SmallString toNativeFilePath(const FilePath &filePath)
-{
- Utils::SmallString filePathString = filePath.directory().clone();
- filePathString.append("/");
- filePathString.append(filePath.name());
-
- return toNativePath(std::move(filePathString));
-}
-}
-
void ClangTool::addUnsavedFiles(const V2::FileContainers &unsavedFiles)
{
unsavedFileContents.reserve(unsavedFileContents.size() + unsavedFiles.size());
auto convertToUnsavedFileContent = [] (const V2::FileContainer &unsavedFile) {
- return UnsavedFileContent{toNativeFilePath(unsavedFile.filePath()),
+ return UnsavedFileContent{toNativePath(unsavedFile.filePath().path().clone()),
unsavedFile.unsavedFileContent().clone()};
};
@@ -111,7 +100,8 @@ void ClangTool::addUnsavedFiles(const V2::FileContainers &unsavedFiles)
}
namespace {
-llvm::StringRef toStringRef(const Utils::SmallString &string)
+template <typename String>
+llvm::StringRef toStringRef(const String &string)
{
return llvm::StringRef(string.data(), string.size());
}
diff --git a/src/tools/clangrefactoringbackend/source/clangtool.h b/src/tools/clangrefactoringbackend/source/clangtool.h
index c7ee2a83e0..c643920914 100644
--- a/src/tools/clangrefactoringbackend/source/clangtool.h
+++ b/src/tools/clangrefactoringbackend/source/clangtool.h
@@ -77,13 +77,13 @@ struct FileContent
struct UnsavedFileContent
{
- UnsavedFileContent(Utils::SmallString &&filePath,
+ UnsavedFileContent(Utils::PathString &&filePath,
Utils::SmallString &&content)
: filePath(std::move(filePath)),
content(std::move(content))
{}
- Utils::SmallString filePath;
+ Utils::PathString filePath;
Utils::SmallString content;
};
diff --git a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp
index 58e944784d..cf233baf34 100644
--- a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp
+++ b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp
@@ -37,6 +37,7 @@
#include <QCoreApplication>
#include <functional>
+#include <atomic>
namespace ClangBackEnd {
@@ -125,7 +126,7 @@ void RefactoringServer::gatherSourceRangesAndDiagnosticsForQueryMessages(
uint freeProcessors = std::thread::hardware_concurrency();
#endif
- m_gatherer = ClangQueryGatherer(std::move(sources), std::move(unsaved), std::move(query));
+ m_gatherer = ClangQueryGatherer(&m_filePathCache, std::move(sources), std::move(unsaved), std::move(query));
m_gatherer.setProcessingSlotCount(freeProcessors);
m_pollTimer.start();
diff --git a/src/tools/clangrefactoringbackend/source/refactoringserver.h b/src/tools/clangrefactoringbackend/source/refactoringserver.h
index e3b40d3c56..1befa07621 100644
--- a/src/tools/clangrefactoringbackend/source/refactoringserver.h
+++ b/src/tools/clangrefactoringbackend/source/refactoringserver.h
@@ -30,7 +30,12 @@
#include <refactoringserverinterface.h>
#include <QTimer>
+#include <stringcache.h>
+#include <utils/smallstring.h>
+
+#include <future>
+#include <mutex>
#include <vector>
namespace ClangBackEnd {
@@ -65,6 +70,7 @@ private:
Utils::SmallString &&query);
private:
+ StringCache<Utils::PathString, std::mutex> m_filePathCache;
ClangQueryGatherer m_gatherer;
QTimer m_pollTimer;
};
diff --git a/src/tools/clangrefactoringbackend/source/sourcelocationsutils.h b/src/tools/clangrefactoringbackend/source/sourcelocationsutils.h
index 78076f5f2b..df07b42daa 100644
--- a/src/tools/clangrefactoringbackend/source/sourcelocationsutils.h
+++ b/src/tools/clangrefactoringbackend/source/sourcelocationsutils.h
@@ -53,7 +53,7 @@
namespace ClangBackEnd {
inline
-llvm::SmallString<256> absolutePath(const llvm::StringRef &path)
+llvm::SmallString<256> absolutePath(clang::StringRef path)
{
llvm::SmallString<256> absolutePath(path);
@@ -64,9 +64,9 @@ llvm::SmallString<256> absolutePath(const llvm::StringRef &path)
}
template <typename Container>
-Utils::SmallString fromNativePath(Container container)
+Utils::PathString fromNativePath(Container container)
{
- Utils::SmallString path(container.data(), container.size());
+ Utils::PathString path(container.data(), container.size());
#ifdef _WIN32
std::replace(path.begin(), path.end(), '\\', '/');
@@ -89,13 +89,9 @@ void appendSourceLocationsToSourceLocationsContainer(
const auto fileId = decomposedLoction.first;
const auto offset = decomposedLoction.second;
const auto fileEntry = sourceManager.getFileEntryForID(fileId);
- auto filePath = absolutePath(fileEntry->getName());
- const auto fileName = llvm::sys::path::filename(filePath);
- llvm::sys::path::remove_filename(filePath);
sourceLocationsContainer.insertFilePath(fileId.getHashValue(),
- fromNativePath(filePath),
- fromNativePath(fileName));
+ fromNativePath(fileEntry->tryGetRealPathName()));
sourceLocationsContainer.insertSourceLocation(fileId.getHashValue(),
fullSourceLocation.getSpellingLineNumber(),
fullSourceLocation.getSpellingColumnNumber(),
diff --git a/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp
index 18b6288cae..e83f6a3c38 100644
--- a/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp
+++ b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp
@@ -51,11 +51,14 @@
namespace ClangBackEnd {
-SourceRangeExtractor::SourceRangeExtractor(const clang::SourceManager &sourceManager,
- const clang::LangOptions &languageOptions,
- SourceRangesContainer &sourceRangesContainer)
+SourceRangeExtractor::SourceRangeExtractor(
+ const clang::SourceManager &sourceManager,
+ const clang::LangOptions &languageOptions,
+ ClangBackEnd::StringCache<Utils::PathString, std::mutex> &filePathCache,
+ SourceRangesContainer &sourceRangesContainer)
: sourceManager(sourceManager),
languageOptions(languageOptions),
+ filePathCache(filePathCache),
sourceRangesContainer(sourceRangesContainer)
{
}
@@ -123,19 +126,16 @@ const clang::SourceRange SourceRangeExtractor::extendSourceRangeToLastTokenEnd(c
return {sourceRange.getBegin(), endLocation};
}
-void SourceRangeExtractor::insertSourceRange(uint fileHash,
- Utils::SmallString &&directoryPath,
- Utils::SmallString &&fileName,
+void SourceRangeExtractor::insertSourceRange(uint fileId,
+ Utils::PathString &&filePath,
const clang::FullSourceLoc &startLocation,
uint startOffset,
const clang::FullSourceLoc &endLocation,
uint endOffset,
Utils::SmallString &&lineSnippet)
{
- sourceRangesContainer.insertFilePath(fileHash,
- std::move(directoryPath),
- std::move(fileName));
- sourceRangesContainer.insertSourceRange(fileHash,
+ sourceRangesContainer.insertFilePath(fileId, std::move(filePath));
+ sourceRangesContainer.insertSourceRange(fileId,
startLocation.getSpellingLineNumber(),
startLocation.getSpellingColumnNumber(),
startOffset,
@@ -145,6 +145,17 @@ void SourceRangeExtractor::insertSourceRange(uint fileHash,
std::move(lineSnippet));
}
+uint SourceRangeExtractor::findFileId(clang::FileID fileId, const clang::FileEntry *fileEntry) const
+{
+ auto found = m_fileIdMapping.find(fileId.getHashValue());
+ if (found != m_fileIdMapping.end()) {
+ return found->second;
+ }
+
+ auto filePath = absolutePath(fileEntry->tryGetRealPathName());
+ return filePathCache.stringId(fromNativePath(filePath));
+}
+
void SourceRangeExtractor::addSourceRange(const clang::SourceRange &sourceRange)
{
auto extendedSourceRange = extendSourceRangeToLastTokenEnd(sourceRange);
@@ -158,15 +169,13 @@ void SourceRangeExtractor::addSourceRange(const clang::SourceRange &sourceRange)
const auto startOffset = startDecomposedLoction.second;
const auto endOffset = endDecomposedLoction.second;
const auto fileEntry = sourceManager.getFileEntryForID(fileId);
- auto filePath = absolutePath(fileEntry->getName());
- const auto fileName = llvm::sys::path::filename(filePath);
- llvm::sys::path::remove_filename(filePath);
+
Utils::SmallString lineSnippet = getExpandedText(startSourceLocation.getBufferData(),
startOffset,
endOffset);
- insertSourceRange(fileId.getHashValue(),
- fromNativePath(filePath),
- {fileName.data(), fileName.size()},
+
+ insertSourceRange(findFileId(fileId, fileEntry),
+ fromNativePath(fileEntry->tryGetRealPathName()),
startSourceLocation,
startOffset,
endSourceLocation,
diff --git a/src/tools/clangrefactoringbackend/source/sourcerangeextractor.h b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.h
index 5bd6cf75ab..7a07e5c3f8 100644
--- a/src/tools/clangrefactoringbackend/source/sourcerangeextractor.h
+++ b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.h
@@ -25,9 +25,14 @@
#pragma once
+#include <stringcache.h>
+
+#include <filepath.h>
+
#include <utils/smallstringfwd.h>
#include <vector>
+#include <unordered_map>
using uint = unsigned int;
@@ -40,6 +45,8 @@ class SourceManager;
class LangOptions;
class SourceRange;
class FullSourceLoc;
+class FileID;
+class FileEntry;
}
namespace ClangBackEnd {
@@ -52,6 +59,7 @@ class SourceRangeExtractor
public:
SourceRangeExtractor(const clang::SourceManager &sourceManager,
const clang::LangOptions &languageOptions,
+ ClangBackEnd::StringCache<Utils::PathString, std::mutex> &filePathCache,
SourceRangesContainer &sourceRangesContainer);
void addSourceRange(const clang::SourceRange &sourceRange);
@@ -66,18 +74,21 @@ public:
const clang::SourceRange extendSourceRangeToLastTokenEnd(const clang::SourceRange sourceRange);
private:
- void insertSourceRange(uint fileHash,
- Utils::SmallString &&directoryPath,
- Utils::SmallString &&fileName,
+ void insertSourceRange(uint fileId,
+ Utils::PathString &&filePath,
const clang::FullSourceLoc &startLocation,
uint startOffset,
const clang::FullSourceLoc &endLocation,
uint endOffset,
Utils::SmallString &&lineSnippet);
+ uint findFileId(clang::FileID fileId, const clang::FileEntry *fileEntry) const;
+
private:
+ mutable std::unordered_map<uint, uint> m_fileIdMapping;
const clang::SourceManager &sourceManager;
const clang::LangOptions &languageOptions;
+ ClangBackEnd::StringCache<Utils::PathString, std::mutex> &filePathCache;
SourceRangesContainer &sourceRangesContainer;
};
diff --git a/tests/unit/unittest/clangquery-test.cpp b/tests/unit/unittest/clangquery-test.cpp
index b71e267697..39f82e0955 100644
--- a/tests/unit/unittest/clangquery-test.cpp
+++ b/tests/unit/unittest/clangquery-test.cpp
@@ -29,7 +29,10 @@
#include <clangquery.h>
+#include <mutex>
+
using ClangBackEnd::ClangQuery;
+using ClangBackEnd::StringCache;
using testing::IsEmpty;
using testing::Not;
@@ -43,8 +46,9 @@ protected:
void SetUp() override;
protected:
- ::ClangQuery simpleFunctionQuery;
- ::ClangQuery simpleClassQuery;
+ StringCache<Utils::PathString, std::mutex> filePathCache;
+ ::ClangQuery simpleFunctionQuery{filePathCache};
+ ::ClangQuery simpleClassQuery{filePathCache};
};
using ClangQuerySlowTest = ClangQuery;
@@ -77,7 +81,7 @@ TEST_F(ClangQuerySlowTest, RootSourceRangeForSimpleFunctionDeclarationRange)
TEST_F(ClangQuerySlowTest, SourceRangeInUnsavedFileDeclarationRange)
{
- ::ClangQuery query;
+ ::ClangQuery query(filePathCache);
query.addFile(TESTDATA_DIR, "query_simplefunction.cpp", "#include \"unsaved.h\"", {"cc", "query_simplefunction.cpp", "-std=c++14"});
query.setQuery("functionDecl()");
ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR, "unsaved.h"}, "void unsaved();", {}};
@@ -91,7 +95,7 @@ TEST_F(ClangQuerySlowTest, SourceRangeInUnsavedFileDeclarationRange)
TEST_F(ClangQuerySlowTest, DISABLED_SourceRangeInUnsavedFileDeclarationRangeOverride) // seems not to work in Clang
{
- ::ClangQuery query;
+ ::ClangQuery query(filePathCache);
query.addFile(TESTDATA_DIR, "query_simplefunction.cpp", "void f() {}", {"cc", "query_simplefunction.cpp", "-std=c++14"});
query.setQuery("functionDecl()");
ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR, "query_simplefunction.cpp"}, "void unsaved();", {}};
diff --git a/tests/unit/unittest/clangquerygatherer-test.cpp b/tests/unit/unittest/clangquerygatherer-test.cpp
index 089f273f06..0e24e4fa6d 100644
--- a/tests/unit/unittest/clangquerygatherer-test.cpp
+++ b/tests/unit/unittest/clangquerygatherer-test.cpp
@@ -71,6 +71,7 @@ protected:
void SetUp() override;
protected:
+ ClangBackEnd::StringCache<Utils::PathString, std::mutex> filePathCache;
Utils::SmallString sourceContent{"#include \"query_simplefunction.h\"\nvoid f()\n {}"};
FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"},
sourceContent.clone(),
@@ -80,15 +81,16 @@ protected:
unsavedContent.clone(),
{}};
Utils::SmallString query{"functionDecl()"};
- ClangBackEnd::ClangQueryGatherer gatherer{{source.clone()}, {unsaved.clone()}, query.clone()};
- ClangBackEnd::ClangQueryGatherer manyGatherer{{source.clone(), source.clone(), source.clone()},
+ ClangBackEnd::ClangQueryGatherer gatherer{&filePathCache, {source.clone()}, {unsaved.clone()}, query.clone()};
+ ClangBackEnd::ClangQueryGatherer manyGatherer{&filePathCache,
+ {source.clone(), source.clone(), source.clone()},
{unsaved.clone()},
query.clone()};
};
TEST_F(ClangQueryGatherer, CreateSourceRangesAndDiagnostics)
{
- auto sourceRangesAndDiagnostics = gatherer.createSourceRangesAndDiagnosticsForSource(source.clone(), {}, query.clone());
+ auto sourceRangesAndDiagnostics = gatherer.createSourceRangesAndDiagnosticsForSource(&filePathCache, source.clone(), {}, query.clone());
ASSERT_THAT(sourceRangesAndDiagnostics,
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges,
@@ -98,7 +100,7 @@ TEST_F(ClangQueryGatherer, CreateSourceRangesAndDiagnostics)
TEST_F(ClangQueryGatherer, CreateSourceRangesAndDiagnosticssWithUnsavedContent)
{
- auto sourceRangesAndDiagnostics = gatherer.createSourceRangesAndDiagnosticsForSource(source.clone(), {unsaved}, query.clone());
+ auto sourceRangesAndDiagnostics = gatherer.createSourceRangesAndDiagnosticsForSource(&filePathCache, source.clone(), {unsaved}, query.clone());
ASSERT_THAT(sourceRangesAndDiagnostics,
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges,
@@ -113,7 +115,7 @@ TEST_F(ClangQueryGatherer, CanCreateSourceRangesAndDiagnosticsIfItHasSources)
TEST_F(ClangQueryGatherer, CanNotCreateSourceRangesAndDiagnosticsIfItHasNoSources)
{
- ClangBackEnd::ClangQueryGatherer empthyGatherer{{}, {unsaved.clone()}, query.clone()};
+ ClangBackEnd::ClangQueryGatherer empthyGatherer{&filePathCache, {}, {unsaved.clone()}, query.clone()};
ASSERT_FALSE(empthyGatherer.canCreateSourceRangesAndDiagnostics());
}
diff --git a/tests/unit/unittest/filepath-test.cpp b/tests/unit/unittest/filepath-test.cpp
new file mode 100644
index 0000000000..d82e94f211
--- /dev/null
+++ b/tests/unit/unittest/filepath-test.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "googletest.h"
+
+#include <filepath.h>
+
+namespace {
+
+TEST(FilePath, CreateFromPathString)
+{
+ ClangBackEnd::FilePath filePath{Utils::PathString{"/file/pathOne"}};
+
+ ASSERT_THAT(filePath.directory(), "/file");
+ ASSERT_THAT(filePath.name(), "pathOne");
+}
+
+TEST(FilePath, CreateFromQString)
+{
+ ClangBackEnd::FilePath filePath{QString{"/file/pathOne"}};
+
+ ASSERT_THAT(filePath.directory(), "/file");
+ ASSERT_THAT(filePath.name(), "pathOne");
+}
+
+TEST(FilePath, EmptyFilePath)
+{
+ ClangBackEnd::FilePath filePath;
+
+ ASSERT_THAT(filePath.directory(), "");
+ ASSERT_THAT(filePath.name(), "");
+}
+
+}
diff --git a/tests/unit/unittest/pchcreator-test.cpp b/tests/unit/unittest/pchcreator-test.cpp
index 0798e9d63c..763521da42 100644
--- a/tests/unit/unittest/pchcreator-test.cpp
+++ b/tests/unit/unittest/pchcreator-test.cpp
@@ -73,7 +73,7 @@ protected:
PathString main2Path = TESTDATA_DIR "/includecollector_main2.cpp";
PathString header1Path = TESTDATA_DIR "/includecollector_header1.h";
PathString header2Path = TESTDATA_DIR "/includecollector_header2.h";
- SmallString generatedFileName = "includecollector_generated_file.h";
+ PathString generatedFileName = "includecollector_generated_file.h";
PathString generatedFilePath = TESTDATA_DIR "/includecollector_generated_file.h";
ProjectPartContainer projectPart1{"project1",
{"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
diff --git a/tests/unit/unittest/sourcerangeextractor-test.cpp b/tests/unit/unittest/sourcerangeextractor-test.cpp
index df527b4e62..8bf676b796 100644
--- a/tests/unit/unittest/sourcerangeextractor-test.cpp
+++ b/tests/unit/unittest/sourcerangeextractor-test.cpp
@@ -28,23 +28,12 @@
#include <sourcerangeextractor.h>
#include <sourcerangescontainer.h>
-
-#if defined(__GNUC__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wunused-parameter"
-#elif defined(_MSC_VER)
-# pragma warning(push)
-# pragma warning( disable : 4100 )
-#endif
+#include <stringcache.h>
#include <clang/Basic/SourceManager.h>
#include <clang/Lex/Lexer.h>
-#if defined(__GNUC__)
-# pragma GCC diagnostic pop
-#elif defined(_MSC_VER)
-# pragma warning(pop)
-#endif
+#include <mutex>
using testing::Contains;
using ::testing::Eq;
@@ -65,7 +54,8 @@ protected:
TestClangTool clangTool{TESTDATA_DIR, "sourcerangeextractor_location.cpp", "", {"cc", "sourcerangeextractor_location.cpp"}};
ClangBackEnd::SourceRangesContainer sourceRangesContainer;
const clang::SourceManager &sourceManager{clangTool.sourceManager()};
- ClangBackEnd::SourceRangeExtractor extractor{sourceManager, clangTool.languageOptions(), sourceRangesContainer};
+ ClangBackEnd::StringCache<Utils::PathString, std::mutex> filePathCache;
+ ClangBackEnd::SourceRangeExtractor extractor{sourceManager, clangTool.languageOptions(), filePathCache, sourceRangesContainer};
clang::SourceLocation startLocation = sourceManager.getLocForStartOfFile(sourceManager.getMainFileID());
clang::SourceLocation endLocation = sourceManager.getLocForStartOfFile(sourceManager.getMainFileID()).getLocWithOffset(4);
clang::SourceRange sourceRange{startLocation, endLocation};
@@ -76,7 +66,7 @@ using SourceRangeExtractorSlowTest = SourceRangeExtractor;
TEST_F(SourceRangeExtractorSlowTest, ExtractSourceRangeContainer)
{
- SourceRangeWithTextContainer sourceRangeContainer{1, 1, 1, 0, 1, 10, 9, Utils::SmallString("int value;")};
+ SourceRangeWithTextContainer sourceRangeContainer{0, 1, 1, 0, 1, 10, 9, Utils::SmallString("int value;")};
extractor.addSourceRange(sourceRange);
diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro
index 73e0ed31a3..4e32ce0413 100644
--- a/tests/unit/unittest/unittest.pro
+++ b/tests/unit/unittest/unittest.pro
@@ -63,6 +63,8 @@ SOURCES += \
projectupdater-test.cpp \
pchmanagerserver-test.cpp \
pchmanagerclientserverinprocess-test.cpp \
+ clangquerygatherer-test.cpp \
+ filepath-test.cpp
!isEmpty(LIBCLANG_LIBS) {
SOURCES += \