ValueDecl *getDecl() { return D; }
const ValueDecl *getDecl() const { return D; }
- void setDecl(ValueDecl *NewD) { D = NewD; }
+ void setDecl(ValueDecl *NewD);
DeclarationNameInfo getNameInfo() const {
return DeclarationNameInfo(getDecl()->getDeclName(), getLocation(), DNLoc);
/// The returned declaration will be a FieldDecl or (in C++) a VarDecl (for
/// static data members), a CXXMethodDecl, or an EnumConstantDecl.
ValueDecl *getMemberDecl() const { return MemberDecl; }
- void setMemberDecl(ValueDecl *D) { MemberDecl = D; }
+ void setMemberDecl(ValueDecl *D);
/// Retrieves the declaration found by lookup.
DeclAccessPair getFoundDecl() const {
return new (Mem) DeclRefExpr(EmptyShell());
}
+void DeclRefExpr::setDecl(ValueDecl *NewD) {
+ D = NewD;
+ setDependence(computeDependence(this, NewD->getASTContext()));
+}
+
SourceLocation DeclRefExpr::getBeginLoc() const {
if (hasQualifier())
return getQualifierLoc().getBeginLoc();
return new (Mem) MemberExpr(EmptyShell());
}
+void MemberExpr::setMemberDecl(ValueDecl *D) {
+ MemberDecl = D;
+ setDependence(computeDependence(this));
+}
+
SourceLocation MemberExpr::getBeginLoc() const {
if (isImplicitAccess()) {
if (hasQualifier())
SemaRef.runWithSufficientStackSpace(PointOfInstantiation, [&] {
SemaRef.InstantiateVariableDefinition(PointOfInstantiation, Var);
});
+
+ // Re-set the member to trigger a recomputation of the dependence bits
+ // for the expression.
+ if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E))
+ DRE->setDecl(DRE->getDecl());
+ else if (auto *ME = dyn_cast_or_null<MemberExpr>(E))
+ ME->setMemberDecl(ME->getMemberDecl());
} else if (FirstInstantiation ||
isa<VarTemplateSpecializationDecl>(Var)) {
// FIXME: For a specialization of a variable template, we don't
}
/// Perform reference-marking and odr-use handling for a DeclRefExpr.
+///
+/// Note, this may change the dependence of the DeclRefExpr, and so needs to be
+/// handled with care if the DeclRefExpr is not newly-created.
void Sema::MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base) {
// TODO: update this with DR# once a defect report is filed.
// C++11 defect. The address of a pure member should not be an ODR use, even
if (VD->hasLocalStorage())
return;
}
+
+ // FIXME: This can trigger the instantiation of the initializer of a
+ // variable, which can cause the expression to become value-dependent
+ // or error-dependent. Do we need to propagate the new dependence bits?
S.MarkDeclRefReferenced(E);
}
// verify no crash on evaluating the size of undeduced auto type.
static_assert(sizeof(f(1)), ""); // expected-error {{no matching function for call to 'f'}}
}
+
+namespace test10 {
+// Ensure we don't assert here.
+int f(); // expected-note {{candidate}}
+template<typename T> const int k = f(T()); // expected-error {{no matching function}}
+static_assert(k<int> == 1, ""); // expected-note {{instantiation of}}
+}