"Invalid Expr argument to DoMarkVarDeclReferenced");
Var->setReferenced();
+ TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind();
+
// If the context is not potentially evaluated, this is not an odr-use and
// does not trigger instantiation.
if (!IsPotentiallyEvaluatedContext(SemaRef)) {
// arguments, where local variables can't be used.
const bool RefersToEnclosingScope =
(SemaRef.CurContext != Var->getDeclContext() &&
- Var->getDeclContext()->isFunctionOrMethod() &&
- Var->hasLocalStorage());
- if (!RefersToEnclosingScope)
- return;
-
- if (LambdaScopeInfo *const LSI = SemaRef.getCurLambda()) {
- // If a variable could potentially be odr-used, defer marking it so
- // until we finish analyzing the full expression for any lvalue-to-rvalue
- // or discarded value conversions that would obviate odr-use.
- // Add it to the list of potential captures that will be analyzed
- // later (ActOnFinishFullExpr) for eventual capture and odr-use marking
- // unless the variable is a reference that was initialized by a constant
- // expression (this will never need to be captured or odr-used).
- assert(E && "Capture variable should be used in an expression.");
- if (!Var->getType()->isReferenceType() ||
- !IsVariableNonDependentAndAConstantExpression(Var, SemaRef.Context))
- LSI->addPotentialCapture(E->IgnoreParens());
+ Var->getDeclContext()->isFunctionOrMethod() && Var->hasLocalStorage());
+ if (RefersToEnclosingScope) {
+ if (LambdaScopeInfo *const LSI = SemaRef.getCurLambda()) {
+ // If a variable could potentially be odr-used, defer marking it so
+ // until we finish analyzing the full expression for any
+ // lvalue-to-rvalue
+ // or discarded value conversions that would obviate odr-use.
+ // Add it to the list of potential captures that will be analyzed
+ // later (ActOnFinishFullExpr) for eventual capture and odr-use marking
+ // unless the variable is a reference that was initialized by a constant
+ // expression (this will never need to be captured or odr-used).
+ assert(E && "Capture variable should be used in an expression.");
+ if (!Var->getType()->isReferenceType() ||
+ !IsVariableNonDependentAndAConstantExpression(Var, SemaRef.Context))
+ LSI->addPotentialCapture(E->IgnoreParens());
+ }
}
- return;
+
+ if (!isTemplateInstantiation(TSK))
+ return;
}
VarTemplateSpecializationDecl *VarSpec =
// templates of class templates, and variable template specializations. Delay
// instantiations of variable templates, except for those that could be used
// in a constant expression.
- TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind();
if (isTemplateInstantiation(TSK)) {
bool TryInstantiating = TSK == TSK_ImplicitInstantiation;
static int a;
};
-template<int N> struct S; // expected-note 2{{here}}
+template<int N> struct S; // expected-note 6{{here}}
template<int N>
-int U<N>::a = S<N>::kError; // expected-error 2{{undefined}}
+int U<N>::a = S<N>::kError; // expected-error 6{{undefined}}
template<typename T>
void f() {
- // FIXME: The standard suggests that U<0>::a is odr-used by this expression,
- // but it's not entirely clear that's the right behaviour.
- (void)alias_ref<int, int&, U<0>::a>();
+ (void)alias_ref<int, int&, U<0>::a>(); // expected-note {{here}}
(void)func_ref<int, int&, U<1>::a>(); // expected-note {{here}}
(void)class_ref<int, int&, U<2>::a>(); // expected-note {{here}}
};
+template<int N>
+void fi() {
+ (void)alias_ref<int, int&, U<N>::a>(); // expected-note {{here}}
+ (void)func_ref<int, int&, U<N+1>::a>(); // expected-note {{here}}
+ (void)class_ref<int, int&, U<N+2>::a>(); // expected-note {{here}}
+};
+
int main() {
- f<int>(); // expected-note 2{{here}}
+ f<int>(); // NOTE: Non-dependent name uses are type-checked at template definition time.
+ fi<10>(); // expected-note 3{{here}}
}
namespace N {
}
int j = f<int>();
}
+