forked from OSchip/llvm-project
[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:
parent
1db8b341a6
commit
b4f02d89e5
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue