================
@@ -1068,28 +1086,38 @@ void Sema::InstantiateAttrs(const
MultiLevelTemplateArgumentList &TemplateArgs,
assert(!TmplAttr->isPackExpansion());
if (TmplAttr->isLateParsed() && LateAttrs) {
- // Late parsed attributes must be instantiated and attached after the
- // enclosing class has been instantiated. See Sema::InstantiateClass.
- LocalInstantiationScope *Saved = nullptr;
- if (CurrentInstantiationScope)
- Saved = CurrentInstantiationScope->cloneScopes(OuterMostScope);
+ // A late-parsed attribute may name a declaration that is instantiated
+ // after the one it is on: a class member's names a later member, and a
+ // parameter's a later parameter. Defer it, with the scope to instantiate
+ // it in, until they all are; see InstantiateLateAttrs.
+ assert(CurrentInstantiationScope && "no scope to defer the attribute
in");
+ LocalInstantiationScope *Saved =
+ CurrentInstantiationScope->cloneScopes(OuterMostScope);
LateAttrs->push_back(LateInstantiatedAttribute(TmplAttr, Saved, New));
} else {
- // Allow 'this' within late-parsed attributes.
- auto *ND = cast<NamedDecl>(New);
- auto *ThisContext =
dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext());
- CXXThisScopeRAII ThisScope(*this, ThisContext, Qualifiers(),
- ND->isCXXInstanceMember());
-
- Attr *NewAttr = sema::instantiateTemplateAttribute(TmplAttr, Context,
- *this, TemplateArgs);
- if (NewAttr && isRelevantAttr(*this, New, TmplAttr) &&
- checkInstantiatedThreadSafetyAttrs(New, NewAttr))
- New->addAttr(NewAttr);
+ instantiateAttrOnDecl(*this, TemplateArgs, TmplAttr, New);
}
}
}
+void Sema::InstantiateLateAttrs(
+ const MultiLevelTemplateArgumentList &TemplateArgs,
+ LateInstantiatedAttrVec &LateAttrs,
+ LocalInstantiationScope *OuterMostScope) {
+ assert(
+ CurrentInstantiationScope == OuterMostScope &&
+ "late attributes instantiated outside the scope they were deferred in");
+ for (const LateInstantiatedAttribute &LA : LateAttrs) {
+ CurrentInstantiationScope = LA.Scope;
+ instantiateAttrOnDecl(*this, TemplateArgs, LA.TmplAttr, LA.NewDecl);
+ // Exiting the saved scopes restores the outermost one.
+ LocalInstantiationScope::deleteScopes(LA.Scope, OuterMostScope);
+ assert(CurrentInstantiationScope == OuterMostScope &&
+ "deferred scope did not extend the outermost scope");
+ }
+ LateAttrs.clear();
----------------
aaronpuchert wrote:
It would seem cleaner to me to leave this to the caller and make the parameter
a `const` reference.
https://github.com/llvm/llvm-project/pull/232784
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits