PPCallbacks.h revision ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0ed
1//===--- PPCallbacks.h - Callbacks for Preprocessor actions -----*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file defines the PPCallbacks interface.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_LEX_PPCALLBACKS_H
15#define LLVM_CLANG_LEX_PPCALLBACKS_H
16
17#include "clang/Lex/DirectoryLookup.h"
18#include "clang/Basic/SourceLocation.h"
19#include "llvm/ADT/StringRef.h"
20#include <string>
21
22namespace clang {
23  class SourceLocation;
24  class Token;
25  class IdentifierInfo;
26  class MacroInfo;
27
28/// PPCallbacks - This interface provides a way to observe the actions of the
29/// preprocessor as it does its thing.  Clients can define their hooks here to
30/// implement preprocessor level tools.
31class PPCallbacks {
32public:
33  virtual ~PPCallbacks();
34
35  enum FileChangeReason {
36    EnterFile, ExitFile, SystemHeaderPragma, RenameFile
37  };
38
39  /// FileChanged - This callback is invoked whenever a source file is
40  /// entered or exited.  The SourceLocation indicates the new location, and
41  /// EnteringFile indicates whether this is because we are entering a new
42  /// #include'd file (when true) or whether we're exiting one because we ran
43  /// off the end (when false).
44  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
45                           SrcMgr::CharacteristicKind FileType) {
46  }
47
48  /// FileSkipped - This callback is invoked whenever a source file is
49  /// skipped as the result of header guard optimization.  ParentFile
50  /// is the file that #includes the skipped file.  FilenameTok is the
51  /// token in ParentFile that indicates the skipped file.
52  virtual void FileSkipped(const FileEntry &ParentFile,
53                           const Token &FilenameTok,
54                           SrcMgr::CharacteristicKind FileType) {
55  }
56
57  /// \brief This callback is invoked whenever an inclusion directive of
58  /// any kind (\c #include, \c #import, etc.) has been processed, regardless
59  /// of whether the inclusion will actually result in an inclusion.
60  ///
61  /// \param HashLoc The location of the '#' that starts the inclusion
62  /// directive.
63  ///
64  /// \param IncludeTok The token that indicates the kind of inclusion
65  /// directive, e.g., 'include' or 'import'.
66  ///
67  /// \param FileName The name of the file being included, as written in the
68  /// source code.
69  ///
70  /// \param IsAngled Whether the file name was enclosed in angle brackets;
71  /// otherwise, it was enclosed in quotes.
72  ///
73  /// \param File The actual file that may be included by this inclusion
74  /// directive.
75  ///
76  /// \param EndLoc The location of the last token within the inclusion
77  /// directive.
78  virtual void InclusionDirective(SourceLocation HashLoc,
79                                  const Token &IncludeTok,
80                                  llvm::StringRef FileName,
81                                  bool IsAngled,
82                                  const FileEntry *File,
83                                  SourceLocation EndLoc) {
84  }
85
86  /// EndOfMainFile - This callback is invoked when the end of the main file is
87  /// reach, no subsequent callbacks will be made.
88  virtual void EndOfMainFile() {
89  }
90
91  /// Ident - This callback is invoked when a #ident or #sccs directive is read.
92  ///
93  virtual void Ident(SourceLocation Loc, const std::string &str) {
94  }
95
96  /// PragmaComment - This callback is invoked when a #pragma comment directive
97  /// is read.
98  ///
99  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
100                             const std::string &Str) {
101  }
102
103  /// PragmaMessage - This callback is invoked when a #pragma message directive
104  /// is read.
105  ///
106  virtual void PragmaMessage(SourceLocation Loc, llvm::StringRef Str) {
107  }
108
109  /// MacroExpands - This is called by
110  /// Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is
111  /// found.
112  virtual void MacroExpands(const Token &Id, const MacroInfo* MI) {
113  }
114
115  /// MacroDefined - This hook is called whenever a macro definition is seen.
116  virtual void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI) {
117  }
118
119  /// MacroUndefined - This hook is called whenever a macro #undef is seen.
120  /// MI is released immediately following this callback.
121  virtual void MacroUndefined(SourceLocation Loc, const IdentifierInfo *II,
122                              const MacroInfo *MI) {
123  }
124};
125
126/// PPChainedCallbacks - Simple wrapper class for chaining callbacks.
127class PPChainedCallbacks : public PPCallbacks {
128  PPCallbacks *First, *Second;
129
130public:
131  PPChainedCallbacks(PPCallbacks *_First, PPCallbacks *_Second)
132    : First(_First), Second(_Second) {}
133  ~PPChainedCallbacks() {
134    delete Second;
135    delete First;
136  }
137
138  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
139                           SrcMgr::CharacteristicKind FileType) {
140    First->FileChanged(Loc, Reason, FileType);
141    Second->FileChanged(Loc, Reason, FileType);
142  }
143
144  virtual void FileSkipped(const FileEntry &ParentFile,
145                           const Token &FilenameTok,
146                           SrcMgr::CharacteristicKind FileType) {
147    First->FileSkipped(ParentFile, FilenameTok, FileType);
148    Second->FileSkipped(ParentFile, FilenameTok, FileType);
149  }
150
151  virtual void EndOfMainFile() {
152    First->EndOfMainFile();
153    Second->EndOfMainFile();
154  }
155
156  virtual void Ident(SourceLocation Loc, const std::string &str) {
157    First->Ident(Loc, str);
158    Second->Ident(Loc, str);
159  }
160
161  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
162                             const std::string &Str) {
163    First->PragmaComment(Loc, Kind, Str);
164    Second->PragmaComment(Loc, Kind, Str);
165  }
166
167  virtual void PragmaMessage(SourceLocation Loc, llvm::StringRef Str) {
168    First->PragmaMessage(Loc, Str);
169    Second->PragmaMessage(Loc, Str);
170  }
171
172  virtual void MacroExpands(const Token &Id, const MacroInfo* MI) {
173    First->MacroExpands(Id, MI);
174    Second->MacroExpands(Id, MI);
175  }
176
177  virtual void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI) {
178    First->MacroDefined(II, MI);
179    Second->MacroDefined(II, MI);
180  }
181
182  virtual void MacroUndefined(SourceLocation Loc, const IdentifierInfo *II,
183                              const MacroInfo *MI) {
184    First->MacroUndefined(Loc, II, MI);
185    Second->MacroUndefined(Loc, II, MI);
186  }
187};
188
189}  // end namespace clang
190
191#endif
192