From f6b491041f8479fc39365a2ec3ddd8161afc83c8 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Tue, 11 Oct 2016 15:51:06 +0000 Subject: [PATCH] Revert r283887 and r283882, until the issue is understood and fixed. llvm-svn: 283890 --- clang/include/clang/AST/Decl.h | 26 +---------- clang/lib/AST/Decl.cpp | 53 ---------------------- clang/lib/Sema/SemaDecl.cpp | 17 ------- clang/lib/Sema/SemaTemplate.cpp | 47 ++++++------------- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 40 ++++++++-------- clang/lib/Sema/SemaType.cpp | 4 -- clang/lib/Serialization/ASTReaderDecl.cpp | 29 ------------ clang/lib/Serialization/ASTWriterDecl.cpp | 4 -- clang/test/Modules/Inputs/PR28752/Subdir1/b.h | 1 - clang/test/Modules/Inputs/PR28752/Subdir1/c.h | 0 .../Inputs/PR28752/Subdir1/module.modulemap | 5 -- clang/test/Modules/Inputs/PR28752/a.h | 1 - clang/test/Modules/Inputs/PR28752/module.modulemap | 1 - clang/test/Modules/Inputs/PR28752/vector | 28 ------------ clang/test/Modules/pr28752.cpp | 19 -------- 15 files changed, 36 insertions(+), 239 deletions(-) delete mode 100644 clang/test/Modules/Inputs/PR28752/Subdir1/b.h delete mode 100644 clang/test/Modules/Inputs/PR28752/Subdir1/c.h delete mode 100644 clang/test/Modules/Inputs/PR28752/Subdir1/module.modulemap delete mode 100644 clang/test/Modules/Inputs/PR28752/a.h delete mode 100644 clang/test/Modules/Inputs/PR28752/module.modulemap delete mode 100644 clang/test/Modules/Inputs/PR28752/vector delete mode 100644 clang/test/Modules/pr28752.cpp diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index e4e3388..90d8727 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -865,11 +865,6 @@ protected: unsigned : NumVarDeclBits; - // FIXME: We need something similar to CXXRecordDecl::DefinitionData. - /// \brief Whether this variable is a definition which was demoted due to - /// module merge. - unsigned IsThisDeclarationADemotedDefinition : 1; - /// \brief Whether this variable is the exception variable in a C++ catch /// or an Objective-C @catch statement. unsigned ExceptionVar : 1; @@ -1203,27 +1198,12 @@ public: InitializationStyle getInitStyle() const { return static_cast(VarDeclBits.InitStyle); } + /// \brief Whether the initializer is a direct-initializer (list or call). bool isDirectInit() const { return getInitStyle() != CInit; } - /// \brief If this definition should pretend to be a declaration. - bool isThisDeclarationADemotedDefinition() const { - return NonParmVarDeclBits.IsThisDeclarationADemotedDefinition; - } - - /// \brief This is a definition which should be demoted to a declaration. - /// - /// In some cases (mostly module merging) we can end up with two visible - /// definitions one of which needs to be demoted to a declaration to keep - /// the AST invariants. - void demoteThisDefinitionToDeclaration() { - assert (!isThisDeclarationADemotedDefinition() && "Aleady demoted!"); - assert (isThisDeclarationADefinition() && "Not a definition!"); - NonParmVarDeclBits.IsThisDeclarationADemotedDefinition = 1; - } - /// \brief Determine whether this variable is the exception variable in a /// C++ catch statememt or an Objective-C \@catch statement. bool isExceptionVariable() const { @@ -1322,10 +1302,6 @@ public: NonParmVarDeclBits.PreviousDeclInSameBlockScope = Same; } - /// \brief Retrieve the variable declaration from which this variable could - /// be instantiated, if it is an instantiation (rather than a non-template). - VarDecl *getTemplateInstantiationPattern() const; - /// \brief If this variable is an instantiated static data member of a /// class template specialization, returns the templated static data member /// from which it was instantiated. diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 3d601ee..e330e31 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1926,9 +1926,6 @@ VarDecl::isThisDeclarationADefinition(ASTContext &C) const { // // FIXME: How do you declare (but not define) a partial specialization of // a static data member template outside the containing class? - if (isThisDeclarationADemotedDefinition()) - return DeclarationOnly; - if (isStaticDataMember()) { if (isOutOfLine() && !(getCanonicalDecl()->isInline() && @@ -2253,56 +2250,6 @@ bool VarDecl::checkInitIsICE() const { return Eval->IsICE; } -VarDecl *VarDecl::getTemplateInstantiationPattern() const { - // If it's a variable template specialization, find the template or partial - // specialization from which it was instantiated. - if (auto *VDTemplSpec = dyn_cast(this)) { - auto From = VDTemplSpec->getInstantiatedFrom(); - if (auto *VTD = From.dyn_cast()) { - while (auto *NewVTD = VTD->getInstantiatedFromMemberTemplate()) { - if (NewVTD->isMemberSpecialization()) - break; - VTD = NewVTD; - } - return VTD->getTemplatedDecl()->getDefinition(); - } - if (auto *VTPSD = - From.dyn_cast()) { - while (auto *NewVTPSD = VTPSD->getInstantiatedFromMember()) { - if (NewVTPSD->isMemberSpecialization()) - break; - VTPSD = NewVTPSD; - } - return VTPSD->getDefinition(); - } - } - - if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) { - if (isTemplateInstantiation(MSInfo->getTemplateSpecializationKind())) { - VarDecl *VD = getInstantiatedFromStaticDataMember(); - while (auto *NewVD = VD->getInstantiatedFromStaticDataMember()) - VD = NewVD; - return VD->getDefinition(); - } - } - - if (VarTemplateDecl *VarTemplate = getDescribedVarTemplate()) { - - while (VarTemplate->getInstantiatedFromMemberTemplate()) { - if (VarTemplate->isMemberSpecialization()) - break; - VarTemplate = VarTemplate->getInstantiatedFromMemberTemplate(); - } - - assert((!VarTemplate->getTemplatedDecl() || - !isTemplateInstantiation(getTemplateSpecializationKind())) && - "couldn't find pattern for variable instantiation"); - - return VarTemplate->getTemplatedDecl(); - } - return nullptr; -} - VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const { if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) return cast(MSI->getInstantiatedFrom()); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index cf6f0c8..7baa85a 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -9708,23 +9708,6 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, VDecl->getDeclContext()->isDependentContext())) { // The previous definition is hidden, and multiple definitions are // permitted (in separate TUs). Form another definition of it. - - if (!isa(VDecl)) { - // Demote the newly parsed definition to a fake declaration. - if (!VDecl->isThisDeclarationADemotedDefinition()) - VDecl->demoteThisDefinitionToDeclaration(); - - // Make the definition visible from the point of the demotion on. - assert (!Hidden || Def == Hidden && - "We were suggested another hidden definition!"); - makeMergedDefinitionVisible(Def, VDecl->getLocation()); - - // If this is a variable template definition, make its enclosing template - // visible. - if (VarDecl *VarPattern = Def->getTemplateInstantiationPattern()) - if (VarPattern->isThisDeclarationADefinition()) - makeMergedDefinitionVisible(VarPattern, VDecl->getLocation()); - } } else { Diag(VDecl->getLocation(), diag::err_redefinition) << VDecl->getDeclName(); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 71b2153..0a03f8e 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -466,14 +466,10 @@ bool Sema::DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation, const NamedDecl *PatternDef, TemplateSpecializationKind TSK, bool Complain /*= true*/) { - assert(isa(Instantiation) || isa(Instantiation) || - isa(Instantiation)); + assert(isa(Instantiation) || isa(Instantiation)); - bool IsEntityBeingDefined = false; - if (const TagDecl *TD = dyn_cast_or_null(PatternDef)) - IsEntityBeingDefined = TD->isBeingDefined(); - - if (PatternDef && !IsEntityBeingDefined) { + if (PatternDef && (isa(PatternDef) + || !cast(PatternDef)->isBeingDefined())) { NamedDecl *SuggestedDef = nullptr; if (!hasVisibleDefinition(const_cast(PatternDef), &SuggestedDef, /*OnlyNeedComplete*/false)) { @@ -490,14 +486,13 @@ bool Sema::DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation, if (!Complain || (PatternDef && PatternDef->isInvalidDecl())) return true; - llvm::Optional Note; QualType InstantiationTy; if (TagDecl *TD = dyn_cast(Instantiation)) InstantiationTy = Context.getTypeDeclType(TD); if (PatternDef) { Diag(PointOfInstantiation, diag::err_template_instantiate_within_definition) - << /*implicit|explicit*/(TSK != TSK_ImplicitInstantiation) + << (TSK != TSK_ImplicitInstantiation) << InstantiationTy; // Not much point in noting the template declaration here, since // we're lexically inside it. @@ -506,44 +501,28 @@ bool Sema::DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation, if (isa(Instantiation)) { Diag(PointOfInstantiation, diag::err_explicit_instantiation_undefined_member) - << /*member function*/ 1 << Instantiation->getDeclName() - << Instantiation->getDeclContext(); - Note = diag::note_explicit_instantiation_here; + << 1 << Instantiation->getDeclName() << Instantiation->getDeclContext(); } else { - assert(isa(Instantiation) && "Must be a TagDecl!"); Diag(PointOfInstantiation, diag::err_implicit_instantiate_member_undefined) << InstantiationTy; - Note = diag::note_member_declared_at; } + Diag(Pattern->getLocation(), isa(Instantiation) + ? diag::note_explicit_instantiation_here + : diag::note_member_declared_at); } else { - if (isa(Instantiation)) { + if (isa(Instantiation)) Diag(PointOfInstantiation, diag::err_explicit_instantiation_undefined_func_template) << Pattern; - Note = diag::note_explicit_instantiation_here; - } else if (isa(Instantiation)) { + else Diag(PointOfInstantiation, diag::err_template_instantiate_undefined) << (TSK != TSK_ImplicitInstantiation) << InstantiationTy; - Note = diag::note_template_decl_here; - } else { - assert(isa(Instantiation) && "Must be a VarDecl!"); - if (isa(Instantiation)) { - Diag(PointOfInstantiation, - diag::err_explicit_instantiation_undefined_var_template) - << Instantiation; - Instantiation->setInvalidDecl(); - } else - Diag(PointOfInstantiation, - diag::err_explicit_instantiation_undefined_member) - << /*static data member*/ 2 << Instantiation->getDeclName() - << Instantiation->getDeclContext(); - Note = diag::note_explicit_instantiation_here; - } + Diag(Pattern->getLocation(), isa(Instantiation) + ? diag::note_explicit_instantiation_here + : diag::note_template_decl_here); } - if (Note) // Diagnostics were emitted. - Diag(Pattern->getLocation(), Note.getValue()); // In general, Instantiation isn't marked invalid to get more than one // error for multiple undefined instantiations. But the code that does diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 911bc51..09068d7 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4068,10 +4068,6 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation, PrettyDeclStackTraceEntry CrashInfo(*this, Var, SourceLocation(), "instantiating variable initializer"); - // The instantiation is visible here, even if it was first declared in an - // unimported module. - Var->setHidden(false); - // If we're performing recursive template instantiation, create our own // queue of pending implicit instantiations that we will instantiate // later, while we're still within our own instantiation context. @@ -4120,17 +4116,33 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation, Def = PatternDecl->getDefinition(); } - TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind(); + // FIXME: Check that the definition is visible before trying to instantiate + // it. This requires us to track the instantiation stack in order to know + // which definitions should be visible. // If we don't have a definition of the variable template, we won't perform // any instantiation. Rather, we rely on the user to instantiate this // definition (or provide a specialization for it) in another translation // unit. - if (!Def && !DefinitionRequired) { - if (TSK == TSK_ExplicitInstantiationDefinition) { + if (!Def) { + if (DefinitionRequired) { + if (VarSpec) { + Diag(PointOfInstantiation, + diag::err_explicit_instantiation_undefined_var_template) << Var; + Var->setInvalidDecl(); + } + else + Diag(PointOfInstantiation, + diag::err_explicit_instantiation_undefined_member) + << 2 << Var->getDeclName() << Var->getDeclContext(); + Diag(PatternDecl->getLocation(), + diag::note_explicit_instantiation_here); + } else if (Var->getTemplateSpecializationKind() + == TSK_ExplicitInstantiationDefinition) { PendingInstantiations.push_back( std::make_pair(Var, PointOfInstantiation)); - } else if (TSK == TSK_ImplicitInstantiation) { + } else if (Var->getTemplateSpecializationKind() + == TSK_ImplicitInstantiation) { // Warn about missing definition at the end of translation unit. if (AtEndOfTU && !getDiagnostics().hasErrorOccurred()) { Diag(PointOfInstantiation, diag::warn_var_template_missing) @@ -4139,20 +4151,12 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation, if (getLangOpts().CPlusPlus11) Diag(PointOfInstantiation, diag::note_inst_declaration_hint) << Var; } - return; } - } - - // FIXME: We need to track the instantiation stack in order to know which - // definitions should be visible within this instantiation. - // FIXME: Produce diagnostics when Var->getInstantiatedFromStaticDataMember(). - if (DiagnoseUninstantiableTemplate(PointOfInstantiation, Var, - /*InstantiatedFromMember*/false, - PatternDecl, Def, TSK, - /*Complain*/DefinitionRequired)) return; + } + TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind(); // Never instantiate an explicit specialization. if (TSK == TSK_ExplicitSpecialization) diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 97eb3a1..b0f18fd 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -6900,10 +6900,6 @@ bool Sema::hasVisibleDefinition(NamedDecl *D, NamedDecl **Suggested, if (auto *Pattern = FD->getTemplateInstantiationPattern()) FD = Pattern; D = FD->getDefinition(); - } else if (auto *VD = dyn_cast(D)) { - if (auto *Pattern = VD->getTemplateInstantiationPattern()) - VD = Pattern; - D = VD->getDefinition(); } assert(D && "missing definition for pattern of instantiated definition"); diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 864eaf0..19113da 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1216,7 +1216,6 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) { VD->VarDeclBits.TSCSpec = Record[Idx++]; VD->VarDeclBits.InitStyle = Record[Idx++]; if (!isa(VD)) { - VD->NonParmVarDeclBits.IsThisDeclarationADemotedDefinition = Record[Idx++]; VD->NonParmVarDeclBits.ExceptionVar = Record[Idx++]; VD->NonParmVarDeclBits.NRVOVariable = Record[Idx++]; VD->NonParmVarDeclBits.CXXForRangeDecl = Record[Idx++]; @@ -3070,34 +3069,6 @@ void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, namespace clang { template<> void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, - Redeclarable *D, - Decl *Previous, Decl *Canon) { - VarDecl *VD = static_cast(D); - VarDecl *PrevVD = cast(Previous); - D->RedeclLink.setPrevious(PrevVD); - D->First = PrevVD->First; - - - // We should keep at most one definition on the chain. - if (VD->isThisDeclarationADefinition()) { - for (VarDecl *CurD = PrevVD; CurD; CurD = CurD->getPreviousDecl()) { - // If we find an already demoted definition, this we already visited this - // part of the chain. Reduces the loop from quadratic-time to linear-time. - if (CurD->isThisDeclarationADemotedDefinition()) { - VD->demoteThisDefinitionToDeclaration(); - break; - } - if (CurD->isThisDeclarationADefinition()) { - // If we found another definition on the chain, demote the current one. - VD->demoteThisDefinitionToDeclaration(); - break; - } - } - } -} - -template<> -void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, Redeclarable *D, Decl *Previous, Decl *Canon) { FunctionDecl *FD = static_cast(D); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 2146861..a0fc155 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -894,7 +894,6 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { Record.push_back(D->getTSCSpec()); Record.push_back(D->getInitStyle()); if (!isa(D)) { - Record.push_back(D->isThisDeclarationADemotedDefinition()); Record.push_back(D->isExceptionVariable()); Record.push_back(D->isNRVOVariable()); Record.push_back(D->isCXXForRangeDecl()); @@ -999,8 +998,6 @@ void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) { // Check things we know are true of *every* PARM_VAR_DECL, which is more than // just us assuming it. assert(!D->getTSCSpec() && "PARM_VAR_DECL can't use TLS"); - assert(!D->isThisDeclarationADemotedDefinition() - && "PARM_VAR_DECL can't be demoted definition."); assert(D->getAccess() == AS_none && "PARM_VAR_DECL can't be public/private"); assert(!D->isExceptionVariable() && "PARM_VAR_DECL can't be exception var"); assert(D->getPreviousDecl() == nullptr && "PARM_VAR_DECL can't be redecl"); @@ -1960,7 +1957,6 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // SClass Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // TSCSpec Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // InitStyle - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsThisDeclarationADemotedDefinition Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isExceptionVariable Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isNRVOVariable Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCXXForRangeDecl diff --git a/clang/test/Modules/Inputs/PR28752/Subdir1/b.h b/clang/test/Modules/Inputs/PR28752/Subdir1/b.h deleted file mode 100644 index 3b3a25f..0000000 --- a/clang/test/Modules/Inputs/PR28752/Subdir1/b.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/clang/test/Modules/Inputs/PR28752/Subdir1/c.h b/clang/test/Modules/Inputs/PR28752/Subdir1/c.h deleted file mode 100644 index e69de29..0000000 diff --git a/clang/test/Modules/Inputs/PR28752/Subdir1/module.modulemap b/clang/test/Modules/Inputs/PR28752/Subdir1/module.modulemap deleted file mode 100644 index 8d3bfe9..0000000 --- a/clang/test/Modules/Inputs/PR28752/Subdir1/module.modulemap +++ /dev/null @@ -1,5 +0,0 @@ -module b { - module "b.h" { header "b.h" export * } - module "c.h" { header "c.h" export * } - export * -} diff --git a/clang/test/Modules/Inputs/PR28752/a.h b/clang/test/Modules/Inputs/PR28752/a.h deleted file mode 100644 index 3b3a25f..0000000 --- a/clang/test/Modules/Inputs/PR28752/a.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/clang/test/Modules/Inputs/PR28752/module.modulemap b/clang/test/Modules/Inputs/PR28752/module.modulemap deleted file mode 100644 index caf888f..0000000 --- a/clang/test/Modules/Inputs/PR28752/module.modulemap +++ /dev/null @@ -1 +0,0 @@ -module a { header "a.h" export * } diff --git a/clang/test/Modules/Inputs/PR28752/vector b/clang/test/Modules/Inputs/PR28752/vector deleted file mode 100644 index fc5dafa..0000000 --- a/clang/test/Modules/Inputs/PR28752/vector +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef VECTOR -#define VECTOR -template struct B; -template struct B { typedef _Tp type; }; -namespace std { -template struct D { - - template struct F { - static const bool value = 0; - }; - - template - typename B::value, _Alloc2>::type _S_select(_Alloc2); - template - static - typename B::value, _Alloc2>::type _S_select(_Alloc2); -}; -template -template -const bool D<_Alloc>::F<_Alloc2>::value; - -template class vector { -public: - vector(int); - vector(vector &) : vector(D::_S_select((bool)0)) {} -}; -} -#endif // VECTOR \ No newline at end of file diff --git a/clang/test/Modules/pr28752.cpp b/clang/test/Modules/pr28752.cpp deleted file mode 100644 index e73a54b..0000000 --- a/clang/test/Modules/pr28752.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -std=c++11 -nostdsysteminc -I%S/Inputs/PR28752 -verify %s -// RUN: %clang_cc1 -std=c++11 -nostdsysteminc -fmodules -fmodule-map-file=%S/Inputs/PR28752/Subdir1/module.modulemap -fmodule-map-file=%S/Inputs/PR28752/module.modulemap -fmodules-cache-path=%t -I%S/Inputs/PR28752 -I%S/Inputs/PR28752/Subdir1 -verify %s - -#include "a.h" -#include "Subdir1/c.h" -#include - -class TClingClassInfo { - std::vector fIterStack; -}; - -TClingClassInfo *a; -class TClingBaseClassInfo { - TClingBaseClassInfo() { new TClingClassInfo(*a); } -}; - -// expected-no-diagnostics - -- 2.7.4