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 const Counter &getCounter()
const {
return Count; }
52 void setCounter(Counter
C) {
Count =
C; }
54 bool hasStartLoc()
const {
return LocStart.hasValue(); }
59 assert(LocStart &&
"Region has no start location");
63 bool hasEndLoc()
const {
return LocEnd.hasValue(); }
68 assert(LocEnd &&
"Region has no end location");
75 class CoverageMappingBuilder {
83 llvm::SmallDenseMap<FileID, std::pair<unsigned, SourceLocation>, 8>
90 std::vector<SourceMappingRegion> SourceRegions;
94 : CVM(CVM), SM(SM), LangOpts(LangOpts) {}
144 return getPreciseTokenLocEnd(Loc);
153 FileIDMapping.clear();
157 for (
const auto &Region : SourceRegions) {
160 if (std::find(Visited.begin(), Visited.end(), File) != Visited.end())
162 Visited.push_back(File);
166 Parent.
isValid(); Parent = getIncludeOrExpansionLoc(Parent))
168 FileLocs.push_back(std::make_pair(Loc, Depth));
170 std::stable_sort(FileLocs.begin(), FileLocs.end(), llvm::less_second());
172 for (
const auto &FL : FileLocs) {
179 FileIDMapping[
SM.
getFileID(Loc)] = std::make_pair(Mapping.size(), Loc);
180 Mapping.push_back(CVM.getFileID(Entry));
188 auto Mapping = FileIDMapping.find(
SM.
getFileID(Loc));
189 if (Mapping != FileIDMapping.end())
190 return Mapping->second.first;
196 bool hasExistingCoverageFileID(
FileID File)
const {
197 return FileIDMapping.count(File);
202 void gatherSkippedRegions() {
206 FileLineRanges.resize(
207 FileIDMapping.size(),
208 std::make_pair(std::numeric_limits<unsigned>::max(), 0));
209 for (
const auto &R : MappingRegions) {
210 FileLineRanges[R.FileID].first =
211 std::min(FileLineRanges[R.FileID].first, R.LineStart);
212 FileLineRanges[R.FileID].second =
213 std::max(FileLineRanges[R.FileID].second, R.LineEnd);
216 auto SkippedRanges = CVM.getSourceInfo().getSkippedRanges();
217 for (
const auto &
I : SkippedRanges) {
218 auto LocStart =
I.getBegin();
219 auto LocEnd =
I.getEnd();
221 "region spans multiple files");
223 auto CovFileID = getCoverageFileID(LocStart);
230 auto Region = CounterMappingRegion::makeSkipped(
231 *CovFileID, LineStart, ColumnStart, LineEnd, ColumnEnd);
234 if (Region.LineStart >= FileLineRanges[*CovFileID].first &&
235 Region.LineEnd <= FileLineRanges[*CovFileID].second)
236 MappingRegions.push_back(Region);
242 void emitSourceRegions() {
243 for (
const auto &Region : SourceRegions) {
244 assert(Region.hasEndLoc() &&
"incomplete region");
249 auto CovFileID = getCoverageFileID(LocStart);
256 "region spans multiple files");
264 assert(LineStart <= LineEnd &&
"region start and end out of order");
265 MappingRegions.push_back(CounterMappingRegion::makeRegion(
266 Region.getCounter(), *CovFileID, LineStart, ColumnStart, LineEnd,
272 void emitExpansionRegions() {
273 for (
const auto &FM : FileIDMapping) {
279 auto ParentFileID = getCoverageFileID(ParentLoc);
282 auto ExpandedFileID = getCoverageFileID(ExpandedLoc);
283 assert(ExpandedFileID &&
"expansion in uncovered file");
287 "region spans multiple files");
294 MappingRegions.push_back(CounterMappingRegion::makeExpansion(
295 *ParentFileID, *ExpandedFileID, LineStart, ColumnStart, LineEnd,
303 struct EmptyCoverageMappingBuilder :
public CoverageMappingBuilder {
306 : CoverageMappingBuilder(CVM, SM, LangOpts) {}
308 void VisitDecl(
const Decl *D) {
312 SourceRegions.emplace_back(Counter(), getStart(Body), getEnd(Body));
316 void write(llvm::raw_ostream &OS) {
318 gatherFileIDs(FileIDMapping);
321 CoverageMappingWriter Writer(FileIDMapping, None, MappingRegions);
328 struct CounterCoverageMappingBuilder
329 :
public CoverageMappingBuilder,
332 llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
335 std::vector<SourceMappingRegion> RegionStack;
337 CounterExpressionBuilder
Builder;
346 Counter subtractCounters(Counter LHS, Counter RHS) {
347 return Builder.subtract(LHS, RHS);
351 Counter addCounters(Counter LHS, Counter RHS) {
355 Counter addCounters(Counter C1, Counter C2, Counter C3) {
356 return addCounters(addCounters(C1, C2), C3);
359 Counter addCounters(Counter C1, Counter C2, Counter C3, Counter C4) {
360 return addCounters(addCounters(C1, C2, C3), C4);
366 Counter getRegionCounter(
const Stmt *S) {
367 return Counter::getCounter(CounterMap[S]);
377 MostRecentLocation = *StartLoc;
378 RegionStack.emplace_back(Count, StartLoc, EndLoc);
380 return RegionStack.size() - 1;
387 void popRegions(
size_t ParentIndex) {
388 assert(RegionStack.size() >= ParentIndex &&
"parent not in stack");
389 while (RegionStack.size() > ParentIndex) {
390 SourceMappingRegion &Region = RegionStack.back();
391 if (Region.hasStartLoc()) {
395 : RegionStack[ParentIndex].getEndLoc();
402 SourceRegions.emplace_back(Region.getCounter(), NestedLoc, EndLoc);
404 EndLoc = getPreciseTokenLocEnd(getIncludeOrExpansionLoc(EndLoc));
406 llvm::report_fatal_error(
"File exit not handled before popRegions");
408 Region.setEndLoc(EndLoc);
410 MostRecentLocation = EndLoc;
413 if (StartLoc == getStartOfFileOrMacro(StartLoc) &&
414 EndLoc == getEndOfFileOrMacro(EndLoc))
415 MostRecentLocation = getIncludeOrExpansionLoc(EndLoc);
418 SourceRegions.push_back(Region);
420 RegionStack.pop_back();
425 SourceMappingRegion &getRegion() {
426 assert(!RegionStack.empty() &&
"statement has no region");
427 return RegionStack.back();
431 Counter propagateCounts(Counter TopCount,
const Stmt *S) {
432 size_t Index = pushRegion(TopCount, getStart(S), getEnd(S));
434 Counter ExitCount = getRegion().getCounter();
443 MostRecentLocation = EndLoc;
446 if (getRegion().hasEndLoc() &&
447 MostRecentLocation == getEndOfFileOrMacro(MostRecentLocation))
448 MostRecentLocation = getIncludeOrExpansionLoc(MostRecentLocation);
454 Loc = getIncludeOrExpansionLoc(Loc);
475 while (!isNestedIn(MostRecentLocation, ParentFile)) {
476 LCA = getIncludeOrExpansionLoc(LCA);
480 MostRecentLocation = NewLoc;
486 llvm::SmallSet<SourceLocation, 8> StartLocs;
488 for (SourceMappingRegion &
I : llvm::reverse(RegionStack)) {
489 if (!
I.hasStartLoc())
492 if (!isNestedIn(Loc, ParentFile)) {
493 ParentCounter =
I.getCounter();
501 if (StartLocs.insert(Loc).second)
502 SourceRegions.emplace_back(
I.getCounter(), Loc,
503 getEndOfFileOrMacro(Loc));
504 Loc = getIncludeOrExpansionLoc(Loc);
506 I.setStartLoc(getPreciseTokenLocEnd(Loc));
514 while (isNestedIn(Loc, ParentFile)) {
516 if (StartLocs.insert(FileStart).second)
517 SourceRegions.emplace_back(*ParentCounter, FileStart,
518 getEndOfFileOrMacro(Loc));
519 Loc = getIncludeOrExpansionLoc(Loc);
523 MostRecentLocation = NewLoc;
527 void extendRegion(
const Stmt *S) {
528 SourceMappingRegion &Region = getRegion();
531 handleFileExit(StartLoc);
532 if (!Region.hasStartLoc())
533 Region.setStartLoc(StartLoc);
537 void terminateRegion(
const Stmt *S) {
539 SourceMappingRegion &Region = getRegion();
540 if (!Region.hasEndLoc())
541 Region.setEndLoc(getEnd(S));
542 pushRegion(Counter::getZero());
546 struct BreakContinue {
548 Counter ContinueCount;
552 CounterCoverageMappingBuilder(
556 : CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap) {}
559 void write(llvm::raw_ostream &OS) {
561 gatherFileIDs(VirtualFileMapping);
563 emitExpansionRegions();
564 gatherSkippedRegions();
566 CoverageMappingWriter Writer(VirtualFileMapping,
Builder.getExpressions(),
571 void VisitStmt(
const Stmt *S) {
572 if (S->getLocStart().isValid())
574 for (
const Stmt *Child : S->children())
577 handleFileExit(getEnd(S));
580 void VisitDecl(
const Decl *D) {
582 propagateCounts(getRegionCounter(Body), Body);
599 void VisitGotoStmt(
const GotoStmt *S) { terminateRegion(S); }
601 void VisitLabelStmt(
const LabelStmt *S) {
604 handleFileExit(Start);
605 pushRegion(getRegionCounter(S), Start);
609 void VisitBreakStmt(
const BreakStmt *S) {
610 assert(!BreakContinueStack.empty() &&
"break not in a loop or switch!");
611 BreakContinueStack.back().BreakCount = addCounters(
612 BreakContinueStack.back().BreakCount, getRegion().getCounter());
617 assert(!BreakContinueStack.empty() &&
"continue stmt not in a loop!");
618 BreakContinueStack.back().ContinueCount = addCounters(
619 BreakContinueStack.back().ContinueCount, getRegion().getCounter());
623 void VisitWhileStmt(
const WhileStmt *S) {
626 Counter ParentCount = getRegion().getCounter();
627 Counter BodyCount = getRegionCounter(S);
630 BreakContinueStack.push_back(BreakContinue());
632 Counter BackedgeCount = propagateCounts(BodyCount, S->
getBody());
633 BreakContinue BC = BreakContinueStack.pop_back_val();
637 addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
638 propagateCounts(CondCount, S->
getCond());
639 adjustForOutOfOrderTraversal(getEnd(S));
642 addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
643 if (OutCount != ParentCount)
644 pushRegion(OutCount);
647 void VisitDoStmt(
const DoStmt *S) {
650 Counter ParentCount = getRegion().getCounter();
651 Counter BodyCount = getRegionCounter(S);
653 BreakContinueStack.push_back(BreakContinue());
655 Counter BackedgeCount =
656 propagateCounts(addCounters(ParentCount, BodyCount), S->
getBody());
657 BreakContinue BC = BreakContinueStack.pop_back_val();
659 Counter CondCount = addCounters(BackedgeCount, BC.ContinueCount);
660 propagateCounts(CondCount, S->
getCond());
663 addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
664 if (OutCount != ParentCount)
665 pushRegion(OutCount);
668 void VisitForStmt(
const ForStmt *S) {
673 Counter ParentCount = getRegion().getCounter();
674 Counter BodyCount = getRegionCounter(S);
677 BreakContinueStack.push_back(BreakContinue());
679 Counter BackedgeCount = propagateCounts(BodyCount, S->
getBody());
680 BreakContinue BC = BreakContinueStack.pop_back_val();
685 propagateCounts(addCounters(BackedgeCount, BC.ContinueCount), Inc);
689 addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
691 propagateCounts(CondCount, Cond);
692 adjustForOutOfOrderTraversal(getEnd(S));
696 addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
697 if (OutCount != ParentCount)
698 pushRegion(OutCount);
706 Counter ParentCount = getRegion().getCounter();
707 Counter BodyCount = getRegionCounter(S);
709 BreakContinueStack.push_back(BreakContinue());
711 Counter BackedgeCount = propagateCounts(BodyCount, S->
getBody());
712 BreakContinue BC = BreakContinueStack.pop_back_val();
715 addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
717 addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount));
718 if (OutCount != ParentCount)
719 pushRegion(OutCount);
726 Counter ParentCount = getRegion().getCounter();
727 Counter BodyCount = getRegionCounter(S);
729 BreakContinueStack.push_back(BreakContinue());
731 Counter BackedgeCount = propagateCounts(BodyCount, S->
getBody());
732 BreakContinue BC = BreakContinueStack.pop_back_val();
735 addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
737 addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount));
738 if (OutCount != ParentCount)
739 pushRegion(OutCount);
746 BreakContinueStack.push_back(BreakContinue());
750 if (
const auto *CS = dyn_cast<CompoundStmt>(Body)) {
751 if (!CS->body_empty()) {
757 pushRegion(Counter::getZero(), getStart(CS->body_front()),
758 getEnd(CS->body_back()));
759 for (
const auto *Child : CS->children())
764 propagateCounts(Counter::getZero(), Body);
765 BreakContinue BC = BreakContinueStack.pop_back_val();
767 if (!BreakContinueStack.empty())
768 BreakContinueStack.back().ContinueCount = addCounters(
769 BreakContinueStack.back().ContinueCount, BC.ContinueCount);
771 Counter ExitCount = getRegionCounter(S);
772 pushRegion(ExitCount);
778 SourceMappingRegion &Parent = getRegion();
780 Counter Count = addCounters(Parent.getCounter(), getRegionCounter(S));
783 if (Parent.hasStartLoc() && Parent.getStartLoc() == getStart(S))
784 Parent.setCounter(Count);
786 pushRegion(Count, getStart(S));
788 if (
const auto *CS = dyn_cast<CaseStmt>(S)) {
790 if (
const Expr *RHS = CS->getRHS())
796 void VisitIfStmt(
const IfStmt *S) {
802 Counter ParentCount = getRegion().getCounter();
803 Counter ThenCount = getRegionCounter(S);
807 propagateCounts(ParentCount, S->
getCond());
810 Counter OutCount = propagateCounts(ThenCount, S->
getThen());
812 Counter ElseCount = subtractCounters(ParentCount, ThenCount);
815 OutCount = addCounters(OutCount, propagateCounts(ElseCount, Else));
817 OutCount = addCounters(OutCount, ElseCount);
819 if (OutCount != ParentCount)
820 pushRegion(OutCount);
829 Counter ExitCount = getRegionCounter(S);
830 pushRegion(ExitCount);
840 Counter ParentCount = getRegion().getCounter();
841 Counter TrueCount = getRegionCounter(E);
845 if (!isa<BinaryConditionalOperator>(E)) {
850 propagateCounts(subtractCounters(ParentCount, TrueCount),
858 extendRegion(E->
getRHS());
859 propagateCounts(getRegionCounter(E), E->
getRHS());
866 extendRegion(E->
getRHS());
867 propagateCounts(getRegionCounter(E), E->
getRHS());
882 return llvm::getInstrProfCoverageSectionName(
isMachO(CGM));
885 static void dump(llvm::raw_ostream &OS, StringRef FunctionName,
888 OS << FunctionName <<
":\n";
889 CounterMappingContext Ctx(Expressions);
890 for (
const auto &R : Regions) {
893 case CounterMappingRegion::CodeRegion:
895 case CounterMappingRegion::ExpansionRegion:
898 case CounterMappingRegion::SkippedRegion:
903 OS <<
"File " << R.FileID <<
", " << R.LineStart <<
":" << R.ColumnStart
904 <<
" -> " << R.LineEnd <<
":" << R.ColumnEnd <<
" = ";
905 Ctx.dump(R.Count, OS);
906 if (R.Kind == CounterMappingRegion::ExpansionRegion)
907 OS <<
" (Expanded file = " << R.ExpandedFileID <<
")";
913 llvm::GlobalVariable *NamePtr, StringRef NameValue, uint64_t FuncHash,
914 const std::string &CoverageMapping,
bool isUsed) {
915 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
916 if (!FunctionRecordTy) {
917 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) LLVMType,
919 #include "llvm/ProfileData/InstrProfData.inc"
922 llvm::StructType::get(Ctx, makeArrayRef(FunctionRecordTypes),
926 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Init,
927 llvm::Constant *FunctionRecordVals[] = {
928 #include "llvm/ProfileData/InstrProfData.inc"
930 FunctionRecords.push_back(llvm::ConstantStruct::get(
931 FunctionRecordTy, makeArrayRef(FunctionRecordVals)));
933 FunctionNames.push_back(
934 llvm::ConstantExpr::getBitCast(NamePtr, llvm::Type::getInt8PtrTy(Ctx)));
935 CoverageMappings += CoverageMapping;
937 if (CGM.getCodeGenOpts().DumpCoverageMapping) {
943 std::vector<StringRef> Filenames;
944 std::vector<CounterExpression> Expressions;
945 std::vector<CounterMappingRegion> Regions;
947 FilenameRefs.resize(FileEntries.size());
948 for (
const auto &Entry : FileEntries)
949 FilenameRefs[Entry.second] = Entry.first->getName();
950 RawCoverageMappingReader Reader(CoverageMapping, FilenameRefs, Filenames,
951 Expressions, Regions);
954 dump(llvm::outs(), NameValue, Expressions, Regions);
959 if (FunctionRecords.empty())
961 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
962 auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
967 FilenameStrs.resize(FileEntries.size());
968 FilenameRefs.resize(FileEntries.size());
969 for (
const auto &Entry : FileEntries) {
971 llvm::sys::fs::make_absolute(Path);
973 auto I = Entry.second;
974 FilenameStrs[
I] = std::string(Path.begin(), Path.end());
975 FilenameRefs[
I] = FilenameStrs[
I];
978 std::string FilenamesAndCoverageMappings;
979 llvm::raw_string_ostream OS(FilenamesAndCoverageMappings);
980 CoverageFilenamesSectionWriter(FilenameRefs).write(OS);
981 OS << CoverageMappings;
982 size_t CoverageMappingSize = CoverageMappings.size();
983 size_t FilenamesSize = OS.str().size() - CoverageMappingSize;
986 if (
size_t Rem = OS.str().size() % 8) {
987 CoverageMappingSize += 8 - Rem;
988 for (
size_t I = 0, S = 8 - Rem;
I <
S; ++
I)
991 auto *FilenamesAndMappingsVal =
992 llvm::ConstantDataArray::getString(Ctx, OS.str(),
false);
996 llvm::ArrayType::get(FunctionRecordTy, FunctionRecords.size());
997 auto RecordsVal = llvm::ConstantArray::get(RecordsTy, FunctionRecords);
1000 #define COVMAP_HEADER(Type, LLVMType, Name, Init) LLVMType,
1001 #include "llvm/ProfileData/InstrProfData.inc"
1003 auto CovDataHeaderTy =
1004 llvm::StructType::get(Ctx, makeArrayRef(CovDataHeaderTypes));
1005 llvm::Constant *CovDataHeaderVals[] = {
1006 #define COVMAP_HEADER(Type, LLVMType, Name, Init) Init,
1007 #include "llvm/ProfileData/InstrProfData.inc"
1009 auto CovDataHeaderVal = llvm::ConstantStruct::get(
1010 CovDataHeaderTy, makeArrayRef(CovDataHeaderVals));
1013 llvm::Type *CovDataTypes[] = {CovDataHeaderTy, RecordsTy,
1014 FilenamesAndMappingsVal->getType()};
1015 auto CovDataTy = llvm::StructType::get(Ctx, makeArrayRef(CovDataTypes));
1016 llvm::Constant *TUDataVals[] = {CovDataHeaderVal, RecordsVal,
1017 FilenamesAndMappingsVal};
1019 llvm::ConstantStruct::get(CovDataTy, makeArrayRef(TUDataVals));
1020 auto CovData =
new llvm::GlobalVariable(
1022 CovDataVal, llvm::getCoverageMappingVarName());
1025 CovData->setAlignment(8);
1028 CGM.addUsedGlobal(CovData);
1030 if (!FunctionNames.empty()) {
1031 auto NamesArrTy = llvm::ArrayType::get(llvm::Type::getInt8PtrTy(Ctx),
1032 FunctionNames.size());
1033 auto NamesArrVal = llvm::ConstantArray::get(NamesArrTy, FunctionNames);
1036 new llvm::GlobalVariable(CGM.getModule(), NamesArrTy,
true,
1038 llvm::getCoverageNamesVarName());
1043 auto It = FileEntries.find(File);
1044 if (It != FileEntries.end())
1046 unsigned FileID = FileEntries.size();
1047 FileEntries.insert(std::make_pair(File,
FileID));
1052 llvm::raw_ostream &OS) {
1054 CounterCoverageMappingBuilder Walker(CVM, *CounterMap,
SM, LangOpts);
1055 Walker.VisitDecl(D);
1060 llvm::raw_ostream &OS) {
1061 EmptyCoverageMappingBuilder Walker(CVM,
SM, LangOpts);
1062 Walker.VisitDecl(D);
bool isMacroArgExpansion(SourceLocation Loc, SourceLocation *StartLoc=nullptr) const
Tests whether the given source location represents a macro argument's expansion into the function-lik...
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID. ...
CXXCatchStmt * getHandler(unsigned i)
IfStmt - This represents an if/then/else.
unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
Decl - This represents one declaration (or definition), e.g.
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.
LabelStmt - Represents a label, which has a substatement.
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.
ForStmt - This represents a 'for (init;cond;inc)' stmt.
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".
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
detail::InMemoryDirectory::const_iterator I
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...
Expr - This represents one expression.
static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
MeasureTokenLength - Relex the token at the specified location and return its length in bytes in the ...
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.
CXXTryStmt - A C++ try block, including all handlers.
SourceLocation getIncludeLoc(FileID FID) const
Returns the include location if FID is a #include'd file otherwise it returns an invalid location...
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
unsigned getFileID(const FileEntry *File)
Return the coverage mapping translation unit file id for the given file.
DoStmt - This represents a 'do/while' stmt.
The l-value was considered opaque, so the alignment was determined from a type.
static StringRef getCoverageSection(const CodeGenModule &CGM)
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
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
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
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...
This class organizes the cross-function state that is used while generating LLVM code.
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.
detail::InMemoryDirectory::const_iterator E
const Expr * getRetValue() const
const Stmt * getThen() const
SwitchStmt - This represents a 'switch' stmt.
Expr * getFalseExpr() const
Represents Objective-C's collection statement.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
DeclStmt * getRangeStmt()
GotoStmt - This represents a direct goto.
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
ContinueStmt - This represents a continue.
CXXCatchStmt - This represents a C++ catch block.
WhileStmt - This represents a 'while' stmt.
const Expr * getCond() const
CompoundStmt * getTryBlock()
void addFunctionMappingRecord(llvm::GlobalVariable *FunctionName, StringRef FunctionNameValue, uint64_t FunctionHash, const std::string &CoverageMapping, bool isUsed=true)
Add a function's coverage mapping record to the collection of the function mapping records...
BreakStmt - This represents a break.
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.
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.