mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-22 14:12:10 +02:00
Bug 545021 - Implement noexcept operator
- Adds getNoexceptSpecifier() to ICPPFunctionType, returning the evaluation for the noexcept specifier. - Adds isNoexcept() to ICPPEvaluation, which returns the result of applying the noexcept operator to the evaluation. - Empty throw() specifier is treated as noexcept(true). - Improves EvalTypeID.isConstantExpression() for conversions. Change-Id: I4c6418aea21bb258693b33d956bc3745918f3759 Signed-off-by: Hannes Vogt <hannes@havogt.de>
This commit is contained in:
parent
0552fcbf97
commit
f938b4d08e
44 changed files with 531 additions and 46 deletions
|
@ -11645,10 +11645,10 @@ public class AST2CPPTests extends AST2CPPTestBase {
|
||||||
ICPPFunction waldo3 = helper.assertNonProblem("waldo3");
|
ICPPFunction waldo3 = helper.assertNonProblem("waldo3");
|
||||||
// constexpr on a function *should not* make its return type const
|
// constexpr on a function *should not* make its return type const
|
||||||
assertSameType(waldo1.getType().getReturnType(), CommonCPPTypes.int_);
|
assertSameType(waldo1.getType().getReturnType(), CommonCPPTypes.int_);
|
||||||
assertSameType(waldo2.getType().getReturnType(),
|
assertSameType(waldo2.getType().getReturnType(), new CPPPointerType(
|
||||||
new CPPPointerType(new CPPFunctionType(CommonCPPTypes.int_, new IType[] { CommonCPPTypes.int_ })));
|
new CPPFunctionType(CommonCPPTypes.int_, new IType[] { CommonCPPTypes.int_ }, null)));
|
||||||
// constexpr on a method *should not* make the method const
|
// constexpr on a method *should not* make the method const
|
||||||
assertSameType(waldo3.getType(), new CPPFunctionType(CommonCPPTypes.int_, new IType[] {}));
|
assertSameType(waldo3.getType(), new CPPFunctionType(CommonCPPTypes.int_, new IType[] {}, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
// void waldo() noexcept;
|
// void waldo() noexcept;
|
||||||
|
@ -13135,4 +13135,211 @@ public class AST2CPPTests extends AST2CPPTestBase {
|
||||||
parseAndCheckImplicitNameBindings();
|
parseAndCheckImplicitNameBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// int fun();
|
||||||
|
// int fun_noexcept() noexcept;
|
||||||
|
// int fun2(int);
|
||||||
|
// int fun2_noexcept(int) noexcept;
|
||||||
|
// constexpr int fun_constexpr() {return 1;}
|
||||||
|
// int (*fptr)();
|
||||||
|
// int (*fptr_noexcept)() noexcept;
|
||||||
|
// bool condition();
|
||||||
|
//
|
||||||
|
// constexpr bool fun_is_not_noexcept = noexcept(fun());
|
||||||
|
// constexpr bool unevaluated_fun_is_noexcept = noexcept(fun);
|
||||||
|
// constexpr bool fun_noexcept_is_noexcept = noexcept(fun_noexcept());
|
||||||
|
// constexpr bool fun2_arg_is_not_noexcept = noexcept(fun2(1));
|
||||||
|
// constexpr bool fun2_noexcept_arg_is_noexcept = noexcept(fun2_noexcept(1));
|
||||||
|
// constexpr bool fun2_noexcept_arg_not_noexcept_is_not_noexcept = noexcept(fun2_noexcept(fun()));
|
||||||
|
// constexpr bool fun_constexpr_is_noexcept = noexcept(fun_constexpr());
|
||||||
|
// constexpr bool fptr_is_not_noexcept = noexcept(fptr());
|
||||||
|
// constexpr bool fptr_noexcept_is_noexcept = noexcept(fptr_noexcept());
|
||||||
|
// constexpr bool throw_is_not_noexcept = noexcept(throw fun_noexcept());
|
||||||
|
public void testNoexceptOperatorFunctions_545021() throws Exception {
|
||||||
|
parseAndCheckBindings();
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
helper.assertVariableValue("fun_is_not_noexcept", 0);
|
||||||
|
helper.assertVariableValue("unevaluated_fun_is_noexcept", 1);
|
||||||
|
helper.assertVariableValue("fun_noexcept_is_noexcept", 1);
|
||||||
|
helper.assertVariableValue("fun2_arg_is_not_noexcept", 0);
|
||||||
|
helper.assertVariableValue("fun2_noexcept_arg_is_noexcept", 1);
|
||||||
|
helper.assertVariableValue("fun2_noexcept_arg_not_noexcept_is_not_noexcept", 0);
|
||||||
|
helper.assertVariableValue("fun_constexpr_is_noexcept", 1);
|
||||||
|
helper.assertVariableValue("fptr_is_not_noexcept", 0);
|
||||||
|
helper.assertVariableValue("fptr_noexcept_is_noexcept", 1);
|
||||||
|
helper.assertVariableValue("throw_is_not_noexcept", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// int fun();
|
||||||
|
// int fun_noexcept() noexcept;
|
||||||
|
// bool condition();
|
||||||
|
// bool noexcept_condition() noexcept;
|
||||||
|
// constexpr bool comma_is_noexcept = noexcept(fun_noexcept(), fun_noexcept());
|
||||||
|
// constexpr bool comma_is_not_noexcept = noexcept(fun(), fun_noexcept());
|
||||||
|
// constexpr bool not_noexcept_conditional = noexcept(noexcept_condition() ? fun() : fun_noexcept());
|
||||||
|
// constexpr bool is_noexcept_conditional = noexcept(noexcept_condition() ? fun_noexcept() : fun_noexcept());
|
||||||
|
// constexpr bool condition_not_noexcept = noexcept(condition() ? fun_noexcept() : fun_noexcept());
|
||||||
|
public void testNoexceptOperatorOperators_545021() throws Exception {
|
||||||
|
parseAndCheckBindings();
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
helper.assertVariableValue("comma_is_noexcept", 1);
|
||||||
|
helper.assertVariableValue("comma_is_not_noexcept", 0);
|
||||||
|
helper.assertVariableValue("not_noexcept_conditional", 0);
|
||||||
|
helper.assertVariableValue("is_noexcept_conditional", 1);
|
||||||
|
helper.assertVariableValue("condition_not_noexcept", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// struct aggregate{
|
||||||
|
// int a;
|
||||||
|
// };
|
||||||
|
// aggregate agg;
|
||||||
|
//
|
||||||
|
// constexpr bool aggregate_init_is_noexcept = noexcept(aggregate{1});
|
||||||
|
// constexpr bool aggregate_access_is_noexcept = noexcept(agg.a);
|
||||||
|
public void testNoexceptOperatorAggregate_545021() throws Exception {
|
||||||
|
parseAndCheckBindings();
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
helper.assertVariableValue("aggregate_init_is_noexcept", 1);
|
||||||
|
helper.assertVariableValue("aggregate_access_is_noexcept", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// struct myclass{
|
||||||
|
// myclass() noexcept{}
|
||||||
|
// myclass(int){}
|
||||||
|
// constexpr myclass(int, int){}
|
||||||
|
// };
|
||||||
|
// constexpr bool ctor_is_noexcept = noexcept(myclass{});
|
||||||
|
// constexpr bool ctor_is_not_noexcept = noexcept(myclass{1});
|
||||||
|
// constexpr bool constexpr_ctor_is_noexcept = noexcept(myclass{1, 1});
|
||||||
|
public void testNoexceptOperatorConstructors_545021() throws Exception {
|
||||||
|
parseAndCheckBindings();
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
helper.assertVariableValue("ctor_is_noexcept", 1);
|
||||||
|
helper.assertVariableValue("ctor_is_not_noexcept", 0);
|
||||||
|
helper.assertVariableValue("constexpr_ctor_is_noexcept", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// struct type {
|
||||||
|
// int mem();
|
||||||
|
// int mem_noexcept() noexcept;
|
||||||
|
// constexpr int constexpr_mem() {return 1;}
|
||||||
|
// operator int() noexcept;
|
||||||
|
// operator int*();
|
||||||
|
// };
|
||||||
|
// type t;
|
||||||
|
// int (type::*memptr)();
|
||||||
|
// int (type::*memptr_noexcept)() noexcept;
|
||||||
|
// constexpr bool mem_is_not_noexcept = noexcept(type{}.mem());
|
||||||
|
// constexpr bool unevaluated_mem_is_noexcept = noexcept(type{}.mem);
|
||||||
|
// constexpr bool mem_noexcept_is_noexcept = noexcept(type{}.mem_noexcept());
|
||||||
|
// constexpr bool constexpr_mem_is_noexcept = noexcept(type{}.constexpr_mem());
|
||||||
|
// constexpr bool memptr_is_not_noexcept = noexcept((type{}.*(memptr))());
|
||||||
|
// constexpr bool unevaluated_memptr_is_noexcept = noexcept((type{}.*(memptr)));
|
||||||
|
// constexpr bool memptr_noexcept_is_noexcept = noexcept((type{}.*(memptr_noexcept))());
|
||||||
|
// constexpr bool noexcept_conversion = noexcept(static_cast<int>(t));
|
||||||
|
// constexpr bool not_noexcept_conversion = noexcept(static_cast<int*>(t));
|
||||||
|
// constexpr bool conversion_from_constructor = noexcept(static_cast<int*>(type{}));
|
||||||
|
public void testNoexceptOperatorType_545021() throws Exception {
|
||||||
|
parseAndCheckBindings();
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
helper.assertVariableValue("mem_is_not_noexcept", 0);
|
||||||
|
helper.assertVariableValue("unevaluated_mem_is_noexcept", 1);
|
||||||
|
helper.assertVariableValue("mem_noexcept_is_noexcept", 1);
|
||||||
|
helper.assertVariableValue("constexpr_mem_is_noexcept", 1);
|
||||||
|
helper.assertVariableValue("memptr_is_not_noexcept", 0);
|
||||||
|
// TODO(havogt): needs implementation of [except.spec] p.14 (c++11) noexcept for implicitly declared special member functions
|
||||||
|
// helper.assertVariableValue("unevaluated_memptr_is_noexcept", 1);
|
||||||
|
helper.assertVariableValue("memptr_noexcept_is_noexcept", 1);
|
||||||
|
helper.assertVariableValue("noexcept_conversion", 1);
|
||||||
|
helper.assertVariableValue("not_noexcept_conversion", 0);
|
||||||
|
helper.assertVariableValue("conversion_from_constructor", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// template<typename T>
|
||||||
|
// int funt(T);
|
||||||
|
// template<typename T>
|
||||||
|
// int funt_noexcept(T) noexcept;
|
||||||
|
//
|
||||||
|
// constexpr bool funt_is_not_noexcept = noexcept(funt(1));
|
||||||
|
// constexpr bool funt_noexcept_is_noexcept = noexcept(funt_noexcept(1));
|
||||||
|
public void testNoexceptOperatorFunctionTemplates_545021() throws Exception {
|
||||||
|
parseAndCheckBindings();
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
helper.assertVariableValue("funt_is_not_noexcept", 0);
|
||||||
|
helper.assertVariableValue("funt_noexcept_is_noexcept", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// struct type1{
|
||||||
|
// void operator=(int);
|
||||||
|
// bool operator!();
|
||||||
|
// };
|
||||||
|
// type1 t1;
|
||||||
|
// struct type2{
|
||||||
|
// void operator=(int) noexcept;
|
||||||
|
// bool operator!() noexcept;
|
||||||
|
// };
|
||||||
|
// type2 t2;
|
||||||
|
// constexpr bool binaryop_is_not_noexcept = noexcept(t1 = 1);
|
||||||
|
// constexpr bool unaryop_is_not_noexcept = noexcept(!t1);
|
||||||
|
// constexpr bool noexcept_binaryop_is_noexcept = noexcept(t2 = 1);
|
||||||
|
// constexpr bool noexcept_unaryop_is_noexcept = noexcept(!t2);
|
||||||
|
public void testNoexceptOperatorOverloadedOperators_545021() throws Exception {
|
||||||
|
parseAndCheckBindings();
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
helper.assertVariableValue("binaryop_is_not_noexcept", 0);
|
||||||
|
helper.assertVariableValue("unaryop_is_not_noexcept", 0);
|
||||||
|
helper.assertVariableValue("noexcept_binaryop_is_noexcept", 1);
|
||||||
|
helper.assertVariableValue("noexcept_unaryop_is_noexcept", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// void fun();
|
||||||
|
// void fun_taking_funptr(void(*ptr)()) noexcept;
|
||||||
|
//
|
||||||
|
// constexpr bool is_noexcept = noexcept(fun_taking_funptr(fun));
|
||||||
|
public void testNoexceptOperatorNoncalledFunctionPtr_545021() throws Exception {
|
||||||
|
parseAndCheckBindings();
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
helper.assertVariableValue("is_noexcept", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// void fun() throw();
|
||||||
|
// constexpr bool is_noexcept = noexcept(fun());
|
||||||
|
public void testNoexceptOperatorEmptyThrow_545021() throws Exception {
|
||||||
|
parseAndCheckBindings();
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
helper.assertVariableValue("is_noexcept", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// auto closure_noexcept = [](int i) noexcept {return i;};
|
||||||
|
// constexpr bool is_noexcept = noexcept(closure_noexcept());
|
||||||
|
// auto closure = [](int i) {return i;};
|
||||||
|
// constexpr bool is_not_noexcept = noexcept(closure());
|
||||||
|
// constexpr bool conversion_is_noexcept = noexcept(static_cast<int (*)(int)>(closure));
|
||||||
|
public void testNoexceptOperatorLambda_545021() throws Exception {
|
||||||
|
parseAndCheckBindings();
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
helper.assertVariableValue("is_noexcept", 1);
|
||||||
|
helper.assertVariableValue("is_not_noexcept", 0);
|
||||||
|
helper.assertVariableValue("conversion_is_noexcept", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// template <bool B>
|
||||||
|
// void foo() noexcept(B);
|
||||||
|
//
|
||||||
|
// constexpr bool is_noexcept = noexcept(foo<true>());
|
||||||
|
// constexpr bool is_not_noexcept = noexcept(foo<false>());
|
||||||
|
public void testNoexceptOperatorDependentNoexcept_545021() throws Exception {
|
||||||
|
parseAndCheckBindings();
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
helper.assertVariableValue("is_noexcept", 1);
|
||||||
|
helper.assertVariableValue("is_not_noexcept", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// struct S { int mem; };
|
||||||
|
// S foo(); // could throw
|
||||||
|
// constexpr bool is_not_noexcept = noexcept(foo().mem); // should be false
|
||||||
|
public void testNoexceptOperatorOwnerEval_545021() throws Exception {
|
||||||
|
parseAndCheckBindings();
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
helper.assertVariableValue("is_not_noexcept", 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2552,4 +2552,12 @@ public class IndexCPPBindingResolutionTest extends IndexBindingResolutionTestBas
|
||||||
public void testOOM_529646() throws Exception {
|
public void testOOM_529646() throws Exception {
|
||||||
checkBindings();
|
checkBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// int foo() noexcept;
|
||||||
|
|
||||||
|
// constexpr bool is_noexcept = noexcept(foo());
|
||||||
|
public void testNoexceptOperator_545021() throws Exception {
|
||||||
|
IVariable isNoexcept = getBindingFromASTName("is_noexcept", 11);
|
||||||
|
assertEquals(1, isNoexcept.getInitialValue().numberValue().longValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||||
import org.eclipse.cdt.core.parser.Keywords;
|
import org.eclipse.cdt.core.parser.Keywords;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLiteralExpression;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLiteralExpression;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* C++ adds a few things to function declarators.
|
* C++ adds a few things to function declarators.
|
||||||
|
@ -154,6 +155,14 @@ public interface ICPPASTFunctionDeclarator extends IASTStandardFunctionDeclarato
|
||||||
*/
|
*/
|
||||||
public ICPPASTExpression getNoexceptExpression();
|
public ICPPASTExpression getNoexceptExpression();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the noexcept evaluation, or {@code null} if no noexcept specification is present, or
|
||||||
|
* or an evaluation representing {@code noexcept(true)} in case of an empty exception specification.
|
||||||
|
* @since 6.7
|
||||||
|
* @noreference This method is not intended to be referenced by clients.
|
||||||
|
*/
|
||||||
|
public ICPPEvaluation getNoexceptEvaluation();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the noexcept expression.
|
* Sets the noexcept expression.
|
||||||
* @since 5.5
|
* @since 5.5
|
||||||
|
|
|
@ -17,6 +17,7 @@ package org.eclipse.cdt.core.dom.ast.cpp;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @noextend This interface is not intended to be extended by clients.
|
* @noextend This interface is not intended to be extended by clients.
|
||||||
|
@ -45,6 +46,13 @@ public interface ICPPFunctionType extends IFunctionType {
|
||||||
*/
|
*/
|
||||||
public boolean isRValueReference();
|
public boolean isRValueReference();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the evaluation object for the noexcept specifier or null if there is no noexcept specifier.
|
||||||
|
* @since 6.7
|
||||||
|
* @noreference This method is not intended to be referenced by clients.
|
||||||
|
*/
|
||||||
|
public ICPPEvaluation getNoexceptSpecifier();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the function type takes variable number of arguments.
|
* Whether the function type takes variable number of arguments.
|
||||||
* @since 5.2
|
* @since 5.2
|
||||||
|
|
|
@ -494,7 +494,7 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider {
|
||||||
theParms[i] = fCpp ? new CPPBuiltinParameter(pType) : new CBuiltinParameter(pType);
|
theParms[i] = fCpp ? new CPPBuiltinParameter(pType) : new CBuiltinParameter(pType);
|
||||||
}
|
}
|
||||||
IType rt = toType(returnType);
|
IType rt = toType(returnType);
|
||||||
IFunctionType ft = fCpp ? new CPPFunctionType(rt, pTypes) : new CFunctionType(rt, pTypes);
|
IFunctionType ft = fCpp ? new CPPFunctionType(rt, pTypes, null) : new CFunctionType(rt, pTypes);
|
||||||
|
|
||||||
IBinding b = fCpp
|
IBinding b = fCpp
|
||||||
? new CPPImplicitFunction(toCharArray(name), fScope, (ICPPFunctionType) ft, (ICPPParameter[]) theParms,
|
? new CPPImplicitFunction(toCharArray(name), fScope, (ICPPFunctionType) ft, (ICPPParameter[]) theParms,
|
||||||
|
@ -608,7 +608,7 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider {
|
||||||
} else if (tstr.equals("va_list")) {
|
} else if (tstr.equals("va_list")) {
|
||||||
// Use 'char*(*)()'
|
// Use 'char*(*)()'
|
||||||
IType rt = toType("char*");
|
IType rt = toType("char*");
|
||||||
t = fCpp ? new CPPPointerType(new CPPFunctionType(rt, IType.EMPTY_TYPE_ARRAY))
|
t = fCpp ? new CPPPointerType(new CPPFunctionType(rt, IType.EMPTY_TYPE_ARRAY, null))
|
||||||
: new CPointerType(new CFunctionType(rt, IType.EMPTY_TYPE_ARRAY), 0);
|
: new CPointerType(new CFunctionType(rt, IType.EMPTY_TYPE_ARRAY), 0);
|
||||||
} else if (tstr.equals("size_t")) {
|
} else if (tstr.equals("size_t")) {
|
||||||
t = toType("unsigned long");
|
t = toType("unsigned long");
|
||||||
|
|
|
@ -18,6 +18,7 @@ import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,4 +82,9 @@ public class ProblemFunctionType extends ProblemType implements ICPPFunctionType
|
||||||
public IPointerType getThisType() {
|
public IPointerType getThisType() {
|
||||||
return new CPPPointerType(new ProblemType(getID()));
|
return new CPPPointerType(new ProblemType(getID()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ICPPEvaluation getNoexceptSpecifier() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class CExternalFunction extends CFunction implements ICExternalBinding {
|
||||||
public IFunctionType getType() {
|
public IFunctionType getType() {
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
// Bug 321856: Prevent recursions
|
// Bug 321856: Prevent recursions
|
||||||
type = new CPPFunctionType(VOID_TYPE, IType.EMPTY_TYPE_ARRAY);
|
type = new CPPFunctionType(VOID_TYPE, IType.EMPTY_TYPE_ARRAY, null);
|
||||||
IFunctionType computedType = createType();
|
IFunctionType computedType = createType();
|
||||||
if (computedType != null) {
|
if (computedType != null) {
|
||||||
type = computedType;
|
type = computedType;
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||||
|
@ -31,11 +32,16 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVirtSpecifier.SpecifierKind;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope;
|
||||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a function declarator.
|
* Represents a function declarator.
|
||||||
*/
|
*/
|
||||||
public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPASTFunctionDeclarator {
|
public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPASTFunctionDeclarator {
|
||||||
|
public static final ICPPEvaluation NOEXCEPT_TRUE = new EvalFixed(CPPBasicType.BOOLEAN, ValueCategory.PRVALUE,
|
||||||
|
IntegralValue.create(true));
|
||||||
|
|
||||||
private ICPPASTParameterDeclaration[] parameters;
|
private ICPPASTParameterDeclaration[] parameters;
|
||||||
private IASTTypeId[] typeIds = NO_EXCEPTION_SPECIFICATION;
|
private IASTTypeId[] typeIds = NO_EXCEPTION_SPECIFICATION;
|
||||||
private ICPPASTExpression noexceptExpression;
|
private ICPPASTExpression noexceptExpression;
|
||||||
|
@ -388,4 +394,14 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ICPPEvaluation getNoexceptEvaluation() {
|
||||||
|
if (getNoexceptExpression() != null) {
|
||||||
|
return getNoexceptExpression().getEvaluation();
|
||||||
|
} else if (getExceptionSpecification() == IASTTypeId.EMPTY_TYPEID_ARRAY) {
|
||||||
|
return NOEXCEPT_TRUE;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPAST
|
||||||
IBinding temp = null;
|
IBinding temp = null;
|
||||||
IType[] newParms = new IType[1];
|
IType[] newParms = new IType[1];
|
||||||
newParms[0] = cpp_size_t;
|
newParms[0] = cpp_size_t;
|
||||||
ICPPFunctionType newFunctionType = new CPPFunctionType(cpp_void_p, newParms);
|
ICPPFunctionType newFunctionType = new CPPFunctionType(cpp_void_p, newParms, null);
|
||||||
ICPPParameter[] newTheParms = new ICPPParameter[1];
|
ICPPParameter[] newTheParms = new ICPPParameter[1];
|
||||||
newTheParms[0] = new CPPBuiltinParameter(newParms[0]);
|
newTheParms[0] = new CPPBuiltinParameter(newParms[0]);
|
||||||
temp = new CPPImplicitFunction(OverloadableOperator.NEW.toCharArray(), theScope, newFunctionType, newTheParms,
|
temp = new CPPImplicitFunction(OverloadableOperator.NEW.toCharArray(), theScope, newFunctionType, newTheParms,
|
||||||
|
@ -120,7 +120,7 @@ public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPAST
|
||||||
temp = null;
|
temp = null;
|
||||||
IType[] deleteParms = new IType[1];
|
IType[] deleteParms = new IType[1];
|
||||||
deleteParms[0] = cpp_void_p;
|
deleteParms[0] = cpp_void_p;
|
||||||
ICPPFunctionType deleteFunctionType = new CPPFunctionType(cpp_void, deleteParms);
|
ICPPFunctionType deleteFunctionType = new CPPFunctionType(cpp_void, deleteParms, null);
|
||||||
ICPPParameter[] deleteTheParms = new ICPPParameter[1];
|
ICPPParameter[] deleteTheParms = new ICPPParameter[1];
|
||||||
deleteTheParms[0] = new CPPBuiltinParameter(deleteParms[0]);
|
deleteTheParms[0] = new CPPBuiltinParameter(deleteParms[0]);
|
||||||
temp = new CPPImplicitFunction(OverloadableOperator.DELETE.toCharArray(), theScope, deleteFunctionType,
|
temp = new CPPImplicitFunction(OverloadableOperator.DELETE.toCharArray(), theScope, deleteFunctionType,
|
||||||
|
|
|
@ -115,7 +115,8 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
|
||||||
// Function call operator
|
// Function call operator
|
||||||
final IType returnType = getReturnType();
|
final IType returnType = getReturnType();
|
||||||
final IType[] parameterTypes = getParameterTypes();
|
final IType[] parameterTypes = getParameterTypes();
|
||||||
ft = new CPPFunctionType(returnType, parameterTypes, !isMutable(), false, false, false, false);
|
ft = new CPPFunctionType(returnType, parameterTypes, getNoexceptEvaluation(), !isMutable(), false, false, false,
|
||||||
|
false);
|
||||||
|
|
||||||
ICPPParameter[] params = getParameters();
|
ICPPParameter[] params = getParameters();
|
||||||
char[] operatorParensName = OverloadableOperator.PAREN.toCharArray();
|
char[] operatorParensName = OverloadableOperator.PAREN.toCharArray();
|
||||||
|
@ -139,8 +140,9 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
|
||||||
|
|
||||||
// Conversion operator
|
// Conversion operator
|
||||||
if (needConversionOperator) {
|
if (needConversionOperator) {
|
||||||
final CPPFunctionType conversionTarget = new CPPFunctionType(returnType, parameterTypes);
|
final CPPFunctionType conversionTarget = new CPPFunctionType(returnType, parameterTypes, null);
|
||||||
ft = new CPPFunctionType(conversionTarget, IType.EMPTY_TYPE_ARRAY, true, false, false, false, false);
|
ft = new CPPFunctionType(conversionTarget, IType.EMPTY_TYPE_ARRAY,
|
||||||
|
CPPASTFunctionDeclarator.NOEXCEPT_TRUE /* (CWG DR 1722) */, true, false, false, false, false);
|
||||||
// Calling CPPASTConversionName.createName(IType) would try to stringize the type to
|
// Calling CPPASTConversionName.createName(IType) would try to stringize the type to
|
||||||
// construct a name, which is unnecessary work (not to mention prone to recursion with
|
// construct a name, which is unnecessary work (not to mention prone to recursion with
|
||||||
// dependent types). Since the name doesn't matter anyways, just make one up.
|
// dependent types). Since the name doesn't matter anyways, just make one up.
|
||||||
|
@ -258,6 +260,13 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
|
||||||
return fParameterTypes;
|
return fParameterTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ICPPEvaluation getNoexceptEvaluation() {
|
||||||
|
ICPPEvaluation eval = null;
|
||||||
|
if (fLambdaExpression.getDeclarator() != null)
|
||||||
|
eval = fLambdaExpression.getDeclarator().getNoexceptEvaluation();
|
||||||
|
return eval;
|
||||||
|
}
|
||||||
|
|
||||||
public ICPPParameter[] getParameters() {
|
public ICPPParameter[] getParameters() {
|
||||||
if (fParameters == null) {
|
if (fParameters == null) {
|
||||||
final IType[] parameterTypes = getParameterTypes();
|
final IType[] parameterTypes = getParameterTypes();
|
||||||
|
|
|
@ -36,7 +36,7 @@ import org.eclipse.core.runtime.CoreException;
|
||||||
public class CPPDeferredFunction extends CPPUnknownBinding
|
public class CPPDeferredFunction extends CPPUnknownBinding
|
||||||
implements ICPPDeferredFunction, ICPPComputableFunction, ISerializableType {
|
implements ICPPDeferredFunction, ICPPComputableFunction, ISerializableType {
|
||||||
private static final ICPPFunctionType FUNCTION_TYPE = new CPPFunctionType(ProblemType.UNKNOWN_FOR_EXPRESSION,
|
private static final ICPPFunctionType FUNCTION_TYPE = new CPPFunctionType(ProblemType.UNKNOWN_FOR_EXPRESSION,
|
||||||
IType.EMPTY_TYPE_ARRAY);
|
IType.EMPTY_TYPE_ARRAY, null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a CPPDeferredFunction given a set of overloaded functions
|
* Creates a CPPDeferredFunction given a set of overloaded functions
|
||||||
|
|
|
@ -37,13 +37,14 @@ public class CPPFunctionType implements ICPPFunctionType, ISerializableType {
|
||||||
private final boolean hasRefQualifier;
|
private final boolean hasRefQualifier;
|
||||||
private final boolean isRValueReference;
|
private final boolean isRValueReference;
|
||||||
private final boolean takesVarargs;
|
private final boolean takesVarargs;
|
||||||
|
private final ICPPEvaluation noexceptSpecifier;
|
||||||
|
|
||||||
public CPPFunctionType(IType returnType, IType[] types) {
|
public CPPFunctionType(IType returnType, IType[] types, ICPPEvaluation noexceptSpecifier) {
|
||||||
this(returnType, types, false, false, false, false, false);
|
this(returnType, types, noexceptSpecifier, false, false, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CPPFunctionType(IType returnType, IType[] types, boolean isConst, boolean isVolatile,
|
public CPPFunctionType(IType returnType, IType[] types, ICPPEvaluation noexceptSpecifier, boolean isConst,
|
||||||
boolean hasRefQualifier, boolean isRValueReference, boolean takesVarargs) {
|
boolean isVolatile, boolean hasRefQualifier, boolean isRValueReference, boolean takesVarargs) {
|
||||||
this.returnType = returnType;
|
this.returnType = returnType;
|
||||||
this.parameters = types;
|
this.parameters = types;
|
||||||
this.isConst = isConst;
|
this.isConst = isConst;
|
||||||
|
@ -51,6 +52,7 @@ public class CPPFunctionType implements ICPPFunctionType, ISerializableType {
|
||||||
this.hasRefQualifier = hasRefQualifier;
|
this.hasRefQualifier = hasRefQualifier;
|
||||||
this.isRValueReference = isRValueReference;
|
this.isRValueReference = isRValueReference;
|
||||||
this.takesVarargs = takesVarargs;
|
this.takesVarargs = takesVarargs;
|
||||||
|
this.noexceptSpecifier = noexceptSpecifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -167,6 +169,7 @@ public class CPPFunctionType implements ICPPFunctionType, ISerializableType {
|
||||||
for (int i = 0; i < parameters.length; i++) {
|
for (int i = 0; i < parameters.length; i++) {
|
||||||
buffer.marshalType(parameters[i]);
|
buffer.marshalType(parameters[i]);
|
||||||
}
|
}
|
||||||
|
buffer.marshalEvaluation(noexceptSpecifier, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IType unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException {
|
public static IType unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException {
|
||||||
|
@ -176,11 +179,18 @@ public class CPPFunctionType implements ICPPFunctionType, ISerializableType {
|
||||||
for (int i = 0; i < pars.length; i++) {
|
for (int i = 0; i < pars.length; i++) {
|
||||||
pars[i] = buffer.unmarshalType();
|
pars[i] = buffer.unmarshalType();
|
||||||
}
|
}
|
||||||
|
ICPPEvaluation noexcept = buffer.unmarshalEvaluation();
|
||||||
boolean isConst = (firstBytes & ITypeMarshalBuffer.FLAG1) != 0;
|
boolean isConst = (firstBytes & ITypeMarshalBuffer.FLAG1) != 0;
|
||||||
boolean takesVarargs = (firstBytes & ITypeMarshalBuffer.FLAG2) != 0;
|
boolean takesVarargs = (firstBytes & ITypeMarshalBuffer.FLAG2) != 0;
|
||||||
boolean isVolatile = (firstBytes & ITypeMarshalBuffer.FLAG3) != 0;
|
boolean isVolatile = (firstBytes & ITypeMarshalBuffer.FLAG3) != 0;
|
||||||
boolean hasRefQualifier = (firstBytes & ITypeMarshalBuffer.FLAG4) != 0;
|
boolean hasRefQualifier = (firstBytes & ITypeMarshalBuffer.FLAG4) != 0;
|
||||||
boolean isRValueReference = (firstBytes & ITypeMarshalBuffer.FLAG5) != 0;
|
boolean isRValueReference = (firstBytes & ITypeMarshalBuffer.FLAG5) != 0;
|
||||||
return new CPPFunctionType(rt, pars, isConst, isVolatile, hasRefQualifier, isRValueReference, takesVarargs);
|
return new CPPFunctionType(rt, pars, noexcept, isConst, isVolatile, hasRefQualifier, isRValueReference,
|
||||||
|
takesVarargs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ICPPEvaluation getNoexceptSpecifier() {
|
||||||
|
return noexceptSpecifier;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
|
||||||
*/
|
*/
|
||||||
public class CPPUnknownMethod extends CPPUnknownMember implements ICPPMethod {
|
public class CPPUnknownMethod extends CPPUnknownMember implements ICPPMethod {
|
||||||
private static final ICPPFunctionType FUNCTION_TYPE = new CPPFunctionType(ProblemType.UNKNOWN_FOR_EXPRESSION,
|
private static final ICPPFunctionType FUNCTION_TYPE = new CPPFunctionType(ProblemType.UNKNOWN_FOR_EXPRESSION,
|
||||||
IType.EMPTY_TYPE_ARRAY);
|
IType.EMPTY_TYPE_ARRAY, null);
|
||||||
|
|
||||||
public CPPUnknownMethod(IType owner, char[] name) {
|
public CPPUnknownMethod(IType owner, char[] name) {
|
||||||
super(owner, name);
|
super(owner, name);
|
||||||
|
|
|
@ -51,6 +51,12 @@ public interface ICPPEvaluation {
|
||||||
*/
|
*/
|
||||||
boolean isConstantExpression();
|
boolean isConstantExpression();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the result of the noexcept-operator applied to the expression.
|
||||||
|
* [expr.unary.noexcept]
|
||||||
|
*/
|
||||||
|
boolean isNoexcept();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns {@code true} if this expression is equivalent to 'other' for
|
* Returns {@code true} if this expression is equivalent to 'other' for
|
||||||
* declaration matching purposes.
|
* declaration matching purposes.
|
||||||
|
|
|
@ -41,7 +41,7 @@ class AutoTypeResolver implements ICPPFunctionTemplate {
|
||||||
private final CPPFunctionType functionType;
|
private final CPPFunctionType functionType;
|
||||||
|
|
||||||
public AutoTypeResolver(IType paramType) {
|
public AutoTypeResolver(IType paramType) {
|
||||||
functionType = new CPPFunctionType(new CPPBasicType(Kind.eVoid, 0), new IType[] { paramType });
|
functionType = new CPPFunctionType(new CPPBasicType(Kind.eVoid, 0), new IType[] { paramType }, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -555,7 +555,7 @@ class BuiltinOperators {
|
||||||
|
|
||||||
private void addFunction(IType returnType, IType[] parameterTypes) {
|
private void addFunction(IType returnType, IType[] parameterTypes) {
|
||||||
ICPPParameter[] parameter = new ICPPParameter[parameterTypes.length];
|
ICPPParameter[] parameter = new ICPPParameter[parameterTypes.length];
|
||||||
ICPPFunctionType functionType = new CPPFunctionType(returnType, parameterTypes);
|
ICPPFunctionType functionType = new CPPFunctionType(returnType, parameterTypes, null);
|
||||||
String sig = ASTTypeUtil.getType(functionType, true);
|
String sig = ASTTypeUtil.getType(functionType, true);
|
||||||
if (fSignatures == null) {
|
if (fSignatures == null) {
|
||||||
fSignatures = new HashSet<>();
|
fSignatures = new HashSet<>();
|
||||||
|
|
|
@ -172,9 +172,10 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
|
||||||
* @param argument the evaluation to convert
|
* @param argument the evaluation to convert
|
||||||
* @param targetType the type to convert to
|
* @param targetType the type to convert to
|
||||||
* @param allowContextualConversion enable/disable explicit contextual conversion
|
* @param allowContextualConversion enable/disable explicit contextual conversion
|
||||||
|
* @param onlyConstexprConversion allow only constexpr conversion operators
|
||||||
*/
|
*/
|
||||||
protected static ICPPEvaluation maybeApplyConversion(ICPPEvaluation argument, IType targetType,
|
protected static ICPPEvaluation maybeApplyConversion(ICPPEvaluation argument, IType targetType,
|
||||||
boolean allowContextualConversion) {
|
boolean allowContextualConversion, boolean onlyConstexprConversion) {
|
||||||
if (targetType == null) {
|
if (targetType == null) {
|
||||||
return argument;
|
return argument;
|
||||||
}
|
}
|
||||||
|
@ -195,7 +196,7 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
|
||||||
targetType, false, allowContextualConversion);
|
targetType, false, allowContextualConversion);
|
||||||
ICPPFunction conversion = cost.getUserDefinedConversion();
|
ICPPFunction conversion = cost.getUserDefinedConversion();
|
||||||
if (conversion != null) {
|
if (conversion != null) {
|
||||||
if (!conversion.isConstexpr()) {
|
if (onlyConstexprConversion && !conversion.isConstexpr()) {
|
||||||
return EvalFixed.INCOMPLETE;
|
return EvalFixed.INCOMPLETE;
|
||||||
}
|
}
|
||||||
ICPPEvaluation eval = new EvalMemberAccess(uqType, valueCategory, conversion, argument, false,
|
ICPPEvaluation eval = new EvalMemberAccess(uqType, valueCategory, conversion, argument, false,
|
||||||
|
|
|
@ -4132,7 +4132,7 @@ public class CPPSemantics {
|
||||||
parms[i] = t;
|
parms[i] = t;
|
||||||
theParms[i] = new CPPBuiltinParameter(t);
|
theParms[i] = new CPPBuiltinParameter(t);
|
||||||
}
|
}
|
||||||
ICPPFunctionType functionType = new CPPFunctionType(returnType, parms);
|
ICPPFunctionType functionType = new CPPFunctionType(returnType, parms, null);
|
||||||
return new CPPImplicitFunction(CALL_FUNCTION, scope, functionType, theParms, false, false);
|
return new CPPImplicitFunction(CALL_FUNCTION, scope, functionType, theParms, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1559,7 +1559,10 @@ public class CPPTemplates {
|
||||||
IType[] params = instantiateTypes(ps, context);
|
IType[] params = instantiateTypes(ps, context);
|
||||||
final IType r = ft.getReturnType();
|
final IType r = ft.getReturnType();
|
||||||
IType ret = instantiateType(r, context);
|
IType ret = instantiateType(r, context);
|
||||||
if (ret == r && params == ps) {
|
ICPPEvaluation noex = ft.getNoexceptSpecifier();
|
||||||
|
ICPPEvaluation noexcept = noex == null ? null
|
||||||
|
: noex.instantiate(context, IntegralValue.MAX_RECURSION_DEPTH);
|
||||||
|
if (ret == r && params == ps && noexcept == noex) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
// The parameter types need to be adjusted.
|
// The parameter types need to be adjusted.
|
||||||
|
@ -1569,7 +1572,8 @@ public class CPPTemplates {
|
||||||
params[i] = CPPVisitor.adjustParameterType(p, true);
|
params[i] = CPPVisitor.adjustParameterType(p, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new CPPFunctionType(ret, params, ft.isConst(), ft.isVolatile(), ft.hasRefQualifier(),
|
|
||||||
|
return new CPPFunctionType(ret, params, noexcept, ft.isConst(), ft.isVolatile(), ft.hasRefQualifier(),
|
||||||
ft.isRValueReference(), ft.takesVarArgs());
|
ft.isRValueReference(), ft.takesVarArgs());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2609,8 +2613,8 @@ public class CPPTemplates {
|
||||||
IType[] parameterTypesWithExplicitArguments = Arrays.copyOf(originalType.getParameterTypes(),
|
IType[] parameterTypesWithExplicitArguments = Arrays.copyOf(originalType.getParameterTypes(),
|
||||||
nExplicitArgs);
|
nExplicitArgs);
|
||||||
return new CPPFunctionType(originalType.getReturnType(), parameterTypesWithExplicitArguments,
|
return new CPPFunctionType(originalType.getReturnType(), parameterTypesWithExplicitArguments,
|
||||||
originalType.isConst(), originalType.isVolatile(), originalType.hasRefQualifier(),
|
originalType.getNoexceptSpecifier(), originalType.isConst(), originalType.isVolatile(),
|
||||||
originalType.isRValueReference(), originalType.takesVarArgs());
|
originalType.hasRefQualifier(), originalType.isRValueReference(), originalType.takesVarArgs());
|
||||||
} else
|
} else
|
||||||
return originalType;
|
return originalType;
|
||||||
}
|
}
|
||||||
|
@ -2966,7 +2970,7 @@ public class CPPTemplates {
|
||||||
Cost cost = Conversions.checkImplicitConversionSequence(p, a, LVALUE, UDCMode.FORBIDDEN, Context.ORDINARY);
|
Cost cost = Conversions.checkImplicitConversionSequence(p, a, LVALUE, UDCMode.FORBIDDEN, Context.ORDINARY);
|
||||||
if (cost == null || !cost.converts()) {
|
if (cost == null || !cost.converts()) {
|
||||||
ICPPEvaluation eval = arg.getNonTypeEvaluation();
|
ICPPEvaluation eval = arg.getNonTypeEvaluation();
|
||||||
ICPPEvaluation newEval = CPPEvaluation.maybeApplyConversion(eval, p, false);
|
ICPPEvaluation newEval = CPPEvaluation.maybeApplyConversion(eval, p, false, true);
|
||||||
if (newEval == EvalFixed.INCOMPLETE && newEval != eval)
|
if (newEval == EvalFixed.INCOMPLETE && newEval != eval)
|
||||||
return null;
|
return null;
|
||||||
return new CPPTemplateNonTypeArgument(newEval);
|
return new CPPTemplateNonTypeArgument(newEval);
|
||||||
|
|
|
@ -1899,7 +1899,9 @@ public class CPPVisitor extends ASTQueries {
|
||||||
pTypes[i] = pt;
|
pTypes[i] = pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new CPPFunctionType(returnType, pTypes, isConst, isVolatile, false, false, false);
|
return new CPPFunctionType(returnType, pTypes,
|
||||||
|
null /* TODO(havogt) [except.spec] p.14 (c++11) noexcept for implicitly declared special member functions not implemented */,
|
||||||
|
isConst, isVolatile, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1946,8 +1948,8 @@ public class CPPVisitor extends ASTQueries {
|
||||||
}
|
}
|
||||||
|
|
||||||
RefQualifier refQualifier = fnDtor.getRefQualifier();
|
RefQualifier refQualifier = fnDtor.getRefQualifier();
|
||||||
CPPFunctionType type = new CPPFunctionType(returnType, pTypes, fnDtor.isConst(), fnDtor.isVolatile(),
|
CPPFunctionType type = new CPPFunctionType(returnType, pTypes, fnDtor.getNoexceptEvaluation(), fnDtor.isConst(),
|
||||||
refQualifier != null, refQualifier == RefQualifier.RVALUE, fnDtor.takesVarArgs());
|
fnDtor.isVolatile(), refQualifier != null, refQualifier == RefQualifier.RVALUE, fnDtor.takesVarArgs());
|
||||||
final IASTDeclarator nested = fnDtor.getNestedDeclarator();
|
final IASTDeclarator nested = fnDtor.getNestedDeclarator();
|
||||||
if (nested != null) {
|
if (nested != null) {
|
||||||
return createType(type, nested);
|
return createType(type, nested);
|
||||||
|
@ -2546,8 +2548,9 @@ public class CPPVisitor extends ASTQueries {
|
||||||
// above.
|
// above.
|
||||||
IType[] pTypes = createParameterTypes(declarator);
|
IType[] pTypes = createParameterTypes(declarator);
|
||||||
RefQualifier refQualifier = declarator.getRefQualifier();
|
RefQualifier refQualifier = declarator.getRefQualifier();
|
||||||
IType result = new CPPFunctionType(returnType, pTypes, declarator.isConst(), declarator.isVolatile(),
|
IType result = new CPPFunctionType(returnType, pTypes, declarator.getNoexceptEvaluation(),
|
||||||
refQualifier != null, refQualifier == RefQualifier.RVALUE, declarator.takesVarArgs());
|
declarator.isConst(), declarator.isVolatile(), refQualifier != null,
|
||||||
|
refQualifier == RefQualifier.RVALUE, declarator.takesVarArgs());
|
||||||
final IASTDeclarator nested = declarator.getNestedDeclarator();
|
final IASTDeclarator nested = declarator.getNestedDeclarator();
|
||||||
if (nested != null) {
|
if (nested != null) {
|
||||||
result = createType(result, nested);
|
result = createType(result, nested);
|
||||||
|
|
|
@ -184,8 +184,8 @@ public class EvalBinary extends CPPDependentEvaluation {
|
||||||
IType[] parameterTypes = SemanticUtil.getParameterTypesIncludingImplicitThis(overload);
|
IType[] parameterTypes = SemanticUtil.getParameterTypesIncludingImplicitThis(overload);
|
||||||
if (parameterTypes.length >= 2) {
|
if (parameterTypes.length >= 2) {
|
||||||
boolean allowContextualConversion = operatorAllowsContextualConversion();
|
boolean allowContextualConversion = operatorAllowsContextualConversion();
|
||||||
arg1 = maybeApplyConversion(fArg1, parameterTypes[0], allowContextualConversion);
|
arg1 = maybeApplyConversion(fArg1, parameterTypes[0], allowContextualConversion, true);
|
||||||
arg2 = maybeApplyConversion(fArg2, parameterTypes[1], allowContextualConversion);
|
arg2 = maybeApplyConversion(fArg2, parameterTypes[1], allowContextualConversion, true);
|
||||||
} else {
|
} else {
|
||||||
CCorePlugin.log(IStatus.ERROR, "Unexpected overload for binary operator " + fOperator //$NON-NLS-1$
|
CCorePlugin.log(IStatus.ERROR, "Unexpected overload for binary operator " + fOperator //$NON-NLS-1$
|
||||||
+ ": '" + overload.getName() + "'"); //$NON-NLS-1$//$NON-NLS-2$
|
+ ": '" + overload.getName() + "'"); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
|
@ -611,4 +611,14 @@ public class EvalBinary extends CPPDependentEvaluation {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return fArg1.toString() + " <op> " + fArg2.toString(); //$NON-NLS-1$
|
return fArg1.toString() + " <op> " + fArg2.toString(); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoexcept() {
|
||||||
|
ICPPFunction overload = getOverload();
|
||||||
|
if (overload != null) {
|
||||||
|
if (!EvalUtil.evaluateNoexceptSpecifier(overload.getType().getNoexceptSpecifier()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return fArg1.isNoexcept() && fArg2.isNoexcept();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,4 +167,9 @@ public class EvalBinaryTypeId extends CPPDependentEvaluation {
|
||||||
public boolean referencesTemplateParameter() {
|
public boolean referencesTemplateParameter() {
|
||||||
return isValueDependent();
|
return isValueDependent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoexcept() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -532,4 +532,9 @@ public class EvalBinding extends CPPDependentEvaluation {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getBinding().toString();
|
return getBinding().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoexcept() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -265,4 +265,18 @@ public class EvalComma extends CPPDependentEvaluation {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoexcept() {
|
||||||
|
if (getOverloads() != null)
|
||||||
|
for (ICPPFunction overload : getOverloads()) {
|
||||||
|
if (overload != null && !EvalUtil.evaluateNoexceptSpecifier(overload.getType().getNoexceptSpecifier()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (ICPPEvaluation arg : fArguments) {
|
||||||
|
if (!arg.isNoexcept())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,4 +188,9 @@ public final class EvalCompositeAccess implements ICPPEvaluation {
|
||||||
int elementId = buffer.getInt();
|
int elementId = buffer.getInt();
|
||||||
return new EvalCompositeAccess(parent, elementId);
|
return new EvalCompositeAccess(parent, elementId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoexcept() {
|
||||||
|
return parent.isNoexcept();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,4 +142,9 @@ public class EvalCompoundStatementExpression extends CPPDependentEvaluation {
|
||||||
public boolean referencesTemplateParameter() {
|
public boolean referencesTemplateParameter() {
|
||||||
return fDelegate.referencesTemplateParameter();
|
return fDelegate.referencesTemplateParameter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoexcept() {
|
||||||
|
return fDelegate.isNoexcept();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -417,4 +417,9 @@ public class EvalConditional extends CPPDependentEvaluation {
|
||||||
|| (fPositive != null && fPositive.referencesTemplateParameter())
|
|| (fPositive != null && fPositive.referencesTemplateParameter())
|
||||||
|| fNegative.referencesTemplateParameter();
|
|| fNegative.referencesTemplateParameter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoexcept() {
|
||||||
|
return fCondition.isNoexcept() && fPositive.isNoexcept() && fNegative.isNoexcept();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -391,4 +391,9 @@ public final class EvalConstructor extends CPPDependentEvaluation {
|
||||||
|
|
||||||
return new EvalConstructor(newType, newConstructor, newArguments, getTemplateDefinition());
|
return new EvalConstructor(newType, newConstructor, newArguments, getTemplateDefinition());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoexcept() {
|
||||||
|
return EvalUtil.evaluateNoexceptSpecifier(fConstructor.getType().getNoexceptSpecifier());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,4 +226,9 @@ public final class EvalFixed extends CPPEvaluation {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return fType.toString() + ": " + fValue.toString(); //$NON-NLS-1$
|
return fType.toString() + ": " + fValue.toString(); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoexcept() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -33,6 +33,7 @@ import org.eclipse.cdt.core.dom.ast.IValue;
|
||||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
||||||
|
@ -42,6 +43,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.CompositeValue;
|
import org.eclipse.cdt.internal.core.dom.parser.CompositeValue;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.DependentValue;
|
import org.eclipse.cdt.internal.core.dom.parser.DependentValue;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
|
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClosureType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPExecution;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPExecution;
|
||||||
|
@ -126,7 +128,7 @@ public final class EvalFunctionCall extends CPPDependentEvaluation {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean computeIsConstantExpression() {
|
private boolean computeIsConstantExpression() {
|
||||||
return areAllConstantExpressions(fArguments) && isNullOrConstexprFunc(getOverload());
|
return areAllConstantExpressions(fArguments) && isNullOrConstexprFunc(resolveFunctionBinding());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -425,7 +427,7 @@ public final class EvalFunctionCall extends CPPDependentEvaluation {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (j < arguments.length) {
|
if (j < arguments.length) {
|
||||||
ICPPEvaluation argument = maybeApplyConversion(arguments[j++], param.getType(), false);
|
ICPPEvaluation argument = maybeApplyConversion(arguments[j++], param.getType(), false, true);
|
||||||
record.update(param, argument);
|
record.update(param, argument);
|
||||||
} else if (param.hasDefaultValue()) {
|
} else if (param.hasDefaultValue()) {
|
||||||
IValue value = param.getDefaultValue();
|
IValue value = param.getDefaultValue();
|
||||||
|
@ -495,4 +497,37 @@ public final class EvalFunctionCall extends CPPDependentEvaluation {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ICPPFunctionType resolveFunctionType() {
|
||||||
|
ICPPFunction function = resolveFunctionBinding();
|
||||||
|
if (function != null) {
|
||||||
|
return function.getType();
|
||||||
|
}
|
||||||
|
IType result = fArguments[0].getType();
|
||||||
|
if (result instanceof IPointerType) {
|
||||||
|
result = ((IPointerType) result).getType();
|
||||||
|
} else if (result instanceof CPPClosureType) {
|
||||||
|
result = ((CPPClosureType) result).getFunctionCallOperator().getType();
|
||||||
|
}
|
||||||
|
if (result instanceof ICPPFunctionType) {
|
||||||
|
return (ICPPFunctionType) result;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoexcept() {
|
||||||
|
ICPPFunctionType fctType = resolveFunctionType();
|
||||||
|
if (fctType != null) {
|
||||||
|
if (!EvalUtil.evaluateNoexceptSpecifier(fctType.getNoexceptSpecifier()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < fArguments.length; i++) {
|
||||||
|
ICPPEvaluation eval = fArguments[i];
|
||||||
|
if (!eval.isNoexcept())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -380,4 +380,10 @@ public class EvalFunctionSet extends CPPDependentEvaluation {
|
||||||
public boolean referencesTemplateParameter() {
|
public boolean referencesTemplateParameter() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoexcept() {
|
||||||
|
assert false; // Shouldn't exist outside of a dependent context
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -513,4 +513,10 @@ public class EvalID extends CPPDependentEvaluation {
|
||||||
public boolean referencesTemplateParameter() {
|
public boolean referencesTemplateParameter() {
|
||||||
return fFieldOwner != null && fFieldOwner.referencesTemplateParameter();
|
return fFieldOwner != null && fFieldOwner.referencesTemplateParameter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoexcept() {
|
||||||
|
assert false; // Shouldn't exist outside of a dependent context
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,4 +180,13 @@ public class EvalInitList extends CPPDependentEvaluation {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoexcept() {
|
||||||
|
for (ICPPEvaluation eval : getClauses()) {
|
||||||
|
if (!eval.isNoexcept())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -470,4 +470,9 @@ public class EvalMemberAccess extends CPPDependentEvaluation {
|
||||||
public boolean referencesTemplateParameter() {
|
public boolean referencesTemplateParameter() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoexcept() {
|
||||||
|
return fOwnerEval.isNoexcept();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,4 +169,9 @@ public class EvalNaryTypeId extends CPPDependentEvaluation {
|
||||||
IBinding templateDefinition = buffer.unmarshalBinding();
|
IBinding templateDefinition = buffer.unmarshalBinding();
|
||||||
return new EvalNaryTypeId(Operator.values()[op], operands, templateDefinition);
|
return new EvalNaryTypeId(Operator.values()[op], operands, templateDefinition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoexcept() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,4 +145,10 @@ public class EvalPackExpansion extends CPPDependentEvaluation {
|
||||||
IBinding templateDefinition = buffer.unmarshalBinding();
|
IBinding templateDefinition = buffer.unmarshalBinding();
|
||||||
return new EvalPackExpansion(expansionPattern, templateDefinition);
|
return new EvalPackExpansion(expansionPattern, templateDefinition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoexcept() {
|
||||||
|
assert false; // Shouldn't exist outside of a dependent context
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -193,4 +193,10 @@ public class EvalReference extends CPPDependentEvaluation {
|
||||||
return new EvalReference(record, referredBinding, templateDefinition);
|
return new EvalReference(record, referredBinding, templateDefinition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoexcept() {
|
||||||
|
assert false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,6 +250,12 @@ public class EvalTypeId extends CPPDependentEvaluation {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean computeIsConstantExpression() {
|
private boolean computeIsConstantExpression() {
|
||||||
|
if (getConstructor() == null && fArguments.length == 1) {
|
||||||
|
// maybe EvalTypeID represents a conversion
|
||||||
|
ICPPEvaluation conversionEval = maybeApplyConversion(fArguments[0], fInputType, false, false);
|
||||||
|
if (!conversionEval.isConstantExpression())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return !fRepresentsNewExpression && areAllConstantExpressions(fArguments)
|
return !fRepresentsNewExpression && areAllConstantExpressions(fArguments)
|
||||||
&& isNullOrConstexprFunc(getConstructor());
|
&& isNullOrConstexprFunc(getConstructor());
|
||||||
}
|
}
|
||||||
|
@ -477,4 +483,24 @@ public class EvalTypeId extends CPPDependentEvaluation {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoexcept() {
|
||||||
|
if (getConstructor() instanceof CPPFunction) {
|
||||||
|
CPPFunction f = (CPPFunction) getConstructor();
|
||||||
|
if (f != AGGREGATE_INITIALIZATION) {
|
||||||
|
if (!EvalUtil.evaluateNoexceptSpecifier(f.getType().getNoexceptSpecifier()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (fArguments.length == 1) {
|
||||||
|
// maybe EvalTypeID represents a conversion
|
||||||
|
ICPPEvaluation conversionEval = maybeApplyConversion(fArguments[0], fInputType, false, false);
|
||||||
|
return conversionEval.isNoexcept();
|
||||||
|
}
|
||||||
|
for (ICPPEvaluation arg : fArguments) {
|
||||||
|
if (!arg.isNoexcept())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -313,7 +313,7 @@ public class EvalUnary extends CPPDependentEvaluation {
|
||||||
if (parameterTypes.length == 0)
|
if (parameterTypes.length == 0)
|
||||||
return IntegralValue.ERROR;
|
return IntegralValue.ERROR;
|
||||||
IType targetType = parameterTypes[0];
|
IType targetType = parameterTypes[0];
|
||||||
arg = maybeApplyConversion(arg, targetType, fOperator == op_not);
|
arg = maybeApplyConversion(arg, targetType, fOperator == op_not, false);
|
||||||
|
|
||||||
if (!(overload instanceof CPPImplicitFunction)) {
|
if (!(overload instanceof CPPImplicitFunction)) {
|
||||||
if (!overload.isConstexpr())
|
if (!overload.isConstexpr())
|
||||||
|
@ -334,7 +334,11 @@ public class EvalUnary extends CPPDependentEvaluation {
|
||||||
return info == null ? IntegralValue.UNKNOWN : IntegralValue.create(info.alignment);
|
return info == null ? IntegralValue.UNKNOWN : IntegralValue.create(info.alignment);
|
||||||
}
|
}
|
||||||
case op_noexcept:
|
case op_noexcept:
|
||||||
return IntegralValue.UNKNOWN; // TODO(sprigogin): Implement
|
// [expr.unary.noexcept]
|
||||||
|
if (arg.isConstantExpression())
|
||||||
|
return IntegralValue.create(true);
|
||||||
|
else
|
||||||
|
return IntegralValue.create(arg.isNoexcept());
|
||||||
case op_sizeofParameterPack:
|
case op_sizeofParameterPack:
|
||||||
IValue opVal = fArgument.getValue();
|
IValue opVal = fArgument.getValue();
|
||||||
return IntegralValue.create(opVal.numberOfSubValues());
|
return IntegralValue.create(opVal.numberOfSubValues());
|
||||||
|
@ -523,4 +527,16 @@ public class EvalUnary extends CPPDependentEvaluation {
|
||||||
public boolean referencesTemplateParameter() {
|
public boolean referencesTemplateParameter() {
|
||||||
return fArgument.referencesTemplateParameter();
|
return fArgument.referencesTemplateParameter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoexcept() {
|
||||||
|
if (fOperator == op_throw)
|
||||||
|
return false;
|
||||||
|
ICPPFunction overload = getOverload();
|
||||||
|
if (overload != null) {
|
||||||
|
if (!EvalUtil.evaluateNoexceptSpecifier(overload.getType().getNoexceptSpecifier()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return fArgument.isNoexcept();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -297,4 +297,9 @@ public class EvalUnaryTypeID extends CPPDependentEvaluation {
|
||||||
}
|
}
|
||||||
return EvalFixed.INCOMPLETE;
|
return EvalFixed.INCOMPLETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoexcept() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,4 +203,13 @@ public class EvalUtil {
|
||||||
public static boolean isDefaultConstructor(ICPPConstructor constructor) {
|
public static boolean isDefaultConstructor(ICPPConstructor constructor) {
|
||||||
return constructor.getRequiredArgumentCount() == 0;
|
return constructor.getRequiredArgumentCount() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean evaluateNoexceptSpecifier(ICPPEvaluation noexceptSpecifier) {
|
||||||
|
if (noexceptSpecifier != null && noexceptSpecifier.getValue() instanceof IntegralValue) {
|
||||||
|
IntegralValue v = (IntegralValue) noexceptSpecifier.getValue();
|
||||||
|
if (v.numberValue() != null)
|
||||||
|
return v.numberValue().longValue() == 1;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -361,8 +361,8 @@ public class SemanticUtil {
|
||||||
if (ret == r && params == ps) {
|
if (ret == r && params == ps) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
return new CPPFunctionType(ret, params, ft.isConst(), ft.isVolatile(), ft.hasRefQualifier(),
|
return new CPPFunctionType(ret, params, ft.getNoexceptSpecifier(), ft.isConst(), ft.isVolatile(),
|
||||||
ft.isRValueReference(), ft.takesVarArgs());
|
ft.hasRefQualifier(), ft.isRValueReference(), ft.takesVarArgs());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type instanceof ITypedef) {
|
if (type instanceof ITypedef) {
|
||||||
|
|
|
@ -178,8 +178,10 @@ public class CPPCompositesFactory extends AbstractCompositeFactory {
|
||||||
IType r2 = getCompositeType(r);
|
IType r2 = getCompositeType(r);
|
||||||
IType[] p = ft.getParameterTypes();
|
IType[] p = ft.getParameterTypes();
|
||||||
IType[] p2 = getCompositeTypes(p);
|
IType[] p2 = getCompositeTypes(p);
|
||||||
if (r != r2 || p != p2) {
|
ICPPEvaluation n = ft.getNoexceptSpecifier();
|
||||||
return new CPPFunctionType(r2, p2, ft.isConst(), ft.isVolatile(), ft.hasRefQualifier(),
|
ICPPEvaluation n2 = getCompositeEvaluation(n);
|
||||||
|
if (r != r2 || p != p2 || n != n2) {
|
||||||
|
return new CPPFunctionType(r2, p2, n2, ft.isConst(), ft.isVolatile(), ft.hasRefQualifier(),
|
||||||
ft.isRValueReference(), ft.takesVarArgs());
|
ft.isRValueReference(), ft.takesVarArgs());
|
||||||
}
|
}
|
||||||
return ft;
|
return ft;
|
||||||
|
|
|
@ -296,10 +296,13 @@ public class PDOM extends PlatformObject implements IPDOM {
|
||||||
* CDT 9.5 development (version not supported on the 9.4.x branch)
|
* CDT 9.5 development (version not supported on the 9.4.x branch)
|
||||||
* 212.0 - C++ constexpr if and if init-statement evaluation
|
* 212.0 - C++ constexpr if and if init-statement evaluation
|
||||||
* 213.0 - C++ switch init-statement evaluation
|
* 213.0 - C++ switch init-statement evaluation
|
||||||
|
*
|
||||||
|
* CDT 9.8 development (version not supported on the 9.7.x branch)
|
||||||
|
* 214.0 - Noexcept specifier in CPPFunctionType, bug 545021
|
||||||
*/
|
*/
|
||||||
private static final int MIN_SUPPORTED_VERSION = version(213, 0);
|
private static final int MIN_SUPPORTED_VERSION = version(214, 0);
|
||||||
private static final int MAX_SUPPORTED_VERSION = version(213, Short.MAX_VALUE);
|
private static final int MAX_SUPPORTED_VERSION = version(214, Short.MAX_VALUE);
|
||||||
private static final int DEFAULT_VERSION = version(213, 0);
|
private static final int DEFAULT_VERSION = version(214, 0);
|
||||||
|
|
||||||
private static int version(int major, int minor) {
|
private static int version(int major, int minor) {
|
||||||
return (major << 16) + minor;
|
return (major << 16) + minor;
|
||||||
|
|
Loading…
Add table
Reference in a new issue