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"
27 using namespace clang;
28 using namespace CodeGen;
29 using namespace llvm::coverage;
32 SkippedRanges.push_back(Range);
38 class SourceMappingRegion {
50 : Count(Count), LocStart(LocStart), LocEnd(LocEnd) {}
52 const Counter &getCounter()
const {
return Count; }
54 void setCounter(Counter C) {
Count = C; }
56 bool hasStartLoc()
const {
return LocStart.hasValue(); }
61 assert(LocStart &&
"Region has no start location");
65 bool hasEndLoc()
const {
return LocEnd.hasValue(); }
70 assert(LocEnd &&
"Region has no end location");
77 class CoverageMappingBuilder {
85 llvm::SmallDenseMap<FileID, std::pair<unsigned, SourceLocation>, 8>
92 std::vector<SourceMappingRegion> SourceRegions;
96 : CVM(CVM), SM(SM), LangOpts(LangOpts) {}
136 Loc = getIncludeOrExpansionLoc(Loc);
156 return getPreciseTokenLocEnd(Loc);
165 FileIDMapping.clear();
167 llvm::SmallSet<FileID, 8> Visited;
169 for (
const auto &Region : SourceRegions) {
172 if (!Visited.insert(File).second)
181 Parent.
isValid(); Parent = getIncludeOrExpansionLoc(Parent))
183 FileLocs.push_back(std::make_pair(Loc, Depth));
185 std::stable_sort(FileLocs.begin(), FileLocs.end(), llvm::less_second());
187 for (
const auto &FL : FileLocs) {
194 FileIDMapping[
SM.
getFileID(Loc)] = std::make_pair(Mapping.size(), Loc);
195 Mapping.push_back(CVM.getFileID(Entry));
203 auto Mapping = FileIDMapping.find(
SM.
getFileID(Loc));
204 if (Mapping != FileIDMapping.end())
205 return Mapping->second.first;
211 void gatherSkippedRegions() {
215 FileLineRanges.resize(
216 FileIDMapping.size(),
218 for (
const auto &R : MappingRegions) {
219 FileLineRanges[R.FileID].first =
220 std::min(FileLineRanges[R.FileID].first, R.LineStart);
221 FileLineRanges[R.FileID].second =
222 std::max(FileLineRanges[R.FileID].second, R.LineEnd);
225 auto SkippedRanges = CVM.getSourceInfo().getSkippedRanges();
226 for (
const auto &
I : SkippedRanges) {
227 auto LocStart =
I.getBegin();
228 auto LocEnd =
I.getEnd();
230 "region spans multiple files");
232 auto CovFileID = getCoverageFileID(LocStart);
239 auto Region = CounterMappingRegion::makeSkipped(
240 *CovFileID, LineStart, ColumnStart, LineEnd, ColumnEnd);
243 if (Region.LineStart >= FileLineRanges[*CovFileID].first &&
244 Region.LineEnd <= FileLineRanges[*CovFileID].second)
245 MappingRegions.push_back(Region);
251 void emitSourceRegions() {
252 for (
const auto &Region : SourceRegions) {
253 assert(Region.hasEndLoc() &&
"incomplete region");
262 auto CovFileID = getCoverageFileID(LocStart);
269 "region spans multiple files");
277 assert(LineStart <= LineEnd &&
"region start and end out of order");
278 MappingRegions.push_back(CounterMappingRegion::makeRegion(
279 Region.getCounter(), *CovFileID, LineStart, ColumnStart, LineEnd,
285 void emitExpansionRegions() {
286 for (
const auto &FM : FileIDMapping) {
292 auto ParentFileID = getCoverageFileID(ParentLoc);
295 auto ExpandedFileID = getCoverageFileID(ExpandedLoc);
296 assert(ExpandedFileID &&
"expansion in uncovered file");
300 "region spans multiple files");
307 MappingRegions.push_back(CounterMappingRegion::makeExpansion(
308 *ParentFileID, *ExpandedFileID, LineStart, ColumnStart, LineEnd,
316 struct EmptyCoverageMappingBuilder :
public CoverageMappingBuilder {
319 : CoverageMappingBuilder(CVM, SM, LangOpts) {}
321 void VisitDecl(
const Decl *D) {
324 auto Body = D->getBody();
332 while (StartFileID != EndFileID && !isNestedIn(End, StartFileID)) {
333 Start = getIncludeOrExpansionLoc(Start);
335 "Declaration start location not nested within a known region");
338 while (StartFileID != EndFileID) {
339 End = getPreciseTokenLocEnd(getIncludeOrExpansionLoc(End));
341 "Declaration end location not nested within a known region");
345 SourceRegions.emplace_back(Counter(), Start, End);
349 void write(llvm::raw_ostream &OS) {
351 gatherFileIDs(FileIDMapping);
354 if (MappingRegions.empty())
357 CoverageMappingWriter Writer(FileIDMapping, None, MappingRegions);
364 struct CounterCoverageMappingBuilder
365 :
public CoverageMappingBuilder,
368 llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
371 std::vector<SourceMappingRegion> RegionStack;
373 CounterExpressionBuilder
Builder;
382 Counter subtractCounters(Counter LHS, Counter RHS) {
383 return Builder.subtract(LHS, RHS);
387 Counter addCounters(Counter LHS, Counter RHS) {
391 Counter addCounters(Counter C1, Counter C2, Counter C3) {
392 return addCounters(addCounters(C1, C2), C3);
398 Counter getRegionCounter(
const Stmt *S) {
399 return Counter::getCounter(CounterMap[S]);
409 MostRecentLocation = *StartLoc;
410 RegionStack.emplace_back(Count, StartLoc, EndLoc);
412 return RegionStack.size() - 1;
419 void popRegions(
size_t ParentIndex) {
420 assert(RegionStack.size() >= ParentIndex &&
"parent not in stack");
421 while (RegionStack.size() > ParentIndex) {
422 SourceMappingRegion &Region = RegionStack.back();
423 if (Region.hasStartLoc()) {
427 : RegionStack[ParentIndex].getEndLoc();
434 SourceRegions.emplace_back(Region.getCounter(), NestedLoc, EndLoc);
436 EndLoc = getPreciseTokenLocEnd(getIncludeOrExpansionLoc(EndLoc));
438 llvm::report_fatal_error(
"File exit not handled before popRegions");
440 Region.setEndLoc(EndLoc);
442 MostRecentLocation = EndLoc;
445 if (StartLoc == getStartOfFileOrMacro(StartLoc) &&
446 EndLoc == getEndOfFileOrMacro(EndLoc))
447 MostRecentLocation = getIncludeOrExpansionLoc(EndLoc);
450 SourceRegions.push_back(Region);
452 RegionStack.pop_back();
457 SourceMappingRegion &getRegion() {
458 assert(!RegionStack.empty() &&
"statement has no region");
459 return RegionStack.back();
463 Counter propagateCounts(Counter TopCount,
const Stmt *S) {
464 size_t Index = pushRegion(TopCount, getStart(S), getEnd(S));
466 Counter ExitCount = getRegion().getCounter();
472 MostRecentLocation = getEnd(S);
480 return SourceRegions.rend() !=
481 std::find_if(SourceRegions.rbegin(), SourceRegions.rend(),
482 [&](
const SourceMappingRegion &Region) {
483 return Region.getStartLoc() == StartLoc &&
484 Region.getEndLoc() == EndLoc;
492 MostRecentLocation = EndLoc;
498 if (getRegion().hasEndLoc() &&
499 MostRecentLocation == getEndOfFileOrMacro(MostRecentLocation) &&
500 isRegionAlreadyAdded(getStartOfFileOrMacro(MostRecentLocation),
502 MostRecentLocation = getIncludeOrExpansionLoc(MostRecentLocation);
519 while (!isNestedIn(MostRecentLocation, ParentFile)) {
520 LCA = getIncludeOrExpansionLoc(LCA);
524 MostRecentLocation = NewLoc;
530 llvm::SmallSet<SourceLocation, 8> StartLocs;
532 for (SourceMappingRegion &
I : llvm::reverse(RegionStack)) {
533 if (!
I.hasStartLoc())
536 if (!isNestedIn(Loc, ParentFile)) {
537 ParentCounter =
I.getCounter();
545 if (StartLocs.insert(Loc).second)
546 SourceRegions.emplace_back(
I.getCounter(), Loc,
547 getEndOfFileOrMacro(Loc));
548 Loc = getIncludeOrExpansionLoc(Loc);
550 I.setStartLoc(getPreciseTokenLocEnd(Loc));
558 while (isNestedIn(Loc, ParentFile)) {
560 if (StartLocs.insert(FileStart).second)
561 SourceRegions.emplace_back(*ParentCounter, FileStart,
562 getEndOfFileOrMacro(Loc));
563 Loc = getIncludeOrExpansionLoc(Loc);
567 MostRecentLocation = NewLoc;
571 void extendRegion(
const Stmt *S) {
572 SourceMappingRegion &Region = getRegion();
575 handleFileExit(StartLoc);
576 if (!Region.hasStartLoc())
577 Region.setStartLoc(StartLoc);
581 void terminateRegion(
const Stmt *S) {
583 SourceMappingRegion &Region = getRegion();
584 if (!Region.hasEndLoc())
585 Region.setEndLoc(getEnd(S));
586 pushRegion(Counter::getZero());
590 struct BreakContinue {
592 Counter ContinueCount;
596 CounterCoverageMappingBuilder(
600 : CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap) {}
603 void write(llvm::raw_ostream &OS) {
605 gatherFileIDs(VirtualFileMapping);
607 emitExpansionRegions();
608 gatherSkippedRegions();
610 if (MappingRegions.empty())
613 CoverageMappingWriter Writer(VirtualFileMapping,
Builder.getExpressions(),
618 void VisitStmt(
const Stmt *S) {
619 if (S->getLocStart().isValid())
621 for (
const Stmt *Child : S->children())
624 handleFileExit(getEnd(S));
627 void VisitDecl(
const Decl *D) {
628 Stmt *Body = D->getBody();
634 propagateCounts(getRegionCounter(Body), Body);
651 void VisitGotoStmt(
const GotoStmt *S) { terminateRegion(S); }
653 void VisitLabelStmt(
const LabelStmt *S) {
656 handleFileExit(Start);
657 pushRegion(getRegionCounter(S), Start);
661 void VisitBreakStmt(
const BreakStmt *S) {
662 assert(!BreakContinueStack.empty() &&
"break not in a loop or switch!");
663 BreakContinueStack.back().BreakCount = addCounters(
664 BreakContinueStack.back().BreakCount, getRegion().getCounter());
669 assert(!BreakContinueStack.empty() &&
"continue stmt not in a loop!");
670 BreakContinueStack.back().ContinueCount = addCounters(
671 BreakContinueStack.back().ContinueCount, getRegion().getCounter());
675 void VisitWhileStmt(
const WhileStmt *S) {
678 Counter ParentCount = getRegion().getCounter();
679 Counter BodyCount = getRegionCounter(S);
682 BreakContinueStack.push_back(BreakContinue());
684 Counter BackedgeCount = propagateCounts(BodyCount, S->
getBody());
685 BreakContinue BC = BreakContinueStack.pop_back_val();
689 addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
690 propagateCounts(CondCount, S->
getCond());
691 adjustForOutOfOrderTraversal(getEnd(S));
694 addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
695 if (OutCount != ParentCount)
696 pushRegion(OutCount);
699 void VisitDoStmt(
const DoStmt *S) {
702 Counter ParentCount = getRegion().getCounter();
703 Counter BodyCount = getRegionCounter(S);
705 BreakContinueStack.push_back(BreakContinue());
707 Counter BackedgeCount =
708 propagateCounts(addCounters(ParentCount, BodyCount), S->
getBody());
709 BreakContinue BC = BreakContinueStack.pop_back_val();
711 Counter CondCount = addCounters(BackedgeCount, BC.ContinueCount);
712 propagateCounts(CondCount, S->
getCond());
715 addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
716 if (OutCount != ParentCount)
717 pushRegion(OutCount);
720 void VisitForStmt(
const ForStmt *S) {
725 Counter ParentCount = getRegion().getCounter();
726 Counter BodyCount = getRegionCounter(S);
729 BreakContinueStack.push_back(BreakContinue());
731 Counter BackedgeCount = propagateCounts(BodyCount, S->
getBody());
732 BreakContinue BC = BreakContinueStack.pop_back_val();
737 propagateCounts(addCounters(BackedgeCount, BC.ContinueCount), Inc);
741 addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
743 propagateCounts(CondCount, Cond);
744 adjustForOutOfOrderTraversal(getEnd(S));
748 addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
749 if (OutCount != ParentCount)
750 pushRegion(OutCount);
758 Counter ParentCount = getRegion().getCounter();
759 Counter BodyCount = getRegionCounter(S);
761 BreakContinueStack.push_back(BreakContinue());
763 Counter BackedgeCount = propagateCounts(BodyCount, S->
getBody());
764 BreakContinue BC = BreakContinueStack.pop_back_val();
767 addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
769 addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount));
770 if (OutCount != ParentCount)
771 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 BreakContinueStack.push_back(BreakContinue());
802 if (
const auto *CS = dyn_cast<CompoundStmt>(Body)) {
803 if (!CS->body_empty()) {
809 pushRegion(Counter::getZero(), getStart(CS->body_front()),
810 getEnd(CS->body_back()));
811 for (
const auto *Child : CS->children())
816 propagateCounts(Counter::getZero(), Body);
817 BreakContinue BC = BreakContinueStack.pop_back_val();
819 if (!BreakContinueStack.empty())
820 BreakContinueStack.back().ContinueCount = addCounters(
821 BreakContinueStack.back().ContinueCount, BC.ContinueCount);
823 Counter ExitCount = getRegionCounter(S);
825 pushRegion(ExitCount, getStart(S), ExitLoc);
826 handleFileExit(ExitLoc);
832 SourceMappingRegion &Parent = getRegion();
834 Counter Count = addCounters(Parent.getCounter(), getRegionCounter(S));
837 if (Parent.hasStartLoc() && Parent.getStartLoc() == getStart(S))
838 Parent.setCounter(Count);
840 pushRegion(Count, getStart(S));
842 if (
const auto *CS = dyn_cast<CaseStmt>(S)) {
844 if (
const Expr *RHS = CS->getRHS())
850 void VisitIfStmt(
const IfStmt *S) {
856 Counter ParentCount = getRegion().getCounter();
857 Counter ThenCount = getRegionCounter(S);
861 propagateCounts(ParentCount, S->
getCond());
864 Counter OutCount = propagateCounts(ThenCount, S->
getThen());
866 Counter ElseCount = subtractCounters(ParentCount, ThenCount);
869 OutCount = addCounters(OutCount, propagateCounts(ElseCount, Else));
871 OutCount = addCounters(OutCount, ElseCount);
873 if (OutCount != ParentCount)
874 pushRegion(OutCount);
882 Counter ParentCount = getRegion().getCounter();
888 Counter ExitCount = getRegionCounter(S);
889 pushRegion(ExitCount);
899 Counter ParentCount = getRegion().getCounter();
900 Counter TrueCount = getRegionCounter(E);
904 if (!isa<BinaryConditionalOperator>(E)) {
909 propagateCounts(subtractCounters(ParentCount, TrueCount),
917 extendRegion(E->
getRHS());
918 propagateCounts(getRegionCounter(E), E->
getRHS());
925 extendRegion(E->
getRHS());
926 propagateCounts(getRegionCounter(E), E->
getRHS());
941 return llvm::getInstrProfCoverageSectionName(
isMachO(CGM));
944 static void dump(llvm::raw_ostream &OS, StringRef FunctionName,
947 OS << FunctionName <<
":\n";
948 CounterMappingContext Ctx(Expressions);
949 for (
const auto &R : Regions) {
952 case CounterMappingRegion::CodeRegion:
954 case CounterMappingRegion::ExpansionRegion:
957 case CounterMappingRegion::SkippedRegion:
962 OS <<
"File " << R.FileID <<
", " << R.LineStart <<
":" << R.ColumnStart
963 <<
" -> " << R.LineEnd <<
":" << R.ColumnEnd <<
" = ";
964 Ctx.dump(R.Count, OS);
965 if (R.Kind == CounterMappingRegion::ExpansionRegion)
966 OS <<
" (Expanded file = " << R.ExpandedFileID <<
")";
972 llvm::GlobalVariable *NamePtr, StringRef NameValue, uint64_t FuncHash,
973 const std::string &CoverageMapping,
bool IsUsed) {
974 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
975 if (!FunctionRecordTy) {
976 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) LLVMType,
978 #include "llvm/ProfileData/InstrProfData.inc"
981 llvm::StructType::get(Ctx, makeArrayRef(FunctionRecordTypes),
985 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Init,
986 llvm::Constant *FunctionRecordVals[] = {
987 #include "llvm/ProfileData/InstrProfData.inc"
989 FunctionRecords.push_back(llvm::ConstantStruct::get(
990 FunctionRecordTy, makeArrayRef(FunctionRecordVals)));
992 FunctionNames.push_back(
993 llvm::ConstantExpr::getBitCast(NamePtr, llvm::Type::getInt8PtrTy(Ctx)));
994 CoverageMappings.push_back(CoverageMapping);
996 if (CGM.getCodeGenOpts().DumpCoverageMapping) {
1002 std::vector<StringRef> Filenames;
1003 std::vector<CounterExpression> Expressions;
1004 std::vector<CounterMappingRegion> Regions;
1006 FilenameRefs.resize(FileEntries.size());
1007 for (
const auto &Entry : FileEntries)
1008 FilenameRefs[Entry.second] = Entry.first->getName();
1009 RawCoverageMappingReader Reader(CoverageMapping, FilenameRefs, Filenames,
1010 Expressions, Regions);
1013 dump(llvm::outs(), NameValue, Expressions, Regions);
1018 if (FunctionRecords.empty())
1020 llvm::LLVMContext &Ctx = CGM.getLLVMContext();
1021 auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
1026 FilenameStrs.resize(FileEntries.size());
1027 FilenameRefs.resize(FileEntries.size());
1028 for (
const auto &Entry : FileEntries) {
1030 llvm::sys::fs::make_absolute(Path);
1032 auto I = Entry.second;
1033 FilenameStrs[
I] = std::string(Path.begin(), Path.end());
1034 FilenameRefs[
I] = FilenameStrs[
I];
1037 std::string FilenamesAndCoverageMappings;
1038 llvm::raw_string_ostream OS(FilenamesAndCoverageMappings);
1039 CoverageFilenamesSectionWriter(FilenameRefs).write(OS);
1040 std::string RawCoverageMappings =
1041 llvm::join(CoverageMappings.begin(), CoverageMappings.end(),
"");
1042 OS << RawCoverageMappings;
1043 size_t CoverageMappingSize = RawCoverageMappings.size();
1044 size_t FilenamesSize = OS.str().size() - CoverageMappingSize;
1047 if (
size_t Rem = OS.str().size() % 8) {
1048 CoverageMappingSize += 8 - Rem;
1049 for (
size_t I = 0, S = 8 - Rem;
I <
S; ++
I)
1052 auto *FilenamesAndMappingsVal =
1053 llvm::ConstantDataArray::getString(Ctx, OS.str(),
false);
1057 llvm::ArrayType::get(FunctionRecordTy, FunctionRecords.size());
1058 auto RecordsVal = llvm::ConstantArray::get(RecordsTy, FunctionRecords);
1061 #define COVMAP_HEADER(Type, LLVMType, Name, Init) LLVMType,
1062 #include "llvm/ProfileData/InstrProfData.inc"
1064 auto CovDataHeaderTy =
1065 llvm::StructType::get(Ctx, makeArrayRef(CovDataHeaderTypes));
1066 llvm::Constant *CovDataHeaderVals[] = {
1067 #define COVMAP_HEADER(Type, LLVMType, Name, Init) Init,
1068 #include "llvm/ProfileData/InstrProfData.inc"
1070 auto CovDataHeaderVal = llvm::ConstantStruct::get(
1071 CovDataHeaderTy, makeArrayRef(CovDataHeaderVals));
1074 llvm::Type *CovDataTypes[] = {CovDataHeaderTy, RecordsTy,
1075 FilenamesAndMappingsVal->getType()};
1076 auto CovDataTy = llvm::StructType::get(Ctx, makeArrayRef(CovDataTypes));
1077 llvm::Constant *TUDataVals[] = {CovDataHeaderVal, RecordsVal,
1078 FilenamesAndMappingsVal};
1080 llvm::ConstantStruct::get(CovDataTy, makeArrayRef(TUDataVals));
1081 auto CovData =
new llvm::GlobalVariable(
1083 CovDataVal, llvm::getCoverageMappingVarName());
1086 CovData->setAlignment(8);
1089 CGM.addUsedGlobal(CovData);
1091 if (!FunctionNames.empty()) {
1092 auto NamesArrTy = llvm::ArrayType::get(llvm::Type::getInt8PtrTy(Ctx),
1093 FunctionNames.size());
1094 auto NamesArrVal = llvm::ConstantArray::get(NamesArrTy, FunctionNames);
1097 new llvm::GlobalVariable(CGM.getModule(), NamesArrTy,
true,
1099 llvm::getCoverageUnusedNamesVarName());
1104 auto It = FileEntries.find(File);
1105 if (It != FileEntries.end())
1107 unsigned FileID = FileEntries.size();
1108 FileEntries.insert(std::make_pair(File,
FileID));
1113 llvm::raw_ostream &OS) {
1115 CounterCoverageMappingBuilder Walker(CVM, *CounterMap,
SM, LangOpts);
1116 Walker.VisitDecl(D);
1121 llvm::raw_ostream &OS) {
1122 EmptyCoverageMappingBuilder Walker(CVM,
SM, LangOpts);
1123 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
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.
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.
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.
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...
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.
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.
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
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...
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.
This class handles loading and caching of source files into memory.