[include-cleaner] Add the missing parts of Symbol and Header clases.
authorSam McCall <sam.mccall@gmail.com>
Tue, 25 Oct 2022 19:04:59 +0000 (21:04 +0200)
committerSam McCall <sam.mccall@gmail.com>
Tue, 8 Nov 2022 11:19:23 +0000 (12:19 +0100)
Differential Revision: https://reviews.llvm.org/D136710

clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h
clang-tools-extra/include-cleaner/lib/CMakeLists.txt
clang-tools-extra/include-cleaner/lib/Types.cpp [new file with mode: 0644]

index a03b30e..e33693c 100644 (file)
@@ -26,6 +26,9 @@
 #include <memory>
 #include <vector>
 
+namespace llvm {
+class raw_ostream;
+} // namespace llvm
 namespace clang {
 class Decl;
 class FileEntry;
@@ -33,28 +36,58 @@ namespace include_cleaner {
 
 /// An entity that can be referenced in the code.
 struct Symbol {
-  Symbol(Decl &D) : Storage(&D) {}
+  enum Kind {
+    /// A canonical clang declaration.
+    Declaration,
+    /// A recognized symbol from the standard library, like std::string.
+    Standard,
+  };
+
+  Symbol(const Decl &D) : Storage(&D) {}
   Symbol(tooling::stdlib::Symbol S) : Storage(S) {}
 
+  Kind kind() const { return static_cast<Kind>(Storage.index()); }
+  bool operator==(const Symbol &RHS) const { return Storage == RHS.Storage; }
+
+  tooling::stdlib::Symbol standard() const {
+    return std::get<Standard>(Storage);
+  }
+  const Decl &declaration() const { return *std::get<Declaration>(Storage); }
+
 private:
   // FIXME: Add support for macros.
+  // Order must match Kind enum!
   std::variant<const Decl *, tooling::stdlib::Symbol> Storage;
 };
+llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Symbol &);
 
 /// Represents a file that provides some symbol. Might not be includeable, e.g.
 /// built-in or main-file itself.
 struct Header {
-  /// A physical (or logical, in case of a builtin) file.
+  enum Kind {
+    /// A source file parsed by clang. (May also be a <built-in> buffer).
+    Physical,
+    /// A recognized standard library header, like <string>.
+    Standard,
+  };
+
   Header(const FileEntry *FE) : Storage(FE) {}
-  /// A logical file representing a stdlib header.
   Header(tooling::stdlib::Header H) : Storage(H) {}
 
+  Kind kind() const { return static_cast<Kind>(Storage.index()); }
   bool operator==(const Header &RHS) const { return Storage == RHS.Storage; }
 
+  const FileEntry *physical() const { return std::get<Physical>(Storage); }
+  tooling::stdlib::Header standard() const {
+    return std::get<Standard>(Storage);
+  }
+
 private:
   // FIXME: Handle verbatim spellings.
+  // Order must match Kind enum!
   std::variant<const FileEntry *, tooling::stdlib::Header> Storage;
 };
+llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Header &);
 
 } // namespace include_cleaner
 } // namespace clang
index 759261e..62c61f4 100644 (file)
@@ -4,6 +4,7 @@ add_clang_library(clangIncludeCleaner
   Analysis.cpp
   HTMLReport.cpp
   Record.cpp
+  Types.cpp
   WalkAST.cpp
 
   LINK_LIBS
diff --git a/clang-tools-extra/include-cleaner/lib/Types.cpp b/clang-tools-extra/include-cleaner/lib/Types.cpp
new file mode 100644 (file)
index 0000000..1b673ab
--- /dev/null
@@ -0,0 +1,38 @@
+//===--- Types.cpp --------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang-include-cleaner/Types.h"
+#include "clang/AST/Decl.h"
+#include "clang/Basic/FileEntry.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang::include_cleaner {
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S) {
+  switch (S.kind()) {
+  case Symbol::Declaration:
+    if (const auto *ND = llvm::dyn_cast<NamedDecl>(&S.declaration()))
+      return OS << ND->getNameAsString();
+    return OS << S.declaration().getDeclKindName();
+  case Symbol::Standard:
+    return OS << S.standard().scope() << S.standard().name();
+  }
+  llvm_unreachable("Unhandled Symbol kind");
+}
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Header &H) {
+  switch (H.kind()) {
+  case Header::Physical:
+    return OS << H.physical()->getName();
+  case Header::Standard:
+    return OS << H.standard().name();
+  }
+  llvm_unreachable("Unhandled Header kind");
+}
+
+} // namespace clang::include_cleaner