1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-25 09:55:29 +02:00

Patch for Devin Steffler.

This patch includes:
- ICPPASTConversionName that represents C++ conversion member functions
 -> also keeps track of the IASTTypeId for the conversion member function
- ICPPASTOperatorName that represents C++ overloaded operator member function
- a couple tests
This commit is contained in:
John Camelon 2005-04-04 19:27:22 +00:00
parent cb199fd44a
commit 26b0ae693a
13 changed files with 590 additions and 105 deletions

View file

@ -28,8 +28,10 @@ import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBasicType;
@ -49,6 +51,8 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
@ -3194,5 +3198,75 @@ public class AST2CPPTests extends AST2BaseTest {
IEnumerator one = (IEnumerator) col.getName(3).resolveBinding();
assertSame( one.getType(), e );
}
public void testOperatorConversionNames() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("class Foo {\n"); //$NON-NLS-1$
buffer.append("public:\n"); //$NON-NLS-1$
buffer.append("operator int();\n"); //$NON-NLS-1$
buffer.append("char& operator[](unsigned int);\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); //$NON-NLS-1$
CPPNameCollector col = new CPPNameCollector();
tu.accept( col );
IASTName name1 = col.getName(1);
IASTName name2 = col.getName(2);
assertNotNull(name1);
assertNotNull(name2);
assertTrue(name1 instanceof ICPPASTConversionName);
assertTrue(name2 instanceof ICPPASTOperatorName);
IASTTypeId typeId = ((ICPPASTConversionName)name1).getTypeId();
assertNotNull(typeId);
assertEquals( ((IASTSimpleDeclSpecifier)typeId.getDeclSpecifier()).getType(), IASTSimpleDeclSpecifier.t_int );
}
public void testBug36769B() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("class X { operator int(); }; \n"); //$NON-NLS-1$
buffer.append("X::operator int() { } \n"); //$NON-NLS-1$
buffer.append("template <class A,B> class X<A,C> { operator int(); }; \n"); //$NON-NLS-1$
buffer.append("template <class A,B> X<A,C>::operator int() { } \n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); //$NON-NLS-1$
CPPNameCollector col = new CPPNameCollector();
tu.accept( col );
// 1,4,12,21 - conversion
// 2, 16 .isConversion
assertEquals(col.size(), 22);
assertNotNull(col.getName(1));
assertNotNull(col.getName(4));
assertNotNull(col.getName(12));
assertNotNull(col.getName(21));
assertNotNull(col.getName(2));
assertNotNull(col.getName(16));
// ensure the conversions are conversions
assertTrue(col.getName(1) instanceof ICPPASTConversionName);
assertTrue(col.getName(4) instanceof ICPPASTConversionName);
assertTrue(col.getName(12) instanceof ICPPASTConversionName);
assertTrue(col.getName(21) instanceof ICPPASTConversionName);
assertNotNull(((ICPPASTConversionName)col.getName(1)).getTypeId());
assertNotNull(((ICPPASTConversionName)col.getName(4)).getTypeId());
assertNotNull(((ICPPASTConversionName)col.getName(12)).getTypeId());
assertNotNull(((ICPPASTConversionName)col.getName(21)).getTypeId());
// ensure qualified name isConversionOrOperator
assertTrue(col.getName(2) instanceof ICPPASTQualifiedName);
assertTrue(col.getName(16) instanceof ICPPASTQualifiedName);
assertTrue(((ICPPASTQualifiedName)col.getName(2)).isConversionOrOperator());
assertTrue(((ICPPASTQualifiedName)col.getName(16)).isConversionOrOperator());
}
}

View file

@ -0,0 +1,41 @@
/**********************************************************************
* Copyright (c) 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
/**
* This interface represents a C++ conversion member function.
*
* @author dsteffle
*/
public interface ICPPASTConversionName extends IASTName {
public static final ASTNodeProperty TYPE_ID=new ASTNodeProperty(
"IASTArrayDeclarator.TYPE_ID - IASTTypeId for ICPPASTConversionName"); //$NON-NLS-1$
/**
* Returns the IASTTypeId for the ICPPASTConversionName.
*
* i.e. getTypeId() on operator int(); would return the IASTTypeId for "int"
*
* @return
*/
public IASTTypeId getTypeId();
/**
* Sets the IASTTypeId for the ICPPASTConversionName.
*
* @param typeId
*/
public void setTypeId(IASTTypeId typeId);
}

View file

@ -0,0 +1,22 @@
/**********************************************************************
* Copyright (c) 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.IASTName;
/**
* This interface represents a C++ overloaded operator member function.
*
* @author dsteffle
*/
public interface ICPPASTOperatorName extends IASTName {
}

View file

@ -56,4 +56,12 @@ public interface ICPPASTQualifiedName extends IASTName, IASTNameOwner {
* boolean
*/
public void setFullyQualified(boolean value);
/**
* This is used to check if the ICPPASTQualifiedName's last segment is
* an ICPPASTConversionName or an ICPPASTOperatorName.
*
* @return
*/
public boolean isConversionOrOperator();
}

View file

@ -69,8 +69,4 @@ public interface ITokenDuple {
public void freeReferences( );
public void acceptElement( ISourceElementRequestor requestor );
/**
* @return
*/
public abstract boolean isConversion();
}

View file

@ -0,0 +1,47 @@
/**********************************************************************
* Copyright (c) 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
/**
* The implemented ICPPASTConversionName.
*
* @author dsteffle
*/
public class CPPASTConversionName extends CPPASTName implements ICPPASTConversionName {
private IASTTypeId typeId=null;
public CPPASTConversionName() {
super();
}
public CPPASTConversionName(char[] name) {
super(name);
}
public IASTTypeId getTypeId() {
return typeId;
}
public void setTypeId(IASTTypeId typeId) {
this.typeId=typeId;
}
public boolean accept(ASTVisitor action) {
boolean why = super.accept(action);
if( why && typeId != null )
return typeId.accept( action );
return why;
}
}

View file

@ -0,0 +1,28 @@
/**********************************************************************
* Copyright (c) 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName;
/**
* The imlemented ICPPASTOperatorName.
*
* @author dsteffle
*/
public class CPPASTOperatorName extends CPPASTName implements ICPPASTOperatorName {
public CPPASTOperatorName() {
super();
}
public CPPASTOperatorName(char[] name) {
super(name);
}
}

View file

@ -15,7 +15,10 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNameOwner;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
/**
* @author jcamelon
@ -259,4 +262,22 @@ public class CPPASTQualifiedName extends CPPASTNode implements
names[names.length - 1].setBinding( binding );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName#isConversionOrOperator()
*/
public boolean isConversionOrOperator() {
IASTName[] nonNullNames = getNames(); // ensure no null names
int len=nonNullNames.length;
if (nonNullNames[len-1] instanceof ICPPASTConversionName || nonNullNames[len-1] instanceof ICPPASTOperatorName) return true;
// check templateId's name
if (nonNullNames[len-1] instanceof ICPPASTTemplateId) {
IASTName tempName = ((ICPPASTTemplateId)nonNullNames[len-1]).getTemplateName();
if (tempName instanceof ICPPASTConversionName || tempName instanceof ICPPASTOperatorName) return true;
}
return false;
}
}

View file

@ -22,8 +22,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
* @author jcamelon
*/
public class CPPASTTemplateId extends CPPASTNode implements ICPPASTTemplateId {
private static final char[] EMPTY_CHAR_ARRAY = { };
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
// private static final char[] EMPTY_CHAR_ARRAY = { };
// private static final String EMPTY_STRING = ""; //$NON-NLS-1$
private IASTName templateName;
/* (non-Javadoc)

View file

@ -81,6 +81,7 @@ 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.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
@ -130,12 +131,12 @@ import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.ITokenDuple;
import org.eclipse.cdt.core.parser.ParseError;
import org.eclipse.cdt.core.parser.ParserMode;
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.AbstractGNUSourceCodeParser;
import org.eclipse.cdt.internal.core.dom.parser.BacktrackException;
import org.eclipse.cdt.internal.core.parser.SimpleDeclarationStrategy;
import org.eclipse.cdt.internal.core.parser.TemplateParameterManager;
import org.eclipse.cdt.internal.core.parser.token.OperatorTokenDuple;
import org.eclipse.cdt.internal.core.parser.token.TokenFactory;
/**
@ -148,6 +149,7 @@ import org.eclipse.cdt.internal.core.parser.token.TokenFactory;
*/
public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
private static final String COMPL = "~"; //$NON-NLS-1$
private static final String CONST_CAST = "const_cast"; //$NON-NLS-1$
private static final String REINTERPRET_CAST = "reinterpret_cast"; //$NON-NLS-1$
private static final String STATIC_CAST = "static_cast"; //$NON-NLS-1$
@ -422,12 +424,13 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return last;
}
protected ITokenDuple operatorId(IToken originalToken,
protected IASTName operatorId(IToken originalToken,
TemplateParameterManager templateArgs) throws BacktrackException,
EndOfFileException {
// we know this is an operator
IToken operatorToken = consume(IToken.t_operator);
IToken toSend = null;
IASTTypeId typeId = null;
if (LA(1).isOperator() || LT(1) == IToken.tLPAREN
|| LT(1) == IToken.tLBRACKET) {
if ((LT(1) == IToken.t_new || LT(1) == IToken.t_delete)
@ -452,7 +455,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
} else {
// must be a conversion function
IToken t = LA(1);
typeId(true, false);
typeId = typeId(true, false);
if (t != LA(1)) {
while (t.getNext() != LA(1)) {
t = t.getNext();
@ -474,12 +477,18 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
hasTemplateId = true;
}
ITokenDuple duple = TokenFactory
ITokenDuple duple = TokenFactory
.createTokenDuple(originalToken == null ? operatorToken
: originalToken, toSend, (hasTemplateId ? templateArgs
.getTemplateArgumentsList() : null));
return duple;
OperatorTokenDuple operator= new OperatorTokenDuple(duple);
if (typeId!=null) { // if it's a conversion operator
operator.setConversionOperator(true);
operator.setTypeId(typeId);
}
return createName(operator);
} finally {
if (grabbedNewInstance)
TemplateParameterManager.returnInstance(templateArgs);
@ -1528,7 +1537,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
isTemplate = true;
}
IASTName name = createName(idExpression());
IASTName name = idExpression();
ICPPASTFieldReference fieldReference = createFieldReference();
((ASTNode) fieldReference).setOffsetAndLength(
@ -1556,7 +1565,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
isTemplate = true;
}
name = createName(idExpression());
name = idExpression();
fieldReference = createFieldReference();
((ASTNode) fieldReference).setOffsetAndLength(
@ -1728,11 +1737,10 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
case IToken.t_operator:
case IToken.tCOMPL:
{
ITokenDuple duple = idExpression();
IASTName name = createName(duple);
IASTName name = idExpression();
IASTIdExpression idExpression = createIdExpression();
((ASTNode) idExpression).setOffsetAndLength(duple.getStartOffset(),
duple.getEndOffset() - duple.getStartOffset());
((ASTNode) idExpression).setOffsetAndLength(((ASTNode)name).getOffset(),
((ASTNode)name).getOffset() + ((ASTNode)name).getLength() - ((ASTNode)name).getOffset());
idExpression.setName(name);
name.setParent(idExpression);
name.setPropertyInParent(IASTIdExpression.ID_NAME);
@ -1772,11 +1780,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return new CPPASTIdExpression();
}
protected ITokenDuple idExpression() throws EndOfFileException,
protected IASTName idExpression() throws EndOfFileException,
BacktrackException {
ITokenDuple duple = null;
IASTName name = null;
try {
duple = name();
name = createName(name());
} catch (BacktrackException bt) {
IToken mark = mark();
if (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) {
@ -1791,16 +1799,16 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
if (LT(1) == IToken.t_operator)
duple = operatorId(start, null);
name = operatorId(start, null);
else {
backup(mark);
throwBacktrack(start.getOffset(), end.getEndOffset()
- start.getOffset());
}
} else if (LT(1) == IToken.t_operator)
duple = operatorId(null, null);
name = operatorId(null, null);
}
return duple;
return name;
}
@ -2543,6 +2551,12 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
else
// templateID
subName = createTemplateID(segments[i]);
if (i==segments.length-1 &&
duple instanceof OperatorTokenDuple) { // make sure the last segment is an OperatorName/ConversionName
subName = createOperatorName((OperatorTokenDuple)duple, subName);
}
subName.setParent(result);
subName.setPropertyInParent(ICPPASTQualifiedName.SEGMENT_NAME);
((ASTNode) subName).setOffsetAndLength(segments[i].getStartOffset(),
@ -2598,8 +2612,12 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if( duple.getTemplateIdArgLists() != null )
return createTemplateID( duple );
// We're a single token
CPPASTName name = new CPPASTName(duple.toCharArray());
// We're a single name
IASTName name = new CPPASTName(duple.toCharArray());
if (duple instanceof OperatorTokenDuple) {
name = createOperatorName((OperatorTokenDuple)duple, name);
}
IToken token = duple.getFirstToken();
switch (token.getType()) {
case IToken.tCOMPLETION:
@ -2608,10 +2626,32 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
break;
}
name.setOffsetAndLength(duple.getStartOffset(), duple.getEndOffset()
- duple.getStartOffset());
((ASTNode)name).setOffsetAndLength(duple.getStartOffset(), duple.getEndOffset()
- duple.getStartOffset());
return name;
}
protected IASTName createOperatorName(OperatorTokenDuple duple, IASTName name) {
IASTName aName=null;
if (duple.isConversionOperator()) {
aName = new CPPASTConversionName(name.toCharArray());
IASTTypeId typeId = duple.getTypeId();
typeId.setParent(aName);
typeId.setPropertyInParent(ICPPASTConversionName.TYPE_ID);
((CPPASTConversionName)aName).setTypeId(typeId);
} else {
aName = new CPPASTOperatorName(name.toCharArray());
}
if (name instanceof ICPPASTTemplateId) {
((ICPPASTTemplateId)name).setTemplateName(aName);
return name;
}
return aName;
}
/**
* @return
@ -2923,7 +2963,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* @throws EndOfFileException
* we could encounter EOF while looking ahead
*/
protected boolean lookAheadForConstructorOrConversion(Flags flags)
protected boolean lookAheadForConstructorOrOperator(Flags flags)
throws EndOfFileException {
if (flags.isForParameterDeclaration())
return false;
@ -2931,9 +2971,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return true;
IToken mark = mark();
ITokenDuple duple = null;
IASTName name = null;
try {
duple = consumeTemplatedOperatorName();
name = consumeTemplatedOperatorName();
} catch (BacktrackException e) {
backup(mark);
return false;
@ -2942,50 +2982,48 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return false;
}
if (duple == null) {
if (name == null) {
backup(mark);
return false;
}
ITokenDuple leadingSegments = duple.getLeadingSegments();
if (leadingSegments == null) {
backup(mark);
return false;
}
ITokenDuple lastSegment = duple.getLastSegment();
char[] className = lastSegment.extractNameFromTemplateId();
if (className == null || CharArrayUtils.equals(className, EMPTY_STRING)) {
backup(mark);
return false;
}
ITokenDuple secondlastSegment = leadingSegments.getLastSegment();
if (secondlastSegment == null) {
backup(mark);
return false;
}
char[] otherName = secondlastSegment.extractNameFromTemplateId();
if (otherName == null || CharArrayUtils.equals(otherName, EMPTY_STRING)) {
backup(mark);
return false;
}
if (lastSegment.isConversion()) {
backup(mark);
return true;
}
if (CharArrayUtils.equals(className, otherName)) {
backup(mark);
return true;
}
char[] destructorName = CharArrayUtils.concat(
"~".toCharArray(), otherName); //$NON-NLS-1$
if (CharArrayUtils.equals(destructorName, className)) {
backup(mark);
return true;
}
// constructor/conversion must be an ICPPASTQualifiedName (i.e. can't be defined for the global scope)
if (name instanceof ICPPASTQualifiedName) {
IASTName[] segments = ((ICPPASTQualifiedName)name).getNames();
int len = segments.length;
if (len >= 2) {
if (segments[0].toString().length() == 0) {
backup(mark);
return false;
}
if (((ICPPASTQualifiedName)name).isConversionOrOperator()) { // conversion or operator
backup(mark);
return true;
}
if (segments[len-1].toString().equals(segments[len-2].toString())) { // constructor
backup(mark);
return true;
}
StringBuffer destructorName = new StringBuffer();
destructorName.append(COMPL);
destructorName.append(segments[len-2]);
if (segments[len-1].toString().equals(destructorName.toString())) { // destructor
backup(mark);
return true;
}
} else {
backup(mark);
return false;
}
} else {
backup(mark);
return false;
}
backup(mark);
return false;
}
@ -3185,7 +3223,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (parm && flags.haveEncounteredTypename())
break declSpecifiers;
if (lookAheadForConstructorOrConversion(flags))
if (lookAheadForConstructorOrOperator(flags))
break declSpecifiers;
if (lookAheadForDeclarator(flags))
@ -3600,10 +3638,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
declaratorName = createName();
} else {
try {
ITokenDuple d = consumeTemplatedOperatorName();
declaratorName = createName(d);
declaratorName = consumeTemplatedOperatorName();
finalOffset = calculateEndOffset(declaratorName);
if (d.isConversion())
if (declaratorName instanceof ICPPASTQualifiedName && ((ICPPASTQualifiedName)declaratorName).isConversionOrOperator())
isFunction = true;
} catch (BacktrackException bt) {
declaratorName = createName();
@ -3899,7 +3936,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return new CPPASTDeclarator();
}
protected ITokenDuple consumeTemplatedOperatorName()
protected IASTName consumeTemplatedOperatorName()
throws EndOfFileException, BacktrackException {
TemplateParameterManager argumentList = TemplateParameterManager
.getInstance();
@ -3908,13 +3945,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return operatorId(null, null);
try {
return name();
return createName(name());
} catch (BacktrackException bt) {
}
IToken start = null;
boolean hasTemplateId = false;
IToken mark = mark();
if (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) {
start = consume();
@ -3922,28 +3957,22 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (start.getType() == IToken.tIDENTIFIER) {
end = consumeTemplateArguments(end, argumentList);
if (end != null && end.getType() == IToken.tGT)
hasTemplateId = true;
}
while (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) {
end = consume();
if (end.getType() == IToken.tIDENTIFIER) {
end = consumeTemplateArguments(end, argumentList);
if (end.getType() == IToken.tGT)
hasTemplateId = true;
}
}
if (LT(1) == IToken.t_operator)
end = operatorId(start, (hasTemplateId ? argumentList : null))
.getLastToken();
else {
int endOffset = (end != null) ? end.getEndOffset() : 0;
backup(mark);
throwBacktrack(mark.getOffset(), endOffset - mark.getOffset());
if (LT(1) == IToken.t_operator) {
return operatorId(start, argumentList );
}
return TokenFactory.createTokenDuple(start, end, argumentList
.getTemplateArgumentsList());
int endOffset = (end != null) ? end.getEndOffset() : 0;
backup(mark);
throwBacktrack(mark.getOffset(), endOffset - mark.getOffset());
}
int endOffset = (mark != null) ? mark.getEndOffset() : 0;
backup(mark);
@ -4533,15 +4562,23 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createName(org.eclipse.cdt.core.parser.IToken)
*/
protected IASTName createName(IToken token) {
CPPASTName n = new CPPASTName(token.getCharImage());
IASTName n = null;
if (token instanceof OperatorTokenDuple) {
n = createOperatorName((OperatorTokenDuple)token, n);
} else {
n = new CPPASTName(token.getCharImage());
}
switch (token.getType()) {
case IToken.tCOMPLETION:
case IToken.tEOC:
createCompletionNode(token).addName(n);
break;
}
n.setOffsetAndLength(token.getOffset(), token.getLength());
return n;
((ASTNode)n).setOffsetAndLength(token.getOffset(), token.getLength());
return n;
}
/*

View file

@ -598,15 +598,4 @@ public class BasicTokenDuple implements ITokenDuple {
public char[] getFilename() {
return firstToken.getFilename();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#isConversion()
*/
public boolean isConversion() {
int index = findLastTokenType( IToken.t_operator );
if( index == -1 ) return false;
return true;
}
}

View file

@ -0,0 +1,220 @@
/**********************************************************************
* Copyright (c) 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.internal.core.parser.token;
import java.util.Iterator;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.parser.ISourceElementRequestor;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.ITokenDuple;
/**
* This class is used by the GNUCPPSourceParser as an intermediate determinant of whether a
* BasicTokenDuple represents an IASTConversionFunction or an IASTOperatorFunction.
*
* @author dsteffle
*/
public class OperatorTokenDuple implements ITokenDuple {
private ITokenDuple token = null;
private IASTTypeId typeId = null;
private boolean isConversionOperator=false;
/**
* Simple constructor. token is wrapped by this class.
* @param token
*/
public OperatorTokenDuple(ITokenDuple token) {
this.token=token;
}
// below are functions used by GNUCPPSourceParser, see IOperatorTokenDuple
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.token.IOperatorTokenDuple#isConversionOperator()
*/
public boolean isConversionOperator() {
return isConversionOperator;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.token.IOperatorTokenDuple#setConversionOperator(boolean)
*/
public void setConversionOperator(boolean isConversionOperator) {
this.isConversionOperator = isConversionOperator;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.token.IOperatorTokenDuple#getTypeId()
*/
public IASTTypeId getTypeId() {
return typeId;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.token.IOperatorTokenDuple#
* isConversionOperator(org.eclipse.cdt.core.dom.ast.IASTTypeId)
*/
public void setTypeId(IASTTypeId typeId) {
this.typeId = typeId;
}
// below are ITokenDuple functions
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#getFirstToken()
*/
public IToken getFirstToken() {
return token.getFirstToken();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#getLastToken()
*/
public IToken getLastToken() {
return token.getLastToken();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#getTemplateIdArgLists()
*/
public List[] getTemplateIdArgLists() {
return token.getTemplateIdArgLists();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#getLastSegment()
*/
public ITokenDuple getLastSegment() {
return token.getLastSegment();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#getLeadingSegments()
*/
public ITokenDuple getLeadingSegments() {
return token.getLeadingSegments();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#getSegmentCount()
*/
public int getSegmentCount() {
return token.getSegmentCount();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#iterator()
*/
public Iterator iterator() {
return token.iterator();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#toCharArray()
*/
public char[] toCharArray() {
return token.toCharArray();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#getFilename()
*/
public char[] getFilename() {
return token.getFilename();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#isIdentifier()
*/
public boolean isIdentifier() {
return token.isIdentifier();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#length()
*/
public int length() {
return token.length();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#getSubrange(int, int)
*/
public ITokenDuple getSubrange(int startIndex, int endIndex) {
return token.getSubrange(startIndex, endIndex);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#getToken(int)
*/
public IToken getToken(int index) {
return token.getToken(index);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#getSegments()
*/
public ITokenDuple[] getSegments() {
return token.getSegments();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#findLastTokenType(int)
*/
public int findLastTokenType(int type) {
return token.findLastTokenType(type);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#getStartOffset()
*/
public int getStartOffset() {
return token.getStartOffset();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#getEndOffset()
*/
public int getEndOffset() {
return token.getEndOffset();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#getLineNumber()
*/
public int getLineNumber() {
return token.getLineNumber();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#syntaxOfName()
*/
public boolean syntaxOfName() {
return token.syntaxOfName();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#extractNameFromTemplateId()
*/
public char[] extractNameFromTemplateId() {
return token.extractNameFromTemplateId();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#contains(org.eclipse.cdt.core.parser.ITokenDuple)
*/
public boolean contains(ITokenDuple duple) {
return token.contains(duple);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#toQualifiedName()
*/
public String[] toQualifiedName() {
return token.toQualifiedName();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#freeReferences()
*/
public void freeReferences() {
token.freeReferences();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#
* acceptElement(org.eclipse.cdt.core.parser.ISourceElementRequestor)
*/
public void acceptElement(ISourceElementRequestor requestor) {
token.acceptElement(requestor);
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
public String toString() {
return token.toString();
}
}

View file

@ -309,6 +309,7 @@ public class DOMASTNodeLeaf implements IAdaptable {
}
private static class ASTPropertySource implements IPropertySource {
private static final IPropertyDescriptor[] BLANK_DESCRIPTORS = new IPropertyDescriptor[0];
private static final String OPEN_PAREN = " ("; //$NON-NLS-1$
private static final String CLOSE_PAREN = ")"; //$NON-NLS-1$
private static final String L_BRACKET_STRING = "["; //$NON-NLS-1$
@ -360,6 +361,7 @@ public class DOMASTNodeLeaf implements IAdaptable {
private IPropertyDescriptor[] getPropertyDescriptors(Object obj) {
IPropertyDescriptor[] desc = new IPropertyDescriptor[DEFAULT_DESCRIPTOR_SIZE];
if (obj==null) return BLANK_DESCRIPTORS;
Class objClass = obj.getClass();
Class[] interfaces = objClass.getInterfaces();