File: TypesInternal.h

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (101 lines) | stat: -rw-r--r-- 3,831 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//===--- TypesInternal.h - Intermediate structures used for analysis C++-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef CLANG_INCLUDE_CLEANER_TYPESINTERNAL_H
#define CLANG_INCLUDE_CLEANER_TYPESINTERNAL_H

#include "clang/Basic/SourceLocation.h"
#include "clang/Tooling/Inclusions/StandardLibrary.h"
#include "llvm/ADT/BitmaskEnum.h"
#include <cstdint>
#include <utility>
#include <variant>

namespace llvm {
class raw_ostream;
}
namespace clang::include_cleaner {
/// A place where a symbol can be provided.
/// It is either a physical file of the TU (SourceLocation) or a logical
/// location in the standard library (stdlib::Symbol).
struct SymbolLocation {
  enum Kind {
    /// A position within a source file (or macro expansion) parsed by clang.
    Physical,
    /// A recognized standard library symbol, like std::string.
    Standard,
  };

  SymbolLocation(SourceLocation S) : Storage(S) {}
  SymbolLocation(tooling::stdlib::Symbol S) : Storage(S) {}

  Kind kind() const { return static_cast<Kind>(Storage.index()); }
  bool operator==(const SymbolLocation &RHS) const {
    return Storage == RHS.Storage;
  }
  SourceLocation physical() const { return std::get<Physical>(Storage); }
  tooling::stdlib::Symbol standard() const {
    return std::get<Standard>(Storage);
  }

private:
  // Order must match Kind enum!
  std::variant<SourceLocation, tooling::stdlib::Symbol> Storage;
};
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolLocation &);

/// Represents properties of a symbol provider.
///
/// Hints represents the properties of the edges traversed when finding headers
/// that satisfy an AST node (AST node => symbols => locations => headers).
///
/// Since there can be multiple paths from an AST node to same header, we need
/// to merge hints. These hints are merged by taking the union of all the
/// properties along all the paths. We choose the boolean sense accordingly,
/// e.g. "Public" rather than "Private", because a header is good if it provides
/// any public definition, even if it also provides private ones.
///
/// Hints are sorted in ascending order of relevance.
enum class Hints : uint8_t {
  None = 0x00,
  /// Symbol is directly originating from this header, rather than being
  /// exported or included transitively.
  OriginHeader = 1 << 0,
  /// Provides a generally-usable definition for the symbol. (a function decl,
  /// or class definition and not a forward declaration of a template).
  CompleteSymbol = 1 << 1,
  /// Symbol is provided by a public file. Only absent in the cases where file
  /// is explicitly marked as such, non self-contained or IWYU private
  /// pragmas.
  PublicHeader = 1 << 2,
  /// Header providing the symbol is explicitly marked as preferred, with an
  /// IWYU private pragma that points at this provider or header and symbol has
  /// ~the same name.
  PreferredHeader = 1 << 3,
  LLVM_MARK_AS_BITMASK_ENUM(PreferredHeader),
};
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
/// A wrapper to augment values with hints.
template <typename T> struct Hinted : public T {
  Hints Hint;
  Hinted(T &&Wrapped, Hints H) : T(std::move(Wrapped)), Hint(H) {}

  /// Since hints are sorted by relevance, use it directly.
  bool operator<(const Hinted<T> &Other) const {
    return static_cast<int>(Hint) < static_cast<int>(Other.Hint);
  }

  friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
                                       const Hinted<T> &H) {
    return OS << static_cast<int>(H.Hint) << " - " << static_cast<T>(H);
  }
};

} // namespace clang::include_cleaner

#endif