clang  15.0.0git
InclusionRewriter.cpp
Go to the documentation of this file.
1 //===--- InclusionRewriter.cpp - Rewrite includes into their expansions ---===//
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 code rewrites include invocations into their expansions. This gives you
10 // a file with all included files merged into it.
11 //
12 //===----------------------------------------------------------------------===//
13 
17 #include "clang/Lex/Pragma.h"
18 #include "clang/Lex/Preprocessor.h"
19 #include "llvm/ADT/SmallString.h"
20 #include "llvm/Support/raw_ostream.h"
21 
22 using namespace clang;
23 using namespace llvm;
24 
25 namespace {
26 
27 class InclusionRewriter : public PPCallbacks {
28  /// Information about which #includes were actually performed,
29  /// created by preprocessor callbacks.
30  struct IncludedFile {
31  FileID Id;
33  IncludedFile(FileID Id, SrcMgr::CharacteristicKind FileType)
34  : Id(Id), FileType(FileType) {}
35  };
36  Preprocessor &PP; ///< Used to find inclusion directives.
37  SourceManager &SM; ///< Used to read and manage source files.
38  raw_ostream &OS; ///< The destination stream for rewritten contents.
39  StringRef MainEOL; ///< The line ending marker to use.
40  llvm::MemoryBufferRef PredefinesBuffer; ///< The preprocessor predefines.
41  bool ShowLineMarkers; ///< Show #line markers.
42  bool UseLineDirectives; ///< Use of line directives or line markers.
43  /// Tracks where inclusions that change the file are found.
44  std::map<SourceLocation, IncludedFile> FileIncludes;
45  /// Tracks where inclusions that import modules are found.
46  std::map<SourceLocation, const Module *> ModuleIncludes;
47  /// Tracks where inclusions that enter modules (in a module build) are found.
48  std::map<SourceLocation, const Module *> ModuleEntryIncludes;
49  /// Tracks where #if and #elif directives get evaluated and whether to true.
50  std::map<SourceLocation, bool> IfConditions;
51  /// Used transitively for building up the FileIncludes mapping over the
52  /// various \c PPCallbacks callbacks.
53  SourceLocation LastInclusionLocation;
54 public:
55  InclusionRewriter(Preprocessor &PP, raw_ostream &OS, bool ShowLineMarkers,
56  bool UseLineDirectives);
57  void Process(FileID FileId, SrcMgr::CharacteristicKind FileType);
58  void setPredefinesBuffer(const llvm::MemoryBufferRef &Buf) {
59  PredefinesBuffer = Buf;
60  }
61  void detectMainFileEOL();
62  void handleModuleBegin(Token &Tok) {
63  assert(Tok.getKind() == tok::annot_module_begin);
64  ModuleEntryIncludes.insert(
65  {Tok.getLocation(), (Module *)Tok.getAnnotationValue()});
66  }
67 private:
68  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
70  FileID PrevFID) override;
71  void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok,
72  SrcMgr::CharacteristicKind FileType) override;
73  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
74  StringRef FileName, bool IsAngled,
75  CharSourceRange FilenameRange,
76  Optional<FileEntryRef> File, StringRef SearchPath,
77  StringRef RelativePath, const Module *Imported,
78  SrcMgr::CharacteristicKind FileType) override;
79  void If(SourceLocation Loc, SourceRange ConditionRange,
80  ConditionValueKind ConditionValue) override;
81  void Elif(SourceLocation Loc, SourceRange ConditionRange,
82  ConditionValueKind ConditionValue, SourceLocation IfLoc) override;
83  void WriteLineInfo(StringRef Filename, int Line,
85  StringRef Extra = StringRef());
86  void WriteImplicitModuleImport(const Module *Mod);
87  void OutputContentUpTo(const MemoryBufferRef &FromFile, unsigned &WriteFrom,
88  unsigned WriteTo, StringRef EOL, int &lines,
89  bool EnsureNewline);
90  void CommentOutDirective(Lexer &DirectivesLex, const Token &StartToken,
91  const MemoryBufferRef &FromFile, StringRef EOL,
92  unsigned &NextToWrite, int &Lines);
93  const IncludedFile *FindIncludeAtLocation(SourceLocation Loc) const;
94  const Module *FindModuleAtLocation(SourceLocation Loc) const;
95  const Module *FindEnteredModule(SourceLocation Loc) const;
96  bool IsIfAtLocationTrue(SourceLocation Loc) const;
97  StringRef NextIdentifierName(Lexer &RawLex, Token &RawToken);
98 };
99 
100 } // end anonymous namespace
101 
102 /// Initializes an InclusionRewriter with a \p PP source and \p OS destination.
103 InclusionRewriter::InclusionRewriter(Preprocessor &PP, raw_ostream &OS,
104  bool ShowLineMarkers,
105  bool UseLineDirectives)
106  : PP(PP), SM(PP.getSourceManager()), OS(OS), MainEOL("\n"),
107  ShowLineMarkers(ShowLineMarkers), UseLineDirectives(UseLineDirectives),
108  LastInclusionLocation(SourceLocation()) {}
109 
110 /// Write appropriate line information as either #line directives or GNU line
111 /// markers depending on what mode we're in, including the \p Filename and
112 /// \p Line we are located at, using the specified \p EOL line separator, and
113 /// any \p Extra context specifiers in GNU line directives.
114 void InclusionRewriter::WriteLineInfo(StringRef Filename, int Line,
116  StringRef Extra) {
117  if (!ShowLineMarkers)
118  return;
119  if (UseLineDirectives) {
120  OS << "#line" << ' ' << Line << ' ' << '"';
121  OS.write_escaped(Filename);
122  OS << '"';
123  } else {
124  // Use GNU linemarkers as described here:
125  // http://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html
126  OS << '#' << ' ' << Line << ' ' << '"';
127  OS.write_escaped(Filename);
128  OS << '"';
129  if (!Extra.empty())
130  OS << Extra;
131  if (FileType == SrcMgr::C_System)
132  // "`3' This indicates that the following text comes from a system header
133  // file, so certain warnings should be suppressed."
134  OS << " 3";
135  else if (FileType == SrcMgr::C_ExternCSystem)
136  // as above for `3', plus "`4' This indicates that the following text
137  // should be treated as being wrapped in an implicit extern "C" block."
138  OS << " 3 4";
139  }
140  OS << MainEOL;
141 }
142 
143 void InclusionRewriter::WriteImplicitModuleImport(const Module *Mod) {
144  OS << "#pragma clang module import " << Mod->getFullModuleName(true)
145  << " /* clang -frewrite-includes: implicit import */" << MainEOL;
146 }
147 
148 /// FileChanged - Whenever the preprocessor enters or exits a #include file
149 /// it invokes this handler.
150 void InclusionRewriter::FileChanged(SourceLocation Loc,
151  FileChangeReason Reason,
152  SrcMgr::CharacteristicKind NewFileType,
153  FileID) {
154  if (Reason != EnterFile)
155  return;
156  if (LastInclusionLocation.isInvalid())
157  // we didn't reach this file (eg: the main file) via an inclusion directive
158  return;
159  FileID Id = FullSourceLoc(Loc, SM).getFileID();
160  auto P = FileIncludes.insert(
161  std::make_pair(LastInclusionLocation, IncludedFile(Id, NewFileType)));
162  (void)P;
163  assert(P.second && "Unexpected revisitation of the same include directive");
164  LastInclusionLocation = SourceLocation();
165 }
166 
167 /// Called whenever an inclusion is skipped due to canonical header protection
168 /// macros.
169 void InclusionRewriter::FileSkipped(const FileEntryRef & /*SkippedFile*/,
170  const Token & /*FilenameTok*/,
171  SrcMgr::CharacteristicKind /*FileType*/) {
172  assert(LastInclusionLocation.isValid() &&
173  "A file, that wasn't found via an inclusion directive, was skipped");
174  LastInclusionLocation = SourceLocation();
175 }
176 
177 /// This should be called whenever the preprocessor encounters include
178 /// directives. It does not say whether the file has been included, but it
179 /// provides more information about the directive (hash location instead
180 /// of location inside the included file). It is assumed that the matching
181 /// FileChanged() or FileSkipped() is called after this (or neither is
182 /// called if this #include results in an error or does not textually include
183 /// anything).
184 void InclusionRewriter::InclusionDirective(SourceLocation HashLoc,
185  const Token &/*IncludeTok*/,
186  StringRef /*FileName*/,
187  bool /*IsAngled*/,
188  CharSourceRange /*FilenameRange*/,
189  Optional<FileEntryRef> /*File*/,
190  StringRef /*SearchPath*/,
191  StringRef /*RelativePath*/,
192  const Module *Imported,
193  SrcMgr::CharacteristicKind FileType){
194  if (Imported) {
195  auto P = ModuleIncludes.insert(std::make_pair(HashLoc, Imported));
196  (void)P;
197  assert(P.second && "Unexpected revisitation of the same include directive");
198  } else
199  LastInclusionLocation = HashLoc;
200 }
201 
202 void InclusionRewriter::If(SourceLocation Loc, SourceRange ConditionRange,
203  ConditionValueKind ConditionValue) {
204  auto P = IfConditions.insert(std::make_pair(Loc, ConditionValue == CVK_True));
205  (void)P;
206  assert(P.second && "Unexpected revisitation of the same if directive");
207 }
208 
209 void InclusionRewriter::Elif(SourceLocation Loc, SourceRange ConditionRange,
210  ConditionValueKind ConditionValue,
211  SourceLocation IfLoc) {
212  auto P = IfConditions.insert(std::make_pair(Loc, ConditionValue == CVK_True));
213  (void)P;
214  assert(P.second && "Unexpected revisitation of the same elif directive");
215 }
216 
217 /// Simple lookup for a SourceLocation (specifically one denoting the hash in
218 /// an inclusion directive) in the map of inclusion information, FileChanges.
219 const InclusionRewriter::IncludedFile *
220 InclusionRewriter::FindIncludeAtLocation(SourceLocation Loc) const {
221  const auto I = FileIncludes.find(Loc);
222  if (I != FileIncludes.end())
223  return &I->second;
224  return nullptr;
225 }
226 
227 /// Simple lookup for a SourceLocation (specifically one denoting the hash in
228 /// an inclusion directive) in the map of module inclusion information.
229 const Module *
230 InclusionRewriter::FindModuleAtLocation(SourceLocation Loc) const {
231  const auto I = ModuleIncludes.find(Loc);
232  if (I != ModuleIncludes.end())
233  return I->second;
234  return nullptr;
235 }
236 
237 /// Simple lookup for a SourceLocation (specifically one denoting the hash in
238 /// an inclusion directive) in the map of module entry information.
239 const Module *
240 InclusionRewriter::FindEnteredModule(SourceLocation Loc) const {
241  const auto I = ModuleEntryIncludes.find(Loc);
242  if (I != ModuleEntryIncludes.end())
243  return I->second;
244  return nullptr;
245 }
246 
247 bool InclusionRewriter::IsIfAtLocationTrue(SourceLocation Loc) const {
248  const auto I = IfConditions.find(Loc);
249  if (I != IfConditions.end())
250  return I->second;
251  return false;
252 }
253 
254 void InclusionRewriter::detectMainFileEOL() {
255  Optional<MemoryBufferRef> FromFile = *SM.getBufferOrNone(SM.getMainFileID());
256  assert(FromFile);
257  if (!FromFile)
258  return; // Should never happen, but whatever.
259  MainEOL = FromFile->getBuffer().detectEOL();
260 }
261 
262 /// Writes out bytes from \p FromFile, starting at \p NextToWrite and ending at
263 /// \p WriteTo - 1.
264 void InclusionRewriter::OutputContentUpTo(const MemoryBufferRef &FromFile,
265  unsigned &WriteFrom, unsigned WriteTo,
266  StringRef LocalEOL, int &Line,
267  bool EnsureNewline) {
268  if (WriteTo <= WriteFrom)
269  return;
270  if (FromFile == PredefinesBuffer) {
271  // Ignore the #defines of the predefines buffer.
272  WriteFrom = WriteTo;
273  return;
274  }
275 
276  // If we would output half of a line ending, advance one character to output
277  // the whole line ending. All buffers are null terminated, so looking ahead
278  // one byte is safe.
279  if (LocalEOL.size() == 2 &&
280  LocalEOL[0] == (FromFile.getBufferStart() + WriteTo)[-1] &&
281  LocalEOL[1] == (FromFile.getBufferStart() + WriteTo)[0])
282  WriteTo++;
283 
284  StringRef TextToWrite(FromFile.getBufferStart() + WriteFrom,
285  WriteTo - WriteFrom);
286 
287  if (MainEOL == LocalEOL) {
288  OS << TextToWrite;
289  // count lines manually, it's faster than getPresumedLoc()
290  Line += TextToWrite.count(LocalEOL);
291  if (EnsureNewline && !TextToWrite.endswith(LocalEOL))
292  OS << MainEOL;
293  } else {
294  // Output the file one line at a time, rewriting the line endings as we go.
295  StringRef Rest = TextToWrite;
296  while (!Rest.empty()) {
297  StringRef LineText;
298  std::tie(LineText, Rest) = Rest.split(LocalEOL);
299  OS << LineText;
300  Line++;
301  if (!Rest.empty())
302  OS << MainEOL;
303  }
304  if (TextToWrite.endswith(LocalEOL) || EnsureNewline)
305  OS << MainEOL;
306  }
307  WriteFrom = WriteTo;
308 }
309 
310 /// Print characters from \p FromFile starting at \p NextToWrite up until the
311 /// inclusion directive at \p StartToken, then print out the inclusion
312 /// inclusion directive disabled by a #if directive, updating \p NextToWrite
313 /// and \p Line to track the number of source lines visited and the progress
314 /// through the \p FromFile buffer.
315 void InclusionRewriter::CommentOutDirective(Lexer &DirectiveLex,
316  const Token &StartToken,
317  const MemoryBufferRef &FromFile,
318  StringRef LocalEOL,
319  unsigned &NextToWrite, int &Line) {
320  OutputContentUpTo(FromFile, NextToWrite,
321  SM.getFileOffset(StartToken.getLocation()), LocalEOL, Line,
322  false);
323  Token DirectiveToken;
324  do {
325  DirectiveLex.LexFromRawLexer(DirectiveToken);
326  } while (!DirectiveToken.is(tok::eod) && DirectiveToken.isNot(tok::eof));
327  if (FromFile == PredefinesBuffer) {
328  // OutputContentUpTo() would not output anything anyway.
329  return;
330  }
331  OS << "#if 0 /* expanded by -frewrite-includes */" << MainEOL;
332  OutputContentUpTo(FromFile, NextToWrite,
333  SM.getFileOffset(DirectiveToken.getLocation()) +
334  DirectiveToken.getLength(),
335  LocalEOL, Line, true);
336  OS << "#endif /* expanded by -frewrite-includes */" << MainEOL;
337 }
338 
339 /// Find the next identifier in the pragma directive specified by \p RawToken.
340 StringRef InclusionRewriter::NextIdentifierName(Lexer &RawLex,
341  Token &RawToken) {
342  RawLex.LexFromRawLexer(RawToken);
343  if (RawToken.is(tok::raw_identifier))
344  PP.LookUpIdentifierInfo(RawToken);
345  if (RawToken.is(tok::identifier))
346  return RawToken.getIdentifierInfo()->getName();
347  return StringRef();
348 }
349 
350 /// Use a raw lexer to analyze \p FileId, incrementally copying parts of it
351 /// and including content of included files recursively.
352 void InclusionRewriter::Process(FileID FileId,
353  SrcMgr::CharacteristicKind FileType) {
354  MemoryBufferRef FromFile;
355  {
356  auto B = SM.getBufferOrNone(FileId);
357  assert(B && "Attempting to process invalid inclusion");
358  if (B)
359  FromFile = *B;
360  }
361  StringRef FileName = FromFile.getBufferIdentifier();
362  Lexer RawLex(FileId, FromFile, PP.getSourceManager(), PP.getLangOpts());
363  RawLex.SetCommentRetentionState(false);
364 
365  StringRef LocalEOL = FromFile.getBuffer().detectEOL();
366 
367  // Per the GNU docs: "1" indicates entering a new file.
368  if (FileId == SM.getMainFileID() || FileId == PP.getPredefinesFileID())
369  WriteLineInfo(FileName, 1, FileType, "");
370  else
371  WriteLineInfo(FileName, 1, FileType, " 1");
372 
373  if (SM.getFileIDSize(FileId) == 0)
374  return;
375 
376  // The next byte to be copied from the source file, which may be non-zero if
377  // the lexer handled a BOM.
378  unsigned NextToWrite = SM.getFileOffset(RawLex.getSourceLocation());
379  assert(SM.getLineNumber(FileId, NextToWrite) == 1);
380  int Line = 1; // The current input file line number.
381 
382  Token RawToken;
383  RawLex.LexFromRawLexer(RawToken);
384 
385  // TODO: Consider adding a switch that strips possibly unimportant content,
386  // such as comments, to reduce the size of repro files.
387  while (RawToken.isNot(tok::eof)) {
388  if (RawToken.is(tok::hash) && RawToken.isAtStartOfLine()) {
389  RawLex.setParsingPreprocessorDirective(true);
390  Token HashToken = RawToken;
391  RawLex.LexFromRawLexer(RawToken);
392  if (RawToken.is(tok::raw_identifier))
393  PP.LookUpIdentifierInfo(RawToken);
394  if (RawToken.getIdentifierInfo() != nullptr) {
395  switch (RawToken.getIdentifierInfo()->getPPKeywordID()) {
396  case tok::pp_include:
398  case tok::pp_import: {
399  CommentOutDirective(RawLex, HashToken, FromFile, LocalEOL, NextToWrite,
400  Line);
401  if (FileId != PP.getPredefinesFileID())
402  WriteLineInfo(FileName, Line - 1, FileType, "");
403  StringRef LineInfoExtra;
404  SourceLocation Loc = HashToken.getLocation();
405  if (const Module *Mod = FindModuleAtLocation(Loc))
406  WriteImplicitModuleImport(Mod);
407  else if (const IncludedFile *Inc = FindIncludeAtLocation(Loc)) {
408  const Module *Mod = FindEnteredModule(Loc);
409  if (Mod)
410  OS << "#pragma clang module begin "
411  << Mod->getFullModuleName(true) << "\n";
412 
413  // Include and recursively process the file.
414  Process(Inc->Id, Inc->FileType);
415 
416  if (Mod)
417  OS << "#pragma clang module end /*"
418  << Mod->getFullModuleName(true) << "*/\n";
419 
420  // Add line marker to indicate we're returning from an included
421  // file.
422  LineInfoExtra = " 2";
423  }
424  // fix up lineinfo (since commented out directive changed line
425  // numbers) for inclusions that were skipped due to header guards
426  WriteLineInfo(FileName, Line, FileType, LineInfoExtra);
427  break;
428  }
429  case tok::pp_pragma: {
430  StringRef Identifier = NextIdentifierName(RawLex, RawToken);
431  if (Identifier == "clang" || Identifier == "GCC") {
432  if (NextIdentifierName(RawLex, RawToken) == "system_header") {
433  // keep the directive in, commented out
434  CommentOutDirective(RawLex, HashToken, FromFile, LocalEOL,
435  NextToWrite, Line);
436  // update our own type
437  FileType = SM.getFileCharacteristic(RawToken.getLocation());
438  WriteLineInfo(FileName, Line, FileType);
439  }
440  } else if (Identifier == "once") {
441  // keep the directive in, commented out
442  CommentOutDirective(RawLex, HashToken, FromFile, LocalEOL,
443  NextToWrite, Line);
444  WriteLineInfo(FileName, Line, FileType);
445  }
446  break;
447  }
448  case tok::pp_if:
449  case tok::pp_elif: {
450  bool elif = (RawToken.getIdentifierInfo()->getPPKeywordID() ==
451  tok::pp_elif);
452  bool isTrue = IsIfAtLocationTrue(RawToken.getLocation());
453  OutputContentUpTo(FromFile, NextToWrite,
454  SM.getFileOffset(HashToken.getLocation()),
455  LocalEOL, Line, /*EnsureNewline=*/true);
456  do {
457  RawLex.LexFromRawLexer(RawToken);
458  } while (!RawToken.is(tok::eod) && RawToken.isNot(tok::eof));
459  // We need to disable the old condition, but that is tricky.
460  // Trying to comment it out can easily lead to comment nesting.
461  // So instead make the condition harmless by making it enclose
462  // and empty block. Moreover, put it itself inside an #if 0 block
463  // to disable it from getting evaluated (e.g. __has_include_next
464  // warns if used from the primary source file).
465  OS << "#if 0 /* disabled by -frewrite-includes */" << MainEOL;
466  if (elif) {
467  OS << "#if 0" << MainEOL;
468  }
469  OutputContentUpTo(FromFile, NextToWrite,
470  SM.getFileOffset(RawToken.getLocation()) +
471  RawToken.getLength(),
472  LocalEOL, Line, /*EnsureNewline=*/true);
473  // Close the empty block and the disabling block.
474  OS << "#endif" << MainEOL;
475  OS << "#endif /* disabled by -frewrite-includes */" << MainEOL;
476  OS << (elif ? "#elif " : "#if ") << (isTrue ? "1" : "0")
477  << " /* evaluated by -frewrite-includes */" << MainEOL;
478  WriteLineInfo(FileName, Line, FileType);
479  break;
480  }
481  case tok::pp_endif:
482  case tok::pp_else: {
483  // We surround every #include by #if 0 to comment it out, but that
484  // changes line numbers. These are fixed up right after that, but
485  // the whole #include could be inside a preprocessor conditional
486  // that is not processed. So it is necessary to fix the line
487  // numbers one the next line after each #else/#endif as well.
488  RawLex.SetKeepWhitespaceMode(true);
489  do {
490  RawLex.LexFromRawLexer(RawToken);
491  } while (RawToken.isNot(tok::eod) && RawToken.isNot(tok::eof));
492  OutputContentUpTo(FromFile, NextToWrite,
493  SM.getFileOffset(RawToken.getLocation()) +
494  RawToken.getLength(),
495  LocalEOL, Line, /*EnsureNewline=*/ true);
496  WriteLineInfo(FileName, Line, FileType);
497  RawLex.SetKeepWhitespaceMode(false);
498  break;
499  }
500  default:
501  break;
502  }
503  }
504  RawLex.setParsingPreprocessorDirective(false);
505  }
506  RawLex.LexFromRawLexer(RawToken);
507  }
508  OutputContentUpTo(FromFile, NextToWrite,
509  SM.getFileOffset(SM.getLocForEndOfFile(FileId)), LocalEOL,
510  Line, /*EnsureNewline=*/true);
511 }
512 
513 /// InclusionRewriterInInput - Implement -frewrite-includes mode.
514 void clang::RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS,
515  const PreprocessorOutputOptions &Opts) {
517  InclusionRewriter *Rewrite = new InclusionRewriter(
518  PP, *OS, Opts.ShowLineMarkers, Opts.UseLineDirectives);
519  Rewrite->detectMainFileEOL();
520 
521  PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Rewrite));
522  PP.IgnorePragmas();
523 
524  // First let the preprocessor process the entire file and call callbacks.
525  // Callbacks will record which #include's were actually performed.
526  PP.EnterMainSourceFile();
527  Token Tok;
528  // Only preprocessor directives matter here, so disable macro expansion
529  // everywhere else as an optimization.
530  // TODO: It would be even faster if the preprocessor could be switched
531  // to a mode where it would parse only preprocessor directives and comments,
532  // nothing else matters for parsing or processing.
534  do {
535  PP.Lex(Tok);
536  if (Tok.is(tok::annot_module_begin))
537  Rewrite->handleModuleBegin(Tok);
538  } while (Tok.isNot(tok::eof));
539  Rewrite->setPredefinesBuffer(SM.getBufferOrFake(PP.getPredefinesFileID()));
541  Rewrite->Process(SM.getMainFileID(), SrcMgr::C_User);
542  OS->flush();
543 }
llvm
YAML serialization mapping.
Definition: Dominators.h:30
clang::Lexer::SetCommentRetentionState
void SetCommentRetentionState(bool Mode)
SetCommentRetentionMode - Change the comment retention mode of the lexer to the specified mode.
Definition: Lexer.h:244
clang::FileEntryRef
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
Definition: FileEntry.h:60
clang::FullSourceLoc
A SourceLocation and its associated SourceManager.
Definition: SourceLocation.h:368
clang::SourceRange
A trivial tuple used to represent a source range.
Definition: SourceLocation.h:210
clang::Preprocessor::Lex
void Lex(Token &Result)
Lex the next token for this preprocessor.
Definition: Preprocessor.cpp:892
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:86
clang::Module::getFullModuleName
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
Definition: Module.cpp:219
clang::PPCallbacks
This interface provides a way to observe the actions of the preprocessor as it does its thing.
Definition: PPCallbacks.h:35
clang::Preprocessor::IgnorePragmas
void IgnorePragmas()
Install empty handlers for all pragmas (making them ignored).
Definition: Pragma.cpp:2126
clang::Token::getIdentifierInfo
IdentifierInfo * getIdentifierInfo() const
Definition: Token.h:178
clang::TemplateSubstitutionKind::Rewrite
@ Rewrite
We are substituting template parameters for (typically) other template parameters in order to rewrite...
Filename
StringRef Filename
Definition: Format.cpp:2551
clang::Token::isAtStartOfLine
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
Definition: Token.h:267
llvm::Optional< FileEntryRef >
clang::minimize_source_to_dependency_directives::pp_import
@ pp_import
Definition: DependencyDirectivesSourceMinimizer.h:39
SourceManager.h
clang::SrcMgr::CharacteristicKind
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
Definition: SourceManager.h:79
clang::Lexer::LexFromRawLexer
bool LexFromRawLexer(Token &Result)
LexFromRawLexer - Lex a token from a designated raw lexer (one with no associated preprocessor object...
Definition: Lexer.h:211
Identifier
StringRef Identifier
Definition: Format.cpp:2559
clang::Token
Token - This structure provides full information about a lexed token.
Definition: Token.h:34
clang::PreprocessorOutputOptions::ShowLineMarkers
unsigned ShowLineMarkers
Show #line markers.
Definition: PreprocessorOutputOptions.h:20
PreprocessorOutputOptions.h
clang::SourceManager
This class handles loading and caching of source files into memory.
Definition: SourceManager.h:627
clang::Preprocessor::getLangOpts
const LangOptions & getLangOpts() const
Definition: Preprocessor.h:994
Preprocessor.h
clang::Lexer
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
Definition: Lexer.h:77
clang::minimize_source_to_dependency_directives::pp_if
@ pp_if
Definition: DependencyDirectivesSourceMinimizer.h:46
Rewriters.h
clang::Module
Describes a module or submodule.
Definition: Module.h:96
clang::PreprocessorOutputOptions
PreprocessorOutputOptions - Options for controlling the C preprocessor output (e.g....
Definition: PreprocessorOutputOptions.h:16
clang::minimize_source_to_dependency_directives::pp_include_next
@ pp_include_next
Definition: DependencyDirectivesSourceMinimizer.h:45
Id
int Id
Definition: ASTDiff.cpp:191
Pragma.h
clang::Token::getKind
tok::TokenKind getKind() const
Definition: Token.h:92
clang::PreprocessorOutputOptions::UseLineDirectives
unsigned UseLineDirectives
Use #line instead of GCC-style # N.
Definition: PreprocessorOutputOptions.h:21
clang::Token::getAnnotationValue
void * getAnnotationValue() const
Definition: Token.h:225
clang::Token::is
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
Definition: Token.h:97
clang::RewriteIncludesInInput
void RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS, const PreprocessorOutputOptions &Opts)
RewriteIncludesInInput - Implement -frewrite-includes mode.
Definition: InclusionRewriter.cpp:514
clang::minimize_source_to_dependency_directives::pp_include
@ pp_include
Definition: DependencyDirectivesSourceMinimizer.h:35
clang::SrcMgr::C_User
@ C_User
Definition: SourceManager.h:80
clang::Preprocessor::EnterMainSourceFile
void EnterMainSourceFile()
Enter the specified FileID as the main source file, which implicitly adds the builtin defines etc.
Definition: Preprocessor.cpp:535
Line
const AnnotatedLine * Line
Definition: UsingDeclarationsSorter.cpp:68
clang::Token::isNot
bool isNot(tok::TokenKind K) const
Definition: Token.h:98
clang::Lexer::getSourceLocation
SourceLocation getSourceLocation(const char *Loc, unsigned TokLen=1) const
getSourceLocation - Return a source location identifier for the specified offset in the current file.
Definition: Lexer.cpp:1149
clang::PreprocessorLexer::setParsingPreprocessorDirective
void setParsingPreprocessorDirective(bool f)
Inform the lexer whether or not we are currently lexing a preprocessor directive.
Definition: PreprocessorLexer.h:137
clang::minimize_source_to_dependency_directives::pp_else
@ pp_else
Definition: DependencyDirectivesSourceMinimizer.h:52
clang::Token::getLength
unsigned getLength() const
Definition: Token.h:128
clang::Preprocessor::getSourceManager
SourceManager & getSourceManager() const
Definition: Preprocessor.h:998
clang::Preprocessor::SetMacroExpansionOnlyInDirectives
void SetMacroExpansionOnlyInDirectives()
Disables macro expansion everywhere except for preprocessor directives.
Definition: Preprocessor.h:1564
P
StringRef P
Definition: ASTMatchersInternal.cpp:563
clang::InclusionDirective
Record the location of an inclusion directive, such as an #include or #import statement.
Definition: PreprocessingRecord.h:208
clang::CharSourceRange
Represents a character-granular source range.
Definition: SourceLocation.h:253
clang::IdentifierInfo::getPPKeywordID
tok::PPKeywordKind getPPKeywordID() const
Return the preprocessor keyword ID for this identifier.
Definition: IdentifierTable.cpp:324
clang::FullSourceLoc::getFileID
FileID getFileID() const
Definition: SourceLocation.cpp:159
clang::Token::getLocation
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
Definition: Token.h:125
clang::Lexer::SetKeepWhitespaceMode
void SetKeepWhitespaceMode(bool Val)
SetKeepWhitespaceMode - This method lets clients enable or disable whitespace retention mode.
Definition: Lexer.h:229
clang::IdentifierInfo::getName
StringRef getName() const
Return the actual identifier string.
Definition: IdentifierTable.h:195
clang::SourceLocation::isInvalid
bool isInvalid() const
Definition: SourceLocation.h:111
clang
Definition: CalledOnceCheck.h:17
clang::SrcMgr::C_ExternCSystem
@ C_ExternCSystem
Definition: SourceManager.h:82
clang::Preprocessor::addPPCallbacks
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
Definition: Preprocessor.h:1092
clang::Preprocessor::LookUpIdentifierInfo
IdentifierInfo * LookUpIdentifierInfo(Token &Identifier) const
Given a tok::raw_identifier token, look up the identifier information for the token and install it in...
Definition: Preprocessor.cpp:700
clang::FileID
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Definition: SourceLocation.h:38
clang::SourceLocation::isValid
bool isValid() const
Return true if this is a valid SourceLocation object.
Definition: SourceLocation.h:110
clang::minimize_source_to_dependency_directives::pp_endif
@ pp_endif
Definition: DependencyDirectivesSourceMinimizer.h:53
clang::comments::tok::eof
@ eof
Definition: CommentLexer.h:33
clang::SrcMgr::C_System
@ C_System
Definition: SourceManager.h:81
clang::Preprocessor
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Definition: Preprocessor.h:131
SM
#define SM(sm)
Definition: Cuda.cpp:81
clang::Preprocessor::getPredefinesFileID
FileID getPredefinesFileID() const
Returns the FileID for the preprocessor predefines.
Definition: Preprocessor.h:1084
clang::minimize_source_to_dependency_directives::pp_elif
@ pp_elif
Definition: DependencyDirectivesSourceMinimizer.h:49
clang::ento::ObjKind::OS
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...