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

@ -11624,6 +11624,13 @@ public class AST2CPPTests extends AST2TestBase {
assertTrue(test.getType() instanceof IProblemType); // resolution is ambiguous
}
// char foo() {
// return '*';
// }
public void testRegression_484618() throws Exception {
parseAndCheckImplicitNameBindings();
}
// constexpr int lambdas_supported =
// #if __has_feature(cxx_lambdas)
// 1;

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
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
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.
* @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.
*/

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.DOMException;
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.Kind;
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.parser.util.CharArrayUtils;
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.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
@ -56,6 +58,9 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
private boolean fIsCompilerSuffix = true;
private ICPPEvaluation fEvaluation;
private IBinding fUserDefinedLiteralOperator;
private IASTImplicitName[] fImplicitNames;
public CPPASTLiteralExpression() {
}
@ -64,7 +69,7 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
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.setSuffix(suffix);
}
@ -78,7 +83,8 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
public CPPASTLiteralExpression copy(CopyStyle style) {
CPPASTLiteralExpression copy = new CPPASTLiteralExpression(fKind,
fValue == null ? null : fValue.clone(),
fSuffix == null ? null : fSuffix.clone());
fSuffix == null ? null : fSuffix.clone(),
fIsCompilerSuffix);
copy.setOffsetAndLength(this);
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);
if (offset > 0) {
setSuffix(CharArrayUtils.subarray(fValue, offset + 1, -1));
if (fSuffix.length > 0) {
fIsCompilerSuffix = false;
}
}
}
break;
@ -166,6 +175,9 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
final int offset = CharArrayUtils.lastIndexOf('\'', fValue, CharArrayUtils.indexOf('\'', fValue) + 1);
if (offset > 0) {
setSuffix(CharArrayUtils.subarray(fValue, offset + 1, -1));
if (fSuffix.length > 0) {
fIsCompilerSuffix = false;
}
}
}
break;
@ -194,6 +206,13 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
default: break;
}
}
if (action.shouldVisitImplicitNames) {
for (IASTImplicitName name : getImplicitNames()) {
if (!name.accept(action)) return false;
}
}
if (action.shouldVisitExpressions) {
switch (action.leave(this)) {
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);
}
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
private IType getUserDefinedLiteralOperatorType() {
IType ret = new ProblemType(ISemanticProblem.TYPE_UNRESOLVED_NAME);
try {
IBinding func = CPPSemantics.findUserDefinedLiteralOperator(this);
IBinding func = getUserDefinedLiteralOperator();
if (func != null && func instanceof ICPPFunction) {
ret = ((ICPPFunction) func).getType().getReturnType();
}
} catch (DOMException e) { /* ignore and return the problem type */ }
return ret;
}
@ -660,4 +691,20 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
public ValueCategory getValueCategory() {
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 {
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;
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);
}
}