brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.0 KiB · 0ed5059 Raw
192 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9// Instrumentation-based code coverage mapping generator10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_CLANG_LIB_CODEGEN_COVERAGEMAPPINGGEN_H14#define LLVM_CLANG_LIB_CODEGEN_COVERAGEMAPPINGGEN_H15 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/CommandLine.h"23#include "llvm/Support/raw_ostream.h"24 25namespace llvm::coverage {26extern cl::opt<bool> SystemHeadersCoverage;27}28 29namespace clang {30 31class LangOptions;32class SourceManager;33class FileEntry;34class Preprocessor;35class Decl;36class Stmt;37 38struct SkippedRange {39  enum Kind {40    PPIfElse, // Preprocessor #if/#else ...41    EmptyLine,42    Comment,43  };44 45  SourceRange Range;46  // The location of token before the skipped source range.47  SourceLocation PrevTokLoc;48  // The location of token after the skipped source range.49  SourceLocation NextTokLoc;50  // The nature of this skipped range51  Kind RangeKind;52 53  bool isComment() { return RangeKind == Comment; }54  bool isEmptyLine() { return RangeKind == EmptyLine; }55  bool isPPIfElse() { return RangeKind == PPIfElse; }56 57  SkippedRange(SourceRange Range, Kind K,58               SourceLocation PrevTokLoc = SourceLocation(),59               SourceLocation NextTokLoc = SourceLocation())60      : Range(Range), PrevTokLoc(PrevTokLoc), NextTokLoc(NextTokLoc),61        RangeKind(K) {}62};63 64/// Stores additional source code information like skipped ranges which65/// is required by the coverage mapping generator and is obtained from66/// the preprocessor.67class CoverageSourceInfo : public PPCallbacks,68                           public CommentHandler,69                           public EmptylineHandler {70  // A vector of skipped source ranges and PrevTokLoc with NextTokLoc.71  std::vector<SkippedRange> SkippedRanges;72 73  SourceManager &SourceMgr;74 75public:76  // Location of the token parsed before HandleComment is called. This is77  // updated every time Preprocessor::Lex lexes a new token.78  SourceLocation PrevTokLoc;79 80  CoverageSourceInfo(SourceManager &SourceMgr) : SourceMgr(SourceMgr) {}81 82  std::vector<SkippedRange> &getSkippedRanges() { return SkippedRanges; }83 84  void AddSkippedRange(SourceRange Range, SkippedRange::Kind RangeKind);85 86  void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override;87 88  void HandleEmptyline(SourceRange Range) override;89 90  bool HandleComment(Preprocessor &PP, SourceRange Range) override;91 92  void updateNextTokLoc(SourceLocation Loc);93};94 95namespace CodeGen {96 97class CodeGenModule;98class CounterPair;99 100namespace MCDC {101struct State;102}103 104/// Organizes the cross-function state that is used while generating105/// code coverage mapping data.106class CoverageMappingModuleGen {107  /// Information needed to emit a coverage record for a function.108  struct FunctionInfo {109    uint64_t NameHash;110    uint64_t FuncHash;111    std::string CoverageMapping;112    bool IsUsed;113  };114 115  CodeGenModule &CGM;116  CoverageSourceInfo &SourceInfo;117  llvm::SmallDenseMap<FileEntryRef, unsigned, 8> FileEntries;118  std::vector<llvm::Constant *> FunctionNames;119  std::vector<FunctionInfo> FunctionRecords;120 121  std::string getCurrentDirname();122  std::string normalizeFilename(StringRef Filename);123 124  /// Emit a function record.125  void emitFunctionMappingRecord(const FunctionInfo &Info,126                                 uint64_t FilenamesRef);127 128public:129  static CoverageSourceInfo *setUpCoverageCallbacks(Preprocessor &PP);130 131  CoverageMappingModuleGen(CodeGenModule &CGM, CoverageSourceInfo &SourceInfo);132 133  CoverageSourceInfo &getSourceInfo() const {134    return SourceInfo;135  }136 137  /// Add a function's coverage mapping record to the collection of the138  /// function mapping records.139  void addFunctionMappingRecord(llvm::GlobalVariable *FunctionName,140                                StringRef FunctionNameValue,141                                uint64_t FunctionHash,142                                const std::string &CoverageMapping,143                                bool IsUsed = true);144 145  /// Emit the coverage mapping data for a translation unit.146  void emit();147 148  /// Return the coverage mapping translation unit file id149  /// for the given file.150  unsigned getFileID(FileEntryRef File);151 152  /// Return an interface into CodeGenModule.153  CodeGenModule &getCodeGenModule() { return CGM; }154};155 156/// Organizes the per-function state that is used while generating157/// code coverage mapping data.158class CoverageMappingGen {159  CoverageMappingModuleGen &CVM;160  SourceManager &SM;161  const LangOptions &LangOpts;162  llvm::DenseMap<const Stmt *, CounterPair> *CounterMap;163  MCDC::State *MCDCState;164 165public:166  CoverageMappingGen(CoverageMappingModuleGen &CVM, SourceManager &SM,167                     const LangOptions &LangOpts)168      : CVM(CVM), SM(SM), LangOpts(LangOpts), CounterMap(nullptr),169        MCDCState(nullptr) {}170 171  CoverageMappingGen(CoverageMappingModuleGen &CVM, SourceManager &SM,172                     const LangOptions &LangOpts,173                     llvm::DenseMap<const Stmt *, CounterPair> *CounterMap,174                     MCDC::State *MCDCState)175      : CVM(CVM), SM(SM), LangOpts(LangOpts), CounterMap(CounterMap),176        MCDCState(MCDCState) {}177 178  /// Emit the coverage mapping data which maps the regions of179  /// code to counters that will be used to find the execution180  /// counts for those regions.181  void emitCounterMapping(const Decl *D, llvm::raw_ostream &OS);182 183  /// Emit the coverage mapping data for an unused function.184  /// It creates mapping regions with the counter of zero.185  void emitEmptyMapping(const Decl *D, llvm::raw_ostream &OS);186};187 188} // end namespace CodeGen189} // end namespace clang190 191#endif192