diff options
Diffstat (limited to 'clang/lib/AST/ASTContext.cpp')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 96b7b56c1c7..43577e8640a 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -9553,6 +9553,29 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { else return false; + if (D->isFromASTFile() && !LangOpts.BuildingPCHWithObjectFile) { + assert(getExternalSource() && "It's from an AST file; must have a source."); + // On Windows, PCH files are built together with an object file. If this + // declaration comes from such a PCH and DeclMustBeEmitted would return + // true, it would have returned true and the decl would have been emitted + // into that object file, so it doesn't need to be emitted here. + // Note that decls are still emitted if they're referenced, as usual; + // DeclMustBeEmitted is used to decide whether a decl must be emitted even + // if it's not referenced. + // + // Explicit template instantiation definitions are tricky. If there was an + // explicit template instantiation decl in the PCH before, it will look like + // the definition comes from there, even if that was just the declaration. + // (Explicit instantiation defs of variable templates always get emitted.) + bool IsExpInstDef = + isa<FunctionDecl>(D) && + cast<FunctionDecl>(D)->getTemplateSpecializationKind() == + TSK_ExplicitInstantiationDefinition; + + if (getExternalSource()->DeclIsFromPCHWithObjectFile(D) && !IsExpInstDef) + return false; + } + // If this is a member of a class template, we do not need to emit it. if (D->getDeclContext()->isDependentContext()) return false; @@ -9573,7 +9596,7 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { // Constructors and destructors are required. if (FD->hasAttr<ConstructorAttr>() || FD->hasAttr<DestructorAttr>()) return true; - + // The key function for a class is required. This rule only comes // into play when inline functions can be key functions, though. if (getTargetInfo().getCXXABI().canKeyFunctionBeInline()) { @@ -9594,7 +9617,7 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { // Implicit template instantiations can also be deferred in C++. return !isDiscardableGVALinkage(Linkage); } - + const auto *VD = cast<VarDecl>(D); assert(VD->isFileVarDecl() && "Expected file scoped var"); |