brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.8 KiB · 2dcb5ea Raw
154 lines · c
1//===--- Record.h - Record compiler events ------------------------- 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-exception6//7//===----------------------------------------------------------------------===//8//9// Where Analysis.h analyzes AST nodes and recorded preprocessor events, this10// file defines ways to capture AST and preprocessor information from a parse.11//12// These are the simplest way to connect include-cleaner logic to the parser,13// but other ways are possible (for example clangd records includes separately).14//15//===----------------------------------------------------------------------===//16 17#ifndef CLANG_INCLUDE_CLEANER_RECORD_H18#define CLANG_INCLUDE_CLEANER_RECORD_H19 20#include "clang-include-cleaner/Types.h"21#include "clang/Basic/SourceLocation.h"22#include "llvm/ADT/DenseMap.h"23#include "llvm/ADT/DenseSet.h"24#include "llvm/ADT/SmallVector.h"25#include "llvm/ADT/StringRef.h"26#include "llvm/Support/Allocator.h"27#include "llvm/Support/FileSystem/UniqueID.h"28#include <memory>29#include <vector>30 31namespace clang {32class ASTConsumer;33class ASTContext;34class CompilerInstance;35class Decl;36class FileEntry;37class Preprocessor;38class PPCallbacks;39class FileManager;40 41namespace include_cleaner {42 43/// Captures #include mapping information. It analyses IWYU Pragma comments and44/// other use-instead-like mechanisms (#pragma include_instead) on included45/// files.46///47/// This is a low-level piece being used in the "Location => Header" analysis48/// step to determine the final public header rather than the header directly49/// defines the symbol.50class PragmaIncludes {51public:52  /// Installs an analysing PPCallback and CommentHandler and populates results53  /// to the structure.54  void record(const CompilerInstance &CI);55 56  /// Installs an analysing PPCallback and CommentHandler and populates results57  /// to the structure.58  void record(Preprocessor &P);59 60  /// Returns true if the given #include of the main-file should never be61  /// removed.62  bool shouldKeep(const FileEntry *FE) const;63 64  /// Returns the public mapping include for the given physical header file.65  /// Returns "" if there is none.66  llvm::StringRef getPublic(const FileEntry *File) const;67 68  /// Returns all direct exporter headers for the given header file.69  /// Returns empty if there is none.70  llvm::SmallVector<FileEntryRef> getExporters(const FileEntry *File,71                                               FileManager &FM) const;72  llvm::SmallVector<FileEntryRef> getExporters(tooling::stdlib::Header,73                                               FileManager &FM) const;74 75  /// Returns true if the given file is a self-contained file.76  bool isSelfContained(const FileEntry *File) const;77 78  /// Returns true if the given file is marked with the IWYU private pragma.79  bool isPrivate(const FileEntry *File) const;80 81private:82  class RecordPragma;83 84  /// The public header mapping by the IWYU private pragma. For private pragmas85  //  without public mapping an empty StringRef is stored.86  //87  // !!NOTE: instead of using a FileEntry* to identify the physical file, we88  // deliberately use the UniqueID to ensure the result is stable across89  // FileManagers (for clangd's preamble and main-file builds).90  llvm::DenseMap<llvm::sys::fs::UniqueID, llvm::StringRef /*VerbatimSpelling*/>91      IWYUPublic;92 93  /// A reverse map from the underlying header to its exporter headers.94  ///95  /// There's no way to get a FileEntry from a UniqueID, especially when it96  /// hasn't been opened before. So store the path and convert it to a97  /// FileEntry by opening the file again through a FileManager.98  ///99  /// We don't use RealPathName, as opening the file through a different name100  /// changes its preferred name. Clearly this is fragile!101  llvm::DenseMap<llvm::sys::fs::UniqueID,102                 llvm::SmallVector</*FileEntry::getName()*/ llvm::StringRef>>103      IWYUExportBy;104  llvm::DenseMap<tooling::stdlib::Header,105                 llvm::SmallVector</*FileEntry::getName()*/ llvm::StringRef>>106      StdIWYUExportBy;107 108  /// Contains all non self-contained files detected during the parsing.109  llvm::DenseSet<llvm::sys::fs::UniqueID> NonSelfContainedFiles;110  // Files whose inclusions shouldn't be dropped. E.g. because they have an111  // always_keep pragma or because user marked particular includes with112  // keep/export pragmas in the main file.113  llvm::DenseSet<llvm::sys::fs::UniqueID> ShouldKeep;114 115  /// Owns the strings.116  /// Each record() pushes a new one, while keeping all the old strings alive.117  std::vector<std::shared_ptr<const llvm::BumpPtrAllocator>> Arena;118 119  // FIXME: add support for clang use_instead pragma120};121 122/// Recorded main-file parser events relevant to include-cleaner.123struct RecordedAST {124  /// The consumer (when installed into clang) tracks declarations in `*this`.125  std::unique_ptr<ASTConsumer> record();126 127  ASTContext *Ctx = nullptr;128  /// The set of declarations written at file scope inside the main file.129  ///130  /// These are the roots of the subtrees that should be traversed to find uses.131  /// (Traversing the TranslationUnitDecl would find uses inside headers!)132  std::vector<Decl *> Roots;133};134 135/// Recorded main-file preprocessor events relevant to include-cleaner.136///137/// This doesn't include facts that we record globally for the whole TU, even138/// when they occur in the main file (e.g. IWYU pragmas).139struct RecordedPP {140  /// The callback (when installed into clang) tracks macros/includes in this.141  std::unique_ptr<PPCallbacks> record(const Preprocessor &PP);142 143  /// Describes where macros were used in the main file.144  std::vector<SymbolReference> MacroReferences;145 146  /// The include directives seen in the main file.147  include_cleaner::Includes Includes;148};149 150} // namespace include_cleaner151} // namespace clang152 153#endif154