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