186150471SEugene Zelenko //===--- PPCallbacksTracker.h - Preprocessor tracking -----------*- C++ -*-===// 29979454eSJohn Thompson // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 69979454eSJohn Thompson // 786150471SEugene Zelenko //===----------------------------------------------------------------------===// 89979454eSJohn Thompson /// 99979454eSJohn Thompson /// \file 10282dc72cSDmitri Gribenko /// Classes and definitions for preprocessor tracking. 119979454eSJohn Thompson /// 129979454eSJohn Thompson /// The core definition is the PPCallbacksTracker class, derived from Clang's 139979454eSJohn Thompson /// PPCallbacks class from the Lex library, which overrides all the callbacks 149979454eSJohn Thompson /// and collects information about each callback call, saving it in a 159979454eSJohn Thompson /// data structure built up of CallbackCall and Argument objects, which 169979454eSJohn Thompson /// record the preprocessor callback name and arguments in high-level string 179979454eSJohn Thompson /// form for later inspection. 189979454eSJohn Thompson /// 1986150471SEugene Zelenko //===----------------------------------------------------------------------===// 209979454eSJohn Thompson 219979454eSJohn Thompson #ifndef PPTRACE_PPCALLBACKSTRACKER_H 229979454eSJohn Thompson #define PPTRACE_PPCALLBACKSTRACKER_H 239979454eSJohn Thompson 249979454eSJohn Thompson #include "clang/Lex/PPCallbacks.h" 259979454eSJohn Thompson #include "clang/Lex/Preprocessor.h" 26205c0589SKrzysztof Parzyszek #include "clang/Basic/SourceManager.h" 2786150471SEugene Zelenko #include "llvm/ADT/ArrayRef.h" 2886150471SEugene Zelenko #include "llvm/ADT/SmallSet.h" 29560a45a3SFangrui Song #include "llvm/ADT/StringMap.h" 3086150471SEugene Zelenko #include "llvm/ADT/StringRef.h" 31560a45a3SFangrui Song #include "llvm/Support/GlobPattern.h" 3286150471SEugene Zelenko #include <string> 3386150471SEugene Zelenko #include <vector> 349979454eSJohn Thompson 35be860a04SFangrui Song namespace clang { 36be860a04SFangrui Song namespace pp_trace { 379979454eSJohn Thompson 38be860a04SFangrui Song // This struct represents one callback function argument by name and value. 39be860a04SFangrui Song struct Argument { 409979454eSJohn Thompson std::string Name; 419979454eSJohn Thompson std::string Value; 429979454eSJohn Thompson }; 439979454eSJohn Thompson 44282dc72cSDmitri Gribenko /// This class represents one callback call by name and an array 459979454eSJohn Thompson /// of arguments. 469979454eSJohn Thompson class CallbackCall { 479979454eSJohn Thompson public: CallbackCall(llvm::StringRef Name)489979454eSJohn Thompson CallbackCall(llvm::StringRef Name) : Name(Name) {} 4986150471SEugene Zelenko CallbackCall() = default; 509979454eSJohn Thompson 519979454eSJohn Thompson std::string Name; 529979454eSJohn Thompson std::vector<Argument> Arguments; 539979454eSJohn Thompson }; 549979454eSJohn Thompson 55560a45a3SFangrui Song using FilterType = std::vector<std::pair<llvm::GlobPattern, bool>>; 56560a45a3SFangrui Song 57282dc72cSDmitri Gribenko /// This class overrides the PPCallbacks class for tracking preprocessor 589979454eSJohn Thompson /// activity by means of its callback functions. 599979454eSJohn Thompson /// 609979454eSJohn Thompson /// This object is given a vector for storing the trace information, built up 619979454eSJohn Thompson /// of CallbackCall and subordinate Argument objects for representing the 629979454eSJohn Thompson /// callback calls and their arguments. It's a reference so the vector can 639979454eSJohn Thompson /// exist beyond the lifetime of this object, because it's deleted by the 649979454eSJohn Thompson /// preprocessor automatically in its destructor. 659979454eSJohn Thompson /// 669979454eSJohn Thompson /// This class supports a mechanism for inhibiting trace output for 679979454eSJohn Thompson /// specific callbacks by name, for the purpose of eliminating output for 689979454eSJohn Thompson /// callbacks of no interest that might clutter the output. 699979454eSJohn Thompson /// 709979454eSJohn Thompson /// Following the constructor and destructor function declarations, the 71dd5571d5SKazuaki Ishizaki /// overridden callback functions are defined. The remaining functions are 729979454eSJohn Thompson /// helpers for recording the trace data, to reduce the coupling between it 739979454eSJohn Thompson /// and the recorded data structure. 74be860a04SFangrui Song class PPCallbacksTracker : public PPCallbacks { 759979454eSJohn Thompson public: 76282dc72cSDmitri Gribenko /// Note that all of the arguments are references, and owned 779979454eSJohn Thompson /// by the caller. 78560a45a3SFangrui Song /// \param Filters - List of (Glob,Enabled) pairs used to filter callbacks. 799979454eSJohn Thompson /// \param CallbackCalls - Trace buffer. 809979454eSJohn Thompson /// \param PP - The preprocessor. Needed for getting some argument strings. 81560a45a3SFangrui Song PPCallbacksTracker(const FilterType &Filters, 829979454eSJohn Thompson std::vector<CallbackCall> &CallbackCalls, 83be860a04SFangrui Song Preprocessor &PP); 849979454eSJohn Thompson 8587638f63SAlexander Kornienko ~PPCallbacksTracker() override; 869979454eSJohn Thompson 87dd5571d5SKazuaki Ishizaki // Overridden callback functions. 889979454eSJohn Thompson 89be860a04SFangrui Song void FileChanged(SourceLocation Loc, PPCallbacks::FileChangeReason Reason, 90be860a04SFangrui Song SrcMgr::CharacteristicKind FileType, 91be860a04SFangrui Song FileID PrevFID = FileID()) override; 9267d25fedSAlex Lorenz void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok, 93be860a04SFangrui Song SrcMgr::CharacteristicKind FileType) override; 94be860a04SFangrui Song void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, 959979454eSJohn Thompson llvm::StringRef FileName, bool IsAngled, 96d79ad2f1SJan Svoboda CharSourceRange FilenameRange, 97854c10f8SBenjamin Kramer OptionalFileEntryRef File, llvm::StringRef SearchPath, 98*da95d926SJan Svoboda llvm::StringRef RelativePath, 99*da95d926SJan Svoboda const Module *SuggestedModule, bool ModuleImported, 100be860a04SFangrui Song SrcMgr::CharacteristicKind FileType) override; 101be860a04SFangrui Song void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path, 102be860a04SFangrui Song const Module *Imported) override; 103a3dbe841SCraig Topper void EndOfMainFile() override; 104be860a04SFangrui Song void Ident(SourceLocation Loc, llvm::StringRef str) override; 105be860a04SFangrui Song void PragmaDirective(SourceLocation Loc, 106be860a04SFangrui Song PragmaIntroducerKind Introducer) override; 107be860a04SFangrui Song void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, 108d218565cSRafael Espindola llvm::StringRef Str) override; 109be860a04SFangrui Song void PragmaDetectMismatch(SourceLocation Loc, llvm::StringRef Name, 110d218565cSRafael Espindola llvm::StringRef Value) override; 111be860a04SFangrui Song void PragmaDebug(SourceLocation Loc, llvm::StringRef DebugType) override; 112be860a04SFangrui Song void PragmaMessage(SourceLocation Loc, llvm::StringRef Namespace, 113be860a04SFangrui Song PPCallbacks::PragmaMessageKind Kind, 114a3dbe841SCraig Topper llvm::StringRef Str) override; 115be860a04SFangrui Song void PragmaDiagnosticPush(SourceLocation Loc, 116a3dbe841SCraig Topper llvm::StringRef Namespace) override; 117be860a04SFangrui Song void PragmaDiagnosticPop(SourceLocation Loc, 118a3dbe841SCraig Topper llvm::StringRef Namespace) override; 119be860a04SFangrui Song void PragmaDiagnostic(SourceLocation Loc, llvm::StringRef Namespace, 120be860a04SFangrui Song diag::Severity mapping, llvm::StringRef Str) override; 121be860a04SFangrui Song void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name, 122be860a04SFangrui Song SourceLocation StateLoc, unsigned State) override; 1235cf06061SNico Weber void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier WarningSpec, 124a3dbe841SCraig Topper llvm::ArrayRef<int> Ids) override; 125be860a04SFangrui Song void PragmaWarningPush(SourceLocation Loc, int Level) override; 126be860a04SFangrui Song void PragmaWarningPop(SourceLocation Loc) override; 127be860a04SFangrui Song void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) override; 128be860a04SFangrui Song void PragmaExecCharsetPop(SourceLocation Loc) override; 129be860a04SFangrui Song void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, 130be860a04SFangrui Song SourceRange Range, const MacroArgs *Args) override; 131be860a04SFangrui Song void MacroDefined(const Token &MacroNameTok, 132be860a04SFangrui Song const MacroDirective *MD) override; 133be860a04SFangrui Song void MacroUndefined(const Token &MacroNameTok, const MacroDefinition &MD, 134be860a04SFangrui Song const MacroDirective *Undef) override; 135be860a04SFangrui Song void Defined(const Token &MacroNameTok, const MacroDefinition &MD, 136be860a04SFangrui Song SourceRange Range) override; 137be860a04SFangrui Song void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override; 138be860a04SFangrui Song void If(SourceLocation Loc, SourceRange ConditionRange, 139a3dbe841SCraig Topper ConditionValueKind ConditionValue) override; 140be860a04SFangrui Song void Elif(SourceLocation Loc, SourceRange ConditionRange, 141be860a04SFangrui Song ConditionValueKind ConditionValue, SourceLocation IfLoc) override; 142be860a04SFangrui Song void Ifdef(SourceLocation Loc, const Token &MacroNameTok, 143be860a04SFangrui Song const MacroDefinition &MD) override; 144be860a04SFangrui Song void Ifndef(SourceLocation Loc, const Token &MacroNameTok, 145be860a04SFangrui Song const MacroDefinition &MD) override; 146be860a04SFangrui Song void Else(SourceLocation Loc, SourceLocation IfLoc) override; 147be860a04SFangrui Song void Endif(SourceLocation Loc, SourceLocation IfLoc) override; 1489979454eSJohn Thompson 1499979454eSJohn Thompson // Helper functions. 1509979454eSJohn Thompson 151282dc72cSDmitri Gribenko /// Start a new callback. 1529979454eSJohn Thompson void beginCallback(const char *Name); 1539979454eSJohn Thompson 154282dc72cSDmitri Gribenko /// Append a string to the top trace item. 1559979454eSJohn Thompson void append(const char *Str); 1569979454eSJohn Thompson 157282dc72cSDmitri Gribenko /// Append a bool argument to the top trace item. 1589979454eSJohn Thompson void appendArgument(const char *Name, bool Value); 1599979454eSJohn Thompson 160282dc72cSDmitri Gribenko /// Append an int argument to the top trace item. 1619979454eSJohn Thompson void appendArgument(const char *Name, int Value); 1629979454eSJohn Thompson 163282dc72cSDmitri Gribenko /// Append a string argument to the top trace item. 1649979454eSJohn Thompson void appendArgument(const char *Name, const char *Value); 1659979454eSJohn Thompson 166282dc72cSDmitri Gribenko /// Append a string reference object argument to the top trace item. 1679979454eSJohn Thompson void appendArgument(const char *Name, llvm::StringRef Value); 1689979454eSJohn Thompson 169282dc72cSDmitri Gribenko /// Append a string object argument to the top trace item. 1709979454eSJohn Thompson void appendArgument(const char *Name, const std::string &Value); 1719979454eSJohn Thompson 172282dc72cSDmitri Gribenko /// Append a token argument to the top trace item. 173be860a04SFangrui Song void appendArgument(const char *Name, const Token &Value); 1749979454eSJohn Thompson 175282dc72cSDmitri Gribenko /// Append an enum argument to the top trace item. 17645857d4bSCraig Topper void appendArgument(const char *Name, int Value, const char *const Strings[]); 1779979454eSJohn Thompson 178282dc72cSDmitri Gribenko /// Append a FileID argument to the top trace item. 179be860a04SFangrui Song void appendArgument(const char *Name, FileID Value); 1809979454eSJohn Thompson 181d79ad2f1SJan Svoboda /// Append a FileEntryRef argument to the top trace item. 182854c10f8SBenjamin Kramer void appendArgument(const char *Name, OptionalFileEntryRef Value); 183d79ad2f1SJan Svoboda void appendArgument(const char *Name, FileEntryRef Value); 1849979454eSJohn Thompson 185282dc72cSDmitri Gribenko /// Append a SourceLocation argument to the top trace item. 186be860a04SFangrui Song void appendArgument(const char *Name, SourceLocation Value); 1879979454eSJohn Thompson 188282dc72cSDmitri Gribenko /// Append a SourceRange argument to the top trace item. 189be860a04SFangrui Song void appendArgument(const char *Name, SourceRange Value); 1909979454eSJohn Thompson 191282dc72cSDmitri Gribenko /// Append a CharSourceRange argument to the top trace item. 192be860a04SFangrui Song void appendArgument(const char *Name, CharSourceRange Value); 1939979454eSJohn Thompson 194282dc72cSDmitri Gribenko /// Append a ModuleIdPath argument to the top trace item. 195be860a04SFangrui Song void appendArgument(const char *Name, ModuleIdPath Value); 1969979454eSJohn Thompson 197282dc72cSDmitri Gribenko /// Append an IdentifierInfo argument to the top trace item. 198be860a04SFangrui Song void appendArgument(const char *Name, const IdentifierInfo *Value); 1999979454eSJohn Thompson 200282dc72cSDmitri Gribenko /// Append a MacroDirective argument to the top trace item. 201be860a04SFangrui Song void appendArgument(const char *Name, const MacroDirective *Value); 2029979454eSJohn Thompson 203282dc72cSDmitri Gribenko /// Append a MacroDefinition argument to the top trace item. 204be860a04SFangrui Song void appendArgument(const char *Name, const MacroDefinition &Value); 20533de8566SRichard Smith 206282dc72cSDmitri Gribenko /// Append a MacroArgs argument to the top trace item. 207be860a04SFangrui Song void appendArgument(const char *Name, const MacroArgs *Value); 2089979454eSJohn Thompson 209282dc72cSDmitri Gribenko /// Append a Module argument to the top trace item. 210be860a04SFangrui Song void appendArgument(const char *Name, const Module *Value); 2119979454eSJohn Thompson 212282dc72cSDmitri Gribenko /// Append a double-quoted argument to the top trace item. 21340178c35SYaron Keren void appendQuotedArgument(const char *Name, const std::string &Value); 2149979454eSJohn Thompson 215282dc72cSDmitri Gribenko /// Append a double-quoted file path argument to the top trace item. 2169979454eSJohn Thompson void appendFilePathArgument(const char *Name, llvm::StringRef Value); 2179979454eSJohn Thompson 218282dc72cSDmitri Gribenko /// Get the raw source string of the range. 219be860a04SFangrui Song llvm::StringRef getSourceString(CharSourceRange Range); 2209979454eSJohn Thompson 221282dc72cSDmitri Gribenko /// Callback trace information. 2229979454eSJohn Thompson /// We use a reference so the trace will be preserved for the caller 2239979454eSJohn Thompson /// after this object is destructed. 2249979454eSJohn Thompson std::vector<CallbackCall> &CallbackCalls; 2259979454eSJohn Thompson 226560a45a3SFangrui Song // List of (Glob,Enabled) pairs used to filter callbacks. 227560a45a3SFangrui Song const FilterType &Filters; 228560a45a3SFangrui Song 229560a45a3SFangrui Song // Whether a callback should be printed. 230560a45a3SFangrui Song llvm::StringMap<bool> CallbackIsEnabled; 2319979454eSJohn Thompson 232282dc72cSDmitri Gribenko /// Inhibit trace while this is set. 2339979454eSJohn Thompson bool DisableTrace; 2349979454eSJohn Thompson 235be860a04SFangrui Song Preprocessor &PP; 2369979454eSJohn Thompson }; 2379979454eSJohn Thompson 238be860a04SFangrui Song } // namespace pp_trace 239be860a04SFangrui Song } // namespace clang 240be860a04SFangrui Song 2419979454eSJohn Thompson #endif // PPTRACE_PPCALLBACKSTRACKER_H 242