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 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
//===- 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 llvm {
namespace vfs {
class OverlayFileSystem;
class InMemoryFileSystem;
} // namespace vfs
} // namespace llvm
namespace clang {
class CompilerInstance;
namespace serialization {
class ModuleFile;
} // namespace serialization
namespace tooling {
/// 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();
/// 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, Optional<FileEntryRef> ,
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> PP;
bool EnteredMainFile = false;
bool StartedLexing = false;
Token CurrentToken;
};
} // namespace tooling
} // namespace clang
#endif // LLVM_CLANG_TOOLING_EXPANDMODULARHEADERSPPCALLBACKS_H_
|