1 //===--- TypesInternal.h - Intermediate structures used for analysis 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 //===----------------------------------------------------------------------===//
9 #ifndef CLANG_INCLUDE_CLEANER_TYPESINTERNAL_H
10 #define CLANG_INCLUDE_CLEANER_TYPESINTERNAL_H
12 #include "clang/Basic/SourceLocation.h"
13 #include "clang/Tooling/Inclusions/StandardLibrary.h"
14 #include "llvm/ADT/BitmaskEnum.h"
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
{
28 /// A position within a source file (or macro expansion) parsed by clang.
30 /// A recognized standard library symbol, like std::string.
34 SymbolLocation(SourceLocation S
) : Storage(S
) {}
35 SymbolLocation(tooling::stdlib::Symbol S
) : Storage(S
) {}
37 Kind
kind() const { return static_cast<Kind
>(Storage
.index()); }
38 bool operator==(const SymbolLocation
&RHS
) const {
39 return Storage
== RHS
.Storage
;
41 SourceLocation
physical() const { return std::get
<Physical
>(Storage
); }
42 tooling::stdlib::Symbol
standard() const {
43 return std::get
<Standard
>(Storage
);
47 // Order must match Kind enum!
48 std::variant
<SourceLocation
, tooling::stdlib::Symbol
> Storage
;
50 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&, const SymbolLocation
&);
52 /// Represents properties of a symbol provider.
54 /// Hints represents the properties of the edges traversed when finding headers
55 /// that satisfy an AST node (AST node => symbols => locations => headers).
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.
63 /// Hints are sorted in ascending order of relevance.
64 enum class Hints
: uint8_t {
66 /// Symbol is directly originating from this header, rather than being
67 /// exported or included transitively.
68 OriginHeader
= 1 << 0,
69 /// Provides a generally-usable definition for the symbol. (a function decl,
70 /// or class definition and not a forward declaration of a template).
71 CompleteSymbol
= 1 << 1,
72 /// Symbol is provided by a public file. Only absent in the cases where file
73 /// is explicitly marked as such, non self-contained or IWYU private
75 PublicHeader
= 1 << 2,
76 /// Header providing the symbol is explicitly marked as preferred, with an
77 /// IWYU private pragma that points at this provider or header and symbol has
79 PreferredHeader
= 1 << 3,
80 LLVM_MARK_AS_BITMASK_ENUM(PreferredHeader
),
82 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
83 /// A wrapper to augment values with hints.
84 template <typename T
> struct Hinted
: public T
{
86 Hinted(T
&&Wrapped
, Hints H
) : T(std::move(Wrapped
)), Hint(H
) {}
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
);
93 friend llvm::raw_ostream
&operator<<(llvm::raw_ostream
&OS
,
95 return OS
<< static_cast<int>(H
.Hint
) << " - " << static_cast<T
>(H
);
99 } // namespace clang::include_cleaner