18 #include "llvm/ADT/Optional.h"
19 #include "llvm/ProfileData/CoverageMapping.h"
20 #include "llvm/ProfileData/CoverageMappingReader.h"
21 #include "llvm/ProfileData/CoverageMappingWriter.h"
22 #include "llvm/ProfileData/InstrProfReader.h"
23 #include "llvm/Support/FileSystem.h"
25 using namespace clang;
26 using namespace CodeGen;
27 using namespace llvm::coverage;
30 SkippedRanges.push_back(Range);
36 class SourceMappingRegion {
48 : Count(Count), LocStart(LocStart), LocEnd(LocEnd) {}
50 SourceMappingRegion(SourceMappingRegion &&Region)
51 :
Count(std::move(Region.
Count)), LocStart(std::move(Region.LocStart)),
52 LocEnd(std::move(Region.LocEnd)) {}
54 SourceMappingRegion &operator=(SourceMappingRegion &&RHS) {
55 Count = std::move(RHS.Count);
56 LocStart = std::move(RHS.LocStart);
57 LocEnd = std::move(RHS.LocEnd);
61 const Counter &getCounter()
const {
return Count; }
63 void setCounter(Counter
C) {
Count =
C; }
65 bool hasStartLoc()
const {
return LocStart.hasValue(); }
70 assert(LocStart &&
"Region has no start location");
74 bool hasEndLoc()
const {
return LocEnd.hasValue(); }
79 assert(LocEnd &&
"Region has no end location");
86 class CoverageMappingBuilder {
94 llvm::SmallDenseMap<FileID, std::pair<unsigned, SourceLocation>, 8>
101 std::vector<SourceMappingRegion> SourceRegions;
105 : CVM(CVM), SM(SM), LangOpts(LangOpts) {}
155 return getPreciseTokenLocEnd(Loc);
164 FileIDMapping.clear();
168 for (
const auto &Region : SourceRegions) {
171 if (std::find(Visited.begin(), Visited.end(), File) != Visited.end())
173 Visited.push_back(File);
177 !Parent.
isInvalid(); Parent = getIncludeOrExpansionLoc(Parent))
179 FileLocs.push_back(std::make_pair(Loc, Depth));
181 std::stable_sort(FileLocs.begin(), FileLocs.end(), llvm::less_second());
183 for (
const auto &FL : FileLocs) {
190 FileIDMapping[
SM.
getFileID(Loc)] = std::make_pair(Mapping.size(), Loc);
191 Mapping.push_back(CVM.getFileID(Entry));
199 auto Mapping = FileIDMapping.find(
SM.
getFileID(Loc));
200 if (Mapping != FileIDMapping.end())
201 return Mapping->second.first;
207 bool hasExistingCoverageFileID(
FileID File)
const {
208 return FileIDMapping.count(File);
213 void gatherSkippedRegions() {
217 FileLineRanges.resize(
218 FileIDMapping.size(),
219 std::make_pair(std::numeric_limits<unsigned>::max(), 0));
220 for (
const auto &R : MappingRegions) {
221 FileLineRanges[R.FileID].first =
222 std::min(FileLineRanges[R.FileID].first, R.LineStart);
223 FileLineRanges[R.FileID].second =
224 std::max(FileLineRanges[R.FileID].second, R.LineEnd);
227 auto SkippedRanges = CVM.getSourceInfo().getSkippedRanges();
228 for (
const auto &I : SkippedRanges) {
229 auto LocStart = I.getBegin();
230 auto LocEnd = I.getEnd();
232 "region spans multiple files");
234 auto CovFileID = getCoverageFileID(LocStart);
241 auto Region = CounterMappingRegion::makeSkipped(
242 *CovFileID, LineStart, ColumnStart, LineEnd, ColumnEnd);
245 if (Region.LineStart >= FileLineRanges[*CovFileID].first &&
246 Region.LineEnd <= FileLineRanges[*CovFileID].second)
247 MappingRegions.push_back(Region);
253 void emitSourceRegions() {
254 for (
const auto &Region : SourceRegions) {
255 assert(Region.hasEndLoc() &&
"incomplete region");
260 auto CovFileID = getCoverageFileID(LocStart);
267 "region spans multiple files");
275 assert(LineStart <= LineEnd &&
"region start and end out of order");
276 MappingRegions.push_back(CounterMappingRegion::makeRegion(
277 Region.getCounter(), *CovFileID, LineStart, ColumnStart, LineEnd,
283 void emitExpansionRegions() {
284 for (
const auto &FM : FileIDMapping) {
290 auto ParentFileID = getCoverageFileID(ParentLoc);
293 auto ExpandedFileID = getCoverageFileID(ExpandedLoc);
294 assert(ExpandedFileID &&
"expansion in uncovered file");
298 "region spans multiple files");
305 MappingRegions.push_back(CounterMappingRegion::makeExpansion(
306 *ParentFileID, *ExpandedFileID, LineStart, ColumnStart, LineEnd,
314 struct EmptyCoverageMappingBuilder :
public CoverageMappingBuilder {
317 : CoverageMappingBuilder(CVM, SM, LangOpts) {}
319 void VisitDecl(
const Decl *D) {
323 SourceRegions.emplace_back(Counter(), getStart(Body), getEnd(Body));
327 void write(llvm::raw_ostream &OS) {
329 gatherFileIDs(FileIDMapping);
332 CoverageMappingWriter Writer(FileIDMapping, None, MappingRegions);
339 struct CounterCoverageMappingBuilder
340 :
public CoverageMappingBuilder,
343 llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
346 std::vector<SourceMappingRegion> RegionStack;
348 CounterExpressionBuilder
Builder;
357 Counter subtractCounters(Counter LHS, Counter RHS) {
358 return Builder.subtract(LHS, RHS);
362 Counter addCounters(Counter LHS, Counter RHS) {
366 Counter addCounters(Counter C1, Counter C2, Counter C3) {
367 return addCounters(addCounters(C1, C2), C3);
370 Counter addCounters(Counter C1, Counter C2, Counter C3, Counter C4) {
371 return addCounters(addCounters(C1, C2, C3), C4);
377 Counter getRegionCounter(
const Stmt *S) {
378 return Counter::getCounter(CounterMap[S]);
388 MostRecentLocation = *StartLoc;
389 RegionStack.emplace_back(Count, StartLoc, EndLoc);
391 return RegionStack.size() - 1;
398 void popRegions(
size_t ParentIndex) {
399 assert(RegionStack.size() >= ParentIndex &&
"parent not in stack");
400 while (RegionStack.size() > ParentIndex) {
401 SourceMappingRegion &Region = RegionStack.back();
402 if (Region.hasStartLoc()) {
406 : RegionStack[ParentIndex].getEndLoc();
413 SourceRegions.emplace_back(Region.getCounter(), NestedLoc, EndLoc);
415 EndLoc = getPreciseTokenLocEnd(getIncludeOrExpansionLoc(EndLoc));
417 "File exit was not handled before popRegions");
419 Region.setEndLoc(EndLoc);
421 MostRecentLocation = EndLoc;
424 if (StartLoc == getStartOfFileOrMacro(StartLoc) &&
425 EndLoc == getEndOfFileOrMacro(EndLoc))
426 MostRecentLocation = getIncludeOrExpansionLoc(EndLoc);
429 SourceRegions.push_back(std::move(Region));
431 RegionStack.pop_back();
436 SourceMappingRegion &getRegion() {
437 assert(!RegionStack.empty() &&
"statement has no region");
438 return RegionStack.back();
442 Counter propagateCounts(Counter TopCount,
const Stmt *S) {
443 size_t Index = pushRegion(TopCount, getStart(S), getEnd(S));
445 Counter ExitCount = getRegion().getCounter();
454 MostRecentLocation = EndLoc;
457 if (getRegion().hasEndLoc() &&
458 MostRecentLocation == getEndOfFileOrMacro(MostRecentLocation))
459 MostRecentLocation = getIncludeOrExpansionLoc(MostRecentLocation);
465 Loc = getIncludeOrExpansionLoc(Loc);
486 while (!isNestedIn(MostRecentLocation, ParentFile)) {
487 LCA = getIncludeOrExpansionLoc(LCA);
491 MostRecentLocation = NewLoc;
497 llvm::SmallSet<SourceLocation, 8> StartLocs;
499 for (
auto I = RegionStack.rbegin(), E = RegionStack.rend(); I != E; ++I) {
500 if (!I->hasStartLoc())
503 if (!isNestedIn(Loc, ParentFile)) {
504 ParentCounter = I->getCounter();
512 if (StartLocs.insert(Loc).second)
513 SourceRegions.emplace_back(I->getCounter(), Loc,
514 getEndOfFileOrMacro(Loc));
515 Loc = getIncludeOrExpansionLoc(Loc);
517 I->setStartLoc(getPreciseTokenLocEnd(Loc));
525 while (isNestedIn(Loc, ParentFile)) {
527 if (StartLocs.insert(FileStart).second)
528 SourceRegions.emplace_back(*ParentCounter, FileStart,
529 getEndOfFileOrMacro(Loc));
530 Loc = getIncludeOrExpansionLoc(Loc);
534 MostRecentLocation = NewLoc;
538 void extendRegion(
const Stmt *S) {
539 SourceMappingRegion &Region = getRegion();
542 handleFileExit(StartLoc);
543 if (!Region.hasStartLoc())
544 Region.setStartLoc(StartLoc);
548 void terminateRegion(
const Stmt *S) {
550 SourceMappingRegion &Region = getRegion();
551 if (!Region.hasEndLoc())
552 Region.setEndLoc(getEnd(S));
553 pushRegion(Counter::getZero());
557 struct BreakContinue {
559 Counter ContinueCount;
563 CounterCoverageMappingBuilder(
567 : CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap) {}
570 void write(llvm::raw_ostream &OS) {
572 gatherFileIDs(VirtualFileMapping);
574 emitExpansionRegions();
575 gatherSkippedRegions();
577 CoverageMappingWriter Writer(VirtualFileMapping,
Builder.getExpressions(),
582 void VisitStmt(
const Stmt *S) {
583 if (!S->getLocStart().isInvalid())
585 for (
const Stmt *Child : S->children())
588 handleFileExit(getEnd(S));
591 void VisitDecl(
const Decl *D) {
593 propagateCounts(getRegionCounter(Body), Body);
610 void VisitGotoStmt(
const GotoStmt *S) { terminateRegion(S); }
612 void VisitLabelStmt(
const LabelStmt *S) {
615 handleFileExit(Start);
616 pushRegion(getRegionCounter(S), Start);
620 void VisitBreakStmt(
const BreakStmt *S) {
621 assert(!BreakContinueStack.empty() &&
"break not in a loop or switch!");
622 BreakContinueStack.back().BreakCount = addCounters(
623 BreakContinueStack.back().BreakCount, getRegion().getCounter());
628 assert(!BreakContinueStack.empty() &&
"continue stmt not in a loop!");
629 BreakContinueStack.back().ContinueCount = addCounters(
630 BreakContinueStack.back().ContinueCount, getRegion().getCounter());
634 void VisitWhileStmt(
const WhileStmt *S) {
637 Counter ParentCount = getRegion().getCounter();
638 Counter BodyCount = getRegionCounter(S);
641 BreakContinueStack.push_back(BreakContinue());
643 Counter BackedgeCount = propagateCounts(BodyCount, S->
getBody());
644 BreakContinue BC = BreakContinueStack.pop_back_val();
648 addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
649 propagateCounts(CondCount, S->
getCond());
650 adjustForOutOfOrderTraversal(getEnd(S));
653 addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
654 if (OutCount != ParentCount)
655 pushRegion(OutCount);
658 void VisitDoStmt(
const DoStmt *S) {
661 Counter ParentCount = getRegion().getCounter();
662 Counter BodyCount = getRegionCounter(S);
664 BreakContinueStack.push_back(BreakContinue());
666 Counter BackedgeCount =
667 propagateCounts(addCounters(ParentCount, BodyCount), S->
getBody());
668 BreakContinue BC = BreakContinueStack.pop_back_val();
670 Counter CondCount = addCounters(BackedgeCount, BC.ContinueCount);
671 propagateCounts(CondCount, S->
getCond());
674 addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
675 if (OutCount != ParentCount)
676 pushRegion(OutCount);
679 void VisitForStmt(
const ForStmt *S) {
684 Counter ParentCount = getRegion().getCounter();
685 Counter BodyCount = getRegionCounter(S);
688 BreakContinueStack.push_back(BreakContinue());
690 Counter BackedgeCount = propagateCounts(BodyCount, S->
getBody());
691 BreakContinue BC = BreakContinueStack.pop_back_val();
696 propagateCounts(addCounters(BackedgeCount, BC.ContinueCount), Inc);
700 addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
702 propagateCounts(CondCount, Cond);
703 adjustForOutOfOrderTraversal(getEnd(S));
707 addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
708 if (OutCount != ParentCount)
709 pushRegion(OutCount);
717 Counter ParentCount = getRegion().getCounter();
718 Counter BodyCount = getRegionCounter(S);
720 BreakContinueStack.push_back(BreakContinue());
722 Counter BackedgeCount = propagateCounts(BodyCount, S->
getBody());
723 BreakContinue BC = BreakContinueStack.pop_back_val();
726 addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
728 addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount));
729 if (OutCount != ParentCount)
730 pushRegion(OutCount);
737 Counter ParentCount = getRegion().getCounter();
738 Counter BodyCount = getRegionCounter(S);
740 BreakContinueStack.push_back(BreakContinue());
742 Counter BackedgeCount = propagateCounts(BodyCount, S->
getBody());
743 BreakContinue BC = BreakContinueStack.pop_back_val();
746 addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
748 addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount));
749 if (OutCount != ParentCount)
750 pushRegion(OutCount);
757 BreakContinueStack.push_back(BreakContinue());
761 if (
const auto *CS = dyn_cast<CompoundStmt>(Body)) {
762 if (!CS->body_empty()) {
768 pushRegion(Counter::getZero(), getStart(CS->body_front()),
769 getEnd(CS->body_back()));
770 for (
const auto *Child : CS->children())
775 propagateCounts(Counter::getZero(), Body);
776 BreakContinue BC = BreakContinueStack.pop_back_val();
778 if (!BreakContinueStack.empty())
779 BreakContinueStack.back().ContinueCount = addCounters(
780 BreakContinueStack.back().ContinueCount, BC.ContinueCount);
782 Counter ExitCount = getRegionCounter(S);
783 pushRegion(ExitCount);
789 SourceMappingRegion &Parent = getRegion();
791 Counter Count = addCounters(Parent.getCounter(), getRegionCounter(S));
794 if (Parent.hasStartLoc() && Parent.getStartLoc() == getStart(S))
795 Parent.setCounter(Count);
797 pushRegion(Count, getStart(S));
799 if (
const CaseStmt *CS = dyn_cast<CaseStmt>(S)) {
801 if (
const Expr *RHS = CS->getRHS())
807 void VisitIfStmt(
const IfStmt *S) {
813 Counter ParentCount = getRegion().getCounter();
814 Counter ThenCount = getRegionCounter(S);
818 propagateCounts(ParentCount, S->
getCond());
821 Counter OutCount = propagateCounts(ThenCount, S->
getThen());
823 Counter ElseCount = subtractCounters(ParentCount, ThenCount);
826 OutCount = addCounters(OutCount, propagateCounts(ElseCount, Else));
828 OutCount = addCounters(OutCount, ElseCount);
830 if (OutCount != ParentCount)
831 pushRegion(OutCount);
840 Counter ExitCount = getRegionCounter(S);
841 pushRegion(ExitCount);
852 Counter ParentCount = getRegion().getCounter();
853 Counter TrueCount = getRegionCounter(E);
857 if (!isa<BinaryConditionalOperator>(E)) {
862 propagateCounts(subtractCounters(ParentCount, TrueCount),
870 extendRegion(E->
getRHS());
871 propagateCounts(getRegionCounter(E), E->
getRHS());
878 extendRegion(E->
getRHS());
879 propagateCounts(getRegionCounter(E), E->
getRHS());
894 return isMachO(CGM) ?
"__DATA,__llvm_covmap" :
"__llvm_covmap";
897 static void dump(llvm::raw_ostream &OS, StringRef FunctionName,
900 OS << FunctionName <<
":\n";
901 CounterMappingContext Ctx(Expressions);
902 for (
const auto &R : Regions) {
905 case CounterMappingRegion::CodeRegion:
907 case CounterMappingRegion::ExpansionRegion:
910 case CounterMappingRegion::SkippedRegion:
915 OS <<
"File " << R.FileID <<
", " << R.LineStart <<
":" << R.ColumnStart
916 <<
" -> " << R.LineEnd <<
":" << R.ColumnEnd <<
" = ";
917 Ctx.dump(R.Count, OS);
918 if (R.Kind == CounterMappingRegion::ExpansionRegion)
919 OS <<
" (Expanded file = " << R.ExpandedFileID <<
")";
925 llvm::GlobalVariable *FunctionName, StringRef FunctionNameValue,
926 uint64_t FunctionHash,
const std::string &CoverageMapping) {
927 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
928 auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
929 auto *Int64Ty = llvm::Type::getInt64Ty(Ctx);
930 auto *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx);
931 if (!FunctionRecordTy) {
932 llvm::Type *FunctionRecordTypes[] = {Int8PtrTy, Int32Ty, Int32Ty, Int64Ty};
934 llvm::StructType::get(Ctx, makeArrayRef(FunctionRecordTypes),
938 llvm::Constant *FunctionRecordVals[] = {
939 llvm::ConstantExpr::getBitCast(FunctionName, Int8PtrTy),
940 llvm::ConstantInt::get(Int32Ty, FunctionNameValue.size()),
941 llvm::ConstantInt::get(Int32Ty, CoverageMapping.size()),
942 llvm::ConstantInt::get(Int64Ty, FunctionHash)};
943 FunctionRecords.push_back(llvm::ConstantStruct::get(
944 FunctionRecordTy, makeArrayRef(FunctionRecordVals)));
945 CoverageMappings += CoverageMapping;
947 if (CGM.getCodeGenOpts().DumpCoverageMapping) {
953 std::vector<StringRef> Filenames;
954 std::vector<CounterExpression> Expressions;
955 std::vector<CounterMappingRegion> Regions;
957 FilenameRefs.resize(FileEntries.size());
958 for (
const auto &Entry : FileEntries)
959 FilenameRefs[Entry.second] = Entry.first->getName();
960 RawCoverageMappingReader Reader(CoverageMapping, FilenameRefs, Filenames,
961 Expressions, Regions);
964 dump(llvm::outs(), FunctionNameValue, Expressions, Regions);
969 if (FunctionRecords.empty())
971 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
972 auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
977 FilenameStrs.resize(FileEntries.size());
978 FilenameRefs.resize(FileEntries.size());
979 for (
const auto &Entry : FileEntries) {
981 llvm::sys::fs::make_absolute(Path);
983 auto I = Entry.second;
984 FilenameStrs[I] = std::string(Path.begin(), Path.end());
985 FilenameRefs[I] = FilenameStrs[I];
988 std::string FilenamesAndCoverageMappings;
989 llvm::raw_string_ostream OS(FilenamesAndCoverageMappings);
990 CoverageFilenamesSectionWriter(FilenameRefs).write(OS);
991 OS << CoverageMappings;
992 size_t CoverageMappingSize = CoverageMappings.size();
993 size_t FilenamesSize = OS.str().size() - CoverageMappingSize;
996 if (
size_t Rem = OS.str().size() % 8) {
997 CoverageMappingSize += 8 - Rem;
998 for (
size_t I = 0, S = 8 - Rem; I <
S; ++I)
1001 auto *FilenamesAndMappingsVal =
1002 llvm::ConstantDataArray::getString(Ctx, OS.str(),
false);
1006 llvm::ArrayType::get(FunctionRecordTy, FunctionRecords.size());
1007 auto RecordsVal = llvm::ConstantArray::get(RecordsTy, FunctionRecords);
1010 llvm::Type *CovDataTypes[] = {Int32Ty, Int32Ty,
1012 RecordsTy, FilenamesAndMappingsVal->getType()};
1013 auto CovDataTy = llvm::StructType::get(Ctx, makeArrayRef(CovDataTypes));
1014 llvm::Constant *TUDataVals[] = {
1015 llvm::ConstantInt::get(Int32Ty, FunctionRecords.size()),
1016 llvm::ConstantInt::get(Int32Ty, FilenamesSize),
1017 llvm::ConstantInt::get(Int32Ty, CoverageMappingSize),
1018 llvm::ConstantInt::get(Int32Ty,
1019 CoverageMappingVersion1),
1020 RecordsVal, FilenamesAndMappingsVal};
1022 llvm::ConstantStruct::get(CovDataTy, makeArrayRef(TUDataVals));
1023 auto CovData =
new llvm::GlobalVariable(CGM.getModule(), CovDataTy,
true,
1026 "__llvm_coverage_mapping");
1029 CovData->setAlignment(8);
1032 CGM.addUsedGlobal(CovData);
1036 auto It = FileEntries.find(File);
1037 if (It != FileEntries.end())
1039 unsigned FileID = FileEntries.size();
1040 FileEntries.insert(std::make_pair(File,
FileID));
1045 llvm::raw_ostream &OS) {
1047 CounterCoverageMappingBuilder Walker(CVM, *CounterMap,
SM, LangOpts);
1048 Walker.VisitDecl(D);
1053 llvm::raw_ostream &OS) {
1054 EmptyCoverageMappingBuilder Walker(CVM,
SM, LangOpts);
1055 Walker.VisitDecl(D);
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID. ...
CXXCatchStmt * getHandler(unsigned i)
unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
static bool isMachO(const CodeGenModule &CGM)
const Stmt * getElse() const
A C++ throw-expression (C++ [except.throw]).
void emit()
Emit the coverage mapping data for a translation unit.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
std::pair< FileID, unsigned > getDecomposedSpellingLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
unsigned getFileIDSize(FileID FID) const
The size of the SLocEntry that FID represents.
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
Expr * getTrueExpr() const
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
Stmt * getHandlerBlock() const
A builtin binary operation expression such as "x + y" or "x <= y".
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
SourceLocation getLocForEndOfFile(FileID FID) const
Return the source location corresponding to the last byte of the specified file.
const TargetInfo & getTarget() const
bool isInFileID(SourceLocation Loc, FileID FID, unsigned *RelativeOffset=nullptr) const
Given a specific FileID, returns true if Loc is inside that FileID chunk and sets relative offset (of...
bool isWrittenInSameFile(SourceLocation Loc1, SourceLocation Loc2) const
Returns true if the spelling locations for both SourceLocations are part of the same file buffer...
static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Organizes the cross-function state that is used while generating code coverage mapping data...
const char * getBufferName(SourceLocation Loc, bool *Invalid=nullptr) const
Return the filename or buffer identifier of the buffer the location is in.
SourceLocation getIncludeLoc(FileID FID) const
Returns the include location if FID is a #include'd file otherwise it returns an invalid location...
unsigned getFileID(const FileEntry *File)
Return the coverage mapping translation unit file id for the given file.
static StringRef getCoverageSection(const CodeGenModule &CGM)
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
const Expr * getCond() const
Cached information about one file (either on disk or in the virtual file system). ...
unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
virtual Stmt * getBody() const
void SourceRangeSkipped(SourceRange Range) override
Hook called when a source range is skipped.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
const Expr * getSubExpr() const
const Stmt * getBody() const
std::pair< SourceLocation, SourceLocation > getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
unsigned getNumHandlers() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
const Expr * getRetValue() const
const Stmt * getThen() const
Expr * getFalseExpr() const
Represents Objective-C's collection statement.
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
DeclStmt * getRangeStmt()
void emitCounterMapping(const Decl *D, llvm::raw_ostream &OS)
Emit the coverage mapping data which maps the regions of code to counters that will be used to find t...
BoundNodesTreeBuilder *const Builder
const Expr * getCond() const
CompoundStmt * getTryBlock()
void addFunctionMappingRecord(llvm::GlobalVariable *FunctionName, StringRef FunctionNameValue, uint64_t FunctionHash, const std::string &CoverageMapping)
Add a function's coverage mapping record to the collection of the function mapping records...
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file. ...
unsigned getFileOffset(SourceLocation SpellingLoc) const
Returns the offset from the start of the file that the specified SourceLocation represents.
DeclStmt * getLoopVarStmt()
A trivial tuple used to represent a source range.
void emitEmptyMapping(const Decl *D, llvm::raw_ostream &OS)
Emit the coverage mapping data for an unused function. It creates mapping regions with the counter of...
virtual bool hasBody() const
Returns true if this Decl represents a declaration for a body of code, such as a function or method d...
This class handles loading and caching of source files into memory.
bool isMacroArgExpansion(SourceLocation Loc) const
Tests whether the given source location represents a macro argument's expansion into the function-lik...