1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 17:05:26 +02:00

Bug 516290 - Correct computation of decltype(expr) for dependent expressions

Change-Id: Iabc49563e85e8649a94a77210eb066253925ea3c
This commit is contained in:
Nathan Ridge 2017-05-07 20:38:59 -04:00
parent b564575d51
commit 9c0d9fec08
3 changed files with 44 additions and 2 deletions

View file

@ -10216,6 +10216,22 @@ public class AST2TemplateTests extends AST2TestBase {
parseAndCheckBindings();
}
// struct S {
// int& foo();
// };
//
// template<typename T>
// decltype(S().foo()) bar();
//
// void waldo(int&);
//
// int main() {
// waldo(bar<S>());
// }
public void testDependentMemberAccess_516290() throws Exception {
parseAndCheckBindings();
}
// template <typename>
// struct A;
//

View file

@ -4410,4 +4410,29 @@ public class CPPSemantics {
public static boolean isUsingPromiscuousBindingResolution() {
return fAllowPromiscuousBindingResolution.get();
}
/**
* Compute decltype(expr) for an expression represented by an evaluation.
* This is similar to CPPVisitor.getDeclType(IASTExpression), but used in cases where the
* original expression was dependent, so we had to represent it as an evaluation and
* instantiate it.
*
* @param eval the (instantiated) evaluation representing the expression
* @param point
*/
public static IType getDeclTypeForEvaluation(ICPPEvaluation eval, IASTNode point) {
IType expressionType = eval.getType(point);
boolean namedEntity = eval instanceof EvalBinding || eval instanceof EvalMemberAccess;
if (!namedEntity && !(expressionType instanceof ICPPReferenceType)) {
switch (eval.getValueCategory(point)) {
case XVALUE:
return new CPPReferenceType(expressionType, true);
case LVALUE:
return new CPPReferenceType(expressionType, false);
case PRVALUE:
break;
}
}
return expressionType;
}
}

View file

@ -1525,8 +1525,9 @@ public class CPPTemplates {
if (type instanceof TypeOfDependentExpression) {
ICPPEvaluation eval = ((TypeOfDependentExpression) type).getEvaluation();
ICPPEvaluation instantiated = eval.instantiate(context, IntegralValue.MAX_RECURSION_DEPTH);
if (instantiated != eval)
return instantiated.getType(context.getPoint());
if (instantiated != eval) {
return CPPSemantics.getDeclTypeForEvaluation(instantiated, context.getPoint());
}
} else {
IBinding binding= resolveUnknown((ICPPUnknownBinding) type, context);
if (binding instanceof IType)