diff options
Diffstat (limited to 'clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h')
-rw-r--r-- | clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h new file mode 100644 index 00000000000..eff456e4ce4 --- /dev/null +++ b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h @@ -0,0 +1,137 @@ +//===- ExpandModularHeadersPPCallbacks.h - clang-tidy -----------*- 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 LLVM_CLANG_TOOLING_EXPANDMODULARHEADERSPPCALLBACKS_H_ +#define LLVM_CLANG_TOOLING_EXPANDMODULARHEADERSPPCALLBACKS_H_ + +#include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/Preprocessor.h" +#include "llvm/ADT/DenseSet.h" + +namespace clang { +class CompilerInstance; + +namespace serialization { +class ModuleFile; +} // namespace serialization + +namespace tooling { + +/// \brief Handles PPCallbacks and re-runs preprocessing of the whole +/// translation unit with modules disabled. +/// +/// This way it's possible to get PPCallbacks for the whole translation unit +/// including the contents of the modular headers and all their transitive +/// includes. +/// +/// This allows existing tools based on PPCallbacks to retain their functionality +/// when running with C++ modules enabled. This only works in the backwards +/// compatible modules mode, i.e. when code can still be parsed in non-modular +/// way. +class ExpandModularHeadersPPCallbacks : public PPCallbacks { +public: + ExpandModularHeadersPPCallbacks( + CompilerInstance *Compiler, + IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS); + ~ExpandModularHeadersPPCallbacks(); + + /// \brief Returns the preprocessor that provides callbacks for the whole + /// translation unit, including the main file, textual headers, and modular + /// headers. + /// + /// This preprocessor is separate from the one used by the rest of the + /// compiler. + Preprocessor *getPreprocessor() const; + +private: + class FileRecorder; + + void handleModuleFile(serialization::ModuleFile *MF); + void parseToLocation(SourceLocation Loc); + + // Handle PPCallbacks. + void FileChanged(SourceLocation Loc, FileChangeReason Reason, + SrcMgr::CharacteristicKind FileType, + FileID PrevFID) override; + + void InclusionDirective(SourceLocation DirectiveLoc, + const Token &IncludeToken, StringRef IncludedFilename, + bool IsAngled, CharSourceRange FilenameRange, + const FileEntry *IncludedFile, StringRef SearchPath, + StringRef RelativePath, const Module *Imported, + SrcMgr::CharacteristicKind FileType) override; + + void EndOfMainFile() override; + + // Handle all other callbacks. + // Just parse to the corresponding location to generate PPCallbacks for the + // corresponding range + void Ident(SourceLocation Loc, StringRef) override; + void PragmaDirective(SourceLocation Loc, PragmaIntroducerKind) override; + void PragmaComment(SourceLocation Loc, const IdentifierInfo *, + StringRef) override; + void PragmaDetectMismatch(SourceLocation Loc, StringRef, StringRef) override; + void PragmaDebug(SourceLocation Loc, StringRef) override; + void PragmaMessage(SourceLocation Loc, StringRef, PragmaMessageKind, + StringRef) override; + void PragmaDiagnosticPush(SourceLocation Loc, StringRef) override; + void PragmaDiagnosticPop(SourceLocation Loc, StringRef) override; + void PragmaDiagnostic(SourceLocation Loc, StringRef, diag::Severity, + StringRef) override; + void HasInclude(SourceLocation Loc, StringRef, bool, const FileEntry *, + SrcMgr::CharacteristicKind) override; + void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *, + SourceLocation StateLoc, unsigned) override; + void PragmaWarning(SourceLocation Loc, StringRef, ArrayRef<int>) override; + void PragmaWarningPush(SourceLocation Loc, int) override; + void PragmaWarningPop(SourceLocation Loc) override; + void PragmaAssumeNonNullBegin(SourceLocation Loc) override; + void PragmaAssumeNonNullEnd(SourceLocation Loc) override; + void MacroExpands(const Token &MacroNameTok, const MacroDefinition &, + SourceRange Range, const MacroArgs *) override; + void MacroDefined(const Token &MacroNameTok, + const MacroDirective *MD) override; + void MacroUndefined(const Token &, const MacroDefinition &, + const MacroDirective *Undef) override; + void Defined(const Token &MacroNameTok, const MacroDefinition &, + SourceRange Range) override; + void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override; + void If(SourceLocation Loc, SourceRange, ConditionValueKind) override; + void Elif(SourceLocation Loc, SourceRange, ConditionValueKind, + SourceLocation) override; + void Ifdef(SourceLocation Loc, const Token &, + const MacroDefinition &) override; + void Ifndef(SourceLocation Loc, const Token &, + const MacroDefinition &) override; + void Else(SourceLocation Loc, SourceLocation) override; + void Endif(SourceLocation Loc, SourceLocation) override; + + std::unique_ptr<FileRecorder> Recorder; + // Set of all the modules visited. Avoids processing a module more than once. + llvm::DenseSet<serialization::ModuleFile *> VisitedModules; + + CompilerInstance &Compiler; + // Additional filesystem for replay. Provides all input files from modules. + llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFs; + + SourceManager &Sources; + DiagnosticsEngine Diags; + LangOptions LangOpts; + TrivialModuleLoader ModuleLoader; + + std::unique_ptr<HeaderSearch> HeaderInfo; + std::unique_ptr<Preprocessor> Preprocessor; + bool EnteredMainFile = false; + bool StartedLexing = false; + Token CurrentToken; +}; + +} // namespace tooling +} // namespace clang + +#endif // LLVM_CLANG_TOOLING_EXPANDMODULARHEADERSPPCALLBACKS_H_ |