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

llvm-svn: 360024
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 1ab99be..1ac4870 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -3055,20 +3055,11 @@
   // 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 @@
     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>(
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index f3c34d7..71bbd82 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -955,15 +955,13 @@
 
   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()))
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 499a451..19fd388 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2713,6 +2713,7 @@
   FunctionDeclBits.SClass = S;
   FunctionDeclBits.IsInline = isInlineSpecified;
   FunctionDeclBits.IsInlineSpecified = isInlineSpecified;
+  FunctionDeclBits.IsExplicitSpecified = false;
   FunctionDeclBits.IsVirtualAsWritten = false;
   FunctionDeclBits.IsPure = false;
   FunctionDeclBits.HasInheritedPrototype = false;
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index b9ecdc6..d7eae5a 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -1879,47 +1879,19 @@
 
 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 @@
 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 @@
 
 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 {
diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp
index 78a7afd..325400e 100644
--- a/clang/lib/AST/DeclPrinter.cpp
+++ b/clang/lib/AST/DeclPrinter.cpp
@@ -566,21 +566,6 @@
   }
 }
 
-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 @@
     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);