summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/Decl.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard@metafoo.co.uk>2019-12-05 13:37:35 -0800
committerRichard Smith <richard@metafoo.co.uk>2019-12-09 17:40:36 -0800
commit848934c67d484da737b4b92c087bffce069b24ba (patch)
tree85ddebae5f1249c32ef844f92e8477946c01f1cf /clang/lib/AST/Decl.cpp
parent6507e13589687b40530dedc4dec670f2c1bfdc71 (diff)
downloadbcm5719-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.cpp43
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;
}
OpenPOWER on IntegriCloud