diff options
author | Nicolas Lesser <blitzrakete@gmail.com> | 2019-05-04 00:09:00 +0000 |
---|---|---|
committer | Nicolas Lesser <blitzrakete@gmail.com> | 2019-05-04 00:09:00 +0000 |
commit | 6de0b449c07ec7adbcb34e7c94c544ee37ef5963 (patch) | |
tree | 0e2112dbbe57b79622f5a7708add8fecc6a75b80 /lib/Sema/SemaInit.cpp | |
parent | 6cc60c9164a96f1d73ccfd302303490e0d085b87 (diff) | |
download | clang-6de0b449c07ec7adbcb34e7c94c544ee37ef5963.tar.gz |
[clang] adding explicit(bool) from c++2a
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
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@359949 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaInit.cpp')
-rw-r--r-- | lib/Sema/SemaInit.cpp | 88 |
1 files changed, 48 insertions, 40 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index e8a8887736..5b78d449d0 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -3763,9 +3763,10 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc, hasCopyOrMoveCtorParam(S.Context, Info)); if (Info.ConstructorTmpl) - S.AddTemplateOverloadCandidate(Info.ConstructorTmpl, Info.FoundDecl, - /*ExplicitArgs*/ nullptr, Args, - CandidateSet, SuppressUserConversions); + S.AddTemplateOverloadCandidate( + Info.ConstructorTmpl, Info.FoundDecl, + /*ExplicitArgs*/ nullptr, Args, CandidateSet, SuppressUserConversions, + /*PartialOverloading=*/false, AllowExplicit); else { // C++ [over.match.copy]p1: // - When initializing a temporary to be bound to the first parameter @@ -3779,8 +3780,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); } } @@ -3813,16 +3814,17 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc, else Conv = cast<CXXConversionDecl>(D); - if ((AllowExplicit && !CopyInitializing) || !Conv->isExplicit()) { + if (AllowExplicit || !Conv->isExplicit()) { if (ConvTemplate) - S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(), - ActingDC, Initializer, DestType, - CandidateSet, AllowExplicit, - /*AllowResultConversion*/false); + S.AddTemplateConversionCandidate( + ConvTemplate, I.getPair(), ActingDC, Initializer, DestType, + CandidateSet, AllowExplicit, AllowExplicit, + /*AllowResultConversion*/ false); else S.AddConversionCandidate(Conv, I.getPair(), ActingDC, Initializer, DestType, CandidateSet, AllowExplicit, - /*AllowResultConversion*/false); + AllowExplicit, + /*AllowResultConversion*/ false); } } } @@ -4368,14 +4370,16 @@ 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); + S.AddTemplateOverloadCandidate( + Info.ConstructorTmpl, Info.FoundDecl, + /*ExplicitArgs*/ nullptr, Initializer, CandidateSet, + /*SuppressUserConversions=*/true, + /*PartialOverloading*/ false, AllowExplicitCtors); else - S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, - Initializer, CandidateSet, - /*SuppressUserConversions=*/true); + S.AddOverloadCandidate( + Info.Constructor, Info.FoundDecl, Initializer, CandidateSet, + /*SuppressUserConversions=*/true, + /*PartialOverloading*/ false, AllowExplicitCtors); } } } @@ -4410,17 +4414,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); + S.AddTemplateConversionCandidate( + ConvTemplate, I.getPair(), ActingDC, Initializer, DestType, + CandidateSet, + /*AllowObjCConversionOnExplicit=*/false, AllowExplicitConvs); else - S.AddConversionCandidate(Conv, I.getPair(), ActingDC, - Initializer, DestType, CandidateSet, - /*AllowObjCConversionOnExplicit=*/false); + S.AddConversionCandidate( + Conv, I.getPair(), ActingDC, Initializer, DestType, CandidateSet, + /*AllowObjCConversionOnExplicit=*/false, AllowExplicitConvs); } } } @@ -4996,14 +5000,16 @@ 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); + S.AddTemplateOverloadCandidate( + Info.ConstructorTmpl, Info.FoundDecl, + /*ExplicitArgs*/ nullptr, Initializer, CandidateSet, + /*SuppressUserConversions=*/true, + /*PartialOverloading*/ false, AllowExplicit); else S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, Initializer, CandidateSet, - /*SuppressUserConversions=*/true); + /*SuppressUserConversions=*/true, + /*PartialOverloading*/ false, AllowExplicit); } } } @@ -5038,12 +5044,12 @@ static void TryUserDefinedConversion(Sema &S, if (AllowExplicit || !Conv->isExplicit()) { if (ConvTemplate) - S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(), - ActingDC, Initializer, DestType, - CandidateSet, AllowExplicit); + S.AddTemplateConversionCandidate( + ConvTemplate, I.getPair(), ActingDC, Initializer, DestType, + CandidateSet, AllowExplicit, AllowExplicit); else - S.AddConversionCandidate(Conv, I.getPair(), ActingDC, - Initializer, DestType, CandidateSet, + S.AddConversionCandidate(Conv, I.getPair(), ActingDC, Initializer, + DestType, CandidateSet, AllowExplicit, AllowExplicit); } } @@ -9336,6 +9342,7 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( OverloadCandidateSet::iterator Best; bool HasAnyDeductionGuide = false; + bool AllowExplicit = !Kind.isCopyInit() || ListInit; auto tryToResolveOverload = [&](bool OnlyListConstructors) -> OverloadingResult { @@ -9361,7 +9368,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 (Kind.isCopyInit() && !ListInit) { + if (!AllowExplicit) { // Only consider converting constructors. if (GD->isExplicit()) continue; @@ -9396,8 +9403,9 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( if (TD) AddTemplateOverloadCandidate(TD, I.getPair(), /*ExplicitArgs*/ nullptr, - Inits, Candidates, - SuppressUserConversions); + Inits, Candidates, SuppressUserConversions, + /*PartialOverloading*/ false, + AllowExplicit); else AddOverloadCandidate(GD, I.getPair(), Inits, Candidates, SuppressUserConversions); |