summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2019-05-06 09:51:10 +0000
committerHans Wennborg <hans@hanshq.net>2019-05-06 09:51:10 +0000
commitd2b9fc88c8c4c758068da680cd0e42e6ca41ffcd (patch)
treea211c3ae7ae48386887be271a497d37fbb8088bc /clang/lib
parent3cfb48b87729a656128a2f4c9884f66f7eccb353 (diff)
downloadbcm5719-llvm-d2b9fc88c8c4c758068da680cd0e42e6ca41ffcd.tar.gz
bcm5719-llvm-d2b9fc88c8c4c758068da680cd0e42e6ca41ffcd.zip
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
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTImporter.cpp28
-rw-r--r--clang/lib/AST/ASTStructuralEquivalence.cpp6
-rw-r--r--clang/lib/AST/Decl.cpp1
-rw-r--r--clang/lib/AST/DeclCXX.cpp109
-rw-r--r--clang/lib/AST/DeclPrinter.cpp22
-rw-r--r--clang/lib/Frontend/InitPreprocessor.cpp2
-rw-r--r--clang/lib/Parse/ParseDecl.cpp62
-rw-r--r--clang/lib/Sema/DeclSpec.cpp28
-rw-r--r--clang/lib/Sema/SemaCodeComplete.cpp6
-rw-r--r--clang/lib/Sema/SemaDecl.cpp18
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp59
-rw-r--r--clang/lib/Sema/SemaInit.cpp88
-rw-r--r--clang/lib/Sema/SemaLambda.cpp4
-rw-r--r--clang/lib/Sema/SemaLookup.cpp9
-rw-r--r--clang/lib/Sema/SemaOverload.cpp173
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp16
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp53
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp9
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp1
-rw-r--r--clang/lib/Serialization/ASTWriterDecl.cpp24
20 files changed, 240 insertions, 478 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 1ab99bec38b..1ac4870cabe 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -3055,20 +3055,11 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
// 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::VisitFunctionDecl(FunctionDecl *D) {
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 f3c34d73bdb..71bbd824812 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -955,15 +955,13 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
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 499a4513804..19fd3882bd4 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2713,6 +2713,7 @@ FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC,
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 b9ecdc65720..d7eae5ad1e1 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -1879,47 +1879,19 @@ bool CXXRecordDecl::mayBeAbstract() const {
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::getSourceRange() const {
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 {
diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp
index 78a7afdbf09..325400e4630 100644
--- a/clang/lib/AST/DeclPrinter.cpp
+++ b/clang/lib/AST/DeclPrinter.cpp
@@ -566,21 +566,6 @@ void DeclPrinter::VisitEnumConstantDecl(EnumConstantDecl *D) {
}
}
-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(FunctionDecl *D) {
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);
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 5aa2ea3fba1..b0fb124251e 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -540,8 +540,6 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
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");
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index f883ecc45f1..c4f02b9b999 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -2442,12 +2442,12 @@ void Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS,
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(DeclSpec &DS,
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(DeclSpec &DS,
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(DeclSpec &DS,
// 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();
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp
index df2792289e4..4f3e2faa8e0 100644
--- a/clang/lib/Sema/DeclSpec.cpp
+++ b/clang/lib/Sema/DeclSpec.cpp
@@ -445,7 +445,7 @@ unsigned DeclSpec::getParsedSpecifiers() const {
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(SourceLocation Loc,
}
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 PrintingPolicy &Policy) {
// 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();
}
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index d86668c49fb..c2d80409f1a 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -4961,15 +4961,13 @@ QualType Sema::ProduceConstructorSignatureHelp(Scope *S, QualType Type,
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);
}
}
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 86b5645d115..379e2aefb46 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -5705,7 +5705,7 @@ void Sema::DiagnoseFunctionSpecifiers(const DeclSpec &DS) {
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* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
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* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
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* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
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, Declarator &D, DeclContext *DC,
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, Declarator &D, DeclContext *DC,
// 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());
}
}
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 8ddc5f12cf1..7e4aab0fae5 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -657,13 +657,14 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old,
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(Declarator &D, QualType &R,
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::DeclareImplicitDefaultConstructor(
= 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(SourceLocation Loc,
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::DeclareImplicitCopyConstructor(
// 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::DeclareImplicitMoveConstructor(
// 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();
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 5b78d449d0c..e8a8887736e 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -3763,10 +3763,9 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc,
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, SourceLocation DeclLoc,
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, SourceLocation DeclLoc,
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 TryRefInitWithConversionFunction(
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 TryRefInitWithConversionFunction(
// 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(Sema &S,
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(Sema &S,
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::DeduceTemplateSpecializationFromInitializer(
OverloadCandidateSet::iterator Best;
bool HasAnyDeductionGuide = false;
- bool AllowExplicit = !Kind.isCopyInit() || ListInit;
auto tryToResolveOverload =
[&](bool OnlyListConstructors) -> OverloadingResult {
@@ -9368,7 +9361,7 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
// 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::DeduceTemplateSpecializationFromInitializer(
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);
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 1966e9e0803..b686681f04f 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1325,7 +1325,7 @@ static void addFunctionPointerConversion(Sema &S,
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(Sema &S,
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);
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index a91c20e00a6..2b7924d244e 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -3041,15 +3041,10 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD,
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)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 1ef932e05e9..df979b68b6e 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -3242,13 +3242,10 @@ IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType,
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 *From, QualType ToType,
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 *From, QualType ToType,
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, ImplicitConversionSequence &ICS,
}
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 CheckConvertedConstantExpression(Sema &S, Expr *From,
// 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 &SemaRef, Expr *From, QualType ToType,
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 IsAcceptableNonMemberOperatorCandidate(ASTContext &Context,
/// \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 isAllowableExplicitConversion(Sema &S,
/// 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::AddTemplateConversionCandidate(
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::AddArgumentDependentLookupCandidates(DeclarationName Name,
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(Sema &S, OverloadCandidate *Cand) {
<< 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 &S, OverloadCandidate *Cand,
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, Expr *MemExprE,
// 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.
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index b2f80ebd119..58ad439747e 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -1109,7 +1109,7 @@ NamedDecl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
if (DS.isVirtualSpecified())
EmitDiag(DS.getVirtualSpecLoc());
- if (DS.hasExplicitSpecifier())
+ if (DS.isExplicitSpecified())
EmitDiag(DS.getExplicitSpecLoc());
if (DS.isNoreturnSpecified())
@@ -1789,8 +1789,8 @@ struct ConvertConstructorToDeductionGuideTransform {
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 ConvertConstructorToDeductionGuideTransform {
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);
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 1c7341d3cf8..653eb693268 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -366,29 +366,6 @@ static void instantiateDependentAMDGPUFlatWorkGroupSizeAttr(
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::VisitFunctionDecl(FunctionDecl *D,
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::VisitFunctionDecl(FunctionDecl *D,
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::VisitCXXMethodDecl(
}
}
- 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::VisitCXXMethodDecl(
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::VisitCXXMethodDecl(
} 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;
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 27fcc9e40b5..ffe0e8bd74e 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -858,6 +858,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
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(CXXRecordDecl *D) {
}
void ASTDeclReader::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
- D->setExplicitSpecifier(Record.readExplicitSpec());
VisitFunctionDecl(D);
D->setIsCopyDeductionCandidate(Record.readInt());
}
@@ -2002,7 +2002,6 @@ void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) {
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::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
}
void ASTDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) {
- D->setExplicitSpecifier(Record.readExplicitSpec());
VisitCXXMethodDecl(D);
}
@@ -3752,7 +3750,10 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
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);
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index ca61edd8d29..756411a8c5b 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -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);
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index 5c0f2dff56e..159a76d5efb 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -535,6 +535,7 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
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(FunctionDecl *D) {
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(CXXMethodDecl *D) {
}
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::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
}
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
OpenPOWER on IntegriCloud