[AST] Make Expr::setDependence protected and remove add/removeDependence. NFC

Summary:
The expected pattern is for subclasses to initialize through
computeDependence, which needs only setDependence.
The few places that still use addDependence can be simulated with get+set.

Reviewers: hokein

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D76392
This commit is contained in:
Sam McCall 2020-03-18 23:38:08 +01:00
parent 1db8b341a6
commit b4f02d89e5
5 changed files with 46 additions and 38 deletions

View File

@ -130,6 +130,14 @@ protected:
/// 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 @@ public:
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
@ -2773,6 +2769,12 @@ public:
/// 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() &&
@ -4384,7 +4386,7 @@ public:
InitExprs[Init] = expr;
if (expr)
addDependence(expr->getDependence());
setDependence(getDependence() | expr->getDependence());
}
/// Reserve space for some number of initializers.

View File

@ -482,7 +482,25 @@ ExprDependence clang::computeDependence(OffsetOfExpr *E) {
}
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) {

View File

@ -1497,28 +1497,15 @@ MemberExpr *MemberExpr::Create(
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 @@ MemberExpr *MemberExpr::Create(
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;
}

View File

@ -175,13 +175,13 @@ RequiresExpr::RequiresExpr(ASTContext &C, SourceLocation RequiresKWLoc,
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,

View File

@ -12720,7 +12720,7 @@ bool Sema::buildOverloadedCallSet(Scope *S, Expr *Fn,
// base classes.
CallExpr *CE = CallExpr::Create(Context, Fn, Args, Context.DependentTy,
VK_RValue, RParenLoc);
CE->addDependence(ExprDependence::TypeValueInstantiation);
CE->markDependentForPostponedNameLookup();
*Result = CE;
return true;
}