InclusionRewriter.cpp revision 1505edfeb85f54f2a982f76542b51e5ddd12b44c
18c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie//===--- InclusionRewriter.cpp - Rewrite includes into their expansions ---===//
28c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie//
38c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie//                     The LLVM Compiler Infrastructure
48c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie//
58c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie// This file is distributed under the University of Illinois Open Source
68c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie// License. See LICENSE.TXT for details.
78c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie//
88c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie//===----------------------------------------------------------------------===//
98c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie//
108c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie// This code rewrites include invocations into their expansions.  This gives you
118c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie// a file with all included files merged into it.
128c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie//
138c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie//===----------------------------------------------------------------------===//
148c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
15305c613af6cfc40e519c75d9d2c84c6fa9a841c0Ted Kremenek#include "clang/Rewrite/Frontend/Rewriters.h"
168c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie#include "clang/Basic/SourceManager.h"
178c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie#include "clang/Frontend/PreprocessorOutputOptions.h"
18596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer#include "clang/Lex/HeaderSearch.h"
198ee6a0dcc985c65bf5fd61a63e3f86e3ac516f5eLubos Lunak#include "clang/Lex/Pragma.h"
2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/Preprocessor.h"
21596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer#include "llvm/ADT/SmallString.h"
228c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie#include "llvm/Support/raw_ostream.h"
238c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
248c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikieusing namespace clang;
258c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikieusing namespace llvm;
268c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
278c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikienamespace {
288c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
298c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikieclass InclusionRewriter : public PPCallbacks {
308c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  /// Information about which #includes were actually performed,
318c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  /// created by preprocessor callbacks.
328c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  struct FileChange {
3303409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis    const Module *Mod;
348c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    SourceLocation From;
358c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    FileID Id;
368c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    SrcMgr::CharacteristicKind FileType;
3703409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis    FileChange(SourceLocation From, const Module *Mod) : Mod(Mod), From(From) {
388c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    }
398c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  };
4049fdccb4595862828aa5cadc1497d466a8031ddaDmitri Gribenko  Preprocessor &PP; ///< Used to find inclusion directives.
4149fdccb4595862828aa5cadc1497d466a8031ddaDmitri Gribenko  SourceManager &SM; ///< Used to read and manage source files.
4249fdccb4595862828aa5cadc1497d466a8031ddaDmitri Gribenko  raw_ostream &OS; ///< The destination stream for rewritten contents.
43e9512e2c275bf24295202443452da314fb77270fArgyrios Kyrtzidis  const llvm::MemoryBuffer *PredefinesBuffer; ///< The preprocessor predefines.
4449fdccb4595862828aa5cadc1497d466a8031ddaDmitri Gribenko  bool ShowLineMarkers; ///< Show #line markers.
4549fdccb4595862828aa5cadc1497d466a8031ddaDmitri Gribenko  bool UseLineDirective; ///< Use of line directives or line markers.
468c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  typedef std::map<unsigned, FileChange> FileChangeMap;
47959dc8475fc20ce8c3fd55021cb9f02a531cddc5Dmitri Gribenko  FileChangeMap FileChanges; ///< Tracks which files were included where.
488c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  /// Used transitively for building up the FileChanges mapping over the
498c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  /// various \c PPCallbacks callbacks.
508c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  FileChangeMap::iterator LastInsertedFileChange;
518c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikiepublic:
528c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  InclusionRewriter(Preprocessor &PP, raw_ostream &OS, bool ShowLineMarkers);
538c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  bool Process(FileID FileId, SrcMgr::CharacteristicKind FileType);
54e9512e2c275bf24295202443452da314fb77270fArgyrios Kyrtzidis  void setPredefinesBuffer(const llvm::MemoryBuffer *Buf) {
55e9512e2c275bf24295202443452da314fb77270fArgyrios Kyrtzidis    PredefinesBuffer = Buf;
56e9512e2c275bf24295202443452da314fb77270fArgyrios Kyrtzidis  }
578c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikieprivate:
588c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
598c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                           SrcMgr::CharacteristicKind FileType,
608c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                           FileID PrevFID);
618c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  virtual void FileSkipped(const FileEntry &ParentFile,
628c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                           const Token &FilenameTok,
638c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                           SrcMgr::CharacteristicKind FileType);
648c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  virtual void InclusionDirective(SourceLocation HashLoc,
658c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                  const Token &IncludeTok,
668c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                  StringRef FileName,
678c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                  bool IsAngled,
68da313592441db36cf4b06be97c4bcc238ee6fa9cArgyrios Kyrtzidis                                  CharSourceRange FilenameRange,
698c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                  const FileEntry *File,
708c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                  StringRef SearchPath,
71f8afcffe6a0213760b64c211812b1750e1e1e967Argyrios Kyrtzidis                                  StringRef RelativePath,
72f8afcffe6a0213760b64c211812b1750e1e1e967Argyrios Kyrtzidis                                  const Module *Imported);
738c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  void WriteLineInfo(const char *Filename, int Line,
748c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                     SrcMgr::CharacteristicKind FileType,
758c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                     StringRef EOL, StringRef Extra = StringRef());
7603409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis  void WriteImplicitModuleImport(const Module *Mod, StringRef EOL);
778c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  void OutputContentUpTo(const MemoryBuffer &FromFile,
788c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                         unsigned &WriteFrom, unsigned WriteTo,
798c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                         StringRef EOL, int &lines,
808c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                         bool EnsureNewline = false);
818c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  void CommentOutDirective(Lexer &DirectivesLex, const Token &StartToken,
828c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                           const MemoryBuffer &FromFile, StringRef EOL,
838c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                           unsigned &NextToWrite, int &Lines);
84596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  bool HandleHasInclude(FileID FileId, Lexer &RawLex,
85596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                        const DirectoryLookup *Lookup, Token &Tok,
86596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                        bool &FileExists);
878c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  const FileChange *FindFileChangeLocation(SourceLocation Loc) const;
888c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  StringRef NextIdentifierName(Lexer &RawLex, Token &RawToken);
898c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie};
908c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
918c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie}  // end anonymous namespace
928c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
938c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// Initializes an InclusionRewriter with a \p PP source and \p OS destination.
948c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid BlaikieInclusionRewriter::InclusionRewriter(Preprocessor &PP, raw_ostream &OS,
958c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                     bool ShowLineMarkers)
96e9512e2c275bf24295202443452da314fb77270fArgyrios Kyrtzidis    : PP(PP), SM(PP.getSourceManager()), OS(OS), PredefinesBuffer(0),
978c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    ShowLineMarkers(ShowLineMarkers),
988c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    LastInsertedFileChange(FileChanges.end()) {
998c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  // If we're in microsoft mode, use normal #line instead of line markers.
1008c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  UseLineDirective = PP.getLangOpts().MicrosoftExt;
1018c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie}
1028c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
1038c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// Write appropriate line information as either #line directives or GNU line
1048c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// markers depending on what mode we're in, including the \p Filename and
1058c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// \p Line we are located at, using the specified \p EOL line separator, and
1068c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// any \p Extra context specifiers in GNU line directives.
1078c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikievoid InclusionRewriter::WriteLineInfo(const char *Filename, int Line,
1088c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                      SrcMgr::CharacteristicKind FileType,
1098c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                      StringRef EOL, StringRef Extra) {
1108c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  if (!ShowLineMarkers)
1118c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    return;
1128c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  if (UseLineDirective) {
113a2b4754bb241bb21b94832916ee07cbf7351b958Eli Friedman    OS << "#line" << ' ' << Line << ' ' << '"';
114a2b4754bb241bb21b94832916ee07cbf7351b958Eli Friedman    OS.write_escaped(Filename);
115a2b4754bb241bb21b94832916ee07cbf7351b958Eli Friedman    OS << '"';
1168c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  } else {
1178c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    // Use GNU linemarkers as described here:
1188c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    // http://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html
1193432b7800d447267f4353e70a319f6f5a0bb4aabEli Friedman    OS << '#' << ' ' << Line << ' ' << '"';
1203432b7800d447267f4353e70a319f6f5a0bb4aabEli Friedman    OS.write_escaped(Filename);
1213432b7800d447267f4353e70a319f6f5a0bb4aabEli Friedman    OS << '"';
1228c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    if (!Extra.empty())
1238c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie      OS << Extra;
1248c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    if (FileType == SrcMgr::C_System)
1258c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie      // "`3' This indicates that the following text comes from a system header
1268c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie      // file, so certain warnings should be suppressed."
1278c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie      OS << " 3";
1288c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    else if (FileType == SrcMgr::C_ExternCSystem)
1298c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie      // as above for `3', plus "`4' This indicates that the following text
1308c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie      // should be treated as being wrapped in an implicit extern "C" block."
1318c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie      OS << " 3 4";
1328c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  }
1338c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  OS << EOL;
1348c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie}
1358c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
13603409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidisvoid InclusionRewriter::WriteImplicitModuleImport(const Module *Mod,
13703409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis                                                  StringRef EOL) {
13803409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis  OS << "@import " << Mod->getFullModuleName() << ";"
13903409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis     << " /* clang -frewrite-includes: implicit import */" << EOL;
14003409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis}
14103409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis
1428c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// FileChanged - Whenever the preprocessor enters or exits a #include file
1438c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// it invokes this handler.
1448c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikievoid InclusionRewriter::FileChanged(SourceLocation Loc,
1458c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                    FileChangeReason Reason,
1468c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                    SrcMgr::CharacteristicKind NewFileType,
1478c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                    FileID) {
1488c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  if (Reason != EnterFile)
1498c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    return;
1508c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  if (LastInsertedFileChange == FileChanges.end())
1518c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    // we didn't reach this file (eg: the main file) via an inclusion directive
1528c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    return;
1538c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  LastInsertedFileChange->second.Id = FullSourceLoc(Loc, SM).getFileID();
1548c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  LastInsertedFileChange->second.FileType = NewFileType;
1558c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  LastInsertedFileChange = FileChanges.end();
1568c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie}
1578c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
1588c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// Called whenever an inclusion is skipped due to canonical header protection
1598c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// macros.
1608c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikievoid InclusionRewriter::FileSkipped(const FileEntry &/*ParentFile*/,
1618c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                    const Token &/*FilenameTok*/,
1628c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                    SrcMgr::CharacteristicKind /*FileType*/) {
1638c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  assert(LastInsertedFileChange != FileChanges.end() && "A file, that wasn't "
1648c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    "found via an inclusion directive, was skipped");
1658c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  FileChanges.erase(LastInsertedFileChange);
1668c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  LastInsertedFileChange = FileChanges.end();
1678c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie}
1688c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
1698c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// This should be called whenever the preprocessor encounters include
1708c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// directives. It does not say whether the file has been included, but it
1718c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// provides more information about the directive (hash location instead
1728c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// of location inside the included file). It is assumed that the matching
1738c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// FileChanged() or FileSkipped() is called after this.
1748c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikievoid InclusionRewriter::InclusionDirective(SourceLocation HashLoc,
1758c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                           const Token &/*IncludeTok*/,
1768c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                           StringRef /*FileName*/,
1778c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                           bool /*IsAngled*/,
178da313592441db36cf4b06be97c4bcc238ee6fa9cArgyrios Kyrtzidis                                           CharSourceRange /*FilenameRange*/,
1798c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                           const FileEntry * /*File*/,
1808c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                           StringRef /*SearchPath*/,
181f8afcffe6a0213760b64c211812b1750e1e1e967Argyrios Kyrtzidis                                           StringRef /*RelativePath*/,
18203409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis                                           const Module *Imported) {
1838c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  assert(LastInsertedFileChange == FileChanges.end() && "Another inclusion "
1848c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    "directive was found before the previous one was processed");
1858c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  std::pair<FileChangeMap::iterator, bool> p = FileChanges.insert(
18603409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis    std::make_pair(HashLoc.getRawEncoding(), FileChange(HashLoc, Imported)));
1878c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  assert(p.second && "Unexpected revisitation of the same include directive");
18803409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis  if (!Imported)
18903409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis    LastInsertedFileChange = p.first;
1908c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie}
1918c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
1928c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// Simple lookup for a SourceLocation (specifically one denoting the hash in
1938c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// an inclusion directive) in the map of inclusion information, FileChanges.
1948c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikieconst InclusionRewriter::FileChange *
1958c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid BlaikieInclusionRewriter::FindFileChangeLocation(SourceLocation Loc) const {
1968c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  FileChangeMap::const_iterator I = FileChanges.find(Loc.getRawEncoding());
1978c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  if (I != FileChanges.end())
1988c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    return &I->second;
1998c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  return NULL;
2008c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie}
2018c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
2028c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// Detect the likely line ending style of \p FromFile by examining the first
2038c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// newline found within it.
2048c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikiestatic StringRef DetectEOL(const MemoryBuffer &FromFile) {
2058c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  // detect what line endings the file uses, so that added content does not mix
2068c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  // the style
2078c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  const char *Pos = strchr(FromFile.getBufferStart(), '\n');
2088c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  if (Pos == NULL)
2098c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    return "\n";
2108c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  if (Pos + 1 < FromFile.getBufferEnd() && Pos[1] == '\r')
2118c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    return "\n\r";
2128c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  if (Pos - 1 >= FromFile.getBufferStart() && Pos[-1] == '\r')
2138c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    return "\r\n";
2148c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  return "\n";
2158c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie}
2168c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
2178c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// Writes out bytes from \p FromFile, starting at \p NextToWrite and ending at
2188c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// \p WriteTo - 1.
2198c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikievoid InclusionRewriter::OutputContentUpTo(const MemoryBuffer &FromFile,
2208c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                          unsigned &WriteFrom, unsigned WriteTo,
2218c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                          StringRef EOL, int &Line,
2228c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                          bool EnsureNewline) {
2238c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  if (WriteTo <= WriteFrom)
2248c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    return;
225e9512e2c275bf24295202443452da314fb77270fArgyrios Kyrtzidis  if (&FromFile == PredefinesBuffer) {
226e9512e2c275bf24295202443452da314fb77270fArgyrios Kyrtzidis    // Ignore the #defines of the predefines buffer.
227e9512e2c275bf24295202443452da314fb77270fArgyrios Kyrtzidis    WriteFrom = WriteTo;
228e9512e2c275bf24295202443452da314fb77270fArgyrios Kyrtzidis    return;
229e9512e2c275bf24295202443452da314fb77270fArgyrios Kyrtzidis  }
2308c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  OS.write(FromFile.getBufferStart() + WriteFrom, WriteTo - WriteFrom);
2318c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  // count lines manually, it's faster than getPresumedLoc()
2323159819ed71a2e814175a593147f7637a423ba56Benjamin Kramer  Line += std::count(FromFile.getBufferStart() + WriteFrom,
2333159819ed71a2e814175a593147f7637a423ba56Benjamin Kramer                     FromFile.getBufferStart() + WriteTo, '\n');
2348c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  if (EnsureNewline) {
2358c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    char LastChar = FromFile.getBufferStart()[WriteTo - 1];
2368c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    if (LastChar != '\n' && LastChar != '\r')
2378c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie      OS << EOL;
2388c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  }
2398c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  WriteFrom = WriteTo;
2408c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie}
2418c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
2428c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// Print characters from \p FromFile starting at \p NextToWrite up until the
2438c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// inclusion directive at \p StartToken, then print out the inclusion
2448c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// inclusion directive disabled by a #if directive, updating \p NextToWrite
2458c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// and \p Line to track the number of source lines visited and the progress
2468c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// through the \p FromFile buffer.
2478c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikievoid InclusionRewriter::CommentOutDirective(Lexer &DirectiveLex,
2488c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                            const Token &StartToken,
2498c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                            const MemoryBuffer &FromFile,
2508c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                            StringRef EOL,
2518c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                            unsigned &NextToWrite, int &Line) {
2528c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  OutputContentUpTo(FromFile, NextToWrite,
2538c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    SM.getFileOffset(StartToken.getLocation()), EOL, Line);
2548c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  Token DirectiveToken;
2558c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  do {
2568c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    DirectiveLex.LexFromRawLexer(DirectiveToken);
2578c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  } while (!DirectiveToken.is(tok::eod) && DirectiveToken.isNot(tok::eof));
25860ad16b7e24cdb88c577c107b69da85458000858David Blaikie  OS << "#if 0 /* expanded by -frewrite-includes */" << EOL;
2598c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  OutputContentUpTo(FromFile, NextToWrite,
2608c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    SM.getFileOffset(DirectiveToken.getLocation()) + DirectiveToken.getLength(),
2618c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    EOL, Line);
26260ad16b7e24cdb88c577c107b69da85458000858David Blaikie  OS << "#endif /* expanded by -frewrite-includes */" << EOL;
2638c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie}
2648c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
2658c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// Find the next identifier in the pragma directive specified by \p RawToken.
2668c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid BlaikieStringRef InclusionRewriter::NextIdentifierName(Lexer &RawLex,
2678c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                                Token &RawToken) {
2688c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  RawLex.LexFromRawLexer(RawToken);
2698c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  if (RawToken.is(tok::raw_identifier))
2708c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    PP.LookUpIdentifierInfo(RawToken);
2718c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  if (RawToken.is(tok::identifier))
2728c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    return RawToken.getIdentifierInfo()->getName();
2738c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  return StringRef();
2748c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie}
2758c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
276596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer// Expand __has_include and __has_include_next if possible. If there's no
277596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer// definitive answer return false.
278596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramerbool InclusionRewriter::HandleHasInclude(
279596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer    FileID FileId, Lexer &RawLex, const DirectoryLookup *Lookup, Token &Tok,
280596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer    bool &FileExists) {
281596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  // Lex the opening paren.
282596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  RawLex.LexFromRawLexer(Tok);
283596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  if (Tok.isNot(tok::l_paren))
284596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer    return false;
285596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer
286596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  RawLex.LexFromRawLexer(Tok);
287596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer
288596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  SmallString<128> FilenameBuffer;
289596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  StringRef Filename;
290596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  // Since the raw lexer doesn't give us angle_literals we have to parse them
291596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  // ourselves.
292596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  // FIXME: What to do if the file name is a macro?
293596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  if (Tok.is(tok::less)) {
294596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer    RawLex.LexFromRawLexer(Tok);
295596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer
296596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer    FilenameBuffer += '<';
297596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer    do {
298596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer      if (Tok.is(tok::eod)) // Sanity check.
299596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer        return false;
300596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer
301596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer      if (Tok.is(tok::raw_identifier))
302596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer        PP.LookUpIdentifierInfo(Tok);
303596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer
304596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer      // Get the string piece.
305596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer      SmallVector<char, 128> TmpBuffer;
306596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer      bool Invalid = false;
307596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer      StringRef TmpName = PP.getSpelling(Tok, TmpBuffer, &Invalid);
308596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer      if (Invalid)
309596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer        return false;
310596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer
311596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer      FilenameBuffer += TmpName;
312596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer
313596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer      RawLex.LexFromRawLexer(Tok);
314596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer    } while (Tok.isNot(tok::greater));
315596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer
316596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer    FilenameBuffer += '>';
317596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer    Filename = FilenameBuffer;
318596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  } else {
319596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer    if (Tok.isNot(tok::string_literal))
320596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer      return false;
321596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer
322596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer    bool Invalid = false;
323596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer    Filename = PP.getSpelling(Tok, FilenameBuffer, &Invalid);
324596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer    if (Invalid)
325596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer      return false;
326596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  }
327596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer
328596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  // Lex the closing paren.
329596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  RawLex.LexFromRawLexer(Tok);
330596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  if (Tok.isNot(tok::r_paren))
331596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer    return false;
332596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer
333596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  // Now ask HeaderInfo if it knows about the header.
334596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  // FIXME: Subframeworks aren't handled here. Do we care?
335596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  bool isAngled = PP.GetIncludeFilenameSpelling(Tok.getLocation(), Filename);
336596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  const DirectoryLookup *CurDir;
337596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  const FileEntry *File = PP.getHeaderSearchInfo().LookupFile(
338596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer      Filename, isAngled, 0, CurDir,
339596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer      PP.getSourceManager().getFileEntryForID(FileId), 0, 0, 0, false);
340596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer
341596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  FileExists = File != 0;
342596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer  return true;
343596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer}
344596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer
3451505edfeb85f54f2a982f76542b51e5ddd12b44cBenjamin Kramer/// Use a raw lexer to analyze \p FileId, incrementally copying parts of it
3468c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie/// and including content of included files recursively.
3478c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikiebool InclusionRewriter::Process(FileID FileId,
3488c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                SrcMgr::CharacteristicKind FileType)
3498c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie{
3508c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  bool Invalid;
3518c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  const MemoryBuffer &FromFile = *SM.getBuffer(FileId, &Invalid);
352bae2b31822e3c2139b5f8fbb127e4c5674cce6dbDavid Blaikie  if (Invalid) // invalid inclusion
353507d496e18fb7bf54e4cb8f79df56941f93f1edaArgyrios Kyrtzidis    return false;
3548c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  const char *FileName = FromFile.getBufferIdentifier();
3558c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  Lexer RawLex(FileId, &FromFile, PP.getSourceManager(), PP.getLangOpts());
3568c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  RawLex.SetCommentRetentionState(false);
3578c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
3588c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  StringRef EOL = DetectEOL(FromFile);
3598c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
3608c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  // Per the GNU docs: "1" indicates the start of a new file.
3618c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  WriteLineInfo(FileName, 1, FileType, EOL, " 1");
3628c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
3638c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  if (SM.getFileIDSize(FileId) == 0)
364507d496e18fb7bf54e4cb8f79df56941f93f1edaArgyrios Kyrtzidis    return false;
3658c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
3668c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  // The next byte to be copied from the source file
3678c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  unsigned NextToWrite = 0;
3688c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  int Line = 1; // The current input file line number.
3698c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
3708c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  Token RawToken;
3718c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  RawLex.LexFromRawLexer(RawToken);
3728c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
3738c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  // TODO: Consider adding a switch that strips possibly unimportant content,
3748c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  // such as comments, to reduce the size of repro files.
3758c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  while (RawToken.isNot(tok::eof)) {
3768c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    if (RawToken.is(tok::hash) && RawToken.isAtStartOfLine()) {
3778c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie      RawLex.setParsingPreprocessorDirective(true);
3788c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie      Token HashToken = RawToken;
3798c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie      RawLex.LexFromRawLexer(RawToken);
3808c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie      if (RawToken.is(tok::raw_identifier))
3818c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie        PP.LookUpIdentifierInfo(RawToken);
382ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak      if (RawToken.getIdentifierInfo() != NULL) {
3838c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie        switch (RawToken.getIdentifierInfo()->getPPKeywordID()) {
3848c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie          case tok::pp_include:
3858c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie          case tok::pp_include_next:
3868c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie          case tok::pp_import: {
3878c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie            CommentOutDirective(RawLex, HashToken, FromFile, EOL, NextToWrite,
3888c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie              Line);
38903409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis            StringRef LineInfoExtra;
3908c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie            if (const FileChange *Change = FindFileChangeLocation(
3918c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                HashToken.getLocation())) {
39203409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis              if (Change->Mod) {
39303409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis                WriteImplicitModuleImport(Change->Mod, EOL);
39403409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis
39503409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis              // else now include and recursively process the file
39603409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis              } else if (Process(Change->Id, Change->FileType)) {
3978c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                // and set lineinfo back to this file, if the nested one was
3988c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                // actually included
3998c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                // `2' indicates returning to a file (after having included
4008c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                // another file.
40103409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis                LineInfoExtra = " 2";
402507d496e18fb7bf54e4cb8f79df56941f93f1edaArgyrios Kyrtzidis              }
40303409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis            }
40403409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis            // fix up lineinfo (since commented out directive changed line
40503409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis            // numbers) for inclusions that were skipped due to header guards
40603409967bd9860ffb2ff6b38126e04493c55567fArgyrios Kyrtzidis            WriteLineInfo(FileName, Line, FileType, EOL, LineInfoExtra);
4078c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie            break;
4088c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie          }
4098c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie          case tok::pp_pragma: {
4108c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie            StringRef Identifier = NextIdentifierName(RawLex, RawToken);
4118c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie            if (Identifier == "clang" || Identifier == "GCC") {
4128c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie              if (NextIdentifierName(RawLex, RawToken) == "system_header") {
4138c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                // keep the directive in, commented out
4148c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                CommentOutDirective(RawLex, HashToken, FromFile, EOL,
4158c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                  NextToWrite, Line);
4168c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                // update our own type
4178c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                FileType = SM.getFileCharacteristic(RawToken.getLocation());
4188c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                WriteLineInfo(FileName, Line, FileType, EOL);
4198c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie              }
4208c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie            } else if (Identifier == "once") {
4218c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie              // keep the directive in, commented out
4228c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie              CommentOutDirective(RawLex, HashToken, FromFile, EOL,
4238c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                NextToWrite, Line);
4248c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie              WriteLineInfo(FileName, Line, FileType, EOL);
4258c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie            }
4268c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie            break;
4278c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie          }
428596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer          case tok::pp_if:
429ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak          case tok::pp_elif: {
430ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak            bool elif = (RawToken.getIdentifierInfo()->getPPKeywordID() ==
431ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak                         tok::pp_elif);
432596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer            // Rewrite special builtin macros to avoid pulling in host details.
433596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer            do {
434596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer              // Walk over the directive.
435596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer              RawLex.LexFromRawLexer(RawToken);
436596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer              if (RawToken.is(tok::raw_identifier))
437596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                PP.LookUpIdentifierInfo(RawToken);
438596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer
439596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer              if (RawToken.is(tok::identifier)) {
440596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                bool HasFile;
441596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                SourceLocation Loc = RawToken.getLocation();
442596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer
443596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                // Rewrite __has_include(x)
444596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                if (RawToken.getIdentifierInfo()->isStr("__has_include")) {
445596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                  if (!HandleHasInclude(FileId, RawLex, 0, RawToken, HasFile))
446596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                    continue;
447596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                  // Rewrite __has_include_next(x)
448596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                } else if (RawToken.getIdentifierInfo()->isStr(
449596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                               "__has_include_next")) {
450596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                  const DirectoryLookup *Lookup = PP.GetCurDirLookup();
451596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                  if (Lookup)
452596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                    ++Lookup;
453596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer
454596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                  if (!HandleHasInclude(FileId, RawLex, Lookup, RawToken,
455596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                                        HasFile))
456596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                    continue;
457596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                } else {
458596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                  continue;
459596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                }
460596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                // Replace the macro with (0) or (1), followed by the commented
461596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                // out macro for reference.
462596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                OutputContentUpTo(FromFile, NextToWrite, SM.getFileOffset(Loc),
463596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                                  EOL, Line);
464596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                OS << '(' << (int) HasFile << ")/*";
465596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                OutputContentUpTo(FromFile, NextToWrite,
466596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                                  SM.getFileOffset(RawToken.getLocation()) +
467596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                                  RawToken.getLength(),
468596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                                  EOL, Line);
469596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer                OS << "*/";
470596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer              }
471596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer            } while (RawToken.isNot(tok::eod));
472ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak            if (elif) {
473ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak              OutputContentUpTo(FromFile, NextToWrite,
474ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak                                SM.getFileOffset(RawToken.getLocation()) +
475ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak                                    RawToken.getLength(),
476ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak                                EOL, Line, /*EnsureNewLine*/ true);
477ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak              WriteLineInfo(FileName, Line, FileType, EOL);
478ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak            }
479596eea7cc26979c952a0b177d024787a99b299dfBenjamin Kramer            break;
480ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak          }
481ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak          case tok::pp_endif:
482ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak          case tok::pp_else: {
483ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak            // We surround every #include by #if 0 to comment it out, but that
484ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak            // changes line numbers. These are fixed up right after that, but
485ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak            // the whole #include could be inside a preprocessor conditional
486ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak            // that is not processed. So it is necessary to fix the line
487ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak            // numbers one the next line after each #else/#endif as well.
488ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak            RawLex.SetKeepWhitespaceMode(true);
489ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak            do {
490ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak              RawLex.LexFromRawLexer(RawToken);
491ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak            } while (RawToken.isNot(tok::eod) && RawToken.isNot(tok::eof));
492ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak            OutputContentUpTo(
493ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak                FromFile, NextToWrite,
494ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak                SM.getFileOffset(RawToken.getLocation()) + RawToken.getLength(),
495ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak                EOL, Line, /*EnsureNewLine*/ true);
496ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak            WriteLineInfo(FileName, Line, FileType, EOL);
497ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak            RawLex.SetKeepWhitespaceMode(false);
498ce6af1189fb8f6d2a6fa083cff84a796c8377504Lubos Lunak          }
4998c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie          default:
5008c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie            break;
5018c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie        }
5028c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie      }
5038c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie      RawLex.setParsingPreprocessorDirective(false);
5048c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    }
5058c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    RawLex.LexFromRawLexer(RawToken);
5068c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  }
5078c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  OutputContentUpTo(FromFile, NextToWrite,
508b18840ddd6aa472bbf78ab9de59159eb128fb6a9Argyrios Kyrtzidis    SM.getFileOffset(SM.getLocForEndOfFile(FileId)), EOL, Line,
5098c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    /*EnsureNewline*/true);
5108c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  return true;
5118c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie}
5128c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
51360ad16b7e24cdb88c577c107b69da85458000858David Blaikie/// InclusionRewriterInInput - Implement -frewrite-includes mode.
5148c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikievoid clang::RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS,
5158c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                   const PreprocessorOutputOptions &Opts) {
5168c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  SourceManager &SM = PP.getSourceManager();
5178c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  InclusionRewriter *Rewrite = new InclusionRewriter(PP, *OS,
5188c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie                                                     Opts.ShowLineMarkers);
5198c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  PP.addPPCallbacks(Rewrite);
5208ee6a0dcc985c65bf5fd61a63e3f86e3ac516f5eLubos Lunak  // Ignore all pragmas, otherwise there will be warnings about unknown pragmas
5218ee6a0dcc985c65bf5fd61a63e3f86e3ac516f5eLubos Lunak  // (because there's nothing to handle them).
5228ee6a0dcc985c65bf5fd61a63e3f86e3ac516f5eLubos Lunak  PP.AddPragmaHandler(new EmptyPragmaHandler());
5238ee6a0dcc985c65bf5fd61a63e3f86e3ac516f5eLubos Lunak  // Ignore also all pragma in all namespaces created
5248ee6a0dcc985c65bf5fd61a63e3f86e3ac516f5eLubos Lunak  // in Preprocessor::RegisterBuiltinPragmas().
5258ee6a0dcc985c65bf5fd61a63e3f86e3ac516f5eLubos Lunak  PP.AddPragmaHandler("GCC", new EmptyPragmaHandler());
5268ee6a0dcc985c65bf5fd61a63e3f86e3ac516f5eLubos Lunak  PP.AddPragmaHandler("clang", new EmptyPragmaHandler());
5278c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie
5288c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  // First let the preprocessor process the entire file and call callbacks.
5298c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  // Callbacks will record which #include's were actually performed.
5308c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  PP.EnterMainSourceFile();
5318c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  Token Tok;
5328c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  // Only preprocessor directives matter here, so disable macro expansion
5338c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  // everywhere else as an optimization.
5348c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  // TODO: It would be even faster if the preprocessor could be switched
5358c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  // to a mode where it would parse only preprocessor directives and comments,
5368c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  // nothing else matters for parsing or processing.
5378c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  PP.SetMacroExpansionOnlyInDirectives();
5388c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  do {
5398c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie    PP.Lex(Tok);
5408c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  } while (Tok.isNot(tok::eof));
541e9512e2c275bf24295202443452da314fb77270fArgyrios Kyrtzidis  Rewrite->setPredefinesBuffer(SM.getBuffer(PP.getPredefinesFileID()));
542e9512e2c275bf24295202443452da314fb77270fArgyrios Kyrtzidis  Rewrite->Process(PP.getPredefinesFileID(), SrcMgr::C_User);
5438c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  Rewrite->Process(SM.getMainFileID(), SrcMgr::C_User);
5448c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie  OS->flush();
5458c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie}
546