mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 10:16:03 +02:00
Bug 316307: [C++0x] Semantics for lamda expressions.
This commit is contained in:
parent
b6d83a4804
commit
9cb98d05cf
19 changed files with 889 additions and 154 deletions
|
@ -8856,7 +8856,7 @@ public class AST2CPPTests extends AST2BaseTest {
|
||||||
// return abs(a) < abs(b);
|
// return abs(a) < abs(b);
|
||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
public void _testLambdaExpression_316307b() throws Exception {
|
public void testLambdaExpression_316307b() throws Exception {
|
||||||
String code= getAboveComment();
|
String code= getAboveComment();
|
||||||
parseAndCheckBindings(code);
|
parseAndCheckBindings(code);
|
||||||
}
|
}
|
||||||
|
|
|
@ -869,7 +869,6 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
||||||
// foo/*i*/(23489); // IASTLiteralExpression
|
// foo/*i*/(23489); // IASTLiteralExpression
|
||||||
// foo/*j*/(sizeof(C));/*9*/ // IASTTypeIdExpression
|
// foo/*j*/(sizeof(C));/*9*/ // IASTTypeIdExpression
|
||||||
// foo/*k*/(*cp);/*10*/ // IASTUnaryExpression
|
// foo/*k*/(*cp);/*10*/ // IASTUnaryExpression
|
||||||
// foo/*l*/(delete cp);/*11*/ // ICPPASTDeleteExpression
|
|
||||||
// foo/*m*/(new C());/*12*/ // ICPPASTNewExpression
|
// foo/*m*/(new C());/*12*/ // ICPPASTNewExpression
|
||||||
// // ?? foo/*n*/(); // ICPPASTSimpleTypeConstructorExpression
|
// // ?? foo/*n*/(); // ICPPASTSimpleTypeConstructorExpression
|
||||||
// // ?? foo/*o*/(); // ICPPASTTypenameExprssion
|
// // ?? foo/*o*/(); // ICPPASTTypenameExprssion
|
||||||
|
@ -916,9 +915,6 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
||||||
IBinding b10 = getBindingFromASTName("foo/*k*/", 3);
|
IBinding b10 = getBindingFromASTName("foo/*k*/", 3);
|
||||||
IBinding b10a = getBindingFromASTName("cp);/*10*/", 2);
|
IBinding b10a = getBindingFromASTName("cp);/*10*/", 2);
|
||||||
|
|
||||||
IBinding b11 = getBindingFromASTName("foo/*l*/", 3);
|
|
||||||
IBinding b11a = getBindingFromASTName("cp);/*11*/", 2);
|
|
||||||
|
|
||||||
IBinding b12 = getBindingFromASTName("foo/*m*/", 3);
|
IBinding b12 = getBindingFromASTName("foo/*m*/", 3);
|
||||||
IBinding b12a = getBindingFromASTName("C());/*12*/", 1);
|
IBinding b12a = getBindingFromASTName("C());/*12*/", 1);
|
||||||
// IBinding b13 = getBindingFromASTName(ast, "foo/*n*/", 3);
|
// IBinding b13 = getBindingFromASTName(ast, "foo/*n*/", 3);
|
||||||
|
|
|
@ -13,6 +13,8 @@ package org.eclipse.cdt.core.dom.ast.cpp;
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lambda expression, introduced in C++0x.
|
* Lambda expression, introduced in C++0x.
|
||||||
|
@ -21,7 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
* @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 ICPPASTLambdaExpression extends IASTExpression {
|
public interface ICPPASTLambdaExpression extends IASTExpression, IASTImplicitNameOwner {
|
||||||
ASTNodeProperty CAPTURE = new ASTNodeProperty("ICPPASTLambdaExpression - CAPTURE [ICPPASTCapture]"); //$NON-NLS-1$
|
ASTNodeProperty CAPTURE = new ASTNodeProperty("ICPPASTLambdaExpression - CAPTURE [ICPPASTCapture]"); //$NON-NLS-1$
|
||||||
ASTNodeProperty DECLARATOR = new ASTNodeProperty("ICPPASTLambdaExpression - DECLARATOR [ICPPASTFunctionDeclarator]"); //$NON-NLS-1$
|
ASTNodeProperty DECLARATOR = new ASTNodeProperty("ICPPASTLambdaExpression - DECLARATOR [ICPPASTFunctionDeclarator]"); //$NON-NLS-1$
|
||||||
ASTNodeProperty BODY = new ASTNodeProperty("ICPPASTLambdaExpression - BODY [IASTCompoundStatement]"); //$NON-NLS-1$
|
ASTNodeProperty BODY = new ASTNodeProperty("ICPPASTLambdaExpression - BODY [IASTCompoundStatement]"); //$NON-NLS-1$
|
||||||
|
@ -40,13 +42,24 @@ public interface ICPPASTLambdaExpression extends IASTExpression {
|
||||||
* Returns the array of captures for this lambda expression.
|
* Returns the array of captures for this lambda expression.
|
||||||
*/
|
*/
|
||||||
ICPPASTCapture[] getCaptures();
|
ICPPASTCapture[] getCaptures();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an implicit name that represents the closure type.
|
||||||
|
*/
|
||||||
|
IASTImplicitName getClosureTypeName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the lambda declarator for this lambda expression, or <code>null</code>
|
* Returns the lambda declarator for this lambda expression, or <code>null</code>
|
||||||
* in case it was not specified.
|
* in case it was not specified.
|
||||||
*/
|
*/
|
||||||
ICPPASTFunctionDeclarator getDeclarator();
|
ICPPASTFunctionDeclarator getDeclarator();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an implicit name that represents the implicit function call operator of
|
||||||
|
* the closure.
|
||||||
|
*/
|
||||||
|
IASTImplicitName getFunctionCallOperatorName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the compound statement of this lambda expression. Can be <code>null</code>
|
* Returns the compound statement of this lambda expression. Can be <code>null</code>
|
||||||
* when creating AST for content assist.
|
* when creating AST for content assist.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2005, 2008 IBM Corporation and others.
|
* Copyright (c) 2005, 2010 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
|
||||||
|
@ -14,6 +14,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
|
@ -91,25 +92,31 @@ public class CPPASTConversionName extends CPPASTNameBase implements ICPPASTConve
|
||||||
|
|
||||||
public char[] toCharArray() {
|
public char[] toCharArray() {
|
||||||
if (fName == null) {
|
if (fName == null) {
|
||||||
StringBuilder buf= new StringBuilder();
|
IType t= null;
|
||||||
buf.append(Keywords.cOPERATOR);
|
|
||||||
buf.append(' ');
|
|
||||||
if (typeId != null) {
|
if (typeId != null) {
|
||||||
IType t= CPPVisitor.createType(typeId);
|
t= CPPVisitor.createType(typeId);
|
||||||
if (t != null) {
|
|
||||||
buf.append(ASTTypeUtil.getType(t, true));
|
|
||||||
} else {
|
|
||||||
buf.append(typeId.getRawSignature());
|
|
||||||
WHITESPACE_SEQ.matcher(buf).replaceAll(" "); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
final int len= buf.length();
|
fName= createName(t, typeId);
|
||||||
fName= new char[len];
|
|
||||||
buf.getChars(0, len, fName, 0);
|
|
||||||
}
|
}
|
||||||
return fName;
|
return fName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static char[] createName(IType t, IASTNode typeId) {
|
||||||
|
StringBuilder buf= new StringBuilder();
|
||||||
|
buf.append(Keywords.cOPERATOR);
|
||||||
|
buf.append(' ');
|
||||||
|
if (t != null) {
|
||||||
|
buf.append(ASTTypeUtil.getType(t, true));
|
||||||
|
} else {
|
||||||
|
buf.append(typeId.getRawSignature());
|
||||||
|
WHITESPACE_SEQ.matcher(buf).replaceAll(" "); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
final int len= buf.length();
|
||||||
|
char[] name= new char[len];
|
||||||
|
buf.getChars(0, len, name, 0);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
public char[] getSimpleID() {
|
public char[] getSimpleID() {
|
||||||
return toCharArray();
|
return toCharArray();
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression;
|
||||||
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.ICPPConstructor;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||||
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.ICPPMethod;
|
||||||
import org.eclipse.cdt.core.parser.IToken;
|
import org.eclipse.cdt.core.parser.IToken;
|
||||||
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.IASTAmbiguityParent;
|
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
||||||
|
@ -109,8 +110,11 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
|
||||||
public IASTImplicitName[] getImplicitNames() {
|
public IASTImplicitName[] getImplicitNames() {
|
||||||
if (implicitNames == null) {
|
if (implicitNames == null) {
|
||||||
ICPPFunction overload = getOperator();
|
ICPPFunction overload = getOperator();
|
||||||
if (overload == null || overload instanceof CPPImplicitFunction)
|
if (overload == null || overload instanceof CPPImplicitFunction) {
|
||||||
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
if (!(overload instanceof ICPPMethod) || ((ICPPMethod) overload).isImplicit()) {
|
||||||
|
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// create separate implicit names for the two brackets
|
// create separate implicit names for the two brackets
|
||||||
CPPASTImplicitName n1 = new CPPASTImplicitName(OverloadableOperator.PAREN, this);
|
CPPASTImplicitName n1 = new CPPASTImplicitName(OverloadableOperator.PAREN, this);
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
public class CPPASTImplicitName extends CPPASTName implements IASTImplicitName {
|
public class CPPASTImplicitName extends CPPASTName implements IASTImplicitName {
|
||||||
private boolean alternate;
|
private boolean alternate;
|
||||||
private boolean isOperator;
|
private boolean isOperator;
|
||||||
|
private boolean isDefinition= false;
|
||||||
|
|
||||||
public CPPASTImplicitName(char[] name, IASTNode parent) {
|
public CPPASTImplicitName(char[] name, IASTNode parent) {
|
||||||
super(name);
|
super(name);
|
||||||
|
@ -74,12 +75,16 @@ public class CPPASTImplicitName extends CPPASTName implements IASTImplicitName {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDefinition() {
|
public boolean isDefinition() {
|
||||||
return false;
|
return isDefinition;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isReference() {
|
public boolean isReference() {
|
||||||
return true;
|
return !isDefinition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsDefinition(boolean val) {
|
||||||
|
isDefinition= val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,10 +13,11 @@ 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.IASTCompoundStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
|
|
||||||
|
@ -29,7 +30,12 @@ public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpr
|
||||||
private CaptureDefault fCaptureDefault;
|
private CaptureDefault fCaptureDefault;
|
||||||
private ICPPASTCapture[] fCaptures;
|
private ICPPASTCapture[] fCaptures;
|
||||||
private ICPPASTFunctionDeclarator fDeclarator;
|
private ICPPASTFunctionDeclarator fDeclarator;
|
||||||
|
|
||||||
private IASTCompoundStatement fBody;
|
private IASTCompoundStatement fBody;
|
||||||
|
|
||||||
|
private CPPClosureType fClosureType;
|
||||||
|
private IASTImplicitName fClosureTypeName;
|
||||||
|
private IASTImplicitName fImplicitFunctionCallName;
|
||||||
|
|
||||||
public CPPASTLambdaExpression() {
|
public CPPASTLambdaExpression() {
|
||||||
fCaptureDefault= CaptureDefault.UNSPECIFIED;
|
fCaptureDefault= CaptureDefault.UNSPECIFIED;
|
||||||
|
@ -59,6 +65,41 @@ public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpr
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IASTImplicitName[] getImplicitNames() {
|
||||||
|
return new IASTImplicitName[] {getFunctionCallOperatorName()};
|
||||||
|
}
|
||||||
|
|
||||||
|
public IASTImplicitName getClosureTypeName() {
|
||||||
|
if (fClosureTypeName == null) {
|
||||||
|
final CPPClosureType closureType = getExpressionType();
|
||||||
|
CPPASTImplicitName name = new CPPASTImplicitName(closureType.getNameCharArray(), this);
|
||||||
|
name.setBinding(closureType);
|
||||||
|
name.setIsDefinition(true);
|
||||||
|
|
||||||
|
name.setOffsetAndLength(getOffset(), 1);
|
||||||
|
fClosureTypeName= name;
|
||||||
|
}
|
||||||
|
return fClosureTypeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IASTImplicitName getFunctionCallOperatorName() {
|
||||||
|
if (fImplicitFunctionCallName == null) {
|
||||||
|
final CPPClosureType closureType = getExpressionType();
|
||||||
|
ICPPFunction callOperator= closureType.getFunctionCallOperator();
|
||||||
|
|
||||||
|
CPPASTImplicitName name = new CPPASTImplicitName(closureType.getNameCharArray(), this);
|
||||||
|
name.setBinding(callOperator);
|
||||||
|
name.setIsDefinition(true);
|
||||||
|
|
||||||
|
if (fBody instanceof ASTNode) {
|
||||||
|
ASTNode bodyNode= (ASTNode) fBody;
|
||||||
|
name.setOffsetAndLength(bodyNode.getOffset(), 1);
|
||||||
|
}
|
||||||
|
fImplicitFunctionCallName= name;
|
||||||
|
}
|
||||||
|
return fImplicitFunctionCallName;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(ASTVisitor visitor) {
|
public boolean accept(ASTVisitor visitor) {
|
||||||
if (visitor.shouldVisitExpressions) {
|
if (visitor.shouldVisitExpressions) {
|
||||||
|
@ -69,6 +110,9 @@ public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (visitor.shouldVisitImplicitNames && !getClosureTypeName().accept(visitor))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (fCaptures != null) {
|
if (fCaptures != null) {
|
||||||
for (ICPPASTCapture cap : fCaptures) {
|
for (ICPPASTCapture cap : fCaptures) {
|
||||||
if (cap != null && !cap.accept(visitor))
|
if (cap != null && !cap.accept(visitor))
|
||||||
|
@ -77,6 +121,10 @@ public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpr
|
||||||
}
|
}
|
||||||
if (fDeclarator != null && !fDeclarator.accept(visitor))
|
if (fDeclarator != null && !fDeclarator.accept(visitor))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (visitor.shouldVisitImplicitNames && !getFunctionCallOperatorName().accept(visitor))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (fBody != null && !fBody.accept(visitor))
|
if (fBody != null && !fBody.accept(visitor))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -133,9 +181,11 @@ public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpr
|
||||||
fDeclarator= dtor;
|
fDeclarator= dtor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IType getExpressionType() {
|
public CPPClosureType getExpressionType() {
|
||||||
// mstodo type for lambda expressions
|
if (fClosureType == null)
|
||||||
return null;
|
fClosureType= new CPPClosureType(this);
|
||||||
|
|
||||||
|
return fClosureType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLValue() {
|
public boolean isLValue() {
|
||||||
|
|
|
@ -0,0 +1,400 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2010 Wind River Systems, Inc. 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
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Markus Schorn (Wind River Systems) - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ILinkage;
|
||||||
|
import org.eclipse.cdt.core.dom.IName;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.EScopeKind;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IField;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression.CaptureDefault;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
||||||
|
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.ICPPParameter;
|
||||||
|
import org.eclipse.cdt.core.index.IIndexBinding;
|
||||||
|
import org.eclipse.cdt.core.index.IIndexFileSet;
|
||||||
|
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.Linkage;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||||
|
import org.eclipse.core.runtime.PlatformObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binding for a class type.
|
||||||
|
*/
|
||||||
|
public class CPPClosureType extends PlatformObject implements ICPPClassType, ICPPInternalBinding {
|
||||||
|
private static final CPPBasicType NO_RETURN_TYPE = new CPPBasicType(Kind.eUnspecified, 0);
|
||||||
|
|
||||||
|
private final ICPPASTLambdaExpression fLambdaExpression;
|
||||||
|
private ICPPMethod[] fMethods;
|
||||||
|
private ClassScope fScope;
|
||||||
|
|
||||||
|
public CPPClosureType(ICPPASTLambdaExpression lambdaExpr) {
|
||||||
|
fLambdaExpression= lambdaExpr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ICPPMethod[] createMethods() {
|
||||||
|
boolean needConversionOperator=
|
||||||
|
fLambdaExpression.getCaptureDefault() == CaptureDefault.UNSPECIFIED &&
|
||||||
|
fLambdaExpression.getCaptures().length == 0;
|
||||||
|
|
||||||
|
final ICPPClassScope scope= getCompositeScope();
|
||||||
|
ICPPMethod[] result= new ICPPMethod[needConversionOperator ? 6 : 5];
|
||||||
|
|
||||||
|
// Deleted default constructor: A()
|
||||||
|
CPPImplicitConstructor ctor= new CPPImplicitConstructor(scope, CharArrayUtils.EMPTY, ICPPParameter.EMPTY_CPPPARAMETER_ARRAY);
|
||||||
|
ctor.setDeleted(true);
|
||||||
|
result[0]= ctor;
|
||||||
|
|
||||||
|
// Copy constructor: A(const A &)
|
||||||
|
IType pType = new CPPReferenceType(SemanticUtil.addQualifiers(this, true, false), false);
|
||||||
|
ICPPParameter[] ps = new ICPPParameter[] { new CPPParameter(pType, 0) };
|
||||||
|
ctor = new CPPImplicitConstructor(scope, CharArrayUtils.EMPTY, ps);
|
||||||
|
result[1]= ctor;
|
||||||
|
|
||||||
|
// Deleted copy assignment operator: A& operator = (const A &)
|
||||||
|
IType refType = new CPPReferenceType(this, false);
|
||||||
|
ICPPFunctionType ft= CPPVisitor.createImplicitFunctionType(refType, ps, false, false);
|
||||||
|
ICPPMethod m = new CPPImplicitMethod(scope, OverloadableOperator.ASSIGN.toCharArray(), ft, ps);
|
||||||
|
result[2]= m;
|
||||||
|
|
||||||
|
// Destructor: ~A()
|
||||||
|
ft= CPPVisitor.createImplicitFunctionType(NO_RETURN_TYPE, ICPPParameter.EMPTY_CPPPARAMETER_ARRAY, false, false);
|
||||||
|
m = new CPPImplicitMethod(scope, new char[] {'~'}, ft, ICPPParameter.EMPTY_CPPPARAMETER_ARRAY);
|
||||||
|
result[3]= m;
|
||||||
|
|
||||||
|
// Function call operator
|
||||||
|
final IType returnType= getReturnType();
|
||||||
|
final IType[] parameterTypes= getParameterTypes();
|
||||||
|
ft= new CPPFunctionType(returnType, parameterTypes, isMutable(), false, false);
|
||||||
|
|
||||||
|
ICPPParameter[] params = new ICPPParameter[parameterTypes.length];
|
||||||
|
for (int i = 0; i < params.length; i++) {
|
||||||
|
params[i]= new CPPParameter(parameterTypes[i], 0);
|
||||||
|
}
|
||||||
|
m= new CPPImplicitMethod(scope, OverloadableOperator.PAREN.toCharArray(), ft, params) {
|
||||||
|
@Override
|
||||||
|
public boolean isImplicit() {return false;}
|
||||||
|
};
|
||||||
|
result[4]= m;
|
||||||
|
|
||||||
|
// Conversion operator
|
||||||
|
if (needConversionOperator) {
|
||||||
|
final CPPFunctionType conversionTarget = new CPPFunctionType(returnType, parameterTypes);
|
||||||
|
ft= new CPPFunctionType(conversionTarget, IType.EMPTY_TYPE_ARRAY, true, false, false);
|
||||||
|
m= new CPPImplicitMethod(scope, CPPASTConversionName.createName(conversionTarget, null), ft, params);
|
||||||
|
result[5]= m;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICPPMethod getFunctionCallOperator() {
|
||||||
|
return getMethods()[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isMutable() {
|
||||||
|
ICPPASTFunctionDeclarator lambdaDtor = fLambdaExpression.getDeclarator();
|
||||||
|
return lambdaDtor != null && lambdaDtor.isMutable();
|
||||||
|
}
|
||||||
|
|
||||||
|
private IType getReturnType() {
|
||||||
|
ICPPASTFunctionDeclarator lambdaDtor = fLambdaExpression.getDeclarator();
|
||||||
|
if (lambdaDtor != null) {
|
||||||
|
IASTTypeId trailingReturnType = lambdaDtor.getTrailingReturnType();
|
||||||
|
if (trailingReturnType != null) {
|
||||||
|
IType type= CPPVisitor.createType(trailingReturnType);
|
||||||
|
if (type != null)
|
||||||
|
return type;
|
||||||
|
return CPPSemantics.VOID_TYPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IASTCompoundStatement body = fLambdaExpression.getBody();
|
||||||
|
if (body != null) {
|
||||||
|
IASTStatement[] stmts = body.getStatements();
|
||||||
|
if (stmts.length > 0) {
|
||||||
|
// Gnu extension allows to deduce return type in complex compound statements
|
||||||
|
IASTStatement stmt= stmts[stmts.length-1];
|
||||||
|
if (stmt instanceof IASTReturnStatement) {
|
||||||
|
IASTReturnStatement rtstmt= (IASTReturnStatement) stmt;
|
||||||
|
IASTExpression expr= rtstmt.getReturnValue();
|
||||||
|
if (expr != null) {
|
||||||
|
IType type= expr.getExpressionType();
|
||||||
|
type= Conversions.lvalue_to_rvalue(type);
|
||||||
|
type= Conversions.array_to_pointer(type);
|
||||||
|
type= Conversions.function_to_pointer(type);
|
||||||
|
if (type != null) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CPPSemantics.VOID_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IType[] getParameterTypes() {
|
||||||
|
ICPPASTFunctionDeclarator lambdaDtor = fLambdaExpression.getDeclarator();
|
||||||
|
if (lambdaDtor != null) {
|
||||||
|
return CPPVisitor.createParameterTypes(lambdaDtor);
|
||||||
|
}
|
||||||
|
return IType.EMPTY_TYPE_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String getName() {
|
||||||
|
return ""; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
public char[] getNameCharArray() {
|
||||||
|
return CharArrayUtils.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IScope getScope() {
|
||||||
|
return CPPVisitor.getContainingScope(fLambdaExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICPPClassScope getCompositeScope() {
|
||||||
|
if (fScope == null) {
|
||||||
|
fScope= new ClassScope();
|
||||||
|
}
|
||||||
|
return fScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getKey() {
|
||||||
|
return k_class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getQualifiedName() {
|
||||||
|
return CPPVisitor.getQualifiedName(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public char[][] getQualifiedNameCharArray() {
|
||||||
|
return CPPVisitor.getQualifiedNameCharArray(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGloballyQualified() {
|
||||||
|
return getOwner() == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ILinkage getLinkage() {
|
||||||
|
return Linkage.CPP_LINKAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSameType(IType type) {
|
||||||
|
if (type == this)
|
||||||
|
return true;
|
||||||
|
if (type instanceof ITypedef || type instanceof IIndexBinding)
|
||||||
|
return type.isSameType(this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICPPBase[] getBases() {
|
||||||
|
return ICPPBase.EMPTY_BASE_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICPPField[] getFields() {
|
||||||
|
return ICPPField.EMPTY_CPPFIELD_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICPPField[] getDeclaredFields() {
|
||||||
|
return ICPPField.EMPTY_CPPFIELD_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICPPMethod[] getMethods() {
|
||||||
|
if (fMethods == null) {
|
||||||
|
fMethods= createMethods();
|
||||||
|
}
|
||||||
|
return fMethods;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICPPMethod[] getAllDeclaredMethods() {
|
||||||
|
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICPPMethod[] getDeclaredMethods() {
|
||||||
|
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICPPConstructor[] getConstructors() {
|
||||||
|
ICPPMethod[] methods= getMethods();
|
||||||
|
int i= 0;
|
||||||
|
for (; i < methods.length; i++) {
|
||||||
|
if (!(methods[i] instanceof ICPPConstructor)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ICPPConstructor[] result= new ICPPConstructor[i];
|
||||||
|
System.arraycopy(methods, 0, result, 0, i);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBinding[] getFriends() {
|
||||||
|
return IBinding.EMPTY_BINDING_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICPPClassType[] getNestedClasses() {
|
||||||
|
return ICPPClassType.EMPTY_CLASS_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IField findField(String name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object clone() {
|
||||||
|
try {
|
||||||
|
return super.clone();
|
||||||
|
} catch (CloneNotSupportedException e) {
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For debugging purposes, only.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
char[] name= ASTTypeUtil.createNameForAnonymous(this);
|
||||||
|
if (name != null)
|
||||||
|
return new String(name);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBinding getOwner() {
|
||||||
|
return CPPVisitor.findDeclarationOwner(fLambdaExpression, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAnonymous() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IASTNode getDefinition() {
|
||||||
|
return fLambdaExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IASTNode[] getDeclarations() {
|
||||||
|
return IASTNode.EMPTY_NODE_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addDefinition(IASTNode node) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addDeclaration(IASTNode node) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private final class ClassScope implements ICPPClassScope {
|
||||||
|
public EScopeKind getKind() {
|
||||||
|
return EScopeKind.eClassType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IName getScopeName() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IScope getParent() {
|
||||||
|
return getScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
private IBinding getBinding(char[] name) {
|
||||||
|
for (ICPPMethod m : getMethods()) {
|
||||||
|
if (!(m instanceof ICPPConstructor) && CharArrayUtils.equals(name, m.getNameCharArray())) {
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IBinding[] getBindings(char[] name) {
|
||||||
|
IBinding m= getBinding(name);
|
||||||
|
if (m != null) {
|
||||||
|
return new IBinding[] {m};
|
||||||
|
}
|
||||||
|
return IBinding.EMPTY_BINDING_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IBinding[] getPrefixBindings(char[] name) {
|
||||||
|
List<IBinding> result= new ArrayList<IBinding>();
|
||||||
|
for (ICPPMethod m : getMethods()) {
|
||||||
|
if (!(m instanceof ICPPConstructor)) {
|
||||||
|
if (CharArrayUtils.equals(name, 0, name.length, m.getNameCharArray(), true)) {
|
||||||
|
result.add(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toArray(new IBinding[result.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBinding[] find(String name) {
|
||||||
|
return getBindings(name.toCharArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBinding getBinding(IASTName name, boolean resolve) {
|
||||||
|
if (name instanceof ICPPASTTemplateId)
|
||||||
|
return null;
|
||||||
|
return getBinding(name.getSimpleID());
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet acceptLocalBindings) {
|
||||||
|
return getBinding(name, resolve);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup) {
|
||||||
|
if (name instanceof ICPPASTTemplateId)
|
||||||
|
return IBinding.EMPTY_BINDING_ARRAY;
|
||||||
|
|
||||||
|
if (prefixLookup)
|
||||||
|
return getPrefixBindings(name.getSimpleID());
|
||||||
|
return getBindings(name.getSimpleID());
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup,
|
||||||
|
IIndexFileSet acceptLocalBindings) {
|
||||||
|
return getBindings(name, resolve, prefixLookup);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICPPClassType getClassType() {
|
||||||
|
return CPPClosureType.this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICPPMethod[] getImplicitMethods() {
|
||||||
|
return getMethods();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICPPConstructor[] getConstructors() {
|
||||||
|
return CPPClosureType.this.getConstructors();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2005, 2009 IBM Corporation and others.
|
* Copyright (c) 2005, 2010 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
|
||||||
|
@ -27,8 +27,9 @@ public class CPPImplicitFunction extends CPPFunction {
|
||||||
private ICPPParameter[] parms=null;
|
private ICPPParameter[] parms=null;
|
||||||
private IScope scope=null;
|
private IScope scope=null;
|
||||||
private ICPPFunctionType functionType=null;
|
private ICPPFunctionType functionType=null;
|
||||||
private boolean takesVarArgs=false;
|
private final boolean takesVarArgs;
|
||||||
private char[] name=null;
|
private boolean isDeleted;
|
||||||
|
private final char[] name;
|
||||||
|
|
||||||
public CPPImplicitFunction(char[] name, IScope scope, ICPPFunctionType type, ICPPParameter[] parms, boolean takesVarArgs) {
|
public CPPImplicitFunction(char[] name, IScope scope, ICPPFunctionType type, ICPPParameter[] parms, boolean takesVarArgs) {
|
||||||
super( null );
|
super( null );
|
||||||
|
@ -82,8 +83,17 @@ public class CPPImplicitFunction extends CPPFunction {
|
||||||
return takesVarArgs;
|
return takesVarArgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDeleted() {
|
||||||
|
return isDeleted;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinding getOwner() {
|
public IBinding getOwner() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDeleted(boolean val) {
|
||||||
|
isDeleted= val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,149 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2010 Wind River Systems, Inc. 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
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Markus Schorn (Wind River Systems) - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ILinkage;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IValue;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.Linkage;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||||
|
import org.eclipse.core.runtime.PlatformObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binding for a c++ function parameter
|
||||||
|
*/
|
||||||
|
public class CPPLambdaExpressionParameter extends PlatformObject implements ICPPParameter {
|
||||||
|
private IType fType = null;
|
||||||
|
private IASTName fDeclaration = null;
|
||||||
|
|
||||||
|
public CPPLambdaExpressionParameter(IASTName name) {
|
||||||
|
fDeclaration = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isParameterPack() {
|
||||||
|
return getType() instanceof ICPPParameterPackType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return new String(getNameCharArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public char[] getNameCharArray() {
|
||||||
|
return fDeclaration.getSimpleID();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IScope getScope() {
|
||||||
|
return CPPVisitor.getContainingScope(fDeclaration);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IType getType() {
|
||||||
|
if (fType == null) {
|
||||||
|
IASTNode parent= fDeclaration.getParent();
|
||||||
|
while (parent != null) {
|
||||||
|
if (parent instanceof ICPPASTParameterDeclaration) {
|
||||||
|
fType= CPPVisitor.createParameterType((ICPPASTParameterDeclaration) parent, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
parent= parent.getParent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStatic() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public String[] getQualifiedName() {
|
||||||
|
return new String[] { getName() };
|
||||||
|
}
|
||||||
|
public char[][] getQualifiedNameCharArray() {
|
||||||
|
return new char[][] { getNameCharArray() };
|
||||||
|
}
|
||||||
|
public boolean isGloballyQualified() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isExtern() {
|
||||||
|
//7.1.1-5 extern can not be used in the declaration of a parameter
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMutable() {
|
||||||
|
//7.1.1-8 mutable can only apply to class members
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAuto() {
|
||||||
|
return hasStorageClass(IASTDeclSpecifier.sc_auto);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRegister() {
|
||||||
|
return hasStorageClass(IASTDeclSpecifier.sc_register);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasStorageClass(int storage) {
|
||||||
|
IASTNode parent = fDeclaration.getParent();
|
||||||
|
while (parent != null && !(parent instanceof IASTParameterDeclaration))
|
||||||
|
parent = parent.getParent();
|
||||||
|
if (parent != null) {
|
||||||
|
IASTDeclSpecifier declSpec = ((IASTParameterDeclaration) parent).getDeclSpecifier();
|
||||||
|
if (declSpec.getStorageClass() == storage)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasDefaultValue() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ILinkage getLinkage() {
|
||||||
|
return Linkage.CPP_LINKAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isExternC() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
String name = getName();
|
||||||
|
return name.length() != 0 ? name : "<unnamed>"; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBinding getOwner() {
|
||||||
|
IASTNode node= fDeclaration;
|
||||||
|
while (node != null && !(node instanceof ICPPASTLambdaExpression))
|
||||||
|
node= node.getParent();
|
||||||
|
|
||||||
|
if (node instanceof ICPPASTLambdaExpression) {
|
||||||
|
IType type= ((ICPPASTLambdaExpression) node).getExpressionType();
|
||||||
|
if (type instanceof IBinding) {
|
||||||
|
return (IBinding) type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IValue getInitialValue() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -96,6 +96,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
|
||||||
|
@ -1322,7 +1323,12 @@ public class CPPSemantics {
|
||||||
if (p instanceof IASTFunctionDefinition) {
|
if (p instanceof IASTFunctionDefinition) {
|
||||||
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) ((IASTFunctionDefinition) p).getDeclarator();
|
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) ((IASTFunctionDefinition) p).getDeclarator();
|
||||||
nodes = dtor.getParameters();
|
nodes = dtor.getParameters();
|
||||||
}
|
} else if (p instanceof ICPPASTLambdaExpression) {
|
||||||
|
ICPPASTFunctionDeclarator dtor = ((ICPPASTLambdaExpression) p).getDeclarator();
|
||||||
|
if (dtor != null) {
|
||||||
|
nodes = dtor.getParameters();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (p instanceof ICPPASTCatchHandler) {
|
if (p instanceof ICPPASTCatchHandler) {
|
||||||
parent = p;
|
parent = p;
|
||||||
} else if (nodes == null || nodes.length == 0) {
|
} else if (nodes == null || nodes.length == 0) {
|
||||||
|
|
|
@ -15,11 +15,15 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||||
|
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.ASTGenericVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||||
|
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.EScopeKind;
|
import org.eclipse.cdt.core.dom.ast.EScopeKind;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
|
||||||
|
@ -80,7 +84,6 @@ import org.eclipse.cdt.core.dom.ast.IScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||||
|
@ -97,6 +100,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
|
||||||
|
@ -161,6 +165,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionTemplate;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionTemplate;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPLabel;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPLabel;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPLambdaExpressionParameter;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethod;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethod;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethodTemplate;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethodTemplate;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPNamespace;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPNamespace;
|
||||||
|
@ -603,16 +608,24 @@ public class CPPVisitor extends ASTQueries {
|
||||||
if (parent instanceof IASTStandardFunctionDeclarator) {
|
if (parent instanceof IASTStandardFunctionDeclarator) {
|
||||||
IASTStandardFunctionDeclarator fdtor = (IASTStandardFunctionDeclarator) param.getParent();
|
IASTStandardFunctionDeclarator fdtor = (IASTStandardFunctionDeclarator) param.getParent();
|
||||||
// Create parameter bindings only if the declarator declares a function
|
// Create parameter bindings only if the declarator declares a function
|
||||||
if (!(findOutermostDeclarator(fdtor).getParent() instanceof IASTDeclaration) ||
|
if (findTypeRelevantDeclarator(fdtor) != fdtor)
|
||||||
findTypeRelevantDeclarator(fdtor) != fdtor)
|
|
||||||
return null;
|
return null;
|
||||||
IASTParameterDeclaration[] params = fdtor.getParameters();
|
|
||||||
int i= 0;
|
final IASTNode dtorParent= findOutermostDeclarator(fdtor).getParent();
|
||||||
for (; i < params.length; i++) {
|
if (dtorParent instanceof ICPPASTLambdaExpression) {
|
||||||
if (params[i] == param)
|
return new CPPLambdaExpressionParameter(name);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return new CPPParameter(name, i);
|
|
||||||
|
if (dtorParent instanceof IASTDeclaration) {
|
||||||
|
IASTParameterDeclaration[] params = fdtor.getParameters();
|
||||||
|
int i= 0;
|
||||||
|
for (; i < params.length; i++) {
|
||||||
|
if (params[i] == param)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return new CPPParameter(name, i);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
} else if (parent instanceof ICPPASTTemplateDeclaration) {
|
} else if (parent instanceof ICPPASTTemplateDeclaration) {
|
||||||
return CPPTemplates.createBinding(param);
|
return CPPTemplates.createBinding(param);
|
||||||
}
|
}
|
||||||
|
@ -894,14 +907,21 @@ public class CPPVisitor extends ASTQueries {
|
||||||
while (parent.getParent() instanceof IASTDeclarator)
|
while (parent.getParent() instanceof IASTDeclarator)
|
||||||
parent = parent.getParent();
|
parent = parent.getParent();
|
||||||
ASTNodeProperty prop = parent.getPropertyInParent();
|
ASTNodeProperty prop = parent.getPropertyInParent();
|
||||||
if (prop == IASTSimpleDeclaration.DECLARATOR)
|
if (prop == IASTSimpleDeclaration.DECLARATOR) {
|
||||||
return dtor.getFunctionScope();
|
return dtor.getFunctionScope();
|
||||||
else if (prop == IASTFunctionDefinition.DECLARATOR) {
|
}
|
||||||
|
if (prop == IASTFunctionDefinition.DECLARATOR) {
|
||||||
final IASTCompoundStatement body = (IASTCompoundStatement) ((IASTFunctionDefinition) parent.getParent()).getBody();
|
final IASTCompoundStatement body = (IASTCompoundStatement) ((IASTFunctionDefinition) parent.getParent()).getBody();
|
||||||
if (body != null)
|
if (body != null)
|
||||||
return body.getScope();
|
return body.getScope();
|
||||||
return dtor.getFunctionScope();
|
return dtor.getFunctionScope();
|
||||||
}
|
}
|
||||||
|
if (prop == ICPPASTLambdaExpression.DECLARATOR) {
|
||||||
|
final IASTCompoundStatement body = ((ICPPASTLambdaExpression) parent.getParent()).getBody();
|
||||||
|
if (body != null)
|
||||||
|
return body.getScope();
|
||||||
|
return dtor.getFunctionScope();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (parent instanceof ICPPASTTemplateDeclaration) {
|
} else if (parent instanceof ICPPASTTemplateDeclaration) {
|
||||||
return CPPTemplates.getContainingScope(node);
|
return CPPTemplates.getContainingScope(node);
|
||||||
|
@ -1222,95 +1242,37 @@ public class CPPVisitor extends ASTQueries {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CollectProblemsAction extends CPPASTVisitor {
|
private static class CollectProblemsAction extends ASTGenericVisitor {
|
||||||
{
|
private List<IASTProblem> fProblems = null;
|
||||||
shouldVisitDeclarations = true;
|
|
||||||
shouldVisitExpressions = true;
|
|
||||||
shouldVisitStatements = true;
|
|
||||||
shouldVisitTypeIds = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int DEFAULT_CHILDREN_LIST_SIZE = 8;
|
CollectProblemsAction() {
|
||||||
private IASTProblem[] problems = null;
|
super(true);
|
||||||
int numFound = 0;
|
}
|
||||||
|
|
||||||
public CollectProblemsAction() {
|
|
||||||
problems = new IASTProblem[DEFAULT_CHILDREN_LIST_SIZE];
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addProblem(IASTProblem problem) {
|
private void addProblem(IASTProblem problem) {
|
||||||
if (problems.length == numFound) { // if the found array is full, then double the array
|
if (fProblems == null) {
|
||||||
IASTProblem[] old = problems;
|
fProblems= new ArrayList<IASTProblem>();
|
||||||
problems = new IASTProblem[old.length * 2];
|
|
||||||
for (int j = 0; j < old.length; ++j)
|
|
||||||
problems[j] = old[j];
|
|
||||||
}
|
|
||||||
problems[numFound++] = problem;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IASTProblem[] removeNullFromProblems() {
|
|
||||||
if (problems[problems.length-1] != null) { // if the last element in the list is not null then return the list
|
|
||||||
return problems;
|
|
||||||
} else if (problems[0] == null) { // if the first element in the list is null, then return empty list
|
|
||||||
return new IASTProblem[0];
|
|
||||||
}
|
}
|
||||||
|
fProblems.add(problem);
|
||||||
IASTProblem[] results = new IASTProblem[numFound];
|
}
|
||||||
for (int i=0; i<results.length; i++)
|
|
||||||
results[i] = problems[i];
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IASTProblem[] getProblems() {
|
public IASTProblem[] getProblems() {
|
||||||
return removeNullFromProblems();
|
if (fProblems == null)
|
||||||
|
return new IASTProblem[0];
|
||||||
|
|
||||||
|
return fProblems.toArray(new IASTProblem[fProblems.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processDeclaration(org.eclipse.cdt.core.dom.ast.IASTDeclaration)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public int visit(IASTDeclaration declaration) {
|
public int genericVisit(IASTNode node) {
|
||||||
if (declaration instanceof IASTProblemHolder)
|
if (node instanceof IASTProblemHolder)
|
||||||
addProblem(((IASTProblemHolder) declaration).getProblem());
|
addProblem(((IASTProblemHolder) node).getProblem());
|
||||||
|
|
||||||
return PROCESS_CONTINUE;
|
|
||||||
}
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processExpression(org.eclipse.cdt.core.dom.ast.IASTExpression)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int visit(IASTExpression expression) {
|
|
||||||
if (expression instanceof IASTProblemHolder)
|
|
||||||
addProblem(((IASTProblemHolder) expression).getProblem());
|
|
||||||
|
|
||||||
return PROCESS_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processStatement(org.eclipse.cdt.core.dom.ast.IASTStatement)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int visit(IASTStatement statement) {
|
|
||||||
if (statement instanceof IASTProblemHolder)
|
|
||||||
addProblem(((IASTProblemHolder) statement).getProblem());
|
|
||||||
|
|
||||||
return PROCESS_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processTypeId(org.eclipse.cdt.core.dom.ast.IASTTypeId)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int visit(IASTTypeId typeId) {
|
|
||||||
if (typeId instanceof IASTProblemHolder)
|
|
||||||
addProblem(((IASTProblemHolder) typeId).getProblem());
|
|
||||||
|
|
||||||
return PROCESS_CONTINUE;
|
return PROCESS_CONTINUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CollectDeclarationsAction extends CPPASTVisitor {
|
public static class CollectDeclarationsAction extends ASTVisitor {
|
||||||
private static final int DEFAULT_LIST_SIZE = 8;
|
private static final int DEFAULT_LIST_SIZE = 8;
|
||||||
private IASTName[] decls;
|
private IASTName[] decls;
|
||||||
private IBinding[] bindings;
|
private IBinding[] bindings;
|
||||||
|
@ -1484,7 +1446,7 @@ public class CPPVisitor extends ASTQueries {
|
||||||
return binding;
|
return binding;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CollectReferencesAction extends CPPASTVisitor {
|
public static class CollectReferencesAction extends ASTVisitor {
|
||||||
private static final int DEFAULT_LIST_SIZE = 8;
|
private static final int DEFAULT_LIST_SIZE = 8;
|
||||||
private IASTName[] refs;
|
private IASTName[] refs;
|
||||||
private IBinding[] bindings;
|
private IBinding[] bindings;
|
||||||
|
@ -1664,11 +1626,7 @@ public class CPPVisitor extends ASTQueries {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IType createType(IType returnType, ICPPASTFunctionDeclarator fnDtor) {
|
private static IType createType(IType returnType, ICPPASTFunctionDeclarator fnDtor) {
|
||||||
ICPPASTParameterDeclaration[] params = fnDtor.getParameters();
|
IType[] pTypes = createParameterTypes(fnDtor);
|
||||||
IType[] pTypes = new IType[params.length];
|
|
||||||
for (int i = 0; i < params.length; i++) {
|
|
||||||
pTypes[i]= createParameterType(params[i], true);
|
|
||||||
}
|
|
||||||
|
|
||||||
IASTName name = fnDtor.getName();
|
IASTName name = fnDtor.getName();
|
||||||
if (name instanceof ICPPASTQualifiedName) {
|
if (name instanceof ICPPASTQualifiedName) {
|
||||||
|
@ -1690,6 +1648,15 @@ public class CPPVisitor extends ASTQueries {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IType[] createParameterTypes(ICPPASTFunctionDeclarator fnDtor) {
|
||||||
|
ICPPASTParameterDeclaration[] params = fnDtor.getParameters();
|
||||||
|
IType[] pTypes = new IType[params.length];
|
||||||
|
for (int i = 0; i < params.length; i++) {
|
||||||
|
pTypes[i]= createParameterType(params[i], true);
|
||||||
|
}
|
||||||
|
return pTypes;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the type for a parameter declaration.
|
* Creates the type for a parameter declaration.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -989,7 +989,9 @@ public class Conversions {
|
||||||
// 4.8 floating point conversion
|
// 4.8 floating point conversion
|
||||||
// 4.9 floating-integral conversion
|
// 4.9 floating-integral conversion
|
||||||
if (s instanceof IBasicType) {
|
if (s instanceof IBasicType) {
|
||||||
// 4.7 An rvalue of an integer type can be converted to an rvalue of another integer type.
|
if (((IBasicType) s).getKind() == Kind.eVoid)
|
||||||
|
return false;
|
||||||
|
|
||||||
cost.setRank(Rank.CONVERSION);
|
cost.setRank(Rank.CONVERSION);
|
||||||
cost.setCouldNarrow();
|
cost.setCouldNarrow();
|
||||||
return true;
|
return true;
|
||||||
|
@ -1087,4 +1089,41 @@ public class Conversions {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 4.1
|
||||||
|
*/
|
||||||
|
public static IType lvalue_to_rvalue(IType type) {
|
||||||
|
IType nested= SemanticUtil.getNestedType(type, TDEF | REF);
|
||||||
|
if (nested == null || nested == type || nested instanceof IArrayType || nested instanceof ICPPFunctionType) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
IType unqualified= SemanticUtil.getNestedType(nested, TDEF | ALLCVQ);
|
||||||
|
if (unqualified instanceof ICPPClassType)
|
||||||
|
return nested;
|
||||||
|
|
||||||
|
return unqualified;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 4.2
|
||||||
|
*/
|
||||||
|
public static IType array_to_pointer(IType type) {
|
||||||
|
IType nested= SemanticUtil.getNestedType(type, TDEF);
|
||||||
|
if (nested instanceof IArrayType) {
|
||||||
|
return new CPPPointerType(((IArrayType) nested).getType());
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 4.3
|
||||||
|
*/
|
||||||
|
public static IType function_to_pointer(IType type) {
|
||||||
|
IType nested= SemanticUtil.getNestedType(type, TDEF);
|
||||||
|
if (nested instanceof IFunctionType) {
|
||||||
|
return new CPPPointerType(nested);
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
||||||
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.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
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;
|
||||||
|
@ -28,7 +29,6 @@ import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IQualifierType;
|
import org.eclipse.cdt.core.dom.ast.IQualifierType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
|
||||||
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.ICPPFunctionType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
|
||||||
|
@ -156,17 +156,12 @@ public class SemanticUtil {
|
||||||
* @return true if the specified method is a conversion operator
|
* @return true if the specified method is a conversion operator
|
||||||
*/
|
*/
|
||||||
public static final boolean isConversionOperator(ICPPMethod method) {
|
public static final boolean isConversionOperator(ICPPMethod method) {
|
||||||
boolean result= false;
|
final char[] name= method.getNameCharArray();
|
||||||
if (!method.isImplicit()) {
|
if (name.length > OPERATOR_CHARS.length + 1 && name[OPERATOR_CHARS.length] == ' ' &&
|
||||||
final char[] name= method.getNameCharArray();
|
CharArrayUtils.equals(name, 0, OPERATOR_CHARS.length, OPERATOR_CHARS)) {
|
||||||
if (name.length > OPERATOR_CHARS.length + 1 &&
|
return !cas.containsKey(name, OPERATOR_CHARS.length + 1, name.length - (OPERATOR_CHARS.length+1));
|
||||||
CharArrayUtils.equals(name, 0, OPERATOR_CHARS.length, OPERATOR_CHARS)) {
|
|
||||||
if (name[OPERATOR_CHARS.length] == ' ') {
|
|
||||||
result= !cas.containsKey(name, OPERATOR_CHARS.length + 1, name.length - (OPERATOR_CHARS.length+1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -71,6 +71,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
|
||||||
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.CPPArrayType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArrayType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClosureType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPParameterPackType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPParameterPackType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType;
|
||||||
|
@ -273,6 +274,9 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
|
||||||
pdomBinding = createBinding(parent, binding, fileLocalRec[0]);
|
pdomBinding = createBinding(parent, binding, fileLocalRec[0]);
|
||||||
if (pdomBinding != null) {
|
if (pdomBinding != null) {
|
||||||
getPDOM().putCachedResult(inputBinding, pdomBinding);
|
getPDOM().putCachedResult(inputBinding, pdomBinding);
|
||||||
|
if (inputBinding instanceof CPPClosureType) {
|
||||||
|
addImplicitMethods(pdomBinding, (ICPPClassType) binding);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
throw new CoreException(Util.createStatus(e));
|
throw new CoreException(Util.createStatus(e));
|
||||||
|
@ -395,7 +399,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
|
||||||
if (parent2 != null) {
|
if (parent2 != null) {
|
||||||
parent2.addChild(pdomBinding);
|
parent2.addChild(pdomBinding);
|
||||||
}
|
}
|
||||||
if (parent2 != this) {
|
if (parent != this && parent2 != this) {
|
||||||
insertIntoNestedBindingsIndex(pdomBinding);
|
insertIntoNestedBindingsIndex(pdomBinding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2006, 2009 Wind River Systems, Inc. and others.
|
* Copyright (c) 2006, 2010 Wind River Systems, Inc. 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
|
||||||
|
@ -14,9 +14,11 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
||||||
|
@ -25,7 +27,10 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTProblem;
|
import org.eclipse.cdt.core.dom.ast.IASTProblem;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.c.ICASTCompositeTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.c.ICASTCompositeTypeSpecifier;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
|
||||||
|
|
||||||
|
@ -51,6 +56,7 @@ abstract public class IndexerASTVisitor extends ASTVisitor {
|
||||||
shouldVisitInitializers= true;
|
shouldVisitInitializers= true;
|
||||||
shouldVisitDeclSpecifiers= true;
|
shouldVisitDeclSpecifiers= true;
|
||||||
shouldVisitProblems= true;
|
shouldVisitProblems= true;
|
||||||
|
shouldVisitExpressions= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<IASTProblem> getProblems() {
|
public List<IASTProblem> getProblems() {
|
||||||
|
@ -112,13 +118,11 @@ abstract public class IndexerASTVisitor extends ASTVisitor {
|
||||||
IASTName name= getLastInQualified(nestedDeclarator.getName());
|
IASTName name= getLastInQualified(nestedDeclarator.getName());
|
||||||
visit(name, fDefinitionName);
|
visit(name, fDefinitionName);
|
||||||
push(name, decl);
|
push(name, decl);
|
||||||
}
|
} else if (decl instanceof IASTSimpleDeclaration) {
|
||||||
else if (decl instanceof IASTSimpleDeclaration) {
|
|
||||||
IASTSimpleDeclaration sdecl= (IASTSimpleDeclaration) decl;
|
IASTSimpleDeclaration sdecl= (IASTSimpleDeclaration) decl;
|
||||||
if (sdecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef) {
|
if (sdecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef) {
|
||||||
IASTDeclarator[] declarators= sdecl.getDeclarators();
|
IASTDeclarator[] declarators= sdecl.getDeclarators();
|
||||||
for (int i = 0; i < declarators.length; i++) {
|
for (IASTDeclarator declarator : declarators) {
|
||||||
IASTDeclarator declarator = declarators[i];
|
|
||||||
if (declarator.getPointerOperators().length == 0 &&
|
if (declarator.getPointerOperators().length == 0 &&
|
||||||
declarator.getNestedDeclarator() == null) {
|
declarator.getNestedDeclarator() == null) {
|
||||||
IASTName name= getLastInQualified(declarator.getName());
|
IASTName name= getLastInQualified(declarator.getName());
|
||||||
|
@ -127,7 +131,7 @@ abstract public class IndexerASTVisitor extends ASTVisitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return PROCESS_CONTINUE;
|
return PROCESS_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,4 +189,40 @@ abstract public class IndexerASTVisitor extends ASTVisitor {
|
||||||
pop(initializer);
|
pop(initializer);
|
||||||
return PROCESS_CONTINUE;
|
return PROCESS_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lambda expressions
|
||||||
|
@Override
|
||||||
|
public int visit(IASTExpression expr) {
|
||||||
|
if (expr instanceof ICPPASTLambdaExpression) {
|
||||||
|
return visit((ICPPASTLambdaExpression) expr);
|
||||||
|
}
|
||||||
|
return PROCESS_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int visit(final ICPPASTLambdaExpression lambdaExpr) {
|
||||||
|
// Captures
|
||||||
|
for (ICPPASTCapture cap : lambdaExpr.getCaptures()) {
|
||||||
|
if (!cap.accept(this))
|
||||||
|
return PROCESS_ABORT;
|
||||||
|
}
|
||||||
|
// Definition of closure type
|
||||||
|
final IASTName closureName = lambdaExpr.getClosureTypeName();
|
||||||
|
visit(closureName, fDefinitionName);
|
||||||
|
|
||||||
|
// Definition of call operator
|
||||||
|
IASTName callOp= lambdaExpr.getFunctionCallOperatorName();
|
||||||
|
visit(callOp, closureName);
|
||||||
|
push(callOp, lambdaExpr);
|
||||||
|
|
||||||
|
ICPPASTFunctionDeclarator dtor = lambdaExpr.getDeclarator();
|
||||||
|
if (dtor != null && !dtor.accept(this))
|
||||||
|
return PROCESS_ABORT;
|
||||||
|
|
||||||
|
IASTCompoundStatement body = lambdaExpr.getBody();
|
||||||
|
if (body != null && !body.accept(this))
|
||||||
|
return PROCESS_ABORT;
|
||||||
|
|
||||||
|
pop(lambdaExpr);
|
||||||
|
return PROCESS_SKIP;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -465,4 +465,41 @@ public class CppCallHierarchyTest extends CallHierarchyBaseTest {
|
||||||
checkTreeNode(tree, 0, 0, "testchar()");
|
checkTreeNode(tree, 0, 0, "testchar()");
|
||||||
checkTreeNode(tree, 0, 1, null);
|
checkTreeNode(tree, 0, 1, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// void a() {}
|
||||||
|
// auto b= [] {a();};
|
||||||
|
// void c() {
|
||||||
|
// b();
|
||||||
|
// }
|
||||||
|
// void d() {
|
||||||
|
// []{c();}();
|
||||||
|
// }
|
||||||
|
public void testClosures_316307() throws Exception {
|
||||||
|
StringBuffer[] content= getContentsForTest(1);
|
||||||
|
String source = content[0].toString();
|
||||||
|
IFile file= createFile(getProject(), "testClosures.cpp", source);
|
||||||
|
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
|
||||||
|
waitForIndexer(fIndex, file, CallHierarchyBaseTest.INDEXER_WAIT_TIME);
|
||||||
|
CCorePlugin.getIndexManager().joinIndexer(INDEXER_WAIT_TIME, npm());
|
||||||
|
|
||||||
|
CEditor editor= openEditor(file);
|
||||||
|
int pos= source.indexOf("a(");
|
||||||
|
editor.selectAndReveal(pos, 1);
|
||||||
|
openCallHierarchy(editor, true);
|
||||||
|
Tree tree = getCHTreeViewer().getTree();
|
||||||
|
|
||||||
|
checkTreeNode(tree, 0, "a()");
|
||||||
|
TreeItem node = checkTreeNode(tree, 0, 0, "(anonymous)::operator ()()");
|
||||||
|
expandTreeItem(node);
|
||||||
|
node= checkTreeNode(node, 0, "c()");
|
||||||
|
checkTreeNode(node, 1, null);
|
||||||
|
expandTreeItem(node);
|
||||||
|
node= checkTreeNode(node, 0, "(anonymous)::operator ()()");
|
||||||
|
checkTreeNode(node, 1, null);
|
||||||
|
expandTreeItem(node);
|
||||||
|
node= checkTreeNode(node, 0, "d()");
|
||||||
|
checkTreeNode(node, 1, null);
|
||||||
|
expandTreeItem(node);
|
||||||
|
checkTreeNode(node, 0, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -405,6 +405,9 @@ public class SemanticHighlightings {
|
||||||
@Override
|
@Override
|
||||||
public boolean consumes(SemanticToken token) {
|
public boolean consumes(SemanticToken token) {
|
||||||
IASTNode node= token.getNode();
|
IASTNode node= token.getNode();
|
||||||
|
if (node instanceof IASTImplicitName)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (node instanceof IASTName) {
|
if (node instanceof IASTName) {
|
||||||
IASTName name= (IASTName)node;
|
IASTName name= (IASTName)node;
|
||||||
if (!name.isReference()) {
|
if (!name.isReference()) {
|
||||||
|
@ -659,6 +662,9 @@ public class SemanticHighlightings {
|
||||||
@Override
|
@Override
|
||||||
public boolean consumes(SemanticToken token) {
|
public boolean consumes(SemanticToken token) {
|
||||||
IASTNode node= token.getNode();
|
IASTNode node= token.getNode();
|
||||||
|
if (node instanceof IASTImplicitName)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (node instanceof IASTName) {
|
if (node instanceof IASTName) {
|
||||||
IASTName name= (IASTName)node;
|
IASTName name= (IASTName)node;
|
||||||
if (name.isDeclaration()) {
|
if (name.isDeclaration()) {
|
||||||
|
@ -1989,17 +1995,21 @@ public class SemanticHighlightings {
|
||||||
public boolean consumes(SemanticToken token) {
|
public boolean consumes(SemanticToken token) {
|
||||||
IASTNode node = token.getNode();
|
IASTNode node = token.getNode();
|
||||||
// so far we only have implicit names for overloaded operators and destructors, so this works
|
// so far we only have implicit names for overloaded operators and destructors, so this works
|
||||||
if(node instanceof IASTImplicitName) {
|
if (node instanceof IASTImplicitName) {
|
||||||
IASTImplicitName name = (IASTImplicitName) node;
|
IASTImplicitName name = (IASTImplicitName) node;
|
||||||
IBinding binding = name.resolveBinding();
|
if (name.isReference() && name.isOperator()) {
|
||||||
if(binding instanceof ICPPMethod && !(binding instanceof IProblemBinding) && ((ICPPMethod)binding).isImplicit()) {
|
IBinding binding = name.resolveBinding();
|
||||||
return false;
|
if (binding instanceof ICPPMethod && !(binding instanceof IProblemBinding)
|
||||||
|
&& ((ICPPMethod) binding).isImplicit()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
char[] chars = name.toCharArray();
|
||||||
|
if (chars[0] == '~' || OverloadableOperator.isNew(chars)
|
||||||
|
|| OverloadableOperator.isDelete(chars)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
char[] chars = name.toCharArray();
|
|
||||||
if(chars[0] == '~' || OverloadableOperator.isNew(chars) || OverloadableOperator.isDelete(chars)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -417,6 +417,9 @@ public class IndexUI {
|
||||||
if (ast != null) {
|
if (ast != null) {
|
||||||
final IASTNodeSelector nodeSelector = ast.getNodeSelector(null);
|
final IASTNodeSelector nodeSelector = ast.getNodeSelector(null);
|
||||||
IASTName name= nodeSelector.findEnclosingName(offset, length);
|
IASTName name= nodeSelector.findEnclosingName(offset, length);
|
||||||
|
if (name == null) {
|
||||||
|
name= nodeSelector.findImplicitName(offset, length);
|
||||||
|
}
|
||||||
if (name != null && name.getParent() instanceof IASTPreprocessorMacroExpansion) {
|
if (name != null && name.getParent() instanceof IASTPreprocessorMacroExpansion) {
|
||||||
IASTFileLocation floc= name.getParent().getFileLocation();
|
IASTFileLocation floc= name.getParent().getFileLocation();
|
||||||
IASTNode node= nodeSelector.findEnclosingNodeInExpansion(floc.getNodeOffset(), floc.getNodeLength());
|
IASTNode node= nodeSelector.findEnclosingNodeInExpansion(floc.getNodeOffset(), floc.getNodeLength());
|
||||||
|
|
Loading…
Add table
Reference in a new issue