18 #include "llvm/ADT/SmallSet.h"
19 #include "llvm/ADT/StringExtras.h"
20 #include "llvm/ADT/Optional.h"
21 #include "llvm/ProfileData/Coverage/CoverageMapping.h"
22 #include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
23 #include "llvm/ProfileData/Coverage/CoverageMappingWriter.h"
24 #include "llvm/ProfileData/InstrProfReader.h"
25 #include "llvm/Support/FileSystem.h"
26 #include "llvm/Support/Path.h"
28 using namespace clang;
29 using namespace CodeGen;
30 using namespace llvm::coverage;
33 SkippedRanges.push_back(Range);
39 class SourceMappingRegion {
51 : Count(Count), LocStart(LocStart), LocEnd(LocEnd) {}
53 const Counter &getCounter()
const {
return Count; }
55 void setCounter(Counter C) { Count = C; }
57 bool hasStartLoc()
const {
return LocStart.hasValue(); }
62 assert(LocStart &&
"Region has no start location");
66 bool hasEndLoc()
const {
return LocEnd.hasValue(); }
71 assert(LocEnd &&
"Region has no end location");
78 class CoverageMappingBuilder {
86 llvm::SmallDenseMap<FileID, std::pair<unsigned, SourceLocation>, 8>
93 std::vector<SourceMappingRegion> SourceRegions;
100 typedef llvm::SmallSet<std::pair<SourceLocation, SourceLocation>, 8>
105 : CVM(CVM), SM(SM), LangOpts(LangOpts) {}
145 Loc = getIncludeOrExpansionLoc(Loc);
165 return getPreciseTokenLocEnd(Loc);
174 FileIDMapping.clear();
176 llvm::SmallSet<FileID, 8> Visited;
178 for (
const auto &Region : SourceRegions) {
181 if (!Visited.insert(File).second)
190 Parent.
isValid(); Parent = getIncludeOrExpansionLoc(Parent))
192 FileLocs.push_back(std::make_pair(Loc, Depth));
194 std::stable_sort(FileLocs.begin(), FileLocs.end(), llvm::less_second());
196 for (
const auto &FL : FileLocs) {
203 FileIDMapping[
SM.
getFileID(Loc)] = std::make_pair(Mapping.size(), Loc);
204 Mapping.push_back(CVM.getFileID(Entry));
212 auto Mapping = FileIDMapping.find(
SM.
getFileID(Loc));
213 if (Mapping != FileIDMapping.end())
214 return Mapping->second.first;
220 void gatherSkippedRegions() {
224 FileLineRanges.resize(
225 FileIDMapping.size(),
227 for (
const auto &R : MappingRegions) {
228 FileLineRanges[R.FileID].first =
229 std::min(FileLineRanges[R.FileID].first, R.LineStart);
230 FileLineRanges[R.FileID].second =
231 std::max(FileLineRanges[R.FileID].second, R.LineEnd);
234 auto SkippedRanges = CVM.getSourceInfo().getSkippedRanges();
235 for (
const auto &
I : SkippedRanges) {
236 auto LocStart =
I.getBegin();
237 auto LocEnd =
I.getEnd();
239 "region spans multiple files");
241 auto CovFileID = getCoverageFileID(LocStart);
248 auto Region = CounterMappingRegion::makeSkipped(
249 *CovFileID, LineStart, ColumnStart, LineEnd, ColumnEnd);
252 if (Region.LineStart >= FileLineRanges[*CovFileID].first &&
253 Region.LineEnd <= FileLineRanges[*CovFileID].second)
254 MappingRegions.push_back(Region);
260 void emitSourceRegions(
const SourceRegionFilter &Filter) {
261 for (
const auto &Region : SourceRegions) {
262 assert(Region.hasEndLoc() &&
"incomplete region");
271 auto CovFileID = getCoverageFileID(LocStart);
278 "region spans multiple files");
284 if (Filter.count(std::make_pair(LocStart, LocEnd)))
293 assert(LineStart <= LineEnd &&
"region start and end out of order");
294 MappingRegions.push_back(CounterMappingRegion::makeRegion(
295 Region.getCounter(), *CovFileID, LineStart, ColumnStart, LineEnd,
301 SourceRegionFilter emitExpansionRegions() {
302 SourceRegionFilter Filter;
303 for (
const auto &FM : FileIDMapping) {
309 auto ParentFileID = getCoverageFileID(ParentLoc);
312 auto ExpandedFileID = getCoverageFileID(ExpandedLoc);
313 assert(ExpandedFileID &&
"expansion in uncovered file");
317 "region spans multiple files");
318 Filter.insert(std::make_pair(ParentLoc, LocEnd));
325 MappingRegions.push_back(CounterMappingRegion::makeExpansion(
326 *ParentFileID, *ExpandedFileID, LineStart, ColumnStart, LineEnd,
335 struct EmptyCoverageMappingBuilder :
public CoverageMappingBuilder {
338 : CoverageMappingBuilder(CVM, SM, LangOpts) {}
340 void VisitDecl(
const Decl *D) {
351 while (StartFileID != EndFileID && !isNestedIn(End, StartFileID)) {
352 Start = getIncludeOrExpansionLoc(Start);
354 "Declaration start location not nested within a known region");
357 while (StartFileID != EndFileID) {
358 End = getPreciseTokenLocEnd(getIncludeOrExpansionLoc(End));
360 "Declaration end location not nested within a known region");
364 SourceRegions.emplace_back(Counter(), Start, End);
368 void write(llvm::raw_ostream &OS) {
370 gatherFileIDs(FileIDMapping);
371 emitSourceRegions(SourceRegionFilter());
373 if (MappingRegions.empty())
376 CoverageMappingWriter Writer(FileIDMapping, None, MappingRegions);
383 struct CounterCoverageMappingBuilder
384 :
public CoverageMappingBuilder,
387 llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
390 std::vector<SourceMappingRegion> RegionStack;
392 CounterExpressionBuilder
Builder;
401 Counter subtractCounters(Counter LHS, Counter RHS) {
402 return Builder.subtract(LHS, RHS);
406 Counter addCounters(Counter LHS, Counter RHS) {
410 Counter addCounters(Counter C1, Counter C2, Counter C3) {
411 return addCounters(addCounters(C1, C2), C3);
417 Counter getRegionCounter(
const Stmt *S) {
418 return Counter::getCounter(CounterMap[S]);
428 MostRecentLocation = *StartLoc;
429 RegionStack.emplace_back(Count, StartLoc, EndLoc);
431 return RegionStack.size() - 1;
438 void popRegions(
size_t ParentIndex) {
439 assert(RegionStack.size() >= ParentIndex &&
"parent not in stack");
440 while (RegionStack.size() > ParentIndex) {
441 SourceMappingRegion &Region = RegionStack.back();
442 if (Region.hasStartLoc()) {
446 : RegionStack[ParentIndex].getEndLoc();
453 if (!isRegionAlreadyAdded(NestedLoc, EndLoc))
454 SourceRegions.emplace_back(Region.getCounter(), NestedLoc, EndLoc);
456 EndLoc = getPreciseTokenLocEnd(getIncludeOrExpansionLoc(EndLoc));
458 llvm::report_fatal_error(
"File exit not handled before popRegions");
460 Region.setEndLoc(EndLoc);
462 MostRecentLocation = EndLoc;
465 if (StartLoc == getStartOfFileOrMacro(StartLoc) &&
466 EndLoc == getEndOfFileOrMacro(EndLoc))
467 MostRecentLocation = getIncludeOrExpansionLoc(EndLoc);
470 SourceRegions.push_back(Region);
472 RegionStack.pop_back();
477 SourceMappingRegion &getRegion() {
478 assert(!RegionStack.empty() &&
"statement has no region");
479 return RegionStack.back();
483 Counter propagateCounts(Counter TopCount,
const Stmt *S) {
484 size_t Index = pushRegion(TopCount, getStart(S), getEnd(S));
486 Counter ExitCount = getRegion().getCounter();
492 MostRecentLocation = getEnd(S);
500 return SourceRegions.rend() !=
501 std::find_if(SourceRegions.rbegin(), SourceRegions.rend(),
502 [&](
const SourceMappingRegion &Region) {
503 return Region.getStartLoc() == StartLoc &&
504 Region.getEndLoc() == EndLoc;
512 MostRecentLocation = EndLoc;
518 if (getRegion().hasEndLoc() &&
519 MostRecentLocation == getEndOfFileOrMacro(MostRecentLocation) &&
520 isRegionAlreadyAdded(getStartOfFileOrMacro(MostRecentLocation),
522 MostRecentLocation = getIncludeOrExpansionLoc(MostRecentLocation);
539 while (!isNestedIn(MostRecentLocation, ParentFile)) {
540 LCA = getIncludeOrExpansionLoc(LCA);
544 MostRecentLocation = NewLoc;
550 llvm::SmallSet<SourceLocation, 8> StartLocs;
552 for (SourceMappingRegion &
I : llvm::reverse(RegionStack)) {
553 if (!
I.hasStartLoc())
556 if (!isNestedIn(Loc, ParentFile)) {
557 ParentCounter =
I.getCounter();
565 if (StartLocs.insert(Loc).second)
566 SourceRegions.emplace_back(
I.getCounter(), Loc,
567 getEndOfFileOrMacro(Loc));
568 Loc = getIncludeOrExpansionLoc(Loc);
570 I.setStartLoc(getPreciseTokenLocEnd(Loc));
578 while (isNestedIn(Loc, ParentFile)) {
580 if (StartLocs.insert(FileStart).second)
581 SourceRegions.emplace_back(*ParentCounter, FileStart,
582 getEndOfFileOrMacro(Loc));
583 Loc = getIncludeOrExpansionLoc(Loc);
587 MostRecentLocation = NewLoc;
591 void extendRegion(
const Stmt *S) {
592 SourceMappingRegion &Region = getRegion();
595 handleFileExit(StartLoc);
596 if (!Region.hasStartLoc())
597 Region.setStartLoc(StartLoc);
601 void terminateRegion(
const Stmt *S) {
603 SourceMappingRegion &Region = getRegion();
604 if (!Region.hasEndLoc())
605 Region.setEndLoc(getEnd(S));
606 pushRegion(Counter::getZero());
610 struct BreakContinue {
612 Counter ContinueCount;
616 CounterCoverageMappingBuilder(
620 : CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap) {}
623 void write(llvm::raw_ostream &OS) {
625 gatherFileIDs(VirtualFileMapping);
626 SourceRegionFilter Filter = emitExpansionRegions();
627 emitSourceRegions(Filter);
628 gatherSkippedRegions();
630 if (MappingRegions.empty())
633 CoverageMappingWriter Writer(VirtualFileMapping,
Builder.getExpressions(),
638 void VisitStmt(
const Stmt *S) {
644 handleFileExit(getEnd(S));
647 void VisitDecl(
const Decl *D) {
654 propagateCounts(getRegionCounter(Body), Body);
671 void VisitGotoStmt(
const GotoStmt *S) { terminateRegion(S); }
673 void VisitLabelStmt(
const LabelStmt *S) {
676 handleFileExit(Start);
677 pushRegion(getRegionCounter(S), Start);
681 void VisitBreakStmt(
const BreakStmt *S) {
682 assert(!BreakContinueStack.empty() &&
"break not in a loop or switch!");
683 BreakContinueStack.back().BreakCount = addCounters(
684 BreakContinueStack.back().BreakCount, getRegion().getCounter());
689 assert(!BreakContinueStack.empty() &&
"continue stmt not in a loop!");
690 BreakContinueStack.back().ContinueCount = addCounters(
691 BreakContinueStack.back().ContinueCount, getRegion().getCounter());
695 void VisitWhileStmt(
const WhileStmt *S) {
698 Counter ParentCount = getRegion().getCounter();
699 Counter BodyCount = getRegionCounter(S);
702 BreakContinueStack.push_back(BreakContinue());
704 Counter BackedgeCount = propagateCounts(BodyCount, S->
getBody());
705 BreakContinue BC = BreakContinueStack.pop_back_val();
709 addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
710 propagateCounts(CondCount, S->
getCond());
711 adjustForOutOfOrderTraversal(getEnd(S));
714 addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
715 if (OutCount != ParentCount)
716 pushRegion(OutCount);
719 void VisitDoStmt(
const DoStmt *S) {
722 Counter ParentCount = getRegion().getCounter();
723 Counter BodyCount = getRegionCounter(S);
725 BreakContinueStack.push_back(BreakContinue());
727 Counter BackedgeCount =
728 propagateCounts(addCounters(ParentCount, BodyCount), S->
getBody());
729 BreakContinue BC = BreakContinueStack.pop_back_val();
731 Counter CondCount = addCounters(BackedgeCount, BC.ContinueCount);
732 propagateCounts(CondCount, S->
getCond());
735 addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
736 if (OutCount != ParentCount)
737 pushRegion(OutCount);
740 void VisitForStmt(
const ForStmt *S) {
745 Counter ParentCount = getRegion().getCounter();
746 Counter BodyCount = getRegionCounter(S);
749 BreakContinueStack.push_back(BreakContinue());
751 Counter BackedgeCount = propagateCounts(BodyCount, S->
getBody());
752 BreakContinue BC = BreakContinueStack.pop_back_val();
757 propagateCounts(addCounters(BackedgeCount, BC.ContinueCount), Inc);
761 addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
763 propagateCounts(CondCount, Cond);
764 adjustForOutOfOrderTraversal(getEnd(S));
768 addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
769 if (OutCount != ParentCount)
770 pushRegion(OutCount);
778 Counter ParentCount = getRegion().getCounter();
779 Counter BodyCount = getRegionCounter(S);
781 BreakContinueStack.push_back(BreakContinue());
783 Counter BackedgeCount = propagateCounts(BodyCount, S->
getBody());
784 BreakContinue BC = BreakContinueStack.pop_back_val();
787 addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
789 addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount));
790 if (OutCount != ParentCount)
791 pushRegion(OutCount);
798 Counter ParentCount = getRegion().getCounter();
799 Counter BodyCount = getRegionCounter(S);
801 BreakContinueStack.push_back(BreakContinue());
803 Counter BackedgeCount = propagateCounts(BodyCount, S->
getBody());
804 BreakContinue BC = BreakContinueStack.pop_back_val();
807 addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
809 addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount));
810 if (OutCount != ParentCount)
811 pushRegion(OutCount);
820 BreakContinueStack.push_back(BreakContinue());
824 if (
const auto *CS = dyn_cast<CompoundStmt>(Body)) {
825 if (!CS->body_empty()) {
831 pushRegion(Counter::getZero(), getStart(CS->body_front()),
832 getEnd(CS->body_back()));
833 for (
const auto *Child : CS->children())
838 propagateCounts(Counter::getZero(), Body);
839 BreakContinue BC = BreakContinueStack.pop_back_val();
841 if (!BreakContinueStack.empty())
842 BreakContinueStack.back().ContinueCount = addCounters(
843 BreakContinueStack.back().ContinueCount, BC.ContinueCount);
845 Counter ExitCount = getRegionCounter(S);
847 pushRegion(ExitCount);
851 MostRecentLocation = getStart(S);
852 handleFileExit(ExitLoc);
858 SourceMappingRegion &Parent = getRegion();
860 Counter Count = addCounters(Parent.getCounter(), getRegionCounter(S));
863 if (Parent.hasStartLoc() && Parent.getStartLoc() == getStart(S))
864 Parent.setCounter(Count);
866 pushRegion(Count, getStart(S));
868 if (
const auto *CS = dyn_cast<CaseStmt>(S)) {
870 if (
const Expr *RHS = CS->getRHS())
876 void VisitIfStmt(
const IfStmt *S) {
885 Counter ParentCount = getRegion().getCounter();
886 Counter ThenCount = getRegionCounter(S);
890 propagateCounts(ParentCount, S->
getCond());
893 Counter OutCount = propagateCounts(ThenCount, S->
getThen());
895 Counter ElseCount = subtractCounters(ParentCount, ThenCount);
898 OutCount = addCounters(OutCount, propagateCounts(ElseCount, Else));
900 OutCount = addCounters(OutCount, ElseCount);
902 if (OutCount != ParentCount)
903 pushRegion(OutCount);
911 Counter ParentCount = getRegion().getCounter();
917 Counter ExitCount = getRegionCounter(S);
918 pushRegion(ExitCount);
928 Counter ParentCount = getRegion().getCounter();
929 Counter TrueCount = getRegionCounter(E);
933 if (!isa<BinaryConditionalOperator>(E)) {
938 propagateCounts(subtractCounters(ParentCount, TrueCount),
946 extendRegion(E->
getRHS());
947 propagateCounts(getRegionCounter(E), E->
getRHS());
954 extendRegion(E->
getRHS());
955 propagateCounts(getRegionCounter(E), E->
getRHS());
965 return llvm::getInstrProfSectionName(
970 std::string normalizeFilename(StringRef
Filename) {
972 llvm::sys::fs::make_absolute(Path);
973 llvm::sys::path::remove_dots(Path,
true);
974 return Path.str().str();
979 static void dump(llvm::raw_ostream &OS, StringRef FunctionName,
982 OS << FunctionName <<
":\n";
983 CounterMappingContext Ctx(Expressions);
984 for (
const auto &R : Regions) {
987 case CounterMappingRegion::CodeRegion:
989 case CounterMappingRegion::ExpansionRegion:
992 case CounterMappingRegion::SkippedRegion:
997 OS <<
"File " << R.FileID <<
", " << R.LineStart <<
":" << R.ColumnStart
998 <<
" -> " << R.LineEnd <<
":" << R.ColumnEnd <<
" = ";
999 Ctx.dump(R.Count, OS);
1000 if (R.Kind == CounterMappingRegion::ExpansionRegion)
1001 OS <<
" (Expanded file = " << R.ExpandedFileID <<
")";
1007 llvm::GlobalVariable *NamePtr, StringRef NameValue, uint64_t FuncHash,
1008 const std::string &CoverageMapping,
bool IsUsed) {
1010 if (!FunctionRecordTy) {
1011 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) LLVMType,
1013 #include "llvm/ProfileData/InstrProfData.inc"
1016 llvm::StructType::get(Ctx, makeArrayRef(FunctionRecordTypes),
1020 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Init,
1021 llvm::Constant *FunctionRecordVals[] = {
1022 #include "llvm/ProfileData/InstrProfData.inc"
1024 FunctionRecords.push_back(llvm::ConstantStruct::get(
1025 FunctionRecordTy, makeArrayRef(FunctionRecordVals)));
1027 FunctionNames.push_back(
1028 llvm::ConstantExpr::getBitCast(NamePtr, llvm::Type::getInt8PtrTy(Ctx)));
1029 CoverageMappings.push_back(CoverageMapping);
1037 std::vector<StringRef> Filenames;
1038 std::vector<CounterExpression> Expressions;
1039 std::vector<CounterMappingRegion> Regions;
1042 FilenameStrs.resize(FileEntries.size());
1043 FilenameRefs.resize(FileEntries.size());
1044 for (
const auto &Entry : FileEntries) {
1045 auto I = Entry.second;
1046 FilenameStrs[
I] = normalizeFilename(Entry.first->getName());
1047 FilenameRefs[
I] = FilenameStrs[
I];
1049 RawCoverageMappingReader Reader(CoverageMapping, FilenameRefs, Filenames,
1050 Expressions, Regions);
1053 dump(llvm::outs(), NameValue, Expressions, Regions);
1058 if (FunctionRecords.empty())
1061 auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
1066 FilenameStrs.resize(FileEntries.size());
1067 FilenameRefs.resize(FileEntries.size());
1068 for (
const auto &Entry : FileEntries) {
1069 auto I = Entry.second;
1070 FilenameStrs[
I] = normalizeFilename(Entry.first->getName());
1071 FilenameRefs[
I] = FilenameStrs[
I];
1074 std::string FilenamesAndCoverageMappings;
1075 llvm::raw_string_ostream OS(FilenamesAndCoverageMappings);
1076 CoverageFilenamesSectionWriter(FilenameRefs).write(OS);
1077 std::string RawCoverageMappings =
1078 llvm::join(CoverageMappings.begin(), CoverageMappings.end(),
"");
1079 OS << RawCoverageMappings;
1080 size_t CoverageMappingSize = RawCoverageMappings.size();
1081 size_t FilenamesSize = OS.str().size() - CoverageMappingSize;
1084 if (
size_t Rem = OS.str().size() % 8) {
1085 CoverageMappingSize += 8 - Rem;
1086 for (
size_t I = 0, S = 8 - Rem;
I <
S; ++
I)
1089 auto *FilenamesAndMappingsVal =
1090 llvm::ConstantDataArray::getString(Ctx, OS.str(),
false);
1094 llvm::ArrayType::get(FunctionRecordTy, FunctionRecords.size());
1095 auto RecordsVal = llvm::ConstantArray::get(RecordsTy, FunctionRecords);
1098 #define COVMAP_HEADER(Type, LLVMType, Name, Init) LLVMType,
1099 #include "llvm/ProfileData/InstrProfData.inc"
1101 auto CovDataHeaderTy =
1102 llvm::StructType::get(Ctx, makeArrayRef(CovDataHeaderTypes));
1103 llvm::Constant *CovDataHeaderVals[] = {
1104 #define COVMAP_HEADER(Type, LLVMType, Name, Init) Init,
1105 #include "llvm/ProfileData/InstrProfData.inc"
1107 auto CovDataHeaderVal = llvm::ConstantStruct::get(
1108 CovDataHeaderTy, makeArrayRef(CovDataHeaderVals));
1111 llvm::Type *CovDataTypes[] = {CovDataHeaderTy, RecordsTy,
1112 FilenamesAndMappingsVal->getType()};
1113 auto CovDataTy = llvm::StructType::get(Ctx, makeArrayRef(CovDataTypes));
1114 llvm::Constant *TUDataVals[] = {CovDataHeaderVal, RecordsVal,
1115 FilenamesAndMappingsVal};
1117 llvm::ConstantStruct::get(CovDataTy, makeArrayRef(TUDataVals));
1118 auto CovData =
new llvm::GlobalVariable(
1120 CovDataVal, llvm::getCoverageMappingVarName());
1122 CovData->setSection(getCoverageSection(CGM));
1123 CovData->setAlignment(8);
1128 if (!FunctionNames.empty()) {
1129 auto NamesArrTy = llvm::ArrayType::get(llvm::Type::getInt8PtrTy(Ctx),
1130 FunctionNames.size());
1131 auto NamesArrVal = llvm::ConstantArray::get(NamesArrTy, FunctionNames);
1134 new llvm::GlobalVariable(CGM.
getModule(), NamesArrTy,
true,
1136 llvm::getCoverageUnusedNamesVarName());
1141 auto It = FileEntries.find(File);
1142 if (It != FileEntries.end())
1144 unsigned FileID = FileEntries.size();
1145 FileEntries.insert(std::make_pair(File,
FileID));
1150 llvm::raw_ostream &OS) {
1152 CounterCoverageMappingBuilder Walker(CVM, *CounterMap,
SM, LangOpts);
1153 Walker.VisitDecl(D);
1158 llvm::raw_ostream &OS) {
1159 EmptyCoverageMappingBuilder Walker(CVM,
SM, LangOpts);
1160 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.
llvm::Module & getModule() const
llvm::LLVMContext & getLLVMContext()
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID. ...
Stmt - This represents one statement.
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.
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.
StringRef getBufferName(SourceLocation Loc, bool *Invalid=nullptr) const
Return the filename or buffer identifier of the buffer the location is in.
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...
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.
const TargetInfo & getTargetInfo() const
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.
SourceLocation getLocEnd() const LLVM_READONLY
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.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
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...
ASTContext & getContext() const
CXXTryStmt - A C++ try block, including all handlers.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
char __ovld __cnfn min(char x, char y)
Returns y if y < x, otherwise it returns x.
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.
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...
const CodeGenOptions & getCodeGenOpts() const
void SourceRangeSkipped(SourceRange Range) override
Hook called when a source range is skipped.
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
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...
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
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()
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.
SourceLocation getLocStart() const LLVM_READONLY
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.