diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/CodeGen/CoverageMappingGen.h')
-rw-r--r-- | contrib/llvm-project/clang/lib/CodeGen/CoverageMappingGen.h | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CoverageMappingGen.h b/contrib/llvm-project/clang/lib/CodeGen/CoverageMappingGen.h new file mode 100644 index 000000000000..b26f79be5316 --- /dev/null +++ b/contrib/llvm-project/clang/lib/CodeGen/CoverageMappingGen.h @@ -0,0 +1,163 @@ +//===---- CoverageMappingGen.h - Coverage mapping generation ----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Instrumentation-based code coverage mapping generator +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_CODEGEN_COVERAGEMAPPINGGEN_H +#define LLVM_CLANG_LIB_CODEGEN_COVERAGEMAPPINGGEN_H + +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/Preprocessor.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/IR/GlobalValue.h" +#include "llvm/Support/raw_ostream.h" + +namespace clang { + +class LangOptions; +class SourceManager; +class FileEntry; +class Preprocessor; +class Decl; +class Stmt; + +struct SkippedRange { + SourceRange Range; + // The location of token before the skipped source range. + SourceLocation PrevTokLoc; + // The location of token after the skipped source range. + SourceLocation NextTokLoc; + + SkippedRange(SourceRange Range, SourceLocation PrevTokLoc = SourceLocation(), + SourceLocation NextTokLoc = SourceLocation()) + : Range(Range), PrevTokLoc(PrevTokLoc), NextTokLoc(NextTokLoc) {} +}; + +/// Stores additional source code information like skipped ranges which +/// is required by the coverage mapping generator and is obtained from +/// the preprocessor. +class CoverageSourceInfo : public PPCallbacks, + public CommentHandler, + public EmptylineHandler { + // A vector of skipped source ranges and PrevTokLoc with NextTokLoc. + std::vector<SkippedRange> SkippedRanges; + + SourceManager &SourceMgr; + +public: + // Location of the token parsed before HandleComment is called. This is + // updated every time Preprocessor::Lex lexes a new token. + SourceLocation PrevTokLoc; + + CoverageSourceInfo(SourceManager &SourceMgr) : SourceMgr(SourceMgr) {} + + std::vector<SkippedRange> &getSkippedRanges() { return SkippedRanges; } + + void AddSkippedRange(SourceRange Range); + + void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override; + + void HandleEmptyline(SourceRange Range) override; + + bool HandleComment(Preprocessor &PP, SourceRange Range) override; + + void updateNextTokLoc(SourceLocation Loc); +}; + +namespace CodeGen { + +class CodeGenModule; + +/// Organizes the cross-function state that is used while generating +/// code coverage mapping data. +class CoverageMappingModuleGen { + /// Information needed to emit a coverage record for a function. + struct FunctionInfo { + uint64_t NameHash; + uint64_t FuncHash; + std::string CoverageMapping; + bool IsUsed; + }; + + CodeGenModule &CGM; + CoverageSourceInfo &SourceInfo; + llvm::SmallDenseMap<const FileEntry *, unsigned, 8> FileEntries; + std::vector<llvm::Constant *> FunctionNames; + std::vector<FunctionInfo> FunctionRecords; + std::map<std::string, std::string> ProfilePrefixMap; + + std::string normalizeFilename(StringRef Filename); + + /// Emit a function record. + void emitFunctionMappingRecord(const FunctionInfo &Info, + uint64_t FilenamesRef); + +public: + static CoverageSourceInfo *setUpCoverageCallbacks(Preprocessor &PP); + + CoverageMappingModuleGen(CodeGenModule &CGM, CoverageSourceInfo &SourceInfo); + + CoverageSourceInfo &getSourceInfo() const { + return SourceInfo; + } + + /// Add a function's coverage mapping record to the collection of the + /// function mapping records. + void addFunctionMappingRecord(llvm::GlobalVariable *FunctionName, + StringRef FunctionNameValue, + uint64_t FunctionHash, + const std::string &CoverageMapping, + bool IsUsed = true); + + /// Emit the coverage mapping data for a translation unit. + void emit(); + + /// Return the coverage mapping translation unit file id + /// for the given file. + unsigned getFileID(const FileEntry *File); + + /// Return an interface into CodeGenModule. + CodeGenModule &getCodeGenModule() { return CGM; } +}; + +/// Organizes the per-function state that is used while generating +/// code coverage mapping data. +class CoverageMappingGen { + CoverageMappingModuleGen &CVM; + SourceManager &SM; + const LangOptions &LangOpts; + llvm::DenseMap<const Stmt *, unsigned> *CounterMap; + +public: + CoverageMappingGen(CoverageMappingModuleGen &CVM, SourceManager &SM, + const LangOptions &LangOpts) + : CVM(CVM), SM(SM), LangOpts(LangOpts), CounterMap(nullptr) {} + + CoverageMappingGen(CoverageMappingModuleGen &CVM, SourceManager &SM, + const LangOptions &LangOpts, + llvm::DenseMap<const Stmt *, unsigned> *CounterMap) + : CVM(CVM), SM(SM), LangOpts(LangOpts), CounterMap(CounterMap) {} + + /// Emit the coverage mapping data which maps the regions of + /// code to counters that will be used to find the execution + /// counts for those regions. + void emitCounterMapping(const Decl *D, llvm::raw_ostream &OS); + + /// Emit the coverage mapping data for an unused function. + /// It creates mapping regions with the counter of zero. + void emitEmptyMapping(const Decl *D, llvm::raw_ostream &OS); +}; + +} // end namespace CodeGen +} // end namespace clang + +#endif |