1//===--- MacroPPCallbacks.h -------------------------------------*- 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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines implementation for the macro preprocessors callbacks.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_LIB_CODEGEN_MACROPPCALLBACKS_H
14#define LLVM_CLANG_LIB_CODEGEN_MACROPPCALLBACKS_H
15
16#include "clang/Lex/PPCallbacks.h"
17
18namespace llvm {
19class DIMacroFile;
20}
21namespace clang {
22class Preprocessor;
23class MacroInfo;
24class CodeGenerator;
25
26class MacroPPCallbacks : public PPCallbacks {
27 /// A pointer to code generator, where debug info generator can be found.
28 CodeGenerator *Gen;
29
30 /// Preprocessor.
31 Preprocessor &PP;
32
33 /// Location of recent included file, used for line number.
34 SourceLocation LastHashLoc;
35
36 /// Counts current number of command line included files, which were entered
37 /// and were not exited yet.
38 int EnteredCommandLineIncludeFiles = 0;
39
40 enum FileScopeStatus {
41 NoScope = 0, // Scope is not initialized yet.
42 InitializedScope, // Main file scope is initialized but not set yet.
43 BuiltinScope, // <built-in> and <command line> file scopes.
44 CommandLineIncludeScope, // Included file, from <command line> file, scope.
45 MainFileScope // Main file scope.
46 };
47 FileScopeStatus Status;
48
49 /// Parent contains all entered files that were not exited yet according to
50 /// the inclusion order.
51 llvm::SmallVector<llvm::DIMacroFile *, 4> Scopes;
52
53 /// Get current DIMacroFile scope.
54 /// \return current DIMacroFile scope or nullptr if there is no such scope.
55 llvm::DIMacroFile *getCurrentScope();
56
57 /// Get current line location or invalid location.
58 /// \param Loc current line location.
59 /// \return current line location \p `Loc`, or invalid location if it's in a
60 /// skipped file scope.
61 SourceLocation getCorrectLocation(SourceLocation Loc);
62
63 /// Use the passed preprocessor to write the macro name and value from the
64 /// given macro info and identifier info into the given \p `Name` and \p
65 /// `Value` output streams.
66 ///
67 /// \param II Identifier info, used to get the Macro name.
68 /// \param MI Macro info, used to get the Macro argumets and values.
69 /// \param PP Preprocessor.
70 /// \param [out] Name Place holder for returned macro name and arguments.
71 /// \param [out] Value Place holder for returned macro value.
72 static void writeMacroDefinition(const IdentifierInfo &II,
73 const MacroInfo &MI, Preprocessor &PP,
74 raw_ostream &Name, raw_ostream &Value);
75
76 /// Update current file scope status to next file scope.
77 void updateStatusToNextScope();
78
79 /// Handle the case when entering a file.
80 ///
81 /// \param Loc Indicates the new location.
82 void FileEntered(SourceLocation Loc);
83
84 /// Handle the case when exiting a file.
85 ///
86 /// \param Loc Indicates the new location.
87 void FileExited(SourceLocation Loc);
88
89public:
90 MacroPPCallbacks(CodeGenerator *Gen, Preprocessor &PP);
91
92 /// Callback invoked whenever a source file is entered or exited.
93 ///
94 /// \param Loc Indicates the new location.
95 /// \param PrevFID the file that was exited if \p Reason is ExitFile.
96 void FileChanged(SourceLocation Loc, FileChangeReason Reason,
97 SrcMgr::CharacteristicKind FileType,
98 FileID PrevFID = FileID()) override;
99
100 /// Callback invoked whenever a directive (#xxx) is processed.
101 void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
102 StringRef FileName, bool IsAngled,
103 CharSourceRange FilenameRange,
104 OptionalFileEntryRef File, StringRef SearchPath,
105 StringRef RelativePath, const Module *SuggestedModule,
106 bool ModuleImported,
107 SrcMgr::CharacteristicKind FileType) override;
108
109 /// Hook called whenever a macro definition is seen.
110 void MacroDefined(const Token &MacroNameTok,
111 const MacroDirective *MD) override;
112
113 /// Hook called whenever a macro \#undef is seen.
114 ///
115 /// MD is released immediately following this callback.
116 void MacroUndefined(const Token &MacroNameTok, const MacroDefinition &MD,
117 const MacroDirective *Undef) override;
118};
119
120} // end namespace clang
121
122#endif
123