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