diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp index f4740a5..035c37c 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp @@ -893,6 +893,16 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, LookupQualifiedName(Previous, SemanticContext); } else { SemanticContext = CurContext; + + // C++14 [class.mem]p14: + // If T is the name of a class, then each of the following shall have a + // name different from T: + // -- every member template of class T + if (TUK != TUK_Friend && + DiagnoseClassNameShadow(SemanticContext, + DeclarationNameInfo(Name, NameLoc))) + return true; + LookupName(Previous, S); } @@ -947,8 +957,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, // Check that the chosen semantic context doesn't already contain a // declaration of this name as a non-tag type. - LookupResult Previous(*this, Name, NameLoc, LookupOrdinaryName, - ForRedeclaration); + Previous.clear(LookupOrdinaryName); DeclContext *LookupContext = SemanticContext; while (LookupContext->isTransparentContext()) LookupContext = LookupContext->getLookupParent(); @@ -962,9 +971,25 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, } } } else if (PrevDecl && - !isDeclInScope(PrevDecl, SemanticContext, S, SS.isValid())) + !isDeclInScope(Previous.getRepresentativeDecl(), SemanticContext, + S, SS.isValid())) PrevDecl = PrevClassTemplate = nullptr; + if (auto *Shadow = dyn_cast_or_null<UsingShadowDecl>( + PrevDecl ? Previous.getRepresentativeDecl() : nullptr)) { + if (SS.isEmpty() && + !(PrevClassTemplate && + PrevClassTemplate->getDeclContext()->getRedeclContext()->Equals( + SemanticContext->getRedeclContext()))) { + Diag(KWLoc, diag::err_using_decl_conflict_reverse); + Diag(Shadow->getTargetDecl()->getLocation(), + diag::note_using_decl_target); + Diag(Shadow->getUsingDecl()->getLocation(), diag::note_using_decl) << 0; + // Recover by ignoring the old declaration. + PrevDecl = PrevClassTemplate = nullptr; + } + } + if (PrevClassTemplate) { // Ensure that the template parameter lists are compatible. Skip this check // for a friend in a dependent context: the template parameter list itself @@ -983,7 +1008,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, // template declaration (7.1.5.3). RecordDecl *PrevRecordDecl = PrevClassTemplate->getTemplatedDecl(); if (!isAcceptableTagRedeclaration(PrevRecordDecl, Kind, - TUK == TUK_Definition, KWLoc, *Name)) { + TUK == TUK_Definition, KWLoc, Name)) { Diag(KWLoc, diag::err_use_with_wrong_tag) << Name << FixItHint::CreateReplacement(KWLoc, PrevRecordDecl->getKindName()); @@ -2285,7 +2310,7 @@ TypeResult Sema::ActOnTagTemplateIdType(TagUseKind TUK, assert(Id && "templated class must have an identifier"); if (!isAcceptableTagRedeclaration(D, TagKind, TUK == TUK_Definition, - TagLoc, *Id)) { + TagLoc, Id)) { Diag(TagLoc, diag::err_use_with_wrong_tag) << Result << FixItHint::CreateReplacement(SourceRange(TagLoc), D->getKindName()); @@ -6174,7 +6199,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, assert(Kind != TTK_Enum && "Invalid enum tag in class template spec!"); if (!isAcceptableTagRedeclaration(ClassTemplate->getTemplatedDecl(), Kind, TUK == TUK_Definition, KWLoc, - *ClassTemplate->getIdentifier())) { + ClassTemplate->getIdentifier())) { Diag(KWLoc, diag::err_use_with_wrong_tag) << ClassTemplate << FixItHint::CreateReplacement(KWLoc, @@ -7210,7 +7235,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, if (!isAcceptableTagRedeclaration(ClassTemplate->getTemplatedDecl(), Kind, /*isDefinition*/false, KWLoc, - *ClassTemplate->getIdentifier())) { + ClassTemplate->getIdentifier())) { Diag(KWLoc, diag::err_use_with_wrong_tag) << ClassTemplate << FixItHint::CreateReplacement(KWLoc, |