1//===--- TypesInternal.h - Intermediate structures used for analysis 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 CLANG_INCLUDE_CLEANER_TYPESINTERNAL_H
10#define CLANG_INCLUDE_CLEANER_TYPESINTERNAL_H
11
12#include "clang/Basic/SourceLocation.h"
13#include "clang/Tooling/Inclusions/StandardLibrary.h"
14#include "llvm/ADT/BitmaskEnum.h"
15#include <cstdint>
16#include <utility>
17#include <variant>
18
19namespace llvm {
20class raw_ostream;
21}
22namespace clang::include_cleaner {
23/// A place where a symbol can be provided.
24/// It is either a physical file of the TU (SourceLocation) or a logical
25/// location in the standard library (stdlib::Symbol).
26struct SymbolLocation {
27 enum Kind {
28 /// A position within a source file (or macro expansion) parsed by clang.
29 Physical,
30 /// A recognized standard library symbol, like std::string.
31 Standard,
32 };
33
34 SymbolLocation(SourceLocation S) : Storage(S) {}
35 SymbolLocation(tooling::stdlib::Symbol S) : Storage(S) {}
36
37 Kind kind() const { return static_cast<Kind>(Storage.index()); }
38 bool operator==(const SymbolLocation &RHS) const {
39 return Storage == RHS.Storage;
40 }
41 SourceLocation physical() const { return std::get<Physical>(v: Storage); }
42 tooling::stdlib::Symbol standard() const {
43 return std::get<Standard>(v: Storage);
44 }
45
46private:
47 // Order must match Kind enum!
48 std::variant<SourceLocation, tooling::stdlib::Symbol> Storage;
49};
50llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolLocation &);
51
52/// Represents properties of a symbol provider.
53///
54/// Hints represents the properties of the edges traversed when finding headers
55/// that satisfy an AST node (AST node => symbols => locations => headers).
56///
57/// Since there can be multiple paths from an AST node to same header, we need
58/// to merge hints. These hints are merged by taking the union of all the
59/// properties along all the paths. We choose the boolean sense accordingly,
60/// e.g. "Public" rather than "Private", because a header is good if it provides
61/// any public definition, even if it also provides private ones.
62///
63/// Hints are sorted in ascending order of relevance.
64enum class Hints : uint8_t {
65 None = 0x00,
66 /// Symbol is directly originating from this header, rather than being
67 /// exported or included transitively.
68 OriginHeader = 1 << 0,
69 /// Header providing the symbol is explicitly marked as preferred, with an
70 /// IWYU private pragma that points at this provider or header and symbol has
71 /// ~the same name.
72 PreferredHeader = 1 << 1,
73 /// Provides a generally-usable definition for the symbol. (a function decl,
74 /// or class definition and not a forward declaration of a template).
75 CompleteSymbol = 1 << 2,
76 /// Symbol is provided by a public file. Only absent in the cases where file
77 /// is explicitly marked as such, non self-contained or IWYU private
78 /// pragmas.
79 PublicHeader = 1 << 3,
80 LLVM_MARK_AS_BITMASK_ENUM(PublicHeader),
81};
82LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
83/// A wrapper to augment values with hints.
84template <typename T> struct Hinted : public T {
85 Hints Hint;
86 Hinted(T &&Wrapped, Hints H) : T(std::move(Wrapped)), Hint(H) {}
87
88 /// Since hints are sorted by relevance, use it directly.
89 bool operator<(const Hinted<T> &Other) const {
90 return static_cast<int>(Hint) < static_cast<int>(Other.Hint);
91 }
92
93 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
94 const Hinted<T> &H) {
95 return OS << static_cast<int>(H.Hint) << " - " << static_cast<T>(H);
96 }
97};
98
99} // namespace clang::include_cleaner
100
101#endif
102

source code of clang-tools-extra/include-cleaner/lib/TypesInternal.h