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

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 28 12:03:58 PDT 2016


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->getConstructedBaseClassShadowDecl()));
+      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>




More information about the cfe-commits mailing list