1
0
Fork 0
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:
Nathan Ridge 2015-12-25 00:02:26 -05:00 committed by Gerrit Code Review @ Eclipse.org
parent 2cc3e248b4
commit 60e390b0e4
5 changed files with 85 additions and 11 deletions

View file

@ -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)

View file

@ -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.
*/ */

View file

@ -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;
}
} }

View file

@ -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();
}
} }

View file

@ -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);
}
} }