sammccall updated this revision to Diff 251337.
sammccall added a comment.
Add comment on markDependentForPostponedNameLookup
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D76392/new/
https://reviews.llvm.org/D76392
Files:
clang/include/clang/AST/Expr.h
clang/lib/AST/ComputeDependence.cpp
clang/lib/AST/Expr.cpp
clang/lib/AST/ExprConcepts.cpp
clang/lib/Sema/SemaOverload.cpp
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -12720,7 +12720,7 @@
// base classes.
CallExpr *CE = CallExpr::Create(Context, Fn, Args, Context.DependentTy,
VK_RValue, RParenLoc);
- CE->addDependence(ExprDependence::TypeValueInstantiation);
+ CE->markDependentForPostponedNameLookup();
*Result = CE;
return true;
}
Index: clang/lib/AST/ExprConcepts.cpp
===================================================================
--- clang/lib/AST/ExprConcepts.cpp
+++ clang/lib/AST/ExprConcepts.cpp
@@ -175,13 +175,13 @@
RequiresExprBits.IsSatisfied |= Dependent;
// FIXME: move the computing dependency logic to ComputeDependence.h
if (ContainsUnexpandedParameterPack)
- addDependence(ExprDependence::UnexpandedPack);
+ setDependence(getDependence() | ExprDependence::UnexpandedPack);
// FIXME: this is incorrect for cases where we have a non-dependent
// requirement, but its parameters are instantiation-dependent. RequiresExpr
// should be instantiation-dependent if it has instantiation-dependent
// parameters.
if (Dependent)
- addDependence(ExprDependence::ValueInstantiation);
+ setDependence(getDependence() | ExprDependence::ValueInstantiation);
}
RequiresExpr::RequiresExpr(ASTContext &C, EmptyShell Empty,
Index: clang/lib/AST/Expr.cpp
===================================================================
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -1497,28 +1497,15 @@
MemberExpr *E = new (Mem) MemberExpr(Base, IsArrow, OperatorLoc, MemberDecl,
NameInfo, T, VK, OK, NOUR);
- if (isa<FieldDecl>(MemberDecl)) {
- DeclContext *DC = MemberDecl->getDeclContext();
- // dyn_cast_or_null is used to handle objC variables which do not
- // have a declaration context.
- CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(DC);
- if (RD && RD->isDependentContext() && RD->isCurrentInstantiation(DC)) {
- if (E->isTypeDependent() && !T->isDependentType())
- E->removeDependence(ExprDependence::Type);
- }
- // Bitfield with value-dependent width is type-dependent.
- FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl);
- if (FD && FD->isBitField() && FD->getBitWidth()->isValueDependent())
- E->addDependence(ExprDependence::Type);
- }
-
+ // FIXME: remove remaining dependence computation to computeDependence().
+ auto Deps = E->getDependence();
if (HasQualOrFound) {
// FIXME: Wrong. We should be looking at the member declaration we found.
if (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isDependent())
- E->addDependence(ExprDependence::TypeValueInstantiation);
+ Deps |= ExprDependence::TypeValueInstantiation;
else if (QualifierLoc &&
QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())
- E->addDependence(ExprDependence::Instantiation);
+ Deps |= ExprDependence::Instantiation;
E->MemberExprBits.HasQualifierOrFoundDecl = true;
@@ -1532,16 +1519,17 @@
TemplateArgs || TemplateKWLoc.isValid();
if (TemplateArgs) {
- auto Deps = TemplateArgumentDependence::None;
+ auto TemplateArgDeps = TemplateArgumentDependence::None;
E->getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
TemplateKWLoc, *TemplateArgs,
- E->getTrailingObjects<TemplateArgumentLoc>(), Deps);
- if (Deps & TemplateArgumentDependence::Instantiation)
- E->addDependence(ExprDependence::Instantiation);
+ E->getTrailingObjects<TemplateArgumentLoc>(), TemplateArgDeps);
+ if (TemplateArgDeps & TemplateArgumentDependence::Instantiation)
+ Deps |= ExprDependence::Instantiation;
} else if (TemplateKWLoc.isValid()) {
E->getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
TemplateKWLoc);
}
+ E->setDependence(Deps);
return E;
}
Index: clang/lib/AST/ComputeDependence.cpp
===================================================================
--- clang/lib/AST/ComputeDependence.cpp
+++ clang/lib/AST/ComputeDependence.cpp
@@ -475,7 +475,25 @@
}
ExprDependence clang::computeDependence(MemberExpr *E) {
- return E->getBase()->getDependence();
+ auto *MemberDecl = E->getMemberDecl();
+ auto D = E->getBase()->getDependence();
+ if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl)) {
+ DeclContext *DC = MemberDecl->getDeclContext();
+ // dyn_cast_or_null is used to handle objC variables which do not
+ // have a declaration context.
+ CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(DC);
+ if (RD && RD->isDependentContext() && RD->isCurrentInstantiation(DC)) {
+ if (!E->getType()->isDependentType())
+ D &= ~ExprDependence::Type;
+ }
+
+ // Bitfield with value-dependent width is type-dependent.
+ if (FD && FD->isBitField() && FD->getBitWidth()->isValueDependent()) {
+ D |= ExprDependence::Type;
+ }
+ }
+ // FIXME: move remaining dependence computation from MemberExpr::Create()
+ return D;
}
ExprDependence clang::computeDependence(InitListExpr *E) {
Index: clang/include/clang/AST/Expr.h
===================================================================
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -130,6 +130,14 @@
/// Construct an empty expression.
explicit Expr(StmtClass SC, EmptyShell) : ValueStmt(SC) { }
+ /// Each concrete expr subclass is expected to compute its dependence and call
+ /// this in the constructor.
+ void setDependence(ExprDependence Deps) {
+ ExprBits.Dependent = static_cast<unsigned>(Deps);
+ }
+ friend class ASTImporter; // Sets dependence dircetly.
+ friend class ASTStmtReader; // Sets dependence dircetly.
+
public:
QualType getType() const { return TR; }
void setType(QualType t) {
@@ -149,18 +157,6 @@
return static_cast<ExprDependence>(ExprBits.Dependent);
}
- /// Each concrete expr subclass is expected to compute its dependence and call
- /// this in the constructor.
- void setDependence(ExprDependence Deps) {
- ExprBits.Dependent = static_cast<unsigned>(Deps);
- }
- void addDependence(ExprDependence Deps) {
- ExprBits.Dependent |= static_cast<unsigned>(Deps);
- }
- void removeDependence(ExprDependence Deps) {
- ExprBits.Dependent &= ~static_cast<unsigned>(Deps);
- }
-
/// isValueDependent - Determines whether this expression is
/// value-dependent (C++ [temp.dep.constexpr]). For example, the
/// array bound of "Chars" in the following example is
@@ -2767,6 +2763,12 @@
/// a non-value-dependent constant parameter evaluating as false.
bool isBuiltinAssumeFalse(const ASTContext &Ctx) const;
+ /// Used by Sema to implement MSVC-compatible delayed name lookup.
+ /// (Usually Exprs themselves should set dependence).
+ void markDependentForPostponedNameLookup() {
+ setDependence(getDependence() | ExprDependence::TypeValueInstantiation);
+ }
+
bool isCallToStdMove() const {
const FunctionDecl *FD = getDirectCallee();
return getNumArgs() == 1 && FD && FD->isInStdNamespace() &&
@@ -4378,7 +4380,7 @@
InitExprs[Init] = expr;
if (expr)
- addDependence(expr->getDependence());
+ setDependence(getDependence() | expr->getDependence());
}
/// Reserve space for some number of initializers.
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits