1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Cleanup parsing of qualified names, fixes bug 256840.

This commit is contained in:
Markus Schorn 2008-12-09 10:49:09 +00:00
parent 66e2ae5119
commit b66d33d52d
16 changed files with 665 additions and 2178 deletions

View file

@ -4397,7 +4397,7 @@ public class AST2CPPTests extends AST2BaseTest {
IASTDeclarator d = p2m.getDeclarators()[0]; IASTDeclarator d = p2m.getDeclarators()[0];
ICPPASTPointerToMember po = (ICPPASTPointerToMember) d ICPPASTPointerToMember po = (ICPPASTPointerToMember) d
.getPointerOperators()[0]; .getPointerOperators()[0];
assertEquals(po.getName().toString(), "X::"); //$NON-NLS-1$ assertEquals("X::", po.getName().toString()); //$NON-NLS-1$
} }
// struct B {}; // struct B {};
@ -6150,9 +6150,11 @@ public class AST2CPPTests extends AST2BaseTest {
// struct B { // struct B {
// operator ns::A(); // problems on operator ns and on A // operator ns::A(); // problems on operator ns and on A
// }; // };
public void _testNamespaceQualifiedOperator_256840() throws Exception { public void testNamespaceQualifiedOperator_256840() throws Exception {
BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true); final String code = getAboveComment();
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
bh.assertNonProblem("operator ns::A", 14); bh.assertNonProblem("operator ns::A", 14);
parseAndCheckBindings(code, ParserLanguage.CPP);
} }
// void f(); // void f();

View file

@ -6,17 +6,14 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM Corporation - initial API and implementation * Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
/*
* Created on Jan 17, 2005
*/
package org.eclipse.cdt.core.dom.ast; package org.eclipse.cdt.core.dom.ast;
/** /**
* @author aniefer * Interface for problem bindings.
* @noimplement This interface is not intended to be implemented by clients.
*/ */
public interface IProblemBinding extends IBinding, IScope, IType { public interface IProblemBinding extends IBinding, IScope, IType {
@ -123,5 +120,15 @@ public interface IProblemBinding extends IBinding, IScope, IType {
public static final int SEMANTIC_RECURSION_IN_LOOKUP = 0x00E; public static final int SEMANTIC_RECURSION_IN_LOOKUP = 0x00E;
public static final int LAST_PROBLEM = SEMANTIC_RECURSION_IN_LOOKUP; /**
* @deprecated, there may be additional problems.
*/
@Deprecated
public static final int LAST_PROBLEM = 0x00E;
/**
* @since 5.1
*/
public static final int SEMANTIC_INVALID_TEMPLATE_ARGUMENTS = 0x00F;
} }

View file

@ -18,8 +18,9 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
/** /**
* @author jcamelon * @deprecated
*/ */
@Deprecated
public interface ITokenDuple { public interface ITokenDuple {
public abstract IToken getFirstToken(); public abstract IToken getFirstToken();

View file

@ -415,17 +415,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
* @throws BacktrackException * @throws BacktrackException
* request a backtrack * request a backtrack
*/ */
protected IToken identifier() throws EndOfFileException, BacktrackException { protected abstract IASTName identifier() throws EndOfFileException, BacktrackException;
switch (LT(1)) {
case IToken.tIDENTIFIER:
case IToken.tCOMPLETION:
case IToken.tEOC:
return consume();
default:
throw backtrack;
}
}
/** /**
* @return Returns the backtrackCount. * @return Returns the backtrackCount.
@ -887,8 +877,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected abstract IASTExpression unaryExpression() throws BacktrackException, EndOfFileException; protected abstract IASTExpression unaryExpression() throws BacktrackException, EndOfFileException;
protected abstract IASTExpression primaryExpression() throws BacktrackException, EndOfFileException; protected abstract IASTExpression primaryExpression() throws BacktrackException, EndOfFileException;
protected abstract IASTExpression buildTypeIdExpression(int op, IASTTypeId typeId, int startingOffset, int endingOffset);
protected abstract IASTTranslationUnit getTranslationUnit(); protected abstract IASTTranslationUnit getTranslationUnit();
protected abstract void setupTranslationUnit() throws Exception; protected abstract void setupTranslationUnit() throws Exception;
@ -1268,7 +1256,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
IASTName name; IASTName name;
if (LT(1) == IToken.tIDENTIFIER) { if (LT(1) == IToken.tIDENTIFIER) {
name= createName(identifier()); name= identifier();
} else { } else {
name= nodeFactory.newName(); name= nodeFactory.newName();
} }
@ -1308,7 +1296,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
if (needComma) if (needComma)
throw backtrack; throw backtrack;
final IASTName etorName= createName(identifier()); final IASTName etorName= identifier();
final IASTEnumerator enumerator= nodeFactory.newEnumerator(etorName, null); final IASTEnumerator enumerator= nodeFactory.newEnumerator(etorName, null);
endOffset= calculateEndOffset(etorName); endOffset= calculateEndOffset(etorName);
setRange(enumerator, problemOffset, endOffset); setRange(enumerator, problemOffset, endOffset);
@ -1339,8 +1327,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected abstract IASTStatement statement() throws EndOfFileException, BacktrackException; protected abstract IASTStatement statement() throws EndOfFileException, BacktrackException;
protected abstract IASTName createName(IToken token);
protected IASTExpression condition(boolean followedByParenthesis) throws BacktrackException, EndOfFileException { protected IASTExpression condition(boolean followedByParenthesis) throws BacktrackException, EndOfFileException {
IToken mark= mark(); IToken mark= mark();
try { try {
@ -1666,15 +1652,15 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected abstract IASTAmbiguousStatement createAmbiguousStatement(); protected abstract IASTAmbiguousStatement createAmbiguousStatement();
protected IASTStatement parseLabelStatement() throws EndOfFileException, BacktrackException { protected IASTStatement parseLabelStatement() throws EndOfFileException, BacktrackException {
IToken labelName = consume(); // tIDENTIFIER int offset= LA(1).getOffset();
consume(); // tCOLON IASTName name = identifier(); // tIDENTIFIER
consume(IToken.tCOLON); // tCOLON
IASTStatement nestedStatement = statement(); IASTStatement nestedStatement = statement();
int lastOffset = calculateEndOffset( nestedStatement ); int lastOffset = calculateEndOffset( nestedStatement );
IASTName name = createName(labelName);
IASTLabelStatement label_statement = nodeFactory.newLabelStatement(name, nestedStatement); IASTLabelStatement label_statement = nodeFactory.newLabelStatement(name, nestedStatement);
((ASTNode) label_statement).setOffsetAndLength(labelName.getOffset(), lastOffset - labelName.getOffset()); setRange(label_statement, offset, lastOffset);
return label_statement; return label_statement;
} }
@ -1688,10 +1674,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected IASTStatement parseGotoStatement() throws EndOfFileException, BacktrackException { protected IASTStatement parseGotoStatement() throws EndOfFileException, BacktrackException {
int startOffset = consume().getOffset(); // t_goto int startOffset = consume().getOffset(); // t_goto
IToken identifier = consume(IToken.tIDENTIFIER); IASTName goto_label_name = identifier();
int lastOffset = consume(IToken.tSEMI).getEndOffset(); int lastOffset = consume(IToken.tSEMI).getEndOffset();
IASTName goto_label_name = createName(identifier);
IASTGotoStatement goto_statement = nodeFactory.newGotoStatement(goto_label_name); IASTGotoStatement goto_statement = nodeFactory.newGotoStatement(goto_label_name);
((ASTNode) goto_statement).setOffsetAndLength(startOffset, lastOffset - startOffset); ((ASTNode) goto_statement).setOffsetAndLength(startOffset, lastOffset - startOffset);
return goto_statement; return goto_statement;
@ -1745,7 +1730,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
switch (LT(1)) { switch (LT(1)) {
case IToken.tEOC: case IToken.tEOC:
// We're trying to start one // We're trying to start one
IASTName name = createName(LA(1)); IASTName name = identifier();
IASTIdExpression idExpr = nodeFactory.newIdExpression(name); IASTIdExpression idExpr = nodeFactory.newIdExpression(name);
result = idExpr; result = idExpr;
break; break;
@ -1945,8 +1930,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
consume(); consume();
IASTExpression expr2= expression(); IASTExpression expr2= expression();
endOffset1= consumeOrEOC(IToken.tRPAREN).getEndOffset(); endOffset1= consumeOrEOC(IToken.tRPAREN).getEndOffset();
expr= nodeFactory.newTypeIdExpression(IASTTypeIdExpression.op_typeof, typeid);
expr= buildTypeIdExpression(IASTTypeIdExpression.op_typeof, typeid, typeidOffset, calculateEndOffset(typeid)); setRange(expr, typeidOffset, calculateEndOffset(typeid));
IASTExpressionList expressionList = nodeFactory.newExpressionList(); IASTExpressionList expressionList = nodeFactory.newExpressionList();
((ASTNode) expressionList).setOffsetAndLength(typeidOffset, calculateEndOffset(expr2)-typeidOffset); ((ASTNode) expressionList).setOffsetAndLength(typeidOffset, calculateEndOffset(expr2)-typeidOffset);
@ -1989,7 +1974,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
IASTExpression result1= null; IASTExpression result1= null;
if (typeid != null && endOffset1 >= endOffset2) { if (typeid != null && endOffset1 >= endOffset2) {
result1= buildTypeIdExpression(typeExprKind, typeid, offset, endOffset1); IASTTypeIdExpression typeIdExpression = nodeFactory.newTypeIdExpression(typeExprKind, typeid);
setRange(typeIdExpression, offset, endOffset1);
result1= typeIdExpression;
backup(typeidLA); backup(typeidLA);
if (expr == null || endOffset1 > endOffset2) if (expr == null || endOffset1 > endOffset2)

View file

@ -36,7 +36,7 @@ import org.eclipse.core.runtime.PlatformObject;
*/ */
public class ProblemBinding extends PlatformObject implements IProblemBinding, IType, IScope, IASTInternalScope { public class ProblemBinding extends PlatformObject implements IProblemBinding, IType, IScope, IASTInternalScope {
protected final int id; protected final int id;
protected final char[] arg; protected char[] arg;
protected IASTNode node; protected IASTNode node;
private String message = null; private String message = null;
@ -56,7 +56,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
protected static final String[] errorMessages; protected static final String[] errorMessages;
static { static {
errorMessages = new String[IProblemBinding.LAST_PROBLEM]; errorMessages = new String[IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS];
errorMessages[SEMANTIC_NAME_NOT_FOUND - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.nameNotFound"); //$NON-NLS-1$ errorMessages[SEMANTIC_NAME_NOT_FOUND - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.nameNotFound"); //$NON-NLS-1$
errorMessages[SEMANTIC_AMBIGUOUS_LOOKUP - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.pst.ambiguousLookup"); //$NON-NLS-1$ errorMessages[SEMANTIC_AMBIGUOUS_LOOKUP - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.pst.ambiguousLookup"); //$NON-NLS-1$
errorMessages[SEMANTIC_INVALID_TYPE - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.pst.invalidType"); //$NON-NLS-1$ errorMessages[SEMANTIC_INVALID_TYPE - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.pst.invalidType"); //$NON-NLS-1$
@ -71,6 +71,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
errorMessages[SEMANTIC_BAD_SCOPE - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.dom.badScope"); //$NON-NLS-1$ errorMessages[SEMANTIC_BAD_SCOPE - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.dom.badScope"); //$NON-NLS-1$
errorMessages[SEMANTIC_RECURSION_IN_LOOKUP - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.dom.recursionInResolution"); //$NON-NLS-1$ errorMessages[SEMANTIC_RECURSION_IN_LOOKUP - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.dom.recursionInResolution"); //$NON-NLS-1$
errorMessages[SEMANTIC_MEMBER_DECLARATION_NOT_FOUND - 1]= ParserMessages.getString("ASTProblemFactory.error.semantic.dom.memberDeclNotFound"); //$NON-NLS-1$ errorMessages[SEMANTIC_MEMBER_DECLARATION_NOT_FOUND - 1]= ParserMessages.getString("ASTProblemFactory.error.semantic.dom.memberDeclNotFound"); //$NON-NLS-1$
errorMessages[SEMANTIC_INVALID_TEMPLATE_ARGUMENTS - 1]= ParserMessages.getString("ASTProblemFactory.error.semantic.dom.invalidTemplateArgs"); //$NON-NLS-1$
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -87,7 +88,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
if (message != null) if (message != null)
return message; return message;
String msg = (id >= 0 && id <= LAST_PROBLEM) ? errorMessages[id - 1] : ""; //$NON-NLS-1$ String msg = (id > 0 && id <= errorMessages.length) ? errorMessages[id - 1] : ""; //$NON-NLS-1$
if (arg != null) { if (arg != null) {
msg = MessageFormat.format(msg, new Object[] { new String(arg) }); msg = MessageFormat.format(msg, new Object[] { new String(arg) });
@ -224,6 +225,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
public int getLineNumber() { public int getLineNumber() {
if (node != null) { if (node != null) {
IASTFileLocation fileLoc = node.getFileLocation(); IASTFileLocation fileLoc = node.getFileLocation();
if (fileLoc != null)
return fileLoc.getStartingLineNumber(); return fileLoc.getStartingLineNumber();
} }
return -1; return -1;
@ -245,4 +247,11 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
public IBinding getOwner() throws DOMException { public IBinding getOwner() throws DOMException {
return null; return null;
} }
public void setASTNode(IASTNode node, char[] arg) {
if (node != null)
this.node= node;
if (arg != null)
this.arg= arg;
}
} }

View file

@ -227,10 +227,9 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
switch (LT(1)) { switch (LT(1)) {
case IToken.tDOT: case IToken.tDOT:
int offset = consume().getOffset(); int offset = consume().getOffset();
IToken id = identifier(); IASTName n = identifier();
IASTName n = createName(id);
ICASTFieldDesignator fieldDesignator = nodeFactory.newFieldDesignator(n); ICASTFieldDesignator fieldDesignator = nodeFactory.newFieldDesignator(n);
setRange(fieldDesignator, offset, id.getEndOffset()); setRange(fieldDesignator, offset, calculateEndOffset(n));
if (designatorList == null) if (designatorList == null)
designatorList = new ArrayList<ICASTDesignator>(DEFAULT_DESIGNATOR_LIST_SIZE); designatorList = new ArrayList<ICASTDesignator>(DEFAULT_DESIGNATOR_LIST_SIZE);
designatorList.add(fieldDesignator); designatorList.add(fieldDesignator);
@ -266,11 +265,11 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
// fix for 84176: if reach identifier and it's not a designator then return empty designator list // fix for 84176: if reach identifier and it's not a designator then return empty designator list
if (supportGCCStyleDesignators && lt1 == IToken.tIDENTIFIER && LT(2) == IToken.tCOLON) { if (supportGCCStyleDesignators && lt1 == IToken.tIDENTIFIER && LT(2) == IToken.tCOLON) {
IToken identifier = identifier(); int offset= LA(1).getOffset();
IASTName n = identifier();
int lastOffset = consume(IToken.tCOLON).getEndOffset(); int lastOffset = consume(IToken.tCOLON).getEndOffset();
IASTName n = createName(identifier);
ICASTFieldDesignator designator = nodeFactory.newFieldDesignator(n); ICASTFieldDesignator designator = nodeFactory.newFieldDesignator(n);
((ASTNode) designator).setOffsetAndLength(identifier.getOffset(), lastOffset - identifier.getOffset()); setRange(designator, offset, lastOffset);
return Collections.singletonList(designator); return Collections.singletonList(designator);
} }
@ -542,15 +541,6 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
} }
} }
@Override
protected IASTExpression buildTypeIdExpression(int op, IASTTypeId typeId,
int startingOffset, int endingOffset) {
IASTTypeIdExpression result = nodeFactory.newTypeIdExpression(op, typeId);
((ASTNode) result).setOffsetAndLength(startingOffset, endingOffset - startingOffset);
return result;
}
protected IASTExpression postfixExpression() throws EndOfFileException, BacktrackException { protected IASTExpression postfixExpression() throws EndOfFileException, BacktrackException {
IASTExpression firstExpression = null; IASTExpression firstExpression = null;
switch (LT(1)) { switch (LT(1)) {
@ -634,7 +624,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
case IToken.tDOT: case IToken.tDOT:
// member access // member access
IToken dot = consume(); IToken dot = consume();
IASTName name = createName(identifier()); IASTName name = identifier();
if (name == null) if (name == null)
throwBacktrack(((ASTNode) firstExpression).getOffset(), throwBacktrack(((ASTNode) firstExpression).getOffset(),
((ASTNode) firstExpression).getLength() + dot.getLength()); ((ASTNode) firstExpression).getLength() + dot.getLength());
@ -648,7 +638,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
case IToken.tARROW: case IToken.tARROW:
// member access // member access
IToken arrow = consume(); IToken arrow = consume();
name = createName(identifier()); name = identifier();
if (name == null) if (name == null)
throwBacktrack(((ASTNode) firstExpression).getOffset(), throwBacktrack(((ASTNode) firstExpression).getOffset(),
((ASTNode) firstExpression).getLength() + arrow.getLength()); ((ASTNode) firstExpression).getLength() + arrow.getLength());
@ -722,8 +712,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
case IToken.tCOMPLETION: case IToken.tCOMPLETION:
case IToken.tEOC: case IToken.tEOC:
int startingOffset = LA(1).getOffset(); int startingOffset = LA(1).getOffset();
IToken t1 = identifier(); IASTName name = identifier();
IASTName name = createName(t1);
IASTIdExpression idExpression = nodeFactory.newIdExpression(name); IASTIdExpression idExpression = nodeFactory.newIdExpression(name);
((ASTNode) idExpression).setOffsetAndLength((ASTNode) name); ((ASTNode) idExpression).setOffsetAndLength((ASTNode) name);
return idExpression; return idExpression;
@ -843,7 +832,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
int options= 0; int options= 0;
int isLong= 0; int isLong= 0;
IToken identifier= null; IASTName identifier= null;
IASTDeclSpecifier result= null; IASTDeclSpecifier result= null;
IASTExpression typeofExpression= null; IASTExpression typeofExpression= null;
IASTProblem problem= null; IASTProblem problem= null;
@ -1001,11 +990,11 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
IToken mark= mark(); IToken mark= mark();
try { try {
final IToken idToken= identifier(); // for the specifier final IASTName id= identifier(); // for the specifier
final IASTDeclarator altDtor = initDeclarator(declOption); final IASTDeclarator altDtor = initDeclarator(declOption);
if (LA(1) == e.currToken) { if (LA(1) == e.currToken) {
e.altDeclarator= altDtor; e.altDeclarator= altDtor;
e.altSpec= buildNamedTypeSpecifier(idToken, storageClass, options, offset, idToken.getEndOffset()); e.altSpec= buildNamedTypeSpecifier(id, storageClass, options, offset, calculateEndOffset(id));
} }
} catch (FoundAggregateInitializer lie) { } catch (FoundAggregateInitializer lie) {
lie.fDeclSpec= e.declSpec; lie.fDeclSpec= e.declSpec;
@ -1017,7 +1006,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
throw e; throw e;
} }
identifier = identifier(); identifier = identifier();
endOffset= identifier.getEndOffset(); endOffset= calculateEndOffset(identifier);
encounteredTypename= true; encounteredTypename= true;
break; break;
case IToken.t_struct: case IToken.t_struct:
@ -1121,9 +1110,8 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
return buildSimpleDeclSpec(storageClass, simpleType, options, isLong, typeofExpression, offset, endOffset); return buildSimpleDeclSpec(storageClass, simpleType, options, isLong, typeofExpression, offset, endOffset);
} }
private ICASTTypedefNameSpecifier buildNamedTypeSpecifier(IToken identifier, int storageClass, private ICASTTypedefNameSpecifier buildNamedTypeSpecifier(IASTName name, int storageClass,
int options, int offset, int endOffset) { int options, int offset, int endOffset) {
IASTName name = createName(identifier);
ICASTTypedefNameSpecifier declSpec = nodeFactory.newTypedefNameSpecifier(name); ICASTTypedefNameSpecifier declSpec = nodeFactory.newTypedefNameSpecifier(name);
configureDeclSpec(declSpec, storageClass, options); configureDeclSpec(declSpec, storageClass, options);
declSpec.setRestrict((options & RESTRICT) != 0); declSpec.setRestrict((options & RESTRICT) != 0);
@ -1218,9 +1206,9 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
__attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers); __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
// class name // class name
IToken nameToken = null; IASTName name = null;
if (LT(1) == IToken.tIDENTIFIER) { if (LT(1) == IToken.tIDENTIFIER) {
nameToken = identifier(); name = identifier();
} }
// if __attribute__ or __declspec occurs after struct/union/class identifier and before the { or ; // if __attribute__ or __declspec occurs after struct/union/class identifier and before the { or ;
@ -1232,7 +1220,9 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
throwBacktrack(errorPoint); throwBacktrack(errorPoint);
} }
IASTName name = (nameToken == null) ? nodeFactory.newName() : createName(nameToken); if (name == null) {
name= nodeFactory.newName();
}
ICASTCompositeTypeSpecifier result = nodeFactory.newCompositeTypeSpecifier(classKind, name); ICASTCompositeTypeSpecifier result = nodeFactory.newCompositeTypeSpecifier(classKind, name);
int endOffset= consume().getEndOffset(); int endOffset= consume().getEndOffset();
@ -1303,8 +1293,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
// if __attribute__ or __declspec occurs after struct/union/class and before the identifier // if __attribute__ or __declspec occurs after struct/union/class and before the identifier
__attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers); __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
IToken identifier = identifier(); IASTName name = identifier();
IASTName name = createName(identifier);
IASTElaboratedTypeSpecifier result = nodeFactory.newElaboratedTypeSpecifier(eck, name); IASTElaboratedTypeSpecifier result = nodeFactory.newElaboratedTypeSpecifier(eck, name);
((ASTNode) result).setOffsetAndLength(t.getOffset(), calculateEndOffset(name) - t.getOffset()); ((ASTNode) result).setOffsetAndLength(t.getOffset(), calculateEndOffset(name) - t.getOffset());
return result; return result;
@ -1361,7 +1350,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
if (option.fRequireAbstract) if (option.fRequireAbstract)
throwBacktrack(LA(1)); throwBacktrack(LA(1));
final IASTName declaratorName = createName(identifier()); final IASTName declaratorName = identifier();
endOffset= calculateEndOffset(declaratorName); endOffset= calculateEndOffset(declaratorName);
return declarator(pointerOps, declaratorName, null, startingOffset, endOffset, option); return declarator(pointerOps, declaratorName, null, startingOffset, endOffset, option);
} }
@ -1520,14 +1509,14 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
switch (LT(1)) { switch (LT(1)) {
case IToken.tCOMMA: case IToken.tCOMMA:
last = consume(); last = consume();
parmNames[i] = createName(identifier()); parmNames[i] = identifier();
seenParameter = true; seenParameter = true;
break; break;
case IToken.tIDENTIFIER: case IToken.tIDENTIFIER:
if (seenParameter) if (seenParameter)
throwBacktrack(startOffset, last.getEndOffset() - startOffset); throwBacktrack(startOffset, last.getEndOffset() - startOffset);
parmNames[i] = createName(identifier()); parmNames[i] = identifier();
seenParameter = true; seenParameter = true;
break; break;
case IToken.tRPAREN: case IToken.tRPAREN:
@ -1672,18 +1661,29 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
@Override @Override
protected IASTName createName(IToken t) { protected IASTName identifier() throws EndOfFileException, BacktrackException {
IASTName n = nodeFactory.newName(t.getCharImage()); final IToken t= LA(1);
IASTName n;
switch (t.getType()) { switch (t.getType()) {
case IToken.tIDENTIFIER:
consume();
n = nodeFactory.newName(t.getCharImage());
break;
case IToken.tCOMPLETION: case IToken.tCOMPLETION:
case IToken.tEOC: case IToken.tEOC:
consume();
n = nodeFactory.newName(t.getCharImage());
createCompletionNode(t).addName(n); createCompletionNode(t).addName(n);
break;
}
((ASTNode) n).setOffsetAndLength(t.getOffset(), t.getEndOffset() - t.getOffset());
return n; return n;
default:
throw backtrack;
} }
setRange(n, t.getOffset(), t.getEndOffset());
return n;
}
protected void consumeArrayModifiers(List<IASTArrayModifier> arrayMods) throws EndOfFileException, BacktrackException { protected void consumeArrayModifiers(List<IASTArrayModifier> arrayMods) throws EndOfFileException, BacktrackException {
while (LT(1) == IToken.tLBRACKET) { while (LT(1) == IToken.tLBRACKET) {

View file

@ -112,23 +112,22 @@ public class CPPASTIfStatement extends ASTNode implements ICPPASTIfStatement, IA
} }
public void replace(IASTNode child, IASTNode other) { public void replace(IASTNode child, IASTNode other) {
if( thenClause == child ) if (thenClause == child) {
{
other.setParent(child.getParent()); other.setParent(child.getParent());
other.setPropertyInParent(child.getPropertyInParent()); other.setPropertyInParent(child.getPropertyInParent());
thenClause = (IASTStatement) other; thenClause = (IASTStatement) other;
} } else if (elseClause == child) {
else if( elseClause == child )
{
other.setParent(child.getParent()); other.setParent(child.getParent());
other.setPropertyInParent(child.getPropertyInParent()); other.setPropertyInParent(child.getPropertyInParent());
elseClause = (IASTStatement) other; elseClause = (IASTStatement) other;
} } else if (condDecl == child) {
if( condDecl == child )
{
other.setParent(child.getParent()); other.setParent(child.getParent());
other.setPropertyInParent(child.getPropertyInParent()); other.setPropertyInParent(child.getPropertyInParent());
condDecl = (IASTDeclaration) other; condDecl = (IASTDeclaration) other;
} else if (condition == child) {
other.setParent(child.getParent());
other.setPropertyInParent(child.getPropertyInParent());
condition = (IASTExpression) other;
} }
} }

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
@ -97,7 +98,15 @@ public abstract class CPPASTNameBase extends ASTNode implements IASTName {
fBinding= new RecursionResolvingBinding(this); fBinding= new RecursionResolvingBinding(this);
} else { } else {
fIsFinal= false; fIsFinal= false;
fBinding= createIntermediateBinding(); final IBinding b= createIntermediateBinding();
if (b instanceof ProblemBinding) {
ProblemBinding pb= (ProblemBinding) b;
final IASTNode node= pb.getASTNode();
if (node == null || node.getParent() == null) {
pb.setASTNode(this, toCharArray());
}
}
fBinding= b;
} }
} }
if (!fIsFinal) if (!fIsFinal)

View file

@ -162,7 +162,7 @@ public class CPPTemplates {
final int numArgs = arguments.length; final int numArgs = arguments.length;
final int numParams= parameters.length; final int numParams= parameters.length;
if (numParams == 0 || numParams < numArgs) if (numParams == 0 || numParams < numArgs)
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_USING); return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
ICPPTemplateArgument[] completeArgs= new ICPPTemplateArgument[numParams]; ICPPTemplateArgument[] completeArgs= new ICPPTemplateArgument[numParams];
CPPTemplateParameterMap map= new CPPTemplateParameterMap(numParams); CPPTemplateParameterMap map= new CPPTemplateParameterMap(numParams);
@ -176,7 +176,7 @@ public class CPPTemplates {
} else { } else {
ICPPTemplateArgument defaultArg= param.getDefaultValue(); ICPPTemplateArgument defaultArg= param.getDefaultValue();
if (defaultArg == null) { if (defaultArg == null) {
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_USING); return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
} }
arg= instantiateArgument(defaultArg, map, null); arg= instantiateArgument(defaultArg, map, null);
arg= SemanticUtil.getSimplifiedArgument(arg); arg= SemanticUtil.getSimplifiedArgument(arg);
@ -186,7 +186,7 @@ public class CPPTemplates {
if (!hasDependentDefaultArg) { if (!hasDependentDefaultArg) {
arg= CPPTemplates.matchTemplateParameterAndArgument(param, arg, map); arg= CPPTemplates.matchTemplateParameterAndArgument(param, arg, map);
if (arg == null) if (arg == null)
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_USING); return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
} }
map.put(param, arg); map.put(param, arg);
@ -212,19 +212,7 @@ public class CPPTemplates {
} }
private static IBinding createProblem(ICPPClassTemplate template, int id) { private static IBinding createProblem(ICPPClassTemplate template, int id) {
IASTNode node= null; IASTNode node= new CPPASTName(template.getNameCharArray());
if (template instanceof ICPPInternalBinding) {
ICPPInternalBinding internal= (ICPPInternalBinding) template;
node= internal.getDefinition();
if (node == null) {
IASTNode[] decls= internal.getDeclarations();
if (decls != null && decls.length > 0)
node= decls[0];
}
}
if (node == null) {
node= new CPPASTName(template.getNameCharArray());
}
return new ProblemBinding(node, id, template.getNameCharArray()); return new ProblemBinding(node, id, template.getNameCharArray());
} }

View file

@ -75,4 +75,5 @@ ASTProblemFactory.error.semantic.dom.invalidRedeclaration=Invalid redeclaration
ASTProblemFactory.error.semantic.dom.recursionInResolution=Recursion while looking up ''{0}'' ASTProblemFactory.error.semantic.dom.recursionInResolution=Recursion while looking up ''{0}''
ASTProblemFactory.error.semantic.dom.badScope=A scope could not be created to represent the name {0} ASTProblemFactory.error.semantic.dom.badScope=A scope could not be created to represent the name {0}
ASTProblemFactory.error.semantic.dom.memberDeclNotFound=A declaration could not be found for this member definition: {0} ASTProblemFactory.error.semantic.dom.memberDeclNotFound=A declaration could not be found for this member definition: {0}
ASTProblemFactory.error.semantic.dom.invalidTemplateArgs=A template id provides illegal arguments for the instantiation: {0}
CPPASTAmbiguousTemplateArgument_InvalidConstruction=Internal parser error: Template argument ambiguity constructed with {0} CPPASTAmbiguousTemplateArgument_InvalidConstruction=Internal parser error: Template argument ambiguity constructed with {0}

View file

@ -1,105 +0,0 @@
/*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTNode;
/**
* Manages lists of template parameter nodes during the parsing
* of names. The purpose of this class is performance, as these
* lists are managed using lazy initialization and object pooling.
* This class is basically as substitute for List<List<IASTNode>>.
*
* When using the object pool code must be wrapped in a try-finally
* block to ensure the object is returned to the pool.
*
* TODO: How much of a performance improvement are we talking about here?
* It might make sense just to get rid of this class. The extra complexity
* might not be worth it.
*/
public final class TemplateParameterManager {
protected void reset() {
list = Collections.emptyList();
emptySegmentCount = 0;
}
private TemplateParameterManager(int i) {
reset();
counterId = i;
}
private final int counterId;
private List<List<IASTNode>> list;
private int emptySegmentCount;
public List<List<IASTNode>> getTemplateArgumentsList() {
return list;
}
public void addSegment(List<IASTNode> inputSegment) {
// avoid creating an actual ArrayList instance for as long as possible
if(inputSegment == null) {
if(list.isEmpty())
++emptySegmentCount;
else
list.add( null );
}
else {
if(list.isEmpty()) {
list = new ArrayList<List<IASTNode>>();
for( int i = 0; i < emptySegmentCount; ++i )
list.add( null );
}
list.add( inputSegment );
}
}
// An object pool
private static final int NUMBER_OF_INSTANCES = 8;
private static final boolean [] instancesUsed = new boolean[ NUMBER_OF_INSTANCES ];
private static final TemplateParameterManager [] counters = new TemplateParameterManager[ NUMBER_OF_INSTANCES ];
private static int counter = 8;
static {
for( int i = 0; i < NUMBER_OF_INSTANCES; ++i ) {
counters[ i ] = new TemplateParameterManager( i );
}
}
public synchronized static TemplateParameterManager getInstance() {
int index = findFreeCounter();
if( index == -1 )
return new TemplateParameterManager(++counter);
instancesUsed[ index ] = true;
return counters[ index ];
}
public synchronized static void returnInstance( TemplateParameterManager c ) {
if( c.counterId > 0 && c.counterId < NUMBER_OF_INSTANCES )
instancesUsed[ c.counterId ] = false;
c.reset();
}
private static int findFreeCounter() {
for( int i = 0; i < NUMBER_OF_INSTANCES; ++i )
if( instancesUsed[i] == false )
return i;
return -1;
}
}

View file

@ -1,607 +0,0 @@
/*******************************************************************************
* Copyright (c) 2002, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.token;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.ITokenDuple;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
/**
* @author jcamelon
*
*/
public class BasicTokenDuple implements ITokenDuple {
BasicTokenDuple( IToken first, IToken last )
{
// assert ( first != null && last != null ) : this;
firstToken = first;
lastToken = last;
}
protected int numSegments = -1;
BasicTokenDuple( ITokenDuple firstDuple, ITokenDuple secondDuple ){
this( firstDuple.getFirstToken(), secondDuple.getLastToken() );
}
protected final IToken firstToken, lastToken;
public IToken getFirstToken() {
return firstToken;
}
public IToken getLastToken() {
return lastToken;
}
public Iterator<IToken> iterator()
{
return new TokenIterator();
}
public ITokenDuple getLastSegment()
{
IToken first = null, last = null, token = null;
for( ; ; ){
if( token == getLastToken() )
break;
token = ( token != null ) ? token.getNext() : getFirstToken();
if( first == null )
first = token;
if( token.getType() == IToken.tLT )
token = TokenFactory.consumeTemplateIdArguments( token, getLastToken() );
else if( token.getType() == IToken.tCOLONCOLON ){
first = null;
continue;
}
last = token;
}
List<IASTNode> [] args = getTemplateIdArgLists();
if( args != null && args[ args.length - 1 ] != null ){
List<List<IASTNode>> newArgs = new ArrayList<List<IASTNode>>( 1 );
newArgs.add( args[ args.length - 1 ] );
return TokenFactory.createTokenDuple( first, last, newArgs );
}
return TokenFactory.createTokenDuple( first, last );
}
public ITokenDuple[] getSegments()
{
List<ITokenDuple> r = new ArrayList<ITokenDuple>();
IToken token = null;
IToken prev = null;
IToken last = getLastToken();
IToken startOfSegment = getFirstToken();
for( ;; ){
if( token == last )
break;
if( startOfSegment == last.getNext() && startOfSegment.getType() != IToken.tEOC ) // for the EOC token, next points to itself
{
startOfSegment = null;
break;
}
prev = token;
token = ( token != null ) ? token.getNext() : getFirstToken();
if( token.getType() == IToken.tLT )
token = TokenFactory.consumeTemplateIdArguments( token, last );
if( token.getType() == IToken.tCOLONCOLON ){
if( startOfSegment == token ){
//an empty segment, prev is not valid (and neither is the code)
prev = null;
}
ITokenDuple d = TokenFactory.createTokenDuple( startOfSegment, ( prev == null ) ? startOfSegment : prev );
r.add( d );
startOfSegment = token.getNext();
continue;
}
}
if( startOfSegment != null )
{
ITokenDuple d = TokenFactory.createTokenDuple( startOfSegment, last );
r.add( d );
}
return r.toArray( new ITokenDuple[ r.size() ]);
}
public ITokenDuple getLeadingSegments(){
if( getFirstToken() == null )
return null;
int num = getSegmentCount();
if( num <= 1 )
return null;
IToken first = null, last = null;
IToken previous = null, token = null;
for( ; ; ){
if( token == getLastToken() )
break;
token = ( token != null ) ? token.getNext() : getFirstToken();
if( first == null )
first = token;
if( token.getType() == IToken.tLT )
token = TokenFactory.consumeTemplateIdArguments( token, getLastToken() );
else if( token.getType() == IToken.tCOLONCOLON ){
last = previous;
continue;
}
previous = token;
}
if( last == null ){
//"::A"
return null;
}
if( getTemplateIdArgLists() != null ){
List<IASTNode>[] args = getTemplateIdArgLists();
List<List<IASTNode>> newArgs = new ArrayList<List<IASTNode>>( args.length - 1 );
boolean foundArgs = false;
for( int i = 0; i < args.length - 1; i++ ){
newArgs.add( args[i] );
if( args[i] != null )
foundArgs = true;
}
return TokenFactory.createTokenDuple( first, last, ( foundArgs ? newArgs : null ) );
}
return TokenFactory.createTokenDuple( first, last );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#getSegmentCount()
*/
public int getSegmentCount() {
if( numSegments == -1 )
numSegments = calculateSegmentCount();
return numSegments;
}
private static final char[] EMPTY_STRING = "".toCharArray(); //$NON-NLS-1$
private char[] stringRepresentation = null;
private class TokenIterator implements Iterator<IToken>
{
private IToken iter = firstToken;
/* (non-Javadoc)
* @see java.util.Iterator#hasNext()
*/
public boolean hasNext() {
return ( iter != null );
}
/* (non-Javadoc)
* @see java.util.Iterator#next()
*/
public IToken next() {
if( ! hasNext() )
throw new NoSuchElementException();
IToken temp = iter;
if( iter == lastToken )
iter = null;
else
iter = iter.getNext();
return temp;
}
/* (non-Javadoc)
* @see java.util.Iterator#remove()
*/
public void remove() {
throw new UnsupportedOperationException();
}
}
public static int getCharArrayLength( IToken f, IToken l ){
if( f == l )
return f.getCharImage().length;
IToken prev = null;
IToken iter = f;
int length = 0;
for( ; ; ){
if( iter == null ) return 0;
if( prev != null && prev.getType() != IToken.tCOLONCOLON &&
prev.getType() != IToken.tIDENTIFIER &&
prev.getType() != IToken.tLT &&
prev.getType() != IToken.tBITCOMPLEMENT &&
iter.getType() != IToken.tGT &&
prev.getType() != IToken.tLBRACKET &&
iter.getType() != IToken.tRBRACKET &&
iter.getType() != IToken.tCOLONCOLON )
{
length++;
}
length += iter.getCharImage().length;
if( iter == l ) break;
prev = iter;
iter = iter.getNext();
}
return length;
}
public static char[] createCharArrayRepresentation( IToken f, IToken l)
{
if( f == l ) return f.getCharImage();
IToken prev = null;
IToken iter = f;
int length = getCharArrayLength( f, l );
char[] buff = new char[ length ];
for( int i = 0; i < length; )
{
if( prev != null &&
prev.getType() != IToken.tCOLONCOLON &&
prev.getType() != IToken.tIDENTIFIER &&
prev.getType() != IToken.tLT &&
prev.getType() != IToken.tBITCOMPLEMENT &&
iter.getType() != IToken.tGT &&
prev.getType() != IToken.tLBRACKET &&
iter.getType() != IToken.tRBRACKET &&
iter.getType() != IToken.tCOLONCOLON )
buff[i++] = ' ';
if( iter == null ) return EMPTY_STRING;
CharArrayUtils.overWrite( buff, i, iter.getCharImage() );
i+= iter.getCharImage().length;
if( iter == l ) break;
prev = iter;
iter = iter.getNext();
}
return buff;
}
@Override
public String toString()
{
if( stringRepresentation == null )
stringRepresentation = createCharArrayRepresentation(firstToken, lastToken);
return String.valueOf(stringRepresentation);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#length()
*/
public int length()
{
int count = 1;
IToken i = firstToken;
while( i != lastToken )
{
++count;
i = i.getNext();
}
return count;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#getSubDuple(int, int)
*/
public ITokenDuple getSubrange(int startIndex, int endIndex)
{
return TokenFactory.createTokenDuple( getToken( startIndex ), getToken( endIndex) );
}
public IToken getToken(int index)
{
if( index < 0 ) return null;
IToken iter = firstToken;
int count = 0;
while( iter != lastToken )
{
iter = iter.getNext();
if( count == index )
return iter;
++count;
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#findLastTokenType(int)
*/
public int findLastTokenType(int type)
{
int count = 0;
int lastFound = -1;
IToken i = firstToken;
while( i != lastToken )
{
if( i.getType() == type )
lastFound = count;
++count;
i = i.getNext();
}
return lastFound;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#getEndOffset()
*/
public int getEndOffset() {
return getLastToken().getEndOffset();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#getStartOffset()
*/
public int getStartOffset() {
return getFirstToken().getOffset();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#getTemplateIdArgLists()
*/
public List<IASTNode>[] getTemplateIdArgLists() {
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#syntaxOfName()
*/
public boolean syntaxOfName() {
IToken iter = firstToken;
while( iter != lastToken)
{
if( iter.getType() == IToken.tLT ){
iter = TokenFactory.consumeTemplateIdArguments( iter, lastToken );
if( iter.getType() == IToken.tGT ){
if( iter == lastToken ) break;
iter = iter.getNext();
continue;
}
continue;
}
if( iter.isOperator() )
{
iter = iter.getNext();
continue;
}
switch( iter.getType() )
{
case IToken.tBITCOMPLEMENT:
case IToken.tIDENTIFIER:
case IToken.tCOLONCOLON:
case IToken.t_operator:
iter = iter.getNext();
continue;
default:
return false;
}
}
return true;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object other) {
if( !(other instanceof ITokenDuple ) ) return false;
if( ((ITokenDuple) other).getFirstToken().equals( getFirstToken() ) &&
((ITokenDuple) other).getLastToken().equals( getLastToken() ) )
return true;
return false;
}
public ITokenDuple getTemplateIdNameTokenDuple() {
ITokenDuple nameDuple = getLastSegment();
List<IASTNode>[] argLists = getTemplateIdArgLists();
if( argLists == null || argLists[ argLists.length - 1 ] == null )
return nameDuple;
IToken i = nameDuple.getFirstToken();
IToken last = nameDuple.getLastToken();
if( i.getType() == IToken.t_template )
i = i.getNext();
if( i == last )
return TokenFactory.createTokenDuple(i, i);
IToken first= i;
//destructors
if( i.getType() == IToken.tBITCOMPLEMENT ){
i = i.getNext();
}
//operators
else if( i.getType() == IToken.t_operator ){
i = i.getNext();
IToken temp = null;
while( i != last ){
temp = i.getNext();
if( temp.getType() != IToken.tLT )
i = temp;
else
break;
}
}
return TokenFactory.createTokenDuple(first, i);
}
public char[] extractNameFromTemplateId(){
ITokenDuple nameDuple = getLastSegment();
List<IASTNode>[] argLists = getTemplateIdArgLists();
if( argLists == null || argLists[ argLists.length - 1 ] == null )
return nameDuple.toCharArray();
IToken i = nameDuple.getFirstToken();
IToken last = nameDuple.getLastToken();
if( i == null )
return EMPTY_STRING;
else if( i.getType() == IToken.t_template )
i = i.getNext();
char[] tempArray = i.getCharImage();
if( i == last )
return tempArray;
char[] nameBuffer = new char[ getCharArrayLength( i, lastToken ) ];
CharArrayUtils.overWrite( nameBuffer, 0, tempArray );
int idx = tempArray.length;
//appending of spaces needs to be the same as in toString()
//destructors
if( i.getType() == IToken.tBITCOMPLEMENT ){
i = i.getNext();
tempArray = i.getCharImage();
CharArrayUtils.overWrite( nameBuffer, idx, tempArray );
idx += tempArray.length;
}
//operators
else if( i.getType() == IToken.t_operator ){
i = i.getNext();
nameBuffer[ idx++ ] = ' ';
IToken first = i;
IToken temp = null;
while( i != last ){
temp = i.getNext();
if( temp.getType() != IToken.tLT )
i = temp;
else
break;
}
CharArrayUtils.overWrite( nameBuffer, idx, createCharArrayRepresentation( first, i ) );
idx += getCharArrayLength( first, i );
}
return CharArrayUtils.extract( nameBuffer, 0, idx );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#contains(org.eclipse.cdt.core.parser.ITokenDuple)
*/
public boolean contains(ITokenDuple duple) {
if( duple == null ) return false;
boolean foundFirst = false;
boolean foundLast = false;
for( IToken current = getFirstToken(); current != null; current = current.getNext() )
{
if( current == duple.getFirstToken() ) foundFirst = true;
if( current == duple.getLastToken() ) foundLast = true;
if( foundFirst && foundLast ) break;
if( current == getLastToken() ) break;
}
return ( foundFirst && foundLast );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#toQualifiedName()
*/
public String[] toQualifiedName() {
return generateQualifiedName();
}
/**
*
*/
private String [] generateQualifiedName() {
List<String> qn = new ArrayList<String>();
IToken i = firstToken;
while( i != lastToken )
{
boolean compl = false;
if( i.getType() == IToken.tCOLONCOLON )
{
i = i.getNext();
continue;
}
if( i.getType() == IToken.tBITCOMPLEMENT )
{
compl = true;
i = i.getNext();
}
if( i.getType() == IToken.tIDENTIFIER )
{
if( compl )
{
StringBuffer buff = new StringBuffer( "~" ); //$NON-NLS-1$
buff.append( i.getImage() );
qn.add( buff.toString() );
}
else
qn.add( i.getImage() );
}
i = i.getNext();
}
if( i.getType() == IToken.tIDENTIFIER ){
qn.add( i.getImage() );
}
String [] qualifiedName = new String[ qn.size() ];
return qn.toArray( qualifiedName );
}
/**
*
*/
protected int calculateSegmentCount() {
int n = 1;
IToken token = null;
IToken last = getLastToken();
for( ;; ){
if( token == last )
break;
token = ( token != null ) ? token.getNext() : getFirstToken();
if( token == null ) break;
if( token.getType() == IToken.tLT )
token = TokenFactory.consumeTemplateIdArguments( token, last );
if( token.getType() == IToken.tCOLONCOLON ){
n++;
continue;
}
}
return n;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#toCharArray()
*/
public char[] toCharArray() {
if( stringRepresentation == null )
stringRepresentation = createCharArrayRepresentation(firstToken, lastToken);
return stringRepresentation;
}
}

View file

@ -1,136 +0,0 @@
/*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-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.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.ITokenDuple;
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
/**
* 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;
private OverloadableOperator op = null;
/**
* Simple constructor. token is wrapped by this class.
* @param token
*/
public OperatorTokenDuple(ITokenDuple token, OverloadableOperator op) {
this.token=token;
this.op = op;
}
// 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;
}
public OverloadableOperator getOperator() {
return op;
}
// below are ITokenDuple functions
public IToken getFirstToken() {
return token.getFirstToken();
}
public IToken getLastToken() {
return token.getLastToken();
}
public List<IASTNode>[] getTemplateIdArgLists() {
return token.getTemplateIdArgLists();
}
public ITokenDuple getLastSegment() {
return token.getLastSegment();
}
public ITokenDuple getLeadingSegments() {
return token.getLeadingSegments();
}
public int getSegmentCount() {
return token.getSegmentCount();
}
public Iterator<IToken> iterator() {
return token.iterator();
}
public char[] toCharArray() {
return token.toCharArray();
}
public int length() {
return token.length();
}
public IToken getToken(int index) {
return token.getToken(index);
}
public ITokenDuple[] getSegments() {
return token.getSegments();
}
public int getStartOffset() {
return token.getStartOffset();
}
public int getEndOffset() {
return token.getEndOffset();
}
public char[] extractNameFromTemplateId() {
return token.extractNameFromTemplateId();
}
@Override
public String toString() {
return token.toString();
}
}

View file

@ -1,152 +0,0 @@
/*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.token;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.ITokenDuple;
/**
* @author jcamelon
*
*/
public class TemplateTokenDuple extends BasicTokenDuple {
protected final List<IASTNode>[] argLists;
/**
* @param first
* @param last
* @param templateArgLists
*/
public TemplateTokenDuple(IToken first, IToken last, List<List<IASTNode>> templateArgLists) {
super(first, last);
argLists = toArray(templateArgLists);
numSegments = calculateSegmentCount();
}
@SuppressWarnings("unchecked")
private <T> List<T>[] toArray(List<List<T>> templateArgLists) {
return templateArgLists.toArray( new List[templateArgLists.size()] );
}
@SuppressWarnings("unchecked")
private <T> List<T>[] newArrayOfLists(int size) {
return new List[size];
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#getSegmentCount()
*/
@Override
public int getSegmentCount() {
return numSegments;
}
@Override
public ITokenDuple getLastSegment()
{
IToken first = null, last = null, token = null;
for( ; ; ){
if( token == getLastToken() )
break;
token = ( token != null ) ? token.getNext() : getFirstToken();
if( first == null )
first = token;
if( token.getType() == IToken.tLT )
token = TokenFactory.consumeTemplateIdArguments( token, getLastToken() );
else if( token.getType() == IToken.tCOLONCOLON ){
first = null;
continue;
}
last = token;
}
List<IASTNode>[] args = getTemplateIdArgLists();
if( args != null && args[ args.length - 1 ] != null ){
List<List<IASTNode>> newArgs = new ArrayList<List<IASTNode>>( 1 );
newArgs.add( args[ args.length - 1 ] );
return TokenFactory.createTokenDuple( first, last, newArgs );
}
return TokenFactory.createTokenDuple( first, last );
}
public TemplateTokenDuple( ITokenDuple first, ITokenDuple last )
{
super( first, last );
List<IASTNode>[] a1 = first.getTemplateIdArgLists();
List<IASTNode>[] a2 = last.getTemplateIdArgLists();
int l1 = ( a1 != null ) ? a1.length : first.getSegmentCount();
int l2 = ( a2 != null ) ? a2.length : first.getSegmentCount();
argLists = newArrayOfLists(l1 + l2);
if( a1 != null )
System.arraycopy( a1, 0, argLists, 0, l1 );
if( a2 != null )
System.arraycopy( a2, 0, argLists, l1, l2 );
numSegments = calculateSegmentCount();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ITokenDuple#getTemplateIdArgLists()
*/
@Override
public List<IASTNode>[] getTemplateIdArgLists() {
return argLists;
}
@Override
public ITokenDuple[] getSegments()
{
List<ITokenDuple> r = new ArrayList<ITokenDuple>();
IToken token = null;
IToken prev = null;
IToken last = getLastToken();
IToken startOfSegment = getFirstToken();
int count = 0;
for( ;; ){
if( token == last )
break;
prev = token;
token = ( token != null ) ? token.getNext() : getFirstToken();
if( token.getType() == IToken.tLT )
token = TokenFactory.consumeTemplateIdArguments( token, last );
if( token.getType() == IToken.tCOLONCOLON ){
List<List<IASTNode>> newArgs = null;
if( argLists[count] != null )
{
newArgs = new ArrayList<List<IASTNode>>(1);
newArgs.add( argLists[count]);
}
ITokenDuple d = TokenFactory.createTokenDuple( startOfSegment, prev != null ? prev : startOfSegment, newArgs );
r.add( d );
startOfSegment = (token != last ) ? token.getNext() : last;
++count;
continue;
}
}
List<List<IASTNode>> newArgs = null;
//pointer to members could have a A::B<int>::
if( count < argLists.length && argLists[count] != null )
{
newArgs = new ArrayList<List<IASTNode>>(1);
newArgs.add(argLists[count]);
}
ITokenDuple d = TokenFactory.createTokenDuple( startOfSegment, last, newArgs);
r.add( d );
return r.toArray( new ITokenDuple[ r.size() ]);
}
}

View file

@ -1,275 +0,0 @@
/*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.token;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.ITokenDuple;
/**
* @author johnc
*/
public class TokenFactory {
protected static final char[] EMPTY_CHAR_ARRAY = "".toCharArray(); //$NON-NLS-1$
private static class TokenWrapper implements ITokenDuple {
private final IToken fToken;
public TokenWrapper(IToken t) {
fToken= t;
}
@Override
public String toString() {
return fToken.toString();
}
public char[] extractNameFromTemplateId(){
return fToken.getCharImage();
}
public IToken getFirstToken() {
return fToken;
}
public ITokenDuple getLastSegment() {
return this;
}
public IToken getLastToken() {
return fToken;
}
public ITokenDuple getLeadingSegments() {
return null;
}
public int getSegmentCount() {
return 1;
}
public int getStartOffset() {
return fToken.getOffset();
}
public List<IASTNode>[] getTemplateIdArgLists() {
return null;
}
public IToken getToken(int index) {
if( index == 0 ) return fToken;
return null;
}
public Iterator<IToken> iterator() {
return new Iterator<IToken>() {
private boolean hasNext = true;
public void remove() {
throw new UnsupportedOperationException();
}
public boolean hasNext() {
return hasNext;
}
public IToken next() {
hasNext = false;
return fToken;
}
};
}
public int length() {
return 1;
}
public ITokenDuple[] getSegments() {
return new ITokenDuple[] {this};
}
public int getEndOffset() {
return fToken.getEndOffset();
}
public char[] toCharArray() {
return fToken.getCharImage();
}
}
public static ITokenDuple createTokenDuple(IToken first, IToken last) {
if (first == last) {
if (first instanceof ITokenDuple) {
return (ITokenDuple) first;
}
return new TokenWrapper(first);
}
return new BasicTokenDuple( first, last );
}
public static ITokenDuple createTokenDuple(IToken first, IToken last, List<List<IASTNode>> templateArgLists) {
if (templateArgLists == null || templateArgLists.isEmpty()) {
return createTokenDuple(first, last);
}
return new TemplateTokenDuple( first, last, templateArgLists );
}
public static ITokenDuple createTokenDuple( ITokenDuple firstDuple, ITokenDuple secondDuple ){
if( secondDuple == null ) return firstDuple;
if( firstDuple == null ) return secondDuple;
List<IASTNode>[] f1 = firstDuple.getTemplateIdArgLists();
List<IASTNode>[] f2 = secondDuple.getTemplateIdArgLists();
if( f1 == null && f2 == null )
return new BasicTokenDuple( firstDuple, secondDuple );
return new TemplateTokenDuple( firstDuple, secondDuple );
}
public static IToken consumeTemplateIdArguments( IToken name, IToken last ){
IToken token = name;
if( token.getType() == IToken.tLT )
{
if( token == last )
return token;
BraceCounter scopes = BraceCounter.getCounter();
try
{
scopes.addValue( IToken.tLT );
while (!scopes.isEmpty() && token != last )
{
int top;
token = token.getNext();
switch( token.getType() ){
case IToken.tGT:
if( scopes.getLast() == IToken.tLT ) {
scopes.removeValue();
}
break;
case IToken.tRBRACKET :
do {
top = scopes.removeValue();
} while (!scopes.isEmpty() && top == IToken.tLT);
break;
case IToken.tRPAREN :
do {
top = scopes.removeValue();
} while (!scopes.isEmpty() && top == IToken.tLT);
break;
case IToken.tLT: scopes.addValue( IToken.tLT ); break;
case IToken.tLBRACKET: scopes.addValue( IToken.tLBRACKET ); break;
case IToken.tLPAREN: scopes.addValue( IToken.tLPAREN ); break;
}
}
}
finally
{
BraceCounter.returnCounter(scopes);
}
}
return token;
}
protected static class BraceCounter
{
private static final int POOLSIZE = 8;
private static final BraceCounter [] pool;
private static final boolean [] free;
private static int newObjectCount = POOLSIZE;
static
{
pool = new BraceCounter[ POOLSIZE ];
free = new boolean[8];
for( int i = 0; i < POOLSIZE; ++i )
{
pool[i] = new BraceCounter(i);
free[i] = true;
}
}
public static synchronized BraceCounter getCounter()
{
for( int i = 0; i < POOLSIZE; ++i )
{
if( free[i] )
{
free[i] = false;
return pool[i];
}
}
//if there is nothing free, allocate a new one and return it
return new BraceCounter(newObjectCount++);
}
public static synchronized void returnCounter( BraceCounter c )
{
if( c.getKey() > 0 && c.getKey() < POOLSIZE )
{
free[ c.getKey() ] = true;
c.clear();
}
// otherwise, the object shall get garbage collected
}
/**
*
*/
private void clear() {
currentIndex = 0;
Arrays.fill( array, 0, array.length, -1 );
}
private final int key;
private int [] array = new int[ 8 ];
int currentIndex = 0;
private void resizeArray()
{
int [] newArray = new int[ (array.length * 2) ];
System.arraycopy( array, 0, newArray, 0, array.length );
array = newArray;
}
public void addValue( int value )
{
if( currentIndex == array.length )
resizeArray();
array[currentIndex] = value;
++currentIndex;
}
public int removeValue()
{
int result = array[--currentIndex];
array[currentIndex] = -1;
return result;
}
public int getLast()
{
if( isEmpty() ) return -1;
return array[ currentIndex - 1 ];
}
public boolean isEmpty() {
return (currentIndex == 0 );
}
public BraceCounter(int i) {
key = i;
clear();
}
/**
* @return Returns the key.
*/
public int getKey() {
return key;
}
}
public static char[] createCharArrayRepresentation(IToken first, IToken last) {
return BasicTokenDuple.createCharArrayRepresentation(first, last);
}
}