xref: /llvm-project/clang-tools-extra/include-cleaner/lib/TypesInternal.h (revision 73b2c86d95dc510d6972aaa4b44688aebebd89f1)
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 
19 namespace llvm {
20 class raw_ostream;
21 }
22 namespace 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).
26 struct 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 
SymbolLocationSymbolLocation34   SymbolLocation(SourceLocation S) : Storage(S) {}
SymbolLocationSymbolLocation35   SymbolLocation(tooling::stdlib::Symbol S) : Storage(S) {}
36 
kindSymbolLocation37   Kind kind() const { return static_cast<Kind>(Storage.index()); }
38   bool operator==(const SymbolLocation &RHS) const {
39     return Storage == RHS.Storage;
40   }
physicalSymbolLocation41   SourceLocation physical() const { return std::get<Physical>(Storage); }
standardSymbolLocation42   tooling::stdlib::Symbol standard() const {
43     return std::get<Standard>(Storage);
44   }
45 
46 private:
47   // Order must match Kind enum!
48   std::variant<SourceLocation, tooling::stdlib::Symbol> Storage;
49 };
50 llvm::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.
64 enum 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 };
82 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
83 /// A wrapper to augment values with hints.
84 template <typename T> struct Hinted : public T {
85   Hints Hint;
HintedHinted86   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