@@ -221,6 +221,48 @@ namespace clang {
221221 Record.AddDeclRef (F.second );
222222 }
223223
224+ template <typename T> bool shouldSkipWritingSpecializations (T *Spec) {
225+ // Now we will only avoid writing specializations if we're generating
226+ // reduced BMI.
227+ if (!GeneratingReducedBMI)
228+ return false ;
229+
230+ assert ((isa<FunctionDecl, ClassTemplateSpecializationDecl,
231+ VarTemplateSpecializationDecl>(Spec)));
232+
233+ ArrayRef<TemplateArgument> Args;
234+ if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Spec))
235+ Args = CTSD->getTemplateArgs ().asArray ();
236+ else if (auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(Spec))
237+ Args = VTSD->getTemplateArgs ().asArray ();
238+ else
239+ Args = cast<FunctionDecl>(Spec)
240+ ->getTemplateSpecializationArgs ()
241+ ->asArray ();
242+
243+ // If there is any template argument is TULocal, we can avoid writing the
244+ // specialization since the consumers of reduced BMI won't get the
245+ // specialization anyway.
246+ for (const TemplateArgument &TA : Args) {
247+ switch (TA.getKind ()) {
248+ case TemplateArgument::Type: {
249+ Linkage L = TA.getAsType ()->getLinkage ();
250+ if (!isExternallyVisible (L))
251+ return true ;
252+ break ;
253+ }
254+ case TemplateArgument::Declaration:
255+ if (!TA.getAsDecl ()->isExternallyVisible ())
256+ return true ;
257+ break ;
258+ default :
259+ break ;
260+ }
261+ }
262+
263+ return false ;
264+ }
265+
224266 // / Add to the record the first template specialization from each module
225267 // / file that provides a declaration of D. We store the DeclId and an
226268 // / ODRHash of the template arguments of D which should provide enough
@@ -235,6 +277,9 @@ namespace clang {
235277 CollectFirstDeclFromEachModule (D, /* IncludeLocal*/ true , Firsts);
236278
237279 for (const auto &F : Firsts) {
280+ if (shouldSkipWritingSpecializations (F.second ))
281+ continue ;
282+
238283 if (isa<ClassTemplatePartialSpecializationDecl,
239284 VarTemplatePartialSpecializationDecl>(F.second ))
240285 PartialSpecsInMap.push_back (F.second );
0 commit comments