1 //===---- CoverageMappingGen.h - Coverage mapping generation ----*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Instrumentation-based code coverage mapping generator 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_CLANG_LIB_CODEGEN_COVERAGEMAPPINGGEN_H 14 #define LLVM_CLANG_LIB_CODEGEN_COVERAGEMAPPINGGEN_H 15 16 #include "clang/Basic/LLVM.h" 17 #include "clang/Basic/SourceLocation.h" 18 #include "clang/Lex/PPCallbacks.h" 19 #include "clang/Lex/Preprocessor.h" 20 #include "llvm/ADT/DenseMap.h" 21 #include "llvm/IR/GlobalValue.h" 22 #include "llvm/Support/raw_ostream.h" 23 24 namespace clang { 25 26 class LangOptions; 27 class SourceManager; 28 class FileEntry; 29 class Preprocessor; 30 class Decl; 31 class Stmt; 32 33 struct SkippedRange { 34 SourceRange Range; 35 // The location of token before the skipped source range. 36 SourceLocation PrevTokLoc; 37 // The location of token after the skipped source range. 38 SourceLocation NextTokLoc; 39 40 SkippedRange(SourceRange Range, SourceLocation PrevTokLoc = SourceLocation(), 41 SourceLocation NextTokLoc = SourceLocation()) 42 : Range(Range), PrevTokLoc(PrevTokLoc), NextTokLoc(NextTokLoc) {} 43 }; 44 45 /// Stores additional source code information like skipped ranges which 46 /// is required by the coverage mapping generator and is obtained from 47 /// the preprocessor. 48 class CoverageSourceInfo : public PPCallbacks, 49 public CommentHandler, 50 public EmptylineHandler { 51 // A vector of skipped source ranges and PrevTokLoc with NextTokLoc. 52 std::vector<SkippedRange> SkippedRanges; 53 54 SourceManager &SourceMgr; 55 56 public: 57 // Location of the token parsed before HandleComment is called. This is 58 // updated every time Preprocessor::Lex lexes a new token. 59 SourceLocation PrevTokLoc; 60 61 CoverageSourceInfo(SourceManager &SourceMgr) : SourceMgr(SourceMgr) {} 62 63 std::vector<SkippedRange> &getSkippedRanges() { return SkippedRanges; } 64 65 void AddSkippedRange(SourceRange Range); 66 67 void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override; 68 69 void HandleEmptyline(SourceRange Range) override; 70 71 bool HandleComment(Preprocessor &PP, SourceRange Range) override; 72 73 void updateNextTokLoc(SourceLocation Loc); 74 }; 75 76 namespace CodeGen { 77 78 class CodeGenModule; 79 80 /// Organizes the cross-function state that is used while generating 81 /// code coverage mapping data. 82 class CoverageMappingModuleGen { 83 /// Information needed to emit a coverage record for a function. 84 struct FunctionInfo { 85 uint64_t NameHash; 86 uint64_t FuncHash; 87 std::string CoverageMapping; 88 bool IsUsed; 89 }; 90 91 CodeGenModule &CGM; 92 CoverageSourceInfo &SourceInfo; 93 llvm::SmallDenseMap<const FileEntry *, unsigned, 8> FileEntries; 94 std::vector<llvm::Constant *> FunctionNames; 95 std::vector<FunctionInfo> FunctionRecords; 96 std::map<std::string, std::string> CoveragePrefixMap; 97 98 std::string getCurrentDirname(); 99 std::string normalizeFilename(StringRef Filename); 100 101 /// Emit a function record. 102 void emitFunctionMappingRecord(const FunctionInfo &Info, 103 uint64_t FilenamesRef); 104 105 public: 106 static CoverageSourceInfo *setUpCoverageCallbacks(Preprocessor &PP); 107 108 CoverageMappingModuleGen(CodeGenModule &CGM, CoverageSourceInfo &SourceInfo); 109 110 CoverageSourceInfo &getSourceInfo() const { 111 return SourceInfo; 112 } 113 114 /// Add a function's coverage mapping record to the collection of the 115 /// function mapping records. 116 void addFunctionMappingRecord(llvm::GlobalVariable *FunctionName, 117 StringRef FunctionNameValue, 118 uint64_t FunctionHash, 119 const std::string &CoverageMapping, 120 bool IsUsed = true); 121 122 /// Emit the coverage mapping data for a translation unit. 123 void emit(); 124 125 /// Return the coverage mapping translation unit file id 126 /// for the given file. 127 unsigned getFileID(const FileEntry *File); 128 129 /// Return an interface into CodeGenModule. 130 CodeGenModule &getCodeGenModule() { return CGM; } 131 }; 132 133 /// Organizes the per-function state that is used while generating 134 /// code coverage mapping data. 135 class CoverageMappingGen { 136 CoverageMappingModuleGen &CVM; 137 SourceManager &SM; 138 const LangOptions &LangOpts; 139 llvm::DenseMap<const Stmt *, unsigned> *CounterMap; 140 141 public: 142 CoverageMappingGen(CoverageMappingModuleGen &CVM, SourceManager &SM, 143 const LangOptions &LangOpts) 144 : CVM(CVM), SM(SM), LangOpts(LangOpts), CounterMap(nullptr) {} 145 146 CoverageMappingGen(CoverageMappingModuleGen &CVM, SourceManager &SM, 147 const LangOptions &LangOpts, 148 llvm::DenseMap<const Stmt *, unsigned> *CounterMap) 149 : CVM(CVM), SM(SM), LangOpts(LangOpts), CounterMap(CounterMap) {} 150 151 /// Emit the coverage mapping data which maps the regions of 152 /// code to counters that will be used to find the execution 153 /// counts for those regions. 154 void emitCounterMapping(const Decl *D, llvm::raw_ostream &OS); 155 156 /// Emit the coverage mapping data for an unused function. 157 /// It creates mapping regions with the counter of zero. 158 void emitEmptyMapping(const Decl *D, llvm::raw_ostream &OS); 159 }; 160 161 } // end namespace CodeGen 162 } // end namespace clang 163 164 #endif 165