Hi Vassil, Any change between this commit and “r283887 + r283882”? And what was the issue that caused the revert?
Thanks, Manman > On Oct 12, 2016, at 4:57 AM, Vassil Vassilev via cfe-commits > <cfe-commits@lists.llvm.org> wrote: > > Author: vvassilev > Date: Wed Oct 12 06:57:08 2016 > New Revision: 284008 > > URL: http://llvm.org/viewvc/llvm-project?rev=284008&view=rev > Log: > Reinstate r283887 and r283882. > > Original message: > "[modules] PR28752: Do not instantiate variable declarations which are not > visible. > > https://reviews.llvm.org/D24508 > > Patch developed in collaboration with Richard Smith!" > > Added: > cfe/trunk/test/Modules/Inputs/PR28752/ > cfe/trunk/test/Modules/Inputs/PR28752/Subdir1/ > cfe/trunk/test/Modules/Inputs/PR28752/Subdir1/b.h > cfe/trunk/test/Modules/Inputs/PR28752/Subdir1/c.h > cfe/trunk/test/Modules/Inputs/PR28752/Subdir1/module.modulemap > cfe/trunk/test/Modules/Inputs/PR28752/a.h > cfe/trunk/test/Modules/Inputs/PR28752/module.modulemap > cfe/trunk/test/Modules/Inputs/PR28752/vector > 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=284008&r1=284007&r2=284008&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/Decl.h (original) > +++ cfe/trunk/include/clang/AST/Decl.h Wed Oct 12 06:57:08 2016 > @@ -865,6 +865,11 @@ 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; > @@ -1198,12 +1203,28 @@ 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 { > @@ -1302,6 +1323,10 @@ 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=284008&r1=284007&r2=284008&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/Decl.cpp (original) > +++ cfe/trunk/lib/AST/Decl.cpp Wed Oct 12 06:57:08 2016 > @@ -1926,6 +1926,9 @@ 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() && > @@ -2250,6 +2253,56 @@ 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=284008&r1=284007&r2=284008&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Oct 12 06:57:08 2016 > @@ -9708,6 +9708,22 @@ 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=284008&r1=284007&r2=284008&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original) > +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Oct 12 06:57:08 2016 > @@ -466,10 +466,14 @@ bool Sema::DiagnoseUninstantiableTemplat > const NamedDecl *PatternDef, > TemplateSpecializationKind TSK, > bool Complain /*= true*/) { > - assert(isa<TagDecl>(Instantiation) || isa<FunctionDecl>(Instantiation)); > + assert(isa<TagDecl>(Instantiation) || isa<FunctionDecl>(Instantiation) || > + isa<VarDecl>(Instantiation)); > > - if (PatternDef && (isa<FunctionDecl>(PatternDef) > - || !cast<TagDecl>(PatternDef)->isBeingDefined())) { > + bool IsEntityBeingDefined = false; > + if (const TagDecl *TD = dyn_cast_or_null<TagDecl>(PatternDef)) > + IsEntityBeingDefined = TD->isBeingDefined(); > + > + if (PatternDef && !IsEntityBeingDefined) { > NamedDecl *SuggestedDef = nullptr; > if (!hasVisibleDefinition(const_cast<NamedDecl*>(PatternDef), > &SuggestedDef, > /*OnlyNeedComplete*/false)) { > @@ -486,13 +490,14 @@ 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) > - << (TSK != TSK_ImplicitInstantiation) > + << /*implicit|explicit*/(TSK != TSK_ImplicitInstantiation) > << InstantiationTy; > // Not much point in noting the template declaration here, since > // we're lexically inside it. > @@ -501,28 +506,44 @@ bool Sema::DiagnoseUninstantiableTemplat > if (isa<FunctionDecl>(Instantiation)) { > Diag(PointOfInstantiation, > diag::err_explicit_instantiation_undefined_member) > - << 1 << Instantiation->getDeclName() << > Instantiation->getDeclContext(); > + << /*member function*/ 1 << Instantiation->getDeclName() > + << Instantiation->getDeclContext(); > + Note = diag::note_explicit_instantiation_here; > } 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; > - else > + Note = diag::note_explicit_instantiation_here; > + } else if (isa<TagDecl>(Instantiation)) { > Diag(PointOfInstantiation, diag::err_template_instantiate_undefined) > << (TSK != TSK_ImplicitInstantiation) > << InstantiationTy; > - Diag(Pattern->getLocation(), isa<FunctionDecl>(Instantiation) > - ? diag::note_explicit_instantiation_here > - : diag::note_template_decl_here); > + 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; > + } > } > + 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=284008&r1=284007&r2=284008&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original) > +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Oct 12 06:57:08 > 2016 > @@ -4068,6 +4068,10 @@ 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. > @@ -4116,33 +4120,17 @@ void Sema::InstantiateVariableDefinition > Def = PatternDecl->getDefinition(); > } > > - // 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. > + TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind(); > > // 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) { > - 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) { > + if (!Def && !DefinitionRequired) { > + if (TSK == TSK_ExplicitInstantiationDefinition) { > PendingInstantiations.push_back( > std::make_pair(Var, PointOfInstantiation)); > - } else if (Var->getTemplateSpecializationKind() > - == TSK_ImplicitInstantiation) { > + } else if (TSK == TSK_ImplicitInstantiation) { > // Warn about missing definition at the end of translation unit. > if (AtEndOfTU && !getDiagnostics().hasErrorOccurred()) { > Diag(PointOfInstantiation, diag::warn_var_template_missing) > @@ -4151,12 +4139,20 @@ void Sema::InstantiateVariableDefinition > if (getLangOpts().CPlusPlus11) > Diag(PointOfInstantiation, diag::note_inst_declaration_hint) << Var; > } > + return; > } > > - return; > } > > - TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind(); > + // 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; > + > > // 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=284008&r1=284007&r2=284008&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaType.cpp (original) > +++ cfe/trunk/lib/Sema/SemaType.cpp Wed Oct 12 06:57:08 2016 > @@ -6888,6 +6888,10 @@ 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=284008&r1=284007&r2=284008&view=diff > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Oct 12 06:57:08 2016 > @@ -1216,6 +1216,7 @@ 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++]; > @@ -3069,6 +3070,29 @@ 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=284008&r1=284007&r2=284008&view=diff > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Wed Oct 12 06:57:08 2016 > @@ -894,6 +894,7 @@ 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()); > @@ -998,6 +999,8 @@ 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"); > @@ -1957,6 +1960,7 @@ 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 > > Added: cfe/trunk/test/Modules/Inputs/PR28752/Subdir1/b.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/PR28752/Subdir1/b.h?rev=284008&view=auto > ============================================================================== > --- cfe/trunk/test/Modules/Inputs/PR28752/Subdir1/b.h (added) > +++ cfe/trunk/test/Modules/Inputs/PR28752/Subdir1/b.h Wed Oct 12 06:57:08 2016 > @@ -0,0 +1 @@ > +#include <vector> > > Added: cfe/trunk/test/Modules/Inputs/PR28752/Subdir1/c.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/PR28752/Subdir1/c.h?rev=284008&view=auto > ============================================================================== > (empty) > > Added: cfe/trunk/test/Modules/Inputs/PR28752/Subdir1/module.modulemap > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/PR28752/Subdir1/module.modulemap?rev=284008&view=auto > ============================================================================== > --- cfe/trunk/test/Modules/Inputs/PR28752/Subdir1/module.modulemap (added) > +++ cfe/trunk/test/Modules/Inputs/PR28752/Subdir1/module.modulemap Wed Oct 12 > 06:57:08 2016 > @@ -0,0 +1,5 @@ > +module b { > + module "b.h" { header "b.h" export * } > + module "c.h" { header "c.h" export * } > + export * > +} > > Added: cfe/trunk/test/Modules/Inputs/PR28752/a.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/PR28752/a.h?rev=284008&view=auto > ============================================================================== > --- cfe/trunk/test/Modules/Inputs/PR28752/a.h (added) > +++ cfe/trunk/test/Modules/Inputs/PR28752/a.h Wed Oct 12 06:57:08 2016 > @@ -0,0 +1 @@ > +#include <vector> > > Added: cfe/trunk/test/Modules/Inputs/PR28752/module.modulemap > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/PR28752/module.modulemap?rev=284008&view=auto > ============================================================================== > --- cfe/trunk/test/Modules/Inputs/PR28752/module.modulemap (added) > +++ cfe/trunk/test/Modules/Inputs/PR28752/module.modulemap Wed Oct 12 > 06:57:08 2016 > @@ -0,0 +1 @@ > +module a { header "a.h" export * } > > Added: cfe/trunk/test/Modules/Inputs/PR28752/vector > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/PR28752/vector?rev=284008&view=auto > ============================================================================== > --- cfe/trunk/test/Modules/Inputs/PR28752/vector (added) > +++ cfe/trunk/test/Modules/Inputs/PR28752/vector Wed Oct 12 06:57:08 2016 > @@ -0,0 +1,28 @@ > +#ifndef VECTOR > +#define VECTOR > +template <bool, typename> struct B; > +template <typename _Tp> struct B<true, _Tp> { typedef _Tp type; }; > +namespace std { > +template <typename> struct D { > + > + template <typename _Alloc2> struct F { > + static const bool value = 0; > + }; > + > + template <typename _Alloc2> > + typename B<F<_Alloc2>::value, _Alloc2>::type _S_select(_Alloc2); > + template <typename _Alloc2> > + static > + typename B<!F<_Alloc2>::value, _Alloc2>::type _S_select(_Alloc2); > +}; > +template <typename _Alloc> > +template <typename _Alloc2> > +const bool D<_Alloc>::F<_Alloc2>::value; > + > +template <typename> class vector { > +public: > + vector(int); > + vector(vector &) : vector(D<bool>::_S_select((bool)0)) {} > +}; > +} > +#endif // VECTOR > \ No newline at end of file > > Added: cfe/trunk/test/Modules/pr28752.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/pr28752.cpp?rev=284008&view=auto > ============================================================================== > --- cfe/trunk/test/Modules/pr28752.cpp (added) > +++ cfe/trunk/test/Modules/pr28752.cpp Wed Oct 12 06:57:08 2016 > @@ -0,0 +1,19 @@ > +// 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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits