diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 31 |
4 files changed, 44 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 1c350a7e38b..31210264aff 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -6723,6 +6723,7 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K, // Diagnostics for deprecated or unavailable. unsigned diag, diag_message, diag_fwdclass_message; unsigned diag_available_here = diag::note_availability_specified_here; + SourceLocation NoteLocation = D->getLocation(); // Matches 'diag::note_property_attribute' options. unsigned property_note_select; @@ -6745,6 +6746,8 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K, diag_fwdclass_message = diag::warn_deprecated_fwdclass_message; property_note_select = /* deprecated */ 0; available_here_select_kind = /* deprecated */ 2; + if (const auto *attr = D->getAttr<DeprecatedAttr>()) + NoteLocation = attr->getLocation(); break; case AR_Unavailable: @@ -6863,7 +6866,7 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K, } } else - S.Diag(D->getLocation(), diag_available_here) + S.Diag(NoteLocation, diag_available_here) << D << available_here_select_kind; if (K == AR_NotYetIntroduced) diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index f6c6ccbd410..b344279784e 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -2846,6 +2846,13 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, Decl->setLexicalDeclContext(ClassTemplate->getLexicalDeclContext()); } + if (Decl->getSpecializationKind() == TSK_Undeclared) { + MultiLevelTemplateArgumentList TemplateArgLists; + TemplateArgLists.addOuterTemplateArguments(Converted); + InstantiateAttrsForDecl(TemplateArgLists, ClassTemplate->getTemplatedDecl(), + Decl); + } + // Diagnose uses of this specialization. (void)DiagnoseUseOfDecl(Decl, TemplateLoc); diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 314dfe32561..67e330a6da9 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1939,6 +1939,9 @@ namespace clang { namespace sema { Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs); + Attr *instantiateTemplateAttributeForDecl( + const Attr *At, ASTContext &C, Sema &S, + const MultiLevelTemplateArgumentList &TemplateArgs); } } diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index cab55ea0bf7..d75d705f882 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -328,6 +328,34 @@ static void instantiateOMPDeclareSimdDeclAttr( Attr.getRange()); } +static bool DeclContainsAttr(const Decl *D, const Attr *NewAttr) { + if (!D->hasAttrs() || NewAttr->duplicatesAllowed()) + return false; + return llvm::find_if(D->getAttrs(), [NewAttr](const Attr *Attr) { + return Attr->getKind() == NewAttr->getKind(); + }) != D->getAttrs().end(); +} + +void Sema::InstantiateAttrsForDecl( + const MultiLevelTemplateArgumentList &TemplateArgs, const Decl *Tmpl, + Decl *New, LateInstantiatedAttrVec *LateAttrs, + LocalInstantiationScope *OuterMostScope) { + if (NamedDecl *ND = dyn_cast<NamedDecl>(New)) { + for (const auto *TmplAttr : Tmpl->attrs()) { + // FIXME: If any of the special case versions from InstantiateAttrs become + // applicable to template declaration, we'll need to add them here. + CXXThisScopeRAII ThisScope( + *this, dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext()), + /*TypeQuals*/ 0, ND->isCXXInstanceMember()); + + Attr *NewAttr = sema::instantiateTemplateAttributeForDecl( + TmplAttr, Context, *this, TemplateArgs); + if (NewAttr && !DeclContainsAttr(New, NewAttr)) + New->addAttr(NewAttr); + } + } +} + void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, const Decl *Tmpl, Decl *New, LateInstantiatedAttrVec *LateAttrs, @@ -421,7 +449,8 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, Attr *NewAttr = sema::instantiateTemplateAttribute(TmplAttr, Context, *this, TemplateArgs); - if (NewAttr) + + if (NewAttr && !DeclContainsAttr(New, NewAttr)) New->addAttr(NewAttr); } } |