diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 99a5cd71619..b4f5fc2833a 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -4397,7 +4397,7 @@ public class AST2CPPTests extends AST2BaseTest { IASTDeclarator d = p2m.getDeclarators()[0]; ICPPASTPointerToMember po = (ICPPASTPointerToMember) d .getPointerOperators()[0]; - assertEquals(po.getName().toString(), "X::"); //$NON-NLS-1$ + assertEquals("X::", po.getName().toString()); //$NON-NLS-1$ } // struct B {}; @@ -6150,9 +6150,11 @@ public class AST2CPPTests extends AST2BaseTest { // struct B { // operator ns::A(); // problems on operator ns and on A // }; - public void _testNamespaceQualifiedOperator_256840() throws Exception { - BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true); + public void testNamespaceQualifiedOperator_256840() throws Exception { + final String code = getAboveComment(); + BindingAssertionHelper bh= new BindingAssertionHelper(code, true); bh.assertNonProblem("operator ns::A", 14); + parseAndCheckBindings(code, ParserLanguage.CPP); } // void f(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IProblemBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IProblemBinding.java index 76d1be024de..4b4b1159dcc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IProblemBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IProblemBinding.java @@ -6,17 +6,14 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM Corporation - initial API and implementation + * Andrew Niefer (IBM Corporation) - initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ - -/* - * Created on Jan 17, 2005 - */ 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 { @@ -123,5 +120,15 @@ public interface IProblemBinding extends IBinding, IScope, IType { 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; + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ITokenDuple.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ITokenDuple.java index c8e323e0660..51fa91c3aef 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ITokenDuple.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ITokenDuple.java @@ -18,8 +18,9 @@ import org.eclipse.cdt.core.dom.ast.IASTNode; /** - * @author jcamelon + * @deprecated */ +@Deprecated public interface ITokenDuple { public abstract IToken getFirstToken(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java index 0edabcf9813..69723f794d2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java @@ -415,17 +415,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { * @throws BacktrackException * request a backtrack */ - protected IToken identifier() throws EndOfFileException, BacktrackException { - switch (LT(1)) { - case IToken.tIDENTIFIER: - case IToken.tCOMPLETION: - case IToken.tEOC: - return consume(); - default: - throw backtrack; - } - - } + protected abstract IASTName identifier() throws EndOfFileException, BacktrackException; /** * @return Returns the backtrackCount. @@ -887,8 +877,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { protected abstract IASTExpression unaryExpression() 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 void setupTranslationUnit() throws Exception; @@ -1268,7 +1256,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { IASTName name; if (LT(1) == IToken.tIDENTIFIER) { - name= createName(identifier()); + name= identifier(); } else { name= nodeFactory.newName(); } @@ -1308,7 +1296,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { if (needComma) throw backtrack; - final IASTName etorName= createName(identifier()); + final IASTName etorName= identifier(); final IASTEnumerator enumerator= nodeFactory.newEnumerator(etorName, null); endOffset= calculateEndOffset(etorName); setRange(enumerator, problemOffset, endOffset); @@ -1339,8 +1327,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { protected abstract IASTStatement statement() throws EndOfFileException, BacktrackException; - protected abstract IASTName createName(IToken token); - protected IASTExpression condition(boolean followedByParenthesis) throws BacktrackException, EndOfFileException { IToken mark= mark(); try { @@ -1666,15 +1652,15 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { protected abstract IASTAmbiguousStatement createAmbiguousStatement(); protected IASTStatement parseLabelStatement() throws EndOfFileException, BacktrackException { - IToken labelName = consume(); // tIDENTIFIER - consume(); // tCOLON + int offset= LA(1).getOffset(); + IASTName name = identifier(); // tIDENTIFIER + consume(IToken.tCOLON); // tCOLON IASTStatement nestedStatement = statement(); int lastOffset = calculateEndOffset( nestedStatement ); - IASTName name = createName(labelName); IASTLabelStatement label_statement = nodeFactory.newLabelStatement(name, nestedStatement); - ((ASTNode) label_statement).setOffsetAndLength(labelName.getOffset(), lastOffset - labelName.getOffset()); + setRange(label_statement, offset, lastOffset); return label_statement; } @@ -1688,10 +1674,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { protected IASTStatement parseGotoStatement() throws EndOfFileException, BacktrackException { int startOffset = consume().getOffset(); // t_goto - IToken identifier = consume(IToken.tIDENTIFIER); + IASTName goto_label_name = identifier(); int lastOffset = consume(IToken.tSEMI).getEndOffset(); - IASTName goto_label_name = createName(identifier); IASTGotoStatement goto_statement = nodeFactory.newGotoStatement(goto_label_name); ((ASTNode) goto_statement).setOffsetAndLength(startOffset, lastOffset - startOffset); return goto_statement; @@ -1745,7 +1730,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { switch (LT(1)) { case IToken.tEOC: // We're trying to start one - IASTName name = createName(LA(1)); + IASTName name = identifier(); IASTIdExpression idExpr = nodeFactory.newIdExpression(name); result = idExpr; break; @@ -1945,8 +1930,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { consume(); IASTExpression expr2= expression(); endOffset1= consumeOrEOC(IToken.tRPAREN).getEndOffset(); - - expr= buildTypeIdExpression(IASTTypeIdExpression.op_typeof, typeid, typeidOffset, calculateEndOffset(typeid)); + expr= nodeFactory.newTypeIdExpression(IASTTypeIdExpression.op_typeof, typeid); + setRange(expr, typeidOffset, calculateEndOffset(typeid)); IASTExpressionList expressionList = nodeFactory.newExpressionList(); ((ASTNode) expressionList).setOffsetAndLength(typeidOffset, calculateEndOffset(expr2)-typeidOffset); @@ -1989,7 +1974,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { IASTExpression result1= null; 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); if (expr == null || endOffset1 > endOffset2) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java index 1fe3978deeb..8ba8560e07e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java @@ -36,7 +36,7 @@ import org.eclipse.core.runtime.PlatformObject; */ public class ProblemBinding extends PlatformObject implements IProblemBinding, IType, IScope, IASTInternalScope { protected final int id; - protected final char[] arg; + protected char[] arg; protected IASTNode node; private String message = null; @@ -56,7 +56,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I protected static final String[] errorMessages; 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_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$ @@ -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_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_INVALID_TEMPLATE_ARGUMENTS - 1]= ParserMessages.getString("ASTProblemFactory.error.semantic.dom.invalidTemplateArgs"); //$NON-NLS-1$ } /* (non-Javadoc) @@ -87,7 +88,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I if (message != null) 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) { msg = MessageFormat.format(msg, new Object[] { new String(arg) }); @@ -224,7 +225,8 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I public int getLineNumber() { if (node != null) { IASTFileLocation fileLoc = node.getFileLocation(); - return fileLoc.getStartingLineNumber(); + if (fileLoc != null) + return fileLoc.getStartingLineNumber(); } return -1; } @@ -245,4 +247,11 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I public IBinding getOwner() throws DOMException { return null; } + + public void setASTNode(IASTNode node, char[] arg) { + if (node != null) + this.node= node; + if (arg != null) + this.arg= arg; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java index c44b6100b68..9c6a007d0ff 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java @@ -227,10 +227,9 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { switch (LT(1)) { case IToken.tDOT: int offset = consume().getOffset(); - IToken id = identifier(); - IASTName n = createName(id); + IASTName n = identifier(); ICASTFieldDesignator fieldDesignator = nodeFactory.newFieldDesignator(n); - setRange(fieldDesignator, offset, id.getEndOffset()); + setRange(fieldDesignator, offset, calculateEndOffset(n)); if (designatorList == null) designatorList = new ArrayList(DEFAULT_DESIGNATOR_LIST_SIZE); 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 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(); - IASTName n = createName(identifier); ICASTFieldDesignator designator = nodeFactory.newFieldDesignator(n); - ((ASTNode) designator).setOffsetAndLength(identifier.getOffset(), lastOffset - identifier.getOffset()); + setRange(designator, offset, lastOffset); 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 { IASTExpression firstExpression = null; switch (LT(1)) { @@ -634,7 +624,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { case IToken.tDOT: // member access IToken dot = consume(); - IASTName name = createName(identifier()); + IASTName name = identifier(); if (name == null) throwBacktrack(((ASTNode) firstExpression).getOffset(), ((ASTNode) firstExpression).getLength() + dot.getLength()); @@ -648,7 +638,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { case IToken.tARROW: // member access IToken arrow = consume(); - name = createName(identifier()); + name = identifier(); if (name == null) throwBacktrack(((ASTNode) firstExpression).getOffset(), ((ASTNode) firstExpression).getLength() + arrow.getLength()); @@ -722,8 +712,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { case IToken.tCOMPLETION: case IToken.tEOC: int startingOffset = LA(1).getOffset(); - IToken t1 = identifier(); - IASTName name = createName(t1); + IASTName name = identifier(); IASTIdExpression idExpression = nodeFactory.newIdExpression(name); ((ASTNode) idExpression).setOffsetAndLength((ASTNode) name); return idExpression; @@ -843,7 +832,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { int options= 0; int isLong= 0; - IToken identifier= null; + IASTName identifier= null; IASTDeclSpecifier result= null; IASTExpression typeofExpression= null; IASTProblem problem= null; @@ -1001,11 +990,11 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { IToken mark= mark(); try { - final IToken idToken= identifier(); // for the specifier + final IASTName id= identifier(); // for the specifier final IASTDeclarator altDtor = initDeclarator(declOption); if (LA(1) == e.currToken) { e.altDeclarator= altDtor; - e.altSpec= buildNamedTypeSpecifier(idToken, storageClass, options, offset, idToken.getEndOffset()); + e.altSpec= buildNamedTypeSpecifier(id, storageClass, options, offset, calculateEndOffset(id)); } } catch (FoundAggregateInitializer lie) { lie.fDeclSpec= e.declSpec; @@ -1017,7 +1006,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { throw e; } identifier = identifier(); - endOffset= identifier.getEndOffset(); + endOffset= calculateEndOffset(identifier); encounteredTypename= true; break; case IToken.t_struct: @@ -1121,9 +1110,8 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { 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) { - IASTName name = createName(identifier); ICASTTypedefNameSpecifier declSpec = nodeFactory.newTypedefNameSpecifier(name); configureDeclSpec(declSpec, storageClass, options); declSpec.setRestrict((options & RESTRICT) != 0); @@ -1218,9 +1206,9 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers); // class name - IToken nameToken = null; + IASTName name = null; if (LT(1) == IToken.tIDENTIFIER) { - nameToken = identifier(); + name = identifier(); } // 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); } - IASTName name = (nameToken == null) ? nodeFactory.newName() : createName(nameToken); + if (name == null) { + name= nodeFactory.newName(); + } ICASTCompositeTypeSpecifier result = nodeFactory.newCompositeTypeSpecifier(classKind, name); 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 __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers); - IToken identifier = identifier(); - IASTName name = createName(identifier); + IASTName name = identifier(); IASTElaboratedTypeSpecifier result = nodeFactory.newElaboratedTypeSpecifier(eck, name); ((ASTNode) result).setOffsetAndLength(t.getOffset(), calculateEndOffset(name) - t.getOffset()); return result; @@ -1361,7 +1350,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { if (option.fRequireAbstract) throwBacktrack(LA(1)); - final IASTName declaratorName = createName(identifier()); + final IASTName declaratorName = identifier(); endOffset= calculateEndOffset(declaratorName); return declarator(pointerOps, declaratorName, null, startingOffset, endOffset, option); } @@ -1520,14 +1509,14 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { switch (LT(1)) { case IToken.tCOMMA: last = consume(); - parmNames[i] = createName(identifier()); + parmNames[i] = identifier(); seenParameter = true; break; case IToken.tIDENTIFIER: if (seenParameter) throwBacktrack(startOffset, last.getEndOffset() - startOffset); - parmNames[i] = createName(identifier()); + parmNames[i] = identifier(); seenParameter = true; break; case IToken.tRPAREN: @@ -1670,21 +1659,32 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { return d; } - + @Override - protected IASTName createName(IToken t) { - IASTName n = nodeFactory.newName(t.getCharImage()); - switch (t.getType()) { - case IToken.tCOMPLETION: - case IToken.tEOC: - createCompletionNode(t).addName(n); + protected IASTName identifier() throws EndOfFileException, BacktrackException { + final IToken t= LA(1); + IASTName n; + switch (t.getType()) { + case IToken.tIDENTIFIER: + consume(); + n = nodeFactory.newName(t.getCharImage()); break; - } - ((ASTNode) n).setOffsetAndLength(t.getOffset(), t.getEndOffset() - t.getOffset()); + + case IToken.tCOMPLETION: + case IToken.tEOC: + consume(); + n = nodeFactory.newName(t.getCharImage()); + createCompletionNode(t).addName(n); + return n; + + default: + throw backtrack; + } + + setRange(n, t.getOffset(), t.getEndOffset()); return n; } - protected void consumeArrayModifiers(List arrayMods) throws EndOfFileException, BacktrackException { while (LT(1) == IToken.tLBRACKET) { // eat the '[' diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIfStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIfStatement.java index f3c5611028c..2e6b58df1c3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIfStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIfStatement.java @@ -112,25 +112,24 @@ public class CPPASTIfStatement extends ASTNode implements ICPPASTIfStatement, IA } public void replace(IASTNode child, IASTNode other) { - if( thenClause == child ) - { - other.setParent( child.getParent() ); - other.setPropertyInParent( child.getPropertyInParent() ); - thenClause = (IASTStatement) other; - } - else if( elseClause == child ) - { - other.setParent( child.getParent() ); - other.setPropertyInParent( child.getPropertyInParent() ); - elseClause = (IASTStatement) other; - } - if( condDecl == child ) - { - other.setParent( child.getParent() ); - other.setPropertyInParent( child.getPropertyInParent() ); - condDecl = (IASTDeclaration) other; - } - } + if (thenClause == child) { + other.setParent(child.getParent()); + other.setPropertyInParent(child.getPropertyInParent()); + thenClause = (IASTStatement) other; + } else if (elseClause == child) { + other.setParent(child.getParent()); + other.setPropertyInParent(child.getPropertyInParent()); + elseClause = (IASTStatement) other; + } else if (condDecl == child) { + other.setParent(child.getParent()); + other.setPropertyInParent(child.getPropertyInParent()); + condDecl = (IASTDeclaration) other; + } else if (condition == child) { + other.setParent(child.getParent()); + other.setPropertyInParent(child.getPropertyInParent()); + condition = (IASTExpression) other; + } + } public IASTDeclaration getConditionDeclaration() { return condDecl; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNameBase.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNameBase.java index f077e6fe967..084537b0891 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNameBase.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNameBase.java @@ -11,6 +11,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; 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.IProblemBinding; 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); } else { 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) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index dfc76ea23e0..b292588538c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -61,7 +61,6 @@ import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IASTWhileStatement; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IScope; -import org.eclipse.cdt.core.dom.ast.c.ICASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAmbiguousTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression; @@ -86,7 +85,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; -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.ICPPASTReferenceOperator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier; @@ -122,7 +120,6 @@ import org.eclipse.cdt.core.parser.IParserLogService; import org.eclipse.cdt.core.parser.IProblem; import org.eclipse.cdt.core.parser.IScanner; import org.eclipse.cdt.core.parser.IToken; -import org.eclipse.cdt.core.parser.ITokenDuple; import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArrayUtils; @@ -135,14 +132,7 @@ import org.eclipse.cdt.internal.core.dom.parser.BacktrackException; import org.eclipse.cdt.internal.core.dom.parser.DeclarationOptions; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousStatement; -import org.eclipse.cdt.internal.core.dom.parser.c.CASTElaboratedTypeSpecifier; -import org.eclipse.cdt.internal.core.dom.parser.c.CASTEnumerationSpecifier; -import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; -import org.eclipse.cdt.internal.core.parser.TemplateParameterManager; -import org.eclipse.cdt.internal.core.parser.token.BasicTokenDuple; -import org.eclipse.cdt.internal.core.parser.token.OperatorTokenDuple; -import org.eclipse.cdt.internal.core.parser.token.TokenFactory; /** * This is our implementation of the IParser interface, serving as a parser for @@ -197,84 +187,273 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { this.nodeFactory = CPPNodeFactory.getDefault(); } - /** - * Identifies the first and last tokens that make up the template parameter list. - * Used as part of parsing an idExpression(). - * - * @param previousLast Previous "last" token (returned if nothing was consumed) - * @return Last consumed token, or previousLast if nothing was consumed - * @throws BacktrackException request a backtrack - */ - protected IToken consumeTemplateParameters(IToken previousLast) throws EndOfFileException, BacktrackException { - final int offset = previousLast == null ? LA(1).getOffset() : previousLast.getOffset(); - IToken last = previousLast; // if there are no parameters then previousLast gets returned - - if (LT(1) == IToken.tLT) { - last= consume(); - int nk= 0; - int depth= 0; - int angleDepth= 0; + @Override + protected IASTName identifier() throws EndOfFileException, BacktrackException { + switch (LT(1)) { + case IToken.tIDENTIFIER: + case IToken.tCOMPLETION: + case IToken.tEOC: + return buildName(-1, consume()); + } - while(true) { - last= consume(); - switch(last.getType()) { - case IToken.tLT: - if (nk == 0) { - angleDepth++; - } - break; - case IToken.tGT: - if (nk == 0) { - if (--angleDepth < 0) - return last; - } - break; - - case IToken.tLBRACKET: - if (nk == 0) { - nk= IToken.tLBRACKET; - } else if (nk == IToken.tLBRACKET) { - depth++; - } - break; - - case IToken.tRBRACKET: - if (nk == IToken.tLBRACKET) { - if (--depth < 0) { - nk= 0; - } - } - break; - - case IToken.tLPAREN: - if (nk == 0) { - nk= IToken.tLPAREN; - } else if (nk == IToken.tLPAREN) { - depth++; - } - break; - - case IToken.tRPAREN: - if (nk == IToken.tLPAREN) { - if (--depth < 0) { - nk= 0; - } - } - break; - case IToken.tSEMI: - case IToken.tLBRACE: - case IToken.tRBRACE: - if (nk == 0) { - throwBacktrack(offset, last.getOffset() - offset); - } - break; - } - } - } - return last; + throw backtrack; } - protected List templateArgumentList() throws EndOfFileException, BacktrackException { + protected IASTName idExpression() throws EndOfFileException, BacktrackException { + try { + if (true) { + rejectLogicalOperatorInTemplateID++; + } + return qualifiedName(); + } finally { + if (true) { + rejectLogicalOperatorInTemplateID--; + } + } + } + + /** + * Parse a name. + * name ::= ("::")? name2 ("::" name2)* + * name2 ::= IDENTIFER | template-id + * + * @throws BacktrackException request a backtrack + */ + private IASTName qualifiedName() throws BacktrackException, EndOfFileException { + // mstodo + IToken first= LA(1); + ICPPASTQualifiedName qname= null; + IASTName name= null; + final int offset= LA(1).getOffset(); + int endOffset= offset; + if (LT(1) == IToken.tCOLONCOLON) { + endOffset= consume().getEndOffset(); + qname= nodeFactory.newQualifiedName(); + qname.setFullyQualified(true); + } + + boolean mustBeLast= false; + boolean haveName= false; + loop: for(;;) { + boolean forceTemplate= false; + if (qname != null && LT(1) == IToken.t_template) { + consume().getEndOffset(); + forceTemplate= true; + } + + int destructorOffset= -1; + if (LT(1) == IToken.tBITCOMPLEMENT) { + destructorOffset= consume().getOffset(); + mustBeLast= true; + } + + switch (LT(1)) { + case IToken.tIDENTIFIER: + case IToken.tCOMPLETION: + case IToken.tEOC: + IToken nt= consume(); + name = buildName(destructorOffset, nt); + break; + + case IToken.t_operator: + name= operatorId(); + break; + + default: + if (!haveName || destructorOffset >= 0 || forceTemplate) { + throwBacktrack(LA(1)); + } + name= nodeFactory.newName(CharArrayUtils.EMPTY); + if (qname != null) { + qname.addName(name); + } + break loop; + } + + haveName= true; + name= addTemplateArguments(name); + endOffset= calculateEndOffset(name); + if (qname != null) { + qname.addName(name); + } + + if (LT(1) != IToken.tCOLONCOLON) + break loop; + + if (mustBeLast) + throwBacktrack(LA(1)); + + endOffset= consume().getEndOffset(); // :: + if (qname == null) { + qname= nodeFactory.newQualifiedName(); + qname.addName(name); + } + } + if (qname == null) + return name; + + setRange(qname, offset, endOffset); + // mstodo + ((CPPASTQualifiedName) qname).setSignature(new String(computeOperatorImage(first, LA(1)))); + return qname; + } + + private IASTName buildName(int destructorOffset, IToken nt) { + IASTName name; + if (destructorOffset < 0) { + name= nodeFactory.newName(nt.getCharImage()); + setRange(name, nt.getOffset(), nt.getEndOffset()); + } else { + char[] nchars= nt.getCharImage(); + final int len= nchars.length; + char[] image = new char[len+1]; + image[0]= '~'; + System.arraycopy(nchars, 0, image, 1, len); + name= nodeFactory.newName(image); + setRange(name, destructorOffset, nt.getEndOffset()); + } + switch(nt.getType()) { + case IToken.tEOC: + case IToken.tCOMPLETION: + createCompletionNode(nt).addName(name); + break; + } + return name; + } + + private IASTName addTemplateArguments(IASTName templateName) throws EndOfFileException, BacktrackException { + if (!canBeTemplateArguments()) + return templateName; + + IToken secondMark = mark(); + consume(IToken.tLT); + final boolean wasOnTop= onTopInTemplateArgs; + onTopInTemplateArgs= true; + try { + // bug 229062: content assist after '<' needs to prefer to backtrack here + if (rejectLogicalOperatorInTemplateID == 1) { + final int lt1= LT(1); + if (lt1 == IToken.tCOMPLETION || lt1 == IToken.tEOC) { + throw backtrack; + } + } + + List list = templateArgumentList(); + IToken end= LA(1); + switch(end.getType()) { + case IToken.tGT: + consume(); + break; + case IToken.tEOC: + break; + default: + throw backtrack; + } + return buildTemplateID(templateName, end.getEndOffset(), list); + } catch (BacktrackException bt) { + backup(secondMark); + return templateName; + } finally { + onTopInTemplateArgs= wasOnTop; + } + } + + private ICPPASTTemplateId buildTemplateID(IASTName templateName, int endOffset, List args) { + ICPPASTTemplateId result = nodeFactory.newTemplateId(templateName); + setRange(result, ((ASTNode) templateName).getOffset(), endOffset); + for (IASTNode n : args) { + if (n instanceof IASTTypeId) { + result.addTemplateArgument((IASTTypeId) n); + } else if(n instanceof IASTExpression) { + result.addTemplateArgument((IASTExpression) n); + } else if(n instanceof ICPPASTAmbiguousTemplateArgument) { + result.addTemplateArgument((ICPPASTAmbiguousTemplateArgument) n); + } + } + return result; + } + + /** + * Makes a fast check whether there could be template arguments. + */ + private boolean canBeTemplateArguments() throws EndOfFileException, BacktrackException { + if (LT(1) != IToken.tLT) + return false; + + final IToken mark= mark(); + try { + consume(); + int nk= 0; + int depth= 0; + int angleDepth= 0; + int limit= 100; + + while(--limit > 0) { + switch(consume().getType()) { + case IToken.tEOC: + case IToken.tCOMPLETION: + return true; + + case IToken.tLT: + if (nk == 0) { + angleDepth++; + } + break; + case IToken.tGT: + if (nk == 0) { + if (--angleDepth < 0) { + final int lt1= LTcatchEOF(1); + return (lt1 != IToken.tINTEGER && lt1 != IToken.tFLOATINGPT); + } + } + break; + case IToken.tLBRACKET: + if (nk == 0) { + nk= IToken.tLBRACKET; + depth= 0; + } else if (nk == IToken.tLBRACKET) { + depth++; + } + break; + case IToken.tRBRACKET: + if (nk == IToken.tLBRACKET) { + if (--depth < 0) { + nk= 0; + } + } + break; + case IToken.tLPAREN: + if (nk == 0) { + nk= IToken.tLPAREN; + depth= 0; + } else if (nk == IToken.tLPAREN) { + depth++; + } + break; + + case IToken.tRPAREN: + if (nk == IToken.tLPAREN) { + if (--depth < 0) { + nk= 0; + } + } + break; + case IToken.tSEMI: + case IToken.tLBRACE: + case IToken.tRBRACE: + if (nk == 0) { + return false; + } + break; + } + } + return true; + } finally { + backup(mark); + } + } + + private List templateArgumentList() throws EndOfFileException, BacktrackException { IToken start = LA(1); int startingOffset = start.getOffset(); int endOffset = 0; @@ -350,100 +529,100 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { return list; } - /** - * To disambiguate between logical expressions and template id's in some situations - * we forbid the usage of the logical operators '&&' or '||' within template ids. - * @throws EndOfFileException - * @since 5.0 - */ - protected final ITokenDuple nameWithoutLogicalOperatorInTemplateID() throws BacktrackException, EndOfFileException { - rejectLogicalOperatorInTemplateID++; - try { - return name(); - } - finally { - rejectLogicalOperatorInTemplateID--; - } - } - /** - * Parse a name. - * name ::= ("::")? name2 ("::" name2)* - * name2 ::= IDENTIFER | template-id - * - * @throws BacktrackException request a backtrack - */ - protected ITokenDuple name() throws BacktrackException, EndOfFileException { - - TemplateParameterManager argumentList = TemplateParameterManager.getInstance(); - - try { - IToken first = LA(1); - IToken last = null; - IToken mark = mark(); - - boolean hasTemplateId = false; - - if (LT(1) == IToken.tCOLONCOLON) { - argumentList.addSegment(null); - last = consume(); - } - - if (LT(1) == IToken.tBITCOMPLEMENT) - consume(); - - switch (LT(1)) { - case IToken.tIDENTIFIER: - case IToken.tCOMPLETION: - case IToken.tEOC: - last = consume(); - IToken templateLast = consumeTemplateArguments(last, argumentList); - if (last != templateLast) { - last = templateLast; - hasTemplateId = true; - } - break; - - default: - IToken l = LA(1); - backup(mark); - throwBacktrack(first.getOffset(), l.getEndOffset() - - first.getOffset()); - } - - while (LT(1) == IToken.tCOLONCOLON) { - last = consume(); - - if (LT(1) == IToken.t_template) { - consume(); - } - - if (LT(1) == IToken.tBITCOMPLEMENT) - consume(); - - switch (LT(1)) { - case IToken.t_operator: - IToken l = LA(1); - backup(mark); - throwBacktrack(first.getOffset(), l.getEndOffset() - first.getOffset()); - break; - case IToken.tIDENTIFIER: - case IToken.tCOMPLETION: - case IToken.tEOC: - last = consume(); - last = consumeTemplateArguments(last, argumentList); - if (last.getType() == IToken.tGT || last.getType() == IToken.tEOC) - hasTemplateId = true; - } - } - - ITokenDuple tokenDuple = TokenFactory.createTokenDuple(first, last, - (hasTemplateId ? argumentList.getTemplateArgumentsList() - : null)); - return tokenDuple; - } finally { - TemplateParameterManager.returnInstance(argumentList); + private IASTName operatorId() throws BacktrackException, EndOfFileException { + final IToken firstToken = consume(IToken.t_operator); + int endOffset= firstToken.getEndOffset(); + IASTTypeId typeId = null; + OverloadableOperator op = null; + final int lt1= LT(1); + switch (lt1) { + case IToken.tLPAREN: + op = OverloadableOperator.PAREN; // operator () + consume(); + endOffset = consume(IToken.tRPAREN).getEndOffset(); + break; + case IToken.tLBRACKET: + op = OverloadableOperator.BRACKET; // operator [] + consume(); + endOffset = consume(IToken.tRBRACKET).getEndOffset(); + break; + case IToken.t_new: + case IToken.t_delete: + if (LT(2) == IToken.tLBRACKET) { + op= lt1 == IToken.t_new ? OverloadableOperator.NEW_ARRAY : OverloadableOperator.DELETE_ARRAY; + consume(); + consume(); + endOffset= consume(IToken.tRBRACKET).getEndOffset(); + } else { + IToken t= consume(); + endOffset= t.getEndOffset(); + op= OverloadableOperator.valueOf(t); + } + break; + default: + op= OverloadableOperator.valueOf(LA(1)); + if (op != null) { + endOffset= consume().getEndOffset(); + } + break; + } + + if (op != null) { + IASTName name= nodeFactory.newOperatorName(op.toCharArray()); + setRange(name, firstToken.getOffset(), endOffset); + return name; } + // must be a conversion function + IToken t = LA(1); + typeId= typeId(DeclarationOptions.TYPEID_CONVERSION); + if (typeId == null) + throwBacktrack(t); + + char[] image= computeOperatorImage(firstToken, LA(1)); + IASTName name = nodeFactory.newConversionName(image, typeId); + setRange(name, firstToken.getOffset(), calculateEndOffset(typeId)); + return name; + } + + private char[] computeOperatorImage(IToken from, final IToken to) throws EndOfFileException { + if(from == to) + return CharArrayUtils.EMPTY; + + StringBuilder buf= new StringBuilder(); + int prevKind= -1; + while (from != to && from != null) { + final int nextKind= from.getType(); + if (prevKind != -1 && + prevKind != IToken.tCOLONCOLON && + prevKind != IToken.tIDENTIFIER && + prevKind != IToken.tLT && + prevKind != IToken.tBITCOMPLEMENT && + prevKind != IToken.tLBRACKET && + nextKind != IToken.tGT && + nextKind != IToken.tRBRACKET && + nextKind != IToken.tCOLONCOLON) { + buf.append(' '); + } + buf.append(from.getCharImage()); + prevKind= nextKind; + from= from.getNext(); + } + final int len= buf.length(); + final char[] result= new char[len]; + buf.getChars(0, len, result, 0); + return result; + } + + @Override + protected IASTExpression expression() throws EndOfFileException, BacktrackException { + final boolean wasOnTop= onTopInTemplateArgs; + onTopInTemplateArgs= false; + try { + return super.expression(); + } finally { + onTopInTemplateArgs= wasOnTop; + } } @Override @@ -468,255 +647,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { return expr; } - protected IToken consumeTemplateArguments(IToken last, TemplateParameterManager argumentList) throws EndOfFileException, BacktrackException { - if (LT(1) == IToken.tLT) { - IToken secondMark = mark(); - consume(); - final boolean wasOnTop= onTopInTemplateArgs; - onTopInTemplateArgs= true; - try { - // bug 229062: content assist after '<' needs to prefer to backtrack here - if (rejectLogicalOperatorInTemplateID == 1) { - final int lt1= LT(1); - if (lt1 == IToken.tCOMPLETION || lt1 == IToken.tEOC) { - throw backtrack; - } - } - - List list = templateArgumentList(); - switch(LT(1)) { - case IToken.tGT: - final int lt2= LT(2); - if (lt2 == IToken.tINTEGER || lt2 == IToken.tFLOATINGPT) { - throw backtrack; - } - break; - case IToken.tEOC: - break; - default: - throw backtrack; - } - argumentList.addSegment(list); - last = consume(); - } catch (BacktrackException bt) { - argumentList.addSegment(null); - backup(secondMark); - } finally { - onTopInTemplateArgs= wasOnTop; - } - } else { - argumentList.addSegment(null); - } - return last; - } - - - - protected IASTName operatorId(IToken originalToken, TemplateParameterManager templateArgs) throws BacktrackException, EndOfFileException { - // we know this is an operator - IToken operatorToken = consume(); - IToken toSend = null; - IASTTypeId typeId = null; - OverloadableOperator op = null; - if (LA(1).isOperator() || LT(1) == IToken.tLPAREN || LT(1) == IToken.tLBRACKET) { - if ((LT(1) == IToken.t_new || LT(1) == IToken.t_delete) && - LT(2) == IToken.tLBRACKET && LT(3) == IToken.tRBRACKET) { - op = LT(1) == IToken.t_new ? OverloadableOperator.NEW_ARRAY : OverloadableOperator.DELETE_ARRAY; - consume(); // new or delete - consume(); // lbracket - toSend = consume(); // rbracket - // vector new and delete operators - } else if (LT(1) == IToken.tLPAREN && LT(2) == IToken.tRPAREN) { - // operator () - consume(); // "(" - toSend = consume(); // ")" - op = OverloadableOperator.PAREN; - } else if (LT(1) == IToken.tLBRACKET && LT(2) == IToken.tRBRACKET) { - consume(); // "[" - toSend = consume(); // "]" - op = OverloadableOperator.BRACKET; - } else if (LA(1).isOperator()) { - toSend = consume(); - op = OverloadableOperator.valueOf(toSend); - } - else - throwBacktrack(operatorToken.getOffset(), 0); // toSend must be null - } else { - // must be a conversion function - IToken t = LA(1); - typeId= typeId(DeclarationOptions.TYPEID_CONVERSION); - if (typeId == null) - throwBacktrack(t); - - if (t != LA(1)) { - while (t.getNext() != LA(1)) { - t = t.getNext(); - } - toSend = t; - } - } - - boolean hasTemplateId = (templateArgs != null); - boolean grabbedNewInstance = false; - if (templateArgs == null) { - templateArgs = TemplateParameterManager.getInstance(); - grabbedNewInstance = true; - } - - try { - toSend = consumeTemplateArguments(toSend, templateArgs); - if (toSend.getType() == IToken.tGT) { - hasTemplateId = true; - } - - ITokenDuple duple = TokenFactory.createTokenDuple( - originalToken == null ? operatorToken : originalToken, - toSend, (hasTemplateId ? templateArgs - .getTemplateArgumentsList() : null)); - - OperatorTokenDuple operatorDuple = new OperatorTokenDuple(duple, op); - if (typeId != null) { // if it's a conversion operator - operatorDuple.setConversionOperator(true); - operatorDuple.setTypeId(typeId); - } - - return buildName(operatorDuple); - } finally { - if (grabbedNewInstance) - TemplateParameterManager.returnInstance(templateArgs); - } - } - - /** - * Parse a Pointer Operator. ptrOperator : "*" (cvQualifier)* | "&" | ::? - * nestedNameSpecifier "*" (cvQualifier)* - * - * @throws BacktrackException - * request a backtrack - */ - protected void consumePointerOperators(List collection) - throws EndOfFileException, BacktrackException { - - for (;;) { - // __attribute__ in-between pointers - __attribute_decl_seq(supportAttributeSpecifiers, false); - - if (LT(1) == IToken.tAMPER) { -// boolean isRestrict= false; - IToken lastToken= consume(); - final int from= lastToken.getOffset(); - if (allowCPPRestrict && LT(1) == IToken.t_restrict) { -// isRestrict= true; - lastToken= consume(); - } - ICPPASTReferenceOperator refOp = nodeFactory.newReferenceOperator(); - ((ASTNode) refOp).setOffsetAndLength(from, lastToken.getEndOffset()-from); - collection.add(refOp); - return; - } - IToken last = null; - IToken mark = mark(); - ITokenDuple nameDuple = null; - boolean isConst = false, isVolatile = false, isRestrict = false; - if (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tCOLONCOLON) { - try { - nameDuple = name(); - if (nameDuple.length() == 1) { - backup(mark); - return; - } - if (nameDuple.getLastToken().getType() != IToken.tCOLONCOLON) { - backup(mark); - return; - } - last = nameDuple.getLastToken(); - } catch (BacktrackException bt) { - backup(mark); - return; - } - } - if (LT(1) == IToken.tSTAR) { - last = consume(); - int starOffset = last.getOffset(); - - for (;;) { - IToken t = LA(1); - int startingOffset = LA(1).getOffset(); - switch (LT(1)) { - case IToken.t_const: - last = consume(); - isConst = true; - break; - case IToken.t_volatile: - last = consume(); - isVolatile = true; - break; - case IToken.t_restrict: - if (allowCPPRestrict) { - last = consume(); - isRestrict = true; - break; - } - IToken la = LA(1); - throwBacktrack(startingOffset, la.getEndOffset() - startingOffset); - - } - if (t == LA(1)) - break; - } - - if (nameDuple != null) { - IASTName name = buildName(nameDuple); - ICPPASTPointerToMember p2m; - if(isRestrict) { - IGPPASTPointerToMember gppp2m = nodeFactory.newPointerToMemberGPP(name); - gppp2m.setRestrict(true); - p2m = gppp2m; - } - else { - p2m = nodeFactory.newPointerToMember(name); - } - - ((ASTNode) p2m).setOffsetAndLength(nameDuple.getFirstToken().getOffset(), - last.getEndOffset() - nameDuple.getFirstToken().getOffset()); - p2m.setConst(isConst); - p2m.setVolatile(isVolatile); - collection.add(p2m); - } else { - IASTPointer pointer; - if(isRestrict) { - IGPPASTPointer gpppo = nodeFactory.newPointerGPP(); - gpppo.setRestrict(true); - pointer = gpppo; - } - else { - pointer = nodeFactory.newPointer(); - } - ((ASTNode) pointer).setOffsetAndLength(starOffset, last.getEndOffset() - starOffset); - pointer.setConst(isConst); - pointer.setVolatile(isVolatile); - collection.add(pointer); - } - - continue; - } - - backup(mark); - return; - } - } - - - @Override - protected IASTExpression expression() throws EndOfFileException, BacktrackException { - final boolean wasOnTop= onTopInTemplateArgs; - onTopInTemplateArgs= false; - try { - return super.expression(); - } finally { - onTopInTemplateArgs= wasOnTop; - } - } @Override protected IASTExpression constantExpression() throws EndOfFileException, BacktrackException { @@ -834,37 +764,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } } - @Override - protected IASTTypeId typeId(DeclarationOptions option) throws EndOfFileException { - if (!canBeTypeSpecifier()) { - return null; - } - IToken mark = mark(); - int startingOffset = mark.getOffset(); - IASTDeclSpecifier declSpecifier = null; - IASTDeclarator declarator = null; - try { - declSpecifier = declSpecifierSeq(option); - if (LT(1) != IToken.tEOC) { - declarator= declarator(DtorStrategy.PREFER_FUNCTION, option); - } - } catch (FoundDeclaratorException e) { - declSpecifier= e.declSpec; - declarator= e.declarator; - backup(e.currToken); - } catch (FoundAggregateInitializer lie) { - // type-ids have no initializers - return null; - } catch (BacktrackException bt) { - return null; - } - IASTTypeId result = nodeFactory.newTypeId(declSpecifier, declarator); - ((ASTNode) result).setOffsetAndLength(startingOffset, figureEndOffset(declSpecifier, declarator) - startingOffset); - return result; - - } - - protected IASTExpression deleteExpression() throws EndOfFileException, BacktrackException { int startingOffset = LA(1).getOffset(); boolean global = false; @@ -1083,14 +982,13 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { consume(); templateTokenConsumed = true; } - ITokenDuple nestedName = name(); - IASTName name = buildName(nestedName); + IASTName name = idExpression(); if (LT(1) != IToken.tLPAREN) { - throwBacktrack(nestedName.getFirstToken().getOffset(), nestedName.getLastToken().getEndOffset()); + throwBacktrack(LA(1)); } ICPPASTTypenameExpression result = nodeFactory.newTypenameExpression(name, null, templateTokenConsumed); - ((ASTNode) result).setOffsetAndLength(typenameOffset, nestedName.getLastToken().getEndOffset() - typenameOffset); + setRange(result, typenameOffset, calculateEndOffset(name)); firstExpression = result; break; // simple-type-specifier ( assignment-expression , .. ) @@ -1366,37 +1264,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } - - protected IASTName idExpression() throws EndOfFileException, BacktrackException { - IASTName name = null; - try { - name = buildName(nameWithoutLogicalOperatorInTemplateID()); - } catch (BacktrackException bt) { - IToken mark = mark(); - if (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) { - IToken start = consume(); - IToken end = null; - if (start.getType() == IToken.tIDENTIFIER) - end = consumeTemplateParameters(end); - while (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) { - end = consume(); - if (end.getType() == IToken.tIDENTIFIER) - end = consumeTemplateParameters(end); - } - - if (LT(1) == IToken.t_operator) - name = operatorId(start, null); - else { - backup(mark); - throwBacktrack(start.getOffset(), end == null ? start.getLength() : end.getEndOffset()); - } - } else if (LT(1) == IToken.t_operator) - name = operatorId(null, null); - } - return name; - - } - protected IASTExpression specialCastExpression(int kind) throws EndOfFileException, BacktrackException { final int offset = LA(1).getOffset(); final int optype= consume().getType(); @@ -1449,7 +1316,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { case IToken.tIDENTIFIER: case IToken.tCOLONCOLON: case IToken.tCOMPLETION: - name = buildName(name()); + name = qualifiedName(); break; default: throwBacktrack(offset, endOffset - offset); @@ -1710,7 +1577,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { IASTTypeId typeId = null; if (LT(1) == IToken.tIDENTIFIER) { // optional identifier - identifierName = createName(identifier()); + identifierName = identifier(); lastOffset = calculateEndOffset(identifierName); if (LT(1) == IToken.tASSIGN) { // optional = type-id consume(); @@ -1738,7 +1605,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { IASTExpression optionalExpression = null; if (LT(1) == IToken.tIDENTIFIER) { // optional identifier - identifierName = createName(identifier()); + identifierName = identifier(); last = calculateEndOffset(identifierName); if (LT(1) == IToken.tASSIGN) { // optional = type-id consume(); @@ -1831,7 +1698,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { // optional name IASTName name = null; if (LT(1) == IToken.tIDENTIFIER) { - name = createName(identifier()); + name = identifier(); endOffset= calculateEndOffset(name); } else { name = nodeFactory.newName(); @@ -1900,8 +1767,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { return null; } - ITokenDuple duple = name(); - IASTName qualifiedName = buildName(duple); + IASTName qualifiedName= qualifiedName(); endOffset = consume(IToken.tSEMI).getEndOffset(); ICPPASTNamespaceAlias alias = nodeFactory.newNamespaceAlias(name, qualifiedName); @@ -1913,147 +1779,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } - protected ICPPASTQualifiedName buildQualifiedName(ITokenDuple duple) { - ICPPASTQualifiedName result = nodeFactory.newQualifiedName(); - ((ASTNode)result).setOffsetAndLength(duple.getStartOffset(), duple.getEndOffset() - duple.getStartOffset()); - if(result instanceof CPPASTQualifiedName) - ((CPPASTQualifiedName)result).setSignature(duple.toString()); - ITokenDuple[] segments = duple.getSegments(); - int startingValue = 0; - if (segments.length > 0) { - final ITokenDuple firstSeg= segments[0]; - final IToken firstToken= firstSeg.getFirstToken(); - if (firstToken.getType() == IToken.tCOLONCOLON) { - if (firstToken == firstSeg.getLastToken() && firstSeg.getTemplateIdArgLists() == null) { - ++startingValue; - result.setFullyQualified(true); - } - } - } - for (int i = startingValue; i < segments.length; ++i) { - IASTName subName = null; - // take each name and add it to the result - final ITokenDuple seg= segments[i]; - if (seg.getTemplateIdArgLists() == null) { - final IToken firstToken= seg.getFirstToken(); - if (firstToken == seg.getLastToken()) { - subName= createName(firstToken); - } - else { - subName = buildName(seg); - } - } - else { - // templateID - subName = buildTemplateID(segments[i]); - } - - if (i == segments.length - 1 && duple instanceof OperatorTokenDuple) { - // make sure the last segment is an OperatorName/ConversionName - subName = buildOperatorName((OperatorTokenDuple) duple, subName); - } - - // bug 189299, 193152 indicate that there have been nested qualified names - // as a work around just flatten them. - if (subName instanceof ICPPASTQualifiedName) { - IASTName[] subNames= ((ICPPASTQualifiedName) subName).getNames(); - for (IASTName subName2 : subNames) { - subName = subName2; - result.addName(subName); - } - } - else { - ((ASTNode) subName).setOffsetAndLength(segments[i].getStartOffset(), - segments[i].getEndOffset() - segments[i].getStartOffset()); - result.addName(subName); - } - } - return result; - } - - protected ICPPASTTemplateId buildTemplateID(ITokenDuple duple) { - ICPPASTTemplateId result = nodeFactory.newTemplateId(null); - ((ASTNode) result).setOffsetAndLength(duple.getStartOffset(), duple.getEndOffset() - duple.getStartOffset()); - IASTName templateIdName= null; - if (duple instanceof BasicTokenDuple) { - ITokenDuple nameDuple= ((BasicTokenDuple)duple).getTemplateIdNameTokenDuple(); - templateIdName= buildName(nameDuple); - } - else { - char[] image = duple.extractNameFromTemplateId(); - templateIdName= nodeFactory.newName(image); - ((ASTNode)templateIdName).setOffsetAndLength(duple.getStartOffset(), image.length); - } - result.setTemplateName(templateIdName); - if (duple.getTemplateIdArgLists() != null) { - List args= duple.getTemplateIdArgLists()[0]; - if (args != null) - for (int i = 0; i < args.size(); ++i) { - IASTNode n = args.get(i); - if (n instanceof IASTTypeId) { - result.addTemplateArgument((IASTTypeId) n); - } else if(n instanceof IASTExpression) { - result.addTemplateArgument((IASTExpression) n); - } else if(n instanceof ICPPASTAmbiguousTemplateArgument) { - result.addTemplateArgument((ICPPASTAmbiguousTemplateArgument) n); - } - } - } - return result; - } - - - protected IASTName buildName(ITokenDuple duple) { - if (duple == null) - return nodeFactory.newName(); - if (duple.getSegmentCount() != 1) { - // workaround for bug 193152, - // looks like duple.getSeqmentCount() and duple.getSegments().length can be different. - ICPPASTQualifiedName qname= buildQualifiedName(duple); - if (qname.getNames().length > 0) { - return qname; - } - } - if (duple.getTemplateIdArgLists() != null) - return buildTemplateID(duple); - - // We're a single name - IASTName name = nodeFactory.newName(duple.toCharArray()); - if (duple instanceof OperatorTokenDuple) { - name = buildOperatorName((OperatorTokenDuple) duple, name); - } - - IToken token = duple.getFirstToken(); - switch (token.getType()) { - case IToken.tCOMPLETION: - case IToken.tEOC: - createCompletionNode(token).addName(name); - break; - } - - ((ASTNode) name).setOffsetAndLength(duple.getStartOffset(), duple.getEndOffset() - duple.getStartOffset()); - return name; - } - - protected IASTName buildOperatorName(OperatorTokenDuple duple, IASTName name) { - IASTName aName = null; - - if (duple.isConversionOperator()) { - IASTTypeId typeId = duple.getTypeId(); - aName = nodeFactory.newConversionName(name.toCharArray(), typeId); - } else { - aName = nodeFactory.newOperatorName(duple.getOperator().toCharArray()); - } - - if (name instanceof ICPPASTTemplateId) { - ((ICPPASTTemplateId) name).setTemplateName(aName); - return name; - } - - return aName; - } - - /** * Parses a declaration with the given options. */ @@ -2270,10 +1995,10 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { protected void ctorInitializer(ICPPASTFunctionDefinition fdef) throws EndOfFileException, BacktrackException { consume(); ctorLoop: for (;;) { - ITokenDuple duple = name(); - IASTName name = buildName(duple); + int offset= LA(1).getOffset(); + IASTName name = qualifiedName(); - int end; + int endOffset; IASTExpression expressionList = null; switch (LT(1)) { case IToken.tLPAREN: @@ -2285,21 +2010,21 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { switch (LT(1)) { case IToken.tRPAREN: case IToken.tEOC: - end = consume().getEndOffset(); + endOffset = consume().getEndOffset(); break; default: throw backtrack; } break; case IToken.tEOC: - end = consume().getEndOffset(); + endOffset = consume().getEndOffset(); break; default: throw backtrack; } ICPPASTConstructorChainInitializer ctorInitializer = nodeFactory.newConstructorChainInitializer(name, expressionList); - ((ASTNode) ctorInitializer).setOffsetAndLength(duple.getStartOffset(), end - duple.getStartOffset()); + setRange(ctorInitializer, offset, endOffset); fdef.addMemberInitializer(ctorInitializer); switch (LT(1)) { @@ -2376,7 +2101,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { int options= 0; int isLong= 0; - ITokenDuple identifier= null; + IASTName identifier= null; ICPPASTDeclSpecifier result= null; IASTExpression typeofExpression= null; IASTProblem problem= null; @@ -2541,8 +2266,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { if (encounteredTypename || encounteredRawType) break declSpecifiers; consume(); - identifier= name(); - endOffset= identifier.getLastToken().getEndOffset(); + identifier= qualifiedName(); + endOffset= calculateEndOffset(identifier); isTypename = true; encounteredTypename= true; break; @@ -2568,11 +2293,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } } - identifier= name(); - if (identifier.getLastToken().getType() == IToken.tCOLONCOLON) - throwBacktrack(identifier.getLastToken()); + identifier= qualifiedName(); + if (identifier.getLastName().toCharArray().length == 0) + throwBacktrack(LA(1)); - endOffset= identifier.getLastToken().getEndOffset(); + endOffset= calculateEndOffset(identifier); encounteredTypename= true; break; case IToken.t_class: @@ -2655,15 +2380,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { if (result != null) { configureDeclSpec(result, storageClass, options); - if ((options & RESTRICT) != 0) { - if (result instanceof ICASTCompositeTypeSpecifier) { - ((ICASTCompositeTypeSpecifier) result).setRestrict(true); - } else if (result instanceof CASTEnumerationSpecifier) { - ((CASTEnumerationSpecifier) result).setRestrict(true); - } else if (result instanceof CASTElaboratedTypeSpecifier) { - ((CASTElaboratedTypeSpecifier) result).setRestrict(true); - } - } + // cannot store restrict in the cpp-nodes. + // if ((options & RESTRICT) != 0) { + // } ((ASTNode) result).setOffsetAndLength(offset, endOffset - offset); if (problem != null) { throwBacktrack(problem, result); @@ -2710,9 +2429,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { return false; } - private ICPPASTNamedTypeSpecifier buildNamedTypeSpecifier(ITokenDuple identifier, boolean isTypename, + private ICPPASTNamedTypeSpecifier buildNamedTypeSpecifier(IASTName name, boolean isTypename, int storageClass, int options, int offset, int endOffset) { - IASTName name = buildName(identifier); ICPPASTNamedTypeSpecifier declSpec = nodeFactory.newTypedefNameSpecifier(name); declSpec.setIsTypename(isTypename); configureDeclSpec(declSpec, storageClass, options); @@ -2776,7 +2494,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { case IToken.t_volatile: if (option == DeclarationOptions.GLOBAL || option == DeclarationOptions.CPP_MEMBER || option == DeclarationOptions.FUNCTION_STYLE_ASM) { - if (CVisitor.findTypeRelevantDeclarator(dtor) instanceof IASTFunctionDeclarator) { + if (CPPVisitor.findTypeRelevantDeclarator(dtor) instanceof IASTFunctionDeclarator) { return true; } } @@ -2827,7 +2545,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { // if __attribute__ or __declspec occurs after struct/union/class and before the identifier __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers); - IASTName name = buildName(name()); + IASTName name = qualifiedName(); ICPPASTElaboratedTypeSpecifier elaboratedTypeSpec = nodeFactory.newElaboratedTypeSpecifier(eck, name); ((ASTNode) elaboratedTypeSpec).setOffsetAndLength(t.getOffset(), calculateEndOffset(name) - t.getOffset()); @@ -3049,6 +2767,36 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } + @Override + protected IASTTypeId typeId(DeclarationOptions option) throws EndOfFileException { + if (!canBeTypeSpecifier()) { + return null; + } + IToken mark = mark(); + int startingOffset = mark.getOffset(); + IASTDeclSpecifier declSpecifier = null; + IASTDeclarator declarator = null; + try { + declSpecifier = declSpecifierSeq(option); + if (LT(1) != IToken.tEOC) { + declarator= declarator(DtorStrategy.PREFER_FUNCTION, option); + } + } catch (FoundDeclaratorException e) { + declSpecifier= e.declSpec; + declarator= e.declarator; + backup(e.currToken); + } catch (FoundAggregateInitializer lie) { + // type-ids have no initializers + return null; + } catch (BacktrackException bt) { + return null; + } + IASTTypeId result = nodeFactory.newTypeId(declSpecifier, declarator); + ((ASTNode) result).setOffsetAndLength(startingOffset, figureEndOffset(declSpecifier, declarator) - startingOffset); + return result; + + } + /** * Parse a declarator, as according to the ANSI C++ specification. * declarator : (ptrOperator)* directDeclarator @@ -3090,7 +2838,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { if (option.fRequireAbstract) throwBacktrack(LA(1)); - final IASTName declaratorName= consumeTemplatedOperatorName(); + final IASTName declaratorName= qualifiedName(); endOffset= calculateEndOffset(declaratorName); return declarator(pointerOps, declaratorName, null, startingOffset, endOffset, strategy, option); } @@ -3158,6 +2906,117 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { return declarator(pointerOps, nodeFactory.newName(), null, startingOffset, endOffset, strategy, option); } + /** + * Parse a Pointer Operator. ptrOperator : "*" (cvQualifier)* | "&" | ::? + * nestedNameSpecifier "*" (cvQualifier)* + * + * @throws BacktrackException + * request a backtrack + */ + private void consumePointerOperators(List collection) + throws EndOfFileException, BacktrackException { + + for (;;) { + // __attribute__ in-between pointers + __attribute_decl_seq(supportAttributeSpecifiers, false); + + if (LT(1) == IToken.tAMPER) { +// boolean isRestrict= false; + IToken lastToken= consume(); + final int from= lastToken.getOffset(); + if (allowCPPRestrict && LT(1) == IToken.t_restrict) { +// isRestrict= true; + lastToken= consume(); + } + ICPPASTReferenceOperator refOp = nodeFactory.newReferenceOperator(); + ((ASTNode) refOp).setOffsetAndLength(from, lastToken.getEndOffset()-from); + collection.add(refOp); + return; + } + + IToken mark = mark(); + final int startOffset = mark.getOffset(); + boolean isConst = false, isVolatile = false, isRestrict = false; + IASTName name= null; + int coloncolon= LT(1) == IToken.tCOLONCOLON ? 1 : 0; + loop: while (LT(coloncolon+1) == IToken.tIDENTIFIER) { + switch(LT(coloncolon+2)) { + case IToken.tCOLONCOLON: + coloncolon+= 2; + break; + case IToken.tLT: + coloncolon= 1; + break loop; + default: + coloncolon= 0; + break loop; + } + } + if (coloncolon != 0) { + try { + name= qualifiedName(); + if (name.getLastName().toCharArray().length != 0) { + backup(mark); + return; + } + } catch (BacktrackException bt) { + backup(mark); + return; + } + } + if (LT(1) != IToken.tSTAR) { + backup(mark); + return; + } + + int endOffset= consume().getEndOffset(); + loop: for (;;) { + switch (LT(1)) { + case IToken.t_const: + endOffset= consume().getEndOffset(); + isConst = true; + break; + case IToken.t_volatile: + endOffset= consume().getEndOffset(); + isVolatile = true; + break; + case IToken.t_restrict: + if (!allowCPPRestrict) + throwBacktrack(LA(1)); + endOffset= consume().getEndOffset(); + isRestrict = true; + break; + default: + break loop; + } + } + + + IASTPointer pointer; + if (name != null) { + if(isRestrict) { + IGPPASTPointerToMember gppp2m = nodeFactory.newPointerToMemberGPP(name); + gppp2m.setRestrict(true); + pointer= gppp2m; + } else { + pointer= nodeFactory.newPointerToMember(name); + } + } else { + if(isRestrict) { + IGPPASTPointer gpppo = nodeFactory.newPointerGPP(); + gpppo.setRestrict(true); + pointer= gpppo; + } else { + pointer = nodeFactory.newPointer(); + } + } + pointer.setConst(isConst); + pointer.setVolatile(isVolatile); + setRange(pointer, startOffset, endOffset); + collection.add(pointer); + } + } + private IASTDeclarator declarator(List pointerOps, IASTName declaratorName, IASTDeclarator nestedDeclarator, int startingOffset, int endOffset, DtorStrategy strategy, DeclarationOptions option) @@ -3375,53 +3234,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { return d; } - - protected IASTName consumeTemplatedOperatorName() throws EndOfFileException, BacktrackException { - TemplateParameterManager argumentList = TemplateParameterManager.getInstance(); - try { - if (LT(1) == IToken.t_operator) - return operatorId(null, null); - - try { - return buildName(name()); - } catch (BacktrackException bt) { - } - IToken start = null; - - IToken mark = mark(); - if (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) { - start = consume(); - IToken end = null; - - if (start.getType() == IToken.tIDENTIFIER) { - end = consumeTemplateArguments(end, argumentList); - } - - while (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) { - end = consume(); - if (end.getType() == IToken.tIDENTIFIER) { - end = consumeTemplateArguments(end, argumentList); - } - } - - if (LT(1) == IToken.t_operator) { - return operatorId(start, argumentList); - } - - int endOffset = (end != null) ? end.getEndOffset() : 0; - backup(mark); - throwBacktrack(mark.getOffset(), endOffset - mark.getOffset()); - } - int endOffset= mark.getEndOffset(); - backup(mark); - throwBacktrack(mark.getOffset(), endOffset - mark.getOffset()); - - return null; - } finally { - TemplateParameterManager.returnInstance(argumentList); - } - } - /** * Parse a class/struct/union definition. classSpecifier : classKey name * (baseClause)? "{" (memberSpecification)* "}" @@ -3459,7 +3271,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { // class name IASTName name = null; if (LT(1) == IToken.tIDENTIFIER) - name = buildName(name()); + name = qualifiedName(); else name = nodeFactory.newName(); @@ -3587,80 +3399,59 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { * @throws BacktrackException */ protected void baseSpecifier(ICPPASTCompositeTypeSpecifier astClassSpec) throws EndOfFileException, BacktrackException { - IToken last = consume(); // tCOLON - + int endOffset= consume().getEndOffset(); // tCOLON + int startOffset= LA(1).getOffset(); + boolean isVirtual = false; - int visibility = 0; // ASTAccessVisibility.PUBLIC; + int visibility = 0; IASTName name = null; - IToken firstToken = null; baseSpecifierLoop: for (;;) { switch (LT(1)) { case IToken.t_virtual: - if (firstToken == null) { - firstToken = consume(); - last = firstToken; - } else - last = consume(); isVirtual = true; + endOffset= consume().getEndOffset(); break; case IToken.t_public: visibility = ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.v_public; - if (firstToken == null) { - firstToken = consume(); - last = firstToken; - } else - last = consume(); + endOffset= consume().getEndOffset(); break; case IToken.t_protected: visibility = ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.v_protected; - if (firstToken == null) { - firstToken = consume(); - last = firstToken; - } else - last = consume(); + endOffset= consume().getEndOffset(); break; case IToken.t_private: visibility = ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.v_private; - if (firstToken == null) { - firstToken = consume(); - last = firstToken; - } else - last = consume(); + endOffset= consume().getEndOffset(); break; case IToken.tCOLONCOLON: case IToken.tIDENTIFIER: case IToken.tCOMPLETION: // to get templates right we need to use the class as the scope - ITokenDuple d = name(); - name = buildName(d); - if (firstToken == null) - firstToken = d.getFirstToken(); - last = d.getLastToken(); + name = qualifiedName(); + endOffset= calculateEndOffset(name); break; case IToken.tCOMMA: if (name == null) name = nodeFactory.newName(); consume(); ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier baseSpec = nodeFactory.newBaseSpecifier(name, visibility, isVirtual); - if (firstToken != null) - ((ASTNode) baseSpec).setOffsetAndLength(firstToken.getOffset(), last.getEndOffset() - firstToken.getOffset()); + setRange(baseSpec, startOffset, endOffset); astClassSpec.addBaseSpecifier(baseSpec); isVirtual = false; visibility = 0; name = null; - firstToken = null; - + startOffset= endOffset= LA(1).getOffset(); continue baseSpecifierLoop; case IToken.tLBRACE: case IToken.tEOC: if (name == null) name = nodeFactory.newName(); baseSpec = nodeFactory.newBaseSpecifier(name, visibility, isVirtual); - if (firstToken != null) - ((ASTNode) baseSpec).setOffsetAndLength(firstToken.getOffset(), last.getEndOffset() - firstToken.getOffset()); + setRange(baseSpec, startOffset, endOffset); astClassSpec.addBaseSpecifier(baseSpec); break baseSpecifierLoop; + default: break baseSpecifierLoop; } @@ -3780,7 +3571,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } - protected void consumeArrayModifiers(DeclarationOptions option, List collection) + private void consumeArrayModifiers(DeclarationOptions option, List collection) throws EndOfFileException, BacktrackException { boolean allowExpression= option == DeclarationOptions.TYPEID_NEW; while (LT(1) == IToken.tLBRACKET) { @@ -3813,38 +3604,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { return translationUnit; } - - @Override - protected IASTName createName(IToken token) { - IASTName n = null; - - if (token instanceof OperatorTokenDuple) { - n = buildOperatorName((OperatorTokenDuple) token, n); - } else { - n = nodeFactory.newName(token.getCharImage()); - } - - switch (token.getType()) { - case IToken.tCOMPLETION: - case IToken.tEOC: - createCompletionNode(token).addName(n); - break; - } - ((ASTNode) n).setOffsetAndLength(token.getOffset(), token.getLength()); - - return n; - } - - - @Override - protected IASTExpression buildTypeIdExpression(int op, IASTTypeId typeId, int startingOffset, int endingOffset) { - IASTTypeIdExpression typeIdExpression = nodeFactory.newTypeIdExpression(op, typeId); - ((ASTNode) typeIdExpression).setOffsetAndLength(startingOffset, endingOffset - startingOffset); - return typeIdExpression; - } - - - @Override protected IASTStatement statement() throws EndOfFileException, BacktrackException { switch (LT(1)) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 681bc0f17b4..96b461cca86 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -162,7 +162,7 @@ public class CPPTemplates { final int numArgs = arguments.length; final int numParams= parameters.length; 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]; CPPTemplateParameterMap map= new CPPTemplateParameterMap(numParams); @@ -176,7 +176,7 @@ public class CPPTemplates { } else { ICPPTemplateArgument defaultArg= param.getDefaultValue(); if (defaultArg == null) { - return createProblem(template, IProblemBinding.SEMANTIC_INVALID_USING); + return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS); } arg= instantiateArgument(defaultArg, map, null); arg= SemanticUtil.getSimplifiedArgument(arg); @@ -186,7 +186,7 @@ public class CPPTemplates { if (!hasDependentDefaultArg) { arg= CPPTemplates.matchTemplateParameterAndArgument(param, arg, map); if (arg == null) - return createProblem(template, IProblemBinding.SEMANTIC_INVALID_USING); + return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS); } map.put(param, arg); @@ -212,19 +212,7 @@ public class CPPTemplates { } private static IBinding createProblem(ICPPClassTemplate template, int id) { - IASTNode node= null; - 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()); - } + IASTNode node= new CPPASTName(template.getNameCharArray()); return new ProblemBinding(node, id, template.getNameCharArray()); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties index 5e4a4361fca..2498435fb4e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties @@ -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.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.invalidTemplateArgs=A template id provides illegal arguments for the instantiation: {0} CPPASTAmbiguousTemplateArgument_InvalidConstruction=Internal parser error: Template argument ambiguity constructed with {0} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/TemplateParameterManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/TemplateParameterManager.java deleted file mode 100644 index 381d4ef548d..00000000000 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/TemplateParameterManager.java +++ /dev/null @@ -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>. - * - * 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; - private int emptySegmentCount; - - public List> getTemplateArgumentsList() { - return list; - } - - public void addSegment(List 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>(); - 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; - } - -} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/BasicTokenDuple.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/BasicTokenDuple.java deleted file mode 100644 index cbbb61e826f..00000000000 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/BasicTokenDuple.java +++ /dev/null @@ -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 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 [] args = getTemplateIdArgLists(); - if( args != null && args[ args.length - 1 ] != null ){ - List> newArgs = new ArrayList>( 1 ); - newArgs.add( args[ args.length - 1 ] ); - return TokenFactory.createTokenDuple( first, last, newArgs ); - } - return TokenFactory.createTokenDuple( first, last ); - } - - public ITokenDuple[] getSegments() - { - - List r = new ArrayList(); - 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[] args = getTemplateIdArgLists(); - List> newArgs = new ArrayList>( 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 - { - 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[] 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[] 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[] 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 qn = new ArrayList(); - 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; - } -} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/OperatorTokenDuple.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/OperatorTokenDuple.java deleted file mode 100644 index 2a8cc67037a..00000000000 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/OperatorTokenDuple.java +++ /dev/null @@ -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[] getTemplateIdArgLists() { - return token.getTemplateIdArgLists(); - } - - public ITokenDuple getLastSegment() { - return token.getLastSegment(); - } - - public ITokenDuple getLeadingSegments() { - return token.getLeadingSegments(); - } - - public int getSegmentCount() { - return token.getSegmentCount(); - } - - public Iterator 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(); - } -} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/TemplateTokenDuple.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/TemplateTokenDuple.java deleted file mode 100644 index a08349d7081..00000000000 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/TemplateTokenDuple.java +++ /dev/null @@ -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[] argLists; - - /** - * @param first - * @param last - * @param templateArgLists - */ - public TemplateTokenDuple(IToken first, IToken last, List> templateArgLists) { - super(first, last); - argLists = toArray(templateArgLists); - numSegments = calculateSegmentCount(); - } - - @SuppressWarnings("unchecked") - private List[] toArray(List> templateArgLists) { - return templateArgLists.toArray( new List[templateArgLists.size()] ); - } - @SuppressWarnings("unchecked") - private List[] 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[] args = getTemplateIdArgLists(); - if( args != null && args[ args.length - 1 ] != null ){ - List> newArgs = new ArrayList>( 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[] a1 = first.getTemplateIdArgLists(); - List[] 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[] getTemplateIdArgLists() { - return argLists; - } - - @Override - public ITokenDuple[] getSegments() - { - List r = new ArrayList(); - 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> newArgs = null; - if( argLists[count] != null ) - { - newArgs = new ArrayList>(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> newArgs = null; - //pointer to members could have a A::B:: - if( count < argLists.length && argLists[count] != null ) - { - newArgs = new ArrayList>(1); - newArgs.add(argLists[count]); - } - ITokenDuple d = TokenFactory.createTokenDuple( startOfSegment, last, newArgs); - r.add( d ); - return r.toArray( new ITokenDuple[ r.size() ]); - - } - -} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/TokenFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/TokenFactory.java deleted file mode 100644 index 339fa83e81f..00000000000 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/TokenFactory.java +++ /dev/null @@ -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[] getTemplateIdArgLists() { - return null; - } - public IToken getToken(int index) { - if( index == 0 ) return fToken; - return null; - } - public Iterator iterator() { - return new Iterator() { - 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> 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[] f1 = firstDuple.getTemplateIdArgLists(); - List[] 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); - } -}