From e869b753e4edb9aee7fc30cc2dd886241cbdba1f Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Mon, 6 Jul 2015 22:56:29 +0000 Subject: [PATCH] Refactor to avoid long if-condition. llvm-svn: 241518 --- clang/lib/Sema/SemaDecl.cpp | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index acd331050cfd..9db14bf70e70 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11424,6 +11424,27 @@ static FixItHint createFriendTagNNSFixIt(Sema &SemaRef, NamedDecl *ND, Scope *S, return FixItHint::CreateInsertion(NameLoc, Insertion); } +/// \brief Determine whether a tag originally declared in context \p OldDC can +/// be redeclared with an unqualfied name in \p NewDC (assuming name lookup +/// found a declaration in \p OldDC as a previous decl, perhaps through a +/// using-declaration). +static bool isAcceptableTagRedeclContext(Sema &S, DeclContext *OldDC, + DeclContext *NewDC) { + OldDC = OldDC->getRedeclContext(); + NewDC = NewDC->getRedeclContext(); + + if (OldDC->Equals(NewDC)) + return true; + + // In MSVC mode, we allow a redeclaration if the contexts are related (either + // encloses the other). + if (S.getLangOpts().MSVCCompat && + (OldDC->Encloses(NewDC) || NewDC->Encloses(OldDC))) + return true; + + return false; +} + /// \brief This is invoked when we see 'struct foo' or 'struct {'. In the /// former case, Name will be non-null. In the later case, Name will be null. /// TagSpec indicates what kind of tag this is. TUK indicates whether this is a @@ -11802,14 +11823,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, auto *OldTag = dyn_cast(PrevDecl); if (SS.isEmpty() && TUK != TUK_Reference && TUK != TUK_Friend && isDeclInScope(Shadow, SearchDC, S, isExplicitSpecialization) && - !(OldTag && - (getLangOpts().MSVCCompat - ? SearchDC->getRedeclContext()->Encloses( - OldTag->getDeclContext()->getRedeclContext()) || - OldTag->getDeclContext()->getRedeclContext()->Encloses( - SearchDC->getRedeclContext()) - : SearchDC->getRedeclContext()->Equals( - OldTag->getDeclContext()->getRedeclContext())))) { + !(OldTag && isAcceptableTagRedeclContext( + *this, OldTag->getDeclContext(), SearchDC))) { Diag(KWLoc, diag::err_using_decl_conflict_reverse); Diag(Shadow->getTargetDecl()->getLocation(), diag::note_using_decl_target);