mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-22 14:12:10 +02:00
Bug 484618 - Implicit names for calls to user-defined literal operators
Change-Id: I15df0f5729b5c4ba6c557789be5db56baaf3afbc Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
This commit is contained in:
parent
2cc3e248b4
commit
60e390b0e4
5 changed files with 85 additions and 11 deletions
|
@ -11622,7 +11622,14 @@ public class AST2CPPTests extends AST2TestBase {
|
||||||
BindingAssertionHelper bh = getAssertionHelper();
|
BindingAssertionHelper bh = getAssertionHelper();
|
||||||
ICPPVariable test = bh.assertNonProblemOnFirstIdentifier("test");
|
ICPPVariable test = bh.assertNonProblemOnFirstIdentifier("test");
|
||||||
assertTrue(test.getType() instanceof IProblemType); // resolution is ambiguous
|
assertTrue(test.getType() instanceof IProblemType); // resolution is ambiguous
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// char foo() {
|
||||||
|
// return '*';
|
||||||
|
// }
|
||||||
|
public void testRegression_484618() throws Exception {
|
||||||
|
parseAndCheckImplicitNameBindings();
|
||||||
|
}
|
||||||
|
|
||||||
// constexpr int lambdas_supported =
|
// constexpr int lambdas_supported =
|
||||||
// #if __has_feature(cxx_lambdas)
|
// #if __has_feature(cxx_lambdas)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2004, 2011 IBM Corporation and others.
|
* Copyright (c) 2004, 2015 IBM Corporation and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -10,6 +10,7 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,7 +19,8 @@ import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
|
||||||
* @noextend This interface is not intended to be extended by clients.
|
* @noextend This interface is not intended to be extended by clients.
|
||||||
* @noimplement This interface is not intended to be implemented by clients.
|
* @noimplement This interface is not intended to be implemented by clients.
|
||||||
*/
|
*/
|
||||||
public interface ICPPASTLiteralExpression extends IASTLiteralExpression, ICPPASTExpression {
|
public interface ICPPASTLiteralExpression extends IASTLiteralExpression, ICPPASTExpression,
|
||||||
|
IASTImplicitNameOwner {
|
||||||
/**
|
/**
|
||||||
* <code>lk_this</code> represents the 'this' keyword.
|
* <code>lk_this</code> represents the 'this' keyword.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -19,6 +19,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
|
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
|
@ -30,6 +31,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
|
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.Value;
|
import org.eclipse.cdt.internal.core.dom.parser.Value;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||||
|
@ -55,6 +57,9 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
|
||||||
private char[] fSuffix = CharArrayUtils.EMPTY;
|
private char[] fSuffix = CharArrayUtils.EMPTY;
|
||||||
private boolean fIsCompilerSuffix = true;
|
private boolean fIsCompilerSuffix = true;
|
||||||
private ICPPEvaluation fEvaluation;
|
private ICPPEvaluation fEvaluation;
|
||||||
|
|
||||||
|
private IBinding fUserDefinedLiteralOperator;
|
||||||
|
private IASTImplicitName[] fImplicitNames;
|
||||||
|
|
||||||
public CPPASTLiteralExpression() {
|
public CPPASTLiteralExpression() {
|
||||||
}
|
}
|
||||||
|
@ -64,7 +69,7 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
|
||||||
this.fValue = value;
|
this.fValue = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CPPASTLiteralExpression(int kind, char[] value, char[] suffix) {
|
public CPPASTLiteralExpression(int kind, char[] value, char[] suffix, boolean isCompilerSuffix) {
|
||||||
this(kind, value);
|
this(kind, value);
|
||||||
this.setSuffix(suffix);
|
this.setSuffix(suffix);
|
||||||
}
|
}
|
||||||
|
@ -78,7 +83,8 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
|
||||||
public CPPASTLiteralExpression copy(CopyStyle style) {
|
public CPPASTLiteralExpression copy(CopyStyle style) {
|
||||||
CPPASTLiteralExpression copy = new CPPASTLiteralExpression(fKind,
|
CPPASTLiteralExpression copy = new CPPASTLiteralExpression(fKind,
|
||||||
fValue == null ? null : fValue.clone(),
|
fValue == null ? null : fValue.clone(),
|
||||||
fSuffix == null ? null : fSuffix.clone());
|
fSuffix == null ? null : fSuffix.clone(),
|
||||||
|
fIsCompilerSuffix);
|
||||||
copy.setOffsetAndLength(this);
|
copy.setOffsetAndLength(this);
|
||||||
return copy(copy, style);
|
return copy(copy, style);
|
||||||
}
|
}
|
||||||
|
@ -158,6 +164,9 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
|
||||||
final int offset = CharArrayUtils.lastIndexOf('"', fValue, CharArrayUtils.indexOf('"', fValue) + 1);
|
final int offset = CharArrayUtils.lastIndexOf('"', fValue, CharArrayUtils.indexOf('"', fValue) + 1);
|
||||||
if (offset > 0) {
|
if (offset > 0) {
|
||||||
setSuffix(CharArrayUtils.subarray(fValue, offset + 1, -1));
|
setSuffix(CharArrayUtils.subarray(fValue, offset + 1, -1));
|
||||||
|
if (fSuffix.length > 0) {
|
||||||
|
fIsCompilerSuffix = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -166,6 +175,9 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
|
||||||
final int offset = CharArrayUtils.lastIndexOf('\'', fValue, CharArrayUtils.indexOf('\'', fValue) + 1);
|
final int offset = CharArrayUtils.lastIndexOf('\'', fValue, CharArrayUtils.indexOf('\'', fValue) + 1);
|
||||||
if (offset > 0) {
|
if (offset > 0) {
|
||||||
setSuffix(CharArrayUtils.subarray(fValue, offset + 1, -1));
|
setSuffix(CharArrayUtils.subarray(fValue, offset + 1, -1));
|
||||||
|
if (fSuffix.length > 0) {
|
||||||
|
fIsCompilerSuffix = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -194,6 +206,13 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (action.shouldVisitImplicitNames) {
|
||||||
|
for (IASTImplicitName name : getImplicitNames()) {
|
||||||
|
if (!name.accept(action)) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (action.shouldVisitExpressions) {
|
if (action.shouldVisitExpressions) {
|
||||||
switch (action.leave(this)) {
|
switch (action.leave(this)) {
|
||||||
case ASTVisitor.PROCESS_ABORT: return false;
|
case ASTVisitor.PROCESS_ABORT: return false;
|
||||||
|
@ -287,16 +306,28 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
|
||||||
return fSuffix.length > 0 ? getUserDefinedLiteralOperatorType() : new CPPBasicType(getBasicCharKind(), 0, this);
|
return fSuffix.length > 0 ? getUserDefinedLiteralOperatorType() : new CPPBasicType(getBasicCharKind(), 0, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IBinding getUserDefinedLiteralOperator() {
|
||||||
|
if (!fIsCompilerSuffix && fUserDefinedLiteralOperator == null) {
|
||||||
|
try {
|
||||||
|
fUserDefinedLiteralOperator = CPPSemantics.findUserDefinedLiteralOperator(this);
|
||||||
|
} catch (DOMException e) {
|
||||||
|
}
|
||||||
|
if (fUserDefinedLiteralOperator == null) {
|
||||||
|
fUserDefinedLiteralOperator = new ProblemBinding(this, ISemanticProblem.BINDING_NOT_FOUND,
|
||||||
|
fSuffix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fUserDefinedLiteralOperator;
|
||||||
|
}
|
||||||
|
|
||||||
// 13.5.8
|
// 13.5.8
|
||||||
private IType getUserDefinedLiteralOperatorType() {
|
private IType getUserDefinedLiteralOperatorType() {
|
||||||
IType ret = new ProblemType(ISemanticProblem.TYPE_UNRESOLVED_NAME);
|
IType ret = new ProblemType(ISemanticProblem.TYPE_UNRESOLVED_NAME);
|
||||||
|
|
||||||
try {
|
IBinding func = getUserDefinedLiteralOperator();
|
||||||
IBinding func = CPPSemantics.findUserDefinedLiteralOperator(this);
|
if (func != null && func instanceof ICPPFunction) {
|
||||||
if (func != null && func instanceof ICPPFunction) {
|
ret = ((ICPPFunction) func).getType().getReturnType();
|
||||||
ret = ((ICPPFunction) func).getType().getReturnType();
|
}
|
||||||
}
|
|
||||||
} catch (DOMException e) { /* ignore and return the problem type */ }
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -660,4 +691,20 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
|
||||||
public ValueCategory getValueCategory() {
|
public ValueCategory getValueCategory() {
|
||||||
return getKind() == lk_string_literal ? LVALUE : PRVALUE;
|
return getKind() == lk_string_literal ? LVALUE : PRVALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IASTImplicitName[] getImplicitNames() {
|
||||||
|
if (fImplicitNames == null) {
|
||||||
|
if (fIsCompilerSuffix) {
|
||||||
|
fImplicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
|
} else {
|
||||||
|
CPPASTImplicitName operatorName = new CPPASTImplicitName(fSuffix, this);
|
||||||
|
operatorName.setOperator(true);
|
||||||
|
operatorName.setBinding(getUserDefinedLiteralOperator());
|
||||||
|
operatorName.setOffsetAndLength(getOffset() + fValue.length, fSuffix.length);
|
||||||
|
fImplicitNames = new IASTImplicitName[] { operatorName };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fImplicitNames;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -440,4 +440,11 @@ public class SemanticHighlightingTest extends TestCase {
|
||||||
public void testHighlightingInsideAlignmentSpecifier_451082() throws Exception {
|
public void testHighlightingInsideAlignmentSpecifier_451082() throws Exception {
|
||||||
makeAssertions();
|
makeAssertions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// struct Duration {}; //$class
|
||||||
|
// Duration operator "" _d(unsigned long long); //$class,functionDeclaration
|
||||||
|
// Duration dur = 1000_d; //$class,globalVariable,overloadedOperator
|
||||||
|
public void testUserDefinedLiteralSuffix_484617() throws Exception {
|
||||||
|
makeAssertions();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1248,4 +1248,15 @@ public class CPPSelectionTestsNoIndexer extends BaseSelectionTests {
|
||||||
offset = code.indexOf("::other->foo") + 9;
|
offset = code.indexOf("::other->foo") + 9;
|
||||||
assertTrue(testF3(file, offset) instanceof IASTName);
|
assertTrue(testF3(file, offset) instanceof IASTName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// struct Duration {};
|
||||||
|
// Duration operator "" _d(unsigned long long);
|
||||||
|
// Duration dur = 42_d;
|
||||||
|
public void testUserDefinedLiteralSuffix_484618() throws Exception {
|
||||||
|
String code = getAboveComment();
|
||||||
|
IFile file = importFile("testBug484618.cpp", code);
|
||||||
|
|
||||||
|
int offset = code.indexOf("42_d") + 3;
|
||||||
|
assertTrue(testF3(file, offset) instanceof IASTName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue