|
21 | 21 | #include "CGOpenMPRuntime.h"
|
22 | 22 | #include "CodeGenFunction.h"
|
23 | 23 | #include "CodeGenPGO.h"
|
| 24 | +#include "CoverageMappingGen.h" |
24 | 25 | #include "CodeGenTBAA.h"
|
25 | 26 | #include "TargetInfo.h"
|
26 | 27 | #include "clang/AST/ASTContext.h"
|
@@ -74,7 +75,8 @@ static CGCXXABI *createCXXABI(CodeGenModule &CGM) {
|
74 | 75 |
|
75 | 76 | CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
|
76 | 77 | llvm::Module &M, const llvm::DataLayout &TD,
|
77 |
| - DiagnosticsEngine &diags) |
| 78 | + DiagnosticsEngine &diags, |
| 79 | + CoverageSourceInfo *CoverageInfo) |
78 | 80 | : Context(C), LangOpts(C.getLangOpts()), CodeGenOpts(CGO), TheModule(M),
|
79 | 81 | Diags(diags), TheDataLayout(TD), Target(C.getTargetInfo()),
|
80 | 82 | ABI(createCXXABI(*this)), VMContext(M.getContext()), TBAA(nullptr),
|
@@ -146,6 +148,11 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
|
146 | 148 | getDiags().Report(DiagID) << EC.message();
|
147 | 149 | }
|
148 | 150 | }
|
| 151 | + |
| 152 | + // If coverage mapping generation is enabled, create the |
| 153 | + // CoverageMappingModuleGen object. |
| 154 | + if (CodeGenOpts.CoverageMapping) |
| 155 | + CoverageMapping.reset(new CoverageMappingModuleGen(*this, *CoverageInfo)); |
149 | 156 | }
|
150 | 157 |
|
151 | 158 | CodeGenModule::~CodeGenModule() {
|
@@ -344,6 +351,9 @@ void CodeGenModule::Release() {
|
344 | 351 | EmitCtorList(GlobalDtors, "llvm.global_dtors");
|
345 | 352 | EmitGlobalAnnotations();
|
346 | 353 | EmitStaticExternCAliases();
|
| 354 | + EmitDeferredUnusedCoverageMappings(); |
| 355 | + if (CoverageMapping) |
| 356 | + CoverageMapping->emit(); |
347 | 357 | emitLLVMUsed();
|
348 | 358 |
|
349 | 359 | if (CodeGenOpts.Autolink &&
|
@@ -2989,6 +2999,9 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
|
2989 | 2999 | return;
|
2990 | 3000 |
|
2991 | 3001 | EmitGlobal(cast<FunctionDecl>(D));
|
| 3002 | + // Always provide some coverage mapping |
| 3003 | + // even for the functions that aren't emitted. |
| 3004 | + AddDeferredUnusedCoverageMapping(D); |
2992 | 3005 | break;
|
2993 | 3006 |
|
2994 | 3007 | case Decl::Var:
|
@@ -3138,6 +3151,80 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
|
3138 | 3151 | }
|
3139 | 3152 | }
|
3140 | 3153 |
|
| 3154 | +void CodeGenModule::AddDeferredUnusedCoverageMapping(Decl *D) { |
| 3155 | + // Do we need to generate coverage mapping? |
| 3156 | + if (!CodeGenOpts.CoverageMapping) |
| 3157 | + return; |
| 3158 | + switch (D->getKind()) { |
| 3159 | + case Decl::CXXConversion: |
| 3160 | + case Decl::CXXMethod: |
| 3161 | + case Decl::Function: |
| 3162 | + case Decl::ObjCMethod: |
| 3163 | + case Decl::CXXConstructor: |
| 3164 | + case Decl::CXXDestructor: { |
| 3165 | + if (!cast<FunctionDecl>(D)->hasBody()) |
| 3166 | + return; |
| 3167 | + auto I = DeferredEmptyCoverageMappingDecls.find(D); |
| 3168 | + if (I == DeferredEmptyCoverageMappingDecls.end()) |
| 3169 | + DeferredEmptyCoverageMappingDecls[D] = true; |
| 3170 | + break; |
| 3171 | + } |
| 3172 | + default: |
| 3173 | + break; |
| 3174 | + }; |
| 3175 | +} |
| 3176 | + |
| 3177 | +void CodeGenModule::ClearUnusedCoverageMapping(const Decl *D) { |
| 3178 | + // Do we need to generate coverage mapping? |
| 3179 | + if (!CodeGenOpts.CoverageMapping) |
| 3180 | + return; |
| 3181 | + if (const auto *Fn = dyn_cast<FunctionDecl>(D)) { |
| 3182 | + if (Fn->isTemplateInstantiation()) |
| 3183 | + ClearUnusedCoverageMapping(Fn->getTemplateInstantiationPattern()); |
| 3184 | + } |
| 3185 | + auto I = DeferredEmptyCoverageMappingDecls.find(D); |
| 3186 | + if (I == DeferredEmptyCoverageMappingDecls.end()) |
| 3187 | + DeferredEmptyCoverageMappingDecls[D] = false; |
| 3188 | + else |
| 3189 | + I->second = false; |
| 3190 | +} |
| 3191 | + |
| 3192 | +void CodeGenModule::EmitDeferredUnusedCoverageMappings() { |
| 3193 | + for (const auto I : DeferredEmptyCoverageMappingDecls) { |
| 3194 | + if (!I.second) |
| 3195 | + continue; |
| 3196 | + const auto *D = I.first; |
| 3197 | + switch (D->getKind()) { |
| 3198 | + case Decl::CXXConversion: |
| 3199 | + case Decl::CXXMethod: |
| 3200 | + case Decl::Function: |
| 3201 | + case Decl::ObjCMethod: { |
| 3202 | + CodeGenPGO PGO(*this); |
| 3203 | + GlobalDecl GD(cast<FunctionDecl>(D)); |
| 3204 | + PGO.emitEmptyCounterMapping(D, getMangledName(GD), |
| 3205 | + getFunctionLinkage(GD)); |
| 3206 | + break; |
| 3207 | + } |
| 3208 | + case Decl::CXXConstructor: { |
| 3209 | + CodeGenPGO PGO(*this); |
| 3210 | + GlobalDecl GD(cast<CXXConstructorDecl>(D), Ctor_Base); |
| 3211 | + PGO.emitEmptyCounterMapping(D, getMangledName(GD), |
| 3212 | + getFunctionLinkage(GD)); |
| 3213 | + break; |
| 3214 | + } |
| 3215 | + case Decl::CXXDestructor: { |
| 3216 | + CodeGenPGO PGO(*this); |
| 3217 | + GlobalDecl GD(cast<CXXDestructorDecl>(D), Dtor_Base); |
| 3218 | + PGO.emitEmptyCounterMapping(D, getMangledName(GD), |
| 3219 | + getFunctionLinkage(GD)); |
| 3220 | + break; |
| 3221 | + } |
| 3222 | + default: |
| 3223 | + break; |
| 3224 | + }; |
| 3225 | + } |
| 3226 | +} |
| 3227 | + |
3141 | 3228 | /// Turns the given pointer into a constant.
|
3142 | 3229 | static llvm::Constant *GetPointerConstant(llvm::LLVMContext &Context,
|
3143 | 3230 | const void *Ptr) {
|
|
0 commit comments