diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/DeclSpec.cpp | 28 | ||||
-rw-r--r-- | clang/lib/Sema/SemaCodeComplete.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 18 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 59 | ||||
-rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 88 | ||||
-rw-r--r-- | clang/lib/Sema/SemaLambda.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 173 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 53 |
10 files changed, 161 insertions, 293 deletions
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; |