1 //===--- PPCallbacksTracker.cpp - Preprocessor tracker -*--*-------------===//
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 /// \file
11 /// \brief Implementations for preprocessor tracking.
12 ///
13 /// See the header for details.
14 ///
15 //===--------------------------------------------------------------------===//
16 
17 #include "PPCallbacksTracker.h"
18 #include "clang/Lex/MacroArgs.h"
19 #include "llvm/Support/raw_ostream.h"
20 #include <stdarg.h>
21 #include <stdio.h>
22 
23 // Utility functions.
24 
25 // Get a "file:line:column" source location string.
26 static std::string getSourceLocationString(clang::Preprocessor &PP,
27                                            clang::SourceLocation Loc) {
28   if (Loc.isInvalid())
29     return std::string("(none)");
30 
31   if (Loc.isFileID()) {
32     clang::PresumedLoc PLoc = PP.getSourceManager().getPresumedLoc(Loc);
33 
34     if (PLoc.isInvalid()) {
35       return std::string("(invalid)");
36     }
37 
38     std::string Str;
39     llvm::raw_string_ostream SS(Str);
40 
41     // The macro expansion and spelling pos is identical for file locs.
42     SS << "\"" << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
43        << PLoc.getColumn() << "\"";
44 
45     std::string Result = SS.str();
46 
47     // YAML treats backslash as escape, so use forward slashes.
48     std::replace(Result.begin(), Result.end(), '\\', '/');
49 
50     return Result;
51   }
52 
53   return std::string("(nonfile)");
54 }
55 
56 // Enum string tables.
57 
58 // FileChangeReason strings.
59 static const char *FileChangeReasonStrings[] = {
60   "EnterFile", "ExitFile", "SystemHeaderPragma", "RenameFile"
61 };
62 
63 // CharacteristicKind strings.
64 static const char *CharacteristicKindStrings[] = { "C_User", "C_System",
65                                                    "C_ExternCSystem" };
66 
67 // MacroDirective::Kind strings.
68 static const char *MacroDirectiveKindStrings[] = { "MD_Define", "MD_Undefine",
69                                                    "MD_Visibility" };
70 
71 // PragmaIntroducerKind strings.
72 static const char *PragmaIntroducerKindStrings[] = { "PIK_HashPragma",
73                                                      "PIK__Pragma",
74                                                      "PIK___pragma" };
75 
76 // PragmaMessageKind strings.
77 static const char *PragmaMessageKindStrings[] = { "PMK_Message", "PMK_Warning",
78                                                   "PMK_Error" };
79 
80 // ConditionValueKind strings.
81 const char *
82 ConditionValueKindStrings[] = {
83   "CVK_NotEvaluated", "CVK_False", "CVK_True"
84 };
85 
86 // Mapping strings.
87 static const char *MappingStrings[] = { "0",          "MAP_IGNORE",
88                                         "MAP_REMARK", "MAP_WARNING",
89                                         "MAP_ERROR",  "MAP_FATAL" };
90 
91 // PPCallbacksTracker functions.
92 
93 PPCallbacksTracker::PPCallbacksTracker(llvm::SmallSet<std::string, 4> &Ignore,
94                                        std::vector<CallbackCall> &CallbackCalls,
95                                        clang::Preprocessor &PP)
96     : CallbackCalls(CallbackCalls), Ignore(Ignore), PP(PP) {}
97 
98 PPCallbacksTracker::~PPCallbacksTracker() {}
99 
100 // Callback functions.
101 
102 // Callback invoked whenever a source file is entered or exited.
103 void PPCallbacksTracker::FileChanged(
104     clang::SourceLocation Loc, clang::PPCallbacks::FileChangeReason Reason,
105     clang::SrcMgr::CharacteristicKind FileType, clang::FileID PrevFID) {
106   beginCallback("FileChanged");
107   appendArgument("Loc", Loc);
108   appendArgument("Reason", Reason, FileChangeReasonStrings);
109   appendArgument("FileType", FileType, CharacteristicKindStrings);
110   appendArgument("PrevFID", PrevFID);
111 }
112 
113 // Callback invoked whenever a source file is skipped as the result
114 // of header guard optimization.
115 void
116 PPCallbacksTracker::FileSkipped(const clang::FileEntry &ParentFile,
117                                 const clang::Token &FilenameTok,
118                                 clang::SrcMgr::CharacteristicKind FileType) {
119   beginCallback("FileSkipped");
120   appendArgument("ParentFile", &ParentFile);
121   appendArgument("FilenameTok", FilenameTok);
122   appendArgument("FileType", FileType, CharacteristicKindStrings);
123 }
124 
125 // Callback invoked whenever an inclusion directive results in a
126 // file-not-found error.
127 bool
128 PPCallbacksTracker::FileNotFound(llvm::StringRef FileName,
129                                  llvm::SmallVectorImpl<char> &RecoveryPath) {
130   beginCallback("FileNotFound");
131   appendFilePathArgument("FileName", FileName);
132   return false;
133 }
134 
135 // Callback invoked whenever an inclusion directive of
136 // any kind (#include, #import, etc.) has been processed, regardless
137 // of whether the inclusion will actually result in an inclusion.
138 void PPCallbacksTracker::InclusionDirective(
139     clang::SourceLocation HashLoc, const clang::Token &IncludeTok,
140     llvm::StringRef FileName, bool IsAngled,
141     clang::CharSourceRange FilenameRange, const clang::FileEntry *File,
142     llvm::StringRef SearchPath, llvm::StringRef RelativePath,
143     const clang::Module *Imported) {
144   beginCallback("InclusionDirective");
145   appendArgument("IncludeTok", IncludeTok);
146   appendFilePathArgument("FileName", FileName);
147   appendArgument("IsAngled", IsAngled);
148   appendArgument("FilenameRange", FilenameRange);
149   appendArgument("File", File);
150   appendFilePathArgument("SearchPath", SearchPath);
151   appendFilePathArgument("RelativePath", RelativePath);
152   appendArgument("Imported", Imported);
153 }
154 
155 // Callback invoked whenever there was an explicit module-import
156 // syntax.
157 void PPCallbacksTracker::moduleImport(clang::SourceLocation ImportLoc,
158                                       clang::ModuleIdPath Path,
159                                       const clang::Module *Imported) {
160   beginCallback("moduleImport");
161   appendArgument("ImportLoc", ImportLoc);
162   appendArgument("Path", Path);
163   appendArgument("Imported", Imported);
164 }
165 
166 // Callback invoked when the end of the main file is reached.
167 // No subsequent callbacks will be made.
168 void PPCallbacksTracker::EndOfMainFile() { beginCallback("EndOfMainFile"); }
169 
170 // Callback invoked when a #ident or #sccs directive is read.
171 void PPCallbacksTracker::Ident(clang::SourceLocation Loc,
172                                const std::string &Str) {
173   beginCallback("Ident");
174   appendArgument("Loc", Loc);
175   appendArgument("Str", Str);
176 }
177 
178 // Callback invoked when start reading any pragma directive.
179 void
180 PPCallbacksTracker::PragmaDirective(clang::SourceLocation Loc,
181                                     clang::PragmaIntroducerKind Introducer) {
182   beginCallback("PragmaDirective");
183   appendArgument("Loc", Loc);
184   appendArgument("Introducer", Introducer, PragmaIntroducerKindStrings);
185 }
186 
187 // Callback invoked when a #pragma comment directive is read.
188 void PPCallbacksTracker::PragmaComment(clang::SourceLocation Loc,
189                                        const clang::IdentifierInfo *Kind,
190                                        const std::string &Str) {
191   beginCallback("PragmaComment");
192   appendArgument("Loc", Loc);
193   appendArgument("Kind", Kind);
194   appendArgument("Str", Str);
195 }
196 
197 // Callback invoked when a #pragma detect_mismatch directive is
198 // read.
199 void PPCallbacksTracker::PragmaDetectMismatch(clang::SourceLocation Loc,
200                                               const std::string &Name,
201                                               const std::string &Value) {
202   beginCallback("PragmaDetectMismatch");
203   appendArgument("Loc", Loc);
204   appendArgument("Name", Name);
205   appendArgument("Value", Value);
206 }
207 
208 // Callback invoked when a #pragma clang __debug directive is read.
209 void PPCallbacksTracker::PragmaDebug(clang::SourceLocation Loc,
210                                      llvm::StringRef DebugType) {
211   beginCallback("PragmaDebug");
212   appendArgument("Loc", Loc);
213   appendArgument("DebugType", DebugType);
214 }
215 
216 // Callback invoked when a #pragma message directive is read.
217 void PPCallbacksTracker::PragmaMessage(
218     clang::SourceLocation Loc, llvm::StringRef Namespace,
219     clang::PPCallbacks::PragmaMessageKind Kind, llvm::StringRef Str) {
220   beginCallback("PragmaMessage");
221   appendArgument("Loc", Loc);
222   appendArgument("Namespace", Namespace);
223   appendArgument("Kind", Kind, PragmaMessageKindStrings);
224   appendArgument("Str", Str);
225 }
226 
227 // Callback invoked when a #pragma gcc dianostic push directive
228 // is read.
229 void PPCallbacksTracker::PragmaDiagnosticPush(clang::SourceLocation Loc,
230                                               llvm::StringRef Namespace) {
231   beginCallback("PragmaDiagnosticPush");
232   appendArgument("Loc", Loc);
233   appendArgument("Namespace", Namespace);
234 }
235 
236 // Callback invoked when a #pragma gcc dianostic pop directive
237 // is read.
238 void PPCallbacksTracker::PragmaDiagnosticPop(clang::SourceLocation Loc,
239                                              llvm::StringRef Namespace) {
240   beginCallback("PragmaDiagnosticPop");
241   appendArgument("Loc", Loc);
242   appendArgument("Namespace", Namespace);
243 }
244 
245 // Callback invoked when a #pragma gcc dianostic directive is read.
246 void PPCallbacksTracker::PragmaDiagnostic(clang::SourceLocation Loc,
247                                           llvm::StringRef Namespace,
248                                           clang::diag::Severity Mapping,
249                                           llvm::StringRef Str) {
250   beginCallback("PragmaDiagnostic");
251   appendArgument("Loc", Loc);
252   appendArgument("Namespace", Namespace);
253   appendArgument("Mapping", (unsigned)Mapping, MappingStrings);
254   appendArgument("Str", Str);
255 }
256 
257 // Called when an OpenCL extension is either disabled or
258 // enabled with a pragma.
259 void PPCallbacksTracker::PragmaOpenCLExtension(
260     clang::SourceLocation NameLoc, const clang::IdentifierInfo *Name,
261     clang::SourceLocation StateLoc, unsigned State) {
262   beginCallback("PragmaOpenCLExtension");
263   appendArgument("NameLoc", NameLoc);
264   appendArgument("Name", Name);
265   appendArgument("StateLoc", StateLoc);
266   appendArgument("State", (int)State);
267 }
268 
269 // Callback invoked when a #pragma warning directive is read.
270 void PPCallbacksTracker::PragmaWarning(clang::SourceLocation Loc,
271                                        llvm::StringRef WarningSpec,
272                                        llvm::ArrayRef<int> Ids) {
273   beginCallback("PragmaWarning");
274   appendArgument("Loc", Loc);
275   appendArgument("WarningSpec", WarningSpec);
276 
277   std::string Str;
278   llvm::raw_string_ostream SS(Str);
279   SS << "[";
280   for (int i = 0, e = Ids.size(); i != e; ++i) {
281     if (i)
282       SS << ", ";
283     SS << Ids[i];
284   }
285   SS << "]";
286   appendArgument("Ids", SS.str());
287 }
288 
289 // Callback invoked when a #pragma warning(push) directive is read.
290 void PPCallbacksTracker::PragmaWarningPush(clang::SourceLocation Loc,
291                                            int Level) {
292   beginCallback("PragmaWarningPush");
293   appendArgument("Loc", Loc);
294   appendArgument("Level", Level);
295 }
296 
297 // Callback invoked when a #pragma warning(pop) directive is read.
298 void PPCallbacksTracker::PragmaWarningPop(clang::SourceLocation Loc) {
299   beginCallback("PragmaWarningPop");
300   appendArgument("Loc", Loc);
301 }
302 
303 // Called by Preprocessor::HandleMacroExpandedIdentifier when a
304 // macro invocation is found.
305 void
306 PPCallbacksTracker::MacroExpands(const clang::Token &MacroNameTok,
307                                  const clang::MacroDirective *MacroDirective,
308                                  clang::SourceRange Range,
309                                  const clang::MacroArgs *Args) {
310   beginCallback("MacroExpands");
311   appendArgument("MacroNameTok", MacroNameTok);
312   appendArgument("MacroDirective", MacroDirective);
313   appendArgument("Range", Range);
314   appendArgument("Args", Args);
315 }
316 
317 // Hook called whenever a macro definition is seen.
318 void
319 PPCallbacksTracker::MacroDefined(const clang::Token &MacroNameTok,
320                                  const clang::MacroDirective *MacroDirective) {
321   beginCallback("MacroDefined");
322   appendArgument("MacroNameTok", MacroNameTok);
323   appendArgument("MacroDirective", MacroDirective);
324 }
325 
326 // Hook called whenever a macro #undef is seen.
327 void PPCallbacksTracker::MacroUndefined(
328     const clang::Token &MacroNameTok,
329     const clang::MacroDirective *MacroDirective) {
330   beginCallback("MacroUndefined");
331   appendArgument("MacroNameTok", MacroNameTok);
332   appendArgument("MacroDirective", MacroDirective);
333 }
334 
335 // Hook called whenever the 'defined' operator is seen.
336 void PPCallbacksTracker::Defined(const clang::Token &MacroNameTok,
337                                  const clang::MacroDirective *MacroDirective,
338                                  clang::SourceRange Range) {
339   beginCallback("Defined");
340   appendArgument("MacroNameTok", MacroNameTok);
341   appendArgument("MacroDirective", MacroDirective);
342   appendArgument("Range", Range);
343 }
344 
345 // Hook called when a source range is skipped.
346 void PPCallbacksTracker::SourceRangeSkipped(clang::SourceRange Range) {
347   beginCallback("SourceRangeSkipped");
348   appendArgument("Range", Range);
349 }
350 
351 // Hook called whenever an #if is seen.
352 void PPCallbacksTracker::If(clang::SourceLocation Loc,
353                             clang::SourceRange ConditionRange,
354                             ConditionValueKind ConditionValue) {
355   beginCallback("If");
356   appendArgument("Loc", Loc);
357   appendArgument("ConditionRange", ConditionRange);
358   appendArgument("ConditionValue", ConditionValue, ConditionValueKindStrings);
359 }
360 
361 // Hook called whenever an #elif is seen.
362 void PPCallbacksTracker::Elif(clang::SourceLocation Loc,
363                               clang::SourceRange ConditionRange,
364                               ConditionValueKind ConditionValue,
365                               clang::SourceLocation IfLoc) {
366   beginCallback("Elif");
367   appendArgument("Loc", Loc);
368   appendArgument("ConditionRange", ConditionRange);
369   appendArgument("ConditionValue", ConditionValue, ConditionValueKindStrings);
370   appendArgument("IfLoc", IfLoc);
371 }
372 
373 // Hook called whenever an #ifdef is seen.
374 void PPCallbacksTracker::Ifdef(clang::SourceLocation Loc,
375                                const clang::Token &MacroNameTok,
376                                const clang::MacroDirective *MacroDirective) {
377   beginCallback("Ifdef");
378   appendArgument("Loc", Loc);
379   appendArgument("MacroNameTok", MacroNameTok);
380   appendArgument("MacroDirective", MacroDirective);
381 }
382 
383 // Hook called whenever an #ifndef is seen.
384 void PPCallbacksTracker::Ifndef(clang::SourceLocation Loc,
385                                 const clang::Token &MacroNameTok,
386                                 const clang::MacroDirective *MacroDirective) {
387   beginCallback("Ifndef");
388   appendArgument("Loc", Loc);
389   appendArgument("MacroNameTok", MacroNameTok);
390   appendArgument("MacroDirective", MacroDirective);
391 }
392 
393 // Hook called whenever an #else is seen.
394 void PPCallbacksTracker::Else(clang::SourceLocation Loc,
395                               clang::SourceLocation IfLoc) {
396   beginCallback("Else");
397   appendArgument("Loc", Loc);
398   appendArgument("IfLoc", IfLoc);
399 }
400 
401 // Hook called whenever an #endif is seen.
402 void PPCallbacksTracker::Endif(clang::SourceLocation Loc,
403                                clang::SourceLocation IfLoc) {
404   beginCallback("Endif");
405   appendArgument("Loc", Loc);
406   appendArgument("IfLoc", IfLoc);
407 }
408 
409 // Helper functions.
410 
411 // Start a new callback.
412 void PPCallbacksTracker::beginCallback(const char *Name) {
413   DisableTrace = Ignore.count(std::string(Name));
414   if (DisableTrace)
415     return;
416   CallbackCalls.push_back(CallbackCall(Name));
417 }
418 
419 // Append a bool argument to the top trace item.
420 void PPCallbacksTracker::appendArgument(const char *Name, bool Value) {
421   appendArgument(Name, (Value ? "true" : "false"));
422 }
423 
424 // Append an int argument to the top trace item.
425 void PPCallbacksTracker::appendArgument(const char *Name, int Value) {
426   std::string Str;
427   llvm::raw_string_ostream SS(Str);
428   SS << Value;
429   appendArgument(Name, SS.str());
430 }
431 
432 // Append a string argument to the top trace item.
433 void PPCallbacksTracker::appendArgument(const char *Name, const char *Value) {
434   if (DisableTrace)
435     return;
436   CallbackCalls.back().Arguments.push_back(Argument(Name, Value));
437 }
438 
439 // Append a string object argument to the top trace item.
440 void PPCallbacksTracker::appendArgument(const char *Name,
441                                         llvm::StringRef Value) {
442   appendArgument(Name, Value.str());
443 }
444 
445 // Append a string object argument to the top trace item.
446 void PPCallbacksTracker::appendArgument(const char *Name,
447                                         const std::string &Value) {
448   appendArgument(Name, Value.c_str());
449 }
450 
451 // Append a token argument to the top trace item.
452 void PPCallbacksTracker::appendArgument(const char *Name,
453                                         const clang::Token &Value) {
454   appendArgument(Name, PP.getSpelling(Value));
455 }
456 
457 // Append an enum argument to the top trace item.
458 void PPCallbacksTracker::appendArgument(const char *Name, int Value,
459                                         const char *Strings[]) {
460   appendArgument(Name, Strings[Value]);
461 }
462 
463 // Append a FileID argument to the top trace item.
464 void PPCallbacksTracker::appendArgument(const char *Name, clang::FileID Value) {
465   if (Value.isInvalid()) {
466     appendArgument(Name, "(invalid)");
467     return;
468   }
469   const clang::FileEntry *FileEntry =
470       PP.getSourceManager().getFileEntryForID(Value);
471   if (!FileEntry) {
472     appendArgument(Name, "(getFileEntryForID failed)");
473     return;
474   }
475   appendFilePathArgument(Name, FileEntry->getName());
476 }
477 
478 // Append a FileEntry argument to the top trace item.
479 void PPCallbacksTracker::appendArgument(const char *Name,
480                                         const clang::FileEntry *Value) {
481   if (!Value) {
482     appendArgument(Name, "(null)");
483     return;
484   }
485   appendFilePathArgument(Name, Value->getName());
486 }
487 
488 // Append a SourceLocation argument to the top trace item.
489 void PPCallbacksTracker::appendArgument(const char *Name,
490                                         clang::SourceLocation Value) {
491   if (Value.isInvalid()) {
492     appendArgument(Name, "(invalid)");
493     return;
494   }
495   appendArgument(Name, getSourceLocationString(PP, Value).c_str());
496 }
497 
498 // Append a SourceRange argument to the top trace item.
499 void PPCallbacksTracker::appendArgument(const char *Name,
500                                         clang::SourceRange Value) {
501   if (DisableTrace)
502     return;
503   if (Value.isInvalid()) {
504     appendArgument(Name, "(invalid)");
505     return;
506   }
507   std::string Str;
508   llvm::raw_string_ostream SS(Str);
509   SS << "[" << getSourceLocationString(PP, Value.getBegin()) << ", "
510      << getSourceLocationString(PP, Value.getEnd()) << "]";
511   appendArgument(Name, SS.str());
512 }
513 
514 // Append a CharSourceRange argument to the top trace item.
515 void PPCallbacksTracker::appendArgument(const char *Name,
516                                         clang::CharSourceRange Value) {
517   if (Value.isInvalid()) {
518     appendArgument(Name, "(invalid)");
519     return;
520   }
521   appendArgument(Name, getSourceString(Value).str().c_str());
522 }
523 
524 // Append a SourceLocation argument to the top trace item.
525 void PPCallbacksTracker::appendArgument(const char *Name,
526                                         clang::ModuleIdPath Value) {
527   if (DisableTrace)
528     return;
529   std::string Str;
530   llvm::raw_string_ostream SS(Str);
531   SS << "[";
532   for (int I = 0, E = Value.size(); I != E; ++I) {
533     if (I)
534       SS << ", ";
535     SS << "{"
536        << "Name: " << Value[I].first->getName() << ", "
537        << "Loc: " << getSourceLocationString(PP, Value[I].second) << "}";
538   }
539   SS << "]";
540   appendArgument(Name, SS.str());
541 }
542 
543 // Append an IdentifierInfo argument to the top trace item.
544 void PPCallbacksTracker::appendArgument(const char *Name,
545                                         const clang::IdentifierInfo *Value) {
546   if (!Value) {
547     appendArgument(Name, "(null)");
548     return;
549   }
550   appendArgument(Name, Value->getName().str().c_str());
551 }
552 
553 // Append a MacroDirective argument to the top trace item.
554 void PPCallbacksTracker::appendArgument(const char *Name,
555                                         const clang::MacroDirective *Value) {
556   if (!Value) {
557     appendArgument(Name, "(null)");
558     return;
559   }
560   appendArgument(Name, MacroDirectiveKindStrings[Value->getKind()]);
561 }
562 
563 // Append a MacroArgs argument to the top trace item.
564 void PPCallbacksTracker::appendArgument(const char *Name,
565                                         const clang::MacroArgs *Value) {
566   if (!Value) {
567     appendArgument(Name, "(null)");
568     return;
569   }
570   std::string Str;
571   llvm::raw_string_ostream SS(Str);
572   SS << "[";
573   // The argument tokens might include end tokens, so we reflect how
574   // how getUnexpArgument provides the arguments.
575   for (int I = 0, E = Value->getNumArguments(); I < E; ++I) {
576     const clang::Token *Current = Value->getUnexpArgument(I);
577     int TokenCount = Value->getArgLength(Current) + 1; // include EOF
578     E -= TokenCount;
579     if (I)
580       SS << ", ";
581     // We're assuming tokens are contiguous, as otherwise we have no
582     // other way to get at them.
583     --TokenCount;
584     for (int TokenIndex = 0; TokenIndex < TokenCount; ++TokenIndex, ++Current) {
585       if (TokenIndex)
586         SS << " ";
587       // We need to be careful here because the arguments might not be legal in
588       // YAML, so we use the token name for anything but identifiers and
589       // numeric literals.
590       if (Current->isAnyIdentifier() ||
591           Current->is(clang::tok::numeric_constant)) {
592         SS << PP.getSpelling(*Current);
593       } else {
594         SS << "<" << Current->getName() << ">";
595       }
596     }
597   }
598   SS << "]";
599   appendArgument(Name, SS.str());
600 }
601 
602 // Append a Module argument to the top trace item.
603 void PPCallbacksTracker::appendArgument(const char *Name,
604                                         const clang::Module *Value) {
605   if (!Value) {
606     appendArgument(Name, "(null)");
607     return;
608   }
609   appendArgument(Name, Value->Name.c_str());
610 }
611 
612 // Append a double-quoted argument to the top trace item.
613 void PPCallbacksTracker::appendQuotedArgument(const char *Name,
614                                               const std::string &Value) {
615   std::string Str;
616   llvm::raw_string_ostream SS(Str);
617   SS << "\"" << Value << "\"";
618   appendArgument(Name, SS.str());
619 }
620 
621 // Append a double-quoted file path argument to the top trace item.
622 void PPCallbacksTracker::appendFilePathArgument(const char *Name,
623                                                 llvm::StringRef Value) {
624   std::string Path(Value);
625   // YAML treats backslash as escape, so use forward slashes.
626   std::replace(Path.begin(), Path.end(), '\\', '/');
627   appendQuotedArgument(Name, Path);
628 }
629 
630 // Get the raw source string of the range.
631 llvm::StringRef
632 PPCallbacksTracker::getSourceString(clang::CharSourceRange Range) {
633   const char *B = PP.getSourceManager().getCharacterData(Range.getBegin());
634   const char *E = PP.getSourceManager().getCharacterData(Range.getEnd());
635   return llvm::StringRef(B, E - B);
636 }
637