1*67e74705SXin Li //===--- CoverageMappingGen.cpp - Coverage mapping generation ---*- C++ -*-===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // Instrumentation-based code coverage mapping generator
11*67e74705SXin Li //
12*67e74705SXin Li //===----------------------------------------------------------------------===//
13*67e74705SXin Li
14*67e74705SXin Li #include "CoverageMappingGen.h"
15*67e74705SXin Li #include "CodeGenFunction.h"
16*67e74705SXin Li #include "clang/AST/StmtVisitor.h"
17*67e74705SXin Li #include "clang/Lex/Lexer.h"
18*67e74705SXin Li #include "llvm/ADT/SmallSet.h"
19*67e74705SXin Li #include "llvm/ADT/StringExtras.h"
20*67e74705SXin Li #include "llvm/ADT/Optional.h"
21*67e74705SXin Li #include "llvm/ProfileData/Coverage/CoverageMapping.h"
22*67e74705SXin Li #include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
23*67e74705SXin Li #include "llvm/ProfileData/Coverage/CoverageMappingWriter.h"
24*67e74705SXin Li #include "llvm/ProfileData/InstrProfReader.h"
25*67e74705SXin Li #include "llvm/Support/FileSystem.h"
26*67e74705SXin Li
27*67e74705SXin Li using namespace clang;
28*67e74705SXin Li using namespace CodeGen;
29*67e74705SXin Li using namespace llvm::coverage;
30*67e74705SXin Li
SourceRangeSkipped(SourceRange Range)31*67e74705SXin Li void CoverageSourceInfo::SourceRangeSkipped(SourceRange Range) {
32*67e74705SXin Li SkippedRanges.push_back(Range);
33*67e74705SXin Li }
34*67e74705SXin Li
35*67e74705SXin Li namespace {
36*67e74705SXin Li
37*67e74705SXin Li /// \brief A region of source code that can be mapped to a counter.
38*67e74705SXin Li class SourceMappingRegion {
39*67e74705SXin Li Counter Count;
40*67e74705SXin Li
41*67e74705SXin Li /// \brief The region's starting location.
42*67e74705SXin Li Optional<SourceLocation> LocStart;
43*67e74705SXin Li
44*67e74705SXin Li /// \brief The region's ending location.
45*67e74705SXin Li Optional<SourceLocation> LocEnd;
46*67e74705SXin Li
47*67e74705SXin Li public:
SourceMappingRegion(Counter Count,Optional<SourceLocation> LocStart,Optional<SourceLocation> LocEnd)48*67e74705SXin Li SourceMappingRegion(Counter Count, Optional<SourceLocation> LocStart,
49*67e74705SXin Li Optional<SourceLocation> LocEnd)
50*67e74705SXin Li : Count(Count), LocStart(LocStart), LocEnd(LocEnd) {}
51*67e74705SXin Li
getCounter() const52*67e74705SXin Li const Counter &getCounter() const { return Count; }
53*67e74705SXin Li
setCounter(Counter C)54*67e74705SXin Li void setCounter(Counter C) { Count = C; }
55*67e74705SXin Li
hasStartLoc() const56*67e74705SXin Li bool hasStartLoc() const { return LocStart.hasValue(); }
57*67e74705SXin Li
setStartLoc(SourceLocation Loc)58*67e74705SXin Li void setStartLoc(SourceLocation Loc) { LocStart = Loc; }
59*67e74705SXin Li
getStartLoc() const60*67e74705SXin Li SourceLocation getStartLoc() const {
61*67e74705SXin Li assert(LocStart && "Region has no start location");
62*67e74705SXin Li return *LocStart;
63*67e74705SXin Li }
64*67e74705SXin Li
hasEndLoc() const65*67e74705SXin Li bool hasEndLoc() const { return LocEnd.hasValue(); }
66*67e74705SXin Li
setEndLoc(SourceLocation Loc)67*67e74705SXin Li void setEndLoc(SourceLocation Loc) { LocEnd = Loc; }
68*67e74705SXin Li
getEndLoc() const69*67e74705SXin Li SourceLocation getEndLoc() const {
70*67e74705SXin Li assert(LocEnd && "Region has no end location");
71*67e74705SXin Li return *LocEnd;
72*67e74705SXin Li }
73*67e74705SXin Li };
74*67e74705SXin Li
75*67e74705SXin Li /// \brief Provides the common functionality for the different
76*67e74705SXin Li /// coverage mapping region builders.
77*67e74705SXin Li class CoverageMappingBuilder {
78*67e74705SXin Li public:
79*67e74705SXin Li CoverageMappingModuleGen &CVM;
80*67e74705SXin Li SourceManager &SM;
81*67e74705SXin Li const LangOptions &LangOpts;
82*67e74705SXin Li
83*67e74705SXin Li private:
84*67e74705SXin Li /// \brief Map of clang's FileIDs to IDs used for coverage mapping.
85*67e74705SXin Li llvm::SmallDenseMap<FileID, std::pair<unsigned, SourceLocation>, 8>
86*67e74705SXin Li FileIDMapping;
87*67e74705SXin Li
88*67e74705SXin Li public:
89*67e74705SXin Li /// \brief The coverage mapping regions for this function
90*67e74705SXin Li llvm::SmallVector<CounterMappingRegion, 32> MappingRegions;
91*67e74705SXin Li /// \brief The source mapping regions for this function.
92*67e74705SXin Li std::vector<SourceMappingRegion> SourceRegions;
93*67e74705SXin Li
CoverageMappingBuilder(CoverageMappingModuleGen & CVM,SourceManager & SM,const LangOptions & LangOpts)94*67e74705SXin Li CoverageMappingBuilder(CoverageMappingModuleGen &CVM, SourceManager &SM,
95*67e74705SXin Li const LangOptions &LangOpts)
96*67e74705SXin Li : CVM(CVM), SM(SM), LangOpts(LangOpts) {}
97*67e74705SXin Li
98*67e74705SXin Li /// \brief Return the precise end location for the given token.
getPreciseTokenLocEnd(SourceLocation Loc)99*67e74705SXin Li SourceLocation getPreciseTokenLocEnd(SourceLocation Loc) {
100*67e74705SXin Li // We avoid getLocForEndOfToken here, because it doesn't do what we want for
101*67e74705SXin Li // macro locations, which we just treat as expanded files.
102*67e74705SXin Li unsigned TokLen =
103*67e74705SXin Li Lexer::MeasureTokenLength(SM.getSpellingLoc(Loc), SM, LangOpts);
104*67e74705SXin Li return Loc.getLocWithOffset(TokLen);
105*67e74705SXin Li }
106*67e74705SXin Li
107*67e74705SXin Li /// \brief Return the start location of an included file or expanded macro.
getStartOfFileOrMacro(SourceLocation Loc)108*67e74705SXin Li SourceLocation getStartOfFileOrMacro(SourceLocation Loc) {
109*67e74705SXin Li if (Loc.isMacroID())
110*67e74705SXin Li return Loc.getLocWithOffset(-SM.getFileOffset(Loc));
111*67e74705SXin Li return SM.getLocForStartOfFile(SM.getFileID(Loc));
112*67e74705SXin Li }
113*67e74705SXin Li
114*67e74705SXin Li /// \brief Return the end location of an included file or expanded macro.
getEndOfFileOrMacro(SourceLocation Loc)115*67e74705SXin Li SourceLocation getEndOfFileOrMacro(SourceLocation Loc) {
116*67e74705SXin Li if (Loc.isMacroID())
117*67e74705SXin Li return Loc.getLocWithOffset(SM.getFileIDSize(SM.getFileID(Loc)) -
118*67e74705SXin Li SM.getFileOffset(Loc));
119*67e74705SXin Li return SM.getLocForEndOfFile(SM.getFileID(Loc));
120*67e74705SXin Li }
121*67e74705SXin Li
122*67e74705SXin Li /// \brief Find out where the current file is included or macro is expanded.
getIncludeOrExpansionLoc(SourceLocation Loc)123*67e74705SXin Li SourceLocation getIncludeOrExpansionLoc(SourceLocation Loc) {
124*67e74705SXin Li return Loc.isMacroID() ? SM.getImmediateExpansionRange(Loc).first
125*67e74705SXin Li : SM.getIncludeLoc(SM.getFileID(Loc));
126*67e74705SXin Li }
127*67e74705SXin Li
128*67e74705SXin Li /// \brief Return true if \c Loc is a location in a built-in macro.
isInBuiltin(SourceLocation Loc)129*67e74705SXin Li bool isInBuiltin(SourceLocation Loc) {
130*67e74705SXin Li return strcmp(SM.getBufferName(SM.getSpellingLoc(Loc)), "<built-in>") == 0;
131*67e74705SXin Li }
132*67e74705SXin Li
133*67e74705SXin Li /// \brief Check whether \c Loc is included or expanded from \c Parent.
isNestedIn(SourceLocation Loc,FileID Parent)134*67e74705SXin Li bool isNestedIn(SourceLocation Loc, FileID Parent) {
135*67e74705SXin Li do {
136*67e74705SXin Li Loc = getIncludeOrExpansionLoc(Loc);
137*67e74705SXin Li if (Loc.isInvalid())
138*67e74705SXin Li return false;
139*67e74705SXin Li } while (!SM.isInFileID(Loc, Parent));
140*67e74705SXin Li return true;
141*67e74705SXin Li }
142*67e74705SXin Li
143*67e74705SXin Li /// \brief Get the start of \c S ignoring macro arguments and builtin macros.
getStart(const Stmt * S)144*67e74705SXin Li SourceLocation getStart(const Stmt *S) {
145*67e74705SXin Li SourceLocation Loc = S->getLocStart();
146*67e74705SXin Li while (SM.isMacroArgExpansion(Loc) || isInBuiltin(Loc))
147*67e74705SXin Li Loc = SM.getImmediateExpansionRange(Loc).first;
148*67e74705SXin Li return Loc;
149*67e74705SXin Li }
150*67e74705SXin Li
151*67e74705SXin Li /// \brief Get the end of \c S ignoring macro arguments and builtin macros.
getEnd(const Stmt * S)152*67e74705SXin Li SourceLocation getEnd(const Stmt *S) {
153*67e74705SXin Li SourceLocation Loc = S->getLocEnd();
154*67e74705SXin Li while (SM.isMacroArgExpansion(Loc) || isInBuiltin(Loc))
155*67e74705SXin Li Loc = SM.getImmediateExpansionRange(Loc).first;
156*67e74705SXin Li return getPreciseTokenLocEnd(Loc);
157*67e74705SXin Li }
158*67e74705SXin Li
159*67e74705SXin Li /// \brief Find the set of files we have regions for and assign IDs
160*67e74705SXin Li ///
161*67e74705SXin Li /// Fills \c Mapping with the virtual file mapping needed to write out
162*67e74705SXin Li /// coverage and collects the necessary file information to emit source and
163*67e74705SXin Li /// expansion regions.
gatherFileIDs(SmallVectorImpl<unsigned> & Mapping)164*67e74705SXin Li void gatherFileIDs(SmallVectorImpl<unsigned> &Mapping) {
165*67e74705SXin Li FileIDMapping.clear();
166*67e74705SXin Li
167*67e74705SXin Li llvm::SmallSet<FileID, 8> Visited;
168*67e74705SXin Li SmallVector<std::pair<SourceLocation, unsigned>, 8> FileLocs;
169*67e74705SXin Li for (const auto &Region : SourceRegions) {
170*67e74705SXin Li SourceLocation Loc = Region.getStartLoc();
171*67e74705SXin Li FileID File = SM.getFileID(Loc);
172*67e74705SXin Li if (!Visited.insert(File).second)
173*67e74705SXin Li continue;
174*67e74705SXin Li
175*67e74705SXin Li // Do not map FileID's associated with system headers.
176*67e74705SXin Li if (SM.isInSystemHeader(SM.getSpellingLoc(Loc)))
177*67e74705SXin Li continue;
178*67e74705SXin Li
179*67e74705SXin Li unsigned Depth = 0;
180*67e74705SXin Li for (SourceLocation Parent = getIncludeOrExpansionLoc(Loc);
181*67e74705SXin Li Parent.isValid(); Parent = getIncludeOrExpansionLoc(Parent))
182*67e74705SXin Li ++Depth;
183*67e74705SXin Li FileLocs.push_back(std::make_pair(Loc, Depth));
184*67e74705SXin Li }
185*67e74705SXin Li std::stable_sort(FileLocs.begin(), FileLocs.end(), llvm::less_second());
186*67e74705SXin Li
187*67e74705SXin Li for (const auto &FL : FileLocs) {
188*67e74705SXin Li SourceLocation Loc = FL.first;
189*67e74705SXin Li FileID SpellingFile = SM.getDecomposedSpellingLoc(Loc).first;
190*67e74705SXin Li auto Entry = SM.getFileEntryForID(SpellingFile);
191*67e74705SXin Li if (!Entry)
192*67e74705SXin Li continue;
193*67e74705SXin Li
194*67e74705SXin Li FileIDMapping[SM.getFileID(Loc)] = std::make_pair(Mapping.size(), Loc);
195*67e74705SXin Li Mapping.push_back(CVM.getFileID(Entry));
196*67e74705SXin Li }
197*67e74705SXin Li }
198*67e74705SXin Li
199*67e74705SXin Li /// \brief Get the coverage mapping file ID for \c Loc.
200*67e74705SXin Li ///
201*67e74705SXin Li /// If such file id doesn't exist, return None.
getCoverageFileID(SourceLocation Loc)202*67e74705SXin Li Optional<unsigned> getCoverageFileID(SourceLocation Loc) {
203*67e74705SXin Li auto Mapping = FileIDMapping.find(SM.getFileID(Loc));
204*67e74705SXin Li if (Mapping != FileIDMapping.end())
205*67e74705SXin Li return Mapping->second.first;
206*67e74705SXin Li return None;
207*67e74705SXin Li }
208*67e74705SXin Li
209*67e74705SXin Li /// \brief Gather all the regions that were skipped by the preprocessor
210*67e74705SXin Li /// using the constructs like #if.
gatherSkippedRegions()211*67e74705SXin Li void gatherSkippedRegions() {
212*67e74705SXin Li /// An array of the minimum lineStarts and the maximum lineEnds
213*67e74705SXin Li /// for mapping regions from the appropriate source files.
214*67e74705SXin Li llvm::SmallVector<std::pair<unsigned, unsigned>, 8> FileLineRanges;
215*67e74705SXin Li FileLineRanges.resize(
216*67e74705SXin Li FileIDMapping.size(),
217*67e74705SXin Li std::make_pair(std::numeric_limits<unsigned>::max(), 0));
218*67e74705SXin Li for (const auto &R : MappingRegions) {
219*67e74705SXin Li FileLineRanges[R.FileID].first =
220*67e74705SXin Li std::min(FileLineRanges[R.FileID].first, R.LineStart);
221*67e74705SXin Li FileLineRanges[R.FileID].second =
222*67e74705SXin Li std::max(FileLineRanges[R.FileID].second, R.LineEnd);
223*67e74705SXin Li }
224*67e74705SXin Li
225*67e74705SXin Li auto SkippedRanges = CVM.getSourceInfo().getSkippedRanges();
226*67e74705SXin Li for (const auto &I : SkippedRanges) {
227*67e74705SXin Li auto LocStart = I.getBegin();
228*67e74705SXin Li auto LocEnd = I.getEnd();
229*67e74705SXin Li assert(SM.isWrittenInSameFile(LocStart, LocEnd) &&
230*67e74705SXin Li "region spans multiple files");
231*67e74705SXin Li
232*67e74705SXin Li auto CovFileID = getCoverageFileID(LocStart);
233*67e74705SXin Li if (!CovFileID)
234*67e74705SXin Li continue;
235*67e74705SXin Li unsigned LineStart = SM.getSpellingLineNumber(LocStart);
236*67e74705SXin Li unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart);
237*67e74705SXin Li unsigned LineEnd = SM.getSpellingLineNumber(LocEnd);
238*67e74705SXin Li unsigned ColumnEnd = SM.getSpellingColumnNumber(LocEnd);
239*67e74705SXin Li auto Region = CounterMappingRegion::makeSkipped(
240*67e74705SXin Li *CovFileID, LineStart, ColumnStart, LineEnd, ColumnEnd);
241*67e74705SXin Li // Make sure that we only collect the regions that are inside
242*67e74705SXin Li // the souce code of this function.
243*67e74705SXin Li if (Region.LineStart >= FileLineRanges[*CovFileID].first &&
244*67e74705SXin Li Region.LineEnd <= FileLineRanges[*CovFileID].second)
245*67e74705SXin Li MappingRegions.push_back(Region);
246*67e74705SXin Li }
247*67e74705SXin Li }
248*67e74705SXin Li
249*67e74705SXin Li /// \brief Generate the coverage counter mapping regions from collected
250*67e74705SXin Li /// source regions.
emitSourceRegions()251*67e74705SXin Li void emitSourceRegions() {
252*67e74705SXin Li for (const auto &Region : SourceRegions) {
253*67e74705SXin Li assert(Region.hasEndLoc() && "incomplete region");
254*67e74705SXin Li
255*67e74705SXin Li SourceLocation LocStart = Region.getStartLoc();
256*67e74705SXin Li assert(SM.getFileID(LocStart).isValid() && "region in invalid file");
257*67e74705SXin Li
258*67e74705SXin Li // Ignore regions from system headers.
259*67e74705SXin Li if (SM.isInSystemHeader(SM.getSpellingLoc(LocStart)))
260*67e74705SXin Li continue;
261*67e74705SXin Li
262*67e74705SXin Li auto CovFileID = getCoverageFileID(LocStart);
263*67e74705SXin Li // Ignore regions that don't have a file, such as builtin macros.
264*67e74705SXin Li if (!CovFileID)
265*67e74705SXin Li continue;
266*67e74705SXin Li
267*67e74705SXin Li SourceLocation LocEnd = Region.getEndLoc();
268*67e74705SXin Li assert(SM.isWrittenInSameFile(LocStart, LocEnd) &&
269*67e74705SXin Li "region spans multiple files");
270*67e74705SXin Li
271*67e74705SXin Li // Find the spilling locations for the mapping region.
272*67e74705SXin Li unsigned LineStart = SM.getSpellingLineNumber(LocStart);
273*67e74705SXin Li unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart);
274*67e74705SXin Li unsigned LineEnd = SM.getSpellingLineNumber(LocEnd);
275*67e74705SXin Li unsigned ColumnEnd = SM.getSpellingColumnNumber(LocEnd);
276*67e74705SXin Li
277*67e74705SXin Li assert(LineStart <= LineEnd && "region start and end out of order");
278*67e74705SXin Li MappingRegions.push_back(CounterMappingRegion::makeRegion(
279*67e74705SXin Li Region.getCounter(), *CovFileID, LineStart, ColumnStart, LineEnd,
280*67e74705SXin Li ColumnEnd));
281*67e74705SXin Li }
282*67e74705SXin Li }
283*67e74705SXin Li
284*67e74705SXin Li /// \brief Generate expansion regions for each virtual file we've seen.
emitExpansionRegions()285*67e74705SXin Li void emitExpansionRegions() {
286*67e74705SXin Li for (const auto &FM : FileIDMapping) {
287*67e74705SXin Li SourceLocation ExpandedLoc = FM.second.second;
288*67e74705SXin Li SourceLocation ParentLoc = getIncludeOrExpansionLoc(ExpandedLoc);
289*67e74705SXin Li if (ParentLoc.isInvalid())
290*67e74705SXin Li continue;
291*67e74705SXin Li
292*67e74705SXin Li auto ParentFileID = getCoverageFileID(ParentLoc);
293*67e74705SXin Li if (!ParentFileID)
294*67e74705SXin Li continue;
295*67e74705SXin Li auto ExpandedFileID = getCoverageFileID(ExpandedLoc);
296*67e74705SXin Li assert(ExpandedFileID && "expansion in uncovered file");
297*67e74705SXin Li
298*67e74705SXin Li SourceLocation LocEnd = getPreciseTokenLocEnd(ParentLoc);
299*67e74705SXin Li assert(SM.isWrittenInSameFile(ParentLoc, LocEnd) &&
300*67e74705SXin Li "region spans multiple files");
301*67e74705SXin Li
302*67e74705SXin Li unsigned LineStart = SM.getSpellingLineNumber(ParentLoc);
303*67e74705SXin Li unsigned ColumnStart = SM.getSpellingColumnNumber(ParentLoc);
304*67e74705SXin Li unsigned LineEnd = SM.getSpellingLineNumber(LocEnd);
305*67e74705SXin Li unsigned ColumnEnd = SM.getSpellingColumnNumber(LocEnd);
306*67e74705SXin Li
307*67e74705SXin Li MappingRegions.push_back(CounterMappingRegion::makeExpansion(
308*67e74705SXin Li *ParentFileID, *ExpandedFileID, LineStart, ColumnStart, LineEnd,
309*67e74705SXin Li ColumnEnd));
310*67e74705SXin Li }
311*67e74705SXin Li }
312*67e74705SXin Li };
313*67e74705SXin Li
314*67e74705SXin Li /// \brief Creates unreachable coverage regions for the functions that
315*67e74705SXin Li /// are not emitted.
316*67e74705SXin Li struct EmptyCoverageMappingBuilder : public CoverageMappingBuilder {
EmptyCoverageMappingBuilder__anon610d26880111::EmptyCoverageMappingBuilder317*67e74705SXin Li EmptyCoverageMappingBuilder(CoverageMappingModuleGen &CVM, SourceManager &SM,
318*67e74705SXin Li const LangOptions &LangOpts)
319*67e74705SXin Li : CoverageMappingBuilder(CVM, SM, LangOpts) {}
320*67e74705SXin Li
VisitDecl__anon610d26880111::EmptyCoverageMappingBuilder321*67e74705SXin Li void VisitDecl(const Decl *D) {
322*67e74705SXin Li if (!D->hasBody())
323*67e74705SXin Li return;
324*67e74705SXin Li auto Body = D->getBody();
325*67e74705SXin Li SourceLocation Start = getStart(Body);
326*67e74705SXin Li SourceLocation End = getEnd(Body);
327*67e74705SXin Li if (!SM.isWrittenInSameFile(Start, End)) {
328*67e74705SXin Li // Walk up to find the common ancestor.
329*67e74705SXin Li // Correct the locations accordingly.
330*67e74705SXin Li FileID StartFileID = SM.getFileID(Start);
331*67e74705SXin Li FileID EndFileID = SM.getFileID(End);
332*67e74705SXin Li while (StartFileID != EndFileID && !isNestedIn(End, StartFileID)) {
333*67e74705SXin Li Start = getIncludeOrExpansionLoc(Start);
334*67e74705SXin Li assert(Start.isValid() &&
335*67e74705SXin Li "Declaration start location not nested within a known region");
336*67e74705SXin Li StartFileID = SM.getFileID(Start);
337*67e74705SXin Li }
338*67e74705SXin Li while (StartFileID != EndFileID) {
339*67e74705SXin Li End = getPreciseTokenLocEnd(getIncludeOrExpansionLoc(End));
340*67e74705SXin Li assert(End.isValid() &&
341*67e74705SXin Li "Declaration end location not nested within a known region");
342*67e74705SXin Li EndFileID = SM.getFileID(End);
343*67e74705SXin Li }
344*67e74705SXin Li }
345*67e74705SXin Li SourceRegions.emplace_back(Counter(), Start, End);
346*67e74705SXin Li }
347*67e74705SXin Li
348*67e74705SXin Li /// \brief Write the mapping data to the output stream
write__anon610d26880111::EmptyCoverageMappingBuilder349*67e74705SXin Li void write(llvm::raw_ostream &OS) {
350*67e74705SXin Li SmallVector<unsigned, 16> FileIDMapping;
351*67e74705SXin Li gatherFileIDs(FileIDMapping);
352*67e74705SXin Li emitSourceRegions();
353*67e74705SXin Li
354*67e74705SXin Li CoverageMappingWriter Writer(FileIDMapping, None, MappingRegions);
355*67e74705SXin Li Writer.write(OS);
356*67e74705SXin Li }
357*67e74705SXin Li };
358*67e74705SXin Li
359*67e74705SXin Li /// \brief A StmtVisitor that creates coverage mapping regions which map
360*67e74705SXin Li /// from the source code locations to the PGO counters.
361*67e74705SXin Li struct CounterCoverageMappingBuilder
362*67e74705SXin Li : public CoverageMappingBuilder,
363*67e74705SXin Li public ConstStmtVisitor<CounterCoverageMappingBuilder> {
364*67e74705SXin Li /// \brief The map of statements to count values.
365*67e74705SXin Li llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
366*67e74705SXin Li
367*67e74705SXin Li /// \brief A stack of currently live regions.
368*67e74705SXin Li std::vector<SourceMappingRegion> RegionStack;
369*67e74705SXin Li
370*67e74705SXin Li CounterExpressionBuilder Builder;
371*67e74705SXin Li
372*67e74705SXin Li /// \brief A location in the most recently visited file or macro.
373*67e74705SXin Li ///
374*67e74705SXin Li /// This is used to adjust the active source regions appropriately when
375*67e74705SXin Li /// expressions cross file or macro boundaries.
376*67e74705SXin Li SourceLocation MostRecentLocation;
377*67e74705SXin Li
378*67e74705SXin Li /// \brief Return a counter for the subtraction of \c RHS from \c LHS
subtractCounters__anon610d26880111::CounterCoverageMappingBuilder379*67e74705SXin Li Counter subtractCounters(Counter LHS, Counter RHS) {
380*67e74705SXin Li return Builder.subtract(LHS, RHS);
381*67e74705SXin Li }
382*67e74705SXin Li
383*67e74705SXin Li /// \brief Return a counter for the sum of \c LHS and \c RHS.
addCounters__anon610d26880111::CounterCoverageMappingBuilder384*67e74705SXin Li Counter addCounters(Counter LHS, Counter RHS) {
385*67e74705SXin Li return Builder.add(LHS, RHS);
386*67e74705SXin Li }
387*67e74705SXin Li
addCounters__anon610d26880111::CounterCoverageMappingBuilder388*67e74705SXin Li Counter addCounters(Counter C1, Counter C2, Counter C3) {
389*67e74705SXin Li return addCounters(addCounters(C1, C2), C3);
390*67e74705SXin Li }
391*67e74705SXin Li
392*67e74705SXin Li /// \brief Return the region counter for the given statement.
393*67e74705SXin Li ///
394*67e74705SXin Li /// This should only be called on statements that have a dedicated counter.
getRegionCounter__anon610d26880111::CounterCoverageMappingBuilder395*67e74705SXin Li Counter getRegionCounter(const Stmt *S) {
396*67e74705SXin Li return Counter::getCounter(CounterMap[S]);
397*67e74705SXin Li }
398*67e74705SXin Li
399*67e74705SXin Li /// \brief Push a region onto the stack.
400*67e74705SXin Li ///
401*67e74705SXin Li /// Returns the index on the stack where the region was pushed. This can be
402*67e74705SXin Li /// used with popRegions to exit a "scope", ending the region that was pushed.
pushRegion__anon610d26880111::CounterCoverageMappingBuilder403*67e74705SXin Li size_t pushRegion(Counter Count, Optional<SourceLocation> StartLoc = None,
404*67e74705SXin Li Optional<SourceLocation> EndLoc = None) {
405*67e74705SXin Li if (StartLoc)
406*67e74705SXin Li MostRecentLocation = *StartLoc;
407*67e74705SXin Li RegionStack.emplace_back(Count, StartLoc, EndLoc);
408*67e74705SXin Li
409*67e74705SXin Li return RegionStack.size() - 1;
410*67e74705SXin Li }
411*67e74705SXin Li
412*67e74705SXin Li /// \brief Pop regions from the stack into the function's list of regions.
413*67e74705SXin Li ///
414*67e74705SXin Li /// Adds all regions from \c ParentIndex to the top of the stack to the
415*67e74705SXin Li /// function's \c SourceRegions.
popRegions__anon610d26880111::CounterCoverageMappingBuilder416*67e74705SXin Li void popRegions(size_t ParentIndex) {
417*67e74705SXin Li assert(RegionStack.size() >= ParentIndex && "parent not in stack");
418*67e74705SXin Li while (RegionStack.size() > ParentIndex) {
419*67e74705SXin Li SourceMappingRegion &Region = RegionStack.back();
420*67e74705SXin Li if (Region.hasStartLoc()) {
421*67e74705SXin Li SourceLocation StartLoc = Region.getStartLoc();
422*67e74705SXin Li SourceLocation EndLoc = Region.hasEndLoc()
423*67e74705SXin Li ? Region.getEndLoc()
424*67e74705SXin Li : RegionStack[ParentIndex].getEndLoc();
425*67e74705SXin Li while (!SM.isWrittenInSameFile(StartLoc, EndLoc)) {
426*67e74705SXin Li // The region ends in a nested file or macro expansion. Create a
427*67e74705SXin Li // separate region for each expansion.
428*67e74705SXin Li SourceLocation NestedLoc = getStartOfFileOrMacro(EndLoc);
429*67e74705SXin Li assert(SM.isWrittenInSameFile(NestedLoc, EndLoc));
430*67e74705SXin Li
431*67e74705SXin Li SourceRegions.emplace_back(Region.getCounter(), NestedLoc, EndLoc);
432*67e74705SXin Li
433*67e74705SXin Li EndLoc = getPreciseTokenLocEnd(getIncludeOrExpansionLoc(EndLoc));
434*67e74705SXin Li if (EndLoc.isInvalid())
435*67e74705SXin Li llvm::report_fatal_error("File exit not handled before popRegions");
436*67e74705SXin Li }
437*67e74705SXin Li Region.setEndLoc(EndLoc);
438*67e74705SXin Li
439*67e74705SXin Li MostRecentLocation = EndLoc;
440*67e74705SXin Li // If this region happens to span an entire expansion, we need to make
441*67e74705SXin Li // sure we don't overlap the parent region with it.
442*67e74705SXin Li if (StartLoc == getStartOfFileOrMacro(StartLoc) &&
443*67e74705SXin Li EndLoc == getEndOfFileOrMacro(EndLoc))
444*67e74705SXin Li MostRecentLocation = getIncludeOrExpansionLoc(EndLoc);
445*67e74705SXin Li
446*67e74705SXin Li assert(SM.isWrittenInSameFile(Region.getStartLoc(), EndLoc));
447*67e74705SXin Li SourceRegions.push_back(Region);
448*67e74705SXin Li }
449*67e74705SXin Li RegionStack.pop_back();
450*67e74705SXin Li }
451*67e74705SXin Li }
452*67e74705SXin Li
453*67e74705SXin Li /// \brief Return the currently active region.
getRegion__anon610d26880111::CounterCoverageMappingBuilder454*67e74705SXin Li SourceMappingRegion &getRegion() {
455*67e74705SXin Li assert(!RegionStack.empty() && "statement has no region");
456*67e74705SXin Li return RegionStack.back();
457*67e74705SXin Li }
458*67e74705SXin Li
459*67e74705SXin Li /// \brief Propagate counts through the children of \c S.
propagateCounts__anon610d26880111::CounterCoverageMappingBuilder460*67e74705SXin Li Counter propagateCounts(Counter TopCount, const Stmt *S) {
461*67e74705SXin Li size_t Index = pushRegion(TopCount, getStart(S), getEnd(S));
462*67e74705SXin Li Visit(S);
463*67e74705SXin Li Counter ExitCount = getRegion().getCounter();
464*67e74705SXin Li popRegions(Index);
465*67e74705SXin Li
466*67e74705SXin Li // The statement may be spanned by an expansion. Make sure we handle a file
467*67e74705SXin Li // exit out of this expansion before moving to the next statement.
468*67e74705SXin Li if (SM.isBeforeInTranslationUnit(getStart(S), S->getLocStart()))
469*67e74705SXin Li MostRecentLocation = getEnd(S);
470*67e74705SXin Li
471*67e74705SXin Li return ExitCount;
472*67e74705SXin Li }
473*67e74705SXin Li
474*67e74705SXin Li /// \brief Check whether a region with bounds \c StartLoc and \c EndLoc
475*67e74705SXin Li /// is already added to \c SourceRegions.
isRegionAlreadyAdded__anon610d26880111::CounterCoverageMappingBuilder476*67e74705SXin Li bool isRegionAlreadyAdded(SourceLocation StartLoc, SourceLocation EndLoc) {
477*67e74705SXin Li return SourceRegions.rend() !=
478*67e74705SXin Li std::find_if(SourceRegions.rbegin(), SourceRegions.rend(),
479*67e74705SXin Li [&](const SourceMappingRegion &Region) {
480*67e74705SXin Li return Region.getStartLoc() == StartLoc &&
481*67e74705SXin Li Region.getEndLoc() == EndLoc;
482*67e74705SXin Li });
483*67e74705SXin Li }
484*67e74705SXin Li
485*67e74705SXin Li /// \brief Adjust the most recently visited location to \c EndLoc.
486*67e74705SXin Li ///
487*67e74705SXin Li /// This should be used after visiting any statements in non-source order.
adjustForOutOfOrderTraversal__anon610d26880111::CounterCoverageMappingBuilder488*67e74705SXin Li void adjustForOutOfOrderTraversal(SourceLocation EndLoc) {
489*67e74705SXin Li MostRecentLocation = EndLoc;
490*67e74705SXin Li // The code region for a whole macro is created in handleFileExit() when
491*67e74705SXin Li // it detects exiting of the virtual file of that macro. If we visited
492*67e74705SXin Li // statements in non-source order, we might already have such a region
493*67e74705SXin Li // added, for example, if a body of a loop is divided among multiple
494*67e74705SXin Li // macros. Avoid adding duplicate regions in such case.
495*67e74705SXin Li if (getRegion().hasEndLoc() &&
496*67e74705SXin Li MostRecentLocation == getEndOfFileOrMacro(MostRecentLocation) &&
497*67e74705SXin Li isRegionAlreadyAdded(getStartOfFileOrMacro(MostRecentLocation),
498*67e74705SXin Li MostRecentLocation))
499*67e74705SXin Li MostRecentLocation = getIncludeOrExpansionLoc(MostRecentLocation);
500*67e74705SXin Li }
501*67e74705SXin Li
502*67e74705SXin Li /// \brief Adjust regions and state when \c NewLoc exits a file.
503*67e74705SXin Li ///
504*67e74705SXin Li /// If moving from our most recently tracked location to \c NewLoc exits any
505*67e74705SXin Li /// files, this adjusts our current region stack and creates the file regions
506*67e74705SXin Li /// for the exited file.
handleFileExit__anon610d26880111::CounterCoverageMappingBuilder507*67e74705SXin Li void handleFileExit(SourceLocation NewLoc) {
508*67e74705SXin Li if (NewLoc.isInvalid() ||
509*67e74705SXin Li SM.isWrittenInSameFile(MostRecentLocation, NewLoc))
510*67e74705SXin Li return;
511*67e74705SXin Li
512*67e74705SXin Li // If NewLoc is not in a file that contains MostRecentLocation, walk up to
513*67e74705SXin Li // find the common ancestor.
514*67e74705SXin Li SourceLocation LCA = NewLoc;
515*67e74705SXin Li FileID ParentFile = SM.getFileID(LCA);
516*67e74705SXin Li while (!isNestedIn(MostRecentLocation, ParentFile)) {
517*67e74705SXin Li LCA = getIncludeOrExpansionLoc(LCA);
518*67e74705SXin Li if (LCA.isInvalid() || SM.isWrittenInSameFile(LCA, MostRecentLocation)) {
519*67e74705SXin Li // Since there isn't a common ancestor, no file was exited. We just need
520*67e74705SXin Li // to adjust our location to the new file.
521*67e74705SXin Li MostRecentLocation = NewLoc;
522*67e74705SXin Li return;
523*67e74705SXin Li }
524*67e74705SXin Li ParentFile = SM.getFileID(LCA);
525*67e74705SXin Li }
526*67e74705SXin Li
527*67e74705SXin Li llvm::SmallSet<SourceLocation, 8> StartLocs;
528*67e74705SXin Li Optional<Counter> ParentCounter;
529*67e74705SXin Li for (SourceMappingRegion &I : llvm::reverse(RegionStack)) {
530*67e74705SXin Li if (!I.hasStartLoc())
531*67e74705SXin Li continue;
532*67e74705SXin Li SourceLocation Loc = I.getStartLoc();
533*67e74705SXin Li if (!isNestedIn(Loc, ParentFile)) {
534*67e74705SXin Li ParentCounter = I.getCounter();
535*67e74705SXin Li break;
536*67e74705SXin Li }
537*67e74705SXin Li
538*67e74705SXin Li while (!SM.isInFileID(Loc, ParentFile)) {
539*67e74705SXin Li // The most nested region for each start location is the one with the
540*67e74705SXin Li // correct count. We avoid creating redundant regions by stopping once
541*67e74705SXin Li // we've seen this region.
542*67e74705SXin Li if (StartLocs.insert(Loc).second)
543*67e74705SXin Li SourceRegions.emplace_back(I.getCounter(), Loc,
544*67e74705SXin Li getEndOfFileOrMacro(Loc));
545*67e74705SXin Li Loc = getIncludeOrExpansionLoc(Loc);
546*67e74705SXin Li }
547*67e74705SXin Li I.setStartLoc(getPreciseTokenLocEnd(Loc));
548*67e74705SXin Li }
549*67e74705SXin Li
550*67e74705SXin Li if (ParentCounter) {
551*67e74705SXin Li // If the file is contained completely by another region and doesn't
552*67e74705SXin Li // immediately start its own region, the whole file gets a region
553*67e74705SXin Li // corresponding to the parent.
554*67e74705SXin Li SourceLocation Loc = MostRecentLocation;
555*67e74705SXin Li while (isNestedIn(Loc, ParentFile)) {
556*67e74705SXin Li SourceLocation FileStart = getStartOfFileOrMacro(Loc);
557*67e74705SXin Li if (StartLocs.insert(FileStart).second)
558*67e74705SXin Li SourceRegions.emplace_back(*ParentCounter, FileStart,
559*67e74705SXin Li getEndOfFileOrMacro(Loc));
560*67e74705SXin Li Loc = getIncludeOrExpansionLoc(Loc);
561*67e74705SXin Li }
562*67e74705SXin Li }
563*67e74705SXin Li
564*67e74705SXin Li MostRecentLocation = NewLoc;
565*67e74705SXin Li }
566*67e74705SXin Li
567*67e74705SXin Li /// \brief Ensure that \c S is included in the current region.
extendRegion__anon610d26880111::CounterCoverageMappingBuilder568*67e74705SXin Li void extendRegion(const Stmt *S) {
569*67e74705SXin Li SourceMappingRegion &Region = getRegion();
570*67e74705SXin Li SourceLocation StartLoc = getStart(S);
571*67e74705SXin Li
572*67e74705SXin Li handleFileExit(StartLoc);
573*67e74705SXin Li if (!Region.hasStartLoc())
574*67e74705SXin Li Region.setStartLoc(StartLoc);
575*67e74705SXin Li }
576*67e74705SXin Li
577*67e74705SXin Li /// \brief Mark \c S as a terminator, starting a zero region.
terminateRegion__anon610d26880111::CounterCoverageMappingBuilder578*67e74705SXin Li void terminateRegion(const Stmt *S) {
579*67e74705SXin Li extendRegion(S);
580*67e74705SXin Li SourceMappingRegion &Region = getRegion();
581*67e74705SXin Li if (!Region.hasEndLoc())
582*67e74705SXin Li Region.setEndLoc(getEnd(S));
583*67e74705SXin Li pushRegion(Counter::getZero());
584*67e74705SXin Li }
585*67e74705SXin Li
586*67e74705SXin Li /// \brief Keep counts of breaks and continues inside loops.
587*67e74705SXin Li struct BreakContinue {
588*67e74705SXin Li Counter BreakCount;
589*67e74705SXin Li Counter ContinueCount;
590*67e74705SXin Li };
591*67e74705SXin Li SmallVector<BreakContinue, 8> BreakContinueStack;
592*67e74705SXin Li
CounterCoverageMappingBuilder__anon610d26880111::CounterCoverageMappingBuilder593*67e74705SXin Li CounterCoverageMappingBuilder(
594*67e74705SXin Li CoverageMappingModuleGen &CVM,
595*67e74705SXin Li llvm::DenseMap<const Stmt *, unsigned> &CounterMap, SourceManager &SM,
596*67e74705SXin Li const LangOptions &LangOpts)
597*67e74705SXin Li : CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap) {}
598*67e74705SXin Li
599*67e74705SXin Li /// \brief Write the mapping data to the output stream
write__anon610d26880111::CounterCoverageMappingBuilder600*67e74705SXin Li void write(llvm::raw_ostream &OS) {
601*67e74705SXin Li llvm::SmallVector<unsigned, 8> VirtualFileMapping;
602*67e74705SXin Li gatherFileIDs(VirtualFileMapping);
603*67e74705SXin Li emitSourceRegions();
604*67e74705SXin Li emitExpansionRegions();
605*67e74705SXin Li gatherSkippedRegions();
606*67e74705SXin Li
607*67e74705SXin Li CoverageMappingWriter Writer(VirtualFileMapping, Builder.getExpressions(),
608*67e74705SXin Li MappingRegions);
609*67e74705SXin Li Writer.write(OS);
610*67e74705SXin Li }
611*67e74705SXin Li
VisitStmt__anon610d26880111::CounterCoverageMappingBuilder612*67e74705SXin Li void VisitStmt(const Stmt *S) {
613*67e74705SXin Li if (S->getLocStart().isValid())
614*67e74705SXin Li extendRegion(S);
615*67e74705SXin Li for (const Stmt *Child : S->children())
616*67e74705SXin Li if (Child)
617*67e74705SXin Li this->Visit(Child);
618*67e74705SXin Li handleFileExit(getEnd(S));
619*67e74705SXin Li }
620*67e74705SXin Li
VisitDecl__anon610d26880111::CounterCoverageMappingBuilder621*67e74705SXin Li void VisitDecl(const Decl *D) {
622*67e74705SXin Li Stmt *Body = D->getBody();
623*67e74705SXin Li propagateCounts(getRegionCounter(Body), Body);
624*67e74705SXin Li }
625*67e74705SXin Li
VisitReturnStmt__anon610d26880111::CounterCoverageMappingBuilder626*67e74705SXin Li void VisitReturnStmt(const ReturnStmt *S) {
627*67e74705SXin Li extendRegion(S);
628*67e74705SXin Li if (S->getRetValue())
629*67e74705SXin Li Visit(S->getRetValue());
630*67e74705SXin Li terminateRegion(S);
631*67e74705SXin Li }
632*67e74705SXin Li
VisitCXXThrowExpr__anon610d26880111::CounterCoverageMappingBuilder633*67e74705SXin Li void VisitCXXThrowExpr(const CXXThrowExpr *E) {
634*67e74705SXin Li extendRegion(E);
635*67e74705SXin Li if (E->getSubExpr())
636*67e74705SXin Li Visit(E->getSubExpr());
637*67e74705SXin Li terminateRegion(E);
638*67e74705SXin Li }
639*67e74705SXin Li
VisitGotoStmt__anon610d26880111::CounterCoverageMappingBuilder640*67e74705SXin Li void VisitGotoStmt(const GotoStmt *S) { terminateRegion(S); }
641*67e74705SXin Li
VisitLabelStmt__anon610d26880111::CounterCoverageMappingBuilder642*67e74705SXin Li void VisitLabelStmt(const LabelStmt *S) {
643*67e74705SXin Li SourceLocation Start = getStart(S);
644*67e74705SXin Li // We can't extendRegion here or we risk overlapping with our new region.
645*67e74705SXin Li handleFileExit(Start);
646*67e74705SXin Li pushRegion(getRegionCounter(S), Start);
647*67e74705SXin Li Visit(S->getSubStmt());
648*67e74705SXin Li }
649*67e74705SXin Li
VisitBreakStmt__anon610d26880111::CounterCoverageMappingBuilder650*67e74705SXin Li void VisitBreakStmt(const BreakStmt *S) {
651*67e74705SXin Li assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
652*67e74705SXin Li BreakContinueStack.back().BreakCount = addCounters(
653*67e74705SXin Li BreakContinueStack.back().BreakCount, getRegion().getCounter());
654*67e74705SXin Li terminateRegion(S);
655*67e74705SXin Li }
656*67e74705SXin Li
VisitContinueStmt__anon610d26880111::CounterCoverageMappingBuilder657*67e74705SXin Li void VisitContinueStmt(const ContinueStmt *S) {
658*67e74705SXin Li assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
659*67e74705SXin Li BreakContinueStack.back().ContinueCount = addCounters(
660*67e74705SXin Li BreakContinueStack.back().ContinueCount, getRegion().getCounter());
661*67e74705SXin Li terminateRegion(S);
662*67e74705SXin Li }
663*67e74705SXin Li
VisitWhileStmt__anon610d26880111::CounterCoverageMappingBuilder664*67e74705SXin Li void VisitWhileStmt(const WhileStmt *S) {
665*67e74705SXin Li extendRegion(S);
666*67e74705SXin Li
667*67e74705SXin Li Counter ParentCount = getRegion().getCounter();
668*67e74705SXin Li Counter BodyCount = getRegionCounter(S);
669*67e74705SXin Li
670*67e74705SXin Li // Handle the body first so that we can get the backedge count.
671*67e74705SXin Li BreakContinueStack.push_back(BreakContinue());
672*67e74705SXin Li extendRegion(S->getBody());
673*67e74705SXin Li Counter BackedgeCount = propagateCounts(BodyCount, S->getBody());
674*67e74705SXin Li BreakContinue BC = BreakContinueStack.pop_back_val();
675*67e74705SXin Li
676*67e74705SXin Li // Go back to handle the condition.
677*67e74705SXin Li Counter CondCount =
678*67e74705SXin Li addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
679*67e74705SXin Li propagateCounts(CondCount, S->getCond());
680*67e74705SXin Li adjustForOutOfOrderTraversal(getEnd(S));
681*67e74705SXin Li
682*67e74705SXin Li Counter OutCount =
683*67e74705SXin Li addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
684*67e74705SXin Li if (OutCount != ParentCount)
685*67e74705SXin Li pushRegion(OutCount);
686*67e74705SXin Li }
687*67e74705SXin Li
VisitDoStmt__anon610d26880111::CounterCoverageMappingBuilder688*67e74705SXin Li void VisitDoStmt(const DoStmt *S) {
689*67e74705SXin Li extendRegion(S);
690*67e74705SXin Li
691*67e74705SXin Li Counter ParentCount = getRegion().getCounter();
692*67e74705SXin Li Counter BodyCount = getRegionCounter(S);
693*67e74705SXin Li
694*67e74705SXin Li BreakContinueStack.push_back(BreakContinue());
695*67e74705SXin Li extendRegion(S->getBody());
696*67e74705SXin Li Counter BackedgeCount =
697*67e74705SXin Li propagateCounts(addCounters(ParentCount, BodyCount), S->getBody());
698*67e74705SXin Li BreakContinue BC = BreakContinueStack.pop_back_val();
699*67e74705SXin Li
700*67e74705SXin Li Counter CondCount = addCounters(BackedgeCount, BC.ContinueCount);
701*67e74705SXin Li propagateCounts(CondCount, S->getCond());
702*67e74705SXin Li
703*67e74705SXin Li Counter OutCount =
704*67e74705SXin Li addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
705*67e74705SXin Li if (OutCount != ParentCount)
706*67e74705SXin Li pushRegion(OutCount);
707*67e74705SXin Li }
708*67e74705SXin Li
VisitForStmt__anon610d26880111::CounterCoverageMappingBuilder709*67e74705SXin Li void VisitForStmt(const ForStmt *S) {
710*67e74705SXin Li extendRegion(S);
711*67e74705SXin Li if (S->getInit())
712*67e74705SXin Li Visit(S->getInit());
713*67e74705SXin Li
714*67e74705SXin Li Counter ParentCount = getRegion().getCounter();
715*67e74705SXin Li Counter BodyCount = getRegionCounter(S);
716*67e74705SXin Li
717*67e74705SXin Li // Handle the body first so that we can get the backedge count.
718*67e74705SXin Li BreakContinueStack.push_back(BreakContinue());
719*67e74705SXin Li extendRegion(S->getBody());
720*67e74705SXin Li Counter BackedgeCount = propagateCounts(BodyCount, S->getBody());
721*67e74705SXin Li BreakContinue BC = BreakContinueStack.pop_back_val();
722*67e74705SXin Li
723*67e74705SXin Li // The increment is essentially part of the body but it needs to include
724*67e74705SXin Li // the count for all the continue statements.
725*67e74705SXin Li if (const Stmt *Inc = S->getInc())
726*67e74705SXin Li propagateCounts(addCounters(BackedgeCount, BC.ContinueCount), Inc);
727*67e74705SXin Li
728*67e74705SXin Li // Go back to handle the condition.
729*67e74705SXin Li Counter CondCount =
730*67e74705SXin Li addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
731*67e74705SXin Li if (const Expr *Cond = S->getCond()) {
732*67e74705SXin Li propagateCounts(CondCount, Cond);
733*67e74705SXin Li adjustForOutOfOrderTraversal(getEnd(S));
734*67e74705SXin Li }
735*67e74705SXin Li
736*67e74705SXin Li Counter OutCount =
737*67e74705SXin Li addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
738*67e74705SXin Li if (OutCount != ParentCount)
739*67e74705SXin Li pushRegion(OutCount);
740*67e74705SXin Li }
741*67e74705SXin Li
VisitCXXForRangeStmt__anon610d26880111::CounterCoverageMappingBuilder742*67e74705SXin Li void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
743*67e74705SXin Li extendRegion(S);
744*67e74705SXin Li Visit(S->getLoopVarStmt());
745*67e74705SXin Li Visit(S->getRangeStmt());
746*67e74705SXin Li
747*67e74705SXin Li Counter ParentCount = getRegion().getCounter();
748*67e74705SXin Li Counter BodyCount = getRegionCounter(S);
749*67e74705SXin Li
750*67e74705SXin Li BreakContinueStack.push_back(BreakContinue());
751*67e74705SXin Li extendRegion(S->getBody());
752*67e74705SXin Li Counter BackedgeCount = propagateCounts(BodyCount, S->getBody());
753*67e74705SXin Li BreakContinue BC = BreakContinueStack.pop_back_val();
754*67e74705SXin Li
755*67e74705SXin Li Counter LoopCount =
756*67e74705SXin Li addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
757*67e74705SXin Li Counter OutCount =
758*67e74705SXin Li addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount));
759*67e74705SXin Li if (OutCount != ParentCount)
760*67e74705SXin Li pushRegion(OutCount);
761*67e74705SXin Li }
762*67e74705SXin Li
VisitObjCForCollectionStmt__anon610d26880111::CounterCoverageMappingBuilder763*67e74705SXin Li void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
764*67e74705SXin Li extendRegion(S);
765*67e74705SXin Li Visit(S->getElement());
766*67e74705SXin Li
767*67e74705SXin Li Counter ParentCount = getRegion().getCounter();
768*67e74705SXin Li Counter BodyCount = getRegionCounter(S);
769*67e74705SXin Li
770*67e74705SXin Li BreakContinueStack.push_back(BreakContinue());
771*67e74705SXin Li extendRegion(S->getBody());
772*67e74705SXin Li Counter BackedgeCount = propagateCounts(BodyCount, S->getBody());
773*67e74705SXin Li BreakContinue BC = BreakContinueStack.pop_back_val();
774*67e74705SXin Li
775*67e74705SXin Li Counter LoopCount =
776*67e74705SXin Li addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
777*67e74705SXin Li Counter OutCount =
778*67e74705SXin Li addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount));
779*67e74705SXin Li if (OutCount != ParentCount)
780*67e74705SXin Li pushRegion(OutCount);
781*67e74705SXin Li }
782*67e74705SXin Li
VisitSwitchStmt__anon610d26880111::CounterCoverageMappingBuilder783*67e74705SXin Li void VisitSwitchStmt(const SwitchStmt *S) {
784*67e74705SXin Li extendRegion(S);
785*67e74705SXin Li Visit(S->getCond());
786*67e74705SXin Li
787*67e74705SXin Li BreakContinueStack.push_back(BreakContinue());
788*67e74705SXin Li
789*67e74705SXin Li const Stmt *Body = S->getBody();
790*67e74705SXin Li extendRegion(Body);
791*67e74705SXin Li if (const auto *CS = dyn_cast<CompoundStmt>(Body)) {
792*67e74705SXin Li if (!CS->body_empty()) {
793*67e74705SXin Li // The body of the switch needs a zero region so that fallthrough counts
794*67e74705SXin Li // behave correctly, but it would be misleading to include the braces of
795*67e74705SXin Li // the compound statement in the zeroed area, so we need to handle this
796*67e74705SXin Li // specially.
797*67e74705SXin Li size_t Index =
798*67e74705SXin Li pushRegion(Counter::getZero(), getStart(CS->body_front()),
799*67e74705SXin Li getEnd(CS->body_back()));
800*67e74705SXin Li for (const auto *Child : CS->children())
801*67e74705SXin Li Visit(Child);
802*67e74705SXin Li popRegions(Index);
803*67e74705SXin Li }
804*67e74705SXin Li } else
805*67e74705SXin Li propagateCounts(Counter::getZero(), Body);
806*67e74705SXin Li BreakContinue BC = BreakContinueStack.pop_back_val();
807*67e74705SXin Li
808*67e74705SXin Li if (!BreakContinueStack.empty())
809*67e74705SXin Li BreakContinueStack.back().ContinueCount = addCounters(
810*67e74705SXin Li BreakContinueStack.back().ContinueCount, BC.ContinueCount);
811*67e74705SXin Li
812*67e74705SXin Li Counter ExitCount = getRegionCounter(S);
813*67e74705SXin Li SourceLocation ExitLoc = getEnd(S);
814*67e74705SXin Li pushRegion(ExitCount, getStart(S), ExitLoc);
815*67e74705SXin Li handleFileExit(ExitLoc);
816*67e74705SXin Li }
817*67e74705SXin Li
VisitSwitchCase__anon610d26880111::CounterCoverageMappingBuilder818*67e74705SXin Li void VisitSwitchCase(const SwitchCase *S) {
819*67e74705SXin Li extendRegion(S);
820*67e74705SXin Li
821*67e74705SXin Li SourceMappingRegion &Parent = getRegion();
822*67e74705SXin Li
823*67e74705SXin Li Counter Count = addCounters(Parent.getCounter(), getRegionCounter(S));
824*67e74705SXin Li // Reuse the existing region if it starts at our label. This is typical of
825*67e74705SXin Li // the first case in a switch.
826*67e74705SXin Li if (Parent.hasStartLoc() && Parent.getStartLoc() == getStart(S))
827*67e74705SXin Li Parent.setCounter(Count);
828*67e74705SXin Li else
829*67e74705SXin Li pushRegion(Count, getStart(S));
830*67e74705SXin Li
831*67e74705SXin Li if (const auto *CS = dyn_cast<CaseStmt>(S)) {
832*67e74705SXin Li Visit(CS->getLHS());
833*67e74705SXin Li if (const Expr *RHS = CS->getRHS())
834*67e74705SXin Li Visit(RHS);
835*67e74705SXin Li }
836*67e74705SXin Li Visit(S->getSubStmt());
837*67e74705SXin Li }
838*67e74705SXin Li
VisitIfStmt__anon610d26880111::CounterCoverageMappingBuilder839*67e74705SXin Li void VisitIfStmt(const IfStmt *S) {
840*67e74705SXin Li extendRegion(S);
841*67e74705SXin Li // Extend into the condition before we propagate through it below - this is
842*67e74705SXin Li // needed to handle macros that generate the "if" but not the condition.
843*67e74705SXin Li extendRegion(S->getCond());
844*67e74705SXin Li
845*67e74705SXin Li Counter ParentCount = getRegion().getCounter();
846*67e74705SXin Li Counter ThenCount = getRegionCounter(S);
847*67e74705SXin Li
848*67e74705SXin Li // Emitting a counter for the condition makes it easier to interpret the
849*67e74705SXin Li // counter for the body when looking at the coverage.
850*67e74705SXin Li propagateCounts(ParentCount, S->getCond());
851*67e74705SXin Li
852*67e74705SXin Li extendRegion(S->getThen());
853*67e74705SXin Li Counter OutCount = propagateCounts(ThenCount, S->getThen());
854*67e74705SXin Li
855*67e74705SXin Li Counter ElseCount = subtractCounters(ParentCount, ThenCount);
856*67e74705SXin Li if (const Stmt *Else = S->getElse()) {
857*67e74705SXin Li extendRegion(S->getElse());
858*67e74705SXin Li OutCount = addCounters(OutCount, propagateCounts(ElseCount, Else));
859*67e74705SXin Li } else
860*67e74705SXin Li OutCount = addCounters(OutCount, ElseCount);
861*67e74705SXin Li
862*67e74705SXin Li if (OutCount != ParentCount)
863*67e74705SXin Li pushRegion(OutCount);
864*67e74705SXin Li }
865*67e74705SXin Li
VisitCXXTryStmt__anon610d26880111::CounterCoverageMappingBuilder866*67e74705SXin Li void VisitCXXTryStmt(const CXXTryStmt *S) {
867*67e74705SXin Li extendRegion(S);
868*67e74705SXin Li // Handle macros that generate the "try" but not the rest.
869*67e74705SXin Li extendRegion(S->getTryBlock());
870*67e74705SXin Li
871*67e74705SXin Li Counter ParentCount = getRegion().getCounter();
872*67e74705SXin Li propagateCounts(ParentCount, S->getTryBlock());
873*67e74705SXin Li
874*67e74705SXin Li for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
875*67e74705SXin Li Visit(S->getHandler(I));
876*67e74705SXin Li
877*67e74705SXin Li Counter ExitCount = getRegionCounter(S);
878*67e74705SXin Li pushRegion(ExitCount);
879*67e74705SXin Li }
880*67e74705SXin Li
VisitCXXCatchStmt__anon610d26880111::CounterCoverageMappingBuilder881*67e74705SXin Li void VisitCXXCatchStmt(const CXXCatchStmt *S) {
882*67e74705SXin Li propagateCounts(getRegionCounter(S), S->getHandlerBlock());
883*67e74705SXin Li }
884*67e74705SXin Li
VisitAbstractConditionalOperator__anon610d26880111::CounterCoverageMappingBuilder885*67e74705SXin Li void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
886*67e74705SXin Li extendRegion(E);
887*67e74705SXin Li
888*67e74705SXin Li Counter ParentCount = getRegion().getCounter();
889*67e74705SXin Li Counter TrueCount = getRegionCounter(E);
890*67e74705SXin Li
891*67e74705SXin Li Visit(E->getCond());
892*67e74705SXin Li
893*67e74705SXin Li if (!isa<BinaryConditionalOperator>(E)) {
894*67e74705SXin Li extendRegion(E->getTrueExpr());
895*67e74705SXin Li propagateCounts(TrueCount, E->getTrueExpr());
896*67e74705SXin Li }
897*67e74705SXin Li extendRegion(E->getFalseExpr());
898*67e74705SXin Li propagateCounts(subtractCounters(ParentCount, TrueCount),
899*67e74705SXin Li E->getFalseExpr());
900*67e74705SXin Li }
901*67e74705SXin Li
VisitBinLAnd__anon610d26880111::CounterCoverageMappingBuilder902*67e74705SXin Li void VisitBinLAnd(const BinaryOperator *E) {
903*67e74705SXin Li extendRegion(E);
904*67e74705SXin Li Visit(E->getLHS());
905*67e74705SXin Li
906*67e74705SXin Li extendRegion(E->getRHS());
907*67e74705SXin Li propagateCounts(getRegionCounter(E), E->getRHS());
908*67e74705SXin Li }
909*67e74705SXin Li
VisitBinLOr__anon610d26880111::CounterCoverageMappingBuilder910*67e74705SXin Li void VisitBinLOr(const BinaryOperator *E) {
911*67e74705SXin Li extendRegion(E);
912*67e74705SXin Li Visit(E->getLHS());
913*67e74705SXin Li
914*67e74705SXin Li extendRegion(E->getRHS());
915*67e74705SXin Li propagateCounts(getRegionCounter(E), E->getRHS());
916*67e74705SXin Li }
917*67e74705SXin Li
VisitLambdaExpr__anon610d26880111::CounterCoverageMappingBuilder918*67e74705SXin Li void VisitLambdaExpr(const LambdaExpr *LE) {
919*67e74705SXin Li // Lambdas are treated as their own functions for now, so we shouldn't
920*67e74705SXin Li // propagate counts into them.
921*67e74705SXin Li }
922*67e74705SXin Li };
923*67e74705SXin Li }
924*67e74705SXin Li
isMachO(const CodeGenModule & CGM)925*67e74705SXin Li static bool isMachO(const CodeGenModule &CGM) {
926*67e74705SXin Li return CGM.getTarget().getTriple().isOSBinFormatMachO();
927*67e74705SXin Li }
928*67e74705SXin Li
getCoverageSection(const CodeGenModule & CGM)929*67e74705SXin Li static StringRef getCoverageSection(const CodeGenModule &CGM) {
930*67e74705SXin Li return llvm::getInstrProfCoverageSectionName(isMachO(CGM));
931*67e74705SXin Li }
932*67e74705SXin Li
dump(llvm::raw_ostream & OS,StringRef FunctionName,ArrayRef<CounterExpression> Expressions,ArrayRef<CounterMappingRegion> Regions)933*67e74705SXin Li static void dump(llvm::raw_ostream &OS, StringRef FunctionName,
934*67e74705SXin Li ArrayRef<CounterExpression> Expressions,
935*67e74705SXin Li ArrayRef<CounterMappingRegion> Regions) {
936*67e74705SXin Li OS << FunctionName << ":\n";
937*67e74705SXin Li CounterMappingContext Ctx(Expressions);
938*67e74705SXin Li for (const auto &R : Regions) {
939*67e74705SXin Li OS.indent(2);
940*67e74705SXin Li switch (R.Kind) {
941*67e74705SXin Li case CounterMappingRegion::CodeRegion:
942*67e74705SXin Li break;
943*67e74705SXin Li case CounterMappingRegion::ExpansionRegion:
944*67e74705SXin Li OS << "Expansion,";
945*67e74705SXin Li break;
946*67e74705SXin Li case CounterMappingRegion::SkippedRegion:
947*67e74705SXin Li OS << "Skipped,";
948*67e74705SXin Li break;
949*67e74705SXin Li }
950*67e74705SXin Li
951*67e74705SXin Li OS << "File " << R.FileID << ", " << R.LineStart << ":" << R.ColumnStart
952*67e74705SXin Li << " -> " << R.LineEnd << ":" << R.ColumnEnd << " = ";
953*67e74705SXin Li Ctx.dump(R.Count, OS);
954*67e74705SXin Li if (R.Kind == CounterMappingRegion::ExpansionRegion)
955*67e74705SXin Li OS << " (Expanded file = " << R.ExpandedFileID << ")";
956*67e74705SXin Li OS << "\n";
957*67e74705SXin Li }
958*67e74705SXin Li }
959*67e74705SXin Li
addFunctionMappingRecord(llvm::GlobalVariable * NamePtr,StringRef NameValue,uint64_t FuncHash,const std::string & CoverageMapping,bool IsUsed)960*67e74705SXin Li void CoverageMappingModuleGen::addFunctionMappingRecord(
961*67e74705SXin Li llvm::GlobalVariable *NamePtr, StringRef NameValue, uint64_t FuncHash,
962*67e74705SXin Li const std::string &CoverageMapping, bool IsUsed) {
963*67e74705SXin Li llvm::LLVMContext &Ctx = CGM.getLLVMContext();
964*67e74705SXin Li if (!FunctionRecordTy) {
965*67e74705SXin Li #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) LLVMType,
966*67e74705SXin Li llvm::Type *FunctionRecordTypes[] = {
967*67e74705SXin Li #include "llvm/ProfileData/InstrProfData.inc"
968*67e74705SXin Li };
969*67e74705SXin Li FunctionRecordTy =
970*67e74705SXin Li llvm::StructType::get(Ctx, makeArrayRef(FunctionRecordTypes),
971*67e74705SXin Li /*isPacked=*/true);
972*67e74705SXin Li }
973*67e74705SXin Li
974*67e74705SXin Li #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Init,
975*67e74705SXin Li llvm::Constant *FunctionRecordVals[] = {
976*67e74705SXin Li #include "llvm/ProfileData/InstrProfData.inc"
977*67e74705SXin Li };
978*67e74705SXin Li FunctionRecords.push_back(llvm::ConstantStruct::get(
979*67e74705SXin Li FunctionRecordTy, makeArrayRef(FunctionRecordVals)));
980*67e74705SXin Li if (!IsUsed)
981*67e74705SXin Li FunctionNames.push_back(
982*67e74705SXin Li llvm::ConstantExpr::getBitCast(NamePtr, llvm::Type::getInt8PtrTy(Ctx)));
983*67e74705SXin Li CoverageMappings.push_back(CoverageMapping);
984*67e74705SXin Li
985*67e74705SXin Li if (CGM.getCodeGenOpts().DumpCoverageMapping) {
986*67e74705SXin Li // Dump the coverage mapping data for this function by decoding the
987*67e74705SXin Li // encoded data. This allows us to dump the mapping regions which were
988*67e74705SXin Li // also processed by the CoverageMappingWriter which performs
989*67e74705SXin Li // additional minimization operations such as reducing the number of
990*67e74705SXin Li // expressions.
991*67e74705SXin Li std::vector<StringRef> Filenames;
992*67e74705SXin Li std::vector<CounterExpression> Expressions;
993*67e74705SXin Li std::vector<CounterMappingRegion> Regions;
994*67e74705SXin Li llvm::SmallVector<StringRef, 16> FilenameRefs;
995*67e74705SXin Li FilenameRefs.resize(FileEntries.size());
996*67e74705SXin Li for (const auto &Entry : FileEntries)
997*67e74705SXin Li FilenameRefs[Entry.second] = Entry.first->getName();
998*67e74705SXin Li RawCoverageMappingReader Reader(CoverageMapping, FilenameRefs, Filenames,
999*67e74705SXin Li Expressions, Regions);
1000*67e74705SXin Li if (Reader.read())
1001*67e74705SXin Li return;
1002*67e74705SXin Li dump(llvm::outs(), NameValue, Expressions, Regions);
1003*67e74705SXin Li }
1004*67e74705SXin Li }
1005*67e74705SXin Li
emit()1006*67e74705SXin Li void CoverageMappingModuleGen::emit() {
1007*67e74705SXin Li if (FunctionRecords.empty())
1008*67e74705SXin Li return;
1009*67e74705SXin Li llvm::LLVMContext &Ctx = CGM.getLLVMContext();
1010*67e74705SXin Li auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
1011*67e74705SXin Li
1012*67e74705SXin Li // Create the filenames and merge them with coverage mappings
1013*67e74705SXin Li llvm::SmallVector<std::string, 16> FilenameStrs;
1014*67e74705SXin Li llvm::SmallVector<StringRef, 16> FilenameRefs;
1015*67e74705SXin Li FilenameStrs.resize(FileEntries.size());
1016*67e74705SXin Li FilenameRefs.resize(FileEntries.size());
1017*67e74705SXin Li for (const auto &Entry : FileEntries) {
1018*67e74705SXin Li llvm::SmallString<256> Path(Entry.first->getName());
1019*67e74705SXin Li llvm::sys::fs::make_absolute(Path);
1020*67e74705SXin Li
1021*67e74705SXin Li auto I = Entry.second;
1022*67e74705SXin Li FilenameStrs[I] = std::string(Path.begin(), Path.end());
1023*67e74705SXin Li FilenameRefs[I] = FilenameStrs[I];
1024*67e74705SXin Li }
1025*67e74705SXin Li
1026*67e74705SXin Li std::string FilenamesAndCoverageMappings;
1027*67e74705SXin Li llvm::raw_string_ostream OS(FilenamesAndCoverageMappings);
1028*67e74705SXin Li CoverageFilenamesSectionWriter(FilenameRefs).write(OS);
1029*67e74705SXin Li std::string RawCoverageMappings =
1030*67e74705SXin Li llvm::join(CoverageMappings.begin(), CoverageMappings.end(), "");
1031*67e74705SXin Li OS << RawCoverageMappings;
1032*67e74705SXin Li size_t CoverageMappingSize = RawCoverageMappings.size();
1033*67e74705SXin Li size_t FilenamesSize = OS.str().size() - CoverageMappingSize;
1034*67e74705SXin Li // Append extra zeroes if necessary to ensure that the size of the filenames
1035*67e74705SXin Li // and coverage mappings is a multiple of 8.
1036*67e74705SXin Li if (size_t Rem = OS.str().size() % 8) {
1037*67e74705SXin Li CoverageMappingSize += 8 - Rem;
1038*67e74705SXin Li for (size_t I = 0, S = 8 - Rem; I < S; ++I)
1039*67e74705SXin Li OS << '\0';
1040*67e74705SXin Li }
1041*67e74705SXin Li auto *FilenamesAndMappingsVal =
1042*67e74705SXin Li llvm::ConstantDataArray::getString(Ctx, OS.str(), false);
1043*67e74705SXin Li
1044*67e74705SXin Li // Create the deferred function records array
1045*67e74705SXin Li auto RecordsTy =
1046*67e74705SXin Li llvm::ArrayType::get(FunctionRecordTy, FunctionRecords.size());
1047*67e74705SXin Li auto RecordsVal = llvm::ConstantArray::get(RecordsTy, FunctionRecords);
1048*67e74705SXin Li
1049*67e74705SXin Li llvm::Type *CovDataHeaderTypes[] = {
1050*67e74705SXin Li #define COVMAP_HEADER(Type, LLVMType, Name, Init) LLVMType,
1051*67e74705SXin Li #include "llvm/ProfileData/InstrProfData.inc"
1052*67e74705SXin Li };
1053*67e74705SXin Li auto CovDataHeaderTy =
1054*67e74705SXin Li llvm::StructType::get(Ctx, makeArrayRef(CovDataHeaderTypes));
1055*67e74705SXin Li llvm::Constant *CovDataHeaderVals[] = {
1056*67e74705SXin Li #define COVMAP_HEADER(Type, LLVMType, Name, Init) Init,
1057*67e74705SXin Li #include "llvm/ProfileData/InstrProfData.inc"
1058*67e74705SXin Li };
1059*67e74705SXin Li auto CovDataHeaderVal = llvm::ConstantStruct::get(
1060*67e74705SXin Li CovDataHeaderTy, makeArrayRef(CovDataHeaderVals));
1061*67e74705SXin Li
1062*67e74705SXin Li // Create the coverage data record
1063*67e74705SXin Li llvm::Type *CovDataTypes[] = {CovDataHeaderTy, RecordsTy,
1064*67e74705SXin Li FilenamesAndMappingsVal->getType()};
1065*67e74705SXin Li auto CovDataTy = llvm::StructType::get(Ctx, makeArrayRef(CovDataTypes));
1066*67e74705SXin Li llvm::Constant *TUDataVals[] = {CovDataHeaderVal, RecordsVal,
1067*67e74705SXin Li FilenamesAndMappingsVal};
1068*67e74705SXin Li auto CovDataVal =
1069*67e74705SXin Li llvm::ConstantStruct::get(CovDataTy, makeArrayRef(TUDataVals));
1070*67e74705SXin Li auto CovData = new llvm::GlobalVariable(
1071*67e74705SXin Li CGM.getModule(), CovDataTy, true, llvm::GlobalValue::InternalLinkage,
1072*67e74705SXin Li CovDataVal, llvm::getCoverageMappingVarName());
1073*67e74705SXin Li
1074*67e74705SXin Li CovData->setSection(getCoverageSection(CGM));
1075*67e74705SXin Li CovData->setAlignment(8);
1076*67e74705SXin Li
1077*67e74705SXin Li // Make sure the data doesn't get deleted.
1078*67e74705SXin Li CGM.addUsedGlobal(CovData);
1079*67e74705SXin Li // Create the deferred function records array
1080*67e74705SXin Li if (!FunctionNames.empty()) {
1081*67e74705SXin Li auto NamesArrTy = llvm::ArrayType::get(llvm::Type::getInt8PtrTy(Ctx),
1082*67e74705SXin Li FunctionNames.size());
1083*67e74705SXin Li auto NamesArrVal = llvm::ConstantArray::get(NamesArrTy, FunctionNames);
1084*67e74705SXin Li // This variable will *NOT* be emitted to the object file. It is used
1085*67e74705SXin Li // to pass the list of names referenced to codegen.
1086*67e74705SXin Li new llvm::GlobalVariable(CGM.getModule(), NamesArrTy, true,
1087*67e74705SXin Li llvm::GlobalValue::InternalLinkage, NamesArrVal,
1088*67e74705SXin Li llvm::getCoverageUnusedNamesVarName());
1089*67e74705SXin Li }
1090*67e74705SXin Li }
1091*67e74705SXin Li
getFileID(const FileEntry * File)1092*67e74705SXin Li unsigned CoverageMappingModuleGen::getFileID(const FileEntry *File) {
1093*67e74705SXin Li auto It = FileEntries.find(File);
1094*67e74705SXin Li if (It != FileEntries.end())
1095*67e74705SXin Li return It->second;
1096*67e74705SXin Li unsigned FileID = FileEntries.size();
1097*67e74705SXin Li FileEntries.insert(std::make_pair(File, FileID));
1098*67e74705SXin Li return FileID;
1099*67e74705SXin Li }
1100*67e74705SXin Li
emitCounterMapping(const Decl * D,llvm::raw_ostream & OS)1101*67e74705SXin Li void CoverageMappingGen::emitCounterMapping(const Decl *D,
1102*67e74705SXin Li llvm::raw_ostream &OS) {
1103*67e74705SXin Li assert(CounterMap);
1104*67e74705SXin Li CounterCoverageMappingBuilder Walker(CVM, *CounterMap, SM, LangOpts);
1105*67e74705SXin Li Walker.VisitDecl(D);
1106*67e74705SXin Li Walker.write(OS);
1107*67e74705SXin Li }
1108*67e74705SXin Li
emitEmptyMapping(const Decl * D,llvm::raw_ostream & OS)1109*67e74705SXin Li void CoverageMappingGen::emitEmptyMapping(const Decl *D,
1110*67e74705SXin Li llvm::raw_ostream &OS) {
1111*67e74705SXin Li EmptyCoverageMappingBuilder Walker(CVM, SM, LangOpts);
1112*67e74705SXin Li Walker.VisitDecl(D);
1113*67e74705SXin Li Walker.write(OS);
1114*67e74705SXin Li }
1115