diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 18 |
3 files changed, 21 insertions, 6 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index ccbbe50093b..a9c5f7d58bf 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -644,7 +644,8 @@ void Sema::getUndefinedButUsed( continue; if (FD->isExternallyVisible() && !isExternalWithNoLinkageType(FD) && - !FD->getMostRecentDecl()->isInlined()) + !FD->getMostRecentDecl()->isInlined() && + !FD->hasAttr<ExcludeFromExplicitInstantiationAttr>()) continue; if (FD->getBuiltinID()) continue; @@ -654,7 +655,8 @@ void Sema::getUndefinedButUsed( continue; if (VD->isExternallyVisible() && !isExternalWithNoLinkageType(VD) && - !VD->getMostRecentDecl()->isInline()) + !VD->getMostRecentDecl()->isInline() && + !VD->hasAttr<ExcludeFromExplicitInstantiationAttr>()) continue; // Skip VarDecls that lack formal definitions but which we know are in diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index a437f159968..c0fb3356bae 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -6512,6 +6512,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case ParsedAttr::AT_InternalLinkage: handleInternalLinkageAttr(S, D, AL); break; + case ParsedAttr::AT_ExcludeFromExplicitInstantiation: + handleSimpleAttribute<ExcludeFromExplicitInstantiationAttr>(S, D, AL); + break; case ParsedAttr::AT_LTOVisibilityPublic: handleSimpleAttribute<LTOVisibilityPublicAttr>(S, D, AL); break; diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 5666cf04a24..cfedf0a0994 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2574,10 +2574,14 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, for (auto *D : Instantiation->decls()) { bool SuppressNew = false; if (auto *Function = dyn_cast<FunctionDecl>(D)) { - if (FunctionDecl *Pattern - = Function->getInstantiatedFromMemberFunction()) { - MemberSpecializationInfo *MSInfo - = Function->getMemberSpecializationInfo(); + if (FunctionDecl *Pattern = + Function->getInstantiatedFromMemberFunction()) { + + if (Function->hasAttr<ExcludeFromExplicitInstantiationAttr>()) + continue; + + MemberSpecializationInfo *MSInfo = + Function->getMemberSpecializationInfo(); assert(MSInfo && "No member specialization information?"); if (MSInfo->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) @@ -2618,6 +2622,9 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, continue; if (Var->isStaticDataMember()) { + if (Var->hasAttr<ExcludeFromExplicitInstantiationAttr>()) + continue; + MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo(); assert(MSInfo && "No member specialization information?"); if (MSInfo->getTemplateSpecializationKind() @@ -2649,6 +2656,9 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, } } } else if (auto *Record = dyn_cast<CXXRecordDecl>(D)) { + if (Record->hasAttr<ExcludeFromExplicitInstantiationAttr>()) + continue; + // Always skip the injected-class-name, along with any // redeclarations of nested classes, since both would cause us // to try to instantiate the members of a class twice. |