blob: 465ad1bffe15ab04545e8308466220d15b9a7fd2 [file] [log] [blame]
John Thompson99794542013-10-31 12:23:32 +00001//===--- 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.
26static 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.
59static const char *FileChangeReasonStrings[] = {
60 "EnterFile", "ExitFile", "SystemHeaderPragma", "RenameFile"
61};
62
63// CharacteristicKind strings.
64static const char *CharacteristicKindStrings[] = { "C_User", "C_System",
65 "C_ExternCSystem" };
66
67// MacroDirective::Kind strings.
68static const char *MacroDirectiveKindStrings[] = { "MD_Define", "MD_Undefine",
69 "MD_Visibility" };
70
71// PragmaIntroducerKind strings.
72static const char *PragmaIntroducerKindStrings[] = { "PIK_HashPragma",
73 "PIK__Pragma",
74 "PIK___pragma" };
75
76// PragmaMessageKind strings.
77static const char *PragmaMessageKindStrings[] = { "PMK_Message", "PMK_Warning",
78 "PMK_Error" };
79
John Thompson87f9fef2013-12-07 08:41:15 +000080// ConditionValueKind strings.
81const char *
82ConditionValueKindStrings[] = {
83 "CVK_NotEvaluated", "CVK_False", "CVK_True"
84};
85
John Thompson99794542013-10-31 12:23:32 +000086// Mapping strings.
Tobias Grosser6c6af852014-02-28 09:42:12 +000087static const char *MappingStrings[] = { "0", "MAP_IGNORE",
88 "MAP_REMARK", "MAP_WARNING",
89 "MAP_ERROR", "MAP_FATAL" };
John Thompson99794542013-10-31 12:23:32 +000090
91// PPCallbacksTracker functions.
92
93PPCallbacksTracker::PPCallbacksTracker(llvm::SmallSet<std::string, 4> &Ignore,
94 std::vector<CallbackCall> &CallbackCalls,
95 clang::Preprocessor &PP)
96 : CallbackCalls(CallbackCalls), Ignore(Ignore), PP(PP) {}
97
98PPCallbacksTracker::~PPCallbacksTracker() {}
99
100// Callback functions.
101
102// Callback invoked whenever a source file is entered or exited.
103void 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.
115void
116PPCallbacksTracker::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.
127bool
128PPCallbacksTracker::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.
138void 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.
157void 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.
168void PPCallbacksTracker::EndOfMainFile() { beginCallback("EndOfMainFile"); }
169
170// Callback invoked when a #ident or #sccs directive is read.
171void PPCallbacksTracker::Ident(clang::SourceLocation Loc,
172 const std::string &Str) {
173 beginCallback("Ident");
174 appendArgument("Loc", Loc);
John Thompsonc1a13f32013-11-12 03:12:18 +0000175 appendArgument("Str", Str);
John Thompson99794542013-10-31 12:23:32 +0000176}
177
178// Callback invoked when start reading any pragma directive.
179void
180PPCallbacksTracker::PragmaDirective(clang::SourceLocation Loc,
181 clang::PragmaIntroducerKind Introducer) {
182 beginCallback("PragmaDirective");
183 appendArgument("Loc", Loc);
John Thompson52523252013-11-05 14:16:11 +0000184 appendArgument("Introducer", Introducer, PragmaIntroducerKindStrings);
John Thompson99794542013-10-31 12:23:32 +0000185}
186
187// Callback invoked when a #pragma comment directive is read.
188void 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.
199void 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.
209void 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.
217void 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.
229void 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.
238void 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.
246void PPCallbacksTracker::PragmaDiagnostic(clang::SourceLocation Loc,
247 llvm::StringRef Namespace,
248 clang::diag::Mapping Mapping,
249 llvm::StringRef Str) {
250 beginCallback("PragmaDiagnostic");
251 appendArgument("Loc", Loc);
252 appendArgument("Namespace", Namespace);
253 appendArgument("Mapping", Mapping, MappingStrings);
254 appendArgument("Str", Str);
255}
256
257// Called when an OpenCL extension is either disabled or
258// enabled with a pragma.
259void 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.
270void 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 }
John Thompsonc2d8a5c2013-11-14 00:18:19 +0000285 SS << "]";
John Thompson99794542013-10-31 12:23:32 +0000286 appendArgument("Ids", SS.str());
287}
288
289// Callback invoked when a #pragma warning(push) directive is read.
290void 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.
298void 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.
305void
306PPCallbacksTracker::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.
318void
319PPCallbacksTracker::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.
327void 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.
336void 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.
346void PPCallbacksTracker::SourceRangeSkipped(clang::SourceRange Range) {
347 beginCallback("SourceRangeSkipped");
348 appendArgument("Range", Range);
349}
350
351// Hook called whenever an #if is seen.
352void PPCallbacksTracker::If(clang::SourceLocation Loc,
353 clang::SourceRange ConditionRange,
John Thompson87f9fef2013-12-07 08:41:15 +0000354 ConditionValueKind ConditionValue) {
John Thompson99794542013-10-31 12:23:32 +0000355 beginCallback("If");
356 appendArgument("Loc", Loc);
357 appendArgument("ConditionRange", ConditionRange);
John Thompson87f9fef2013-12-07 08:41:15 +0000358 appendArgument("ConditionValue", ConditionValue, ConditionValueKindStrings);
John Thompson99794542013-10-31 12:23:32 +0000359}
360
361// Hook called whenever an #elif is seen.
362void PPCallbacksTracker::Elif(clang::SourceLocation Loc,
363 clang::SourceRange ConditionRange,
John Thompson87f9fef2013-12-07 08:41:15 +0000364 ConditionValueKind ConditionValue,
John Thompson99794542013-10-31 12:23:32 +0000365 clang::SourceLocation IfLoc) {
366 beginCallback("Elif");
367 appendArgument("Loc", Loc);
368 appendArgument("ConditionRange", ConditionRange);
John Thompson87f9fef2013-12-07 08:41:15 +0000369 appendArgument("ConditionValue", ConditionValue, ConditionValueKindStrings);
John Thompson99794542013-10-31 12:23:32 +0000370 appendArgument("IfLoc", IfLoc);
371}
372
373// Hook called whenever an #ifdef is seen.
374void 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.
384void 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.
394void 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.
402void 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.
412void 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.
420void 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.
425void 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.
433void 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.
440void 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.
446void 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.
452void 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.
458void 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.
464void 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 == 0) {
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.
479void PPCallbacksTracker::appendArgument(const char *Name,
480 const clang::FileEntry *Value) {
481 if (Value == 0) {
482 appendArgument(Name, "(null)");
483 return;
484 }
485 appendFilePathArgument(Name, Value->getName());
486}
487
488// Append a SourceLocation argument to the top trace item.
489void 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.
499void 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.
515void 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.
525void 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() << ", "
John Thompsonc1a13f32013-11-12 03:12:18 +0000537 << "Loc: " << getSourceLocationString(PP, Value[I].second) << "}";
John Thompson99794542013-10-31 12:23:32 +0000538 }
539 SS << "]";
540 appendArgument(Name, SS.str());
541}
542
543// Append an IdentifierInfo argument to the top trace item.
544void 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.
554void 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.
564void 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.
603void 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.
613void 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.
622void 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.
631llvm::StringRef
632PPCallbacksTracker::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}