Skip to content

Commit 075be6d

Browse files
Hack lldb to load CAS content
This is a hack and very rough.
1 parent 7410ded commit 075be6d

File tree

10 files changed

+185
-14
lines changed

10 files changed

+185
-14
lines changed

clang/test/ClangScanDeps/gmodules.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ int main(void) {
218218
struct Right _right;
219219
struct Top _top;
220220
struct Prefix _prefix;
221+
return 0;
221222
}
222223

223224
//--- cas-config.template

lldb/include/lldb/Host/FileSystem.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "lldb/Utility/Status.h"
1717
#include "lldb/Utility/TildeExpressionResolver.h"
1818

19+
#include "llvm/CAS/AutoCASFileSystem.h"
1920
#include "llvm/Support/Chrono.h"
2021
#include "llvm/Support/VirtualFileSystem.h"
2122

@@ -33,13 +34,15 @@ class FileSystem {
3334
static const char *PATH_CONVERSION_ERROR;
3435

3536
FileSystem()
36-
: m_fs(llvm::vfs::getRealFileSystem()),
37+
: m_fs(
38+
llvm::cas::createAutoCASFileSystem(llvm::vfs::getRealFileSystem())),
3739
m_tilde_resolver(std::make_unique<StandardTildeExpressionResolver>()) {}
3840
FileSystem(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs)
39-
: m_fs(std::move(fs)),
41+
: m_fs(llvm::cas::createAutoCASFileSystem(std::move(fs))),
4042
m_tilde_resolver(std::make_unique<StandardTildeExpressionResolver>()) {}
4143
FileSystem(std::unique_ptr<TildeExpressionResolver> tilde_resolver)
42-
: m_fs(llvm::vfs::getRealFileSystem()),
44+
: m_fs(
45+
llvm::cas::createAutoCASFileSystem(llvm::vfs::getRealFileSystem())),
4346
m_tilde_resolver(std::move(tilde_resolver)) {}
4447

4548
FileSystem(const FileSystem &fs) = delete;

lldb/source/Host/common/FileSystem.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -295,12 +295,18 @@ FileSystem::CreateWritableDataBuffer(const llvm::Twine &path, uint64_t size,
295295
std::shared_ptr<DataBuffer>
296296
FileSystem::CreateDataBuffer(const llvm::Twine &path, uint64_t size,
297297
uint64_t offset) {
298-
const bool is_volatile = !IsLocal(path);
299-
auto buffer =
300-
GetMemoryBuffer<llvm::MemoryBuffer>(path, size, offset, is_volatile);
298+
auto buffer = m_fs->getBufferForFile(path);
301299
if (!buffer)
302300
return {};
303-
return std::make_shared<DataBufferLLVM>(std::move(buffer));
301+
302+
if (size == 0)
303+
return std::make_shared<DataBufferLLVM>(std::move(*buffer));
304+
305+
auto slice = (*buffer)->getBuffer().slice(offset, offset + size);
306+
auto sliced_buffer = llvm::MemoryBuffer::getMemBufferCopy(
307+
slice, (*buffer)->getBufferIdentifier());
308+
309+
return std::make_shared<DataBufferLLVM>(std::move(sliced_buffer));
304310
}
305311

306312
std::shared_ptr<WritableDataBuffer>

lldb/source/Utility/FileSpec.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,9 @@ void FileSpec::GetPath(llvm::SmallVectorImpl<char> &path,
395395
bool denormalize) const {
396396
path.append(m_directory.GetStringRef().begin(),
397397
m_directory.GetStringRef().end());
398+
// FIXME: HACK
399+
if (llvm::toStringRef(path).starts_with("llvmcas:"))
400+
path.insert(path.end(), '/');
398401
// Since the path was normalized and all paths use '/' when stored in these
399402
// objects, we don't need to look for the actual syntax specific path
400403
// separator, we just look for and insert '/'.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//===- llvm/CAS/AutoCASFileSystem.h -----------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_CAS_AUTOCASDISKFILESYSTEM_H
10+
#define LLVM_CAS_AUTOCASDISKFILESYSTEM_H
11+
12+
#include "llvm/ADT/SmallVector.h"
13+
#include "llvm/CAS/CASConfiguration.h"
14+
#include "llvm/CAS/ObjectStore.h"
15+
#include "llvm/Support/VirtualFileSystem.h"
16+
17+
namespace llvm::cas {
18+
19+
/// A file system that will discover CASConfiguration when accessing new files,
20+
/// and able to load CASIDs after new CASes are loaded from discovered
21+
/// CASConfiguration.
22+
class AutoCASFileSystem : public vfs::ProxyFileSystem {
23+
virtual void anchor() override;
24+
25+
public:
26+
AutoCASFileSystem(IntrusiveRefCntPtr<FileSystem> Base)
27+
: vfs::ProxyFileSystem(Base) {}
28+
29+
llvm::ErrorOr<std::unique_ptr<vfs::File>>
30+
openFileForRead(const Twine &Path) override;
31+
32+
ErrorOr<vfs::Status> status(const Twine &Path) override;
33+
34+
private:
35+
llvm::Error discoverNewCASConfiguration(const llvm::Twine &Path);
36+
std::optional<std::unique_ptr<vfs::File>> lookupMaybeCASID(StringRef Path);
37+
38+
SmallVector<std::pair<CASConfiguration, std::shared_ptr<ObjectStore>>, 4>
39+
LoadedCAS;
40+
std::mutex DiscoverLock;
41+
};
42+
43+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
44+
createAutoCASFileSystem(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> Base);
45+
46+
} // namespace llvm::cas
47+
48+
#endif

llvm/include/llvm/CAS/CASConfiguration.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class CASConfiguration {
7171
static std::optional<std::pair<std::string, CASConfiguration>>
7272
createFromSearchConfigFile(
7373
StringRef Path,
74-
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
74+
llvm::vfs::FileSystem &VFS = *llvm::vfs::getRealFileSystem());
7575
};
7676

7777
} // namespace llvm::cas

llvm/lib/CAS/AutoCASFileSystem.cpp

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
//===- AutoCASFileSystem.cpp ------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "llvm/CAS/AutoCASFileSystem.h"
10+
#include "llvm/ADT/STLExtras.h"
11+
12+
using namespace llvm;
13+
using namespace llvm::cas;
14+
15+
void AutoCASFileSystem::anchor() {}
16+
17+
namespace {
18+
class CASFile final : public vfs::File {
19+
ObjectProxy Proxy;
20+
21+
public:
22+
CASFile(ObjectProxy Proxy) : Proxy(Proxy) {}
23+
24+
ErrorOr<vfs::Status> status() override {
25+
// Return a mostly default constructed status but get the file size correct.
26+
return vfs::Status(/*Name=*/{}, /*UID=*/{}, /*MTime=*/{}, /*User=*/{},
27+
/*Group=*/{}, /*Size=*/Proxy.getData().size(),
28+
/*Type=*/{}, /*Perms=*/{});
29+
}
30+
31+
ErrorOr<std::unique_ptr<MemoryBuffer>> getBuffer(const Twine &Name,
32+
int64_t FileSize,
33+
bool RequiresNullTerminator,
34+
bool IsVolatile) override {
35+
return Proxy.getMemoryBuffer();
36+
}
37+
38+
ErrorOr<std::optional<cas::ObjectRef>> getObjectRefForContent() override {
39+
return Proxy.getRef();
40+
}
41+
42+
std::error_code close() override { return std::error_code(); }
43+
};
44+
} // namespace
45+
46+
ErrorOr<std::unique_ptr<vfs::File>>
47+
AutoCASFileSystem::openFileForRead(const Twine &Path) {
48+
if (auto E = discoverNewCASConfiguration(Path))
49+
return errorToErrorCode(std::move(E));
50+
if (auto File = lookupMaybeCASID(Path.str()))
51+
return std::move(*File);
52+
return vfs::ProxyFileSystem::openFileForRead(Path);
53+
}
54+
55+
ErrorOr<vfs::Status> AutoCASFileSystem::status(const Twine &Path) {
56+
if (auto E = discoverNewCASConfiguration(Path))
57+
return errorToErrorCode(std::move(E));
58+
if (auto File = lookupMaybeCASID(Path.str()))
59+
return (*File)->status();
60+
return vfs::ProxyFileSystem::status(Path);
61+
}
62+
63+
Error AutoCASFileSystem::discoverNewCASConfiguration(const Twine &Path) {
64+
auto NewConfig = CASConfiguration::createFromSearchConfigFile(
65+
Path.str(), getUnderlyingFS());
66+
if (!NewConfig)
67+
return Error::success();
68+
69+
std::scoped_lock<std::mutex> Lock(DiscoverLock);
70+
71+
if (llvm::find_if(LoadedCAS, [&](const auto &Entry) {
72+
return Entry.first == NewConfig->second;
73+
}) != LoadedCAS.end())
74+
return Error::success();
75+
76+
auto DB = NewConfig->second.createDatabases();
77+
if (!DB)
78+
return DB.takeError();
79+
80+
LoadedCAS.emplace_back(std::move(NewConfig->second), std::move(DB->first));
81+
return Error::success();
82+
}
83+
84+
std::optional<std::unique_ptr<vfs::File>>
85+
AutoCASFileSystem::lookupMaybeCASID(StringRef Path) {
86+
if (LoadedCAS.empty())
87+
return std::nullopt;
88+
89+
std::scoped_lock<std::mutex> Lock(DiscoverLock);
90+
for (auto &CAS : llvm::reverse(LoadedCAS)) {
91+
auto ID = CAS.second->parseID(Path);
92+
if (!ID) {
93+
consumeError(ID.takeError());
94+
return std::nullopt;
95+
}
96+
auto Proxy = CAS.second->getProxy(*ID);
97+
if (!Proxy) {
98+
consumeError(Proxy.takeError());
99+
return std::nullopt;
100+
}
101+
return std::make_unique<CASFile>(*Proxy);
102+
}
103+
return std::nullopt;
104+
}
105+
106+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
107+
llvm::cas::createAutoCASFileSystem(
108+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> Base) {
109+
return llvm::makeIntrusiveRefCnt<llvm::cas::AutoCASFileSystem>(
110+
std::move(Base));
111+
}

llvm/lib/CAS/CASConfiguration.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,12 @@ CASConfiguration::createFromConfig(StringRef Content) {
9090
}
9191

9292
std::optional<std::pair<std::string, CASConfiguration>>
93-
CASConfiguration::createFromSearchConfigFile(
94-
StringRef Path, IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
95-
if (!VFS)
96-
VFS = vfs::getRealFileSystem();
97-
93+
CASConfiguration::createFromSearchConfigFile(StringRef Path,
94+
vfs::FileSystem &VFS) {
9895
while (!Path.empty()) {
9996
SmallString<256> ConfigPath(Path);
10097
sys::path::append(ConfigPath, ".cas-config");
101-
auto File = VFS->openFileForRead(ConfigPath);
98+
auto File = VFS.openFileForRead(ConfigPath);
10299
if (!File || !*File) {
103100
Path = sys::path::parent_path(Path);
104101
continue;

llvm/lib/CAS/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ endif()
55
add_llvm_component_library(LLVMCAS
66
ActionCache.cpp
77
ActionCaches.cpp
8+
AutoCASFileSystem.cpp
89
BuiltinCAS.cpp
910
BuiltinUnifiedCASDatabases.cpp
1011
CASConfiguration.cpp

llvm/tools/dsymutil/dsymutil.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "llvm/ADT/StringExtras.h"
2525
#include "llvm/ADT/StringRef.h"
2626
#include "llvm/CAS/ActionCache.h"
27+
#include "llvm/CAS/AutoCASFileSystem.h"
2728
#include "llvm/CAS/BuiltinUnifiedCASDatabases.h"
2829
#include "llvm/CAS/ObjectStore.h"
2930
#include "llvm/DebugInfo/DIContext.h"

0 commit comments

Comments
 (0)