[prev in list] [next in list] [prev in thread] [next in thread] 

List:       cfe-commits
Subject:    Re: r214752 - Add coverage mapping generation.
From:       Alex L <arphaman () gmail ! com>
Date:       2014-08-04 19:10:23
Message-ID: CAKS3GBsoN14hygVEEp0cLrEvyCfNx9=QAwQ0DLMXzdeYYxOYhA () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


I actually fixed it in r214757, now there are two :)
I will revert mine


2014-08-04 12:08 GMT-07:00 David Blaikie <dblaikie@gmail.com>:

> CMake build fixed in  r214758
> 
> On Mon, Aug 4, 2014 at 11:41 AM, Alex Lorenz <arphaman@gmail.com> wrote:
> > Author: arphaman
> > Date: Mon Aug  4 13:41:51 2014
> > New Revision: 214752
> > 
> > URL: http://llvm.org/viewvc/llvm-project?rev=214752&view=rev
> > Log:
> > Add coverage mapping generation.
> > 
> > This patch adds the '-fcoverage-mapping' option which
> > allows clang to generate the coverage mapping information
> > that can be used to provide code coverage analysis using
> > the execution counts obtained from the instrumentation
> > based profiling (-fprofile-instr-generate).
> > 
> > Added:
> > cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp
> > cfe/trunk/lib/CodeGen/CoverageMappingGen.h
> > Modified:
> > cfe/trunk/include/clang/CodeGen/CodeGenABITypes.h
> > cfe/trunk/include/clang/CodeGen/ModuleBuilder.h
> > cfe/trunk/include/clang/Driver/Options.td
> > cfe/trunk/include/clang/Frontend/CodeGenOptions.def
> > cfe/trunk/lib/CodeGen/CodeGenABITypes.cpp
> > cfe/trunk/lib/CodeGen/CodeGenAction.cpp
> > cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
> > cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> > cfe/trunk/lib/CodeGen/CodeGenModule.h
> > cfe/trunk/lib/CodeGen/CodeGenPGO.cpp
> > cfe/trunk/lib/CodeGen/CodeGenPGO.h
> > cfe/trunk/lib/CodeGen/ModuleBuilder.cpp
> > cfe/trunk/lib/Driver/Tools.cpp
> > cfe/trunk/lib/Frontend/CompilerInvocation.cpp
> > 
> > Modified: cfe/trunk/include/clang/CodeGen/CodeGenABITypes.h
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/CodeGenABITypes.h?rev=214752&r1=214751&r2=214752&view=diff
> 
> > 
> ==============================================================================
> > --- cfe/trunk/include/clang/CodeGen/CodeGenABITypes.h (original)
> > +++ cfe/trunk/include/clang/CodeGen/CodeGenABITypes.h Mon Aug  4
> 13:41:51 2014
> > @@ -39,6 +39,7 @@ class CXXRecordDecl;
> > class CodeGenOptions;
> > class DiagnosticsEngine;
> > class ObjCMethodDecl;
> > +class CoverageSourceInfo;
> > 
> > namespace CodeGen {
> > class CGFunctionInfo;
> > @@ -47,7 +48,8 @@ class CodeGenModule;
> > class CodeGenABITypes
> > {
> > public:
> > -  CodeGenABITypes(ASTContext &C, llvm::Module &M, const
> llvm::DataLayout &TD);
> > +  CodeGenABITypes(ASTContext &C, llvm::Module &M, const
> llvm::DataLayout &TD,
> > +                  CoverageSourceInfo *CoverageInfo = nullptr);
> > ~CodeGenABITypes();
> > 
> > /// These methods all forward to methods in the private
> implementation class
> > 
> > Modified: cfe/trunk/include/clang/CodeGen/ModuleBuilder.h
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/ModuleBuilder.h?rev=214752&r1=214751&r2=214752&view=diff
> 
> > 
> ==============================================================================
> > --- cfe/trunk/include/clang/CodeGen/ModuleBuilder.h (original)
> > +++ cfe/trunk/include/clang/CodeGen/ModuleBuilder.h Mon Aug  4 13:41:51
> 2014
> > @@ -24,6 +24,7 @@ namespace llvm {
> > 
> > namespace clang {
> > class DiagnosticsEngine;
> > +  class CoverageSourceInfo;
> > class LangOptions;
> > class CodeGenOptions;
> > class TargetOptions;
> > @@ -44,7 +45,8 @@ namespace clang {
> > const std::string &ModuleName,
> > const CodeGenOptions &CGO,
> > const TargetOptions &TO,
> > -                                   llvm::LLVMContext& C);
> > +                                   llvm::LLVMContext& C,
> > +                                   CoverageSourceInfo *CoverageInfo =
> nullptr);
> > }
> > 
> > #endif
> > 
> > Modified: cfe/trunk/include/clang/Driver/Options.td
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=214752&r1=214751&r2=214752&view=diff
> 
> > 
> ==============================================================================
> > --- cfe/trunk/include/clang/Driver/Options.td (original)
> > +++ cfe/trunk/include/clang/Driver/Options.td Mon Aug  4 13:41:51 2014
> > @@ -408,6 +408,9 @@ def fprofile_instr_use : Flag<["-"], "fp
> > def fprofile_instr_use_EQ : Joined<["-"], "fprofile-instr-use=">,
> > Group<f_Group>, Flags<[CC1Option]>,
> > HelpText<"Use instrumentation data for profile-guided
> optimization">;
> > +def fcoverage_mapping : Flag<["-"], "fcoverage-mapping">,
> > +    Group<f_Group>, Flags<[CC1Option]>,
> > +    HelpText<"Generate coverage mapping to enable code coverage
> analysis">;
> > 
> > def fblocks : Flag<["-"], "fblocks">, Group<f_Group>,
> Flags<[CC1Option]>,
> > HelpText<"Enable the 'blocks' language feature">;
> > 
> > Modified: cfe/trunk/include/clang/Frontend/CodeGenOptions.def
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenOptions.def?rev=214752&r1=214751&r2=214752&view=diff
> 
> > 
> ==============================================================================
> > --- cfe/trunk/include/clang/Frontend/CodeGenOptions.def (original)
> > +++ cfe/trunk/include/clang/Frontend/CodeGenOptions.def Mon Aug  4
> 13:41:51 2014
> > @@ -88,6 +88,8 @@ VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///
> > 
> > CODEGENOPT(ProfileInstrGenerate , 1, 0) ///< Instrument code to generate
> > ///< execution counts to use
> with PGO.
> > +CODEGENOPT(CoverageMapping , 1, 0) ///< Generate coverage mapping
> regions to
> > +                                   ///< enable code coverage analysis.
> > 
> > /// If -fpcc-struct-return or -freg-struct-return is specified.
> > ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2,
> SRCK_Default)
> > 
> > Modified: cfe/trunk/lib/CodeGen/CodeGenABITypes.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenABITypes.cpp?rev=214752&r1=214751&r2=214752&view=diff
> 
> > 
> ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CodeGenABITypes.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/CodeGenABITypes.cpp Mon Aug  4 13:41:51 2014
> > @@ -26,9 +26,11 @@ using namespace CodeGen;
> > 
> > CodeGenABITypes::CodeGenABITypes(ASTContext &C,
> > llvm::Module &M,
> > -                                 const llvm::DataLayout &TD)
> > +                                 const llvm::DataLayout &TD,
> > +                                 CoverageSourceInfo *CoverageInfo)
> > > CGO(new CodeGenOptions),
> > -    CGM(new CodeGen::CodeGenModule(C, *CGO, M, TD, C.getDiagnostics()))
> {
> > +    CGM(new CodeGen::CodeGenModule(C, *CGO, M, TD, C.getDiagnostics(),
> > +                                   CoverageInfo)) {
> > }
> > 
> > CodeGenABITypes::~CodeGenABITypes()
> > 
> > Modified: cfe/trunk/lib/CodeGen/CodeGenAction.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenAction.cpp?rev=214752&r1=214751&r2=214752&view=diff
> 
> > 
> ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CodeGenAction.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/CodeGenAction.cpp Mon Aug  4 13:41:51 2014
> > @@ -7,6 +7,7 @@
> > //
> > 
> //===----------------------------------------------------------------------===//
> > 
> > +#include "CoverageMappingGen.h"
> > #include "clang/CodeGen/CodeGenAction.h"
> > #include "clang/AST/ASTConsumer.h"
> > #include "clang/AST/ASTContext.h"
> > @@ -15,6 +16,7 @@
> > #include "clang/Basic/FileManager.h"
> > #include "clang/Basic/SourceManager.h"
> > #include "clang/Basic/TargetInfo.h"
> > +#include "clang/Lex/Preprocessor.h"
> > #include "clang/CodeGen/BackendUtil.h"
> > #include "clang/CodeGen/ModuleBuilder.h"
> > #include "clang/Frontend/CompilerInstance.h"
> > @@ -59,11 +61,13 @@ namespace clang {
> > const TargetOptions &targetopts,
> > const LangOptions &langopts, bool TimePasses,
> > const std::string &infile, llvm::Module *LinkModule,
> > -                    raw_ostream *OS, LLVMContext &C)
> > +                    raw_ostream *OS, LLVMContext &C,
> > +                    CoverageSourceInfo *CoverageInfo = nullptr)
> > > Diags(_Diags), Action(action), CodeGenOpts(compopts),
> > TargetOpts(targetopts), LangOpts(langopts), AsmOutStream(OS),
> > Context(), LLVMIRGeneration("LLVM IR Generation Time"),
> > -          Gen(CreateLLVMCodeGen(Diags, infile, compopts, targetopts,
> C)),
> > +          Gen(CreateLLVMCodeGen(Diags, infile, compopts,
> > +                                targetopts, C, CoverageInfo)),
> > LinkModule(LinkModule) {
> > llvm::TimePassesIsEnabled = TimePasses;
> > }
> > @@ -636,10 +640,17 @@ ASTConsumer *CodeGenAction::CreateASTCon
> > LinkModuleToUse = ModuleOrErr.get();
> > }
> > 
> > +  CoverageSourceInfo *CoverageInfo = nullptr;
> > +  // Add the preprocessor callback only when the coverage mapping is
> generated.
> > +  if (CI.getCodeGenOpts().CoverageMapping) {
> > +    CoverageInfo = new CoverageSourceInfo;
> > +    CI.getPreprocessor().addPPCallbacks(CoverageInfo);
> > +  }
> > BEConsumer = new BackendConsumer(BA, CI.getDiagnostics(),
> CI.getCodeGenOpts(),
> > CI.getTargetOpts(), CI.getLangOpts(),
> > CI.getFrontendOpts().ShowTimers,
> InFile,
> > -                                   LinkModuleToUse, OS.release(),
> *VMContext);
> > +                                   LinkModuleToUse, OS.release(),
> *VMContext,
> > +                                   CoverageInfo);
> > return BEConsumer;
> > }
> > 
> > 
> > Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=214752&r1=214751&r2=214752&view=diff
> 
> > 
> ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Mon Aug  4 13:41:51 2014
> > @@ -829,6 +829,7 @@ void CodeGenFunction::GenerateCode(Globa
> > StartFunction(GD, ResTy, Fn, FnInfo, Args, Loc, BodyRange.getBegin());
> > 
> > // Generate the body of the function.
> > +  PGO.checkGlobalDecl(GD);
> > PGO.assignRegionCounters(GD.getDecl(), CurFn);
> > if (isa<CXXDestructorDecl>(FD))
> > EmitDestructorBody(Args);
> > 
> > Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=214752&r1=214751&r2=214752&view=diff
> 
> > 
> ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon Aug  4 13:41:51 2014
> > @@ -21,6 +21,7 @@
> > #include "CGOpenMPRuntime.h"
> > #include "CodeGenFunction.h"
> > #include "CodeGenPGO.h"
> > +#include "CoverageMappingGen.h"
> > #include "CodeGenTBAA.h"
> > #include "TargetInfo.h"
> > #include "clang/AST/ASTContext.h"
> > @@ -74,7 +75,8 @@ static CGCXXABI *createCXXABI(CodeGenMod
> > 
> > CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
> > llvm::Module &M, const llvm::DataLayout
> &TD,
> > -                             DiagnosticsEngine &diags)
> > +                             DiagnosticsEngine &diags,
> > +                             CoverageSourceInfo *CoverageInfo)
> > > Context(C), LangOpts(C.getLangOpts()), CodeGenOpts(CGO),
> TheModule(M),
> > Diags(diags), TheDataLayout(TD), Target(C.getTargetInfo()),
> > ABI(createCXXABI(*this)), VMContext(M.getContext()),
> TBAA(nullptr),
> > @@ -146,6 +148,11 @@ CodeGenModule::CodeGenModule(ASTContext
> > getDiags().Report(DiagID) << EC.message();
> > }
> > }
> > +
> > +  // If coverage mapping generation is enabled, create the
> > +  // CoverageMappingModuleGen object.
> > +  if (CodeGenOpts.CoverageMapping)
> > +    CoverageMapping.reset(new CoverageMappingModuleGen(*this,
> *CoverageInfo));
> > }
> > 
> > CodeGenModule::~CodeGenModule() {
> > @@ -344,6 +351,9 @@ void CodeGenModule::Release() {
> > EmitCtorList(GlobalDtors, "llvm.global_dtors");
> > EmitGlobalAnnotations();
> > EmitStaticExternCAliases();
> > +  EmitDeferredUnusedCoverageMappings();
> > +  if (CoverageMapping)
> > +    CoverageMapping->emit();
> > emitLLVMUsed();
> > 
> > if (CodeGenOpts.Autolink &&
> > @@ -2989,6 +2999,9 @@ void CodeGenModule::EmitTopLevelDecl(Dec
> > return;
> > 
> > EmitGlobal(cast<FunctionDecl>(D));
> > +    // Always provide some coverage mapping
> > +    // even for the functions that aren't emitted.
> > +    AddDeferredUnusedCoverageMapping(D);
> > break;
> > 
> > case Decl::Var:
> > @@ -3138,6 +3151,80 @@ void CodeGenModule::EmitTopLevelDecl(Dec
> > }
> > }
> > 
> > +void CodeGenModule::AddDeferredUnusedCoverageMapping(Decl *D) {
> > +  // Do we need to generate coverage mapping?
> > +  if (!CodeGenOpts.CoverageMapping)
> > +    return;
> > +  switch (D->getKind()) {
> > +  case Decl::CXXConversion:
> > +  case Decl::CXXMethod:
> > +  case Decl::Function:
> > +  case Decl::ObjCMethod:
> > +  case Decl::CXXConstructor:
> > +  case Decl::CXXDestructor: {
> > +    if (!cast<FunctionDecl>(D)->hasBody())
> > +      return;
> > +    auto I = DeferredEmptyCoverageMappingDecls.find(D);
> > +    if (I == DeferredEmptyCoverageMappingDecls.end())
> > +      DeferredEmptyCoverageMappingDecls[D] = true;
> > +    break;
> > +  }
> > +  default:
> > +    break;
> > +  };
> > +}
> > +
> > +void CodeGenModule::ClearUnusedCoverageMapping(const Decl *D) {
> > +  // Do we need to generate coverage mapping?
> > +  if (!CodeGenOpts.CoverageMapping)
> > +    return;
> > +  if (const auto *Fn = dyn_cast<FunctionDecl>(D)) {
> > +    if (Fn->isTemplateInstantiation())
> > +      ClearUnusedCoverageMapping(Fn->getTemplateInstantiationPattern());
> > +  }
> > +  auto I = DeferredEmptyCoverageMappingDecls.find(D);
> > +  if (I == DeferredEmptyCoverageMappingDecls.end())
> > +    DeferredEmptyCoverageMappingDecls[D] = false;
> > +  else
> > +    I->second = false;
> > +}
> > +
> > +void CodeGenModule::EmitDeferredUnusedCoverageMappings() {
> > +  for (const auto I : DeferredEmptyCoverageMappingDecls) {
> > +    if (!I.second)
> > +      continue;
> > +    const auto *D = I.first;
> > +    switch (D->getKind()) {
> > +    case Decl::CXXConversion:
> > +    case Decl::CXXMethod:
> > +    case Decl::Function:
> > +    case Decl::ObjCMethod: {
> > +      CodeGenPGO PGO(*this);
> > +      GlobalDecl GD(cast<FunctionDecl>(D));
> > +      PGO.emitEmptyCounterMapping(D, getMangledName(GD),
> > +                                  getFunctionLinkage(GD));
> > +      break;
> > +    }
> > +    case Decl::CXXConstructor: {
> > +      CodeGenPGO PGO(*this);
> > +      GlobalDecl GD(cast<CXXConstructorDecl>(D), Ctor_Base);
> > +      PGO.emitEmptyCounterMapping(D, getMangledName(GD),
> > +                                  getFunctionLinkage(GD));
> > +      break;
> > +    }
> > +    case Decl::CXXDestructor: {
> > +      CodeGenPGO PGO(*this);
> > +      GlobalDecl GD(cast<CXXDestructorDecl>(D), Dtor_Base);
> > +      PGO.emitEmptyCounterMapping(D, getMangledName(GD),
> > +                                  getFunctionLinkage(GD));
> > +      break;
> > +    }
> > +    default:
> > +      break;
> > +    };
> > +  }
> > +}
> > +
> > /// Turns the given pointer into a constant.
> > static llvm::Constant *GetPointerConstant(llvm::LLVMContext &Context,
> > const void *Ptr) {
> > 
> > Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=214752&r1=214751&r2=214752&view=diff
> 
> > 
> ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
> > +++ cfe/trunk/lib/CodeGen/CodeGenModule.h Mon Aug  4 13:41:51 2014
> > @@ -73,6 +73,7 @@ class DiagnosticsEngine;
> > class AnnotateAttr;
> > class CXXDestructorDecl;
> > class Module;
> > +class CoverageSourceInfo;
> > 
> > namespace CodeGen {
> > 
> > @@ -87,6 +88,7 @@ class CGOpenMPRuntime;
> > class CGCUDARuntime;
> > class BlockFieldFlags;
> > class FunctionArgList;
> > +class CoverageMappingModuleGen;
> > 
> > struct OrderGlobalInits {
> > unsigned int priority;
> > @@ -477,10 +479,15 @@ class CodeGenModule : public CodeGenType
> > std::unique_ptr<SanitizerMetadata> SanitizerMD;
> > 
> > /// @}
> > +
> > +  llvm::DenseMap<const Decl *, bool> DeferredEmptyCoverageMappingDecls;
> > +
> > +  std::unique_ptr<CoverageMappingModuleGen> CoverageMapping;
> > public:
> > CodeGenModule(ASTContext &C, const CodeGenOptions &CodeGenOpts,
> > llvm::Module &M, const llvm::DataLayout &TD,
> > -                DiagnosticsEngine &Diags);
> > +                DiagnosticsEngine &Diags,
> > +                CoverageSourceInfo *CoverageInfo = nullptr);
> > 
> > ~CodeGenModule();
> > 
> > @@ -529,6 +536,10 @@ public:
> > InstrProfStats &getPGOStats() { return PGOStats; }
> > llvm::IndexedInstrProfReader *getPGOReader() const { return
> PGOReader.get(); }
> > 
> > +  CoverageMappingModuleGen *getCoverageMapping() const {
> > +    return CoverageMapping.get();
> > +  }
> > +
> > llvm::Constant *getStaticLocalDeclAddress(const VarDecl *D) {
> > return StaticLocalDeclMap[D];
> > }
> > @@ -815,6 +826,18 @@ public:
> > /// Emit code for a single top level declaration.
> > void EmitTopLevelDecl(Decl *D);
> > 
> > +  /// \brief Stored a deferred empty coverage mapping for an unused
> > +  /// and thus uninstrumented top level declaration.
> > +  void AddDeferredUnusedCoverageMapping(Decl *D);
> > +
> > +  /// \brief Remove the deferred empty coverage mapping as this
> > +  /// declaration is actually instrumented.
> > +  void ClearUnusedCoverageMapping(const Decl *D);
> > +
> > +  /// \brief Emit all the deferred coverage mappings
> > +  /// for the uninstrumented functions.
> > +  void EmitDeferredUnusedCoverageMappings();
> > +
> > /// Tell the consumer that this variable has been instantiated.
> > void HandleCXXStaticMemberVarInstantiation(VarDecl *VD);
> > 
> > 
> > Modified: cfe/trunk/lib/CodeGen/CodeGenPGO.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenPGO.cpp?rev=214752&r1=214751&r2=214752&view=diff
> 
> > 
> ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CodeGenPGO.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/CodeGenPGO.cpp Mon Aug  4 13:41:51 2014
> > @@ -13,6 +13,7 @@
> > 
> > #include "CodeGenPGO.h"
> > #include "CodeGenFunction.h"
> > +#include "CoverageMappingGen.h"
> > #include "clang/AST/RecursiveASTVisitor.h"
> > #include "clang/AST/StmtVisitor.h"
> > #include "llvm/IR/MDBuilder.h"
> > @@ -24,8 +25,9 @@
> > using namespace clang;
> > using namespace CodeGen;
> > 
> > -void CodeGenPGO::setFuncName(llvm::Function *Fn) {
> > -  RawFuncName = Fn->getName();
> > +void CodeGenPGO::setFuncName(StringRef Name,
> > +                             llvm::GlobalValue::LinkageTypes Linkage) {
> > +  RawFuncName = Name;
> > 
> > // Function names may be prefixed with a binary '1' to indicate
> > // that the backend should not modify the symbols due to any platform
> > @@ -33,7 +35,7 @@ void CodeGenPGO::setFuncName(llvm::Funct
> > if (RawFuncName[0] == '\1')
> > RawFuncName = RawFuncName.substr(1);
> > 
> > -  if (!Fn->hasLocalLinkage()) {
> > +  if (!llvm::GlobalValue::isLocalLinkage(Linkage)) {
> > PrefixedFuncName.reset(new std::string(RawFuncName));
> > return;
> > }
> > @@ -49,6 +51,27 @@ void CodeGenPGO::setFuncName(llvm::Funct
> > PrefixedFuncName->append(RawFuncName);
> > }
> > 
> > +void CodeGenPGO::setFuncName(llvm::Function *Fn) {
> > +  setFuncName(Fn->getName(), Fn->getLinkage());
> > +}
> > +
> > +void CodeGenPGO::setVarLinkage(llvm::GlobalValue::LinkageTypes Linkage)
> {
> > +  // Set the linkage for variables based on the function linkage.
> Usually, we
> > +  // want to match it, but available_externally and extern_weak both
> have the
> > +  // wrong semantics.
> > +  VarLinkage = Linkage;
> > +  switch (VarLinkage) {
> > +  case llvm::GlobalValue::ExternalWeakLinkage:
> > +    VarLinkage = llvm::GlobalValue::LinkOnceAnyLinkage;
> > +    break;
> > +  case llvm::GlobalValue::AvailableExternallyLinkage:
> > +    VarLinkage = llvm::GlobalValue::LinkOnceODRLinkage;
> > +    break;
> > +  default:
> > +    break;
> > +  }
> > +}
> > +
> > static llvm::Function *getRegisterFunc(CodeGenModule &CGM) {
> > return
> CGM.getModule().getFunction("__llvm_profile_register_functions");
> > }
> > @@ -120,37 +143,48 @@ llvm::GlobalVariable *CodeGenPGO::buildD
> > auto *Int64Ty = llvm::Type::getInt64Ty(Ctx);
> > auto *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx);
> > auto *Int64PtrTy = llvm::Type::getInt64PtrTy(Ctx);
> > -  llvm::Type *DataTypes[] = {
> > -    Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int64PtrTy
> > -  };
> > -  auto *DataTy = llvm::StructType::get(Ctx, makeArrayRef(DataTypes));
> > -  llvm::Constant *DataVals[] = {
> > -    llvm::ConstantInt::get(Int32Ty, getFuncName().size()),
> > -    llvm::ConstantInt::get(Int32Ty, NumRegionCounters),
> > -    llvm::ConstantInt::get(Int64Ty, FunctionHash),
> > -    llvm::ConstantExpr::getBitCast(Name, Int8PtrTy),
> > -    llvm::ConstantExpr::getBitCast(RegionCounters, Int64PtrTy)
> > -  };
> > -  auto *Data =
> > -    new llvm::GlobalVariable(CGM.getModule(), DataTy, true, VarLinkage,
> > -                             llvm::ConstantStruct::get(DataTy,
> DataVals),
> > -                             getFuncVarName("data"));
> > -
> > -  // All the data should be packed into an array in its own section.
> > -  Data->setSection(getDataSection(CGM));
> > -  Data->setAlignment(8);
> > +  llvm::GlobalVariable *Data = nullptr;
> > +  if (RegionCounters) {
> > +    llvm::Type *DataTypes[] = {
> > +      Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int64PtrTy
> > +    };
> > +    auto *DataTy = llvm::StructType::get(Ctx, makeArrayRef(DataTypes));
> > +    llvm::Constant *DataVals[] = {
> > +      llvm::ConstantInt::get(Int32Ty, getFuncName().size()),
> > +      llvm::ConstantInt::get(Int32Ty, NumRegionCounters),
> > +      llvm::ConstantInt::get(Int64Ty, FunctionHash),
> > +      llvm::ConstantExpr::getBitCast(Name, Int8PtrTy),
> > +      llvm::ConstantExpr::getBitCast(RegionCounters, Int64PtrTy)
> > +    };
> > +    Data =
> > +      new llvm::GlobalVariable(CGM.getModule(), DataTy, true,
> VarLinkage,
> > +                               llvm::ConstantStruct::get(DataTy,
> DataVals),
> > +                               getFuncVarName("data"));
> > +
> > +    // All the data should be packed into an array in its own section.
> > +    Data->setSection(getDataSection(CGM));
> > +    Data->setAlignment(8);
> > +  }
> > +
> > +  // Create coverage mapping data variable.
> > +  if (!CoverageMapping.empty())
> > +    CGM.getCoverageMapping()->addFunctionMappingRecord(Name,
> > +
> getFuncName().size(),
> > +                                                       CoverageMapping);
> > 
> > // Hide all these symbols so that we correctly get a copy for each
> > // executable.  The profile format expects names and counters to be
> > // contiguous, so references into shared objects would be invalid.
> > if (!llvm::GlobalValue::isLocalLinkage(VarLinkage)) {
> > Name->setVisibility(llvm::GlobalValue::HiddenVisibility);
> > -    Data->setVisibility(llvm::GlobalValue::HiddenVisibility);
> > -    RegionCounters->setVisibility(llvm::GlobalValue::HiddenVisibility);
> > +    if (Data) {
> > +      Data->setVisibility(llvm::GlobalValue::HiddenVisibility);
> > +
> RegionCounters->setVisibility(llvm::GlobalValue::HiddenVisibility);
> > +    }
> > }
> > 
> > // Make sure the data doesn't get deleted.
> > -  CGM.addUsedGlobal(Data);
> > +  if (Data) CGM.addUsedGlobal(Data);
> > return Data;
> > }
> > 
> > @@ -807,6 +841,20 @@ static void emitRuntimeHook(CodeGenModul
> > CGM.addUsedGlobal(User);
> > }
> > 
> > +void CodeGenPGO::checkGlobalDecl(GlobalDecl GD) {
> > +  // Make sure we only emit coverage mapping for one
> constructor/destructor.
> > +  // Clang emits several functions for the constructor and the
> destructor of
> > +  // a class. Every function is instrumented, but we only want to
> provide
> > +  // coverage for one of them. Because of that we only emit the
> coverage mapping
> > +  // for the base constructor/destructor.
> > +  if ((isa<CXXConstructorDecl>(GD.getDecl()) &&
> > +       GD.getCtorType() != Ctor_Base) ||
> > +      (isa<CXXDestructorDecl>(GD.getDecl()) &&
> > +       GD.getDtorType() != Dtor_Base)) {
> > +    SkipCoverageMapping = true;
> > +  }
> > +}
> > +
> > void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function
> *Fn) {
> > bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate;
> > llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
> > @@ -814,27 +862,16 @@ void CodeGenPGO::assignRegionCounters(co
> > return;
> > if (D->isImplicit())
> > return;
> > +  CGM.ClearUnusedCoverageMapping(D);
> > setFuncName(Fn);
> > -
> > -  // Set the linkage for variables based on the function linkage.
> Usually, we
> > -  // want to match it, but available_externally and extern_weak both
> have the
> > -  // wrong semantics.
> > -  VarLinkage = Fn->getLinkage();
> > -  switch (VarLinkage) {
> > -  case llvm::GlobalValue::ExternalWeakLinkage:
> > -    VarLinkage = llvm::GlobalValue::LinkOnceAnyLinkage;
> > -    break;
> > -  case llvm::GlobalValue::AvailableExternallyLinkage:
> > -    VarLinkage = llvm::GlobalValue::LinkOnceODRLinkage;
> > -    break;
> > -  default:
> > -    break;
> > -  }
> > +  setVarLinkage(Fn->getLinkage());
> > 
> > mapRegionCounters(D);
> > if (InstrumentRegions) {
> > emitRuntimeHook(CGM);
> > emitCounterVariables();
> > +    if (CGM.getCodeGenOpts().CoverageMapping)
> > +      emitCounterRegionMapping(D);
> > }
> > if (PGOReader) {
> > SourceManager &SM = CGM.getContext().getSourceManager();
> > @@ -860,6 +897,45 @@ void CodeGenPGO::mapRegionCounters(const
> > FunctionHash = Walker.Hash.finalize();
> > }
> > 
> > +void CodeGenPGO::emitCounterRegionMapping(const Decl *D) {
> > +  if (SkipCoverageMapping)
> > +    return;
> > +  // Don't map the functions inside the system headers
> > +  auto Loc = D->getBody()->getLocStart();
> > +  if (CGM.getContext().getSourceManager().isInSystemHeader(Loc))
> > +    return;
> > +
> > +  llvm::raw_string_ostream OS(CoverageMapping);
> > +  CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
> > +                                CGM.getContext().getSourceManager(),
> > +                                CGM.getLangOpts(),
> RegionCounterMap.get(),
> > +                                NumRegionCounters);
> > +  MappingGen.emitCounterMapping(D, OS);
> > +  OS.flush();
> > +}
> > +
> > +void
> > +CodeGenPGO::emitEmptyCounterMapping(const Decl *D, StringRef FuncName,
> > +                                    llvm::GlobalValue::LinkageTypes
> Linkage) {
> > +  if (SkipCoverageMapping)
> > +    return;
> > +  setFuncName(FuncName, Linkage);
> > +  setVarLinkage(Linkage);
> > +
> > +  // Don't map the functions inside the system headers
> > +  auto Loc = D->getBody()->getLocStart();
> > +  if (CGM.getContext().getSourceManager().isInSystemHeader(Loc))
> > +    return;
> > +
> > +  llvm::raw_string_ostream OS(CoverageMapping);
> > +  CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),
> > +                                CGM.getContext().getSourceManager(),
> > +                                CGM.getLangOpts());
> > +  MappingGen.emitEmptyMapping(D, OS);
> > +  OS.flush();
> > +  buildDataVar();
> > +}
> > +
> > void CodeGenPGO::computeRegionCounts(const Decl *D) {
> > StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>);
> > ComputeRegionCounts Walker(*StmtCountMap, *this);
> > 
> > Modified: cfe/trunk/lib/CodeGen/CodeGenPGO.h
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenPGO.h?rev=214752&r1=214751&r2=214752&view=diff
> 
> > 
> ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CodeGenPGO.h (original)
> > +++ cfe/trunk/lib/CodeGen/CodeGenPGO.h Mon Aug  4 13:41:51 2014
> > @@ -42,11 +42,16 @@ private:
> > std::unique_ptr<llvm::DenseMap<const Stmt *, uint64_t>> StmtCountMap;
> > std::unique_ptr<std::vector<uint64_t>> RegionCounts;
> > uint64_t CurrentRegionCount;
> > +  std::string CoverageMapping;
> > +  /// \brief A flag that is set to true when this function doesn't need
> > +  /// to have coverage mapping data.
> > +  bool SkipCoverageMapping;
> > 
> > public:
> > CodeGenPGO(CodeGenModule &CGM)
> > > CGM(CGM), NumRegionCounters(0), FunctionHash(0),
> > -        RegionCounters(nullptr), CurrentRegionCount(0) {}
> > +        RegionCounters(nullptr), CurrentRegionCount(0),
> > +        SkipCoverageMapping(false) {}
> > 
> > /// Whether or not we have PGO region data for the current function.
> This is
> > /// false both when we have no data at all and when our data has been
> > @@ -99,6 +104,8 @@ public:
> > llvm::MDNode *createBranchWeights(ArrayRef<uint64_t> Weights);
> > llvm::MDNode *createLoopWeights(const Stmt *Cond, RegionCounter &Cnt);
> > 
> > +  /// Check if we need to emit coverage mapping for a given declaration
> > +  void checkGlobalDecl(GlobalDecl GD);
> > /// Assign counters to regions and configure them for PGO of a given
> > /// function. Does nothing if instrumentation is not enabled and
> either
> > /// generates global variables or associates PGO data with each of the
> > @@ -111,9 +118,14 @@ public:
> > void destroyRegionCounters();
> > /// Emit static initialization code, if any.
> > static llvm::Function *emitInitialization(CodeGenModule &CGM);
> > -
> > +  /// Emit a coverage mapping range with a counter zero
> > +  /// for an unused declaration.
> > +  void emitEmptyCounterMapping(const Decl *D, StringRef FuncName,
> > +                               llvm::GlobalValue::LinkageTypes Linkage);
> > private:
> > void setFuncName(llvm::Function *Fn);
> > +  void setFuncName(StringRef Name, llvm::GlobalValue::LinkageTypes
> Linkage);
> > +  void setVarLinkage(llvm::GlobalValue::LinkageTypes Linkage);
> > void mapRegionCounters(const Decl *D);
> > void computeRegionCounts(const Decl *D);
> > void applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
> > @@ -122,6 +134,7 @@ private:
> > bool IsInMainFile);
> > void emitCounterVariables();
> > llvm::GlobalVariable *buildDataVar();
> > +  void emitCounterRegionMapping(const Decl *D);
> > 
> > /// Emit code to increment the counter at the given index
> > void emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter);
> > 
> > Added: cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp?rev=214752&view=auto
> 
> > 
> ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp (added)
> > +++ cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp Mon Aug  4 13:41:51 2014
> > @@ -0,0 +1,1166 @@
> > +//===--- CoverageMappingGen.cpp - Coverage mapping generation ---*- C++
> -*-===//
> > +//
> > +//                     The LLVM Compiler Infrastructure
> > +//
> > +// This file is distributed under the University of Illinois Open Source
> > +// License. See LICENSE.TXT for details.
> > +//
> > 
> +//===----------------------------------------------------------------------===//
> > +//
> > +// Instrumentation-based code coverage mapping generator
> > +//
> > 
> +//===----------------------------------------------------------------------===//
> > +
> > +#include "CoverageMappingGen.h"
> > +#include "CodeGenFunction.h"
> > +#include "clang/AST/StmtVisitor.h"
> > +#include "clang/Lex/Lexer.h"
> > +#include "llvm/ProfileData/InstrProfReader.h"
> > +#include "llvm/ProfileData/CoverageMapping.h"
> > +#include "llvm/ProfileData/CoverageMappingWriter.h"
> > +#include "llvm/Support/FileSystem.h"
> > +
> > +using namespace clang;
> > +using namespace CodeGen;
> > +using namespace llvm::coverage;
> > +
> > +void CoverageSourceInfo::SourceRangeSkipped(SourceRange Range) {
> > +  SkippedRanges.push_back(Range);
> > +}
> > +
> > +namespace {
> > +
> > +/// \brief A region of source code that can be mapped to a counter.
> > +struct SourceMappingRegion {
> > +  enum RegionFlags {
> > +    /// \brief This region won't be emitted if it wasn't extended.
> > +    /// This is useful so that we won't emit source ranges for single
> tokens
> > +    /// that we don't really care that much about, like:
> > +    ///   the '(' token in #define MACRO (
> > +    IgnoreIfNotExtended = 0x0001,
> > +  };
> > +
> > +  FileID File, MacroArgumentFile;
> > +
> > +  Counter Count;
> > +
> > +  /// \brief A statement that initiated the count of Zero.
> > +  ///
> > +  /// This initiator statement is useful to prevent merging of
> unreachable
> > +  /// regions with different statements that caused the counter to
> become
> > +  /// unreachable.
> > +  const Stmt *UnreachableInitiator;
> > +
> > +  /// \brief A statement that separates certain mapping regions into
> groups.
> > +  ///
> > +  /// The group statement is sometimes useful when we are emitting the
> source
> > +  /// regions not in their correct lexical order, e.g. the regions for
> the
> > +  /// incrementation expression in the 'for' construct. By marking the
> regions
> > +  /// in the incrementation expression with the group statement, we
> avoid the
> > +  /// merging of the regions from the incrementation expression and the
> loop's
> > +  /// body.
> > +  const Stmt *Group;
> > +
> > +  /// \brief The region's starting location.
> > +  SourceLocation LocStart;
> > +
> > +  /// \brief The region's ending location.
> > +  SourceLocation LocEnd, AlternativeLocEnd;
> > +  unsigned Flags;
> > +  CounterMappingRegion::RegionKind Kind;
> > +
> > +  SourceMappingRegion(FileID File, FileID MacroArgumentFile, Counter
> Count,
> > +                      const Stmt *UnreachableInitiator, const Stmt
> *Group,
> > +                      SourceLocation LocStart, SourceLocation LocEnd,
> > +                      unsigned Flags = 0,
> > +                      CounterMappingRegion::RegionKind Kind =
> > +                          CounterMappingRegion::CodeRegion)
> > +      : File(File), MacroArgumentFile(MacroArgumentFile), Count(Count),
> > +        UnreachableInitiator(UnreachableInitiator), Group(Group),
> > +        LocStart(LocStart), LocEnd(LocEnd), AlternativeLocEnd(LocStart),
> > +        Flags(Flags), Kind(Kind) {}
> > +
> > +  bool hasFlag(RegionFlags Flag) const { return (Flags & Flag) != 0; }
> > +
> > +  void setFlag(RegionFlags Flag) { Flags |= Flag; }
> > +
> > +  void clearFlag(RegionFlags Flag) { Flags &= ~Flag; }
> > +
> > +  /// \brief Return true if two regions can be merged together.
> > +  bool isMergeable(SourceMappingRegion &R) {
> > +    return File == R.File && MacroArgumentFile == R.MacroArgumentFile &&
> > +           Count == R.Count && UnreachableInitiator ==
> R.UnreachableInitiator &&
> > +           Group == R.Group && Kind == R.Kind;
> > +  }
> > +
> > +  /// \brief Merge two regions by extending the 'this' region to cover
> the
> > +  /// given region.
> > +  void mergeByExtendingTo(SourceMappingRegion &R) {
> > +    LocEnd = R.LocEnd;
> > +    AlternativeLocEnd = R.LocStart;
> > +    if (hasFlag(IgnoreIfNotExtended))
> > +      clearFlag(IgnoreIfNotExtended);
> > +  }
> > +};
> > +
> > +/// \brief The state of the coverage mapping builder.
> > +struct SourceMappingState {
> > +  Counter CurrentRegionCount;
> > +  const Stmt *CurrentSourceGroup;
> > +  const Stmt *CurrentUnreachableRegionInitiator;
> > +
> > +  SourceMappingState(Counter CurrentRegionCount, const Stmt
> *CurrentSourceGroup,
> > +                     const Stmt *CurrentUnreachableRegionInitiator)
> > +      : CurrentRegionCount(CurrentRegionCount),
> > +        CurrentSourceGroup(CurrentSourceGroup),
> > +
> CurrentUnreachableRegionInitiator(CurrentUnreachableRegionInitiator) {}
> > +};
> > +
> > +/// \brief Provides the common functionality for the different
> > +/// coverage mapping region builders.
> > +class CoverageMappingBuilder {
> > +public:
> > +  CoverageMappingModuleGen &CVM;
> > +  SourceManager &SM;
> > +  const LangOptions &LangOpts;
> > +
> > +private:
> > +  struct FileInfo {
> > +    /// \brief The file id that will be used by the coverage mapping
> system.
> > +    unsigned CovMappingFileID;
> > +    const FileEntry *Entry;
> > +
> > +    FileInfo(unsigned CovMappingFileID, const FileEntry *Entry)
> > +        : CovMappingFileID(CovMappingFileID), Entry(Entry) {}
> > +  };
> > +
> > +  /// \brief This mapping maps clang's FileIDs to file ids used
> > +  /// by the coverage mapping system and clang's file entries.
> > +  llvm::SmallDenseMap<FileID, FileInfo, 8> FileIDMapping;
> > +
> > +public:
> > +  /// \brief The statement that corresponds to the current source group.
> > +  const Stmt *CurrentSourceGroup;
> > +
> > +  /// \brief The statement the initiated the current unreachable region.
> > +  const Stmt *CurrentUnreachableRegionInitiator;
> > +
> > +  /// \brief The coverage mapping regions for this function
> > +  llvm::SmallVector<CounterMappingRegion, 32> MappingRegions;
> > +  /// \brief The source mapping regions for this function.
> > +  llvm::SmallVector<SourceMappingRegion, 32> SourceRegions;
> > +
> > +  CoverageMappingBuilder(CoverageMappingModuleGen &CVM, SourceManager
> &SM,
> > +                         const LangOptions &LangOpts)
> > +      : CVM(CVM), SM(SM), LangOpts(LangOpts),
> > +        CurrentSourceGroup(nullptr),
> > +        CurrentUnreachableRegionInitiator(nullptr) {}
> > +
> > +  /// \brief Return the precise end location for the given token.
> > +  SourceLocation getPreciseTokenLocEnd(SourceLocation Loc) {
> > +    return Lexer::getLocForEndOfToken(SM.getSpellingLoc(Loc), 0, SM,
> LangOpts);
> > +  }
> > +
> > +  /// \brief Create the mapping that maps from the function's file ids
> to
> > +  /// the indices for the translation unit's filenames.
> > +  void createFileIDMapping(SmallVectorImpl<unsigned> &Mapping) {
> > +    Mapping.resize(FileIDMapping.size(), 0);
> > +    for (const auto &I : FileIDMapping)
> > +      Mapping[I.second.CovMappingFileID] =
> CVM.getFileID(I.second.Entry);
> > +  }
> > +
> > +  /// \brief Get the coverage mapping file id that corresponds to the
> given
> > +  /// clang file id. If such file id doesn't exist, it gets added to the
> > +  /// mapping that maps from clang's file ids to coverage mapping file
> ids.
> > +  /// Return true if there was an error getting the coverage mapping
> file id.
> > +  /// An example of an when this function fails is when the region tries
> > +  /// to get a coverage file id for a location in a built-in macro.
> > +  bool getCoverageFileID(SourceLocation LocStart, FileID File,
> > +                         FileID SpellingFile, unsigned &Result) {
> > +    auto Mapping = FileIDMapping.find(File);
> > +    if (Mapping != FileIDMapping.end()) {
> > +      Result = Mapping->second.CovMappingFileID;
> > +      return false;
> > +    }
> > +
> > +    auto Entry = SM.getFileEntryForID(SpellingFile);
> > +    if (!Entry)
> > +      return true;
> > +
> > +    Result = FileIDMapping.size();
> > +    FileIDMapping.insert(std::make_pair(File, FileInfo(Result, Entry)));
> > +    createFileExpansionRegion(LocStart, File);
> > +    return false;
> > +  }
> > +
> > +  /// \brief Get the coverage mapping file id that corresponds to the
> given
> > +  /// clang file id.
> > +  /// Return true if there was an error getting the coverage mapping
> file id.
> > +  bool getExistingCoverageFileID(FileID File, unsigned &Result) {
> > +    // Make sure that the file is valid.
> > +    if (File.isInvalid())
> > +      return true;
> > +    auto Mapping = FileIDMapping.find(File);
> > +    if (Mapping != FileIDMapping.end()) {
> > +      Result = Mapping->second.CovMappingFileID;
> > +      return false;
> > +    }
> > +    return true;
> > +  }
> > +
> > +  /// \brief Return true if the given clang's file id has a
> corresponding
> > +  /// coverage file id.
> > +  bool hasExistingCoverageFileID(FileID File) const {
> > +    return FileIDMapping.count(File);
> > +  }
> > +
> > +  /// \brief Gather all the regions that were skipped by the
> preprocessor
> > +  /// using the constructs like #if.
> > +  void gatherSkippedRegions() {
> > +    /// An array of the minimum lineStarts and the maximum lineEnds
> > +    /// for mapping regions from the appropriate source files.
> > +    llvm::SmallVector<std::pair<unsigned, unsigned>, 8> FileLineRanges;
> > +    FileLineRanges.resize(
> > +        FileIDMapping.size(),
> > +        std::make_pair(std::numeric_limits<unsigned>::max(), 0));
> > +    for (const auto &R : MappingRegions) {
> > +      FileLineRanges[R.FileID].first =
> > +          std::min(FileLineRanges[R.FileID].first, R.LineStart);
> > +      FileLineRanges[R.FileID].second =
> > +          std::max(FileLineRanges[R.FileID].second, R.LineEnd);
> > +    }
> > +
> > +    auto SkippedRanges = CVM.getSourceInfo().getSkippedRanges();
> > +    for (const auto &I : SkippedRanges) {
> > +      auto LocStart = I.getBegin();
> > +      auto LocEnd = I.getEnd();
> > +      auto FileStart = SM.getFileID(LocStart);
> > +      if (!hasExistingCoverageFileID(FileStart))
> > +        continue;
> > +      auto ActualFileStart =
> SM.getDecomposedSpellingLoc(LocStart).first;
> > +      if (ActualFileStart != SM.getDecomposedSpellingLoc(LocEnd).first)
> > +        // Ignore regions that span across multiple files.
> > +        continue;
> > +
> > +      unsigned CovFileID;
> > +      if (getCoverageFileID(LocStart, FileStart, ActualFileStart,
> CovFileID))
> > +        continue;
> > +      unsigned LineStart = SM.getSpellingLineNumber(LocStart);
> > +      unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart);
> > +      unsigned LineEnd = SM.getSpellingLineNumber(LocEnd);
> > +      unsigned ColumnEnd = SM.getSpellingColumnNumber(LocEnd);
> > +      CounterMappingRegion Region(Counter(), CovFileID, LineStart,
> ColumnStart,
> > +                                  LineEnd, ColumnEnd, false,
> > +                                  CounterMappingRegion::SkippedRegion);
> > +      // Make sure that we only collect the regions that are inside
> > +      // the souce code of this function.
> > +      if (Region.LineStart >= FileLineRanges[CovFileID].first &&
> > +          Region.LineEnd <= FileLineRanges[CovFileID].second)
> > +        MappingRegions.push_back(Region);
> > +    }
> > +  }
> > +
> > +  /// \brief Create a mapping region that correponds to an expansion of
> > +  /// a macro or an embedded include.
> > +  void createFileExpansionRegion(SourceLocation Loc, FileID
> ExpandedFile) {
> > +    SourceLocation LocStart;
> > +    if (Loc.isMacroID())
> > +      LocStart = SM.getImmediateExpansionRange(Loc).first;
> > +    else {
> > +      LocStart = SM.getIncludeLoc(ExpandedFile);
> > +      if (LocStart.isInvalid())
> > +        return; // This file has no expansion region.
> > +    }
> > +
> > +    auto File = SM.getFileID(LocStart);
> > +    auto SpellingFile = SM.getDecomposedSpellingLoc(LocStart).first;
> > +    unsigned CovFileID, ExpandedFileID;
> > +    if (getExistingCoverageFileID(ExpandedFile, ExpandedFileID))
> > +      return;
> > +    if (getCoverageFileID(LocStart, File, SpellingFile, CovFileID))
> > +      return;
> > +    unsigned LineStart = SM.getSpellingLineNumber(LocStart);
> > +    unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart);
> > +    unsigned LineEnd = LineStart;
> > +    // Compute the end column manually as Lexer::getLocForEndOfToken
> doesn't
> > +    // give the correct result in all cases.
> > +    unsigned ColumnEnd =
> > +        ColumnStart +
> > +        Lexer::MeasureTokenLength(SM.getSpellingLoc(LocStart), SM,
> LangOpts);
> > +
> > +    MappingRegions.push_back(CounterMappingRegion(
> > +        Counter(), CovFileID, LineStart, ColumnStart, LineEnd,
> ColumnEnd,
> > +        false, CounterMappingRegion::ExpansionRegion));
> > +    MappingRegions.back().ExpandedFileID = ExpandedFileID;
> > +  }
> > +
> > +  /// \brief Enter a source region group that is identified by the given
> > +  /// statement.
> > +  /// It's not possible to enter a group when there is already
> > +  /// another group present.
> > +  void beginSourceRegionGroup(const Stmt *Group) {
> > +    assert(!CurrentSourceGroup);
> > +    CurrentSourceGroup = Group;
> > +  }
> > +
> > +  /// \brief Exit the current source region group.
> > +  void endSourceRegionGroup() { CurrentSourceGroup = nullptr; }
> > +
> > +  /// \brief Brings a region that has the same counter and file to the
> back
> > +  /// of the source regions array.
> > +  void bringSimilarRegionBack(Counter Count, FileID File,
> > +                              FileID MacroArgumentFile,
> > +                              const Stmt *UnreachableInitiator,
> > +                              const Stmt *SourceGroup) {
> > +    for (size_t I = SourceRegions.size(); I != 0;) {
> > +      --I;
> > +      if (SourceRegions[I].Count == Count && SourceRegions[I].File ==
> File &&
> > +          SourceRegions[I].MacroArgumentFile == MacroArgumentFile &&
> > +          SourceRegions[I].UnreachableInitiator == UnreachableInitiator
> &&
> > +          SourceRegions[I].Group == SourceGroup) {
> > +        if (I != SourceRegions.size() - 1)
> > +          std::swap(SourceRegions[I], SourceRegions.back());
> > +        return;
> > +      }
> > +    }
> > +  }
> > +
> > +  /// \brief Associate a counter with a given source code range.
> > +  void mapSourceCodeRange(SourceLocation LocStart, SourceLocation
> LocEnd,
> > +                          Counter Count, const Stmt
> *UnreachableInitiator,
> > +                          const Stmt *SourceGroup, unsigned Flags = 0,
> > +                          FileID MacroArgumentFile = FileID()) {
> > +    if (SM.isMacroArgExpansion(LocStart)) {
> > +      // Map the code range with the macro argument's value.
> > +      mapSourceCodeRange(SM.getImmediateSpellingLoc(LocStart),
> > +                         SM.getImmediateSpellingLoc(LocEnd), Count,
> > +                         UnreachableInitiator, SourceGroup, Flags,
> > +                         SM.getFileID(LocStart));
> > +      // Map the code range where the macro argument is referenced.
> > +      SourceLocation
> RefLocStart(SM.getImmediateExpansionRange(LocStart).first);
> > +      SourceLocation RefLocEnd(RefLocStart);
> > +      if (SM.isMacroArgExpansion(RefLocStart))
> > +        mapSourceCodeRange(RefLocStart, RefLocEnd, Count,
> UnreachableInitiator,
> > +                           SourceGroup, 0, SM.getFileID(RefLocStart));
> > +      else
> > +        mapSourceCodeRange(RefLocStart, RefLocEnd, Count,
> UnreachableInitiator,
> > +                           SourceGroup);
> > +      return;
> > +    }
> > +    auto File = SM.getFileID(LocStart);
> > +    // Make sure that the file id is valid.
> > +    if (File.isInvalid())
> > +      return;
> > +    bringSimilarRegionBack(Count, File, MacroArgumentFile,
> UnreachableInitiator,
> > +                           SourceGroup);
> > +    SourceMappingRegion R(File, MacroArgumentFile, Count,
> UnreachableInitiator,
> > +                          SourceGroup, LocStart, LocEnd, Flags);
> > +    if (SourceRegions.empty() || !SourceRegions.back().isMergeable(R)) {
> > +      SourceRegions.push_back(R);
> > +      return;
> > +    }
> > +    SourceRegions.back().mergeByExtendingTo(R);
> > +  }
> > +
> > +  void mapSourceCodeRange(SourceLocation LocStart, SourceLocation
> LocEnd,
> > +                          Counter Count, unsigned Flags = 0) {
> > +    mapSourceCodeRange(LocStart, LocEnd, Count,
> > +                       CurrentUnreachableRegionInitiator,
> CurrentSourceGroup,
> > +                       Flags);
> > +  }
> > +
> > +  void mapSourceCodeRange(const SourceMappingState &State,
> > +                          SourceLocation LocStart, SourceLocation
> LocEnd,
> > +                          unsigned Flags = 0) {
> > +    mapSourceCodeRange(LocStart, LocEnd, State.CurrentRegionCount,
> > +                       State.CurrentUnreachableRegionInitiator,
> > +                       State.CurrentSourceGroup, Flags);
> > +  }
> > +
> > +  /// \brief Generate the coverage counter mapping regions from
> collected
> > +  /// source regions.
> > +  void emitSourceRegions() {
> > +    for (const auto &R : SourceRegions) {
> > +      SourceLocation LocStart = R.LocStart;
> > +      SourceLocation LocEnd = R.LocEnd;
> > +      if (SM.getFileID(LocEnd) != R.File)
> > +        LocEnd = R.AlternativeLocEnd;
> > +
> > +      if (R.hasFlag(SourceMappingRegion::IgnoreIfNotExtended) &&
> > +          LocStart == LocEnd)
> > +        continue;
> > +
> > +      LocEnd = getPreciseTokenLocEnd(LocEnd);
> > +      unsigned LineStart = SM.getSpellingLineNumber(LocStart);
> > +      unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart);
> > +      unsigned LineEnd = SM.getSpellingLineNumber(LocEnd);
> > +      unsigned ColumnEnd = SM.getSpellingColumnNumber(LocEnd);
> > +
> > +      auto SpellingFile = SM.getDecomposedSpellingLoc(R.LocStart).first;
> > +      unsigned CovFileID;
> > +      if (getCoverageFileID(R.LocStart, R.File, SpellingFile,
> CovFileID))
> > +        continue;
> > +
> > +      assert(LineStart <= LineEnd);
> > +      MappingRegions.push_back(CounterMappingRegion(
> > +          R.Count, CovFileID, LineStart, ColumnStart, LineEnd,
> ColumnEnd,
> > +          false, CounterMappingRegion::CodeRegion));
> > +    }
> > +  }
> > +};
> > +
> > +/// \brief Creates unreachable coverage regions for the functions that
> > +/// are not emitted.
> > +struct EmptyCoverageMappingBuilder : public CoverageMappingBuilder {
> > +  EmptyCoverageMappingBuilder(CoverageMappingModuleGen &CVM,
> SourceManager &SM,
> > +                              const LangOptions &LangOpts)
> > +      : CoverageMappingBuilder(CVM, SM, LangOpts) {}
> > +
> > +  void VisitDecl(const Decl *D) {
> > +    if (!D->hasBody())
> > +      return;
> > +    auto Body = D->getBody();
> > +    mapSourceCodeRange(Body->getLocStart(), Body->getLocEnd(),
> Counter());
> > +  }
> > +
> > +  /// \brief Write the mapping data to the output stream
> > +  void write(llvm::raw_ostream &OS) {
> > +    emitSourceRegions();
> > +    SmallVector<unsigned, 16> FileIDMapping;
> > +    createFileIDMapping(FileIDMapping);
> > +
> > +    CoverageMappingWriter Writer(
> > +        FileIDMapping, ArrayRef<CounterExpression>(), MappingRegions);
> > +    Writer.write(OS);
> > +  }
> > +};
> > +
> > +/// \brief A StmtVisitor that creates coverage mapping regions which map
> > +/// from the source code locations to the PGO counters.
> > +struct CounterCoverageMappingBuilder
> > +    : public CoverageMappingBuilder,
> > +      public ConstStmtVisitor<CounterCoverageMappingBuilder> {
> > +  /// \brief The map of statements to count values.
> > +  llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
> > +
> > +  Counter CurrentRegionCount;
> > +
> > +  CounterExpressionBuilder Builder;
> > +
> > +  /// \brief Return a counter that represents the
> > +  /// expression that subracts rhs from lhs.
> > +  Counter subtractCounters(Counter LHS, Counter RHS) {
> > +    return Builder.subtract(LHS, RHS);
> > +  }
> > +
> > +  /// \brief Return a counter that represents the
> > +  /// the exression that adds lhs and rhs.
> > +  Counter addCounters(Counter LHS, Counter RHS) {
> > +    return Builder.add(LHS, RHS);
> > +  }
> > +
> > +  /// \brief Return the region counter for the given statement.
> > +  /// This should only be called on statements that have a dedicated
> counter.
> > +  unsigned getRegionCounter(const Stmt *S) { return CounterMap[S]; }
> > +
> > +  /// \brief Return the region count for the counter at the given index.
> > +  Counter getRegionCount(unsigned CounterId) {
> > +    return Counter::getCounter(CounterId);
> > +  }
> > +
> > +  /// \brief Return the counter value of the current region.
> > +  Counter getCurrentRegionCount() { return CurrentRegionCount; }
> > +
> > +  /// \brief Set the counter value for the current region.
> > +  /// This is used to keep track of changes to the most recent counter
> > +  /// from control flow and non-local exits.
> > +  void setCurrentRegionCount(Counter Count) {
> > +    CurrentRegionCount = Count;
> > +    CurrentUnreachableRegionInitiator = nullptr;
> > +  }
> > +
> > +  /// \brief Indicate that the current region is never reached,
> > +  /// and thus should have a counter value of zero.
> > +  /// This is important so that subsequent regions can correctly track
> > +  /// their parent counts.
> > +  void setCurrentRegionUnreachable(const Stmt *Initiator) {
> > +    CurrentRegionCount = Counter::getZero();
> > +    CurrentUnreachableRegionInitiator = Initiator;
> > +  }
> > +
> > +  /// \brief A counter for a particular region.
> > +  /// This is the primary interface through
> > +  /// which the coverage mapping builder manages counters and their
> values.
> > +  class RegionMapper {
> > +    CounterCoverageMappingBuilder &Mapping;
> > +    Counter Count;
> > +    Counter ParentCount;
> > +    Counter RegionCount;
> > +    Counter Adjust;
> > +
> > +  public:
> > +    RegionMapper(CounterCoverageMappingBuilder *Mapper, const Stmt *S)
> > +        : Mapping(*Mapper),
> > +          Count(Mapper->getRegionCount(Mapper->getRegionCounter(S))),
> > +          ParentCount(Mapper->getCurrentRegionCount()) {}
> > +
> > +    /// Get the value of the counter. In most cases this is the number
> of times
> > +    /// the region of the counter was entered, but for switch labels
> it's the
> > +    /// number of direct jumps to that label.
> > +    Counter getCount() const { return Count; }
> > +
> > +    /// Get the value of the counter with adjustments applied.
> Adjustments occur
> > +    /// when control enters or leaves the region abnormally; i.e., if
> there is a
> > +    /// jump to a label within the region, or if the function can
> return from
> > +    /// within the region. The adjusted count, then, is the value of
> the counter
> > +    /// at the end of the region.
> > +    Counter getAdjustedCount() const {
> > +      return Mapping.addCounters(Count, Adjust);
> > +    }
> > +
> > +    /// Get the value of the counter in this region's parent, i.e., the
> region
> > +    /// that was active when this region began. This is useful for
> deriving
> > +    /// counts in implicitly counted regions, like the false case of a
> condition
> > +    /// or the normal exits of a loop.
> > +    Counter getParentCount() const { return ParentCount; }
> > +
> > +    /// Activate the counter by emitting an increment and starting to
> track
> > +    /// adjustments. If AddIncomingFallThrough is true, the current
> region count
> > +    /// will be added to the counter for the purposes of tracking the
> region.
> > +    void beginRegion(bool AddIncomingFallThrough = false) {
> > +      RegionCount = Count;
> > +      if (AddIncomingFallThrough)
> > +        RegionCount =
> > +            Mapping.addCounters(RegionCount,
> Mapping.getCurrentRegionCount());
> > +      Mapping.setCurrentRegionCount(RegionCount);
> > +    }
> > +
> > +    /// For counters on boolean branches, begins tracking adjustments
> for the
> > +    /// uncounted path.
> > +    void beginElseRegion() {
> > +      RegionCount = Mapping.subtractCounters(ParentCount, Count);
> > +      Mapping.setCurrentRegionCount(RegionCount);
> > +    }
> > +
> > +    /// Reset the current region count.
> > +    void setCurrentRegionCount(Counter CurrentCount) {
> > +      RegionCount = CurrentCount;
> > +      Mapping.setCurrentRegionCount(RegionCount);
> > +    }
> > +
> > +    /// Adjust for non-local control flow after emitting a
> subexpression or
> > +    /// substatement. This must be called to account for constructs
> such as
> > +    /// gotos,
> > +    /// labels, and returns, so that we can ensure that our region's
> count is
> > +    /// correct in the code that follows.
> > +    void adjustForControlFlow() {
> > +      Adjust = Mapping.addCounters(
> > +          Adjust,
> Mapping.subtractCounters(Mapping.getCurrentRegionCount(),
> > +                                           RegionCount));
> > +      // Reset the region count in case this is called again later.
> > +      RegionCount = Mapping.getCurrentRegionCount();
> > +    }
> > +
> > +    /// Commit all adjustments to the current region. If the region is
> a loop,
> > +    /// the LoopAdjust value should be the count of all the breaks and
> continues
> > +    /// from the loop, to compensate for those counts being deducted
> from the
> > +    /// adjustments for the body of the loop.
> > +    void applyAdjustmentsToRegion() {
> > +      Mapping.setCurrentRegionCount(Mapping.addCounters(ParentCount,
> Adjust));
> > +    }
> > +    void applyAdjustmentsToRegion(Counter LoopAdjust) {
> > +      Mapping.setCurrentRegionCount(Mapping.addCounters(
> > +          Mapping.addCounters(ParentCount, Adjust), LoopAdjust));
> > +    }
> > +  };
> > +
> > +  /// \brief Keep counts of breaks and continues inside loops.
> > +  struct BreakContinue {
> > +    Counter BreakCount;
> > +    Counter ContinueCount;
> > +  };
> > +  SmallVector<BreakContinue, 8> BreakContinueStack;
> > +
> > +  CounterCoverageMappingBuilder(
> > +      CoverageMappingModuleGen &CVM,
> > +      llvm::DenseMap<const Stmt *, unsigned> &CounterMap,
> > +      unsigned NumRegionCounters, SourceManager &SM,
> > +      const LangOptions &LangOpts)
> > +      : CoverageMappingBuilder(CVM, SM, LangOpts),
> CounterMap(CounterMap),
> > +        Builder(NumRegionCounters) {}
> > +
> > +  /// \brief Write the mapping data to the output stream
> > +  void write(llvm::raw_ostream &OS) {
> > +    emitSourceRegions();
> > +    llvm::SmallVector<unsigned, 8> VirtualFileMapping;
> > +    createFileIDMapping(VirtualFileMapping);
> > +    gatherSkippedRegions();
> > +
> > +    CoverageMappingWriter Writer(
> > +        VirtualFileMapping, Builder.getExpressions(), MappingRegions);
> > +    Writer.write(OS);
> > +  }
> > +
> > +  /// \brief Return the current source mapping state.
> > +  SourceMappingState getCurrentState() const {
> > +    return SourceMappingState(CurrentRegionCount, CurrentSourceGroup,
> > +                              CurrentUnreachableRegionInitiator);
> > +  }
> > +
> > +  /// \brief Associate the source code range with the current region
> count.
> > +  void mapSourceCodeRange(SourceLocation LocStart, SourceLocation
> LocEnd,
> > +                          unsigned Flags = 0) {
> > +    CoverageMappingBuilder::mapSourceCodeRange(LocStart, LocEnd,
> > +                                               CurrentRegionCount,
> Flags);
> > +  }
> > +
> > +  void mapSourceCodeRange(SourceLocation LocStart) {
> > +    CoverageMappingBuilder::mapSourceCodeRange(LocStart, LocStart,
> > +                                               CurrentRegionCount);
> > +  }
> > +
> > +  /// \brief Associate the source range of a token with the current
> region
> > +  /// count.
> > +  /// Ignore the source range for this token if it produces a distinct
> > +  /// mapping region with no other source ranges.
> > +  void mapToken(SourceLocation LocStart) {
> > +    CoverageMappingBuilder::mapSourceCodeRange(
> > +        LocStart, LocStart, CurrentRegionCount,
> > +        SourceMappingRegion::IgnoreIfNotExtended);
> > +  }
> > +
> > +  void mapToken(const SourceMappingState &State, SourceLocation
> LocStart) {
> > +    CoverageMappingBuilder::mapSourceCodeRange(
> > +        State, LocStart, LocStart,
> SourceMappingRegion::IgnoreIfNotExtended);
> > +  }
> > +
> > +  void VisitStmt(const Stmt *S) {
> > +    mapSourceCodeRange(S->getLocStart());
> > +    for (Stmt::const_child_range I = S->children(); I; ++I) {
> > +      if (*I)
> > +        this->Visit(*I);
> > +    }
> > +  }
> > +
> > +  /// \brief If the given statement is a compound statement,
> > +  /// map '}' with the same count as '{'.
> > +  void VisitSubStmtRBraceState(const Stmt *S) {
> > +    if (!isa<CompoundStmt>(S))
> > +      return Visit(S);
> > +    const auto *CS = cast<CompoundStmt>(S);
> > +    auto State = getCurrentState();
> > +    mapSourceCodeRange(CS->getLBracLoc());
> > +    for (Stmt::const_child_range I = S->children(); I; ++I) {
> > +      if (*I)
> > +        this->Visit(*I);
> > +    }
> > +    CoverageMappingBuilder::mapSourceCodeRange(State, CS->getRBracLoc(),
> > +                                               CS->getRBracLoc());
> > +  }
> > +
> > +  void VisitDecl(const Decl *D) {
> > +    if (!D->hasBody())
> > +      return;
> > +    // Counter tracks entry to the function body.
> > +    auto Body = D->getBody();
> > +    RegionMapper Cnt(this, Body);
> > +    Cnt.beginRegion();
> > +    VisitSubStmtRBraceState(Body);
> > +  }
> > +
> > +  void VisitDeclStmt(const DeclStmt *S) {
> > +    mapSourceCodeRange(S->getLocStart());
> > +    for (Stmt::const_child_range I = static_cast<const Stmt
> *>(S)->children();
> > +         I; ++I) {
> > +      if (*I)
> > +        this->Visit(*I);
> > +    }
> > +  }
> > +
> > +  void VisitCompoundStmt(const CompoundStmt *S) {
> > +    mapSourceCodeRange(S->getLBracLoc());
> > +    for (Stmt::const_child_range I = S->children(); I; ++I) {
> > +      if (*I)
> > +        this->Visit(*I);
> > +    }
> > +    mapSourceCodeRange(S->getRBracLoc(), S->getRBracLoc());
> > +  }
> > +
> > +  void VisitReturnStmt(const ReturnStmt *S) {
> > +    mapSourceCodeRange(S->getLocStart());
> > +    if (S->getRetValue())
> > +      Visit(S->getRetValue());
> > +    setCurrentRegionUnreachable(S);
> > +  }
> > +
> > +  void VisitGotoStmt(const GotoStmt *S) {
> > +    mapSourceCodeRange(S->getLocStart());
> > +    mapToken(S->getLabelLoc());
> > +    setCurrentRegionUnreachable(S);
> > +  }
> > +
> > +  void VisitLabelStmt(const LabelStmt *S) {
> > +    // Counter tracks the block following the label.
> > +    RegionMapper Cnt(this, S);
> > +    Cnt.beginRegion();
> > +    mapSourceCodeRange(S->getLocStart());
> > +    // Can't map the ':' token as its location isn't known.
> > +    Visit(S->getSubStmt());
> > +  }
> > +
> > +  void VisitBreakStmt(const BreakStmt *S) {
> > +    mapSourceCodeRange(S->getLocStart());
> > +    assert(!BreakContinueStack.empty() && "break not in a loop or
> switch!");
> > +    BreakContinueStack.back().BreakCount = addCounters(
> > +        BreakContinueStack.back().BreakCount, getCurrentRegionCount());
> > +    setCurrentRegionUnreachable(S);
> > +  }
> > +
> > +  void VisitContinueStmt(const ContinueStmt *S) {
> > +    mapSourceCodeRange(S->getLocStart());
> > +    assert(!BreakContinueStack.empty() && "continue stmt not in a
> loop!");
> > +    BreakContinueStack.back().ContinueCount = addCounters(
> > +        BreakContinueStack.back().ContinueCount,
> getCurrentRegionCount());
> > +    setCurrentRegionUnreachable(S);
> > +  }
> > +
> > +  void VisitWhileStmt(const WhileStmt *S) {
> > +    mapSourceCodeRange(S->getLocStart());
> > +    // Counter tracks the body of the loop.
> > +    RegionMapper Cnt(this, S);
> > +    BreakContinueStack.push_back(BreakContinue());
> > +    // Visit the body region first so the break/continue adjustments
> can be
> > +    // included when visiting the condition.
> > +    Cnt.beginRegion();
> > +    VisitSubStmtRBraceState(S->getBody());
> > +    Cnt.adjustForControlFlow();
> > +
> > +    // ...then go back and propagate counts through the condition. The
> count
> > +    // at the start of the condition is the sum of the incoming edges,
> > +    // the backedge from the end of the loop body, and the edges from
> > +    // continue statements.
> > +    BreakContinue BC = BreakContinueStack.pop_back_val();
> > +    Cnt.setCurrentRegionCount(
> > +        addCounters(Cnt.getParentCount(),
> > +                    addCounters(Cnt.getAdjustedCount(),
> BC.ContinueCount)));
> > +    beginSourceRegionGroup(S->getCond());
> > +    Visit(S->getCond());
> > +    endSourceRegionGroup();
> > +    Cnt.adjustForControlFlow();
> > +    Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount,
> BC.ContinueCount));
> > +  }
> > +
> > +  void VisitDoStmt(const DoStmt *S) {
> > +    mapSourceCodeRange(S->getLocStart());
> > +    // Counter tracks the body of the loop.
> > +    RegionMapper Cnt(this, S);
> > +    BreakContinueStack.push_back(BreakContinue());
> > +    Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
> > +    VisitSubStmtRBraceState(S->getBody());
> > +    Cnt.adjustForControlFlow();
> > +
> > +    BreakContinue BC = BreakContinueStack.pop_back_val();
> > +    // The count at the start of the condition is equal to the count at
> the
> > +    // end of the body. The adjusted count does not include either the
> > +    // fall-through count coming into the loop or the continue count,
> so add
> > +    // both of those separately. This is coincidentally the same
> equation as
> > +    // with while loops but for different reasons.
> > +    Cnt.setCurrentRegionCount(
> > +        addCounters(Cnt.getParentCount(),
> > +                    addCounters(Cnt.getAdjustedCount(),
> BC.ContinueCount)));
> > +    Visit(S->getCond());
> > +    Cnt.adjustForControlFlow();
> > +    Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount,
> BC.ContinueCount));
> > +  }
> > +
> > +  void VisitForStmt(const ForStmt *S) {
> > +    mapSourceCodeRange(S->getLocStart());
> > +    if (S->getInit())
> > +      Visit(S->getInit());
> > +
> > +    // Counter tracks the body of the loop.
> > +    RegionMapper Cnt(this, S);
> > +    BreakContinueStack.push_back(BreakContinue());
> > +    // Visit the body region first. (This is basically the same as a
> while
> > +    // loop; see further comments in VisitWhileStmt.)
> > +    Cnt.beginRegion();
> > +    VisitSubStmtRBraceState(S->getBody());
> > +    Cnt.adjustForControlFlow();
> > +
> > +    // The increment is essentially part of the body but it needs to
> include
> > +    // the count for all the continue statements.
> > +    if (S->getInc()) {
> > +      Cnt.setCurrentRegionCount(addCounters(
> > +          getCurrentRegionCount(),
> BreakContinueStack.back().ContinueCount));
> > +      beginSourceRegionGroup(S->getInc());
> > +      Visit(S->getInc());
> > +      endSourceRegionGroup();
> > +      Cnt.adjustForControlFlow();
> > +    }
> > +
> > +    BreakContinue BC = BreakContinueStack.pop_back_val();
> > +
> > +    // ...then go back and propagate counts through the condition.
> > +    if (S->getCond()) {
> > +      Cnt.setCurrentRegionCount(
> > +          addCounters(addCounters(Cnt.getParentCount(),
> Cnt.getAdjustedCount()),
> > +                      BC.ContinueCount));
> > +      beginSourceRegionGroup(S->getCond());
> > +      Visit(S->getCond());
> > +      endSourceRegionGroup();
> > +      Cnt.adjustForControlFlow();
> > +    }
> > +    Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount,
> BC.ContinueCount));
> > +  }
> > +
> > +  void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
> > +    mapSourceCodeRange(S->getLocStart());
> > +    Visit(S->getRangeStmt());
> > +    Visit(S->getBeginEndStmt());
> > +    // Counter tracks the body of the loop.
> > +    RegionMapper Cnt(this, S);
> > +    BreakContinueStack.push_back(BreakContinue());
> > +    // Visit the body region first. (This is basically the same as a
> while
> > +    // loop; see further comments in VisitWhileStmt.)
> > +    Cnt.beginRegion();
> > +    VisitSubStmtRBraceState(S->getBody());
> > +    Cnt.adjustForControlFlow();
> > +    BreakContinue BC = BreakContinueStack.pop_back_val();
> > +    Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount,
> BC.ContinueCount));
> > +  }
> > +
> > +  void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
> > +    mapSourceCodeRange(S->getLocStart());
> > +    Visit(S->getElement());
> > +    // Counter tracks the body of the loop.
> > +    RegionMapper Cnt(this, S);
> > +    BreakContinueStack.push_back(BreakContinue());
> > +    VisitSubStmtRBraceState(S->getBody());
> > +    BreakContinue BC = BreakContinueStack.pop_back_val();
> > +    Cnt.adjustForControlFlow();
> > +    Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount,
> BC.ContinueCount));
> > +  }
> > +
> > +  void VisitSwitchStmt(const SwitchStmt *S) {
> > +    mapSourceCodeRange(S->getLocStart());
> > +    Visit(S->getCond());
> > +    BreakContinueStack.push_back(BreakContinue());
> > +    // Map the '}' for the body to have the same count as the regions
> after
> > +    // the switch.
> > +    SourceLocation RBracLoc;
> > +    if (const auto *CS = dyn_cast<CompoundStmt>(S->getBody())) {
> > +      mapSourceCodeRange(CS->getLBracLoc());
> > +      setCurrentRegionUnreachable(S);
> > +      for (Stmt::const_child_range I = CS->children(); I; ++I) {
> > +        if (*I)
> > +          this->Visit(*I);
> > +      }
> > +      RBracLoc = CS->getRBracLoc();
> > +    } else {
> > +      setCurrentRegionUnreachable(S);
> > +      Visit(S->getBody());
> > +    }
> > +    // If the switch is inside a loop, add the continue counts.
> > +    BreakContinue BC = BreakContinueStack.pop_back_val();
> > +    if (!BreakContinueStack.empty())
> > +      BreakContinueStack.back().ContinueCount = addCounters(
> > +          BreakContinueStack.back().ContinueCount, BC.ContinueCount);
> > +    // Counter tracks the exit block of the switch.
> > +    RegionMapper ExitCnt(this, S);
> > +    ExitCnt.beginRegion();
> > +    if (RBracLoc.isValid())
> > +      mapSourceCodeRange(RBracLoc);
> > +  }
> > +
> > +  void VisitCaseStmt(const CaseStmt *S) {
> > +    // Counter for this particular case. This counts only jumps from the
> > +    // switch header and does not include fallthrough from the case
> before
> > +    // this one.
> > +    RegionMapper Cnt(this, S);
> > +    Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
> > +    mapSourceCodeRange(S->getLocStart());
> > +    mapToken(S->getColonLoc());
> > +    Visit(S->getSubStmt());
> > +  }
> > +
> > +  void VisitDefaultStmt(const DefaultStmt *S) {
> > +    // Counter for this default case. This does not include fallthrough
> from
> > +    // the previous case.
> > +    RegionMapper Cnt(this, S);
> > +    Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
> > +    mapSourceCodeRange(S->getLocStart());
> > +    mapToken(S->getColonLoc());
> > +    Visit(S->getSubStmt());
> > +  }
> > +
> > +  void VisitIfStmt(const IfStmt *S) {
> > +    mapSourceCodeRange(S->getLocStart());
> > +    Visit(S->getCond());
> > +    mapToken(S->getElseLoc());
> > +
> > +    // Counter tracks the "then" part of an if statement. The count for
> > +    // the "else" part, if it exists, will be calculated from this
> counter.
> > +    RegionMapper Cnt(this, S);
> > +    Cnt.beginRegion();
> > +    VisitSubStmtRBraceState(S->getThen());
> > +    Cnt.adjustForControlFlow();
> > +
> > +    if (S->getElse()) {
> > +      Cnt.beginElseRegion();
> > +      VisitSubStmtRBraceState(S->getElse());
> > +      Cnt.adjustForControlFlow();
> > +    }
> > +    Cnt.applyAdjustmentsToRegion();
> > +  }
> > +
> > +  void VisitCXXTryStmt(const CXXTryStmt *S) {
> > +    mapSourceCodeRange(S->getLocStart());
> > +    Visit(S->getTryBlock());
> > +    for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
> > +      Visit(S->getHandler(I));
> > +    // Counter tracks the continuation block of the try statement.
> > +    RegionMapper Cnt(this, S);
> > +    Cnt.beginRegion();
> > +  }
> > +
> > +  void VisitCXXCatchStmt(const CXXCatchStmt *S) {
> > +    mapSourceCodeRange(S->getLocStart());
> > +    // Counter tracks the catch statement's handler block.
> > +    RegionMapper Cnt(this, S);
> > +    Cnt.beginRegion();
> > +    VisitSubStmtRBraceState(S->getHandlerBlock());
> > +  }
> > +
> > +  void VisitAbstractConditionalOperator(const
> AbstractConditionalOperator *E) {
> > +    Visit(E->getCond());
> > +    mapToken(E->getQuestionLoc());
> > +    auto State = getCurrentState();
> > +
> > +    // Counter tracks the "true" part of a conditional operator. The
> > +    // count in the "false" part will be calculated from this counter.
> > +    RegionMapper Cnt(this, E);
> > +    Cnt.beginRegion();
> > +    Visit(E->getTrueExpr());
> > +    Cnt.adjustForControlFlow();
> > +
> > +    mapToken(State, E->getColonLoc());
> > +
> > +    Cnt.beginElseRegion();
> > +    Visit(E->getFalseExpr());
> > +    Cnt.adjustForControlFlow();
> > +
> > +    Cnt.applyAdjustmentsToRegion();
> > +  }
> > +
> > +  void VisitBinLAnd(const BinaryOperator *E) {
> > +    Visit(E->getLHS());
> > +    mapToken(E->getOperatorLoc());
> > +    // Counter tracks the right hand side of a logical and operator.
> > +    RegionMapper Cnt(this, E);
> > +    Cnt.beginRegion();
> > +    Visit(E->getRHS());
> > +    Cnt.adjustForControlFlow();
> > +    Cnt.applyAdjustmentsToRegion();
> > +  }
> > +
> > +  void VisitBinLOr(const BinaryOperator *E) {
> > +    Visit(E->getLHS());
> > +    mapToken(E->getOperatorLoc());
> > +    // Counter tracks the right hand side of a logical or operator.
> > +    RegionMapper Cnt(this, E);
> > +    Cnt.beginRegion();
> > +    Visit(E->getRHS());
> > +    Cnt.adjustForControlFlow();
> > +    Cnt.applyAdjustmentsToRegion();
> > +  }
> > +
> > +  void VisitParenExpr(const ParenExpr *E) {
> > +    mapToken(E->getLParen());
> > +    Visit(E->getSubExpr());
> > +    mapToken(E->getRParen());
> > +  }
> > +
> > +  void VisitBinaryOperator(const BinaryOperator *E) {
> > +    Visit(E->getLHS());
> > +    mapToken(E->getOperatorLoc());
> > +    Visit(E->getRHS());
> > +  }
> > +
> > +  void VisitUnaryOperator(const UnaryOperator *E) {
> > +    bool Postfix = E->isPostfix();
> > +    if (!Postfix)
> > +      mapToken(E->getOperatorLoc());
> > +    Visit(E->getSubExpr());
> > +    if (Postfix)
> > +      mapToken(E->getOperatorLoc());
> > +  }
> > +
> > +  void VisitMemberExpr(const MemberExpr *E) {
> > +    Visit(E->getBase());
> > +    mapToken(E->getMemberLoc());
> > +  }
> > +
> > +  void VisitCallExpr(const CallExpr *E) {
> > +    Visit(E->getCallee());
> > +    for (const auto &Arg : E->arguments())
> > +      Visit(Arg);
> > +    mapToken(E->getRParenLoc());
> > +  }
> > +
> > +  void VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
> > +    Visit(E->getLHS());
> > +    Visit(E->getRHS());
> > +    mapToken(E->getRBracketLoc());
> > +  }
> > +
> > +  void VisitCStyleCastExpr(const CStyleCastExpr *E) {
> > +    mapToken(E->getLParenLoc());
> > +    mapToken(E->getRParenLoc());
> > +    Visit(E->getSubExpr());
> > +  }
> > +
> > +  // Map literals as tokens so that the macros like #define PI 3.14
> > +  // won't generate coverage mapping regions.
> > +
> > +  void VisitIntegerLiteral(const IntegerLiteral *E) {
> > +    mapToken(E->getLocStart());
> > +  }
> > +
> > +  void VisitFloatingLiteral(const FloatingLiteral *E) {
> > +    mapToken(E->getLocStart());
> > +  }
> > +
> > +  void VisitCharacterLiteral(const CharacterLiteral *E) {
> > +    mapToken(E->getLocStart());
> > +  }
> > +
> > +  void VisitStringLiteral(const StringLiteral *E) {
> > +    mapToken(E->getLocStart());
> > +  }
> > +
> > +  void VisitImaginaryLiteral(const ImaginaryLiteral *E) {
> > +    mapToken(E->getLocStart());
> > +  }
> > +};
> > +}
> > +
> > +static bool isMachO(const CodeGenModule &CGM) {
> > +  return CGM.getTarget().getTriple().isOSBinFormatMachO();
> > +}
> > +
> > +static StringRef getCoverageSection(const CodeGenModule &CGM) {
> > +  return isMachO(CGM) ? "__DATA,__llvm_covmap" : "__llvm_covmap";
> > +}
> > +
> > +void CoverageMappingModuleGen::addFunctionMappingRecord(
> > +    llvm::GlobalVariable *FunctionName, unsigned FunctionNameSize,
> > +    const std::string &CoverageMapping) {
> > +  llvm::LLVMContext &Ctx = CGM.getLLVMContext();
> > +  auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
> > +  auto *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx);
> > +  if (!FunctionRecordTy) {
> > +    llvm::Type *FunctionRecordTypes[] = {Int8PtrTy, Int32Ty, Int32Ty};
> > +    FunctionRecordTy =
> > +        llvm::StructType::get(Ctx, makeArrayRef(FunctionRecordTypes));
> > +  }
> > +
> > +  llvm::Constant *FunctionRecordVals[] = {
> > +      llvm::ConstantExpr::getBitCast(FunctionName, Int8PtrTy),
> > +      llvm::ConstantInt::get(Int32Ty, FunctionNameSize),
> > +      llvm::ConstantInt::get(Int32Ty, CoverageMapping.size())};
> > +  FunctionRecords.push_back(llvm::ConstantStruct::get(
> > +      FunctionRecordTy, makeArrayRef(FunctionRecordVals)));
> > +  CoverageMappings += CoverageMapping;
> > +}
> > +
> > +void CoverageMappingModuleGen::emit() {
> > +  if (FunctionRecords.empty())
> > +    return;
> > +  llvm::LLVMContext &Ctx = CGM.getLLVMContext();
> > +  auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
> > +
> > +  // Create the filenames and merge them with coverage mappings
> > +  llvm::SmallVector<std::string, 16> FilenameStrs;
> > +  llvm::SmallVector<StringRef, 16> FilenameRefs;
> > +  FilenameStrs.resize(FileEntries.size());
> > +  FilenameRefs.resize(FileEntries.size());
> > +  for (const auto &Entry : FileEntries) {
> > +    llvm::SmallString<256> Path(Entry.first->getName());
> > +    llvm::sys::fs::make_absolute(Path);
> > +
> > +    auto I = Entry.second;
> > +    FilenameStrs[I] = std::move(std::string(Path.begin(), Path.end()));
> > +    FilenameRefs[I] = FilenameStrs[I];
> > +  }
> > +
> > +  std::string FilenamesAndCoverageMappings;
> > +  llvm::raw_string_ostream OS(FilenamesAndCoverageMappings);
> > +  CoverageFilenamesSectionWriter(FilenameRefs).write(OS);
> > +  OS << CoverageMappings;
> > +  size_t CoverageMappingSize = CoverageMappings.size();
> > +  size_t FilenamesSize = OS.str().size() - CoverageMappingSize;
> > +  // Append extra zeroes if necessary to ensure that the size of the
> filenames
> > +  // and coverage mappings is a multiple of 8.
> > +  if (size_t Rem = OS.str().size() % 8) {
> > +    CoverageMappingSize += 8 - Rem;
> > +    for (size_t I = 0, S = 8 - Rem; I < S; ++I)
> > +      OS << '\0';
> > +  }
> > +  auto *FilenamesAndMappingsVal =
> > +      llvm::ConstantDataArray::getString(Ctx, OS.str(), false);
> > +
> > +  // Create the deferred function records array
> > +  auto RecordsTy =
> > +      llvm::ArrayType::get(FunctionRecordTy, FunctionRecords.size());
> > +  auto RecordsVal = llvm::ConstantArray::get(RecordsTy,
> FunctionRecords);
> > +
> > +  // Create the coverage data record
> > +  llvm::Type *CovDataTypes[] = {Int32Ty,   Int32Ty,
> > +                                Int32Ty,   Int32Ty,
> > +                                RecordsTy,
> FilenamesAndMappingsVal->getType()};
> > +  auto CovDataTy = llvm::StructType::get(Ctx,
> makeArrayRef(CovDataTypes));
> > +  llvm::Constant *TUDataVals[] = {
> > +      llvm::ConstantInt::get(Int32Ty, FunctionRecords.size()),
> > +      llvm::ConstantInt::get(Int32Ty, FilenamesSize),
> > +      llvm::ConstantInt::get(Int32Ty, CoverageMappingSize),
> > +      llvm::ConstantInt::get(Int32Ty,
> > +                             /*Version=*/CoverageMappingVersion1),
> > +      RecordsVal, FilenamesAndMappingsVal};
> > +  auto CovDataVal =
> > +      llvm::ConstantStruct::get(CovDataTy, makeArrayRef(TUDataVals));
> > +  auto CovData = new llvm::GlobalVariable(CGM.getModule(), CovDataTy,
> true,
> > +
> llvm::GlobalValue::InternalLinkage,
> > +                                          CovDataVal,
> > +                                          "__llvm_coverage_mapping");
> > +
> > +  CovData->setSection(getCoverageSection(CGM));
> > +  CovData->setAlignment(8);
> > +
> > +  // Make sure the data doesn't get deleted.
> > +  CGM.addUsedGlobal(CovData);
> > +}
> > +
> > +unsigned CoverageMappingModuleGen::getFileID(const FileEntry *File) {
> > +  auto It = FileEntries.find(File);
> > +  if (It != FileEntries.end())
> > +    return It->second;
> > +  unsigned FileID = FileEntries.size();
> > +  FileEntries.insert(std::make_pair(File, FileID));
> > +  return FileID;
> > +}
> > +
> > +void CoverageMappingGen::emitCounterMapping(const Decl *D,
> > +                                            llvm::raw_ostream &OS) {
> > +  assert(CounterMap);
> > +  CounterCoverageMappingBuilder Walker(CVM, *CounterMap,
> NumRegionCounters, SM,
> > +                                       LangOpts);
> > +  Walker.VisitDecl(D);
> > +  Walker.write(OS);
> > +}
> > +
> > +void CoverageMappingGen::emitEmptyMapping(const Decl *D,
> > +                                          llvm::raw_ostream &OS) {
> > +  EmptyCoverageMappingBuilder Walker(CVM, SM, LangOpts);
> > +  Walker.VisitDecl(D);
> > +  Walker.write(OS);
> > +}
> > 
> > Added: cfe/trunk/lib/CodeGen/CoverageMappingGen.h
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CoverageMappingGen.h?rev=214752&view=auto
> 
> > 
> ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CoverageMappingGen.h (added)
> > +++ cfe/trunk/lib/CodeGen/CoverageMappingGen.h Mon Aug  4 13:41:51 2014
> > @@ -0,0 +1,117 @@
> > +//===---- CoverageMappingGen.h - Coverage mapping generation ----*- C++
> -*-===//
> > +//
> > +//                     The LLVM Compiler Infrastructure
> > +//
> > +// This file is distributed under the University of Illinois Open Source
> > +// License. See LICENSE.TXT for details.
> > +//
> > 
> +//===----------------------------------------------------------------------===//
> > +//
> > +// Instrumentation-based code coverage mapping generator
> > +//
> > 
> +//===----------------------------------------------------------------------===//
> > +
> > +#ifndef CLANG_CODEGEN_COVERAGEMAPPINGGEN_H
> > +#define CLANG_CODEGEN_COVERAGEMAPPINGGEN_H
> > +
> > +#include "clang/Basic/LLVM.h"
> > +#include "clang/Basic/SourceLocation.h"
> > +#include "clang/Lex/PPCallbacks.h"
> > +#include "clang/Frontend/CodeGenOptions.h"
> > +#include "llvm/ADT/StringMap.h"
> > +#include "llvm/ADT/DenseMap.h"
> > +#include "llvm/IR/GlobalValue.h"
> > +#include "llvm/Support/raw_ostream.h"
> > +
> > +namespace clang {
> > +
> > +class LangOptions;
> > +class SourceManager;
> > +class FileEntry;
> > +class Preprocessor;
> > +class Decl;
> > +class Stmt;
> > +
> > +/// \brief Stores additional source code information like skipped
> ranges which
> > +/// is required by the coverage mapping generator and is obtained from
> > +/// the preprocessor.
> > +class CoverageSourceInfo : public PPCallbacks {
> > +  std::vector<SourceRange> SkippedRanges;
> > +public:
> > +  ArrayRef<SourceRange> getSkippedRanges() const { return
> SkippedRanges; }
> > +
> > +  void SourceRangeSkipped(SourceRange Range) override;
> > +};
> > +
> > +namespace CodeGen {
> > +
> > +class CodeGenModule;
> > +
> > +/// \brief Organizes the cross-function state that is used while
> generating
> > +/// code coverage mapping data.
> > +class CoverageMappingModuleGen {
> > +  CodeGenModule &CGM;
> > +  CoverageSourceInfo &SourceInfo;
> > +  llvm::SmallDenseMap<const FileEntry *, unsigned, 8> FileEntries;
> > +  std::vector<llvm::Constant *> FunctionRecords;
> > +  llvm::StructType *FunctionRecordTy;
> > +  std::string CoverageMappings;
> > +
> > +public:
> > +  CoverageMappingModuleGen(CodeGenModule &CGM, CoverageSourceInfo
> &SourceInfo)
> > +      : CGM(CGM), SourceInfo(SourceInfo), FunctionRecordTy(nullptr) {}
> > +
> > +  CoverageSourceInfo &getSourceInfo() const {
> > +    return SourceInfo;
> > +  }
> > +
> > +  /// \brief Add a function's coverage mapping record to the collection
> of the
> > +  /// function mapping records.
> > +  void addFunctionMappingRecord(llvm::GlobalVariable *FunctionName,
> > +                                unsigned FunctionNameSize,
> > +                                const std::string &CoverageMapping);
> > +
> > +  /// \brief Emit the coverage mapping data for a translation unit.
> > +  void emit();
> > +
> > +  /// \brief Return the coverage mapping translation unit file id
> > +  /// for the given file.
> > +  unsigned getFileID(const FileEntry *File);
> > +};
> > +
> > +/// \brief Organizes the per-function state that is used while
> generating
> > +/// code coverage mapping data.
> > +class CoverageMappingGen {
> > +  CoverageMappingModuleGen &CVM;
> > +  SourceManager &SM;
> > +  const LangOptions &LangOpts;
> > +  llvm::DenseMap<const Stmt *, unsigned> *CounterMap;
> > +  unsigned NumRegionCounters;
> > +
> > +public:
> > +  CoverageMappingGen(CoverageMappingModuleGen &CVM, SourceManager &SM,
> > +                     const LangOptions &LangOpts)
> > +      : CVM(CVM), SM(SM), LangOpts(LangOpts), CounterMap(nullptr),
> > +        NumRegionCounters(0) {}
> > +
> > +  CoverageMappingGen(CoverageMappingModuleGen &CVM, SourceManager &SM,
> > +                     const LangOptions &LangOpts,
> > +                     llvm::DenseMap<const Stmt *, unsigned> *CounterMap,
> > +                     unsigned NumRegionCounters)
> > +      : CVM(CVM), SM(SM), LangOpts(LangOpts), CounterMap(CounterMap),
> > +        NumRegionCounters(NumRegionCounters) {}
> > +
> > +  /// \brief Emit the coverage mapping data which maps the regions of
> > +  /// code to counters that will be used to find the execution
> > +  /// counts for those regions.
> > +  void emitCounterMapping(const Decl *D, llvm::raw_ostream &OS);
> > +
> > +  /// \brief Emit the coverage mapping data for an unused function.
> > +  /// It creates mapping regions with the counter of zero.
> > +  void emitEmptyMapping(const Decl *D, llvm::raw_ostream &OS);
> > +};
> > +
> > +} // end namespace CodeGen
> > +} // end namespace clang
> > +
> > +#endif
> > 
> > Modified: cfe/trunk/lib/CodeGen/ModuleBuilder.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ModuleBuilder.cpp?rev=214752&r1=214751&r2=214752&view=diff
> 
> > 
> ==============================================================================
> > --- cfe/trunk/lib/CodeGen/ModuleBuilder.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/ModuleBuilder.cpp Mon Aug  4 13:41:51 2014
> > @@ -46,14 +46,18 @@ namespace {
> > }
> > };
> > 
> > +    CoverageSourceInfo *CoverageInfo;
> > +
> > protected:
> > std::unique_ptr<llvm::Module> M;
> > std::unique_ptr<CodeGen::CodeGenModule> Builder;
> > 
> > public:
> > CodeGeneratorImpl(DiagnosticsEngine &diags, const std::string&
> ModuleName,
> > -                      const CodeGenOptions &CGO, llvm::LLVMContext& C)
> > +                      const CodeGenOptions &CGO, llvm::LLVMContext& C,
> > +                      CoverageSourceInfo *CoverageInfo = nullptr)
> > > Diags(diags), CodeGenOpts(CGO), HandlingTopLevelDecls(0),
> > +        CoverageInfo(CoverageInfo),
> > M(new llvm::Module(ModuleName, C)) {}
> > 
> > virtual ~CodeGeneratorImpl() {}
> > @@ -86,7 +90,7 @@ namespace {
> > M->setDataLayout(Ctx->getTargetInfo().getTargetDescription());
> > TD.reset(new
> llvm::DataLayout(Ctx->getTargetInfo().getTargetDescription()));
> > Builder.reset(new CodeGen::CodeGenModule(Context, CodeGenOpts,
> *M, *TD,
> > -                                               Diags));
> > +                                               Diags, CoverageInfo));
> > 
> > for (size_t i = 0, e = CodeGenOpts.DependentLibraries.size(); i <
> e; ++i)
> > HandleDependentLibrary(CodeGenOpts.DependentLibraries[i]);
> > @@ -136,6 +140,10 @@ namespace {
> > //     void foo() { bar(); }
> > //   } A;
> > DeferredInlineMethodDefinitions.push_back(D);
> > +
> > +      // Always provide some coverage mapping
> > +      // even for the methods that aren't emitted.
> > +      Builder->AddDeferredUnusedCoverageMapping(D);
> > }
> > 
> > /// HandleTagDeclDefinition - This callback is invoked each time a
> TagDecl
> > @@ -221,6 +229,7 @@ CodeGenerator *clang::CreateLLVMCodeGen(
> > const std::string& ModuleName,
> > const CodeGenOptions &CGO,
> > const TargetOptions &/*TO*/,
> > -                                        llvm::LLVMContext& C) {
> > -  return new CodeGeneratorImpl(Diags, ModuleName, CGO, C);
> > +                                        llvm::LLVMContext& C,
> > +                                        CoverageSourceInfo
> *CoverageInfo) {
> > +  return new CodeGeneratorImpl(Diags, ModuleName, CGO, C, CoverageInfo);
> > }
> > 
> > Modified: cfe/trunk/lib/Driver/Tools.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=214752&r1=214751&r2=214752&view=diff
> 
> > 
> ==============================================================================
> > --- cfe/trunk/lib/Driver/Tools.cpp (original)
> > +++ cfe/trunk/lib/Driver/Tools.cpp Mon Aug  4 13:41:51 2014
> > @@ -3230,6 +3230,14 @@ void Clang::ConstructJob(Compilation &C,
> > Args.hasArg(options::OPT_coverage))
> > CmdArgs.push_back("-femit-coverage-data");
> > 
> > +  if (Args.hasArg(options::OPT_fcoverage_mapping) &&
> > +      !Args.hasArg(options::OPT_fprofile_instr_generate))
> > +    D.Diag(diag::err_drv_argument_only_allowed_with)
> > +      << "-fcoverage-mapping" << "-fprofile-instr-generate";
> > +
> > +  if (Args.hasArg(options::OPT_fcoverage_mapping))
> > +    CmdArgs.push_back("-fcoverage-mapping");
> > +
> > if (C.getArgs().hasArg(options::OPT_c) ||
> > C.getArgs().hasArg(options::OPT_S)) {
> > if (Output.isFilename()) {
> > 
> > Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=214752&r1=214751&r2=214752&view=diff
> 
> > 
> ==============================================================================
> > --- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
> > +++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Mon Aug  4 13:41:51
> 2014
> > @@ -403,6 +403,7 @@ static bool ParseCodeGenArgs(CodeGenOpti
> > Opts.SampleProfileFile =
> Args.getLastArgValue(OPT_fprofile_sample_use_EQ);
> > Opts.ProfileInstrGenerate = Args.hasArg(OPT_fprofile_instr_generate);
> > Opts.InstrProfileInput =
> Args.getLastArgValue(OPT_fprofile_instr_use_EQ);
> > +  Opts.CoverageMapping = Args.hasArg(OPT_fcoverage_mapping);
> > Opts.AsmVerbose = Args.hasArg(OPT_masm_verbose);
> > Opts.ObjCAutoRefCountExceptions =
> Args.hasArg(OPT_fobjc_arc_exceptions);
> > Opts.CUDAIsDevice = Args.hasArg(OPT_fcuda_is_device);
> > 
> > 
> > _______________________________________________
> > cfe-commits mailing list
> > cfe-commits@cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
> 


[Attachment #5 (text/html)]

<div dir="ltr"><div>I actually fixed it in r214757, now there are two :) <br></div>I \
will revert mine<br></div><div class="gmail_extra"><br><br><div \
class="gmail_quote">2014-08-04 12:08 GMT-07:00 David Blaikie <span dir="ltr">&lt;<a \
href="mailto:dblaikie@gmail.com" \
target="_blank">dblaikie@gmail.com</a>&gt;</span>:<br> <blockquote \
class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc \
solid;padding-left:1ex">CMake build fixed in   r214758<br> <div class="HOEnZb"><div \
class="h5"><br> On Mon, Aug 4, 2014 at 11:41 AM, Alex Lorenz &lt;<a \
href="mailto:arphaman@gmail.com">arphaman@gmail.com</a>&gt; wrote:<br> &gt; Author: \
arphaman<br> &gt; Date: Mon Aug   4 13:41:51 2014<br>
&gt; New Revision: 214752<br>
&gt;<br>
&gt; URL: <a href="http://llvm.org/viewvc/llvm-project?rev=214752&amp;view=rev" \
target="_blank">http://llvm.org/viewvc/llvm-project?rev=214752&amp;view=rev</a><br> \
&gt; Log:<br> &gt; Add coverage mapping generation.<br>
&gt;<br>
&gt; This patch adds the &#39;-fcoverage-mapping&#39; option which<br>
&gt; allows clang to generate the coverage mapping information<br>
&gt; that can be used to provide code coverage analysis using<br>
&gt; the execution counts obtained from the instrumentation<br>
&gt; based profiling (-fprofile-instr-generate).<br>
&gt;<br>
&gt; Added:<br>
&gt;       cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp<br>
&gt;       cfe/trunk/lib/CodeGen/CoverageMappingGen.h<br>
&gt; Modified:<br>
&gt;       cfe/trunk/include/clang/CodeGen/CodeGenABITypes.h<br>
&gt;       cfe/trunk/include/clang/CodeGen/ModuleBuilder.h<br>
&gt;       cfe/trunk/include/clang/Driver/Options.td<br>
&gt;       cfe/trunk/include/clang/Frontend/CodeGenOptions.def<br>
&gt;       cfe/trunk/lib/CodeGen/CodeGenABITypes.cpp<br>
&gt;       cfe/trunk/lib/CodeGen/CodeGenAction.cpp<br>
&gt;       cfe/trunk/lib/CodeGen/CodeGenFunction.cpp<br>
&gt;       cfe/trunk/lib/CodeGen/CodeGenModule.cpp<br>
&gt;       cfe/trunk/lib/CodeGen/CodeGenModule.h<br>
&gt;       cfe/trunk/lib/CodeGen/CodeGenPGO.cpp<br>
&gt;       cfe/trunk/lib/CodeGen/CodeGenPGO.h<br>
&gt;       cfe/trunk/lib/CodeGen/ModuleBuilder.cpp<br>
&gt;       cfe/trunk/lib/Driver/Tools.cpp<br>
&gt;       cfe/trunk/lib/Frontend/CompilerInvocation.cpp<br>
&gt;<br>
&gt; Modified: cfe/trunk/include/clang/CodeGen/CodeGenABITypes.h<br>
&gt; URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/CodeGenABITypes.h?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff" \
target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/CodeGenABITypes.h?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff</a><br>


&gt; ==============================================================================<br>
 &gt; --- cfe/trunk/include/clang/CodeGen/CodeGenABITypes.h (original)<br>
&gt; +++ cfe/trunk/include/clang/CodeGen/CodeGenABITypes.h Mon Aug   4 13:41:51 \
2014<br> &gt; @@ -39,6 +39,7 @@ class CXXRecordDecl;<br>
&gt;   class CodeGenOptions;<br>
&gt;   class DiagnosticsEngine;<br>
&gt;   class ObjCMethodDecl;<br>
&gt; +class CoverageSourceInfo;<br>
&gt;<br>
&gt;   namespace CodeGen {<br>
&gt;   class CGFunctionInfo;<br>
&gt; @@ -47,7 +48,8 @@ class CodeGenModule;<br>
&gt;   class CodeGenABITypes<br>
&gt;   {<br>
&gt;   public:<br>
&gt; -   CodeGenABITypes(ASTContext &amp;C, llvm::Module &amp;M, const \
llvm::DataLayout &amp;TD);<br> &gt; +   CodeGenABITypes(ASTContext &amp;C, \
llvm::Module &amp;M, const llvm::DataLayout &amp;TD,<br> &gt; +                       \
CoverageSourceInfo *CoverageInfo = nullptr);<br> &gt;      ~CodeGenABITypes();<br>
&gt;<br>
&gt;      /// These methods all forward to methods in the private implementation \
class<br> &gt;<br>
&gt; Modified: cfe/trunk/include/clang/CodeGen/ModuleBuilder.h<br>
&gt; URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/ModuleBuilder.h?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff" \
target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/ModuleBuilder.h?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff</a><br>


&gt; ==============================================================================<br>
 &gt; --- cfe/trunk/include/clang/CodeGen/ModuleBuilder.h (original)<br>
&gt; +++ cfe/trunk/include/clang/CodeGen/ModuleBuilder.h Mon Aug   4 13:41:51 \
2014<br> &gt; @@ -24,6 +24,7 @@ namespace llvm {<br>
&gt;<br>
&gt;   namespace clang {<br>
&gt;      class DiagnosticsEngine;<br>
&gt; +   class CoverageSourceInfo;<br>
&gt;      class LangOptions;<br>
&gt;      class CodeGenOptions;<br>
&gt;      class TargetOptions;<br>
&gt; @@ -44,7 +45,8 @@ namespace clang {<br>
&gt;                                                       const std::string \
&amp;ModuleName,<br> &gt;                                                       const \
CodeGenOptions &amp;CGO,<br> &gt;                                                     \
const TargetOptions &amp;TO,<br> &gt; -                                               \
llvm::LLVMContext&amp; C);<br> &gt; +                                                 \
llvm::LLVMContext&amp; C,<br> &gt; +                                                  \
CoverageSourceInfo *CoverageInfo = nullptr);<br> &gt;   }<br>
&gt;<br>
&gt;   #endif<br>
&gt;<br>
&gt; Modified: cfe/trunk/include/clang/Driver/Options.td<br>
&gt; URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff" \
target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff</a><br>


&gt; ==============================================================================<br>
 &gt; --- cfe/trunk/include/clang/Driver/Options.td (original)<br>
&gt; +++ cfe/trunk/include/clang/Driver/Options.td Mon Aug   4 13:41:51 2014<br>
&gt; @@ -408,6 +408,9 @@ def fprofile_instr_use : Flag&lt;[&quot;-&quot;], \
&quot;fp<br> &gt;   def fprofile_instr_use_EQ : Joined&lt;[&quot;-&quot;], \
&quot;fprofile-instr-use=&quot;&gt;,<br> &gt;         Group&lt;f_Group&gt;, \
Flags&lt;[CC1Option]&gt;,<br> &gt;         HelpText&lt;&quot;Use instrumentation data \
for profile-guided optimization&quot;&gt;;<br> &gt; +def fcoverage_mapping : \
Flag&lt;[&quot;-&quot;], &quot;fcoverage-mapping&quot;&gt;,<br> &gt; +      \
Group&lt;f_Group&gt;, Flags&lt;[CC1Option]&gt;,<br> &gt; +      \
HelpText&lt;&quot;Generate coverage mapping to enable code coverage \
analysis&quot;&gt;;<br> &gt;<br>
&gt;   def fblocks : Flag&lt;[&quot;-&quot;], &quot;fblocks&quot;&gt;, \
Group&lt;f_Group&gt;, Flags&lt;[CC1Option]&gt;,<br> &gt;      \
HelpText&lt;&quot;Enable the &#39;blocks&#39; language feature&quot;&gt;;<br> \
&gt;<br> &gt; Modified: cfe/trunk/include/clang/Frontend/CodeGenOptions.def<br>
&gt; URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenOptions.def?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff" \
target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenOptions.def?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff</a><br>


&gt; ==============================================================================<br>
 &gt; --- cfe/trunk/include/clang/Frontend/CodeGenOptions.def (original)<br>
&gt; +++ cfe/trunk/include/clang/Frontend/CodeGenOptions.def Mon Aug   4 13:41:51 \
2014<br> &gt; @@ -88,6 +88,8 @@ VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///<br>
&gt;<br>
&gt;   CODEGENOPT(ProfileInstrGenerate , 1, 0) ///&lt; Instrument code to \
generate<br> &gt;                                                               \
///&lt; execution counts to use with PGO.<br> &gt; +CODEGENOPT(CoverageMapping , 1, \
0) ///&lt; Generate coverage mapping regions to<br> &gt; +                            \
///&lt; enable code coverage analysis.<br> &gt;<br>
&gt;      /// If -fpcc-struct-return or -freg-struct-return is specified.<br>
&gt;   ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, \
SRCK_Default)<br> &gt;<br>
&gt; Modified: cfe/trunk/lib/CodeGen/CodeGenABITypes.cpp<br>
&gt; URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenABITypes.cpp?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff" \
target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenABITypes.cpp?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff</a><br>


&gt; ==============================================================================<br>
 &gt; --- cfe/trunk/lib/CodeGen/CodeGenABITypes.cpp (original)<br>
&gt; +++ cfe/trunk/lib/CodeGen/CodeGenABITypes.cpp Mon Aug   4 13:41:51 2014<br>
&gt; @@ -26,9 +26,11 @@ using namespace CodeGen;<br>
&gt;<br>
&gt;   CodeGenABITypes::CodeGenABITypes(ASTContext &amp;C,<br>
&gt;                                                    llvm::Module &amp;M,<br>
&gt; -                                                 const llvm::DataLayout \
&amp;TD)<br> &gt; +                                                 const \
llvm::DataLayout &amp;TD,<br> &gt; +                                                 \
CoverageSourceInfo *CoverageInfo)<br> &gt;      : CGO(new CodeGenOptions),<br>
&gt; -      CGM(new CodeGen::CodeGenModule(C, *CGO, M, TD, C.getDiagnostics())) {<br>
&gt; +      CGM(new CodeGen::CodeGenModule(C, *CGO, M, TD, C.getDiagnostics(),<br>
&gt; +                                                    CoverageInfo)) {<br>
&gt;   }<br>
&gt;<br>
&gt;   CodeGenABITypes::~CodeGenABITypes()<br>
&gt;<br>
&gt; Modified: cfe/trunk/lib/CodeGen/CodeGenAction.cpp<br>
&gt; URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenAction.cpp?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff" \
target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenAction.cpp?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff</a><br>


&gt; ==============================================================================<br>
 &gt; --- cfe/trunk/lib/CodeGen/CodeGenAction.cpp (original)<br>
&gt; +++ cfe/trunk/lib/CodeGen/CodeGenAction.cpp Mon Aug   4 13:41:51 2014<br>
&gt; @@ -7,6 +7,7 @@<br>
&gt;   //<br>
&gt;   //===----------------------------------------------------------------------===//<br>
 &gt;<br>
&gt; +#include &quot;CoverageMappingGen.h&quot;<br>
&gt;   #include &quot;clang/CodeGen/CodeGenAction.h&quot;<br>
&gt;   #include &quot;clang/AST/ASTConsumer.h&quot;<br>
&gt;   #include &quot;clang/AST/ASTContext.h&quot;<br>
&gt; @@ -15,6 +16,7 @@<br>
&gt;   #include &quot;clang/Basic/FileManager.h&quot;<br>
&gt;   #include &quot;clang/Basic/SourceManager.h&quot;<br>
&gt;   #include &quot;clang/Basic/TargetInfo.h&quot;<br>
&gt; +#include &quot;clang/Lex/Preprocessor.h&quot;<br>
&gt;   #include &quot;clang/CodeGen/BackendUtil.h&quot;<br>
&gt;   #include &quot;clang/CodeGen/ModuleBuilder.h&quot;<br>
&gt;   #include &quot;clang/Frontend/CompilerInstance.h&quot;<br>
&gt; @@ -59,11 +61,13 @@ namespace clang {<br>
&gt;                                 const TargetOptions &amp;targetopts,<br>
&gt;                                 const LangOptions &amp;langopts, bool \
TimePasses,<br> &gt;                                 const std::string &amp;infile, \
llvm::Module *LinkModule,<br> &gt; -                              raw_ostream *OS, \
LLVMContext &amp;C)<br> &gt; +                              raw_ostream *OS, \
LLVMContext &amp;C,<br> &gt; +                              CoverageSourceInfo \
*CoverageInfo = nullptr)<br> &gt;               : Diags(_Diags), Action(action), \
CodeGenOpts(compopts),<br> &gt;                  TargetOpts(targetopts), \
LangOpts(langopts), AsmOutStream(OS),<br> &gt;                  Context(), \
LLVMIRGeneration(&quot;LLVM IR Generation Time&quot;),<br> &gt; -               \
Gen(CreateLLVMCodeGen(Diags, infile, compopts, targetopts, C)),<br> &gt; +            \
Gen(CreateLLVMCodeGen(Diags, infile, compopts,<br> &gt; +                             \
targetopts, C, CoverageInfo)),<br> &gt;                  LinkModule(LinkModule) {<br>
&gt;            llvm::TimePassesIsEnabled = TimePasses;<br>
&gt;         }<br>
&gt; @@ -636,10 +640,17 @@ ASTConsumer *CodeGenAction::CreateASTCon<br>
&gt;         LinkModuleToUse = ModuleOrErr.get();<br>
&gt;      }<br>
&gt;<br>
&gt; +   CoverageSourceInfo *CoverageInfo = nullptr;<br>
&gt; +   // Add the preprocessor callback only when the coverage mapping is \
generated.<br> &gt; +   if (CI.getCodeGenOpts().CoverageMapping) {<br>
&gt; +      CoverageInfo = new CoverageSourceInfo;<br>
&gt; +      CI.getPreprocessor().addPPCallbacks(CoverageInfo);<br>
&gt; +   }<br>
&gt;      BEConsumer = new BackendConsumer(BA, CI.getDiagnostics(), \
CI.getCodeGenOpts(),<br> &gt;                                                       \
CI.getTargetOpts(), CI.getLangOpts(),<br> &gt;                                        \
CI.getFrontendOpts().ShowTimers, InFile,<br> &gt; -                                   \
LinkModuleToUse, OS.release(), *VMContext);<br> &gt; +                                \
LinkModuleToUse, OS.release(), *VMContext,<br> &gt; +                                 \
CoverageInfo);<br> &gt;      return BEConsumer;<br>
&gt;   }<br>
&gt;<br>
&gt;<br>
&gt; Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp<br>
&gt; URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff" \
target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff</a><br>


&gt; ==============================================================================<br>
 &gt; --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)<br>
&gt; +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Mon Aug   4 13:41:51 2014<br>
&gt; @@ -829,6 +829,7 @@ void CodeGenFunction::GenerateCode(Globa<br>
&gt;      StartFunction(GD, ResTy, Fn, FnInfo, Args, Loc, BodyRange.getBegin());<br>
&gt;<br>
&gt;      // Generate the body of the function.<br>
&gt; +   PGO.checkGlobalDecl(GD);<br>
&gt;      PGO.assignRegionCounters(GD.getDecl(), CurFn);<br>
&gt;      if (isa&lt;CXXDestructorDecl&gt;(FD))<br>
&gt;         EmitDestructorBody(Args);<br>
&gt;<br>
&gt; Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp<br>
&gt; URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff" \
target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff</a><br>


&gt; ==============================================================================<br>
 &gt; --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)<br>
&gt; +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon Aug   4 13:41:51 2014<br>
&gt; @@ -21,6 +21,7 @@<br>
&gt;   #include &quot;CGOpenMPRuntime.h&quot;<br>
&gt;   #include &quot;CodeGenFunction.h&quot;<br>
&gt;   #include &quot;CodeGenPGO.h&quot;<br>
&gt; +#include &quot;CoverageMappingGen.h&quot;<br>
&gt;   #include &quot;CodeGenTBAA.h&quot;<br>
&gt;   #include &quot;TargetInfo.h&quot;<br>
&gt;   #include &quot;clang/AST/ASTContext.h&quot;<br>
&gt; @@ -74,7 +75,8 @@ static CGCXXABI *createCXXABI(CodeGenMod<br>
&gt;<br>
&gt;   CodeGenModule::CodeGenModule(ASTContext &amp;C, const CodeGenOptions \
&amp;CGO,<br> &gt;                                              llvm::Module &amp;M, \
const llvm::DataLayout &amp;TD,<br> &gt; -                                           \
DiagnosticsEngine &amp;diags)<br> &gt; +                                           \
DiagnosticsEngine &amp;diags,<br> &gt; +                                           \
CoverageSourceInfo *CoverageInfo)<br> &gt;         : Context(C), \
LangOpts(C.getLangOpts()), CodeGenOpts(CGO), TheModule(M),<br> &gt;            \
Diags(diags), TheDataLayout(TD), Target(C.getTargetInfo()),<br> &gt;            \
ABI(createCXXABI(*this)), VMContext(M.getContext()), TBAA(nullptr),<br> &gt; @@ \
-146,6 +148,11 @@ CodeGenModule::CodeGenModule(ASTContext<br> &gt;            \
getDiags().Report(DiagID) &lt;&lt; EC.message();<br> &gt;         }<br>
&gt;      }<br>
&gt; +<br>
&gt; +   // If coverage mapping generation is enabled, create the<br>
&gt; +   // CoverageMappingModuleGen object.<br>
&gt; +   if (CodeGenOpts.CoverageMapping)<br>
&gt; +      CoverageMapping.reset(new CoverageMappingModuleGen(*this, \
*CoverageInfo));<br> &gt;   }<br>
&gt;<br>
&gt;   CodeGenModule::~CodeGenModule() {<br>
&gt; @@ -344,6 +351,9 @@ void CodeGenModule::Release() {<br>
&gt;      EmitCtorList(GlobalDtors, &quot;llvm.global_dtors&quot;);<br>
&gt;      EmitGlobalAnnotations();<br>
&gt;      EmitStaticExternCAliases();<br>
&gt; +   EmitDeferredUnusedCoverageMappings();<br>
&gt; +   if (CoverageMapping)<br>
&gt; +      CoverageMapping-&gt;emit();<br>
&gt;      emitLLVMUsed();<br>
&gt;<br>
&gt;      if (CodeGenOpts.Autolink &amp;&amp;<br>
&gt; @@ -2989,6 +2999,9 @@ void CodeGenModule::EmitTopLevelDecl(Dec<br>
&gt;            return;<br>
&gt;<br>
&gt;         EmitGlobal(cast&lt;FunctionDecl&gt;(D));<br>
&gt; +      // Always provide some coverage mapping<br>
&gt; +      // even for the functions that aren&#39;t emitted.<br>
&gt; +      AddDeferredUnusedCoverageMapping(D);<br>
&gt;         break;<br>
&gt;<br>
&gt;      case Decl::Var:<br>
&gt; @@ -3138,6 +3151,80 @@ void CodeGenModule::EmitTopLevelDecl(Dec<br>
&gt;      }<br>
&gt;   }<br>
&gt;<br>
&gt; +void CodeGenModule::AddDeferredUnusedCoverageMapping(Decl *D) {<br>
&gt; +   // Do we need to generate coverage mapping?<br>
&gt; +   if (!CodeGenOpts.CoverageMapping)<br>
&gt; +      return;<br>
&gt; +   switch (D-&gt;getKind()) {<br>
&gt; +   case Decl::CXXConversion:<br>
&gt; +   case Decl::CXXMethod:<br>
&gt; +   case Decl::Function:<br>
&gt; +   case Decl::ObjCMethod:<br>
&gt; +   case Decl::CXXConstructor:<br>
&gt; +   case Decl::CXXDestructor: {<br>
&gt; +      if (!cast&lt;FunctionDecl&gt;(D)-&gt;hasBody())<br>
&gt; +         return;<br>
&gt; +      auto I = DeferredEmptyCoverageMappingDecls.find(D);<br>
&gt; +      if (I == DeferredEmptyCoverageMappingDecls.end())<br>
&gt; +         DeferredEmptyCoverageMappingDecls[D] = true;<br>
&gt; +      break;<br>
&gt; +   }<br>
&gt; +   default:<br>
&gt; +      break;<br>
&gt; +   };<br>
&gt; +}<br>
&gt; +<br>
&gt; +void CodeGenModule::ClearUnusedCoverageMapping(const Decl *D) {<br>
&gt; +   // Do we need to generate coverage mapping?<br>
&gt; +   if (!CodeGenOpts.CoverageMapping)<br>
&gt; +      return;<br>
&gt; +   if (const auto *Fn = dyn_cast&lt;FunctionDecl&gt;(D)) {<br>
&gt; +      if (Fn-&gt;isTemplateInstantiation())<br>
&gt; +         ClearUnusedCoverageMapping(Fn-&gt;getTemplateInstantiationPattern());<br>
 &gt; +   }<br>
&gt; +   auto I = DeferredEmptyCoverageMappingDecls.find(D);<br>
&gt; +   if (I == DeferredEmptyCoverageMappingDecls.end())<br>
&gt; +      DeferredEmptyCoverageMappingDecls[D] = false;<br>
&gt; +   else<br>
&gt; +      I-&gt;second = false;<br>
&gt; +}<br>
&gt; +<br>
&gt; +void CodeGenModule::EmitDeferredUnusedCoverageMappings() {<br>
&gt; +   for (const auto I : DeferredEmptyCoverageMappingDecls) {<br>
&gt; +      if (!I.second)<br>
&gt; +         continue;<br>
&gt; +      const auto *D = I.first;<br>
&gt; +      switch (D-&gt;getKind()) {<br>
&gt; +      case Decl::CXXConversion:<br>
&gt; +      case Decl::CXXMethod:<br>
&gt; +      case Decl::Function:<br>
&gt; +      case Decl::ObjCMethod: {<br>
&gt; +         CodeGenPGO PGO(*this);<br>
&gt; +         GlobalDecl GD(cast&lt;FunctionDecl&gt;(D));<br>
&gt; +         PGO.emitEmptyCounterMapping(D, getMangledName(GD),<br>
&gt; +                                                   getFunctionLinkage(GD));<br>
&gt; +         break;<br>
&gt; +      }<br>
&gt; +      case Decl::CXXConstructor: {<br>
&gt; +         CodeGenPGO PGO(*this);<br>
&gt; +         GlobalDecl GD(cast&lt;CXXConstructorDecl&gt;(D), Ctor_Base);<br>
&gt; +         PGO.emitEmptyCounterMapping(D, getMangledName(GD),<br>
&gt; +                                                   getFunctionLinkage(GD));<br>
&gt; +         break;<br>
&gt; +      }<br>
&gt; +      case Decl::CXXDestructor: {<br>
&gt; +         CodeGenPGO PGO(*this);<br>
&gt; +         GlobalDecl GD(cast&lt;CXXDestructorDecl&gt;(D), Dtor_Base);<br>
&gt; +         PGO.emitEmptyCounterMapping(D, getMangledName(GD),<br>
&gt; +                                                   getFunctionLinkage(GD));<br>
&gt; +         break;<br>
&gt; +      }<br>
&gt; +      default:<br>
&gt; +         break;<br>
&gt; +      };<br>
&gt; +   }<br>
&gt; +}<br>
&gt; +<br>
&gt;   /// Turns the given pointer into a constant.<br>
&gt;   static llvm::Constant *GetPointerConstant(llvm::LLVMContext &amp;Context,<br>
&gt;                                                                  const void \
*Ptr) {<br> &gt;<br>
&gt; Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h<br>
&gt; URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff" \
target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff</a><br>


&gt; ==============================================================================<br>
 &gt; --- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)<br>
&gt; +++ cfe/trunk/lib/CodeGen/CodeGenModule.h Mon Aug   4 13:41:51 2014<br>
&gt; @@ -73,6 +73,7 @@ class DiagnosticsEngine;<br>
&gt;   class AnnotateAttr;<br>
&gt;   class CXXDestructorDecl;<br>
&gt;   class Module;<br>
&gt; +class CoverageSourceInfo;<br>
&gt;<br>
&gt;   namespace CodeGen {<br>
&gt;<br>
&gt; @@ -87,6 +88,7 @@ class CGOpenMPRuntime;<br>
&gt;   class CGCUDARuntime;<br>
&gt;   class BlockFieldFlags;<br>
&gt;   class FunctionArgList;<br>
&gt; +class CoverageMappingModuleGen;<br>
&gt;<br>
&gt;   struct OrderGlobalInits {<br>
&gt;      unsigned int priority;<br>
&gt; @@ -477,10 +479,15 @@ class CodeGenModule : public CodeGenType<br>
&gt;      std::unique_ptr&lt;SanitizerMetadata&gt; SanitizerMD;<br>
&gt;<br>
&gt;      /// @}<br>
&gt; +<br>
&gt; +   llvm::DenseMap&lt;const Decl *, bool&gt; \
DeferredEmptyCoverageMappingDecls;<br> &gt; +<br>
&gt; +   std::unique_ptr&lt;CoverageMappingModuleGen&gt; CoverageMapping;<br>
&gt;   public:<br>
&gt;      CodeGenModule(ASTContext &amp;C, const CodeGenOptions &amp;CodeGenOpts,<br>
&gt;                           llvm::Module &amp;M, const llvm::DataLayout \
&amp;TD,<br> &gt; -                        DiagnosticsEngine &amp;Diags);<br>
&gt; +                        DiagnosticsEngine &amp;Diags,<br>
&gt; +                        CoverageSourceInfo *CoverageInfo = nullptr);<br>
&gt;<br>
&gt;      ~CodeGenModule();<br>
&gt;<br>
&gt; @@ -529,6 +536,10 @@ public:<br>
&gt;      InstrProfStats &amp;getPGOStats() { return PGOStats; }<br>
&gt;      llvm::IndexedInstrProfReader *getPGOReader() const { return \
PGOReader.get(); }<br> &gt;<br>
&gt; +   CoverageMappingModuleGen *getCoverageMapping() const {<br>
&gt; +      return CoverageMapping.get();<br>
&gt; +   }<br>
&gt; +<br>
&gt;      llvm::Constant *getStaticLocalDeclAddress(const VarDecl *D) {<br>
&gt;         return StaticLocalDeclMap[D];<br>
&gt;      }<br>
&gt; @@ -815,6 +826,18 @@ public:<br>
&gt;      /// Emit code for a single top level declaration.<br>
&gt;      void EmitTopLevelDecl(Decl *D);<br>
&gt;<br>
&gt; +   /// \brief Stored a deferred empty coverage mapping for an unused<br>
&gt; +   /// and thus uninstrumented top level declaration.<br>
&gt; +   void AddDeferredUnusedCoverageMapping(Decl *D);<br>
&gt; +<br>
&gt; +   /// \brief Remove the deferred empty coverage mapping as this<br>
&gt; +   /// declaration is actually instrumented.<br>
&gt; +   void ClearUnusedCoverageMapping(const Decl *D);<br>
&gt; +<br>
&gt; +   /// \brief Emit all the deferred coverage mappings<br>
&gt; +   /// for the uninstrumented functions.<br>
&gt; +   void EmitDeferredUnusedCoverageMappings();<br>
&gt; +<br>
&gt;      /// Tell the consumer that this variable has been instantiated.<br>
&gt;      void HandleCXXStaticMemberVarInstantiation(VarDecl *VD);<br>
&gt;<br>
&gt;<br>
&gt; Modified: cfe/trunk/lib/CodeGen/CodeGenPGO.cpp<br>
&gt; URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenPGO.cpp?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff" \
target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenPGO.cpp?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff</a><br>


&gt; ==============================================================================<br>
 &gt; --- cfe/trunk/lib/CodeGen/CodeGenPGO.cpp (original)<br>
&gt; +++ cfe/trunk/lib/CodeGen/CodeGenPGO.cpp Mon Aug   4 13:41:51 2014<br>
&gt; @@ -13,6 +13,7 @@<br>
&gt;<br>
&gt;   #include &quot;CodeGenPGO.h&quot;<br>
&gt;   #include &quot;CodeGenFunction.h&quot;<br>
&gt; +#include &quot;CoverageMappingGen.h&quot;<br>
&gt;   #include &quot;clang/AST/RecursiveASTVisitor.h&quot;<br>
&gt;   #include &quot;clang/AST/StmtVisitor.h&quot;<br>
&gt;   #include &quot;llvm/IR/MDBuilder.h&quot;<br>
&gt; @@ -24,8 +25,9 @@<br>
&gt;   using namespace clang;<br>
&gt;   using namespace CodeGen;<br>
&gt;<br>
&gt; -void CodeGenPGO::setFuncName(llvm::Function *Fn) {<br>
&gt; -   RawFuncName = Fn-&gt;getName();<br>
&gt; +void CodeGenPGO::setFuncName(StringRef Name,<br>
&gt; +                                           llvm::GlobalValue::LinkageTypes \
Linkage) {<br> &gt; +   RawFuncName = Name;<br>
&gt;<br>
&gt;      // Function names may be prefixed with a binary &#39;1&#39; to indicate<br>
&gt;      // that the backend should not modify the symbols due to any platform<br>
&gt; @@ -33,7 +35,7 @@ void CodeGenPGO::setFuncName(llvm::Funct<br>
&gt;      if (RawFuncName[0] == &#39;\1&#39;)<br>
&gt;         RawFuncName = RawFuncName.substr(1);<br>
&gt;<br>
&gt; -   if (!Fn-&gt;hasLocalLinkage()) {<br>
&gt; +   if (!llvm::GlobalValue::isLocalLinkage(Linkage)) {<br>
&gt;         PrefixedFuncName.reset(new std::string(RawFuncName));<br>
&gt;         return;<br>
&gt;      }<br>
&gt; @@ -49,6 +51,27 @@ void CodeGenPGO::setFuncName(llvm::Funct<br>
&gt;      PrefixedFuncName-&gt;append(RawFuncName);<br>
&gt;   }<br>
&gt;<br>
&gt; +void CodeGenPGO::setFuncName(llvm::Function *Fn) {<br>
&gt; +   setFuncName(Fn-&gt;getName(), Fn-&gt;getLinkage());<br>
&gt; +}<br>
&gt; +<br>
&gt; +void CodeGenPGO::setVarLinkage(llvm::GlobalValue::LinkageTypes Linkage) {<br>
&gt; +   // Set the linkage for variables based on the function linkage.   Usually, \
we<br> &gt; +   // want to match it, but available_externally and extern_weak both \
have the<br> &gt; +   // wrong semantics.<br>
&gt; +   VarLinkage = Linkage;<br>
&gt; +   switch (VarLinkage) {<br>
&gt; +   case llvm::GlobalValue::ExternalWeakLinkage:<br>
&gt; +      VarLinkage = llvm::GlobalValue::LinkOnceAnyLinkage;<br>
&gt; +      break;<br>
&gt; +   case llvm::GlobalValue::AvailableExternallyLinkage:<br>
&gt; +      VarLinkage = llvm::GlobalValue::LinkOnceODRLinkage;<br>
&gt; +      break;<br>
&gt; +   default:<br>
&gt; +      break;<br>
&gt; +   }<br>
&gt; +}<br>
&gt; +<br>
&gt;   static llvm::Function *getRegisterFunc(CodeGenModule &amp;CGM) {<br>
&gt;      return CGM.getModule().getFunction(&quot;__llvm_profile_register_functions&quot;);<br>
 &gt;   }<br>
&gt; @@ -120,37 +143,48 @@ llvm::GlobalVariable *CodeGenPGO::buildD<br>
&gt;      auto *Int64Ty = llvm::Type::getInt64Ty(Ctx);<br>
&gt;      auto *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx);<br>
&gt;      auto *Int64PtrTy = llvm::Type::getInt64PtrTy(Ctx);<br>
&gt; -   llvm::Type *DataTypes[] = {<br>
&gt; -      Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int64PtrTy<br>
&gt; -   };<br>
&gt; -   auto *DataTy = llvm::StructType::get(Ctx, makeArrayRef(DataTypes));<br>
&gt; -   llvm::Constant *DataVals[] = {<br>
&gt; -      llvm::ConstantInt::get(Int32Ty, getFuncName().size()),<br>
&gt; -      llvm::ConstantInt::get(Int32Ty, NumRegionCounters),<br>
&gt; -      llvm::ConstantInt::get(Int64Ty, FunctionHash),<br>
&gt; -      llvm::ConstantExpr::getBitCast(Name, Int8PtrTy),<br>
&gt; -      llvm::ConstantExpr::getBitCast(RegionCounters, Int64PtrTy)<br>
&gt; -   };<br>
&gt; -   auto *Data =<br>
&gt; -      new llvm::GlobalVariable(CGM.getModule(), DataTy, true, VarLinkage,<br>
&gt; -                                           llvm::ConstantStruct::get(DataTy, \
DataVals),<br> &gt; -                                           \
getFuncVarName(&quot;data&quot;));<br> &gt; -<br>
&gt; -   // All the data should be packed into an array in its own section.<br>
&gt; -   Data-&gt;setSection(getDataSection(CGM));<br>
&gt; -   Data-&gt;setAlignment(8);<br>
&gt; +   llvm::GlobalVariable *Data = nullptr;<br>
&gt; +   if (RegionCounters) {<br>
&gt; +      llvm::Type *DataTypes[] = {<br>
&gt; +         Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int64PtrTy<br>
&gt; +      };<br>
&gt; +      auto *DataTy = llvm::StructType::get(Ctx, makeArrayRef(DataTypes));<br>
&gt; +      llvm::Constant *DataVals[] = {<br>
&gt; +         llvm::ConstantInt::get(Int32Ty, getFuncName().size()),<br>
&gt; +         llvm::ConstantInt::get(Int32Ty, NumRegionCounters),<br>
&gt; +         llvm::ConstantInt::get(Int64Ty, FunctionHash),<br>
&gt; +         llvm::ConstantExpr::getBitCast(Name, Int8PtrTy),<br>
&gt; +         llvm::ConstantExpr::getBitCast(RegionCounters, Int64PtrTy)<br>
&gt; +      };<br>
&gt; +      Data =<br>
&gt; +         new llvm::GlobalVariable(CGM.getModule(), DataTy, true, \
VarLinkage,<br> &gt; +                                              \
llvm::ConstantStruct::get(DataTy, DataVals),<br> &gt; +                               \
getFuncVarName(&quot;data&quot;));<br> &gt; +<br>
&gt; +      // All the data should be packed into an array in its own section.<br>
&gt; +      Data-&gt;setSection(getDataSection(CGM));<br>
&gt; +      Data-&gt;setAlignment(8);<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   // Create coverage mapping data variable.<br>
&gt; +   if (!CoverageMapping.empty())<br>
&gt; +      CGM.getCoverageMapping()-&gt;addFunctionMappingRecord(Name,<br>
&gt; +                                                                                \
getFuncName().size(),<br> &gt; +                                                      \
CoverageMapping);<br> &gt;<br>
&gt;      // Hide all these symbols so that we correctly get a copy for each<br>
&gt;      // executable.   The profile format expects names and counters to be<br>
&gt;      // contiguous, so references into shared objects would be invalid.<br>
&gt;      if (!llvm::GlobalValue::isLocalLinkage(VarLinkage)) {<br>
&gt;         Name-&gt;setVisibility(llvm::GlobalValue::HiddenVisibility);<br>
&gt; -      Data-&gt;setVisibility(llvm::GlobalValue::HiddenVisibility);<br>
&gt; -      RegionCounters-&gt;setVisibility(llvm::GlobalValue::HiddenVisibility);<br>
 &gt; +      if (Data) {<br>
&gt; +         Data-&gt;setVisibility(llvm::GlobalValue::HiddenVisibility);<br>
&gt; +         RegionCounters-&gt;setVisibility(llvm::GlobalValue::HiddenVisibility);<br>
 &gt; +      }<br>
&gt;      }<br>
&gt;<br>
&gt;      // Make sure the data doesn&#39;t get deleted.<br>
&gt; -   CGM.addUsedGlobal(Data);<br>
&gt; +   if (Data) CGM.addUsedGlobal(Data);<br>
&gt;      return Data;<br>
&gt;   }<br>
&gt;<br>
&gt; @@ -807,6 +841,20 @@ static void emitRuntimeHook(CodeGenModul<br>
&gt;      CGM.addUsedGlobal(User);<br>
&gt;   }<br>
&gt;<br>
&gt; +void CodeGenPGO::checkGlobalDecl(GlobalDecl GD) {<br>
&gt; +   // Make sure we only emit coverage mapping for one \
constructor/destructor.<br> &gt; +   // Clang emits several functions for the \
constructor and the destructor of<br> &gt; +   // a class. Every function is \
instrumented, but we only want to provide<br> &gt; +   // coverage for one of them. \
Because of that we only emit the coverage mapping<br> &gt; +   // for the base \
constructor/destructor.<br> &gt; +   if ((isa&lt;CXXConstructorDecl&gt;(GD.getDecl()) \
&amp;&amp;<br> &gt; +          GD.getCtorType() != Ctor_Base) ||<br>
&gt; +         (isa&lt;CXXDestructorDecl&gt;(GD.getDecl()) &amp;&amp;<br>
&gt; +          GD.getDtorType() != Dtor_Base)) {<br>
&gt; +      SkipCoverageMapping = true;<br>
&gt; +   }<br>
&gt; +}<br>
&gt; +<br>
&gt;   void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) {<br>
&gt;      bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate;<br>
&gt;      llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();<br>
&gt; @@ -814,27 +862,16 @@ void CodeGenPGO::assignRegionCounters(co<br>
&gt;         return;<br>
&gt;      if (D-&gt;isImplicit())<br>
&gt;         return;<br>
&gt; +   CGM.ClearUnusedCoverageMapping(D);<br>
&gt;      setFuncName(Fn);<br>
&gt; -<br>
&gt; -   // Set the linkage for variables based on the function linkage.   Usually, \
we<br> &gt; -   // want to match it, but available_externally and extern_weak both \
have the<br> &gt; -   // wrong semantics.<br>
&gt; -   VarLinkage = Fn-&gt;getLinkage();<br>
&gt; -   switch (VarLinkage) {<br>
&gt; -   case llvm::GlobalValue::ExternalWeakLinkage:<br>
&gt; -      VarLinkage = llvm::GlobalValue::LinkOnceAnyLinkage;<br>
&gt; -      break;<br>
&gt; -   case llvm::GlobalValue::AvailableExternallyLinkage:<br>
&gt; -      VarLinkage = llvm::GlobalValue::LinkOnceODRLinkage;<br>
&gt; -      break;<br>
&gt; -   default:<br>
&gt; -      break;<br>
&gt; -   }<br>
&gt; +   setVarLinkage(Fn-&gt;getLinkage());<br>
&gt;<br>
&gt;      mapRegionCounters(D);<br>
&gt;      if (InstrumentRegions) {<br>
&gt;         emitRuntimeHook(CGM);<br>
&gt;         emitCounterVariables();<br>
&gt; +      if (CGM.getCodeGenOpts().CoverageMapping)<br>
&gt; +         emitCounterRegionMapping(D);<br>
&gt;      }<br>
&gt;      if (PGOReader) {<br>
&gt;         SourceManager &amp;SM = CGM.getContext().getSourceManager();<br>
&gt; @@ -860,6 +897,45 @@ void CodeGenPGO::mapRegionCounters(const<br>
&gt;      FunctionHash = Walker.Hash.finalize();<br>
&gt;   }<br>
&gt;<br>
&gt; +void CodeGenPGO::emitCounterRegionMapping(const Decl *D) {<br>
&gt; +   if (SkipCoverageMapping)<br>
&gt; +      return;<br>
&gt; +   // Don&#39;t map the functions inside the system headers<br>
&gt; +   auto Loc = D-&gt;getBody()-&gt;getLocStart();<br>
&gt; +   if (CGM.getContext().getSourceManager().isInSystemHeader(Loc))<br>
&gt; +      return;<br>
&gt; +<br>
&gt; +   llvm::raw_string_ostream OS(CoverageMapping);<br>
&gt; +   CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),<br>
&gt; +                                                \
CGM.getContext().getSourceManager(),<br> &gt; +                                       \
CGM.getLangOpts(), RegionCounterMap.get(),<br> &gt; +                                 \
NumRegionCounters);<br> &gt; +   MappingGen.emitCounterMapping(D, OS);<br>
&gt; +   OS.flush();<br>
&gt; +}<br>
&gt; +<br>
&gt; +void<br>
&gt; +CodeGenPGO::emitEmptyCounterMapping(const Decl *D, StringRef FuncName,<br>
&gt; +                                                      \
llvm::GlobalValue::LinkageTypes Linkage) {<br> &gt; +   if (SkipCoverageMapping)<br>
&gt; +      return;<br>
&gt; +   setFuncName(FuncName, Linkage);<br>
&gt; +   setVarLinkage(Linkage);<br>
&gt; +<br>
&gt; +   // Don&#39;t map the functions inside the system headers<br>
&gt; +   auto Loc = D-&gt;getBody()-&gt;getLocStart();<br>
&gt; +   if (CGM.getContext().getSourceManager().isInSystemHeader(Loc))<br>
&gt; +      return;<br>
&gt; +<br>
&gt; +   llvm::raw_string_ostream OS(CoverageMapping);<br>
&gt; +   CoverageMappingGen MappingGen(*CGM.getCoverageMapping(),<br>
&gt; +                                                \
CGM.getContext().getSourceManager(),<br> &gt; +                                       \
CGM.getLangOpts());<br> &gt; +   MappingGen.emitEmptyMapping(D, OS);<br>
&gt; +   OS.flush();<br>
&gt; +   buildDataVar();<br>
&gt; +}<br>
&gt; +<br>
&gt;   void CodeGenPGO::computeRegionCounts(const Decl *D) {<br>
&gt;      StmtCountMap.reset(new llvm::DenseMap&lt;const Stmt *, uint64_t&gt;);<br>
&gt;      ComputeRegionCounts Walker(*StmtCountMap, *this);<br>
&gt;<br>
&gt; Modified: cfe/trunk/lib/CodeGen/CodeGenPGO.h<br>
&gt; URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenPGO.h?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff" \
target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenPGO.h?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff</a><br>


&gt; ==============================================================================<br>
 &gt; --- cfe/trunk/lib/CodeGen/CodeGenPGO.h (original)<br>
&gt; +++ cfe/trunk/lib/CodeGen/CodeGenPGO.h Mon Aug   4 13:41:51 2014<br>
&gt; @@ -42,11 +42,16 @@ private:<br>
&gt;      std::unique_ptr&lt;llvm::DenseMap&lt;const Stmt *, uint64_t&gt;&gt; \
StmtCountMap;<br> &gt;      std::unique_ptr&lt;std::vector&lt;uint64_t&gt;&gt; \
RegionCounts;<br> &gt;      uint64_t CurrentRegionCount;<br>
&gt; +   std::string CoverageMapping;<br>
&gt; +   /// \brief A flag that is set to true when this function doesn&#39;t \
need<br> &gt; +   /// to have coverage mapping data.<br>
&gt; +   bool SkipCoverageMapping;<br>
&gt;<br>
&gt;   public:<br>
&gt;      CodeGenPGO(CodeGenModule &amp;CGM)<br>
&gt;            : CGM(CGM), NumRegionCounters(0), FunctionHash(0),<br>
&gt; -            RegionCounters(nullptr), CurrentRegionCount(0) {}<br>
&gt; +            RegionCounters(nullptr), CurrentRegionCount(0),<br>
&gt; +            SkipCoverageMapping(false) {}<br>
&gt;<br>
&gt;      /// Whether or not we have PGO region data for the current function. This \
is<br> &gt;      /// false both when we have no data at all and when our data has \
been<br> &gt; @@ -99,6 +104,8 @@ public:<br>
&gt;      llvm::MDNode *createBranchWeights(ArrayRef&lt;uint64_t&gt; Weights);<br>
&gt;      llvm::MDNode *createLoopWeights(const Stmt *Cond, RegionCounter \
&amp;Cnt);<br> &gt;<br>
&gt; +   /// Check if we need to emit coverage mapping for a given declaration<br>
&gt; +   void checkGlobalDecl(GlobalDecl GD);<br>
&gt;      /// Assign counters to regions and configure them for PGO of a given<br>
&gt;      /// function. Does nothing if instrumentation is not enabled and either<br>
&gt;      /// generates global variables or associates PGO data with each of the<br>
&gt; @@ -111,9 +118,14 @@ public:<br>
&gt;      void destroyRegionCounters();<br>
&gt;      /// Emit static initialization code, if any.<br>
&gt;      static llvm::Function *emitInitialization(CodeGenModule &amp;CGM);<br>
&gt; -<br>
&gt; +   /// Emit a coverage mapping range with a counter zero<br>
&gt; +   /// for an unused declaration.<br>
&gt; +   void emitEmptyCounterMapping(const Decl *D, StringRef FuncName,<br>
&gt; +                                              llvm::GlobalValue::LinkageTypes \
Linkage);<br> &gt;   private:<br>
&gt;      void setFuncName(llvm::Function *Fn);<br>
&gt; +   void setFuncName(StringRef Name, llvm::GlobalValue::LinkageTypes \
Linkage);<br> &gt; +   void setVarLinkage(llvm::GlobalValue::LinkageTypes \
Linkage);<br> &gt;      void mapRegionCounters(const Decl *D);<br>
&gt;      void computeRegionCounts(const Decl *D);<br>
&gt;      void applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,<br>
&gt; @@ -122,6 +134,7 @@ private:<br>
&gt;                                       bool IsInMainFile);<br>
&gt;      void emitCounterVariables();<br>
&gt;      llvm::GlobalVariable *buildDataVar();<br>
&gt; +   void emitCounterRegionMapping(const Decl *D);<br>
&gt;<br>
&gt;      /// Emit code to increment the counter at the given index<br>
&gt;      void emitCounterIncrement(CGBuilderTy &amp;Builder, unsigned Counter);<br>
&gt;<br>
&gt; Added: cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp<br>
&gt; URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp?rev=214752&amp;view=auto" \
target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp?rev=214752&amp;view=auto</a><br>


&gt; ==============================================================================<br>
 &gt; --- cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp (added)<br>
&gt; +++ cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp Mon Aug   4 13:41:51 2014<br>
&gt; @@ -0,0 +1,1166 @@<br>
&gt; +//===--- CoverageMappingGen.cpp - Coverage mapping generation ---*- C++ \
-*-===//<br> &gt; +//<br>
&gt; +//                               The LLVM Compiler Infrastructure<br>
&gt; +//<br>
&gt; +// This file is distributed under the University of Illinois Open Source<br>
&gt; +// License. See LICENSE.TXT for details.<br>
&gt; +//<br>
&gt; +//===----------------------------------------------------------------------===//<br>
 &gt; +//<br>
&gt; +// Instrumentation-based code coverage mapping generator<br>
&gt; +//<br>
&gt; +//===----------------------------------------------------------------------===//<br>
 &gt; +<br>
&gt; +#include &quot;CoverageMappingGen.h&quot;<br>
&gt; +#include &quot;CodeGenFunction.h&quot;<br>
&gt; +#include &quot;clang/AST/StmtVisitor.h&quot;<br>
&gt; +#include &quot;clang/Lex/Lexer.h&quot;<br>
&gt; +#include &quot;llvm/ProfileData/InstrProfReader.h&quot;<br>
&gt; +#include &quot;llvm/ProfileData/CoverageMapping.h&quot;<br>
&gt; +#include &quot;llvm/ProfileData/CoverageMappingWriter.h&quot;<br>
&gt; +#include &quot;llvm/Support/FileSystem.h&quot;<br>
&gt; +<br>
&gt; +using namespace clang;<br>
&gt; +using namespace CodeGen;<br>
&gt; +using namespace llvm::coverage;<br>
&gt; +<br>
&gt; +void CoverageSourceInfo::SourceRangeSkipped(SourceRange Range) {<br>
&gt; +   SkippedRanges.push_back(Range);<br>
&gt; +}<br>
&gt; +<br>
&gt; +namespace {<br>
&gt; +<br>
&gt; +/// \brief A region of source code that can be mapped to a counter.<br>
&gt; +struct SourceMappingRegion {<br>
&gt; +   enum RegionFlags {<br>
&gt; +      /// \brief This region won&#39;t be emitted if it wasn&#39;t \
extended.<br> &gt; +      /// This is useful so that we won&#39;t emit source ranges \
for single tokens<br> &gt; +      /// that we don&#39;t really care that much about, \
like:<br> &gt; +      ///    the &#39;(&#39; token in #define MACRO (<br>
&gt; +      IgnoreIfNotExtended = 0x0001,<br>
&gt; +   };<br>
&gt; +<br>
&gt; +   FileID File, MacroArgumentFile;<br>
&gt; +<br>
&gt; +   Counter Count;<br>
&gt; +<br>
&gt; +   /// \brief A statement that initiated the count of Zero.<br>
&gt; +   ///<br>
&gt; +   /// This initiator statement is useful to prevent merging of unreachable<br>
&gt; +   /// regions with different statements that caused the counter to become<br>
&gt; +   /// unreachable.<br>
&gt; +   const Stmt *UnreachableInitiator;<br>
&gt; +<br>
&gt; +   /// \brief A statement that separates certain mapping regions into \
groups.<br> &gt; +   ///<br>
&gt; +   /// The group statement is sometimes useful when we are emitting the \
source<br> &gt; +   /// regions not in their correct lexical order, e.g. the regions \
for the<br> &gt; +   /// incrementation expression in the &#39;for&#39; construct. By \
marking the regions<br> &gt; +   /// in the incrementation expression with the group \
statement, we avoid the<br> &gt; +   /// merging of the regions from the \
incrementation expression and the loop&#39;s<br> &gt; +   /// body.<br>
&gt; +   const Stmt *Group;<br>
&gt; +<br>
&gt; +   /// \brief The region&#39;s starting location.<br>
&gt; +   SourceLocation LocStart;<br>
&gt; +<br>
&gt; +   /// \brief The region&#39;s ending location.<br>
&gt; +   SourceLocation LocEnd, AlternativeLocEnd;<br>
&gt; +   unsigned Flags;<br>
&gt; +   CounterMappingRegion::RegionKind Kind;<br>
&gt; +<br>
&gt; +   SourceMappingRegion(FileID File, FileID MacroArgumentFile, Counter \
Count,<br> &gt; +                                 const Stmt *UnreachableInitiator, \
const Stmt *Group,<br> &gt; +                                 SourceLocation \
LocStart, SourceLocation LocEnd,<br> &gt; +                                 unsigned \
Flags = 0,<br> &gt; +                                 \
CounterMappingRegion::RegionKind Kind =<br> &gt; +                                    \
CounterMappingRegion::CodeRegion)<br> &gt; +         : File(File), \
MacroArgumentFile(MacroArgumentFile), Count(Count),<br> &gt; +            \
UnreachableInitiator(UnreachableInitiator), Group(Group),<br> &gt; +            \
LocStart(LocStart), LocEnd(LocEnd), AlternativeLocEnd(LocStart),<br> &gt; +           \
Flags(Flags), Kind(Kind) {}<br> &gt; +<br>
&gt; +   bool hasFlag(RegionFlags Flag) const { return (Flags &amp; Flag) != 0; }<br>
&gt; +<br>
&gt; +   void setFlag(RegionFlags Flag) { Flags |= Flag; }<br>
&gt; +<br>
&gt; +   void clearFlag(RegionFlags Flag) { Flags &amp;= ~Flag; }<br>
&gt; +<br>
&gt; +   /// \brief Return true if two regions can be merged together.<br>
&gt; +   bool isMergeable(SourceMappingRegion &amp;R) {<br>
&gt; +      return File == R.File &amp;&amp; MacroArgumentFile == R.MacroArgumentFile \
&amp;&amp;<br> &gt; +                Count == R.Count &amp;&amp; UnreachableInitiator \
== R.UnreachableInitiator &amp;&amp;<br> &gt; +                Group == R.Group \
&amp;&amp; Kind == R.Kind;<br> &gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief Merge two regions by extending the &#39;this&#39; region to cover \
the<br> &gt; +   /// given region.<br>
&gt; +   void mergeByExtendingTo(SourceMappingRegion &amp;R) {<br>
&gt; +      LocEnd = R.LocEnd;<br>
&gt; +      AlternativeLocEnd = R.LocStart;<br>
&gt; +      if (hasFlag(IgnoreIfNotExtended))<br>
&gt; +         clearFlag(IgnoreIfNotExtended);<br>
&gt; +   }<br>
&gt; +};<br>
&gt; +<br>
&gt; +/// \brief The state of the coverage mapping builder.<br>
&gt; +struct SourceMappingState {<br>
&gt; +   Counter CurrentRegionCount;<br>
&gt; +   const Stmt *CurrentSourceGroup;<br>
&gt; +   const Stmt *CurrentUnreachableRegionInitiator;<br>
&gt; +<br>
&gt; +   SourceMappingState(Counter CurrentRegionCount, const Stmt \
*CurrentSourceGroup,<br> &gt; +                               const Stmt \
*CurrentUnreachableRegionInitiator)<br> &gt; +         : \
CurrentRegionCount(CurrentRegionCount),<br> &gt; +            \
CurrentSourceGroup(CurrentSourceGroup),<br> &gt; +            \
CurrentUnreachableRegionInitiator(CurrentUnreachableRegionInitiator) {}<br> &gt; \
+};<br> &gt; +<br>
&gt; +/// \brief Provides the common functionality for the different<br>
&gt; +/// coverage mapping region builders.<br>
&gt; +class CoverageMappingBuilder {<br>
&gt; +public:<br>
&gt; +   CoverageMappingModuleGen &amp;CVM;<br>
&gt; +   SourceManager &amp;SM;<br>
&gt; +   const LangOptions &amp;LangOpts;<br>
&gt; +<br>
&gt; +private:<br>
&gt; +   struct FileInfo {<br>
&gt; +      /// \brief The file id that will be used by the coverage mapping \
system.<br> &gt; +      unsigned CovMappingFileID;<br>
&gt; +      const FileEntry *Entry;<br>
&gt; +<br>
&gt; +      FileInfo(unsigned CovMappingFileID, const FileEntry *Entry)<br>
&gt; +            : CovMappingFileID(CovMappingFileID), Entry(Entry) {}<br>
&gt; +   };<br>
&gt; +<br>
&gt; +   /// \brief This mapping maps clang&#39;s FileIDs to file ids used<br>
&gt; +   /// by the coverage mapping system and clang&#39;s file entries.<br>
&gt; +   llvm::SmallDenseMap&lt;FileID, FileInfo, 8&gt; FileIDMapping;<br>
&gt; +<br>
&gt; +public:<br>
&gt; +   /// \brief The statement that corresponds to the current source group.<br>
&gt; +   const Stmt *CurrentSourceGroup;<br>
&gt; +<br>
&gt; +   /// \brief The statement the initiated the current unreachable region.<br>
&gt; +   const Stmt *CurrentUnreachableRegionInitiator;<br>
&gt; +<br>
&gt; +   /// \brief The coverage mapping regions for this function<br>
&gt; +   llvm::SmallVector&lt;CounterMappingRegion, 32&gt; MappingRegions;<br>
&gt; +   /// \brief The source mapping regions for this function.<br>
&gt; +   llvm::SmallVector&lt;SourceMappingRegion, 32&gt; SourceRegions;<br>
&gt; +<br>
&gt; +   CoverageMappingBuilder(CoverageMappingModuleGen &amp;CVM, SourceManager \
&amp;SM,<br> &gt; +                                     const LangOptions \
&amp;LangOpts)<br> &gt; +         : CVM(CVM), SM(SM), LangOpts(LangOpts),<br>
&gt; +            CurrentSourceGroup(nullptr),<br>
&gt; +            CurrentUnreachableRegionInitiator(nullptr) {}<br>
&gt; +<br>
&gt; +   /// \brief Return the precise end location for the given token.<br>
&gt; +   SourceLocation getPreciseTokenLocEnd(SourceLocation Loc) {<br>
&gt; +      return Lexer::getLocForEndOfToken(SM.getSpellingLoc(Loc), 0, SM, \
LangOpts);<br> &gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief Create the mapping that maps from the function&#39;s file ids \
to<br> &gt; +   /// the indices for the translation unit&#39;s filenames.<br>
&gt; +   void createFileIDMapping(SmallVectorImpl&lt;unsigned&gt; &amp;Mapping) {<br>
&gt; +      Mapping.resize(FileIDMapping.size(), 0);<br>
&gt; +      for (const auto &amp;I : FileIDMapping)<br>
&gt; +         Mapping[I.second.CovMappingFileID] = \
CVM.getFileID(I.second.Entry);<br> &gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief Get the coverage mapping file id that corresponds to the \
given<br> &gt; +   /// clang file id. If such file id doesn&#39;t exist, it gets \
added to the<br> &gt; +   /// mapping that maps from clang&#39;s file ids to coverage \
mapping file ids.<br> &gt; +   /// Return true if there was an error getting the \
coverage mapping file id.<br> &gt; +   /// An example of an when this function fails \
is when the region tries<br> &gt; +   /// to get a coverage file id for a location in \
a built-in macro.<br> &gt; +   bool getCoverageFileID(SourceLocation LocStart, FileID \
File,<br> &gt; +                                     FileID SpellingFile, unsigned \
&amp;Result) {<br> &gt; +      auto Mapping = FileIDMapping.find(File);<br>
&gt; +      if (Mapping != FileIDMapping.end()) {<br>
&gt; +         Result = Mapping-&gt;second.CovMappingFileID;<br>
&gt; +         return false;<br>
&gt; +      }<br>
&gt; +<br>
&gt; +      auto Entry = SM.getFileEntryForID(SpellingFile);<br>
&gt; +      if (!Entry)<br>
&gt; +         return true;<br>
&gt; +<br>
&gt; +      Result = FileIDMapping.size();<br>
&gt; +      FileIDMapping.insert(std::make_pair(File, FileInfo(Result, Entry)));<br>
&gt; +      createFileExpansionRegion(LocStart, File);<br>
&gt; +      return false;<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief Get the coverage mapping file id that corresponds to the \
given<br> &gt; +   /// clang file id.<br>
&gt; +   /// Return true if there was an error getting the coverage mapping file \
id.<br> &gt; +   bool getExistingCoverageFileID(FileID File, unsigned &amp;Result) \
{<br> &gt; +      // Make sure that the file is valid.<br>
&gt; +      if (File.isInvalid())<br>
&gt; +         return true;<br>
&gt; +      auto Mapping = FileIDMapping.find(File);<br>
&gt; +      if (Mapping != FileIDMapping.end()) {<br>
&gt; +         Result = Mapping-&gt;second.CovMappingFileID;<br>
&gt; +         return false;<br>
&gt; +      }<br>
&gt; +      return true;<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief Return true if the given clang&#39;s file id has a \
corresponding<br> &gt; +   /// coverage file id.<br>
&gt; +   bool hasExistingCoverageFileID(FileID File) const {<br>
&gt; +      return FileIDMapping.count(File);<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief Gather all the regions that were skipped by the preprocessor<br>
&gt; +   /// using the constructs like #if.<br>
&gt; +   void gatherSkippedRegions() {<br>
&gt; +      /// An array of the minimum lineStarts and the maximum lineEnds<br>
&gt; +      /// for mapping regions from the appropriate source files.<br>
&gt; +      llvm::SmallVector&lt;std::pair&lt;unsigned, unsigned&gt;, 8&gt; \
FileLineRanges;<br> &gt; +      FileLineRanges.resize(<br>
&gt; +            FileIDMapping.size(),<br>
&gt; +            std::make_pair(std::numeric_limits&lt;unsigned&gt;::max(), 0));<br>
&gt; +      for (const auto &amp;R : MappingRegions) {<br>
&gt; +         FileLineRanges[R.FileID].first =<br>
&gt; +               std::min(FileLineRanges[R.FileID].first, R.LineStart);<br>
&gt; +         FileLineRanges[R.FileID].second =<br>
&gt; +               std::max(FileLineRanges[R.FileID].second, R.LineEnd);<br>
&gt; +      }<br>
&gt; +<br>
&gt; +      auto SkippedRanges = CVM.getSourceInfo().getSkippedRanges();<br>
&gt; +      for (const auto &amp;I : SkippedRanges) {<br>
&gt; +         auto LocStart = I.getBegin();<br>
&gt; +         auto LocEnd = I.getEnd();<br>
&gt; +         auto FileStart = SM.getFileID(LocStart);<br>
&gt; +         if (!hasExistingCoverageFileID(FileStart))<br>
&gt; +            continue;<br>
&gt; +         auto ActualFileStart = \
SM.getDecomposedSpellingLoc(LocStart).first;<br> &gt; +         if (ActualFileStart \
!= SM.getDecomposedSpellingLoc(LocEnd).first)<br> &gt; +            // Ignore regions \
that span across multiple files.<br> &gt; +            continue;<br>
&gt; +<br>
&gt; +         unsigned CovFileID;<br>
&gt; +         if (getCoverageFileID(LocStart, FileStart, ActualFileStart, \
CovFileID))<br> &gt; +            continue;<br>
&gt; +         unsigned LineStart = SM.getSpellingLineNumber(LocStart);<br>
&gt; +         unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart);<br>
&gt; +         unsigned LineEnd = SM.getSpellingLineNumber(LocEnd);<br>
&gt; +         unsigned ColumnEnd = SM.getSpellingColumnNumber(LocEnd);<br>
&gt; +         CounterMappingRegion Region(Counter(), CovFileID, LineStart, \
ColumnStart,<br> &gt; +                                                   LineEnd, \
ColumnEnd, false,<br> &gt; +                                                   \
CounterMappingRegion::SkippedRegion);<br> &gt; +         // Make sure that we only \
collect the regions that are inside<br> &gt; +         // the souce code of this \
function.<br> &gt; +         if (Region.LineStart &gt;= \
FileLineRanges[CovFileID].first &amp;&amp;<br> &gt; +               Region.LineEnd \
&lt;= FileLineRanges[CovFileID].second)<br> &gt; +            \
MappingRegions.push_back(Region);<br> &gt; +      }<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief Create a mapping region that correponds to an expansion of<br>
&gt; +   /// a macro or an embedded include.<br>
&gt; +   void createFileExpansionRegion(SourceLocation Loc, FileID ExpandedFile) \
{<br> &gt; +      SourceLocation LocStart;<br>
&gt; +      if (Loc.isMacroID())<br>
&gt; +         LocStart = SM.getImmediateExpansionRange(Loc).first;<br>
&gt; +      else {<br>
&gt; +         LocStart = SM.getIncludeLoc(ExpandedFile);<br>
&gt; +         if (LocStart.isInvalid())<br>
&gt; +            return; // This file has no expansion region.<br>
&gt; +      }<br>
&gt; +<br>
&gt; +      auto File = SM.getFileID(LocStart);<br>
&gt; +      auto SpellingFile = SM.getDecomposedSpellingLoc(LocStart).first;<br>
&gt; +      unsigned CovFileID, ExpandedFileID;<br>
&gt; +      if (getExistingCoverageFileID(ExpandedFile, ExpandedFileID))<br>
&gt; +         return;<br>
&gt; +      if (getCoverageFileID(LocStart, File, SpellingFile, CovFileID))<br>
&gt; +         return;<br>
&gt; +      unsigned LineStart = SM.getSpellingLineNumber(LocStart);<br>
&gt; +      unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart);<br>
&gt; +      unsigned LineEnd = LineStart;<br>
&gt; +      // Compute the end column manually as Lexer::getLocForEndOfToken \
doesn&#39;t<br> &gt; +      // give the correct result in all cases.<br>
&gt; +      unsigned ColumnEnd =<br>
&gt; +            ColumnStart +<br>
&gt; +            Lexer::MeasureTokenLength(SM.getSpellingLoc(LocStart), SM, \
LangOpts);<br> &gt; +<br>
&gt; +      MappingRegions.push_back(CounterMappingRegion(<br>
&gt; +            Counter(), CovFileID, LineStart, ColumnStart, LineEnd, \
ColumnEnd,<br> &gt; +            false, CounterMappingRegion::ExpansionRegion));<br>
&gt; +      MappingRegions.back().ExpandedFileID = ExpandedFileID;<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief Enter a source region group that is identified by the given<br>
&gt; +   /// statement.<br>
&gt; +   /// It&#39;s not possible to enter a group when there is already<br>
&gt; +   /// another group present.<br>
&gt; +   void beginSourceRegionGroup(const Stmt *Group) {<br>
&gt; +      assert(!CurrentSourceGroup);<br>
&gt; +      CurrentSourceGroup = Group;<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief Exit the current source region group.<br>
&gt; +   void endSourceRegionGroup() { CurrentSourceGroup = nullptr; }<br>
&gt; +<br>
&gt; +   /// \brief Brings a region that has the same counter and file to the \
back<br> &gt; +   /// of the source regions array.<br>
&gt; +   void bringSimilarRegionBack(Counter Count, FileID File,<br>
&gt; +                                             FileID MacroArgumentFile,<br>
&gt; +                                             const Stmt \
*UnreachableInitiator,<br> &gt; +                                             const \
Stmt *SourceGroup) {<br> &gt; +      for (size_t I = SourceRegions.size(); I != 0;) \
{<br> &gt; +         --I;<br>
&gt; +         if (SourceRegions[I].Count == Count &amp;&amp; SourceRegions[I].File \
== File &amp;&amp;<br> &gt; +               SourceRegions[I].MacroArgumentFile == \
MacroArgumentFile &amp;&amp;<br> &gt; +               \
SourceRegions[I].UnreachableInitiator == UnreachableInitiator &amp;&amp;<br> &gt; +   \
SourceRegions[I].Group == SourceGroup) {<br> &gt; +            if (I != \
SourceRegions.size() - 1)<br> &gt; +               std::swap(SourceRegions[I], \
SourceRegions.back());<br> &gt; +            return;<br>
&gt; +         }<br>
&gt; +      }<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief Associate a counter with a given source code range.<br>
&gt; +   void mapSourceCodeRange(SourceLocation LocStart, SourceLocation LocEnd,<br>
&gt; +                                       Counter Count, const Stmt \
*UnreachableInitiator,<br> &gt; +                                       const Stmt \
*SourceGroup, unsigned Flags = 0,<br> &gt; +                                       \
FileID MacroArgumentFile = FileID()) {<br> &gt; +      if \
(SM.isMacroArgExpansion(LocStart)) {<br> &gt; +         // Map the code range with \
the macro argument&#39;s value.<br> &gt; +         \
mapSourceCodeRange(SM.getImmediateSpellingLoc(LocStart),<br> &gt; +                   \
SM.getImmediateSpellingLoc(LocEnd), Count,<br> &gt; +                                 \
UnreachableInitiator, SourceGroup, Flags,<br> &gt; +                                  \
SM.getFileID(LocStart));<br> &gt; +         // Map the code range where the macro \
argument is referenced.<br> &gt; +         SourceLocation \
RefLocStart(SM.getImmediateExpansionRange(LocStart).first);<br> &gt; +         \
SourceLocation RefLocEnd(RefLocStart);<br> &gt; +         if \
(SM.isMacroArgExpansion(RefLocStart))<br> &gt; +            \
mapSourceCodeRange(RefLocStart, RefLocEnd, Count, UnreachableInitiator,<br> &gt; +    \
SourceGroup, 0, SM.getFileID(RefLocStart));<br> &gt; +         else<br>
&gt; +            mapSourceCodeRange(RefLocStart, RefLocEnd, Count, \
UnreachableInitiator,<br> &gt; +                                        \
SourceGroup);<br> &gt; +         return;<br>
&gt; +      }<br>
&gt; +      auto File = SM.getFileID(LocStart);<br>
&gt; +      // Make sure that the file id is valid.<br>
&gt; +      if (File.isInvalid())<br>
&gt; +         return;<br>
&gt; +      bringSimilarRegionBack(Count, File, MacroArgumentFile, \
UnreachableInitiator,<br> &gt; +                                        \
SourceGroup);<br> &gt; +      SourceMappingRegion R(File, MacroArgumentFile, Count, \
UnreachableInitiator,<br> &gt; +                                       SourceGroup, \
LocStart, LocEnd, Flags);<br> &gt; +      if (SourceRegions.empty() || \
!SourceRegions.back().isMergeable(R)) {<br> &gt; +         \
SourceRegions.push_back(R);<br> &gt; +         return;<br>
&gt; +      }<br>
&gt; +      SourceRegions.back().mergeByExtendingTo(R);<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void mapSourceCodeRange(SourceLocation LocStart, SourceLocation LocEnd,<br>
&gt; +                                       Counter Count, unsigned Flags = 0) {<br>
&gt; +      mapSourceCodeRange(LocStart, LocEnd, Count,<br>
&gt; +                                  CurrentUnreachableRegionInitiator, \
CurrentSourceGroup,<br> &gt; +                                  Flags);<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void mapSourceCodeRange(const SourceMappingState &amp;State,<br>
&gt; +                                       SourceLocation LocStart, SourceLocation \
LocEnd,<br> &gt; +                                       unsigned Flags = 0) {<br>
&gt; +      mapSourceCodeRange(LocStart, LocEnd, State.CurrentRegionCount,<br>
&gt; +                                  State.CurrentUnreachableRegionInitiator,<br>
&gt; +                                  State.CurrentSourceGroup, Flags);<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief Generate the coverage counter mapping regions from collected<br>
&gt; +   /// source regions.<br>
&gt; +   void emitSourceRegions() {<br>
&gt; +      for (const auto &amp;R : SourceRegions) {<br>
&gt; +         SourceLocation LocStart = R.LocStart;<br>
&gt; +         SourceLocation LocEnd = R.LocEnd;<br>
&gt; +         if (SM.getFileID(LocEnd) != R.File)<br>
&gt; +            LocEnd = R.AlternativeLocEnd;<br>
&gt; +<br>
&gt; +         if (R.hasFlag(SourceMappingRegion::IgnoreIfNotExtended) &amp;&amp;<br>
&gt; +               LocStart == LocEnd)<br>
&gt; +            continue;<br>
&gt; +<br>
&gt; +         LocEnd = getPreciseTokenLocEnd(LocEnd);<br>
&gt; +         unsigned LineStart = SM.getSpellingLineNumber(LocStart);<br>
&gt; +         unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart);<br>
&gt; +         unsigned LineEnd = SM.getSpellingLineNumber(LocEnd);<br>
&gt; +         unsigned ColumnEnd = SM.getSpellingColumnNumber(LocEnd);<br>
&gt; +<br>
&gt; +         auto SpellingFile = SM.getDecomposedSpellingLoc(R.LocStart).first;<br>
&gt; +         unsigned CovFileID;<br>
&gt; +         if (getCoverageFileID(R.LocStart, R.File, SpellingFile, \
CovFileID))<br> &gt; +            continue;<br>
&gt; +<br>
&gt; +         assert(LineStart &lt;= LineEnd);<br>
&gt; +         MappingRegions.push_back(CounterMappingRegion(<br>
&gt; +               R.Count, CovFileID, LineStart, ColumnStart, LineEnd, \
ColumnEnd,<br> &gt; +               false, CounterMappingRegion::CodeRegion));<br>
&gt; +      }<br>
&gt; +   }<br>
&gt; +};<br>
&gt; +<br>
&gt; +/// \brief Creates unreachable coverage regions for the functions that<br>
&gt; +/// are not emitted.<br>
&gt; +struct EmptyCoverageMappingBuilder : public CoverageMappingBuilder {<br>
&gt; +   EmptyCoverageMappingBuilder(CoverageMappingModuleGen &amp;CVM, SourceManager \
&amp;SM,<br> &gt; +                                             const LangOptions \
&amp;LangOpts)<br> &gt; +         : CoverageMappingBuilder(CVM, SM, LangOpts) {}<br>
&gt; +<br>
&gt; +   void VisitDecl(const Decl *D) {<br>
&gt; +      if (!D-&gt;hasBody())<br>
&gt; +         return;<br>
&gt; +      auto Body = D-&gt;getBody();<br>
&gt; +      mapSourceCodeRange(Body-&gt;getLocStart(), Body-&gt;getLocEnd(), \
Counter());<br> &gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief Write the mapping data to the output stream<br>
&gt; +   void write(llvm::raw_ostream &amp;OS) {<br>
&gt; +      emitSourceRegions();<br>
&gt; +      SmallVector&lt;unsigned, 16&gt; FileIDMapping;<br>
&gt; +      createFileIDMapping(FileIDMapping);<br>
&gt; +<br>
&gt; +      CoverageMappingWriter Writer(<br>
&gt; +            FileIDMapping, ArrayRef&lt;CounterExpression&gt;(), \
MappingRegions);<br> &gt; +      Writer.write(OS);<br>
&gt; +   }<br>
&gt; +};<br>
&gt; +<br>
&gt; +/// \brief A StmtVisitor that creates coverage mapping regions which map<br>
&gt; +/// from the source code locations to the PGO counters.<br>
&gt; +struct CounterCoverageMappingBuilder<br>
&gt; +      : public CoverageMappingBuilder,<br>
&gt; +         public ConstStmtVisitor&lt;CounterCoverageMappingBuilder&gt; {<br>
&gt; +   /// \brief The map of statements to count values.<br>
&gt; +   llvm::DenseMap&lt;const Stmt *, unsigned&gt; &amp;CounterMap;<br>
&gt; +<br>
&gt; +   Counter CurrentRegionCount;<br>
&gt; +<br>
&gt; +   CounterExpressionBuilder Builder;<br>
&gt; +<br>
&gt; +   /// \brief Return a counter that represents the<br>
&gt; +   /// expression that subracts rhs from lhs.<br>
&gt; +   Counter subtractCounters(Counter LHS, Counter RHS) {<br>
&gt; +      return Builder.subtract(LHS, RHS);<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief Return a counter that represents the<br>
&gt; +   /// the exression that adds lhs and rhs.<br>
&gt; +   Counter addCounters(Counter LHS, Counter RHS) {<br>
&gt; +      return Builder.add(LHS, RHS);<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief Return the region counter for the given statement.<br>
&gt; +   /// This should only be called on statements that have a dedicated \
counter.<br> &gt; +   unsigned getRegionCounter(const Stmt *S) { return \
CounterMap[S]; }<br> &gt; +<br>
&gt; +   /// \brief Return the region count for the counter at the given index.<br>
&gt; +   Counter getRegionCount(unsigned CounterId) {<br>
&gt; +      return Counter::getCounter(CounterId);<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief Return the counter value of the current region.<br>
&gt; +   Counter getCurrentRegionCount() { return CurrentRegionCount; }<br>
&gt; +<br>
&gt; +   /// \brief Set the counter value for the current region.<br>
&gt; +   /// This is used to keep track of changes to the most recent counter<br>
&gt; +   /// from control flow and non-local exits.<br>
&gt; +   void setCurrentRegionCount(Counter Count) {<br>
&gt; +      CurrentRegionCount = Count;<br>
&gt; +      CurrentUnreachableRegionInitiator = nullptr;<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief Indicate that the current region is never reached,<br>
&gt; +   /// and thus should have a counter value of zero.<br>
&gt; +   /// This is important so that subsequent regions can correctly track<br>
&gt; +   /// their parent counts.<br>
&gt; +   void setCurrentRegionUnreachable(const Stmt *Initiator) {<br>
&gt; +      CurrentRegionCount = Counter::getZero();<br>
&gt; +      CurrentUnreachableRegionInitiator = Initiator;<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief A counter for a particular region.<br>
&gt; +   /// This is the primary interface through<br>
&gt; +   /// which the coverage mapping builder manages counters and their \
values.<br> &gt; +   class RegionMapper {<br>
&gt; +      CounterCoverageMappingBuilder &amp;Mapping;<br>
&gt; +      Counter Count;<br>
&gt; +      Counter ParentCount;<br>
&gt; +      Counter RegionCount;<br>
&gt; +      Counter Adjust;<br>
&gt; +<br>
&gt; +   public:<br>
&gt; +      RegionMapper(CounterCoverageMappingBuilder *Mapper, const Stmt *S)<br>
&gt; +            : Mapping(*Mapper),<br>
&gt; +               \
Count(Mapper-&gt;getRegionCount(Mapper-&gt;getRegionCounter(S))),<br> &gt; +          \
ParentCount(Mapper-&gt;getCurrentRegionCount()) {}<br> &gt; +<br>
&gt; +      /// Get the value of the counter. In most cases this is the number of \
times<br> &gt; +      /// the region of the counter was entered, but for switch \
labels it&#39;s the<br> &gt; +      /// number of direct jumps to that label.<br>
&gt; +      Counter getCount() const { return Count; }<br>
&gt; +<br>
&gt; +      /// Get the value of the counter with adjustments applied. Adjustments \
occur<br> &gt; +      /// when control enters or leaves the region abnormally; i.e., \
if there is a<br> &gt; +      /// jump to a label within the region, or if the \
function can return from<br> &gt; +      /// within the region. The adjusted count, \
then, is the value of the counter<br> &gt; +      /// at the end of the region.<br>
&gt; +      Counter getAdjustedCount() const {<br>
&gt; +         return Mapping.addCounters(Count, Adjust);<br>
&gt; +      }<br>
&gt; +<br>
&gt; +      /// Get the value of the counter in this region&#39;s parent, i.e., the \
region<br> &gt; +      /// that was active when this region began. This is useful for \
deriving<br> &gt; +      /// counts in implicitly counted regions, like the false \
case of a condition<br> &gt; +      /// or the normal exits of a loop.<br>
&gt; +      Counter getParentCount() const { return ParentCount; }<br>
&gt; +<br>
&gt; +      /// Activate the counter by emitting an increment and starting to \
track<br> &gt; +      /// adjustments. If AddIncomingFallThrough is true, the current \
region count<br> &gt; +      /// will be added to the counter for the purposes of \
tracking the region.<br> &gt; +      void beginRegion(bool AddIncomingFallThrough = \
false) {<br> &gt; +         RegionCount = Count;<br>
&gt; +         if (AddIncomingFallThrough)<br>
&gt; +            RegionCount =<br>
&gt; +                  Mapping.addCounters(RegionCount, \
Mapping.getCurrentRegionCount());<br> &gt; +         \
Mapping.setCurrentRegionCount(RegionCount);<br> &gt; +      }<br>
&gt; +<br>
&gt; +      /// For counters on boolean branches, begins tracking adjustments for \
the<br> &gt; +      /// uncounted path.<br>
&gt; +      void beginElseRegion() {<br>
&gt; +         RegionCount = Mapping.subtractCounters(ParentCount, Count);<br>
&gt; +         Mapping.setCurrentRegionCount(RegionCount);<br>
&gt; +      }<br>
&gt; +<br>
&gt; +      /// Reset the current region count.<br>
&gt; +      void setCurrentRegionCount(Counter CurrentCount) {<br>
&gt; +         RegionCount = CurrentCount;<br>
&gt; +         Mapping.setCurrentRegionCount(RegionCount);<br>
&gt; +      }<br>
&gt; +<br>
&gt; +      /// Adjust for non-local control flow after emitting a subexpression \
or<br> &gt; +      /// substatement. This must be called to account for constructs \
such as<br> &gt; +      /// gotos,<br>
&gt; +      /// labels, and returns, so that we can ensure that our region&#39;s \
count is<br> &gt; +      /// correct in the code that follows.<br>
&gt; +      void adjustForControlFlow() {<br>
&gt; +         Adjust = Mapping.addCounters(<br>
&gt; +               Adjust, \
Mapping.subtractCounters(Mapping.getCurrentRegionCount(),<br> &gt; +                  \
RegionCount));<br> &gt; +         // Reset the region count in case this is called \
again later.<br> &gt; +         RegionCount = Mapping.getCurrentRegionCount();<br>
&gt; +      }<br>
&gt; +<br>
&gt; +      /// Commit all adjustments to the current region. If the region is a \
loop,<br> &gt; +      /// the LoopAdjust value should be the count of all the breaks \
and continues<br> &gt; +      /// from the loop, to compensate for those counts being \
deducted from the<br> &gt; +      /// adjustments for the body of the loop.<br>
&gt; +      void applyAdjustmentsToRegion() {<br>
&gt; +         Mapping.setCurrentRegionCount(Mapping.addCounters(ParentCount, \
Adjust));<br> &gt; +      }<br>
&gt; +      void applyAdjustmentsToRegion(Counter LoopAdjust) {<br>
&gt; +         Mapping.setCurrentRegionCount(Mapping.addCounters(<br>
&gt; +               Mapping.addCounters(ParentCount, Adjust), LoopAdjust));<br>
&gt; +      }<br>
&gt; +   };<br>
&gt; +<br>
&gt; +   /// \brief Keep counts of breaks and continues inside loops.<br>
&gt; +   struct BreakContinue {<br>
&gt; +      Counter BreakCount;<br>
&gt; +      Counter ContinueCount;<br>
&gt; +   };<br>
&gt; +   SmallVector&lt;BreakContinue, 8&gt; BreakContinueStack;<br>
&gt; +<br>
&gt; +   CounterCoverageMappingBuilder(<br>
&gt; +         CoverageMappingModuleGen &amp;CVM,<br>
&gt; +         llvm::DenseMap&lt;const Stmt *, unsigned&gt; &amp;CounterMap,<br>
&gt; +         unsigned NumRegionCounters, SourceManager &amp;SM,<br>
&gt; +         const LangOptions &amp;LangOpts)<br>
&gt; +         : CoverageMappingBuilder(CVM, SM, LangOpts), \
CounterMap(CounterMap),<br> &gt; +            Builder(NumRegionCounters) {}<br>
&gt; +<br>
&gt; +   /// \brief Write the mapping data to the output stream<br>
&gt; +   void write(llvm::raw_ostream &amp;OS) {<br>
&gt; +      emitSourceRegions();<br>
&gt; +      llvm::SmallVector&lt;unsigned, 8&gt; VirtualFileMapping;<br>
&gt; +      createFileIDMapping(VirtualFileMapping);<br>
&gt; +      gatherSkippedRegions();<br>
&gt; +<br>
&gt; +      CoverageMappingWriter Writer(<br>
&gt; +            VirtualFileMapping, Builder.getExpressions(), MappingRegions);<br>
&gt; +      Writer.write(OS);<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief Return the current source mapping state.<br>
&gt; +   SourceMappingState getCurrentState() const {<br>
&gt; +      return SourceMappingState(CurrentRegionCount, CurrentSourceGroup,<br>
&gt; +                                             \
CurrentUnreachableRegionInitiator);<br> &gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief Associate the source code range with the current region \
count.<br> &gt; +   void mapSourceCodeRange(SourceLocation LocStart, SourceLocation \
LocEnd,<br> &gt; +                                       unsigned Flags = 0) {<br>
&gt; +      CoverageMappingBuilder::mapSourceCodeRange(LocStart, LocEnd,<br>
&gt; +                                                                      \
CurrentRegionCount, Flags);<br> &gt; +   }<br>
&gt; +<br>
&gt; +   void mapSourceCodeRange(SourceLocation LocStart) {<br>
&gt; +      CoverageMappingBuilder::mapSourceCodeRange(LocStart, LocStart,<br>
&gt; +                                                                      \
CurrentRegionCount);<br> &gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief Associate the source range of a token with the current region<br>
&gt; +   /// count.<br>
&gt; +   /// Ignore the source range for this token if it produces a distinct<br>
&gt; +   /// mapping region with no other source ranges.<br>
&gt; +   void mapToken(SourceLocation LocStart) {<br>
&gt; +      CoverageMappingBuilder::mapSourceCodeRange(<br>
&gt; +            LocStart, LocStart, CurrentRegionCount,<br>
&gt; +            SourceMappingRegion::IgnoreIfNotExtended);<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void mapToken(const SourceMappingState &amp;State, SourceLocation LocStart) \
{<br> &gt; +      CoverageMappingBuilder::mapSourceCodeRange(<br>
&gt; +            State, LocStart, LocStart, \
SourceMappingRegion::IgnoreIfNotExtended);<br> &gt; +   }<br>
&gt; +<br>
&gt; +   void VisitStmt(const Stmt *S) {<br>
&gt; +      mapSourceCodeRange(S-&gt;getLocStart());<br>
&gt; +      for (Stmt::const_child_range I = S-&gt;children(); I; ++I) {<br>
&gt; +         if (*I)<br>
&gt; +            this-&gt;Visit(*I);<br>
&gt; +      }<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief If the given statement is a compound statement,<br>
&gt; +   /// map &#39;}&#39; with the same count as &#39;{&#39;.<br>
&gt; +   void VisitSubStmtRBraceState(const Stmt *S) {<br>
&gt; +      if (!isa&lt;CompoundStmt&gt;(S))<br>
&gt; +         return Visit(S);<br>
&gt; +      const auto *CS = cast&lt;CompoundStmt&gt;(S);<br>
&gt; +      auto State = getCurrentState();<br>
&gt; +      mapSourceCodeRange(CS-&gt;getLBracLoc());<br>
&gt; +      for (Stmt::const_child_range I = S-&gt;children(); I; ++I) {<br>
&gt; +         if (*I)<br>
&gt; +            this-&gt;Visit(*I);<br>
&gt; +      }<br>
&gt; +      CoverageMappingBuilder::mapSourceCodeRange(State, \
CS-&gt;getRBracLoc(),<br> &gt; +                                                      \
CS-&gt;getRBracLoc());<br> &gt; +   }<br>
&gt; +<br>
&gt; +   void VisitDecl(const Decl *D) {<br>
&gt; +      if (!D-&gt;hasBody())<br>
&gt; +         return;<br>
&gt; +      // Counter tracks entry to the function body.<br>
&gt; +      auto Body = D-&gt;getBody();<br>
&gt; +      RegionMapper Cnt(this, Body);<br>
&gt; +      Cnt.beginRegion();<br>
&gt; +      VisitSubStmtRBraceState(Body);<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitDeclStmt(const DeclStmt *S) {<br>
&gt; +      mapSourceCodeRange(S-&gt;getLocStart());<br>
&gt; +      for (Stmt::const_child_range I = static_cast&lt;const Stmt \
*&gt;(S)-&gt;children();<br> &gt; +             I; ++I) {<br>
&gt; +         if (*I)<br>
&gt; +            this-&gt;Visit(*I);<br>
&gt; +      }<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitCompoundStmt(const CompoundStmt *S) {<br>
&gt; +      mapSourceCodeRange(S-&gt;getLBracLoc());<br>
&gt; +      for (Stmt::const_child_range I = S-&gt;children(); I; ++I) {<br>
&gt; +         if (*I)<br>
&gt; +            this-&gt;Visit(*I);<br>
&gt; +      }<br>
&gt; +      mapSourceCodeRange(S-&gt;getRBracLoc(), S-&gt;getRBracLoc());<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitReturnStmt(const ReturnStmt *S) {<br>
&gt; +      mapSourceCodeRange(S-&gt;getLocStart());<br>
&gt; +      if (S-&gt;getRetValue())<br>
&gt; +         Visit(S-&gt;getRetValue());<br>
&gt; +      setCurrentRegionUnreachable(S);<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitGotoStmt(const GotoStmt *S) {<br>
&gt; +      mapSourceCodeRange(S-&gt;getLocStart());<br>
&gt; +      mapToken(S-&gt;getLabelLoc());<br>
&gt; +      setCurrentRegionUnreachable(S);<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitLabelStmt(const LabelStmt *S) {<br>
&gt; +      // Counter tracks the block following the label.<br>
&gt; +      RegionMapper Cnt(this, S);<br>
&gt; +      Cnt.beginRegion();<br>
&gt; +      mapSourceCodeRange(S-&gt;getLocStart());<br>
&gt; +      // Can&#39;t map the &#39;:&#39; token as its location isn&#39;t \
known.<br> &gt; +      Visit(S-&gt;getSubStmt());<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitBreakStmt(const BreakStmt *S) {<br>
&gt; +      mapSourceCodeRange(S-&gt;getLocStart());<br>
&gt; +      assert(!BreakContinueStack.empty() &amp;&amp; &quot;break not in a loop \
or switch!&quot;);<br> &gt; +      BreakContinueStack.back().BreakCount = \
addCounters(<br> &gt; +            BreakContinueStack.back().BreakCount, \
getCurrentRegionCount());<br> &gt; +      setCurrentRegionUnreachable(S);<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitContinueStmt(const ContinueStmt *S) {<br>
&gt; +      mapSourceCodeRange(S-&gt;getLocStart());<br>
&gt; +      assert(!BreakContinueStack.empty() &amp;&amp; &quot;continue stmt not in \
a loop!&quot;);<br> &gt; +      BreakContinueStack.back().ContinueCount = \
addCounters(<br> &gt; +            BreakContinueStack.back().ContinueCount, \
getCurrentRegionCount());<br> &gt; +      setCurrentRegionUnreachable(S);<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitWhileStmt(const WhileStmt *S) {<br>
&gt; +      mapSourceCodeRange(S-&gt;getLocStart());<br>
&gt; +      // Counter tracks the body of the loop.<br>
&gt; +      RegionMapper Cnt(this, S);<br>
&gt; +      BreakContinueStack.push_back(BreakContinue());<br>
&gt; +      // Visit the body region first so the break/continue adjustments can \
be<br> &gt; +      // included when visiting the condition.<br>
&gt; +      Cnt.beginRegion();<br>
&gt; +      VisitSubStmtRBraceState(S-&gt;getBody());<br>
&gt; +      Cnt.adjustForControlFlow();<br>
&gt; +<br>
&gt; +      // ...then go back and propagate counts through the condition. The \
count<br> &gt; +      // at the start of the condition is the sum of the incoming \
edges,<br> &gt; +      // the backedge from the end of the loop body, and the edges \
from<br> &gt; +      // continue statements.<br>
&gt; +      BreakContinue BC = BreakContinueStack.pop_back_val();<br>
&gt; +      Cnt.setCurrentRegionCount(<br>
&gt; +            addCounters(Cnt.getParentCount(),<br>
&gt; +                              addCounters(Cnt.getAdjustedCount(), \
BC.ContinueCount)));<br> &gt; +      beginSourceRegionGroup(S-&gt;getCond());<br>
&gt; +      Visit(S-&gt;getCond());<br>
&gt; +      endSourceRegionGroup();<br>
&gt; +      Cnt.adjustForControlFlow();<br>
&gt; +      Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount, \
BC.ContinueCount));<br> &gt; +   }<br>
&gt; +<br>
&gt; +   void VisitDoStmt(const DoStmt *S) {<br>
&gt; +      mapSourceCodeRange(S-&gt;getLocStart());<br>
&gt; +      // Counter tracks the body of the loop.<br>
&gt; +      RegionMapper Cnt(this, S);<br>
&gt; +      BreakContinueStack.push_back(BreakContinue());<br>
&gt; +      Cnt.beginRegion(/*AddIncomingFallThrough=*/true);<br>
&gt; +      VisitSubStmtRBraceState(S-&gt;getBody());<br>
&gt; +      Cnt.adjustForControlFlow();<br>
&gt; +<br>
&gt; +      BreakContinue BC = BreakContinueStack.pop_back_val();<br>
&gt; +      // The count at the start of the condition is equal to the count at \
the<br> &gt; +      // end of the body. The adjusted count does not include either \
the<br> &gt; +      // fall-through count coming into the loop or the continue count, \
so add<br> &gt; +      // both of those separately. This is coincidentally the same \
equation as<br> &gt; +      // with while loops but for different reasons.<br>
&gt; +      Cnt.setCurrentRegionCount(<br>
&gt; +            addCounters(Cnt.getParentCount(),<br>
&gt; +                              addCounters(Cnt.getAdjustedCount(), \
BC.ContinueCount)));<br> &gt; +      Visit(S-&gt;getCond());<br>
&gt; +      Cnt.adjustForControlFlow();<br>
&gt; +      Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount, \
BC.ContinueCount));<br> &gt; +   }<br>
&gt; +<br>
&gt; +   void VisitForStmt(const ForStmt *S) {<br>
&gt; +      mapSourceCodeRange(S-&gt;getLocStart());<br>
&gt; +      if (S-&gt;getInit())<br>
&gt; +         Visit(S-&gt;getInit());<br>
&gt; +<br>
&gt; +      // Counter tracks the body of the loop.<br>
&gt; +      RegionMapper Cnt(this, S);<br>
&gt; +      BreakContinueStack.push_back(BreakContinue());<br>
&gt; +      // Visit the body region first. (This is basically the same as a \
while<br> &gt; +      // loop; see further comments in VisitWhileStmt.)<br>
&gt; +      Cnt.beginRegion();<br>
&gt; +      VisitSubStmtRBraceState(S-&gt;getBody());<br>
&gt; +      Cnt.adjustForControlFlow();<br>
&gt; +<br>
&gt; +      // The increment is essentially part of the body but it needs to \
include<br> &gt; +      // the count for all the continue statements.<br>
&gt; +      if (S-&gt;getInc()) {<br>
&gt; +         Cnt.setCurrentRegionCount(addCounters(<br>
&gt; +               getCurrentRegionCount(), \
BreakContinueStack.back().ContinueCount));<br> &gt; +         \
beginSourceRegionGroup(S-&gt;getInc());<br> &gt; +         Visit(S-&gt;getInc());<br>
&gt; +         endSourceRegionGroup();<br>
&gt; +         Cnt.adjustForControlFlow();<br>
&gt; +      }<br>
&gt; +<br>
&gt; +      BreakContinue BC = BreakContinueStack.pop_back_val();<br>
&gt; +<br>
&gt; +      // ...then go back and propagate counts through the condition.<br>
&gt; +      if (S-&gt;getCond()) {<br>
&gt; +         Cnt.setCurrentRegionCount(<br>
&gt; +               addCounters(addCounters(Cnt.getParentCount(), \
Cnt.getAdjustedCount()),<br> &gt; +                                 \
BC.ContinueCount));<br> &gt; +         beginSourceRegionGroup(S-&gt;getCond());<br>
&gt; +         Visit(S-&gt;getCond());<br>
&gt; +         endSourceRegionGroup();<br>
&gt; +         Cnt.adjustForControlFlow();<br>
&gt; +      }<br>
&gt; +      Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount, \
BC.ContinueCount));<br> &gt; +   }<br>
&gt; +<br>
&gt; +   void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {<br>
&gt; +      mapSourceCodeRange(S-&gt;getLocStart());<br>
&gt; +      Visit(S-&gt;getRangeStmt());<br>
&gt; +      Visit(S-&gt;getBeginEndStmt());<br>
&gt; +      // Counter tracks the body of the loop.<br>
&gt; +      RegionMapper Cnt(this, S);<br>
&gt; +      BreakContinueStack.push_back(BreakContinue());<br>
&gt; +      // Visit the body region first. (This is basically the same as a \
while<br> &gt; +      // loop; see further comments in VisitWhileStmt.)<br>
&gt; +      Cnt.beginRegion();<br>
&gt; +      VisitSubStmtRBraceState(S-&gt;getBody());<br>
&gt; +      Cnt.adjustForControlFlow();<br>
&gt; +      BreakContinue BC = BreakContinueStack.pop_back_val();<br>
&gt; +      Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount, \
BC.ContinueCount));<br> &gt; +   }<br>
&gt; +<br>
&gt; +   void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {<br>
&gt; +      mapSourceCodeRange(S-&gt;getLocStart());<br>
&gt; +      Visit(S-&gt;getElement());<br>
&gt; +      // Counter tracks the body of the loop.<br>
&gt; +      RegionMapper Cnt(this, S);<br>
&gt; +      BreakContinueStack.push_back(BreakContinue());<br>
&gt; +      VisitSubStmtRBraceState(S-&gt;getBody());<br>
&gt; +      BreakContinue BC = BreakContinueStack.pop_back_val();<br>
&gt; +      Cnt.adjustForControlFlow();<br>
&gt; +      Cnt.applyAdjustmentsToRegion(addCounters(BC.BreakCount, \
BC.ContinueCount));<br> &gt; +   }<br>
&gt; +<br>
&gt; +   void VisitSwitchStmt(const SwitchStmt *S) {<br>
&gt; +      mapSourceCodeRange(S-&gt;getLocStart());<br>
&gt; +      Visit(S-&gt;getCond());<br>
&gt; +      BreakContinueStack.push_back(BreakContinue());<br>
&gt; +      // Map the &#39;}&#39; for the body to have the same count as the regions \
after<br> &gt; +      // the switch.<br>
&gt; +      SourceLocation RBracLoc;<br>
&gt; +      if (const auto *CS = dyn_cast&lt;CompoundStmt&gt;(S-&gt;getBody())) {<br>
&gt; +         mapSourceCodeRange(CS-&gt;getLBracLoc());<br>
&gt; +         setCurrentRegionUnreachable(S);<br>
&gt; +         for (Stmt::const_child_range I = CS-&gt;children(); I; ++I) {<br>
&gt; +            if (*I)<br>
&gt; +               this-&gt;Visit(*I);<br>
&gt; +         }<br>
&gt; +         RBracLoc = CS-&gt;getRBracLoc();<br>
&gt; +      } else {<br>
&gt; +         setCurrentRegionUnreachable(S);<br>
&gt; +         Visit(S-&gt;getBody());<br>
&gt; +      }<br>
&gt; +      // If the switch is inside a loop, add the continue counts.<br>
&gt; +      BreakContinue BC = BreakContinueStack.pop_back_val();<br>
&gt; +      if (!BreakContinueStack.empty())<br>
&gt; +         BreakContinueStack.back().ContinueCount = addCounters(<br>
&gt; +               BreakContinueStack.back().ContinueCount, BC.ContinueCount);<br>
&gt; +      // Counter tracks the exit block of the switch.<br>
&gt; +      RegionMapper ExitCnt(this, S);<br>
&gt; +      ExitCnt.beginRegion();<br>
&gt; +      if (RBracLoc.isValid())<br>
&gt; +         mapSourceCodeRange(RBracLoc);<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitCaseStmt(const CaseStmt *S) {<br>
&gt; +      // Counter for this particular case. This counts only jumps from the<br>
&gt; +      // switch header and does not include fallthrough from the case \
before<br> &gt; +      // this one.<br>
&gt; +      RegionMapper Cnt(this, S);<br>
&gt; +      Cnt.beginRegion(/*AddIncomingFallThrough=*/true);<br>
&gt; +      mapSourceCodeRange(S-&gt;getLocStart());<br>
&gt; +      mapToken(S-&gt;getColonLoc());<br>
&gt; +      Visit(S-&gt;getSubStmt());<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitDefaultStmt(const DefaultStmt *S) {<br>
&gt; +      // Counter for this default case. This does not include fallthrough \
from<br> &gt; +      // the previous case.<br>
&gt; +      RegionMapper Cnt(this, S);<br>
&gt; +      Cnt.beginRegion(/*AddIncomingFallThrough=*/true);<br>
&gt; +      mapSourceCodeRange(S-&gt;getLocStart());<br>
&gt; +      mapToken(S-&gt;getColonLoc());<br>
&gt; +      Visit(S-&gt;getSubStmt());<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitIfStmt(const IfStmt *S) {<br>
&gt; +      mapSourceCodeRange(S-&gt;getLocStart());<br>
&gt; +      Visit(S-&gt;getCond());<br>
&gt; +      mapToken(S-&gt;getElseLoc());<br>
&gt; +<br>
&gt; +      // Counter tracks the &quot;then&quot; part of an if statement. The count \
for<br> &gt; +      // the &quot;else&quot; part, if it exists, will be calculated \
from this counter.<br> &gt; +      RegionMapper Cnt(this, S);<br>
&gt; +      Cnt.beginRegion();<br>
&gt; +      VisitSubStmtRBraceState(S-&gt;getThen());<br>
&gt; +      Cnt.adjustForControlFlow();<br>
&gt; +<br>
&gt; +      if (S-&gt;getElse()) {<br>
&gt; +         Cnt.beginElseRegion();<br>
&gt; +         VisitSubStmtRBraceState(S-&gt;getElse());<br>
&gt; +         Cnt.adjustForControlFlow();<br>
&gt; +      }<br>
&gt; +      Cnt.applyAdjustmentsToRegion();<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitCXXTryStmt(const CXXTryStmt *S) {<br>
&gt; +      mapSourceCodeRange(S-&gt;getLocStart());<br>
&gt; +      Visit(S-&gt;getTryBlock());<br>
&gt; +      for (unsigned I = 0, E = S-&gt;getNumHandlers(); I &lt; E; ++I)<br>
&gt; +         Visit(S-&gt;getHandler(I));<br>
&gt; +      // Counter tracks the continuation block of the try statement.<br>
&gt; +      RegionMapper Cnt(this, S);<br>
&gt; +      Cnt.beginRegion();<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitCXXCatchStmt(const CXXCatchStmt *S) {<br>
&gt; +      mapSourceCodeRange(S-&gt;getLocStart());<br>
&gt; +      // Counter tracks the catch statement&#39;s handler block.<br>
&gt; +      RegionMapper Cnt(this, S);<br>
&gt; +      Cnt.beginRegion();<br>
&gt; +      VisitSubStmtRBraceState(S-&gt;getHandlerBlock());<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) \
{<br> &gt; +      Visit(E-&gt;getCond());<br>
&gt; +      mapToken(E-&gt;getQuestionLoc());<br>
&gt; +      auto State = getCurrentState();<br>
&gt; +<br>
&gt; +      // Counter tracks the &quot;true&quot; part of a conditional operator. \
The<br> &gt; +      // count in the &quot;false&quot; part will be calculated from \
this counter.<br> &gt; +      RegionMapper Cnt(this, E);<br>
&gt; +      Cnt.beginRegion();<br>
&gt; +      Visit(E-&gt;getTrueExpr());<br>
&gt; +      Cnt.adjustForControlFlow();<br>
&gt; +<br>
&gt; +      mapToken(State, E-&gt;getColonLoc());<br>
&gt; +<br>
&gt; +      Cnt.beginElseRegion();<br>
&gt; +      Visit(E-&gt;getFalseExpr());<br>
&gt; +      Cnt.adjustForControlFlow();<br>
&gt; +<br>
&gt; +      Cnt.applyAdjustmentsToRegion();<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitBinLAnd(const BinaryOperator *E) {<br>
&gt; +      Visit(E-&gt;getLHS());<br>
&gt; +      mapToken(E-&gt;getOperatorLoc());<br>
&gt; +      // Counter tracks the right hand side of a logical and operator.<br>
&gt; +      RegionMapper Cnt(this, E);<br>
&gt; +      Cnt.beginRegion();<br>
&gt; +      Visit(E-&gt;getRHS());<br>
&gt; +      Cnt.adjustForControlFlow();<br>
&gt; +      Cnt.applyAdjustmentsToRegion();<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitBinLOr(const BinaryOperator *E) {<br>
&gt; +      Visit(E-&gt;getLHS());<br>
&gt; +      mapToken(E-&gt;getOperatorLoc());<br>
&gt; +      // Counter tracks the right hand side of a logical or operator.<br>
&gt; +      RegionMapper Cnt(this, E);<br>
&gt; +      Cnt.beginRegion();<br>
&gt; +      Visit(E-&gt;getRHS());<br>
&gt; +      Cnt.adjustForControlFlow();<br>
&gt; +      Cnt.applyAdjustmentsToRegion();<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitParenExpr(const ParenExpr *E) {<br>
&gt; +      mapToken(E-&gt;getLParen());<br>
&gt; +      Visit(E-&gt;getSubExpr());<br>
&gt; +      mapToken(E-&gt;getRParen());<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitBinaryOperator(const BinaryOperator *E) {<br>
&gt; +      Visit(E-&gt;getLHS());<br>
&gt; +      mapToken(E-&gt;getOperatorLoc());<br>
&gt; +      Visit(E-&gt;getRHS());<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitUnaryOperator(const UnaryOperator *E) {<br>
&gt; +      bool Postfix = E-&gt;isPostfix();<br>
&gt; +      if (!Postfix)<br>
&gt; +         mapToken(E-&gt;getOperatorLoc());<br>
&gt; +      Visit(E-&gt;getSubExpr());<br>
&gt; +      if (Postfix)<br>
&gt; +         mapToken(E-&gt;getOperatorLoc());<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitMemberExpr(const MemberExpr *E) {<br>
&gt; +      Visit(E-&gt;getBase());<br>
&gt; +      mapToken(E-&gt;getMemberLoc());<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitCallExpr(const CallExpr *E) {<br>
&gt; +      Visit(E-&gt;getCallee());<br>
&gt; +      for (const auto &amp;Arg : E-&gt;arguments())<br>
&gt; +         Visit(Arg);<br>
&gt; +      mapToken(E-&gt;getRParenLoc());<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {<br>
&gt; +      Visit(E-&gt;getLHS());<br>
&gt; +      Visit(E-&gt;getRHS());<br>
&gt; +      mapToken(E-&gt;getRBracketLoc());<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitCStyleCastExpr(const CStyleCastExpr *E) {<br>
&gt; +      mapToken(E-&gt;getLParenLoc());<br>
&gt; +      mapToken(E-&gt;getRParenLoc());<br>
&gt; +      Visit(E-&gt;getSubExpr());<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   // Map literals as tokens so that the macros like #define PI 3.14<br>
&gt; +   // won&#39;t generate coverage mapping regions.<br>
&gt; +<br>
&gt; +   void VisitIntegerLiteral(const IntegerLiteral *E) {<br>
&gt; +      mapToken(E-&gt;getLocStart());<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitFloatingLiteral(const FloatingLiteral *E) {<br>
&gt; +      mapToken(E-&gt;getLocStart());<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitCharacterLiteral(const CharacterLiteral *E) {<br>
&gt; +      mapToken(E-&gt;getLocStart());<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitStringLiteral(const StringLiteral *E) {<br>
&gt; +      mapToken(E-&gt;getLocStart());<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   void VisitImaginaryLiteral(const ImaginaryLiteral *E) {<br>
&gt; +      mapToken(E-&gt;getLocStart());<br>
&gt; +   }<br>
&gt; +};<br>
&gt; +}<br>
&gt; +<br>
&gt; +static bool isMachO(const CodeGenModule &amp;CGM) {<br>
&gt; +   return CGM.getTarget().getTriple().isOSBinFormatMachO();<br>
&gt; +}<br>
&gt; +<br>
&gt; +static StringRef getCoverageSection(const CodeGenModule &amp;CGM) {<br>
&gt; +   return isMachO(CGM) ? &quot;__DATA,__llvm_covmap&quot; : \
&quot;__llvm_covmap&quot;;<br> &gt; +}<br>
&gt; +<br>
&gt; +void CoverageMappingModuleGen::addFunctionMappingRecord(<br>
&gt; +      llvm::GlobalVariable *FunctionName, unsigned FunctionNameSize,<br>
&gt; +      const std::string &amp;CoverageMapping) {<br>
&gt; +   llvm::LLVMContext &amp;Ctx = CGM.getLLVMContext();<br>
&gt; +   auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);<br>
&gt; +   auto *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx);<br>
&gt; +   if (!FunctionRecordTy) {<br>
&gt; +      llvm::Type *FunctionRecordTypes[] = {Int8PtrTy, Int32Ty, Int32Ty};<br>
&gt; +      FunctionRecordTy =<br>
&gt; +            llvm::StructType::get(Ctx, makeArrayRef(FunctionRecordTypes));<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   llvm::Constant *FunctionRecordVals[] = {<br>
&gt; +         llvm::ConstantExpr::getBitCast(FunctionName, Int8PtrTy),<br>
&gt; +         llvm::ConstantInt::get(Int32Ty, FunctionNameSize),<br>
&gt; +         llvm::ConstantInt::get(Int32Ty, CoverageMapping.size())};<br>
&gt; +   FunctionRecords.push_back(llvm::ConstantStruct::get(<br>
&gt; +         FunctionRecordTy, makeArrayRef(FunctionRecordVals)));<br>
&gt; +   CoverageMappings += CoverageMapping;<br>
&gt; +}<br>
&gt; +<br>
&gt; +void CoverageMappingModuleGen::emit() {<br>
&gt; +   if (FunctionRecords.empty())<br>
&gt; +      return;<br>
&gt; +   llvm::LLVMContext &amp;Ctx = CGM.getLLVMContext();<br>
&gt; +   auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);<br>
&gt; +<br>
&gt; +   // Create the filenames and merge them with coverage mappings<br>
&gt; +   llvm::SmallVector&lt;std::string, 16&gt; FilenameStrs;<br>
&gt; +   llvm::SmallVector&lt;StringRef, 16&gt; FilenameRefs;<br>
&gt; +   FilenameStrs.resize(FileEntries.size());<br>
&gt; +   FilenameRefs.resize(FileEntries.size());<br>
&gt; +   for (const auto &amp;Entry : FileEntries) {<br>
&gt; +      llvm::SmallString&lt;256&gt; Path(Entry.first-&gt;getName());<br>
&gt; +      llvm::sys::fs::make_absolute(Path);<br>
&gt; +<br>
&gt; +      auto I = Entry.second;<br>
&gt; +      FilenameStrs[I] = std::move(std::string(Path.begin(), Path.end()));<br>
&gt; +      FilenameRefs[I] = FilenameStrs[I];<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   std::string FilenamesAndCoverageMappings;<br>
&gt; +   llvm::raw_string_ostream OS(FilenamesAndCoverageMappings);<br>
&gt; +   CoverageFilenamesSectionWriter(FilenameRefs).write(OS);<br>
&gt; +   OS &lt;&lt; CoverageMappings;<br>
&gt; +   size_t CoverageMappingSize = CoverageMappings.size();<br>
&gt; +   size_t FilenamesSize = OS.str().size() - CoverageMappingSize;<br>
&gt; +   // Append extra zeroes if necessary to ensure that the size of the \
filenames<br> &gt; +   // and coverage mappings is a multiple of 8.<br>
&gt; +   if (size_t Rem = OS.str().size() % 8) {<br>
&gt; +      CoverageMappingSize += 8 - Rem;<br>
&gt; +      for (size_t I = 0, S = 8 - Rem; I &lt; S; ++I)<br>
&gt; +         OS &lt;&lt; &#39;\0&#39;;<br>
&gt; +   }<br>
&gt; +   auto *FilenamesAndMappingsVal =<br>
&gt; +         llvm::ConstantDataArray::getString(Ctx, OS.str(), false);<br>
&gt; +<br>
&gt; +   // Create the deferred function records array<br>
&gt; +   auto RecordsTy =<br>
&gt; +         llvm::ArrayType::get(FunctionRecordTy, FunctionRecords.size());<br>
&gt; +   auto RecordsVal = llvm::ConstantArray::get(RecordsTy, FunctionRecords);<br>
&gt; +<br>
&gt; +   // Create the coverage data record<br>
&gt; +   llvm::Type *CovDataTypes[] = {Int32Ty,    Int32Ty,<br>
&gt; +                                                Int32Ty,    Int32Ty,<br>
&gt; +                                                RecordsTy, \
FilenamesAndMappingsVal-&gt;getType()};<br> &gt; +   auto CovDataTy = \
llvm::StructType::get(Ctx, makeArrayRef(CovDataTypes));<br> &gt; +   llvm::Constant \
*TUDataVals[] = {<br> &gt; +         llvm::ConstantInt::get(Int32Ty, \
FunctionRecords.size()),<br> &gt; +         llvm::ConstantInt::get(Int32Ty, \
FilenamesSize),<br> &gt; +         llvm::ConstantInt::get(Int32Ty, \
CoverageMappingSize),<br> &gt; +         llvm::ConstantInt::get(Int32Ty,<br>
&gt; +                                           \
/*Version=*/CoverageMappingVersion1),<br> &gt; +         RecordsVal, \
FilenamesAndMappingsVal};<br> &gt; +   auto CovDataVal =<br>
&gt; +         llvm::ConstantStruct::get(CovDataTy, makeArrayRef(TUDataVals));<br>
&gt; +   auto CovData = new llvm::GlobalVariable(CGM.getModule(), CovDataTy, \
true,<br> &gt; +                                                               \
llvm::GlobalValue::InternalLinkage,<br> &gt; +                                        \
CovDataVal,<br> &gt; +                                                               \
&quot;__llvm_coverage_mapping&quot;);<br> &gt; +<br>
&gt; +   CovData-&gt;setSection(getCoverageSection(CGM));<br>
&gt; +   CovData-&gt;setAlignment(8);<br>
&gt; +<br>
&gt; +   // Make sure the data doesn&#39;t get deleted.<br>
&gt; +   CGM.addUsedGlobal(CovData);<br>
&gt; +}<br>
&gt; +<br>
&gt; +unsigned CoverageMappingModuleGen::getFileID(const FileEntry *File) {<br>
&gt; +   auto It = FileEntries.find(File);<br>
&gt; +   if (It != FileEntries.end())<br>
&gt; +      return It-&gt;second;<br>
&gt; +   unsigned FileID = FileEntries.size();<br>
&gt; +   FileEntries.insert(std::make_pair(File, FileID));<br>
&gt; +   return FileID;<br>
&gt; +}<br>
&gt; +<br>
&gt; +void CoverageMappingGen::emitCounterMapping(const Decl *D,<br>
&gt; +                                                                  \
llvm::raw_ostream &amp;OS) {<br> &gt; +   assert(CounterMap);<br>
&gt; +   CounterCoverageMappingBuilder Walker(CVM, *CounterMap, NumRegionCounters, \
SM,<br> &gt; +                                                          \
LangOpts);<br> &gt; +   Walker.VisitDecl(D);<br>
&gt; +   Walker.write(OS);<br>
&gt; +}<br>
&gt; +<br>
&gt; +void CoverageMappingGen::emitEmptyMapping(const Decl *D,<br>
&gt; +                                                               \
llvm::raw_ostream &amp;OS) {<br> &gt; +   EmptyCoverageMappingBuilder Walker(CVM, SM, \
LangOpts);<br> &gt; +   Walker.VisitDecl(D);<br>
&gt; +   Walker.write(OS);<br>
&gt; +}<br>
&gt;<br>
&gt; Added: cfe/trunk/lib/CodeGen/CoverageMappingGen.h<br>
&gt; URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CoverageMappingGen.h?rev=214752&amp;view=auto" \
target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CoverageMappingGen.h?rev=214752&amp;view=auto</a><br>


&gt; ==============================================================================<br>
 &gt; --- cfe/trunk/lib/CodeGen/CoverageMappingGen.h (added)<br>
&gt; +++ cfe/trunk/lib/CodeGen/CoverageMappingGen.h Mon Aug   4 13:41:51 2014<br>
&gt; @@ -0,0 +1,117 @@<br>
&gt; +//===---- CoverageMappingGen.h - Coverage mapping generation ----*- C++ \
-*-===//<br> &gt; +//<br>
&gt; +//                               The LLVM Compiler Infrastructure<br>
&gt; +//<br>
&gt; +// This file is distributed under the University of Illinois Open Source<br>
&gt; +// License. See LICENSE.TXT for details.<br>
&gt; +//<br>
&gt; +//===----------------------------------------------------------------------===//<br>
 &gt; +//<br>
&gt; +// Instrumentation-based code coverage mapping generator<br>
&gt; +//<br>
&gt; +//===----------------------------------------------------------------------===//<br>
 &gt; +<br>
&gt; +#ifndef CLANG_CODEGEN_COVERAGEMAPPINGGEN_H<br>
&gt; +#define CLANG_CODEGEN_COVERAGEMAPPINGGEN_H<br>
&gt; +<br>
&gt; +#include &quot;clang/Basic/LLVM.h&quot;<br>
&gt; +#include &quot;clang/Basic/SourceLocation.h&quot;<br>
&gt; +#include &quot;clang/Lex/PPCallbacks.h&quot;<br>
&gt; +#include &quot;clang/Frontend/CodeGenOptions.h&quot;<br>
&gt; +#include &quot;llvm/ADT/StringMap.h&quot;<br>
&gt; +#include &quot;llvm/ADT/DenseMap.h&quot;<br>
&gt; +#include &quot;llvm/IR/GlobalValue.h&quot;<br>
&gt; +#include &quot;llvm/Support/raw_ostream.h&quot;<br>
&gt; +<br>
&gt; +namespace clang {<br>
&gt; +<br>
&gt; +class LangOptions;<br>
&gt; +class SourceManager;<br>
&gt; +class FileEntry;<br>
&gt; +class Preprocessor;<br>
&gt; +class Decl;<br>
&gt; +class Stmt;<br>
&gt; +<br>
&gt; +/// \brief Stores additional source code information like skipped ranges \
which<br> &gt; +/// is required by the coverage mapping generator and is obtained \
from<br> &gt; +/// the preprocessor.<br>
&gt; +class CoverageSourceInfo : public PPCallbacks {<br>
&gt; +   std::vector&lt;SourceRange&gt; SkippedRanges;<br>
&gt; +public:<br>
&gt; +   ArrayRef&lt;SourceRange&gt; getSkippedRanges() const { return SkippedRanges; \
}<br> &gt; +<br>
&gt; +   void SourceRangeSkipped(SourceRange Range) override;<br>
&gt; +};<br>
&gt; +<br>
&gt; +namespace CodeGen {<br>
&gt; +<br>
&gt; +class CodeGenModule;<br>
&gt; +<br>
&gt; +/// \brief Organizes the cross-function state that is used while generating<br>
&gt; +/// code coverage mapping data.<br>
&gt; +class CoverageMappingModuleGen {<br>
&gt; +   CodeGenModule &amp;CGM;<br>
&gt; +   CoverageSourceInfo &amp;SourceInfo;<br>
&gt; +   llvm::SmallDenseMap&lt;const FileEntry *, unsigned, 8&gt; FileEntries;<br>
&gt; +   std::vector&lt;llvm::Constant *&gt; FunctionRecords;<br>
&gt; +   llvm::StructType *FunctionRecordTy;<br>
&gt; +   std::string CoverageMappings;<br>
&gt; +<br>
&gt; +public:<br>
&gt; +   CoverageMappingModuleGen(CodeGenModule &amp;CGM, CoverageSourceInfo \
&amp;SourceInfo)<br> &gt; +         : CGM(CGM), SourceInfo(SourceInfo), \
FunctionRecordTy(nullptr) {}<br> &gt; +<br>
&gt; +   CoverageSourceInfo &amp;getSourceInfo() const {<br>
&gt; +      return SourceInfo;<br>
&gt; +   }<br>
&gt; +<br>
&gt; +   /// \brief Add a function&#39;s coverage mapping record to the collection of \
the<br> &gt; +   /// function mapping records.<br>
&gt; +   void addFunctionMappingRecord(llvm::GlobalVariable *FunctionName,<br>
&gt; +                                                unsigned FunctionNameSize,<br>
&gt; +                                                const std::string \
&amp;CoverageMapping);<br> &gt; +<br>
&gt; +   /// \brief Emit the coverage mapping data for a translation unit.<br>
&gt; +   void emit();<br>
&gt; +<br>
&gt; +   /// \brief Return the coverage mapping translation unit file id<br>
&gt; +   /// for the given file.<br>
&gt; +   unsigned getFileID(const FileEntry *File);<br>
&gt; +};<br>
&gt; +<br>
&gt; +/// \brief Organizes the per-function state that is used while generating<br>
&gt; +/// code coverage mapping data.<br>
&gt; +class CoverageMappingGen {<br>
&gt; +   CoverageMappingModuleGen &amp;CVM;<br>
&gt; +   SourceManager &amp;SM;<br>
&gt; +   const LangOptions &amp;LangOpts;<br>
&gt; +   llvm::DenseMap&lt;const Stmt *, unsigned&gt; *CounterMap;<br>
&gt; +   unsigned NumRegionCounters;<br>
&gt; +<br>
&gt; +public:<br>
&gt; +   CoverageMappingGen(CoverageMappingModuleGen &amp;CVM, SourceManager \
&amp;SM,<br> &gt; +                               const LangOptions \
&amp;LangOpts)<br> &gt; +         : CVM(CVM), SM(SM), LangOpts(LangOpts), \
CounterMap(nullptr),<br> &gt; +            NumRegionCounters(0) {}<br>
&gt; +<br>
&gt; +   CoverageMappingGen(CoverageMappingModuleGen &amp;CVM, SourceManager \
&amp;SM,<br> &gt; +                               const LangOptions \
&amp;LangOpts,<br> &gt; +                               llvm::DenseMap&lt;const Stmt \
*, unsigned&gt; *CounterMap,<br> &gt; +                               unsigned \
NumRegionCounters)<br> &gt; +         : CVM(CVM), SM(SM), LangOpts(LangOpts), \
CounterMap(CounterMap),<br> &gt; +            NumRegionCounters(NumRegionCounters) \
{}<br> &gt; +<br>
&gt; +   /// \brief Emit the coverage mapping data which maps the regions of<br>
&gt; +   /// code to counters that will be used to find the execution<br>
&gt; +   /// counts for those regions.<br>
&gt; +   void emitCounterMapping(const Decl *D, llvm::raw_ostream &amp;OS);<br>
&gt; +<br>
&gt; +   /// \brief Emit the coverage mapping data for an unused function.<br>
&gt; +   /// It creates mapping regions with the counter of zero.<br>
&gt; +   void emitEmptyMapping(const Decl *D, llvm::raw_ostream &amp;OS);<br>
&gt; +};<br>
&gt; +<br>
&gt; +} // end namespace CodeGen<br>
&gt; +} // end namespace clang<br>
&gt; +<br>
&gt; +#endif<br>
&gt;<br>
&gt; Modified: cfe/trunk/lib/CodeGen/ModuleBuilder.cpp<br>
&gt; URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ModuleBuilder.cpp?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff" \
target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ModuleBuilder.cpp?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff</a><br>


&gt; ==============================================================================<br>
 &gt; --- cfe/trunk/lib/CodeGen/ModuleBuilder.cpp (original)<br>
&gt; +++ cfe/trunk/lib/CodeGen/ModuleBuilder.cpp Mon Aug   4 13:41:51 2014<br>
&gt; @@ -46,14 +46,18 @@ namespace {<br>
&gt;            }<br>
&gt;         };<br>
&gt;<br>
&gt; +      CoverageSourceInfo *CoverageInfo;<br>
&gt; +<br>
&gt;      protected:<br>
&gt;         std::unique_ptr&lt;llvm::Module&gt; M;<br>
&gt;         std::unique_ptr&lt;CodeGen::CodeGenModule&gt; Builder;<br>
&gt;<br>
&gt;      public:<br>
&gt;         CodeGeneratorImpl(DiagnosticsEngine &amp;diags, const std::string&amp; \
ModuleName,<br> &gt; -                                 const CodeGenOptions &amp;CGO, \
llvm::LLVMContext&amp; C)<br> &gt; +                                 const \
CodeGenOptions &amp;CGO, llvm::LLVMContext&amp; C,<br> &gt; +                         \
CoverageSourceInfo *CoverageInfo = nullptr)<br> &gt;            : Diags(diags), \
CodeGenOpts(CGO), HandlingTopLevelDecls(0),<br> &gt; +            \
CoverageInfo(CoverageInfo),<br> &gt;               M(new llvm::Module(ModuleName, C)) \
{}<br> &gt;<br>
&gt;         virtual ~CodeGeneratorImpl() {}<br>
&gt; @@ -86,7 +90,7 @@ namespace {<br>
&gt;            M-&gt;setDataLayout(Ctx-&gt;getTargetInfo().getTargetDescription());<br>
 &gt;            TD.reset(new \
llvm::DataLayout(Ctx-&gt;getTargetInfo().getTargetDescription()));<br> &gt;           \
Builder.reset(new CodeGen::CodeGenModule(Context, CodeGenOpts, *M, *TD,<br> &gt; -    \
Diags));<br> &gt; +                                                                   \
Diags, CoverageInfo));<br> &gt;<br>
&gt;            for (size_t i = 0, e = CodeGenOpts.DependentLibraries.size(); i &lt; \
e; ++i)<br> &gt;               \
HandleDependentLibrary(CodeGenOpts.DependentLibraries[i]);<br> &gt; @@ -136,6 +140,10 \
@@ namespace {<br> &gt;            //       void foo() { bar(); }<br>
&gt;            //    } A;<br>
&gt;            DeferredInlineMethodDefinitions.push_back(D);<br>
&gt; +<br>
&gt; +         // Always provide some coverage mapping<br>
&gt; +         // even for the methods that aren&#39;t emitted.<br>
&gt; +         Builder-&gt;AddDeferredUnusedCoverageMapping(D);<br>
&gt;         }<br>
&gt;<br>
&gt;         /// HandleTagDeclDefinition - This callback is invoked each time a \
TagDecl<br> &gt; @@ -221,6 +229,7 @@ CodeGenerator *clang::CreateLLVMCodeGen(<br>
&gt;                                                               const \
std::string&amp; ModuleName,<br> &gt;                                                 \
const CodeGenOptions &amp;CGO,<br> &gt;                                               \
const TargetOptions &amp;/*TO*/,<br> &gt; -                                           \
llvm::LLVMContext&amp; C) {<br> &gt; -   return new CodeGeneratorImpl(Diags, \
ModuleName, CGO, C);<br> &gt; +                                                       \
llvm::LLVMContext&amp; C,<br> &gt; +                                                  \
CoverageSourceInfo *CoverageInfo) {<br> &gt; +   return new CodeGeneratorImpl(Diags, \
ModuleName, CGO, C, CoverageInfo);<br> &gt;   }<br>
&gt;<br>
&gt; Modified: cfe/trunk/lib/Driver/Tools.cpp<br>
&gt; URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff" \
target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff</a><br>


&gt; ==============================================================================<br>
 &gt; --- cfe/trunk/lib/Driver/Tools.cpp (original)<br>
&gt; +++ cfe/trunk/lib/Driver/Tools.cpp Mon Aug   4 13:41:51 2014<br>
&gt; @@ -3230,6 +3230,14 @@ void Clang::ConstructJob(Compilation &amp;C,<br>
&gt;            Args.hasArg(options::OPT_coverage))<br>
&gt;         CmdArgs.push_back(&quot;-femit-coverage-data&quot;);<br>
&gt;<br>
&gt; +   if (Args.hasArg(options::OPT_fcoverage_mapping) &amp;&amp;<br>
&gt; +         !Args.hasArg(options::OPT_fprofile_instr_generate))<br>
&gt; +      D.Diag(diag::err_drv_argument_only_allowed_with)<br>
&gt; +         &lt;&lt; &quot;-fcoverage-mapping&quot; &lt;&lt; \
&quot;-fprofile-instr-generate&quot;;<br> &gt; +<br>
&gt; +   if (Args.hasArg(options::OPT_fcoverage_mapping))<br>
&gt; +      CmdArgs.push_back(&quot;-fcoverage-mapping&quot;);<br>
&gt; +<br>
&gt;      if (C.getArgs().hasArg(options::OPT_c) ||<br>
&gt;            C.getArgs().hasArg(options::OPT_S)) {<br>
&gt;         if (Output.isFilename()) {<br>
&gt;<br>
&gt; Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp<br>
&gt; URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff" \
target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=214752&amp;r1=214751&amp;r2=214752&amp;view=diff</a><br>


&gt; ==============================================================================<br>
 &gt; --- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)<br>
&gt; +++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Mon Aug   4 13:41:51 2014<br>
&gt; @@ -403,6 +403,7 @@ static bool ParseCodeGenArgs(CodeGenOpti<br>
&gt;      Opts.SampleProfileFile = \
Args.getLastArgValue(OPT_fprofile_sample_use_EQ);<br> &gt;      \
Opts.ProfileInstrGenerate = Args.hasArg(OPT_fprofile_instr_generate);<br> &gt;      \
Opts.InstrProfileInput = Args.getLastArgValue(OPT_fprofile_instr_use_EQ);<br> &gt; +  \
Opts.CoverageMapping = Args.hasArg(OPT_fcoverage_mapping);<br> &gt;      \
Opts.AsmVerbose = Args.hasArg(OPT_masm_verbose);<br> &gt;      \
Opts.ObjCAutoRefCountExceptions = Args.hasArg(OPT_fobjc_arc_exceptions);<br> &gt;     \
Opts.CUDAIsDevice = Args.hasArg(OPT_fcuda_is_device);<br> &gt;<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; cfe-commits mailing list<br>
&gt; <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
&gt; <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" \
target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br> \
</div></div></blockquote></div><br></div>



_______________________________________________
cfe-commits mailing list
cfe-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic