147 lines · c
1//===- ExpandModularHeadersPPCallbacks.h - clang-tidy -----------*- 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#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_EXPANDMODULARHEADERSPPCALLBACKS_H10#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_EXPANDMODULARHEADERSPPCALLBACKS_H11 12#include "clang/Lex/HeaderSearchOptions.h"13#include "clang/Lex/PPCallbacks.h"14#include "clang/Lex/Preprocessor.h"15#include "llvm/ADT/DenseSet.h"16 17namespace llvm::vfs {18class OverlayFileSystem;19class InMemoryFileSystem;20} // namespace llvm::vfs21 22namespace clang {23class CompilerInstance;24 25namespace serialization {26class ModuleFile;27} // namespace serialization28 29namespace tooling {30 31/// Handles PPCallbacks and re-runs preprocessing of the whole32/// translation unit with modules disabled.33///34/// This way it's possible to get PPCallbacks for the whole translation unit35/// including the contents of the modular headers and all their transitive36/// includes.37///38/// This allows existing tools based on PPCallbacks to retain their39/// functionality when running with C++ modules enabled. This only works in the40/// backwards compatible modules mode, i.e. when code can still be parsed in41/// non-modular way.42class ExpandModularHeadersPPCallbacks : public PPCallbacks {43public:44 ExpandModularHeadersPPCallbacks(CompilerInstance *CI,45 llvm::vfs::OverlayFileSystem &OverlayFS);46 ~ExpandModularHeadersPPCallbacks() override;47 48 /// Returns the preprocessor that provides callbacks for the whole49 /// translation unit, including the main file, textual headers, and modular50 /// headers.51 ///52 /// This preprocessor is separate from the one used by the rest of the53 /// compiler.54 Preprocessor *getPreprocessor() const;55 56private:57 class FileRecorder;58 59 void handleModuleFile(serialization::ModuleFile *MF);60 void parseToLocation(SourceLocation Loc);61 62 // Handle PPCallbacks.63 void FileChanged(SourceLocation Loc, FileChangeReason Reason,64 SrcMgr::CharacteristicKind FileType,65 FileID PrevFID) override;66 67 void InclusionDirective(SourceLocation DirectiveLoc,68 const Token &IncludeToken, StringRef IncludedFilename,69 bool IsAngled, CharSourceRange FilenameRange,70 OptionalFileEntryRef IncludedFile,71 StringRef SearchPath, StringRef RelativePath,72 const Module *SuggestedModule, bool ModuleImported,73 SrcMgr::CharacteristicKind FileType) override;74 75 void EndOfMainFile() override;76 77 // Handle all other callbacks.78 // Just parse to the corresponding location to generate PPCallbacks for the79 // corresponding range80 void Ident(SourceLocation Loc, StringRef) override;81 void PragmaDirective(SourceLocation Loc, PragmaIntroducerKind) override;82 void PragmaComment(SourceLocation Loc, const IdentifierInfo *,83 StringRef) override;84 void PragmaDetectMismatch(SourceLocation Loc, StringRef, StringRef) override;85 void PragmaDebug(SourceLocation Loc, StringRef) override;86 void PragmaMessage(SourceLocation Loc, StringRef, PragmaMessageKind,87 StringRef) override;88 void PragmaDiagnosticPush(SourceLocation Loc, StringRef) override;89 void PragmaDiagnosticPop(SourceLocation Loc, StringRef) override;90 void PragmaDiagnostic(SourceLocation Loc, StringRef, diag::Severity,91 StringRef) override;92 void HasInclude(SourceLocation Loc, StringRef, bool, OptionalFileEntryRef,93 SrcMgr::CharacteristicKind) override;94 void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *,95 SourceLocation StateLoc, unsigned) override;96 void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier,97 ArrayRef<int>) override;98 void PragmaWarningPush(SourceLocation Loc, int) override;99 void PragmaWarningPop(SourceLocation Loc) override;100 void PragmaAssumeNonNullBegin(SourceLocation Loc) override;101 void PragmaAssumeNonNullEnd(SourceLocation Loc) override;102 void MacroExpands(const Token &MacroNameTok, const MacroDefinition &,103 SourceRange Range, const MacroArgs *) override;104 void MacroDefined(const Token &MacroNameTok,105 const MacroDirective *MD) override;106 void MacroUndefined(const Token &, const MacroDefinition &,107 const MacroDirective *Undef) override;108 void Defined(const Token &MacroNameTok, const MacroDefinition &,109 SourceRange Range) override;110 void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override;111 void If(SourceLocation Loc, SourceRange, ConditionValueKind) override;112 void Elif(SourceLocation Loc, SourceRange, ConditionValueKind,113 SourceLocation) override;114 void Ifdef(SourceLocation Loc, const Token &,115 const MacroDefinition &) override;116 void Ifndef(SourceLocation Loc, const Token &,117 const MacroDefinition &) override;118 void Else(SourceLocation Loc, SourceLocation) override;119 void Endif(SourceLocation Loc, SourceLocation) override;120 121 std::unique_ptr<FileRecorder> Recorder;122 // Set of all the modules visited. Avoids processing a module more than once.123 llvm::DenseSet<serialization::ModuleFile *> VisitedModules;124 125 CompilerInstance &Compiler;126 // Additional filesystem for replay. Provides all input files from modules.127 llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFs;128 129 SourceManager &Sources;130 DiagnosticOptions DiagOpts;131 DiagnosticsEngine Diags;132 LangOptions LangOpts;133 HeaderSearchOptions HSOpts;134 TrivialModuleLoader ModuleLoader;135 136 std::unique_ptr<HeaderSearch> HeaderInfo;137 std::unique_ptr<Preprocessor> PP;138 bool EnteredMainFile = false;139 bool StartedLexing = false;140 Token CurrentToken;141};142 143} // namespace tooling144} // namespace clang145 146#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_EXPANDMODULARHEADERSPPCALLBACKS_H147