Index: include/clang/AST/ExprCXX.h =================================================================== --- include/clang/AST/ExprCXX.h +++ include/clang/AST/ExprCXX.h @@ -3784,39 +3784,54 @@ /// temporary. When either happens, the expression will also track the /// declaration which is responsible for the lifetime extension. class MaterializeTemporaryExpr : public Expr { -public: - /// \brief The temporary-generating expression whose value will be - /// materialized. - Stmt *Temporary; +private: + struct ExtraState { + /// \brief The temporary-generating expression whose value will be + /// materialized. + Stmt *Temporary; - /// \brief The declaration which lifetime-extended this reference, if any. - /// Either a VarDecl, or (for a ctor-initializer) a FieldDecl. - const ValueDecl *ExtendingDecl; + /// \brief The declaration which lifetime-extended this reference, if any. + /// Either a VarDecl, or (for a ctor-initializer) a FieldDecl. + const ValueDecl *ExtendingDecl; + + unsigned ManglingNumber; + }; + llvm::PointerUnion State; friend class ASTStmtReader; friend class ASTStmtWriter; + void initializeExtraState(const ValueDecl *ExtendedBy, + unsigned ManglingNumber); + public: MaterializeTemporaryExpr(QualType T, Expr *Temporary, bool BoundToLvalueReference, - const ValueDecl *ExtendedBy) + const ValueDecl *ExtendedBy, unsigned ManglingNumber) : Expr(MaterializeTemporaryExprClass, T, BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary, Temporary->isTypeDependent(), Temporary->isValueDependent(), Temporary->isInstantiationDependent(), Temporary->containsUnexpandedParameterPack()), - Temporary(Temporary), ExtendingDecl(ExtendedBy) { + State(Temporary) { + initializeExtraState(ExtendedBy, ManglingNumber); } MaterializeTemporaryExpr(EmptyShell Empty) : Expr(MaterializeTemporaryExprClass, Empty) { } + Stmt *getTemporary() const { + return State.is() ? State.get() + : State.get()->Temporary; + } + /// \brief Retrieve the temporary-generating subexpression whose value will /// be materialized into a glvalue. - Expr *GetTemporaryExpr() const { return static_cast(Temporary); } + Expr *GetTemporaryExpr() const { return static_cast(getTemporary()); } /// \brief Retrieve the storage duration for the materialized temporary. StorageDuration getStorageDuration() const { + const ValueDecl *ExtendingDecl = getExtendingDecl(); if (!ExtendingDecl) return SD_FullExpression; // FIXME: This is not necessarily correct for a temporary materialized @@ -3828,10 +3843,17 @@ /// \brief Get the declaration which triggered the lifetime-extension of this /// temporary, if any. - const ValueDecl *getExtendingDecl() const { return ExtendingDecl; } + const ValueDecl *getExtendingDecl() const { + return State.is() ? nullptr + : State.get()->ExtendingDecl; + } + + void setExtendingDecl(const ValueDecl *ExtendedBy, unsigned ManglingNumber) { + initializeExtraState(ExtendedBy, ManglingNumber); + } - void setExtendingDecl(const ValueDecl *ExtendedBy) { - ExtendingDecl = ExtendedBy; + unsigned getManglingNumber() const { + return State.is() ? 0 : State.get()->ManglingNumber; } /// \brief Determine whether this materialized temporary is bound to an @@ -3841,10 +3863,10 @@ } SourceLocation getLocStart() const LLVM_READONLY { - return Temporary->getLocStart(); + return getTemporary()->getLocStart(); } SourceLocation getLocEnd() const LLVM_READONLY { - return Temporary->getLocEnd(); + return getTemporary()->getLocEnd(); } static bool classof(const Stmt *T) { @@ -3852,7 +3874,13 @@ } // Iterators - child_range children() { return child_range(&Temporary, &Temporary + 1); } + child_range children() { + if (State.is()) + return child_range(State.getAddrOfPtr1(), State.getAddrOfPtr1() + 1); + + auto ES = State.get(); + return child_range(&ES->Temporary, &ES->Temporary + 1); + } }; } // end namespace clang Index: include/clang/AST/Mangle.h =================================================================== --- include/clang/AST/Mangle.h +++ include/clang/AST/Mangle.h @@ -130,6 +130,7 @@ const ThisAdjustment &ThisAdjustment, raw_ostream &) = 0; virtual void mangleReferenceTemporary(const VarDecl *D, + unsigned ManglingNumber, raw_ostream &) = 0; virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0; virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0; Index: include/clang/Sema/Initialization.h =================================================================== --- include/clang/Sema/Initialization.h +++ include/clang/Sema/Initialization.h @@ -103,6 +103,9 @@ /// \brief The type of the object or reference being initialized. QualType Type; + /// \brief The mangling number for the next reference temporary to be created. + mutable unsigned ManglingNumber; + struct LN { /// \brief When Kind == EK_Result, EK_Exception, EK_New, the /// location of the 'return', 'throw', or 'new' keyword, @@ -155,11 +158,11 @@ struct C Capture; }; - InitializedEntity() { } + InitializedEntity() : ManglingNumber(1) {} /// \brief Create the initialization entity for a variable. InitializedEntity(VarDecl *Var) - : Kind(EK_Variable), Parent(0), Type(Var->getType()), + : Kind(EK_Variable), Parent(0), Type(Var->getType()), ManglingNumber(1), VariableOrMember(Var) { } /// \brief Create the initialization entity for the result of a @@ -167,7 +170,7 @@ /// initializing a parameter for which there is no declaration. InitializedEntity(EntityKind Kind, SourceLocation Loc, QualType Type, bool NRVO = false) - : Kind(Kind), Parent(0), Type(Type) + : Kind(Kind), Parent(0), Type(Type), ManglingNumber(1) { LocAndNRVO.Location = Loc.getRawEncoding(); LocAndNRVO.NRVO = NRVO; @@ -176,7 +179,7 @@ /// \brief Create the initialization entity for a member subobject. InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent) : Kind(EK_Member), Parent(Parent), Type(Member->getType()), - VariableOrMember(Member) { } + ManglingNumber(1), VariableOrMember(Member) { } /// \brief Create the initialization entity for an array element. InitializedEntity(ASTContext &Context, unsigned Index, @@ -184,7 +187,7 @@ /// \brief Create the initialization entity for a lambda capture. InitializedEntity(IdentifierInfo *VarID, QualType FieldType, SourceLocation Loc) - : Kind(EK_LambdaCapture), Parent(0), Type(FieldType) + : Kind(EK_LambdaCapture), Parent(0), Type(FieldType), ManglingNumber(1) { Capture.VarID = VarID; Capture.Location = Loc.getRawEncoding(); @@ -418,6 +421,8 @@ Kind = EK_Parameter_CF_Audited; } + unsigned &getManglingNumber() const { return ManglingNumber; } + /// Dump a representation of the initialized entity to standard error, /// for debugging purposes. void dump() const; Index: lib/AST/ExprCXX.cpp =================================================================== --- lib/AST/ExprCXX.cpp +++ lib/AST/ExprCXX.cpp @@ -1446,6 +1446,25 @@ FunctionParmPackExpr(QualType(), 0, SourceLocation(), 0, 0); } +void MaterializeTemporaryExpr::initializeExtraState(const ValueDecl *ExtendedBy, + unsigned ManglingNumber) { + // We only need extra state if we have to remember more than just the Stmt. + if (!ExtendedBy) + return; + + // We may need to allocate extra storage for the mangling number and the + // extended-by ValueDecl. + if (!State.is()) { + auto ES = new (ExtendedBy->getASTContext()) ExtraState; + ES->Temporary = State.get(); + State = ES; + } + + auto ES = State.get(); + ES->ExtendingDecl = ExtendedBy; + ES->ManglingNumber = ManglingNumber; +} + TypeTraitExpr::TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind, ArrayRef Args, SourceLocation RParenLoc, Index: lib/AST/ItaniumMangle.cpp =================================================================== --- lib/AST/ItaniumMangle.cpp +++ lib/AST/ItaniumMangle.cpp @@ -136,7 +136,8 @@ void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, const ThisAdjustment &ThisAdjustment, raw_ostream &) override; - void mangleReferenceTemporary(const VarDecl *D, raw_ostream &) override; + void mangleReferenceTemporary(const VarDecl *D, unsigned ManglingNumber, + raw_ostream &) override; void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) override; void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) override; void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset, @@ -3781,12 +3782,16 @@ } void ItaniumMangleContextImpl::mangleReferenceTemporary(const VarDecl *D, + unsigned ManglingNumber, raw_ostream &Out) { // We match the GCC mangling here. // ::= GR CXXNameMangler Mangler(*this, Out); Mangler.getStream() << "_ZGR"; Mangler.mangleName(D); + assert(ManglingNumber > 0 && "Reference temporary mangling number is zero!"); + if (ManglingNumber > 1) + Mangler.mangleNumber(ManglingNumber - 2); } void ItaniumMangleContextImpl::mangleCXXVTable(const CXXRecordDecl *RD, Index: lib/AST/MicrosoftMangle.cpp =================================================================== --- lib/AST/MicrosoftMangle.cpp +++ lib/AST/MicrosoftMangle.cpp @@ -117,7 +117,7 @@ raw_ostream &) override; void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, raw_ostream &) override; - void mangleReferenceTemporary(const VarDecl *, raw_ostream &) override; + void mangleReferenceTemporary(const VarDecl *, unsigned ManglingNumber, raw_ostream &) override; void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &Out) override; void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) override; void mangleDynamicAtExitDestructor(const VarDecl *D, @@ -2267,6 +2267,7 @@ } void MicrosoftMangleContextImpl::mangleReferenceTemporary(const VarDecl *VD, + unsigned, raw_ostream &) { unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error, "cannot mangle this reference temporary yet"); Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -2828,7 +2828,8 @@ // we also need to make the temporaries externally-visible). SmallString<256> Name; llvm::raw_svector_ostream Out(Name); - getCXXABI().getMangleContext().mangleReferenceTemporary(VD, Out); + getCXXABI().getMangleContext().mangleReferenceTemporary( + VD, E->getManglingNumber(), Out); Out.flush(); APValue *Value = 0; Index: lib/Sema/SemaCast.cpp =================================================================== --- lib/Sema/SemaCast.cpp +++ lib/Sema/SemaCast.cpp @@ -1584,8 +1584,8 @@ // This is a const_cast from a class prvalue to an rvalue reference type. // Materialize a temporary to store the result of the conversion. SrcExpr = new (Self.Context) MaterializeTemporaryExpr( - SrcType, SrcExpr.take(), /*IsLValueReference*/ false, - /*ExtendingDecl*/ 0); + SrcType, SrcExpr.take(), /*IsLValueReference=*/false, + /*ExtendingDecl=*/nullptr, /*ManglingNumber=*/0); return TC_Success; } Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -8884,8 +8884,9 @@ if (sfinae) return QualType(); // Materialize the temporary as an lvalue so that we can take its address. - OrigOp = op = new (Context) - MaterializeTemporaryExpr(op->getType(), OrigOp.take(), true, 0); + OrigOp = op = new (Context) MaterializeTemporaryExpr( + op->getType(), OrigOp.take(), /*BoundToLvalueReference=*/true, + /*ExtendingDecl=*/nullptr, /*ManglingNumber=*/0); } else if (isa(op)) { return Context.getPointerType(op->getType()); } else if (lval == Expr::LV_MemberFunction) { Index: lib/Sema/SemaInit.cpp =================================================================== --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -5311,25 +5311,25 @@ /// Determine the declaration which an initialized entity ultimately refers to, /// for the purpose of lifetime-extending a temporary bound to a reference in /// the initialization of \p Entity. -static const ValueDecl * -getDeclForTemporaryLifetimeExtension(const InitializedEntity &Entity, - const ValueDecl *FallbackDecl = 0) { +static const InitializedEntity *getEntityForTemporaryLifetimeExtension( + const InitializedEntity *Entity, + const InitializedEntity *FallbackDecl = 0) { // C++11 [class.temporary]p5: - switch (Entity.getKind()) { + switch (Entity->getKind()) { case InitializedEntity::EK_Variable: // The temporary [...] persists for the lifetime of the reference - return Entity.getDecl(); + return Entity; case InitializedEntity::EK_Member: // For subobjects, we look at the complete object. - if (Entity.getParent()) - return getDeclForTemporaryLifetimeExtension(*Entity.getParent(), - Entity.getDecl()); + if (Entity->getParent()) + return getEntityForTemporaryLifetimeExtension(Entity->getParent(), + Entity); // except: // -- A temporary bound to a reference member in a constructor's // ctor-initializer persists until the constructor exits. - return Entity.getDecl(); + return Entity; case InitializedEntity::EK_Parameter: case InitializedEntity::EK_Parameter_CF_Audited: @@ -5344,7 +5344,7 @@ // -- A temporary bound to a reference in a new-initializer persists // until the completion of the full-expression containing the // new-initializer. - return 0; + return nullptr; case InitializedEntity::EK_Temporary: case InitializedEntity::EK_CompoundLiteralInit: @@ -5352,12 +5352,12 @@ // We don't yet know the storage duration of the surrounding temporary. // Assume it's got full-expression duration for now, it will patch up our // storage duration if that's not correct. - return 0; + return nullptr; case InitializedEntity::EK_ArrayElement: // For subobjects, we look at the complete object. - return getDeclForTemporaryLifetimeExtension(*Entity.getParent(), - FallbackDecl); + return getEntityForTemporaryLifetimeExtension(Entity->getParent(), + FallbackDecl); case InitializedEntity::EK_Base: case InitializedEntity::EK_Delegating: @@ -5372,17 +5372,19 @@ case InitializedEntity::EK_Exception: case InitializedEntity::EK_VectorElement: case InitializedEntity::EK_ComplexElement: - return 0; + return nullptr; } llvm_unreachable("unknown entity kind"); } -static void performLifetimeExtension(Expr *Init, const ValueDecl *ExtendingD); +static void performLifetimeExtension(Expr *Init, const ValueDecl *ExtendingD, + unsigned &ManglingNumber); /// Update a glvalue expression that is used as the initializer of a reference /// to note that its lifetime is extended. /// \return \c true if any temporary had its lifetime extended. -static bool performReferenceExtension(Expr *Init, const ValueDecl *ExtendingD) { +static bool performReferenceExtension(Expr *Init, const ValueDecl *ExtendingD, + unsigned &ManglingNumber) { if (InitListExpr *ILE = dyn_cast(Init)) { if (ILE->getNumInits() == 1 && ILE->isGLValue()) { // This is just redundant braces around an initializer. Step over it. @@ -5416,8 +5418,10 @@ if (MaterializeTemporaryExpr *ME = dyn_cast(Init)) { // Update the storage duration of the materialized temporary. // FIXME: Rebuild the expression instead of mutating it. - ME->setExtendingDecl(ExtendingD); - performLifetimeExtension(ME->GetTemporaryExpr(), ExtendingD); + ME->setExtendingDecl(ExtendingD, ManglingNumber); + ++ManglingNumber; + performLifetimeExtension(ME->GetTemporaryExpr(), ExtendingD, + ManglingNumber); return true; } @@ -5426,7 +5430,8 @@ /// Update a prvalue expression that is going to be materialized as a /// lifetime-extended temporary. -static void performLifetimeExtension(Expr *Init, const ValueDecl *ExtendingD) { +static void performLifetimeExtension(Expr *Init, const ValueDecl *ExtendingD, + unsigned &ManglingNumber) { // Dig out the expression which constructs the extended temporary. SmallVector CommaLHSs; SmallVector Adjustments; @@ -5438,14 +5443,14 @@ if (CXXStdInitializerListExpr *ILE = dyn_cast(Init)) { - performReferenceExtension(ILE->getSubExpr(), ExtendingD); + performReferenceExtension(ILE->getSubExpr(), ExtendingD, ManglingNumber); return; } if (InitListExpr *ILE = dyn_cast(Init)) { if (ILE->getType()->isArrayType()) { for (unsigned I = 0, N = ILE->getNumInits(); I != N; ++I) - performLifetimeExtension(ILE->getInit(I), ExtendingD); + performLifetimeExtension(ILE->getInit(I), ExtendingD, ManglingNumber); return; } @@ -5457,7 +5462,7 @@ // bound to temporaries, those temporaries are also lifetime-extended. if (RD->isUnion() && ILE->getInitializedFieldInUnion() && ILE->getInitializedFieldInUnion()->getType()->isReferenceType()) - performReferenceExtension(ILE->getInit(0), ExtendingD); + performReferenceExtension(ILE->getInit(0), ExtendingD, ManglingNumber); else { unsigned Index = 0; for (const auto *I : RD->fields()) { @@ -5467,13 +5472,13 @@ continue; Expr *SubInit = ILE->getInit(Index); if (I->getType()->isReferenceType()) - performReferenceExtension(SubInit, ExtendingD); + performReferenceExtension(SubInit, ExtendingD, ManglingNumber); else if (isa(SubInit) || isa(SubInit)) // This may be either aggregate-initialization of a member or // initialization of a std::initializer_list object. Either way, // we should recursively lifetime-extend that initializer. - performLifetimeExtension(SubInit, ExtendingD); + performLifetimeExtension(SubInit, ExtendingD, ManglingNumber); ++Index; } } @@ -5759,9 +5764,11 @@ // Even though we didn't materialize a temporary, the binding may still // extend the lifetime of a temporary. This happens if we bind a reference // to the result of a cast to reference type. - if (const ValueDecl *ExtendingDecl = - getDeclForTemporaryLifetimeExtension(Entity)) { - if (performReferenceExtension(CurInit.get(), ExtendingDecl)) + if (const InitializedEntity *ExtendingEntity = + getEntityForTemporaryLifetimeExtension(&Entity)) { + const ValueDecl *ExtendingDecl = ExtendingEntity->getDecl(); + if (performReferenceExtension(CurInit.get(), ExtendingDecl, + ExtendingEntity->getManglingNumber())) warnOnLifetimeExtension(S, Entity, CurInit.get(), false, ExtendingDecl); } @@ -5776,19 +5783,29 @@ if (S.CheckExceptionSpecCompatibility(CurInit.get(), DestType)) return ExprError(); + unsigned ManglingNumber = 1; + const ValueDecl *ExtendingDecl = nullptr; + // Maybe lifetime-extend the temporary's subobjects to match the // entity's lifetime. - const ValueDecl *ExtendingDecl = - getDeclForTemporaryLifetimeExtension(Entity); - if (ExtendingDecl) { - performLifetimeExtension(CurInit.get(), ExtendingDecl); + const InitializedEntity *ExtendingEntity = + getEntityForTemporaryLifetimeExtension(&Entity); + if (ExtendingEntity) { + unsigned &ExtendingEntityManglingNumber = + ExtendingEntity->getManglingNumber(); + ManglingNumber = ExtendingEntityManglingNumber++; + + ExtendingDecl = ExtendingEntity->getDecl(); + performLifetimeExtension(CurInit.get(), ExtendingDecl, + ExtendingEntityManglingNumber); warnOnLifetimeExtension(S, Entity, CurInit.get(), false, ExtendingDecl); } // Materialize the temporary into memory. MaterializeTemporaryExpr *MTE = new (S.Context) MaterializeTemporaryExpr( Entity.getType().getNonReferenceType(), CurInit.get(), - Entity.getType()->isLValueReferenceType(), ExtendingDecl); + Entity.getType()->isLValueReferenceType(), ExtendingDecl, + ManglingNumber); // If we're binding to an Objective-C object that has lifetime, we // need cleanups. Likewise if we're extending this temporary to automatic @@ -6176,19 +6193,29 @@ diag::warn_cxx98_compat_initializer_list_init) << CurInit.get()->getSourceRange(); + unsigned ManglingNumber = 1; + const ValueDecl *ExtendingDecl = nullptr; + // Maybe lifetime-extend the array temporary's subobjects to match the // entity's lifetime. - const ValueDecl *ExtendingDecl = - getDeclForTemporaryLifetimeExtension(Entity); - if (ExtendingDecl) { - performLifetimeExtension(CurInit.get(), ExtendingDecl); + const InitializedEntity *ExtendingEntity = + getEntityForTemporaryLifetimeExtension(&Entity); + if (ExtendingEntity) { + unsigned &ExtendingEntityManglingNumber = + ExtendingEntity->getManglingNumber(); + ManglingNumber = ExtendingEntityManglingNumber++; + + ExtendingDecl = ExtendingEntity->getDecl(); + performLifetimeExtension(CurInit.get(), ExtendingDecl, + ExtendingEntityManglingNumber); warnOnLifetimeExtension(S, Entity, CurInit.get(), true, ExtendingDecl); } // Materialize the temporary into memory. MaterializeTemporaryExpr *MTE = new (S.Context) MaterializeTemporaryExpr(CurInit.get()->getType(), CurInit.get(), - /*lvalue reference*/ false, ExtendingDecl); + /*BoundToLvalueReference=*/false, + ExtendingDecl, ManglingNumber); // Wrap it in a construction of a std::initializer_list. CurInit = S.Owned( Index: lib/Serialization/ASTReaderStmt.cpp =================================================================== --- lib/Serialization/ASTReaderStmt.cpp +++ lib/Serialization/ASTReaderStmt.cpp @@ -1572,8 +1572,10 @@ void ASTStmtReader::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) { VisitExpr(E); - E->Temporary = Reader.ReadSubExpr(); - E->ExtendingDecl = ReadDeclAs(Record, Idx); + E->State = Reader.ReadSubExpr(); + auto VD = ReadDeclAs(Record, Idx); + unsigned ManglingNumber = Record[Idx++]; + E->initializeExtraState(VD, ManglingNumber); } void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) { Index: lib/Serialization/ASTWriterStmt.cpp =================================================================== --- lib/Serialization/ASTWriterStmt.cpp +++ lib/Serialization/ASTWriterStmt.cpp @@ -1567,8 +1567,9 @@ void ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) { VisitExpr(E); - Writer.AddStmt(E->Temporary); - Writer.AddDeclRef(E->ExtendingDecl, Record); + Writer.AddStmt(E->getTemporary()); + Writer.AddDeclRef(E->getExtendingDecl(), Record); + Record.push_back(E->getManglingNumber()); Code = serialization::EXPR_MATERIALIZE_TEMPORARY; } Index: test/CodeGenCXX/const-init-cxx1y.cpp =================================================================== --- test/CodeGenCXX/const-init-cxx1y.cpp +++ test/CodeGenCXX/const-init-cxx1y.cpp @@ -54,16 +54,16 @@ const int &use = i; } -// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE = linkonce_odr constant i32 1 -// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE2 = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE } +// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE1 = linkonce_odr constant i32 1 +// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE0 = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE1 } // CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE3 = linkonce_odr constant i32 2 -// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE4 = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE3 } +// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE2 = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE3 } // CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE5 = linkonce_odr constant i32 3 -// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE6 = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE5 } +// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE4 = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE5 } // CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE7 = linkonce_odr constant i32 4 -// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE8 = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE7 } -// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE9 = linkonce_odr global {{.*}} { {{.*}} @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE2, {{.*}} @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE4, {{.*}} @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE6, {{.*}} @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE8 } -// CHECK: @_ZN24VariableTemplateWithPack1pE = global {{.*}} @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE9 +// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE6 = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE7 } +// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE = linkonce_odr global %"struct.VariableTemplateWithPack::S" { {{.*}}* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE0, {{.*}}* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE2, {{.*}}* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE4, {{.*}}* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE6 } +// CHECK: @_ZN24VariableTemplateWithPack1pE = global {{.*}} @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE namespace VariableTemplateWithPack { struct A { const int &r; Index: test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp =================================================================== --- test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp +++ test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp @@ -55,76 +55,76 @@ {1, a}, {3, b}, {5, c} }; -// CHECK-STATIC-BL: @_ZGR6nested = private constant [2 x i32] [i32 1, i32 2], align 4 +// CHECK-STATIC-BL: @_ZGR6nested0 = private constant [2 x i32] [i32 1, i32 2], align 4 // CHECK-STATIC-BL: @_ZGR6nested1 = private constant [2 x i32] [i32 3, i32 4], align 4 // CHECK-STATIC-BL: @_ZGR6nested2 = private constant [2 x i32] [i32 5, i32 6], align 4 -// CHECK-STATIC-BL: @_ZGR6nested3 = private constant [3 x {{.*}}] [ -// CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested, i32 0, i32 0), i64 2 }, +// CHECK-STATIC-BL: @_ZGR6nested = private constant [3 x {{.*}}] [ +// CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0, i32 0, i32 0), i64 2 }, // CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i32 0, i32 0), i64 2 }, // CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i32 0, i32 0), i64 2 } // CHECK-STATIC-BL: ], align 8 -// CHECK-STATIC-BL: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested3, i32 0, i32 0), i64 3 }, align 8 +// CHECK-STATIC-BL: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i32 0, i32 0), i64 3 }, align 8 // CHECK-DYNAMIC-BL: @nested = global // CHECK-DYNAMIC-BL: @_ZGR6nested = private global [3 x +// CHECK-DYNAMIC-BL: @_ZGR6nested0 = private global [2 x i32] zeroinitializer // CHECK-DYNAMIC-BL: @_ZGR6nested1 = private global [2 x i32] zeroinitializer // CHECK-DYNAMIC-BL: @_ZGR6nested2 = private global [2 x i32] zeroinitializer -// CHECK-DYNAMIC-BL: @_ZGR6nested3 = private global [2 x i32] zeroinitializer -// CHECK-DYNAMIC-BL: store i32 1, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0) -// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 1) -// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0), +// CHECK-DYNAMIC-BL: store i32 1, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0, i64 0, i64 0) +// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0, i64 0, i64 1) +// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0, i64 0, i64 0), // CHECK-DYNAMIC-BL: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 0), align 8 // CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 1), align 8 -// CHECK-DYNAMIC-BL: store i32 3, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0) -// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 1) -// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0), +// CHECK-DYNAMIC-BL: store i32 3, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0) +// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 1) +// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0), // CHECK-DYNAMIC-BL: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 0), align 8 // CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 1), align 8 -// CHECK-DYNAMIC-BL: store i32 5, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 0) -// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 1) -// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 0), +// CHECK-DYNAMIC-BL: store i32 5, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0) +// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 1) +// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0), // CHECK-DYNAMIC-BL: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 2, i32 0), align 8 // CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 2, i32 1), align 8 // CHECK-DYNAMIC-BL: store {{.*}}* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0), // CHECK-DYNAMIC-BL: {{.*}}** getelementptr inbounds ({{.*}}* @nested, i32 0, i32 0), align 8 // CHECK-DYNAMIC-BL: store i64 3, i64* getelementptr inbounds ({{.*}}* @nested, i32 0, i32 1), align 8 -// CHECK-STATIC-BE: @_ZGR6nested = private constant [2 x i32] [i32 1, i32 2], align 4 +// CHECK-STATIC-BE: @_ZGR6nested0 = private constant [2 x i32] [i32 1, i32 2], align 4 // CHECK-STATIC-BE: @_ZGR6nested1 = private constant [2 x i32] [i32 3, i32 4], align 4 // CHECK-STATIC-BE: @_ZGR6nested2 = private constant [2 x i32] [i32 5, i32 6], align 4 -// CHECK-STATIC-BE: @_ZGR6nested3 = private constant [3 x {{.*}}] [ -// CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested, i32 0, i32 0), -// CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested to i8*), i64 8) to i32*) } +// CHECK-STATIC-BE: @_ZGR6nested = private constant [3 x {{.*}}] [ +// CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0, i32 0, i32 0), +// CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested0 to i8*), i64 8) to i32*) } // CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i32 0, i32 0), // CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested1 to i8*), i64 8) to i32*) } // CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i32 0, i32 0), // CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested2 to i8*), i64 8) to i32*) } // CHECK-STATIC-BE: ], align 8 -// CHECK-STATIC-BE: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested3, i32 0, i32 0), -// CHECK-STATIC-BE: {{.*}} bitcast ({{.*}}* getelementptr (i8* bitcast ([3 x {{.*}}]* @_ZGR6nested3 to i8*), i64 48) to {{.*}}*) } +// CHECK-STATIC-BE: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i32 0, i32 0), +// CHECK-STATIC-BE: {{.*}} bitcast ({{.*}}* getelementptr (i8* bitcast ([3 x {{.*}}]* @_ZGR6nested to i8*), i64 48) to {{.*}}*) } // CHECK-DYNAMIC-BE: @nested = global // CHECK-DYNAMIC-BE: @_ZGR6nested = private global [3 x +// CHECK-DYNAMIC-BE: @_ZGR6nested0 = private global [2 x i32] zeroinitializer // CHECK-DYNAMIC-BE: @_ZGR6nested1 = private global [2 x i32] zeroinitializer // CHECK-DYNAMIC-BE: @_ZGR6nested2 = private global [2 x i32] zeroinitializer -// CHECK-DYNAMIC-BE: @_ZGR6nested3 = private global [2 x i32] zeroinitializer -// CHECK-DYNAMIC-BE: store i32 1, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0) +// CHECK-DYNAMIC-BE: store i32 1, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0, i64 0, i64 0) +// CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0, i64 0, i64 1) +// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0, i64 0, i64 0), +// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 0), align 8 +// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0, i64 1, i64 0), +// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 1), align 8 +// CHECK-DYNAMIC-BE: store i32 3, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0) // CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 1) // CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0), -// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 0), align 8 +// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 0), align 8 // CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 1, i64 0), -// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 1), align 8 -// CHECK-DYNAMIC-BE: store i32 3, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0) +// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 1), align 8 +// CHECK-DYNAMIC-BE: store i32 5, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0) // CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 1) // CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0), -// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 0), align 8 -// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 1, i64 0), -// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 1), align 8 -// CHECK-DYNAMIC-BE: store i32 5, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 0) -// CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 1) -// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 0), // CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 2, i32 0), align 8 -// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 1, i64 0), +// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 1, i64 0), // CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 2, i32 1), align 8 // CHECK-DYNAMIC-BE: store {{.*}}* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0), // CHECK-DYNAMIC-BE: {{.*}}** getelementptr inbounds ({{.*}}* @nested, i32 0, i32 0), align 8