diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index fe3fce65a9a..bcf3f344e29 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -11382,6 +11382,19 @@ public class AST2CPPTests extends AST2CPPTestBase { parseAndCheckBindings(getAboveComment(), CPP, true /* use GNU extensions */); } + // enum class TestEnum : char { + // }; + // + // void bar(__underlying_type(TestEnum) as) { + // } + // + // void foo() { + // bar('a'); // Invalid arguments 'Candidates are: void bar(@120932903)' + // } + public void testUnderlyingType_568625() throws Exception { + parseAndCheckBindings(getAboveComment(), CPP, true /* use GNU extensions */); + } + // void ptrFunc(void*); // void intFunc(int); // void foo(int* pi, unsigned i) { @@ -13636,6 +13649,7 @@ public class AST2CPPTests extends AST2CPPTestBase { // Test<__is_same(Enum, Enum)>::true_val; // Test<__is_same(Enum, int)>::false_val; // Test<__is_same(EnumChar, char)>::false_val; + // Test<__is_same(__underlying_type(EnumChar), char)>::true_val; // // Test::Value>::false_val; // Test::Value>::true_val; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 96e1d2c47d4..a4a8339066d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -1717,12 +1717,7 @@ public class CPPTemplates { if (type instanceof ICPPUnaryTypeTransformation) { ICPPUnaryTypeTransformation typeTransformation = (ICPPUnaryTypeTransformation) type; IType operand = instantiateType(typeTransformation.getOperand(), context); - switch (typeTransformation.getOperator()) { - case underlying_type: - return TypeTraits.underlyingType(operand); - default: - return null; // shouldn't happen - } + return SemanticUtil.applyTypeTransformation(typeTransformation.getOperator(), operand); } if (type instanceof CPPClosureType) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index 11cc4769f92..80858af908b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -236,7 +236,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedef; -import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnaryTypeTransformation; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownTypeScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariable; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariableTemplate; @@ -2793,7 +2792,12 @@ public class CPPVisitor extends ASTQueries { name = ((IASTEnumerationSpecifier) declSpec).getName(); } else if (declSpec instanceof ICPPASTTypeTransformationSpecifier) { ICPPASTTypeTransformationSpecifier spec = (ICPPASTTypeTransformationSpecifier) declSpec; - return new CPPUnaryTypeTransformation(spec.getOperator(), createType(spec.getOperand())); + IType type = SemanticUtil.applyTypeTransformation(spec.getOperator(), createType(spec.getOperand())); + if (type != null) + return type; + + return ProblemType.UNRESOLVED_NAME; + } else if (declSpec instanceof ICPPASTSimpleDeclSpecifier) { ICPPASTSimpleDeclSpecifier spec = (ICPPASTSimpleDeclSpecifier) declSpec; // Check for decltype(expr) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java index f84d285bad6..ebf6c6d1b86 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java @@ -68,6 +68,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUnaryTypeTransformation; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.parser.Keywords; import org.eclipse.cdt.core.parser.util.ArrayUtil; @@ -945,4 +946,13 @@ public class SemanticUtil { } return result; } + + public static IType applyTypeTransformation(ICPPUnaryTypeTransformation.Operator operator, IType type) { + switch (operator) { + case underlying_type: + return TypeTraits.underlyingType(type); + default: + return null; // shouldn't happen + } + } }