diff options
author | Richard Smith <richard@metafoo.co.uk> | 2019-12-05 13:37:35 -0800 |
---|---|---|
committer | Richard Smith <richard@metafoo.co.uk> | 2019-12-09 17:40:36 -0800 |
commit | 848934c67d484da737b4b92c087bffce069b24ba (patch) | |
tree | 85ddebae5f1249c32ef844f92e8477946c01f1cf /clang/lib/AST/Decl.cpp | |
parent | 6507e13589687b40530dedc4dec670f2c1bfdc71 (diff) | |
download | bcm5719-llvm-848934c67d484da737b4b92c087bffce069b24ba.tar.gz bcm5719-llvm-848934c67d484da737b4b92c087bffce069b24ba.zip |
[c++20] Fix handling of unqualified lookups from a defaulted comparison
function.
We need to perform unqualified lookups from the context of a defaulted
comparison, but not until we implicitly define the function, at which
point we can't do those lookups any more. So perform the lookup from the
end of the class containing the =default declaration and store the
lookup results on the defaulted function until we synthesize the body.
Diffstat (limited to 'clang/lib/AST/Decl.cpp')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 314d1750f43..9f09898a957 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2774,7 +2774,7 @@ FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, ConstexprSpecKind ConstexprKind) : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo, StartLoc), - DeclContext(DK), redeclarable_base(C), ODRHash(0), + DeclContext(DK), redeclarable_base(C), Body(), ODRHash(0), EndRangeLoc(NameInfo.getEndLoc()), DNLoc(NameInfo.getInfo()) { assert(T.isNull() || T->isFunctionType()); FunctionDeclBits.SClass = S; @@ -2789,6 +2789,7 @@ FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, FunctionDeclBits.IsTrivialForCall = false; FunctionDeclBits.IsDefaulted = false; FunctionDeclBits.IsExplicitlyDefaulted = false; + FunctionDeclBits.HasDefaultedFunctionInfo = false; FunctionDeclBits.HasImplicitReturnZero = false; FunctionDeclBits.IsLateTemplateParsed = false; FunctionDeclBits.ConstexprKind = ConstexprKind; @@ -2816,6 +2817,32 @@ bool FunctionDecl::isVariadic() const { return false; } +FunctionDecl::DefaultedFunctionInfo * +FunctionDecl::DefaultedFunctionInfo::Create(ASTContext &Context, + ArrayRef<DeclAccessPair> Lookups) { + DefaultedFunctionInfo *Info = new (Context.Allocate( + totalSizeToAlloc<DeclAccessPair>(Lookups.size()), + std::max(alignof(DefaultedFunctionInfo), alignof(DeclAccessPair)))) + DefaultedFunctionInfo; + Info->NumLookups = Lookups.size(); + std::uninitialized_copy(Lookups.begin(), Lookups.end(), + Info->getTrailingObjects<DeclAccessPair>()); + return Info; +} + +void FunctionDecl::setDefaultedFunctionInfo(DefaultedFunctionInfo *Info) { + assert(!FunctionDeclBits.HasDefaultedFunctionInfo && "already have this"); + assert(!Body && "can't replace function body with defaulted function info"); + + FunctionDeclBits.HasDefaultedFunctionInfo = true; + DefaultedInfo = Info; +} + +FunctionDecl::DefaultedFunctionInfo * +FunctionDecl::getDefaultedFunctionInfo() const { + return FunctionDeclBits.HasDefaultedFunctionInfo ? DefaultedInfo : nullptr; +} + bool FunctionDecl::hasBody(const FunctionDecl *&Definition) const { for (auto I : redecls()) { if (I->doesThisDeclarationHaveABody()) { @@ -2827,8 +2854,7 @@ bool FunctionDecl::hasBody(const FunctionDecl *&Definition) const { return false; } -bool FunctionDecl::hasTrivialBody() const -{ +bool FunctionDecl::hasTrivialBody() const { Stmt *S = getBody(); if (!S) { // Since we don't have a body for this function, we don't know if it's @@ -2856,6 +2882,8 @@ Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const { if (!hasBody(Definition)) return nullptr; + assert(!Definition->FunctionDeclBits.HasDefaultedFunctionInfo && + "definition should not have a body"); if (Definition->Body) return Definition->Body.get(getASTContext().getExternalSource()); @@ -2863,7 +2891,8 @@ Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const { } void FunctionDecl::setBody(Stmt *B) { - Body = B; + FunctionDeclBits.HasDefaultedFunctionInfo = false; + Body = LazyDeclStmtPtr(B); if (B) EndRangeLoc = B->getEndLoc(); } @@ -3304,9 +3333,9 @@ bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const { const FunctionDecl *Prev = this; bool FoundBody = false; while ((Prev = Prev->getPreviousDecl())) { - FoundBody |= Prev->Body.isValid(); + FoundBody |= Prev->doesThisDeclarationHaveABody(); - if (Prev->Body) { + if (Prev->doesThisDeclarationHaveABody()) { // If it's not the case that both 'inline' and 'extern' are // specified on the definition, then it is always externally visible. if (!Prev->isInlineSpecified() || @@ -3329,7 +3358,7 @@ bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const { const FunctionDecl *Prev = this; bool FoundBody = false; while ((Prev = Prev->getPreviousDecl())) { - FoundBody |= Prev->Body.isValid(); + FoundBody |= Prev->doesThisDeclarationHaveABody(); if (RedeclForcesDefC99(Prev)) return false; } |