DeclContext *Owner;
const MultiLevelTemplateArgumentList &TemplateArgs;
- void InstantiateAttrs(Decl *Tmpl, Decl *New);
+ bool InstantiateAttrs(Decl *Tmpl, Decl *New);
public:
typedef Sema::OwningExprResult OwningExprResult;
}
// FIXME: Is this too simple?
-void TemplateDeclInstantiator::InstantiateAttrs(Decl *Tmpl, Decl *New) {
+bool TemplateDeclInstantiator::InstantiateAttrs(Decl *Tmpl, Decl *New) {
for (const Attr *TmplAttr = Tmpl->getAttrs(); TmplAttr;
TmplAttr = TmplAttr->getNext()) {
New->addAttr(NewAttr);
}
+
+ return false;
}
Decl *
D->getQualifier(),
D->getTargetNameLoc(),
D->getNamespace());
+ InstantiateAttrs(D, Inst);
Owner->addDecl(Inst);
+
return Inst;
}
Var->setAccess(D->getAccess());
Var->setUsed(D->isUsed());
-
+ InstantiateAttrs(D, Var);
+
// FIXME: In theory, we could have a previous declaration for variables that
// are not static data members.
bool Redeclaration = false;
FriendDecl *FD =
FriendDecl::Create(SemaRef.Context, Owner, D->getLocation(),
cast<NamedDecl>(NewND), D->getFriendLoc());
+ InstantiateAttrs(D, FD);
+
FD->setAccess(AS_public);
Owner->addDecl(FD);
return FD;
Enum->setInstantiationOfMemberEnum(D);
Enum->setAccess(D->getAccess());
if (SubstQualifier(D, Enum)) return 0;
+ InstantiateAttrs(D, Enum);
Owner->addDecl(Enum);
Enum->startDefinition();
PrevClassTemplate);
RecordInst->setDescribedClassTemplate(Inst);
+ InstantiateAttrs(D, Inst);
+
if (isFriend) {
if (PrevClassTemplate)
Inst->setAccess(PrevClassTemplate->getAccess());
!(isFriend && !D->getTemplatedDecl()->isThisDeclarationADefinition()))
InstTemplate->setInstantiatedFromMemberTemplate(D);
+ InstantiateAttrs(D, InstTemplate);
+
// Make declarations visible in the appropriate context.
if (!isFriend)
Owner->addDecl(InstTemplate);
D->getLocation(), D->getIdentifier(),
D->getTagKeywordLoc(), PrevDecl);
+ InstantiateAttrs(D, Record);
+
// Substitute the nested name specifier, if any.
if (SubstQualifier(D, Record))
return 0;
TTPT->getName(),
D->wasDeclaredWithTypename(),
D->isParameterPack());
+ InstantiateAttrs(D, Inst);
if (D->hasDefaultArgument())
Inst->setDefaultArgument(D->getDefaultArgumentInfo(), false);
if (Invalid)
Param->setInvalidDecl();
+ InstantiateAttrs(D, Param);
Param->setDefaultArgument(D->getDefaultArgument());
// Introduce this template parameter's instantiation into the instantiation
D->getDepth() - 1, D->getPosition(),
D->getIdentifier(), InstParams);
Param->setDefaultArgument(D->getDefaultArgument());
-
+ InstantiateAttrs(D, Param);
+
// Introduce this template parameter's instantiation into the instantiation
// scope.
SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Param);
D->getIdentLocation(),
D->getNominatedNamespace(),
D->getCommonAncestor());
+ InstantiateAttrs(D, Inst);
+
Owner->addDecl(Inst);
return Inst;
}
D->getTargetNestedNameDecl(),
D->getDeclName(),
D->isTypeName());
+ InstantiateAttrs(D, NewUD);
CXXScopeSpec SS;
SS.setScopeRep(D->getTargetNestedNameDecl());
D->getDeclName(), 0,
/*instantiation*/ true,
/*typename*/ true, D->getTypenameLoc());
- if (UD)
+ if (UD) {
+ InstantiateAttrs(D, UD);
SemaRef.Context.setInstantiatedFromUsingDecl(cast<UsingDecl>(UD), D);
+ }
return UD;
}
D->getDeclName(), 0,
/*instantiation*/ true,
/*typename*/ false, SourceLocation());
- if (UD)
+ if (UD) {
+ InstantiateAttrs(D, UD);
SemaRef.Context.setInstantiatedFromUsingDecl(cast<UsingDecl>(UD), D);
+ }
return UD;
}
return 0;
InstPartialSpec->setInstantiatedFromMember(PartialSpec);
- InstPartialSpec->setTypeAsWritten(WrittenTy);
-
+ InstPartialSpec->setTypeAsWritten(WrittenTy);
+ InstantiateAttrs(PartialSpec, InstPartialSpec);
+
// Add this partial specialization to the set of class template partial
// specializations.
ClassTemplate->getPartialSpecializations().InsertNode(InstPartialSpec,
if (Tmpl->isDeleted())
New->setDeleted();
+ if (InstantiateAttrs(Tmpl, New))
+ return true;
+
// If we are performing substituting explicitly-specified template arguments
// or deduced template arguments into a function template and we reach this
// point, we are now past the point where SFINAE applies and have committed