Author: rsmith Date: Wed Oct 12 18:29:02 2016 New Revision: 284081 URL: http://llvm.org/viewvc/llvm-project?rev=284081&view=rev Log: Revert r284008. This is us to fail to instantiate static data members in some cases. I'm working on reducing a testcase.
Removed: cfe/trunk/test/Modules/Inputs/PR28752/ cfe/trunk/test/Modules/pr28752.cpp Modified: cfe/trunk/include/clang/AST/Decl.h cfe/trunk/lib/AST/Decl.cpp cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaTemplate.cpp cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp cfe/trunk/lib/Sema/SemaType.cpp cfe/trunk/lib/Serialization/ASTReaderDecl.cpp cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Modified: cfe/trunk/include/clang/AST/Decl.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=284081&r1=284080&r2=284081&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Decl.h (original) +++ cfe/trunk/include/clang/AST/Decl.h Wed Oct 12 18:29:02 2016 @@ -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,28 +1198,12 @@ public: InitializationStyle getInitStyle() const { return static_cast<InitializationStyle>(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 isa<ParmVarDecl>(this) ? false : - 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 (isThisDeclarationADefinition() && "Not a definition!"); - assert (!isa<ParmVarDecl>(this) && "Cannot demote ParmVarDecls!"); - 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 { @@ -1323,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. Modified: cfe/trunk/lib/AST/Decl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=284081&r1=284080&r2=284081&view=diff ============================================================================== --- cfe/trunk/lib/AST/Decl.cpp (original) +++ cfe/trunk/lib/AST/Decl.cpp Wed Oct 12 18:29:02 2016 @@ -1926,9 +1926,6 @@ VarDecl::isThisDeclarationADefinition(AS // // 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<VarTemplateSpecializationDecl>(this)) { - auto From = VDTemplSpec->getInstantiatedFrom(); - if (auto *VTD = From.dyn_cast<VarTemplateDecl *>()) { - while (auto *NewVTD = VTD->getInstantiatedFromMemberTemplate()) { - if (NewVTD->isMemberSpecialization()) - break; - VTD = NewVTD; - } - return VTD->getTemplatedDecl()->getDefinition(); - } - if (auto *VTPSD = - From.dyn_cast<VarTemplatePartialSpecializationDecl *>()) { - 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<VarDecl>(MSI->getInstantiatedFrom()); Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=284081&r1=284080&r2=284081&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Oct 12 18:29:02 2016 @@ -9708,22 +9708,6 @@ void Sema::AddInitializerToDecl(Decl *Re VDecl->getDeclContext()->isDependentContext())) { // The previous definition is hidden, and multiple definitions are // permitted (in separate TUs). Form another definition of it. - if (!isa<ParmVarDecl>(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(); Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=284081&r1=284080&r2=284081&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Oct 12 18:29:02 2016 @@ -466,14 +466,10 @@ bool Sema::DiagnoseUninstantiableTemplat const NamedDecl *PatternDef, TemplateSpecializationKind TSK, bool Complain /*= true*/) { - assert(isa<TagDecl>(Instantiation) || isa<FunctionDecl>(Instantiation) || - isa<VarDecl>(Instantiation)); + assert(isa<TagDecl>(Instantiation) || isa<FunctionDecl>(Instantiation)); - bool IsEntityBeingDefined = false; - if (const TagDecl *TD = dyn_cast_or_null<TagDecl>(PatternDef)) - IsEntityBeingDefined = TD->isBeingDefined(); - - if (PatternDef && !IsEntityBeingDefined) { + if (PatternDef && (isa<FunctionDecl>(PatternDef) + || !cast<TagDecl>(PatternDef)->isBeingDefined())) { NamedDecl *SuggestedDef = nullptr; if (!hasVisibleDefinition(const_cast<NamedDecl*>(PatternDef), &SuggestedDef, /*OnlyNeedComplete*/false)) { @@ -490,14 +486,13 @@ bool Sema::DiagnoseUninstantiableTemplat if (!Complain || (PatternDef && PatternDef->isInvalidDecl())) return true; - llvm::Optional<unsigned> Note; QualType InstantiationTy; if (TagDecl *TD = dyn_cast<TagDecl>(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::DiagnoseUninstantiableTemplat if (isa<FunctionDecl>(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<TagDecl>(Instantiation) && "Must be a TagDecl!"); Diag(PointOfInstantiation, diag::err_implicit_instantiate_member_undefined) << InstantiationTy; - Note = diag::note_member_declared_at; } + Diag(Pattern->getLocation(), isa<FunctionDecl>(Instantiation) + ? diag::note_explicit_instantiation_here + : diag::note_member_declared_at); } else { - if (isa<FunctionDecl>(Instantiation)) { + if (isa<FunctionDecl>(Instantiation)) Diag(PointOfInstantiation, diag::err_explicit_instantiation_undefined_func_template) << Pattern; - Note = diag::note_explicit_instantiation_here; - } else if (isa<TagDecl>(Instantiation)) { + else Diag(PointOfInstantiation, diag::err_template_instantiate_undefined) << (TSK != TSK_ImplicitInstantiation) << InstantiationTy; - Note = diag::note_template_decl_here; - } else { - assert(isa<VarDecl>(Instantiation) && "Must be a VarDecl!"); - if (isa<VarTemplateSpecializationDecl>(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<FunctionDecl>(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 Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=284081&r1=284080&r2=284081&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Oct 12 18:29:02 2016 @@ -4068,10 +4068,6 @@ void Sema::InstantiateVariableDefinition 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 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 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) Modified: cfe/trunk/lib/Sema/SemaType.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=284081&r1=284080&r2=284081&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaType.cpp (original) +++ cfe/trunk/lib/Sema/SemaType.cpp Wed Oct 12 18:29:02 2016 @@ -6888,10 +6888,6 @@ bool Sema::hasVisibleDefinition(NamedDec if (auto *Pattern = FD->getTemplateInstantiationPattern()) FD = Pattern; D = FD->getDefinition(); - } else if (auto *VD = dyn_cast<VarDecl>(D)) { - if (auto *Pattern = VD->getTemplateInstantiationPattern()) - VD = Pattern; - D = VD->getDefinition(); } assert(D && "missing definition for pattern of instantiated definition"); Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=284081&r1=284080&r2=284081&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Oct 12 18:29:02 2016 @@ -1216,7 +1216,6 @@ ASTDeclReader::RedeclarableResult ASTDec VD->VarDeclBits.TSCSpec = Record[Idx++]; VD->VarDeclBits.InitStyle = Record[Idx++]; if (!isa<ParmVarDecl>(VD)) { - VD->NonParmVarDeclBits.IsThisDeclarationADemotedDefinition = Record[Idx++]; VD->NonParmVarDeclBits.ExceptionVar = Record[Idx++]; VD->NonParmVarDeclBits.NRVOVariable = Record[Idx++]; VD->NonParmVarDeclBits.CXXForRangeDecl = Record[Idx++]; @@ -3070,29 +3069,6 @@ void ASTDeclReader::attachPreviousDeclIm namespace clang { template<> void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, - Redeclarable<VarDecl> *D, - Decl *Previous, Decl *Canon) { - VarDecl *VD = static_cast<VarDecl*>(D); - VarDecl *PrevVD = cast<VarDecl>(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() || - CurD->isThisDeclarationADefinition()) { - VD->demoteThisDefinitionToDeclaration(); - break; - } - } - } -} - -template<> -void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, Redeclarable<FunctionDecl> *D, Decl *Previous, Decl *Canon) { FunctionDecl *FD = static_cast<FunctionDecl*>(D); Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=284081&r1=284080&r2=284081&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original) +++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Wed Oct 12 18:29:02 2016 @@ -894,7 +894,6 @@ void ASTDeclWriter::VisitVarDecl(VarDecl Record.push_back(D->getTSCSpec()); Record.push_back(D->getInitStyle()); if (!isa<ParmVarDecl>(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(Par // 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 Removed: cfe/trunk/test/Modules/pr28752.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/pr28752.cpp?rev=284080&view=auto ============================================================================== --- cfe/trunk/test/Modules/pr28752.cpp (original) +++ cfe/trunk/test/Modules/pr28752.cpp (removed) @@ -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 <vector> - -class TClingClassInfo { - std::vector<int> fIterStack; -}; - -TClingClassInfo *a; -class TClingBaseClassInfo { - TClingBaseClassInfo() { new TClingClassInfo(*a); } -}; - -// expected-no-diagnostics - _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits