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