 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
81.3% |
135 / 166 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
89.2% |
148 / 166 |
| |
|
Line Coverage: |
87.2% |
198 / 227 |
| |
 |
|
 |
1 : //===--- PrintPreprocessedOutput.cpp - Implement the -E mode --------------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This code simply runs the preprocessor on the input file and prints out the
11 : // result. This is the traditional behavior of the -E option.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #include "clang/Frontend/Utils.h"
16 : #include "clang/Basic/Diagnostic.h"
17 : #include "clang/Basic/SourceManager.h"
18 : #include "clang/Frontend/PreprocessorOutputOptions.h"
19 : #include "clang/Lex/MacroInfo.h"
20 : #include "clang/Lex/PPCallbacks.h"
21 : #include "clang/Lex/Pragma.h"
22 : #include "clang/Lex/Preprocessor.h"
23 : #include "clang/Lex/TokenConcatenation.h"
24 : #include "llvm/ADT/SmallString.h"
25 : #include "llvm/ADT/STLExtras.h"
26 : #include "llvm/Config/config.h"
27 : #include "llvm/Support/raw_ostream.h"
28 : #include <cstdio>
29 : using namespace clang;
30 :
31 : /// PrintMacroDefinition - Print a macro definition in a form that will be
32 : /// properly accepted back as a definition.
33 : static void PrintMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI,
34 4686: Preprocessor &PP, llvm::raw_ostream &OS) {
35 4686: OS << "#define " << II.getName();
36 :
10: branch 1 taken
4676: branch 2 taken
37 4686: if (MI.isFunctionLike()) {
38 10: OS << '(';
9: branch 1 taken
1: branch 2 taken
39 10: if (!MI.arg_empty()) {
40 9: MacroInfo::arg_iterator AI = MI.arg_begin(), E = MI.arg_end();
3: branch 0 taken
9: branch 1 taken
41 12: for (; AI+1 != E; ++AI) {
42 3: OS << (*AI)->getName();
43 3: OS << ',';
44 : }
45 :
46 : // Last argument.
2: branch 3 taken
7: branch 4 taken
47 9: if ((*AI)->getName() == "__VA_ARGS__")
48 2: OS << "...";
49 : else
50 7: OS << (*AI)->getName();
51 : }
52 :
1: branch 1 taken
9: branch 2 taken
53 10: if (MI.isGNUVarargs())
54 1: OS << "..."; // #define foo(x...)
55 :
56 10: OS << ')';
57 : }
58 :
59 : // GCC always emits a space, even if the macro body is empty. However, do not
60 : // want to emit two spaces if the first token has a leading space.
4615: branch 1 taken
71: branch 2 taken
4607: branch 5 taken
8: branch 6 taken
4678: branch 7 taken
8: branch 8 taken
61 4686: if (MI.tokens_empty() || !MI.tokens_begin()->hasLeadingSpace())
62 4678: OS << ' ';
63 :
64 4686: llvm::SmallVector<char, 128> SpellingBuffer;
6006: branch 2 taken
4686: branch 3 taken
65 10692: for (MacroInfo::tokens_iterator I = MI.tokens_begin(), E = MI.tokens_end();
66 : I != E; ++I) {
401: branch 1 taken
5605: branch 2 taken
67 6006: if (I->hasLeadingSpace())
68 401: OS << ' ';
69 :
70 : // Make sure we have enough space in the spelling buffer.
4955: branch 2 taken
1051: branch 3 taken
71 6006: if (I->getLength() > SpellingBuffer.size())
72 4955: SpellingBuffer.resize(I->getLength());
73 6006: const char *Buffer = SpellingBuffer.data();
74 6006: unsigned SpellingLen = PP.getSpelling(*I, Buffer);
75 6006: OS.write(Buffer, SpellingLen);
76 4686: }
77 4686: }
78 :
79 : //===----------------------------------------------------------------------===//
80 : // Preprocessed token printer
81 : //===----------------------------------------------------------------------===//
82 :
83 : namespace {
200: branch 2 taken
0: branch 3 not taken
0: branch 7 not taken
0: branch 8 not taken
84 200: class PrintPPOutputPPCallbacks : public PPCallbacks {
85 : Preprocessor &PP;
86 : TokenConcatenation ConcatInfo;
87 : public:
88 : llvm::raw_ostream &OS;
89 : private:
90 : unsigned CurLine;
91 : bool EmittedTokensOnThisLine;
92 : bool EmittedMacroOnThisLine;
93 : SrcMgr::CharacteristicKind FileType;
94 : llvm::SmallString<512> CurFilename;
95 : bool Initialized;
96 : bool DisableLineMarkers;
97 : bool DumpDefines;
98 : bool UseLineDirective;
99 : public:
100 : PrintPPOutputPPCallbacks(Preprocessor &pp, llvm::raw_ostream &os,
101 200: bool lineMarkers, bool defines)
102 : : PP(pp), ConcatInfo(PP), OS(os), DisableLineMarkers(lineMarkers),
103 200: DumpDefines(defines) {
104 200: CurLine = 0;
105 200: CurFilename += "<uninit>";
106 200: EmittedTokensOnThisLine = false;
107 200: EmittedMacroOnThisLine = false;
108 200: FileType = SrcMgr::C_User;
109 200: Initialized = false;
110 :
111 : // If we're in microsoft mode, use normal #line instead of line markers.
112 200: UseLineDirective = PP.getLangOptions().Microsoft;
113 200: }
114 :
115 11115: void SetEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; }
116 4663: bool hasEmittedTokensOnThisLine() const { return EmittedTokensOnThisLine; }
117 :
118 : virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
119 : SrcMgr::CharacteristicKind FileType);
120 : virtual void Ident(SourceLocation Loc, const std::string &str);
121 : virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
122 : const std::string &Str);
123 :
124 :
125 : bool HandleFirstTokOnLine(Token &Tok);
126 : bool MoveToLine(SourceLocation Loc);
127 4619: bool AvoidConcat(const Token &PrevTok, const Token &Tok) {
128 4619: return ConcatInfo.AvoidConcat(PrevTok, Tok);
129 : }
130 : void WriteLineInfo(unsigned LineNo, const char *Extra=0, unsigned ExtraLen=0);
131 :
132 : void HandleNewlinesInToken(const char *TokStr, unsigned Len);
133 :
134 : /// MacroDefined - This hook is called whenever a macro definition is seen.
135 : void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI);
136 :
137 : };
138 : } // end anonymous namespace
139 :
140 : void PrintPPOutputPPCallbacks::WriteLineInfo(unsigned LineNo,
141 : const char *Extra,
142 2010: unsigned ExtraLen) {
1795: branch 0 taken
215: branch 1 taken
3: branch 2 taken
1792: branch 3 taken
143 2010: if (EmittedTokensOnThisLine || EmittedMacroOnThisLine) {
144 218: OS << '\n';
145 218: EmittedTokensOnThisLine = false;
146 218: EmittedMacroOnThisLine = false;
147 : }
148 :
149 : // Emit #line directives or GNU line markers depending on what mode we're in.
0: branch 0 not taken
2010: branch 1 taken
150 2010: if (UseLineDirective) {
151 0: OS << "#line" << ' ' << LineNo << ' ' << '"';
152 0: OS.write(&CurFilename[0], CurFilename.size());
153 0: OS << '"';
154 : } else {
155 2010: OS << '#' << ' ' << LineNo << ' ' << '"';
156 2010: OS.write(&CurFilename[0], CurFilename.size());
157 2010: OS << '"';
158 :
1117: branch 0 taken
893: branch 1 taken
159 2010: if (ExtraLen)
160 1117: OS.write(Extra, ExtraLen);
161 :
388: branch 0 taken
1622: branch 1 taken
162 2010: if (FileType == SrcMgr::C_System)
163 388: OS.write(" 3", 2);
293: branch 0 taken
1329: branch 1 taken
164 1622: else if (FileType == SrcMgr::C_ExternCSystem)
165 293: OS.write(" 3 4", 4);
166 : }
167 2010: OS << '\n';
168 2010: }
169 :
170 : /// MoveToLine - Move the output to the source line specified by the location
171 : /// object. We can do this by emitting some number of \n's, or be emitting a
172 : /// #line directive. This returns false if already at the specified line, true
173 : /// if some newlines were emitted.
174 2498: bool PrintPPOutputPPCallbacks::MoveToLine(SourceLocation Loc) {
175 2498: unsigned LineNo = PP.getSourceManager().getInstantiationLineNumber(Loc);
176 :
24: branch 0 taken
2474: branch 1 taken
177 2498: if (DisableLineMarkers) {
6: branch 0 taken
18: branch 1 taken
178 24: if (LineNo == CurLine) return false;
179 :
180 18: CurLine = LineNo;
181 :
12: branch 0 taken
6: branch 1 taken
12: branch 2 taken
0: branch 3 not taken
182 18: if (!EmittedTokensOnThisLine && !EmittedMacroOnThisLine)
183 12: return true;
184 :
185 6: OS << '\n';
186 6: EmittedTokensOnThisLine = false;
187 6: EmittedMacroOnThisLine = false;
188 6: return true;
189 : }
190 :
191 : // If this line is "close enough" to the original line, just print newlines,
192 : // otherwise print a #line directive.
2001: branch 0 taken
473: branch 1 taken
193 2474: if (LineNo-CurLine <= 8) {
1341: branch 0 taken
660: branch 1 taken
194 2001: if (LineNo-CurLine == 1)
195 1341: OS << '\n';
29: branch 0 taken
631: branch 1 taken
196 660: else if (LineNo == CurLine)
197 29: return false; // Spelling line moved, but instantiation line didn't.
198 : else {
199 631: const char *NewLines = "\n\n\n\n\n\n\n\n";
200 631: OS.write(NewLines, LineNo-CurLine);
201 : }
202 : } else {
203 473: WriteLineInfo(LineNo, 0, 0);
204 : }
205 :
206 2445: CurLine = LineNo;
207 2445: return true;
208 : }
209 :
210 :
211 : /// FileChanged - Whenever the preprocessor enters or exits a #include file
212 : /// it invokes this handler. Update our conception of the current source
213 : /// position.
214 : void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc,
215 : FileChangeReason Reason,
216 1381: SrcMgr::CharacteristicKind NewFileType) {
217 : // Unless we are exiting a #include, make sure to skip ahead to the line the
218 : // #include directive was at.
219 1381: SourceManager &SourceMgr = PP.getSourceManager();
672: branch 0 taken
709: branch 1 taken
220 1381: if (Reason == PPCallbacks::EnterFile) {
221 672: SourceLocation IncludeLoc = SourceMgr.getPresumedLoc(Loc).getIncludeLoc();
272: branch 1 taken
400: branch 2 taken
222 672: if (IncludeLoc.isValid())
223 272: MoveToLine(IncludeLoc);
0: branch 0 not taken
709: branch 1 taken
224 709: } else if (Reason == PPCallbacks::SystemHeaderPragma) {
225 0: MoveToLine(Loc);
226 :
227 : // TODO GCC emits the # directive for this directive on the line AFTER the
228 : // directive and emits a bunch of spaces that aren't needed. Emulate this
229 : // strange behavior.
230 : }
231 :
232 1381: Loc = SourceMgr.getInstantiationLoc(Loc);
233 : // FIXME: Should use presumed line #!
234 1381: CurLine = SourceMgr.getInstantiationLineNumber(Loc);
235 :
1343: branch 0 taken
38: branch 1 taken
236 1381: if (DisableLineMarkers) return;
237 :
238 1343: CurFilename.clear();
239 1343: CurFilename += SourceMgr.getPresumedLoc(Loc).getFilename();
240 1343: Lexer::Stringify(CurFilename);
241 1343: FileType = NewFileType;
242 :
194: branch 0 taken
1149: branch 1 taken
243 1343: if (!Initialized) {
244 194: WriteLineInfo(CurLine);
245 194: Initialized = true;
246 : }
247 :
653: branch 0 taken
464: branch 1 taken
226: branch 2 taken
0: branch 3 not taken
248 1343: switch (Reason) {
249 : case PPCallbacks::EnterFile:
250 653: WriteLineInfo(CurLine, " 1", 2);
251 653: break;
252 : case PPCallbacks::ExitFile:
253 464: WriteLineInfo(CurLine, " 2", 2);
254 464: break;
255 : case PPCallbacks::SystemHeaderPragma:
256 : case PPCallbacks::RenameFile:
257 226: WriteLineInfo(CurLine);
258 : break;
259 : }
260 : }
261 :
262 : /// Ident - Handle #ident directives when read by the preprocessor.
263 : ///
264 0: void PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, const std::string &S) {
265 0: MoveToLine(Loc);
266 :
267 0: OS.write("#ident ", strlen("#ident "));
268 0: OS.write(&S[0], S.size());
269 0: EmittedTokensOnThisLine = true;
270 0: }
271 :
272 : /// MacroDefined - This hook is called whenever a macro definition is seen.
273 : void PrintPPOutputPPCallbacks::MacroDefined(const IdentifierInfo *II,
274 23307: const MacroInfo *MI) {
275 : // Only print out macro definitions in -dD mode.
211: branch 0 taken
23096: branch 1 taken
0: branch 3 not taken
211: branch 4 taken
23096: branch 5 taken
211: branch 6 taken
276 23307: if (!DumpDefines ||
277 : // Ignore __FILE__ etc.
278 23096: MI->isBuiltinMacro()) return;
279 :
280 211: MoveToLine(MI->getDefinitionLoc());
281 211: PrintMacroDefinition(*II, *MI, PP, OS);
282 211: EmittedMacroOnThisLine = true;
283 : }
284 :
285 :
286 : void PrintPPOutputPPCallbacks::PragmaComment(SourceLocation Loc,
287 : const IdentifierInfo *Kind,
288 0: const std::string &Str) {
289 0: MoveToLine(Loc);
290 0: OS << "#pragma comment(" << Kind->getName();
291 :
0: branch 1 not taken
0: branch 2 not taken
292 0: if (!Str.empty()) {
293 0: OS << ", \"";
294 :
0: branch 1 not taken
0: branch 2 not taken
295 0: for (unsigned i = 0, e = Str.size(); i != e; ++i) {
296 0: unsigned char Char = Str[i];
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 5 not taken
0: branch 6 not taken
297 0: if (isprint(Char) && Char != '\\' && Char != '"')
298 0: OS << (char)Char;
299 : else // Output anything hard as an octal escape.
300 : OS << '\\'
301 : << (char)('0'+ ((Char >> 6) & 7))
302 : << (char)('0'+ ((Char >> 3) & 7))
303 0: << (char)('0'+ ((Char >> 0) & 7));
304 : }
305 0: OS << '"';
306 : }
307 :
308 0: OS << ')';
309 0: EmittedTokensOnThisLine = true;
310 0: }
311 :
312 :
313 : /// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this
314 : /// is called for the first token on each new line. If this really is the start
315 : /// of a new logical line, handle it and return true, otherwise return false.
316 : /// This may not be the start of a logical line because the "start of line"
317 : /// marker is set for spelling lines, not instantiation ones.
318 2009: bool PrintPPOutputPPCallbacks::HandleFirstTokOnLine(Token &Tok) {
319 : // Figure out what line we went to and insert the appropriate number of
320 : // newline characters.
33: branch 2 taken
1976: branch 3 taken
321 2009: if (!MoveToLine(Tok.getLocation()))
322 33: return false;
323 :
324 : // Print out space characters so that the first token on a line is
325 : // indented for easy reading.
326 1976: const SourceManager &SourceMgr = PP.getSourceManager();
327 1976: unsigned ColNo = SourceMgr.getInstantiationColumnNumber(Tok.getLocation());
328 :
329 : // This hack prevents stuff like:
330 : // #define HASH #
331 : // HASH define foo bar
332 : // From having the # character end up at column 1, which makes it so it
333 : // is not handled as a #define next time through the preprocessor if in
334 : // -fpreprocessed mode.
1806: branch 0 taken
170: branch 1 taken
7: branch 3 taken
1799: branch 4 taken
7: branch 5 taken
1969: branch 6 taken
335 1976: if (ColNo <= 1 && Tok.is(tok::hash))
336 7: OS << ' ';
337 :
338 : // Otherwise, indent the appropriate number of spaces.
666: branch 0 taken
1976: branch 1 taken
339 2642: for (; ColNo > 1; --ColNo)
340 666: OS << ' ';
341 :
342 1976: return true;
343 : }
344 :
345 : void PrintPPOutputPPCallbacks::HandleNewlinesInToken(const char *TokStr,
346 38: unsigned Len) {
347 38: unsigned NumNewlines = 0;
1418: branch 0 taken
38: branch 1 taken
348 1456: for (; Len; --Len, ++TokStr) {
1416: branch 0 taken
2: branch 1 taken
1416: branch 2 taken
0: branch 3 not taken
349 1418: if (*TokStr != '\n' &&
350 : *TokStr != '\r')
351 1416: continue;
352 :
353 2: ++NumNewlines;
354 :
355 : // If we have \n\r or \r\n, skip both and count as one line.
2: branch 0 taken
0: branch 1 not taken
2: branch 2 taken
0: branch 3 not taken
0: branch 4 not taken
2: branch 5 taken
2: branch 6 taken
2: branch 7 taken
356 2: if (Len != 1 &&
357 : (TokStr[1] == '\n' || TokStr[1] == '\r') &&
358 : TokStr[0] != TokStr[1])
359 0: ++TokStr, --Len;
360 : }
361 :
1: branch 0 taken
37: branch 1 taken
362 38: if (NumNewlines == 0) return;
363 :
364 1: CurLine += NumNewlines;
365 : }
366 :
367 :
368 : namespace {
400: branch 1 taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
369 400: struct UnknownPragmaHandler : public PragmaHandler {
370 : const char *Prefix;
371 : PrintPPOutputPPCallbacks *Callbacks;
372 :
373 400: UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks)
374 400: : PragmaHandler(0), Prefix(prefix), Callbacks(callbacks) {}
375 6: virtual void HandlePragma(Preprocessor &PP, Token &PragmaTok) {
376 : // Figure out what line we went to and insert the appropriate number of
377 : // newline characters.
378 6: Callbacks->MoveToLine(PragmaTok.getLocation());
379 6: Callbacks->OS.write(Prefix, strlen(Prefix));
380 :
381 : // Read and print all of the pragma tokens.
18: branch 2 taken
6: branch 3 taken
382 24: while (PragmaTok.isNot(tok::eom)) {
15: branch 1 taken
3: branch 2 taken
383 18: if (PragmaTok.hasLeadingSpace())
384 15: Callbacks->OS << ' ';
385 18: std::string TokSpell = PP.getSpelling(PragmaTok);
386 18: Callbacks->OS.write(&TokSpell[0], TokSpell.size());
387 18: PP.LexUnexpandedToken(PragmaTok);
388 : }
389 6: Callbacks->OS << '\n';
390 6: }
391 : };
392 : } // end anonymous namespace
393 :
394 :
395 : static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok,
396 : PrintPPOutputPPCallbacks *Callbacks,
397 200: llvm::raw_ostream &OS) {
398 : char Buffer[256];
399 200: Token PrevTok;
400 10915: while (1) {
401 :
402 : // If this token is at the start of a line, emit newlines if needed.
2009: branch 1 taken
9106: branch 2 taken
1976: branch 4 taken
33: branch 5 taken
9139: branch 6 taken
1976: branch 7 taken
403 11115: if (Tok.isAtStartOfLine() && Callbacks->HandleFirstTokOnLine(Tok)) {
404 : // done.
4663: branch 1 taken
4476: branch 2 taken
4619: branch 4 taken
44: branch 5 taken
233: branch 7 taken
4386: branch 8 taken
4709: branch 9 taken
4430: branch 10 taken
405 9139: } else if (Tok.hasLeadingSpace() ||
406 : // If we haven't emitted a token on this line yet, PrevTok isn't
407 : // useful to look at and no concatenation could happen anyway.
408 : (Callbacks->hasEmittedTokensOnThisLine() &&
409 : // Don't print "-" next to "-", it would form "--".
410 : Callbacks->AvoidConcat(PrevTok, Tok))) {
411 4709: OS << ' ';
412 : }
413 :
5145: branch 1 taken
5970: branch 2 taken
414 11115: if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
415 5145: OS << II->getName();
1417: branch 1 taken
4553: branch 2 taken
1417: branch 4 taken
0: branch 5 not taken
1417: branch 7 taken
0: branch 8 not taken
1417: branch 9 taken
4553: branch 10 taken
416 5970: } else if (Tok.isLiteral() && !Tok.needsCleaning() &&
417 : Tok.getLiteralData()) {
418 1417: OS.write(Tok.getLiteralData(), Tok.getLength());
4553: branch 1 taken
0: branch 2 not taken
419 4553: } else if (Tok.getLength() < 256) {
420 4553: const char *TokPtr = Buffer;
421 4553: unsigned Len = PP.getSpelling(Tok, TokPtr);
422 4553: OS.write(TokPtr, Len);
423 :
424 : // Tokens that can contain embedded newlines need to adjust our current
425 : // line number.
38: branch 1 taken
4515: branch 2 taken
426 4553: if (Tok.getKind() == tok::comment)
427 38: Callbacks->HandleNewlinesInToken(TokPtr, Len);
428 : } else {
429 0: std::string S = PP.getSpelling(Tok);
430 0: OS.write(&S[0], S.size());
431 :
432 : // Tokens that can contain embedded newlines need to adjust our current
433 : // line number.
0: branch 1 not taken
0: branch 2 not taken
434 0: if (Tok.getKind() == tok::comment)
435 0: Callbacks->HandleNewlinesInToken(&S[0], S.size());
436 : }
437 11115: Callbacks->SetEmittedTokensOnThisLine();
438 :
10915: branch 1 taken
200: branch 2 taken
439 11115: if (Tok.is(tok::eof)) break;
440 :
441 10915: PrevTok = Tok;
442 10915: PP.Lex(Tok);
443 : }
444 200: }
445 :
446 : typedef std::pair<IdentifierInfo*, MacroInfo*> id_macro_pair;
447 27356: static int MacroIDCompare(const void* a, const void* b) {
448 27356: const id_macro_pair *LHS = static_cast<const id_macro_pair*>(a);
449 27356: const id_macro_pair *RHS = static_cast<const id_macro_pair*>(b);
450 27356: return LHS->first->getName().compare(RHS->first->getName());
451 : }
452 :
453 45: static void DoPrintMacros(Preprocessor &PP, llvm::raw_ostream *OS) {
454 : // -dM mode just scans and ignores all tokens in the files, then dumps out
455 : // the macro table at the end.
456 45: PP.EnterMainSourceFile();
457 :
458 45: Token Tok;
253: branch 2 taken
45: branch 3 taken
459 298: do PP.Lex(Tok);
460 : while (Tok.isNot(tok::eof));
461 :
462 : llvm::SmallVector<id_macro_pair, 128>
463 45: MacrosByID(PP.macro_begin(), PP.macro_end());
464 45: llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(), MacroIDCompare);
465 :
5060: branch 1 taken
45: branch 2 taken
466 5105: for (unsigned i = 0, e = MacrosByID.size(); i != e; ++i) {
467 5060: MacroInfo &MI = *MacrosByID[i].second;
468 : // Ignore computed macros like __LINE__ and friends.
4475: branch 1 taken
585: branch 2 taken
469 5060: if (MI.isBuiltinMacro()) continue;
470 :
471 4475: PrintMacroDefinition(*MacrosByID[i].first, MI, PP, *OS);
472 4475: *OS << '\n';
473 45: }
474 45: }
475 :
476 : /// DoPrintPreprocessedInput - This implements -E mode.
477 : ///
478 : void clang::DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream *OS,
479 245: const PreprocessorOutputOptions &Opts) {
480 : // Show macros with no output is handled specially.
45: branch 0 taken
200: branch 1 taken
481 245: if (!Opts.ShowCPP) {
0: branch 0 not taken
45: branch 1 taken
482 45: assert(Opts.ShowMacros && "Not yet implemented!");
483 45: DoPrintMacros(PP, OS);
484 45: return;
485 : }
486 :
487 : // Inform the preprocessor whether we want it to retain comments or not, due
488 : // to -C or -CC.
489 200: PP.SetCommentRetentionState(Opts.ShowComments, Opts.ShowMacroComments);
490 :
491 200: OS->SetBufferSize(64*1024);
492 :
493 : PrintPPOutputPPCallbacks *Callbacks =
494 : new PrintPPOutputPPCallbacks(PP, *OS, !Opts.ShowLineMarkers,
495 200: Opts.ShowMacros);
496 200: PP.AddPragmaHandler(0, new UnknownPragmaHandler("#pragma", Callbacks));
497 : PP.AddPragmaHandler("GCC", new UnknownPragmaHandler("#pragma GCC",
498 200: Callbacks));
499 :
500 200: PP.setPPCallbacks(Callbacks);
501 :
502 : // After we have configured the preprocessor, enter the main file.
503 200: PP.EnterMainSourceFile();
504 :
505 : // Consume all of the tokens that come from the predefines buffer. Those
506 : // should not be emitted into the output and are guaranteed to be at the
507 : // start.
508 200: const SourceManager &SourceMgr = PP.getSourceManager();
509 200: Token Tok;
1211: branch 2 taken
37: branch 3 taken
1171: branch 6 taken
40: branch 7 taken
1048: branch 12 taken
123: branch 13 taken
1048: branch 14 taken
200: branch 15 taken
510 1248: do PP.Lex(Tok);
511 : while (Tok.isNot(tok::eof) && Tok.getLocation().isFileID() &&
512 : !strcmp(SourceMgr.getPresumedLoc(Tok.getLocation()).getFilename(),
513 : "<built-in>"));
514 :
515 : // Read all the preprocessed tokens, printing them out to the stream.
516 200: PrintPreprocessedTokens(PP, Tok, Callbacks, *OS);
517 200: *OS << '\n';
518 : }
519 :
Generated: 2010-02-10 01:31 by zcov