1*67e74705SXin Li //===--- PrintPreprocessedOutput.cpp - Implement the -E mode --------------===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This code simply runs the preprocessor on the input file and prints out the
11*67e74705SXin Li // result. This is the traditional behavior of the -E option.
12*67e74705SXin Li //
13*67e74705SXin Li //===----------------------------------------------------------------------===//
14*67e74705SXin Li
15*67e74705SXin Li #include "clang/Frontend/Utils.h"
16*67e74705SXin Li #include "clang/Basic/CharInfo.h"
17*67e74705SXin Li #include "clang/Basic/Diagnostic.h"
18*67e74705SXin Li #include "clang/Basic/SourceManager.h"
19*67e74705SXin Li #include "clang/Frontend/PreprocessorOutputOptions.h"
20*67e74705SXin Li #include "clang/Lex/MacroInfo.h"
21*67e74705SXin Li #include "clang/Lex/PPCallbacks.h"
22*67e74705SXin Li #include "clang/Lex/Pragma.h"
23*67e74705SXin Li #include "clang/Lex/Preprocessor.h"
24*67e74705SXin Li #include "clang/Lex/TokenConcatenation.h"
25*67e74705SXin Li #include "llvm/ADT/STLExtras.h"
26*67e74705SXin Li #include "llvm/ADT/SmallString.h"
27*67e74705SXin Li #include "llvm/ADT/StringRef.h"
28*67e74705SXin Li #include "llvm/Support/ErrorHandling.h"
29*67e74705SXin Li #include "llvm/Support/raw_ostream.h"
30*67e74705SXin Li #include <cstdio>
31*67e74705SXin Li using namespace clang;
32*67e74705SXin Li
33*67e74705SXin Li /// PrintMacroDefinition - Print a macro definition in a form that will be
34*67e74705SXin Li /// properly accepted back as a definition.
PrintMacroDefinition(const IdentifierInfo & II,const MacroInfo & MI,Preprocessor & PP,raw_ostream & OS)35*67e74705SXin Li static void PrintMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI,
36*67e74705SXin Li Preprocessor &PP, raw_ostream &OS) {
37*67e74705SXin Li OS << "#define " << II.getName();
38*67e74705SXin Li
39*67e74705SXin Li if (MI.isFunctionLike()) {
40*67e74705SXin Li OS << '(';
41*67e74705SXin Li if (!MI.arg_empty()) {
42*67e74705SXin Li MacroInfo::arg_iterator AI = MI.arg_begin(), E = MI.arg_end();
43*67e74705SXin Li for (; AI+1 != E; ++AI) {
44*67e74705SXin Li OS << (*AI)->getName();
45*67e74705SXin Li OS << ',';
46*67e74705SXin Li }
47*67e74705SXin Li
48*67e74705SXin Li // Last argument.
49*67e74705SXin Li if ((*AI)->getName() == "__VA_ARGS__")
50*67e74705SXin Li OS << "...";
51*67e74705SXin Li else
52*67e74705SXin Li OS << (*AI)->getName();
53*67e74705SXin Li }
54*67e74705SXin Li
55*67e74705SXin Li if (MI.isGNUVarargs())
56*67e74705SXin Li OS << "..."; // #define foo(x...)
57*67e74705SXin Li
58*67e74705SXin Li OS << ')';
59*67e74705SXin Li }
60*67e74705SXin Li
61*67e74705SXin Li // GCC always emits a space, even if the macro body is empty. However, do not
62*67e74705SXin Li // want to emit two spaces if the first token has a leading space.
63*67e74705SXin Li if (MI.tokens_empty() || !MI.tokens_begin()->hasLeadingSpace())
64*67e74705SXin Li OS << ' ';
65*67e74705SXin Li
66*67e74705SXin Li SmallString<128> SpellingBuffer;
67*67e74705SXin Li for (const auto &T : MI.tokens()) {
68*67e74705SXin Li if (T.hasLeadingSpace())
69*67e74705SXin Li OS << ' ';
70*67e74705SXin Li
71*67e74705SXin Li OS << PP.getSpelling(T, SpellingBuffer);
72*67e74705SXin Li }
73*67e74705SXin Li }
74*67e74705SXin Li
75*67e74705SXin Li //===----------------------------------------------------------------------===//
76*67e74705SXin Li // Preprocessed token printer
77*67e74705SXin Li //===----------------------------------------------------------------------===//
78*67e74705SXin Li
79*67e74705SXin Li namespace {
80*67e74705SXin Li class PrintPPOutputPPCallbacks : public PPCallbacks {
81*67e74705SXin Li Preprocessor &PP;
82*67e74705SXin Li SourceManager &SM;
83*67e74705SXin Li TokenConcatenation ConcatInfo;
84*67e74705SXin Li public:
85*67e74705SXin Li raw_ostream &OS;
86*67e74705SXin Li private:
87*67e74705SXin Li unsigned CurLine;
88*67e74705SXin Li
89*67e74705SXin Li bool EmittedTokensOnThisLine;
90*67e74705SXin Li bool EmittedDirectiveOnThisLine;
91*67e74705SXin Li SrcMgr::CharacteristicKind FileType;
92*67e74705SXin Li SmallString<512> CurFilename;
93*67e74705SXin Li bool Initialized;
94*67e74705SXin Li bool DisableLineMarkers;
95*67e74705SXin Li bool DumpDefines;
96*67e74705SXin Li bool UseLineDirectives;
97*67e74705SXin Li bool IsFirstFileEntered;
98*67e74705SXin Li public:
PrintPPOutputPPCallbacks(Preprocessor & pp,raw_ostream & os,bool lineMarkers,bool defines,bool UseLineDirectives)99*67e74705SXin Li PrintPPOutputPPCallbacks(Preprocessor &pp, raw_ostream &os, bool lineMarkers,
100*67e74705SXin Li bool defines, bool UseLineDirectives)
101*67e74705SXin Li : PP(pp), SM(PP.getSourceManager()), ConcatInfo(PP), OS(os),
102*67e74705SXin Li DisableLineMarkers(lineMarkers), DumpDefines(defines),
103*67e74705SXin Li UseLineDirectives(UseLineDirectives) {
104*67e74705SXin Li CurLine = 0;
105*67e74705SXin Li CurFilename += "<uninit>";
106*67e74705SXin Li EmittedTokensOnThisLine = false;
107*67e74705SXin Li EmittedDirectiveOnThisLine = false;
108*67e74705SXin Li FileType = SrcMgr::C_User;
109*67e74705SXin Li Initialized = false;
110*67e74705SXin Li IsFirstFileEntered = false;
111*67e74705SXin Li }
112*67e74705SXin Li
setEmittedTokensOnThisLine()113*67e74705SXin Li void setEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; }
hasEmittedTokensOnThisLine() const114*67e74705SXin Li bool hasEmittedTokensOnThisLine() const { return EmittedTokensOnThisLine; }
115*67e74705SXin Li
setEmittedDirectiveOnThisLine()116*67e74705SXin Li void setEmittedDirectiveOnThisLine() { EmittedDirectiveOnThisLine = true; }
hasEmittedDirectiveOnThisLine() const117*67e74705SXin Li bool hasEmittedDirectiveOnThisLine() const {
118*67e74705SXin Li return EmittedDirectiveOnThisLine;
119*67e74705SXin Li }
120*67e74705SXin Li
121*67e74705SXin Li bool startNewLineIfNeeded(bool ShouldUpdateCurrentLine = true);
122*67e74705SXin Li
123*67e74705SXin Li void FileChanged(SourceLocation Loc, FileChangeReason Reason,
124*67e74705SXin Li SrcMgr::CharacteristicKind FileType,
125*67e74705SXin Li FileID PrevFID) override;
126*67e74705SXin Li void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
127*67e74705SXin Li StringRef FileName, bool IsAngled,
128*67e74705SXin Li CharSourceRange FilenameRange, const FileEntry *File,
129*67e74705SXin Li StringRef SearchPath, StringRef RelativePath,
130*67e74705SXin Li const Module *Imported) override;
131*67e74705SXin Li void Ident(SourceLocation Loc, StringRef str) override;
132*67e74705SXin Li void PragmaMessage(SourceLocation Loc, StringRef Namespace,
133*67e74705SXin Li PragmaMessageKind Kind, StringRef Str) override;
134*67e74705SXin Li void PragmaDebug(SourceLocation Loc, StringRef DebugType) override;
135*67e74705SXin Li void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override;
136*67e74705SXin Li void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override;
137*67e74705SXin Li void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
138*67e74705SXin Li diag::Severity Map, StringRef Str) override;
139*67e74705SXin Li void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
140*67e74705SXin Li ArrayRef<int> Ids) override;
141*67e74705SXin Li void PragmaWarningPush(SourceLocation Loc, int Level) override;
142*67e74705SXin Li void PragmaWarningPop(SourceLocation Loc) override;
143*67e74705SXin Li
144*67e74705SXin Li bool HandleFirstTokOnLine(Token &Tok);
145*67e74705SXin Li
146*67e74705SXin Li /// Move to the line of the provided source location. This will
147*67e74705SXin Li /// return true if the output stream required adjustment or if
148*67e74705SXin Li /// the requested location is on the first line.
MoveToLine(SourceLocation Loc)149*67e74705SXin Li bool MoveToLine(SourceLocation Loc) {
150*67e74705SXin Li PresumedLoc PLoc = SM.getPresumedLoc(Loc);
151*67e74705SXin Li if (PLoc.isInvalid())
152*67e74705SXin Li return false;
153*67e74705SXin Li return MoveToLine(PLoc.getLine()) || (PLoc.getLine() == 1);
154*67e74705SXin Li }
155*67e74705SXin Li bool MoveToLine(unsigned LineNo);
156*67e74705SXin Li
AvoidConcat(const Token & PrevPrevTok,const Token & PrevTok,const Token & Tok)157*67e74705SXin Li bool AvoidConcat(const Token &PrevPrevTok, const Token &PrevTok,
158*67e74705SXin Li const Token &Tok) {
159*67e74705SXin Li return ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok, Tok);
160*67e74705SXin Li }
161*67e74705SXin Li void WriteLineInfo(unsigned LineNo, const char *Extra=nullptr,
162*67e74705SXin Li unsigned ExtraLen=0);
LineMarkersAreDisabled() const163*67e74705SXin Li bool LineMarkersAreDisabled() const { return DisableLineMarkers; }
164*67e74705SXin Li void HandleNewlinesInToken(const char *TokStr, unsigned Len);
165*67e74705SXin Li
166*67e74705SXin Li /// MacroDefined - This hook is called whenever a macro definition is seen.
167*67e74705SXin Li void MacroDefined(const Token &MacroNameTok,
168*67e74705SXin Li const MacroDirective *MD) override;
169*67e74705SXin Li
170*67e74705SXin Li /// MacroUndefined - This hook is called whenever a macro #undef is seen.
171*67e74705SXin Li void MacroUndefined(const Token &MacroNameTok,
172*67e74705SXin Li const MacroDefinition &MD) override;
173*67e74705SXin Li };
174*67e74705SXin Li } // end anonymous namespace
175*67e74705SXin Li
WriteLineInfo(unsigned LineNo,const char * Extra,unsigned ExtraLen)176*67e74705SXin Li void PrintPPOutputPPCallbacks::WriteLineInfo(unsigned LineNo,
177*67e74705SXin Li const char *Extra,
178*67e74705SXin Li unsigned ExtraLen) {
179*67e74705SXin Li startNewLineIfNeeded(/*ShouldUpdateCurrentLine=*/false);
180*67e74705SXin Li
181*67e74705SXin Li // Emit #line directives or GNU line markers depending on what mode we're in.
182*67e74705SXin Li if (UseLineDirectives) {
183*67e74705SXin Li OS << "#line" << ' ' << LineNo << ' ' << '"';
184*67e74705SXin Li OS.write_escaped(CurFilename);
185*67e74705SXin Li OS << '"';
186*67e74705SXin Li } else {
187*67e74705SXin Li OS << '#' << ' ' << LineNo << ' ' << '"';
188*67e74705SXin Li OS.write_escaped(CurFilename);
189*67e74705SXin Li OS << '"';
190*67e74705SXin Li
191*67e74705SXin Li if (ExtraLen)
192*67e74705SXin Li OS.write(Extra, ExtraLen);
193*67e74705SXin Li
194*67e74705SXin Li if (FileType == SrcMgr::C_System)
195*67e74705SXin Li OS.write(" 3", 2);
196*67e74705SXin Li else if (FileType == SrcMgr::C_ExternCSystem)
197*67e74705SXin Li OS.write(" 3 4", 4);
198*67e74705SXin Li }
199*67e74705SXin Li OS << '\n';
200*67e74705SXin Li }
201*67e74705SXin Li
202*67e74705SXin Li /// MoveToLine - Move the output to the source line specified by the location
203*67e74705SXin Li /// object. We can do this by emitting some number of \n's, or be emitting a
204*67e74705SXin Li /// #line directive. This returns false if already at the specified line, true
205*67e74705SXin Li /// if some newlines were emitted.
MoveToLine(unsigned LineNo)206*67e74705SXin Li bool PrintPPOutputPPCallbacks::MoveToLine(unsigned LineNo) {
207*67e74705SXin Li // If this line is "close enough" to the original line, just print newlines,
208*67e74705SXin Li // otherwise print a #line directive.
209*67e74705SXin Li if (LineNo-CurLine <= 8) {
210*67e74705SXin Li if (LineNo-CurLine == 1)
211*67e74705SXin Li OS << '\n';
212*67e74705SXin Li else if (LineNo == CurLine)
213*67e74705SXin Li return false; // Spelling line moved, but expansion line didn't.
214*67e74705SXin Li else {
215*67e74705SXin Li const char *NewLines = "\n\n\n\n\n\n\n\n";
216*67e74705SXin Li OS.write(NewLines, LineNo-CurLine);
217*67e74705SXin Li }
218*67e74705SXin Li } else if (!DisableLineMarkers) {
219*67e74705SXin Li // Emit a #line or line marker.
220*67e74705SXin Li WriteLineInfo(LineNo, nullptr, 0);
221*67e74705SXin Li } else {
222*67e74705SXin Li // Okay, we're in -P mode, which turns off line markers. However, we still
223*67e74705SXin Li // need to emit a newline between tokens on different lines.
224*67e74705SXin Li startNewLineIfNeeded(/*ShouldUpdateCurrentLine=*/false);
225*67e74705SXin Li }
226*67e74705SXin Li
227*67e74705SXin Li CurLine = LineNo;
228*67e74705SXin Li return true;
229*67e74705SXin Li }
230*67e74705SXin Li
231*67e74705SXin Li bool
startNewLineIfNeeded(bool ShouldUpdateCurrentLine)232*67e74705SXin Li PrintPPOutputPPCallbacks::startNewLineIfNeeded(bool ShouldUpdateCurrentLine) {
233*67e74705SXin Li if (EmittedTokensOnThisLine || EmittedDirectiveOnThisLine) {
234*67e74705SXin Li OS << '\n';
235*67e74705SXin Li EmittedTokensOnThisLine = false;
236*67e74705SXin Li EmittedDirectiveOnThisLine = false;
237*67e74705SXin Li if (ShouldUpdateCurrentLine)
238*67e74705SXin Li ++CurLine;
239*67e74705SXin Li return true;
240*67e74705SXin Li }
241*67e74705SXin Li
242*67e74705SXin Li return false;
243*67e74705SXin Li }
244*67e74705SXin Li
245*67e74705SXin Li /// FileChanged - Whenever the preprocessor enters or exits a #include file
246*67e74705SXin Li /// it invokes this handler. Update our conception of the current source
247*67e74705SXin Li /// position.
FileChanged(SourceLocation Loc,FileChangeReason Reason,SrcMgr::CharacteristicKind NewFileType,FileID PrevFID)248*67e74705SXin Li void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc,
249*67e74705SXin Li FileChangeReason Reason,
250*67e74705SXin Li SrcMgr::CharacteristicKind NewFileType,
251*67e74705SXin Li FileID PrevFID) {
252*67e74705SXin Li // Unless we are exiting a #include, make sure to skip ahead to the line the
253*67e74705SXin Li // #include directive was at.
254*67e74705SXin Li SourceManager &SourceMgr = SM;
255*67e74705SXin Li
256*67e74705SXin Li PresumedLoc UserLoc = SourceMgr.getPresumedLoc(Loc);
257*67e74705SXin Li if (UserLoc.isInvalid())
258*67e74705SXin Li return;
259*67e74705SXin Li
260*67e74705SXin Li unsigned NewLine = UserLoc.getLine();
261*67e74705SXin Li
262*67e74705SXin Li if (Reason == PPCallbacks::EnterFile) {
263*67e74705SXin Li SourceLocation IncludeLoc = UserLoc.getIncludeLoc();
264*67e74705SXin Li if (IncludeLoc.isValid())
265*67e74705SXin Li MoveToLine(IncludeLoc);
266*67e74705SXin Li } else if (Reason == PPCallbacks::SystemHeaderPragma) {
267*67e74705SXin Li // GCC emits the # directive for this directive on the line AFTER the
268*67e74705SXin Li // directive and emits a bunch of spaces that aren't needed. This is because
269*67e74705SXin Li // otherwise we will emit a line marker for THIS line, which requires an
270*67e74705SXin Li // extra blank line after the directive to avoid making all following lines
271*67e74705SXin Li // off by one. We can do better by simply incrementing NewLine here.
272*67e74705SXin Li NewLine += 1;
273*67e74705SXin Li }
274*67e74705SXin Li
275*67e74705SXin Li CurLine = NewLine;
276*67e74705SXin Li
277*67e74705SXin Li CurFilename.clear();
278*67e74705SXin Li CurFilename += UserLoc.getFilename();
279*67e74705SXin Li FileType = NewFileType;
280*67e74705SXin Li
281*67e74705SXin Li if (DisableLineMarkers) {
282*67e74705SXin Li startNewLineIfNeeded(/*ShouldUpdateCurrentLine=*/false);
283*67e74705SXin Li return;
284*67e74705SXin Li }
285*67e74705SXin Li
286*67e74705SXin Li if (!Initialized) {
287*67e74705SXin Li WriteLineInfo(CurLine);
288*67e74705SXin Li Initialized = true;
289*67e74705SXin Li }
290*67e74705SXin Li
291*67e74705SXin Li // Do not emit an enter marker for the main file (which we expect is the first
292*67e74705SXin Li // entered file). This matches gcc, and improves compatibility with some tools
293*67e74705SXin Li // which track the # line markers as a way to determine when the preprocessed
294*67e74705SXin Li // output is in the context of the main file.
295*67e74705SXin Li if (Reason == PPCallbacks::EnterFile && !IsFirstFileEntered) {
296*67e74705SXin Li IsFirstFileEntered = true;
297*67e74705SXin Li return;
298*67e74705SXin Li }
299*67e74705SXin Li
300*67e74705SXin Li switch (Reason) {
301*67e74705SXin Li case PPCallbacks::EnterFile:
302*67e74705SXin Li WriteLineInfo(CurLine, " 1", 2);
303*67e74705SXin Li break;
304*67e74705SXin Li case PPCallbacks::ExitFile:
305*67e74705SXin Li WriteLineInfo(CurLine, " 2", 2);
306*67e74705SXin Li break;
307*67e74705SXin Li case PPCallbacks::SystemHeaderPragma:
308*67e74705SXin Li case PPCallbacks::RenameFile:
309*67e74705SXin Li WriteLineInfo(CurLine);
310*67e74705SXin Li break;
311*67e74705SXin Li }
312*67e74705SXin Li }
313*67e74705SXin Li
InclusionDirective(SourceLocation HashLoc,const Token & IncludeTok,StringRef FileName,bool IsAngled,CharSourceRange FilenameRange,const FileEntry * File,StringRef SearchPath,StringRef RelativePath,const Module * Imported)314*67e74705SXin Li void PrintPPOutputPPCallbacks::InclusionDirective(SourceLocation HashLoc,
315*67e74705SXin Li const Token &IncludeTok,
316*67e74705SXin Li StringRef FileName,
317*67e74705SXin Li bool IsAngled,
318*67e74705SXin Li CharSourceRange FilenameRange,
319*67e74705SXin Li const FileEntry *File,
320*67e74705SXin Li StringRef SearchPath,
321*67e74705SXin Li StringRef RelativePath,
322*67e74705SXin Li const Module *Imported) {
323*67e74705SXin Li // When preprocessing, turn implicit imports into @imports.
324*67e74705SXin Li // FIXME: This is a stop-gap until a more comprehensive "preprocessing with
325*67e74705SXin Li // modules" solution is introduced.
326*67e74705SXin Li if (Imported) {
327*67e74705SXin Li startNewLineIfNeeded();
328*67e74705SXin Li MoveToLine(HashLoc);
329*67e74705SXin Li if (PP.getLangOpts().ObjC2) {
330*67e74705SXin Li OS << "@import " << Imported->getFullModuleName() << ";"
331*67e74705SXin Li << " /* clang -E: implicit import for \"" << File->getName()
332*67e74705SXin Li << "\" */";
333*67e74705SXin Li } else {
334*67e74705SXin Li // FIXME: Preseve whether this was a
335*67e74705SXin Li // #include/#include_next/#include_macros/#import.
336*67e74705SXin Li OS << "#include "
337*67e74705SXin Li << (IsAngled ? '<' : '"')
338*67e74705SXin Li << FileName
339*67e74705SXin Li << (IsAngled ? '>' : '"')
340*67e74705SXin Li << " /* clang -E: implicit import for module "
341*67e74705SXin Li << Imported->getFullModuleName() << " */";
342*67e74705SXin Li }
343*67e74705SXin Li // Since we want a newline after the @import, but not a #<line>, start a new
344*67e74705SXin Li // line immediately.
345*67e74705SXin Li EmittedTokensOnThisLine = true;
346*67e74705SXin Li startNewLineIfNeeded();
347*67e74705SXin Li }
348*67e74705SXin Li }
349*67e74705SXin Li
350*67e74705SXin Li /// Ident - Handle #ident directives when read by the preprocessor.
351*67e74705SXin Li ///
Ident(SourceLocation Loc,StringRef S)352*67e74705SXin Li void PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, StringRef S) {
353*67e74705SXin Li MoveToLine(Loc);
354*67e74705SXin Li
355*67e74705SXin Li OS.write("#ident ", strlen("#ident "));
356*67e74705SXin Li OS.write(S.begin(), S.size());
357*67e74705SXin Li EmittedTokensOnThisLine = true;
358*67e74705SXin Li }
359*67e74705SXin Li
360*67e74705SXin Li /// MacroDefined - This hook is called whenever a macro definition is seen.
MacroDefined(const Token & MacroNameTok,const MacroDirective * MD)361*67e74705SXin Li void PrintPPOutputPPCallbacks::MacroDefined(const Token &MacroNameTok,
362*67e74705SXin Li const MacroDirective *MD) {
363*67e74705SXin Li const MacroInfo *MI = MD->getMacroInfo();
364*67e74705SXin Li // Only print out macro definitions in -dD mode.
365*67e74705SXin Li if (!DumpDefines ||
366*67e74705SXin Li // Ignore __FILE__ etc.
367*67e74705SXin Li MI->isBuiltinMacro()) return;
368*67e74705SXin Li
369*67e74705SXin Li MoveToLine(MI->getDefinitionLoc());
370*67e74705SXin Li PrintMacroDefinition(*MacroNameTok.getIdentifierInfo(), *MI, PP, OS);
371*67e74705SXin Li setEmittedDirectiveOnThisLine();
372*67e74705SXin Li }
373*67e74705SXin Li
MacroUndefined(const Token & MacroNameTok,const MacroDefinition & MD)374*67e74705SXin Li void PrintPPOutputPPCallbacks::MacroUndefined(const Token &MacroNameTok,
375*67e74705SXin Li const MacroDefinition &MD) {
376*67e74705SXin Li // Only print out macro definitions in -dD mode.
377*67e74705SXin Li if (!DumpDefines) return;
378*67e74705SXin Li
379*67e74705SXin Li MoveToLine(MacroNameTok.getLocation());
380*67e74705SXin Li OS << "#undef " << MacroNameTok.getIdentifierInfo()->getName();
381*67e74705SXin Li setEmittedDirectiveOnThisLine();
382*67e74705SXin Li }
383*67e74705SXin Li
outputPrintable(raw_ostream & OS,StringRef Str)384*67e74705SXin Li static void outputPrintable(raw_ostream &OS, StringRef Str) {
385*67e74705SXin Li for (unsigned char Char : Str) {
386*67e74705SXin Li if (isPrintable(Char) && Char != '\\' && Char != '"')
387*67e74705SXin Li OS << (char)Char;
388*67e74705SXin Li else // Output anything hard as an octal escape.
389*67e74705SXin Li OS << '\\'
390*67e74705SXin Li << (char)('0' + ((Char >> 6) & 7))
391*67e74705SXin Li << (char)('0' + ((Char >> 3) & 7))
392*67e74705SXin Li << (char)('0' + ((Char >> 0) & 7));
393*67e74705SXin Li }
394*67e74705SXin Li }
395*67e74705SXin Li
PragmaMessage(SourceLocation Loc,StringRef Namespace,PragmaMessageKind Kind,StringRef Str)396*67e74705SXin Li void PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc,
397*67e74705SXin Li StringRef Namespace,
398*67e74705SXin Li PragmaMessageKind Kind,
399*67e74705SXin Li StringRef Str) {
400*67e74705SXin Li startNewLineIfNeeded();
401*67e74705SXin Li MoveToLine(Loc);
402*67e74705SXin Li OS << "#pragma ";
403*67e74705SXin Li if (!Namespace.empty())
404*67e74705SXin Li OS << Namespace << ' ';
405*67e74705SXin Li switch (Kind) {
406*67e74705SXin Li case PMK_Message:
407*67e74705SXin Li OS << "message(\"";
408*67e74705SXin Li break;
409*67e74705SXin Li case PMK_Warning:
410*67e74705SXin Li OS << "warning \"";
411*67e74705SXin Li break;
412*67e74705SXin Li case PMK_Error:
413*67e74705SXin Li OS << "error \"";
414*67e74705SXin Li break;
415*67e74705SXin Li }
416*67e74705SXin Li
417*67e74705SXin Li outputPrintable(OS, Str);
418*67e74705SXin Li OS << '"';
419*67e74705SXin Li if (Kind == PMK_Message)
420*67e74705SXin Li OS << ')';
421*67e74705SXin Li setEmittedDirectiveOnThisLine();
422*67e74705SXin Li }
423*67e74705SXin Li
PragmaDebug(SourceLocation Loc,StringRef DebugType)424*67e74705SXin Li void PrintPPOutputPPCallbacks::PragmaDebug(SourceLocation Loc,
425*67e74705SXin Li StringRef DebugType) {
426*67e74705SXin Li startNewLineIfNeeded();
427*67e74705SXin Li MoveToLine(Loc);
428*67e74705SXin Li
429*67e74705SXin Li OS << "#pragma clang __debug ";
430*67e74705SXin Li OS << DebugType;
431*67e74705SXin Li
432*67e74705SXin Li setEmittedDirectiveOnThisLine();
433*67e74705SXin Li }
434*67e74705SXin Li
435*67e74705SXin Li void PrintPPOutputPPCallbacks::
PragmaDiagnosticPush(SourceLocation Loc,StringRef Namespace)436*67e74705SXin Li PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) {
437*67e74705SXin Li startNewLineIfNeeded();
438*67e74705SXin Li MoveToLine(Loc);
439*67e74705SXin Li OS << "#pragma " << Namespace << " diagnostic push";
440*67e74705SXin Li setEmittedDirectiveOnThisLine();
441*67e74705SXin Li }
442*67e74705SXin Li
443*67e74705SXin Li void PrintPPOutputPPCallbacks::
PragmaDiagnosticPop(SourceLocation Loc,StringRef Namespace)444*67e74705SXin Li PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) {
445*67e74705SXin Li startNewLineIfNeeded();
446*67e74705SXin Li MoveToLine(Loc);
447*67e74705SXin Li OS << "#pragma " << Namespace << " diagnostic pop";
448*67e74705SXin Li setEmittedDirectiveOnThisLine();
449*67e74705SXin Li }
450*67e74705SXin Li
PragmaDiagnostic(SourceLocation Loc,StringRef Namespace,diag::Severity Map,StringRef Str)451*67e74705SXin Li void PrintPPOutputPPCallbacks::PragmaDiagnostic(SourceLocation Loc,
452*67e74705SXin Li StringRef Namespace,
453*67e74705SXin Li diag::Severity Map,
454*67e74705SXin Li StringRef Str) {
455*67e74705SXin Li startNewLineIfNeeded();
456*67e74705SXin Li MoveToLine(Loc);
457*67e74705SXin Li OS << "#pragma " << Namespace << " diagnostic ";
458*67e74705SXin Li switch (Map) {
459*67e74705SXin Li case diag::Severity::Remark:
460*67e74705SXin Li OS << "remark";
461*67e74705SXin Li break;
462*67e74705SXin Li case diag::Severity::Warning:
463*67e74705SXin Li OS << "warning";
464*67e74705SXin Li break;
465*67e74705SXin Li case diag::Severity::Error:
466*67e74705SXin Li OS << "error";
467*67e74705SXin Li break;
468*67e74705SXin Li case diag::Severity::Ignored:
469*67e74705SXin Li OS << "ignored";
470*67e74705SXin Li break;
471*67e74705SXin Li case diag::Severity::Fatal:
472*67e74705SXin Li OS << "fatal";
473*67e74705SXin Li break;
474*67e74705SXin Li }
475*67e74705SXin Li OS << " \"" << Str << '"';
476*67e74705SXin Li setEmittedDirectiveOnThisLine();
477*67e74705SXin Li }
478*67e74705SXin Li
PragmaWarning(SourceLocation Loc,StringRef WarningSpec,ArrayRef<int> Ids)479*67e74705SXin Li void PrintPPOutputPPCallbacks::PragmaWarning(SourceLocation Loc,
480*67e74705SXin Li StringRef WarningSpec,
481*67e74705SXin Li ArrayRef<int> Ids) {
482*67e74705SXin Li startNewLineIfNeeded();
483*67e74705SXin Li MoveToLine(Loc);
484*67e74705SXin Li OS << "#pragma warning(" << WarningSpec << ':';
485*67e74705SXin Li for (ArrayRef<int>::iterator I = Ids.begin(), E = Ids.end(); I != E; ++I)
486*67e74705SXin Li OS << ' ' << *I;
487*67e74705SXin Li OS << ')';
488*67e74705SXin Li setEmittedDirectiveOnThisLine();
489*67e74705SXin Li }
490*67e74705SXin Li
PragmaWarningPush(SourceLocation Loc,int Level)491*67e74705SXin Li void PrintPPOutputPPCallbacks::PragmaWarningPush(SourceLocation Loc,
492*67e74705SXin Li int Level) {
493*67e74705SXin Li startNewLineIfNeeded();
494*67e74705SXin Li MoveToLine(Loc);
495*67e74705SXin Li OS << "#pragma warning(push";
496*67e74705SXin Li if (Level >= 0)
497*67e74705SXin Li OS << ", " << Level;
498*67e74705SXin Li OS << ')';
499*67e74705SXin Li setEmittedDirectiveOnThisLine();
500*67e74705SXin Li }
501*67e74705SXin Li
PragmaWarningPop(SourceLocation Loc)502*67e74705SXin Li void PrintPPOutputPPCallbacks::PragmaWarningPop(SourceLocation Loc) {
503*67e74705SXin Li startNewLineIfNeeded();
504*67e74705SXin Li MoveToLine(Loc);
505*67e74705SXin Li OS << "#pragma warning(pop)";
506*67e74705SXin Li setEmittedDirectiveOnThisLine();
507*67e74705SXin Li }
508*67e74705SXin Li
509*67e74705SXin Li /// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this
510*67e74705SXin Li /// is called for the first token on each new line. If this really is the start
511*67e74705SXin Li /// of a new logical line, handle it and return true, otherwise return false.
512*67e74705SXin Li /// This may not be the start of a logical line because the "start of line"
513*67e74705SXin Li /// marker is set for spelling lines, not expansion ones.
HandleFirstTokOnLine(Token & Tok)514*67e74705SXin Li bool PrintPPOutputPPCallbacks::HandleFirstTokOnLine(Token &Tok) {
515*67e74705SXin Li // Figure out what line we went to and insert the appropriate number of
516*67e74705SXin Li // newline characters.
517*67e74705SXin Li if (!MoveToLine(Tok.getLocation()))
518*67e74705SXin Li return false;
519*67e74705SXin Li
520*67e74705SXin Li // Print out space characters so that the first token on a line is
521*67e74705SXin Li // indented for easy reading.
522*67e74705SXin Li unsigned ColNo = SM.getExpansionColumnNumber(Tok.getLocation());
523*67e74705SXin Li
524*67e74705SXin Li // The first token on a line can have a column number of 1, yet still expect
525*67e74705SXin Li // leading white space, if a macro expansion in column 1 starts with an empty
526*67e74705SXin Li // macro argument, or an empty nested macro expansion. In this case, move the
527*67e74705SXin Li // token to column 2.
528*67e74705SXin Li if (ColNo == 1 && Tok.hasLeadingSpace())
529*67e74705SXin Li ColNo = 2;
530*67e74705SXin Li
531*67e74705SXin Li // This hack prevents stuff like:
532*67e74705SXin Li // #define HASH #
533*67e74705SXin Li // HASH define foo bar
534*67e74705SXin Li // From having the # character end up at column 1, which makes it so it
535*67e74705SXin Li // is not handled as a #define next time through the preprocessor if in
536*67e74705SXin Li // -fpreprocessed mode.
537*67e74705SXin Li if (ColNo <= 1 && Tok.is(tok::hash))
538*67e74705SXin Li OS << ' ';
539*67e74705SXin Li
540*67e74705SXin Li // Otherwise, indent the appropriate number of spaces.
541*67e74705SXin Li for (; ColNo > 1; --ColNo)
542*67e74705SXin Li OS << ' ';
543*67e74705SXin Li
544*67e74705SXin Li return true;
545*67e74705SXin Li }
546*67e74705SXin Li
HandleNewlinesInToken(const char * TokStr,unsigned Len)547*67e74705SXin Li void PrintPPOutputPPCallbacks::HandleNewlinesInToken(const char *TokStr,
548*67e74705SXin Li unsigned Len) {
549*67e74705SXin Li unsigned NumNewlines = 0;
550*67e74705SXin Li for (; Len; --Len, ++TokStr) {
551*67e74705SXin Li if (*TokStr != '\n' &&
552*67e74705SXin Li *TokStr != '\r')
553*67e74705SXin Li continue;
554*67e74705SXin Li
555*67e74705SXin Li ++NumNewlines;
556*67e74705SXin Li
557*67e74705SXin Li // If we have \n\r or \r\n, skip both and count as one line.
558*67e74705SXin Li if (Len != 1 &&
559*67e74705SXin Li (TokStr[1] == '\n' || TokStr[1] == '\r') &&
560*67e74705SXin Li TokStr[0] != TokStr[1]) {
561*67e74705SXin Li ++TokStr;
562*67e74705SXin Li --Len;
563*67e74705SXin Li }
564*67e74705SXin Li }
565*67e74705SXin Li
566*67e74705SXin Li if (NumNewlines == 0) return;
567*67e74705SXin Li
568*67e74705SXin Li CurLine += NumNewlines;
569*67e74705SXin Li }
570*67e74705SXin Li
571*67e74705SXin Li
572*67e74705SXin Li namespace {
573*67e74705SXin Li struct UnknownPragmaHandler : public PragmaHandler {
574*67e74705SXin Li const char *Prefix;
575*67e74705SXin Li PrintPPOutputPPCallbacks *Callbacks;
576*67e74705SXin Li
577*67e74705SXin Li // Set to true if tokens should be expanded
578*67e74705SXin Li bool ShouldExpandTokens;
579*67e74705SXin Li
UnknownPragmaHandler__anon837ae7ae0211::UnknownPragmaHandler580*67e74705SXin Li UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks,
581*67e74705SXin Li bool RequireTokenExpansion)
582*67e74705SXin Li : Prefix(prefix), Callbacks(callbacks),
583*67e74705SXin Li ShouldExpandTokens(RequireTokenExpansion) {}
HandlePragma__anon837ae7ae0211::UnknownPragmaHandler584*67e74705SXin Li void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
585*67e74705SXin Li Token &PragmaTok) override {
586*67e74705SXin Li // Figure out what line we went to and insert the appropriate number of
587*67e74705SXin Li // newline characters.
588*67e74705SXin Li Callbacks->startNewLineIfNeeded();
589*67e74705SXin Li Callbacks->MoveToLine(PragmaTok.getLocation());
590*67e74705SXin Li Callbacks->OS.write(Prefix, strlen(Prefix));
591*67e74705SXin Li
592*67e74705SXin Li if (ShouldExpandTokens) {
593*67e74705SXin Li // The first token does not have expanded macros. Expand them, if
594*67e74705SXin Li // required.
595*67e74705SXin Li auto Toks = llvm::make_unique<Token[]>(1);
596*67e74705SXin Li Toks[0] = PragmaTok;
597*67e74705SXin Li PP.EnterTokenStream(std::move(Toks), /*NumToks=*/1,
598*67e74705SXin Li /*DisableMacroExpansion=*/false);
599*67e74705SXin Li PP.Lex(PragmaTok);
600*67e74705SXin Li }
601*67e74705SXin Li Token PrevToken;
602*67e74705SXin Li Token PrevPrevToken;
603*67e74705SXin Li PrevToken.startToken();
604*67e74705SXin Li PrevPrevToken.startToken();
605*67e74705SXin Li
606*67e74705SXin Li // Read and print all of the pragma tokens.
607*67e74705SXin Li while (PragmaTok.isNot(tok::eod)) {
608*67e74705SXin Li if (PragmaTok.hasLeadingSpace() ||
609*67e74705SXin Li Callbacks->AvoidConcat(PrevPrevToken, PrevToken, PragmaTok))
610*67e74705SXin Li Callbacks->OS << ' ';
611*67e74705SXin Li std::string TokSpell = PP.getSpelling(PragmaTok);
612*67e74705SXin Li Callbacks->OS.write(&TokSpell[0], TokSpell.size());
613*67e74705SXin Li
614*67e74705SXin Li PrevPrevToken = PrevToken;
615*67e74705SXin Li PrevToken = PragmaTok;
616*67e74705SXin Li
617*67e74705SXin Li if (ShouldExpandTokens)
618*67e74705SXin Li PP.Lex(PragmaTok);
619*67e74705SXin Li else
620*67e74705SXin Li PP.LexUnexpandedToken(PragmaTok);
621*67e74705SXin Li }
622*67e74705SXin Li Callbacks->setEmittedDirectiveOnThisLine();
623*67e74705SXin Li }
624*67e74705SXin Li };
625*67e74705SXin Li } // end anonymous namespace
626*67e74705SXin Li
627*67e74705SXin Li
PrintPreprocessedTokens(Preprocessor & PP,Token & Tok,PrintPPOutputPPCallbacks * Callbacks,raw_ostream & OS)628*67e74705SXin Li static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok,
629*67e74705SXin Li PrintPPOutputPPCallbacks *Callbacks,
630*67e74705SXin Li raw_ostream &OS) {
631*67e74705SXin Li bool DropComments = PP.getLangOpts().TraditionalCPP &&
632*67e74705SXin Li !PP.getCommentRetentionState();
633*67e74705SXin Li
634*67e74705SXin Li char Buffer[256];
635*67e74705SXin Li Token PrevPrevTok, PrevTok;
636*67e74705SXin Li PrevPrevTok.startToken();
637*67e74705SXin Li PrevTok.startToken();
638*67e74705SXin Li while (1) {
639*67e74705SXin Li if (Callbacks->hasEmittedDirectiveOnThisLine()) {
640*67e74705SXin Li Callbacks->startNewLineIfNeeded();
641*67e74705SXin Li Callbacks->MoveToLine(Tok.getLocation());
642*67e74705SXin Li }
643*67e74705SXin Li
644*67e74705SXin Li // If this token is at the start of a line, emit newlines if needed.
645*67e74705SXin Li if (Tok.isAtStartOfLine() && Callbacks->HandleFirstTokOnLine(Tok)) {
646*67e74705SXin Li // done.
647*67e74705SXin Li } else if (Tok.hasLeadingSpace() ||
648*67e74705SXin Li // If we haven't emitted a token on this line yet, PrevTok isn't
649*67e74705SXin Li // useful to look at and no concatenation could happen anyway.
650*67e74705SXin Li (Callbacks->hasEmittedTokensOnThisLine() &&
651*67e74705SXin Li // Don't print "-" next to "-", it would form "--".
652*67e74705SXin Li Callbacks->AvoidConcat(PrevPrevTok, PrevTok, Tok))) {
653*67e74705SXin Li OS << ' ';
654*67e74705SXin Li }
655*67e74705SXin Li
656*67e74705SXin Li if (DropComments && Tok.is(tok::comment)) {
657*67e74705SXin Li // Skip comments. Normally the preprocessor does not generate
658*67e74705SXin Li // tok::comment nodes at all when not keeping comments, but under
659*67e74705SXin Li // -traditional-cpp the lexer keeps /all/ whitespace, including comments.
660*67e74705SXin Li SourceLocation StartLoc = Tok.getLocation();
661*67e74705SXin Li Callbacks->MoveToLine(StartLoc.getLocWithOffset(Tok.getLength()));
662*67e74705SXin Li } else if (Tok.is(tok::annot_module_include) ||
663*67e74705SXin Li Tok.is(tok::annot_module_begin) ||
664*67e74705SXin Li Tok.is(tok::annot_module_end)) {
665*67e74705SXin Li // PrintPPOutputPPCallbacks::InclusionDirective handles producing
666*67e74705SXin Li // appropriate output here. Ignore this token entirely.
667*67e74705SXin Li PP.Lex(Tok);
668*67e74705SXin Li continue;
669*67e74705SXin Li } else if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
670*67e74705SXin Li OS << II->getName();
671*67e74705SXin Li } else if (Tok.isLiteral() && !Tok.needsCleaning() &&
672*67e74705SXin Li Tok.getLiteralData()) {
673*67e74705SXin Li OS.write(Tok.getLiteralData(), Tok.getLength());
674*67e74705SXin Li } else if (Tok.getLength() < 256) {
675*67e74705SXin Li const char *TokPtr = Buffer;
676*67e74705SXin Li unsigned Len = PP.getSpelling(Tok, TokPtr);
677*67e74705SXin Li OS.write(TokPtr, Len);
678*67e74705SXin Li
679*67e74705SXin Li // Tokens that can contain embedded newlines need to adjust our current
680*67e74705SXin Li // line number.
681*67e74705SXin Li if (Tok.getKind() == tok::comment || Tok.getKind() == tok::unknown)
682*67e74705SXin Li Callbacks->HandleNewlinesInToken(TokPtr, Len);
683*67e74705SXin Li } else {
684*67e74705SXin Li std::string S = PP.getSpelling(Tok);
685*67e74705SXin Li OS.write(&S[0], S.size());
686*67e74705SXin Li
687*67e74705SXin Li // Tokens that can contain embedded newlines need to adjust our current
688*67e74705SXin Li // line number.
689*67e74705SXin Li if (Tok.getKind() == tok::comment || Tok.getKind() == tok::unknown)
690*67e74705SXin Li Callbacks->HandleNewlinesInToken(&S[0], S.size());
691*67e74705SXin Li }
692*67e74705SXin Li Callbacks->setEmittedTokensOnThisLine();
693*67e74705SXin Li
694*67e74705SXin Li if (Tok.is(tok::eof)) break;
695*67e74705SXin Li
696*67e74705SXin Li PrevPrevTok = PrevTok;
697*67e74705SXin Li PrevTok = Tok;
698*67e74705SXin Li PP.Lex(Tok);
699*67e74705SXin Li }
700*67e74705SXin Li }
701*67e74705SXin Li
702*67e74705SXin Li typedef std::pair<const IdentifierInfo *, MacroInfo *> id_macro_pair;
MacroIDCompare(const id_macro_pair * LHS,const id_macro_pair * RHS)703*67e74705SXin Li static int MacroIDCompare(const id_macro_pair *LHS, const id_macro_pair *RHS) {
704*67e74705SXin Li return LHS->first->getName().compare(RHS->first->getName());
705*67e74705SXin Li }
706*67e74705SXin Li
DoPrintMacros(Preprocessor & PP,raw_ostream * OS)707*67e74705SXin Li static void DoPrintMacros(Preprocessor &PP, raw_ostream *OS) {
708*67e74705SXin Li // Ignore unknown pragmas.
709*67e74705SXin Li PP.IgnorePragmas();
710*67e74705SXin Li
711*67e74705SXin Li // -dM mode just scans and ignores all tokens in the files, then dumps out
712*67e74705SXin Li // the macro table at the end.
713*67e74705SXin Li PP.EnterMainSourceFile();
714*67e74705SXin Li
715*67e74705SXin Li Token Tok;
716*67e74705SXin Li do PP.Lex(Tok);
717*67e74705SXin Li while (Tok.isNot(tok::eof));
718*67e74705SXin Li
719*67e74705SXin Li SmallVector<id_macro_pair, 128> MacrosByID;
720*67e74705SXin Li for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end();
721*67e74705SXin Li I != E; ++I) {
722*67e74705SXin Li auto *MD = I->second.getLatest();
723*67e74705SXin Li if (MD && MD->isDefined())
724*67e74705SXin Li MacrosByID.push_back(id_macro_pair(I->first, MD->getMacroInfo()));
725*67e74705SXin Li }
726*67e74705SXin Li llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(), MacroIDCompare);
727*67e74705SXin Li
728*67e74705SXin Li for (unsigned i = 0, e = MacrosByID.size(); i != e; ++i) {
729*67e74705SXin Li MacroInfo &MI = *MacrosByID[i].second;
730*67e74705SXin Li // Ignore computed macros like __LINE__ and friends.
731*67e74705SXin Li if (MI.isBuiltinMacro()) continue;
732*67e74705SXin Li
733*67e74705SXin Li PrintMacroDefinition(*MacrosByID[i].first, MI, PP, *OS);
734*67e74705SXin Li *OS << '\n';
735*67e74705SXin Li }
736*67e74705SXin Li }
737*67e74705SXin Li
738*67e74705SXin Li /// DoPrintPreprocessedInput - This implements -E mode.
739*67e74705SXin Li ///
DoPrintPreprocessedInput(Preprocessor & PP,raw_ostream * OS,const PreprocessorOutputOptions & Opts)740*67e74705SXin Li void clang::DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS,
741*67e74705SXin Li const PreprocessorOutputOptions &Opts) {
742*67e74705SXin Li // Show macros with no output is handled specially.
743*67e74705SXin Li if (!Opts.ShowCPP) {
744*67e74705SXin Li assert(Opts.ShowMacros && "Not yet implemented!");
745*67e74705SXin Li DoPrintMacros(PP, OS);
746*67e74705SXin Li return;
747*67e74705SXin Li }
748*67e74705SXin Li
749*67e74705SXin Li // Inform the preprocessor whether we want it to retain comments or not, due
750*67e74705SXin Li // to -C or -CC.
751*67e74705SXin Li PP.SetCommentRetentionState(Opts.ShowComments, Opts.ShowMacroComments);
752*67e74705SXin Li
753*67e74705SXin Li PrintPPOutputPPCallbacks *Callbacks = new PrintPPOutputPPCallbacks(
754*67e74705SXin Li PP, *OS, !Opts.ShowLineMarkers, Opts.ShowMacros, Opts.UseLineDirectives);
755*67e74705SXin Li
756*67e74705SXin Li // Expand macros in pragmas with -fms-extensions. The assumption is that
757*67e74705SXin Li // the majority of pragmas in such a file will be Microsoft pragmas.
758*67e74705SXin Li PP.AddPragmaHandler(new UnknownPragmaHandler(
759*67e74705SXin Li "#pragma", Callbacks,
760*67e74705SXin Li /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
761*67e74705SXin Li PP.AddPragmaHandler(
762*67e74705SXin Li "GCC", new UnknownPragmaHandler(
763*67e74705SXin Li "#pragma GCC", Callbacks,
764*67e74705SXin Li /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
765*67e74705SXin Li PP.AddPragmaHandler(
766*67e74705SXin Li "clang", new UnknownPragmaHandler(
767*67e74705SXin Li "#pragma clang", Callbacks,
768*67e74705SXin Li /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt));
769*67e74705SXin Li
770*67e74705SXin Li // The tokens after pragma omp need to be expanded.
771*67e74705SXin Li //
772*67e74705SXin Li // OpenMP [2.1, Directive format]
773*67e74705SXin Li // Preprocessing tokens following the #pragma omp are subject to macro
774*67e74705SXin Li // replacement.
775*67e74705SXin Li PP.AddPragmaHandler("omp",
776*67e74705SXin Li new UnknownPragmaHandler("#pragma omp", Callbacks,
777*67e74705SXin Li /*RequireTokenExpansion=*/true));
778*67e74705SXin Li
779*67e74705SXin Li PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks));
780*67e74705SXin Li
781*67e74705SXin Li // After we have configured the preprocessor, enter the main file.
782*67e74705SXin Li PP.EnterMainSourceFile();
783*67e74705SXin Li
784*67e74705SXin Li // Consume all of the tokens that come from the predefines buffer. Those
785*67e74705SXin Li // should not be emitted into the output and are guaranteed to be at the
786*67e74705SXin Li // start.
787*67e74705SXin Li const SourceManager &SourceMgr = PP.getSourceManager();
788*67e74705SXin Li Token Tok;
789*67e74705SXin Li do {
790*67e74705SXin Li PP.Lex(Tok);
791*67e74705SXin Li if (Tok.is(tok::eof) || !Tok.getLocation().isFileID())
792*67e74705SXin Li break;
793*67e74705SXin Li
794*67e74705SXin Li PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());
795*67e74705SXin Li if (PLoc.isInvalid())
796*67e74705SXin Li break;
797*67e74705SXin Li
798*67e74705SXin Li if (strcmp(PLoc.getFilename(), "<built-in>"))
799*67e74705SXin Li break;
800*67e74705SXin Li } while (true);
801*67e74705SXin Li
802*67e74705SXin Li // Read all the preprocessed tokens, printing them out to the stream.
803*67e74705SXin Li PrintPreprocessedTokens(PP, Tok, Callbacks, *OS);
804*67e74705SXin Li *OS << '\n';
805*67e74705SXin Li }
806