> On Oct 12, 2016, at 1:39 PM, Vassil Vassilev <v.g.vassi...@gmail.com> wrote: > > Hi Manman, > On 12/10/16 20:28, Manman wrote: >> Hi Vassil, >> >> Any change between this commit and “r283887 + r283882”? > The only extra change is in: > > + bool isThisDeclarationADemotedDefinition() const { > + return isa<ParmVarDecl>(this) ? false : > + NonParmVarDeclBits.IsThisDeclarationADemotedDefinition; > + } > > The old patch failed because we read the IsThisDeclarationADemotedDefinition > bit of ParmVarDecls. We allow demoting only VarDecls, which are not > ParmVarDecls, and thus we serialize/deserialize this bit only for non > ParmVarDecls. Reading the IsThisDeclarationADemotedDefinition of ParmVarDecls > caused random behavior.
Thanks, Manman > > Cheers, > Vassil >> 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