File: CASOptions.cpp

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (121 lines) | stat: -rw-r--r-- 4,147 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
//===- CASOptions.cpp -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "clang/CAS/CASOptions.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticCAS.h"
#include "llvm/CAS/ActionCache.h"
#include "llvm/CAS/BuiltinUnifiedCASDatabases.h"
#include "llvm/CAS/ObjectStore.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Path.h"

using namespace clang;
using namespace llvm::cas;

std::pair<std::shared_ptr<llvm::cas::ObjectStore>,
          std::shared_ptr<llvm::cas::ActionCache>>
CASOptions::getOrCreateDatabases(DiagnosticsEngine &Diags,
                                 bool CreateEmptyDBsOnFailure) const {
  if (Cache.Config.IsFrozen)
    return {Cache.CAS, Cache.AC};

  if (auto E = initCache())
    Diags.Report(diag::err_cas_cannot_be_initialized) << toString(std::move(E));

  if (!Cache.CAS && CreateEmptyDBsOnFailure)
    Cache.CAS = llvm::cas::createInMemoryCAS();
  if (!Cache.AC && CreateEmptyDBsOnFailure)
    Cache.AC = llvm::cas::createInMemoryActionCache();
  return {Cache.CAS, Cache.AC};
}

llvm::Expected<std::pair<std::shared_ptr<llvm::cas::ObjectStore>,
                         std::shared_ptr<llvm::cas::ActionCache>>>
CASOptions::getOrCreateDatabases() const {
  if (auto E = initCache())
    return std::move(E);
  return std::pair{Cache.CAS, Cache.AC};
}

void CASOptions::freezeConfig(DiagnosticsEngine &Diags) {
  if (Cache.Config.IsFrozen)
    return;

  // Make sure the cache is initialized.
  if (auto E = initCache())
    Diags.Report(diag::err_cas_cannot_be_initialized) << toString(std::move(E));

  // Freeze the CAS and wipe out the visible config to hide it from future
  // accesses. For example, future diagnostics cannot see this. Something that
  // needs direct access to the CAS configuration will need to be
  // scheduled/executed at a level that has access to the configuration.
  auto &CurrentConfig = static_cast<CASConfiguration &>(*this);
  CurrentConfig = CASConfiguration();
  CurrentConfig.IsFrozen = Cache.Config.IsFrozen = true;

  if (Cache.CAS) {
    // Set the CASPath to the hash schema, since that leaks through CASContext's
    // API and is observable.
    CurrentConfig.CASPath =
        Cache.CAS->getContext().getHashSchemaIdentifier().str();
    CurrentConfig.PluginPath.clear();
    CurrentConfig.PluginOptions.clear();
  }
}

void CASOptions::ensurePersistentCAS() {
  assert(!IsFrozen && "Expected to check for a persistent CAS before freezing");
  switch (getKind()) {
  case UnknownCAS:
    llvm_unreachable("Cannot ensure persistent CAS if it's unknown / frozen");
  case InMemoryCAS:
    CASPath = "auto";
    break;
  case OnDiskCAS:
    break;
  }
}

llvm::Error CASOptions::initCache() const {
  auto &CurrentConfig = static_cast<const CASConfiguration &>(*this);
  if (CurrentConfig == Cache.Config && Cache.CAS && Cache.AC)
    return llvm::Error::success();

  Cache.Config = CurrentConfig;
  StringRef CASPath = Cache.Config.CASPath;

  if (!PluginPath.empty()) {
    std::pair<std::shared_ptr<ObjectStore>, std::shared_ptr<ActionCache>> DBs;
    if (llvm::Error E =
            createPluginCASDatabases(PluginPath, CASPath, PluginOptions)
                .moveInto(DBs)) {
      return E;
    }
    std::tie(Cache.CAS, Cache.AC) = std::move(DBs);
    return llvm::Error::success();
  }

  if (CASPath.empty()) {
    Cache.CAS = llvm::cas::createInMemoryCAS();
    Cache.AC = llvm::cas::createInMemoryActionCache();
    return llvm::Error::success();
  }

  SmallString<256> PathBuf;
  if (CASPath == "auto") {
    getDefaultOnDiskCASPath(PathBuf);
    CASPath = PathBuf;
  }
  std::pair<std::unique_ptr<ObjectStore>, std::unique_ptr<ActionCache>> DBs;
  if (llvm::Error E = createOnDiskUnifiedCASDatabases(CASPath).moveInto(DBs))
    return E;

  std::tie(Cache.CAS, Cache.AC) = std::move(DBs);
  return llvm::Error::success();
}