r360024 - Revert r359949 "[clang] adding explicit(bool) from c++2a"

Hans Wennborg via cfe-commits cfe-commits at lists.llvm.org
Mon May 6 02:51:10 PDT 2019


Author: hans
Date: Mon May  6 02:51:10 2019
New Revision: 360024

URL: http://llvm.org/viewvc/llvm-project?rev=360024&view=rev
Log:
Revert r359949 "[clang] adding explicit(bool) from c++2a"

This caused Clang to start erroring on the following:

  struct S {
    template <typename = int> explicit S();
  };

  struct T : S {};

  struct U : T {
    U();
  };
  U::U() {}

  $ clang -c /tmp/x.cc
  /tmp/x.cc:10:4: error: call to implicitly-deleted default constructor of 'T'
  U::U() {}
     ^
  /tmp/x.cc:5:12: note: default constructor of 'T' is implicitly deleted
    because base class 'S' has no default constructor
  struct T : S {};
             ^
  1 error generated.

See discussion on the cfe-commits email thread.

This also reverts the follow-ups r359966 and r359968.

> this patch adds support for the explicit bool specifier.
>
> Changes:
> - The parsing for the explicit(bool) specifier was added in ParseDecl.cpp.
> - The storage of the explicit specifier was changed. the explicit specifier was stored as a boolean value in the FunctionDeclBitfields and in the DeclSpec class. now it is stored as a PointerIntPair<Expr*, 2> with a flag and a potential expression in CXXConstructorDecl, CXXDeductionGuideDecl, CXXConversionDecl and in the DeclSpec class.
> - Following the AST change, Serialization, ASTMatchers, ASTComparator and ASTPrinter were adapted.
> - Template instantiation was adapted to instantiate the potential expressions of the explicit(bool) specifier When instantiating their associated declaration.
> - The Add*Candidate functions were adapted, they now take a Boolean indicating if the context allowing explicit constructor or conversion function and this boolean is used to remove invalid overloads that required template instantiation to be detected.
> - Test for Semantic and Serialization were added.
>
> This patch is not yet complete. I still need to check that interaction with CTAD and deduction guides is correct. and add more tests for AST operations. But I wanted first feedback.
> Perhaps this patch should be spited in smaller patches, but making each patch testable as a standalone may be tricky.
>
> Patch by Tyker
>
> Differential Revision: https://reviews.llvm.org/D60934

Removed:
    cfe/trunk/test/PCH/cxx-explicit-specifier.cpp
    cfe/trunk/test/SemaCXX/cxx2a-explicit-bool.cpp
Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/DeclBase.h
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
    cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Basic/Specifiers.h
    cfe/trunk/include/clang/Sema/DeclSpec.h
    cfe/trunk/include/clang/Sema/Overload.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/AST/DeclPrinter.cpp
    cfe/trunk/lib/Frontend/InitPreprocessor.cpp
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Sema/DeclSpec.cpp
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/lib/Sema/SemaLambda.cpp
    cfe/trunk/lib/Sema/SemaLookup.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
    cfe/trunk/test/CXX/temp/temp.deduct.guide/p1.cpp
    cfe/trunk/test/CXX/temp/temp.deduct.guide/p3.cpp
    cfe/trunk/test/SemaCXX/builtin-is-constant-evaluated.cpp
    cfe/trunk/test/SemaCXX/cxx2a-compat.cpp
    cfe/trunk/test/SemaCXX/explicit.cpp
    cfe/trunk/unittests/AST/Language.cpp
    cfe/trunk/unittests/AST/Language.h
    cfe/trunk/unittests/AST/MatchVerifier.h
    cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp
    cfe/trunk/www/cxx_status.html

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Mon May  6 02:51:10 2019
@@ -2369,6 +2369,16 @@ public:
   /// that was defined in the class body.
   bool isInlined() const { return FunctionDeclBits.IsInline; }
 
+  /// Whether this function is marked as explicit explicitly.
+  bool isExplicitSpecified() const {
+    return FunctionDeclBits.IsExplicitSpecified;
+  }
+
+  /// State that this function is marked as explicit explicitly.
+  void setExplicitSpecified(bool ExpSpec = true) {
+    FunctionDeclBits.IsExplicitSpecified = ExpSpec;
+  }
+
   bool isInlineDefinitionExternallyVisible() const;
 
   bool isMSExternInline() const;

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Mon May  6 02:51:10 2019
@@ -1472,6 +1472,10 @@ class DeclContext {
     uint64_t IsInline : 1;
     uint64_t IsInlineSpecified : 1;
 
+    /// This is shared by CXXConstructorDecl,
+    /// CXXConversionDecl, and CXXDeductionGuideDecl.
+    uint64_t IsExplicitSpecified : 1;
+
     uint64_t IsVirtualAsWritten : 1;
     uint64_t IsPure : 1;
     uint64_t HasInheritedPrototype : 1;
@@ -1519,7 +1523,7 @@ class DeclContext {
   };
 
   /// Number of non-inherited bits in FunctionDeclBitfields.
-  enum { NumFunctionDeclBits = 24 };
+  enum { NumFunctionDeclBits = 25 };
 
   /// Stores the bits used by CXXConstructorDecl. If modified
   /// NumCXXConstructorDeclBits and the accessor
@@ -1531,25 +1535,17 @@ class DeclContext {
     /// For the bits in FunctionDeclBitfields.
     uint64_t : NumFunctionDeclBits;
 
-    /// 24 bits to fit in the remaining available space.
+    /// 25 bits to fit in the remaining availible space.
     /// Note that this makes CXXConstructorDeclBitfields take
     /// exactly 64 bits and thus the width of NumCtorInitializers
     /// will need to be shrunk if some bit is added to NumDeclContextBitfields,
     /// NumFunctionDeclBitfields or CXXConstructorDeclBitfields.
-    uint64_t NumCtorInitializers : 24;
+    uint64_t NumCtorInitializers : 25;
     uint64_t IsInheritingConstructor : 1;
-
-    /// Whether this constructor has a trail-allocated explicit specifier.
-    uint64_t HasTrailingExplicitSpecifier : 1;
-    /// If this constructor does't have a trail-allocated explicit specifier.
-    /// Whether this constructor is explicit specified.
-    uint64_t IsSimpleExplicit : 1;
   };
 
   /// Number of non-inherited bits in CXXConstructorDeclBitfields.
-  enum {
-    NumCXXConstructorDeclBits = 64 - NumDeclContextBits - NumFunctionDeclBits
-  };
+  enum { NumCXXConstructorDeclBits = 26 };
 
   /// Stores the bits used by ObjCMethodDecl.
   /// If modified NumObjCMethodDeclBits and the accessor

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Mon May  6 02:51:10 2019
@@ -1993,50 +1993,6 @@ public:
   }
 };
 
-/// Store information needed for an explicit specifier.
-/// used by CXXDeductionGuideDecl, CXXConstructorDecl and CXXConversionDecl.
-class ExplicitSpecifier {
-  llvm::PointerIntPair<Expr *, 2, ExplicitSpecKind> ExplicitSpec{
-      nullptr, ExplicitSpecKind::ResolvedFalse};
-
-public:
-  ExplicitSpecifier() = default;
-  ExplicitSpecifier(Expr *Expression, ExplicitSpecKind Kind)
-      : ExplicitSpec(Expression, Kind) {}
-  ExplicitSpecKind getKind() const { return ExplicitSpec.getInt(); }
-  const Expr *getExpr() const { return ExplicitSpec.getPointer(); }
-  Expr *getExpr() { return ExplicitSpec.getPointer(); }
-
-  /// Return true if the ExplicitSpecifier isn't defaulted.
-  bool isSpecified() const {
-    return ExplicitSpec.getInt() != ExplicitSpecKind::ResolvedFalse ||
-           ExplicitSpec.getPointer();
-  }
-
-  /// Check for Equivalence of explicit specifiers.
-  /// Return True if the explicit specifier are equivalent false otherwise.
-  bool isEquivalent(const ExplicitSpecifier Other) const;
-  /// Return true if the explicit specifier is already resolved to be explicit.
-  bool isExplicit() const {
-    return ExplicitSpec.getInt() == ExplicitSpecKind::ResolvedTrue;
-  }
-  /// Return true if the ExplicitSpecifier isn't valid.
-  /// This state occurs after a substitution failures.
-  bool isInvalid() const {
-    return ExplicitSpec.getInt() == ExplicitSpecKind::Unresolved &&
-           !ExplicitSpec.getPointer();
-  }
-  void setKind(ExplicitSpecKind Kind) { ExplicitSpec.setInt(Kind); }
-  void setExpr(Expr *E) { ExplicitSpec.setPointer(E); }
-  // getFromDecl - retrieve the explicit specifier in the given declaration.
-  // if the given declaration has no explicit. the returned explicit specifier
-  // is defaulted. .isSpecified() will be false.
-  static ExplicitSpecifier getFromDecl(FunctionDecl *Function);
-  static ExplicitSpecifier Invalid() {
-    return ExplicitSpecifier(nullptr, ExplicitSpecKind::Unresolved);
-  }
-};
-
 /// Represents a C++ deduction guide declaration.
 ///
 /// \code
@@ -2052,36 +2008,31 @@ class CXXDeductionGuideDecl : public Fun
 
 private:
   CXXDeductionGuideDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
-                        ExplicitSpecifier ES,
-                        const DeclarationNameInfo &NameInfo, QualType T,
-                        TypeSourceInfo *TInfo, SourceLocation EndLocation)
+                        bool IsExplicit, const DeclarationNameInfo &NameInfo,
+                        QualType T, TypeSourceInfo *TInfo,
+                        SourceLocation EndLocation)
       : FunctionDecl(CXXDeductionGuide, C, DC, StartLoc, NameInfo, T, TInfo,
-                     SC_None, false, false),
-        ExplicitSpec(ES) {
+                     SC_None, false, false) {
     if (EndLocation.isValid())
       setRangeEnd(EndLocation);
+    setExplicitSpecified(IsExplicit);
     setIsCopyDeductionCandidate(false);
   }
 
-  ExplicitSpecifier ExplicitSpec;
-  void setExplicitSpecifier(ExplicitSpecifier ES) { ExplicitSpec = ES; }
-
 public:
   friend class ASTDeclReader;
   friend class ASTDeclWriter;
 
-  static CXXDeductionGuideDecl *
-  Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
-         ExplicitSpecifier ES, const DeclarationNameInfo &NameInfo, QualType T,
-         TypeSourceInfo *TInfo, SourceLocation EndLocation);
+  static CXXDeductionGuideDecl *Create(ASTContext &C, DeclContext *DC,
+                                       SourceLocation StartLoc, bool IsExplicit,
+                                       const DeclarationNameInfo &NameInfo,
+                                       QualType T, TypeSourceInfo *TInfo,
+                                       SourceLocation EndLocation);
 
   static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, unsigned ID);
 
-  ExplicitSpecifier getExplicitSpecifier() { return ExplicitSpec; }
-  const ExplicitSpecifier getExplicitSpecifier() const { return ExplicitSpec; }
-
-  /// Return true if the declartion is already resolved to be explicit.
-  bool isExplicit() const { return ExplicitSpec.isExplicit(); }
+  /// Whether this deduction guide is explicit.
+  bool isExplicit() const { return isExplicitSpecified(); }
 
   /// Get the template for which this guide performs deduction.
   TemplateDecl *getDeducedTemplate() const {
@@ -2550,8 +2501,7 @@ public:
 /// \endcode
 class CXXConstructorDecl final
     : public CXXMethodDecl,
-      private llvm::TrailingObjects<CXXConstructorDecl, InheritedConstructor,
-                                    ExplicitSpecifier> {
+      private llvm::TrailingObjects<CXXConstructorDecl, InheritedConstructor> {
   // This class stores some data in DeclContext::CXXConstructorDeclBits
   // to save some space. Use the provided accessors to access it.
 
@@ -2561,74 +2511,28 @@ class CXXConstructorDecl final
   LazyCXXCtorInitializersPtr CtorInitializers;
 
   CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
-                     const DeclarationNameInfo &NameInfo, QualType T,
-                     TypeSourceInfo *TInfo, ExplicitSpecifier ES, bool isInline,
+                     const DeclarationNameInfo &NameInfo,
+                     QualType T, TypeSourceInfo *TInfo,
+                     bool isExplicitSpecified, bool isInline,
                      bool isImplicitlyDeclared, bool isConstexpr,
                      InheritedConstructor Inherited);
 
   void anchor() override;
 
-  size_t numTrailingObjects(OverloadToken<InheritedConstructor>) const {
-    return CXXConstructorDeclBits.IsInheritingConstructor;
-  }
-  size_t numTrailingObjects(OverloadToken<ExplicitSpecifier>) const {
-    return CXXConstructorDeclBits.HasTrailingExplicitSpecifier;
-  }
-
-  ExplicitSpecifier getExplicitSpecifierInternal() const {
-    if (CXXConstructorDeclBits.HasTrailingExplicitSpecifier)
-      return *getCanonicalDecl()->getTrailingObjects<ExplicitSpecifier>();
-    return ExplicitSpecifier(
-        nullptr, getCanonicalDecl()->CXXConstructorDeclBits.IsSimpleExplicit
-                     ? ExplicitSpecKind::ResolvedTrue
-                     : ExplicitSpecKind::ResolvedFalse);
-  }
-
-  void setExplicitSpecifier(ExplicitSpecifier ES) {
-    assert((!ES.getExpr() ||
-            CXXConstructorDeclBits.HasTrailingExplicitSpecifier) &&
-           "cannot set this explicit specifier. no trail-allocated space for "
-           "explicit");
-    if (ES.getExpr())
-      *getCanonicalDecl()->getTrailingObjects<ExplicitSpecifier>() = ES;
-    else
-      CXXConstructorDeclBits.IsSimpleExplicit = ES.isExplicit();
-  }
-
-  enum TraillingAllocKind {
-    TAKInheritsConstructor = 1,
-    TAKHasTailExplicit = 1 << 1,
-  };
-
-  uint64_t getTraillingAllocKind() const {
-    return numTrailingObjects(OverloadToken<InheritedConstructor>()) |
-           (numTrailingObjects(OverloadToken<ExplicitSpecifier>()) << 1);
-  }
-
 public:
   friend class ASTDeclReader;
   friend class ASTDeclWriter;
   friend TrailingObjects;
 
   static CXXConstructorDecl *CreateDeserialized(ASTContext &C, unsigned ID,
-                                                uint64_t AllocKind);
+                                                bool InheritsConstructor);
   static CXXConstructorDecl *
   Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
          const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
-         ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared,
+         bool isExplicit, bool isInline, bool isImplicitlyDeclared,
          bool isConstexpr,
          InheritedConstructor Inherited = InheritedConstructor());
 
-  ExplicitSpecifier getExplicitSpecifier() {
-    return getExplicitSpecifierInternal();
-  }
-  const ExplicitSpecifier getExplicitSpecifier() const {
-    return getExplicitSpecifierInternal();
-  }
-
-  /// Return true if the declartion is already resolved to be explicit.
-  bool isExplicit() const { return getExplicitSpecifier().isExplicit(); }
-
   /// Iterates through the member/base initializer list.
   using init_iterator = CXXCtorInitializer **;
 
@@ -2699,6 +2603,11 @@ public:
     CtorInitializers = Initializers;
   }
 
+  /// Whether this function is explicit.
+  bool isExplicit() const {
+    return getCanonicalDecl()->isExplicitSpecified();
+  }
+
   /// Determine whether this constructor is a delegating constructor.
   bool isDelegatingConstructor() const {
     return (getNumCtorInitializers() == 1) &&
@@ -2877,39 +2786,34 @@ public:
 class CXXConversionDecl : public CXXMethodDecl {
   CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
                     const DeclarationNameInfo &NameInfo, QualType T,
-                    TypeSourceInfo *TInfo, bool isInline, ExplicitSpecifier ES,
-                    bool isConstexpr, SourceLocation EndLocation)
+                    TypeSourceInfo *TInfo, bool isInline,
+                    bool isExplicitSpecified, bool isConstexpr,
+                    SourceLocation EndLocation)
       : CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
-                      SC_None, isInline, isConstexpr, EndLocation),
-        ExplicitSpec(ES) {}
-  void anchor() override;
-
-  ExplicitSpecifier ExplicitSpec;
+                      SC_None, isInline, isConstexpr, EndLocation) {
+    setExplicitSpecified(isExplicitSpecified);
+  }
 
-  void setExplicitSpecifier(ExplicitSpecifier ES) { ExplicitSpec = ES; }
+  void anchor() override;
 
 public:
   friend class ASTDeclReader;
   friend class ASTDeclWriter;
 
-  static CXXConversionDecl *
-  Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
-         const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
-         bool isInline, ExplicitSpecifier ES, bool isConstexpr,
-         SourceLocation EndLocation);
+  static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
+                                   SourceLocation StartLoc,
+                                   const DeclarationNameInfo &NameInfo,
+                                   QualType T, TypeSourceInfo *TInfo,
+                                   bool isInline, bool isExplicit,
+                                   bool isConstexpr,
+                                   SourceLocation EndLocation);
   static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
 
-  ExplicitSpecifier getExplicitSpecifier() {
-    return getCanonicalDecl()->ExplicitSpec;
-  }
-
-  const ExplicitSpecifier getExplicitSpecifier() const {
-    return getCanonicalDecl()->ExplicitSpec;
+  /// Whether this function is explicit.
+  bool isExplicit() const {
+    return getCanonicalDecl()->isExplicitSpecified();
   }
 
-  /// Return true if the declartion is already resolved to be explicit.
-  bool isExplicit() const { return getExplicitSpecifier().isExplicit(); }
-
   /// Returns the type that this conversion function is converting to.
   QualType getConversionType() const {
     return getType()->getAs<FunctionType>()->getReturnType();

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Mon May  6 02:51:10 2019
@@ -6171,9 +6171,6 @@ AST_MATCHER(CXXConstructorDecl, isDelega
 AST_POLYMORPHIC_MATCHER(isExplicit,
                         AST_POLYMORPHIC_SUPPORTED_TYPES(CXXConstructorDecl,
                                                         CXXConversionDecl)) {
-  // FIXME : it's not clear whether this should match a dependent
-  //         explicit(....). this matcher should also be able to match
-  //         CXXDeductionGuideDecl with explicit specifier.
   return Node.isExplicit();
 }
 

Modified: cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td Mon May  6 02:51:10 2019
@@ -150,8 +150,6 @@ def ext_warn_duplicate_declspec : ExtWar
 def warn_duplicate_declspec : Warning<"%sub{duplicate_declspec}0">,
   InGroup<DuplicateDeclSpecifier>;
 
-def err_duplicate_declspec : Error<"%sub{duplicate_declspec}0">;
-
 def err_friend_decl_spec : Error<"'%0' is invalid in friend declarations">;
 
 def err_invalid_member_in_interface : Error<

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Mon May  6 02:51:10 2019
@@ -33,10 +33,6 @@ def err_asm_goto_not_supported_yet : Err
 
 let CategoryName = "Parse Issue" in {
 
-def warn_cxx2a_compat_explicit_bool : Warning<
-  "this expression will be parsed as explicit(bool) in C++2a">,
-  InGroup<CXX2aCompat>, DefaultIgnore;
-
 def ext_empty_translation_unit : Extension<
   "ISO C requires a translation unit to contain at least one declaration">,
   InGroup<DiagGroup<"empty-translation-unit">>;

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon May  6 02:51:10 2019
@@ -83,11 +83,11 @@ def err_typecheck_converted_constant_exp
   "bind reference to a temporary">;
 def err_expr_not_cce : Error<
   "%select{case value|enumerator value|non-type template argument|"
-  "array size|constexpr if condition|explicit specifier argument}0 "
+  "array size|constexpr if condition}0 "
   "is not a constant expression">;
 def ext_cce_narrowing : ExtWarn<
   "%select{case value|enumerator value|non-type template argument|"
-  "array size|constexpr if condition|explicit specifier argument}0 "
+  "array size|constexpr if condition}0 "
   "%select{cannot be narrowed from type %2 to %3|"
   "evaluates to %2, which cannot be narrowed to type %3}1">,
   InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure;
@@ -2115,8 +2115,9 @@ def err_deduction_guide_wrong_scope : Er
   "deduction guide must be declared in the same scope as template %q0">;
 def err_deduction_guide_defines_function : Error<
   "deduction guide cannot have a function definition">;
-def err_deduction_guide_redeclared : Error<
-  "redeclaration of deduction guide">;
+def err_deduction_guide_explicit_mismatch : Error<
+  "deduction guide is %select{not |}0declared 'explicit' but "
+  "previous declaration was%select{ not|}0">;
 def err_deduction_guide_specialized : Error<"deduction guide cannot be "
   "%select{explicitly instantiated|explicitly specialized}0">;
 def err_deduction_guide_template_not_deducible : Error<
@@ -3639,10 +3640,6 @@ def note_ovl_candidate : Note<
     "| has different qualifiers (expected %5 but found %6)"
     "| has different exception specification}4">;
 
-def note_ovl_candidate_explicit_forbidden : Note<
-    "candidate %0 ignored: cannot be explicit">;
-def note_explicit_bool_resolved_to_true : Note<
-    "explicit(bool) specifier resolved to true">;
 def note_ovl_candidate_inherited_constructor : Note<
     "constructor from base class %0 inherited here">;
 def note_ovl_candidate_inherited_constructor_slice : Note<

Modified: cfe/trunk/include/clang/Basic/Specifiers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Specifiers.h?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Specifiers.h (original)
+++ cfe/trunk/include/clang/Basic/Specifiers.h Mon May  6 02:51:10 2019
@@ -20,14 +20,6 @@
 #include "llvm/Support/ErrorHandling.h"
 
 namespace clang {
-
-  /// Define the meaning of possible values of the kind in ExplicitSpecifier.
-  enum class ExplicitSpecKind : unsigned {
-    ResolvedFalse,
-    ResolvedTrue,
-    Unresolved,
-  };
-
   /// Specifies the width of a type, e.g., short, long, or long long.
   enum TypeSpecifierWidth {
     TSW_unspecified,

Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Sema/DeclSpec.h Mon May  6 02:51:10 2019
@@ -22,7 +22,6 @@
 #ifndef LLVM_CLANG_SEMA_DECLSPEC_H
 #define LLVM_CLANG_SEMA_DECLSPEC_H
 
-#include "clang/AST/DeclCXX.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/Basic/ExceptionSpecificationType.h"
 #include "clang/Basic/Lambda.h"
@@ -357,6 +356,7 @@ private:
   unsigned FS_inline_specified : 1;
   unsigned FS_forceinline_specified: 1;
   unsigned FS_virtual_specified : 1;
+  unsigned FS_explicit_specified : 1;
   unsigned FS_noreturn_specified : 1;
 
   // friend-specifier
@@ -371,9 +371,6 @@ private:
     Expr *ExprRep;
   };
 
-  /// ExplicitSpecifier - Store information about explicit spicifer.
-  ExplicitSpecifier FS_explicit_specifier;
-
   // attributes.
   ParsedAttributes Attrs;
 
@@ -396,7 +393,6 @@ private:
   SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc,
       TQ_unalignedLoc;
   SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc, FS_noreturnLoc;
-  SourceLocation FS_explicitCloseParenLoc;
   SourceLocation FS_forceinlineLoc;
   SourceLocation FriendLoc, ModulePrivateLoc, ConstexprLoc;
   SourceLocation TQ_pipeLoc;
@@ -424,18 +420,31 @@ public:
   }
 
   DeclSpec(AttributeFactory &attrFactory)
-      : StorageClassSpec(SCS_unspecified),
-        ThreadStorageClassSpec(TSCS_unspecified),
-        SCS_extern_in_linkage_spec(false), TypeSpecWidth(TSW_unspecified),
-        TypeSpecComplex(TSC_unspecified), TypeSpecSign(TSS_unspecified),
-        TypeSpecType(TST_unspecified), TypeAltiVecVector(false),
-        TypeAltiVecPixel(false), TypeAltiVecBool(false), TypeSpecOwned(false),
-        TypeSpecPipe(false), TypeSpecSat(false), TypeQualifiers(TQ_unspecified),
-        FS_inline_specified(false), FS_forceinline_specified(false),
-        FS_virtual_specified(false), FS_noreturn_specified(false),
-        Friend_specified(false), Constexpr_specified(false),
-        FS_explicit_specifier(), Attrs(attrFactory), writtenBS(),
-        ObjCQualifiers(nullptr) {}
+    : StorageClassSpec(SCS_unspecified),
+      ThreadStorageClassSpec(TSCS_unspecified),
+      SCS_extern_in_linkage_spec(false),
+      TypeSpecWidth(TSW_unspecified),
+      TypeSpecComplex(TSC_unspecified),
+      TypeSpecSign(TSS_unspecified),
+      TypeSpecType(TST_unspecified),
+      TypeAltiVecVector(false),
+      TypeAltiVecPixel(false),
+      TypeAltiVecBool(false),
+      TypeSpecOwned(false),
+      TypeSpecPipe(false),
+      TypeSpecSat(false),
+      TypeQualifiers(TQ_unspecified),
+      FS_inline_specified(false),
+      FS_forceinline_specified(false),
+      FS_virtual_specified(false),
+      FS_explicit_specified(false),
+      FS_noreturn_specified(false),
+      Friend_specified(false),
+      Constexpr_specified(false),
+      Attrs(attrFactory),
+      writtenBS(),
+      ObjCQualifiers(nullptr) {
+  }
 
   // storage-class-specifier
   SCS getStorageClassSpec() const { return (SCS)StorageClassSpec; }
@@ -561,22 +570,11 @@ public:
     return FS_inline_specified ? FS_inlineLoc : FS_forceinlineLoc;
   }
 
-  ExplicitSpecifier getExplicitSpecifier() const {
-    return FS_explicit_specifier;
-  }
-
   bool isVirtualSpecified() const { return FS_virtual_specified; }
   SourceLocation getVirtualSpecLoc() const { return FS_virtualLoc; }
 
-  bool hasExplicitSpecifier() const {
-    return FS_explicit_specifier.isSpecified();
-  }
+  bool isExplicitSpecified() const { return FS_explicit_specified; }
   SourceLocation getExplicitSpecLoc() const { return FS_explicitLoc; }
-  SourceRange getExplicitSpecRange() const {
-    return FS_explicit_specifier.getExpr()
-               ? SourceRange(FS_explicitLoc, FS_explicitCloseParenLoc)
-               : SourceRange(FS_explicitLoc);
-  }
 
   bool isNoreturnSpecified() const { return FS_noreturn_specified; }
   SourceLocation getNoreturnSpecLoc() const { return FS_noreturnLoc; }
@@ -588,9 +586,8 @@ public:
     FS_forceinlineLoc = SourceLocation();
     FS_virtual_specified = false;
     FS_virtualLoc = SourceLocation();
-    FS_explicit_specifier = ExplicitSpecifier();
+    FS_explicit_specified = false;
     FS_explicitLoc = SourceLocation();
-    FS_explicitCloseParenLoc = SourceLocation();
     FS_noreturn_specified = false;
     FS_noreturnLoc = SourceLocation();
   }
@@ -709,8 +706,7 @@ public:
   bool setFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec,
                               unsigned &DiagID);
   bool setFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec,
-                               unsigned &DiagID, ExplicitSpecifier ExplicitSpec,
-                               SourceLocation CloseParenLoc);
+                               unsigned &DiagID);
   bool setFunctionSpecNoreturn(SourceLocation Loc, const char *&PrevSpec,
                                unsigned &DiagID);
 

Modified: cfe/trunk/include/clang/Sema/Overload.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Overload.h?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Overload.h (original)
+++ cfe/trunk/include/clang/Sema/Overload.h Mon May  6 02:51:10 2019
@@ -705,11 +705,6 @@ class Sema;
     /// attribute disabled it.
     ovl_fail_enable_if,
 
-    /// This candidate constructor or conversion fonction
-    /// is used implicitly but the explicit(bool) specifier
-    /// was resolved to true
-    ovl_fail_explicit_resolved,
-
     /// This candidate was not viable because its address could not be taken.
     ovl_fail_addr_not_available,
 

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon May  6 02:51:10 2019
@@ -2734,8 +2734,7 @@ public:
     CCEK_Enumerator,  ///< Enumerator value with fixed underlying type.
     CCEK_TemplateArg, ///< Value of a non-type template parameter.
     CCEK_NewExpr,     ///< Constant expression in a noptr-new-declarator.
-    CCEK_ConstexprIf, ///< Condition in a constexpr if statement.
-    CCEK_ExplicitBool ///< Condition in an explicit(bool) specifier.
+    CCEK_ConstexprIf  ///< Condition in a constexpr if statement.
   };
   ExprResult CheckConvertedConstantExpression(Expr *From, QualType T,
                                               llvm::APSInt &Value, CCEKind CCE);
@@ -2858,7 +2857,6 @@ public:
                             bool SuppressUserConversions = false,
                             bool PartialOverloading = false,
                             bool AllowExplicit = false,
-                            bool AllowExplicitConversion = false,
                             ADLCallKind IsADLCandidate = ADLCallKind::NotADL,
                             ConversionSequenceList EarlyConversions = None);
   void AddFunctionCandidates(const UnresolvedSetImpl &Functions,
@@ -2897,7 +2895,7 @@ public:
       FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl,
       TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args,
       OverloadCandidateSet &CandidateSet, bool SuppressUserConversions = false,
-      bool PartialOverloading = false, bool AllowExplicit = false,
+      bool PartialOverloading = false,
       ADLCallKind IsADLCandidate = ADLCallKind::NotADL);
   bool CheckNonDependentConversions(FunctionTemplateDecl *FunctionTemplate,
                                     ArrayRef<QualType> ParamTypes,
@@ -2909,16 +2907,20 @@ public:
                                     QualType ObjectType = QualType(),
                                     Expr::Classification
                                         ObjectClassification = {});
-  void AddConversionCandidate(
-      CXXConversionDecl *Conversion, DeclAccessPair FoundDecl,
-      CXXRecordDecl *ActingContext, Expr *From, QualType ToType,
-      OverloadCandidateSet &CandidateSet, bool AllowObjCConversionOnExplicit,
-      bool AllowExplicit, bool AllowResultConversion = true);
-  void AddTemplateConversionCandidate(
-      FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl,
-      CXXRecordDecl *ActingContext, Expr *From, QualType ToType,
-      OverloadCandidateSet &CandidateSet, bool AllowObjCConversionOnExplicit,
-      bool AllowExplicit, bool AllowResultConversion = true);
+  void AddConversionCandidate(CXXConversionDecl *Conversion,
+                              DeclAccessPair FoundDecl,
+                              CXXRecordDecl *ActingContext,
+                              Expr *From, QualType ToType,
+                              OverloadCandidateSet& CandidateSet,
+                              bool AllowObjCConversionOnExplicit,
+                              bool AllowResultConversion = true);
+  void AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
+                                      DeclAccessPair FoundDecl,
+                                      CXXRecordDecl *ActingContext,
+                                      Expr *From, QualType ToType,
+                                      OverloadCandidateSet &CandidateSet,
+                                      bool AllowObjCConversionOnExplicit,
+                                      bool AllowResultConversion = true);
   void AddSurrogateCandidate(CXXConversionDecl *Conversion,
                              DeclAccessPair FoundDecl,
                              CXXRecordDecl *ActingContext,
@@ -10116,14 +10118,6 @@ public:
   ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E,
                                    bool IsConstexpr = false);
 
-  /// ActOnExplicitBoolSpecifier - Build an ExplicitSpecifier from an expression
-  /// found in an explicit(bool) specifier.
-  ExplicitSpecifier ActOnExplicitBoolSpecifier(Expr *E);
-
-  /// tryResolveExplicitSpecifier - Attempt to resolve the explict specifier.
-  /// Returns true if the explicit specifier is now resolved.
-  bool tryResolveExplicitSpecifier(ExplicitSpecifier &ExplicitSpec);
-
   /// DiagnoseAssignmentAsCondition - Given that an expression is
   /// being used as a boolean condition, warn if it's an assignment.
   void DiagnoseAssignmentAsCondition(Expr *E);

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Mon May  6 02:51:10 2019
@@ -1438,6 +1438,9 @@ namespace serialization {
       /// A CXXConstructorDecl record.
       DECL_CXX_CONSTRUCTOR,
 
+      /// A CXXConstructorDecl record for an inherited constructor.
+      DECL_CXX_INHERITED_CONSTRUCTOR,
+
       /// A CXXDestructorDecl record.
       DECL_CXX_DESTRUCTOR,
 

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Mon May  6 02:51:10 2019
@@ -2430,14 +2430,6 @@ public:
                                                  ID);
   }
 
-  ExplicitSpecifier readExplicitSpec() {
-    uint64_t Kind = readInt();
-    bool HasExpr = Kind & 0x1;
-    Kind = Kind >> 1;
-    return ExplicitSpecifier(HasExpr ? readExpr() : nullptr,
-                             static_cast<ExplicitSpecKind>(Kind));
-  }
-
   void readExceptionSpec(SmallVectorImpl<QualType> &ExceptionStorage,
                          FunctionProtoType::ExceptionSpecInfo &ESI) {
     return Reader->readExceptionSpec(*F, ExceptionStorage, ESI, Record, Idx);

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Mon May  6 02:51:10 2019
@@ -3055,20 +3055,11 @@ ExpectedDecl ASTNodeImporter::VisitFunct
   // Create the imported function.
   FunctionDecl *ToFunction = nullptr;
   if (auto *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
-    Expr *ExplicitExpr = nullptr;
-    if (FromConstructor->getExplicitSpecifier().getExpr()) {
-      auto Imp = importSeq(FromConstructor->getExplicitSpecifier().getExpr());
-      if (!Imp)
-        return Imp.takeError();
-      std::tie(ExplicitExpr) = *Imp;
-    }
     if (GetImportedOrCreateDecl<CXXConstructorDecl>(
-            ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
-            ToInnerLocStart, NameInfo, T, TInfo,
-            ExplicitSpecifier(
-                ExplicitExpr,
-                FromConstructor->getExplicitSpecifier().getKind()),
-            D->isInlineSpecified(), D->isImplicit(), D->isConstexpr()))
+        ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
+        ToInnerLocStart, NameInfo, T, TInfo,
+        FromConstructor->isExplicit(),
+        D->isInlineSpecified(), D->isImplicit(), D->isConstexpr()))
       return ToFunction;
   } else if (CXXDestructorDecl *FromDtor = dyn_cast<CXXDestructorDecl>(D)) {
 
@@ -3094,19 +3085,10 @@ ExpectedDecl ASTNodeImporter::VisitFunct
     ToDtor->setOperatorDelete(ToOperatorDelete, ToThisArg);
   } else if (CXXConversionDecl *FromConversion =
                  dyn_cast<CXXConversionDecl>(D)) {
-    Expr *ExplicitExpr = nullptr;
-    if (FromConversion->getExplicitSpecifier().getExpr()) {
-      auto Imp = importSeq(FromConversion->getExplicitSpecifier().getExpr());
-      if (!Imp)
-        return Imp.takeError();
-      std::tie(ExplicitExpr) = *Imp;
-    }
     if (GetImportedOrCreateDecl<CXXConversionDecl>(
             ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
             ToInnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(),
-            ExplicitSpecifier(ExplicitExpr,
-                              FromConversion->getExplicitSpecifier().getKind()),
-            D->isConstexpr(), SourceLocation()))
+            FromConversion->isExplicit(), D->isConstexpr(), SourceLocation()))
       return ToFunction;
   } else if (auto *Method = dyn_cast<CXXMethodDecl>(D)) {
     if (GetImportedOrCreateDecl<CXXMethodDecl>(

Modified: cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp (original)
+++ cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp Mon May  6 02:51:10 2019
@@ -955,15 +955,13 @@ static bool IsStructurallyEquivalent(Str
 
   if (auto *Constructor1 = dyn_cast<CXXConstructorDecl>(Method1)) {
     auto *Constructor2 = cast<CXXConstructorDecl>(Method2);
-    if (!Constructor1->getExplicitSpecifier().isEquivalent(
-            Constructor2->getExplicitSpecifier()))
+    if (Constructor1->isExplicit() != Constructor2->isExplicit())
       return false;
   }
 
   if (auto *Conversion1 = dyn_cast<CXXConversionDecl>(Method1)) {
     auto *Conversion2 = cast<CXXConversionDecl>(Method2);
-    if (!Conversion1->getExplicitSpecifier().isEquivalent(
-            Conversion2->getExplicitSpecifier()))
+    if (Conversion1->isExplicit() != Conversion2->isExplicit())
       return false;
     if (!IsStructurallyEquivalent(Context, Conversion1->getConversionType(),
                                   Conversion2->getConversionType()))

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Mon May  6 02:51:10 2019
@@ -2713,6 +2713,7 @@ FunctionDecl::FunctionDecl(Kind DK, ASTC
   FunctionDeclBits.SClass = S;
   FunctionDeclBits.IsInline = isInlineSpecified;
   FunctionDeclBits.IsInlineSpecified = isInlineSpecified;
+  FunctionDeclBits.IsExplicitSpecified = false;
   FunctionDeclBits.IsVirtualAsWritten = false;
   FunctionDeclBits.IsPure = false;
   FunctionDeclBits.HasInheritedPrototype = false;

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Mon May  6 02:51:10 2019
@@ -1879,47 +1879,19 @@ bool CXXRecordDecl::mayBeAbstract() cons
 
 void CXXDeductionGuideDecl::anchor() {}
 
-bool ExplicitSpecifier::isEquivalent(const ExplicitSpecifier Other) const {
-  if ((getKind() != Other.getKind() ||
-       getKind() == ExplicitSpecKind::Unresolved)) {
-    if (getKind() == ExplicitSpecKind::Unresolved &&
-        Other.getKind() == ExplicitSpecKind::Unresolved) {
-      ODRHash SelfHash, OtherHash;
-      SelfHash.AddStmt(getExpr());
-      OtherHash.AddStmt(Other.getExpr());
-      return SelfHash.CalculateHash() == OtherHash.CalculateHash();
-    } else
-      return false;
-  }
-  return true;
-}
-
-ExplicitSpecifier ExplicitSpecifier::getFromDecl(FunctionDecl *Function) {
-  switch (Function->getDeclKind()) {
-  case Decl::Kind::CXXConstructor:
-    return cast<CXXConstructorDecl>(Function)->getExplicitSpecifier();
-  case Decl::Kind::CXXConversion:
-    return cast<CXXConversionDecl>(Function)->getExplicitSpecifier();
-  case Decl::Kind::CXXDeductionGuide:
-    return cast<CXXDeductionGuideDecl>(Function)->getExplicitSpecifier();
-  default:
-    return {};
-  }
-}
-
 CXXDeductionGuideDecl *CXXDeductionGuideDecl::Create(
-    ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
-    ExplicitSpecifier ES, const DeclarationNameInfo &NameInfo, QualType T,
-    TypeSourceInfo *TInfo, SourceLocation EndLocation) {
-  return new (C, DC) CXXDeductionGuideDecl(C, DC, StartLoc, ES, NameInfo, T,
-                                           TInfo, EndLocation);
+    ASTContext &C, DeclContext *DC, SourceLocation StartLoc, bool IsExplicit,
+    const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
+    SourceLocation EndLocation) {
+  return new (C, DC) CXXDeductionGuideDecl(C, DC, StartLoc, IsExplicit,
+                                           NameInfo, T, TInfo, EndLocation);
 }
 
 CXXDeductionGuideDecl *CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C,
                                                                  unsigned ID) {
-  return new (C, ID) CXXDeductionGuideDecl(
-      C, nullptr, SourceLocation(), ExplicitSpecifier(), DeclarationNameInfo(),
-      QualType(), nullptr, SourceLocation());
+  return new (C, ID) CXXDeductionGuideDecl(C, nullptr, SourceLocation(), false,
+                                           DeclarationNameInfo(), QualType(),
+                                           nullptr, SourceLocation());
 }
 
 void CXXMethodDecl::anchor() {}
@@ -2357,54 +2329,47 @@ SourceRange CXXCtorInitializer::getSourc
 CXXConstructorDecl::CXXConstructorDecl(
     ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
     const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
-    ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared,
+    bool isExplicitSpecified, bool isInline, bool isImplicitlyDeclared,
     bool isConstexpr, InheritedConstructor Inherited)
     : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
                     SC_None, isInline, isConstexpr, SourceLocation()) {
   setNumCtorInitializers(0);
   setInheritingConstructor(static_cast<bool>(Inherited));
   setImplicit(isImplicitlyDeclared);
-  CXXConstructorDeclBits.HasTrailingExplicitSpecifier = ES.getExpr() ? 1 : 0;
   if (Inherited)
     *getTrailingObjects<InheritedConstructor>() = Inherited;
-  setExplicitSpecifier(ES);
+  setExplicitSpecified(isExplicitSpecified);
 }
 
 void CXXConstructorDecl::anchor() {}
 
 CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C,
                                                            unsigned ID,
-                                                           uint64_t AllocKind) {
-  bool hasTraillingExplicit = static_cast<bool>(AllocKind & TAKHasTailExplicit);
-  bool isInheritingConstructor =
-      static_cast<bool>(AllocKind & TAKInheritsConstructor);
-  unsigned Extra =
-      additionalSizeToAlloc<InheritedConstructor, ExplicitSpecifier>(
-          isInheritingConstructor, hasTraillingExplicit);
+                                                           bool Inherited) {
+  unsigned Extra = additionalSizeToAlloc<InheritedConstructor>(Inherited);
   auto *Result = new (C, ID, Extra) CXXConstructorDecl(
       C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr,
-      ExplicitSpecifier(), false, false, false, InheritedConstructor());
-  Result->setInheritingConstructor(isInheritingConstructor);
-  Result->CXXConstructorDeclBits.HasTrailingExplicitSpecifier =
-      hasTraillingExplicit;
-  Result->setExplicitSpecifier(ExplicitSpecifier());
+      false, false, false, false, InheritedConstructor());
+  Result->setInheritingConstructor(Inherited);
   return Result;
 }
 
-CXXConstructorDecl *CXXConstructorDecl::Create(
-    ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
-    const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
-    ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared,
-    bool isConstexpr, InheritedConstructor Inherited) {
+CXXConstructorDecl *
+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) {
   assert(NameInfo.getName().getNameKind()
          == DeclarationName::CXXConstructorName &&
          "Name must refer to a constructor");
   unsigned Extra =
-      additionalSizeToAlloc<InheritedConstructor, ExplicitSpecifier>(
-          Inherited ? 1 : 0, ES.getExpr() ? 1 : 0);
-  return new (C, RD, Extra)
-      CXXConstructorDecl(C, RD, StartLoc, NameInfo, T, TInfo, ES, isInline,
-                         isImplicitlyDeclared, isConstexpr, Inherited);
+      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 {
@@ -2555,21 +2520,25 @@ void CXXConversionDecl::anchor() {}
 
 CXXConversionDecl *
 CXXConversionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  return new (C, ID) CXXConversionDecl(
-      C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr,
-      false, ExplicitSpecifier(), false, SourceLocation());
+  return new (C, ID) CXXConversionDecl(C, nullptr, SourceLocation(),
+                                       DeclarationNameInfo(), QualType(),
+                                       nullptr, false, false, false,
+                                       SourceLocation());
 }
 
-CXXConversionDecl *CXXConversionDecl::Create(
-    ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
-    const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
-    bool isInline, ExplicitSpecifier ES, bool isConstexpr,
-    SourceLocation EndLocation) {
+CXXConversionDecl *
+CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
+                          SourceLocation StartLoc,
+                          const DeclarationNameInfo &NameInfo,
+                          QualType T, TypeSourceInfo *TInfo,
+                          bool isInline, bool isExplicit,
+                          bool isConstexpr, SourceLocation EndLocation) {
   assert(NameInfo.getName().getNameKind()
          == DeclarationName::CXXConversionFunctionName &&
          "Name must refer to a conversion function");
   return new (C, RD) CXXConversionDecl(C, RD, StartLoc, NameInfo, T, TInfo,
-                                       isInline, ES, isConstexpr, EndLocation);
+                                       isInline, isExplicit, isConstexpr,
+                                       EndLocation);
 }
 
 bool CXXConversionDecl::isLambdaToBlockPointerConversion() const {

Modified: cfe/trunk/lib/AST/DeclPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclPrinter.cpp (original)
+++ cfe/trunk/lib/AST/DeclPrinter.cpp Mon May  6 02:51:10 2019
@@ -566,21 +566,6 @@ void DeclPrinter::VisitEnumConstantDecl(
   }
 }
 
-static void printExplicitSpecifier(ExplicitSpecifier ES, llvm::raw_ostream &Out,
-                                   PrintingPolicy &Policy,
-                                   unsigned Indentation) {
-  std::string Proto = "explicit";
-  llvm::raw_string_ostream EOut(Proto);
-  if (ES.getExpr()) {
-    EOut << "(";
-    ES.getExpr()->printPretty(EOut, nullptr, Policy, Indentation);
-    EOut << ")";
-  }
-  EOut << " ";
-  EOut.flush();
-  Out << EOut.str();
-}
-
 void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
   if (!D->getDescribedFunctionTemplate() &&
       !D->isFunctionTemplateSpecialization())
@@ -611,9 +596,10 @@ void DeclPrinter::VisitFunctionDecl(Func
     if (D->isVirtualAsWritten()) Out << "virtual ";
     if (D->isModulePrivate())    Out << "__module_private__ ";
     if (D->isConstexpr() && !D->isExplicitlyDefaulted()) Out << "constexpr ";
-    ExplicitSpecifier ExplicitSpec = ExplicitSpecifier::getFromDecl(D);
-    if (ExplicitSpec.isSpecified())
-      printExplicitSpecifier(ExplicitSpec, Out, Policy, Indentation);
+    if ((CDecl && CDecl->isExplicitSpecified()) ||
+        (ConversionDecl && ConversionDecl->isExplicitSpecified()) ||
+        (GuideDecl && GuideDecl->isExplicitSpecified()))
+      Out << "explicit ";
   }
 
   PrintingPolicy SubPolicy(Policy);

Modified: cfe/trunk/lib/Frontend/InitPreprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/InitPreprocessor.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/InitPreprocessor.cpp (original)
+++ cfe/trunk/lib/Frontend/InitPreprocessor.cpp Mon May  6 02:51:10 2019
@@ -540,8 +540,6 @@ static void InitializeCPlusPlusFeatureTe
     Builder.defineMacro("__cpp_template_template_args", "201611L");
 
   // C++20 features.
-  if (LangOpts.CPlusPlus2a)
-    Builder.defineMacro("__cpp_conditional_explicit", "201806L");
   if (LangOpts.Char8)
     Builder.defineMacro("__cpp_char8_t", "201811L");
   Builder.defineMacro("__cpp_impl_destroying_delete", "201806L");

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon May  6 02:51:10 2019
@@ -2442,12 +2442,12 @@ void Parser::ParseSpecifierQualifierList
       Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec);
     if (DS.isVirtualSpecified())
       Diag(DS.getVirtualSpecLoc(), diag::err_typename_invalid_functionspec);
-    if (DS.hasExplicitSpecifier())
+    if (DS.isExplicitSpecified())
       Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec);
     DS.ClearFunctionSpecs();
   }
 
-  // Issue diagnostic and remove constexpr specifier if present.
+  // Issue diagnostic and remove constexpr specfier if present.
   if (DS.isConstexprSpecified() && DSC != DeclSpecContext::DSC_condition) {
     Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr);
     DS.ClearConstexprSpec();
@@ -2965,13 +2965,9 @@ void Parser::ParseDeclarationSpecifiers(
   while (1) {
     bool isInvalid = false;
     bool isStorageClass = false;
-    bool isAlreadyConsumed = false;
     const char *PrevSpec = nullptr;
     unsigned DiagID = 0;
 
-    // This value need to be set when isAlreadyConsumed is set to true.
-    SourceLocation RangeEnd;
-
     // HACK: MSVC doesn't consider _Atomic to be a keyword and its STL
     // implementation for VS2013 uses _Atomic as an identifier for one of the
     // classes in <atomic>.
@@ -3522,34 +3518,9 @@ void Parser::ParseDeclarationSpecifiers(
         isInvalid = DS.setFunctionSpecVirtual(Loc, PrevSpec, DiagID);
       }
       break;
-    case tok::kw_explicit: {
-      SourceLocation ExplicitLoc = Loc;
-      SourceLocation CloseParenLoc;
-      ExplicitSpecifier ExplicitSpec(nullptr, ExplicitSpecKind::ResolvedTrue);
-      isAlreadyConsumed = true;
-      RangeEnd = ExplicitLoc;
-      ConsumeToken(); // kw_explicit
-      if (Tok.is(tok::l_paren)) {
-        if (getLangOpts().CPlusPlus2a) {
-          ExprResult ExplicitExpr(static_cast<Expr *>(nullptr));
-          BalancedDelimiterTracker Tracker(*this, tok::l_paren);
-          Tracker.consumeOpen();
-          ExplicitExpr = ParseConstantExpression();
-          RangeEnd = Tok.getLocation();
-          if (ExplicitExpr.isUsable()) {
-            CloseParenLoc = Tok.getLocation();
-            Tracker.consumeClose();
-            ExplicitSpec =
-                Actions.ActOnExplicitBoolSpecifier(ExplicitExpr.get());
-          } else
-            Tracker.skipToEnd();
-        } else
-          Diag(Tok.getLocation(), diag::warn_cxx2a_compat_explicit_bool);
-      }
-      isInvalid = DS.setFunctionSpecExplicit(ExplicitLoc, PrevSpec, DiagID,
-                                             ExplicitSpec, CloseParenLoc);
+    case tok::kw_explicit:
+      isInvalid = DS.setFunctionSpecExplicit(Loc, PrevSpec, DiagID);
       break;
-    }
     case tok::kw__Noreturn:
       if (!getLangOpts().C11)
         Diag(Loc, diag::ext_c11_noreturn);
@@ -3893,32 +3864,25 @@ void Parser::ParseDeclarationSpecifiers(
       // If a type specifier follows, it will be diagnosed elsewhere.
       continue;
     }
-
-    assert((!isAlreadyConsumed || RangeEnd != SourceLocation()) &&
-                                     "both or neither of isAlreadyConsumed and "
-                                     "RangeEnd needs to be set");
-    DS.SetRangeEnd(isAlreadyConsumed ? RangeEnd : Tok.getLocation());
-
     // If the specifier wasn't legal, issue a diagnostic.
     if (isInvalid) {
       assert(PrevSpec && "Method did not return previous specifier!");
       assert(DiagID);
 
       if (DiagID == diag::ext_duplicate_declspec ||
-          DiagID == diag::ext_warn_duplicate_declspec ||
-          DiagID == diag::err_duplicate_declspec)
-        Diag(Loc, DiagID) << PrevSpec
-                          << FixItHint::CreateRemoval(
-                                 SourceRange(Loc, DS.getEndLoc()));
+          DiagID == diag::ext_warn_duplicate_declspec)
+        Diag(Tok, DiagID)
+          << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation());
       else if (DiagID == diag::err_opencl_unknown_type_specifier) {
-        Diag(Loc, DiagID) << getLangOpts().OpenCLCPlusPlus
-                          << getLangOpts().getOpenCLVersionTuple().getAsString()
-                          << PrevSpec << isStorageClass;
+        Diag(Tok, DiagID) << getLangOpts().OpenCLCPlusPlus
+            << getLangOpts().getOpenCLVersionTuple().getAsString()
+            << PrevSpec << isStorageClass;
       } else
-        Diag(Loc, DiagID) << PrevSpec;
+        Diag(Tok, DiagID) << PrevSpec;
     }
 
-    if (DiagID != diag::err_bool_redeclaration && !isAlreadyConsumed)
+    DS.SetRangeEnd(Tok.getLocation());
+    if (DiagID != diag::err_bool_redeclaration)
       // After an error the next token can be an annotation token.
       ConsumeAnyToken();
 

Modified: cfe/trunk/lib/Sema/DeclSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DeclSpec.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/DeclSpec.cpp (original)
+++ cfe/trunk/lib/Sema/DeclSpec.cpp Mon May  6 02:51:10 2019
@@ -445,7 +445,7 @@ unsigned DeclSpec::getParsedSpecifiers()
   if (hasTypeSpecifier())
     Res |= PQ_TypeSpecifier;
 
-  if (FS_inline_specified || FS_virtual_specified || hasExplicitSpecifier() ||
+  if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified ||
       FS_noreturn_specified || FS_forceinline_specified)
     Res |= PQ_FunctionSpecifier;
   return Res;
@@ -944,24 +944,17 @@ bool DeclSpec::setFunctionSpecVirtual(So
 }
 
 bool DeclSpec::setFunctionSpecExplicit(SourceLocation Loc,
-                                       const char *&PrevSpec, unsigned &DiagID,
-                                       ExplicitSpecifier ExplicitSpec,
-                                       SourceLocation CloseParenLoc) {
-  assert((ExplicitSpec.getKind() == ExplicitSpecKind::ResolvedTrue ||
-          ExplicitSpec.getExpr()) &&
-         "invalid ExplicitSpecifier");
+                                       const char *&PrevSpec,
+                                       unsigned &DiagID) {
   // 'explicit explicit' is ok, but warn as this is likely not what the user
   // intended.
-  if (hasExplicitSpecifier()) {
-    DiagID = (ExplicitSpec.getExpr() || FS_explicit_specifier.getExpr())
-                 ? diag::err_duplicate_declspec
-                 : diag::ext_warn_duplicate_declspec;
+  if (FS_explicit_specified) {
+    DiagID = diag::warn_duplicate_declspec;
     PrevSpec = "explicit";
     return true;
   }
-  FS_explicit_specifier = ExplicitSpec;
+  FS_explicit_specified = true;
   FS_explicitLoc = Loc;
-  FS_explicitCloseParenLoc = CloseParenLoc;
   return false;
 }
 
@@ -1300,26 +1293,23 @@ void DeclSpec::Finish(Sema &S, const Pri
   //   The explicit specifier shall be used only in the declaration of
   //   a constructor or conversion function within its class
   //   definition;
-  if (isFriendSpecified() && (isVirtualSpecified() || hasExplicitSpecifier())) {
+  if (isFriendSpecified() && (isVirtualSpecified() || isExplicitSpecified())) {
     StringRef Keyword;
-    FixItHint Hint;
     SourceLocation SCLoc;
 
     if (isVirtualSpecified()) {
       Keyword = "virtual";
       SCLoc = getVirtualSpecLoc();
-      Hint = FixItHint::CreateRemoval(SCLoc);
     } else {
       Keyword = "explicit";
       SCLoc = getExplicitSpecLoc();
-      Hint = FixItHint::CreateRemoval(getExplicitSpecRange());
     }
 
+    FixItHint Hint = FixItHint::CreateRemoval(SCLoc);
     S.Diag(SCLoc, diag::err_friend_decl_spec)
       << Keyword << Hint;
 
-    FS_virtual_specified = false;
-    FS_explicit_specifier = ExplicitSpecifier();
+    FS_virtual_specified = FS_explicit_specified = false;
     FS_virtualLoc = FS_explicitLoc = SourceLocation();
   }
 

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Mon May  6 02:51:10 2019
@@ -4961,15 +4961,13 @@ QualType Sema::ProduceConstructorSignatu
       AddOverloadCandidate(FD, DeclAccessPair::make(FD, C->getAccess()), Args,
                            CandidateSet,
                            /*SuppressUsedConversions=*/false,
-                           /*PartialOverloading=*/true,
-                           /*AllowExplicit*/ true);
+                           /*PartialOverloading=*/true);
     } else if (auto *FTD = dyn_cast<FunctionTemplateDecl>(C)) {
       AddTemplateOverloadCandidate(
           FTD, DeclAccessPair::make(FTD, C->getAccess()),
           /*ExplicitTemplateArgs=*/nullptr, Args, CandidateSet,
           /*SuppressUsedConversions=*/false,
-          /*PartialOverloading=*/true,
-          /*AllowExplicit*/ true);
+          /*PartialOverloading=*/true);
     }
   }
 

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon May  6 02:51:10 2019
@@ -5705,7 +5705,7 @@ void Sema::DiagnoseFunctionSpecifiers(co
     Diag(DS.getVirtualSpecLoc(),
          diag::err_virtual_non_function);
 
-  if (DS.hasExplicitSpecifier())
+  if (DS.isExplicitSpecified())
     Diag(DS.getExplicitSpecLoc(),
          diag::err_explicit_non_function);
 
@@ -7969,7 +7969,7 @@ static FunctionDecl* CreateNewFunctionDe
     return NewFD;
   }
 
-  ExplicitSpecifier ExplicitSpecifier = D.getDeclSpec().getExplicitSpecifier();
+  bool isExplicit = D.getDeclSpec().isExplicitSpecified();
   bool isConstexpr = D.getDeclSpec().isConstexprSpecified();
 
   // Check that the return type is not an abstract class type.
@@ -7989,7 +7989,7 @@ static FunctionDecl* CreateNewFunctionDe
     R = SemaRef.CheckConstructorDeclarator(D, R, SC);
     return CXXConstructorDecl::Create(
         SemaRef.Context, cast<CXXRecordDecl>(DC), D.getBeginLoc(), NameInfo, R,
-        TInfo, ExplicitSpecifier, isInline,
+        TInfo, isExplicit, isInline,
         /*isImplicitlyDeclared=*/false, isConstexpr);
 
   } else if (Name.getNameKind() == DeclarationName::CXXDestructorName) {
@@ -8034,13 +8034,13 @@ static FunctionDecl* CreateNewFunctionDe
     IsVirtualOkay = true;
     return CXXConversionDecl::Create(
         SemaRef.Context, cast<CXXRecordDecl>(DC), D.getBeginLoc(), NameInfo, R,
-        TInfo, isInline, ExplicitSpecifier, isConstexpr, SourceLocation());
+        TInfo, isInline, isExplicit, isConstexpr, SourceLocation());
 
   } else if (Name.getNameKind() == DeclarationName::CXXDeductionGuideName) {
     SemaRef.CheckDeductionGuideDeclarator(D, R, SC);
 
     return CXXDeductionGuideDecl::Create(SemaRef.Context, DC, D.getBeginLoc(),
-                                         ExplicitSpecifier, NameInfo, R, TInfo,
+                                         isExplicit, NameInfo, R, TInfo,
                                          D.getEndLoc());
   } else if (DC->isRecord()) {
     // If the name of the function is the same as the name of the record,
@@ -8401,7 +8401,7 @@ Sema::ActOnFunctionDeclarator(Scope *S,
   if (getLangOpts().CPlusPlus) {
     bool isInline = D.getDeclSpec().isInlineSpecified();
     bool isVirtual = D.getDeclSpec().isVirtualSpecified();
-    bool hasExplicit = D.getDeclSpec().hasExplicitSpecifier();
+    bool isExplicit = D.getDeclSpec().isExplicitSpecified();
     bool isConstexpr = D.getDeclSpec().isConstexprSpecified();
     isFriend = D.getDeclSpec().isFriendSpecified();
     if (isFriend && !isInline && D.isFunctionDefinition()) {
@@ -8584,20 +8584,20 @@ Sema::ActOnFunctionDeclarator(Scope *S,
     //  The explicit specifier shall be used only in the declaration of a
     //  constructor or conversion function within its class definition;
     //  see 12.3.1 and 12.3.2.
-    if (hasExplicit && !NewFD->isInvalidDecl() &&
+    if (isExplicit && !NewFD->isInvalidDecl() &&
         !isa<CXXDeductionGuideDecl>(NewFD)) {
       if (!CurContext->isRecord()) {
         // 'explicit' was specified outside of the class.
         Diag(D.getDeclSpec().getExplicitSpecLoc(),
              diag::err_explicit_out_of_class)
-            << FixItHint::CreateRemoval(D.getDeclSpec().getExplicitSpecRange());
+          << FixItHint::CreateRemoval(D.getDeclSpec().getExplicitSpecLoc());
       } else if (!isa<CXXConstructorDecl>(NewFD) &&
                  !isa<CXXConversionDecl>(NewFD)) {
         // 'explicit' was specified on a function that wasn't a constructor
         // or conversion function.
         Diag(D.getDeclSpec().getExplicitSpecLoc(),
              diag::err_explicit_non_ctor_or_conv_function)
-            << FixItHint::CreateRemoval(D.getDeclSpec().getExplicitSpecRange());
+          << FixItHint::CreateRemoval(D.getDeclSpec().getExplicitSpecLoc());
       }
     }
 

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon May  6 02:51:10 2019
@@ -657,13 +657,14 @@ bool Sema::MergeCXXFunctionDecl(Function
     Invalid = true;
   }
 
-  // C++17 [temp.deduct.guide]p3:
-  //   Two deduction guide declarations in the same translation unit
-  //   for the same class template shall not have equivalent
-  //   parameter-declaration-clauses.
-  if (isa<CXXDeductionGuideDecl>(New) &&
-      !New->isFunctionTemplateSpecialization()) {
-    Diag(New->getLocation(), diag::err_deduction_guide_redeclared);
+  // FIXME: It's not clear what should happen if multiple declarations of a
+  // deduction guide have different explicitness. For now at least we simply
+  // reject any case where the explicitness changes.
+  auto *NewGuide = dyn_cast<CXXDeductionGuideDecl>(New);
+  if (NewGuide && NewGuide->isExplicitSpecified() !=
+                      cast<CXXDeductionGuideDecl>(Old)->isExplicitSpecified()) {
+    Diag(New->getLocation(), diag::err_deduction_guide_explicit_mismatch)
+      << NewGuide->isExplicitSpecified();
     Diag(Old->getLocation(), diag::note_previous_declaration);
   }
 
@@ -8591,12 +8592,12 @@ void Sema::CheckConversionDeclarator(Dec
     R = Context.getFunctionType(ConvType, None, Proto->getExtProtoInfo());
 
   // C++0x explicit conversion operators.
-  if (DS.hasExplicitSpecifier() && !getLangOpts().CPlusPlus2a)
+  if (DS.isExplicitSpecified())
     Diag(DS.getExplicitSpecLoc(),
          getLangOpts().CPlusPlus11
              ? diag::warn_cxx98_compat_explicit_conversion_functions
              : diag::ext_explicit_conversion_functions)
-        << SourceRange(DS.getExplicitSpecRange());
+        << SourceRange(DS.getExplicitSpecLoc());
 }
 
 /// ActOnConversionDeclarator - Called by ActOnDeclarator to complete
@@ -10819,28 +10820,6 @@ struct ComputingExceptionSpec {
 };
 }
 
-bool Sema::tryResolveExplicitSpecifier(ExplicitSpecifier &ExplicitSpec) {
-  llvm::APSInt Result;
-  ExprResult Converted = CheckConvertedConstantExpression(
-      ExplicitSpec.getExpr(), Context.BoolTy, Result, CCEK_ExplicitBool);
-  ExplicitSpec.setExpr(Converted.get());
-  if (Converted.isUsable() && !Converted.get()->isValueDependent()) {
-    ExplicitSpec.setKind(Result.getBoolValue()
-                             ? ExplicitSpecKind::ResolvedTrue
-                             : ExplicitSpecKind::ResolvedFalse);
-    return true;
-  }
-  ExplicitSpec.setKind(ExplicitSpecKind::Unresolved);
-  return false;
-}
-
-ExplicitSpecifier Sema::ActOnExplicitBoolSpecifier(Expr *ExplicitExpr) {
-  ExplicitSpecifier ES(ExplicitExpr, ExplicitSpecKind::Unresolved);
-  if (!ExplicitExpr->isTypeDependent())
-    tryResolveExplicitSpecifier(ES);
-  return ES;
-}
-
 static Sema::ImplicitExceptionSpecification
 ComputeDefaultedSpecialMemberExceptionSpec(
     Sema &S, SourceLocation Loc, CXXMethodDecl *MD, Sema::CXXSpecialMember CSM,
@@ -10989,9 +10968,9 @@ CXXConstructorDecl *Sema::DeclareImplici
     = Context.DeclarationNames.getCXXConstructorName(ClassType);
   DeclarationNameInfo NameInfo(Name, ClassLoc);
   CXXConstructorDecl *DefaultCon = CXXConstructorDecl::Create(
-      Context, ClassDecl, ClassLoc, NameInfo, /*Type*/ QualType(),
-      /*TInfo=*/nullptr, ExplicitSpecifier(),
-      /*isInline=*/true, /*isImplicitlyDeclared=*/true, Constexpr);
+      Context, ClassDecl, ClassLoc, NameInfo, /*Type*/QualType(),
+      /*TInfo=*/nullptr, /*isExplicit=*/false, /*isInline=*/true,
+      /*isImplicitlyDeclared=*/true, Constexpr);
   DefaultCon->setAccess(AS_public);
   DefaultCon->setDefaulted();
 
@@ -11110,7 +11089,7 @@ Sema::findInheritingConstructor(SourceLo
 
   CXXConstructorDecl *DerivedCtor = CXXConstructorDecl::Create(
       Context, Derived, UsingLoc, NameInfo, TInfo->getType(), TInfo,
-      BaseCtor->getExplicitSpecifier(), /*Inline=*/true,
+      BaseCtor->isExplicit(), /*Inline=*/true,
       /*ImplicitlyDeclared=*/true, Constexpr,
       InheritedConstructor(Shadow, BaseCtor));
   if (Shadow->isInvalidDecl())
@@ -12562,9 +12541,8 @@ CXXConstructorDecl *Sema::DeclareImplici
   //   member of its class.
   CXXConstructorDecl *CopyConstructor = CXXConstructorDecl::Create(
       Context, ClassDecl, ClassLoc, NameInfo, QualType(), /*TInfo=*/nullptr,
-      ExplicitSpecifier(),
-      /*isInline=*/true,
-      /*isImplicitlyDeclared=*/true, Constexpr);
+      /*isExplicit=*/false, /*isInline=*/true, /*isImplicitlyDeclared=*/true,
+      Constexpr);
   CopyConstructor->setAccess(AS_public);
   CopyConstructor->setDefaulted();
 
@@ -12693,9 +12671,8 @@ CXXConstructorDecl *Sema::DeclareImplici
   //   member of its class.
   CXXConstructorDecl *MoveConstructor = CXXConstructorDecl::Create(
       Context, ClassDecl, ClassLoc, NameInfo, QualType(), /*TInfo=*/nullptr,
-      ExplicitSpecifier(),
-      /*isInline=*/true,
-      /*isImplicitlyDeclared=*/true, Constexpr);
+      /*isExplicit=*/false, /*isInline=*/true, /*isImplicitlyDeclared=*/true,
+      Constexpr);
   MoveConstructor->setAccess(AS_public);
   MoveConstructor->setDefaulted();
 

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Mon May  6 02:51:10 2019
@@ -3763,10 +3763,9 @@ ResolveConstructorOverload(Sema &S, Sour
          hasCopyOrMoveCtorParam(S.Context, Info));
 
     if (Info.ConstructorTmpl)
-      S.AddTemplateOverloadCandidate(
-          Info.ConstructorTmpl, Info.FoundDecl,
-          /*ExplicitArgs*/ nullptr, Args, CandidateSet, SuppressUserConversions,
-          /*PartialOverloading=*/false, AllowExplicit);
+      S.AddTemplateOverloadCandidate(Info.ConstructorTmpl, Info.FoundDecl,
+                                     /*ExplicitArgs*/ nullptr, Args,
+                                     CandidateSet, SuppressUserConversions);
     else {
       // C++ [over.match.copy]p1:
       //   - When initializing a temporary to be bound to the first parameter
@@ -3780,8 +3779,8 @@ ResolveConstructorOverload(Sema &S, Sour
                                hasCopyOrMoveCtorParam(S.Context, Info);
       S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, Args,
                              CandidateSet, SuppressUserConversions,
-                             /*PartialOverloading=*/false, AllowExplicit,
-                             AllowExplicitConv);
+                             /*PartialOverloading=*/false,
+                             /*AllowExplicit=*/AllowExplicitConv);
     }
   }
 
@@ -3814,17 +3813,16 @@ ResolveConstructorOverload(Sema &S, Sour
         else
           Conv = cast<CXXConversionDecl>(D);
 
-        if (AllowExplicit || !Conv->isExplicit()) {
+        if ((AllowExplicit && !CopyInitializing) || !Conv->isExplicit()) {
           if (ConvTemplate)
-            S.AddTemplateConversionCandidate(
-                ConvTemplate, I.getPair(), ActingDC, Initializer, DestType,
-                CandidateSet, AllowExplicit, AllowExplicit,
-                /*AllowResultConversion*/ false);
+            S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(),
+                                             ActingDC, Initializer, DestType,
+                                             CandidateSet, AllowExplicit,
+                                             /*AllowResultConversion*/false);
           else
             S.AddConversionCandidate(Conv, I.getPair(), ActingDC, Initializer,
                                      DestType, CandidateSet, AllowExplicit,
-                                     AllowExplicit,
-                                     /*AllowResultConversion*/ false);
+                                     /*AllowResultConversion*/false);
         }
       }
     }
@@ -4370,16 +4368,14 @@ static OverloadingResult TryRefInitWithC
       if (!Info.Constructor->isInvalidDecl() &&
           Info.Constructor->isConvertingConstructor(AllowExplicitCtors)) {
         if (Info.ConstructorTmpl)
-          S.AddTemplateOverloadCandidate(
-              Info.ConstructorTmpl, Info.FoundDecl,
-              /*ExplicitArgs*/ nullptr, Initializer, CandidateSet,
-              /*SuppressUserConversions=*/true,
-              /*PartialOverloading*/ false, AllowExplicitCtors);
+          S.AddTemplateOverloadCandidate(Info.ConstructorTmpl, Info.FoundDecl,
+                                         /*ExplicitArgs*/ nullptr,
+                                         Initializer, CandidateSet,
+                                         /*SuppressUserConversions=*/true);
         else
-          S.AddOverloadCandidate(
-              Info.Constructor, Info.FoundDecl, Initializer, CandidateSet,
-              /*SuppressUserConversions=*/true,
-              /*PartialOverloading*/ false, AllowExplicitCtors);
+          S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl,
+                                 Initializer, CandidateSet,
+                                 /*SuppressUserConversions=*/true);
       }
     }
   }
@@ -4414,17 +4410,17 @@ static OverloadingResult TryRefInitWithC
       // candidates with reference-compatible results? That might be needed to
       // break recursion.
       if ((AllowExplicitConvs || !Conv->isExplicit()) &&
-          (AllowRValues ||
-           Conv->getConversionType()->isLValueReferenceType())) {
+          (AllowRValues || Conv->getConversionType()->isLValueReferenceType())){
         if (ConvTemplate)
-          S.AddTemplateConversionCandidate(
-              ConvTemplate, I.getPair(), ActingDC, Initializer, DestType,
-              CandidateSet,
-              /*AllowObjCConversionOnExplicit=*/false, AllowExplicitConvs);
+          S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(),
+                                           ActingDC, Initializer,
+                                           DestType, CandidateSet,
+                                           /*AllowObjCConversionOnExplicit=*/
+                                             false);
         else
-          S.AddConversionCandidate(
-              Conv, I.getPair(), ActingDC, Initializer, DestType, CandidateSet,
-              /*AllowObjCConversionOnExplicit=*/false, AllowExplicitConvs);
+          S.AddConversionCandidate(Conv, I.getPair(), ActingDC,
+                                   Initializer, DestType, CandidateSet,
+                                   /*AllowObjCConversionOnExplicit=*/false);
       }
     }
   }
@@ -5000,16 +4996,14 @@ static void TryUserDefinedConversion(Sem
         if (!Info.Constructor->isInvalidDecl() &&
             Info.Constructor->isConvertingConstructor(AllowExplicit)) {
           if (Info.ConstructorTmpl)
-            S.AddTemplateOverloadCandidate(
-                Info.ConstructorTmpl, Info.FoundDecl,
-                /*ExplicitArgs*/ nullptr, Initializer, CandidateSet,
-                /*SuppressUserConversions=*/true,
-                /*PartialOverloading*/ false, AllowExplicit);
+            S.AddTemplateOverloadCandidate(Info.ConstructorTmpl, Info.FoundDecl,
+                                           /*ExplicitArgs*/ nullptr,
+                                           Initializer, CandidateSet,
+                                           /*SuppressUserConversions=*/true);
           else
             S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl,
                                    Initializer, CandidateSet,
-                                   /*SuppressUserConversions=*/true,
-                                   /*PartialOverloading*/ false, AllowExplicit);
+                                   /*SuppressUserConversions=*/true);
         }
       }
     }
@@ -5044,12 +5038,12 @@ static void TryUserDefinedConversion(Sem
 
         if (AllowExplicit || !Conv->isExplicit()) {
           if (ConvTemplate)
-            S.AddTemplateConversionCandidate(
-                ConvTemplate, I.getPair(), ActingDC, Initializer, DestType,
-                CandidateSet, AllowExplicit, AllowExplicit);
+            S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(),
+                                             ActingDC, Initializer, DestType,
+                                             CandidateSet, AllowExplicit);
           else
-            S.AddConversionCandidate(Conv, I.getPair(), ActingDC, Initializer,
-                                     DestType, CandidateSet, AllowExplicit,
+            S.AddConversionCandidate(Conv, I.getPair(), ActingDC,
+                                     Initializer, DestType, CandidateSet,
                                      AllowExplicit);
         }
       }
@@ -9342,7 +9336,6 @@ QualType Sema::DeduceTemplateSpecializat
   OverloadCandidateSet::iterator Best;
 
   bool HasAnyDeductionGuide = false;
-  bool AllowExplicit = !Kind.isCopyInit() || ListInit;
 
   auto tryToResolveOverload =
       [&](bool OnlyListConstructors) -> OverloadingResult {
@@ -9368,7 +9361,7 @@ QualType Sema::DeduceTemplateSpecializat
       //   converting constructors (12.3.1) of that class.
       // C++ [over.match.copy]p1: (non-list copy-initialization from class)
       //   The converting constructors of T are candidate functions.
-      if (!AllowExplicit) {
+      if (Kind.isCopyInit() && !ListInit) {
         // Only consider converting constructors.
         if (GD->isExplicit())
           continue;
@@ -9403,9 +9396,8 @@ QualType Sema::DeduceTemplateSpecializat
 
       if (TD)
         AddTemplateOverloadCandidate(TD, I.getPair(), /*ExplicitArgs*/ nullptr,
-                                     Inits, Candidates, SuppressUserConversions,
-                                     /*PartialOverloading*/ false,
-                                     AllowExplicit);
+                                     Inits, Candidates,
+                                     SuppressUserConversions);
       else
         AddOverloadCandidate(GD, I.getPair(), Inits, Candidates,
                              SuppressUserConversions);

Modified: cfe/trunk/lib/Sema/SemaLambda.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLambda.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLambda.cpp Mon May  6 02:51:10 2019
@@ -1325,7 +1325,7 @@ static void addFunctionPointerConversion
   CXXConversionDecl *Conversion = CXXConversionDecl::Create(
       S.Context, Class, Loc,
       DeclarationNameInfo(ConversionName, Loc, ConvNameLoc), ConvTy, ConvTSI,
-      /*isInline=*/true, ExplicitSpecifier(),
+      /*isInline=*/true, /*isExplicit=*/false,
       /*isConstexpr=*/S.getLangOpts().CPlusPlus17,
       CallOperator->getBody()->getEndLoc());
   Conversion->setAccess(AS_public);
@@ -1412,7 +1412,7 @@ static void addBlockPointerConversion(Se
   CXXConversionDecl *Conversion = CXXConversionDecl::Create(
       S.Context, Class, Loc, DeclarationNameInfo(Name, Loc, NameLoc), ConvTy,
       S.Context.getTrivialTypeSourceInfo(ConvTy, Loc),
-      /*isInline=*/true, ExplicitSpecifier(),
+      /*isInline=*/true, /*isExplicit=*/false,
       /*isConstexpr=*/false, CallOperator->getBody()->getEndLoc());
   Conversion->setAccess(AS_public);
   Conversion->setImplicit(true);

Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Mon May  6 02:51:10 2019
@@ -3041,15 +3041,10 @@ Sema::SpecialMemberOverloadResult Sema::
                            llvm::makeArrayRef(&Arg, NumArgs), OCS, true);
       else if (CtorInfo)
         AddOverloadCandidate(CtorInfo.Constructor, CtorInfo.FoundDecl,
-                             llvm::makeArrayRef(&Arg, NumArgs), OCS,
-                             /*SuppressUserConversions*/ true,
-                             /*PartialOverloading*/ false,
-                             /*AllowExplcit*/ true);
+                             llvm::makeArrayRef(&Arg, NumArgs), OCS, true);
       else
         AddOverloadCandidate(M, Cand, llvm::makeArrayRef(&Arg, NumArgs), OCS,
-                             /*SuppressUserConversions*/ true,
-                             /*PartialOverloading*/ false,
-                             /*AllowExplcit*/ true);
+                             true);
     } else if (FunctionTemplateDecl *Tmpl =
                  dyn_cast<FunctionTemplateDecl>(Cand->getUnderlyingDecl())) {
       if (SM == CXXCopyAssignment || SM == CXXMoveAssignment)

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon May  6 02:51:10 2019
@@ -3242,13 +3242,10 @@ IsInitializerListConstructorConversion(S
       if (Info.ConstructorTmpl)
         S.AddTemplateOverloadCandidate(Info.ConstructorTmpl, Info.FoundDecl,
                                        /*ExplicitArgs*/ nullptr, From,
-                                       CandidateSet, SuppressUserConversions,
-                                       /*PartialOverloading*/ false,
-                                       AllowExplicit);
+                                       CandidateSet, SuppressUserConversions);
       else
         S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, From,
-                               CandidateSet, SuppressUserConversions,
-                               /*PartialOverloading*/ false, AllowExplicit);
+                               CandidateSet, SuppressUserConversions);
     }
   }
 
@@ -3375,15 +3372,13 @@ IsUserDefinedConversion(Sema &S, Expr *F
             S.AddTemplateOverloadCandidate(
                 Info.ConstructorTmpl, Info.FoundDecl,
                 /*ExplicitArgs*/ nullptr, llvm::makeArrayRef(Args, NumArgs),
-                CandidateSet, SuppressUserConversions,
-                /*PartialOverloading*/ false, AllowExplicit);
+                CandidateSet, SuppressUserConversions);
           else
             // Allow one user-defined conversion when user specifies a
             // From->ToType conversion via an static cast (c-style, etc).
             S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl,
                                    llvm::makeArrayRef(Args, NumArgs),
-                                   CandidateSet, SuppressUserConversions,
-                                   /*PartialOverloading*/ false, AllowExplicit);
+                                   CandidateSet, SuppressUserConversions);
         }
       }
     }
@@ -3415,13 +3410,14 @@ IsUserDefinedConversion(Sema &S, Expr *F
 
         if (AllowExplicit || !Conv->isExplicit()) {
           if (ConvTemplate)
-            S.AddTemplateConversionCandidate(
-                ConvTemplate, FoundDecl, ActingContext, From, ToType,
-                CandidateSet, AllowObjCConversionOnExplicit, AllowExplicit);
+            S.AddTemplateConversionCandidate(ConvTemplate, FoundDecl,
+                                             ActingContext, From, ToType,
+                                             CandidateSet,
+                                             AllowObjCConversionOnExplicit);
           else
-            S.AddConversionCandidate(
-                Conv, FoundDecl, ActingContext, From, ToType, CandidateSet,
-                AllowObjCConversionOnExplicit, AllowExplicit);
+            S.AddConversionCandidate(Conv, FoundDecl, ActingContext,
+                                     From, ToType, CandidateSet,
+                                     AllowObjCConversionOnExplicit);
         }
       }
     }
@@ -4449,13 +4445,13 @@ FindConversionForRefInit(Sema &S, Implic
     }
 
     if (ConvTemplate)
-      S.AddTemplateConversionCandidate(
-          ConvTemplate, I.getPair(), ActingDC, Init, DeclType, CandidateSet,
-          /*AllowObjCConversionOnExplicit=*/false, AllowExplicit);
+      S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(), ActingDC,
+                                       Init, DeclType, CandidateSet,
+                                       /*AllowObjCConversionOnExplicit=*/false);
     else
-      S.AddConversionCandidate(
-          Conv, I.getPair(), ActingDC, Init, DeclType, CandidateSet,
-          /*AllowObjCConversionOnExplicit=*/false, AllowExplicit);
+      S.AddConversionCandidate(Conv, I.getPair(), ActingDC, Init,
+                               DeclType, CandidateSet,
+                               /*AllowObjCConversionOnExplicit=*/false);
   }
 
   bool HadMultipleCandidates = (CandidateSet.size() > 1);
@@ -5418,7 +5414,7 @@ static ExprResult CheckConvertedConstant
   //  condition shall be a contextually converted constant expression of type
   //  bool.
   ImplicitConversionSequence ICS =
-      CCE == Sema::CCEK_ConstexprIf || CCE == Sema::CCEK_ExplicitBool
+      CCE == Sema::CCEK_ConstexprIf
           ? TryContextuallyConvertToBool(S, From)
           : TryCopyInitialization(S, From, T,
                                   /*SuppressUserConversions=*/false,
@@ -5734,13 +5730,12 @@ collectViableConversionCandidates(Sema &
 
     if (ConvTemplate)
       SemaRef.AddTemplateConversionCandidate(
-          ConvTemplate, FoundDecl, ActingContext, From, ToType, CandidateSet,
-          /*AllowObjCConversionOnExplicit=*/false, /*AllowExplicit*/ true);
+        ConvTemplate, FoundDecl, ActingContext, From, ToType, CandidateSet,
+        /*AllowObjCConversionOnExplicit=*/false);
     else
       SemaRef.AddConversionCandidate(Conv, FoundDecl, ActingContext, From,
                                      ToType, CandidateSet,
-                                     /*AllowObjCConversionOnExplicit=*/false,
-                                     /*AllowExplicit*/ true);
+                                     /*AllowObjCConversionOnExplicit=*/false);
   }
 }
 
@@ -5992,11 +5987,13 @@ static bool IsAcceptableNonMemberOperato
 /// \param PartialOverloading true if we are performing "partial" overloading
 /// based on an incomplete set of function arguments. This feature is used by
 /// code completion.
-void Sema::AddOverloadCandidate(
-    FunctionDecl *Function, DeclAccessPair FoundDecl, ArrayRef<Expr *> Args,
-    OverloadCandidateSet &CandidateSet, bool SuppressUserConversions,
-    bool PartialOverloading, bool AllowExplicit, bool AllowExplicitConversions,
-    ADLCallKind IsADLCandidate, ConversionSequenceList EarlyConversions) {
+void Sema::AddOverloadCandidate(FunctionDecl *Function,
+                                DeclAccessPair FoundDecl, ArrayRef<Expr *> Args,
+                                OverloadCandidateSet &CandidateSet,
+                                bool SuppressUserConversions,
+                                bool PartialOverloading, bool AllowExplicit,
+                                ADLCallKind IsADLCandidate,
+                                ConversionSequenceList EarlyConversions) {
   const FunctionProtoType *Proto
     = dyn_cast<FunctionProtoType>(Function->getType()->getAs<FunctionType>());
   assert(Proto && "Functions without a prototype cannot be overloaded");
@@ -6153,11 +6150,13 @@ void Sema::AddOverloadCandidate(
       // (13.3.3.1) that converts that argument to the corresponding
       // parameter of F.
       QualType ParamType = Proto->getParamType(ArgIdx);
-      Candidate.Conversions[ArgIdx] = TryCopyInitialization(
-          *this, Args[ArgIdx], ParamType, SuppressUserConversions,
-          /*InOverloadResolution=*/true,
-          /*AllowObjCWritebackConversion=*/
-          getLangOpts().ObjCAutoRefCount, AllowExplicitConversions);
+      Candidate.Conversions[ArgIdx]
+        = TryCopyInitialization(*this, Args[ArgIdx], ParamType,
+                                SuppressUserConversions,
+                                /*InOverloadResolution=*/true,
+                                /*AllowObjCWritebackConversion=*/
+                                  getLangOpts().ObjCAutoRefCount,
+                                AllowExplicit);
       if (Candidate.Conversions[ArgIdx].isBad()) {
         Candidate.Viable = false;
         Candidate.FailureKind = ovl_fail_bad_conversion;
@@ -6171,15 +6170,6 @@ void Sema::AddOverloadCandidate(
     }
   }
 
-  if (!AllowExplicit) {
-    ExplicitSpecifier ES = ExplicitSpecifier::getFromDecl(Function);
-    if (ES.getKind() != ExplicitSpecKind::ResolvedFalse) {
-      Candidate.Viable = false;
-      Candidate.FailureKind = ovl_fail_explicit_resolved;
-      return;
-    }
-  }
-
   if (EnableIfAttr *FailedAttr = CheckEnableIf(Function, Args)) {
     Candidate.Viable = false;
     Candidate.FailureKind = ovl_fail_enable_if;
@@ -6769,7 +6759,7 @@ void Sema::AddTemplateOverloadCandidate(
     FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl,
     TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args,
     OverloadCandidateSet &CandidateSet, bool SuppressUserConversions,
-    bool PartialOverloading, bool AllowExplicit, ADLCallKind IsADLCandidate) {
+    bool PartialOverloading, ADLCallKind IsADLCandidate) {
   if (!CandidateSet.isNewCandidate(FunctionTemplate))
     return;
 
@@ -6818,10 +6808,9 @@ void Sema::AddTemplateOverloadCandidate(
   // Add the function template specialization produced by template argument
   // deduction as a candidate.
   assert(Specialization && "Missing function template specialization?");
-  AddOverloadCandidate(
-      Specialization, FoundDecl, Args, CandidateSet, SuppressUserConversions,
-      PartialOverloading, AllowExplicit,
-      /*AllowExplicitConversions*/ false, IsADLCandidate, Conversions);
+  AddOverloadCandidate(Specialization, FoundDecl, Args, CandidateSet,
+                       SuppressUserConversions, PartialOverloading,
+                       /*AllowExplicit*/ false, IsADLCandidate, Conversions);
 }
 
 /// Check that implicit conversion sequences can be formed for each argument
@@ -6926,11 +6915,14 @@ static bool isAllowableExplicitConversio
 /// and ToType is the type that we're eventually trying to convert to
 /// (which may or may not be the same type as the type that the
 /// conversion function produces).
-void Sema::AddConversionCandidate(
-    CXXConversionDecl *Conversion, DeclAccessPair FoundDecl,
-    CXXRecordDecl *ActingContext, Expr *From, QualType ToType,
-    OverloadCandidateSet &CandidateSet, bool AllowObjCConversionOnExplicit,
-    bool AllowExplicit, bool AllowResultConversion) {
+void
+Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
+                             DeclAccessPair FoundDecl,
+                             CXXRecordDecl *ActingContext,
+                             Expr *From, QualType ToType,
+                             OverloadCandidateSet& CandidateSet,
+                             bool AllowObjCConversionOnExplicit,
+                             bool AllowResultConversion) {
   assert(!Conversion->getDescribedFunctionTemplate() &&
          "Conversion function templates use AddTemplateConversionCandidate");
   QualType ConvType = Conversion->getConversionType().getNonReferenceType();
@@ -7089,13 +7081,6 @@ void Sema::AddConversionCandidate(
            "Can only end up with a standard conversion sequence or failure");
   }
 
-  if (!AllowExplicit && Conversion->getExplicitSpecifier().getKind() !=
-                            ExplicitSpecKind::ResolvedFalse) {
-    Candidate.Viable = false;
-    Candidate.FailureKind = ovl_fail_explicit_resolved;
-    return;
-  }
-
   if (EnableIfAttr *FailedAttr = CheckEnableIf(Conversion, None)) {
     Candidate.Viable = false;
     Candidate.FailureKind = ovl_fail_enable_if;
@@ -7115,11 +7100,14 @@ void Sema::AddConversionCandidate(
 /// to deduce the template arguments of the conversion function
 /// template from the type that we are converting to (C++
 /// [temp.deduct.conv]).
-void Sema::AddTemplateConversionCandidate(
-    FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl,
-    CXXRecordDecl *ActingDC, Expr *From, QualType ToType,
-    OverloadCandidateSet &CandidateSet, bool AllowObjCConversionOnExplicit,
-    bool AllowExplicit, bool AllowResultConversion) {
+void
+Sema::AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
+                                     DeclAccessPair FoundDecl,
+                                     CXXRecordDecl *ActingDC,
+                                     Expr *From, QualType ToType,
+                                     OverloadCandidateSet &CandidateSet,
+                                     bool AllowObjCConversionOnExplicit,
+                                     bool AllowResultConversion) {
   assert(isa<CXXConversionDecl>(FunctionTemplate->getTemplatedDecl()) &&
          "Only conversion function templates permitted here");
 
@@ -7149,7 +7137,7 @@ void Sema::AddTemplateConversionCandidat
   assert(Specialization && "Missing function template specialization?");
   AddConversionCandidate(Specialization, FoundDecl, ActingDC, From, ToType,
                          CandidateSet, AllowObjCConversionOnExplicit,
-                         AllowExplicit, AllowResultConversion);
+                         AllowResultConversion);
 }
 
 /// AddSurrogateCandidate - Adds a "surrogate" candidate function that
@@ -9003,14 +8991,12 @@ Sema::AddArgumentDependentLookupCandidat
 
       AddOverloadCandidate(FD, FoundDecl, Args, CandidateSet,
                            /*SupressUserConversions=*/false, PartialOverloading,
-                           /*AllowExplicitConversions*/ false,
-                           /*AllowExplicit*/ false, ADLCallKind::UsesADL);
+                           /*AllowExplicit=*/false, ADLCallKind::UsesADL);
     } else {
-      AddTemplateOverloadCandidate(
-          cast<FunctionTemplateDecl>(*I), FoundDecl, ExplicitTemplateArgs, Args,
-          CandidateSet,
-          /*SupressUserConversions=*/false, PartialOverloading,
-          /*AllowExplicit*/ false, ADLCallKind::UsesADL);
+      AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*I), FoundDecl,
+                                   ExplicitTemplateArgs, Args, CandidateSet,
+                                   /*SupressUserConversions=*/false,
+                                   PartialOverloading, ADLCallKind::UsesADL);
     }
   }
 }
@@ -10341,33 +10327,6 @@ static void DiagnoseFailedEnableIfAttr(S
       << Attr->getCond()->getSourceRange() << Attr->getMessage();
 }
 
-static void DiagnoseFailedExplicitSpec(Sema &S, OverloadCandidate *Cand) {
-  ExplicitSpecifier ES;
-  const char *DeclName;
-  switch (Cand->Function->getDeclKind()) {
-  case Decl::Kind::CXXConstructor:
-    ES = cast<CXXConstructorDecl>(Cand->Function)->getExplicitSpecifier();
-    DeclName = "constructor";
-    break;
-  case Decl::Kind::CXXConversion:
-    ES = cast<CXXConversionDecl>(Cand->Function)->getExplicitSpecifier();
-    DeclName = "conversion operator";
-    break;
-  case Decl::Kind::CXXDeductionGuide:
-    ES = cast<CXXDeductionGuideDecl>(Cand->Function)->getExplicitSpecifier();
-    DeclName = "deductiong guide";
-    break;
-  default:
-    llvm_unreachable("invalid Decl");
-  }
-  assert(ES.getExpr() && "null expression should be handled before");
-  S.Diag(Cand->Function->getLocation(),
-         diag::note_ovl_candidate_explicit_forbidden)
-      << DeclName;
-  S.Diag(ES.getExpr()->getBeginLoc(),
-         diag::note_explicit_bool_resolved_to_true);
-}
-
 static void DiagnoseOpenCLExtensionDisabled(Sema &S, OverloadCandidate *Cand) {
   FunctionDecl *Callee = Cand->Function;
 
@@ -10452,9 +10411,6 @@ static void NoteFunctionCandidate(Sema &
   case ovl_fail_enable_if:
     return DiagnoseFailedEnableIfAttr(S, Cand);
 
-  case ovl_fail_explicit_resolved:
-    return DiagnoseFailedExplicitSpec(S, Cand);
-
   case ovl_fail_ext_disabled:
     return DiagnoseOpenCLExtensionDisabled(S, Cand);
 
@@ -13025,11 +12981,8 @@ Sema::BuildCallToMemberFunction(Scope *S
 
       // Microsoft supports direct constructor calls.
       if (getLangOpts().MicrosoftExt && isa<CXXConstructorDecl>(Func)) {
-        AddOverloadCandidate(cast<CXXConstructorDecl>(Func), I.getPair(), Args,
-                             CandidateSet,
-                             /*SuppressUserConversions*/ false,
-                             /*PartialOverloading*/ false,
-                             /*AllowExplicit*/ true);
+        AddOverloadCandidate(cast<CXXConstructorDecl>(Func), I.getPair(),
+                             Args, CandidateSet);
       } else if ((Method = dyn_cast<CXXMethodDecl>(Func))) {
         // If explicit template arguments were provided, we can't call a
         // non-template member function.

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon May  6 02:51:10 2019
@@ -1109,7 +1109,7 @@ NamedDecl *Sema::ActOnNonTypeTemplatePar
     if (DS.isVirtualSpecified())
       EmitDiag(DS.getVirtualSpecLoc());
 
-    if (DS.hasExplicitSpecifier())
+    if (DS.isExplicitSpecified())
       EmitDiag(DS.getExplicitSpecLoc());
 
     if (DS.isNoreturnSpecified())
@@ -1789,8 +1789,8 @@ struct ConvertConstructorToDeductionGuid
       return nullptr;
     TypeSourceInfo *NewTInfo = TLB.getTypeSourceInfo(SemaRef.Context, NewType);
 
-    return buildDeductionGuide(TemplateParams, CD->getExplicitSpecifier(),
-                               NewTInfo, CD->getBeginLoc(), CD->getLocation(),
+    return buildDeductionGuide(TemplateParams, CD->isExplicit(), NewTInfo,
+                               CD->getBeginLoc(), CD->getLocation(),
                                CD->getEndLoc());
   }
 
@@ -1819,8 +1819,8 @@ struct ConvertConstructorToDeductionGuid
       Params.push_back(NewParam);
     }
 
-    return buildDeductionGuide(Template->getTemplateParameters(),
-                               ExplicitSpecifier(), TSI, Loc, Loc, Loc);
+    return buildDeductionGuide(Template->getTemplateParameters(), false, TSI,
+                               Loc, Loc, Loc);
   }
 
 private:
@@ -1970,7 +1970,7 @@ private:
   }
 
   NamedDecl *buildDeductionGuide(TemplateParameterList *TemplateParams,
-                                 ExplicitSpecifier ES, TypeSourceInfo *TInfo,
+                                 bool Explicit, TypeSourceInfo *TInfo,
                                  SourceLocation LocStart, SourceLocation Loc,
                                  SourceLocation LocEnd) {
     DeclarationNameInfo Name(DeductionGuideName, Loc);
@@ -1979,8 +1979,8 @@ private:
 
     // Build the implicit deduction guide template.
     auto *Guide =
-        CXXDeductionGuideDecl::Create(SemaRef.Context, DC, LocStart, ES, Name,
-                                      TInfo->getType(), TInfo, LocEnd);
+        CXXDeductionGuideDecl::Create(SemaRef.Context, DC, LocStart, Explicit,
+                                      Name, TInfo->getType(), TInfo, LocEnd);
     Guide->setImplicit();
     Guide->setParams(Params);
 

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon May  6 02:51:10 2019
@@ -366,29 +366,6 @@ static void instantiateDependentAMDGPUFl
                                    Attr.getSpellingListIndex());
 }
 
-static ExplicitSpecifier
-instantiateExplicitSpecifier(Sema &S,
-                             const MultiLevelTemplateArgumentList &TemplateArgs,
-                             ExplicitSpecifier ES, FunctionDecl *New) {
-  if (!ES.getExpr())
-    return ES;
-  Expr *OldCond = ES.getExpr();
-  Expr *Cond = nullptr;
-  {
-    EnterExpressionEvaluationContext Unevaluated(
-        S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
-    ExprResult SubstResult = S.SubstExpr(OldCond, TemplateArgs);
-    if (SubstResult.isInvalid()) {
-      return ExplicitSpecifier::Invalid();
-    }
-    Cond = SubstResult.get();
-  }
-  ExplicitSpecifier Result(Cond, ES.getKind());
-  if (!Cond->isTypeDependent())
-    S.tryResolveExplicitSpecifier(Result);
-  return Result;
-}
-
 static void instantiateDependentAMDGPUWavesPerEUAttr(
     Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
     const AMDGPUWavesPerEUAttr &Attr, Decl *New) {
@@ -1713,14 +1690,6 @@ Decl *TemplateDeclInstantiator::VisitFun
       cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod());
   LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
 
-  ExplicitSpecifier InstantiatedExplicitSpecifier;
-  if (auto *DGuide = dyn_cast<CXXDeductionGuideDecl>(D)) {
-    InstantiatedExplicitSpecifier = instantiateExplicitSpecifier(
-        SemaRef, TemplateArgs, DGuide->getExplicitSpecifier(), DGuide);
-    if (InstantiatedExplicitSpecifier.isInvalid())
-      return nullptr;
-  }
-
   SmallVector<ParmVarDecl *, 4> Params;
   TypeSourceInfo *TInfo = SubstFunctionType(D, Params);
   if (!TInfo)
@@ -1758,9 +1727,8 @@ Decl *TemplateDeclInstantiator::VisitFun
   FunctionDecl *Function;
   if (auto *DGuide = dyn_cast<CXXDeductionGuideDecl>(D)) {
     Function = CXXDeductionGuideDecl::Create(
-        SemaRef.Context, DC, D->getInnerLocStart(),
-        InstantiatedExplicitSpecifier, NameInfo, T, TInfo,
-        D->getSourceRange().getEnd());
+      SemaRef.Context, DC, D->getInnerLocStart(), DGuide->isExplicit(),
+      NameInfo, T, TInfo, D->getSourceRange().getEnd());
     if (DGuide->isCopyDeductionCandidate())
       cast<CXXDeductionGuideDecl>(Function)->setIsCopyDeductionCandidate();
     Function->setAccess(D->getAccess());
@@ -2028,12 +1996,6 @@ Decl *TemplateDeclInstantiator::VisitCXX
     }
   }
 
-  ExplicitSpecifier InstantiatedExplicitSpecifier =
-      instantiateExplicitSpecifier(SemaRef, TemplateArgs,
-                                   ExplicitSpecifier::getFromDecl(D), D);
-  if (InstantiatedExplicitSpecifier.isInvalid())
-    return nullptr;
-
   SmallVector<ParmVarDecl *, 4> Params;
   TypeSourceInfo *TInfo = SubstFunctionType(D, Params);
   if (!TInfo)
@@ -2073,10 +2035,11 @@ Decl *TemplateDeclInstantiator::VisitCXX
   DeclarationNameInfo NameInfo
     = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
   if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
-    Method = CXXConstructorDecl::Create(
-        SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo,
-        InstantiatedExplicitSpecifier, Constructor->isInlineSpecified(), false,
-        Constructor->isConstexpr());
+    Method = CXXConstructorDecl::Create(SemaRef.Context, Record,
+                                        StartLoc, NameInfo, T, TInfo,
+                                        Constructor->isExplicit(),
+                                        Constructor->isInlineSpecified(),
+                                        false, Constructor->isConstexpr());
     Method->setRangeEnd(Constructor->getEndLoc());
   } else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
     Method = CXXDestructorDecl::Create(SemaRef.Context, Record,
@@ -2087,7 +2050,7 @@ Decl *TemplateDeclInstantiator::VisitCXX
   } else if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(D)) {
     Method = CXXConversionDecl::Create(
         SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo,
-        Conversion->isInlineSpecified(), InstantiatedExplicitSpecifier,
+        Conversion->isInlineSpecified(), Conversion->isExplicit(),
         Conversion->isConstexpr(), Conversion->getEndLoc());
   } else {
     StorageClass SC = D->isStatic() ? SC_Static : SC_None;

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Mon May  6 02:51:10 2019
@@ -858,6 +858,7 @@ void ASTDeclReader::VisitFunctionDecl(Fu
   FD->setStorageClass(static_cast<StorageClass>(Record.readInt()));
   FD->setInlineSpecified(Record.readInt());
   FD->setImplicitlyInline(Record.readInt());
+  FD->setExplicitSpecified(Record.readInt());
   FD->setVirtualAsWritten(Record.readInt());
   FD->setPure(Record.readInt());
   FD->setHasInheritedPrototype(Record.readInt());
@@ -1976,7 +1977,6 @@ ASTDeclReader::VisitCXXRecordDeclImpl(CX
 }
 
 void ASTDeclReader::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
-  D->setExplicitSpecifier(Record.readExplicitSpec());
   VisitFunctionDecl(D);
   D->setIsCopyDeductionCandidate(Record.readInt());
 }
@@ -2002,7 +2002,6 @@ 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.
-  D->setExplicitSpecifier(Record.readExplicitSpec());
   if (D->isInheritingConstructor()) {
     auto *Shadow = ReadDeclAs<ConstructorUsingShadowDecl>();
     auto *Ctor = ReadDeclAs<CXXConstructorDecl>();
@@ -2028,7 +2027,6 @@ void ASTDeclReader::VisitCXXDestructorDe
 }
 
 void ASTDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) {
-  D->setExplicitSpecifier(Record.readExplicitSpec());
   VisitCXXMethodDecl(D);
 }
 
@@ -3752,7 +3750,10 @@ Decl *ASTReader::ReadDeclRecord(DeclID I
     D = CXXMethodDecl::CreateDeserialized(Context, ID);
     break;
   case DECL_CXX_CONSTRUCTOR:
-    D = CXXConstructorDecl::CreateDeserialized(Context, ID, Record.readInt());
+    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/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon May  6 02:51:10 2019
@@ -1266,6 +1266,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=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Mon May  6 02:51:10 2019
@@ -535,6 +535,7 @@ void ASTDeclWriter::VisitFunctionDecl(Fu
   Record.push_back(static_cast<int>(D->getStorageClass())); // FIXME: stable encoding
   Record.push_back(D->isInlineSpecified());
   Record.push_back(D->isInlined());
+  Record.push_back(D->isExplicitSpecified());
   Record.push_back(D->isVirtualAsWritten());
   Record.push_back(D->isPure());
   Record.push_back(D->hasInheritedPrototype());
@@ -637,18 +638,7 @@ void ASTDeclWriter::VisitFunctionDecl(Fu
   Code = serialization::DECL_FUNCTION;
 }
 
-static void addExplicitSpecifier(ExplicitSpecifier ES,
-                                 ASTRecordWriter &Record) {
-  uint64_t Kind = static_cast<uint64_t>(ES.getKind());
-  Kind = Kind << 1 | static_cast<bool>(ES.getExpr());
-  Record.push_back(Kind);
-  if (ES.getExpr()) {
-    Record.AddStmt(ES.getExpr());
-  }
-}
-
 void ASTDeclWriter::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
-  addExplicitSpecifier(D->getExplicitSpecifier(), Record);
   VisitFunctionDecl(D);
   Record.push_back(D->isCopyDeductionCandidate());
   Code = serialization::DECL_CXX_DEDUCTION_GUIDE;
@@ -1341,15 +1331,19 @@ void ASTDeclWriter::VisitCXXMethodDecl(C
 }
 
 void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
-  Record.push_back(D->getTraillingAllocKind());
-  addExplicitSpecifier(D->getExplicitSpecifier(), Record);
   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);
-  Code = serialization::DECL_CXX_CONSTRUCTOR;
+
+  Code = D->isInheritingConstructor()
+             ? serialization::DECL_CXX_INHERITED_CONSTRUCTOR
+             : serialization::DECL_CXX_CONSTRUCTOR;
 }
 
 void ASTDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
@@ -1363,7 +1357,6 @@ void ASTDeclWriter::VisitCXXDestructorDe
 }
 
 void ASTDeclWriter::VisitCXXConversionDecl(CXXConversionDecl *D) {
-  addExplicitSpecifier(D->getExplicitSpecifier(), Record);
   VisitCXXMethodDecl(D);
   Code = serialization::DECL_CXX_CONVERSION;
 }
@@ -2163,6 +2156,7 @@ void ASTWriter::WriteDeclAbbrevs() {
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // StorageClass
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Inline
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InlineSpecified
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ExplicitSpecified
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // VirtualAsWritten
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Pure
   Abv->Add(BitCodeAbbrevOp(0));                         // HasInheritedProto

Modified: cfe/trunk/test/CXX/temp/temp.deduct.guide/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.deduct.guide/p1.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.deduct.guide/p1.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.deduct.guide/p1.cpp Mon May  6 02:51:10 2019
@@ -71,7 +71,7 @@ extern A(int(&)[26]) -> A<int>;
 #endif
 mutable A(int(&)[27]) -> A<int>; // expected-error-re {{{{'mutable' cannot be applied to|illegal storage class on}} function}}
 virtual A(int(&)[28]) -> A<int>; // expected-error {{'virtual' can only appear on non-static member functions}}
-const A(int(&)[31]) -> A<int>; // expected-error {{deduction guide cannot be declared 'const'}}
+const A(int(&)[28]) -> A<int>; // expected-error {{deduction guide cannot be declared 'const'}}
 
 const volatile static constexpr inline A(int(&)[29]) -> A<int>; // expected-error {{deduction guide cannot be declared 'static inline constexpr const volatile'}}
 

Modified: cfe/trunk/test/CXX/temp/temp.deduct.guide/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.deduct.guide/p3.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.deduct.guide/p3.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.deduct.guide/p3.cpp Mon May  6 02:51:10 2019
@@ -3,14 +3,14 @@
 // The same restrictions apply to the parameter-declaration-clause of a
 // deduction guide as in a function declaration.
 template<typename T> struct A {};
-A(void) -> A<int>; // expected-note {{previous}}
+A(void) -> A<int>; // ok
 A(void, int) -> A<int>; // expected-error {{'void' must be the first and only parameter if specified}}
 
-A() -> A<int>; // expected-error {{redeclaration of deduction guide}}
-// expected-note at -1 {{previous}}
+// We interpret this as also extending to the validity of redeclarations. It's
+// a bit of a stretch (OK, a lot of a stretch) but it gives desirable answers.
+A() -> A<int>; // ok, redeclaration
 
 A() -> A<int>; // expected-note {{previous}}
-// expected-error at -1 {{redeclaration of deduction guide}}
 A() -> A<float>; // FIXME: "functions" is a poor term. expected-error {{functions that differ only in their return type cannot be overloaded}}
 
 template<typename T> A(T) -> A<typename T::foo>;

Removed: cfe/trunk/test/PCH/cxx-explicit-specifier.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-explicit-specifier.cpp?rev=360023&view=auto
==============================================================================
--- cfe/trunk/test/PCH/cxx-explicit-specifier.cpp (original)
+++ cfe/trunk/test/PCH/cxx-explicit-specifier.cpp (removed)
@@ -1,124 +0,0 @@
-// RUN: %clang_cc1 -std=c++2a -emit-pch %s -o %t-cxx2a
-// RUN: %clang_cc1 -std=c++2a -DUSE_PCH -include-pch %t-cxx2a %s -ast-print -verify | FileCheck %s
-
-#ifndef USE_PCH
-namespace inheriting_constructor {
-  struct S {};
-
-  template<typename X, typename Y> struct T {
-    template<typename A>
-    explicit((Y{}, true)) T(A &&a) {}
-  };
-
-  template<typename X, typename Y> struct U : T<X, Y> {
-    using T<X, Y>::T;
-  };
-
-  U<S, char> foo(char ch) {
-    return U<S, char>(ch);
-  }
-}
-#else
-namespace inheriting_constructor {
-U<S, char> a = foo('0');
-}
-
-//CHECK: explicit((char{} , true))
-
-#endif
-
-namespace basic {
-#ifndef USE_PCH
-
-struct B {};
-
-struct A {
-  explicit A(int);
-  explicit(false) operator bool();
-  explicit(true) operator B();
-};
-#else
-//expected-note at -6+ {{candidate constructor}}
-//expected-note at -9+ {{candidate constructor}}
-//expected-note at -6+ {{candidate function}}
-
-//CHECK: explicit{{ +}}A(
-//CHECK-NEXT: explicit(false){{ +}}operator
-//CHECK-NEXT: explicit(true){{ +}}operator
-A a = 0; //expected-error {{no viable conversion}}
-A a1(0);
-
-bool b = a1;
-B b1 = a1; //expected-error {{no viable conversion}}
-
-#endif
-}
-
-
-namespace templ {
-#ifndef USE_PCH
-
-template<bool b>
-struct B {
-  static constexpr bool value = b;
-};
-
-template<bool b>
-struct A {
-  explicit(b) A(B<b>) {}
-  template<typename T>
-  explicit(b ^ T::value) operator T();
-};
-B<true> b_true;
-B<false> b_false;
-#else
-//expected-note at -8 {{candidate template ignored}}
-//expected-note at -8+ {{explicit constructor}}
-//expected-note at -15+ {{candidate constructor}}
-//expected-note at -8+ {{candidate conversion operator ignored}}
-//expected-note at -9+ {{explicit(bool) specifier resolved to true}}
-//expected-note at -12 {{explicit(bool) specifier resolved to true}}
-//expected-note at -13+ {{candidate deductiong guide ignored}}
-
-//CHECK: explicit(b){{ +}}A
-//CHECK: explicit(b{{ +}}^{{ +}}T::value){{ +}}operator
-
-A a = { b_true }; //expected-error {{class template argument deduction}}
-A a0 = b_true; //expected-error {{no viable constructor or deduction guide}}
-A a_true(b_true);
-A a_false = b_false;
-
-B<true> b = a_true;
-B<true> b1 = a_false; //expected-error {{no viable conversion}}
-B<false> b2(a_true);
-
-#endif
-
-}
-
-namespace guide {
-
-#ifndef USE_PCH
-
-template<typename T>
-struct A {
-  A(T);
-};
-
-template<typename T>
-explicit(true) A(T) -> A<T>;
-
-explicit(false) A(int) -> A<int>;
-
-#else
-//expected-note at -5 {{explicit deduction guide}}
-
-//CHECK: explicit(true){{ +}}A(
-//CHECK: explicit(false){{ +}}A(
-
-A a = { 0.0 }; //expected-error {{explicit deduction guide}}
-A a1 = { 0 };
-
-#endif
-
-}

Modified: cfe/trunk/test/SemaCXX/builtin-is-constant-evaluated.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/builtin-is-constant-evaluated.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/builtin-is-constant-evaluated.cpp (original)
+++ cfe/trunk/test/SemaCXX/builtin-is-constant-evaluated.cpp Mon May  6 02:51:10 2019
@@ -115,7 +115,7 @@ static_assert(&r == &x);
 
 #if defined(__cpp_conditional_explicit)
 struct TestConditionalExplicit {
-  explicit(!__builtin_is_constant_evaluated()) TestConditionalExplicit(int) {}
+  explicit(__builtin_is_constant_evaluated()) TestConditionalExplicit(int) {}
 };
 TestConditionalExplicit e = 42;
 #endif

Modified: cfe/trunk/test/SemaCXX/cxx2a-compat.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx2a-compat.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx2a-compat.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx2a-compat.cpp Mon May  6 02:51:10 2019
@@ -37,23 +37,3 @@ string u8str = u8"test" u8"test";
 // expected-error at -8 {{cannot initialize a variable of type 'const char *' with an lvalue of type 'const char8_t [6]'}}
 // expected-error at -8 {{no viable conversion from 'const char8_t [9]' to 'string'}}
 #endif
-
-template<bool b>
-struct C {
-  explicit(C)(int);
-};
-#if __cplusplus <= 201703L
-// expected-warning at -3 {{this expression will be parsed as explicit(bool) in C++2a}}
-#if defined(__cpp_conditional_explicit)
-#error "the feature test macro __cpp_conditional_explicit isn't correct"
-#endif
-#else
-// expected-error at -8 {{does not refer to a value}}
-// expected-error at -9 {{expected member name or ';'}}
-// expected-error at -10 {{expected ')'}}
-// expected-note at -12 {{declared here}}
-// expected-note at -12 {{to match this '('}}
-#if !defined(__cpp_conditional_explicit) || __cpp_conditional_explicit != 201806L
-#error "the feature test macro __cpp_conditional_explicit isn't correct"
-#endif
-#endif
\ No newline at end of file

Removed: cfe/trunk/test/SemaCXX/cxx2a-explicit-bool.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx2a-explicit-bool.cpp?rev=360023&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx2a-explicit-bool.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx2a-explicit-bool.cpp (removed)
@@ -1,719 +0,0 @@
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
-
-template <bool b, auto val> struct enable_ifv {};
-
-template <auto val> struct enable_ifv<true, val> {
-  static constexpr auto value = val;
-};
-
-template <typename T1, typename T2> struct is_same {
-  static constexpr bool value = false;
-};
-
-template <typename T> struct is_same<T, T> {
-  static constexpr bool value = true;
-};
-
-namespace special_cases
-{
-
-template<int a>
-struct A {
-// expected-note at -1+ {{candidate constructor}}
-  explicit(1 << a)
-// expected-note at -1 {{negative shift count -1}}
-// expected-error at -2 {{explicit specifier argument is not a constant expression}}
-  A(int);
-};
-
-A<-1> a(0);
-// expected-error at -1 {{no matching constructor}}
-// expected-note at -2 {{in instantiation of template class}}
-
-template<int a>
-struct B {
-  explicit(b)
-  // expected-error at -1 {{use of undeclared identifier}}
-  B(int);
-};
-
-template<int a>
-struct B1 {
-  explicit(a +)
-  // expected-error at -1 {{expected expression}}
-  B1(int);
-};
-
-struct B2 {
-  explicit(false) explicit
-  B2(int);
-  // expected-error at -2 {{duplicate 'explicit' declaration specifier}}
-};
-
-template<int a>
-  struct C {
-  // expected-note at -1 {{candidate constructor}} expected-note at -1 {{candidate constructor}}
-  // expected-note at -2 {{candidate constructor}} expected-note at -2 {{candidate constructor}}
-  explicit(a == 0)
-C(int),
-C(double);
-};
-
-C<0> c0 = 0.0; // expected-error {{no viable conversion}}
-C<0> c1 = 0; // expected-error {{no viable conversion}}
-C<1> c2 = 0.0;
-C<1> c3 = 0;
-
-explicit(false) void f(int);// expected-error {{'explicit' can only be specified inside the class definition}}
-
-struct D {
-  explicit(false) void f(int);// expected-error {{'explicit' can only be applied to a constructor or conversion function}}
-};
-
-template <typename T> struct E {
-  // expected-note at -1+ {{candidate constructor}}
-  explicit((T{}, false))
-  // expected-error at -1 {{illegal initializer type 'void'}}
-  E(int);
-};
-
-E<void> e = 1;
-// expected-error at -1 {{no viable conversion}}
-// expected-note at -2 {{in instantiation of}}
-
-}
-
-namespace trailling_object {
-
-template<bool b>
-struct B {
-  explicit(b) B(int) {}
-};
-
-template<bool b>
-struct A : B<b> {
-  explicit(b) A(int) : B<b>(0) {}
-};
-
-A<true> a(0);
-
-}
-
-namespace constructor1 {
-
-template<bool b>
-  struct A {
-    // expected-note at -1+ {{candidate constructor}}
-    // expected-note at -2+ {{candidate function}}
-    explicit(b) A(int, int = 0);
-  // expected-note at -1+ {{explicit constructor declared here}}
-};
-
-template<bool b>
-A<b>::A(int, int) {}
-
-void f()
-{
-A<true> a0 = 0; // expected-error {{no viable conversion}}
-A<true> a1( 0);
-A<true> && a2 = 0;// expected-error {{could not bind}}
-A<true> && a3( 0);// expected-error {{could not bind}}
-A<true> a4{ 0};
-A<true> && a5 = { 0};// expected-error {{chosen constructor is explicit}}
-A<true> && a6{ 0};
-A<true> a7 = { 0}; // expected-error {{chosen constructor is explicit in copy-initialization}}
-
-a0 = 0;
-a1 = { 0}; // expected-error {{no viable overloaded '='}}
-a2 = A<true>( 0);
-a3 = A<true>{ 0};
-
-A<false> c0 =  ((short)0);
-A<false> c1( ((short)0));
-A<false> && c2 =  ((short)0);
-A<false> && c3( ((short)0));
-A<false> c4{ ((short)0)};
-A<false> && c5 = { ((short)0)};
-A<false> && c6{ ((short)0)};
-
-A<true> d1( 0, 0);
-A<true> d2{ 0, 0};
-A<true> d3 = { 0, 0}; // expected-error {{chosen constructor is explicit in copy-initialization}}
-
-d1 = { 0, 0}; // expected-error {{no viable overloaded '='}}
-d2 = A<true>( 0, 0);
-d3 = A<true>{ 0, 0};
-}
-}
-
-namespace constructor2 {
-
-template<bool a, typename T1>
-struct A {
-  // expected-note at -1 {{candidate constructor}} expected-note at -1 {{candidate constructor}}
-  // expected-note at -2 {{candidate constructor}} expected-note at -2 {{candidate constructor}}
-  template<typename T2>
-  explicit(a ^ is_same<T1, T2>::value)
-  // expected-note at -1+ {{explicit(bool) specifier resolved to true}}
-  A(T2) {}
-  // expected-note at -1+ {{explicit constructor declared here}}
-  // expected-note at -2+ {{candidate constructor ignored}}
-};
-
-A<true, int> a0 = 0.0; // expected-error {{no viable conversion}}
-A<true, int> a1( 0.0);
-A<true, int> && a2 = 0.0;// expected-error {{could not bind}}
-A<true, int> && a3( 0.0);// expected-error {{could not bind}}
-A<true, int> a4{ 0.0};
-A<true, int> && a5 = { 0.0};// expected-error {{chosen constructor is explicit}}
-A<true, int> && a6{ 0.0};
-A<true, int> a7 = { 0.0}; // expected-error {{chosen constructor is explicit in copy-initialization}}
-
-A<true, int> b0 = 0;
-A<true, int> b1( 0);
-A<true, int> && b2 = 0;
-A<true, int> && b3( 0);
-A<true, int> b4{ 0};
-A<true, int> && b5 = { 0};
-A<true, int> && b6{ 0};
-A<true, int> b7 = { 0};
-
-A<true, double> c0 = 0; // expected-error {{no viable conversion}}
-A<true, double> c1( 0);
-A<true, double> && c2 = 0;// expected-error {{could not bind}}
-A<true, double> && c3( 0);// expected-error {{could not bind}}
-A<true, double> c4{ 0};
-A<true, double> && c5 = { 0};// expected-error {{chosen constructor is explicit}}
-A<true, double> && c6{ 0};
-A<true, double> c7 = { 0}; // expected-error {{chosen constructor is explicit in copy-initialization}}
-
-}
-
-namespace constructor_sfinae {
-
-template<bool a>
-struct A {
-  // expected-note at -1+ {{candidate constructor}}
-  template<typename T>
-  explicit(enable_ifv<is_same<int, T>::value, a>::value)
-  //expected-note at -1 {{explicit(bool) specifier resolved to true}}
-  A(T) {}
-  // expected-note at -1+ {{substitution failure}}
-  // expected-note at -2 {{candidate constructor ignored}}
-  // expected-note at -3 {{explicit constructor declared here}}
-  template<typename T, bool c = true>
-  explicit(enable_ifv<is_same<bool, T>::value, a>::value)
-  //expected-note at -1 {{explicit(bool) specifier resolved to true}}
-  A(T) {}
-  // expected-note at -1+ {{substitution failure}}
-  // expected-note at -2 {{candidate constructor ignored}}
-  // expected-note at -3 {{explicit constructor declared here}}
-};
-
-A<true> a0 = 0.0; // expected-error {{no viable conversion}}
-A<true> a1( 0.0); // expected-error {{no matching constructor}}
-A<true> a4{ 0.0}; // expected-error {{no matching constructor}}
-A<true> a7 = { 0.0}; // expected-error {{no matching constructor}}
-
-A<true> b0 = 0; // expected-error {{no viable conversion}}
-A<true> b1( 0);
-A<true> b4{ 0};
-A<true> b7 = { 0}; // expected-error {{chosen constructor is explicit}}
-
-A<false> c0 = 0;
-A<false> c1( 0);
-A<false> c4{ 0};
-A<false> c7 = { 0};
-
-A<true> d0 = true; // expected-error {{no viable conversion}}
-A<true> d1( true);
-A<true> d4{ true};
-A<true> d7 = { true}; // expected-error {{chosen constructor is explicit}}
-
-}
-
-namespace conversion {
-
-template<bool a>
-struct A {
-  explicit(a) operator int ();
-};
-
-template<bool a>
-A<a>::operator int() {
-  return 0;
-}
-
-A<true> A_true;
-A<false> A_false;
-
-int ai0 = A<true>(); // expected-error {{no viable conversion}}
-const int& ai1 = A<true>(); // expected-error {{no viable conversion}}
-int&& ai3 = A<true>(); // expected-error {{no viable conversion}}
-int ai4 = A_true; // expected-error {{no viable conversion}}
-const int& ai5 = A_true; // expected-error {{no viable conversion}}
-
-int ai01 = {A<true>()}; // expected-error {{no viable conversion}}
-const int& ai11 = {A<true>()}; // expected-error {{no viable conversion}}
-int&& ai31 = {A<true>()}; // expected-error {{no viable conversion}}
-int ai41 = {A_true}; // expected-error {{no viable conversion}}
-const int& ai51 = {A_true}; // expected-error {{no viable conversion}}
-
-int ae0(A<true>());
-const int& ae1(A<true>());
-int&& ae3(A<true>());
-int ae4(A_true);
-const int& ae5(A_true);
-
-int bi0 = A<false>();
-const int& bi1 = A<false>();
-int&& bi3 = A<false>();
-int bi4 = A_false;
-const int& bi5 = A_false;
-
-int bi01 = {A<false>()};
-const int& bi11 = {A<false>()};
-int&& bi31 = {A<false>()};
-int bi41 = {A_false};
-const int& bi51 = {A_false};
-
-int be0(A<true>());
-const int& be1(A<true>());
-int&& be3(A<true>());
-int be4(A_true);
-const int& be5(A_true);
-
-}
-
-namespace conversion2 {
-
-struct B {};
-// expected-note at -1+ {{candidate constructor}}
-template<bool a>
-struct A {
-  template<typename T2>
-  explicit(enable_ifv<is_same<B, T2>::value, a>::value)
-  // expected-note at -1+ {{explicit(bool) specifier resolved to true}}
-  operator T2() { return T2(); };
-  // expected-note at -1+ {{substitution failure}}
-  // expected-note at -2+ {{candidate conversion}}
-};
-
-A<false> A_false;
-A<true> A_true;
-
-int ai0 = A<true>(); // expected-error {{no viable conversion}}
-const int& ai1 = A<true>(); // expected-error {{no viable conversion}}
-int&& ai3 = A<true>(); // expected-error {{no viable conversion}}
-int ai4 = A_false; // expected-error {{no viable conversion}}
-const int& ai5 = A_false; // expected-error {{no viable conversion}}
-
-int ae0{A<true>()};  // expected-error {{no viable conversion}}
-const int& ae1{A<true>()};  // expected-error {{no viable conversion}}
-int&& ae3{A<true>()};  // expected-error {{no viable conversion}}
-int ae4{A_true};  // expected-error {{no viable conversion}}
-const int& ae5{A_true};  // expected-error {{no viable conversion}}
-
-int ap0((A<true>()));  // expected-error {{no viable conversion}}
-const int& ap1((A<true>()));  // expected-error {{no viable conversion}}
-int&& ap3((A<true>()));  // expected-error {{no viable conversion}}
-int ap4(A_true);  // expected-error {{no viable conversion}}
-const int& ap5(A_true);  // expected-error {{no viable conversion}}
-
-B b0 = A<true>(); // expected-error {{no viable conversion}}
-const B & b1 = A<true>(); // expected-error {{no viable conversion}}
-B && b3 = A<true>(); // expected-error {{no viable conversion}}
-B b4 = A_true; // expected-error {{no viable conversion}}
-const B & b5 = A_true; // expected-error {{no viable conversion}}
-
-B be0(A<true>());
-const B& be1(A<true>());
-B&& be3(A<true>());
-B be4(A_true);
-const B& be5(A_true);
-
-B c0 = A<false>();
-const B & c1 = A<false>();
-B && c3 = A<false>();
-B c4 = A_false;
-const B & c5 = A_false;
-
-}
-
-namespace parameter_pack {
-
-template<typename T>
-struct A {
-  // expected-note at -1+ {{candidate constructor}}
-  // expected-note at -2+ {{candidate function}}
-  template<typename ... Ts>
-  explicit((is_same<T, Ts>::value && ...))
-  // expected-note at -1 {{explicit(bool) specifier resolved to true}}
-  A(Ts...);
-  // expected-note at -1 {{candidate constructor}}
-  // expected-note at -2 {{explicit constructor}}
-};
-
-template<typename T>
-template<typename ... Ts>
-A<T>::A(Ts ...) {}
-
-void f() {
-
-A<int> a0 = 0; // expected-error {{no viable conversion}}
-A<int> a1( 0, 1);
-A<int> a2{ 0, 1};
-A<int> a3 = { 0, 1}; // expected-error {{chosen constructor is explicit}}
-
-a1 = 0; // expected-error {{no viable overloaded '='}}
-a2 = { 0, 1}; // expected-error {{no viable overloaded '='}}
-
-A<double> b0 = 0;
-A<double> b1( 0, 1);
-A<double> b2{ 0, 1};
-A<double> b3 = { 0, 1};
-
-b1 = 0;
-b2 = { 0, 1};
-
-}
-
-}
-
-namespace deduction_guide {
-
-template<bool b>
-struct B {};
-
-B<true> b_true;
-B<false> b_false;
-
-template<typename T>
-struct nondeduced
-{
-using type = T;
-};
-
-template<typename T1, typename T2, bool b>
-struct A {
-  // expected-note at -1+ {{candidate function}}
-  explicit(false)
-  A(typename nondeduced<T1>::type, typename nondeduced<T2>::type, typename nondeduced<B<b>>::type) {}
-  // expected-note at -1+ {{candidate template ignored}}
-};
-
-template<typename T1, typename T2, bool b>
-explicit(enable_ifv<is_same<T1, T2>::value, b>::value)
-A(T1, T2, B<b>) -> A<T1, T2, b>;
-// expected-note at -1+ {{explicit deduction guide declared here}}
-// expected-note at -2+ {{candidate template ignored}}
-void f() {
-
-A a0( 0.0, 1, b_true); // expected-error {{no viable constructor or deduction guide}}
-A a1{ 0.0, 1, b_true}; // expected-error {{no viable constructor or deduction guide}}
-A a2 = { 0.0, 1, b_true}; // expected-error {{no viable constructor or deduction guide}}
-auto a4 = A( 0.0, 1, b_true); // expected-error {{no viable constructor or deduction guide}}
-auto a5 = A{ 0.0, 1, b_true}; // expected-error {{no viable constructor or deduction guide}}
-
-A b0( 0, 1, b_true);
-A b1{ 0, 1, b_true};
-A b2 = { 0, 1, b_true}; // expected-error {{explicit deduction guide for copy-list-initialization}}
-auto b4 = A( 0, 1, b_true);
-auto b5 = A{ 0, 1, b_true};
-b0 = { 0, 1, b_false}; // expected-error {{no viable overloaded '='}}
-
-A c0( 0, 1, b_false);
-A c1{ 0, 1, b_false};
-A c2 = { 0, 1, b_false};
-auto c4 = A( 0, 1, b_false);
-auto c5 = A{ 0, 1, b_false};
-c2 = { 0, 1, b_false};
-
-}
-
-}
-
-namespace test8 {
-
-template<bool b>
-struct A {
-  //expected-note at -1+ {{candidate function}}
-  template<typename T1, typename T2>
-  explicit(b)
-  A(T1, T2) {}
-  //expected-note at -1 {{explicit constructor declared here}}
-};
-
-template<typename T1, typename T2>
-explicit(!is_same<T1, int>::value)
-A(T1, T2) -> A<!is_same<int, T2>::value>;
-// expected-note at -1+ {{explicit deduction guide declared here}}
-
-template<bool b>
-A<b> v();
-
-void f() {
-
-A a0( 0, 1);
-A a1{ 0, 1};
-A a2 = { 0, 1};
-auto a4 = A( 0, 1);
-auto a5 = A{ 0, 1};
-auto a6(v<false>());
-a6 = { 0, 1};
-
-A b0( 0.0, 1);
-A b1{ 0.0, 1};
-A b2 = { 0.0, 1}; // expected-error {{explicit deduction guide for copy-list-initialization}}
-auto b4 = A( 0.0, 1);
-auto b5 = A{ 0.0, 1};
-
-A c0( 0, 1.0);
-A c1{ 0, 1.0};
-A c2 = { 0, 1.0}; // expected-error {{chosen constructor is explicit}}
-auto c4 = A( 0, 1.0);
-auto c5 = A{ 0, 1.0};
-auto c6(v<true>());
-c0 = { 0, 1.0}; // expected-error {{no viable overloaded '='}}
-
-A d0( 0.0, 1.0);
-A d1{ 0.0, 1.0};
-A d2 = { 0.0, 1.0};  // expected-error {{explicit deduction guide for copy-list-initialization}}
-auto d4 = A( 0.0, 1.0);
-auto d5 = A{ 0.0, 1.0};
-
-}
-
-}
-
-namespace conversion3 {
-
-template<bool b>
-struct A {
-  explicit(!b) operator int();
-  explicit(b) operator bool();
-};
-
-template<bool b>
-A<b>::operator bool() { return false; }
-
-struct B {
-  void f(int);
-  void f(bool);
-};
-
-void f(A<true> a, B b) {
-  b.f(a);
-}
-
-void f1(A<false> a, B b) {
-  b.f(a);
-}
-
-// Taken from 12.3.2p2
-class X { X(); };
-class Y { }; // expected-note+ {{candidate constructor (the implicit}}
-
-template<bool b>
-struct Z {
-  explicit(b) operator X() const;
-  explicit(b) operator Y() const;
-  explicit(b) operator int() const;
-};
-
-void testExplicit()
-{
-Z<true> z;
-// 13.3.1.4p1 & 8.5p16:
-Y y2 = z; // expected-error {{no viable conversion}}
-Y y2b(z);
-Y y3 = (Y)z;
-Y y4 = Y(z);
-Y y5 = static_cast<Y>(z);
-// 13.3.1.5p1 & 8.5p16:
-int i1 = (int)z;
-int i2 = int(z);
-int i3 = static_cast<int>(z);
-int i4(z);
-// 13.3.1.6p1 & 8.5.3p5:
-const Y& y6 = z; // expected-error {{no viable conversion}}
-const int& y7 = z; // expected-error {{no viable conversion}}
-const Y& y8(z);
-const int& y9(z);
-
-// Y is an aggregate, so aggregate-initialization is performed and the
-// conversion function is not considered.
-const Y y10{z}; // expected-error {{excess elements}}
-const Y& y11{z}; // expected-error {{excess elements}} expected-note {{in initialization of temporary}}
-const int& y12{z};
-
-// X is not an aggregate, so constructors are considered,
-// per 13.3.3.1/4 & DR1467.
-const X x1{z};
-const X& x2{z};
-}
-
-struct tmp {};
-
-template<typename T1>
-struct C {
-  template<typename T>
-  explicit(!is_same<T1, T>::value)
-  // expected-note at -1+ {{explicit(bool) specifier resolved to true}}
-  operator T();
-  // expected-note at -1+ {{candidate conversion operator ignored}}
-};
-
-using Bool = C<bool>;
-using Integral = C<int>;
-using Unrelated = C<tmp>;
-
-void testBool() {
-Bool    b;
-Integral n;
-Unrelated u;
-
-(void) (1 + b); // expected-error {{invalid operands to binary expression}}
-(void) (1 + n);
-(void) (1 + u); // expected-error {{invalid operands to binary expression}}
-
-// 5.3.1p9:
-(void) (!b);
-(void) (!n);
-(void) (!u);
-
-// 5.14p1:
-(void) (b && true);
-(void) (n && true);
-(void) (u && true);
-
-// 5.15p1:
-(void) (b || true);
-(void) (n || true);
-(void) (u || true);
-
-// 5.16p1:
-(void) (b ? 0 : 1);
-(void) (n ? 0: 1);
-(void) (u ? 0: 1);
-
-// // 5.19p5:
-// // TODO: After constexpr has been implemented
-
-// 6.4p4:
-if (b) {}
-if (n) {}
-if (u) {}
-
-// 6.4.2p2:
-switch (b) {} // expected-error {{statement requires expression of integer type}}
-switch (n) {} // expected-error {{statement requires expression of integer type}}
-switch (u) {} // expected-error {{statement requires expression of integer type}}
-
-// 6.5.1:
-while (b) {}
-while (n) {}
-while (u) {}
-
-// 6.5.2p1:
-do {} while (b);
-do {} while (n);
-do {} while (u);
-
-// 6.5.3:
-for (;b;) {}
-for (;n;) {}
-for (;u;) {}
-
-// 13.3.1.5p1:
-bool db1(b);
-bool db2(n);
-bool db3(u);
-int di1(b);
-int di2(n);
-int di3(n);
-const bool &direct_cr1(b);
-const bool &direct_cr2(n);
-const bool &direct_cr3(n);
-const int &direct_cr4(b);
-const int &direct_cr5(n);
-const int &direct_cr6(n);
-bool directList1{b};
-bool directList2{n};
-bool directList3{n};
-int directList4{b};
-int directList5{n};
-int directList6{n};
-const bool &directList_cr1{b};
-const bool &directList_cr2{n};
-const bool &directList_cr3{n};
-const int &directList_cr4{b};
-const int &directList_cr5{n};
-const int &directList_cr6{n};
-bool copy1 = b;
-bool copy2 = n;// expected-error {{no viable conversion}}
-bool copyu2 = u;// expected-error {{no viable conversion}}
-int copy3 = b;// expected-error {{no viable conversion}}
-int copy4 = n;
-int copyu4 = u;// expected-error {{no viable conversion}}
-const bool &copy5 = b;
-const bool &copy6 = n;// expected-error {{no viable conversion}}
-const bool &copyu6 = u;// expected-error {{no viable conversion}}
-const int &copy7 = b;// expected-error {{no viable conversion}}
-const int &copy8 = n;
-const int &copyu8 = u;// expected-error {{no viable conversion}}
-bool copyList1 = {b};
-bool copyList2 = {n};// expected-error {{no viable conversion}}
-bool copyListu2 = {u};// expected-error {{no viable conversion}}
-int copyList3 = {b};// expected-error {{no viable conversion}}
-int copyList4 = {n};
-int copyListu4 = {u};// expected-error {{no viable conversion}}
-const bool &copyList5 = {b};
-const bool &copyList6 = {n};// expected-error {{no viable conversion}}
-const bool &copyListu6 = {u};// expected-error {{no viable conversion}}
-const int &copyList7 = {b};// expected-error {{no viable conversion}}
-const int &copyList8 = {n};
-const int &copyListu8 = {u};// expected-error {{no viable conversion}}
-}
-
-}
-
-namespace deduction_guide2 {
-
-template<typename T1 = int, typename T2 = int>
-struct A {
-  // expected-note at -1+ {{candidate template ignored}}
-  explicit(!is_same<T1, T2>::value)
-  // expected-note at -1+ {{explicit(bool) specifier resolved to true}}
-  A(T1 = 0, T2 = 0) {}
-  // expected-note at -1 {{explicit constructor}}
-  // expected-note at -2+ {{candidate deductiong guide ignored}}
-};
-
-A a0 = 0;
-A a1(0, 0);
-A a2{0, 0};
-A a3 = {0, 0};
-
-A b0 = 0.0; // expected-error {{no viable constructor or deduction guide}}
-A b1(0.0, 0.0);
-A b2{0.0, 0.0};
-A b3 = {0.0, 0.0};
-
-A b4 = {0.0, 0}; // expected-error {{explicit constructor}}
-
-template<typename T1, typename T2>
-explicit A(T1, T2) -> A<T1, T2>;
-// expected-note at -1+ {{explicit deduction guide}}
-
-A c0 = 0;
-A c1(0, 0);
-A c2{0, 0};
-A c3 = {0, 0};// expected-error {{explicit deduction guide}}
-
-A d0 = 0.0; // expected-error {{no viable constructor or deduction guide}}
-A d1(0, 0);
-A d2{0, 0};
-A d3 = {0.0, 0.0};// expected-error {{explicit deduction guide}}
-
-}

Modified: cfe/trunk/test/SemaCXX/explicit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/explicit.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/explicit.cpp (original)
+++ cfe/trunk/test/SemaCXX/explicit.cpp Mon May  6 02:51:10 2019
@@ -1,6 +1,4 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++2a %s
-
 namespace Constructor {
 struct A {
   A(int);
@@ -185,8 +183,7 @@ namespace Conversion {
     const int &copyList7 = {b};
     const int &copyList8 = {n}; // expected-error {{no viable conversion}}
   }
-
-#if __cplusplus < 201707L
+  
   void testNew()
   {
     // 5.3.4p6:
@@ -203,8 +200,7 @@ namespace Conversion {
     new int[i];
     new int[ni]; // expected-error {{array size expression of type 'NotInt' requires explicit conversion to type 'int'}}
   }
-#endif
-
+  
   void testDelete()
   {
     // 5.3.5pp2:

Modified: cfe/trunk/unittests/AST/Language.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/Language.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/unittests/AST/Language.cpp (original)
+++ cfe/trunk/unittests/AST/Language.cpp Mon May  6 02:51:10 2019
@@ -34,9 +34,6 @@ ArgVector getBasicRunOptionsForLanguage(
   case Lang_CXX14:
     BasicArgs = {"-std=c++14", "-frtti"};
     break;
-  case Lang_CXX2a:
-    BasicArgs = {"-std=c++2a", "-frtti"};
-    break;
   case Lang_OpenCL:
   case Lang_OBJCXX:
     llvm_unreachable("Not implemented yet!");

Modified: cfe/trunk/unittests/AST/Language.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/Language.h?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/unittests/AST/Language.h (original)
+++ cfe/trunk/unittests/AST/Language.h Mon May  6 02:51:10 2019
@@ -28,7 +28,6 @@ enum Language {
     Lang_CXX,
     Lang_CXX11,
     Lang_CXX14,
-    Lang_CXX2a,
     Lang_OpenCL,
     Lang_OBJCXX
 };

Modified: cfe/trunk/unittests/AST/MatchVerifier.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/MatchVerifier.h?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/unittests/AST/MatchVerifier.h (original)
+++ cfe/trunk/unittests/AST/MatchVerifier.h Mon May  6 02:51:10 2019
@@ -108,10 +108,6 @@ testing::AssertionResult MatchVerifier<N
     Args.push_back("-std=c++14");
     FileName = "input.cc";
     break;
-  case Lang_CXX2a:
-    Args.push_back("-std=c++2a");
-    FileName = "input.cc";
-    break;
   case Lang_OpenCL:
     FileName = "input.cl";
     break;

Modified: cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp (original)
+++ cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp Mon May  6 02:51:10 2019
@@ -806,26 +806,6 @@ TEST_F(StructuralEquivalenceTest, Compar
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
-TEST_F(StructuralEquivalenceTest, ExplicitBoolDifferent) {
-  auto Decls = makeNamedDecls("struct foo {explicit(false) foo(int);};",
-                              "struct foo {explicit(true) foo(int);};", Lang_CXX2a);
-  CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
-      get<0>(Decls), cxxConstructorDecl(hasName("foo")));
-  CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
-      get<1>(Decls), cxxConstructorDecl(hasName("foo")));
-  EXPECT_FALSE(testStructuralMatch(First, Second));
-}
-
-TEST_F(StructuralEquivalenceTest, ExplicitBoolSame) {
-  auto Decls = makeNamedDecls("struct foo {explicit(true) foo(int);};",
-                              "struct foo {explicit(true) foo(int);};", Lang_CXX2a);
-  CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
-      get<0>(Decls), cxxConstructorDecl(hasName("foo")));
-  CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
-      get<1>(Decls), cxxConstructorDecl(hasName("foo")));
-  EXPECT_TRUE(testStructuralMatch(First, Second));
-}
-
 struct StructuralEquivalenceEnumTest : StructuralEquivalenceTest {};
 
 TEST_F(StructuralEquivalenceEnumTest, FwdDeclEnumShouldBeEqualWithFwdDeclEnum) {
@@ -873,25 +853,5 @@ TEST_F(StructuralEquivalenceTemplateTest
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
-TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolSame) {
-  auto Decls = makeNamedDecls("template <bool b> struct foo {explicit(b) foo(int);};",
-                              "template <bool b> struct foo {explicit(b) foo(int);};", Lang_CXX2a);
-  CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
-      get<0>(Decls), cxxConstructorDecl(hasName("foo<b>")));
-  CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
-      get<1>(Decls), cxxConstructorDecl(hasName("foo<b>")));
-  EXPECT_TRUE(testStructuralMatch(First, Second));
-}
-
-TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolDifference) {
-  auto Decls = makeNamedDecls("template <bool b> struct foo {explicit(b) foo(int);};",
-                              "template <bool b> struct foo {explicit(!b) foo(int);};", Lang_CXX2a);
-  CXXConstructorDecl *First = FirstDeclMatcher<CXXConstructorDecl>().match(
-      get<0>(Decls), cxxConstructorDecl(hasName("foo<b>")));
-  CXXConstructorDecl *Second = FirstDeclMatcher<CXXConstructorDecl>().match(
-      get<1>(Decls), cxxConstructorDecl(hasName("foo<b>")));
-  EXPECT_FALSE(testStructuralMatch(First, Second));
-}
-
 } // end namespace ast_matchers
 } // end namespace clang

Modified: cfe/trunk/www/cxx_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=360024&r1=360023&r2=360024&view=diff
==============================================================================
--- cfe/trunk/www/cxx_status.html (original)
+++ cfe/trunk/www/cxx_status.html Mon May  6 02:51:10 2019
@@ -1002,7 +1002,7 @@ as the draft C++2a standard evolves.
     <tr>
       <td><tt>explicit(bool)</tt></td>
       <td><a href="http://wg21.link/p0892r2">P0892R2</a></td>
-      <td class="svn" align="center">SVN</td>
+      <td class="none" align="center">No</td>
     </tr>
     <!-- San Diego papers -->
     <tr>




More information about the cfe-commits mailing list