r274049 - P0136R1, DR1573, DR1645, DR1715, DR1736, DR1903, DR1941, DR1959, DR1991:

Alex L via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 23 11:07:55 PDT 2016


Hi Richard,

I think that this commit has caused a regression that's tracked by PR30274.
I'll try working on a fix for it.

Alex

On 28 June 2016 at 12:03, Richard Smith via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> Author: rsmith
> Date: Tue Jun 28 14:03:57 2016
> New Revision: 274049
>
> URL: http://llvm.org/viewvc/llvm-project?rev=274049&view=rev
> Log:
> P0136R1, DR1573, DR1645, DR1715, DR1736, DR1903, DR1941, DR1959, DR1991:
>
> Replace inheriting constructors implementation with new approach, voted
> into
> C++ last year as a DR against C++11.
>
> Instead of synthesizing a set of derived class constructors for each
> inherited
> base class constructor, we make the constructors of the base class visible
> to
> constructor lookup in the derived class, using the normal rules for
> using-declarations.
>
> For constructors, UsingShadowDecl now has a ConstructorUsingShadowDecl
> derived
> class that tracks the requisite additional information. We create shadow
> constructors (not found by name lookup) in the derived class to model the
> actual initialization, and have a new expression node,
> CXXInheritedCtorInitExpr, to model the initialization of a base class from
> such
> a constructor. (This initialization is special because it performs real
> perfect
> forwarding of arguments.)
>
> In cases where argument forwarding is not possible (for inalloca calls,
> variadic calls, and calls with callee parameter cleanup), the shadow
> inheriting
> constructor is not emitted and instead we directly emit the initialization
> code
> into the caller of the inherited constructor.
>
> Note that this new model is not perfectly compatible with the old model in
> some
> corner cases. In particular:
>  * if B inherits a private constructor from A, and C uses that constructor
> to
>    construct a B, then we previously required that A befriends B and B
>    befriends C, but the new rules require A to befriend C directly, and
>  * if a derived class has its own constructors (and so its implicit default
>    constructor is suppressed), it may still inherit a default constructor
> from
>    a base class
>
> Added:
>     cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp
>     cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p18.cpp
>     cfe/trunk/test/CXX/special/class.init/class.inhctor.init/
>     cfe/trunk/test/CXX/special/class.init/class.inhctor.init/p1.cpp
>     cfe/trunk/test/CXX/special/class.init/class.inhctor.init/p2.cpp
> Modified:
>     cfe/trunk/include/clang/AST/ASTMutationListener.h
>     cfe/trunk/include/clang/AST/Decl.h
>     cfe/trunk/include/clang/AST/DeclCXX.h
>     cfe/trunk/include/clang/AST/ExprCXX.h
>     cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
>     cfe/trunk/include/clang/Basic/DeclNodes.td
>     cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
>     cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>     cfe/trunk/include/clang/Basic/StmtNodes.td
>     cfe/trunk/include/clang/Sema/Overload.h
>     cfe/trunk/include/clang/Sema/Sema.h
>     cfe/trunk/include/clang/Serialization/ASTBitCodes.h
>     cfe/trunk/lib/AST/ASTDumper.cpp
>     cfe/trunk/lib/AST/DeclBase.cpp
>     cfe/trunk/lib/AST/DeclCXX.cpp
>     cfe/trunk/lib/AST/Expr.cpp
>     cfe/trunk/lib/AST/ExprClassification.cpp
>     cfe/trunk/lib/AST/ExprConstant.cpp
>     cfe/trunk/lib/AST/ItaniumMangle.cpp
>     cfe/trunk/lib/AST/NestedNameSpecifier.cpp
>     cfe/trunk/lib/AST/StmtPrinter.cpp
>     cfe/trunk/lib/AST/StmtProfile.cpp
>     cfe/trunk/lib/CodeGen/CGCall.cpp
>     cfe/trunk/lib/CodeGen/CGClass.cpp
>     cfe/trunk/lib/CodeGen/CGDecl.cpp
>     cfe/trunk/lib/CodeGen/CGExprAgg.cpp
>     cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
>     cfe/trunk/lib/CodeGen/CodeGenFunction.h
>     cfe/trunk/lib/CodeGen/CodeGenModule.cpp
>     cfe/trunk/lib/CodeGen/CodeGenTypes.h
>     cfe/trunk/lib/Sema/SemaAccess.cpp
>     cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>     cfe/trunk/lib/Sema/SemaExceptionSpec.cpp
>     cfe/trunk/lib/Sema/SemaExpr.cpp
>     cfe/trunk/lib/Sema/SemaExprCXX.cpp
>     cfe/trunk/lib/Sema/SemaInit.cpp
>     cfe/trunk/lib/Sema/SemaLookup.cpp
>     cfe/trunk/lib/Sema/SemaOverload.cpp
>     cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
>     cfe/trunk/lib/Sema/TreeTransform.h
>     cfe/trunk/lib/Serialization/ASTCommon.cpp
>     cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
>     cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
>     cfe/trunk/lib/Serialization/ASTWriter.cpp
>     cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
>     cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
>     cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
>     cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.
> qual/class.qual/p2.cpp
>     cfe/trunk/test/CXX/basic/basic.types/p10.cpp
>     cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp
>     cfe/trunk/test/CXX/drs/dr15xx.cpp
>     cfe/trunk/test/CXX/drs/dr16xx.cpp
>     cfe/trunk/test/CXX/drs/dr17xx.cpp
>     cfe/trunk/test/CXX/drs/dr19xx.cpp
>     cfe/trunk/test/CXX/except/except.spec/p14.cpp
>     cfe/trunk/test/CXX/special/class.inhctor/p1.cpp
>     cfe/trunk/test/CXX/special/class.inhctor/p2.cpp
>     cfe/trunk/test/CXX/special/class.inhctor/p3.cpp
>     cfe/trunk/test/CXX/special/class.inhctor/p4.cpp
>     cfe/trunk/test/CXX/special/class.inhctor/p7.cpp
>     cfe/trunk/test/CXX/special/class.inhctor/p8.cpp
>     cfe/trunk/test/CodeGenCXX/inheriting-constructor.cpp
>     cfe/trunk/test/PCH/cxx11-inheriting-ctors.cpp
>     cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
>     cfe/trunk/test/SemaCXX/cxx11-inheriting-ctors.cpp
>     cfe/trunk/tools/libclang/CIndex.cpp
>     cfe/trunk/tools/libclang/CXCursor.cpp
>     cfe/trunk/www/cxx_status.html
>
> Modified: cfe/trunk/include/clang/AST/ASTMutationListener.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/AST/ASTMutationListener.h?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/AST/ASTMutationListener.h (original)
> +++ cfe/trunk/include/clang/AST/ASTMutationListener.h Tue Jun 28 14:03:57
> 2016
> @@ -17,6 +17,7 @@ namespace clang {
>    class Attr;
>    class ClassTemplateDecl;
>    class ClassTemplateSpecializationDecl;
> +  class ConstructorUsingShadowDecl;
>    class CXXDestructorDecl;
>    class CXXRecordDecl;
>    class Decl;
>
> Modified: cfe/trunk/include/clang/AST/Decl.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/AST/Decl.h?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/AST/Decl.h (original)
> +++ cfe/trunk/include/clang/AST/Decl.h Tue Jun 28 14:03:57 2016
> @@ -387,6 +387,7 @@ public:
>    NamedDecl *getUnderlyingDecl() {
>      // Fast-path the common case.
>      if (this->getKind() != UsingShadow &&
> +        this->getKind() != ConstructorUsingShadow &&
>          this->getKind() != ObjCCompatibleAlias &&
>          this->getKind() != NamespaceAlias)
>        return this;
>
> Modified: cfe/trunk/include/clang/AST/DeclCXX.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/AST/DeclCXX.h?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/AST/DeclCXX.h (original)
> +++ cfe/trunk/include/clang/AST/DeclCXX.h Tue Jun 28 14:03:57 2016
> @@ -29,6 +29,7 @@ namespace clang {
>
>  class ClassTemplateDecl;
>  class ClassTemplateSpecializationDecl;
> +class ConstructorUsingShadowDecl;
>  class CXXBasePath;
>  class CXXBasePaths;
>  class CXXConstructorDecl;
> @@ -1298,7 +1299,7 @@ public:
>    }
>
>    /// \brief Determine whether this class has a using-declaration that
> names
> -  /// a base class constructor.
> +  /// a user-declared base class constructor.
>    bool hasInheritedConstructor() const {
>      return data().HasInheritedConstructor;
>    }
> @@ -2153,6 +2154,23 @@ public:
>    friend TrailingObjects;
>  };
>
> +/// Description of a constructor that was inherited from a base class.
> +class InheritedConstructor {
> +  ConstructorUsingShadowDecl *Shadow;
> +  CXXConstructorDecl *BaseCtor;
> +
> +public:
> +  InheritedConstructor() : Shadow(), BaseCtor() {}
> +  InheritedConstructor(ConstructorUsingShadowDecl *Shadow,
> +                       CXXConstructorDecl *BaseCtor)
> +      : Shadow(Shadow), BaseCtor(BaseCtor) {}
> +
> +  explicit operator bool() const { return Shadow; }
> +
> +  ConstructorUsingShadowDecl *getShadowDecl() const { return Shadow; }
> +  CXXConstructorDecl *getConstructor() const { return BaseCtor; }
> +};
> +
>  /// \brief Represents a C++ constructor within a class.
>  ///
>  /// For example:
> @@ -2163,41 +2181,51 @@ public:
>  ///   explicit X(int); // represented by a CXXConstructorDecl.
>  /// };
>  /// \endcode
> -class CXXConstructorDecl : public CXXMethodDecl {
> +class CXXConstructorDecl final
> +    : public CXXMethodDecl,
> +      private llvm::TrailingObjects<CXXConstructorDecl,
> InheritedConstructor> {
>    void anchor() override;
>
>    /// \name Support for base and member initializers.
>    /// \{
>    /// \brief The arguments used to initialize the base or member.
>    LazyCXXCtorInitializersPtr CtorInitializers;
> -  unsigned NumCtorInitializers : 31;
> +  unsigned NumCtorInitializers : 30;
>    /// \}
>
>    /// \brief Whether this constructor declaration has the \c explicit
> keyword
>    /// specified.
>    unsigned IsExplicitSpecified : 1;
>
> +  /// \brief Whether this constructor declaration is an
> implicitly-declared
> +  /// inheriting constructor.
> +  unsigned IsInheritingConstructor : 1;
> +
>    CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation
> StartLoc,
>                       const DeclarationNameInfo &NameInfo,
>                       QualType T, TypeSourceInfo *TInfo,
>                       bool isExplicitSpecified, bool isInline,
> -                     bool isImplicitlyDeclared, bool isConstexpr)
> +                     bool isImplicitlyDeclared, bool isConstexpr,
> +                     InheritedConstructor Inherited)
>      : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
>                      SC_None, isInline, isConstexpr, SourceLocation()),
>        CtorInitializers(nullptr), NumCtorInitializers(0),
> -      IsExplicitSpecified(isExplicitSpecified) {
> +      IsExplicitSpecified(isExplicitSpecified),
> +      IsInheritingConstructor((bool)Inherited) {
>      setImplicit(isImplicitlyDeclared);
> +    if (Inherited)
> +      *getTrailingObjects<InheritedConstructor>() = Inherited;
>    }
>
>  public:
> -  static CXXConstructorDecl *CreateDeserialized(ASTContext &C, unsigned
> ID);
> -  static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
> -                                    SourceLocation StartLoc,
> -                                    const DeclarationNameInfo &NameInfo,
> -                                    QualType T, TypeSourceInfo *TInfo,
> -                                    bool isExplicit,
> -                                    bool isInline, bool
> isImplicitlyDeclared,
> -                                    bool isConstexpr);
> +  static CXXConstructorDecl *CreateDeserialized(ASTContext &C, unsigned
> ID,
> +                                                bool InheritsConstructor);
> +  static CXXConstructorDecl *
> +  Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
> +         const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo
> *TInfo,
> +         bool isExplicit, bool isInline, bool isImplicitlyDeclared,
> +         bool isConstexpr,
> +         InheritedConstructor Inherited = InheritedConstructor());
>
>    /// \brief Determine whether this constructor declaration has the
>    /// \c explicit keyword specified.
> @@ -2344,11 +2372,15 @@ public:
>    /// an object.
>    bool isSpecializationCopyingObject() const;
>
> -  /// \brief Get the constructor that this inheriting constructor is
> based on.
> -  const CXXConstructorDecl *getInheritedConstructor() const;
> +  /// \brief Determine whether this is an implicit constructor
> synthesized to
> +  /// model a call to a constructor inherited from a base class.
> +  bool isInheritingConstructor() const { return IsInheritingConstructor; }
>
> -  /// \brief Set the constructor that this inheriting constructor is
> based on.
> -  void setInheritedConstructor(const CXXConstructorDecl *BaseCtor);
> +  /// \brief Get the constructor that this inheriting constructor is
> based on.
> +  InheritedConstructor getInheritedConstructor() const {
> +    return IsInheritingConstructor ? *getTrailingObjects<
> InheritedConstructor>()
> +                                   : InheritedConstructor();
> +  }
>
>    CXXConstructorDecl *getCanonicalDecl() override {
>      return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
> @@ -2363,6 +2395,7 @@ public:
>
>    friend class ASTDeclReader;
>    friend class ASTDeclWriter;
> +  friend TrailingObjects;
>  };
>
>  /// \brief Represents a C++ destructor within a class.
> @@ -2807,18 +2840,6 @@ class UsingShadowDecl : public NamedDecl
>    NamedDecl *UsingOrNextShadow;
>    friend class UsingDecl;
>
> -  UsingShadowDecl(ASTContext &C, DeclContext *DC, SourceLocation Loc,
> -                  UsingDecl *Using, NamedDecl *Target)
> -    : NamedDecl(UsingShadow, DC, Loc, DeclarationName()),
> -      redeclarable_base(C), Underlying(Target),
> -      UsingOrNextShadow(reinterpret_cast<NamedDecl *>(Using)) {
> -    if (Target) {
> -      setDeclName(Target->getDeclName());
> -      IdentifierNamespace = Target->getIdentifierNamespace();
> -    }
> -    setImplicit();
> -  }
> -
>    typedef Redeclarable<UsingShadowDecl> redeclarable_base;
>    UsingShadowDecl *getNextRedeclarationImpl() override {
>      return getNextRedeclaration();
> @@ -2830,11 +2851,16 @@ class UsingShadowDecl : public NamedDecl
>      return getMostRecentDecl();
>    }
>
> +protected:
> +  UsingShadowDecl(Kind K, ASTContext &C, DeclContext *DC, SourceLocation
> Loc,
> +                  UsingDecl *Using, NamedDecl *Target);
> +  UsingShadowDecl(Kind K, ASTContext &C, EmptyShell);
> +
>  public:
>    static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
>                                   SourceLocation Loc, UsingDecl *Using,
>                                   NamedDecl *Target) {
> -    return new (C, DC) UsingShadowDecl(C, DC, Loc, Using, Target);
> +    return new (C, DC) UsingShadowDecl(UsingShadow, C, DC, Loc, Using,
> Target);
>    }
>
>    static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID);
> @@ -2846,6 +2872,7 @@ public:
>    using redeclarable_base::redecls;
>    using redeclarable_base::getPreviousDecl;
>    using redeclarable_base::getMostRecentDecl;
> +  using redeclarable_base::isFirstDecl;
>
>    UsingShadowDecl *getCanonicalDecl() override {
>      return getFirstDecl();
> @@ -2876,7 +2903,125 @@ public:
>    }
>
>    static bool classof(const Decl *D) { return classofKind(D->getKind()); }
> -  static bool classofKind(Kind K) { return K == Decl::UsingShadow; }
> +  static bool classofKind(Kind K) {
> +    return K == Decl::UsingShadow || K == Decl::ConstructorUsingShadow;
> +  }
> +
> +  friend class ASTDeclReader;
> +  friend class ASTDeclWriter;
> +};
> +
> +/// \brief Represents a shadow constructor declaration introduced into a
> +/// class by a C++11 using-declaration that names a constructor.
> +///
> +/// For example:
> +/// \code
> +/// struct Base { Base(int); };
> +/// struct Derived {
> +///    using Base::Base; // creates a UsingDecl and a
> ConstructorUsingShadowDecl
> +/// };
> +/// \endcode
> +class ConstructorUsingShadowDecl final : public UsingShadowDecl {
> +  void anchor() override;
> +
> +  /// \brief If this constructor using declaration inherted the
> constructor
> +  /// from an indirect base class, this is the ConstructorUsingShadowDecl
> +  /// in the named direct base class from which the declaration was
> inherited.
> +  ConstructorUsingShadowDecl *NominatedBaseClassShadowDecl;
> +
> +  /// \brief If this constructor using declaration inherted the
> constructor
> +  /// from an indirect base class, this is the ConstructorUsingShadowDecl
> +  /// that will be used to construct the unique direct or virtual base
> class
> +  /// that receives the constructor arguments.
> +  ConstructorUsingShadowDecl *ConstructedBaseClassShadowDecl;
> +
> +  /// \brief \c true if the constructor ultimately named by this using
> shadow
> +  /// declaration is within a virtual base class subobject of the class
> that
> +  /// contains this declaration.
> +  unsigned IsVirtual : 1;
> +
> +  ConstructorUsingShadowDecl(ASTContext &C, DeclContext *DC,
> SourceLocation Loc,
> +                             UsingDecl *Using, NamedDecl *Target,
> +                             bool TargetInVirtualBase)
> +      : UsingShadowDecl(ConstructorUsingShadow, C, DC, Loc, Using,
> +                        Target->getUnderlyingDecl()),
> +        NominatedBaseClassShadowDecl(
> +            dyn_cast<ConstructorUsingShadowDecl>(Target)),
> +        ConstructedBaseClassShadowDecl(NominatedBaseClassShadowDecl),
> +        IsVirtual(TargetInVirtualBase) {
> +    // If we found a constructor for a non-virtual base class, but it
> chains to
> +    // a constructor for a virtual base, we should directly call the
> virtual
> +    // base constructor instead.
> +    // FIXME: This logic belongs in Sema.
> +    if (!TargetInVirtualBase && NominatedBaseClassShadowDecl &&
> +        NominatedBaseClassShadowDecl->constructsVirtualBase()) {
> +      ConstructedBaseClassShadowDecl =
> +          NominatedBaseClassShadowDecl->ConstructedBaseClassShadowDecl;
> +      IsVirtual = true;
> +    }
> +  }
> +  ConstructorUsingShadowDecl(ASTContext &C, EmptyShell Empty)
> +      : UsingShadowDecl(ConstructorUsingShadow, C, Empty) {}
> +
> +public:
> +  static ConstructorUsingShadowDecl *Create(ASTContext &C, DeclContext
> *DC,
> +                                            SourceLocation Loc,
> +                                            UsingDecl *Using, NamedDecl
> *Target,
> +                                            bool IsVirtual);
> +  static ConstructorUsingShadowDecl *CreateDeserialized(ASTContext &C,
> +                                                        unsigned ID);
> +
> +  /// Returns the parent of this using shadow declaration, which
> +  /// is the class in which this is declared.
> +  //@{
> +  const CXXRecordDecl *getParent() const {
> +    return cast<CXXRecordDecl>(getDeclContext());
> +  }
> +  CXXRecordDecl *getParent() {
> +    return cast<CXXRecordDecl>(getDeclContext());
> +  }
> +  //@}
> +
> +  /// \brief Get the inheriting constructor declaration for the direct
> base
> +  /// class from which this using shadow declaration was inherited, if
> there is
> +  /// one. This can be different for each redeclaration of the same
> shadow decl.
> +  ConstructorUsingShadowDecl *getNominatedBaseClassShadowDecl() const {
> +    return NominatedBaseClassShadowDecl;
> +  }
> +
> +  /// \brief Get the inheriting constructor declaration for the base class
> +  /// for which we don't have an explicit initializer, if there is one.
> +  ConstructorUsingShadowDecl *getConstructedBaseClassShadowDecl() const {
> +    return ConstructedBaseClassShadowDecl;
> +  }
> +
> +  /// \brief Get the base class that was named in the using declaration.
> This
> +  /// can be different for each redeclaration of this same shadow decl.
> +  CXXRecordDecl *getNominatedBaseClass() const;
> +
> +  /// \brief Get the base class whose constructor or constructor shadow
> +  /// declaration is passed the constructor arguments.
> +  CXXRecordDecl *getConstructedBaseClass() const {
> +    return cast<CXXRecordDecl>((ConstructedBaseClassShadowDecl
> +                                    ? ConstructedBaseClassShadowDecl
> +                                    : getTargetDecl())
> +                                   ->getDeclContext());
> +  }
> +
> +  /// \brief Returns \c true if the constructed base class is a virtual
> base
> +  /// class subobject of this declaration's class.
> +  bool constructsVirtualBase() const {
> +    return IsVirtual;
> +  }
> +
> +  /// \brief Get the constructor or constructor template in the derived
> class
> +  /// correspnding to this using shadow declaration, if it has been
> implicitly
> +  /// declared already.
> +  CXXConstructorDecl *getConstructor() const;
> +  void setConstructor(NamedDecl *Ctor);
> +
> +  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
> +  static bool classofKind(Kind K) { return K == ConstructorUsingShadow; }
>
>    friend class ASTDeclReader;
>    friend class ASTDeclWriter;
>
> Modified: cfe/trunk/include/clang/AST/ExprCXX.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/AST/ExprCXX.h?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/AST/ExprCXX.h (original)
> +++ cfe/trunk/include/clang/AST/ExprCXX.h Tue Jun 28 14:03:57 2016
> @@ -1318,6 +1318,73 @@ public:
>    friend class ASTStmtReader;
>  };
>
> +/// \brief Represents a call to an inherited base class constructor from
> an
> +/// inheriting constructor. This call implicitly forwards the arguments
> from
> +/// the enclosing context (an inheriting constructor) to the specified
> inherited
> +/// base class constructor.
> +class CXXInheritedCtorInitExpr : public Expr {
> +private:
> +  CXXConstructorDecl *Constructor;
> +
> +  /// The location of the using declaration.
> +  SourceLocation Loc;
> +
> +  /// Whether this is the construction of a virtual base.
> +  unsigned ConstructsVirtualBase : 1;
> +
> +  /// Whether the constructor is inherited from a virtual base class of
> the
> +  /// class that we construct.
> +  unsigned InheritedFromVirtualBase : 1;
> +
> +public:
> +  /// \brief Construct a C++ inheriting construction expression.
> +  CXXInheritedCtorInitExpr(SourceLocation Loc, QualType T,
> +                           CXXConstructorDecl *Ctor, bool
> ConstructsVirtualBase,
> +                           bool InheritedFromVirtualBase)
> +      : Expr(CXXInheritedCtorInitExprClass, T, VK_RValue, OK_Ordinary,
> false,
> +             false, false, false),
> +        Constructor(Ctor), Loc(Loc),
> +        ConstructsVirtualBase(ConstructsVirtualBase),
> +        InheritedFromVirtualBase(InheritedFromVirtualBase) {
> +    assert(!T->isDependentType());
> +  }
> +
> +  /// \brief Construct an empty C++ inheriting construction expression.
> +  explicit CXXInheritedCtorInitExpr(EmptyShell Empty)
> +      : Expr(CXXInheritedCtorInitExprClass, Empty), Constructor(nullptr),
> +        ConstructsVirtualBase(false), InheritedFromVirtualBase(false) {}
> +
> +  /// \brief Get the constructor that this expression will call.
> +  CXXConstructorDecl *getConstructor() const { return Constructor; }
> +
> +  /// \brief Determine whether this constructor is actually constructing
> +  /// a base class (rather than a complete object).
> +  bool constructsVBase() const { return ConstructsVirtualBase; }
> +  CXXConstructExpr::ConstructionKind getConstructionKind() const {
> +    return ConstructsVirtualBase ? CXXConstructExpr::CK_VirtualBase
> +                                 : CXXConstructExpr::CK_NonVirtualBase;
> +  }
> +
> +  /// \brief Determine whether the inherited constructor is inherited
> from a
> +  /// virtual base of the object we construct. If so, we are not
> responsible
> +  /// for calling the inherited constructor (the complete object
> constructor
> +  /// does that), and so we don't need to pass any arguments.
> +  bool inheritedFromVBase() const { return InheritedFromVirtualBase; }
> +
> +  SourceLocation getLocation() const LLVM_READONLY { return Loc; }
> +  SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
> +  SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
> +
> +  static bool classof(const Stmt *T) {
> +    return T->getStmtClass() == CXXInheritedCtorInitExprClass;
> +  }
> +  child_range children() {
> +    return child_range(child_iterator(), child_iterator());
> +  }
> +
> +  friend class ASTStmtReader;
> +};
> +
>  /// \brief Represents an explicit C++ type conversion that uses
> "functional"
>  /// notation (C++ [expr.type.conv]).
>  ///
>
> Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/AST/RecursiveASTVisitor.h?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
> +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Tue Jun 28 14:03:57
> 2016
> @@ -1466,6 +1466,8 @@ DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
>
>  DEF_TRAVERSE_DECL(UsingShadowDecl, {})
>
> +DEF_TRAVERSE_DECL(ConstructorUsingShadowDecl, {})
> +
>  DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
>    for (auto *I : D->varlists()) {
>      TRY_TO(TraverseStmt(I));
> @@ -2266,6 +2268,7 @@ DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {})
>  DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {})
>  DEF_TRAVERSE_STMT(CXXDeleteExpr, {})
>  DEF_TRAVERSE_STMT(ExprWithCleanups, {})
> +DEF_TRAVERSE_STMT(CXXInheritedCtorInitExpr, {})
>  DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, {})
>  DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, {})
>  DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
>
> Modified: cfe/trunk/include/clang/Basic/DeclNodes.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/Basic/DeclNodes.td?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Basic/DeclNodes.td (original)
> +++ cfe/trunk/include/clang/Basic/DeclNodes.td Tue Jun 28 14:03:57 2016
> @@ -66,6 +66,7 @@ def Named : Decl<1>;
>      def BuiltinTemplate : DDecl<Template>;
>    def Using : DDecl<Named>;
>    def UsingShadow : DDecl<Named>;
> +    def ConstructorUsingShadow : DDecl<UsingShadow>;
>    def ObjCMethod : DDecl<Named>, DeclContext;
>    def ObjCContainer : DDecl<Named, 1>, DeclContext;
>      def ObjCCategory : DDecl<ObjCContainer>;
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/
> DiagnosticASTKinds.td?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td Tue Jun 28
> 14:03:57 2016
> @@ -26,6 +26,9 @@ def note_constexpr_lshift_discards : Not
>  def note_constexpr_invalid_function : Note<
>    "%select{non-constexpr|undefined}0 %select{function|constructor}1 %2
> cannot "
>    "be used in a constant expression">;
> +def note_constexpr_invalid_inhctor : Note<
> +  "constructor inherited from base class %0 cannot be used in a "
> +  "constant expression; derived class cannot be implicitly initialized">;
>  def note_constexpr_no_return : Note<
>    "control reached end of constexpr function">;
>  def note_constexpr_virtual_call : Note<
> @@ -141,6 +144,8 @@ def note_constexpr_calls_suppressed : No
>    "(skipping %0 call%s0 in backtrace; use -fconstexpr-backtrace-limit=0
> to "
>    "see all)">;
>  def note_constexpr_call_here : Note<"in call to '%0'">;
> +def note_constexpr_inherited_ctor_call_here : Note<
> +  "in implicit initialization for inherited constructor of %0">;
>  def note_constexpr_baa_insufficient_alignment : Note<
>    "%select{alignment of|offset of the aligned pointer from}0 the base
> pointee "
>    "object (%1 %plural{1:byte|:bytes}1) is %select{less than|not a
> multiple of}0 the "
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/
> DiagnosticSemaKinds.td?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jun 28
> 14:03:57 2016
> @@ -381,22 +381,12 @@ def err_using_decl_nested_name_specifier
>    "using declaration refers into '%0', which is not a base class of %1">;
>  def err_using_decl_constructor_not_in_direct_base : Error<
>    "%0 is not a direct base of %1, cannot inherit constructors">;
> -def err_using_decl_constructor_conflict : Error<
> -  "cannot inherit constructor, already inherited constructor with "
> -  "the same signature">;
> -def note_using_decl_constructor_conflict_current_ctor : Note<
> -  "conflicting constructor">;
> -def note_using_decl_constructor_conflict_previous_ctor : Note<
> -  "previous constructor">;
> -def note_using_decl_constructor_conflict_previous_using : Note<
> -  "previously inherited here">;
> -def warn_using_decl_constructor_ellipsis : Warning<
> -  "inheriting constructor does not inherit ellipsis">,
> -  InGroup<DiagGroup<"inherited-variadic-ctor">>;
> -def note_using_decl_constructor_ellipsis : Note<
> -  "constructor declared with ellipsis here">;
>  def err_using_decl_can_not_refer_to_class_member : Error<
>    "using declaration cannot refer to class member">;
> +def err_ambiguous_inherited_constructor : Error<
> +  "constructor of %0 inherited from multiple base class subobjects">;
> +def note_ambiguous_inherited_constructor_using : Note<
> +  "inherited from base class %0 here">;
>  def note_using_decl_class_member_workaround : Note<
>    "use %select{an alias declaration|a typedef declaration|a reference|"
>    "a const variable|a constexpr variable}0 instead">;
> @@ -415,7 +405,7 @@ def err_using_decl_template_id : Error<
>    "using declaration cannot refer to a template specialization">;
>  def note_using_decl_target : Note<"target of using declaration">;
>  def note_using_decl_conflict : Note<"conflicting declaration">;
> -def err_using_decl_redeclaration : Error<"redeclaration of using decl">;
> +def err_using_decl_redeclaration : Error<"redeclaration of using
> declaration">;
>  def err_using_decl_conflict : Error<
>    "target of using declaration conflicts with declaration already in
> scope">;
>  def err_using_decl_conflict_reverse : Error<
> @@ -1436,11 +1426,13 @@ def note_member_synthesized_at : Note<
>    "assignment operator|move assignment operator|destructor}0 for %1 first
> "
>    "required here">;
>  def note_inhctor_synthesized_at : Note<
> -  "inheriting constructor for %0 first required here">;
> +  "inherited constructor for %0 first required here">;
>  def err_missing_default_ctor : Error<
> -  "%select{|implicit default |inheriting }0constructor for %1 must
> explicitly "
> -  "initialize the %select{base class|member}2 %3 which does not have a
> default "
> -  "constructor">;
> +  "%select{constructor for %1 must explicitly initialize the|"
> +  "implicit default constructor for %1 must explicitly initialize the|"
> +  "cannot use constructor inherited from base class %4;}0 "
> +  "%select{base class|member}2 %3 %select{which|which|of %1}0 "
> +  "does not have a default constructor">;
>  def note_due_to_dllexported_class : Note<
>    "due to '%0' being dllexported%select{|; try compiling in C++11
> mode}1">;
>
> @@ -3111,7 +3103,9 @@ def err_uninitialized_member_for_assign
>    "non-static %select{reference|const}1 member %2 cannot use copy "
>    "assignment operator">;
>  def err_uninitialized_member_in_ctor : Error<
> -  "%select{|implicit default |inheriting }0constructor for %1 must
> explicitly "
> +  "%select{constructor for %1|"
> +  "implicit default constructor for %1|"
> +  "cannot use constructor inherited from %1:}0 must explicitly "
>    "initialize the %select{reference|const}2 member %3">;
>  def err_default_arg_makes_ctor_special : Error<
>    "addition of default argument on redeclaration makes this constructor a
> "
> @@ -3160,7 +3154,8 @@ def note_ovl_candidate : Note<"candidate
>      "is the implicit move constructor|"
>      "is the implicit copy assignment operator|"
>      "is the implicit move assignment operator|"
> -    "is an inherited constructor}0%1"
> +    "inherited constructor|"
> +    "inherited constructor }0%1"
>      "%select{| has different class%diff{ (expected $ but has $)|}3,4"
>      "| has different number of parameters (expected %3 but has %4)"
>      "| has type mismatch at %ordinal3 parameter"
> @@ -3172,7 +3167,8 @@ def note_ovl_candidate : Note<"candidate
>      "%select{none|const|restrict|const and restrict|volatile|const and
> volatile"
>      "|volatile and restrict|const, volatile, and restrict}4)}2">;
>
> -def note_ovl_candidate_inherited_constructor : Note<"inherited from
> here">;
> +def note_ovl_candidate_inherited_constructor : Note<
> +    "constructor from base class %0 inherited here">;
>  def note_ovl_candidate_illegal_constructor : Note<
>      "candidate %select{constructor|template}0 ignored: "
>      "instantiation %select{takes|would take}0 its own class type by
> value">;
> @@ -3232,7 +3228,8 @@ def note_ovl_candidate_arity : Note<"can
>      "constructor (the implicit move constructor)|"
>      "function (the implicit copy assignment operator)|"
>      "function (the implicit move assignment operator)|"
> -    "constructor (inherited)}0 %select{|template }1"
> +    "inherited constructor|"
> +    "inherited constructor}0 %select{|template }1"
>      "not viable: requires%select{ at least| at most|}2 %3 argument%s3,
> but %4 "
>      "%plural{1:was|:were}4 provided">;
>
> @@ -3243,7 +3240,8 @@ def note_ovl_candidate_arity_one : Note<
>      "constructor (the implicit move constructor)|"
>      "function (the implicit copy assignment operator)|"
>      "function (the implicit move assignment operator)|"
> -    "constructor (inherited)}0 %select{|template }1not viable: "
> +    "inherited constructor|"
> +    "inherited constructor}0 %select{|template }1not viable: "
>      "%select{requires at least|allows at most single|requires single}2 "
>      "argument %3, but %plural{0:no|:%4}4 arguments were provided">;
>
> @@ -3255,7 +3253,8 @@ def note_ovl_candidate_deleted : Note<
>      "constructor (the implicit move constructor)|"
>      "function (the implicit copy assignment operator)|"
>      "function (the implicit move assignment operator)|"
> -    "constructor (inherited)}0%1 has been "
> +    "inherited constructor|"
> +    "inherited constructor }0%1 has been "
>      "%select{explicitly made unavailable|explicitly deleted|"
>      "implicitly deleted}2">;
>
> @@ -3272,7 +3271,8 @@ def note_ovl_candidate_bad_conv_incomple
>      "constructor (the implicit move constructor)|"
>      "function (the implicit copy assignment operator)|"
>      "function (the implicit move assignment operator)|"
> -    "constructor (inherited)}0%1 "
> +    "inherited constructor|"
> +    "inherited constructor }0%1 "
>      "not viable: cannot convert argument of incomplete type "
>      "%diff{$ to $|to parameter type}2,3 for "
>      "%select{%ordinal5 argument|object argument}4"
> @@ -3288,7 +3288,8 @@ def note_ovl_candidate_bad_list_argument
>      "constructor (the implicit move constructor)|"
>      "function (the implicit copy assignment operator)|"
>      "function (the implicit move assignment operator)|"
> -    "constructor (inherited)}0%1 "
> +    "inherited constructor|"
> +    "inherited constructor }0%1 "
>      "not viable: cannot convert initializer list argument to %3">;
>  def note_ovl_candidate_bad_overload : Note<"candidate "
>      "%select{function|function|constructor|"
> @@ -3298,7 +3299,8 @@ def note_ovl_candidate_bad_overload : No
>      "constructor (the implicit move constructor)|"
>      "function (the implicit copy assignment operator)|"
>      "function (the implicit move assignment operator)|"
> -    "constructor (inherited)}0%1"
> +    "inherited constructor|"
> +    "inherited constructor }0%1"
>      " not viable: no overload of %3 matching %2 for %ordinal4 argument">;
>  def note_ovl_candidate_bad_conv : Note<"candidate "
>      "%select{function|function|constructor|"
> @@ -3308,7 +3310,8 @@ def note_ovl_candidate_bad_conv : Note<"
>      "constructor (the implicit move constructor)|"
>      "function (the implicit copy assignment operator)|"
>      "function (the implicit move assignment operator)|"
> -    "constructor (inherited)}0%1"
> +    "inherited constructor|"
> +    "inherited constructor }0%1"
>      " not viable: no known conversion "
>      "%diff{from $ to $|from argument type to parameter type}2,3 for "
>      "%select{%ordinal5 argument|object argument}4"
> @@ -3324,7 +3327,8 @@ def note_ovl_candidate_bad_arc_conv : No
>      "constructor (the implicit move constructor)|"
>      "function (the implicit copy assignment operator)|"
>      "function (the implicit move assignment operator)|"
> -    "constructor (inherited)}0%1"
> +    "inherited constructor|"
> +    "inherited constructor }0%1"
>      " not viable: cannot implicitly convert argument "
>      "%diff{of type $ to $|type to parameter type}2,3 for "
>      "%select{%ordinal5 argument|object argument}4 under ARC">;
> @@ -3336,7 +3340,8 @@ def note_ovl_candidate_bad_lvalue : Note
>      "constructor (the implicit move constructor)|"
>      "function (the implicit copy assignment operator)|"
>      "function (the implicit move assignment operator)|"
> -    "constructor (inherited)}0%1"
> +    "inherited constructor|"
> +    "inherited constructor }0%1"
>      " not viable: expects an l-value for "
>      "%select{%ordinal3 argument|object argument}2">;
>  def note_ovl_candidate_bad_addrspace : Note<"candidate "
> @@ -3347,7 +3352,8 @@ def note_ovl_candidate_bad_addrspace : N
>      "constructor (the implicit move constructor)|"
>      "function (the implicit copy assignment operator)|"
>      "function (the implicit move assignment operator)|"
> -    "constructor (inherited)}0%1 not viable: "
> +    "inherited constructor|"
> +    "inherited constructor }0%1 not viable: "
>      "%select{%ordinal6|'this'}5 argument (%2) is in "
>      "address space %3, but parameter must be in address space %4">;
>  def note_ovl_candidate_bad_gc : Note<"candidate "
> @@ -3358,7 +3364,8 @@ def note_ovl_candidate_bad_gc : Note<"ca
>      "constructor (the implicit move constructor)|"
>      "function (the implicit copy assignment operator)|"
>      "function (the implicit move assignment operator)|"
> -    "constructor (inherited)}0%1 not viable: "
> +    "inherited constructor|"
> +    "inherited constructor }0%1 not viable: "
>      "%select{%ordinal6|'this'}5 argument (%2) has
> %select{no|__weak|__strong}3 "
>      "ownership, but parameter has %select{no|__weak|__strong}4
> ownership">;
>  def note_ovl_candidate_bad_ownership : Note<"candidate "
> @@ -3369,7 +3376,8 @@ def note_ovl_candidate_bad_ownership : N
>      "constructor (the implicit move constructor)|"
>      "function (the implicit copy assignment operator)|"
>      "function (the implicit move assignment operator)|"
> -    "constructor (inherited)}0%1 not viable: "
> +    "inherited constructor|"
> +    "inherited constructor }0%1 not viable: "
>      "%select{%ordinal6|'this'}5 argument (%2) has "
>      "%select{no|__unsafe_unretained|__strong|__weak|__autoreleasing}3
> ownership,"
>      " but parameter has %select{no|__unsafe_unretained|__strong|__weak|"
> @@ -3377,7 +3385,7 @@ def note_ovl_candidate_bad_ownership : N
>  def note_ovl_candidate_bad_cvr_this : Note<"candidate "
>      "%select{|function|||function|||||"
>      "function (the implicit copy assignment operator)|"
> -    "function (the implicit move assignment operator)|}0 not viable: "
> +    "function (the implicit move assignment operator)||}0 not viable: "
>      "'this' argument has type %2, but method is not marked "
>      "%select{const|restrict|const or restrict|volatile|const or volatile|"
>      "volatile or restrict|const, volatile, or restrict}3">;
> @@ -3389,7 +3397,8 @@ def note_ovl_candidate_bad_cvr : Note<"c
>      "constructor (the implicit move constructor)|"
>      "function (the implicit copy assignment operator)|"
>      "function (the implicit move assignment operator)|"
> -    "constructor (inherited)}0%1 not viable: "
> +    "inherited constructor|"
> +    "inherited constructor }0%1 not viable: "
>      "%ordinal4 argument (%2) would lose "
>      "%select{const|restrict|const and restrict|volatile|const and
> volatile|"
>      "volatile and restrict|const, volatile, and restrict}3 qualifier"
> @@ -3402,7 +3411,8 @@ def note_ovl_candidate_bad_unaligned : N
>      "constructor (the implicit move constructor)|"
>      "function (the implicit copy assignment operator)|"
>      "function (the implicit move assignment operator)|"
> -    "constructor (inherited)}0%1 not viable: "
> +    "inherited constructor|"
> +    "inherited constructor }0%1 not viable: "
>      "%ordinal4 argument (%2) would lose __unaligned qualifier">;
>  def note_ovl_candidate_bad_base_to_derived_conv : Note<"candidate "
>      "%select{function|function|constructor|"
> @@ -3412,20 +3422,23 @@ def note_ovl_candidate_bad_base_to_deriv
>      "constructor (the implicit move constructor)|"
>      "function (the implicit copy assignment operator)|"
>      "function (the implicit move assignment operator)|"
> -    "constructor (inherited)}0%1"
> -    " not viable: cannot %select{convert from|convert from|bind}2 "
> +    "inherited constructor|"
> +    "inherited constructor }0%1 not viable: "
> +    "cannot %select{convert from|convert from|bind}2 "
>      "%select{base class pointer|superclass|base class object of type}2 %3
> to "
>      "%select{derived class pointer|subclass|derived class reference}2 %4
> for "
>      "%ordinal5 argument">;
>  def note_ovl_candidate_bad_target : Note<
>      "candidate %select{function|function|constructor|"
> -    "function |function |constructor |"
> +    "function|function|constructor|"
>      "constructor (the implicit default constructor)|"
>      "constructor (the implicit copy constructor)|"
>      "constructor (the implicit move constructor)|"
>      "function (the implicit copy assignment operator)|"
>      "function (the implicit move assignment operator)|"
> -    "constructor (inherited)}0 not viable: call to "
> +    "inherited constructor|"
> +    "inherited constructor}0 not viable: "
> +    "call to "
>      "%select{__device__|__global__|__host__|__host__
> __device__|invalid}1 function from"
>      " %select{__device__|__global__|__host__|__host__
> __device__|invalid}2 function">;
>  def note_implicit_member_target_infer_collision : Note<
> @@ -4237,8 +4250,6 @@ def note_implicitly_deleted : Note<
>    "explicitly defaulted function was implicitly deleted here">;
>  def note_inherited_deleted_here : Note<
>    "deleted constructor was inherited here">;
> -def note_cannot_inherit : Note<
> -  "constructor cannot be inherited">;
>  def warn_not_enough_argument : Warning<
>    "not enough variable arguments in %0 declaration to fit a sentinel">,
>    InGroup<Sentinel>;
>
> Modified: cfe/trunk/include/clang/Basic/StmtNodes.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/Basic/StmtNodes.td?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Basic/StmtNodes.td (original)
> +++ cfe/trunk/include/clang/Basic/StmtNodes.td Tue Jun 28 14:03:57 2016
> @@ -126,6 +126,7 @@ def ArrayTypeTraitExpr : DStmt<Expr>;
>  def ExpressionTraitExpr : DStmt<Expr>;
>  def DependentScopeDeclRefExpr : DStmt<Expr>;
>  def CXXConstructExpr : DStmt<Expr>;
> +def CXXInheritedCtorInitExpr : DStmt<Expr>;
>  def CXXBindTemporaryExpr : DStmt<Expr>;
>  def ExprWithCleanups : DStmt<Expr>;
>  def CXXTemporaryObjectExpr : DStmt<CXXConstructExpr>;
>
> Modified: cfe/trunk/include/clang/Sema/Overload.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/Sema/Overload.h?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Sema/Overload.h (original)
> +++ cfe/trunk/include/clang/Sema/Overload.h Tue Jun 28 14:03:57 2016
> @@ -803,6 +803,7 @@ namespace clang {
>      DeclAccessPair FoundDecl;
>      CXXConstructorDecl *Constructor;
>      FunctionTemplateDecl *ConstructorTmpl;
> +    explicit operator bool() const { return Constructor; }
>    };
>    // FIXME: Add an AddOverloadCandidate / AddTemplateOverloadCandidate
> overload
>    // that takes one of these.
> @@ -818,7 +819,7 @@ namespace clang {
>      Info.ConstructorTmpl = dyn_cast<FunctionTemplateDecl>(D);
>      if (Info.ConstructorTmpl)
>        D = Info.ConstructorTmpl->getTemplatedDecl();
> -    Info.Constructor = cast<CXXConstructorDecl>(D);
> +    Info.Constructor = dyn_cast<CXXConstructorDecl>(D);
>      return Info;
>    }
>  } // end namespace clang
>
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/Sema/Sema.h?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Tue Jun 28 14:03:57 2016
> @@ -4256,6 +4256,13 @@ public:
>
>    bool CheckInheritingConstructorUsingDecl(UsingDecl *UD);
>
> +  /// Given a derived-class using shadow declaration for a constructor
> and the
> +  /// correspnding base class constructor, find or create the implicit
> +  /// synthesized derived class constructor to use for this
> initialization.
> +  CXXConstructorDecl *
> +  findInheritingConstructor(SourceLocation Loc, CXXConstructorDecl
> *BaseCtor,
> +                            ConstructorUsingShadowDecl *DerivedShadow);
> +
>    Decl *ActOnUsingDeclaration(Scope *CurScope,
>                                AccessSpecifier AS,
>                                bool HasUsingKeyword,
> @@ -4422,7 +4429,8 @@ public:
>    /// \brief Determine what sort of exception specification an inheriting
>    /// constructor of a class will have.
>    ImplicitExceptionSpecification
> -  ComputeInheritingCtorExceptionSpec(CXXConstructorDecl *CD);
> +  ComputeInheritingCtorExceptionSpec(SourceLocation Loc,
> +                                     CXXConstructorDecl *CD);
>
>    /// \brief Evaluate the implicit exception specification for a defaulted
>    /// special member function.
> @@ -4491,12 +4499,6 @@ public:
>    void AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl,
>                                       CXXDestructorDecl *Destructor);
>
> -  /// \brief Declare all inheriting constructors for the given class.
> -  ///
> -  /// \param ClassDecl The class declaration into which the inheriting
> -  /// constructors will be added.
> -  void DeclareInheritingConstructors(CXXRecordDecl *ClassDecl);
> -
>    /// \brief Define the specified inheriting constructor.
>    void DefineInheritingConstructor(SourceLocation UseLoc,
>                                     CXXConstructorDecl *Constructor);
> @@ -5562,13 +5564,13 @@ public:
>                                       bool Diagnose = true);
>    AccessResult CheckConstructorAccess(SourceLocation Loc,
>                                        CXXConstructorDecl *D,
> +                                      DeclAccessPair FoundDecl,
>                                        const InitializedEntity &Entity,
> -                                      AccessSpecifier Access,
>                                        bool IsCopyBindingRefToTemp =
> false);
>    AccessResult CheckConstructorAccess(SourceLocation Loc,
>                                        CXXConstructorDecl *D,
> +                                      DeclAccessPair FoundDecl,
>                                        const InitializedEntity &Entity,
> -                                      AccessSpecifier Access,
>                                        const PartialDiagnostic &PDiag);
>    AccessResult CheckDestructorAccess(SourceLocation Loc,
>                                       CXXDestructorDecl *Dtor,
>
> Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/Serialization/ASTBitCodes.h?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
> +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Tue Jun 28
> 14:03:57 2016
> @@ -1083,6 +1083,8 @@ namespace clang {
>        DECL_USING,
>        /// \brief A UsingShadowDecl record.
>        DECL_USING_SHADOW,
> +      /// \brief A ConstructorUsingShadowDecl record.
> +      DECL_CONSTRUCTOR_USING_SHADOW,
>        /// \brief A UsingDirecitveDecl record.
>        DECL_USING_DIRECTIVE,
>        /// \brief An UnresolvedUsingValueDecl record.
> @@ -1097,6 +1099,8 @@ namespace clang {
>        DECL_CXX_METHOD,
>        /// \brief A CXXConstructorDecl record.
>        DECL_CXX_CONSTRUCTOR,
> +      /// \brief A CXXConstructorDecl record for an inherited constructor.
> +      DECL_CXX_INHERITED_CONSTRUCTOR,
>        /// \brief A CXXDestructorDecl record.
>        DECL_CXX_DESTRUCTOR,
>        /// \brief A CXXConversionDecl record.
> @@ -1360,6 +1364,8 @@ namespace clang {
>        EXPR_CXX_MEMBER_CALL,
>        /// \brief A CXXConstructExpr record.
>        EXPR_CXX_CONSTRUCT,
> +      /// \brief A CXXInheritedCtorInitExpr record.
> +      EXPR_CXX_INHERITED_CTOR_INIT,
>        /// \brief A CXXTemporaryObjectExpr record.
>        EXPR_CXX_TEMPORARY_OBJECT,
>        /// \brief A CXXStaticCastExpr record.
>
> Modified: cfe/trunk/lib/AST/ASTDumper.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
> ASTDumper.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/AST/ASTDumper.cpp (original)
> +++ cfe/trunk/lib/AST/ASTDumper.cpp Tue Jun 28 14:03:57 2016
> @@ -474,6 +474,7 @@ namespace  {
>      void VisitUnresolvedUsingTypenameDecl(const
> UnresolvedUsingTypenameDecl *D);
>      void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl
> *D);
>      void VisitUsingShadowDecl(const UsingShadowDecl *D);
> +    void VisitConstructorUsingShadowDecl(const
> ConstructorUsingShadowDecl *D);
>      void VisitLinkageSpecDecl(const LinkageSpecDecl *D);
>      void VisitAccessSpecDecl(const AccessSpecDecl *D);
>      void VisitFriendDecl(const FriendDecl *D);
> @@ -713,6 +714,12 @@ void ASTDumper::dumpTypeAsChild(const Ty
>  }
>
>  void ASTDumper::dumpBareDeclRef(const Decl *D) {
> +  if (!D) {
> +    ColorScope Color(*this, NullColor);
> +    OS << "<<<NULL>>>";
> +    return;
> +  }
> +
>    {
>      ColorScope Color(*this, DeclKindNameColor);
>      OS << D->getDeclKindName();
> @@ -1491,6 +1498,31 @@ void ASTDumper::VisitUsingShadowDecl(con
>      dumpTypeAsChild(TD->getTypeForDecl());
>  }
>
> +void ASTDumper::VisitConstructorUsingShadowDecl(
> +    const ConstructorUsingShadowDecl *D) {
> +  if (D->constructsVirtualBase())
> +    OS << " virtual";
> +
> +  dumpChild([=] {
> +    OS << "target ";
> +    dumpBareDeclRef(D->getTargetDecl());
> +  });
> +
> +  dumpChild([=] {
> +    OS << "nominated ";
> +    dumpBareDeclRef(D->getNominatedBaseClass());
> +    OS << ' ';
> +    dumpBareDeclRef(D->getNominatedBaseClassShadowDecl());
> +  });
> +
> +  dumpChild([=] {
> +    OS << "constructed ";
> +    dumpBareDeclRef(D->getConstructedBaseClass());
> +    OS << ' ';
> +    dumpBareDeclRef(D->getConstructedBaseClassShadowDecl());
> +  });
> +}
> +
>  void ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
>    switch (D->getLanguage()) {
>    case LinkageSpecDecl::lang_c: OS << " C"; break;
>
> Modified: cfe/trunk/lib/AST/DeclBase.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
> DeclBase.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/AST/DeclBase.cpp (original)
> +++ cfe/trunk/lib/AST/DeclBase.cpp Tue Jun 28 14:03:57 2016
> @@ -594,6 +594,7 @@ unsigned Decl::getIdentifierNamespaceFor
>      case Function:
>      case CXXMethod:
>      case CXXConstructor:
> +    case ConstructorUsingShadow:
>      case CXXDestructor:
>      case CXXConversion:
>      case EnumConstant:
>
> Modified: cfe/trunk/lib/AST/DeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
> DeclCXX.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/AST/DeclCXX.cpp (original)
> +++ cfe/trunk/lib/AST/DeclCXX.cpp Tue Jun 28 14:03:57 2016
> @@ -448,6 +448,15 @@ void CXXRecordDecl::addedMember(Decl *D)
>    FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D);
>    if (FunTmpl)
>      D = FunTmpl->getTemplatedDecl();
> +
> +  // FIXME: Pass NamedDecl* to addedMember?
> +  Decl *DUnderlying = D;
> +  if (auto *ND = dyn_cast<NamedDecl>(DUnderlying)) {
> +    DUnderlying = ND->getUnderlyingDecl();
> +    if (FunctionTemplateDecl *UnderlyingFunTmpl =
> +            dyn_cast<FunctionTemplateDecl>(DUnderlying))
> +      DUnderlying = UnderlyingFunTmpl->getTemplatedDecl();
> +  }
>
>    if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
>      if (Method->isVirtual()) {
> @@ -503,15 +512,10 @@ void CXXRecordDecl::addedMember(Decl *D)
>        data().PlainOldData = false;
>      }
>
> -    // Technically, "user-provided" is only defined for special member
> -    // functions, but the intent of the standard is clearly that it
> should apply
> -    // to all functions.
> -    bool UserProvided = Constructor->isUserProvided();
> -
>      if (Constructor->isDefaultConstructor()) {
>        SMKind |= SMF_DefaultConstructor;
>
> -      if (UserProvided)
> +      if (Constructor->isUserProvided())
>          data().UserProvidedDefaultConstructor = true;
>        if (Constructor->isConstexpr())
>          data().HasConstexprDefaultConstructor = true;
> @@ -529,9 +533,17 @@ void CXXRecordDecl::addedMember(Decl *D)
>        } else if (Constructor->isMoveConstructor())
>          SMKind |= SMF_MoveConstructor;
>      }
> +  }
>
> +  // Handle constructors, including those inherited from base classes.
> +  if (CXXConstructorDecl *Constructor =
> +          dyn_cast<CXXConstructorDecl>(DUnderlying)) {
>      // Record if we see any constexpr constructors which are neither copy
>      // nor move constructors.
> +    // C++1z [basic.types]p10:
> +    //   [...] has at least one constexpr constructor or constructor
> template
> +    //   (possibly inherited from a base class) that is not a copy or move
> +    //   constructor [...]
>      if (Constructor->isConstexpr() && !Constructor->
> isCopyOrMoveConstructor())
>        data().HasConstexprNonCopyMoveConstructor = true;
>
> @@ -541,8 +553,12 @@ void CXXRecordDecl::addedMember(Decl *D)
>      // C++11 [dcl.init.aggr]p1:
>      //   An aggregate is an array or a class with no user-provided
>      //   constructors [...].
> +    // C++11 [dcl.init.aggr]p1:
> +    //   An aggregate is an array or a class with no user-provided
> +    //   constructors (including those inherited from a base class) [...].
>      if (getASTContext().getLangOpts().CPlusPlus11
> -          ? UserProvided : !Constructor->isImplicit())
> +            ? Constructor->isUserProvided()
> +            : !Constructor->isImplicit())
>        data().Aggregate = false;
>    }
>
> @@ -1784,11 +1800,15 @@ SourceRange CXXCtorInitializer::getSourc
>
>  void CXXConstructorDecl::anchor() { }
>
> -CXXConstructorDecl *
> -CXXConstructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
> -  return new (C, ID) CXXConstructorDecl(C, nullptr, SourceLocation(),
> -                                        DeclarationNameInfo(), QualType(),
> -                                        nullptr, false, false, false,
> false);
> +CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C,
> +                                                           unsigned ID,
> +                                                           bool
> Inherited) {
> +  unsigned Extra = additionalSizeToAlloc<InheritedConstructor>(
> Inherited);
> +  auto *Result = new (C, ID, Extra) CXXConstructorDecl(
> +      C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(),
> nullptr,
> +      false, false, false, false, InheritedConstructor());
> +  Result->IsInheritingConstructor = Inherited;
> +  return Result;
>  }
>
>  CXXConstructorDecl *
> @@ -1797,13 +1817,16 @@ CXXConstructorDecl::Create(ASTContext &C
>                             const DeclarationNameInfo &NameInfo,
>                             QualType T, TypeSourceInfo *TInfo,
>                             bool isExplicit, bool isInline,
> -                           bool isImplicitlyDeclared, bool isConstexpr) {
> +                           bool isImplicitlyDeclared, bool isConstexpr,
> +                           InheritedConstructor Inherited) {
>    assert(NameInfo.getName().getNameKind()
>           == DeclarationName::CXXConstructorName &&
>           "Name must refer to a constructor");
> -  return new (C, RD) CXXConstructorDecl(C, RD, StartLoc, NameInfo, T,
> TInfo,
> -                                        isExplicit, isInline,
> -                                        isImplicitlyDeclared,
> isConstexpr);
> +  unsigned Extra =
> +      additionalSizeToAlloc<InheritedConstructor>(Inherited ? 1 : 0);
> +  return new (C, RD, Extra) CXXConstructorDecl(
> +      C, RD, StartLoc, NameInfo, T, TInfo, isExplicit, isInline,
> +      isImplicitlyDeclared, isConstexpr, Inherited);
>  }
>
>  CXXConstructorDecl::init_const_iterator CXXConstructorDecl::init_begin()
> const {
> @@ -1918,23 +1941,6 @@ bool CXXConstructorDecl::isSpecializatio
>    return true;
>  }
>
> -const CXXConstructorDecl *CXXConstructorDecl::getInheritedConstructor()
> const {
> -  // Hack: we store the inherited constructor in the overridden method
> table
> -  method_iterator It = getASTContext().overridden_methods_begin(this);
> -  if (It == getASTContext().overridden_methods_end(this))
> -    return nullptr;
> -
> -  return cast<CXXConstructorDecl>(*It);
> -}
> -
> -void
> -CXXConstructorDecl::setInheritedConstructor(const CXXConstructorDecl
> *BaseCtor){
> -  // Hack: we store the inherited constructor in the overridden method
> table
> -  assert(getASTContext().overridden_methods_size(this) == 0 &&
> -         "Base ctor already set.");
> -  getASTContext().addOverriddenMethod(this, BaseCtor);
> -}
> -
>  void CXXDestructorDecl::anchor() { }
>
>  CXXDestructorDecl *
> @@ -2130,10 +2136,24 @@ NamespaceAliasDecl::CreateDeserialized(A
>
>  void UsingShadowDecl::anchor() { }
>
> +UsingShadowDecl::UsingShadowDecl(Kind K, ASTContext &C, DeclContext *DC,
> +                                 SourceLocation Loc, UsingDecl *Using,
> +                                 NamedDecl *Target)
> +    : NamedDecl(K, DC, Loc, Using ? Using->getDeclName() :
> DeclarationName()),
> +      redeclarable_base(C), Underlying(Target),
> +      UsingOrNextShadow(cast<NamedDecl>(Using)) {
> +  if (Target)
> +    IdentifierNamespace = Target->getIdentifierNamespace();
> +  setImplicit();
> +}
> +
> +UsingShadowDecl::UsingShadowDecl(Kind K, ASTContext &C, EmptyShell Empty)
> +    : NamedDecl(K, nullptr, SourceLocation(), DeclarationName()),
> +      redeclarable_base(C), Underlying(), UsingOrNextShadow() {}
> +
>  UsingShadowDecl *
>  UsingShadowDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
> -  return new (C, ID) UsingShadowDecl(C, nullptr, SourceLocation(),
> -                                     nullptr, nullptr);
> +  return new (C, ID) UsingShadowDecl(UsingShadow, C, EmptyShell());
>  }
>
>  UsingDecl *UsingShadowDecl::getUsingDecl() const {
> @@ -2144,6 +2164,25 @@ UsingDecl *UsingShadowDecl::getUsingDecl
>    return cast<UsingDecl>(Shadow->UsingOrNextShadow);
>  }
>
> +void ConstructorUsingShadowDecl::anchor() { }
> +
> +ConstructorUsingShadowDecl *
> +ConstructorUsingShadowDecl::Create(ASTContext &C, DeclContext *DC,
> +                                   SourceLocation Loc, UsingDecl *Using,
> +                                   NamedDecl *Target, bool IsVirtual) {
> +  return new (C, DC) ConstructorUsingShadowDecl(C, DC, Loc, Using, Target,
> +                                                IsVirtual);
> +}
> +
> +ConstructorUsingShadowDecl *
> +ConstructorUsingShadowDecl::CreateDeserialized(ASTContext &C, unsigned
> ID) {
> +  return new (C, ID) ConstructorUsingShadowDecl(C, EmptyShell());
> +}
> +
> +CXXRecordDecl *ConstructorUsingShadowDecl::getNominatedBaseClass() const
> {
> +  return getUsingDecl()->getQualifier()->getAsRecordDecl();
> +}
> +
>  void UsingDecl::anchor() { }
>
>  void UsingDecl::addShadowDecl(UsingShadowDecl *S) {
>
> Modified: cfe/trunk/lib/AST/Expr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
> Expr.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/AST/Expr.cpp (original)
> +++ cfe/trunk/lib/AST/Expr.cpp Tue Jun 28 14:03:57 2016
> @@ -3008,6 +3008,13 @@ bool Expr::HasSideEffects(const ASTConte
>      break;
>    }
>
> +  case CXXInheritedCtorInitExprClass: {
> +    const auto *ICIE = cast<CXXInheritedCtorInitExpr>(this);
> +    if (!ICIE->getConstructor()->isTrivial() && IncludePossibleEffects)
> +      return true;
> +    break;
> +  }
> +
>    case LambdaExprClass: {
>      const LambdaExpr *LE = cast<LambdaExpr>(this);
>      for (LambdaExpr::capture_iterator I = LE->capture_begin(),
>
> Modified: cfe/trunk/lib/AST/ExprClassification.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
> ExprClassification.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/AST/ExprClassification.cpp (original)
> +++ cfe/trunk/lib/AST/ExprClassification.cpp Tue Jun 28 14:03:57 2016
> @@ -360,6 +360,7 @@ static Cl::Kinds ClassifyInternal(ASTCon
>
>      // Some C++ expressions are always class temporaries.
>    case Expr::CXXConstructExprClass:
> +  case Expr::CXXInheritedCtorInitExprClass:
>    case Expr::CXXTemporaryObjectExprClass:
>    case Expr::LambdaExprClass:
>    case Expr::CXXStdInitializerListExprClass:
>
> Modified: cfe/trunk/lib/AST/ExprConstant.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
> ExprConstant.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/AST/ExprConstant.cpp (original)
> +++ cfe/trunk/lib/AST/ExprConstant.cpp Tue Jun 28 14:03:57 2016
> @@ -997,6 +997,16 @@ void EvalInfo::addCallStack(unsigned Lim
>        continue;
>      }
>
> +    // Use a different note for an inheriting constructor, because from
> the
> +    // user's perspective it's not really a function at all.
> +    if (auto *CD = dyn_cast_or_null<CXXConstructorDecl>(Frame->Callee)) {
> +      if (CD->isInheritingConstructor()) {
> +        addDiag(Frame->CallLoc, diag::note_constexpr_
> inherited_ctor_call_here)
> +          << CD->getParent();
> +        continue;
> +      }
> +    }
> +
>      SmallVector<char, 128> Buffer;
>      llvm::raw_svector_ostream Out(Buffer);
>      describeCall(Frame, Out);
> @@ -3845,11 +3855,25 @@ static bool CheckConstexprFunction(EvalI
>
>    if (Info.getLangOpts().CPlusPlus11) {
>      const FunctionDecl *DiagDecl = Definition ? Definition : Declaration;
> -    // FIXME: If DiagDecl is an implicitly-declared special member
> function, we
> -    // should be much more explicit about why it's not constexpr.
> -    Info.Diag(CallLoc, diag::note_constexpr_invalid_function, 1)
> -      << DiagDecl->isConstexpr() << isa<CXXConstructorDecl>(DiagDecl)
> -      << DiagDecl;
> +
> +    // If this function is not constexpr because it is an inherited
> +    // non-constexpr constructor, diagnose that directly.
> +    auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
> +    if (CD && CD->isInheritingConstructor()) {
> +      auto *Inherited = CD->getInheritedConstructor().getConstructor();
> +      if (!Inherited->isConstexpr())
> +        DiagDecl = CD = Inherited;
> +    }
> +
> +    // FIXME: If DiagDecl is an implicitly-declared special member
> function
> +    // or an inheriting constructor, we should be much more explicit
> about why
> +    // it's not constexpr.
> +    if (CD && CD->isInheritingConstructor())
> +      Info.Diag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
> +        << CD->getInheritedConstructor().getConstructor()->getParent();
> +    else
> +      Info.Diag(CallLoc, diag::note_constexpr_invalid_function, 1)
> +        << DiagDecl->isConstexpr() << (bool)CD << DiagDecl;
>      Info.Note(DiagDecl->getLocation(), diag::note_declared_at);
>    } else {
>      Info.Diag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
> @@ -3945,14 +3969,11 @@ static bool HandleFunctionCall(SourceLoc
>  }
>
>  /// Evaluate a constructor call.
> -static bool HandleConstructorCall(SourceLocation CallLoc, const LValue
> &This,
> -                                  ArrayRef<const Expr*> Args,
> +static bool HandleConstructorCall(const Expr *E, const LValue &This,
> +                                  APValue *ArgValues,
>                                    const CXXConstructorDecl *Definition,
>                                    EvalInfo &Info, APValue &Result) {
> -  ArgVector ArgValues(Args.size());
> -  if (!EvaluateArgs(Args, ArgValues, Info))
> -    return false;
> -
> +  SourceLocation CallLoc = E->getExprLoc();
>    if (!Info.CheckCallLimit(CallLoc))
>      return false;
>
> @@ -3962,14 +3983,14 @@ static bool HandleConstructorCall(Source
>      return false;
>    }
>
> -  CallStackFrame Frame(Info, CallLoc, Definition, &This,
> ArgValues.data());
> +  CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues);
>
>    // FIXME: Creating an APValue just to hold a nonexistent return value is
>    // wasteful.
>    APValue RetVal;
>    StmtResult Ret = {RetVal, nullptr};
>
> -  // If it's a delegating constructor, just delegate.
> +  // If it's a delegating constructor, delegate.
>    if (Definition->isDelegatingConstructor()) {
>      CXXConstructorDecl::init_const_iterator I = Definition->init_begin();
>      {
> @@ -3993,8 +4014,9 @@ static bool HandleConstructorCall(Source
>         (Definition->isTrivial() && hasFields(Definition->getParent()))))
> {
>      LValue RHS;
>      RHS.setFrom(Info.Ctx, ArgValues[0]);
> -    return handleLValueToRValueConversion(Info, Args[0],
> Args[0]->getType(),
> -                                          RHS, Result);
> +    return handleLValueToRValueConversion(
> +        Info, E, Definition->getParamDecl(0)->
> getType().getNonReferenceType(),
> +        RHS, Result);
>    }
>
>    // Reserve space for the struct members.
> @@ -4088,6 +4110,18 @@ static bool HandleConstructorCall(Source
>           EvaluateStmt(Ret, Info, Definition->getBody()) != ESR_Failed;
>  }
>
> +static bool HandleConstructorCall(const Expr *E, const LValue &This,
> +                                  ArrayRef<const Expr*> Args,
> +                                  const CXXConstructorDecl *Definition,
> +                                  EvalInfo &Info, APValue &Result) {
> +  ArgVector ArgValues(Args.size());
> +  if (!EvaluateArgs(Args, ArgValues, Info))
> +    return false;
> +
> +  return HandleConstructorCall(E, This, ArgValues.data(), Definition,
> +                               Info, Result);
> +}
> +
>  //===-------------------------------------------------------
> ---------------===//
>  // Generic Evaluation
>  //===-------------------------------------------------------
> ---------------===//
> @@ -5380,6 +5414,7 @@ namespace {
>      bool VisitCXXConstructExpr(const CXXConstructExpr *E) {
>        return VisitCXXConstructExpr(E, E->getType());
>      }
> +    bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr
> *E);
>      bool VisitCXXConstructExpr(const CXXConstructExpr *E, QualType T);
>      bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr
> *E);
>    };
> @@ -5631,7 +5666,29 @@ bool RecordExprEvaluator::VisitCXXConstr
>      return false;
>
>    auto Args = llvm::makeArrayRef(E->getArgs(), E->getNumArgs());
> -  return HandleConstructorCall(E->getExprLoc(), This, Args,
> +  return HandleConstructorCall(E, This, Args,
> +                               cast<CXXConstructorDecl>(Definition),
> Info,
> +                               Result);
> +}
> +
> +bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
> +    const CXXInheritedCtorInitExpr *E) {
> +  if (!Info.CurrentCall) {
> +    assert(Info.checkingPotentialConstantExpression());
> +    return false;
> +  }
> +
> +  const CXXConstructorDecl *FD = E->getConstructor();
> +  if (FD->isInvalidDecl() || FD->getParent()->isInvalidDecl())
> +    return false;
> +
> +  const FunctionDecl *Definition = nullptr;
> +  auto Body = FD->getBody(Definition);
> +
> +  if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition,
> Body))
> +    return false;
> +
> +  return HandleConstructorCall(E, This, Info.CurrentCall->Arguments,
>                                 cast<CXXConstructorDecl>(Definition),
> Info,
>                                 Result);
>  }
> @@ -9305,6 +9362,7 @@ static ICEDiag CheckICE(const Expr* E, c
>    case Expr::TypoExprClass:
>    case Expr::DependentScopeDeclRefExprClass:
>    case Expr::CXXConstructExprClass:
> +  case Expr::CXXInheritedCtorInitExprClass:
>    case Expr::CXXStdInitializerListExprClass:
>    case Expr::CXXBindTemporaryExprClass:
>    case Expr::ExprWithCleanupsClass:
> @@ -9768,17 +9826,17 @@ bool Expr::isPotentialConstantExpr(const
>
>    ArrayRef<const Expr*> Args;
>
> -  SourceLocation Loc = FD->getLocation();
> -
>    APValue Scratch;
>    if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) {
>      // Evaluate the call as a constant initializer, to allow the
> construction
>      // of objects of non-literal types.
>      Info.setEvaluatingDecl(This.getLValueBase(), Scratch);
> -    HandleConstructorCall(Loc, This, Args, CD, Info, Scratch);
> -  } else
> +    HandleConstructorCall(&VIE, This, Args, CD, Info, Scratch);
> +  } else {
> +    SourceLocation Loc = FD->getLocation();
>      HandleFunctionCall(Loc, FD, (MD && MD->isInstance()) ? &This :
> nullptr,
>                         Args, FD->getBody(), Info, Scratch, nullptr);
> +  }
>
>    return Diags.empty();
>  }
>
> Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
> ItaniumMangle.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
> +++ cfe/trunk/lib/AST/ItaniumMangle.cpp Tue Jun 28 14:03:57 2016
> @@ -397,7 +397,7 @@ private:
>    void mangleCastExpression(const Expr *E, StringRef CastEncoding);
>    void mangleInitListElements(const InitListExpr *InitList);
>    void mangleExpression(const Expr *E, unsigned Arity = UnknownArity);
> -  void mangleCXXCtorType(CXXCtorType T);
> +  void mangleCXXCtorType(CXXCtorType T, const CXXRecordDecl
> *InheritedFrom);
>    void mangleCXXDtorType(CXXDtorType T);
>
>    void mangleTemplateArgs(const TemplateArgumentLoc *TemplateArgs,
> @@ -502,6 +502,12 @@ void CXXNameMangler::mangleFunctionEncod
>      FunctionTypeDepth.pop(Saved);
>    }
>
> +  // When mangling an inheriting constructor, the bare function type used
> is
> +  // that of the inherited constructor.
> +  if (auto *CD = dyn_cast<CXXConstructorDecl>(FD))
> +    if (auto Inherited = CD->getInheritedConstructor())
> +      FD = Inherited.getConstructor();
> +
>    // Whether the mangling of a function type includes the return type
> depends on
>    // the context and the nature of the function. The rules for deciding
> whether
>    // the return type is included are:
> @@ -562,7 +568,7 @@ static bool isStdNamespace(const DeclCon
>  static const TemplateDecl *
>  isTemplate(const NamedDecl *ND, const TemplateArgumentList
> *&TemplateArgs) {
>    // Check if we have a function template.
> -  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)){
> +  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
>      if (const TemplateDecl *TD = FD->getPrimaryTemplate()) {
>        TemplateArgs = FD->getTemplateSpecializationArgs();
>        return TD;
> @@ -1048,16 +1054,31 @@ void CXXNameMangler::mangleUnqualifiedNa
>    case DeclarationName::ObjCMultiArgSelector:
>      llvm_unreachable("Can't mangle Objective-C selector names here!");
>
> -  case DeclarationName::CXXConstructorName:
> +  case DeclarationName::CXXConstructorName: {
> +    const CXXRecordDecl *InheritedFrom = nullptr;
> +    const TemplateArgumentList *InheritedTemplateArgs = nullptr;
> +    if (auto Inherited =
> +            cast<CXXConstructorDecl>(ND)->getInheritedConstructor()) {
> +      InheritedFrom = Inherited.getConstructor()->getParent();
> +      InheritedTemplateArgs =
> +          Inherited.getConstructor()->getTemplateSpecializationArgs();
> +    }
> +
>      if (ND == Structor)
>        // If the named decl is the C++ constructor we're mangling, use the
> type
>        // we were given.
> -      mangleCXXCtorType(static_cast<CXXCtorType>(StructorType));
> +      mangleCXXCtorType(static_cast<CXXCtorType>(StructorType),
> InheritedFrom);
>      else
>        // Otherwise, use the complete constructor name. This is relevant
> if a
>        // class with a constructor is declared within a constructor.
> -      mangleCXXCtorType(Ctor_Complete);
> +      mangleCXXCtorType(Ctor_Complete, InheritedFrom);
> +
> +    // FIXME: The template arguments are part of the enclosing prefix or
> +    // nested-name, but it's more convenient to mangle them here.
> +    if (InheritedTemplateArgs)
> +      mangleTemplateArgs(*InheritedTemplateArgs);
>      break;
> +  }
>
>    case DeclarationName::CXXDestructorName:
>      if (ND == Structor)
> @@ -2909,6 +2930,7 @@ recurse:
>    case Expr::MSPropertySubscriptExprClass:
>    case Expr::TypoExprClass:  // This should no longer exist in the AST by
> now.
>    case Expr::OMPArraySectionExprClass:
> +  case Expr::CXXInheritedCtorInitExprClass:
>      llvm_unreachable("unexpected statement kind");
>
>    // FIXME: invent manglings for all these.
> @@ -3688,25 +3710,33 @@ void CXXNameMangler::mangleFunctionParam
>    Out << '_';
>  }
>
> -void CXXNameMangler::mangleCXXCtorType(CXXCtorType T) {
> +void CXXNameMangler::mangleCXXCtorType(CXXCtorType T,
> +                                       const CXXRecordDecl
> *InheritedFrom) {
>    // <ctor-dtor-name> ::= C1  # complete object constructor
>    //                  ::= C2  # base object constructor
> +  //                  ::= CI1 <type> # complete inheriting constructor
> +  //                  ::= CI2 <type> # base inheriting constructor
>    //
>    // In addition, C5 is a comdat name with C1 and C2 in it.
> +  Out << 'C';
> +  if (InheritedFrom)
> +    Out << 'I';
>    switch (T) {
>    case Ctor_Complete:
> -    Out << "C1";
> +    Out << '1';
>      break;
>    case Ctor_Base:
> -    Out << "C2";
> +    Out << '2';
>      break;
>    case Ctor_Comdat:
> -    Out << "C5";
> +    Out << '5';
>      break;
>    case Ctor_DefaultClosure:
>    case Ctor_CopyingClosure:
>      llvm_unreachable("closure constructors don't exist for the Itanium
> ABI!");
>    }
> +  if (InheritedFrom)
> +    mangleName(InheritedFrom);
>  }
>
>  void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
>
> Modified: cfe/trunk/lib/AST/NestedNameSpecifier.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
> NestedNameSpecifier.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/AST/NestedNameSpecifier.cpp (original)
> +++ cfe/trunk/lib/AST/NestedNameSpecifier.cpp Tue Jun 28 14:03:57 2016
> @@ -171,10 +171,19 @@ NamespaceAliasDecl *NestedNameSpecifier:
>
>  /// \brief Retrieve the record declaration stored in this nested name
> specifier.
>  CXXRecordDecl *NestedNameSpecifier::getAsRecordDecl() const {
> -  if (Prefix.getInt() == StoredDecl)
> +  switch (Prefix.getInt()) {
> +  case StoredIdentifier:
> +    return nullptr;
> +
> +  case StoredDecl:
>      return dyn_cast<CXXRecordDecl>(static_cast<NamedDecl *>(Specifier));
>
> -  return nullptr;
> +  case StoredTypeSpec:
> +  case StoredTypeSpecWithTemplate:
> +    return getAsType()->getAsCXXRecordDecl();
> +  }
> +
> +  llvm_unreachable("Invalid NNS Kind!");
>  }
>
>  /// \brief Whether this nested name specifier refers to a dependent
>
> Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
> StmtPrinter.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
> +++ cfe/trunk/lib/AST/StmtPrinter.cpp Tue Jun 28 14:03:57 2016
> @@ -2188,6 +2188,11 @@ void StmtPrinter::VisitCXXConstructExpr(
>      OS << "}";
>  }
>
> +void StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr
> *E) {
> +  // Parens are printed by the surrounding context.
> +  OS << "<forwarded>";
> +}
> +
>  void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr
> *E) {
>    PrintExpr(E->getSubExpr());
>  }
>
> Modified: cfe/trunk/lib/AST/StmtProfile.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
> StmtProfile.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/AST/StmtProfile.cpp (original)
> +++ cfe/trunk/lib/AST/StmtProfile.cpp Tue Jun 28 14:03:57 2016
> @@ -1287,6 +1287,12 @@ void StmtProfiler::VisitCXXConstructExpr
>    ID.AddBoolean(S->isElidable());
>  }
>
> +void StmtProfiler::VisitCXXInheritedCtorInitExpr(
> +    const CXXInheritedCtorInitExpr *S) {
> +  VisitExpr(S);
> +  VisitDecl(S->getConstructor());
> +}
> +
>  void StmtProfiler::VisitCXXFunctionalCastExpr(const
> CXXFunctionalCastExpr *S) {
>    VisitExplicitCastExpr(S);
>  }
>
> Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
> CGCall.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGCall.cpp Tue Jun 28 14:03:57 2016
> @@ -244,6 +244,15 @@ CodeGenTypes::arrangeCXXMethodDeclaratio
>    return arrangeFreeFunctionType(prototype, MD);
>  }
>
> +bool CodeGenTypes::inheritingCtorHasParams(
> +    const InheritedConstructor &Inherited, CXXCtorType Type) {
> +  // Parameters are unnecessary if we're constructing a base class
> subobject
> +  // and the inherited constructor lives in a virtual base.
> +  return Type == Ctor_Complete ||
> +         !Inherited.getShadowDecl()->constructsVirtualBase() ||
> +         !Target.getCXXABI().hasConstructorVariants();
> +  }
> +
>  const CGFunctionInfo &
>  CodeGenTypes::arrangeCXXStructorDeclaration(const CXXMethodDecl *MD,
>                                              StructorType Type) {
> @@ -252,9 +261,16 @@ CodeGenTypes::arrangeCXXStructorDeclarat
>    SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos;
>    argTypes.push_back(GetThisType(Context, MD->getParent()));
>
> +  bool PassParams = true;
> +
>    GlobalDecl GD;
>    if (auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
>      GD = GlobalDecl(CD, toCXXCtorType(Type));
> +
> +    // A base class inheriting constructor doesn't get forwarded arguments
> +    // needed to construct a virtual base (or base class thereof).
> +    if (auto Inherited = CD->getInheritedConstructor())
> +      PassParams = inheritingCtorHasParams(Inherited,
> toCXXCtorType(Type));
>    } else {
>      auto *DD = dyn_cast<CXXDestructorDecl>(MD);
>      GD = GlobalDecl(DD, toCXXDtorType(Type));
> @@ -263,12 +279,14 @@ CodeGenTypes::arrangeCXXStructorDeclarat
>    CanQual<FunctionProtoType> FTP = GetFormalType(MD);
>
>    // Add the formal parameters.
> -  appendParameterTypes(*this, argTypes, paramInfos, FTP, MD);
> +  if (PassParams)
> +    appendParameterTypes(*this, argTypes, paramInfos, FTP, MD);
>
>    TheCXXABI.buildStructorSignature(MD, Type, argTypes);
>
>    RequiredArgs required =
> -      (MD->isVariadic() ? RequiredArgs(argTypes.size()) :
> RequiredArgs::All);
> +      (PassParams && MD->isVariadic() ? RequiredArgs(argTypes.size())
> +                                      : RequiredArgs::All);
>
>    FunctionType::ExtInfo extInfo = FTP->getExtInfo();
>    CanQualType resultType = TheCXXABI.HasThisReturn(GD)
> @@ -3186,10 +3204,10 @@ void CodeGenFunction::EmitCallArgs(
>      size_t CallArgsStart = Args.size();
>      for (int I = ArgTypes.size() - 1; I >= 0; --I) {
>        CallExpr::const_arg_iterator Arg = ArgRange.begin() + I;
> +      MaybeEmitImplicitObjectSize(I, *Arg);
>        EmitCallArg(Args, *Arg, ArgTypes[I]);
>        EmitNonNullArgCheck(Args.back().RV, ArgTypes[I],
> (*Arg)->getExprLoc(),
>                            CalleeDecl, ParamsToSkip + I);
> -      MaybeEmitImplicitObjectSize(I, *Arg);
>      }
>
>      // Un-reverse the arguments we just evaluated so they match up with
> the LLVM
>
> Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
> CGClass.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGClass.cpp Tue Jun 28 14:03:57 2016
> @@ -2048,6 +2048,62 @@ void CodeGenFunction::EmitCXXConstructor
>                                               bool ForVirtualBase,
>                                               bool Delegating, Address
> This,
>                                               const CXXConstructExpr *E) {
> +  CallArgList Args;
> +
> +  // Push the this ptr.
> +  Args.add(RValue::get(This.getPointer()), D->getThisType(getContext()));
> +
> +  // If this is a trivial constructor, emit a memcpy now before we lose
> +  // the alignment information on the argument.
> +  // FIXME: It would be better to preserve alignment information into
> CallArg.
> +  if (isMemcpyEquivalentSpecialMember(D)) {
> +    assert(E->getNumArgs() == 1 && "unexpected argcount for trivial
> ctor");
> +
> +    const Expr *Arg = E->getArg(0);
> +    QualType SrcTy = Arg->getType();
> +    Address Src = EmitLValue(Arg).getAddress();
> +    QualType DestTy = getContext().getTypeDeclType(D->getParent());
> +    EmitAggregateCopyCtor(This, Src, DestTy, SrcTy);
> +    return;
> +  }
> +
> +  // Add the rest of the user-supplied arguments.
> +  const FunctionProtoType *FPT = D->getType()->castAs<
> FunctionProtoType>();
> +  EmitCallArgs(Args, FPT, E->arguments(), E->getConstructor());
> +
> +  EmitCXXConstructorCall(D, Type, ForVirtualBase, Delegating, This, Args);
> +}
> +
> +static bool canEmitDelegateCallArgs(CodeGenFunction &CGF,
> +                                    const CXXConstructorDecl *Ctor,
> +                                    CXXCtorType Type, CallArgList &Args) {
> +  // We can't forward a variadic call.
> +  if (Ctor->isVariadic())
> +    return false;
> +
> +  if (CGF.getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee())
> {
> +    // If the parameters are callee-cleanup, it's not safe to forward.
> +    for (auto *P : Ctor->parameters())
> +      if (P->getType().isDestructedType())
> +        return false;
> +
> +    // Likewise if they're inalloca.
> +    const CGFunctionInfo &Info =
> +        CGF.CGM.getTypes().arrangeCXXConstructorCall(Args, Ctor, Type,
> 0);
> +    if (Info.usesInAlloca())
> +      return false;
> +  }
> +
> +  // Anything else should be OK.
> +  return true;
> +}
> +
> +void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
> +                                             CXXCtorType Type,
> +                                             bool ForVirtualBase,
> +                                             bool Delegating,
> +                                             Address This,
> +                                             CallArgList &Args) {
>    const CXXRecordDecl *ClassDecl = D->getParent();
>
>    // C++11 [class.mfct.non-static]p2:
> @@ -2058,7 +2114,7 @@ void CodeGenFunction::EmitCXXConstructor
>                  This.getPointer(), getContext().getRecordType(
> ClassDecl));
>
>    if (D->isTrivial() && D->isDefaultConstructor()) {
> -    assert(E->getNumArgs() == 0 && "trivial default ctor with args");
> +    assert(Args.size() == 1 && "trivial default ctor with args");
>      return;
>    }
>
> @@ -2066,24 +2122,24 @@ void CodeGenFunction::EmitCXXConstructor
>    // union copy constructor, we must emit a memcpy, because the AST does
> not
>    // model that copy.
>    if (isMemcpyEquivalentSpecialMember(D)) {
> -    assert(E->getNumArgs() == 1 && "unexpected argcount for trivial
> ctor");
> +    assert(Args.size() == 2 && "unexpected argcount for trivial ctor");
>
> -    const Expr *Arg = E->getArg(0);
> -    QualType SrcTy = Arg->getType();
> -    Address Src = EmitLValue(Arg).getAddress();
> +    QualType SrcTy = D->getParamDecl(0)->getType().getNonReferenceType();
> +    Address Src(Args[1].RV.getScalarVal(), getNaturalTypeAlignment(SrcTy)
> );
>      QualType DestTy = getContext().getTypeDeclType(ClassDecl);
>      EmitAggregateCopyCtor(This, Src, DestTy, SrcTy);
>      return;
>    }
>
> -  CallArgList Args;
> -
> -  // Push the this ptr.
> -  Args.add(RValue::get(This.getPointer()), D->getThisType(getContext()));
> -
> -  // Add the rest of the user-supplied arguments.
> -  const FunctionProtoType *FPT = D->getType()->castAs<
> FunctionProtoType>();
> -  EmitCallArgs(Args, FPT, E->arguments(), E->getConstructor());
> +  // Check whether we can actually emit the constructor before trying to
> do so.
> +  if (auto Inherited = D->getInheritedConstructor()) {
> +    if (getTypes().inheritingCtorHasParams(Inherited, Type) &&
> +        !canEmitDelegateCallArgs(*this, D, Type, Args)) {
> +      EmitInlinedInheritingCXXConstructorCall(D, Type, ForVirtualBase,
> +                                              Delegating, Args);
> +      return;
> +    }
> +  }
>
>    // Insert any ABI-specific implicit constructor arguments.
>    unsigned ExtraArgs = CGM.getCXXABI().addImplicitConstructorArgs(
> @@ -2113,6 +2169,95 @@ void CodeGenFunction::EmitCXXConstructor
>      EmitVTableAssumptionLoads(ClassDecl, This);
>  }
>
> +void CodeGenFunction::EmitInheritedCXXConstructorCall(
> +    const CXXConstructorDecl *D, bool ForVirtualBase, Address This,
> +    bool InheritedFromVBase, const CXXInheritedCtorInitExpr *E) {
> +  CallArgList Args;
> +  CallArg ThisArg(RValue::get(This.getPointer()),
> D->getThisType(getContext()),
> +                  /*NeedsCopy=*/false);
> +
> +  // Forward the parameters.
> +  if (InheritedFromVBase &&
> +      CGM.getTarget().getCXXABI().hasConstructorVariants()) {
> +    // Nothing to do; this construction is not responsible for
> constructing
> +    // the base class containing the inherited constructor.
> +    // FIXME: Can we just pass undef's for the remaining arguments if we
> don't
> +    // have constructor variants?
> +    Args.push_back(ThisArg);
> +  } else if (!CXXInheritedCtorInitExprArgs.empty()) {
> +    // The inheriting constructor was inlined; just inject its arguments.
> +    assert(CXXInheritedCtorInitExprArgs.size() >= D->getNumParams() &&
> +           "wrong number of parameters for inherited constructor call");
> +    Args = CXXInheritedCtorInitExprArgs;
> +    Args[0] = ThisArg;
> +  } else {
> +    // The inheriting constructor was not inlined. Emit delegating
> arguments.
> +    Args.push_back(ThisArg);
> +    const auto *OuterCtor = cast<CXXConstructorDecl>(CurCodeDecl);
> +    assert(OuterCtor->getNumParams() == D->getNumParams());
> +    assert(!OuterCtor->isVariadic() && "should have been inlined");
> +
> +    for (const auto *Param : OuterCtor->parameters()) {
> +      assert(getContext().hasSameUnqualifiedType(
> +          OuterCtor->getParamDecl(Param->getFunctionScopeIndex())->
> getType(),
> +          Param->getType()));
> +      EmitDelegateCallArg(Args, Param, E->getLocation());
> +
> +      // Forward __attribute__(pass_object_size).
> +      if (Param->hasAttr<PassObjectSizeAttr>()) {
> +        auto *POSParam = SizeArguments[Param];
> +        assert(POSParam && "missing pass_object_size value for
> forwarding");
> +        EmitDelegateCallArg(Args, POSParam, E->getLocation());
> +      }
> +    }
> +  }
> +
> +  EmitCXXConstructorCall(D, Ctor_Base, ForVirtualBase,
> /*Delegating*/false,
> +                         This, Args);
> +}
> +
> +void CodeGenFunction::EmitInlinedInheritingCXXConstructorCall(
> +    const CXXConstructorDecl *Ctor, CXXCtorType CtorType, bool
> ForVirtualBase,
> +    bool Delegating, CallArgList &Args) {
> +  InlinedInheritingConstructorScope Scope(*this, GlobalDecl(Ctor,
> CtorType));
> +
> +  // Save the arguments to be passed to the inherited constructor.
> +  CXXInheritedCtorInitExprArgs = Args;
> +
> +  FunctionArgList Params;
> +  QualType RetType = BuildFunctionArgList(CurGD, Params);
> +  FnRetTy = RetType;
> +
> +  // Insert any ABI-specific implicit constructor arguments.
> +  CGM.getCXXABI().addImplicitConstructorArgs(*this, Ctor, CtorType,
> +                                             ForVirtualBase, Delegating,
> Args);
> +
> +  // Emit a simplified prolog. We only need to emit the implicit params.
> +  assert(Args.size() >= Params.size() && "too few arguments for call");
> +  for (unsigned I = 0, N = Args.size(); I != N; ++I) {
> +    if (I < Params.size() && isa<ImplicitParamDecl>(Params[I])) {
> +      const RValue &RV = Args[I].RV;
> +      assert(!RV.isComplex() && "complex indirect params not supported");
> +      ParamValue Val = RV.isScalar()
> +                           ? ParamValue::forDirect(RV.getScalarVal())
> +                           : ParamValue::forIndirect(RV.
> getAggregateAddress());
> +      EmitParmDecl(*Params[I], Val, I + 1);
> +    }
> +  }
> +
> +  // Create a return value slot if the ABI implementation wants one.
> +  // FIXME: This is dumb, we should ask the ABI not to try to set the
> return
> +  // value instead.
> +  if (!RetType->isVoidType())
> +    ReturnValue = CreateIRTemp(RetType, "retval.inhctor");
> +
> +  CGM.getCXXABI().EmitInstanceFunctionProlog(*this);
> +  CXXThisValue = CXXABIThisValue;
> +
> +  // Directly emit the constructor initializers.
> +  EmitCtorPrologue(Ctor, CtorType, Params);
> +}
> +
>  void CodeGenFunction::EmitVTableAssumptionLoad(const VPtr &Vptr, Address
> This) {
>    llvm::Value *VTableGlobal =
>        CGM.getCXXABI().getVTableAddressPoint(Vptr.Base, Vptr.VTableClass);
> @@ -2145,19 +2290,6 @@ void
>  CodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl
> *D,
>                                                  Address This, Address Src,
>                                                  const CXXConstructExpr
> *E) {
> -  if (isMemcpyEquivalentSpecialMember(D)) {
> -    assert(E->getNumArgs() == 1 && "unexpected argcount for trivial
> ctor");
> -    assert(D->isCopyOrMoveConstructor() &&
> -           "trivial 1-arg ctor not a copy/move ctor");
> -    EmitAggregateCopyCtor(This, Src,
> -                          getContext().getTypeDeclType(D->getParent()),
> -                          (*E->arg_begin())->getType());
> -    return;
> -  }
> -  llvm::Value *Callee = CGM.getAddrOfCXXStructor(D,
> StructorType::Complete);
> -  assert(D->isInstance() &&
> -         "Trying to emit a member call expr on a static method!");
> -
>    const FunctionProtoType *FPT = D->getType()->castAs<
> FunctionProtoType>();
>
>    CallArgList Args;
> @@ -2175,8 +2307,7 @@ CodeGenFunction::EmitSynthesizedCXXCopyC
>    EmitCallArgs(Args, FPT, drop_begin(E->arguments(), 1),
> E->getConstructor(),
>                 /*ParamsToSkip*/ 1);
>
> -  EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT,
> RequiredArgs::All),
> -           Callee, ReturnValueSlot(), Args, D);
> +  EmitCXXConstructorCall(D, Ctor_Complete, false, false, This, Args);
>  }
>
>  void
> @@ -2190,21 +2321,17 @@ CodeGenFunction::EmitDelegateCXXConstruc
>    assert(I != E && "no parameters to constructor");
>
>    // this
> -  DelegateArgs.add(RValue::get(LoadCXXThis()), (*I)->getType());
> +  Address This = LoadCXXThisAddress();
> +  DelegateArgs.add(RValue::get(This.getPointer()), (*I)->getType());
>    ++I;
>
> -  // vtt
> -  if (llvm::Value *VTT = GetVTTParameter(GlobalDecl(Ctor, CtorType),
> -                                         /*ForVirtualBase=*/false,
> -                                         /*Delegating=*/true)) {
> -    QualType VoidPP = getContext().getPointerType(
> getContext().VoidPtrTy);
> -    DelegateArgs.add(RValue::get(VTT), VoidPP);
> -
> -    if (CGM.getCXXABI().NeedsVTTParameter(CurGD)) {
> -      assert(I != E && "cannot skip vtt parameter, already done with
> args");
> -      assert((*I)->getType() == VoidPP && "skipping parameter not of vtt
> type");
> -      ++I;
> -    }
> +  // FIXME: The location of the VTT parameter in the parameter list is
> +  // specific to the Itanium ABI and shouldn't be hardcoded here.
> +  if (CGM.getCXXABI().NeedsVTTParameter(CurGD)) {
> +    assert(I != E && "cannot skip vtt parameter, already done with args");
> +    assert((*I)->getType()->isPointerType() &&
> +           "skipping parameter not of vtt type");
> +    ++I;
>    }
>
>    // Explicit arguments.
> @@ -2214,11 +2341,8 @@ CodeGenFunction::EmitDelegateCXXConstruc
>      EmitDelegateCallArg(DelegateArgs, param, Loc);
>    }
>
> -  llvm::Value *Callee =
> -      CGM.getAddrOfCXXStructor(Ctor, getFromCtorType(CtorType));
> -  EmitCall(CGM.getTypes()
> -               .arrangeCXXStructorDeclaration(Ctor,
> getFromCtorType(CtorType)),
> -           Callee, ReturnValueSlot(), DelegateArgs, Ctor);
> +  EmitCXXConstructorCall(Ctor, CtorType, /*ForVirtualBase=*/false,
> +                         /*Delegating=*/true, This, DelegateArgs);
>  }
>
>  namespace {
>
> Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
> CGDecl.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGDecl.cpp Tue Jun 28 14:03:57 2016
> @@ -85,6 +85,7 @@ void CodeGenFunction::EmitDecl(const Dec
>    case Decl::Captured:
>    case Decl::ClassScopeFunctionSpecialization:
>    case Decl::UsingShadow:
> +  case Decl::ConstructorUsingShadow:
>    case Decl::ObjCTypeParam:
>      llvm_unreachable("Declaration should not be in declstmts!");
>    case Decl::Function:  // void X();
>
> Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
> CGExprAgg.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Tue Jun 28 14:03:57 2016
> @@ -175,6 +175,7 @@ public:
>    }
>    void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
>    void VisitCXXConstructExpr(const CXXConstructExpr *E);
> +  void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E);
>    void VisitLambdaExpr(LambdaExpr *E);
>    void VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E);
>    void VisitExprWithCleanups(ExprWithCleanups *E);
> @@ -998,6 +999,14 @@ AggExprEmitter::VisitCXXConstructExpr(co
>    CGF.EmitCXXConstructExpr(E, Slot);
>  }
>
> +void AggExprEmitter::VisitCXXInheritedCtorInitExpr(
> +    const CXXInheritedCtorInitExpr *E) {
> +  AggValueSlot Slot = EnsureSlot(E->getType());
> +  CGF.EmitInheritedCXXConstructorCall(
> +      E->getConstructor(), E->constructsVBase(), Slot.getAddress(),
> +      E->inheritedFromVBase(), E);
> +}
> +
>  void
>  AggExprEmitter::VisitLambdaExpr(LambdaExpr *E) {
>    AggValueSlot Slot = EnsureSlot(E->getType());
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
> CodeGenFunction.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Tue Jun 28 14:03:57 2016
> @@ -928,18 +928,11 @@ static void TryMarkNoThrow(llvm::Functio
>    F->setDoesNotThrow();
>  }
>
> -void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
> -                                   const CGFunctionInfo &FnInfo) {
> +QualType CodeGenFunction::BuildFunctionArgList(GlobalDecl GD,
> +                                               FunctionArgList &Args) {
>    const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
> -
> -  // Check if we should generate debug info for this function.
> -  if (FD->hasAttr<NoDebugAttr>())
> -    DebugInfo = nullptr; // disable debug info indefinitely for this
> function
> -
> -  FunctionArgList Args;
>    QualType ResTy = FD->getReturnType();
>
> -  CurGD = GD;
>    const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
>    if (MD && MD->isInstance()) {
>      if (CGM.getCXXABI().HasThisReturn(GD))
> @@ -949,22 +942,48 @@ void CodeGenFunction::GenerateCode(Globa
>      CGM.getCXXABI().buildThisParam(*this, Args);
>    }
>
> -  for (auto *Param : FD->parameters()) {
> -    Args.push_back(Param);
> -    if (!Param->hasAttr<PassObjectSizeAttr>())
> -      continue;
> -
> -    IdentifierInfo *NoID = nullptr;
> -    auto *Implicit = ImplicitParamDecl::Create(
> -        getContext(), Param->getDeclContext(), Param->getLocation(), NoID,
> -        getContext().getSizeType());
> -    SizeArguments[Param] = Implicit;
> -    Args.push_back(Implicit);
> +  // The base version of an inheriting constructor whose constructed base
> is a
> +  // virtual base is not passed any arguments (because it doesn't
> actually call
> +  // the inherited constructor).
> +  bool PassedParams = true;
> +  if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD))
> +    if (auto Inherited = CD->getInheritedConstructor())
> +      PassedParams =
> +          getTypes().inheritingCtorHasParams(Inherited,
> GD.getCtorType());
> +
> +  if (PassedParams) {
> +    for (auto *Param : FD->parameters()) {
> +      Args.push_back(Param);
> +      if (!Param->hasAttr<PassObjectSizeAttr>())
> +        continue;
> +
> +      IdentifierInfo *NoID = nullptr;
> +      auto *Implicit = ImplicitParamDecl::Create(
> +          getContext(), Param->getDeclContext(), Param->getLocation(),
> NoID,
> +          getContext().getSizeType());
> +      SizeArguments[Param] = Implicit;
> +      Args.push_back(Implicit);
> +    }
>    }
>
>    if (MD && (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)))
>      CGM.getCXXABI().addImplicitStructorParams(*this, ResTy, Args);
>
> +  return ResTy;
> +}
> +
> +void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
> +                                   const CGFunctionInfo &FnInfo) {
> +  const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
> +  CurGD = GD;
> +
> +  FunctionArgList Args;
> +  QualType ResTy = BuildFunctionArgList(GD, Args);
> +
> +  // Check if we should generate debug info for this function.
> +  if (FD->hasAttr<NoDebugAttr>())
> +    DebugInfo = nullptr; // disable debug info indefinitely for this
> function
> +
>    SourceRange BodyRange;
>    if (Stmt *Body = FD->getBody()) BodyRange = Body->getSourceRange();
>    CurEHLocation = BodyRange.getEnd();
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
> CodeGenFunction.h?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Jun 28 14:03:57 2016
> @@ -1065,6 +1065,61 @@ public:
>      CharUnits OldCXXThisAlignment;
>    };
>
> +  class InlinedInheritingConstructorScope {
> +  public:
> +    InlinedInheritingConstructorScope(CodeGenFunction &CGF, GlobalDecl
> GD)
> +        : CGF(CGF), OldCurGD(CGF.CurGD), OldCurFuncDecl(CGF.CurFuncDecl),
> +          OldCurCodeDecl(CGF.CurCodeDecl),
> +          OldCXXABIThisDecl(CGF.CXXABIThisDecl),
> +          OldCXXABIThisValue(CGF.CXXABIThisValue),
> +          OldCXXThisValue(CGF.CXXThisValue),
> +          OldCXXABIThisAlignment(CGF.CXXABIThisAlignment),
> +          OldCXXThisAlignment(CGF.CXXThisAlignment),
> +          OldReturnValue(CGF.ReturnValue), OldFnRetTy(CGF.FnRetTy),
> +          OldCXXInheritedCtorInitExprArgs(
> +              std::move(CGF.CXXInheritedCtorInitExprArgs)) {
> +      CGF.CurGD = GD;
> +      CGF.CurFuncDecl = CGF.CurCodeDecl =
> +          cast<CXXConstructorDecl>(GD.getDecl());
> +      CGF.CXXABIThisDecl = nullptr;
> +      CGF.CXXABIThisValue = nullptr;
> +      CGF.CXXThisValue = nullptr;
> +      CGF.CXXABIThisAlignment = CharUnits();
> +      CGF.CXXThisAlignment = CharUnits();
> +      CGF.ReturnValue = Address::invalid();
> +      CGF.FnRetTy = QualType();
> +      CGF.CXXInheritedCtorInitExprArgs.clear();
> +    }
> +    ~InlinedInheritingConstructorScope() {
> +      CGF.CurGD = OldCurGD;
> +      CGF.CurFuncDecl = OldCurFuncDecl;
> +      CGF.CurCodeDecl = OldCurCodeDecl;
> +      CGF.CXXABIThisDecl = OldCXXABIThisDecl;
> +      CGF.CXXABIThisValue = OldCXXABIThisValue;
> +      CGF.CXXThisValue = OldCXXThisValue;
> +      CGF.CXXABIThisAlignment = OldCXXABIThisAlignment;
> +      CGF.CXXThisAlignment = OldCXXThisAlignment;
> +      CGF.ReturnValue = OldReturnValue;
> +      CGF.FnRetTy = OldFnRetTy;
> +      CGF.CXXInheritedCtorInitExprArgs =
> +          std::move(OldCXXInheritedCtorInitExprArgs);
> +    }
> +
> +  private:
> +    CodeGenFunction &CGF;
> +    GlobalDecl OldCurGD;
> +    const Decl *OldCurFuncDecl;
> +    const Decl *OldCurCodeDecl;
> +    ImplicitParamDecl *OldCXXABIThisDecl;
> +    llvm::Value *OldCXXABIThisValue;
> +    llvm::Value *OldCXXThisValue;
> +    CharUnits OldCXXABIThisAlignment;
> +    CharUnits OldCXXThisAlignment;
> +    Address OldReturnValue;
> +    QualType OldFnRetTy;
> +    CallArgList OldCXXInheritedCtorInitExprArgs;
> +  };
> +
>  private:
>    /// CXXThisDecl - When generating code for a C++ member function,
>    /// this will hold the implicit 'this' declaration.
> @@ -1078,6 +1133,10 @@ private:
>    /// this expression.
>    Address CXXDefaultInitExprThis = Address::invalid();
>
> +  /// The values of function arguments to use when evaluating
> +  /// CXXInheritedCtorInitExprs within this context.
> +  CallArgList CXXInheritedCtorInitExprArgs;
> +
>    /// CXXStructorImplicitParamDecl - When generating code for a
> constructor or
>    /// destructor, this will hold the implicit argument (e.g. VTT).
>    ImplicitParamDecl *CXXStructorImplicitParamDecl;
> @@ -1301,6 +1360,8 @@ public:
>
>    const BlockByrefInfo &getBlockByrefInfo(const VarDecl *var);
>
> +  QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args);
> +
>    void GenerateCode(GlobalDecl GD, llvm::Function *Fn,
>                      const CGFunctionInfo &FnInfo);
>    /// \brief Emit code for the start of a function.
> @@ -1874,10 +1935,32 @@ public:
>    void EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor,
>                                          const FunctionArgList &Args);
>
> +  /// Emit a call to an inheriting constructor (that is, one that invokes
> a
> +  /// constructor inherited from a base class) by inlining its
> definition. This
> +  /// is necessary if the ABI does not support forwarding the arguments
> to the
> +  /// base class constructor (because they're variadic or similar).
> +  void EmitInlinedInheritingCXXConstructorCall(const CXXConstructorDecl
> *Ctor,
> +                                               CXXCtorType CtorType,
> +                                               bool ForVirtualBase,
> +                                               bool Delegating,
> +                                               CallArgList &Args);
> +
> +  /// Emit a call to a constructor inherited from a base class, passing
> the
> +  /// current constructor's arguments along unmodified (without even
> making
> +  /// a copy).
> +  void EmitInheritedCXXConstructorCall(const CXXConstructorDecl *D,
> +                                       bool ForVirtualBase, Address This,
> +                                       bool InheritedFromVBase,
> +                                       const CXXInheritedCtorInitExpr *E);
> +
>    void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType
> Type,
>                                bool ForVirtualBase, bool Delegating,
>                                Address This, const CXXConstructExpr *E);
>
> +  void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType
> Type,
> +                              bool ForVirtualBase, bool Delegating,
> +                              Address This, CallArgList &Args);
> +
>    /// Emit assumption load for all bases. Requires to be be called only on
>    /// most-derived class and not under construction of the object.
>    void EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl, Address
> This);
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
> CodeGenModule.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue Jun 28 14:03:57 2016
> @@ -765,6 +765,15 @@ CodeGenModule::getFunctionLinkage(Global
>                                     : llvm::GlobalValue::
> LinkOnceODRLinkage;
>    }
>
> +  if (isa<CXXConstructorDecl>(D) &&
> +      cast<CXXConstructorDecl>(D)->isInheritingConstructor() &&
> +      Context.getTargetInfo().getCXXABI().isMicrosoft()) {
> +    // Our approach to inheriting constructors is fundamentally different
> from
> +    // that used by the MS ABI, so keep our inheriting constructor thunks
> +    // internal rather than trying to pick an unambiguous mangling for
> them.
> +    return llvm::GlobalValue::InternalLinkage;
> +  }
> +
>    return getLLVMLinkageForDeclarator(D, Linkage,
> /*isConstantVariable=*/false);
>  }
>
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
> CodeGenTypes.h?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/CodeGen/CodeGenTypes.h (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenTypes.h Tue Jun 28 14:03:57 2016
> @@ -205,6 +205,11 @@ public:
>    bool isFuncTypeConvertible(const FunctionType *FT);
>    bool isFuncParamTypeConvertible(QualType Ty);
>
> +  /// Determine if a C++ inheriting constructor should have parameters
> matching
> +  /// those of its inherited constructor.
> +  bool inheritingCtorHasParams(const InheritedConstructor &Inherited,
> +                               CXXCtorType Type);
> +
>    /// GetFunctionTypeForVTable - Get the LLVM function type for use in a
> vtable,
>    /// given a CXXMethodDecl. If the method to has an incomplete return
> type,
>    /// and/or incomplete argument types, this will return the opaque type.
>
> Modified: cfe/trunk/lib/Sema/SemaAccess.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaAccess.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaAccess.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaAccess.cpp Tue Jun 28 14:03:57 2016
> @@ -1610,10 +1610,10 @@ Sema::AccessResult Sema::CheckDestructor
>  /// Checks access to a constructor.
>  Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
>                                                  CXXConstructorDecl
> *Constructor,
> +                                                DeclAccessPair Found,
>                                                  const InitializedEntity
> &Entity,
> -                                                AccessSpecifier Access,
>                                                  bool
> IsCopyBindingRefToTemp) {
> -  if (!getLangOpts().AccessControl || Access == AS_public)
> +  if (!getLangOpts().AccessControl || Found.getAccess() == AS_public)
>      return AR_accessible;
>
>    PartialDiagnostic PD(PDiag());
> @@ -1647,17 +1647,17 @@ Sema::AccessResult Sema::CheckConstructo
>
>    }
>
> -  return CheckConstructorAccess(UseLoc, Constructor, Entity, Access, PD);
> +  return CheckConstructorAccess(UseLoc, Constructor, Found, Entity, PD);
>  }
>
>  /// Checks access to a constructor.
>  Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
>                                                  CXXConstructorDecl
> *Constructor,
> +                                                DeclAccessPair Found,
>                                                  const InitializedEntity
> &Entity,
> -                                                AccessSpecifier Access,
>                                                  const PartialDiagnostic
> &PD) {
>    if (!getLangOpts().AccessControl ||
> -      Access == AS_public)
> +      Found.getAccess() == AS_public)
>      return AR_accessible;
>
>    CXXRecordDecl *NamingClass = Constructor->getParent();
> @@ -1670,15 +1670,23 @@ Sema::AccessResult Sema::CheckConstructo
>    // in aggregate initialization. It's not clear whether the object class
>    // should be the base class or the derived class in that case.
>    CXXRecordDecl *ObjectClass;
> -  if (Entity.getKind() == InitializedEntity::EK_Base &&
> !Entity.getParent()) {
> +  if ((Entity.getKind() == InitializedEntity::EK_Base ||
> +       Entity.getKind() == InitializedEntity::EK_Delegating) &&
> +      !Entity.getParent()) {
>      ObjectClass = cast<CXXConstructorDecl>(CurContext)->getParent();
> +  } else if (auto *Shadow =
> +                 dyn_cast<ConstructorUsingShadowDecl>(Found.getDecl())) {
> +    // If we're using an inheriting constructor to construct an object,
> +    // the object class is the derived class, not the base class.
> +    ObjectClass = Shadow->getParent();
>    } else {
>      ObjectClass = NamingClass;
>    }
>
> -  AccessTarget AccessEntity(Context, AccessTarget::Member, NamingClass,
> -                            DeclAccessPair::make(Constructor, Access),
> -                            Context.getTypeDeclType(ObjectClass));
> +  AccessTarget AccessEntity(
> +      Context, AccessTarget::Member, NamingClass,
> +      DeclAccessPair::make(Constructor, Found.getAccess()),
> +      Context.getTypeDeclType(ObjectClass));
>    AccessEntity.setDiag(PD);
>
>    return CheckAccess(*this, UseLoc, AccessEntity);
>
> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaDeclCXX.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Jun 28 14:03:57 2016
> @@ -3356,34 +3356,7 @@ BuildImplicitBaseInitializer(Sema &SemaR
>    ExprResult BaseInit;
>
>    switch (ImplicitInitKind) {
> -  case IIK_Inherit: {
> -    const CXXRecordDecl *Inherited =
> -        Constructor->getInheritedConstructor()->getParent();
> -    const CXXRecordDecl *Base = BaseSpec->getType()->
> getAsCXXRecordDecl();
> -    if (Base && Inherited->getCanonicalDecl() ==
> Base->getCanonicalDecl()) {
> -      // C++11 [class.inhctor]p8:
> -      //   Each expression in the expression-list is of the form
> -      //   static_cast<T&&>(p), where p is the name of the corresponding
> -      //   constructor parameter and T is the declared type of p.
> -      SmallVector<Expr*, 16> Args;
> -      for (unsigned I = 0, E = Constructor->getNumParams(); I != E; ++I) {
> -        ParmVarDecl *PD = Constructor->getParamDecl(I);
> -        ExprResult ArgExpr =
> -            SemaRef.BuildDeclRefExpr(PD, PD->getType().
> getNonReferenceType(),
> -                                     VK_LValue, SourceLocation());
> -        if (ArgExpr.isInvalid())
> -          return true;
> -        Args.push_back(CastForMoving(SemaRef, ArgExpr.get(),
> PD->getType()));
> -      }
> -
> -      InitializationKind InitKind = InitializationKind::CreateDirect(
> -          Constructor->getLocation(), SourceLocation(), SourceLocation());
> -      InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, Args);
> -      BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind, Args);
> -      break;
> -    }
> -  }
> -  // Fall through.
> +  case IIK_Inherit:
>    case IIK_Default: {
>      InitializationKind InitKind
>        = InitializationKind::CreateDefault(Constructor->getLocation());
> @@ -3694,12 +3667,12 @@ struct BaseAndFieldInfo {
>    BaseAndFieldInfo(Sema &S, CXXConstructorDecl *Ctor, bool ErrorsInInits)
>      : S(S), Ctor(Ctor), AnyErrorsInInits(ErrorsInInits) {
>      bool Generated = Ctor->isImplicit() || Ctor->isDefaulted();
> -    if (Generated && Ctor->isCopyConstructor())
> +    if (Ctor->getInheritedConstructor())
> +      IIK = IIK_Inherit;
> +    else if (Generated && Ctor->isCopyConstructor())
>        IIK = IIK_Copy;
>      else if (Generated && Ctor->isMoveConstructor())
>        IIK = IIK_Move;
> -    else if (Ctor->getInheritedConstructor())
> -      IIK = IIK_Inherit;
>      else
>        IIK = IIK_Default;
>    }
> @@ -5065,15 +5038,6 @@ void Sema::CheckCompletedCXXClass(CXXRec
>      Diag(Record->getLocation(), diag::warn_cxx_ms_struct);
>    }
>
> -  // Declare inheriting constructors. We do this eagerly here because:
> -  // - The standard requires an eager diagnostic for conflicting
> inheriting
> -  //   constructors from different classes.
> -  // - The lazy declaration of the other implicit constructors is so as
> to not
> -  //   waste space and performance on classes that are not meant to be
> -  //   instantiated (e.g. meta-functions). This doesn't apply to classes
> that
> -  //   have inheriting constructors.
> -  DeclareInheritingConstructors(Record);
> -
>    checkClassLevelDLLAttribute(Record);
>  }
>
> @@ -5107,11 +5071,110 @@ static Sema::SpecialMemberOverloadResult
>                                 LHSQuals & Qualifiers::Volatile);
>  }
>
> +namespace {
> +struct InheritedConstructorInfo {
> +  Sema &S;
> +  SourceLocation UseLoc;
> +  ConstructorUsingShadowDecl *Shadow;
> +
> +  /// A mapping from the base classes through which the constructor was
> +  /// inherited to the using shadow declaration in that base class (or a
> null
> +  /// pointer if the constructor was declared in that base class).
> +  llvm::DenseMap<CXXRecordDecl *, ConstructorUsingShadowDecl *>
> +      InheritedFromBases;
> +
> +  InheritedConstructorInfo(Sema &S, SourceLocation UseLoc,
> +                           ConstructorUsingShadowDecl *Shadow)
> +      : S(S), UseLoc(UseLoc), Shadow(Shadow) {
> +    bool DiagnosedMultipleConstructedBases = false;
> +    CXXRecordDecl *ConstructedBase = nullptr;
> +    UsingDecl *ConstructedBaseUsing = nullptr;
> +
> +    // Find the set of such base class subobjects and check that there's a
> +    // unique constructed subobject.
> +    for (auto *D : Shadow->redecls()) {
> +      auto *DShadow = cast<ConstructorUsingShadowDecl>(D);
> +      auto *DNominatedBase = DShadow->getNominatedBaseClass();
> +      auto *DConstructedBase = DShadow->getConstructedBaseClass();
> +
> +      InheritedFromBases.insert(
> +          std::make_pair(DNominatedBase->getCanonicalDecl(),
> +                         DShadow->getNominatedBaseClassShadowDecl()));
> +      if (DShadow->constructsVirtualBase())
> +        InheritedFromBases.insert(
> +            std::make_pair(DConstructedBase->getCanonicalDecl(),
> +                           DShadow->getConstructedBaseClassShadowD
> ecl()));
> +      else
> +        assert(DNominatedBase == DConstructedBase);
> +
> +      // [class.inhctor.init]p2:
> +      //   If the constructor was inherited from multiple base class
> subobjects
> +      //   of type B, the program is ill-formed.
> +      if (!ConstructedBase) {
> +        ConstructedBase = DConstructedBase;
> +        ConstructedBaseUsing = D->getUsingDecl();
> +      } else if (ConstructedBase != DConstructedBase &&
> +                 !Shadow->isInvalidDecl()) {
> +        if (!DiagnosedMultipleConstructedBases) {
> +          S.Diag(UseLoc, diag::err_ambiguous_inherited_constructor)
> +              << Shadow->getTargetDecl();
> +          S.Diag(ConstructedBaseUsing->getLocation(),
> +               diag::note_ambiguous_inherited_constructor_using)
> +              << ConstructedBase;
> +          DiagnosedMultipleConstructedBases = true;
> +        }
> +        S.Diag(D->getUsingDecl()->getLocation(),
> +               diag::note_ambiguous_inherited_constructor_using)
> +            << DConstructedBase;
> +      }
> +    }
> +
> +    if (DiagnosedMultipleConstructedBases)
> +      Shadow->setInvalidDecl();
> +  }
> +
> +  /// Find the constructor to use for inherited construction of a base
> class,
> +  /// and whether that base class constructor inherits the constructor
> from a
> +  /// virtual base class (in which case it won't actually invoke it).
> +  std::pair<CXXConstructorDecl *, bool>
> +  findConstructorForBase(CXXRecordDecl *Base, CXXConstructorDecl *Ctor)
> const {
> +    auto It = InheritedFromBases.find(Base->getCanonicalDecl());
> +    if (It == InheritedFromBases.end())
> +      return std::make_pair(nullptr, false);
> +
> +    // This is an intermediary class.
> +    if (It->second)
> +      return std::make_pair(
> +          S.findInheritingConstructor(UseLoc, Ctor, It->second),
> +          It->second->constructsVirtualBase());
> +
> +    // This is the base class from which the constructor was inherited.
> +    return std::make_pair(Ctor, false);
> +  }
> +};
> +}
> +
>  /// Is the special member function which would be selected to perform the
>  /// specified operation on the specified class type a constexpr
> constructor?
> -static bool specialMemberIsConstexpr(Sema &S, CXXRecordDecl *ClassDecl,
> -                                     Sema::CXXSpecialMember CSM,
> -                                     unsigned Quals, bool ConstRHS) {
> +static bool
> +specialMemberIsConstexpr(Sema &S, CXXRecordDecl *ClassDecl,
> +                         Sema::CXXSpecialMember CSM, unsigned Quals,
> +                         bool ConstRHS,
> +                         CXXConstructorDecl *InheritedCtor = nullptr,
> +                         InheritedConstructorInfo *Inherited = nullptr) {
> +  // If we're inheriting a constructor, see if we need to call it for
> this base
> +  // class.
> +  if (InheritedCtor) {
> +    assert(CSM == Sema::CXXDefaultConstructor);
> +    auto BaseCtor =
> +        Inherited->findConstructorForBase(ClassDecl,
> InheritedCtor).first;
> +    if (BaseCtor)
> +      return BaseCtor->isConstexpr();
> +  }
> +
> +  if (CSM == Sema::CXXDefaultConstructor)
> +    return ClassDecl->hasConstexprDefaultConstructor();
> +
>    Sema::SpecialMemberOverloadResult *SMOR =
>        lookupCallFromSpecialMember(S, ClassDecl, CSM, Quals, ConstRHS);
>    if (!SMOR || !SMOR->getMethod())
> @@ -5123,9 +5186,10 @@ static bool specialMemberIsConstexpr(Sem
>
>  /// Determine whether the specified special member function would be
> constexpr
>  /// if it were implicitly defined.
> -static bool defaultedSpecialMemberIsConstexpr(Sema &S, CXXRecordDecl
> *ClassDecl,
> -                                              Sema::CXXSpecialMember CSM,
> -                                              bool ConstArg) {
> +static bool defaultedSpecialMemberIsConstexpr(
> +    Sema &S, CXXRecordDecl *ClassDecl, Sema::CXXSpecialMember CSM,
> +    bool ConstArg, CXXConstructorDecl *InheritedCtor = nullptr,
> +    InheritedConstructorInfo *Inherited = nullptr) {
>    if (!S.getLangOpts().CPlusPlus11)
>      return false;
>
> @@ -5134,6 +5198,8 @@ static bool defaultedSpecialMemberIsCons
>    bool Ctor = true;
>    switch (CSM) {
>    case Sema::CXXDefaultConstructor:
> +    if (Inherited)
> +      break;
>      // Since default constructor lookup is essentially trivial (and cannot
>      // involve, for instance, template instantiation), we compute whether
> a
>      // defaulted default constructor is constexpr directly within
> CXXRecordDecl.
> @@ -5168,7 +5234,10 @@ static bool defaultedSpecialMemberIsCons
>    // will be initialized (if the constructor isn't deleted), we just
> don't know
>    // which one.
>    if (Ctor && ClassDecl->isUnion())
> -    return true;
> +    return CSM == Sema::CXXDefaultConstructor
> +               ? ClassDecl->hasInClassInitializer() ||
> +                     !ClassDecl->hasVariantMembers()
> +               : true;
>
>    //   -- the class shall not have any virtual base classes;
>    if (Ctor && ClassDecl->getNumVBases())
> @@ -5188,7 +5257,8 @@ static bool defaultedSpecialMemberIsCons
>      if (!BaseType) continue;
>
>      CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->
> getDecl());
> -    if (!specialMemberIsConstexpr(S, BaseClassDecl, CSM, 0, ConstArg))
> +    if (!specialMemberIsConstexpr(S, BaseClassDecl, CSM, 0, ConstArg,
> +                                  InheritedCtor, Inherited))
>        return false;
>    }
>
> @@ -5202,6 +5272,8 @@ static bool defaultedSpecialMemberIsCons
>    for (const auto *F : ClassDecl->fields()) {
>      if (F->isInvalidDecl())
>        continue;
> +    if (CSM == Sema::CXXDefaultConstructor && F->hasInClassInitializer())
> +      continue;
>      QualType BaseType = S.Context.getBaseElementType(F->getType());
>      if (const RecordType *RecordTy = BaseType->getAs<RecordType>()) {
>        CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RecordTy->
> getDecl());
> @@ -5209,6 +5281,8 @@ static bool defaultedSpecialMemberIsCons
>                                      BaseType.getCVRQualifiers(),
>                                      ConstArg && !F->isMutable()))
>          return false;
> +    } else if (CSM == Sema::CXXDefaultConstructor) {
> +      return false;
>      }
>    }
>
> @@ -5236,7 +5310,8 @@ computeImplicitExceptionSpec(Sema &S, So
>    }
>    assert(cast<CXXConstructorDecl>(MD)->getInheritedConstructor() &&
>           "only special members have implicit exception specs");
> -  return S.ComputeInheritingCtorExceptionSpec(cast<CXXConstructorDecl>(
> MD));
> +  return S.ComputeInheritingCtorExceptionSpec(Loc,
> +
> cast<CXXConstructorDecl>(MD));
>  }
>
>  static FunctionProtoType::ExtProtoInfo getImplicitMethodEPI(Sema &S,
> @@ -6501,14 +6576,12 @@ void Sema::ActOnFinishCXXMemberSpecifica
>  /// [special]p1).  This routine can only be executed just before the
>  /// definition of the class is complete.
>  void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl)
> {
> -  if (!ClassDecl->hasUserDeclaredConstructor())
> +  if (ClassDecl->needsImplicitDefaultConstructor()) {
>      ++ASTContext::NumImplicitDefaultConstructors;
>
> -  // If this class inherited any constructors, declare the default
> constructor
> -  // now in case it displaces one from a base class.
> -  if (ClassDecl->needsImplicitDefaultConstructor() &&
> -      ClassDecl->hasInheritedConstructor())
> -    DeclareImplicitDefaultConstructor(ClassDecl);
> +    if (ClassDecl->hasInheritedConstructor())
> +      DeclareImplicitDefaultConstructor(ClassDecl);
> +  }
>
>    if (ClassDecl->needsImplicitCopyConstructor()) {
>      ++ASTContext::NumImplicitCopyConstructors;
> @@ -7928,12 +8001,21 @@ bool Sema::CheckUsingShadowDecl(UsingDec
>    return true;
>  }
>
> +/// Determine whether a direct base class is a virtual base class.
> +static bool isVirtualDirectBase(CXXRecordDecl *Derived, CXXRecordDecl
> *Base) {
> +  if (!Derived->getNumVBases())
> +    return false;
> +  for (auto &B : Derived->bases())
> +    if (B.getType()->getAsCXXRecordDecl() == Base)
> +      return B.isVirtual();
> +  llvm_unreachable("not a direct base class");
> +}
> +
>  /// Builds a shadow declaration corresponding to a 'using' declaration.
>  UsingShadowDecl *Sema::BuildUsingShadowDecl(Scope *S,
>                                              UsingDecl *UD,
>                                              NamedDecl *Orig,
>                                              UsingShadowDecl *PrevDecl) {
> -
>    // If we resolved to another shadow declaration, just coalesce them.
>    NamedDecl *Target = Orig;
>    if (isa<UsingShadowDecl>(Target)) {
> @@ -7941,9 +8023,21 @@ UsingShadowDecl *Sema::BuildUsingShadowD
>      assert(!isa<UsingShadowDecl>(Target) && "nested shadow declaration");
>    }
>
> -  UsingShadowDecl *Shadow
> -    = UsingShadowDecl::Create(Context, CurContext,
> -                              UD->getLocation(), UD, Target);
> +  NamedDecl *NonTemplateTarget = Target;
> +  if (auto *TargetTD = dyn_cast<TemplateDecl>(Target))
> +    NonTemplateTarget = TargetTD->getTemplatedDecl();
> +
> +  UsingShadowDecl *Shadow;
> +  if (isa<CXXConstructorDecl>(NonTemplateTarget)) {
> +    bool IsVirtualBase =
> +        isVirtualDirectBase(cast<CXXRecordDecl>(CurContext),
> +                            UD->getQualifier()->getAsRecordDecl());
> +    Shadow = ConstructorUsingShadowDecl::Create(
> +        Context, CurContext, UD->getLocation(), UD, Orig, IsVirtualBase);
> +  } else {
> +    Shadow = UsingShadowDecl::Create(Context, CurContext,
> UD->getLocation(), UD,
> +                                     Target);
> +  }
>    UD->addShadowDecl(Shadow);
>
>    Shadow->setAccess(UD->getAccess());
> @@ -8128,8 +8222,17 @@ NamedDecl *Sema::BuildUsingDeclaration(S
>      return nullptr;
>    }
>
> +  // For an inheriting constructor declaration, the name of the using
> +  // declaration is the name of a constructor in this class, not in the
> +  // base class.
> +  DeclarationNameInfo UsingName = NameInfo;
> +  if (UsingName.getName().getNameKind() == DeclarationName::
> CXXConstructorName)
> +    if (auto *RD = dyn_cast<CXXRecordDecl>(CurContext))
> +      UsingName.setName(Context.DeclarationNames.getCXXConstructorName(
> +          Context.getCanonicalType(Context.getRecordType(RD))));
> +
>    // Do the redeclaration lookup in the current scope.
> -  LookupResult Previous(*this, NameInfo, LookupUsingDeclName,
> +  LookupResult Previous(*this, UsingName, LookupUsingDeclName,
>                          ForRedeclaration);
>    Previous.setHideTags(false);
>    if (S) {
> @@ -8186,8 +8289,8 @@ NamedDecl *Sema::BuildUsingDeclaration(S
>
>    auto Build = [&](bool Invalid) {
>      UsingDecl *UD =
> -        UsingDecl::Create(Context, CurContext, UsingLoc, QualifierLoc,
> NameInfo,
> -                          HasTypenameKeyword);
> +        UsingDecl::Create(Context, CurContext, UsingLoc, QualifierLoc,
> +                          UsingName, HasTypenameKeyword);
>      UD->setAccess(AS);
>      CurContext->addDecl(UD);
>      UD->setInvalidDecl(Invalid);
> @@ -8242,6 +8345,9 @@ NamedDecl *Sema::BuildUsingDeclaration(S
>        // If we corrected to an inheriting constructor, handle it as one.
>        auto *RD = dyn_cast<CXXRecordDecl>(ND);
>        if (RD && RD->isInjectedClassName()) {
> +        // The parent of the injected class name is the class itself.
> +        RD = cast<CXXRecordDecl>(RD->getParent());
> +
>          // Fix up the information we'll use to build the using
> declaration.
>          if (Corrected.WillReplaceSpecifier()) {
>            NestedNameSpecifierLocBuilder Builder;
> @@ -8250,14 +8356,19 @@ NamedDecl *Sema::BuildUsingDeclaration(S
>            QualifierLoc = Builder.getWithLocInContext(Context);
>          }
>
> -        NameInfo.setName(Context.DeclarationNames.getCXXConstructorName(
> -            Context.getCanonicalType(Context.getRecordType(RD))));
> -        NameInfo.setNamedTypeInfo(nullptr);
> +        // In this case, the name we introduce is the name of a derived
> class
> +        // constructor.
> +        auto *CurClass = cast<CXXRecordDecl>(CurContext);
> +        UsingName.setName(Context.DeclarationNames.getCXXConstructorName(
> +            Context.getCanonicalType(Context.getRecordType(CurClass))));
> +        UsingName.setNamedTypeInfo(nullptr);
>          for (auto *Ctor : LookupConstructors(RD))
>            R.addDecl(Ctor);
> +        R.resolveKind();
>        } else {
> -        // FIXME: Pick up all the declarations if we found an overloaded
> function.
> -        NameInfo.setName(ND->getDeclName());
> +        // FIXME: Pick up all the declarations if we found an overloaded
> +        // function.
> +        UsingName.setName(ND->getDeclName());
>          R.addDecl(ND);
>        }
>      } else {
> @@ -8310,17 +8421,16 @@ NamedDecl *Sema::BuildUsingDeclaration(S
>
>    UsingDecl *UD = BuildValid();
>
> -  // The normal rules do not apply to inheriting constructor declarations.
> -  if (NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName)
> {
> +  // Some additional rules apply to inheriting constructors.
> +  if (UsingName.getName().getNameKind() ==
> +        DeclarationName::CXXConstructorName) {
>      // Suppress access diagnostics; the access check is instead performed
> at the
>      // point of use for an inheriting constructor.
>      R.suppressDiagnostics();
> -    CheckInheritingConstructorUsingDecl(UD);
> -    return UD;
> +    if (CheckInheritingConstructorUsingDecl(UD))
> +      return UD;
>    }
>
> -  // Otherwise, look up the target name.
> -
>    for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
>      UsingShadowDecl *PrevDecl = nullptr;
>      if (!CheckUsingShadowDecl(UD, *I, Previous, PrevDecl))
> @@ -8895,7 +9005,8 @@ Sema::ComputeDefaultedDefaultCtorExcepti
>  }
>
>  Sema::ImplicitExceptionSpecification
> -Sema::ComputeInheritingCtorExceptionSpec(CXXConstructorDecl *CD) {
> +Sema::ComputeInheritingCtorExceptionSpec(SourceLocation Loc,
> +                                         CXXConstructorDecl *CD) {
>    CXXRecordDecl *ClassDecl = CD->getParent();
>
>    // C++ [except.spec]p14:
> @@ -8904,36 +9015,26 @@ Sema::ComputeInheritingCtorExceptionSpec
>    if (ClassDecl->isInvalidDecl())
>      return ExceptSpec;
>
> -  // Inherited constructor.
> -  const CXXConstructorDecl *InheritedCD = CD->getInheritedConstructor();
> -  const CXXRecordDecl *InheritedDecl = InheritedCD->getParent();
> -  // FIXME: Copying or moving the parameters could add extra exceptions
> to the
> -  // set, as could the default arguments for the inherited constructor.
> This
> -  // will be addressed when we implement the resolution of core issue
> 1351.
> -  ExceptSpec.CalledDecl(CD->getLocStart(), InheritedCD);
> +  auto Inherited = CD->getInheritedConstructor();
> +  InheritedConstructorInfo ICI(*this, Loc, Inherited.getShadowDecl());
>
> -  // Direct base-class constructors.
> -  for (const auto &B : ClassDecl->bases()) {
> -    if (B.isVirtual()) // Handled below.
> -      continue;
> -
> -    if (const RecordType *BaseType = B.getType()->getAs<RecordType>()) {
> -      CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->
> getDecl());
> -      if (BaseClassDecl == InheritedDecl)
> +  // Direct and virtual base-class constructors.
> +  for (bool VBase : {false, true}) {
> +    for (CXXBaseSpecifier &B :
> +         VBase ? ClassDecl->vbases() : ClassDecl->bases()) {
> +      // Don't visit direct vbases twice.
> +      if (B.isVirtual() != VBase)
>          continue;
> -      CXXConstructorDecl *Constructor = LookupDefaultConstructor(
> BaseClassDecl);
> -      if (Constructor)
> -        ExceptSpec.CalledDecl(B.getLocStart(), Constructor);
> -    }
> -  }
>
> -  // Virtual base-class constructors.
> -  for (const auto &B : ClassDecl->vbases()) {
> -    if (const RecordType *BaseType = B.getType()->getAs<RecordType>()) {
> -      CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->
> getDecl());
> -      if (BaseClassDecl == InheritedDecl)
> +      CXXRecordDecl *BaseClass = B.getType()->getAsCXXRecordDecl();
> +      if (!BaseClass)
>          continue;
> -      CXXConstructorDecl *Constructor = LookupDefaultConstructor(
> BaseClassDecl);
> +
> +      CXXConstructorDecl *Constructor =
> +          ICI.findConstructorForBase(BaseClass,
> Inherited.getConstructor())
> +              .first;
> +      if (!Constructor)
> +        Constructor = LookupDefaultConstructor(BaseClass);
>        if (Constructor)
>          ExceptSpec.CalledDecl(B.getLocStart(), Constructor);
>      }
> @@ -9111,325 +9212,156 @@ void Sema::ActOnFinishDelayedMemberIniti
>    CheckDelayedMemberExceptionSpecs();
>  }
>
> -namespace {
> -/// Information on inheriting constructors to declare.
> -class InheritingConstructorInfo {
> -public:
> -  InheritingConstructorInfo(Sema &SemaRef, CXXRecordDecl *Derived)
> -      : SemaRef(SemaRef), Derived(Derived) {
> -    // Mark the constructors that we already have in the derived class.
> -    //
> -    // C++11 [class.inhctor]p3: [...] a constructor is implicitly
> declared [...]
> -    //   unless there is a user-declared constructor with the same
> signature in
> -    //   the class where the using-declaration appears.
> -    visitAll(Derived, &InheritingConstructorInfo::noteDeclaredInDerived);
> -  }
> -
> -  void inheritAll(CXXRecordDecl *RD) {
> -    visitAll(RD, &InheritingConstructorInfo::inherit);
> -  }
> -
> -private:
> -  /// Information about an inheriting constructor.
> -  struct InheritingConstructor {
> -    InheritingConstructor()
> -      : DeclaredInDerived(false), BaseCtor(nullptr), DerivedCtor(nullptr)
> {}
> -
> -    /// If \c true, a constructor with this signature is already declared
> -    /// in the derived class.
> -    bool DeclaredInDerived;
> -
> -    /// The constructor which is inherited.
> -    const CXXConstructorDecl *BaseCtor;
> -
> -    /// The derived constructor we declared.
> -    CXXConstructorDecl *DerivedCtor;
> -  };
> -
> -  /// Inheriting constructors with a given canonical type. There can be at
> -  /// most one such non-template constructor, and any number of templated
> -  /// constructors.
> -  struct InheritingConstructorsForType {
> -    InheritingConstructor NonTemplate;
> -    SmallVector<std::pair<TemplateParameterList *,
> InheritingConstructor>, 4>
> -        Templates;
> -
> -    InheritingConstructor &getEntry(Sema &S, const CXXConstructorDecl
> *Ctor) {
> -      if (FunctionTemplateDecl *FTD = Ctor->
> getDescribedFunctionTemplate()) {
> -        TemplateParameterList *ParamList = FTD->getTemplateParameters();
> -        for (unsigned I = 0, N = Templates.size(); I != N; ++I)
> -          if (S.TemplateParameterListsAreEqual(ParamList,
> Templates[I].first,
> -                                               false,
> S.TPL_TemplateMatch))
> -            return Templates[I].second;
> -        Templates.push_back(std::make_pair(ParamList,
> InheritingConstructor()));
> -        return Templates.back().second;
> -      }
> -
> -      return NonTemplate;
> -    }
> -  };
> -
> -  /// Get or create the inheriting constructor record for a constructor.
> -  InheritingConstructor &getEntry(const CXXConstructorDecl *Ctor,
> -                                  QualType CtorType) {
> -    return Map[CtorType.getCanonicalType()->castAs<FunctionProtoType>()]
> -        .getEntry(SemaRef, Ctor);
> -  }
> +/// Find or create the fake constructor we synthesize to model
> constructing an
> +/// object of a derived class via a constructor of a base class.
> +CXXConstructorDecl *
> +Sema::findInheritingConstructor(SourceLocation Loc,
> +                                CXXConstructorDecl *BaseCtor,
> +                                ConstructorUsingShadowDecl *Shadow) {
> +  CXXRecordDecl *Derived = Shadow->getParent();
> +  SourceLocation UsingLoc = Shadow->getLocation();
> +
> +  // FIXME: Add a new kind of DeclarationName for an inherited
> constructor.
> +  // For now we use the name of the base class constructor as a member of
> the
> +  // derived class to indicate a (fake) inherited constructor name.
> +  DeclarationName Name = BaseCtor->getDeclName();
> +
> +  // Check to see if we already have a fake constructor for this inherited
> +  // constructor call.
> +  for (NamedDecl *Ctor : Derived->lookup(Name))
> +    if (declaresSameEntity(cast<CXXConstructorDecl>(Ctor)
> +                               ->getInheritedConstructor()
> +                               .getConstructor(),
> +                           BaseCtor))
> +      return cast<CXXConstructorDecl>(Ctor);
> +
> +  DeclarationNameInfo NameInfo(Name, UsingLoc);
> +  TypeSourceInfo *TInfo =
> +      Context.getTrivialTypeSourceInfo(BaseCtor->getType(), UsingLoc);
> +  FunctionProtoTypeLoc ProtoLoc =
> +      TInfo->getTypeLoc().IgnoreParens().castAs<FunctionProtoTypeLoc>();
> +
> +  // Check the inherited constructor is valid and find the list of base
> classes
> +  // from which it was inherited.
> +  InheritedConstructorInfo ICI(*this, Loc, Shadow);
> +
> +  bool Constexpr =
> +      BaseCtor->isConstexpr() &&
> +      defaultedSpecialMemberIsConstexpr(*this, Derived,
> CXXDefaultConstructor,
> +                                        false, BaseCtor, &ICI);
> +
> +  CXXConstructorDecl *DerivedCtor = CXXConstructorDecl::Create(
> +      Context, Derived, UsingLoc, NameInfo, TInfo->getType(), TInfo,
> +      BaseCtor->isExplicit(), /*Inline=*/true,
> +      /*ImplicitlyDeclared=*/true, Constexpr,
> +      InheritedConstructor(Shadow, BaseCtor));
> +  if (Shadow->isInvalidDecl())
> +    DerivedCtor->setInvalidDecl();
> +
> +  // Build an unevaluated exception specification for this fake
> constructor.
> +  const FunctionProtoType *FPT = TInfo->getType()->castAs<
> FunctionProtoType>();
> +  FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
> +  EPI.ExceptionSpec.Type = EST_Unevaluated;
> +  EPI.ExceptionSpec.SourceDecl = DerivedCtor;
> +  DerivedCtor->setType(Context.getFunctionType(FPT->getReturnType(),
> +                                               FPT->getParamTypes(),
> EPI));
> +
> +  // Build the parameter declarations.
> +  SmallVector<ParmVarDecl *, 16> ParamDecls;
> +  for (unsigned I = 0, N = FPT->getNumParams(); I != N; ++I) {
> +    TypeSourceInfo *TInfo =
> +        Context.getTrivialTypeSourceInfo(FPT->getParamType(I), UsingLoc);
> +    ParmVarDecl *PD = ParmVarDecl::Create(
> +        Context, DerivedCtor, UsingLoc, UsingLoc,
> /*IdentifierInfo=*/nullptr,
> +        FPT->getParamType(I), TInfo, SC_None, /*DefaultArg=*/nullptr);
> +    PD->setScopeInfo(0, I);
> +    PD->setImplicit();
> +    // Ensure attributes are propagated onto parameters (this matters for
> +    // format, pass_object_size, ...).
> +    mergeDeclAttributes(PD, BaseCtor->getParamDecl(I));
> +    ParamDecls.push_back(PD);
> +    ProtoLoc.setParam(I, PD);
> +  }
> +
> +  // Set up the new constructor.
> +  assert(!BaseCtor->isDeleted() && "should not use deleted constructor");
> +  DerivedCtor->setAccess(BaseCtor->getAccess());
> +  DerivedCtor->setParams(ParamDecls);
> +  Derived->addDecl(DerivedCtor);
> +  return DerivedCtor;
> +}
>
> -  typedef void (InheritingConstructorInfo::*VisitFn)(const
> CXXConstructorDecl*);
> -
> -  /// Process all constructors for a class.
> -  void visitAll(const CXXRecordDecl *RD, VisitFn Callback) {
> -    for (const auto *Ctor : RD->ctors())
> -      (this->*Callback)(Ctor);
> -    for (CXXRecordDecl::specific_decl_iterator<FunctionTemplateDecl>
> -             I(RD->decls_begin()), E(RD->decls_end());
> -         I != E; ++I) {
> -      const FunctionDecl *FD = (*I)->getTemplatedDecl();
> -      if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(
> FD))
> -        (this->*Callback)(CD);
> -    }
> -  }
> +void Sema::DefineInheritingConstructor(SourceLocation CurrentLocation,
> +                                       CXXConstructorDecl *Constructor) {
> +  CXXRecordDecl *ClassDecl = Constructor->getParent();
> +  assert(Constructor->getInheritedConstructor() &&
> +         !Constructor->doesThisDeclarationHaveABody() &&
> +         !Constructor->isDeleted());
> +  if (Constructor->isInvalidDecl())
> +    return;
>
> -  /// Note that a constructor (or constructor template) was declared in
> Derived.
> -  void noteDeclaredInDerived(const CXXConstructorDecl *Ctor) {
> -    getEntry(Ctor, Ctor->getType()).DeclaredInDerived = true;
> -  }
> +  ConstructorUsingShadowDecl *Shadow =
> +      Constructor->getInheritedConstructor().getShadowDecl();
> +  CXXConstructorDecl *InheritedCtor =
> +      Constructor->getInheritedConstructor().getConstructor();
>
> -  /// Inherit a single constructor.
> -  void inherit(const CXXConstructorDecl *Ctor) {
> -    const FunctionProtoType *CtorType =
> -        Ctor->getType()->castAs<FunctionProtoType>();
> -    ArrayRef<QualType> ArgTypes = CtorType->getParamTypes();
> -    FunctionProtoType::ExtProtoInfo EPI = CtorType->getExtProtoInfo();
> +  // [class.inhctor.init]p1:
> +  //   initialization proceeds as if a defaulted default constructor is
> used to
> +  //   initialize the D object and each base class subobject from which
> the
> +  //   constructor was inherited
>
> -    SourceLocation UsingLoc = getUsingLoc(Ctor->getParent());
> +  InheritedConstructorInfo ICI(*this, CurrentLocation, Shadow);
> +  CXXRecordDecl *RD = Shadow->getParent();
> +  SourceLocation InitLoc = Shadow->getLocation();
>
> -    // Core issue (no number yet): the ellipsis is always discarded.
> -    if (EPI.Variadic) {
> -      SemaRef.Diag(UsingLoc, diag::warn_using_decl_constructor_ellipsis);
> -      SemaRef.Diag(Ctor->getLocation(),
> -                   diag::note_using_decl_constructor_ellipsis);
> -      EPI.Variadic = false;
> -    }
> +  // Initializations are performed "as if by a defaulted default
> constructor",
> +  // so enter the appropriate scope.
> +  SynthesizedFunctionScope Scope(*this, Constructor);
> +  DiagnosticErrorTrap Trap(Diags);
>
> -    // Declare a constructor for each number of parameters.
> -    //
> -    // C++11 [class.inhctor]p1:
> -    //   The candidate set of inherited constructors from the class X
> named in
> -    //   the using-declaration consists of [... modulo defects ...] for
> each
> -    //   constructor or constructor template of X, the set of
> constructors or
> -    //   constructor templates that results from omitting any ellipsis
> parameter
> -    //   specification and successively omitting parameters with a default
> -    //   argument from the end of the parameter-type-list
> -    unsigned MinParams = minParamsToInherit(Ctor);
> -    unsigned Params = Ctor->getNumParams();
> -    if (Params >= MinParams) {
> -      do
> -        declareCtor(UsingLoc, Ctor,
> -                    SemaRef.Context.getFunctionType(
> -                        Ctor->getReturnType(), ArgTypes.slice(0, Params),
> EPI));
> -      while (Params > MinParams &&
> -             Ctor->getParamDecl(--Params)->hasDefaultArg());
> -    }
> -  }
> -
> -  /// Find the using-declaration which specified that we should inherit
> the
> -  /// constructors of \p Base.
> -  SourceLocation getUsingLoc(const CXXRecordDecl *Base) {
> -    // No fancy lookup required; just look for the base constructor name
> -    // directly within the derived class.
> -    ASTContext &Context = SemaRef.Context;
> -    DeclarationName Name = Context.DeclarationNames.
> getCXXConstructorName(
> -        Context.getCanonicalType(Context.getRecordType(Base)));
> -    DeclContext::lookup_result Decls = Derived->lookup(Name);
> -    return Decls.empty() ? Derived->getLocation() :
> Decls[0]->getLocation();
> -  }
> -
> -  unsigned minParamsToInherit(const CXXConstructorDecl *Ctor) {
> -    // C++11 [class.inhctor]p3:
> -    //   [F]or each constructor template in the candidate set of inherited
> -    //   constructors, a constructor template is implicitly declared
> -    if (Ctor->getDescribedFunctionTemplate())
> -      return 0;
> -
> -    //   For each non-template constructor in the candidate set of
> inherited
> -    //   constructors other than a constructor having no parameters or a
> -    //   copy/move constructor having a single parameter, a constructor is
> -    //   implicitly declared [...]
> -    if (Ctor->getNumParams() == 0)
> -      return 1;
> -    if (Ctor->isCopyOrMoveConstructor())
> -      return 2;
> -
> -    // Per discussion on core reflector, never inherit a constructor which
> -    // would become a default, copy, or move constructor of Derived
> either.
> -    const ParmVarDecl *PD = Ctor->getParamDecl(0);
> -    const ReferenceType *RT = PD->getType()->getAs<ReferenceType>();
> -    return (RT && RT->getPointeeCXXRecordDecl() == Derived) ? 2 : 1;
> -  }
> -
> -  /// Declare a single inheriting constructor, inheriting the specified
> -  /// constructor, with the given type.
> -  void declareCtor(SourceLocation UsingLoc, const CXXConstructorDecl
> *BaseCtor,
> -                   QualType DerivedType) {
> -    InheritingConstructor &Entry = getEntry(BaseCtor, DerivedType);
> -
> -    // C++11 [class.inhctor]p3:
> -    //   ... a constructor is implicitly declared with the same
> constructor
> -    //   characteristics unless there is a user-declared constructor with
> -    //   the same signature in the class where the using-declaration
> appears
> -    if (Entry.DeclaredInDerived)
> -      return;
> +  // Build explicit initializers for all base classes from which the
> +  // constructor was inherited.
> +  SmallVector<CXXCtorInitializer*, 8> Inits;
> +  for (bool VBase : {false, true}) {
> +    for (CXXBaseSpecifier &B : VBase ? RD->vbases() : RD->bases()) {
> +      if (B.isVirtual() != VBase)
> +        continue;
>
> -    // C++11 [class.inhctor]p7:
> -    //   If two using-declarations declare inheriting constructors with
> the
> -    //   same signature, the program is ill-formed
> -    if (Entry.DerivedCtor) {
> -      if (BaseCtor->getParent() != Entry.BaseCtor->getParent()) {
> -        // Only diagnose this once per constructor.
> -        if (Entry.DerivedCtor->isInvalidDecl())
> -          return;
> -        Entry.DerivedCtor->setInvalidDecl();
> -
> -        SemaRef.Diag(UsingLoc, diag::err_using_decl_
> constructor_conflict);
> -        SemaRef.Diag(BaseCtor->getLocation(),
> -                     diag::note_using_decl_constructor_conflict_current_
> ctor);
> -        SemaRef.Diag(Entry.BaseCtor->getLocation(),
> -                     diag::note_using_decl_constructor_conflict_previous_
> ctor);
> -        SemaRef.Diag(Entry.DerivedCtor->getLocation(),
> -                     diag::note_using_decl_constructor_conflict_previous_
> using);
> -      } else {
> -        // Core issue (no number): if the same inheriting constructor is
> -        // produced by multiple base class constructors from the same base
> -        // class, the inheriting constructor is defined as deleted.
> -        SemaRef.SetDeclDeleted(Entry.DerivedCtor, UsingLoc);
> -      }
> +      auto *BaseRD = B.getType()->getAsCXXRecordDecl();
> +      if (!BaseRD)
> +        continue;
>
> -      return;
> -    }
> +      auto BaseCtor = ICI.findConstructorForBase(BaseRD, InheritedCtor);
> +      if (!BaseCtor.first)
> +        continue;
>
> -    ASTContext &Context = SemaRef.Context;
> -    DeclarationName Name = Context.DeclarationNames.
> getCXXConstructorName(
> -        Context.getCanonicalType(Context.getRecordType(Derived)));
> -    DeclarationNameInfo NameInfo(Name, UsingLoc);
> -
> -    TemplateParameterList *TemplateParams = nullptr;
> -    if (const FunctionTemplateDecl *FTD =
> -            BaseCtor->getDescribedFunctionTemplate()) {
> -      TemplateParams = FTD->getTemplateParameters();
> -      // We're reusing template parameters from a different DeclContext.
> This
> -      // is questionable at best, but works out because the template
> depth in
> -      // both places is guaranteed to be 0.
> -      // FIXME: Rebuild the template parameters in the new context, and
> -      // transform the function type to refer to them.
> -    }
> +      MarkFunctionReferenced(CurrentLocation, BaseCtor.first);
> +      ExprResult Init = new (Context) CXXInheritedCtorInitExpr(
> +          InitLoc, B.getType(), BaseCtor.first, VBase, BaseCtor.second);
>
> -    // Build type source info pointing at the using-declaration. This is
> -    // required by template instantiation.
> -    TypeSourceInfo *TInfo =
> -        Context.getTrivialTypeSourceInfo(DerivedType, UsingLoc);
> -    FunctionProtoTypeLoc ProtoLoc =
> -        TInfo->getTypeLoc().IgnoreParens().castAs<
> FunctionProtoTypeLoc>();
> -
> -    CXXConstructorDecl *DerivedCtor = CXXConstructorDecl::Create(
> -        Context, Derived, UsingLoc, NameInfo, DerivedType,
> -        TInfo, BaseCtor->isExplicit(), /*Inline=*/true,
> -        /*ImplicitlyDeclared=*/true, /*Constexpr=*/BaseCtor->
> isConstexpr());
> -
> -    // Build an unevaluated exception specification for this constructor.
> -    const FunctionProtoType *FPT = DerivedType->castAs<
> FunctionProtoType>();
> -    FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
> -    EPI.ExceptionSpec.Type = EST_Unevaluated;
> -    EPI.ExceptionSpec.SourceDecl = DerivedCtor;
> -    DerivedCtor->setType(Context.getFunctionType(FPT->getReturnType(),
> -                                                 FPT->getParamTypes(),
> EPI));
> -
> -    // Build the parameter declarations.
> -    SmallVector<ParmVarDecl *, 16> ParamDecls;
> -    for (unsigned I = 0, N = FPT->getNumParams(); I != N; ++I) {
> -      TypeSourceInfo *TInfo =
> -          Context.getTrivialTypeSourceInfo(FPT->getParamType(I),
> UsingLoc);
> -      ParmVarDecl *PD = ParmVarDecl::Create(
> -          Context, DerivedCtor, UsingLoc, UsingLoc,
> /*IdentifierInfo=*/nullptr,
> -          FPT->getParamType(I), TInfo, SC_None, /*DefaultArg=*/nullptr);
> -      PD->setScopeInfo(0, I);
> -      PD->setImplicit();
> -      ParamDecls.push_back(PD);
> -      ProtoLoc.setParam(I, PD);
> -    }
> -
> -    // Set up the new constructor.
> -    DerivedCtor->setAccess(BaseCtor->getAccess());
> -    DerivedCtor->setParams(ParamDecls);
> -    DerivedCtor->setInheritedConstructor(BaseCtor);
> -    if (BaseCtor->isDeleted())
> -      SemaRef.SetDeclDeleted(DerivedCtor, UsingLoc);
> -
> -    // If this is a constructor template, build the template declaration.
> -    if (TemplateParams) {
> -      FunctionTemplateDecl *DerivedTemplate =
> -          FunctionTemplateDecl::Create(SemaRef.Context, Derived,
> UsingLoc, Name,
> -                                       TemplateParams, DerivedCtor);
> -      DerivedTemplate->setAccess(BaseCtor->getAccess());
> -      DerivedCtor->setDescribedFunctionTemplate(DerivedTemplate);
> -      Derived->addDecl(DerivedTemplate);
> -    } else {
> -      Derived->addDecl(DerivedCtor);
> +      auto *TInfo = Context.getTrivialTypeSourceInfo(B.getType(),
> InitLoc);
> +      Inits.push_back(new (Context) CXXCtorInitializer(
> +          Context, TInfo, VBase, InitLoc, Init.get(), InitLoc,
> +          SourceLocation()));
>      }
> -
> -    Entry.BaseCtor = BaseCtor;
> -    Entry.DerivedCtor = DerivedCtor;
>    }
>
> -  Sema &SemaRef;
> -  CXXRecordDecl *Derived;
> -  typedef llvm::DenseMap<const Type *, InheritingConstructorsForType>
> MapType;
> -  MapType Map;
> -};
> -}
> -
> -void Sema::DeclareInheritingConstructors(CXXRecordDecl *ClassDecl) {
> -  // Defer declaring the inheriting constructors until the class is
> -  // instantiated.
> -  if (ClassDecl->isDependentContext())
> -    return;
> -
> -  // Find base classes from which we might inherit constructors.
> -  SmallVector<CXXRecordDecl*, 4> InheritedBases;
> -  for (const auto &BaseIt : ClassDecl->bases())
> -    if (BaseIt.getInheritConstructors())
> -      InheritedBases.push_back(BaseIt.getType()->getAsCXXRecordDecl());
> -
> -  // Go no further if we're not inheriting any constructors.
> -  if (InheritedBases.empty())
> -    return;
> -
> -  // Declare the inherited constructors.
> -  InheritingConstructorInfo ICI(*this, ClassDecl);
> -  for (unsigned I = 0, N = InheritedBases.size(); I != N; ++I)
> -    ICI.inheritAll(InheritedBases[I]);
> -}
> +  // We now proceed as if for a defaulted default constructor, with the
> relevant
> +  // initializers replaced.
>
> -void Sema::DefineInheritingConstructor(SourceLocation CurrentLocation,
> -                                       CXXConstructorDecl *Constructor) {
> -  CXXRecordDecl *ClassDecl = Constructor->getParent();
> -  assert(Constructor->getInheritedConstructor() &&
> -         !Constructor->doesThisDeclarationHaveABody() &&
> -         !Constructor->isDeleted());
> -
> -  SynthesizedFunctionScope Scope(*this, Constructor);
> -  DiagnosticErrorTrap Trap(Diags);
> -  if (SetCtorInitializers(Constructor, /*AnyErrors=*/false) ||
> -      Trap.hasErrorOccurred()) {
> -    Diag(CurrentLocation, diag::note_inhctor_synthesized_at)
> -      << Context.getTagDeclType(ClassDecl);
> +  bool HadError = SetCtorInitializers(Constructor, /*AnyErrors*/false,
> Inits);
> +  if (HadError || Trap.hasErrorOccurred()) {
> +    Diag(CurrentLocation, diag::note_inhctor_synthesized_at) << RD;
>      Constructor->setInvalidDecl();
>      return;
>    }
>
> -  SourceLocation Loc = Constructor->getLocation();
> -  Constructor->setBody(new (Context) CompoundStmt(Loc));
> +  // The exception specification is needed because we are defining the
> +  // function.
> +  ResolveExceptionSpec(CurrentLocation,
> +                       Constructor->getType()->
> castAs<FunctionProtoType>());
> +
> +  Constructor->setBody(new (Context) CompoundStmt(InitLoc));
>
>    Constructor->markUsed(Context);
>    MarkVTableUsed(CurrentLocation, ClassDecl);
> @@ -9437,8 +9369,9 @@ void Sema::DefineInheritingConstructor(S
>    if (ASTMutationListener *L = getASTMutationListener()) {
>      L->CompletedImplicitDefinition(Constructor);
>    }
> -}
>
> +  DiagnoseUninitializedFields(*this, Constructor);
> +}
>
>  Sema::ImplicitExceptionSpecification
>  Sema::ComputeDefaultedDtorExceptionSpec(CXXMethodDecl *MD) {
> @@ -11481,10 +11414,11 @@ Sema::BuildCXXConstructExpr(SourceLocati
>    //       with the same cv-unqualified type, the copy/move operation
>    //       can be omitted by constructing the temporary object
>    //       directly into the target of the omitted copy/move
> -  if (ConstructKind == CXXConstructExpr::CK_Complete &&
> +  if (ConstructKind == CXXConstructExpr::CK_Complete && Constructor &&
>        Constructor->isCopyOrMoveConstructor() &&
> hasOneRealArgument(ExprArgs)) {
>      Expr *SubExpr = ExprArgs[0];
> -    Elidable = SubExpr->isTemporaryObject(Context,
> Constructor->getParent());
> +    Elidable = SubExpr->isTemporaryObject(
> +        Context, cast<CXXRecordDecl>(FoundDecl->getDeclContext()));
>    }
>
>    return BuildCXXConstructExpr(ConstructLoc, DeclInitType,
> @@ -11507,6 +11441,9 @@ Sema::BuildCXXConstructExpr(SourceLocati
>                              bool RequiresZeroInit,
>                              unsigned ConstructKind,
>                              SourceRange ParenRange) {
> +  if (auto *Shadow = dyn_cast<ConstructorUsingShadowDecl>(FoundDecl))
> +    Constructor = findInheritingConstructor(ConstructLoc, Constructor,
> Shadow);
> +
>    return BuildCXXConstructExpr(
>        ConstructLoc, DeclInitType, Constructor, Elidable, ExprArgs,
>        HadMultipleCandidates, IsListInitialization,
> IsStdInitListInitialization,
> @@ -11526,7 +11463,12 @@ Sema::BuildCXXConstructExpr(SourceLocati
>                              bool RequiresZeroInit,
>                              unsigned ConstructKind,
>                              SourceRange ParenRange) {
> +  assert(declaresSameEntity(
> +             Constructor->getParent(),
> +             DeclInitType->getBaseElementTypeUnsafe()->getAsCXXRecordDecl())
> &&
> +         "given constructor for wrong type");
>    MarkFunctionReferenced(ConstructLoc, Constructor);
> +
>    return CXXConstructExpr::Create(
>        Context, DeclInitType, ConstructLoc, Constructor, Elidable,
>        ExprArgs, HadMultipleCandidates, IsListInitialization,
>
> Modified: cfe/trunk/lib/Sema/SemaExceptionSpec.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaExceptionSpec.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaExceptionSpec.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExceptionSpec.cpp Tue Jun 28 14:03:57 2016
> @@ -1001,6 +1001,10 @@ CanThrowResult Sema::canThrow(const Expr
>      return mergeCanThrow(CT, canSubExprsThrow(*this, E));
>    }
>
> +  case Expr::CXXInheritedCtorInitExprClass:
> +    return canCalleeThrow(*this, E,
> +                          cast<CXXInheritedCtorInitExpr>
> (E)->getConstructor());
> +
>    case Expr::LambdaExprClass: {
>      const LambdaExpr *Lambda = cast<LambdaExpr>(E);
>      CanThrowResult CT = CT_Cannot;
>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaExpr.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jun 28 14:03:57 2016
> @@ -221,21 +221,6 @@ void Sema::NoteDeletedFunction(FunctionD
>      return;
>    }
>
> -  if (CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(Decl)) {
> -    if (CXXConstructorDecl *BaseCD =
> -            const_cast<CXXConstructorDecl*>(CD->getInheritedConstructor()))
> {
> -      Diag(Decl->getLocation(), diag::note_inherited_deleted_here);
> -      if (BaseCD->isDeleted()) {
> -        NoteDeletedFunction(BaseCD);
> -      } else {
> -        // FIXME: An explanation of why exactly it can't be inherited
> -        // would be nice.
> -        Diag(BaseCD->getLocation(), diag::note_cannot_inherit);
> -      }
> -      return;
> -    }
> -  }
> -
>    Diag(Decl->getLocation(), diag::note_availability_specified_here)
>      << Decl << true;
>  }
>
> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaExprCXX.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Jun 28 14:03:57 2016
> @@ -3186,9 +3186,8 @@ static ExprResult BuildCXXCastArgument(S
>      if (S.CompleteConstructorCall(Constructor, From, CastLoc,
> ConstructorArgs))
>        return ExprError();
>
> -    S.CheckConstructorAccess(CastLoc, Constructor,
> -                             InitializedEntity::InitializeTemporary(Ty),
> -                             Constructor->getAccess());
> +    S.CheckConstructorAccess(CastLoc, Constructor, FoundDecl,
> +                             InitializedEntity::InitializeTemporary(Ty));
>      if (S.DiagnoseUseOfDecl(Method, CastLoc))
>        return ExprError();
>
>
> Modified: cfe/trunk/lib/Sema/SemaInit.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaInit.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaInit.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaInit.cpp Tue Jun 28 14:03:57 2016
> @@ -5519,8 +5519,8 @@ static ExprResult CopyObject(Sema &S,
>    SmallVector<Expr*, 8> ConstructorArgs;
>    CurInit.get(); // Ownership transferred into MultiExprArg, below.
>
> -  S.CheckConstructorAccess(Loc, Constructor, Entity,
> -                           Best->FoundDecl.getAccess(), IsExtraneousCopy);
> +  S.CheckConstructorAccess(Loc, Constructor, Best->FoundDecl, Entity,
> +                           IsExtraneousCopy);
>
>    if (IsExtraneousCopy) {
>      // If this is a totally extraneous copy for C++03 reference
> @@ -5603,7 +5603,7 @@ static void CheckCXX98CompatAccessibleCo
>    switch (OR) {
>    case OR_Success:
>      S.CheckConstructorAccess(Loc, cast<CXXConstructorDecl>(Best-
> >Function),
> -                             Entity, Best->FoundDecl.getAccess(), Diag);
> +                             Best->FoundDecl, Entity, Diag);
>      // FIXME: Check default arguments as far as that's possible.
>      break;
>
> @@ -5729,7 +5729,6 @@ PerformConstructorInitialization(Sema &S
>
>    if (isExplicitTemporary(Entity, Kind, NumArgs)) {
>      // An explicitly-constructed temporary, e.g., X(1, 2).
> -    S.MarkFunctionReferenced(Loc, Constructor);
>      if (S.DiagnoseUseOfDecl(Constructor, Loc))
>        return ExprError();
>
> @@ -5741,6 +5740,11 @@ PerformConstructorInitialization(Sema &S
>        ? SourceRange(LBraceLoc, RBraceLoc)
>        : Kind.getParenRange();
>
> +    if (auto *Shadow = dyn_cast<ConstructorUsingShadowDecl>(
> +            Step.Function.FoundDecl.getDecl()))
> +      Constructor = S.findInheritingConstructor(Loc, Constructor,
> Shadow);
> +    S.MarkFunctionReferenced(Loc, Constructor);
> +
>      CurInit = new (S.Context) CXXTemporaryObjectExpr(
>          S.Context, Constructor, TSInfo,
>          ConstructorArgs, ParenOrBraceRange, HadMultipleCandidates,
> @@ -5795,8 +5799,7 @@ PerformConstructorInitialization(Sema &S
>      return ExprError();
>
>    // Only check access if all of that succeeded.
> -  S.CheckConstructorAccess(Loc, Constructor, Entity,
> -                           Step.Function.FoundDecl.getAccess());
> +  S.CheckConstructorAccess(Loc, Constructor, Step.Function.FoundDecl,
> Entity);
>    if (S.DiagnoseUseOfDecl(Step.Function.FoundDecl, Loc))
>      return ExprError();
>
> @@ -6529,8 +6532,8 @@ InitializationSequence::Perform(Sema &S,
>          if (CurInit.isInvalid())
>            return ExprError();
>
> -        S.CheckConstructorAccess(Kind.getLocation(), Constructor, Entity,
> -                                 FoundFn.getAccess());
> +        S.CheckConstructorAccess(Kind.getLocation(), Constructor,
> FoundFn,
> +                                 Entity);
>          if (S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation()))
>            return ExprError();
>
> @@ -7296,13 +7299,16 @@ bool InitializationSequence::Diagnose(Se
>            // initialize this base/member.
>            CXXConstructorDecl *Constructor
>              = cast<CXXConstructorDecl>(S.CurContext);
> +          const CXXRecordDecl *InheritedFrom = nullptr;
> +          if (auto Inherited = Constructor->getInheritedConstructor())
> +            InheritedFrom = Inherited.getShadowDecl()->
> getNominatedBaseClass();
>            if (Entity.getKind() == InitializedEntity::EK_Base) {
>              S.Diag(Kind.getLocation(), diag::err_missing_default_ctor)
> -              << (Constructor->getInheritedConstructor() ? 2 :
> -                  Constructor->isImplicit() ? 1 : 0)
> +              << (InheritedFrom ? 2 : Constructor->isImplicit() ? 1 : 0)
>                << S.Context.getTypeDeclType(Constructor->getParent())
>                << /*base=*/0
> -              << Entity.getType();
> +              << Entity.getType()
> +              << InheritedFrom;
>
>              RecordDecl *BaseDecl
>                = Entity.getBaseSpecifier()->getType()->getAs<RecordType>()
> @@ -7311,11 +7317,11 @@ bool InitializationSequence::Diagnose(Se
>                << S.Context.getTagDeclType(BaseDecl);
>            } else {
>              S.Diag(Kind.getLocation(), diag::err_missing_default_ctor)
> -              << (Constructor->getInheritedConstructor() ? 2 :
> -                  Constructor->isImplicit() ? 1 : 0)
> +              << (InheritedFrom ? 2 : Constructor->isImplicit() ? 1 : 0)
>                << S.Context.getTypeDeclType(Constructor->getParent())
>                << /*member=*/1
> -              << Entity.getName();
> +              << Entity.getName()
> +              << InheritedFrom;
>              S.Diag(Entity.getDecl()->getLocation(),
>                     diag::note_member_declared_at);
>
>
> Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaLookup.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaLookup.cpp Tue Jun 28 14:03:57 2016
> @@ -2943,42 +2943,38 @@ Sema::SpecialMemberOverloadResult *Sema:
>    // from an external source and invalidate lookup_result.
>    SmallVector<NamedDecl *, 8> Candidates(R.begin(), R.end());
>
> -  for (auto *Cand : Candidates) {
> -    if (Cand->isInvalidDecl())
> +  for (NamedDecl *CandDecl : Candidates) {
> +    if (CandDecl->isInvalidDecl())
>        continue;
>
> -    if (UsingShadowDecl *U = dyn_cast<UsingShadowDecl>(Cand)) {
> -      // FIXME: [namespace.udecl]p15 says that we should only consider a
> -      // using declaration here if it does not match a declaration in the
> -      // derived class. We do not implement this correctly in other cases
> -      // either.
> -      Cand = U->getTargetDecl();
> -
> -      if (Cand->isInvalidDecl())
> -        continue;
> -    }
> -
> -    if (CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(Cand)) {
> +    DeclAccessPair Cand = DeclAccessPair::make(CandDecl, AS_public);
> +    auto CtorInfo = getConstructorInfo(Cand);
> +    if (CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(Cand->getUnderlyingDecl()))
> {
>        if (SM == CXXCopyAssignment || SM == CXXMoveAssignment)
> -        AddMethodCandidate(M, DeclAccessPair::make(M, AS_public), RD,
> ThisTy,
> -                           Classification, llvm::makeArrayRef(&Arg,
> NumArgs),
> -                           OCS, true);
> -      else
> -        AddOverloadCandidate(M, DeclAccessPair::make(M, AS_public),
> +        AddMethodCandidate(M, Cand, RD, ThisTy, Classification,
> +                           llvm::makeArrayRef(&Arg, NumArgs), OCS, true);
> +      else if (CtorInfo)
> +        AddOverloadCandidate(CtorInfo.Constructor, CtorInfo.FoundDecl,
>                               llvm::makeArrayRef(&Arg, NumArgs), OCS,
> true);
> +      else
> +        AddOverloadCandidate(M, Cand, llvm::makeArrayRef(&Arg, NumArgs),
> OCS,
> +                             true);
>      } else if (FunctionTemplateDecl *Tmpl =
> -                 dyn_cast<FunctionTemplateDecl>(Cand)) {
> +                 dyn_cast<FunctionTemplateDecl>(Cand->getUnderlyingDecl()))
> {
>        if (SM == CXXCopyAssignment || SM == CXXMoveAssignment)
> -        AddMethodTemplateCandidate(Tmpl, DeclAccessPair::make(Tmpl,
> AS_public),
> -                                   RD, nullptr, ThisTy, Classification,
> -                                   llvm::makeArrayRef(&Arg, NumArgs),
> -                                   OCS, true);
> +        AddMethodTemplateCandidate(
> +            Tmpl, Cand, RD, nullptr, ThisTy, Classification,
> +            llvm::makeArrayRef(&Arg, NumArgs), OCS, true);
> +      else if (CtorInfo)
> +        AddTemplateOverloadCandidate(
> +            CtorInfo.ConstructorTmpl, CtorInfo.FoundDecl, nullptr,
> +            llvm::makeArrayRef(&Arg, NumArgs), OCS, true);
>        else
> -        AddTemplateOverloadCandidate(Tmpl, DeclAccessPair::make(Tmpl,
> AS_public),
> -                                     nullptr, llvm::makeArrayRef(&Arg,
> NumArgs),
> -                                     OCS, true);
> +        AddTemplateOverloadCandidate(
> +            Tmpl, Cand, nullptr, llvm::makeArrayRef(&Arg, NumArgs), OCS,
> true);
>      } else {
> -      assert(isa<UsingDecl>(Cand) && "illegal Kind of operator = Decl");
> +      assert(isa<UsingDecl>(Cand.getDecl()) &&
> +             "illegal Kind of operator = Decl");
>      }
>    }
>
>
> Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaOverload.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Jun 28 14:03:57 2016
> @@ -3055,7 +3055,7 @@ IsInitializerListConstructorConversion(S
>                                         bool AllowExplicit) {
>    for (auto *D : S.LookupConstructors(To)) {
>      auto Info = getConstructorInfo(D);
> -    if (!Info.Constructor)
> +    if (!Info)
>        continue;
>
>      bool Usable = !Info.Constructor->isInvalidDecl() &&
> @@ -3174,7 +3174,7 @@ IsUserDefinedConversion(Sema &S, Expr *F
>
>        for (auto *D : S.LookupConstructors(ToRecordDecl)) {
>          auto Info = getConstructorInfo(D);
> -        if (!Info.Constructor)
> +        if (!Info)
>            continue;
>
>          bool Usable = !Info.Constructor->isInvalidDecl();
> @@ -8646,6 +8646,25 @@ bool clang::isBetterOverloadCandidate(Se
>        return BetterTemplate == Cand1.Function->getPrimaryTemplate();
>    }
>
> +  // FIXME: Work around a defect in the C++17 inheriting constructor
> wording.
> +  // A derived-class constructor beats an (inherited) base class
> constructor.
> +  bool Cand1IsInherited =
> +      dyn_cast_or_null<ConstructorUsingShadowDecl>(
> Cand1.FoundDecl.getDecl());
> +  bool Cand2IsInherited =
> +      dyn_cast_or_null<ConstructorUsingShadowDecl>(
> Cand2.FoundDecl.getDecl());
> +  if (Cand1IsInherited != Cand2IsInherited)
> +    return Cand2IsInherited;
> +  else if (Cand1IsInherited) {
> +    assert(Cand2IsInherited);
> +    auto *Cand1Class = cast<CXXRecordDecl>(Cand1.
> Function->getDeclContext());
> +    auto *Cand2Class = cast<CXXRecordDecl>(Cand2.
> Function->getDeclContext());
> +    if (Cand1Class->isDerivedFrom(Cand2Class))
> +      return true;
> +    if (Cand2Class->isDerivedFrom(Cand1Class))
> +      return false;
> +    // Inherited from sibling base classes: still ambiguous.
> +  }
> +
>    // Check for enable_if value-based overload resolution.
>    if (Cand1.Function && Cand2.Function) {
>      Comparison Cmp = compareEnableIfAttrs(S, Cand1.Function,
> Cand2.Function);
> @@ -8837,7 +8856,8 @@ enum OverloadCandidateKind {
>    oc_implicit_move_constructor,
>    oc_implicit_copy_assignment,
>    oc_implicit_move_assignment,
> -  oc_implicit_inherited_constructor
> +  oc_inherited_constructor,
> +  oc_inherited_constructor_template
>  };
>
>  OverloadCandidateKind ClassifyOverloadCandidate(Sema &S,
> @@ -8853,11 +8873,13 @@ OverloadCandidateKind ClassifyOverloadCa
>    }
>
>    if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(Fn)) {
> -    if (!Ctor->isImplicit())
> -      return isTemplate ? oc_constructor_template : oc_constructor;
> -
> -    if (Ctor->getInheritedConstructor())
> -      return oc_implicit_inherited_constructor;
> +    if (!Ctor->isImplicit()) {
> +      if (isa<ConstructorUsingShadowDecl>(Found))
> +        return isTemplate ? oc_inherited_constructor_template
> +                          : oc_inherited_constructor;
> +      else
> +        return isTemplate ? oc_constructor_template : oc_constructor;
> +    }
>
>      if (Ctor->isDefaultConstructor())
>        return oc_implicit_default_constructor;
> @@ -8889,14 +8911,13 @@ OverloadCandidateKind ClassifyOverloadCa
>    return isTemplate ? oc_function_template : oc_function;
>  }
>
> -void MaybeEmitInheritedConstructorNote(Sema &S, Decl *Fn) {
> -  const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(Fn);
> -  if (!Ctor) return;
> -
> -  Ctor = Ctor->getInheritedConstructor();
> -  if (!Ctor) return;
> -
> -  S.Diag(Ctor->getLocation(), diag::note_ovl_candidate_
> inherited_constructor);
> +void MaybeEmitInheritedConstructorNote(Sema &S, Decl *FoundDecl) {
> +  // FIXME: It'd be nice to only emit a note once per using-decl per
> overload
> +  // set.
> +  if (auto *Shadow = dyn_cast<ConstructorUsingShadowDecl>(FoundDecl))
> +    S.Diag(FoundDecl->getLocation(),
> +           diag::note_ovl_candidate_inherited_constructor)
> +      << Shadow->getNominatedBaseClass();
>  }
>
>  } // end anonymous namespace
> @@ -8982,7 +9003,7 @@ void Sema::NoteOverloadCandidate(NamedDe
>
>    HandleFunctionTypeMismatch(PD, Fn->getType(), DestType);
>    Diag(Fn->getLocation(), PD);
> -  MaybeEmitInheritedConstructorNote(*this, Fn);
> +  MaybeEmitInheritedConstructorNote(*this, Found);
>  }
>
>  // Notes the location of all overload candidates designated through
> @@ -9070,7 +9091,7 @@ static void DiagnoseBadConversion(Sema &
>        << (unsigned) FnKind << FnDesc
>        << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
>        << ToTy << Name << I+1;
> -    MaybeEmitInheritedConstructorNote(S, Fn);
> +    MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
>      return;
>    }
>
> @@ -9101,7 +9122,7 @@ static void DiagnoseBadConversion(Sema &
>          << FromTy
>          << FromQs.getAddressSpace() << ToQs.getAddressSpace()
>          << (unsigned) isObjectArgument << I+1;
> -      MaybeEmitInheritedConstructorNote(S, Fn);
> +      MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
>        return;
>      }
>
> @@ -9112,7 +9133,7 @@ static void DiagnoseBadConversion(Sema &
>          << FromTy
>          << FromQs.getObjCLifetime() << ToQs.getObjCLifetime()
>          << (unsigned) isObjectArgument << I+1;
> -      MaybeEmitInheritedConstructorNote(S, Fn);
> +      MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
>        return;
>      }
>
> @@ -9123,7 +9144,7 @@ static void DiagnoseBadConversion(Sema &
>        << FromTy
>        << FromQs.getObjCGCAttr() << ToQs.getObjCGCAttr()
>        << (unsigned) isObjectArgument << I+1;
> -      MaybeEmitInheritedConstructorNote(S, Fn);
> +      MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
>        return;
>      }
>
> @@ -9132,7 +9153,7 @@ static void DiagnoseBadConversion(Sema &
>          << (unsigned) FnKind << FnDesc
>          << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
>          << FromTy << FromQs.hasUnaligned() << I+1;
> -      MaybeEmitInheritedConstructorNote(S, Fn);
> +      MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
>        return;
>      }
>
> @@ -9150,7 +9171,7 @@ static void DiagnoseBadConversion(Sema &
>          << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
>          << FromTy << (CVR - 1) << I+1;
>      }
> -    MaybeEmitInheritedConstructorNote(S, Fn);
> +    MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
>      return;
>    }
>
> @@ -9161,7 +9182,7 @@ static void DiagnoseBadConversion(Sema &
>        << (unsigned) FnKind << FnDesc
>        << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
>        << FromTy << ToTy << (unsigned) isObjectArgument << I+1;
> -    MaybeEmitInheritedConstructorNote(S, Fn);
> +    MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
>      return;
>    }
>
> @@ -9179,7 +9200,7 @@ static void DiagnoseBadConversion(Sema &
>        << FromTy << ToTy << (unsigned) isObjectArgument << I+1
>        << (unsigned) (Cand->Fix.Kind);
>
> -    MaybeEmitInheritedConstructorNote(S, Fn);
> +    MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
>      return;
>    }
>
> @@ -9218,7 +9239,7 @@ static void DiagnoseBadConversion(Sema &
>          << (unsigned) FnKind << FnDesc
>          << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
>          << (unsigned) isObjectArgument << I + 1;
> -      MaybeEmitInheritedConstructorNote(S, Fn);
> +      MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
>        return;
>      }
>    }
> @@ -9230,7 +9251,7 @@ static void DiagnoseBadConversion(Sema &
>        << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
>        << (BaseToDerivedConversion - 1)
>        << FromTy << ToTy << I+1;
> -    MaybeEmitInheritedConstructorNote(S, Fn);
> +    MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
>      return;
>    }
>
> @@ -9243,7 +9264,7 @@ static void DiagnoseBadConversion(Sema &
>          << (unsigned) FnKind << FnDesc
>          << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
>          << FromTy << ToTy << (unsigned) isObjectArgument << I+1;
> -        MaybeEmitInheritedConstructorNote(S, Fn);
> +        MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
>          return;
>        }
>    }
> @@ -9265,7 +9286,7 @@ static void DiagnoseBadConversion(Sema &
>      FDiag << *HI;
>    S.Diag(Fn->getLocation(), FDiag);
>
> -  MaybeEmitInheritedConstructorNote(S, Fn);
> +  MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
>  }
>
>  /// Additional arity mismatch diagnosis specific to a function overload
> @@ -9341,7 +9362,7 @@ static void DiagnoseArityMismatch(Sema &
>      S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity)
>        << (unsigned) FnKind << (Fn->getDescribedFunctionTemplate() !=
> nullptr)
>        << mode << modeCount << NumFormalArgs;
> -  MaybeEmitInheritedConstructorNote(S, Fn);
> +  MaybeEmitInheritedConstructorNote(S, Found);
>  }
>
>  /// Arity mismatch diagnosis specific to a function overload candidate.
> @@ -9377,7 +9398,7 @@ static void DiagnoseBadDeduction(Sema &S
>      S.Diag(Templated->getLocation(),
>             diag::note_ovl_candidate_incomplete_deduction)
>          << ParamD->getDeclName();
> -    MaybeEmitInheritedConstructorNote(S, Templated);
> +    MaybeEmitInheritedConstructorNote(S, Found);
>      return;
>    }
>
> @@ -9402,7 +9423,7 @@ static void DiagnoseBadDeduction(Sema &S
>
>      S.Diag(Templated->getLocation(), diag::note_ovl_candidate_
> underqualified)
>          << ParamD->getDeclName() << Arg << NonCanonParam;
> -    MaybeEmitInheritedConstructorNote(S, Templated);
> +    MaybeEmitInheritedConstructorNote(S, Found);
>      return;
>    }
>
> @@ -9421,7 +9442,7 @@ static void DiagnoseBadDeduction(Sema &S
>             diag::note_ovl_candidate_inconsistent_deduction)
>          << which << ParamD->getDeclName() <<
> *DeductionFailure.getFirstArg()
>          << *DeductionFailure.getSecondArg();
> -    MaybeEmitInheritedConstructorNote(S, Templated);
> +    MaybeEmitInheritedConstructorNote(S, Found);
>      return;
>    }
>
> @@ -9444,7 +9465,7 @@ static void DiagnoseBadDeduction(Sema &S
>               diag::note_ovl_candidate_explicit_arg_mismatch_unnamed)
>            << (index + 1);
>      }
> -    MaybeEmitInheritedConstructorNote(S, Templated);
> +    MaybeEmitInheritedConstructorNote(S, Found);
>      return;
>
>    case Sema::TDK_TooManyArguments:
> @@ -9455,7 +9476,7 @@ static void DiagnoseBadDeduction(Sema &S
>    case Sema::TDK_InstantiationDepth:
>      S.Diag(Templated->getLocation(),
>             diag::note_ovl_candidate_instantiation_depth);
> -    MaybeEmitInheritedConstructorNote(S, Templated);
> +    MaybeEmitInheritedConstructorNote(S, Found);
>      return;
>
>    case Sema::TDK_SubstitutionFailure: {
> @@ -9493,7 +9514,7 @@ static void DiagnoseBadDeduction(Sema &S
>      S.Diag(Templated->getLocation(),
>             diag::note_ovl_candidate_substitution_failure)
>          << TemplateArgString << SFINAEArgString << R;
> -    MaybeEmitInheritedConstructorNote(S, Templated);
> +    MaybeEmitInheritedConstructorNote(S, Found);
>      return;
>    }
>
> @@ -9565,7 +9586,7 @@ static void DiagnoseBadDeduction(Sema &S
>    // note_ovl_candidate_bad_deduction, which is uselessly vague.
>    case Sema::TDK_MiscellaneousDeductionFailure:
>      S.Diag(Templated->getLocation(), diag::note_ovl_candidate_bad_
> deduction);
> -    MaybeEmitInheritedConstructorNote(S, Templated);
> +    MaybeEmitInheritedConstructorNote(S, Found);
>      return;
>    }
>  }
> @@ -9676,7 +9697,7 @@ static void NoteFunctionCandidate(Sema &
>      S.Diag(Fn->getLocation(), diag::note_ovl_candidate_deleted)
>        << FnKind << FnDesc
>        << (Fn->isDeleted() ? (Fn->isDeletedAsWritten() ? 1 : 2) : 0);
> -    MaybeEmitInheritedConstructorNote(S, Fn);
> +    MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
>      return;
>    }
>
> @@ -9698,7 +9719,7 @@ static void NoteFunctionCandidate(Sema &
>    case ovl_fail_illegal_constructor: {
>      S.Diag(Fn->getLocation(), diag::note_ovl_candidate_
> illegal_constructor)
>        << (Fn->getPrimaryTemplate() ? 1 : 0);
> -    MaybeEmitInheritedConstructorNote(S, Fn);
> +    MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
>      return;
>    }
>
> @@ -9764,7 +9785,6 @@ static void NoteSurrogateCandidate(Sema
>
>    S.Diag(Cand->Surrogate->getLocation(), diag::note_ovl_surrogate_cand)
>      << FnType;
> -  MaybeEmitInheritedConstructorNote(S, Cand->Surrogate);
>  }
>
>  static void NoteBuiltinOperatorCandidate(Sema &S, StringRef Opc,
> @@ -10531,9 +10551,10 @@ private:
>      UnresolvedSetIterator Result = S.getMostSpecialized(
>          MatchesCopy.begin(), MatchesCopy.end(), FailedCandidates,
>          SourceExpr->getLocStart(), S.PDiag(),
> -        S.PDiag(diag::err_addr_ovl_ambiguous) << Matches[0]
> -
>  .second->getDeclName(),
> -        S.PDiag(diag::note_ovl_candidate) << (unsigned)oc_function_
> template,
> +        S.PDiag(diag::err_addr_ovl_ambiguous)
> +          << Matches[0].second->getDeclName(),
> +        S.PDiag(diag::note_ovl_candidate)
> +          << (unsigned)oc_function_template,
>          Complain, TargetFunctionType);
>
>      if (Result != MatchesCopy.end()) {
>
> Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaTemplateInstantiateDecl.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Tue Jun 28
> 14:03:57 2016
> @@ -1843,36 +1843,6 @@ TemplateDeclInstantiator::VisitCXXMethod
>                                          Constructor->isExplicit(),
>                                          Constructor->isInlineSpecified(),
>                                          false,
> Constructor->isConstexpr());
> -
> -    // Claim that the instantiation of a constructor or constructor
> template
> -    // inherits the same constructor that the template does.
> -    if (CXXConstructorDecl *Inh = const_cast<CXXConstructorDecl *>(
> -            Constructor->getInheritedConstructor())) {
> -      // If we're instantiating a specialization of a function template,
> our
> -      // "inherited constructor" will actually itself be a function
> template.
> -      // Instantiate a declaration of it, too.
> -      if (FunctionTemplate) {
> -        assert(!TemplateParams && Inh->getDescribedFunctionTemplate() &&
> -               !Inh->getParent()->isDependentContext() &&
> -               "inheriting constructor template in dependent context?");
> -        Sema::InstantiatingTemplate Inst(SemaRef,
> Constructor->getLocation(),
> -                                         Inh);
> -        if (Inst.isInvalid())
> -          return nullptr;
> -        Sema::ContextRAII SavedContext(SemaRef, Inh->getDeclContext());
> -        LocalInstantiationScope LocalScope(SemaRef);
> -
> -        // Use the same template arguments that we deduced for the
> inheriting
> -        // constructor. There's no way they could be deduced differently.
> -        MultiLevelTemplateArgumentList InheritedArgs;
> -        InheritedArgs.addOuterTemplateArguments(
> TemplateArgs.getInnermost());
> -        Inh = cast_or_null<CXXConstructorDecl>(
> -            SemaRef.SubstDecl(Inh, Inh->getDeclContext(), InheritedArgs));
> -        if (!Inh)
> -          return nullptr;
> -      }
> -      cast<CXXConstructorDecl>(Method)->setInheritedConstructor(Inh);
> -    }
>    } else if (CXXDestructorDecl *Destructor =
> dyn_cast<CXXDestructorDecl>(D)) {
>      Method = CXXDestructorDecl::Create(SemaRef.Context, Record,
>                                         StartLoc, NameInfo, T, TInfo,
> @@ -2398,9 +2368,14 @@ Decl *TemplateDeclInstantiator::VisitUsi
>    if (!QualifierLoc)
>      return nullptr;
>
> -  // The name info is non-dependent, so no transformation
> -  // is required.
> +  // For an inheriting constructor declaration, the name of the using
> +  // declaration is the name of a constructor in this class, not in the
> +  // base class.
>    DeclarationNameInfo NameInfo = D->getNameInfo();
> +  if (NameInfo.getName().getNameKind() == DeclarationName::
> CXXConstructorName)
> +    if (auto *RD = dyn_cast<CXXRecordDecl>(SemaRef.CurContext))
> +      NameInfo.setName(SemaRef.Context.DeclarationNames.
> getCXXConstructorName(
> +          SemaRef.Context.getCanonicalType(SemaRef.
> Context.getRecordType(RD))));
>
>    // We only need to do redeclaration lookups if we're in a class
>    // scope (in fact, it's not really even possible in non-class
> @@ -2443,18 +2418,23 @@ Decl *TemplateDeclInstantiator::VisitUsi
>    if (NewUD->isInvalidDecl())
>      return NewUD;
>
> -  if (NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName)
> {
> +  if (NameInfo.getName().getNameKind() == DeclarationName::
> CXXConstructorName)
>      SemaRef.CheckInheritingConstructorUsingDecl(NewUD);
> -    return NewUD;
> -  }
>
>    bool isFunctionScope = Owner->isFunctionOrMethod();
>
>    // Process the shadow decls.
>    for (auto *Shadow : D->shadows()) {
> +    // FIXME: UsingShadowDecl doesn't preserve its immediate target, so
> +    // reconstruct it in the case where it matters.
> +    NamedDecl *OldTarget = Shadow->getTargetDecl();
> +    if (auto *CUSD = dyn_cast<ConstructorUsingShadowDecl>(Shadow))
> +      if (auto *BaseShadow = CUSD->getNominatedBaseClassShadowDecl())
> +        OldTarget = BaseShadow;
> +
>      NamedDecl *InstTarget =
>          cast_or_null<NamedDecl>(SemaRef.FindInstantiatedDecl(
> -            Shadow->getLocation(), Shadow->getTargetDecl(),
> TemplateArgs));
> +            Shadow->getLocation(), OldTarget, TemplateArgs));
>      if (!InstTarget)
>        return nullptr;
>
> @@ -2484,6 +2464,12 @@ Decl *TemplateDeclInstantiator::VisitUsi
>    // Ignore these;  we handle them in bulk when processing the UsingDecl.
>    return nullptr;
>  }
> +
> +Decl *TemplateDeclInstantiator::VisitConstructorUsingShadowDecl(
> +    ConstructorUsingShadowDecl *D) {
> +  // Ignore these;  we handle them in bulk when processing the UsingDecl.
> +  return nullptr;
> +}
>
>  Decl * TemplateDeclInstantiator
>      ::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
>
> Modified: cfe/trunk/lib/Sema/TreeTransform.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> TreeTransform.h?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/TreeTransform.h (original)
> +++ cfe/trunk/lib/Sema/TreeTransform.h Tue Jun 28 14:03:57 2016
> @@ -2690,6 +2690,16 @@ public:
>                                             ParenRange);
>    }
>
> +  /// \brief Build a new implicit construction via inherited constructor
> +  /// expression.
> +  ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation
> Loc,
> +                                             CXXConstructorDecl
> *Constructor,
> +                                             bool ConstructsVBase,
> +                                             bool InheritedFromVBase) {
> +    return new (getSema().Context) CXXInheritedCtorInitExpr(
> +        Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
> +  }
> +
>    /// \brief Build a new object-construction expression.
>    ///
>    /// By default, performs semantic analysis to build the new expression.
> @@ -9937,6 +9947,32 @@ TreeTransform<Derived>::TransformCXXCons
>                                                E->getParenOrBraceRange());
>  }
>
> +template<typename Derived>
> +ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
> +    CXXInheritedCtorInitExpr *E) {
> +  QualType T = getDerived().TransformType(E->getType());
> +  if (T.isNull())
> +    return ExprError();
> +
> +  CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
> +      getDerived().TransformDecl(E->getLocStart(), E->getConstructor()));
> +  if (!Constructor)
> +    return ExprError();
> +
> +  if (!getDerived().AlwaysRebuild() &&
> +      T == E->getType() &&
> +      Constructor == E->getConstructor()) {
> +    // Mark the constructor as referenced.
> +    // FIXME: Instantiation-specific
> +    SemaRef.MarkFunctionReferenced(E->getLocStart(), Constructor);
> +    return E;
> +  }
> +
> +  return getDerived().RebuildCXXInheritedCtorInitExpr(
> +      T, E->getLocation(), Constructor,
> +      E->constructsVBase(), E->inheritedFromVBase());
> +}
> +
>  /// \brief Transform a C++ temporary-binding expression.
>  ///
>  /// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
>
> Modified: cfe/trunk/lib/Serialization/ASTCommon.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/
> Serialization/ASTCommon.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Serialization/ASTCommon.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTCommon.cpp Tue Jun 28 14:03:57 2016
> @@ -258,6 +258,7 @@ bool serialization::isRedeclarableDeclKi
>    case Decl::CXXDestructor:
>    case Decl::CXXConversion:
>    case Decl::UsingShadow:
> +  case Decl::ConstructorUsingShadow:
>    case Decl::Var:
>    case Decl::FunctionTemplate:
>    case Decl::ClassTemplate:
>
> Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/
> Serialization/ASTReaderDecl.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Tue Jun 28 14:03:57 2016
> @@ -324,6 +324,7 @@ namespace clang {
>      void VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
>      void VisitUsingDecl(UsingDecl *D);
>      void VisitUsingShadowDecl(UsingShadowDecl *D);
> +    void VisitConstructorUsingShadowDecl(ConstructorUsingShadowDecl *D);
>      void VisitLinkageSpecDecl(LinkageSpecDecl *D);
>      void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD);
>      void VisitImportDecl(ImportDecl *D);
> @@ -1421,6 +1422,16 @@ void ASTDeclReader::VisitUsingShadowDecl
>    mergeRedeclarable(D, Redecl);
>  }
>
> +void ASTDeclReader::VisitConstructorUsingShadowDecl(
> +    ConstructorUsingShadowDecl *D) {
> +  VisitUsingShadowDecl(D);
> +  D->NominatedBaseClassShadowDecl =
> +      ReadDeclAs<ConstructorUsingShadowDecl>(Record, Idx);
> +  D->ConstructedBaseClassShadowDecl =
> +      ReadDeclAs<ConstructorUsingShadowDecl>(Record, Idx);
> +  D->IsVirtual = Record[Idx++];
> +}
> +
>  void ASTDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
>    VisitNamedDecl(D);
>    D->UsingLoc = ReadSourceLocation(Record, Idx);
> @@ -1768,11 +1779,17 @@ void ASTDeclReader::VisitCXXMethodDecl(C
>  }
>
>  void ASTDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
> +  // We need the inherited constructor information to merge the
> declaration,
> +  // so we have to read it before we call VisitCXXMethodDecl.
> +  if (D->isInheritingConstructor()) {
> +    auto *Shadow = ReadDeclAs<ConstructorUsingShadowDecl>(Record, Idx);
> +    auto *Ctor = ReadDeclAs<CXXConstructorDecl>(Record, Idx);
> +    *D->getTrailingObjects<InheritedConstructor>() =
> +        InheritedConstructor(Shadow, Ctor);
> +  }
> +
>    VisitCXXMethodDecl(D);
>
> -  if (auto *CD = ReadDeclAs<CXXConstructorDecl>(Record, Idx))
> -    if (D->isCanonicalDecl())
> -      D->setInheritedConstructor(CD->getCanonicalDecl());
>    D->IsExplicitSpecified = Record[Idx++];
>  }
>
> @@ -2663,6 +2680,13 @@ static bool isSameEntity(NamedDecl *X, N
>    // functions, etc.
>    if (FunctionDecl *FuncX = dyn_cast<FunctionDecl>(X)) {
>      FunctionDecl *FuncY = cast<FunctionDecl>(Y);
> +    if (CXXConstructorDecl *CtorX = dyn_cast<CXXConstructorDecl>(X)) {
> +      CXXConstructorDecl *CtorY = cast<CXXConstructorDecl>(Y);
> +      if (CtorX->getInheritedConstructor() &&
> +          !isSameEntity(CtorX->getInheritedConstructor().
> getConstructor(),
> +                        CtorY->getInheritedConstructor().
> getConstructor()))
> +        return false;
> +    }
>      return (FuncX->getLinkageInternal() == FuncY->getLinkageInternal()) &&
>        FuncX->getASTContext().hasSameType(FuncX->getType(),
> FuncY->getType());
>    }
> @@ -3240,6 +3264,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID I
>    case DECL_USING_SHADOW:
>      D = UsingShadowDecl::CreateDeserialized(Context, ID);
>      break;
> +  case DECL_CONSTRUCTOR_USING_SHADOW:
> +    D = ConstructorUsingShadowDecl::CreateDeserialized(Context, ID);
> +    break;
>    case DECL_USING_DIRECTIVE:
>      D = UsingDirectiveDecl::CreateDeserialized(Context, ID);
>      break;
> @@ -3256,7 +3283,10 @@ Decl *ASTReader::ReadDeclRecord(DeclID I
>      D = CXXMethodDecl::CreateDeserialized(Context, ID);
>      break;
>    case DECL_CXX_CONSTRUCTOR:
> -    D = CXXConstructorDecl::CreateDeserialized(Context, ID);
> +    D = CXXConstructorDecl::CreateDeserialized(Context, ID, false);
> +    break;
> +  case DECL_CXX_INHERITED_CONSTRUCTOR:
> +    D = CXXConstructorDecl::CreateDeserialized(Context, ID, true);
>      break;
>    case DECL_CXX_DESTRUCTOR:
>      D = CXXDestructorDecl::CreateDeserialized(Context, ID);
>
> Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/
> Serialization/ASTReaderStmt.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Tue Jun 28 14:03:57 2016
> @@ -1250,6 +1250,14 @@ void ASTStmtReader::VisitCXXConstructExp
>    E->ParenOrBraceRange = ReadSourceRange(Record, Idx);
>  }
>
> +void ASTStmtReader::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr
> *E) {
> +  VisitExpr(E);
> +  E->Constructor = ReadDeclAs<CXXConstructorDecl>(Record, Idx);
> +  E->Loc = ReadSourceLocation(Record, Idx);
> +  E->ConstructsVirtualBase = Record[Idx++];
> +  E->InheritedFromVirtualBase = Record[Idx++];
> +}
> +
>  void ASTStmtReader::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr
> *E) {
>    VisitCXXConstructExpr(E);
>    E->Type = GetTypeSourceInfo(Record, Idx);
> @@ -3407,6 +3415,10 @@ Stmt *ASTReader::ReadStmtFromStream(Modu
>        S = new (Context) CXXConstructExpr(Empty);
>        break;
>
> +    case EXPR_CXX_INHERITED_CTOR_INIT:
> +      S = new (Context) CXXInheritedCtorInitExpr(Empty);
> +      break;
> +
>      case EXPR_CXX_TEMPORARY_OBJECT:
>        S = new (Context) CXXTemporaryObjectExpr(Empty);
>        break;
>
> Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/
> Serialization/ASTWriter.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Tue Jun 28 14:03:57 2016
> @@ -1104,6 +1104,7 @@ void ASTWriter::WriteBlockInfoBlock() {
>    RECORD(DECL_CXX_RECORD);
>    RECORD(DECL_CXX_METHOD);
>    RECORD(DECL_CXX_CONSTRUCTOR);
> +  RECORD(DECL_CXX_INHERITED_CONSTRUCTOR);
>    RECORD(DECL_CXX_DESTRUCTOR);
>    RECORD(DECL_CXX_CONVERSION);
>    RECORD(DECL_ACCESS_SPEC);
>
> Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/
> Serialization/ASTWriterDecl.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Tue Jun 28 14:03:57 2016
> @@ -107,6 +107,7 @@ namespace clang {
>      void VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
>      void VisitUsingDecl(UsingDecl *D);
>      void VisitUsingShadowDecl(UsingShadowDecl *D);
> +    void VisitConstructorUsingShadowDecl(ConstructorUsingShadowDecl *D);
>      void VisitLinkageSpecDecl(LinkageSpecDecl *D);
>      void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
>      void VisitImportDecl(ImportDecl *D);
> @@ -1126,6 +1127,15 @@ void ASTDeclWriter::VisitUsingShadowDecl
>    Code = serialization::DECL_USING_SHADOW;
>  }
>
> +void ASTDeclWriter::VisitConstructorUsingShadowDecl(
> +    ConstructorUsingShadowDecl *D) {
> +  VisitUsingShadowDecl(D);
> +  Record.AddDeclRef(D->NominatedBaseClassShadowDecl);
> +  Record.AddDeclRef(D->ConstructedBaseClassShadowDecl);
> +  Record.push_back(D->IsVirtual);
> +  Code = serialization::DECL_CONSTRUCTOR_USING_SHADOW;
> +}
> +
>  void ASTDeclWriter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
>    VisitNamedDecl(D);
>    Record.AddSourceLocation(D->getUsingLoc());
> @@ -1211,12 +1221,21 @@ void ASTDeclWriter::VisitCXXMethodDecl(C
>  }
>
>  void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
> +  if (auto Inherited = D->getInheritedConstructor()) {
> +    Record.AddDeclRef(Inherited.getShadowDecl());
> +    Record.AddDeclRef(Inherited.getConstructor());
> +    Code = serialization::DECL_CXX_INHERITED_CONSTRUCTOR;
> +  } else {
> +    Code = serialization::DECL_CXX_CONSTRUCTOR;
> +  }
> +
>    VisitCXXMethodDecl(D);
>
> -  Record.AddDeclRef(D->getInheritedConstructor());
>    Record.push_back(D->IsExplicitSpecified);
>
> -  Code = serialization::DECL_CXX_CONSTRUCTOR;
> +  Code = D->isInheritingConstructor()
> +             ? serialization::DECL_CXX_INHERITED_CONSTRUCTOR
> +             : serialization::DECL_CXX_CONSTRUCTOR;
>  }
>
>  void ASTDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
>
> Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/
> Serialization/ASTWriterStmt.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Tue Jun 28 14:03:57 2016
> @@ -1218,6 +1218,15 @@ void ASTStmtWriter::VisitCXXConstructExp
>    Code = serialization::EXPR_CXX_CONSTRUCT;
>  }
>
> +void ASTStmtWriter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr
> *E) {
> +  VisitExpr(E);
> +  Record.AddDeclRef(E->getConstructor());
> +  Record.AddSourceLocation(E->getLocation());
> +  Record.push_back(E->constructsVBase());
> +  Record.push_back(E->inheritedFromVBase());
> +  Code = serialization::EXPR_CXX_INHERITED_CTOR_INIT;
> +}
> +
>  void ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr
> *E) {
>    VisitCXXConstructExpr(E);
>    Record.AddTypeSourceInfo(E->getTypeSourceInfo());
>
> Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/
> StaticAnalyzer/Core/ExprEngine.cpp?rev=274049&r1=
> 274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
> +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Tue Jun 28 14:03:57
> 2016
> @@ -755,6 +755,7 @@ void ExprEngine::Visit(const Stmt *S, Ex
>      // C++ and ARC stuff we don't support yet.
>      case Expr::ObjCIndirectCopyRestoreExprClass:
>      case Stmt::CXXDependentScopeMemberExprClass:
> +    case Stmt::CXXInheritedCtorInitExprClass:
>      case Stmt::CXXTryStmtClass:
>      case Stmt::CXXTypeidExprClass:
>      case Stmt::CXXUuidofExprClass:
>
> Modified: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.
> qual/class.qual/p2.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp?
> rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
> (original)
> +++ cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
> Tue Jun 28 14:03:57 2016
> @@ -53,16 +53,17 @@ namespace InhCtor {
>    int n = b.T(); // expected-error {{'T' is a protected member of
> 'InhCtor::A'}}
>                   // expected-note at -15 {{declared protected here}}
>
> +  // FIXME: EDG and GCC reject this too, but it's not clear why it would
> be
> +  // ill-formed.
>    template<typename T>
>    struct S : T {
> -    struct U : S {
> +    struct U : S { // expected-note 6{{candidate}}
>        using S::S;
>      };
>      using T::T;
>    };
> -
> -  S<A>::U ua(0);
> -  S<B>::U ub(0);
> +  S<A>::U ua(0); // expected-error {{no match}}
> +  S<B>::U ub(0); // expected-error {{no match}}
>
>    template<typename T>
>    struct X : T {
>
> Modified: cfe/trunk/test/CXX/basic/basic.types/p10.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> basic/basic.types/p10.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/basic/basic.types/p10.cpp (original)
> +++ cfe/trunk/test/CXX/basic/basic.types/p10.cpp Tue Jun 28 14:03:57 2016
> @@ -141,3 +141,45 @@ constexpr int arb(int n) {
>  }
>  constexpr long Overflow[ // expected-error {{constexpr variable cannot
> have non-literal type 'long const[(1 << 30) << 2]'}}
>      (1 << 30) << 2]{};   // expected-warning {{requires 34 bits to
> represent}}
> +
> +namespace inherited_ctor {
> +  struct A { constexpr A(int); };
> +  struct B : A {
> +    B();
> +    using A::A;
> +  };
> +  constexpr int f(B) { return 0; } // ok
> +
> +  struct C { constexpr C(int); };
> +  struct D : C { // expected-note {{because}}
> +    D(int);
> +    using C::C;
> +  };
> +  constexpr int f(D) { return 0; } // expected-error {{not a literal
> type}}
> +
> +  // This one is a bit odd: F inherits E's default constructor, which is
> +  // constexpr. Because F has a constructor of its own, it doesn't
> declare a
> +  // default constructor hiding E's one.
> +  struct E {};
> +  struct F : E {
> +    F(int);
> +    using E::E;
> +  };
> +  constexpr int f(F) { return 0; }
> +
> +  // FIXME: Is this really the right behavior? We presumably should be
> checking
> +  // whether the inherited constructor would be a copy or move
> constructor for
> +  // the derived class, not for the base class.
> +  struct G { constexpr G(const G&); };
> +  struct H : G { // expected-note {{because}}
> +    using G::G;
> +  };
> +  constexpr int f(H) { return 0; } // expected-error {{not a literal
> type}}
> +
> +  struct J;
> +  struct I { constexpr I(const J&); };
> +  struct J : I {
> +    using I::I;
> +  };
> +  constexpr int f(J) { return 0; }
> +}
>
> Added: cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> dcl.dcl/basic.namespace/namespace.udecl/p15.cpp?rev=274049&view=auto
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp
> (added)
> +++ cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp
> Tue Jun 28 14:03:57 2016
> @@ -0,0 +1,81 @@
> +// RUN: %clang_cc1 -std=c++11 -verify %s
> +
> +struct B1 { // expected-note 2{{candidate}}
> +  B1(int); // expected-note {{candidate}}
> +};
> +
> +struct B2 { // expected-note 2{{candidate}}
> +  B2(int); // expected-note {{candidate}}
> +};
> +
> +struct D1 : B1, B2 { // expected-note 2{{candidate}}
> +  using B1::B1; // expected-note 3{{inherited here}}
> +  using B2::B2; // expected-note 3{{inherited here}}
> +};
> +D1 d1(0); // expected-error {{ambiguous}}
> +
> +struct D2 : B1, B2 {
> +  using B1::B1;
> +  using B2::B2;
> +  D2(int);
> +};
> +D2 d2(0); // ok
> +
> +
> +// The emergent behavior of implicit special members is a bit odd when
> +// inheriting from multiple base classes.
> +namespace default_ctor {
> +  struct C;
> +  struct D;
> +
> +  struct A { // expected-note 4{{candidate}}
> +    A(); // expected-note {{candidate}}
> +
> +    A(C &&); // expected-note {{candidate}}
> +    C &operator=(C&&); // expected-note {{candidate}}
> +
> +    A(D &&); // expected-note {{candidate}}
> +    D &operator=(D&&); // expected-note {{candidate}}
> +  };
> +
> +  struct B { // expected-note 4{{candidate}}
> +    B(); // expected-note {{candidate}}
> +
> +    B(C &&); // expected-note {{candidate}}
> +    C &operator=(C&&); // expected-note {{candidate}}
> +
> +    B(D &&); // expected-note {{candidate}}
> +    D &operator=(D&&); // expected-note {{candidate}}
> +  };
> +
> +  struct C : A, B {
> +    using A::A;
> +    using A::operator=;
> +    using B::B;
> +    using B::operator=;
> +  };
> +  struct D : A, B {
> +    using A::A; // expected-note 5{{inherited here}}
> +    using A::operator=;
> +    using B::B; // expected-note 5{{inherited here}}
> +    using B::operator=;
> +
> +    D(int);
> +    D(const D&); // expected-note {{candidate}}
> +    D &operator=(const D&); // expected-note {{candidate}}
> +  };
> +
> +  C c;
> +  void f(C c) {
> +    C c2(static_cast<C&&>(c));
> +    c = static_cast<C&&>(c);
> +  }
> +
> +  // D does not declare D(), D(D&&), nor operator=(D&&), so the base class
> +  // versions are inherited.
> +  D d; // expected-error {{ambiguous}}
> +  void f(D d) {
> +    D d2(static_cast<D&&>(d)); // expected-error {{ambiguous}}
> +    d = static_cast<D&&>(d); // expected-error {{ambiguous}}
> +  }
> +}
>
> Added: cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p18.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> dcl.dcl/basic.namespace/namespace.udecl/p18.cpp?rev=274049&view=auto
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p18.cpp
> (added)
> +++ cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p18.cpp
> Tue Jun 28 14:03:57 2016
> @@ -0,0 +1,77 @@
> +// RUN: %clang_cc1 -std=c++11 -verify %s
> +
> +struct Public {} public_;
> +struct Protected {} protected_;
> +struct Private {} private_;
> +
> +class A {
> +public:
> +  A(Public);
> +  void f(Public);
> +
> +protected:
> +  A(Protected); // expected-note {{protected here}}
> +  void f(Protected);
> +
> +private:
> +  A(Private); // expected-note 4{{private here}}
> +  void f(Private); // expected-note {{private here}}
> +
> +  friend void Friend();
> +};
> +
> +class B : private A {
> +  using A::A; // ok
> +  using A::f; // expected-error {{private member}}
> +
> +  void f() {
> +    B a(public_);
> +    B b(protected_);
> +    B c(private_); // expected-error {{private}}
> +  }
> +
> +  B(Public p, int) : B(p) {}
> +  B(Protected p, int) : B(p) {}
> +  B(Private p, int) : B(p) {} // expected-error {{private}}
> +};
> +
> +class C : public B {
> +  C(Public p) : B(p) {}
> +  // There is no access check on the conversion from derived to base here;
> +  // protected constructors of A act like protected constructors of B.
> +  C(Protected p) : B(p) {}
> +  C(Private p) : B(p) {} // expected-error {{private}}
> +};
> +
> +void Friend() {
> +  // There is no access check on the conversion from derived to base here.
> +  B a(public_);
> +  B b(protected_);
> +  B c(private_);
> +}
> +
> +void NonFriend() {
> +  B a(public_);
> +  B b(protected_); // expected-error {{protected}}
> +  B c(private_); // expected-error {{private}}
> +}
> +
> +namespace ProtectedAccessFromMember {
> +namespace a {
> +  struct ES {
> +  private:
> +    ES(const ES &) = delete;
> +  protected:
> +    ES(const char *);
> +  };
> +}
> +namespace b {
> +  struct DES : a::ES {
> +    DES *f();
> +  private:
> +    using a::ES::ES;
> +  };
> +}
> +b::DES *b::DES::f() { return new b::DES("foo"); }
> +
> +}
>
> Modified: cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.
> udecl/p4.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> dcl.dcl/basic.namespace/namespace.udecl/p4.cpp?rev=
> 274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp
> (original)
> +++ cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp Tue
> Jun 28 14:03:57 2016
> @@ -1,4 +1,5 @@
>  // RUN: %clang_cc1 -fsyntax-only -verify %s
> +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
>
>  // C++03 [namespace.udecl]p4:
>  //   A using-declaration used as a member-declaration shall refer to a
> @@ -206,8 +207,33 @@ namespace test4 {
>      using Unrelated::foo; // expected-error {{not a base class}}
>      using C::foo; // legal in C++03
>      using Subclass::foo; // legal in C++03
> +#if __cplusplus >= 201103L
> +    // expected-error at -3 {{refers to its own class}}
> +    // expected-error at -3 {{refers into 'Subclass::', which is not a base
> class}}
> +#endif
>
> -    int bar(); //expected-note {{target of using declaration}}
> +    int bar();
> +#if __cplusplus < 201103L
> +    // expected-note at -2 {{target of using declaration}}
> +#endif
>      using C::bar; // expected-error {{refers to its own class}}
>    };
>  }
> +
> +namespace test5 {
> +  struct B;
> +  struct A {
> +    A(const B&);
> +    B &operator=(const B&);
> +  };
> +  struct B : A {
> +#if __cplusplus >= 201103L
> +    using A::A;
> +#endif
> +    using A::operator=;
> +  };
> +  void test(B b) {
> +    B b2(b);
> +    b2 = b;
> +  }
> +}
>
> Modified: cfe/trunk/test/CXX/drs/dr15xx.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> drs/dr15xx.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/drs/dr15xx.cpp (original)
> +++ cfe/trunk/test/CXX/drs/dr15xx.cpp Tue Jun 28 14:03:57 2016
> @@ -22,6 +22,31 @@ namespace dr1560 { // dr1560: 3.5
>    const X &x = true ? get() : throw 0;
>  }
>
> +namespace dr1573 { // dr1573: 3.9
> +#if __cplusplus >= 201103L
> +  // ellipsis is inherited (p0136r1 supersedes this part).
> +  struct A { A(); A(int, char, ...); };
> +  struct B : A { using A::A; };
> +  B b(1, 'x', 4.0, "hello"); // ok
> +
> +  // inherited constructor is effectively constexpr if the user-written
> constructor would be
> +  struct C { C(); constexpr C(int) {} };
> +  struct D : C { using C::C; };
> +  constexpr D d = D(0); // ok
> +  struct E : C { using C::C; A a; }; // expected-note {{non-literal type}}
> +  constexpr E e = E(0); // expected-error {{non-literal type}}
> +  // FIXME: This diagnostic is pretty bad; we should explain that the
> problem
> +  // is that F::c would be initialized by a non-constexpr constructor.
> +  struct F : C { using C::C; C c; }; // expected-note {{here}}
> +  constexpr F f = F(0); // expected-error {{constant expression}}
> expected-note {{constructor inherited from base class 'C'}}
> +
> +  // inherited constructor is effectively deleted if the user-written
> constructor would be
> +  struct G { G(int); }; // expected-note {{declared here}}
> +  struct H : G { using G::G; G g; }; // expected-error {{cannot use
> constructor inherited from base class 'G'; member 'g' of 'dr1573::H' does
> not have a default constructor}} expected-note {{declared here}}
> +  H h(0); // expected-note {{first required here}}
> +#endif
> +}
> +
>  #if __cplusplus >= 201103L
>  namespace std {
>    typedef decltype(sizeof(int)) size_t;
>
> Modified: cfe/trunk/test/CXX/drs/dr16xx.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> drs/dr16xx.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/drs/dr16xx.cpp (original)
> +++ cfe/trunk/test/CXX/drs/dr16xx.cpp Tue Jun 28 14:03:57 2016
> @@ -18,8 +18,8 @@ namespace dr1684 { // dr1684: 3.6
>  #endif
>  }
>
> +namespace dr1631 {  // dr1631: 3.7
>  #if __cplusplus >= 201103L
> -namespace dr1631 {  // dr1631: 3.7 c++11
>    // Incorrect overload resolution for single-element initializer-list
>
>    struct A { int a[1]; };
> @@ -41,5 +41,22 @@ namespace dr1631 {  // dr1631: 3.7 c++11
>        f({0}, {{1}});        // expected-error{{call to 'f' is ambiguous}}
>      }
>    }
> -} // dr1631
>  #endif
> +}
> +
> +namespace dr1645 { // dr1645: 3.9
> +#if __cplusplus >= 201103L
> +  struct A { // expected-note 2{{candidate}}
> +    constexpr A(int, float = 0); // expected-note 2{{candidate}}
> +    explicit A(int, int = 0); // expected-note 2{{candidate}}
> +    A(int, int, int = 0) = delete; // expected-note {{candidate}}
> +  };
> +
> +  struct B : A { // expected-note 2{{candidate}}
> +    using A::A; // expected-note 7{{inherited here}}
> +  };
> +
> +  constexpr B a(0); // expected-error {{ambiguous}}
> +  constexpr B b(0, 0); // expected-error {{ambiguous}}
> +#endif
> +}
>
> Modified: cfe/trunk/test/CXX/drs/dr17xx.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> drs/dr17xx.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/drs/dr17xx.cpp (original)
> +++ cfe/trunk/test/CXX/drs/dr17xx.cpp Tue Jun 28 14:03:57 2016
> @@ -3,19 +3,63 @@
>  // RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions
> -pedantic-errors
>  // RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions
> -pedantic-errors
>
> +#if __cplusplus < 201103L
>  // expected-no-diagnostics
> +#endif
>
> +namespace dr1715 { // dr1715: 3.9
> +#if __cplusplus >= 201103L
> +  struct B {
> +    template<class T> B(T, typename T::Q);
> +  };
> +
> +  class S {
> +    using Q = int;
> +    template<class T> friend B::B(T, typename T::Q);
> +  };
> +
> +  struct D : B {
> +    using B::B;
> +  };
> +  struct E : B { // expected-note 2{{candidate}}
> +    template<class T> E(T t, typename T::Q q) : B(t, q) {} //
> expected-note {{'Q' is a private member}}
> +  };
> +
> +  B b(S(), 1);
> +  D d(S(), 2);
> +  E e(S(), 3); // expected-error {{no match}}
> +#endif
> +}
> +
> +namespace dr1736 { // dr1736: 3.9
> +#if __cplusplus >= 201103L
> +struct S {
> +  template <class T> S(T t) {
> +    struct L : S {
> +      using S::S;
> +    };
> +    typename T::type value; // expected-error {{no member}}
> +    L l(value); // expected-note {{instantiation of}}
> +  }
> +};
> +struct Q { typedef int type; } q;
> +S s(q); // expected-note {{instantiation of}}
> +#endif
> +}
> +
> +namespace dr1756 { // dr1756: 3.7
>  #if __cplusplus >= 201103L
> -namespace dr1756 {  // dr1756: 3.7 c++11
>    // Direct-list-initialization of a non-class object
>
>    int a{0};
>
>    struct X { operator int(); } x;
>    int b{x};
> -} // dr1756
> +#endif
> +}
>
> -namespace dr1758 {  // dr1758: 3.7 c++11
> +namespace dr1758 { // dr1758: 3.7
> +#if __cplusplus >= 201103L
>    // Explicit conversion in copy/move list initialization
>
>    struct X { X(); };
> @@ -30,5 +74,5 @@ namespace dr1758 {  // dr1758: 3.7 c++11
>      operator A() { return A(); }
>    } b;
>    A a{b};
> -} // dr1758
>  #endif
> +}
>
> Modified: cfe/trunk/test/CXX/drs/dr19xx.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> drs/dr19xx.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/drs/dr19xx.cpp (original)
> +++ cfe/trunk/test/CXX/drs/dr19xx.cpp Tue Jun 28 14:03:57 2016
> @@ -39,6 +39,31 @@ namespace dr1902 { // dr1902: 3.7
>  #endif
>  }
>
> +namespace dr1903 {
> +  namespace A {
> +    struct a {};
> +    int a;
> +    namespace B {
> +      int b;
> +    }
> +    using namespace B;
> +    namespace {
> +      int c;
> +    }
> +    namespace D {
> +      int d;
> +    }
> +    using D::d;
> +  }
> +  namespace X {
> +    using A::a;
> +    using A::b;
> +    using A::c;
> +    using A::d;
> +    struct a *p;
> +  }
> +}
> +
>  namespace dr1909 { // dr1909: yes
>    struct A {
>      template<typename T> struct A {}; // expected-error {{member 'A' has
> the same name as its class}}
> @@ -54,22 +79,52 @@ namespace dr1909 { // dr1909: yes
>    };
>  }
>
> -#if __cplusplus >= 201103L
>  namespace dr1940 { // dr1940: yes
> +#if __cplusplus >= 201103L
>  static union {
>    static_assert(true, "");  // ok
>    static_assert(false, ""); // expected-error {{static_assert failed}}
>  };
> -}
>  #endif
> +}
>
> +namespace dr1941 { // dr1941: 3.9
>  #if __cplusplus >= 201402L
> +template<typename X>
> +struct base {
> +  template<typename T>
> +  base(T a, T b, decltype(void(*T()), 0) = 0) {
> +    while (a != b) (void)*a++;
> +  }
> +
> +  template<typename T>
> +  base(T a, X x, decltype(void(T(0) * 1), 0) = 0) {
> +    for (T n = 0; n != a; ++n) (void)X(x);
> +  }
> +};
> +
> +struct derived : base<int> {
> +  using base::base;
> +};
> +
> +struct iter {
> +  iter operator++(int);
> +  int operator*();
> +  friend bool operator!=(iter, iter);
> +} it, end;
> +
> +derived d1(it, end);
> +derived d2(42, 9);
> +#endif
> +}
> +
>  namespace dr1947 { // dr1947: yes
> +#if __cplusplus >= 201402L
>  unsigned o = 0'01;  // ok
>  unsigned b = 0b'01; // expected-error {{invalid digit 'b' in octal
> constant}}
>  unsigned x = 0x'01; // expected-error {{invalid suffix 'x'01' on integer
> constant}}
> -}
>  #endif
> +}
>
>  #if __cplusplus >= 201103L
>  // dr1948: yes
> @@ -77,10 +132,58 @@ unsigned x = 0x'01; // expected-error {{
>  void *operator new(__SIZE_TYPE__) noexcept { return nullptr; } //
> expected-error{{exception specification in declaration does not match
> previous declaration}}
>  #endif
>
> +namespace dr1959 { // dr1959: 3.9
>  #if __cplusplus >= 201103L
> +  struct b;
> +  struct c;
> +  struct a {
> +    a() = default;
> +    a(const a &) = delete; // expected-note 2{{deleted}}
> +    a(const b &) = delete; // not inherited
> +    a(c &&) = delete; // expected-note {{deleted}}
> +    template<typename T> a(T) = delete;
> +  };
> +
> +  struct b : a { // expected-note {{copy constructor of 'b' is implicitly
> deleted because base class 'dr1959::a' has a deleted copy constructor}}
> +    using a::a;
> +  };
> +
> +  a x;
> +  b y = x; // expected-error {{deleted}}
> +  b z = z; // expected-error {{deleted}}
> +
> +  // FIXME: It's not really clear that this matches the intent, but it's
> +  // consistent with the behavior for assignment operators.
> +  struct c : a {
> +    using a::a;
> +    c(const c &);
> +  };
> +  c q(static_cast<c&&>(q)); // expected-error {{call to deleted}}
> +#endif
> +}
> +
>  namespace dr1968 { // dr1968: yes
> -static_assert(&typeid(int) == &typeid(int), ""); // expected-error{{not
> an integral constant expression}}
> +#if __cplusplus >= 201103L
> +  static_assert(&typeid(int) == &typeid(int), ""); // expected-error{{not
> an integral constant expression}}
> +#endif
>  }
> +
> +namespace dr1991 { // dr1991: 3.9
> +#if __cplusplus >= 201103L
> +  struct A {
> +    A(int, int) = delete;
> +  };
> +
> +  struct B : A {
> +    using A::A;
> +    B(int, int, int = 0);
> +  };
> +
> +  // FIXME: As a resolution to an open DR against P0136R1, we treat
> derived
> +  // class constructors as better than base class constructors in the
> presence
> +  // of ambiguity.
> +  B b(0, 0); // ok, calls B constructor
>  #endif
> +}
>
>  // dr1994: dup 529
>
> Modified: cfe/trunk/test/CXX/except/except.spec/p14.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> except/except.spec/p14.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/except/except.spec/p14.cpp (original)
> +++ cfe/trunk/test/CXX/except/except.spec/p14.cpp Tue Jun 28 14:03:57 2016
> @@ -124,14 +124,20 @@ namespace InhCtor {
>    template<typename T> struct Throw {
>      Throw() throw(T);
>    };
> -  struct Derived : Base, Throw<X<3>> {
> +  struct Derived1 : Base, X<5> {
> +    using Base::Base;
> +    int n;
> +  };
> +  struct Derived2 : Base, Throw<X<3>> {
>      using Base::Base;
> -    Throw<X<4>> x;
>    };
> -  struct Test {
> -    friend Derived::Derived(X<0>) throw(X<3>, X<4>);
> -    friend Derived::Derived(X<1>) noexcept(false);
> -    friend Derived::Derived(X<2>) throw(X<2>, X<3>, X<4>);
> +  struct Derived3 : Base {
> +    using Base::Base;
> +    Throw<X<4>> x;
>    };
> -  static_assert(!noexcept(Derived{X<5>{}}), "");
> +  static_assert(noexcept(Derived1(X<0>())), "");
> +  static_assert(!noexcept(Derived1(X<1>())), "");
> +  static_assert(!noexcept(Derived1(X<2>())), "");
> +  static_assert(!noexcept(Derived2(X<0>())), "");
> +  static_assert(!noexcept(Derived3(X<0>())), "");
>  }
>
> Modified: cfe/trunk/test/CXX/special/class.inhctor/p1.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> special/class.inhctor/p1.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/special/class.inhctor/p1.cpp (original)
> +++ cfe/trunk/test/CXX/special/class.inhctor/p1.cpp Tue Jun 28 14:03:57
> 2016
> @@ -1,53 +1,55 @@
>  // RUN: %clang_cc1 -std=c++11 -verify %s
> -// Per a core issue (no number yet), an ellipsis is always dropped.
> -struct A {
> -  A(...); // expected-note {{here}}
> -  A(int = 0, int = 0, int = 0, int = 0, ...); // expected-note 9{{here}}
> expected-note 2{{constructor cannot be inherited}}
> -  A(int = 0, int = 0, ...); // expected-note {{here}}
> +//
> +// Note: [class.inhctor] was removed by P0136R1. This tests the new
> behavior
> +// for the wording that used to be there.
> +
> +struct A { // expected-note 8{{candidate is the implicit}}
> +  A(...); // expected-note 4{{candidate constructor}} expected-note
> 4{{candidate inherited constructor}}
> +  A(int = 0, int = 0, int = 0, int = 0, ...); // expected-note
> 3{{candidate constructor}} expected-note 3{{candidate inherited
> constructor}}
> +  A(int = 0, int = 0, ...); // expected-note 3{{candidate constructor}}
> expected-note 3{{candidate inherited constructor}}
>
> -  template<typename T> A(T, int = 0, ...); // expected-note 5{{here}}
> +  template<typename T> A(T, int = 0, ...); // expected-note 3{{candidate
> constructor}} expected-note 3{{candidate inherited constructor}}
>
> -  template<typename T, int N> A(const T (&)[N]); // expected-note
> 2{{here}} expected-note {{constructor cannot be inherited}}
> -  template<typename T, int N> A(const T (&)[N], int = 0); //
> expected-note 2{{here}}
> +  template<typename T, int N> A(const T (&)[N]); // expected-note
> {{candidate constructor}} expected-note {{candidate inherited constructor}}
> +  template<typename T, int N> A(const T (&)[N], int = 0); //
> expected-note {{candidate constructor}} expected-note {{candidate inherited
> constructor}}
>  };
>
> -struct B : A { // expected-note 6{{candidate}}
> -  using A::A; // expected-warning 4{{inheriting constructor does not
> inherit ellipsis}} expected-note 16{{candidate}} expected-note 3{{deleted
> constructor was inherited here}}
> +struct B : A { // expected-note 4{{candidate is the implicit}}
> +  using A::A; // expected-note 19{{inherited here}}
> +  B(void*);
>  };
>
>  struct C {} c;
>
> -B b0{};
> -// expected-error at -1 {{call to implicitly-deleted default constructor of
> 'B'}}
> -// expected-note at -8 {{default constructor of 'B' is implicitly deleted
> because base class 'A' has multiple default constructors}}
> +A a0{}; // expected-error {{ambiguous}}
> +B b0{}; // expected-error {{ambiguous}}
>
> -B b1{1};
> -// expected-error at -1 {{call to deleted constructor of 'B'}}
> +A a1{1}; // expected-error {{ambiguous}}
> +B b1{1}; // expected-error {{ambiguous}}
>
> -B b2{1,2};
> -// expected-error at -1 {{call to deleted constructor of 'B'}}
> +A a2{1,2}; // expected-error {{ambiguous}}
> +B b2{1,2}; // expected-error {{ambiguous}}
>
> -B b3{1,2,3};
> -// ok
> +A a3{1,2,3}; // ok
> +B b3{1,2,3}; // ok
>
> -B b4{1,2,3,4};
> -// ok
> +A a4{1,2,3,4}; // ok
> +B b4{1,2,3,4}; // ok
>
> -B b5{1,2,3,4,5};
> -// expected-error at -1 {{no matching constructor for initialization of
> 'B'}}
> +A a5{1,2,3,4,5}; // ok
> +B b5{1,2,3,4,5}; // ok
>
> -B b6{c};
> -// ok
> +A a6{c}; // ok
> +B b6{c}; // ok
>
> -B b7{c,0};
> -// ok
> +A a7{c,0}; // ok
> +B b7{c,0}; // ok
>
> -B b8{c,0,1};
> -// expected-error at -1 {{no matching constructor}}
> +A a8{c,0,1}; // ok
> +B b8{c,0,1}; // ok
>
> -B b9{"foo"};
> -// FIXME: explain why the inheriting constructor was deleted
> -// expected-error at -2 {{call to deleted constructor of 'B'}}
> +A a9{"foo"}; // expected-error {{ambiguous}}
> +B b9{"foo"}; // expected-error {{ambiguous}}
>
>  namespace PR15755 {
>    struct X {
>
> Modified: cfe/trunk/test/CXX/special/class.inhctor/p2.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> special/class.inhctor/p2.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/special/class.inhctor/p2.cpp (original)
> +++ cfe/trunk/test/CXX/special/class.inhctor/p2.cpp Tue Jun 28 14:03:57
> 2016
> @@ -1,4 +1,7 @@
>  // RUN: %clang_cc1 -std=c++11 -verify %s
> +//
> +// Note: [class.inhctor] was removed by P0136R1. This tests the new
> behavior
> +// for the wording that used to be there.
>
>  template<int> struct X {};
>
> @@ -8,10 +11,10 @@ template<int> struct X {};
>  //   - absence or presence of explicit
>  //   - absence or presence of constexpr
>  struct A {
> -  A(X<0>) {} // expected-note 2{{here}}
> +  A(X<0>) {} // expected-note 4{{here}}
>    constexpr A(X<1>) {}
> -  explicit A(X<2>) {} // expected-note 3{{here}}
> -  explicit constexpr A(X<3>) {} // expected-note 2{{here}}
> +  explicit A(X<2>) {} // expected-note 6{{here}}
> +  explicit constexpr A(X<3>) {} // expected-note 4{{here}}
>  };
>
>  A a0 { X<0>{} };
> @@ -36,7 +39,7 @@ constexpr A a3ic = { X<3>{} }; // expect
>
>
>  struct B : A {
> -  using A::A; // expected-note 7{{here}}
> +  using A::A;
>  };
>
>  B b0 { X<0>{} };
> @@ -62,14 +65,19 @@ constexpr B b3ic = { X<3>{} }; // expect
>
>  // 'constexpr' is OK even if the constructor doesn't obey the constraints.
>  struct NonLiteral { NonLiteral(); };
> -struct NonConstexpr { NonConstexpr(); constexpr NonConstexpr(int); }; //
> expected-note {{here}}
> +struct NonConstexpr { NonConstexpr(); constexpr NonConstexpr(int); };
>  struct Constexpr { constexpr Constexpr(int) {} };
>
>  struct BothNonLiteral : NonLiteral, Constexpr { using
> Constexpr::Constexpr; }; // expected-note {{base class 'NonLiteral' of
> non-literal type}}
>  constexpr BothNonLiteral bothNL{42}; // expected-error {{constexpr
> variable cannot have non-literal type 'const BothNonLiteral'}}
>
> -struct BothNonConstexpr : NonConstexpr, Constexpr { using
> Constexpr::Constexpr; }; // expected-note {{non-constexpr constructor
> 'NonConstexpr}}
> -constexpr BothNonConstexpr bothNC{42}; // expected-error {{must be
> initialized by a constant expression}} expected-note {{in call to
> 'BothNonConstexpr(42)'}}
> +// FIXME: This diagnostic is not very good. We should explain that the
> problem is that base class NonConstexpr cannot be initialized.
> +struct BothNonConstexpr
> +    : NonConstexpr,
> +      Constexpr {
> +  using Constexpr::Constexpr; // expected-note {{here}}
> +};
> +constexpr BothNonConstexpr bothNC{42}; // expected-error {{must be
> initialized by a constant expression}} expected-note {{inherited from base
> class 'Constexpr'}}
>
>
>  struct ConstexprEval {
> @@ -87,25 +95,25 @@ static_assert(ce.k == 'a', "");
>  static_assert(ce.k2 == 'x', "");
>
>
> -struct TemplateCtors {
> -  constexpr TemplateCtors() {}
> -  template<template<int> class T> TemplateCtors(X<0>, T<0>);
> -  template<int N> TemplateCtors(X<1>, X<N>);
> -  template<typename T> TemplateCtors(X<2>, T);
> +struct TemplateCtors { // expected-note 2{{candidate constructor (the
> implicit}}
> +  constexpr TemplateCtors() {} // expected-note {{candidate inherited
> constructor}}
> +  template<template<int> class T> TemplateCtors(X<0>, T<0>); //
> expected-note {{here}} expected-note {{candidate inherited constructor}}
> +  template<int N> TemplateCtors(X<1>, X<N>); // expected-note {{here}}
> expected-note {{candidate inherited constructor}}
> +  template<typename T> TemplateCtors(X<2>, T); // expected-note {{here}}
> expected-note {{candidate inherited constructor}}
>
> -  template<typename T = int> TemplateCtors(int, int = 0, int = 0); //
> expected-note {{inherited from here}}
> +  template<typename T = int> TemplateCtors(int, int = 0, int = 0);
>  };
>
> -struct UsingTemplateCtors : TemplateCtors {  // expected-note
> 2{{candidate is the implicit}}
> -  using TemplateCtors::TemplateCtors; // expected-note 4{{here}}
> expected-note {{candidate}}
> +struct UsingTemplateCtors : TemplateCtors { // expected-note 2{{candidate
> constructor (the implicit}}
> +  using TemplateCtors::TemplateCtors; // expected-note 6{{inherited here}}
>
> -  constexpr UsingTemplateCtors(X<0>, X<0>) {}
> -  constexpr UsingTemplateCtors(X<1>, X<1>) {}
> -  constexpr UsingTemplateCtors(X<2>, X<2>) {}
> +  constexpr UsingTemplateCtors(X<0>, X<0>) {} // expected-note {{not
> viable}}
> +  constexpr UsingTemplateCtors(X<1>, X<1>) {} // expected-note {{not
> viable}}
> +  constexpr UsingTemplateCtors(X<2>, X<2>) {} // expected-note {{not
> viable}}
>
> -  template<int = 0> constexpr UsingTemplateCtors(int) {} // expected-note
> {{candidate}}
> -  template<typename T = void> constexpr UsingTemplateCtors(int, int) {}
> -  template<typename T, typename U> constexpr UsingTemplateCtors(int, int,
> int) {}
> +  template<int = 0> constexpr UsingTemplateCtors(int) {} // expected-note
> {{not viable}}
> +  template<typename T = void> constexpr UsingTemplateCtors(int, int) {}
> // expected-note {{not viable}}
> +  template<typename T, typename U> constexpr UsingTemplateCtors(int, int,
> int) {} // expected-note {{couldn't infer}}
>  };
>
>  template<int> struct Y {};
> @@ -116,6 +124,10 @@ constexpr UsingTemplateCtors uct4{ X<1>{
>  constexpr UsingTemplateCtors uct5{ X<2>{}, 0 }; // expected-error {{must
> be initialized by a constant expression}} expected-note {{non-constexpr}}
>  constexpr UsingTemplateCtors uct6{ X<2>{}, X<2>{} };
>
> -constexpr UsingTemplateCtors utc7{ 0 }; // expected-error {{ambiguous}}
> +constexpr UsingTemplateCtors utc7{ 0 }; // ok
>  constexpr UsingTemplateCtors utc8{ 0, 0 }; // ok
> -constexpr UsingTemplateCtors utc9{ 0, 0, 0 }; // expected-error {{must be
> initialized by a constant expression}} expected-note {{non-constexpr}}
> +// FIXME: The standard says that UsingTemplateCtors' (int, int, int)
> constructor
> +// hides the one from TemplateCtors, even though the template parameter
> lists
> +// don't match. It's not clear that that's *really* the intent, and it's
> not
> +// what other compilers do.
> +constexpr UsingTemplateCtors utc9{ 0, 0, 0 }; // expected-error {{no
> matching constructor}}
>
> Modified: cfe/trunk/test/CXX/special/class.inhctor/p3.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> special/class.inhctor/p3.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/special/class.inhctor/p3.cpp (original)
> +++ cfe/trunk/test/CXX/special/class.inhctor/p3.cpp Tue Jun 28 14:03:57
> 2016
> @@ -1,8 +1,11 @@
>  // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
> +//
> +// Note: [class.inhctor] was removed by P0136R1. This tests the new
> behavior
> +// for the wording that used to be there.
>
>  struct B1 {
> -  B1(int);
> -  B1(int, int);
> +  B1(int); // expected-note 3{{target of using}}
> +  B1(int, int); // expected-note 3{{target of using}}
>  };
>  struct D1 : B1 {
>    using B1::B1;
> @@ -11,48 +14,56 @@ D1 d1a(1), d1b(1, 1);
>
>  D1 fd1() { return 1; }
>
> -struct B2 {
> +struct B2 { // expected-note 2{{candidate}}
>    explicit B2(int, int = 0, int = 0);
>  };
> -struct D2 : B2 { // expected-note 2 {{candidate constructor}}
> -  using B2::B2;
> +struct D2 : B2 { // expected-note 2{{candidate constructor}}
> +  using B2::B2; // expected-note 2{{inherited here}}
>  };
>  D2 d2a(1), d2b(1, 1), d2c(1, 1, 1);
>
>  D2 fd2() { return 1; } // expected-error {{no viable conversion}}
>
> -struct B3 {
> -  B3(void*); // expected-note {{inherited from here}}
> +struct B3 { // expected-note 2{{candidate}}
> +  B3(void*); // expected-note {{candidate}}
>  };
> -struct D3 : B3 { // expected-note 2 {{candidate constructor}}
> -  using B3::B3; // expected-note {{candidate constructor (inherited)}}
> +struct D3 : B3 { // expected-note 2{{candidate constructor}}
> +  using B3::B3; // expected-note 3{{inherited here}}
>  };
>  D3 fd3() { return 1; } // expected-error {{no viable conversion}}
>
>  template<typename T> struct T1 : B1 {
> -  using B1::B1;
> +  using B1::B1; // expected-note 2{{using declaration}}
>  };
>  template<typename T> struct T2 : T1<T> {
> -  using T1<int>::T1;
> +  using T1<int>::T1; // expected-note 2{{using declaration}}
>  };
>  template<typename T> struct T3 : T1<int> {
> -  using T1<T>::T1;
> +  using T1<T>::T1; // expected-note 2{{using declaration}}
>  };
>  struct U {
> -  friend T1<int>::T1(int);
> -  friend T1<int>::T1(int, int);
> -  friend T2<int>::T2(int);
> -  friend T2<int>::T2(int, int);
> -  friend T3<int>::T3(int);
> -  friend T3<int>::T3(int, int);
> +  // [dcl.meaning]p1: "the member shall not merely hav ebeen introduced
> by a
> +  // using-declaration in the scope of the class [...] nominated by the
> +  // nested-name-specifier of the declarator-id"
> +  friend T1<int>::T1(int); // expected-error {{cannot befriend target of
> using declaration}}
> +  friend T1<int>::T1(int, int); // expected-error {{cannot befriend
> target of using declaration}}
> +  friend T2<int>::T2(int); // expected-error {{cannot befriend target of
> using declaration}}
> +  friend T2<int>::T2(int, int); // expected-error {{cannot befriend
> target of using declaration}}
> +  friend T3<int>::T3(int); // expected-error {{cannot befriend target of
> using declaration}}
> +  friend T3<int>::T3(int, int); // expected-error {{cannot befriend
> target of using declaration}}
>  };
>
>  struct B4 {
> -  template<typename T> explicit B4(T, int = 0);
> +  template<typename T> explicit B4(T, int = 0); // expected-note 2{{here}}
>  };
>  template<typename T> struct T4 : B4 {
> -  using B4::B4; // expected-note {{here}}
> +  using B4::B4;
>    template<typename U> T4(U);
>  };
> +template<typename T> struct U4 : T4<T> {
> +  using T4<T>::T4;
> +};
>  T4<void> t4a = {0};
>  T4<void> t4b = {0, 0}; // expected-error {{chosen constructor is
> explicit}}
> +U4<void> u4a = {0};
> +U4<void> u4b = {0, 0}; // expected-error {{chosen constructor is
> explicit}}
>
> Modified: cfe/trunk/test/CXX/special/class.inhctor/p4.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> special/class.inhctor/p4.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/special/class.inhctor/p4.cpp (original)
> +++ cfe/trunk/test/CXX/special/class.inhctor/p4.cpp Tue Jun 28 14:03:57
> 2016
> @@ -1,4 +1,7 @@
>  // RUN: %clang_cc1 -std=c++11 -verify %s
> +//
> +// Note: [class.inhctor] was removed by P0136R1. This tests the new
> behavior
> +// for the wording that used to be there.
>
>  template<int> struct X {};
>
> @@ -8,20 +11,20 @@ struct A {
>  public:
>    A(X<0>) {}
>  protected:
> -  A(X<1>) {}
> +  A(X<1>) {} // expected-note 2{{declared protected here}}
>  private:
> -  A(X<2>) {} // expected-note {{declared private here}}
> +  A(X<2>) {} // expected-note 2{{declared private here}}
>    friend class FA;
>  };
>
>  struct B : A {
> -  using A::A; // expected-error {{private constructor}} expected-note
> {{implicitly declared protected here}}
> +  using A::A;
>    friend class FB;
>  };
>
>  B b0{X<0>{}};
>  B b1{X<1>{}}; // expected-error {{calling a protected constructor}}
> -B b2{X<2>{}}; // expected-note {{first required here}}
> +B b2{X<2>{}}; // expected-error {{calling a private constructor}}
>
>  struct C : B {
>    C(X<0> x) : B(x) {}
> @@ -34,7 +37,7 @@ struct FB {
>  };
>
>  struct FA : A {
> -  using A::A; // expected-note 2{{here}}
> +  using A::A;
>  };
>  FA fa0{X<0>{}};
>  FA fa1{X<1>{}}; // expected-error {{calling a protected constructor}}
> @@ -47,7 +50,7 @@ struct G {
>    template<typename T> G(T*) = delete; // expected-note {{'G<const char>'
> has been explicitly marked deleted here}}
>  };
>  struct H : G {
> -  using G::G; // expected-note 2{{deleted constructor was inherited here}}
> +  using G::G;
>  };
>  H h1(5); // expected-error {{call to deleted constructor of 'H'}}
>  H h2("foo"); // expected-error {{call to deleted constructor of 'H'}}
> @@ -57,15 +60,15 @@ H h2("foo"); // expected-error {{call to
>  // same signature.
>  namespace DRnnnn {
>    struct A {
> -    constexpr A(int, float = 0) {}
> -    explicit A(int, int = 0) {} // expected-note {{constructor cannot be
> inherited}}
> +    constexpr A(int, float = 0) {} // expected-note {{candidate}}
> +    explicit A(int, int = 0) {} // expected-note {{candidate}}
>
> -    A(int, int, int = 0) = delete;
> +    A(int, int, int = 0) = delete; // expected-note {{deleted}}
>    };
>    struct B : A {
> -    using A::A; // expected-note {{here}}
> +    using A::A; // expected-note 3{{inherited here}}
>    };
>
>    constexpr B b0(0, 0.0f); // ok, constexpr
> -  B b1(0, 1); // expected-error {{call to deleted constructor of
> 'DRnnnn::B'}}
> +  B b1(0, 1); // expected-error {{call to constructor of 'DRnnnn::B' is
> ambiguous}}
>  }
>
> Modified: cfe/trunk/test/CXX/special/class.inhctor/p7.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> special/class.inhctor/p7.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/special/class.inhctor/p7.cpp (original)
> +++ cfe/trunk/test/CXX/special/class.inhctor/p7.cpp Tue Jun 28 14:03:57
> 2016
> @@ -1,47 +1,48 @@
>  // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
> +//
> +// Note: [class.inhctor] was removed by P0136R1. This tests the new
> behavior
> +// for the wording that used to be there.
>
> -// Straight from the standard
> -struct B1 {
> -  B1(int); // expected-note {{previous constructor}} expected-note
> {{conflicting constructor}}
> -};
> -struct B2 {
> -  B2(int); // expected-note {{conflicting constructor}}
> -};
> -struct D1 : B1, B2 {
> -  using B1::B1; // expected-note {{inherited here}}
> -  using B2::B2; // expected-error {{already inherited constructor with
> the same signature}}
> +struct B1 { // expected-note 2{{candidate}}
> +  B1(int); // expected-note {{candidate}}
> +};
> +struct B2 { // expected-note 2{{candidate}}
> +  B2(int); // expected-note {{candidate}}
> +};
> +struct D1 : B1, B2 { // expected-note 2{{candidate}}
> +  using B1::B1; // expected-note 3{{inherited here}}
> +  using B2::B2; // expected-note 3{{inherited here}}
>  };
>  struct D2 : B1, B2 {
>    using B1::B1;
>    using B2::B2;
>    D2(int);
>  };
> +D1 d1(0); // expected-error {{ambiguous}}
> +D2 d2(0);
>
>  template<typename T> struct B3 {
> -  B3(T); // expected-note {{previous constructor}}
> +  B3(T);
>  };
>  template<typename T> struct B4 : B3<T>, B1 {
>    B4();
> -  using B3<T>::B3; // expected-note {{inherited here}}
> -  using B1::B1; // expected-error {{already inherited}}
> +  using B3<T>::B3;
> +  using B1::B1;
>  };
>  B4<char> b4c;
> -B4<int> b4i; // expected-note {{here}}
> +B4<int> b4i;
>
>  struct B5 {
> -  template<typename T> B5(T); // expected-note {{previous constructor}}
> +  template<typename T> B5(T);
>  };
> -struct B6 {
> -  template<typename T> B6(T); // expected-note {{conflicting constructor}}
> -};
> -struct B7 {
> -  template<typename T, int> B7(T);
> -};
> -struct D56 : B5, B6, B7 {
> -  using B5::B5; // expected-note {{inherited here}}
> -  using B6::B6; // expected-error {{already inherited}}
> +struct D6 : B5 {
> +  using B5::B5;
> +  template<typename T> D6(T);
>  };
> -struct D57 : B5, B6, B7 {
> +D6 d6(0);
> +struct D7 : B5 {
>    using B5::B5;
> -  using B7::B7; // ok, not the same signature
> +  template<typename T> D7(T, ...);
>  };
> +// DRxxx (no number yet): derived class ctor beats base class ctor.
> +D7 d7(0);
>
> Modified: cfe/trunk/test/CXX/special/class.inhctor/p8.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> special/class.inhctor/p8.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/special/class.inhctor/p8.cpp (original)
> +++ cfe/trunk/test/CXX/special/class.inhctor/p8.cpp Tue Jun 28 14:03:57
> 2016
> @@ -1,4 +1,7 @@
>  // RUN: %clang_cc1 -std=c++11 -verify %s
> +//
> +// Note: [class.inhctor] was removed by P0136R1. This tests the new
> behavior
> +// for the wording that used to be there.
>
>  struct A {
>    constexpr A(const int&) : rval(false) {}
> @@ -13,8 +16,6 @@ constexpr int k = 0;
>  constexpr A a0{0};
>  constexpr A a1{k};
>  constexpr B b0{0};
> -// This performs static_cast<(const int&)&&>(k), so calls the A(const
> int&)
> -// constructor.
>  constexpr B b1{k};
>
>  static_assert(a0.rval && !a1.rval && b0.rval && !b1.rval, "");
> @@ -28,5 +29,4 @@ struct D : C {
>  };
>  static_assert(D(123).v == 123, "");
>
> -// FIXME: This diagnostic sucks.
> -template<typename T> constexpr D::D(T t) : C(t) {} // expected-error
> {{definition of implicitly declared function}}
> +template<typename T> constexpr D::D(T t) : C(t) {} // expected-error
> {{does not match any declaration in 'D'}}
>
> Added: cfe/trunk/test/CXX/special/class.init/class.inhctor.init/p1.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> special/class.init/class.inhctor.init/p1.cpp?rev=274049&view=auto
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/special/class.init/class.inhctor.init/p1.cpp
> (added)
> +++ cfe/trunk/test/CXX/special/class.init/class.inhctor.init/p1.cpp Tue
> Jun 28 14:03:57 2016
> @@ -0,0 +1,124 @@
> +// RUN: %clang_cc1 -std=c++11 -verify %s
> +
> +namespace std_example {
> +  struct B1 { // expected-note {{declared here}}
> +    B1(int, ...) {}
> +  };
> +
> +  struct B2 {
> +    B2(double) {}
> +  };
> +
> +  int get();
> +
> +  struct D1 : B1 { // expected-note {{no default constructor}}
> +    using B1::B1; // inherits B1(int, ...)
> +    int x;
> +    int y = get();
> +  };
> +
> +  void test() {
> +    D1 d(2, 3, 4); // OK: B1 is initialized by calling B1(2, 3, 4),
> +    // then d.x is default-initialized (no initialization is performed),
> +    // then d.y is initialized by calling get()
> +    D1 e; // expected-error {{implicitly-deleted}}
> +  }
> +
> +  struct D2 : B2 {
> +    using B2::B2; // expected-error {{cannot use constructor inherited
> from base class 'B2'; member 'b' of 'std_example::D2' does not have a
> default constructor}}
> +    B1 b; // expected-note {{member}}
> +  };
> +
> +  D2 f(1.0); // expected-note {{inherited constructor for 'D2' first
> required here}}
> +
> +  struct W {
> +    W(int);
> +  };
> +  struct X : virtual W {
> +    using W::W;
> +    X() = delete;
> +  };
> +  struct Y : X {
> +    using X::X;
> +  };
> +  struct Z : Y, virtual W {
> +    using Y::Y;
> +  };
> +  Z z(0); // OK: initialization of Y does not invoke default constructor
> of X
> +
> +  template <class T> struct Log : T {
> +    using T::T; // inherits all constructors from class T
> +    ~Log() { /* ... */ }
> +  };
> +}
> +
> +namespace vbase {
> +  struct V { // expected-note 2{{declared here}}
> +    V(int);
> +  };
> +
> +  struct A : virtual V {
> +    A() = delete; // expected-note 2{{deleted here}} expected-note
> {{deleted}}
> +    using V::V;
> +  };
> +  struct B : virtual V {
> +    B() = delete; // expected-note 2{{deleted here}}
> +    B(int, int);
> +    using V::V;
> +  };
> +  struct C : B { // expected-note {{deleted default constructor}}
> +    using B::B; // expected-error {{cannot use constructor inherited from
> base class 'B'; base class 'vbase::V' of 'vbase::C' does not have a default
> constructor}}
> +  };
> +  struct D : A, C { // expected-note {{deleted default constructor}}
> +    using A::A;
> +    using C::C; // expected-error {{cannot use constructor inherited from
> base class 'C'; base class 'vbase::V' of 'vbase::D' does not have a default
> constructor}} expected-error {{call to deleted constructor of 'vbase::A'}}
> +  };
> +
> +  A a0; // expected-error {{deleted}}
> +  A a1(0);
> +  B b0; // expected-error {{deleted}}
> +  B b1(0);
> +  B b2(0, 0);
> +  C c0; // expected-error {{deleted}}
> +  C c1(0);
> +  C c2(0, 0); // expected-note {{first required here}}
> +  D d0; // expected-error {{implicitly-deleted}}
> +  D d1(0);
> +  D d2(0, 0); // expected-note {{first required here}}
> +}
> +
> +namespace constexpr_init_order {
> +  struct Param;
> +  struct A {
> +    constexpr A(Param);
> +    int a;
> +  };
> +
> +  struct B : A { B(); using A::A; int b = 2; };
> +  extern const B b;
> +
> +  struct Param {
> +    constexpr Param(int c) : n(4 * b.a + b.b + c) {}
> +    int n;
> +  };
> +
> +  constexpr A::A(Param p) : a(p.n) {}
> +
> +  constexpr B b(1);
> +  constexpr B c(1);
> +  static_assert(b.a == 1, "p should be initialized before B() is
> executed");
> +  static_assert(c.a == 7, "b not initialzed properly");
> +}
> +
> +namespace default_args {
> +  // We work around a defect in P0136R1 where it would reject reasonable
> +  // code like the following:
> +  struct Base {
> +    Base(int = 0);
> +  };
> +  struct Derived : Base {
> +    using Base::Base;
> +  };
> +  Derived d;
> +  // FIXME: Once a fix is standardized, implement it.
> +}
>
> Added: cfe/trunk/test/CXX/special/class.init/class.inhctor.init/p2.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> special/class.init/class.inhctor.init/p2.cpp?rev=274049&view=auto
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/special/class.init/class.inhctor.init/p2.cpp
> (added)
> +++ cfe/trunk/test/CXX/special/class.init/class.inhctor.init/p2.cpp Tue
> Jun 28 14:03:57 2016
> @@ -0,0 +1,33 @@
> +// RUN: %clang_cc1 -std=c++11 -verify %s
> +
> +namespace std_example {
> +  struct A { A(int); };
> +  struct B : A { using A::A; };
> +
> +  struct C1 : B { using B::B; };
> +  struct C2 : B { using B::B; };
> +
> +  struct D1 : C1, C2 {
> +    using C1::C1; // expected-note {{inherited from base class 'C1' here}}
> +    using C2::C2; // expected-note {{inherited from base class 'C2' here}}
> +  };
> +
> +  struct V1 : virtual B { using B::B; };
> +  struct V2 : virtual B { using B::B; };
> +
> +  struct D2 : V1, V2 {
> +    using V1::V1;
> +    using V2::V2;
> +  };
> +
> +  D1 d1(0); // expected-error {{constructor of 'A' inherited from
> multiple base class subobjects}}
> +  D2 d2(0); // OK: initializes virtual B base class, which initializes
> the A base class
> +            // then initializes the V1 and V2 base classes as if by a
> defaulted default constructor
> +
> +  struct M { M(); M(int); };
> +  struct N : M { using M::M; };
> +  struct O : M {};
> +  struct P : N, O { using N::N; using O::O; };
> +  P p(0); // OK: use M(0) to initialize N's base class,
> +          // use M() to initialize O's base class
> +}
>
> Modified: cfe/trunk/test/CodeGenCXX/inheriting-constructor.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
> CodeGenCXX/inheriting-constructor.cpp?rev=274049&r1=
> 274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CodeGenCXX/inheriting-constructor.cpp (original)
> +++ cfe/trunk/test/CodeGenCXX/inheriting-constructor.cpp Tue Jun 28
> 14:03:57 2016
> @@ -1,4 +1,8 @@
> -// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o
> - %s | FileCheck %s
> +// RUN: %clang_cc1 -std=c++11 -triple i386-linux -emit-llvm -o - %s |
> FileCheck %s --check-prefix=CHECK --check-prefix=ITANIUM
> +// RUN: %clang_cc1 -std=c++11 -triple x86_64-darwin -emit-llvm -o - %s |
> FileCheck %s --check-prefix=CHECK --check-prefix=ITANIUM
> +// RUN: %clang_cc1 -std=c++11 -triple arm64-ehabi -emit-llvm -o - %s |
> FileCheck %s --check-prefix=CHECK --check-prefix=ITANIUM
> +// RUN: %clang_cc1 -std=c++11 -triple i386-windows -emit-llvm -o - %s |
> FileCheck %s --check-prefix=CHECK --check-prefix=MSABI --check-prefix=WIN32
> +// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm -o - %s |
> FileCheck %s --check-prefix=CHECK --check-prefix=MSABI --check-prefix=WIN64
>
>  // PR12219
>  struct A { A(int); virtual ~A(); };
> @@ -11,18 +15,396 @@ struct C { template<typename T> C(T); };
>  struct D : C { using C::C; };
>  D d(123);
>
> -// CHECK-LABEL: define void @_ZN1BD2Ev
> -// CHECK-LABEL: define void @_ZN1BD1Ev
> -// CHECK-LABEL: define void @_ZN1BD0Ev
> +// ITANIUM-LABEL: define void @_ZN1BD2Ev
> +// ITANIUM-LABEL: define void @_ZN1BD1Ev
> +// ITANIUM-LABEL: define void @_ZN1BD0Ev
> +// WIN32-LABEL: define {{.*}}void @"\01??1B@@UAE at XZ"
> +// WIN64-LABEL: define {{.*}}void @"\01??1B@@UEAA at XZ"
>
> -// CHECK-LABEL: define linkonce_odr void @_ZN1BC1Ei(
> -// CHECK: call void @_ZN1BC2Ei(
> +// ITANIUM-LABEL: define linkonce_odr void @_ZN1BCI11AEi(
> +// ITANIUM: call void @_ZN1BCI21AEi(
>
> -// CHECK-LABEL: define linkonce_odr void @_ZN1DC1IiEET_(
> -// CHECK: call void @_ZN1DC2IiEET_(
> +// ITANIUM-LABEL: define linkonce_odr void @_ZN1DCI11CIiEET_(
> +// ITANIUM: call void @_ZN1DCI21CIiEET_(
>
> -// CHECK-LABEL: define linkonce_odr void @_ZN1BC2Ei(
> -// CHECK: call void @_ZN1AC2Ei(
> +// WIN32-LABEL: define internal {{.*}} @"\01??0B@@QAE at H@Z"(
> +// WIN32: call {{.*}} @"\01??0A@@QAE at H@Z"(
> +// WIN64-LABEL: define internal {{.*}} @"\01??0B@@QEAA at H@Z"(
> +// WIN64: call {{.*}} @"\01??0A@@QEAA at H@Z"(
>
> -// CHECK-LABEL: define linkonce_odr void @_ZN1DC2IiEET_(
> -// CHECK: call void @_ZN1CC2IiEET_(
> +// WIN32-LABEL: define internal {{.*}} @"\01??0D@@QAE at H@Z"(
> +// WIN32: call {{.*}} @"\01??$?0H at C@@QAE at H@Z"
> +// WIN64-LABEL: define internal {{.*}} @"\01??0D@@QEAA at H@Z"(
> +// WIN64: call {{.*}} @"\01??$?0H at C@@QEAA at H@Z"
> +
> +struct Q { Q(int); Q(const Q&); ~Q(); };
> +struct Z { Z(); Z(int); ~Z(); int n; };
> +
> +namespace noninline_nonvirt {
> +  struct A { A(int, Q&&, void *__attribute__((pass_object_size(0))));
> int n; };
> +  struct B : Z, A { Z z; using A::A; };
> +  B b(1, 2, &b);
> +  // ITANIUM-LABEL: define {{.*}} @__cxx_global_var_init
> +  // ITANIUM: call void @_ZN1QC1Ei({{.*}} %[[TMP:.*]], i32 2)
> +  // ITANIUM: call void @_ZN17noninline_nonvirt1BCI1NS_
> 1AEEiO1QPvU17pass_object_size0({{.*}} @_ZN17noninline_nonvirt1bE, i32 1,
> {{.*}} %[[TMP]], i8* {{.*}} @_ZN17noninline_nonvirt1bE{{.*}}, i{{32|64}}
> 12)
> +  // ITANIUM: call void @_ZN1QD1Ev({{.*}} %[[TMP]])
> +  // ITANIUM: call i32 @__cxa_atexit(
> +
> +  // Complete object ctor for B delegates to base object ctor.
> +  // ITANIUM-LABEL: define linkonce_odr void @_ZN17noninline_
> nonvirt1BCI1NS_1AEEiO1QPvU17pass_object_size0(
> +  // ITANIUM: call void @_ZN17noninline_nonvirt1BCI2NS_
> 1AEEiO1QPvU17pass_object_size0({{.*}}, i32 {{.*}}, %{{.*}}* {{.*}}, i8*
> {{.*}}, i{{32|64}} {{.*}})
> +
> +  // In MSABI, we don't have ctor variants. B ctor forwards to A ctor.
> +  // MSABI-LABEL: define internal {{.*}} @"\01??0B at noninline_nonvirt@@
> Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0 at __clang@@@Z"(%{{.*}},
> i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}})
> +  // MSABI: call {{.*}} @"\01??0Z@@Q{{AE|EAA}}@XZ"(
> +  // MSABI: call {{.*}} @"\01??0A at noninline_nonvirt@@Q{{AE|EAA}}@H
> $$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0 at __clang@@@Z"(%{{.*}},
> i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}})
> +  // MSABI: call {{.*}} @"\01??0Z@@Q{{AE|EAA}}@XZ"(
> +
> +  struct C : B { using B::B; };
> +  C c(1, 2, &c);
> +  // Complete object ctor for C delegates.
> +  // ITANIUM-LABEL: define linkonce_odr void @_ZN17noninline_
> nonvirt1CCI1NS_1AEEiO1QPvU17pass_object_size0(
> +  // ITANIUM: call void @_ZN17noninline_nonvirt1CCI2NS_
> 1AEEiO1QPvU17pass_object_size0({{.*}}, i32 {{.*}}, %{{.*}}* {{.*}}, i8*
> {{.*}}, i{{32|64}} {{.*}})
> +
> +  // MSABI-LABEL: define internal {{.*}} @"\01??0C at noninline_nonvirt@@
> Q{{AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0 at __clang@@@Z"(%{{.*}},
> i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}})
> +  // MSABI: call {{.*}} @"\01??0B at noninline_nonvirt@@Q{{AE|EAA}}@H
> $$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0 at __clang@@@Z"(%{{.*}},
> i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}})
> +}
> +
> +namespace noninline_virt {
> +  struct A { A(int, Q&&, void *__attribute__((pass_object_size(0))));
> int n; };
> +  struct B : Z, virtual A { Z z; using A::A; };
> +  B b(1, 2, &b);
> +  // Complete object ctor forwards to A ctor then constructs Zs.
> +  // ITANIUM-LABEL: define linkonce_odr void @_ZN14noninline_virt1BCI1NS_
> 1AEEiO1QPvU17pass_object_size0(
> +  // ITANIUM: call void @_ZN14noninline_virt1AC2EiO1QPvU17pass_object_size0({{.*}}
> %{{.*}}, i32 %{{.*}}, %{{.*}}* {{.*}}, i8* {{.*}}, i{{32|64}} %{{.*}}
> +  // ITANIUM: call void @_ZN1ZC2Ev(
> +  // ITANIUM: store {{.*}} @_ZTVN14noninline_virt1BE
> +  // ITANIUM: call void @_ZN1ZC1Ev(
> +
> +  // MSABI-LABEL: define internal {{.*}} @"\01??0B at noninline_virt@@Q{{
> AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0 at __clang@@@Z"(%{{.*}},
> i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}}, i32 %{{.*}})
> +  // MSABI: %[[COMPLETE:.*]] = icmp ne
> +  // MSABI: br i1 %[[COMPLETE]],
> +  // MSABI: call {{.*}} @"\01??0A at noninline_virt@@Q{{AE|EAA}}@H
> $$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0 at __clang@@@Z"(%{{.*}},
> i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}})
> +  // MSABI: br
> +  // MSABI: call {{.*}} @"\01??0Z@@Q{{AE|EAA}}@XZ"(
> +  // MSABI: call {{.*}} @"\01??0Z@@Q{{AE|EAA}}@XZ"(
> +
> +  struct C : B { using B::B; };
> +  C c(1, 2, &c);
> +  // Complete object ctor forwards to A ctor, then calls B's base
> inheriting
> +  // constructor, which takes no arguments other than the this pointer
> and VTT.
> +  // ITANIUM_LABEL: define linkonce_odr void @_ZN14noninline_virt1CCI1NS_
> 1AEEiO1QPvU17pass_object_size0(
> +  // ITANIUM: call void @_ZN14noninline_virt1AC2EiO1QPvU17pass_object_size0({{.*}}
> %{{.*}}, i32 %{{.*}}, %{{.*}}* {{.*}}, i8* %{{.*}}, i{{32|64}} %{{.*}})
> +  // ITANIUM: call void @_ZN14noninline_virt1BCI2NS_
> 1AEEiO1QPvU17pass_object_size0(%{{.*}}* %{{.*}}, i8** getelementptr
> inbounds ([2 x i8*], [2 x i8*]* @_ZTTN14noninline_virt1CE, i64 0, i64 1))
> +  // ITANIUM: store {{.*}} @_ZTVN14noninline_virt1CE
> +
> +  // C constructor forwards to B constructor and A constructor. We pass
> the args
> +  // to both. FIXME: Can we pass undef here instead, for the base object
> +  // constructor call?
> +  // MSABI-LABEL: define internal {{.*}} @"\01??0C at noninline_virt@@Q{{
> AE|EAA}}@H$$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0 at __clang@@@Z"(%{{.*}},
> i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}}, i32 %{{.*}})
> +  // MSABI: %[[COMPLETE:.*]] = icmp ne
> +  // MSABI: br i1 %[[COMPLETE]],
> +  // MSABI: call {{.*}} @"\01??0A at noninline_virt@@Q{{AE|EAA}}@H
> $$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0 at __clang@@@Z"(%{{.*}},
> i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}})
> +  // MSABI: br
> +  // MSABI: call {{.*}} @"\01??0B at noninline_virt@@Q{{AE|EAA}}@H
> $$Q{{E?}}AUQ@@P{{E?}}AXW4__pass_object_size0 at __clang@@@Z"(%{{.*}},
> i32{{.*}}, %{{.*}}, i8*{{.*}}, i{{32|64}}{{.*}}, i32 0)
> +}
> +
> +// For MSABI only, check that inalloca arguments result in inlining.
> +namespace inalloca_nonvirt {
> +  struct A { A(Q, int, Q, Q&&); int n; };
> +  struct B : Z, A { Z z; using A::A; };
> +  B b(1, 2, 3, 4);
> +  // No inlining implied for Itanium.
> +  // ITANIUM-LABEL: define linkonce_odr void
> @_ZN16inalloca_nonvirt1BCI1NS_1AEE1QiS1_OS1_(
> +  // ITANIUM: call void @_ZN16inalloca_nonvirt1BCI2NS_1AEE1QiS1_OS1_(
> +
> +  // MSABI-LABEL: define internal void @"\01??__Eb at inalloca_nonvirt@@
> YAXXZ"(
> +
> +  // On Win32, the inalloca call can't be forwarded so we force inlining.
> +  // WIN32: %[[TMP:.*]] = alloca
> +  // WIN32: call i8* @llvm.stacksave()
> +  // WIN32: %[[ARGMEM:.*]] = alloca inalloca
> +  // WIN32: call {{.*}} @"\01??0Q@@QAE at H@Z"(%{{.*}}* %[[TMP]], i32 4)
> +  // WIN32: %[[ARG3:.*]] = getelementptr {{.*}} %[[ARGMEM]]
> +  // WIN32: call {{.*}} @"\01??0Q@@QAE at H@Z"({{.*}}* %[[ARG3]], i32 3)
> +  // WIN32: %[[ARG1:.*]] = getelementptr {{.*}} %[[ARGMEM]]
> +  // WIN32: call {{.*}} @"\01??0Q@@QAE at H@Z"({{.*}}* %[[ARG1]], i32 1)
> +  // WIN32: call {{.*}} @"\01??0Z@@QAE at XZ"(
> +  // WIN32: %[[ARG2:.*]] = getelementptr {{.*}} %[[ARGMEM]]
> +  // WIN32: store i32 2, i32* %[[ARG2]]
> +  // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]]
> +  // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]]
> +  // WIN32: call {{.*}} @"\01??0A at inalloca_nonvirt@@QAE at UQ@@H0$$QAU2@
> @Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]])
> +  // WIN32: call void @llvm.stackrestore(
> +  // WIN32: call {{.*}} @"\01??0Z@@QAE at XZ"(
> +  // WIN32: call {{.*}} @"\01??_DQ@@QAE at XZ"(
> +
> +  // On Win64, the Q arguments would be destroyed in the callee. We don't
> yet
> +  // support that in the non-inlined case, so we force inlining.
> +  // WIN64: %[[TMP:.*]] = alloca
> +  // WIN64: %[[ARG3:.*]] = alloca
> +  // WIN64: %[[ARG1:.*]] = alloca
> +  // WIN64: call {{.*}} @"\01??0Q@@QEAA at H@Z"({{.*}}* %[[TMP]], i32 4)
> +  // WIN64: call {{.*}} @"\01??0Q@@QEAA at H@Z"({{.*}}* %[[ARG3]], i32 3)
> +  // WIN64: call {{.*}} @"\01??0Q@@QEAA at H@Z"({{.*}}* %[[ARG1]], i32 1)
> +  // WIN64: call {{.*}} @"\01??0Z@@QEAA at XZ"(
> +  // WIN64: call {{.*}} @"\01??0A at inalloca_nonvirt@@QEAA at UQ@@H0$$QEAU2@
> @Z"(%{{.*}}, %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}}
> %[[TMP]])
> +  // WIN64: call {{.*}} @"\01??0Z@@QEAA at XZ"(
> +  // WIN64: call void @"\01??_DQ@@QEAA at XZ"({{.*}}* %[[TMP]])
> +
> +  struct C : B { using B::B; };
> +  C c(1, 2, 3, 4);
> +  // MSABI-LABEL: define internal void @"\01??__Ec at inalloca_nonvirt@@
> YAXXZ"(
> +
> +  // On Win32, the inalloca call can't be forwarded so we force inlining.
> +  // WIN32: %[[TMP:.*]] = alloca
> +  // WIN32: call i8* @llvm.stacksave()
> +  // WIN32: %[[ARGMEM:.*]] = alloca inalloca
> +  // WIN32: call {{.*}} @"\01??0Q@@QAE at H@Z"(%{{.*}}* %[[TMP]], i32 4)
> +  // WIN32: %[[ARG3:.*]] = getelementptr {{.*}} %[[ARGMEM]]
> +  // WIN32: call {{.*}} @"\01??0Q@@QAE at H@Z"({{.*}}* %[[ARG3]], i32 3)
> +  // WIN32: %[[ARG1:.*]] = getelementptr {{.*}} %[[ARGMEM]]
> +  // WIN32: call {{.*}} @"\01??0Q@@QAE at H@Z"({{.*}}* %[[ARG1]], i32 1)
> +  // WIN32: call {{.*}} @"\01??0Z@@QAE at XZ"(
> +  // WIN32: %[[ARG2:.*]] = getelementptr {{.*}} %[[ARGMEM]]
> +  // WIN32: store i32 2, i32* %[[ARG2]]
> +  // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]]
> +  // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]]
> +  // WIN32: call {{.*}} @"\01??0A at inalloca_nonvirt@@QAE at UQ@@H0$$QAU2@
> @Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]])
> +  // WIN32: call void @llvm.stackrestore(
> +  // WIN32: call {{.*}} @"\01??0Z@@QAE at XZ"(
> +  // WIN32: call {{.*}} @"\01??_DQ@@QAE at XZ"(
> +
> +  // On Win64, the Q arguments would be destroyed in the callee. We don't
> yet
> +  // support that in the non-inlined case, so we force inlining.
> +  // WIN64: %[[TMP:.*]] = alloca
> +  // WIN64: %[[ARG3:.*]] = alloca
> +  // WIN64: %[[ARG1:.*]] = alloca
> +  // WIN64: call {{.*}} @"\01??0Q@@QEAA at H@Z"({{.*}}* %[[TMP]], i32 4)
> +  // WIN64: call {{.*}} @"\01??0Q@@QEAA at H@Z"({{.*}}* %[[ARG3]], i32 3)
> +  // WIN64: call {{.*}} @"\01??0Q@@QEAA at H@Z"({{.*}}* %[[ARG1]], i32 1)
> +  // WIN64: call {{.*}} @"\01??0Z@@QEAA at XZ"(
> +  // WIN64: call {{.*}} @"\01??0A at inalloca_nonvirt@@QEAA at UQ@@H0$$QEAU2@
> @Z"(%{{.*}}, %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}}
> %[[TMP]])
> +  // WIN64: call {{.*}} @"\01??0Z@@QEAA at XZ"(
> +  // WIN64: call void @"\01??_DQ@@QEAA at XZ"({{.*}}* %[[TMP]])
> +}
> +
> +namespace inalloca_virt {
> +  struct A { A(Q, int, Q, Q&&); int n; };
> +  struct B : Z, virtual A { Z z; using A::A; };
> +  B b(1, 2, 3, 4);
> +
> +  // MSABI-LABEL: define internal void @"\01??__Eb at inalloca_virt@@YAXXZ"(
> +
> +  // On Win32, the inalloca call can't be forwarded so we force inlining.
> +  // WIN32: %[[TMP:.*]] = alloca
> +  // WIN32: call i8* @llvm.stacksave()
> +  // WIN32: %[[ARGMEM:.*]] = alloca inalloca
> +  // WIN32: call {{.*}} @"\01??0Q@@QAE at H@Z"(%{{.*}}* %[[TMP]], i32 4)
> +  // WIN32: %[[ARG3:.*]] = getelementptr {{.*}} %[[ARGMEM]]
> +  // WIN32: call {{.*}} @"\01??0Q@@QAE at H@Z"({{.*}}* %[[ARG3]], i32 3)
> +  // WIN32: %[[ARG1:.*]] = getelementptr {{.*}} %[[ARGMEM]]
> +  // WIN32: call {{.*}} @"\01??0Q@@QAE at H@Z"({{.*}}* %[[ARG1]], i32 1)
> +  // FIXME: It's dumb to round-trip this though memory and generate a
> branch.
> +  // WIN32: store i32 1, i32* %[[IS_MOST_DERIVED_ADDR:.*]]
> +  // WIN32: %[[IS_MOST_DERIVED:.*]] = load i32, i32*
> %[[IS_MOST_DERIVED_ADDR]]
> +  // WIN32: %[[IS_MOST_DERIVED_i1:.*]] = icmp ne i32
> %[[IS_MOST_DERIVED]], 0
> +  // WIN32: br i1 %[[IS_MOST_DERIVED_i1]]
> +  //
> +  // WIN32: store {{.*}} @"\01??_8B at inalloca_virt@@7B@"
> +  // WIN32: %[[ARG2:.*]] = getelementptr {{.*}} %[[ARGMEM]]
> +  // WIN32: store i32 2, i32* %[[ARG2]]
> +  // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]]
> +  // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]]
> +  // WIN32: call {{.*}} @"\01??0A at inalloca_virt@@QAE at UQ@@H0$$QAU2@@Z"(%{{[^,]*}},
> <{{.*}}>* inalloca %[[ARGMEM]])
> +  // WIN32: call void @llvm.stackrestore(
> +  // WIN32: br
> +  //
> +  // Note that if we jumped directly to here we would fail to
> stackrestore and
> +  // destroy the parameters, but that's not actually possible.
> +  // WIN32: call {{.*}} @"\01??0Z@@QAE at XZ"(
> +  // WIN32: call {{.*}} @"\01??0Z@@QAE at XZ"(
> +  // WIN32: call {{.*}} @"\01??_DQ@@QAE at XZ"(
> +
> +  // On Win64, the Q arguments would be destroyed in the callee. We don't
> yet
> +  // support that in the non-inlined case, so we force inlining.
> +  // WIN64: %[[TMP:.*]] = alloca
> +  // WIN64: %[[ARG3:.*]] = alloca
> +  // WIN64: %[[ARG1:.*]] = alloca
> +  // WIN64: call {{.*}} @"\01??0Q@@QEAA at H@Z"({{.*}}* %[[TMP]], i32 4)
> +  // WIN64: call {{.*}} @"\01??0Q@@QEAA at H@Z"({{.*}}* %[[ARG3]], i32 3)
> +  // WIN64: call {{.*}} @"\01??0Q@@QEAA at H@Z"({{.*}}* %[[ARG1]], i32 1)
> +  // WIN64: br i1
> +  // WIN64: call {{.*}} @"\01??0A at inalloca_virt@@QEAA at UQ@@H0$$QEAU2@@Z"(%{{.*}},
> %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}} %[[TMP]])
> +  // WIN64: br
> +  // WIN64: call {{.*}} @"\01??0Z@@QEAA at XZ"(
> +  // WIN64: call {{.*}} @"\01??0Z@@QEAA at XZ"(
> +  // WIN64: call void @"\01??_DQ@@QEAA at XZ"({{.*}}* %[[TMP]])
> +
> +  struct C : B { using B::B; };
> +  C c(1, 2, 3, 4);
> +  // ITANIUM-LABEL: define linkonce_odr void @_ZN13inalloca_virt1CD1Ev(
> +
> +  // MSABI-LABEL: define internal void @"\01??__Ec at inalloca_virt@@YAXXZ"(
> +
> +  // On Win32, the inalloca call can't be forwarded so we force inlining.
> +  // WIN32: %[[TMP:.*]] = alloca
> +  // WIN32: call i8* @llvm.stacksave()
> +  // WIN32: %[[ARGMEM:.*]] = alloca inalloca
> +  // WIN32: call {{.*}} @"\01??0Q@@QAE at H@Z"(%{{.*}}* %[[TMP]], i32 4)
> +  // WIN32: %[[ARG3:.*]] = getelementptr {{.*}} %[[ARGMEM]]
> +  // WIN32: call {{.*}} @"\01??0Q@@QAE at H@Z"({{.*}}* %[[ARG3]], i32 3)
> +  // WIN32: %[[ARG1:.*]] = getelementptr {{.*}} %[[ARGMEM]]
> +  // WIN32: call {{.*}} @"\01??0Q@@QAE at H@Z"({{.*}}* %[[ARG1]], i32 1)
> +  // WIN32: store i32 1, i32* %[[IS_MOST_DERIVED_ADDR:.*]]
> +  // WIN32: %[[IS_MOST_DERIVED:.*]] = load i32, i32*
> %[[IS_MOST_DERIVED_ADDR]]
> +  // WIN32: %[[IS_MOST_DERIVED_i1:.*]] = icmp ne i32
> %[[IS_MOST_DERIVED]], 0
> +  // WIN32: br i1 %[[IS_MOST_DERIVED_i1]]
> +  //
> +  // WIN32: store {{.*}} @"\01??_8C at inalloca_virt@@7B@"
> +  // WIN32: %[[ARG2:.*]] = getelementptr {{.*}} %[[ARGMEM]]
> +  // WIN32: store i32 2, i32* %[[ARG2]]
> +  // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]]
> +  // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]]
> +  // WIN32: call {{.*}} @"\01??0A at inalloca_virt@@QAE at UQ@@H0$$QAU2@@Z"(%{{[^,]*}},
> <{{.*}}>* inalloca %[[ARGMEM]])
> +  // WIN32: call void @llvm.stackrestore(
> +  // WIN32: br
> +  //
> +  // WIN32: store i32 0, i32* %[[IS_MOST_DERIVED_ADDR:.*]]
> +  // WIN32: %[[IS_MOST_DERIVED:.*]] = load i32, i32*
> %[[IS_MOST_DERIVED_ADDR]]
> +  // WIN32: %[[IS_MOST_DERIVED_i1:.*]] = icmp ne i32
> %[[IS_MOST_DERIVED]], 0
> +  // WIN32: br i1 %[[IS_MOST_DERIVED_i1]]
> +  //
> +  // Note: this block is unreachable.
> +  // WIN32: store {{.*}} @"\01??_8B at inalloca_virt@@7B@"
> +  // WIN32: br
> +  //
> +  // WIN32: call {{.*}} @"\01??0Z@@QAE at XZ"(
> +  // WIN32: call {{.*}} @"\01??0Z@@QAE at XZ"(
> +  // WIN32: call {{.*}} @"\01??_DQ@@QAE at XZ"(
> +
> +  // On Win64, the Q arguments would be destroyed in the callee. We don't
> yet
> +  // support that in the non-inlined case, so we force inlining.
> +  // WIN64: %[[TMP:.*]] = alloca
> +  // WIN64: %[[ARG3:.*]] = alloca
> +  // WIN64: %[[ARG1:.*]] = alloca
> +  // WIN64: call {{.*}} @"\01??0Q@@QEAA at H@Z"({{.*}}* %[[TMP]], i32 4)
> +  // WIN64: call {{.*}} @"\01??0Q@@QEAA at H@Z"({{.*}}* %[[ARG3]], i32 3)
> +  // WIN64: call {{.*}} @"\01??0Q@@QEAA at H@Z"({{.*}}* %[[ARG1]], i32 1)
> +  // WIN64: br i1
> +  // WIN64: store {{.*}} @"\01??_8C at inalloca_virt@@7B@"
> +  // WIN64: call {{.*}} @"\01??0A at inalloca_virt@@QEAA at UQ@@H0$$QEAU2@@Z"(%{{.*}},
> %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}} %[[TMP]])
> +  // WIN64: br
> +  // WIN64: br i1
> +  // (Unreachable block)
> +  // WIN64: store {{.*}} @"\01??_8B at inalloca_virt@@7B@"
> +  // WIN64: br
> +  // WIN64: call {{.*}} @"\01??0Z@@QEAA at XZ"(
> +  // WIN64: call {{.*}} @"\01??0Z@@QEAA at XZ"(
> +  // WIN64: call void @"\01??_DQ@@QEAA at XZ"({{.*}}* %[[TMP]])
> +}
> +
> +namespace inline_nonvirt {
> +  struct A { A(Q, int, Q, Q&&, ...); int n; };
> +  struct B : Z, A { Z z; using A::A; };
> +  B b(1, 2, 3, 4, 5, 6);
> +  // Inlined all the way down to the A ctor.
> +  // ITANIUM-LABEL: define {{.*}} @__cxx_global_var_init
> +  // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 1)
> +  // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 3)
> +  // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 4)
> +  // ITANIUM: %[[Z_BASE:.*]] = bitcast %{{.*}}* %[[THIS:.*]] to
> +  // ITANIUM: call void @_ZN1ZC2Ev(
> +  // ITANIUM: %[[B_CAST:.*]] = bitcast {{.*}} %[[THIS]]
> +  // ITANIUM: %[[A_CAST:.*]] = getelementptr {{.*}} %[[B_CAST]],
> i{{32|64}} 4
> +  // ITANIUM: %[[A:.*]] = bitcast {{.*}} %[[A_CAST]]
> +  // ITANIUM: call void ({{.*}}, ...) @_ZN14inline_
> nonvirt1AC2E1QiS1_OS1_z(%{{.*}}* %[[A]], {{.*}}, i32 2, {{.*}}, {{.*}},
> i32 5, i32 6)
> +  // ITANIUM: %[[Z_MEMBER:.*]] = getelementptr {{.*}} %[[THIS]], i32 0,
> i32 2
> +  // ITANIUM: call void @_ZN1ZC1Ev({{.*}} %[[Z_MEMBER]])
> +  // ITANIUM: call void @_ZN1QD1Ev(
> +  // ITANIUM: call void @_ZN1QD1Ev(
> +  // ITANIUM: call void @_ZN1QD1Ev(
> +
> +  struct C : B { using B::B; };
> +  C c(1, 2, 3, 4, 5, 6);
> +  // Inlined all the way down to the A ctor.
> +  // ITANIUM-LABEL: define {{.*}} @__cxx_global_var_init
> +  // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 1)
> +  // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 3)
> +  // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 4)
> +  // ITANIUM: %[[Z_BASE:.*]] = bitcast %{{.*}}* %[[THIS:.*]] to
> +  // ITANIUM: call void @_ZN1ZC2Ev(
> +  // ITANIUM: %[[B_CAST:.*]] = bitcast {{.*}} %[[THIS]]
> +  // ITANIUM: %[[A_CAST:.*]] = getelementptr {{.*}} %[[B_CAST]],
> i{{32|64}} 4
> +  // ITANIUM: %[[A:.*]] = bitcast {{.*}} %[[A_CAST]]
> +  // ITANIUM: call void ({{.*}}, ...) @_ZN14inline_
> nonvirt1AC2E1QiS1_OS1_z(%{{.*}}* %[[A]], {{.*}}, i32 2, {{.*}}, {{.*}},
> i32 5, i32 6)
> +  // ITANIUM: %[[Z_MEMBER:.*]] = getelementptr {{.*}} %{{.*}}, i32 0, i32
> 2
> +  // ITANIUM: call void @_ZN1ZC1Ev({{.*}} %[[Z_MEMBER]])
> +  // ITANIUM: call void @_ZN1QD1Ev(
> +  // ITANIUM: call void @_ZN1QD1Ev(
> +  // ITANIUM: call void @_ZN1QD1Ev(
> +}
> +
> +namespace inline_virt {
> +  struct A { A(Q, int, Q, Q&&, ...); int n; };
> +  struct B : Z, virtual A { Z z; using A::A; };
> +  B b(1, 2, 3, 4, 5, 6);
> +  // Inlined all the way down to the A ctor.
> +  // ITANIUM-LABEL: define {{.*}} @__cxx_global_var_init
> +  // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 1)
> +  // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 3)
> +  // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 4)
> +  // ITANIUM: %[[B_CAST:.*]] = bitcast {{.*}} %[[THIS:.*]]
> +  // ITANIUM: %[[A_CAST:.*]] = getelementptr {{.*}} %[[B_CAST]],
> i{{32|64}} {{12|16}}
> +  // ITANIUM: %[[A:.*]] = bitcast {{.*}} %[[A_CAST]]
> +  // ITANIUM: call void ({{.*}}, ...) @_ZN11inline_virt1AC2E1QiS1_OS1_z(%{{.*}}*
> %[[A]], {{.*}}, i32 2, {{.*}}, {{.*}}, i32 5, i32 6)
> +  // ITANIUM: call void @_ZN1ZC2Ev(
> +  // ITANIUM: call void @_ZN1ZC1Ev(
> +  // ITANIUM: call void @_ZN1QD1Ev(
> +  // ITANIUM: call void @_ZN1QD1Ev(
> +  // ITANIUM: call void @_ZN1QD1Ev(
> +
> +  struct C : B { using B::B; };
> +  C c(1, 2, 3, 4, 5, 6);
> +  // Inlined all the way down to the A ctor, except that we can just call
> the
> +  // B base inheriting constructor to construct that portion (it doesn't
> need
> +  // the forwarded arguments).
> +  // ITANIUM-LABEL: define {{.*}} @__cxx_global_var_init
> +  // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 1)
> +  // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 3)
> +  // ITANIUM: call void @_ZN1QC1Ei({{.*}}, i32 4)
> +  // ITANIUM: %[[B_CAST:.*]] = bitcast {{.*}} %[[THIS:.*]]
> +  // ITANIUM: %[[A_CAST:.*]] = getelementptr {{.*}} %[[B_CAST]],
> i{{32|64}} {{12|16}}
> +  // ITANIUM: %[[A:.*]] = bitcast {{.*}} %[[A_CAST]]
> +  // ITANIUM: call void ({{.*}}, ...) @_ZN11inline_virt1AC2E1QiS1_OS1_z(%{{.*}}*
> %[[A]], {{.*}}, i32 2, {{.*}}, {{.*}}, i32 5, i32 6)
> +  // ITANIUM: call void @_ZN11inline_virt1BCI2NS_1AEE1QiS1_OS1_z({{[^,]*}},
> i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @_ZTTN11inline_virt1CE,
> i64 0, i64 1))
> +  // ITANIUM: store {{.*}} @_ZTVN11inline_virt1CE
> +  // ITANIUM: call void @_ZN1QD1Ev(
> +  // ITANIUM: call void @_ZN1QD1Ev(
> +  // ITANIUM: call void @_ZN1QD1Ev(
> +
> +  // B base object inheriting constructor does not get passed arguments.
> +  // ITANIUM-LABEL: define linkonce_odr void @_ZN11inline_virt1BCI2NS_
> 1AEE1QiS1_OS1_z(
> +  // ITANIUM-NOT: call
> +  // ITANIUM: call void @_ZN1ZC2Ev(%struct.Z* %2)
> +  // ITANIUM-NOT: call
> +  // VTT -> vtable
> +  // ITANIUM: store
> +  // ITANIUM-NOT: call
> +  // ITANIUM: call void @_ZN1ZC1Ev(%struct.Z* %z)
> +  // ITANIUM-NOT: call
> +  // ITANIUM: }
> +}
> +
> +// ITANIUM-LABEL: define linkonce_odr void @_ZN1BCI21AEi(
> +// ITANIUM: call void @_ZN1AC2Ei(
> +
> +// ITANIUM-LABEL: define linkonce_odr void @_ZN1DCI21CIiEET_(
> +// ITANIUM: call void @_ZN1CC2IiEET_(
> +
> +// ITANIUM-LABEL: define linkonce_odr void @_ZN17noninline_
> nonvirt1BCI2NS_1AEEiO1QPvU17pass_object_size0(
> +// ITANIUM: call void @_ZN1ZC2Ev(
> +// ITANIUM: call void @_ZN17noninline_nonvirt1AC2EiO1QPvU17pass_
> object_size0(
> +
> +// ITANIUM-LABEL: define linkonce_odr void @_ZN17noninline_
> nonvirt1CCI2NS_1AEEiO1QPvU17pass_object_size0(
> +// ITANIUM: call void @_ZN17noninline_nonvirt1BCI2NS_
> 1AEEiO1QPvU17pass_object_size0(
>
> Modified: cfe/trunk/test/PCH/cxx11-inheriting-ctors.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/
> cxx11-inheriting-ctors.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/PCH/cxx11-inheriting-ctors.cpp (original)
> +++ cfe/trunk/test/PCH/cxx11-inheriting-ctors.cpp Tue Jun 28 14:03:57 2016
> @@ -1,10 +1,19 @@
> -// RUN: %clang_cc1 -std=c++11 -emit-pch -o %t %s
> -// RUN: %clang_cc1 -std=c++11 -include-pch %t -verify %s
> +// RUN: %clang_cc1 -std=c++11 -include %s -include %s -verify %s
> +//
> +// Emit with definitions in the declaration:
> +// RxN: %clang_cc1 -std=c++11 -emit-pch -o %t.12 -include %s %s
> +// RxN: %clang_cc1 -std=c++11 -include-pch %t.12 -verify %s
> +//
> +// Emit with definitions in update records:
> +// RxN: %clang_cc1 -std=c++11 -emit-pch -o %t.1 %s
> +// RxN: %clang_cc1 -std=c++11 -include-pch %t.1 -emit-pch -o %t.2 -verify
> %s
> +// RxN: %clang_cc1 -std=c++11 -include-pch %t.1 -include-pch %t.2 -verify
> %s
> +
>
>  // expected-no-diagnostics
>
> -#ifndef HEADER_INCLUDED
> -#define HEADER_INCLUDED
> +#ifndef HEADER1
> +#define HEADER1
>
>  struct Base {
>    Base(int) {}
> @@ -27,7 +36,8 @@ struct Test3 : B {
>    using B::B;
>  };
>
> -#else
> +#elif !defined(HEADER2)
> +#define HEADER2
>
>  Test test1a(42);
>  Test test1b(nullptr);
> @@ -36,4 +46,16 @@ Test2<int> test2b(nullptr);
>  Test3<Base> test3a(42);
>  Test3<Base> test3b(nullptr);
>
> -#endif // HEADER_INCLUDED
> +#pragma clang __debug dump Test
> +#pragma clang __debug dump Test2
> +
> +#else
> +
> +Test retest1a(42);
> +Test retest1b(nullptr);
> +Test2<int> retest2a(42);
> +Test2<int> retest2b(nullptr);
> +Test3<Base> retest3a(42);
> +Test3<Base> retest3b(nullptr);
> +
> +#endif
>
> Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
> SemaCXX/constant-expression-cxx11.cpp?rev=274049&r1=
> 274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
> +++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Tue Jun 28
> 14:03:57 2016
> @@ -2029,3 +2029,40 @@ namespace IncompleteClass {
>      static constexpr int j = g(static_cast<XX*>(nullptr)); //
> expected-error {{constexpr variable 'j' must be initialized by a constant
> expression}}  expected-note {{undefined function 'g' cannot be used in a
> constant expression}}
>    };
>  }
> +
> +namespace InheritedCtor {
> +  struct A { constexpr A(int) {} };
> +
> +  struct B : A { int n; using A::A; }; // expected-note {{here}}
> +  constexpr B b(0); // expected-error {{constant expression}}
> expected-note {{derived class}}
> +
> +  struct C : A { using A::A; struct { union { int n, m = 0; }; union {
> int a = 0; }; int k = 0; }; struct {}; union {}; }; // expected-warning
> 4{{extension}}
> +  constexpr C c(0);
> +
> +  struct D : A {
> +    using A::A; // expected-note {{here}}
> +    struct { // expected-warning {{extension}}
> +      union { // expected-warning {{extension}}
> +        int n;
> +      };
> +    };
> +  };
> +  constexpr D d(0); // expected-error {{constant expression}}
> expected-note {{derived class}}
> +
> +  struct E : virtual A { using A::A; }; // expected-note {{here}}
> +  // We wrap a function around this to avoid implicit zero-initialization
> +  // happening first; the zero-initialization step would produce the same
> +  // error and defeat the point of this test.
> +  void f() {
> +    constexpr E e(0); // expected-error {{constant expression}}
> expected-note {{derived class}}
> +  }
> +  // FIXME: This produces a note with no source location.
> +  //constexpr E e(0);
> +
> +  struct W { constexpr W(int n) : w(n) {} int w; };
> +  struct X : W { using W::W; int x = 2; };
> +  struct Y : X { using X::X; int y = 3; };
> +  struct Z : Y { using Y::Y; int z = 4; };
> +  constexpr Z z(1);
> +  static_assert(z.w == 1 && z.x == 2 && z.y == 3 && z.z == 4, "");
> +}
>
> Modified: cfe/trunk/test/SemaCXX/cxx11-inheriting-ctors.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
> SemaCXX/cxx11-inheriting-ctors.cpp?rev=274049&r1=
> 274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/SemaCXX/cxx11-inheriting-ctors.cpp (original)
> +++ cfe/trunk/test/SemaCXX/cxx11-inheriting-ctors.cpp Tue Jun 28 14:03:57
> 2016
> @@ -34,3 +34,13 @@ namespace WrongIdent {
>      using B::A;
>    };
>  }
> +
> +namespace DefaultCtorConflict {
> +  struct A { A(int = 0); };
> +  struct B : A {
> +    using A::A;
> +  } b; // ok, not ambiguous, inherited constructor suppresses implicit
> default constructor
> +  struct C {
> +    B b;
> +  } c;
> +}
>
> Modified: cfe/trunk/tools/libclang/CIndex.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/
> libclang/CIndex.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/tools/libclang/CIndex.cpp (original)
> +++ cfe/trunk/tools/libclang/CIndex.cpp Tue Jun 28 14:03:57 2016
> @@ -3955,6 +3955,9 @@ static const Decl *getDeclFromExpr(const
>    if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
>      if (!CE->isElidable())
>      return CE->getConstructor();
> +  if (const CXXInheritedCtorInitExpr *CE =
> +          dyn_cast<CXXInheritedCtorInitExpr>(E))
> +    return CE->getConstructor();
>    if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
>      return OME->getMethodDecl();
>
> @@ -5665,6 +5668,7 @@ CXCursor clang_getCursorDefinition(CXCur
>                                         D->getLocation(), TU);
>
>    case Decl::UsingShadow:
> +  case Decl::ConstructorUsingShadow:
>      return clang_getCursorDefinition(
>                         MakeCXCursor(cast<UsingShadowDecl>(D)->
> getTargetDecl(),
>                                      TU));
>
> Modified: cfe/trunk/tools/libclang/CXCursor.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/
> libclang/CXCursor.cpp?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/tools/libclang/CXCursor.cpp (original)
> +++ cfe/trunk/tools/libclang/CXCursor.cpp Tue Jun 28 14:03:57 2016
> @@ -504,6 +504,7 @@ CXCursor cxcursor::MakeCXCursor(const St
>    case Stmt::CXXMemberCallExprClass:
>    case Stmt::CUDAKernelCallExprClass:
>    case Stmt::CXXConstructExprClass:
> +  case Stmt::CXXInheritedCtorInitExprClass:
>    case Stmt::CXXTemporaryObjectExprClass:
>    case Stmt::CXXUnresolvedConstructExprClass:
>    case Stmt::UserDefinedLiteralClass:
>
> Modified: cfe/trunk/www/cxx_status.html
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_
> status.html?rev=274049&r1=274048&r2=274049&view=diff
> ============================================================
> ==================
> --- cfe/trunk/www/cxx_status.html (original)
> +++ cfe/trunk/www/cxx_status.html Tue Jun 28 14:03:57 2016
> @@ -623,7 +623,7 @@ as the draft C++1z standard evolves.</p>
>      <tr>
>        <td>New specification for inheriting constructors (<a
> href="cxx_dr_status.html#1941">DR1941</a> et al)</td>
>        <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/
> 2015/p0136r1.html">P0136R1</a></td>
> -      <td class="none" align="center">No</td>
> +      <td class="svn" align="center">SVN <a href="p0136">(9)</a></td>
>      </tr>
>      <!-- Jacksonville papers -->
>      <tr>
> @@ -735,6 +735,9 @@ all language versions that allow type de
>  (per the request of the C++ committee).
>  In Clang 3.7, a warning is emitted for all cases that would change
> meaning.
>  </span>
> +<span id="p0136">(9): This is the resolution to a Defect Report, so is
> applied
> +to all language versions supporting inheriting constructors.
> +</span>
>  </p>
>
>  <h2 id="ts">Technical specifications and standing documents</h2>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160923/ba1a7728/attachment-0001.html>


More information about the cfe-commits mailing list