1 //===--- Ref.cpp -------------------------------------------------*- C++-*-===//
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
7 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/STLExtras.h"
15 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&OS
, RefKind K
) {
16 if (K
== RefKind::Unknown
)
17 return OS
<< "Unknown";
18 static constexpr std::array
<const char *, 4> Messages
= {"Decl", "Def", "Ref",
20 bool VisitedOnce
= false;
21 for (unsigned I
= 0; I
< Messages
.size(); ++I
) {
22 if (static_cast<uint8_t>(K
) & 1u << I
) {
32 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&OS
, const Ref
&R
) {
33 return OS
<< R
.Location
<< ":" << R
.Kind
;
36 void RefSlab::Builder::insert(const SymbolID
&ID
, const Ref
&S
) {
38 E
.Reference
.Location
.FileURI
= UniqueStrings
.save(S
.Location
.FileURI
).data();
39 Entries
.insert(std::move(E
));
42 RefSlab
RefSlab::Builder::build() && {
43 std::vector
<std::pair
<SymbolID
, llvm::ArrayRef
<Ref
>>> Result
;
44 // We'll reuse the arena, as it only has unique strings and we need them all.
45 // We need to group refs by symbol and form contiguous arrays on the arena.
46 std::vector
<std::pair
<SymbolID
, const Ref
*>> Flat
;
47 Flat
.reserve(Entries
.size());
48 for (const Entry
&E
: Entries
)
49 Flat
.emplace_back(E
.Symbol
, &E
.Reference
);
51 llvm::sort(Flat
, llvm::less_first());
52 std::vector
<Ref
> Refs
;
53 // Loop over symbols, copying refs for each onto the arena.
54 for (auto I
= Flat
.begin(), End
= Flat
.end(); I
!= End
;) {
55 SymbolID Sym
= I
->first
;
58 Refs
.push_back(*I
->second
);
60 } while (I
!= End
&& I
->first
== Sym
);
61 llvm::sort(Refs
); // By file, affects xrefs display order.
62 Result
.emplace_back(Sym
, llvm::ArrayRef
<Ref
>(Refs
).copy(Arena
));
64 return RefSlab(std::move(Result
), std::move(Arena
), Entries
.size());