Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Schorn2008-06-18 12:16:19 +0000
committerMarkus Schorn2008-06-18 12:16:19 +0000
commit4e28c73769692c39804c16e81453fcd46ec7c18e (patch)
tree4f4c724501aa142a156fb1c009f5eaf2abf36179 /core/org.eclipse.cdt.core/parser/org
parent03a4e6e5aa6662a006eb8f0293a5dcd8b411ef6b (diff)
downloadorg.eclipse.cdt-4e28c73769692c39804c16e81453fcd46ec7c18e.tar.gz
org.eclipse.cdt-4e28c73769692c39804c16e81453fcd46ec7c18e.tar.xz
org.eclipse.cdt-4e28c73769692c39804c16e81453fcd46ec7c18e.zip
Fixes parsing of declarations and new expressions, bug 84242+236856.
Diffstat (limited to 'core/org.eclipse.cdt.core/parser/org')
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTNewExpression.java24
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java380
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/DeclarationOptions.java60
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTAmbiguousDeclarator.java33
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTAmbiguousParameterDeclaration.java33
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTAmbiguousDeclarator.java95
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTAmbiguousParameterDeclaration.java71
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTArrayModifier.java3
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTDeclarator.java11
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFieldDeclarator.java17
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFunctionDeclarator.java22
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTName.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTParameterDeclaration.java19
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CBasicType.java10
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java52
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java1220
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousDeclarator.java95
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeclarator.java27
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java68
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTParameterDeclaration.java15
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java7
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java2286
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java51
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriter.java13
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriterVisitor.java10
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclaratorWriter.java16
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ExpressionWriter.java17
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java56
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java12
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTExpressionWriter.java12
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java3
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/BasicTokenDuple.java3
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/TemplateTokenDuple.java1
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java4
36 files changed, 2611 insertions, 2147 deletions
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTNewExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTNewExpression.java
index 7469235e9f2..c560b0eec3f 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTNewExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTNewExpression.java
@@ -1,12 +1,13 @@
/*******************************************************************************
- * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * Copyright (c) 2004, 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
+ * IBM - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
@@ -81,8 +82,7 @@ public interface ICPPASTNewExpression extends IASTExpression {
public static final ASTNodeProperty TYPE_ID = new ASTNodeProperty("ICPPASTNewExpression.TYPE_ID - The type being 'newed'"); //$NON-NLS-1$
/**
- * Get the type Id.
- *
+ * Get the type Id. The type-id includes the optional array modifications.
* @return <code>IASTTypeId</code>
*/
public IASTTypeId getTypeId();
@@ -96,9 +96,8 @@ public interface ICPPASTNewExpression extends IASTExpression {
public void setTypeId(IASTTypeId typeId);
/**
- * Is the typeID a new type ID?
- *
- * @return boolean
+ * Returns whether the the typeID a new type ID, which is the case when
+ * the type-id is provided without parenthesis.
*/
public boolean isNewTypeId();
@@ -117,18 +116,15 @@ public interface ICPPASTNewExpression extends IASTExpression {
"ICPPASTNewExpression.NEW_TYPEID_ARRAY_EXPRESSION - Expressions inside array brackets"); //$NON-NLS-1$
/**
- * Get the new array size expressions.
- *
- * @return <code>IASTExpression []</code>
+ * @deprecated the id-expressions are part of the type-id.
*/
+ @Deprecated
public IASTExpression[] getNewTypeIdArrayExpressions();
/**
- * Add another array size expression.
- *
- * @param expression
- * <code>IASTExpression</code>
+ * @deprecated the id-expressions are part of the type-id
*/
+ @Deprecated
public void addNewTypeIdArrayExpression(IASTExpression expression);
}
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 245d4988339..377ad230f3a 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
@@ -37,6 +37,7 @@ import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
+import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
@@ -78,8 +79,7 @@ import org.eclipse.cdt.core.parser.ParserMode;
* @author jcamelon
*/
public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
-
- protected final AbstractParserLogService log;
+ protected final AbstractParserLogService log;
protected final IScanner scanner;
protected final ParserMode mode;
@@ -192,6 +192,12 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
ASTNode node = (ASTNode) n;
return node.getOffset() + node.getLength();
}
+
+ protected void adjustLength(IASTNode n, IASTNode endNode) {
+ final int endOffset= calculateEndOffset(endNode);
+ final ASTNode node = (ASTNode) n;
+ node.setLength(endOffset-node.getOffset());
+ }
/**
* Consume the next token available, regardless of the type.
@@ -201,13 +207,12 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
* If there is no token to consume.
*/
protected IToken consume() throws EndOfFileException {
-
- if (currToken == null)
+ if (currToken == null) {
currToken = fetchToken();
- IToken lastToken = null;
- if (currToken != null)
- lastToken = currToken;
- currToken = currToken.getNext();
+ }
+
+ final IToken lastToken = currToken;
+ currToken= lastToken.getNext();
return lastToken;
}
@@ -220,13 +225,33 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
* @throws BacktrackException
* If LT(1) != type
*/
- protected IToken consume(int type) throws EndOfFileException,
- BacktrackException {
- if (LT(1) == type)
- return consume();
- IToken la = LA(1);
- throwBacktrack(la.getOffset(), la.getLength());
- return null;
+ protected IToken consume(int type) throws EndOfFileException, BacktrackException {
+ final IToken la1= LA(1);
+ if (la1.getType() != type)
+ throwBacktrack(la1);
+
+ return consume();
+ }
+
+ /**
+ * Consume the next token available only if the type is as specified. In case we
+ * reached the end of completion, no token is consumed and the eoc-token returned.
+ *
+ * @param type
+ * The type of token that you are expecting.
+ * @return the token that was consumed and removed from our buffer.
+ * @throws BacktrackException
+ * If LT(1) != type
+ */
+ protected IToken consumeOrEOC(int type) throws EndOfFileException, BacktrackException {
+ final IToken la1= LA(1);
+ final int lt1 = la1.getType();
+ if (lt1 != type) {
+ if (lt1 == IToken.tEOC)
+ return la1;
+ throwBacktrack(la1);
+ }
+ return consume();
}
/**
@@ -560,6 +585,16 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected abstract IGNUASTCompoundStatementExpression createCompoundStatementExpression();
+ protected IASTExpression possiblyEmptyExpressionList(int endToken) throws BacktrackException, EndOfFileException {
+ IToken la1= LA(1);
+ if (la1.getType() == endToken) {
+ IASTExpressionList expressionList = createExpressionList();
+ ((ASTNode) expressionList).setOffsetAndLength(la1.getOffset(), 0);
+ return expressionList;
+ }
+ return expression();
+ }
+
protected IASTExpression expression() throws BacktrackException, EndOfFileException {
IToken la = LA(1);
int startingOffset = la.getOffset();
@@ -593,14 +628,11 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected abstract IASTExpression multiplicativeExpression()
throws BacktrackException, EndOfFileException;
- protected abstract IASTTypeId typeId(boolean forNewExpression)
- throws EndOfFileException;
+ protected abstract IASTTypeId typeId(DeclarationOptions option) throws EndOfFileException;
- protected abstract IASTExpression castExpression()
- throws BacktrackException, EndOfFileException;
+ protected abstract IASTExpression castExpression() throws BacktrackException, EndOfFileException;
- protected abstract IASTExpression unaryExpression()
- throws BacktrackException, EndOfFileException;
+ protected abstract IASTExpression unaryExpression() throws BacktrackException, EndOfFileException;
protected abstract IASTExpression buildTypeIdExpression(int op,
IASTTypeId typeId, int startingOffset, int endingOffset);
@@ -818,7 +850,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
boolean needBack = false;
try {
consume();
- d = typeId(false);
+ d = typeId(DeclarationOptions.TYPEID);
if (d == null)
needBack = true;
else
@@ -862,7 +894,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
}
catch (BacktrackException e) {
backup(m);
- d = typeId(false);
+ d = typeId(DeclarationOptions.TYPEID);
if (d == null)
throw e;
}
@@ -874,14 +906,10 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
if (d != null)
return buildTypeIdExpression(IGNUASTTypeIdExpression.op_typeof, d, offset, lastOffset);
- if (expression != null)
- return buildUnaryExpression(IGNUASTUnaryExpression.op_typeof, expression, offset, lastOffset);
-
- return null;
+ return buildUnaryExpression(IGNUASTUnaryExpression.op_typeof, expression, offset, lastOffset);
}
- protected IASTStatement handleFunctionBody() throws BacktrackException,
- EndOfFileException {
+ protected IASTStatement handleFunctionBody() throws BacktrackException, EndOfFileException {
if (mode == ParserMode.QUICK_PARSE || mode == ParserMode.STRUCTURAL_PARSE) {
IToken curr = LA(1);
IToken last = skipOverCompoundStatement();
@@ -896,9 +924,10 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
IASTCompoundStatement cs = createCompoundStatement();
((ASTNode) cs).setOffsetAndLength(curr.getOffset(), last.getEndOffset() - curr.getOffset());
return cs;
- } else if (mode == ParserMode.COMPLETE_PARSE)
- return functionBody();
- return null;
+ }
+
+ // full parse
+ return functionBody();
}
/**
@@ -912,184 +941,50 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return compoundStatement();
}
- protected abstract IASTDeclarator initDeclarator()
- throws EndOfFileException, BacktrackException;
+ protected abstract IASTDeclarator initDeclarator(DeclarationOptions option) throws EndOfFileException, BacktrackException;
/**
- * @param flags input flags that are used to make our decision
+ * @param option the options with which to parse the declaration
* @throws FoundDeclaratorException encountered EOF while looking ahead
*/
- protected void lookAheadForDeclarator(Flags flags) throws FoundDeclaratorException {
- if (flags.typeId)
- return;
+ protected void lookAheadForDeclarator(final DeclarationOptions option) throws FoundDeclaratorException {
IToken mark = null;
try {
mark = mark();
- } catch (EndOfFileException eof) {
- return;
- }
- try
- {
- if( LT(1) == IToken.tIDENTIFIER && LT(2) == IToken.tIDENTIFIER )
- return;
- }
- catch( EndOfFileException eof )
- {
- backup( mark );
- return;
- }
- try {
- IASTDeclarator d = initDeclarator();
- IToken la = LA(1);
- backup(mark);
- if (la == null || la.getType() == IToken.tEOC)
- return;
- final ASTNode n = ((ASTNode) d);
- final int length = n.getLength();
- final int offset = n.getOffset();
- if (length == 0)
- return;
- if (flags.parm) {
- ASTNode name = (ASTNode) d.getName();
- if (name.getOffset() == offset) {
- // fix for bugs 147903 and 179493
- // https://bugs.eclipse.org/bugs/show_bug.cgi?id=147903
- // https://bugs.eclipse.org/bugs/show_bug.cgi?id=179493
- if (name.getLength() == length || d instanceof IASTArrayDeclarator) {
- return;
- }
- }
- if (d.getInitializer() != null) {
- ASTNode init = (ASTNode) d.getInitializer();
- if (name.getOffset() == offset
- && n.getOffset() + n.getLength() == init
- .getOffset()
- + init.getLength())
- return;
- }
+ final IASTDeclarator dtor= initDeclarator(option);
+ final IToken la = LA(1);
+ if (la == null || la == mark)
+ return;
- switch (la.getType()) {
- case IToken.tCOMMA:
- case IToken.tRPAREN:
- throw new FoundDeclaratorException( d, la );
- default:
- return;
- }
- }
-
- checkTokenVsDeclarator(la, d);
- return;
+ if (verifyLookaheadDeclarator(option, dtor, la))
+ throw new FoundDeclaratorException(dtor, la);
} catch (BacktrackException bte) {
- backup(mark);
- return;
} catch (EndOfFileException e) {
- backup(mark);
- return;
+ } finally {
+ if (mark != null)
+ backup(mark);
}
}
- protected void checkTokenVsDeclarator(IToken la, IASTDeclarator d) throws FoundDeclaratorException {
- switch (la.getType()) {
- case IToken.tCOMMA:
- case IToken.tLBRACE:
- throw new FoundDeclaratorException( d, la );
- case IToken.tSEMI:
- if (d instanceof IASTFieldDeclarator)
- return;
- throw new FoundDeclaratorException( d, la );
- default:
- return;
- }
- }
+ protected abstract boolean verifyLookaheadDeclarator(DeclarationOptions option, IASTDeclarator d, IToken nextToken);
- public static class FoundDeclaratorException extends Exception
- {
+ public static class FoundDeclaratorException extends Exception {
private static final long serialVersionUID = 0;
- public final IASTDeclarator declarator;
- public final IToken currToken;
public IASTDeclSpecifier declSpec;
+ public IASTDeclarator declarator;
+
+ public IASTDeclSpecifier altSpec;
+ public IASTDeclarator altDeclarator;
- public FoundDeclaratorException( IASTDeclarator d, IToken t )
- {
+ public IToken currToken;
+
+ public FoundDeclaratorException(IASTDeclarator d, IToken t) {
this.declarator = d;
this.currToken =t;
}
}
- public static class Flags {
- private boolean encounteredTypename = false;
-
- // have we encountered a typeName yet?
- private boolean encounteredRawType = false;
-
- // have we encountered a raw type yet?
- boolean parm = false;
-
- // is this for a simpleDeclaration or parameterDeclaration?
- boolean constructor = false;
-
- boolean typeId = false;
-
- // are we attempting the constructor strategy?
- public Flags(boolean parm, boolean c, boolean t) {
- this.parm = parm;
- constructor = c;
- typeId = t;
- }
-
- public Flags(boolean parm, boolean typeId) {
- this(parm, false, typeId);
- }
-
- /**
- * @return true if we have encountered a simple type up to this point,
- * false otherwise
- */
- public boolean haveEncounteredRawType() {
- return encounteredRawType;
- }
-
- /**
- * @return true if we have encountered a typename up to this point,
- * false otherwise
- */
- public boolean haveEncounteredTypename() {
- return encounteredTypename;
- }
-
- /**
- * @param b -
- * set to true if we encounter a raw type (int, short, etc.)
- */
- public void setEncounteredRawType(boolean b) {
- encounteredRawType = b;
- }
-
- /**
- * @param b -
- * set to true if we encounter a typename
- */
- public void setEncounteredTypename(boolean b) {
- encounteredTypename = b;
- }
-
- /**
- * @return true if we are parsing for a ParameterDeclaration
- */
- public boolean isForParameterDeclaration() {
- return parm;
- }
-
- /**
- * @return whether or not we are attempting the constructor strategy or
- * not
- */
- public boolean isForConstructor() {
- return constructor;
- }
- }
-
/**
* Parse an enumeration specifier, as according to the ANSI specs in C &
* C++. enumSpecifier: "enum" (name)? "{" (enumerator-list) "}"
@@ -1246,8 +1141,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected abstract IASTCaseStatement createCaseStatement();
- protected abstract IASTDeclaration declaration() throws BacktrackException,
- EndOfFileException;
+ protected abstract IASTDeclaration declaration(DeclarationOptions option) throws BacktrackException, EndOfFileException;
protected IASTDeclaration asmDeclaration() throws EndOfFileException,
@@ -1330,7 +1224,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
* This method will attempt to parse a statement as both an expression and a declaration,
* if both parses succeed then an ambiguity node is returned.
*/
- protected IASTStatement parseDeclarationOrExpressionStatement() throws EndOfFileException, BacktrackException {
+ protected IASTStatement parseDeclarationOrExpressionStatement(DeclarationOptions option) throws EndOfFileException, BacktrackException {
// First attempt to parse an expressionStatement
// Note: the function style cast ambiguity is handled in expression
// Since it only happens when we are in a statement
@@ -1354,7 +1248,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
// Now attempt to parse a declarationStatement
IASTDeclarationStatement ds = null;
try {
- IASTDeclaration d = declaration();
+ IASTDeclaration d = declaration(option);
ds = createDeclarationStatement();
ds.setDeclaration(d);
((ASTNode) ds).setOffsetAndLength(((ASTNode) d).getOffset(), ((ASTNode) d).getLength());
@@ -1369,10 +1263,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return ds;
}
if (ds == null) {
- while (true) {
- if (consume() == lastTokenOfExpression)
- break;
- }
+ backup(lastTokenOfExpression); consume();
return expressionStatement;
}
@@ -1396,61 +1287,49 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
}
}
- // x = y; // implicit int
- // valid at Translation Unit scope but not valid as a statement in a function body
- if(isImplicitInt(ds.getDeclaration())) {
- backup(mark);
- while (true) {
- if (consume() == lastTokenOfExpression)
- break;
- }
-
- return expressionStatement;
- }
-
- // generalization of the previous check for implicit int
- if (ds.getDeclaration() instanceof IASTAmbiguousDeclaration ) {
- IASTAmbiguousDeclaration amb = (IASTAmbiguousDeclaration) ds.getDeclaration();
- boolean allImplicitInt = true;
- for(IASTDeclaration ambD : amb.getDeclarations()) {
- if(!isImplicitInt(ambD)) {
- allImplicitInt = false;
- break;
- }
- }
- if(allImplicitInt) {
- backup(mark);
- while (true) {
- if (consume() == lastTokenOfExpression)
- break;
- }
- return expressionStatement;
- }
- }
-
- // x;
- // a single identifier can be parsed as a named declaration specifier without a declarator
- if(ds.getDeclaration() instanceof IASTSimpleDeclaration &&
- ((IASTSimpleDeclaration) ds.getDeclaration()).getDeclSpecifier() instanceof IASTNamedTypeSpecifier) {
- final IASTDeclarator[] declarators = ((IASTSimpleDeclaration) ds.getDeclaration()).getDeclarators();
- if (declarators.length == 0
- || (declarators.length == 1 && (declarators[0].getName()
- .toCharArray().length == 0 && declarators[0]
- .getNestedDeclarator() == null))) {
- backup(mark);
- while (true) {
- if (consume() == lastTokenOfExpression)
- break;
- }
-
- return expressionStatement;
- }
- }
+ final IASTDeclaration declaration = ds.getDeclaration();
+ if (declaration instanceof IASTSimpleDeclaration) {
+ final IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) declaration;
+ IASTDeclSpecifier declspec= simpleDecl.getDeclSpecifier();
+ if (declspec instanceof IASTNamedTypeSpecifier) {
+ final IASTDeclarator[] declarators = simpleDecl.getDeclarators();
+
+ // x;
+ // can be parsed as a named declaration specifier without a declarator
+ if (declarators.length == 0) {
+ backup(lastTokenOfExpression); consume();
+ return expressionStatement;
+ }
+
+ // a function call interpreted as declaration: 'func(x);' --> 'func x;'
+ if (declarators.length == 1) {
+ IASTName name= ((IASTNamedTypeSpecifier) declspec).getName();
+ final IASTDeclarator dtor= declarators[0];
+ if (name.contains(declspec)) {
+ if (dtor.getNestedDeclarator() != null) {
+ if (dtor instanceof IASTAmbiguousDeclarator == false
+ && dtor instanceof IASTArrayDeclarator == false
+ && dtor instanceof IASTFieldDeclarator == false
+ && dtor instanceof IASTFunctionDeclarator == false) {
+ backup(lastTokenOfExpression); consume();
+ return expressionStatement;
+ }
+ }
+ }
+
+ if (dtor.getName().toCharArray().length == 0 && dtor.getNestedDeclarator() == null) {
+ throw new Error();
+// backup(lastTokenOfExpression); consume();
+// return expressionStatement;
+ }
+ }
+ }
+ }
// create and return ambiguity node
IASTAmbiguousStatement statement = createAmbiguousStatement();
- statement.addStatement(ds);
statement.addStatement(expressionStatement);
+ statement.addStatement(ds);
((ASTNode) statement).setOffsetAndLength((ASTNode) ds);
return statement;
}
@@ -1746,7 +1625,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
try {
if (typeIdWithParentheses)
consume(IToken.tLPAREN);
- typeId = typeId(false);
+ typeId = typeId(DeclarationOptions.TYPEID);
if (typeId != null) {
if (typeIdWithParentheses) {
switch (LT(1)) {
@@ -1827,16 +1706,13 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return null;
}
- protected abstract IASTDeclaration simpleDeclaration() throws BacktrackException,
- EndOfFileException;
-
/**
* @throws BacktrackException
*/
- protected IASTStatement forInitStatement() throws BacktrackException, EndOfFileException {
+ protected IASTStatement forInitStatement(DeclarationOptions option) throws BacktrackException, EndOfFileException {
if( LT(1) == IToken.tSEMI )
return parseNullStatement();
- return parseDeclarationOrExpressionStatement();
+ return parseDeclarationOrExpressionStatement(option);
}
/**
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/DeclarationOptions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/DeclarationOptions.java
new file mode 100644
index 00000000000..9fab6865c7f
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/DeclarationOptions.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.dom.parser;
+
+/**
+ * Configures the parsing of a declaration in various contexts.
+ * @since 5.0
+ */
+public class DeclarationOptions {
+ final public static int ALLOW_EMPTY_SPECIFIER= 0x01;
+ final public static int ALLOW_ABSTRACT= 0x02;
+ final public static int REQUIRE_ABSTRACT= 0x04;
+ final public static int ALLOW_BITFIELD= 0x08;
+ final public static int NO_INITIALIZER= 0x10;
+ final public static int ALLOW_CONSTRUCTOR_INITIALIZER= 0x20;
+ final public static int NO_FUNCTIONS= 0x40;
+ final public static int NO_ARRAYS= 0x80;
+ final public static int NO_NESTED= 0x100;
+
+ public static final DeclarationOptions
+ GLOBAL= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | ALLOW_CONSTRUCTOR_INITIALIZER),
+ C_MEMBER= new DeclarationOptions(ALLOW_BITFIELD),
+ CPP_MEMBER= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | ALLOW_BITFIELD | ALLOW_CONSTRUCTOR_INITIALIZER),
+ LOCAL= new DeclarationOptions(ALLOW_CONSTRUCTOR_INITIALIZER),
+ PARAMETER= new DeclarationOptions(ALLOW_ABSTRACT),
+ TYPEID= new DeclarationOptions(REQUIRE_ABSTRACT | NO_INITIALIZER),
+ TYPEID_NEW= new DeclarationOptions(REQUIRE_ABSTRACT | NO_INITIALIZER | NO_FUNCTIONS | NO_NESTED),
+ TYPEID_CONVERSION= new DeclarationOptions(REQUIRE_ABSTRACT | NO_INITIALIZER | NO_FUNCTIONS | NO_NESTED),
+ EXCEPTION= new DeclarationOptions(ALLOW_ABSTRACT | NO_INITIALIZER),
+ CONDITION= new DeclarationOptions(ALLOW_CONSTRUCTOR_INITIALIZER),
+ C_PARAMETER_NON_ABSTRACT= new DeclarationOptions(ALLOW_ABSTRACT | ALLOW_EMPTY_SPECIFIER);
+
+ final public boolean fAllowEmptySpecifier;
+ final public boolean fAllowAbstract;
+ final public boolean fRequireAbstract;
+ final public boolean fAllowBitField;
+ final public boolean fAllowInitializer;
+ final public boolean fAllowConstructorInitializer;
+ final public boolean fAllowFunctions;
+ final public boolean fAllowNested;
+
+ public DeclarationOptions(int options) {
+ fAllowEmptySpecifier= (options & ALLOW_EMPTY_SPECIFIER) != 0;
+ fRequireAbstract= (options & REQUIRE_ABSTRACT) != 0;
+ fAllowAbstract= fRequireAbstract || (options & ALLOW_ABSTRACT) != 0;
+ fAllowBitField= (options & ALLOW_BITFIELD) != 0;
+ fAllowInitializer= (options & NO_INITIALIZER) == 0;
+ fAllowConstructorInitializer= fAllowInitializer && (options & ALLOW_CONSTRUCTOR_INITIALIZER) != 0;
+ fAllowFunctions= (options & NO_FUNCTIONS) == 0;
+ fAllowNested= (options & NO_NESTED) == 0;
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTAmbiguousDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTAmbiguousDeclarator.java
new file mode 100644
index 00000000000..fa6f9cb031c
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTAmbiguousDeclarator.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Schorn - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.dom.parser;
+
+import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
+import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
+
+/**
+ * Needed to handle the ambiguous declarator.
+ * @since 5.0
+ */
+public interface IASTAmbiguousDeclarator extends IASTDeclarator {
+
+ public static final ASTNodeProperty SUBDECLARATOR = new ASTNodeProperty( "IASTAmbiguousDeclarator.SUBDECLARATOR"); //$NON-NLS-1$
+
+ /**
+ * Add an alternative to this ambiguous declarator.
+ */
+ public void addDeclarator(IASTDeclarator e);
+
+ /**
+ * Return an array of all alternatives for this ambiguous declarator.
+ */
+ public IASTDeclarator[] getDeclarators();
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTAmbiguousParameterDeclaration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTAmbiguousParameterDeclaration.java
new file mode 100644
index 00000000000..5b012f729a1
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTAmbiguousParameterDeclaration.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Schorn - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.dom.parser;
+
+import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
+import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
+
+/**
+ * Needed to handle the ambiguity for parameter declarations in plain C
+ * @since 5.0
+ */
+public interface IASTAmbiguousParameterDeclaration extends IASTParameterDeclaration {
+
+ public static final ASTNodeProperty SUBDECLARATION = new ASTNodeProperty( "IASTAmbiguousParameterDeclaration.SUBDECLARATION"); //$NON-NLS-1$
+
+ /**
+ * Add an alternative to this ambiguous parameter declaration.
+ */
+ public void addParameterDeclaration(IASTParameterDeclaration e);
+
+ /**
+ * Return an array of all alternatives for this ambiguous parameter declaration.
+ */
+ public IASTParameterDeclaration[] getParameterDeclarations();
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTAmbiguousDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTAmbiguousDeclarator.java
new file mode 100644
index 00000000000..3d5372d5242
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTAmbiguousDeclarator.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Schorn - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.dom.parser.c;
+
+import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTInitializer;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
+import org.eclipse.cdt.core.parser.util.ArrayUtil;
+import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclarator;
+import org.eclipse.core.runtime.Assert;
+
+/**
+ * Handles ambiguities when parsing declarators.
+ * <br>
+ * Example: void f(int (D)); // is D a type?
+ * @since 5.0.1
+ */
+public class CASTAmbiguousDeclarator extends CASTAmbiguity implements IASTAmbiguousDeclarator {
+
+ private IASTDeclarator[] dtors = new IASTDeclarator[2];
+ private int dtorPos=-1;
+
+
+ public CASTAmbiguousDeclarator(IASTDeclarator... decls) {
+ for(IASTDeclarator d : decls) {
+ if (d != null) {
+ addDeclarator(d);
+ }
+ }
+ }
+
+ public void addDeclarator(IASTDeclarator d) {
+ if (d != null) {
+ dtors = (IASTDeclarator[]) ArrayUtil.append(IASTDeclarator.class, dtors, ++dtorPos, d);
+ d.setParent(this);
+ d.setPropertyInParent(SUBDECLARATOR);
+ }
+ }
+
+ public IASTDeclarator[] getDeclarators() {
+ dtors = (IASTDeclarator[]) ArrayUtil.removeNullsAfter(IASTDeclarator.class, dtors, dtorPos );
+ return dtors;
+ }
+
+ @Override
+ protected IASTNode[] getNodes() {
+ return getDeclarators();
+ }
+
+ public IASTInitializer getInitializer() {
+ return dtors[0].getInitializer();
+ }
+
+ public IASTName getName() {
+ return dtors[0].getName();
+ }
+
+ public IASTDeclarator getNestedDeclarator() {
+ return dtors[0].getNestedDeclarator();
+ }
+
+ public IASTPointerOperator[] getPointerOperators() {
+ return dtors[0].getPointerOperators();
+ }
+
+ public int getRoleForName(IASTName name) {
+ return dtors[0].getRoleForName(name);
+ }
+
+ public void addPointerOperator(IASTPointerOperator operator) {
+ Assert.isLegal(false);
+ }
+
+ public void setInitializer(IASTInitializer initializer) {
+ Assert.isLegal(false);
+ }
+
+ public void setName(IASTName name) {
+ Assert.isLegal(false);
+ }
+
+ public void setNestedDeclarator(IASTDeclarator nested) {
+ Assert.isLegal(false);
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTAmbiguousParameterDeclaration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTAmbiguousParameterDeclaration.java
new file mode 100644
index 00000000000..3dcc41174a7
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTAmbiguousParameterDeclaration.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Schorn - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.dom.parser.c;
+
+import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
+import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
+import org.eclipse.cdt.core.parser.util.ArrayUtil;
+import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousParameterDeclaration;
+import org.eclipse.core.runtime.Assert;
+
+/**
+ * Handles ambiguities for parameter declarations.
+ * <br>
+ * void function(const D*); // is D a type?
+ * @since 5.0.1
+ */
+public class CASTAmbiguousParameterDeclaration extends CASTAmbiguity implements IASTAmbiguousParameterDeclaration {
+
+ private IASTParameterDeclaration[] paramDecls = new IASTParameterDeclaration[2];
+ private int declPos=-1;
+
+
+ public CASTAmbiguousParameterDeclaration(IASTParameterDeclaration... decls) {
+ for(IASTParameterDeclaration d : decls)
+ addParameterDeclaration(d);
+ }
+
+ public void addParameterDeclaration(IASTParameterDeclaration d) {
+ if (d != null) {
+ paramDecls = (IASTParameterDeclaration[]) ArrayUtil.append(IASTParameterDeclaration.class, paramDecls, ++declPos, d);
+ d.setParent(this);
+ d.setPropertyInParent(SUBDECLARATION);
+ }
+ }
+
+ public IASTParameterDeclaration[] getParameterDeclarations() {
+ paramDecls = (IASTParameterDeclaration[]) ArrayUtil.removeNullsAfter(IASTParameterDeclaration.class, paramDecls, declPos );
+ return paramDecls;
+ }
+
+ @Override
+ protected IASTNode[] getNodes() {
+ return getParameterDeclarations();
+ }
+
+ public IASTDeclSpecifier getDeclSpecifier() {
+ return paramDecls[0].getDeclSpecifier();
+ }
+
+ public IASTDeclarator getDeclarator() {
+ return paramDecls[0].getDeclarator();
+ }
+
+ public void setDeclSpecifier(IASTDeclSpecifier declSpec) {
+ Assert.isLegal(false);
+ }
+
+ public void setDeclarator(IASTDeclarator declarator) {
+ Assert.isLegal(false);
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTArrayModifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTArrayModifier.java
index 32c759ef228..ee75a39facd 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTArrayModifier.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTArrayModifier.java
@@ -6,7 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * IBM Rational Software - Initial API and implementation
+ * IBM Rational Software - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTDeclarator.java
index f04b93afba6..a273c7865f0 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTDeclarator.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTDeclarator.java
@@ -26,11 +26,12 @@ import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
+import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
/**
* @author jcamelon
*/
-public class CASTDeclarator extends CASTNode implements IASTDeclarator {
+public class CASTDeclarator extends CASTNode implements IASTDeclarator, IASTAmbiguityParent {
private IASTInitializer initializer;
private IASTName name;
@@ -207,4 +208,12 @@ public class CASTDeclarator extends CASTNode implements IASTDeclarator {
}
return r_unclear;
}
+
+ public void replace(IASTNode child, IASTNode other) {
+ if (child == nestedDeclarator) {
+ other.setPropertyInParent(child.getPropertyInParent());
+ other.setParent(child.getParent());
+ nestedDeclarator= (IASTDeclarator) other;
+ }
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFieldDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFieldDeclarator.java
index e66b9dbf107..3fbb0dce880 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFieldDeclarator.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFieldDeclarator.java
@@ -6,7 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * IBM Rational Software - Initial API and implementation
+ * IBM Rational Software - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
@@ -16,17 +17,13 @@ import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
-import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
/**
* @author jcamelon
*/
-public class CASTFieldDeclarator extends CASTDeclarator implements
- IASTFieldDeclarator, IASTAmbiguityParent {
-
+public class CASTFieldDeclarator extends CASTDeclarator implements IASTFieldDeclarator {
private IASTExpression bitFieldSize;
-
public CASTFieldDeclarator() {
}
@@ -57,12 +54,14 @@ public class CASTFieldDeclarator extends CASTDeclarator implements
return true;
}
- public void replace(IASTNode child, IASTNode other) {
- if( child == bitFieldSize)
- {
+ @Override
+ public void replace(IASTNode child, IASTNode other) {
+ if( child == bitFieldSize) {
other.setPropertyInParent( child.getPropertyInParent() );
other.setParent( child.getParent() );
bitFieldSize = (IASTExpression) other;
+ } else {
+ super.replace(child, other);
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFunctionDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFunctionDeclarator.java
index b223d3b402f..7168b812af8 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFunctionDeclarator.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFunctionDeclarator.java
@@ -6,13 +6,14 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * IBM Rational Software - Initial API and implementation
- * Markus Schorn (Wind River Systems)
+ * IBM Rational Software - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
@@ -26,8 +27,6 @@ public class CASTFunctionDeclarator extends CASTDeclarator implements IASTStanda
private int parametersPos=-1;
private boolean varArgs;
-
-
public CASTFunctionDeclarator() {
}
@@ -65,4 +64,19 @@ public class CASTFunctionDeclarator extends CASTDeclarator implements IASTStanda
}
return true;
}
+
+ @Override
+ public void replace(IASTNode child, IASTNode other) {
+ if( parameters != null ) {
+ for (int i = 0; i < parameters.length; ++i) {
+ if (child == parameters[i]) {
+ other.setPropertyInParent(child.getPropertyInParent());
+ other.setParent(child.getParent());
+ parameters[i]= (IASTParameterDeclaration) other;
+ return;
+ }
+ }
+ }
+ super.replace(child, other);
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTName.java
index d4721e269a0..4e4f5b59157 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTName.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTName.java
@@ -223,4 +223,8 @@ public class CASTName extends CASTNode implements IASTName, IASTCompletionContex
}
return (IBinding[])ArrayUtil.removeNulls(IBinding.class, bindings);
}
+
+ public IASTName getLastName() {
+ return this;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTParameterDeclaration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTParameterDeclaration.java
index ba30d158900..217ca9834b5 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTParameterDeclaration.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTParameterDeclaration.java
@@ -6,22 +6,23 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * IBM Rational Software - Initial API and implementation
- * Yuan Zhang / Beth Tibbitts (IBM Research)
+ * IBM Rational Software - Initial API and implementation
+ * Yuan Zhang / Beth Tibbitts (IBM Research)
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
+import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
/**
* @author jcamelon
*/
-public class CASTParameterDeclaration extends CASTNode implements
- IASTParameterDeclaration {
-
+public class CASTParameterDeclaration extends CASTNode implements IASTParameterDeclaration, IASTAmbiguityParent {
private IASTDeclSpecifier declSpec;
private IASTDeclarator declarator;
@@ -79,4 +80,12 @@ public class CASTParameterDeclaration extends CASTNode implements
}
return true;
}
+
+ public void replace(IASTNode child, IASTNode other) {
+ if (child == declarator) {
+ other.setPropertyInParent(child.getPropertyInParent());
+ other.setParent(child.getParent());
+ declarator= (IASTDeclarator) other;
+ }
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CBasicType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CBasicType.java
index c1ca4f79654..11cfab8cf62 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CBasicType.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CBasicType.java
@@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * IBM Rational Software - Initial API and implementation
- * Markus Schorn (Wind River Systems)
+ * IBM Rational Software - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
@@ -53,8 +53,9 @@ public class CBasicType implements ICBasicType {
if( type == IBasicType.t_unspecified ){
if( (qualifiers & ( IS_COMPLEX | IS_IMAGINARY )) != 0 )
type = IBasicType.t_float;
- else if( (qualifiers & ~( IS_COMPLEX | IS_IMAGINARY )) != 0 )
+ else {
type = IBasicType.t_int;
+ }
}
}
@@ -65,8 +66,9 @@ public class CBasicType implements ICBasicType {
if( type == IBasicType.t_unspecified ){
if( (qualifiers & ( IS_COMPLEX | IS_IMAGINARY )) != 0 )
type = IBasicType.t_float;
- else if( (qualifiers & ~( IS_COMPLEX | IS_IMAGINARY )) != 0 )
+ else {
type = IBasicType.t_int;
+ }
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java
index 5901eb7bc2c..2088f0bdc60 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java
@@ -36,6 +36,7 @@ import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
+import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
@@ -2156,4 +2157,55 @@ public class CVisitor {
return true;
}
+
+
+ /**
+ * Returns the innermost declarator nested within the given <code>declarator</code>, or
+ * <code>declarator</code> itself.
+ * @since 5.0
+ */
+ public static IASTDeclarator findInnermostDeclarator(IASTDeclarator declarator) {
+ IASTDeclarator innermost= null;
+ while(declarator != null) {
+ innermost= declarator;
+ declarator= declarator.getNestedDeclarator();
+ }
+ return innermost;
+ }
+
+ /**
+ * Returns the outermost declarator the given <code>declarator</code> nests within, or
+ * <code>declarator</code> itself.
+ * @since 5.0
+ */
+ public static IASTDeclarator findOutermostDeclarator(IASTDeclarator declarator) {
+ while(true) {
+ IASTNode parent= declarator.getParent();
+ if (parent instanceof IASTDeclarator) {
+ declarator= (IASTDeclarator) parent;
+ } else {
+ return declarator;
+ }
+ }
+ }
+
+ /**
+ * Searches for the innermost declarator that contributes the the type declared.
+ * @since 5.0
+ */
+ public static IASTDeclarator findTypeRelevantDeclarator(IASTDeclarator declarator) {
+ IASTDeclarator result= findInnermostDeclarator(declarator);
+ while (result.getPointerOperators().length == 0
+ && result instanceof IASTFieldDeclarator == false
+ && result instanceof IASTFunctionDeclarator == false
+ && result instanceof IASTArrayModifier == false) {
+ final IASTNode parent= result.getParent();
+ if (parent instanceof IASTDeclarator) {
+ result= (IASTDeclarator) parent;
+ } else {
+ return result;
+ }
+ }
+ return result;
+ }
}
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 af6e7ab22fb..ac1676681e8 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
@@ -110,26 +110,24 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser;
import org.eclipse.cdt.internal.core.dom.parser.BacktrackException;
+import org.eclipse.cdt.internal.core.dom.parser.DeclarationOptions;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousStatement;
/**
- * @author jcamelon
+ * Source parser for gnu-c syntax.
*/
public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
-
- private static final ASTVisitor EMPTY_VISITOR = new ASTVisitor() {
- };
+ private static final int DEFAULT_POINTEROPS_LIST_SIZE = 4;
+ private static final int DEFAULT_PARAMETERS_LIST_SIZE = 4;
+ private static final ASTVisitor EMPTY_VISITOR = new ASTVisitor() {};
private final boolean supportGCCStyleDesignators;
-
private IIndex index;
+ protected CASTTranslationUnit translationUnit;
+
+ private int fPreventKnrCheck= 0;
- /**
- * @param scanner
- * @param parserMode
- * @param logService
- */
public GNUCSourceParser(IScanner scanner, ParserMode parserMode,
IParserLogService logService, ICParserExtensionConfiguration config) {
this(scanner, parserMode, logService, config, null);
@@ -357,120 +355,100 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
protected ICASTFieldDesignator createFieldDesignator() {
return new CASTFieldDesignator();
}
-
- @Override
- protected IASTDeclaration declaration() throws EndOfFileException,
- BacktrackException {
+
+ @Override
+ protected IASTDeclaration declaration(final DeclarationOptions declOption) throws EndOfFileException, BacktrackException {
switch (LT(1)) {
case IToken.t_asm:
return asmDeclaration();
default:
- IASTDeclaration d = simpleDeclaration();
+ IASTDeclaration d = simpleDeclaration(declOption);
return d;
}
-
}
- /**
- * @throws BacktrackException
- * @throws EndOfFileException
- */
- @Override
- protected IASTDeclaration simpleDeclaration() throws BacktrackException,
- EndOfFileException {
- IToken firstToken = LA(1);
- int firstOffset = firstToken.getOffset();
+ private IASTDeclaration simpleDeclaration(final DeclarationOptions declOption) throws BacktrackException, EndOfFileException {
+ final IToken firstToken = LA(1);
if (firstToken.getType() == IToken.tLBRACE)
- throwBacktrack(firstToken.getOffset(), firstToken.getLength());
-
- firstToken = null; // necessary for scalability
+ throwBacktrack(firstToken);
+
+ final int firstOffset = firstToken.getOffset();
+ int endOffset= firstOffset;
IASTDeclSpecifier declSpec;
- IASTDeclarator [] declarators = new IASTDeclarator[2];
- boolean skipAhead = false;
+ IASTDeclarator dtor= null;
try {
- declSpec = declSpecifierSeq(false, false);
+ declSpec = declSpecifierSeq(declOption);
+ final int lt1= LT(1);
+ if (lt1 != IToken.tSEMI && lt1 != IToken.tEOC) {
+ dtor= initDeclarator(declOption);
+ }
} catch (FoundDeclaratorException e) {
- skipAhead = true;
- declSpec = e.declSpec;
- declarators = (IASTDeclarator[]) ArrayUtil.append( IASTDeclarator.class, declarators, e.declarator );
+ if (e.altSpec != null) {
+ declSpec= e.altSpec;
+ dtor= e.altDeclarator;
+ } else {
+ declSpec = e.declSpec;
+ dtor= e.declarator;
+ }
backup( e.currToken );
}
-
- if (LT(1) != IToken.tSEMI) {
- if( ! skipAhead )
- declarators = (IASTDeclarator[]) ArrayUtil.append( IASTDeclarator.class, declarators, initDeclarator());
-
- while (LT(1) == IToken.tCOMMA) {
- consume();
- declarators = (IASTDeclarator[]) ArrayUtil.append( IASTDeclarator.class, declarators, initDeclarator());
- }
+ IASTDeclarator[] declarators= {dtor};
+ while (LT(1) == IToken.tCOMMA) {
+ consume();
+ declarators= (IASTDeclarator[]) ArrayUtil.append( IASTDeclarator.class, declarators, initDeclarator(declOption));
}
- declarators = (IASTDeclarator[]) ArrayUtil.removeNulls( IASTDeclarator.class, declarators );
-
- boolean hasFunctionBody = false;
- boolean hasFunctionTryBlock = false;
- boolean consumedSemi = false;
- int semiOffset = 0;
+ declarators= (IASTDeclarator[]) ArrayUtil.removeNulls( IASTDeclarator.class, declarators );
switch (LT(1)) {
+ case IToken.tLBRACE:
+ return functionDefinition(firstOffset, declSpec, declarators);
+
case IToken.tSEMI:
- semiOffset = consume().getEndOffset();
- consumedSemi = true;
+ endOffset= consume().getEndOffset();
break;
- case IToken.tLBRACE:
case IToken.tEOC:
+ endOffset= figureEndOffset(declSpec, declarators);
break;
default:
throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset);
}
- if (!consumedSemi) {
- if (LT(1) == IToken.tLBRACE) {
- hasFunctionBody = true;
- }
-
- if (hasFunctionTryBlock && !hasFunctionBody)
- throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset);
- }
-
- if (hasFunctionBody) {
- if (declarators.length != 1)
- throwBacktrack(firstOffset, LA(1).getEndOffset());
-
- IASTDeclarator declarator = declarators[0];
- if (!(declarator instanceof IASTFunctionDeclarator))
- throwBacktrack(firstOffset, LA(1).getEndOffset());
-
- IASTFunctionDefinition funcDefinition = createFunctionDefinition();
- ((ASTNode) funcDefinition).setOffset(firstOffset);
- funcDefinition.setDeclSpecifier(declSpec);
- funcDefinition.setDeclarator((IASTFunctionDeclarator) declarator);
-
- IASTStatement s = handleFunctionBody();
- if (s != null) {
- funcDefinition.setBody(s);
- }
- ((ASTNode) funcDefinition).setLength(calculateEndOffset(s) - firstOffset);
- return funcDefinition;
- }
-
+ // no function body
IASTSimpleDeclaration simpleDeclaration = createSimpleDeclaration();
-
- int length = figureEndOffset(declSpec, declarators) - firstOffset;
- if (consumedSemi)
- length = semiOffset - firstOffset;
- ((ASTNode) simpleDeclaration).setOffsetAndLength(firstOffset, length);
simpleDeclaration.setDeclSpecifier(declSpec);
-
for (int i = 0; i < declarators.length; ++i) {
IASTDeclarator declarator = declarators[i];
simpleDeclaration.addDeclarator(declarator);
}
+
+ ((ASTNode) simpleDeclaration).setOffsetAndLength(firstOffset, endOffset-firstOffset);
return simpleDeclaration;
}
+ private IASTDeclaration functionDefinition(int firstOffset, IASTDeclSpecifier declSpec,
+ IASTDeclarator[] declarators) throws BacktrackException, EndOfFileException {
+ if (declarators.length != 1)
+ throwBacktrack(firstOffset, LA(1).getEndOffset());
+
+// IASTDeclarator declarator= CVisitor.findTypeRelevantDeclarator(declarators[0]); // mstodo
+
+ IASTDeclarator declarator = declarators[0];
+ if (!(declarator instanceof IASTFunctionDeclarator))
+ throwBacktrack(firstOffset, LA(1).getEndOffset());
+
+ IASTFunctionDefinition funcDefinition = createFunctionDefinition();
+ funcDefinition.setDeclSpecifier(declSpec);
+ funcDefinition.setDeclarator((IASTFunctionDeclarator) declarator);
+
+ IASTStatement s= handleFunctionBody();
+ funcDefinition.setBody(s);
+ ((ASTNode) funcDefinition).setOffsetAndLength(firstOffset, calculateEndOffset(s) - firstOffset);
+
+ return funcDefinition;
+ }
+
protected IASTFunctionDefinition createFunctionDefinition() {
return new CASTFunctionDefinition();
}
@@ -480,14 +458,6 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
return new CASTSimpleDeclaration();
}
- protected CASTTranslationUnit translationUnit;
-
- private boolean knr = false;
-
- private static final int DEFAULT_POINTEROPS_LIST_SIZE = 4;
-
- private static final int DEFAULT_PARAMETERS_LIST_SIZE = 4;
-
protected CASTTranslationUnit createTranslationUnit() {
CASTTranslationUnit t = new CASTTranslationUnit();
t.setOffset(0);
@@ -527,7 +497,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
if (LT(1) == IToken.tEOC)
break;
int checkOffset = LA(1).hashCode();
- IASTDeclaration d = declaration();
+ IASTDeclaration d = declaration(DeclarationOptions.GLOBAL);
translationUnit.addDeclaration(d);
if (LA(1).hashCode() == checkOffset)
failParseWithErrorHandling();
@@ -694,7 +664,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
consume();
if (!avoidCastExpressionByHeuristics()) {
- IASTTypeId typeId = typeId(false);
+ IASTTypeId typeId = typeId(DeclarationOptions.TYPEID);
if (typeId != null && LT(1) == IToken.tRPAREN) {
consume();
try {
@@ -775,7 +745,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
IToken m = mark();
try {
int offset = consume().getOffset();
- IASTTypeId t = typeId(false);
+ IASTTypeId t= typeId(DeclarationOptions.TYPEID);
if (t != null) {
consume(IToken.tRPAREN).getEndOffset();
if (LT(1) == IToken.tLBRACE) {
@@ -1003,7 +973,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
}
@Override
- protected IASTTypeId typeId(boolean forNewExpression) throws EndOfFileException {
+ protected IASTTypeId typeId(DeclarationOptions option) throws EndOfFileException {
if (!canBeTypeSpecifier()) {
return null;
}
@@ -1012,19 +982,21 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
IASTDeclSpecifier declSpecifier = null;
IASTDeclarator declarator = null;
+ fPreventKnrCheck++;
try {
- try
- {
- declSpecifier = declSpecifierSeq(false, true);
+ try {
+ declSpecifier= declSpecifierSeq(option);
+ declarator= declarator(option);
} catch (FoundDeclaratorException e) {
- return null;
+ declSpecifier= e.declSpec;
+ declarator= e.declarator;
+ backup(e.currToken);
}
- declarator = declarator();
} catch (BacktrackException bt) {
return null;
+ } finally {
+ fPreventKnrCheck--;
}
- if (declarator == null || declarator.getName().toCharArray().length > 0)
- return null;
IASTTypeId result = createTypeId();
((ASTNode) result).setOffsetAndLength(startingOffset, figureEndOffset(
@@ -1100,304 +1072,316 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
return new CASTPointer();
}
- protected IASTDeclSpecifier declSpecifierSeq(boolean parm, boolean forTypeId)
+ private final static int INLINE=0x1, CONST=0x2, RESTRICT=0x4, VOLATILE=0x8,
+ SHORT=0x10, UNSIGNED= 0x20, SIGNED=0x40, COMPLEX=0x80, IMAGINARY=0x100;
+
+ protected IASTDeclSpecifier declSpecifierSeq(final DeclarationOptions declOption)
throws BacktrackException, EndOfFileException, FoundDeclaratorException {
- Flags flags = new Flags(parm,forTypeId);
-
- int startingOffset = LA(1).getOffset();
- int storageClass = IASTDeclSpecifier.sc_unspecified;
- boolean isInline = false;
- boolean isConst = false, isRestrict = false, isVolatile = false;
- boolean isShort = false, isLong = false, isUnsigned = false, isIdentifier = false, isSigned = false, isLongLong = false;
- boolean isComplex = false, isImaginary = false;
- int simpleType = IASTSimpleDeclSpecifier.t_unspecified;
- IToken identifier = null;
- IASTCompositeTypeSpecifier structSpec = null;
- IASTElaboratedTypeSpecifier elabSpec = null;
- IASTEnumerationSpecifier enumSpec = null;
- IASTExpression typeofExpression = null;
- IToken last = null;
+
+ final int offset= LA(1).getOffset();
+ int endOffset= offset;
+ int storageClass= IASTDeclSpecifier.sc_unspecified;
+ int simpleType= IASTSimpleDeclSpecifier.t_unspecified;
+ int options= 0;
+ int isLong= 0;
+
+ IToken identifier= null;
+ IASTDeclSpecifier result= null;
+ IASTExpression typeofExpression= null;
+
+ boolean encounteredRawType= false;
+ boolean encounteredTypename= false;
declSpecifiers: for (;;) {
- switch (LT(1)) {
+ final IToken token= LA(1);
+ final int lt1= token.getType();
+ switch (lt1) {
// Storage Class Specifiers
case IToken.t_auto:
- last = consume();
+ endOffset= consume().getEndOffset();
storageClass = IASTDeclSpecifier.sc_auto;
break;
case IToken.t_register:
storageClass = IASTDeclSpecifier.sc_register;
- last = consume();
+ endOffset= consume().getEndOffset();
break;
case IToken.t_static:
storageClass = IASTDeclSpecifier.sc_static;
- last = consume();
+ endOffset= consume().getEndOffset();
break;
case IToken.t_extern:
storageClass = IASTDeclSpecifier.sc_extern;
- last = consume();
+ endOffset= consume().getEndOffset();
break;
case IToken.t_typedef:
storageClass = IASTDeclSpecifier.sc_typedef;
- last = consume();
+ endOffset= consume().getEndOffset();
break;
// Function Specifier
case IToken.t_inline:
- isInline = true;
- last = consume();
+ options |= INLINE;
+ endOffset= consume().getEndOffset();
break;
// Type Qualifiers
case IToken.t_const:
- isConst = true;
- last = consume();
+ options |= CONST;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_volatile:
- isVolatile = true;
- last = consume();
+ options |= VOLATILE;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_restrict:
- isRestrict = true;
- last = consume();
+ options |= RESTRICT;
+ endOffset= consume().getEndOffset();
break;
// Type Specifiers
case IToken.t_void:
- flags.setEncounteredRawType(true);
- last = consume();
simpleType = IASTSimpleDeclSpecifier.t_void;
+ encounteredRawType= true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_char:
- flags.setEncounteredRawType(true);
- last = consume();
simpleType = IASTSimpleDeclSpecifier.t_char;
+ encounteredRawType= true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_short:
- flags.setEncounteredRawType(true);
- last = consume();
- isShort = true;
+ options |= SHORT;
+ encounteredRawType= true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_int:
- flags.setEncounteredRawType(true);
- last = consume();
simpleType = IASTSimpleDeclSpecifier.t_int;
+ encounteredRawType= true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_long:
- flags.setEncounteredRawType(true);
- last = consume();
- if (isLong) {
- isLongLong = true;
- isLong = false;
- } else
- isLong = true;
+ isLong++;
+ encounteredRawType= true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_float:
- flags.setEncounteredRawType(true);
- last = consume();
simpleType = IASTSimpleDeclSpecifier.t_float;
+ encounteredRawType= true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_double:
- flags.setEncounteredRawType(true);
- last = consume();
simpleType = IASTSimpleDeclSpecifier.t_double;
+ encounteredRawType= true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_signed:
- flags.setEncounteredRawType(true);
- last = consume();
- isSigned = true;
+ options |= SIGNED;
+ encounteredRawType= true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_unsigned:
- flags.setEncounteredRawType(true);
- last = consume();
- isUnsigned = true;
+ options |= UNSIGNED;
+ encounteredRawType= true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t__Bool:
- flags.setEncounteredRawType(true);
- last = consume();
simpleType = ICASTSimpleDeclSpecifier.t_Bool;
+ encounteredRawType= true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t__Complex:
- last = consume();
- isComplex=true;
+ options |= COMPLEX;
+ endOffset= consume().getEndOffset();
break;
case IToken.t__Imaginary:
- last = consume();
- isImaginary=true;
+ options |= IMAGINARY;
+ endOffset= consume().getEndOffset();
break;
case IToken.tIDENTIFIER:
case IToken.tCOMPLETION:
case IToken.tEOC:
- // TODO - Kludgy way to handle constructors/destructors
- if (flags.haveEncounteredRawType()) {
- break declSpecifiers;
- }
- if (flags.haveEncounteredTypename()) {
+ if (encounteredTypename || encounteredRawType) {
break declSpecifiers;
}
try {
- lookAheadForDeclarator(flags);
- } catch (FoundDeclaratorException e) {
- ICASTSimpleDeclSpecifier declSpec= createSimpleTypeSpecifier();
-
- declSpec.setConst(isConst);
- declSpec.setRestrict(isRestrict);
- declSpec.setVolatile(isVolatile);
- declSpec.setInline(isInline);
- declSpec.setStorageClass(storageClass);
-
- declSpec.setType(simpleType);
- declSpec.setLong(isLong);
- declSpec.setLongLong(isLongLong);
- declSpec.setUnsigned(isUnsigned);
- declSpec.setSigned(isSigned);
- declSpec.setShort(isShort);
- ((ASTNode) declSpec).setOffsetAndLength(startingOffset,
- (last != null) ? last.getEndOffset() - startingOffset : 0);
- e.declSpec = declSpec;
- throw e;
- }
+ if (endOffset != offset || declOption.fAllowEmptySpecifier) {
+ lookAheadForDeclarator(declOption);
+ }
+ } catch (FoundDeclaratorException e) {
+ e.declSpec= createSimpleDeclSpec(storageClass, simpleType, options, isLong, typeofExpression, offset, endOffset);
+
+ IToken mark= mark();
+ try {
+ final IToken idToken= identifier(); // for the specifier
+ final IASTDeclarator altDtor = initDeclarator(declOption);
+ if (LA(1) == e.currToken) {
+ e.altDeclarator= altDtor;
+ e.altSpec= createNamedTypeSpecifier(idToken, storageClass, options, offset, idToken.getEndOffset());
+ }
+ } catch (BacktrackException bt) {
+ } finally {
+ backup(mark);
+ }
+ throw e;
+ }
identifier = identifier();
- last = identifier;
- isIdentifier = true;
- flags.setEncounteredTypename(true);
+ endOffset= identifier.getEndOffset();
+ encounteredTypename= true;
break;
case IToken.t_struct:
case IToken.t_union:
- if (flags.haveEncounteredTypename())
- throwBacktrack(LA(1));
+ if (encounteredTypename || encounteredRawType)
+ throwBacktrack(token);
try {
- structSpec = structOrUnionSpecifier();
- flags.setEncounteredTypename(true);
- break;
+ result= structOrUnionSpecifier();
} catch (BacktrackException bt) {
- elabSpec = elaboratedTypeSpecifier();
- flags.setEncounteredTypename(true);
- break;
+ result= elaboratedTypeSpecifier();
}
+ endOffset= calculateEndOffset(result);
+ encounteredTypename= true;
+ break;
case IToken.t_enum:
- if (flags.haveEncounteredTypename())
- throwBacktrack(LA(1));
+ if (encounteredTypename || encounteredRawType)
+ throwBacktrack(token);
try {
- enumSpec = enumSpecifier();
- flags.setEncounteredTypename(true);
- break;
+ result= enumSpecifier();
} catch (BacktrackException bt) {
// this is an elaborated class specifier
- elabSpec = elaboratedTypeSpecifier();
- flags.setEncounteredTypename(true);
- break;
+ result= elaboratedTypeSpecifier();
}
+ endOffset= calculateEndOffset(result);
+ encounteredTypename= true;
+ break;
+
case IGCCToken.t__attribute__: // if __attribute__ is after the declSpec
- if (supportAttributeSpecifiers)
- __attribute_decl_seq(true, false);
- else
- throwBacktrack(LA(1).getOffset(), LA(1).getLength());
+ if (!supportAttributeSpecifiers)
+ throwBacktrack(token);
+ __attribute_decl_seq(true, false);
break;
case IGCCToken.t__declspec: // __declspec precedes the identifier
- if (identifier == null && supportDeclspecSpecifiers)
- __attribute_decl_seq(false, true);
- else
- throwBacktrack(LA(1).getOffset(), LA(1).getLength());
+ if (identifier != null || !supportDeclspecSpecifiers)
+ throwBacktrack(token);
+ __attribute_decl_seq(false, true);
break;
+
default:
- if (LT(1) >= IExtensionToken.t__otherDeclSpecModifierFirst && LT(1) <= IExtensionToken.t__otherDeclSpecModifierLast) {
+ if (lt1 >= IExtensionToken.t__otherDeclSpecModifierFirst && lt1 <= IExtensionToken.t__otherDeclSpecModifierLast) {
handleOtherDeclSpecModifier();
+ endOffset= LA(1).getOffset();
break;
}
- if (supportTypeOfUnaries && LT(1) == IGCCToken.t_typeof) {
+ if (lt1 == IGCCToken.t_typeof) {
+ if (encounteredRawType || encounteredTypename)
+ throwBacktrack(token);
+
typeofExpression = unaryTypeofExpression();
- if (typeofExpression != null) {
- flags.setEncounteredTypename(true);
- }
+ encounteredTypename= true;
+ endOffset= calculateEndOffset(typeofExpression);
+ break;
}
break declSpecifiers;
}
+
+ if (encounteredRawType && encounteredTypename)
+ throwBacktrack(token);
}
- if (structSpec != null) {
- ((ASTNode) structSpec).setOffsetAndLength(startingOffset,
- calculateEndOffset(structSpec) - startingOffset);
- structSpec.setConst(isConst);
- ((ICASTCompositeTypeSpecifier) structSpec).setRestrict(isRestrict);
- structSpec.setVolatile(isVolatile);
- structSpec.setInline(isInline);
- structSpec.setStorageClass(storageClass);
-
- return structSpec;
- }
-
- if (enumSpec != null) {
- ((ASTNode) enumSpec).setOffsetAndLength(startingOffset,
- calculateEndOffset(enumSpec) - startingOffset);
- enumSpec.setConst(isConst);
- ((CASTEnumerationSpecifier) enumSpec).setRestrict(isRestrict);
- enumSpec.setVolatile(isVolatile);
- enumSpec.setInline(isInline);
- enumSpec.setStorageClass(storageClass);
- return enumSpec;
-
- }
- if (elabSpec != null) {
- ((ASTNode) elabSpec).setOffsetAndLength(startingOffset,
- calculateEndOffset(elabSpec) - startingOffset);
- elabSpec.setConst(isConst);
- ((CASTElaboratedTypeSpecifier) elabSpec).setRestrict(isRestrict);
- elabSpec.setVolatile(isVolatile);
- elabSpec.setInline(isInline);
- elabSpec.setStorageClass(storageClass);
-
- return elabSpec;
+ // check for empty specification
+ if (!encounteredRawType && !encounteredTypename && LT(1) != IToken.tEOC && !declOption.fAllowEmptySpecifier) {
+ if (offset == endOffset) {
+ throwBacktrack(LA(1));
+ }
}
- if (isIdentifier) {
- ICASTTypedefNameSpecifier declSpec = (ICASTTypedefNameSpecifier)createNamedTypeSpecifier();
- declSpec.setConst(isConst);
- declSpec.setRestrict(isRestrict);
- declSpec.setVolatile(isVolatile);
- declSpec.setInline(isInline);
- declSpec.setStorageClass(storageClass);
-
- if (last != null) {
- ((ASTNode) declSpec).setOffsetAndLength(startingOffset, last.getEndOffset() - startingOffset);
+
+ 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);
+ }
}
- IASTName name = createName(identifier);
- declSpec.setName(name);
- return declSpec;
+ ((ASTNode) result).setOffsetAndLength(offset, endOffset - offset);
+ return result;
}
- ICASTSimpleDeclSpecifier declSpec = null;
+
+ if (identifier != null)
+ return createNamedTypeSpecifier(identifier, storageClass, options, offset, endOffset);
+
+ return createSimpleDeclSpec(storageClass, simpleType, options, isLong, typeofExpression, offset, endOffset);
+ }
+
+ private ICASTTypedefNameSpecifier createNamedTypeSpecifier(IToken identifier, int storageClass,
+ int options, int offset, int endOffset) {
+ ICASTTypedefNameSpecifier declSpec = (ICASTTypedefNameSpecifier)createNamedTypeSpecifier();
+ IASTName name = createName(identifier);
+ declSpec.setName(name);
+ configureDeclSpec(declSpec, storageClass, options);
+ declSpec.setRestrict((options & RESTRICT) != 0);
+ ((ASTNode) declSpec).setOffsetAndLength(offset, endOffset - offset);
+ return declSpec;
+ }
+
+ private ICASTSimpleDeclSpecifier createSimpleDeclSpec(int storageClass, int simpleType,
+ int options, int isLong, IASTExpression typeofExpression, int offset, int endOffset) {
+ ICASTSimpleDeclSpecifier declSpec = null;
if (typeofExpression != null) {
declSpec = createGCCSimpleTypeSpecifier();
((IGCCASTSimpleDeclSpecifier) declSpec).setTypeofExpression(typeofExpression);
-
} else {
declSpec = createSimpleTypeSpecifier();
}
- declSpec.setConst(isConst);
- declSpec.setRestrict(isRestrict);
- declSpec.setVolatile(isVolatile);
- declSpec.setInline(isInline);
- declSpec.setStorageClass(storageClass);
-
- declSpec.setType(simpleType);
- declSpec.setLong(isLong);
- declSpec.setLongLong(isLongLong);
- declSpec.setUnsigned(isUnsigned);
- declSpec.setSigned(isSigned);
- declSpec.setShort(isShort);
- declSpec.setComplex(isComplex);
- declSpec.setImaginary(isImaginary);
- if( typeofExpression != null && last == null ){
- ((ASTNode)declSpec).setOffsetAndLength( (ASTNode)typeofExpression );
- } else {
- ((ASTNode) declSpec).setOffsetAndLength(startingOffset,
- (last != null) ? last.getEndOffset() - startingOffset : 0);
- }
- return declSpec;
- }
+ configureDeclSpec(declSpec, storageClass, options);
+ declSpec.setType(simpleType);
+ declSpec.setLong(isLong == 1);
+ declSpec.setLongLong(isLong > 1);
+ declSpec.setRestrict((options & RESTRICT) != 0);
+ declSpec.setUnsigned((options & UNSIGNED) != 0);
+ declSpec.setSigned((options & SIGNED) != 0);
+ declSpec.setShort((options & SHORT) != 0);
+ declSpec.setComplex((options & COMPLEX) != 0);
+ declSpec.setImaginary((options & IMAGINARY) != 0);
+
+ ((ASTNode) declSpec).setOffsetAndLength(offset, endOffset - offset);
+ return declSpec;
+ }
+
+ private void configureDeclSpec(IASTDeclSpecifier declSpec, int storageClass, int options) {
+ declSpec.setStorageClass(storageClass);
+ declSpec.setConst((options & CONST) != 0);
+ declSpec.setVolatile((options & VOLATILE) != 0);
+ declSpec.setInline((options & INLINE) != 0);
+ }
+
+ @Override
+ protected boolean verifyLookaheadDeclarator(DeclarationOptions option, IASTDeclarator dtor, IToken nextToken) {
+ switch (nextToken.getType()) {
+ case IToken.tCOMMA:
+ return true;
+ case IToken.tLBRACE:
+ if (option == DeclarationOptions.GLOBAL || option == DeclarationOptions.C_MEMBER) {
+ if (CVisitor.findTypeRelevantDeclarator(dtor) instanceof IASTFunctionDeclarator) {
+ return true;
+ }
+ }
+ break;
+ case IToken.tSEMI:
+ return option == DeclarationOptions.GLOBAL || option == DeclarationOptions.C_MEMBER ||
+ option == DeclarationOptions.LOCAL;
+ case IToken.tRPAREN:
+ return option == DeclarationOptions.PARAMETER
+ || option == DeclarationOptions.C_PARAMETER_NON_ABSTRACT;
+ }
+ return false;
+ }
+
protected ICASTSimpleDeclSpecifier createSimpleTypeSpecifier() {
return new CASTSimpleDeclSpecifier();
}
@@ -1479,7 +1463,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
default:
int checkToken = LA(1).hashCode();
try {
- IASTDeclaration d = declaration();
+ IASTDeclaration d = declaration(DeclarationOptions.C_MEMBER);
result.addMemberDeclaration(d);
} catch (BacktrackException bt) {
if (checkToken == LA(1).hashCode())
@@ -1540,8 +1524,8 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
}
@Override
- protected IASTDeclarator initDeclarator() throws EndOfFileException, BacktrackException {
- IASTDeclarator d = declarator();
+ protected IASTDeclarator initDeclarator(final DeclarationOptions option) throws EndOfFileException, BacktrackException {
+ IASTDeclarator d = declarator(option);
IASTInitializer i = optionalCInitializer();
if (i != null) {
@@ -1551,265 +1535,337 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
return d;
}
- protected IASTDeclarator declarator() throws EndOfFileException, BacktrackException {
- IASTDeclarator innerDecl = null;
- IASTName declaratorName = null;
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- int finalOffset = startingOffset;
- la = null;
+ protected IASTDeclarator declarator(DeclarationOptions option) throws EndOfFileException, BacktrackException {
+ final int startingOffset = LA(1).getOffset();
+ int endOffset = startingOffset;
+
List<IASTPointerOperator> pointerOps = new ArrayList<IASTPointerOperator>(DEFAULT_POINTEROPS_LIST_SIZE);
- List<IASTNode> parameters = Collections.emptyList();
- List<IASTNode> arrayMods = Collections.emptyList();
- boolean encounteredVarArgs = false;
- IASTExpression bitField = null;
- boolean isFunction = false;
- IASTName[] parmNames = null;
- IASTDeclaration[] parmDeclarations = null;
- int numKnRCParms = 0;
-
- overallLoop: do {
-
- consumePointerOperators(pointerOps);
-
- // Accept __attribute__ or __declspec after the pointer ops and before the declarator ex: void * __attribute__((__cdecl__)) foo();
- __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
+ consumePointerOperators(pointerOps);
+ if (!pointerOps.isEmpty()) {
+ endOffset = calculateEndOffset(pointerOps.get(pointerOps.size() - 1));
+ }
- if (!pointerOps.isEmpty()) {
- finalOffset = calculateEndOffset(pointerOps
- .get(pointerOps.size() - 1));
- }
+ // Accept __attribute__ or __declspec between pointer operators and declarator.
+ __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
+
+ // Look for identifier or nested declarator
+ final int lt1= LT(1);
+ if (lt1 == IToken.tIDENTIFIER) {
+ if (option.fRequireAbstract)
+ throwBacktrack(LA(1));
+
+ final IASTName declaratorName = createName(identifier());
+ endOffset= calculateEndOffset(declaratorName);
+ return declarator(pointerOps, declaratorName, null, startingOffset, endOffset, option);
+ }
+
+ if (lt1 == IToken.tLPAREN) {
+ IASTDeclarator cand1= null;
+ IToken cand1End= null;
+ // try an abstract function declarator
+ if (option.fAllowAbstract) {
+ final IToken mark= mark();
+ try {
+ cand1= declarator(pointerOps, createName(), null, startingOffset, endOffset, option);
+ if (option.fRequireAbstract)
+ return cand1;
+
+ cand1End= LA(1);
+ } catch (BacktrackException e) {
+ }
+ backup(mark);
+ }
+ // try a nested declarator
+ try {
+ consume();
+ if (LT(1) == IToken.tRPAREN)
+ throwBacktrack(LA(1));
+
+ final IASTDeclarator nested= declarator(option);
+ endOffset= consume(IToken.tRPAREN).getEndOffset();
+ final IASTDeclarator cand2= declarator(pointerOps, null, nested, startingOffset, endOffset, option);
+ if (cand1 == null || cand1End == null)
+ return cand2;
+ final IToken cand2End= LA(1);
+ if (cand1End == cand2End) {
+ CASTAmbiguousDeclarator result= new CASTAmbiguousDeclarator(cand1, cand2);
+ ((ASTNode) result).setOffsetAndLength((ASTNode) cand1);
+ return result;
+ }
+ // use the longer variant
+ if (cand1End.getOffset() < cand2End.getOffset())
+ return cand2;
+
+ } catch (BacktrackException e) {
+ if (cand1 == null)
+ throw e;
+ }
+ backup(cand1End);
+ return cand1;
+ }
+
+ // try abstract declarator
+ if (!option.fAllowAbstract) {
+ // bit-fields may be abstract
+ if (!option.fAllowBitField || LT(1) != IToken.tCOLON)
+ throwBacktrack(LA(1));
+ }
+ return declarator(pointerOps, createName(), null, startingOffset, endOffset, option);
+ }
+
+ private IASTDeclarator declarator(final List<IASTPointerOperator> pointerOps,
+ final IASTName declaratorName, final IASTDeclarator nestedDeclarator,
+ final int startingOffset, int endOffset,
+ final DeclarationOptions option) throws EndOfFileException, BacktrackException {
+ IASTDeclarator result= null;
+ loop: while(true) {
+ final int lt1= LT(1);
+ switch (lt1) {
+ case IToken.tLPAREN:
+ result= functionDeclarator(isAbstract(declaratorName, nestedDeclarator)
+ ? DeclarationOptions.PARAMETER : DeclarationOptions.C_PARAMETER_NON_ABSTRACT);
+ setDeclaratorID(result, declaratorName, nestedDeclarator);
+ break loop;
+
+ case IToken.tLBRACKET:
+ result= arrayDeclarator();
+ setDeclaratorID(result, declaratorName, nestedDeclarator);
+ break loop;
+
+ case IToken.tCOLON:
+ if (!option.fAllowBitField)
+ throwBacktrack(LA(1));
+
+ result= bitFieldDeclarator();
+ setDeclaratorID(result, declaratorName, nestedDeclarator);
+ break loop;
+
+ case IGCCToken.t__attribute__: // if __attribute__ is after a declarator
+ if (!supportAttributeSpecifiers)
+ throwBacktrack(LA(1));
+ __attribute_decl_seq(true, supportDeclspecSpecifiers);
+ break;
+ case IGCCToken.t__declspec:
+ if (!supportDeclspecSpecifiers)
+ throwBacktrack(LA(1));
+ __attribute_decl_seq(supportAttributeSpecifiers, true);
+ break;
+ default:
+ break loop;
+ }
+ }
+ __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
- if (LT(1) == IToken.tLPAREN) {
- consume();
- innerDecl = declarator();
- finalOffset = consume(IToken.tRPAREN).getEndOffset();
- declaratorName = createName();
- } else if (LT(1) == IToken.tIDENTIFIER) {
- declaratorName = createName(identifier());
- finalOffset = calculateEndOffset(declaratorName);
- } else
- declaratorName = createName();
+ if (result == null) {
+ result= createDeclarator();
+ setDeclaratorID(result, declaratorName, nestedDeclarator);
+ } else {
+ endOffset= calculateEndOffset(result);
+ }
- for (;;) {
- switch (LT(1)) {
- case IToken.tLPAREN:
- // parameterDeclarationClause
- // d.setIsFunction(true);
- // TODO need to create a temporary scope object here
- IToken last = consume();
- finalOffset = last.getEndOffset();
- isFunction = true;
- boolean seenParameter = false;
-
- // count the number of K&R C parameters (0 K&R C parameters
- // essentially means it's not K&R C)
- if( !knr && supportKnRC)
- numKnRCParms = countKnRCParms();
-
- if (numKnRCParms > 0) { // KnR C parameters were found so
- // handle the declarator accordingly
- parmNames = new IASTName[numKnRCParms];
- parmDeclarations = new IASTDeclaration[numKnRCParms];
-
- for (int i = 0; i <= parmNames.length; i++) {
- switch (LT(1)) {
- case IToken.tCOMMA:
- last = consume();
- parmNames[i] = createName(identifier());
- seenParameter = true;
- break;
- case IToken.tIDENTIFIER:
- if (seenParameter)
- throwBacktrack(startingOffset, last.getEndOffset() - startingOffset);
-
- parmNames[i] = createName(identifier());
- seenParameter = true;
- break;
- case IToken.tRPAREN:
- last = consume();
- break;
- default:
- break;
- }
- }
-
- // now that the parameter names are parsed, parse the
- // parameter declarations
- for (int i = 0; i < numKnRCParms
- && LT(1) != IToken.tLBRACE; i++) { // max
- // parameter
- // declarations
- // same as
- // parameter
- // name count
- // (could be
- // less)
- try {
- boolean hasValidDecltors = true;
-
- IASTDeclaration decl = simpleDeclaration();
- IASTSimpleDeclaration declaration = null;
- if (decl instanceof IASTSimpleDeclaration) {
- declaration = ((IASTSimpleDeclaration) decl);
-
- IASTDeclarator[] decltors = declaration.getDeclarators();
- for (IASTDeclarator decltor : decltors) {
- boolean decltorOk = false;
- for (IASTName parmName : parmNames) {
- if (CharArrayUtils.equals(
- decltor.getName().toCharArray(),
- parmName.toCharArray())) {
- decltorOk = true;
- break;
- }
- }
- if (!decltorOk)
- hasValidDecltors = false;
- }
- } else {
- hasValidDecltors = false;
- }
-
- if (hasValidDecltors) {
- parmDeclarations[i] = declaration;
- } else {
- parmDeclarations[i] = createKnRCProblemDeclaration(
- ((ASTNode) decl).getLength(),
- ((ASTNode) decl).getOffset());
- }
- } catch (BacktrackException b) {
- parmDeclarations[i] = createKnRCProblemDeclaration(
- b.getLength(), b.getOffset());
- }
- }
-
- break overallLoop;
- }
+ if (LT(1) == IToken.t_asm) { // asm labels bug 226121
+ consume();
+ endOffset= asmExpression(null).getEndOffset();
- parameterDeclarationLoop: for (;;) {
- switch (LT(1)) {
- case IToken.tRPAREN:
- case IToken.tEOC:
- last = consume();
- finalOffset = last.getEndOffset();
- break parameterDeclarationLoop;
- case IToken.tELLIPSIS:
- last = consume();
- encounteredVarArgs = true;
- finalOffset = last.getEndOffset();
- break;
- case IToken.tCOMMA:
- last = consume();
- finalOffset = last.getEndOffset();
- seenParameter = false;
- break;
- default:
- if (seenParameter)
- throwBacktrack(startingOffset, last.getEndOffset() - startingOffset);
- IASTParameterDeclaration pd = parameterDeclaration();
- finalOffset = calculateEndOffset(pd);
- if (parameters == Collections.EMPTY_LIST)
- parameters = new ArrayList<IASTNode>(DEFAULT_PARAMETERS_LIST_SIZE);
- parameters.add(pd);
- seenParameter = true;
- }
- }
+ __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
+ }
- break;
- case IToken.tLBRACKET:
- if (arrayMods == Collections.EMPTY_LIST)
- arrayMods = new ArrayList<IASTNode>(DEFAULT_POINTEROPS_LIST_SIZE);
- consumeArrayModifiers(arrayMods);
- if (!arrayMods.isEmpty())
- finalOffset = calculateEndOffset(arrayMods.get(arrayMods.size() - 1));
- continue;
- case IToken.tCOLON:
- consume();
- bitField = constantExpression();
- finalOffset = calculateEndOffset(bitField);
- break;
- case IGCCToken.t__attribute__: // if __attribute__ is after the declarator
- if(supportAttributeSpecifiers)
- __attribute_decl_seq(true, false);
- else
- throwBacktrack(LA(1).getOffset(), LA(1).getLength());
- break;
- case IGCCToken.t__declspec:
- if(supportDeclspecSpecifiers)
- __attribute_decl_seq(false, true);
- else
- throwBacktrack(LA(1).getOffset(), LA(1).getLength());
- break;
- default:
- break;
- }
- break;
- }
+ for (IASTPointerOperator po : pointerOps) {
+ result.addPointerOperator(po);
+ }
- } while (false);
+ ((ASTNode) result).setOffsetAndLength(startingOffset, endOffset - startingOffset);
+ return result;
+ }
- if (LT(1) == IToken.t_asm) { // asm labels bug 226121
- consume();
- finalOffset= asmExpression(null).getEndOffset();
- }
+ private boolean isAbstract(IASTName declaratorName, IASTDeclarator nestedDeclarator) {
+ nestedDeclarator= CVisitor.findInnermostDeclarator(nestedDeclarator);
+ if (nestedDeclarator != null) {
+ declaratorName= nestedDeclarator.getName();
+ }
+ return declaratorName == null || declaratorName.toCharArray().length == 0;
+ }
- // Consume any number of __attribute__ and __declspec tokens after the parameters
- __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
+ private void setDeclaratorID(IASTDeclarator declarator, IASTName declaratorName, IASTDeclarator nestedDeclarator) {
+ if (nestedDeclarator != null) {
+ declarator.setNestedDeclarator(nestedDeclarator);
+ declarator.setName(createName());
+ } else {
+ declarator.setName(declaratorName);
+ }
+ }
- IASTDeclarator d = null;
- if (numKnRCParms > 0 && supportKnRC) {
- ICASTKnRFunctionDeclarator functionDecltor = createKnRFunctionDeclarator();
- parmDeclarations = (IASTDeclaration[]) ArrayUtil.removeNulls( IASTDeclaration.class, parmDeclarations );
- for (int i = 0; i < parmDeclarations.length; ++i) {
- if (parmDeclarations[i] != null) {
- finalOffset = calculateEndOffset(parmDeclarations[i]);
- }
- }
- functionDecltor.setParameterDeclarations(parmDeclarations);
- functionDecltor.setParameterNames(parmNames);
- if (declaratorName != null) {
- functionDecltor.setName(declaratorName);
- }
+ private IASTDeclarator functionDeclarator(DeclarationOptions paramOption) throws EndOfFileException, BacktrackException {
+ IToken last = consume(IToken.tLPAREN);
+ int startOffset= last.getOffset();
+
+ // check for K&R C parameters (0 means it's not K&R C)
+ if (fPreventKnrCheck==0 && supportKnRC) {
+ fPreventKnrCheck++;
+ try {
+ final int numKnRCParms = countKnRCParms();
+ if (numKnRCParms > 0) { // KnR C parameters were found
+ IASTName[] parmNames = new IASTName[numKnRCParms];
+ IASTDeclaration[] parmDeclarations = new IASTDeclaration[numKnRCParms];
+
+ boolean seenParameter= false;
+ for (int i = 0; i <= parmNames.length; i++) {
+ switch (LT(1)) {
+ case IToken.tCOMMA:
+ last = consume();
+ parmNames[i] = createName(identifier());
+ seenParameter = true;
+ break;
+ case IToken.tIDENTIFIER:
+ if (seenParameter)
+ throwBacktrack(startOffset, last.getEndOffset() - startOffset);
+
+ parmNames[i] = createName(identifier());
+ seenParameter = true;
+ break;
+ case IToken.tRPAREN:
+ last = consume();
+ break;
+ default:
+ break;
+ }
+ }
+
+ // now that the parameter names are parsed, parse the parameter declarations
+ // count for parameter declarations <= count for parameter names.
+ int endOffset= last.getEndOffset();
+ for (int i = 0; i < numKnRCParms && LT(1) != IToken.tLBRACE; i++) {
+ try {
+ IASTDeclaration decl= simpleDeclaration(DeclarationOptions.LOCAL);
+ IASTSimpleDeclaration ok= checkKnrParameterDeclaration(decl, parmNames);
+ if (ok != null) {
+ parmDeclarations[i]= ok;
+ endOffset= calculateEndOffset(ok);
+ } else {
+ final ASTNode node = (ASTNode) decl;
+ parmDeclarations[i] = createKnRCProblemDeclaration(node.getOffset(), node.getLength());
+ endOffset= calculateEndOffset(node);
+ }
+ } catch (BacktrackException b) {
+ parmDeclarations[i] = createKnRCProblemDeclaration(b.getOffset(), b.getLength());
+ endOffset= b.getOffset() + b.getLength();
+ }
+ }
+
+ ICASTKnRFunctionDeclarator functionDecltor = createKnRFunctionDeclarator();
+ parmDeclarations = (IASTDeclaration[]) ArrayUtil.removeNulls( IASTDeclaration.class, parmDeclarations );
+ functionDecltor.setParameterDeclarations(parmDeclarations);
+ functionDecltor.setParameterNames(parmNames);
+ ((ASTNode) functionDecltor).setOffsetAndLength(startOffset, endOffset-startOffset);
+ return functionDecltor;
+ }
+ } finally {
+ fPreventKnrCheck--;
+ }
+ }
- d = functionDecltor;
- } else if (isFunction) {
- IASTStandardFunctionDeclarator fc = createFunctionDeclarator();
- fc.setVarArgs(encounteredVarArgs);
- for (int i = 0; i < parameters.size(); ++i) {
- IASTParameterDeclaration p = (IASTParameterDeclaration) parameters.get(i);
- fc.addParameterDeclaration(p);
- }
- d = fc;
- } else if (arrayMods != Collections.EMPTY_LIST) {
- d = createArrayDeclarator();
- for (int i = 0; i < arrayMods.size(); ++i) {
- IASTArrayModifier m = (IASTArrayModifier) arrayMods.get(i);
- ((IASTArrayDeclarator) d).addArrayModifier(m);
- }
- } else if (bitField != null) {
- IASTFieldDeclarator fl = createFieldDeclarator();
- fl.setBitFieldSize(bitField);
- d = fl;
- } else {
- d = createDeclarator();
- }
- for (int i = 0; i < pointerOps.size(); ++i) {
- IASTPointerOperator po = pointerOps.get(i);
- d.addPointerOperator(po);
- }
- if (innerDecl != null) {
- d.setNestedDeclarator(innerDecl);
- }
- if (declaratorName != null) {
- d.setName(declaratorName);
- }
+ boolean seenParameter= false;
+ boolean encounteredVarArgs= false;
+ List<IASTParameterDeclaration> parameters= null;
+ int endOffset= last.getEndOffset();
+
+ paramLoop: while(true) {
+ switch (LT(1)) {
+ case IToken.tRPAREN:
+ case IToken.tEOC:
+ endOffset= consume().getEndOffset();
+ break paramLoop;
+ case IToken.tELLIPSIS:
+ endOffset= consume().getEndOffset();
+ encounteredVarArgs = true;
+ break;
+ case IToken.tCOMMA:
+ endOffset= consume().getEndOffset();
+ seenParameter = false;
+ break;
+ default:
+ if (seenParameter)
+ throwBacktrack(startOffset, endOffset - startOffset);
+
+ IASTParameterDeclaration pd = parameterDeclaration(paramOption);
+ endOffset = calculateEndOffset(pd);
+ if (parameters == null)
+ parameters = new ArrayList<IASTParameterDeclaration>(DEFAULT_PARAMETERS_LIST_SIZE);
+ parameters.add(pd);
+ seenParameter = true;
+ break;
+ }
+ }
+ IASTStandardFunctionDeclarator fc = createFunctionDeclarator();
+ fc.setVarArgs(encounteredVarArgs);
+ if (parameters != null) {
+ for (IASTParameterDeclaration pd : parameters) {
+ fc.addParameterDeclaration(pd);
+ }
+ }
+ ((ASTNode) fc).setOffsetAndLength(startOffset, endOffset-startOffset);
+ return fc;
+ }
- ((ASTNode) d).setOffsetAndLength(startingOffset, finalOffset - startingOffset);
- return d;
- }
+ private IASTSimpleDeclaration checkKnrParameterDeclaration(IASTDeclaration decl, final IASTName[] parmNames) {
+ if (decl instanceof IASTSimpleDeclaration == false)
+ return null;
+
+ IASTSimpleDeclaration declaration= ((IASTSimpleDeclaration) decl);
+ IASTDeclarator[] decltors = declaration.getDeclarators();
+ for (IASTDeclarator decltor : decltors) {
+ boolean decltorOk = false;
+ final char[] nchars = decltor.getName().toCharArray();
+ for (IASTName parmName : parmNames) {
+ if (CharArrayUtils.equals(nchars, parmName.toCharArray())) {
+ decltorOk= true;
+ break;
+ }
+ }
+ if (!decltorOk)
+ return null;
+ }
+ return declaration;
+ }
+
+ /**
+ * Parse an array declarator starting at the square bracket.
+ */
+ private IASTArrayDeclarator arrayDeclarator() throws EndOfFileException, BacktrackException {
+ ArrayList<IASTArrayModifier> arrayMods = new ArrayList<IASTArrayModifier>(DEFAULT_POINTEROPS_LIST_SIZE);
+ int start= LA(1).getOffset();
+ consumeArrayModifiers(arrayMods);
+ if (arrayMods.isEmpty())
+ throwBacktrack(LA(1));
+
+ final int endOffset = calculateEndOffset(arrayMods.get(arrayMods.size() - 1));
+ final IASTArrayDeclarator d = createArrayDeclarator();
+ for (IASTArrayModifier m : arrayMods) {
+ d.addArrayModifier(m);
+ }
+
+ ((ASTNode) d).setOffsetAndLength(start, endOffset-start);
+ return d;
+ }
+
+
+ /**
+ * Parses for a bit field declarator starting with the colon
+ */
+ private IASTFieldDeclarator bitFieldDeclarator() throws EndOfFileException, BacktrackException {
+ int start= consume(IToken.tCOLON).getOffset();
+
+ final IASTExpression bitField = constantExpression();
+ final int endOffset = calculateEndOffset(bitField);
+
+ IASTFieldDeclarator d = createFieldDeclarator();
+ d.setBitFieldSize(bitField);
- protected IASTArrayDeclarator createArrayDeclarator() {
+ ((ASTNode) d).setOffsetAndLength(start, endOffset-start);
+ return d;
+ }
+
+ protected IASTArrayDeclarator createArrayDeclarator() {
return new CASTArrayDeclarator();
}
@@ -1842,9 +1898,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
return new CASTDeclarator();
}
- protected void consumeArrayModifiers(List<IASTNode> arrayMods)
- throws EndOfFileException, BacktrackException {
-
+ protected void consumeArrayModifiers(List<IASTArrayModifier> arrayMods) throws EndOfFileException, BacktrackException {
while (LT(1) == IToken.tLBRACKET) {
// eat the '['
int startOffset = consume().getOffset();
@@ -1931,38 +1985,43 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
return new CASTArrayModifier();
}
- protected IASTParameterDeclaration parameterDeclaration()
- throws BacktrackException, EndOfFileException {
- IToken current = LA(1);
+ protected IASTParameterDeclaration parameterDeclaration(DeclarationOptions option) throws BacktrackException, EndOfFileException {
+ final IToken current = LA(1);
int startingOffset = current.getOffset();
IASTDeclSpecifier declSpec = null;
- try
- {
- declSpec = declSpecifierSeq(true, false);
- }
- catch( FoundDeclaratorException fd )
- {
- declSpec = fd.declSpec;
- }
-
- // bug 167833, no declspec no parameter.
- if (current == LA(1))
- throwBacktrack(current.getOffset(), current.getLength());
-
IASTDeclarator declarator = null;
- if (LT(1) != IToken.tSEMI)
- declarator = initDeclarator();
-
- if (current == LA(1))
- throwBacktrack(current.getOffset(), figureEndOffset(declSpec,
- declarator)
- - current.getOffset());
+ IASTDeclSpecifier altDeclSpec = null;
+ IASTDeclarator altDeclarator = null;
+
+ try {
+ fPreventKnrCheck++;
+ declSpec= declSpecifierSeq(option);
+ declarator = initDeclarator(option);
+ } catch(FoundDeclaratorException fd) {
+ declSpec= fd.declSpec;
+ declarator= fd.declarator;
+ altDeclSpec= fd.altSpec;
+ altDeclarator= fd.altDeclarator;
+ backup(fd.currToken);
+ } finally {
+ fPreventKnrCheck--;
+ }
+ final int length = figureEndOffset(declSpec, declarator) - startingOffset;
IASTParameterDeclaration result = createParameterDeclaration();
- ((ASTNode) result).setOffsetAndLength(startingOffset, figureEndOffset(declSpec, declarator) - startingOffset);
+ ((ASTNode) result).setOffsetAndLength(startingOffset, length);
result.setDeclSpecifier(declSpec);
result.setDeclarator(declarator);
+ if (altDeclarator != null && altDeclSpec != null) {
+ IASTParameterDeclaration alt = createParameterDeclaration();
+ ((ASTNode) alt).setOffsetAndLength(startingOffset, length);
+ alt.setDeclSpecifier(altDeclSpec);
+ alt.setDeclarator(altDeclarator);
+ // order is important, prefer alternative over the declarator found via the lookahead.
+ result= new CASTAmbiguousParameterDeclaration(alt, result);
+ ((ASTNode) result).setOffsetAndLength((ASTNode) alt);
+ }
return result;
}
@@ -2140,7 +2199,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
return parseLabelStatement();
}
- return parseDeclarationOrExpressionStatement();
+ return parseDeclarationOrExpressionStatement(DeclarationOptions.LOCAL);
}
}
@@ -2173,7 +2232,6 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
boolean previousWasIdentifier = false;
try {
- knr = true;
mark = mark();
// starts at the beginning of the parameter list
@@ -2221,7 +2279,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
while (LT(1) != IToken.tLBRACE) {
// fix for 100104: check if the parameter declaration is a valid one
try {
- simpleDeclaration();
+ simpleDeclaration(DeclarationOptions.LOCAL);
} catch (BacktrackException e) {
backup(mark);
return 0;
@@ -2242,17 +2300,13 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
return 0;
}
- finally
- {
- knr = false;
- }
}
- private IASTProblemDeclaration createKnRCProblemDeclaration(int length, int offset) throws EndOfFileException {
+ private IASTProblemDeclaration createKnRCProblemDeclaration(int offset, int length) throws EndOfFileException {
IASTProblem p = createProblem(IProblem.SYNTAX_ERROR, offset, length);
IASTProblemDeclaration pd = createProblemDeclaration();
pd.setProblem(p);
- ((ASTNode) pd).setOffsetAndLength(((ASTNode) p).getOffset(), ((ASTNode) p).getLength());
+ ((ASTNode) pd).setOffsetAndLength((ASTNode) p);
// consume until LBRACE is found (to leave off at the function body and
// continue from there)
@@ -2440,7 +2494,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
int startOffset;
startOffset = consume().getOffset();
consume(IToken.tLPAREN);
- IASTStatement init = forInitStatement();
+ IASTStatement init = forInitStatement(DeclarationOptions.LOCAL);
IASTExpression for_condition = null;
switch (LT(1)) {
case IToken.tSEMI:
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousDeclarator.java
new file mode 100644
index 00000000000..c5d81177cd7
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousDeclarator.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Schorn - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.dom.parser.cpp;
+
+import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTInitializer;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
+import org.eclipse.cdt.core.parser.util.ArrayUtil;
+import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclarator;
+import org.eclipse.core.runtime.Assert;
+
+/**
+ * Handles ambiguities when parsing declarators.
+ * <br>
+ * Example: void f(int (D)); // is D a type?
+ * @since 5.0.1
+ */
+public class CPPASTAmbiguousDeclarator extends CPPASTAmbiguity implements IASTAmbiguousDeclarator {
+
+ private IASTDeclarator[] dtors = new IASTDeclarator[2];
+ private int dtorPos=-1;
+
+
+ public CPPASTAmbiguousDeclarator(IASTDeclarator... decls) {
+ for(IASTDeclarator d : decls) {
+ if (d != null) {
+ addDeclarator(d);
+ }
+ }
+ }
+
+ public void addDeclarator(IASTDeclarator d) {
+ if (d != null) {
+ dtors = (IASTDeclarator[]) ArrayUtil.append(IASTDeclarator.class, dtors, ++dtorPos, d);
+ d.setParent(this);
+ d.setPropertyInParent(SUBDECLARATOR);
+ }
+ }
+
+ public IASTDeclarator[] getDeclarators() {
+ dtors = (IASTDeclarator[]) ArrayUtil.removeNullsAfter(IASTDeclarator.class, dtors, dtorPos );
+ return dtors;
+ }
+
+ @Override
+ protected IASTNode[] getNodes() {
+ return getDeclarators();
+ }
+
+ public IASTInitializer getInitializer() {
+ return dtors[0].getInitializer();
+ }
+
+ public IASTName getName() {
+ return dtors[0].getName();
+ }
+
+ public IASTDeclarator getNestedDeclarator() {
+ return dtors[0].getNestedDeclarator();
+ }
+
+ public IASTPointerOperator[] getPointerOperators() {
+ return dtors[0].getPointerOperators();
+ }
+
+ public int getRoleForName(IASTName name) {
+ return dtors[0].getRoleForName(name);
+ }
+
+ public void addPointerOperator(IASTPointerOperator operator) {
+ Assert.isLegal(false);
+ }
+
+ public void setInitializer(IASTInitializer initializer) {
+ Assert.isLegal(false);
+ }
+
+ public void setName(IASTName name) {
+ Assert.isLegal(false);
+ }
+
+ public void setNestedDeclarator(IASTDeclarator nested) {
+ Assert.isLegal(false);
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeclarator.java
index ce6814c949f..f6ca702b48b 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeclarator.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeclarator.java
@@ -25,6 +25,7 @@ import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
/**
* @author jcamelon
@@ -115,23 +116,20 @@ public class CPPASTDeclarator extends CPPASTNode implements IASTDeclarator {
if( !ptrOps[i].accept( action ) ) return false;
}
- if( getPropertyInParent() != IASTTypeId.ABSTRACT_DECLARATOR &&
- nestedDeclarator == null )
- {
- if( getParent() instanceof IASTDeclarator )
- {
- IASTDeclarator outermostDeclarator = (IASTDeclarator) getParent();
- while( outermostDeclarator.getParent() instanceof IASTDeclarator )
- outermostDeclarator = (IASTDeclarator) outermostDeclarator.getParent();
- if( outermostDeclarator.getPropertyInParent() != IASTTypeId.ABSTRACT_DECLARATOR )
- if( name != null ) if( !name.accept( action ) ) return false;
+ if (nestedDeclarator == null && name != null) {
+ IASTDeclarator outermost= CPPVisitor.findOutermostDeclarator(this);
+ if (outermost.getPropertyInParent() != IASTTypeId.ABSTRACT_DECLARATOR) {
+ if (!name.accept(action)) return false;
}
- else
- if( name != null ) if( !name.accept( action ) ) return false;
}
- if( nestedDeclarator != null ) if( !nestedDeclarator.accept( action ) ) return false;
+ if (nestedDeclarator != null) {
+ if (!nestedDeclarator.accept(action)) return false;
+ }
+ if (!postAccept(action))
+ return false;
+
if( action.shouldVisitDeclarators ){
switch( action.leave( this ) ){
case ASTVisitor.PROCESS_ABORT : return false;
@@ -139,8 +137,7 @@ public class CPPASTDeclarator extends CPPASTNode implements IASTDeclarator {
default : break;
}
}
-
- return postAccept( action );
+ return true;
}
protected boolean postAccept( ASTVisitor action ){
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java
index 280d6728d76..7dfb5bd95b1 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java
@@ -274,4 +274,8 @@ public class CPPASTName extends CPPASTNode implements IASTName, IASTCompletionCo
public ILinkage getLinkage() {
return Linkage.CPP_LINKAGE;
}
+
+ public IASTName getLastName() {
+ return this;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java
index 106e7ddaa46..1e4abc2277e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java
@@ -6,19 +6,25 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * IBM - Initial API and implementation
+ * IBM - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
+import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
+import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
-import org.eclipse.cdt.core.parser.util.ArrayUtil;
+import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
+import org.eclipse.core.runtime.Assert;
/**
* @author jcamelon
@@ -31,6 +37,9 @@ public class CPPASTNewExpression extends CPPASTNode implements
private IASTExpression initializer;
private IASTTypeId typeId;
private boolean isNewTypeId;
+
+ private IASTExpression [] arrayExpressions = null;
+
public CPPASTNewExpression() {
@@ -96,20 +105,44 @@ public class CPPASTNewExpression extends CPPASTNode implements
}
public IASTExpression [] getNewTypeIdArrayExpressions() {
- if( arrayExpressions == null ) return IASTExpression.EMPTY_EXPRESSION_ARRAY;
- return (IASTExpression[]) ArrayUtil.trim( IASTExpression.class, arrayExpressions );
+ if( arrayExpressions == null ) {
+ if (typeId != null) {
+ IASTDeclarator dtor= CPPVisitor.findInnermostDeclarator(typeId.getAbstractDeclarator());
+ if (dtor instanceof IASTArrayDeclarator) {
+ IASTArrayDeclarator ad= (IASTArrayDeclarator) dtor;
+ IASTArrayModifier[] ams= ad.getArrayModifiers();
+ arrayExpressions= new IASTExpression[ams.length];
+ for (int i = 0; i < ams.length; i++) {
+ IASTArrayModifier am = ams[i];
+ arrayExpressions[i]= am.getConstantExpression();
+ }
+ return arrayExpressions;
+ }
+ }
+ arrayExpressions= IASTExpression.EMPTY_EXPRESSION_ARRAY;
+ }
+ return arrayExpressions;
}
public void addNewTypeIdArrayExpression(IASTExpression expression) {
- arrayExpressions = (IASTExpression[]) ArrayUtil.append( IASTExpression.class, arrayExpressions, expression );
- if(expression != null) {
- expression.setParent(this);
- expression.setPropertyInParent(NEW_TYPEID_ARRAY_EXPRESSION);
- }
+ Assert.isNotNull(typeId);
+ IASTDeclarator dtor= CPPVisitor.findInnermostDeclarator(typeId.getAbstractDeclarator());
+ if (dtor instanceof IASTArrayDeclarator == false) {
+ Assert.isNotNull(dtor);
+ Assert.isTrue(dtor.getParent() == typeId);
+ IASTArrayDeclarator adtor= new CPPASTArrayDeclarator(dtor.getName());
+ IASTPointerOperator[] ptrOps= dtor.getPointerOperators();
+ for (IASTPointerOperator ptr : ptrOps) {
+ adtor.addPointerOperator(ptr);
+ }
+ typeId.setAbstractDeclarator(adtor);
+ dtor= adtor;
+ }
+ IASTArrayModifier mod= new CPPASTArrayModifier(expression);
+ ((ASTNode) mod).setOffsetAndLength((ASTNode)expression);
+ ((IASTArrayDeclarator) dtor).addArrayModifier(mod);
}
- private IASTExpression [] arrayExpressions = null;
-
@Override
public boolean accept( ASTVisitor action ){
if( action.shouldVisitExpressions ){
@@ -122,11 +155,6 @@ public class CPPASTNewExpression extends CPPASTNode implements
if( placement != null ) if( !placement.accept( action ) ) return false;
if( typeId != null ) if( !typeId.accept( action ) ) return false;
-
- IASTExpression [] exps = getNewTypeIdArrayExpressions();
- for( int i = 0; i < exps.length; i++ )
- if( !exps[i].accept( action ) ) return false;
-
if( initializer != null ) if( !initializer.accept( action ) ) return false;
if( action.shouldVisitExpressions ){
@@ -152,14 +180,6 @@ public class CPPASTNewExpression extends CPPASTNode implements
other.setParent( child.getParent() );
initializer = (IASTExpression) other;
}
- if( arrayExpressions == null ) return;
- for( int i = 0; i < arrayExpressions.length; ++i )
- if( arrayExpressions[i] == child )
- {
- other.setPropertyInParent( child.getPropertyInParent() );
- other.setParent( child.getParent() );
- arrayExpressions[i] = (IASTExpression) other;
- }
}
public IType getExpressionType() {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTParameterDeclaration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTParameterDeclaration.java
index 402275cd28c..ea0b808eeb6 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTParameterDeclaration.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTParameterDeclaration.java
@@ -6,19 +6,22 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * IBM - Initial API and implementation
+ * IBM - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
+import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
/**
* @author jcamelon
*/
-public class CPPASTParameterDeclaration extends CPPASTNode implements ICPPASTParameterDeclaration {
+public class CPPASTParameterDeclaration extends CPPASTNode implements ICPPASTParameterDeclaration, IASTAmbiguityParent {
private IASTDeclSpecifier declSpec;
private IASTDeclarator declarator;
@@ -78,4 +81,12 @@ public class CPPASTParameterDeclaration extends CPPASTNode implements ICPPASTPar
}
return true;
}
+
+ public void replace(IASTNode child, IASTNode other) {
+ if (child == declarator) {
+ other.setPropertyInParent(child.getPropertyInParent());
+ other.setParent(child.getParent());
+ declarator= (IASTDeclarator) other;
+ }
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java
index 9d651bd4b4a..01aa578e36e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java
@@ -99,10 +99,10 @@ public class CPPASTQualifiedName extends CPPASTNode implements
}
public IASTName getLastName() {
- if (names == null || names.length == 0)
+ if (namesPos < 0)
return null;
- return names[names.length - 1];
+ return names[namesPos];
}
public char[] toCharArray() {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java
index 9329912db9a..a85546022dc 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java
@@ -197,10 +197,11 @@ public class CPPASTTemplateId extends CPPASTNode implements ICPPASTTemplateId, I
}
}
- /* (non-Javadoc)
- * @see org.eclipse.cdt.core.dom.ast.IASTName#getLinkage()
- */
public ILinkage getLinkage() {
return Linkage.CPP_LINKAGE;
}
+
+ public IASTName getLastName() {
+ return this;
+ }
}
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 d9f7c3fabfc..933be75beca 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
@@ -16,7 +16,6 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
@@ -78,6 +77,7 @@ 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.IASTEnumerationSpecifier.IASTEnumerator;
+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;
@@ -85,6 +85,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
@@ -124,7 +125,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTBinaryExpression;
-import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointer;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointerToMember;
@@ -141,14 +141,18 @@ 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;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser;
import org.eclipse.cdt.internal.core.dom.parser.BacktrackException;
-import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclaration;
+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.parser.SimpleDeclarationStrategy;
+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;
@@ -162,17 +166,18 @@ import org.eclipse.cdt.internal.core.parser.token.TokenFactory;
* @author jcamelon
*/
public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
-
-
- private static final int DEFAULT_CATCH_HANDLER_LIST_SIZE = 4;
-
-
+ private static final int DEFAULT_CATCH_HANDLER_LIST_SIZE= 4;
+ private static final int DEFAULT_PARAMETER_LIST_SIZE= 4;
+ private static final ASTVisitor EMPTY_VISITOR = new ASTVisitor() {};
+ private static enum DtorStrategy {PREFER_FUNCTION, PREFER_NESTED}
+
private ScopeStack templateIdScopes = new ScopeStack();
-
private int templateCount = 0;
private int functionBodyCount= 0;
private int templateArgListCount= 0;
- private int rejectLogicalOperatorInTemplateID;
+ private int rejectLogicalOperatorInTemplateID= 0;
+ private char[] currentClassName;
+
protected CPPASTTranslationUnit translationUnit;
@@ -287,7 +292,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
try {
while (LT(1) != IToken.tGT && LT(1) != IToken.tEOC) {
IToken argStart = mark();
- IASTTypeId typeId = typeId(false);
+ IASTTypeId typeId = typeId(DeclarationOptions.TYPEID);
if(typeId != null && (LT(1)==IToken.tCOMMA || LT(1)==IToken.tGT || LT(1)==IToken.tEOC)) {
// potentially a type-id - check for id-expression ambiguity
@@ -548,8 +553,10 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
} else {
// must be a conversion function
IToken t = LA(1);
- typeId = typeId(true);
- if (typeId == null) throw backtrack;
+ typeId= typeId(DeclarationOptions.TYPEID_CONVERSION);
+ if (typeId == null)
+ throwBacktrack(t);
+
if (t != LA(1)) {
while (t.getNext() != LA(1)) {
t = t.getNext();
@@ -943,7 +950,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
try {
if (!avoidCastExpressionByHeuristics()) {
- IASTTypeId typeId = typeId(false);
+ IASTTypeId typeId = typeId(DeclarationOptions.TYPEID);
if (typeId != null && LT(1) == IToken.tRPAREN) {
consume();
if (initialSize > 0) {
@@ -970,7 +977,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
@Override
- protected IASTTypeId typeId(boolean forNewExpression) throws EndOfFileException {
+ protected IASTTypeId typeId(DeclarationOptions option) throws EndOfFileException {
if (!canBeTypeSpecifier()) {
return null;
}
@@ -979,57 +986,17 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
IASTDeclSpecifier declSpecifier = null;
IASTDeclarator declarator = null;
try {
- try {
- declSpecifier = declSpecifierSeq(true, true);
- }
- catch (FoundDeclaratorException e) {
- return null;
+ declSpecifier = declSpecifierSeq(option);
+ if (LT(1) != IToken.tEOC) {
+ declarator= declarator(DtorStrategy.PREFER_FUNCTION, option);
}
- if (LT(1) != IToken.tEOC)
- declarator = declarator(SimpleDeclarationStrategy.TRY_FUNCTION, forNewExpression);
+ } catch (FoundDeclaratorException e) {
+ declSpecifier= e.declSpec;
+ declarator= e.declarator;
+ backup(e.currToken);
} catch (BacktrackException bt) {
return null;
- /*
- backup(mark);
- if (declarator != null || declSpecifier != null)
- throwBacktrack(startingOffset, figureEndOffset(declSpecifier,
- declarator)
- - startingOffset);
- else
- throwBacktrack(startingOffset, bt.getLength());
- */
}
- if (declarator != null) {
- if (declarator.getName().toCharArray().length > 0) {
- return null;
- /*
- backup(mark);
- throwBacktrack(startingOffset, figureEndOffset(declSpecifier,
- declarator)
- - startingOffset);
- */
- }
- if (declSpecifier instanceof IASTSimpleDeclSpecifier
- && ((ASTNode) declSpecifier).getLength() == 0) {
- return null;
- /*
- backup(mark);
- throwBacktrack(startingOffset, figureEndOffset(declSpecifier,
- declarator)
- - startingOffset);
- */
- }
- if (declarator instanceof IASTArrayDeclarator && forNewExpression) {
- return null;
- /*
- backup(mark);
- throwBacktrack(startingOffset, figureEndOffset(declSpecifier,
- declarator)
- - startingOffset);
- */
- }
- }
-
IASTTypeId result = createTypeId();
((ASTNode) result).setOffsetAndLength(startingOffset, figureEndOffset(
declSpecifier, declarator) - startingOffset);
@@ -1078,238 +1045,140 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
/**
- * Parse a new-expression.
- *
- * @throws BacktrackException
- * newexpression: ::? new newplacement? newtypeid
- * newinitializer? ::? new newplacement? ( typeid )
- * newinitializer? newplacement: ( expressionlist ) newtypeid:
- * typespecifierseq newdeclarator? newdeclarator: ptroperator *
- * newdeclarator? | directnewdeclarator directnewdeclarator: [
- * expression ] directnewdeclarator [ constantexpression ]
- * newinitializer: ( expressionlist? )
+ * Parse a new-expression. There is room for ambiguities. With P for placement, T for typeid,
+ * and I for initializer the potential patterns (with the new omitted) are:
+ * easy: T, T(I)
+ * medium: (P) T(I), (P) (T)(I)
+ * hard: (T), (P) T, (P) T, (P) (T), (T)(I)
*/
protected IASTExpression newExpression() throws BacktrackException, EndOfFileException {
IToken la = LA(1);
- int startingOffset = la.getOffset();
- int lastOffset = 0;
+ int offset= la.getOffset();
- boolean isGlobal = false;
- if (LT(1) == IToken.tCOLONCOLON) {
- lastOffset = consume().getEndOffset();
- isGlobal = true;
+ final boolean isGlobal = la.getType() == IToken.tCOLONCOLON;
+ if (isGlobal) {
+ consume();
}
- lastOffset = consume().getEndOffset();
- boolean typeIdInParen = false;
- boolean placementParseFailure = true;
- IToken beforeSecondParen = null;
- IToken backtrackMarker = null;
- IASTTypeId typeId = null;
- IASTExpression newPlacementExpressions = null;
- IASTExpression newInitializerExpressions = null;
- boolean isNewTypeId = false;
+ consume(IToken.t_new);
+ if (LT(1) == IToken.tLPAREN) {
+ consume();
- master_new_loop: for (int i = 0; i < 2; ++i) {
- IToken loopMark = LA(1);
- if (LT(1) == IToken.tLPAREN) {
- lastOffset = consume().getEndOffset();
- if (templateIdScopes.size() > 0) {
- templateIdScopes.push(IToken.tLPAREN);
- }
- try {
- // Try to consume placement list
- if (i == 0) {
- backtrackMarker = mark();
- newPlacementExpressions = expression();
- lastOffset = consume(IToken.tRPAREN).getEndOffset();
- if (LT(1) == IToken.tLBRACKET) {
- backup(backtrackMarker);
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
- } // pop 1st Parent
- placementParseFailure = true;
- throwBacktrack(backtrackMarker.getOffset(),
- backtrackMarker.getLength());
- } else
- placementParseFailure = false;
- }
+ // consider placement first (P) ...
+ IASTExpression plcmt= null;
+ IASTTypeId typeid= null;
+ boolean isNewTypeId= true;
+ IASTExpression init= null;
+ int endOffset= 0;
+ IToken mark= mark();
+ IToken end= null;
+ try {
+ plcmt= expression();
+ endOffset= consumeOrEOC(IToken.tRPAREN).getEndOffset();
+
+ if (LT(1) == IToken.tLPAREN) {
+ // (P)(T) ...
+ isNewTypeId= false;
+ consume(IToken.tLPAREN);
+ typeid= typeId(DeclarationOptions.TYPEID);
+ if (typeid == null)
+ throw backtrack;
+ endOffset= consumeOrEOC(IToken.tRPAREN).getEndOffset();
+ } else {
+ // (P) T ...
+ typeid= typeId(DeclarationOptions.TYPEID_NEW);
+ if (typeid == null)
+ throw backtrack;
+ endOffset= calculateEndOffset(typeid);
+ }
+ end= LA(1);
+ } catch (BacktrackException e) {
+ plcmt= null;
+ typeid= null;
+ }
- if (LT(1) == IToken.tLPAREN) {
- beforeSecondParen = mark();
- lastOffset = consume().getEndOffset();
- if (templateIdScopes.size() > 0) {
- templateIdScopes.push(IToken.tLPAREN);
- } // push 2nd Paren
- typeIdInParen = true;
- }
- } catch (BacktrackException e) {
- backup(backtrackMarker);
- }
- if (placementParseFailure) {
- // CASE: new (typeid-not-looking-as-placement) ...
- // the first expression in () is not a placement
- // - then it has to be typeId
- typeId = typeId(false);
- if (typeId == null) throw backtrack;
- lastOffset = consume(IToken.tRPAREN).getEndOffset();
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
- } // pop 1st Paren
- break master_new_loop;
- }
- if (!typeIdInParen) {
- if (LT(1) == IToken.tLBRACKET) {
- // CASE: new (typeid-looking-as-placement) [expr]...
- // the first expression in () has been parsed as a
- // placement;
- // however, we assume that it was in fact typeId, and
- // this
- // new statement creates an array.
- // Do nothing, fallback to array/initializer processing
- } else {
- // CASE: new (placement) typeid ...
- // the first expression in () is parsed as a placement,
- // and the next expression doesn't start with '(' or '['
- // - then it has to be typeId
- backtrackMarker = mark();
- typeId = typeId(true);
- if (typeId != null) {
- lastOffset = calculateEndOffset(typeId);
- break master_new_loop;
- }
- // Hmmm, so it wasn't typeId after all... Then it is
- // CASE: new (typeid-looking-as-placement)
- backup(loopMark);
- placementParseFailure = true;
- continue master_new_loop;
- }
- } else {
- // Tricky cases: first expression in () is parsed as a
- // placement,
- // and the next expression starts with '('.
- // The problem is, the first expression might as well be a
- // typeid
- typeId = typeId(true);
- if (typeId == null) {
- backup(beforeSecondParen);
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
- }
- } else
- try {
- lastOffset = consume(IToken.tRPAREN).getEndOffset();
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
- } // popping the 2nd Paren
-
- if (LT(1) == IToken.tLPAREN
- || LT(1) == IToken.tLBRACKET) {
- // CASE: new (placement)(typeid)(initializer)
- // CASE: new (placement)(typeid)[] ...
- // Great, so far all our assumptions have been
- // correct
- // Do nothing, fallback to array/initializer
- // processing
- } else {
- // CASE: new (placement)(typeid)
- // CASE: new
- // (typeid-looking-as-placement)(initializer-looking-as-typeid)
- // Worst-case scenario - this cannot be resolved w/o
- // more semantic information.
- // Luckily, we don't need to know what was that - we
- // only know that
- // new-expression ends here.
- ICPPASTNewExpression result = createNewExpression();
- ((ASTNode) result)
- .setOffsetAndLength(startingOffset,
- lastOffset - startingOffset);
- result.setIsGlobal(isGlobal);
- result.setIsNewTypeId(isNewTypeId);
- result.setTypeId(typeId);
- if (newPlacementExpressions != null) {
- result.setNewPlacement(newPlacementExpressions);
- }
- return result;
- }
- break master_new_loop;
- } catch (BacktrackException e) {
- // CASE: new
- // (typeid-looking-as-placement)(initializer-not-looking-as-typeid)
- // Fallback to initializer processing
- backup(beforeSecondParen);
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
- }// pop that 2nd paren
- }
- }
- } else {
- // CASE: new typeid ...
- // new parameters do not start with '('
- // i.e it has to be a plain typeId
- typeId = typeId(true);
- if (typeId == null) throw backtrack;
- lastOffset = calculateEndOffset(typeId);
- isNewTypeId = true;
- break master_new_loop;
- }
- }
- ICPPASTNewExpression result = createNewExpression();
- ((ASTNode) result).setOffsetAndLength(startingOffset, lastOffset
- - startingOffset);
- result.setIsGlobal(isGlobal);
- if (typeId != null) {
- result.setIsNewTypeId(isNewTypeId);
- result.setTypeId(typeId);
- }
- if (newPlacementExpressions != null) {
- result.setNewPlacement(newPlacementExpressions);
- }
+ if (typeid != null && plcmt != null && LT(1) == IToken.tLPAREN) {
+ // (P)(T)(I) or (P) T (I)
+ consume(IToken.tLPAREN);
+ init= possiblyEmptyExpressionList(IToken.tRPAREN);
+ endOffset= consumeOrEOC(IToken.tRPAREN).getEndOffset();
+ return newExpression(isGlobal, plcmt, typeid, isNewTypeId, init, offset, endOffset);
+ }
- while (LT(1) == IToken.tLBRACKET) {
- // array new
- lastOffset = consume().getEndOffset();
+ // (T) ...
+ backup(mark);
+ IASTTypeId typeid2= null;
+ IASTExpression init2= null;
+ int endOffset2;
+ try {
+ typeid2= typeId(DeclarationOptions.TYPEID);
+ if (typeid2 == null)
+ throw backtrack;
+ endOffset2= consumeOrEOC(IToken.tRPAREN).getEndOffset();
+
+ if (LT(1) == IToken.tLPAREN) {
+ if (plcmt != null &&
+ CPPVisitor.findTypeRelevantDeclarator(typeid2.getAbstractDeclarator()) instanceof IASTArrayDeclarator) {
+ throwBacktrack(LA(1));
+ }
+
+ // (T)(I)
+ consume(IToken.tLPAREN);
+ init2= possiblyEmptyExpressionList(IToken.tRPAREN);
+ endOffset2= consumeOrEOC(IToken.tRPAREN).getEndOffset();
+ }
+ } catch (BacktrackException e) {
+ if (plcmt == null)
+ throw e;
+ endOffset2= -1;
+ }
+
- if (templateIdScopes.size() > 0) {
- templateIdScopes.push(IToken.tLBRACKET);
- }
+ if (plcmt == null || endOffset2 > endOffset)
+ return newExpression(isGlobal, null, typeid2, false, init2, offset, endOffset2);
- IASTExpression a = assignmentExpression();
- lastOffset = consume(IToken.tRBRACKET).getEndOffset();
- result.addNewTypeIdArrayExpression(a);
+ if (endOffset != endOffset2) {
+ backup(end);
+ return newExpression(isGlobal, plcmt, typeid, isNewTypeId, init, offset, endOffset);
+ }
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
- }
+ // ambiguity:
+ IASTExpression ex1= newExpression(isGlobal, plcmt, typeid, isNewTypeId, init, offset, endOffset);
+ IASTExpression ex2= newExpression(isGlobal, null, typeid2, false, init2, offset, endOffset2);
+ IASTAmbiguousExpression ambiguity= createAmbiguousExpression();
+ ambiguity.addExpression(ex1);
+ ambiguity.addExpression(ex2);
+ ((ASTNode) ambiguity).setOffsetAndLength((ASTNode) ex1);
+ return ambiguity;
}
- // newinitializer
- if (LT(1) == IToken.tLPAREN) {
- lastOffset = consume().getEndOffset();
- if (templateIdScopes.size() > 0) {
- templateIdScopes.push(IToken.tLPAREN);
- }
-
- // we want to know the difference between no newInitializer and an
- // empty new Initializer
- // if the next token is the RPAREN, then we have an Empty expression
- // in our list.
- if (LT(1) != IToken.tRPAREN)
- newInitializerExpressions = expression();
-
- if (LT(1) == IToken.tEOC) {
- lastOffset = consume().getEndOffset();
- } else {
- lastOffset = consume(IToken.tRPAREN).getEndOffset();
- }
-
- if (templateIdScopes.size() > 0) {
- templateIdScopes.pop();
- }
- if (newInitializerExpressions != null) {
- result.setNewInitializer(newInitializerExpressions);
- }
+
+ // T ...
+ final IASTTypeId typeid = typeId(DeclarationOptions.TYPEID_NEW);
+ if (typeid == null)
+ throw backtrack;
+ int endOffset = calculateEndOffset(typeid);
+ IASTExpression init= null;
+ if (LT(1) == IToken.tLPAREN) {
+ // T(I)
+ consume(IToken.tLPAREN);
+ init= possiblyEmptyExpressionList(IToken.tRPAREN);
+ endOffset= consumeOrEOC(IToken.tRPAREN).getEndOffset();
+ }
+ return newExpression(isGlobal, null, typeid, true, init, offset, endOffset);
+ }
+ private IASTExpression newExpression(boolean isGlobal, IASTExpression placement, IASTTypeId typeid,
+ boolean isNewTypeId, IASTExpression init, int offset, int endOffset) {
+ ICPPASTNewExpression result = createNewExpression();
+ result.setIsGlobal(isGlobal);
+ result.setIsNewTypeId(isNewTypeId);
+ result.setTypeId(typeid);
+ if (placement != null) {
+ result.setNewPlacement(placement);
}
- ((ASTNode) result).setLength(lastOffset - startingOffset);
+ if (init != null) {
+ result.setNewInitializer(init);
+ }
+ ((ASTNode) result).setOffsetAndLength(offset, endOffset - offset);
return result;
}
@@ -1827,7 +1696,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
int startingOffset = LA(1).getOffset();
IToken op = consume();
consume(IToken.tLT);
- IASTTypeId typeID = typeId(false);
+ IASTTypeId typeID = typeId(DeclarationOptions.TYPEID);
if (typeID == null) { throw backtrack; }
consume(IToken.tGT);
consume(IToken.tLPAREN);
@@ -1867,8 +1736,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
private final boolean supportMinAndMaxOperators;
- private final boolean supportComplex;
-
private final boolean supportLongLong;
private final IIndex index;
@@ -1907,7 +1774,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
allowCPPRestrict = config.allowRestrictPointerOperators();
supportExtendedTemplateSyntax = config.supportExtendedTemplateSyntax();
supportMinAndMaxOperators = config.supportMinAndMaxOperators();
- supportComplex = config.supportComplexNumbers();
supportLongLong = config.supportLongLongs();
this.index= index;
}
@@ -1923,7 +1789,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
*/
protected IASTDeclaration usingClause() throws EndOfFileException,
BacktrackException {
- IToken firstToken = consume();
+ final int offset= consume().getOffset();
if (LT(1) == IToken.t_namespace) {
// using-directive
@@ -1936,7 +1802,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
name = createName(name());
break;
default:
- throwBacktrack(firstToken.getOffset(), endOffset - firstToken.getOffset());
+ throwBacktrack(offset, endOffset - offset);
}
switch (LT(1)) {
@@ -1949,13 +1815,18 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
ICPPASTUsingDirective astUD = createUsingDirective();
- ((ASTNode) astUD).setOffsetAndLength(firstToken.getOffset(), endOffset - firstToken.getOffset());
+ ((ASTNode) astUD).setOffsetAndLength(offset, endOffset - offset);
astUD.setQualifiedName(name);
return astUD;
}
- boolean typeName = false;
+ ICPPASTUsingDeclaration result = usingDeclaration(offset);
+ return result;
+ }
+ private ICPPASTUsingDeclaration usingDeclaration(final int offset) throws EndOfFileException,
+ BacktrackException {
+ boolean typeName = false;
if (LT(1) == IToken.t_typename) {
typeName = true;
consume();
@@ -1973,11 +1844,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
ICPPASTUsingDeclaration result = createUsingDeclaration();
- ((ASTNode) result).setOffsetAndLength(firstToken.getOffset(), end - firstToken.getOffset());
+ ((ASTNode) result).setOffsetAndLength(offset, end - offset);
result.setIsTypename(typeName);
result.setName(name);
- return result;
- }
+ return result;
+ }
protected ICPPASTUsingDeclaration createUsingDeclaration() {
@@ -2015,7 +1886,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
break linkageDeclarationLoop;
default:
try {
- IASTDeclaration d = declaration();
+ IASTDeclaration d = declaration(DeclarationOptions.GLOBAL);
linkage.addDeclaration(d);
} catch (BacktrackException bt) {
IASTProblem p = failParse(bt);
@@ -2038,7 +1909,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
// single declaration
- IASTDeclaration d = declaration();
+ IASTDeclaration d = declaration(DeclarationOptions.GLOBAL);
linkage.addDeclaration(d);
((ASTNode) linkage).setLength(calculateEndOffset(d) - firstToken.getOffset());
return linkage;
@@ -2054,11 +1925,12 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* template-declaration: export? template < template-parameter-list >
* declaration explicit-instantiation: template declaration
* explicit-specialization: template <>declaration
+ * @param option
*
* @throws BacktrackException
* request for a backtrack
*/
- protected IASTDeclaration templateDeclaration() throws EndOfFileException,
+ protected IASTDeclaration templateDeclaration(DeclarationOptions option) throws EndOfFileException,
BacktrackException {
IToken mark = mark();
IToken firstToken = null;
@@ -2106,7 +1978,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
} else
templateInstantiation = createTemplateInstantiation();
try {
- IASTDeclaration d = declaration();
+ IASTDeclaration d = declaration(option);
((ASTNode) templateInstantiation).setOffsetAndLength(firstToken
.getOffset(), calculateEndOffset(d) - firstToken.getOffset());
templateInstantiation.setDeclaration(d);
@@ -2122,7 +1994,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
ICPPASTTemplateSpecialization templateSpecialization = createTemplateSpecialization();
try {
- IASTDeclaration d = declaration();
+ IASTDeclaration d = declaration(option);
((ASTNode) templateSpecialization).setOffsetAndLength(
firstToken.getOffset(), calculateEndOffset(d) - firstToken.getOffset());
templateSpecialization.setDeclaration(d);
@@ -2139,7 +2011,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
ICPPASTTemplateDeclaration templateDecl = createTemplateDeclaration();
try
{
- IASTDeclaration d = declaration();
+ IASTDeclaration d = declaration(option);
((ASTNode) templateDecl).setOffsetAndLength(firstToken.getOffset(),
calculateEndOffset(d) - firstToken.getOffset());
templateDecl.setExported(exported);
@@ -2219,7 +2091,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
lastOffset = calculateEndOffset(identifierName);
if (LT(1) == IToken.tASSIGN) { // optional = type-id
consume();
- typeId = typeId(false); // type-id
+ typeId = typeId(DeclarationOptions.TYPEID); // type-id
if (typeId == null)
throw backtrack;
lastOffset = calculateEndOffset(typeId);
@@ -2305,7 +2177,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* request a backtrack
*/
@Override
- protected IASTDeclaration declaration() throws EndOfFileException, BacktrackException {
+ protected IASTDeclaration declaration(DeclarationOptions option) throws EndOfFileException, BacktrackException {
switch (LT(1)) {
case IToken.t_asm:
return asmDeclaration();
@@ -2315,96 +2187,31 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return usingClause();
case IToken.t_export:
case IToken.t_template:
- return templateDeclaration();
+ return templateDeclaration(option);
case IToken.t_extern:
if (LT(2) == IToken.tSTRING)
return linkageSpecification();
if (supportExtendedTemplateSyntax && LT(2) == IToken.t_template)
- return templateDeclaration();
+ return templateDeclaration(option);
break;
case IToken.t_static:
case IToken.t_inline:
if (supportExtendedTemplateSyntax && LT(2) == IToken.t_template)
- return templateDeclaration();
+ return templateDeclaration(option);
break;
+ case IToken.tSEMI:
+ IToken t= consume();
+ IASTSimpleDeclaration decl= createSimpleDeclaration();
+ IASTSimpleDeclSpecifier declspec= createSimpleDeclSpecifier();
+ decl.setDeclSpecifier(declspec);
+ ((ASTNode) declspec).setOffsetAndLength(t.getOffset(), 0);
+ ((ASTNode) decl).setOffsetAndLength(t.getOffset(), t.getLength());
+ return decl;
}
- return simpleDeclarationStrategyUnion();
+ return simpleDeclaration(option);
}
-
- protected IASTDeclaration simpleDeclarationStrategyUnion() throws EndOfFileException, BacktrackException {
- IToken simpleDeclarationMark = mark();
- IASTDeclaration d1 = null, d2 = null;
- IToken after = null;
- try {
- d1 = simpleDeclaration(SimpleDeclarationStrategy.TRY_FUNCTION, false);
- try {
- after = LA(1);
- } catch (EndOfFileException eof) {
- }
- } catch (BacktrackException bt) {
- }
- if (d1 != null) {
- if( templateCount != 0 )
- return d1;
- if( functionBodyCount == 0 )
- return d1;
- if (d1 instanceof IASTFunctionDefinition)
- return d1;
- if (d1 instanceof IASTSimpleDeclaration) {
- IASTSimpleDeclaration sd = (IASTSimpleDeclaration) d1;
- if( sd.getDeclSpecifier() instanceof ICPPASTDeclSpecifier && ((ICPPASTDeclSpecifier)sd.getDeclSpecifier()).isFriend() )
- return d1;
- if (sd.getDeclarators().length != 1)
- return d1;
- if (sd.getDeclSpecifier() instanceof IASTSimpleDeclSpecifier) {
- IASTSimpleDeclSpecifier simpleSpec = (IASTSimpleDeclSpecifier) sd.getDeclSpecifier();
- if( simpleSpec.getType() == IASTSimpleDeclSpecifier.t_void && sd.getDeclarators()[0].getPointerOperators().length == 0 )
- return d1;
- }
-
- if (sd.getDeclarators()[0] instanceof IASTStandardFunctionDeclarator) {
- if (sd.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef)
- return d1;
- } else
- return d1;
- }
- }
-
- // did not work
- backup(simpleDeclarationMark);
-
- try {
- d2 = simpleDeclaration(SimpleDeclarationStrategy.TRY_VARIABLE, false);
- if (after != null && after != LA(1)) {
- backup(after);
- return d1;
- }
- } catch (BacktrackException be) {
- if (d1 == null)
- throw be;
- }
-
- if (d2 == null && d1 != null) {
- backup(after);
- return d1;
- }
-
- if (d1 == null && d2 != null)
- return d2;
-
- IASTAmbiguousDeclaration result = createAmbiguousDeclaration();
- ((ASTNode) result).setOffsetAndLength((ASTNode) d1);
- result.addDeclaration(d1);
- result.addDeclaration(d2);
- return result;
- }
-
- protected IASTAmbiguousDeclaration createAmbiguousDeclaration() {
- return new CPPASTAmbiguousDeclaration();
- }
-
/**
* Serves as the namespace declaration portion of the ANSI C++ grammar.
* namespace-definition: namespace identifier { namespace-body } | namespace {
@@ -2441,7 +2248,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
default:
int checkToken = LA(1).hashCode();
try {
- IASTDeclaration d = declaration();
+ IASTDeclaration d = declaration(DeclarationOptions.GLOBAL);
namespaceDefinition.addDeclaration(d);
} catch (BacktrackException bt) {
IASTProblem p = failParse(bt);
@@ -2641,157 +2448,139 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
/**
- * Serves as the catch-all for all complicated declarations, including
- * function-definitions. simpleDeclaration : (declSpecifier)*
- * (initDeclarator ("," initDeclarator)*)? (";" | { functionBody } Notes: -
- * append functionDefinition stuff to end of this rule To do: - work in
- * functionTryBlock
- *
- * @throws BacktrackException
- * request a backtrack
+ * Parses a declaration with the given options.
*/
- protected IASTDeclaration simpleDeclaration(
- SimpleDeclarationStrategy strategy, boolean fromCatchHandler)
+ protected IASTDeclaration simpleDeclaration(DeclarationOptions option)
throws BacktrackException, EndOfFileException {
- IToken firstToken = LA(1);
- int firstOffset = firstToken.getOffset();
+ final IToken firstToken = LA(1);
if (firstToken.getType() == IToken.tLBRACE)
- throwBacktrack(firstOffset, firstToken.getLength());
- firstToken = null; // necessary for scalability
+ throwBacktrack(firstToken);
+
+ final int firstOffset= firstToken.getOffset();
+ int endOffset= firstOffset;
- IASTDeclSpecifier declSpec;
- IASTDeclarator[] declarators = new IASTDeclarator[2];
- boolean tryAgain = false;
+ ICPPASTDeclSpecifier declSpec;
+ IASTDeclarator dtor= null;
try {
- declSpec = declSpecifierSeq(false, false);
+ declSpec = declSpecifierSeq(option);
+ final int lt1= LT(1);
+ if (lt1 == IToken.tSEMI) {
+ if (!validWithoutDtor(option, declSpec)) {
+ throwBacktrack(LA(1));
+ }
+ } else if (lt1 != IToken.tEOC) {
+ dtor= initDeclarator(declSpec, option);
+ }
} catch (FoundDeclaratorException e) {
- tryAgain = true;
- declSpec = e.declSpec;
- declarators = (IASTDeclarator[]) ArrayUtil.append(IASTDeclarator.class, declarators, e.declarator);
- backup( e.currToken );
+ declSpec= (ICPPASTDeclSpecifier) e.declSpec;
+ dtor= e.declarator;
+ backup(e.currToken);
}
- if (LT(1) != IToken.tSEMI && LT(1) != IToken.tEOC) {
- if( !tryAgain )
- declarators = (IASTDeclarator[]) ArrayUtil.append(IASTDeclarator.class, declarators, initDeclarator(strategy));
- while (LT(1) == IToken.tCOMMA) {
- consume();
- declarators = (IASTDeclarator[]) ArrayUtil.append(IASTDeclarator.class, declarators, initDeclarator(strategy));
- }
+ IASTDeclarator[] declarators= {dtor};
+ while (LT(1) == IToken.tCOMMA) {
+ consume();
+ declarators= (IASTDeclarator[]) ArrayUtil.append( IASTDeclarator.class, declarators, initDeclarator(declSpec, option));
}
+ declarators= (IASTDeclarator[]) ArrayUtil.removeNulls( IASTDeclarator.class, declarators );
- declarators = (IASTDeclarator[]) ArrayUtil.removeNulls(IASTDeclarator.class, declarators);
-
- boolean hasFunctionBody = false;
+ boolean needFunctionBody = false;
boolean hasFunctionTryBlock = false;
- boolean consumedSemi = false;
- int semiOffset = 0;
- List<IASTNode> constructorChain = Collections.emptyList();
switch (LT(1)) {
+ case IToken.tEOC:
+ endOffset= figureEndOffset(declSpec, declarators);
+ break;
case IToken.tSEMI:
- if( fromCatchHandler )
- break;
- semiOffset = consume().getEndOffset();
- consumedSemi = true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_try:
consume();
- if (LT(1) == IToken.tCOLON) {
- constructorChain = new ArrayList<IASTNode>(DEFAULT_CONSTRUCTOR_CHAIN_LIST_SIZE);
- ctorInitializer(constructorChain);
- }
- hasFunctionTryBlock = true;
+ needFunctionBody= true;
+ hasFunctionTryBlock= true;
break;
case IToken.tCOLON:
- constructorChain = new ArrayList<IASTNode>(DEFAULT_CONSTRUCTOR_CHAIN_LIST_SIZE);
- ctorInitializer(constructorChain);
- hasFunctionBody = true;
- break;
case IToken.tLBRACE:
- break;
- case IToken.tRPAREN:
- if (!fromCatchHandler)
- throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset);
- break;
- case IToken.tEOC:
- // Pretend we consumed the semi
- consumedSemi = true;
+ needFunctionBody = true;
break;
default:
throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset);
}
- if (!consumedSemi) {
- if (LT(1) == IToken.tLBRACE) {
- hasFunctionBody = true;
- }
-
- if (hasFunctionTryBlock && !hasFunctionBody)
- throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset);
+ if (needFunctionBody) {
+ if (declarators.length != 1)
+ throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset);
+
+ // mstodo
+ final IASTDeclarator fdtor= declarators[0];
+ if (fdtor instanceof ICPPASTFunctionDeclarator == false)
+ throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset);
+
+ return functionDefinition(firstOffset, declSpec, fdtor, hasFunctionTryBlock);
}
- if (hasFunctionBody) {
- if (declarators.length != 1)
- throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset);
-
- IASTDeclarator declarator = declarators[0];
- if (!(declarator instanceof IASTStandardFunctionDeclarator))
- throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset);
-
- if (!constructorChain.isEmpty() && declarator instanceof ICPPASTFunctionDeclarator) {
- ICPPASTFunctionDeclarator fd = (ICPPASTFunctionDeclarator) declarator;
-
- int size = constructorChain.size();
- for (int i = 0; i < size; ++i) {
- ICPPASTConstructorChainInitializer initializer = (ICPPASTConstructorChainInitializer) constructorChain.get(i);
- fd.addConstructorToChain(initializer);
- }
+ // no function body
+ IASTSimpleDeclaration simpleDeclaration= createSimpleDeclaration();
+ simpleDeclaration.setDeclSpecifier(declSpec);
+ for (IASTDeclarator declarator : declarators) {
+ simpleDeclaration.addDeclarator(declarator);
+ }
+
+ ((ASTNode) simpleDeclaration).setOffsetAndLength(firstOffset, endOffset-firstOffset);
+ return simpleDeclaration;
+ }
- // fix for 86698, now that the constructorChain is established,
- // update the declarator's length
- if (fd instanceof ASTNode && constructorChain.get(size - 1) instanceof ASTNode) {
- ASTNode init = (ASTNode) constructorChain.get(size - 1);
- ((ASTNode) fd).setLength(init.getOffset() + init.getLength() - ((ASTNode) fd).getOffset());
- }
- }
+ private boolean validWithoutDtor(DeclarationOptions option, ICPPASTDeclSpecifier declSpec) {
+ if (declSpec instanceof IASTCompositeTypeSpecifier)
+ return true;
+ if (declSpec instanceof IASTElaboratedTypeSpecifier)
+ return true;
+ if (declSpec instanceof IASTEnumerationSpecifier)
+ return true;
+
+ return false;
+ }
- IASTFunctionDefinition funcDefinition = createFunctionDefinition();
- ((ASTNode) funcDefinition).setOffset(firstOffset);
- funcDefinition.setDeclSpecifier(declSpec);
- funcDefinition.setDeclarator((IASTStandardFunctionDeclarator) declarator);
+ private IASTDeclaration functionDefinition(final int firstOffset, IASTDeclSpecifier declSpec,
+ IASTDeclarator declarator, boolean hasFunctionTryBlock)
+ throws EndOfFileException, BacktrackException {
+ if (LT(1) == IToken.tCOLON) {
+ List<ICPPASTConstructorChainInitializer> constructorChain= new ArrayList<ICPPASTConstructorChainInitializer>(DEFAULT_CONSTRUCTOR_CHAIN_LIST_SIZE);
+ ctorInitializer(constructorChain);
+ if (!constructorChain.isEmpty() && declarator instanceof ICPPASTFunctionDeclarator) {
+ ICPPASTFunctionDeclarator fd = (ICPPASTFunctionDeclarator) declarator;
+ for (ICPPASTConstructorChainInitializer initializer : constructorChain) {
+ fd.addConstructorToChain(initializer);
+ }
+ // fix for 86698, update the declarator's length
+ adjustLength(fd, constructorChain.get(constructorChain.size()-1));
+ }
+ }
- IASTStatement s = handleFunctionBody();
- if (s != null) {
- funcDefinition.setBody(s);
- }
- ((ASTNode) funcDefinition).setLength(calculateEndOffset(s) - firstOffset);
-
- if (hasFunctionTryBlock && declarator instanceof ICPPASTFunctionTryBlockDeclarator) {
- List<ICPPASTCatchHandler> handlers = new ArrayList<ICPPASTCatchHandler>(DEFAULT_CATCH_HANDLER_LIST_SIZE);
- catchHandlerSequence(handlers);
- for (int i = 0; i < handlers.size(); ++i) {
- ICPPASTCatchHandler handler = handlers.get(i);
- ((ICPPASTFunctionTryBlockDeclarator) declarator).addCatchHandler(handler);
- ((ASTNode) funcDefinition).setLength(calculateEndOffset(handler) - firstOffset);
- }
- }
- return funcDefinition;
- }
- IASTSimpleDeclaration simpleDeclaration = createSimpleDeclaration();
- int length = figureEndOffset(declSpec, declarators) - firstOffset;
- if (consumedSemi)
- length = semiOffset - firstOffset;
+ final IASTStatement body= handleFunctionBody();
+ int endOffset= calculateEndOffset(body);
- ((ASTNode) simpleDeclaration).setOffsetAndLength(firstOffset, length);
- simpleDeclaration.setDeclSpecifier(declSpec);
+ if (hasFunctionTryBlock) {
+ List<ICPPASTCatchHandler> handlers = new ArrayList<ICPPASTCatchHandler>(DEFAULT_CATCH_HANDLER_LIST_SIZE);
+ catchHandlerSequence(handlers);
+ if (!handlers.isEmpty() && declarator instanceof ICPPASTFunctionTryBlockDeclarator) {
+ ICPPASTFunctionTryBlockDeclarator tbd= (ICPPASTFunctionTryBlockDeclarator) declarator;
+ for (ICPPASTCatchHandler catchHandler : handlers) {
+ tbd.addCatchHandler(catchHandler);
+ }
+ endOffset= calculateEndOffset(handlers.get(handlers.size()-1));
+ }
+ }
- for (int i = 0; i < declarators.length; ++i) {
- simpleDeclaration.addDeclarator(declarators[i]);
- }
- return simpleDeclaration;
- }
+ IASTFunctionDefinition funcDefinition = createFunctionDefinition();
+ funcDefinition.setDeclSpecifier(declSpec);
+ funcDefinition.setDeclarator((IASTStandardFunctionDeclarator) declarator);
+ funcDefinition.setBody(body);
+
+ ((ASTNode) funcDefinition).setOffsetAndLength(firstOffset, endOffset-firstOffset);
+ return funcDefinition;
+ }
protected IASTFunctionDefinition createFunctionDefinition() {
@@ -2813,7 +2602,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* @throws BacktrackException
* request a backtrack
*/
- protected void ctorInitializer(List<IASTNode> collection) throws EndOfFileException,
+ protected void ctorInitializer(List<ICPPASTConstructorChainInitializer> collection) throws EndOfFileException,
BacktrackException {
consume();
ctorLoop: for (;;) {
@@ -2875,33 +2664,26 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* @throws BacktrackException
* request a backtrack
*/
- protected ICPPASTParameterDeclaration parameterDeclaration()
- throws BacktrackException, EndOfFileException {
- IToken current = LA(1);
- IASTDeclSpecifier declSpec = null;
+ protected ICPPASTParameterDeclaration parameterDeclaration() throws BacktrackException, EndOfFileException {
+ final int startOffset= LA(1).getOffset();
+
+ IASTDeclSpecifier declSpec;
+ IASTDeclarator declarator;
try {
- declSpec = declSpecifierSeq(true, false);
+ declSpec= declSpecifierSeq(DeclarationOptions.PARAMETER);
+ declarator= initDeclarator(declSpec, DeclarationOptions.PARAMETER);
} catch (FoundDeclaratorException e) {
- throwBacktrack( e.currToken );
- }
- IASTDeclarator declarator = null;
- switch (LT(1)) {
- case IToken.tSEMI:
- case IToken.tEOC:
- break;
- default:
- declarator = initDeclarator(SimpleDeclarationStrategy.TRY_FUNCTION);
+ declSpec= e.declSpec;
+ declarator= e.declarator;
+ backup(e.currToken);
}
- if (current == LA(1)) {
- throwBacktrack(current.getOffset(), figureEndOffset(declSpec, declarator) - current.getOffset());
- }
- ICPPASTParameterDeclaration parm = createParameterDeclaration();
- ((ASTNode) parm).setOffsetAndLength(current.getOffset(), figureEndOffset(declSpec, declarator) - current.getOffset());
+ final ICPPASTParameterDeclaration parm = createParameterDeclaration();
parm.setDeclSpecifier(declSpec);
- if (declarator != null) {
- parm.setDeclarator(declarator);
- }
+ parm.setDeclarator(declarator);
+
+ final int endOffset = figureEndOffset(declSpec, declarator);
+ ((ASTNode) parm).setOffsetAndLength(startOffset, endOffset - startOffset);
return parm;
}
@@ -2910,390 +2692,398 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return new CPPASTParameterDeclaration();
}
+
+ private final static int INLINE=0x1, CONST=0x2, RESTRICT=0x4, VOLATILE=0x8,
+ SHORT=0x10, UNSIGNED= 0x20, SIGNED=0x40, COMPLEX=0x80, IMAGINARY=0x100,
+ VIRTUAL=0x200, EXPLICIT=0x400, FRIEND=0x800;
+
+
/**
* This function parses a declaration specifier sequence, as according to
- * the ANSI C++ spec. declSpecifier : "auto" | "register" | "static" |
- * "extern" | "mutable" | "inline" | "virtual" | "explicit" | "char" |
- * "wchar_t" | "bool" | "short" | "int" | "long" | "signed" | "unsigned" |
- * "float" | "double" | "void" | "const" | "volatile" | "friend" | "typedef" |
- * ("typename")? name | {"class"|"struct"|"union"} classSpecifier | {"enum"}
- * enumSpecifier Notes: - folded in storageClassSpecifier, typeSpecifier,
- * functionSpecifier - folded elaboratedTypeSpecifier into classSpecifier
- * and enumSpecifier - find template names in name
- *
- * @param parm
- * Is this for a parameter declaration (true) or simple
- * declaration (false)
- * @param forTypeId
- * TODO
- * @return TODO
- * @throws BacktrackException
- * request a backtrack
- * @throws FoundDeclaratorException
+ * the ANSI C++ specification.
+ * declSpecifier :
+ * "auto" | "register" | "static" | "extern" | "mutable" |
+ * "inline" | "virtual" | "explicit" |
+ * "typedef" | "friend" |
+ * "const" | "volatile" |
+ * "short" | "long" | "signed" | "unsigned" | "int" |
+ * "char" | "wchar_t" | "bool" | "float" | "double" | "void" |
+ * ("typename")? name |
+ * { "class" | "struct" | "union" } classSpecifier |
+ * {"enum"} enumSpecifier
*/
- protected ICPPASTDeclSpecifier declSpecifierSeq(boolean parm,
- boolean forTypeId) throws BacktrackException, EndOfFileException, FoundDeclaratorException {
- IToken firstToken = LA(1);
- Flags flags = new Flags(parm, false, forTypeId);
- IToken last = null;
-
- boolean isInline = false, isVirtual = false, isExplicit = false, isFriend = false;
- boolean isConst = false, isVolatile = false, isRestrict = false;
- boolean isLong = false, isShort = false, isUnsigned = false, isSigned = false, isLongLong = false;
- boolean isComplex = false, isImaginary = false;
- boolean isTypename = false;
-
+ protected ICPPASTDeclSpecifier declSpecifierSeq(final DeclarationOptions option)
+ throws BacktrackException, EndOfFileException, FoundDeclaratorException {
int storageClass = IASTDeclSpecifier.sc_unspecified;
int simpleType = IASTSimpleDeclSpecifier.t_unspecified;
- ITokenDuple duple = null;
+ int options= 0;
+ int isLong= 0;
- ICPPASTCompositeTypeSpecifier classSpec = null;
- ICPPASTElaboratedTypeSpecifier elabSpec = null;
- IASTEnumerationSpecifier enumSpec = null;
- IASTExpression typeofExpression = null;
- int startOffset = firstToken.getOffset();
+ ITokenDuple identifier= null;
+ ICPPASTDeclSpecifier result= null;
+ IASTExpression typeofExpression= null;
+
+ boolean isTypename = false;
+ boolean encounteredRawType= false;
+ boolean encounteredTypename= false;
+
+ final int offset = LA(1).getOffset();
+ int endOffset= offset;
declSpecifiers: for (;;) {
- switch (LT(1)) {
- case IToken.t_inline:
- last = consume();
- isInline = true;
- break;
- case IToken.t_typedef:
- storageClass = IASTDeclSpecifier.sc_typedef;
- last = consume();
- break;
+ final IToken token= LA(1);
+ final int lt1= token.getType();
+ switch (lt1) {
+ // storage class specifiers
case IToken.t_auto:
- last = consume();
storageClass = IASTDeclSpecifier.sc_auto;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_register:
- last = consume();
storageClass = IASTDeclSpecifier.sc_register;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_static:
storageClass = IASTDeclSpecifier.sc_static;
- last = consume();
+ endOffset= consume().getEndOffset();
break;
case IToken.t_extern:
storageClass = IASTDeclSpecifier.sc_extern;
- last = consume();
+ endOffset= consume().getEndOffset();
break;
case IToken.t_mutable:
storageClass = ICPPASTDeclSpecifier.sc_mutable;
- last = consume();
+ endOffset= consume().getEndOffset();
+ break;
+ case IToken.t_typedef:
+ storageClass = IASTDeclSpecifier.sc_typedef;
+ endOffset= consume().getEndOffset();
+ break;
+ // function specifiers
+ case IToken.t_inline:
+ options |= INLINE;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_virtual:
- isVirtual = true;
- last = consume();
+ options |= VIRTUAL;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_explicit:
- isExplicit = true;
- last = consume();
+ options |= EXPLICIT;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_friend:
- isFriend = true;
- last = consume();
+ options |= FRIEND;
+ endOffset= consume().getEndOffset();
break;
+ // type specifier
case IToken.t_const:
- isConst = true;
- last = consume();
+ options |= CONST;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_volatile:
- isVolatile = true;
- last = consume();
+ options |= VOLATILE;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_restrict:
- isRestrict = true;
- last = consume();
+ options |= RESTRICT;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_signed:
- isSigned = true;
- flags.setEncounteredRawType(true);
- last = consume();
+ options |= SIGNED;
+ encounteredRawType= true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_unsigned:
- isUnsigned = true;
- flags.setEncounteredRawType(true);
- last = consume();
+ options |= UNSIGNED;
+ encounteredRawType= true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_short:
- isShort = true;
- flags.setEncounteredRawType(true);
- last = consume();
+ options |= SHORT;
+ encounteredRawType= true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_long:
- if (isLong && supportLongLong) {
- isLong = false;
- isLongLong = true;
- } else
- isLong = true;
- flags.setEncounteredRawType(true);
- last = consume();
+ isLong++;
+ encounteredRawType= true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t__Complex:
- if (!supportComplex) {
- IToken la = LA(1);
- throwBacktrack(la.getOffset(), la.getEndOffset() - la.getOffset());
- }
- last = consume();
- isComplex=true;
+ options |= COMPLEX;
+ endOffset= consume().getEndOffset();
break;
case IToken.t__Imaginary:
- if (!supportComplex) {
- IToken la = LA(1);
- throwBacktrack(la.getOffset(), la.getLength());
- }
- last = consume();
- isImaginary=true;
+ options |= IMAGINARY;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_char:
simpleType = IASTSimpleDeclSpecifier.t_char;
- flags.setEncounteredRawType(true);
- last = consume();
+ encounteredRawType= true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_wchar_t:
simpleType = ICPPASTSimpleDeclSpecifier.t_wchar_t;
- flags.setEncounteredRawType(true);
- last = consume();
+ encounteredRawType= true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_bool:
simpleType = ICPPASTSimpleDeclSpecifier.t_bool;
- flags.setEncounteredRawType(true);
- last = consume();
+ encounteredRawType= true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_int:
- flags.setEncounteredRawType(true);
- last = consume();
simpleType = IASTSimpleDeclSpecifier.t_int;
+ encounteredRawType= true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_float:
simpleType = IASTSimpleDeclSpecifier.t_float;
- flags.setEncounteredRawType(true);
- last = consume();
+ encounteredRawType= true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_double:
simpleType = IASTSimpleDeclSpecifier.t_double;
- flags.setEncounteredRawType(true);
- last = consume();
+ encounteredRawType= true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_void:
simpleType = IASTSimpleDeclSpecifier.t_void;
- flags.setEncounteredRawType(true);
- last = consume();
+ encounteredRawType= true;
+ endOffset= consume().getEndOffset();
break;
case IToken.t_typename:
+ consume();
+ identifier= name();
+ endOffset= identifier.getLastToken().getEndOffset();
isTypename = true;
- last = consume();
- duple = name();
- last = duple.getLastToken();
- flags.setEncounteredTypename(true);
+ encounteredTypename= true;
break;
+ case IToken.tBITCOMPLEMENT:
case IToken.tCOLONCOLON:
case IToken.tIDENTIFIER:
case IToken.tCOMPLETION:
- if (flags.haveEncounteredRawType())
+ if (encounteredRawType || encounteredTypename)
break declSpecifiers;
- if (flags.haveEncounteredTypename())
- break declSpecifiers;
-
- try
- {
- lookAheadForDeclarator(flags);
- }
- catch( FoundDeclaratorException fde )
- {
- ICPPASTSimpleDeclSpecifier simpleDeclSpec = null;
- if (isLongLong) {
- simpleDeclSpec = createGPPSimpleDeclSpecifier();
- ((IGPPASTSimpleDeclSpecifier) simpleDeclSpec).setLongLong(isLongLong);
- } else
- simpleDeclSpec = createSimpleDeclSpecifier();
-
- int l = last != null ? last.getEndOffset() - firstToken.getOffset() : 0;
- ((ASTNode) simpleDeclSpec).setOffsetAndLength(firstToken.getOffset(), l);
-
- simpleDeclSpec.setConst(isConst);
- simpleDeclSpec.setVolatile(isVolatile);
- if (simpleDeclSpec instanceof IGPPASTDeclSpecifier)
- ((IGPPASTDeclSpecifier) simpleDeclSpec).setRestrict(isRestrict);
-
- simpleDeclSpec.setFriend(isFriend);
- simpleDeclSpec.setInline(isInline);
- simpleDeclSpec.setStorageClass(storageClass);
- simpleDeclSpec.setVirtual(isVirtual);
- simpleDeclSpec.setExplicit(isExplicit);
-
- simpleDeclSpec.setType(simpleType);
- simpleDeclSpec.setLong(isLong);
- simpleDeclSpec.setShort(isShort);
- simpleDeclSpec.setUnsigned(isUnsigned);
- simpleDeclSpec.setSigned(isSigned);
- fde.declSpec = simpleDeclSpec;
- throw fde;
+ try {
+ if (option.fAllowEmptySpecifier && lt1 != IToken.tCOMPLETION) {
+ lookAheadForDeclarator(option);
+ }
+ } catch (FoundDeclaratorException e) {
+ if (e.currToken.getType() == IToken.tEOC || canBeConstructorDestructorOrConversion(option, storageClass, options, e.declarator)) {
+ e.declSpec= createSimpleDeclSpec(storageClass, simpleType, options, isLong, typeofExpression, offset, endOffset);
+ throw e;
+ }
}
- duple = name();
- last = duple.getLastToken();
- flags.setEncounteredTypename(true);
+ identifier= name();
+ endOffset= identifier.getLastToken().getEndOffset();
+ encounteredTypename= true;
break;
case IToken.t_class:
case IToken.t_struct:
case IToken.t_union:
- if (flags.haveEncounteredTypename())
- throwBacktrack(LA(1));
+ if (encounteredTypename || encounteredRawType)
+ throwBacktrack(token);
try {
- classSpec = classSpecifier();
- flags.setEncounteredTypename(true);
- break;
+ result= classSpecifier();
} catch (BacktrackException bt) {
- elabSpec = elaboratedTypeSpecifier();
- flags.setEncounteredTypename(true);
- break;
+ result= elaboratedTypeSpecifier();
}
+ endOffset= calculateEndOffset(result);
+ encounteredTypename= true;
+ break;
+
case IToken.t_enum:
- if (flags.haveEncounteredTypename())
- throwBacktrack(LA(1));
+ if (encounteredTypename || encounteredRawType)
+ throwBacktrack(token);
try {
- enumSpec = enumSpecifier();
- flags.setEncounteredTypename(true);
- break;
+ result= (ICPPASTDeclSpecifier) enumSpecifier();
} catch (BacktrackException bt) {
- // this is an elaborated class specifier
- elabSpec = elaboratedTypeSpecifier();
- flags.setEncounteredTypename(true);
- break;
+ result= elaboratedTypeSpecifier();
}
+ endOffset= calculateEndOffset(result);
+ encounteredTypename= true;
+ break;
+
case IGCCToken.t__attribute__: // if __attribute__ is after the declSpec
- if (supportAttributeSpecifiers)
- __attribute_decl_seq(true, false);
- else
- throwBacktrack(LA(1).getOffset(), LA(1).getLength());
+ if (!supportAttributeSpecifiers)
+ throwBacktrack(token);
+ __attribute_decl_seq(true, false);
break;
- case IGCCToken.t__declspec: // if __declspec appears before identifier
- if (duple == null && supportDeclspecSpecifiers)
- __attribute_decl_seq(false, true);
- else
- throwBacktrack(LA(1).getOffset(), LA(1).getLength());
+ case IGCCToken.t__declspec: // __declspec precedes the identifier
+ if (identifier != null || !supportDeclspecSpecifiers)
+ throwBacktrack(token);
+ __attribute_decl_seq(false, true);
break;
-
+
default:
if (LT(1) >= IExtensionToken.t__otherDeclSpecModifierFirst && LT(1) <= IExtensionToken.t__otherDeclSpecModifierLast) {
handleOtherDeclSpecModifier();
+ endOffset= LA(1).getOffset();
break;
}
- if (supportTypeOfUnaries && LT(1) == IGCCToken.t_typeof) {
+ if (LT(1) == IGCCToken.t_typeof) {
+ if (encounteredRawType || encounteredTypename)
+ throwBacktrack(token);
+
typeofExpression = unaryTypeofExpression();
- if (typeofExpression != null) {
- flags.setEncounteredTypename(true);
- }
+ encounteredTypename= true;
+ endOffset= calculateEndOffset(typeofExpression);
+ break;
}
break declSpecifiers;
}
+
+ if (encounteredRawType && encounteredTypename)
+ throwBacktrack(token);
}
- if (elabSpec != null) {
- elabSpec.setConst(isConst);
- elabSpec.setVolatile(isVolatile);
- if (elabSpec instanceof IGPPASTDeclSpecifier)
- ((IGPPASTDeclSpecifier) elabSpec).setRestrict(isRestrict);
- elabSpec.setFriend(isFriend);
- elabSpec.setInline(isInline);
- elabSpec.setStorageClass(storageClass);
- elabSpec.setVirtual(isVirtual);
- elabSpec.setExplicit(isExplicit);
- ((ASTNode) elabSpec).setOffsetAndLength(startOffset, calculateEndOffset(elabSpec) - startOffset);
- return elabSpec;
- }
- if (enumSpec != null) {
- enumSpec.setConst(isConst);
- enumSpec.setVolatile(isVolatile);
- if (enumSpec instanceof IGPPASTDeclSpecifier)
- ((IGPPASTDeclSpecifier) enumSpec).setRestrict(isRestrict);
- ((ICPPASTDeclSpecifier) enumSpec).setFriend(isFriend);
- ((ICPPASTDeclSpecifier) enumSpec).setVirtual(isVirtual);
- ((ICPPASTDeclSpecifier) enumSpec).setExplicit(isExplicit);
- enumSpec.setInline(isInline);
- enumSpec.setStorageClass(storageClass);
- ((ASTNode) enumSpec).setOffsetAndLength(startOffset, calculateEndOffset(enumSpec) - startOffset);
- return (ICPPASTDeclSpecifier) enumSpec;
+ // check for empty specification
+ if (!encounteredRawType && !encounteredTypename && LT(1) != IToken.tEOC && !option.fAllowEmptySpecifier) {
+ throwBacktrack(LA(1));
}
- if (classSpec != null) {
- classSpec.setConst(isConst);
- classSpec.setVolatile(isVolatile);
- if (classSpec instanceof IGPPASTDeclSpecifier)
- ((IGPPASTDeclSpecifier) classSpec).setRestrict(isRestrict);
- classSpec.setFriend(isFriend);
- classSpec.setInline(isInline);
- classSpec.setStorageClass(storageClass);
- classSpec.setVirtual(isVirtual);
- classSpec.setExplicit(isExplicit);
- ((ASTNode) classSpec).setOffsetAndLength(startOffset, calculateEndOffset(classSpec) - startOffset);
- return classSpec;
- }
- if (duple != null) {
- ICPPASTNamedTypeSpecifier nameSpec = (ICPPASTNamedTypeSpecifier) createNamedTypeSpecifier();
- nameSpec.setIsTypename(isTypename);
- IASTName name = createName(duple);
- nameSpec.setName(name);
- nameSpec.setConst(isConst);
- nameSpec.setVolatile(isVolatile);
- if (nameSpec instanceof IGPPASTDeclSpecifier)
- ((IGPPASTDeclSpecifier) nameSpec).setRestrict(isRestrict);
- nameSpec.setFriend(isFriend);
- nameSpec.setInline(isInline);
- nameSpec.setStorageClass(storageClass);
- nameSpec.setVirtual(isVirtual);
- nameSpec.setExplicit(isExplicit);
- if (last != null) {
- ((ASTNode) nameSpec).setOffsetAndLength(startOffset, last.getEndOffset() - startOffset);
- }
- else {
- ((ASTNode) nameSpec).setOffsetAndLength(startOffset, duple.getLastToken().getEndOffset() - startOffset);
+
+ 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);
+ }
}
- return nameSpec;
+ ((ASTNode) result).setOffsetAndLength(offset, endOffset - offset);
+ return result;
}
- ICPPASTSimpleDeclSpecifier simpleDeclSpec = null;
- if (isComplex || isImaginary || isLongLong || typeofExpression != null) {
- simpleDeclSpec = createGPPSimpleDeclSpecifier();
- ((IGPPASTSimpleDeclSpecifier) simpleDeclSpec).setLongLong(isLongLong);
- ((IGPPASTSimpleDeclSpecifier) simpleDeclSpec).setComplex(isComplex);
- ((IGPPASTSimpleDeclSpecifier) simpleDeclSpec).setImaginary(isImaginary);
- if (typeofExpression != null) {
- ((IGPPASTSimpleDeclSpecifier) simpleDeclSpec).setTypeofExpression(typeofExpression);
- }
- } else
- simpleDeclSpec = createSimpleDeclSpecifier();
- if( last == null && typeofExpression != null ){
- ((ASTNode) simpleDeclSpec).setOffsetAndLength((ASTNode) typeofExpression);
- } else {
- int l = last != null ? last.getEndOffset() - firstToken.getOffset() : 0;
- ((ASTNode) simpleDeclSpec).setOffsetAndLength(firstToken.getOffset(), l);
+ if (identifier != null)
+ return createNamedTypeSpecifier(identifier, isTypename, storageClass, options, offset, endOffset);
+
+ return createSimpleDeclSpec(storageClass, simpleType, options, isLong, typeofExpression, offset, endOffset);
+ }
+
+ private boolean canBeConstructorDestructorOrConversion(DeclarationOptions declOption, int storageClass, int options, IASTDeclarator dtor) {
+ final int forbid= CONST | RESTRICT | VOLATILE | SHORT | UNSIGNED | SIGNED | COMPLEX | IMAGINARY | FRIEND;
+ if (storageClass == IASTDeclSpecifier.sc_unspecified && (options & forbid) == 0) {
+ if (CPPVisitor.findTypeRelevantDeclarator(dtor) instanceof IASTFunctionDeclarator) {
+ IASTName name= CPPVisitor.findInnermostDeclarator(dtor).getName();
+ if (name instanceof ICPPASTQualifiedName) {
+ final ICPPASTQualifiedName qname = (ICPPASTQualifiedName) name;
+ final IASTName names[]= qname.getNames();
+ final int len = names.length;
+ if (len > 1 && CharArrayUtils.equals(names[len-2].toCharArray(), names[len-1].toCharArray()))
+ return true; // constructor
+
+ name= qname.getLastName();
+ }
+ if (name instanceof ICPPASTConversionName)
+ return true; // conversion
+ if (name instanceof ICPPASTTemplateId) {
+ if (((ICPPASTTemplateId) name).getTemplateName() instanceof ICPPASTConversionName) {
+ return true;
+ }
+
+ }
+ final char[] nchars= name.toCharArray();
+ if (nchars.length > 0 && nchars[0] == '~')
+ return true; // destructor
+
+ if (declOption == DeclarationOptions.CPP_MEMBER && CharArrayUtils.equals(nchars, currentClassName))
+ return true;
+ }
}
- simpleDeclSpec.setConst(isConst);
- simpleDeclSpec.setVolatile(isVolatile);
- if (simpleDeclSpec instanceof IGPPASTDeclSpecifier)
- ((IGPPASTDeclSpecifier) simpleDeclSpec).setRestrict(isRestrict);
-
- simpleDeclSpec.setFriend(isFriend);
- simpleDeclSpec.setInline(isInline);
- simpleDeclSpec.setStorageClass(storageClass);
- simpleDeclSpec.setVirtual(isVirtual);
- simpleDeclSpec.setExplicit(isExplicit);
-
- simpleDeclSpec.setType(simpleType);
- simpleDeclSpec.setLong(isLong);
- simpleDeclSpec.setShort(isShort);
- simpleDeclSpec.setUnsigned(isUnsigned);
- simpleDeclSpec.setSigned(isSigned);
+ return false;
+ }
+
+ private ICPPASTNamedTypeSpecifier createNamedTypeSpecifier(ITokenDuple identifier, boolean isTypename,
+ int storageClass, int options, int offset, int endOffset) {
+ ICPPASTNamedTypeSpecifier declSpec = (ICPPASTNamedTypeSpecifier)createNamedTypeSpecifier();
+ IASTName name = createName(identifier);
+ declSpec.setName(name);
+ declSpec.setIsTypename(isTypename);
+ configureDeclSpec(declSpec, storageClass, options);
+ ((ASTNode) declSpec).setOffsetAndLength(offset, endOffset - offset);
+ return declSpec;
+ }
+
+ private ICPPASTSimpleDeclSpecifier createSimpleDeclSpec(int storageClass, int simpleType,
+ int options, int isLong, IASTExpression typeofExpression, int offset, int endOffset) {
+
+ if (isLong > 1 && !supportLongLong)
+ isLong= 1;
+
+ ICPPASTSimpleDeclSpecifier declSpec= null;
+ if (isLong > 1 || (options & (RESTRICT|COMPLEX|IMAGINARY)) != 0 || typeofExpression != null) {
+ final IGPPASTSimpleDeclSpecifier gppDeclSpec= createGPPSimpleDeclSpecifier();
+ gppDeclSpec.setLongLong(isLong > 1);
+ gppDeclSpec.setRestrict((options & RESTRICT) != 0);
+ gppDeclSpec.setComplex((options & COMPLEX) != 0);
+ gppDeclSpec.setImaginary((options & IMAGINARY) != 0);
+ gppDeclSpec.setTypeofExpression(typeofExpression);
+
+ declSpec= gppDeclSpec;
+ } else {
+ declSpec = createSimpleDeclSpecifier();
+ }
- return simpleDeclSpec;
- }
+ configureDeclSpec(declSpec, storageClass, options);
+
+ declSpec.setType(simpleType);
+ declSpec.setLong(isLong == 1);
+ declSpec.setShort((options & SHORT) != 0);
+ declSpec.setUnsigned((options & UNSIGNED) != 0);
+ declSpec.setSigned((options & SIGNED) != 0);
+
+ ((ASTNode) declSpec).setOffsetAndLength(offset, endOffset-offset);
+ return declSpec;
+ }
+
+ private void configureDeclSpec(ICPPASTDeclSpecifier declSpec, int storageClass, int options) {
+ declSpec.setStorageClass(storageClass);
+ declSpec.setConst((options & CONST) != 0);
+ declSpec.setVolatile((options & VOLATILE) != 0);
+ declSpec.setInline((options & INLINE) != 0);
+ declSpec.setFriend((options & FRIEND) != 0);
+ declSpec.setVirtual((options & VIRTUAL) != 0);
+ declSpec.setExplicit((options & EXPLICIT) != 0);
+ }
+
+ @Override
+ protected boolean verifyLookaheadDeclarator(DeclarationOptions option, IASTDeclarator dtor, IToken nextToken) {
+ switch (nextToken.getType()) {
+ case IToken.tCOMMA:
+ return true;
+
+ case IToken.tCOLON:
+ case IToken.t_try:
+ case IToken.t_catch:
+ case IToken.tLBRACE:
+ case IToken.t_const:
+ case IToken.t_volatile:
+ if (option == DeclarationOptions.GLOBAL || option == DeclarationOptions.CPP_MEMBER) {
+ if (CVisitor.findTypeRelevantDeclarator(dtor) instanceof IASTFunctionDeclarator) {
+ return true;
+ }
+ }
+ break;
+ case IToken.tSEMI:
+ return option == DeclarationOptions.GLOBAL || option == DeclarationOptions.CPP_MEMBER ||
+ option == DeclarationOptions.LOCAL;
+ case IToken.tRPAREN:
+ return option == DeclarationOptions.PARAMETER;
+
+ case IToken.tEOC:
+ return true;
+ }
+ return false;
+ }
- protected ICPPASTSimpleDeclSpecifier createGPPSimpleDeclSpecifier() {
+ protected IGPPASTSimpleDeclSpecifier createGPPSimpleDeclSpecifier() {
return new GPPASTSimpleDeclSpecifier();
}
@@ -3356,11 +3146,88 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
@Override
- protected IASTDeclarator initDeclarator() throws EndOfFileException, BacktrackException {
- return initDeclarator(SimpleDeclarationStrategy.TRY_FUNCTION);
+ protected IASTDeclarator initDeclarator(DeclarationOptions option) throws EndOfFileException, BacktrackException {
+ // called from the lookahead, only.
+ return initDeclarator(DtorStrategy.PREFER_FUNCTION, option);
}
+
+ protected IASTDeclarator initDeclarator(IASTDeclSpecifier declspec, DeclarationOptions option) throws EndOfFileException, BacktrackException {
+ final IToken mark= mark();
+ IASTDeclarator dtor1= null;
+ IToken end1= null;
+ IASTDeclarator dtor2= null;
+ BacktrackException bt= null;
+ try {
+ dtor1= initDeclarator(DtorStrategy.PREFER_FUNCTION, option);
+ if (dtor1 instanceof IASTFunctionDeclarator == false)
+ return dtor1;
+
+ // optimization outside of function bodies and inside of templates
+ if (functionBodyCount == 0 || templateCount != 0)
+ return dtor1;
+
+ // avoid second option for function definitions
+ end1= LA(1);
+ switch(end1.getType()) {
+ case IToken.tLBRACE: case IToken.tCOLON:
+ case IToken.t_throw: case IToken.t_try:
+ case IToken.t_const: case IToken.t_volatile:
+ return dtor1;
+ }
+ } catch (BacktrackException e) {
+ bt= e;
+ }
+
+ if (!option.fAllowConstructorInitializer || !canHaveConstructorInitializer(declspec)) {
+ if (bt != null)
+ throw bt;
+ return dtor1;
+ }
- /**
+ backup(mark);
+ try {
+ dtor2= initDeclarator(DtorStrategy.PREFER_NESTED, option);
+ if (dtor1 == null) {
+ return dtor2;
+ }
+ } catch (BacktrackException e) {
+ if (dtor1 != null) {
+ backup(end1);
+ return dtor1;
+ }
+ throw e;
+ }
+
+ // we have an ambiguity
+ if (LA(1) != end1) {
+ backup(end1);
+ return dtor1;
+ }
+
+ CPPASTAmbiguousDeclarator dtor= new CPPASTAmbiguousDeclarator(dtor2, dtor1);
+ dtor.setOffsetAndLength((ASTNode) dtor1);
+ return dtor;
+ }
+
+ private boolean canHaveConstructorInitializer(IASTDeclSpecifier declspec) {
+ if (declspec instanceof ICPPASTSimpleDeclSpecifier) {
+ ICPPASTSimpleDeclSpecifier simpleSpecifier= (ICPPASTSimpleDeclSpecifier) declspec;
+ switch(simpleSpecifier.getType()) {
+ case IASTSimpleDeclSpecifier.t_unspecified:
+ case IASTSimpleDeclSpecifier.t_void:
+ return false;
+ }
+ if (simpleSpecifier.isFriend()) {
+ return false;
+ }
+ if (simpleSpecifier.getStorageClass() == IASTDeclSpecifier.sc_typedef) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
* Parses the initDeclarator construct of the ANSI C++ spec. initDeclarator :
* declarator ("=" initializerClause | "(" expressionList ")")?
*
@@ -3368,16 +3235,18 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* @throws BacktrackException
* request a backtrack
*/
- protected IASTDeclarator initDeclarator(SimpleDeclarationStrategy strategy)
+ protected IASTDeclarator initDeclarator(DtorStrategy strategy, DeclarationOptions option)
throws EndOfFileException, BacktrackException {
- IASTDeclarator d = declarator(strategy, false);
- IASTInitializer initializer = optionalCPPInitializer(d);
- if (initializer != null) {
- d.setInitializer(initializer);
- ((ASTNode) d).setLength(calculateEndOffset(initializer) - ((ASTNode) d).getOffset());
+ final IASTDeclarator dtor= declarator(strategy, option);
+ if (option.fAllowInitializer) {
+ IASTInitializer initializer= optionalCPPInitializer(dtor);
+ if (initializer != null) {
+ dtor.setInitializer(initializer);
+ adjustLength(dtor, initializer);
+ }
}
- return d;
+ return dtor;
}
protected IASTInitializer optionalCPPInitializer(IASTDeclarator d)
@@ -3476,346 +3345,359 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
/**
* Parse a declarator, as according to the ANSI C++ specification.
- * declarator : (ptrOperator)* directDeclarator directDeclarator :
- * declaratorId | directDeclarator "(" parameterDeclarationClause ")"
- * (cvQualifier)* (exceptionSpecification)* | directDeclarator "["
- * (constantExpression)? "]" | "(" declarator")" | directDeclarator "("
- * parameterDeclarationClause ")" (oldKRParameterDeclaration)* declaratorId :
- * name
- *
+ * declarator : (ptrOperator)* directDeclarator
+ * directDeclarator :
+ * declaratorId |
+ * directDeclarator "(" parameterDeclarationClause ")" (cvQualifier)* (exceptionSpecification)* |
+ * directDeclarator "[" (constantExpression)? "]" |
+ * "(" declarator")" |
+ * directDeclarator "(" parameterDeclarationClause ")" (oldKRParameterDeclaration)*
+ *
+ * declaratorId : name
* @return declarator that this parsing produced.
* @throws BacktrackException
* request a backtrack
*/
- protected IASTDeclarator declarator(SimpleDeclarationStrategy strategy,
- boolean forNewTypeId) throws EndOfFileException, BacktrackException {
+ protected IASTDeclarator declarator(DtorStrategy strategy, DeclarationOptions option)
+ throws EndOfFileException, BacktrackException {
+
+ final int startingOffset = LA(1).getOffset();
+ int endOffset = startingOffset;
- IToken la = LA(1);
- int startingOffset = la.getOffset();
- la = null;
- IASTDeclarator innerDecl = null;
- IASTName declaratorName = null;
List<IASTPointerOperator> pointerOps = new ArrayList<IASTPointerOperator>(DEFAULT_POINTEROPS_LIST_SIZE);
- List<IASTNode> parameters = Collections.emptyList();
- List<IASTNode> arrayMods = Collections.emptyList();
- List<IASTNode> exceptionSpecIds = Collections.emptyList();
- boolean encounteredVarArgs = false;
- boolean tryEncountered = false;
- IASTExpression bitField = null;
- boolean isFunction = false;
- boolean isPureVirtual = false, isConst = false, isVolatile = false;
- int finalOffset = startingOffset;
- overallLoop: do {
-
- consumePointerOperators(pointerOps);
-
- // if __attribute__ is after the pointer ops and before the declarator ex: void * __attribute__((__cdecl__)) foo();
- __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
+ consumePointerOperators(pointerOps);
+ if (!pointerOps.isEmpty()) {
+ endOffset = calculateEndOffset(pointerOps.get(pointerOps.size() - 1));
+ }
- if (!pointerOps.isEmpty())
- finalOffset = calculateEndOffset(pointerOps.get(pointerOps.size() - 1));
-
- if (!forNewTypeId && LT(1) == IToken.tLPAREN) {
- IToken mark = mark();
- try {
- consume();
- innerDecl = declarator(strategy, forNewTypeId);
- finalOffset = consume(IToken.tRPAREN).getEndOffset();
- } catch (BacktrackException bte) {
- backup(mark);
- innerDecl = null;
- }
- declaratorName = createName();
- } else {
- try {
- declaratorName = consumeTemplatedOperatorName();
- finalOffset = calculateEndOffset(declaratorName);
- if (declaratorName instanceof ICPPASTQualifiedName
- && ((ICPPASTQualifiedName) declaratorName).isConversionOrOperator())
- isFunction = true;
- } catch (BacktrackException bt) {
- declaratorName = createName();
- }
- }
+ // Accept __attribute__ or __declspec between pointer operators and declarator.
+ __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
- for (;;) {
- switch (LT(1)) {
- case IToken.tLPAREN:
- IToken markityMark = mark();
- boolean success = false;
- try
- {
- consume(); // tLPAREN
- expression();
- consume( IToken.tRPAREN );
- success = true;
- backup( markityMark );
- }
- catch( BacktrackException bte )
- {
- backup( markityMark );
- }
- catch( EndOfFileException eof )
- {
- backup( markityMark );
- }
- if( success )
- {
- switch( LT(1) )
- {
- case IToken.tSEMI:
- case IToken.tCOMMA:
- break overallLoop;
- }
- }
+ // Look for identifier or nested declarator
+ final int lt1= LT(1);
+ switch (lt1) {
+ case IToken.tBITCOMPLEMENT:
+ case IToken.t_operator:
+ case IToken.tCOLONCOLON:
+ case IToken.tIDENTIFIER:
+ case IToken.tCOMPLETION:
+ if (option.fRequireAbstract)
+ throwBacktrack(LA(1));
+
+ final IASTName declaratorName= consumeTemplatedOperatorName();
+ endOffset= calculateEndOffset(declaratorName);
+ return declarator(pointerOps, declaratorName, null, startingOffset, endOffset, strategy, option);
+ }
+
+ if (lt1 == IToken.tLPAREN) {
+ IASTDeclarator cand1= null;
+ IToken cand1End= null;
+ // try an abstract function declarator
+ if (option.fAllowAbstract && option.fAllowFunctions) {
+ final IToken mark= mark();
+ try {
+ cand1= declarator(pointerOps, createName(), null, startingOffset, endOffset, strategy, option);
+ if (option.fRequireAbstract || !option.fAllowNested)
+ return cand1;
+
+ cand1End= LA(1);
+ } catch (BacktrackException e) {
+ }
+ backup(mark);
+ }
+
+ // type-ids for new or operator-id:
+ if (!option.fAllowNested) {
+ if (option.fAllowAbstract) {
+ return declarator(pointerOps, createName(), null, startingOffset, endOffset, strategy, option);
+ }
+ throwBacktrack(LA(1));
+ }
+
+ // try a nested declarator
+ try {
+ consume();
+ if (LT(1) == IToken.tRPAREN)
+ throwBacktrack(LA(1));
+
+ final IASTDeclarator nested= declarator(strategy, option);
+ endOffset= consume(IToken.tRPAREN).getEndOffset();
+ final IASTDeclarator cand2= declarator(pointerOps, null, nested, startingOffset, endOffset, DtorStrategy.PREFER_FUNCTION, option);
+ if (cand1 == null || cand1End == null)
+ return cand2;
+ final IToken cand2End= LA(1);
+ if (cand1End == cand2End) {
+ CPPASTAmbiguousDeclarator result= new CPPASTAmbiguousDeclarator(cand1, cand2);
+ ((ASTNode) result).setOffsetAndLength((ASTNode) cand1);
+ return result;
+ }
+ // use the longer variant
+ if (cand1End.getOffset() < cand2End.getOffset())
+ return cand2;
- if( strategy == SimpleDeclarationStrategy.TRY_VARIABLE )
- break overallLoop;
-
-
- if (!looksLikeExpression(LA(2))&& !forNewTypeId) {
- // parameterDeclarationClause
- isFunction = true;
- // TODO need to create a temporary scope object here
- IToken last = consume(IToken.tLPAREN);
- finalOffset = last.getEndOffset();
- boolean seenParameter = false;
- parameterDeclarationLoop: for (;;) {
- switch (LT(1)) {
- case IToken.tRPAREN:
- last = consume();
- finalOffset = last.getEndOffset();
- break parameterDeclarationLoop;
- case IToken.tEOC:
- break parameterDeclarationLoop;
- case IToken.tELLIPSIS:
- last = consume();
- encounteredVarArgs = true;
- finalOffset = last.getEndOffset();
- break;
- case IToken.tCOMMA:
- last = consume();
- seenParameter = false;
- finalOffset = last.getEndOffset();
- break;
- default:
- int endOffset = (last != null) ? last.getEndOffset() : LA(1).getEndOffset();
- if (seenParameter)
- throwBacktrack(startingOffset, endOffset - startingOffset);
- IASTParameterDeclaration p = parameterDeclaration();
- finalOffset = calculateEndOffset(p);
- if (parameters == Collections.EMPTY_LIST)
- parameters = new ArrayList<IASTNode>(DEFAULT_PARM_LIST_SIZE);
- parameters.add(p);
- seenParameter = true;
- }
- }
- }
+ } catch (BacktrackException e) {
+ if (cand1 == null)
+ throw e;
+ }
+ backup(cand1End);
+ return cand1;
+ }
- if (LT(1) == IToken.tCOLON)
- break overallLoop;
+ // try abstract declarator
+ if (!option.fAllowAbstract) {
+ // bit-fields may be abstract
+ if (!option.fAllowBitField || LT(1) != IToken.tCOLON)
+ throwBacktrack(LA(1));
+ }
+ return declarator(pointerOps, createName(), null, startingOffset, endOffset, strategy, option);
+ }
+
+ private IASTDeclarator declarator(List<IASTPointerOperator> pointerOps,
+ IASTName declaratorName, IASTDeclarator nestedDeclarator, int startingOffset, int endOffset,
+ DtorStrategy strategy, DeclarationOptions option)
+ throws EndOfFileException, BacktrackException {
+ IASTDeclarator result= null;
+ loop: while(true) {
+ final int lt1= LT(1);
+ switch (lt1) {
+ case IToken.tLPAREN:
+ if (option.fAllowFunctions && strategy == DtorStrategy.PREFER_FUNCTION) {
+ result= functionDeclarator();
+ setDeclaratorID(result, declaratorName, nestedDeclarator);
+ }
+ break loop;
+
+ case IToken.tLBRACKET:
+ result= arrayDeclarator(option);
+ setDeclaratorID(result, declaratorName, nestedDeclarator);
+ break loop;
+
+ case IToken.tCOLON:
+ if (!option.fAllowBitField)
+ break loop; // no backtrack because typeid can be followed by colon
+
+ result= bitFieldDeclarator();
+ setDeclaratorID(result, declaratorName, nestedDeclarator);
+ break loop;
+
+ case IGCCToken.t__attribute__: // if __attribute__ is after a declarator
+ if (!supportAttributeSpecifiers)
+ throwBacktrack(LA(1));
+ __attribute_decl_seq(true, supportDeclspecSpecifiers);
+ break;
+ case IGCCToken.t__declspec:
+ if (!supportDeclspecSpecifiers)
+ throwBacktrack(LA(1));
+ __attribute_decl_seq(supportAttributeSpecifiers, true);
+ break;
+ default:
+ break loop;
+ }
+ }
+ __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
- if (LT(1) == IToken.t_try) {
- tryEncountered = true;
- break overallLoop;
- }
+ if (result == null) {
+ result= createDeclarator();
+ setDeclaratorID(result, declaratorName, nestedDeclarator);
+ } else {
+ endOffset= calculateEndOffset(result);
+ }
- // Consume any number of __attribute__ tokens after the parameters
- __attribute_decl_seq(supportAttributeSpecifiers, false);
-
-
- IToken beforeCVModifier = mark();
- IToken[] cvModifiers = new IToken[2];
- int numCVModifiers = 0;
- IToken afterCVModifier = beforeCVModifier;
- // const-volatile
- // 2 options: either this is a marker for the method,
- // or it might be the beginning of old K&R style
- // parameter declaration, see
- // void getenv(name) const char * name; {}
- // This will be determined further below
- while ((LT(1) == IToken.t_const || LT(1) == IToken.t_volatile) && numCVModifiers < 2) {
- IToken t = consume();
- finalOffset = t.getEndOffset();
- cvModifiers[numCVModifiers++] = t;
- afterCVModifier = mark();
- }
- // check for throws clause here
-
- if (LT(1) == IToken.t_throw) {
- exceptionSpecIds = new ArrayList<IASTNode>(DEFAULT_SIZE_EXCEPTIONS_LIST);
- consume(); // throw
- consume(IToken.tLPAREN); // (
- boolean done = false;
- while (!done) {
- switch (LT(1)) {
- case IToken.tRPAREN:
- finalOffset = consume().getEndOffset();
- done = true;
- break;
- case IToken.tCOMMA:
- consume();
- break;
- default:
- IToken before = LA(1);
- IASTTypeId typeId = typeId(false);
- if (typeId != null) {
- exceptionSpecIds.add(typeId);
- } else {
- IASTProblem p = createProblem(IProblem.SYNTAX_ERROR,
- before.getOffset(), before.getLength());
- IASTProblemTypeId typeIdProblem = createTypeIDProblem();
- typeIdProblem.setProblem(p);
- ((ASTNode) typeIdProblem).setOffsetAndLength(((ASTNode) p));
- exceptionSpecIds.add(typeIdProblem);
- if (before == LA(1))
- done = true;
- }
- break;
- }
- }
-
- // more __attribute__ after throws
- __attribute_decl_seq(supportAttributeSpecifiers, false);
- }
- // check for optional pure virtual
- if (LT(1) == IToken.tASSIGN && LT(2) == IToken.tINTEGER) {
- char[] image = LA(2).getCharImage();
- if (image.length == 1 && image[0] == '0') {
- consume(); // tASSIGN
- finalOffset = consume().getEndOffset(); // tINTEGER
- isPureVirtual = true;
- }
- }
- if (afterCVModifier != LA(1) || LT(1) == IToken.tSEMI
- || LT(1) == IToken.tLBRACE) {
- // There were C++-specific clauses after
- // const/volatile modifier
- // Then it is a marker for the method
- if (numCVModifiers > 0) {
- for (int i = 0; i < numCVModifiers; i++) {
- if (cvModifiers[i].getType() == IToken.t_const)
- isConst = true;
- if (cvModifiers[i].getType() == IToken.t_volatile)
- isVolatile = true;
- }
- }
- afterCVModifier = mark();
- // In this case (method) we can't expect K&R
- // parameter declarations,
- // but we'll check anyway, for errorhandling
- }
- break;
- case IToken.tLBRACKET:
- if (forNewTypeId)
- break;
- arrayMods = new ArrayList<IASTNode>(DEFAULT_POINTEROPS_LIST_SIZE);
- consumeArrayModifiers(arrayMods);
- if (!arrayMods.isEmpty())
- finalOffset = calculateEndOffset(arrayMods.get(arrayMods.size() - 1));
- continue;
- case IToken.tCOLON:
- if (forNewTypeId)
- break;
- consume();
- bitField = constantExpression();
- finalOffset = calculateEndOffset(bitField);
- break;
- case IGCCToken.t__attribute__: // if __attribute__ is after the declarator
- if(supportAttributeSpecifiers)
- __attribute_decl_seq(supportAttributeSpecifiers, false);
- else
- throwBacktrack(LA(1).getOffset(), LA(1).getLength());
- break;
- default:
- break;
- }
- break;
- }
+ if (LT(1) == IToken.t_asm) { // asm labels bug 226121
+ consume();
+ endOffset= asmExpression(null).getEndOffset();
- } while (false);
+ __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
+ }
- if (LT(1) == IToken.t_asm) { // asm labels bug 226121
- consume();
- finalOffset= asmExpression(null).getEndOffset();
- }
- if(supportAttributeSpecifiers)
- __attribute_decl_seq(supportAttributeSpecifiers, false);
-
- IASTDeclarator d = null;
- if (isFunction) {
+ for (IASTPointerOperator po : pointerOps) {
+ result.addPointerOperator(po);
+ }
- ICPPASTFunctionDeclarator fc = null;
- if (tryEncountered)
- fc = createTryBlockDeclarator();
- else
- fc = createFunctionDeclarator();
- fc.setVarArgs(encounteredVarArgs);
- for (int i = 0; i < parameters.size(); ++i) {
- IASTParameterDeclaration p = (IASTParameterDeclaration) parameters.get(i);
- fc.addParameterDeclaration(p);
- }
- fc.setConst(isConst);
- fc.setVolatile(isVolatile);
- fc.setPureVirtual(isPureVirtual);
- for (int i = 0; i < exceptionSpecIds.size(); ++i) {
- IASTTypeId typeId = (IASTTypeId) exceptionSpecIds.get(i);
- fc.addExceptionSpecificationTypeId(typeId);
- }
- d = fc;
- } else if (arrayMods != Collections.EMPTY_LIST) {
- d = createArrayDeclarator();
- for (int i = 0; i < arrayMods.size(); ++i) {
- IASTArrayModifier m = (IASTArrayModifier) arrayMods.get(i);
- ((IASTArrayDeclarator) d).addArrayModifier(m);
- }
- } else if (bitField != null) {
- IASTFieldDeclarator fl = createFieldDeclarator();
- fl.setBitFieldSize(bitField);
- d = fl;
- } else {
- d = createDeclarator();
- }
- for (int i = 0; i < pointerOps.size(); ++i) {
- IASTPointerOperator po = pointerOps.get(i);
- d.addPointerOperator(po);
- }
- if (innerDecl != null) {
- d.setNestedDeclarator(innerDecl);
- }
- if (declaratorName != null) {
- d.setName(declaratorName);
- }
+ ((ASTNode) result).setOffsetAndLength(startingOffset, endOffset - startingOffset);
+ return result;
+ }
- ((ASTNode) d).setOffsetAndLength(startingOffset, finalOffset - startingOffset);
- return d;
-
- }
-
- private boolean looksLikeExpression(IToken t) {
- switch (t.getType()) {
- case IToken.tINTEGER:
- case IToken.t_false:
- case IToken.t_true:
- case IToken.tSTRING:
- case IToken.tLSTRING:
- case IToken.tFLOATINGPT:
- case IToken.tCHAR:
- case IToken.tAMPER:
- case IToken.tDOT:
- case IToken.tLPAREN:
- case IToken.tMINUS:
- case IToken.tSTAR:
- case IToken.tPLUS:
- case IToken.tNOT:
- case IToken.tBITCOMPLEMENT:
- return true;
+ private void setDeclaratorID(IASTDeclarator declarator, IASTName declaratorName, IASTDeclarator nestedDeclarator) {
+ if (nestedDeclarator != null) {
+ declarator.setNestedDeclarator(nestedDeclarator);
+ declarator.setName(createName());
+ } else {
+ declarator.setName(declaratorName);
+ }
+ }
+
+ /**
+ * Parse a function declarator starting with the left parenthesis.
+ */
+ private IASTDeclarator functionDeclarator() throws EndOfFileException, BacktrackException {
+ IToken last = consume(IToken.tLPAREN);
+ int startOffset= last.getOffset();
+ boolean seenParameter= false;
+ boolean encounteredVarArgs= false;
+ List<IASTParameterDeclaration> parameters= null;
+ int endOffset= last.getEndOffset();
+
+ paramLoop: while(true) {
+ switch (LT(1)) {
+ case IToken.tRPAREN:
+ case IToken.tEOC:
+ endOffset= consume().getEndOffset();
+ break paramLoop;
+ case IToken.tELLIPSIS:
+ endOffset= consume().getEndOffset();
+ encounteredVarArgs = true;
+ break;
+ case IToken.tCOMMA:
+ endOffset= consume().getEndOffset();
+ seenParameter = false;
+ break;
default:
+ if (seenParameter)
+ throwBacktrack(startOffset, endOffset - startOffset);
+
+ IASTParameterDeclaration pd = parameterDeclaration();
+ endOffset = calculateEndOffset(pd);
+ if (parameters == null)
+ parameters = new ArrayList<IASTParameterDeclaration>(DEFAULT_PARAMETER_LIST_SIZE);
+ parameters.add(pd);
+ seenParameter = true;
break;
- }
- return false;
+ }
+ }
+
+ // Consume any number of __attribute__ tokens after the parameters
+ __attribute_decl_seq(supportAttributeSpecifiers, false);
+
+ boolean isTryCatch= false;
+ boolean isConst= false;
+ boolean isVolatile= false;
+ boolean isPureVirtual= false;
+ ArrayList<IASTTypeId> exceptionSpecIds= null;
+
+ if (LT(1) == IToken.t_try) {
+ isTryCatch= true;
+ } else {
+ // cv-qualifiers
+ cvloop: while(true) {
+ switch(LT(1)) {
+ case IToken.t_const:
+ isConst= true;
+ endOffset= consume().getEndOffset();
+ break;
+ case IToken.t_volatile:
+ isVolatile= true;
+ endOffset= consume().getEndOffset();
+ break;
+ default:
+ break cvloop;
+ }
+ }
+
+ // throws clause
+ if (LT(1) == IToken.t_throw) {
+ exceptionSpecIds = new ArrayList<IASTTypeId>(DEFAULT_SIZE_EXCEPTIONS_LIST);
+ consume(); // throw
+ consume(IToken.tLPAREN);
+
+ thloop: while(true) {
+ switch (LT(1)) {
+ case IToken.tRPAREN:
+ case IToken.tEOC:
+ endOffset= consume().getEndOffset();
+ break thloop;
+ case IToken.tCOMMA:
+ consume();
+ break;
+ default:
+ int thoffset= LA(1).getOffset();
+ IASTTypeId typeId= typeId(DeclarationOptions.TYPEID);
+ if (typeId != null) {
+ exceptionSpecIds.add(typeId);
+ } else {
+ int thendoffset= LA(1).getOffset();
+ if (thoffset == thendoffset) {
+ thendoffset= consume().getEndOffset();
+ }
+ IASTProblem p= createProblem(IProblem.SYNTAX_ERROR, thoffset, thendoffset-thoffset);
+ IASTProblemTypeId typeIdProblem = createTypeIDProblem();
+ typeIdProblem.setProblem(p);
+ ((ASTNode) typeIdProblem).setOffsetAndLength(((ASTNode) p));
+ exceptionSpecIds.add(typeIdProblem);
+ }
+ break;
+ }
+ }
+
+ // more __attribute__ after throws
+ __attribute_decl_seq(supportAttributeSpecifiers, false);
+ }
+
+ // pure virtual
+ if (LT(1) == IToken.tASSIGN && LT(2) == IToken.tINTEGER) {
+ char[] image = LA(2).getCharImage();
+ if (image.length == 1 && image[0] == '0') {
+ consume(); // tASSIGN
+ endOffset= consume().getEndOffset(); // tINTEGER
+ isPureVirtual= true;
+ }
+ }
+ }
+
+ final ICPPASTFunctionDeclarator fc= isTryCatch ? createTryBlockDeclarator() : createFunctionDeclarator();
+ fc.setVarArgs(encounteredVarArgs);
+ fc.setConst(isConst);
+ fc.setVolatile(isVolatile);
+ fc.setPureVirtual(isPureVirtual);
+ if (parameters != null) {
+ for (IASTParameterDeclaration param : parameters) {
+ fc.addParameterDeclaration(param);
+ }
+ }
+ if (exceptionSpecIds != null)
+ for (IASTTypeId exception : exceptionSpecIds) {
+ fc.addExceptionSpecificationTypeId(exception);
+ }
+ ((ASTNode) fc).setOffsetAndLength(startOffset, endOffset-startOffset);
+ return fc;
}
+ /**
+ * Parse an array declarator starting at the square bracket.
+ */
+ private IASTArrayDeclarator arrayDeclarator(DeclarationOptions option) throws EndOfFileException, BacktrackException {
+ ArrayList<IASTArrayModifier> arrayMods = new ArrayList<IASTArrayModifier>(DEFAULT_POINTEROPS_LIST_SIZE);
+ int start= LA(1).getOffset();
+ consumeArrayModifiers(option, arrayMods);
+ if (arrayMods.isEmpty())
+ throwBacktrack(LA(1));
+
+ final int endOffset = calculateEndOffset(arrayMods.get(arrayMods.size() - 1));
+ final IASTArrayDeclarator d = createArrayDeclarator();
+ for (IASTArrayModifier m : arrayMods) {
+ d.addArrayModifier(m);
+ }
+
+ ((ASTNode) d).setOffsetAndLength(start, endOffset-start);
+ return d;
+ }
+
+
+ /**
+ * Parses for a bit field declarator starting with the colon
+ */
+ private IASTFieldDeclarator bitFieldDeclarator() throws EndOfFileException, BacktrackException {
+ int start= consume(IToken.tCOLON).getOffset();
+
+ final IASTExpression bitField = constantExpression();
+ final int endOffset = calculateEndOffset(bitField);
+
+ IASTFieldDeclarator d = createFieldDeclarator();
+ d.setBitFieldSize(bitField);
+
+ ((ASTNode) d).setOffsetAndLength(start, endOffset-start);
+ return d;
+ }
protected IASTProblemTypeId createTypeIDProblem() {
return new CPPASTProblemTypeId();
@@ -3837,7 +3719,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
- protected IASTDeclarator createArrayDeclarator() {
+ protected IASTArrayDeclarator createArrayDeclarator() {
return new CPPASTArrayDeclarator();
}
@@ -3957,49 +3839,65 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (LT(1) == IToken.tLBRACE) {
consume();
-
- memberDeclarationLoop: while (true) {
- int checkToken = LA(1).hashCode();
- switch (LT(1)) {
- case IToken.t_public:
- case IToken.t_protected:
- case IToken.t_private: {
- IToken key = consume();
- int l = consume(IToken.tCOLON).getEndOffset();
- ICPPASTVisibilityLabel label = createVisibilityLabel();
- ((ASTNode) label).setOffsetAndLength(key.getOffset(), l - key.getOffset());
- label.setVisibility(token2Visibility(key.getType()));
- astClassSpecifier.addMemberDeclaration(label);
- label.setParent(astClassSpecifier);
- // this overrides the MEMBER_DECLARATION property
- label.setPropertyInParent(ICPPASTCompositeTypeSpecifier.VISIBILITY_LABEL);
- break;
- }
- case IToken.tRBRACE: {
- int l = consume().getEndOffset();
- ((ASTNode) astClassSpecifier).setLength(l - classKey.getOffset());
- break memberDeclarationLoop;
- }
- case IToken.tEOC:
- // Don't care about the offsets
- break memberDeclarationLoop;
- default:
- try {
- IASTDeclaration d = declaration();
- astClassSpecifier.addMemberDeclaration(d);
- } catch (BacktrackException bt) {
- IASTProblem p = failParse(bt);
- IASTProblemDeclaration pd = createProblemDeclaration();
- pd.setProblem(p);
- ((ASTNode) pd).setOffsetAndLength(((ASTNode) p));
- astClassSpecifier.addMemberDeclaration(pd);
- if (checkToken == LA(1).hashCode())
- errorHandling();
- }
-
- if (checkToken == LA(1).hashCode())
- failParseWithErrorHandling();
- }
+ final char[] outerName= currentClassName;
+ if (name instanceof ICPPASTQualifiedName) {
+ currentClassName= ((ICPPASTQualifiedName)name).getLastName().toCharArray();
+ } else {
+ currentClassName= name.toCharArray();
+ }
+ try {
+ memberDeclarationLoop: while (true) {
+ int checkToken = LA(1).hashCode();
+ switch (LT(1)) {
+ case IToken.t_public:
+ case IToken.t_protected:
+ case IToken.t_private: {
+ IToken key = consume();
+ int l = consume(IToken.tCOLON).getEndOffset();
+ ICPPASTVisibilityLabel label = createVisibilityLabel();
+ ((ASTNode) label).setOffsetAndLength(key.getOffset(), l - key.getOffset());
+ label.setVisibility(token2Visibility(key.getType()));
+ astClassSpecifier.addMemberDeclaration(label);
+ label.setParent(astClassSpecifier);
+ // this overrides the MEMBER_DECLARATION property
+ label.setPropertyInParent(ICPPASTCompositeTypeSpecifier.VISIBILITY_LABEL);
+ break;
+ }
+ case IToken.tRBRACE: {
+ int l = consume().getEndOffset();
+ ((ASTNode) astClassSpecifier).setLength(l - classKey.getOffset());
+ break memberDeclarationLoop;
+ }
+ case IToken.tEOC:
+ // Don't care about the offsets
+ break memberDeclarationLoop;
+ default:
+ try {
+ final IToken m= mark();
+ try {
+ IASTDeclaration d= declaration(DeclarationOptions.CPP_MEMBER);
+ astClassSpecifier.addMemberDeclaration(d);
+ } catch (BacktrackException e) {
+ backup(m);
+ IASTDeclaration d= usingDeclaration(m.getOffset());
+ astClassSpecifier.addMemberDeclaration(d);
+ }
+ } catch (BacktrackException bt) {
+ IASTProblem p = failParse(bt);
+ IASTProblemDeclaration pd = createProblemDeclaration();
+ pd.setProblem(p);
+ ((ASTNode) pd).setOffsetAndLength(((ASTNode) p));
+ astClassSpecifier.addMemberDeclaration(pd);
+ if (checkToken == LA(1).hashCode())
+ errorHandling();
+ }
+
+ if (checkToken == LA(1).hashCode())
+ failParseWithErrorHandling();
+ }
+ }
+ } finally {
+ currentClassName= outerName;
}
}
return astClassSpecifier;
@@ -4154,7 +4052,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
consume(IToken.tELLIPSIS);
isEllipsis = true;
} else {
- decl = simpleDeclaration(SimpleDeclarationStrategy.TRY_VARIABLE, true);
+ decl= simpleSingleDeclaration(DeclarationOptions.EXCEPTION);
}
if (LT(1) != IToken.tEOC)
consume(IToken.tRPAREN);
@@ -4193,6 +4091,29 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
}
+ private IASTSimpleDeclaration simpleSingleDeclaration(DeclarationOptions options) throws BacktrackException, EndOfFileException {
+ final int startOffset= LA(1).getOffset();
+ IASTDeclSpecifier declSpec;
+ IASTDeclarator declarator;
+
+ try {
+ declSpec= declSpecifierSeq(options);
+ declarator= initDeclarator(declSpec, options);
+ } catch (FoundDeclaratorException e) {
+ declSpec= e.declSpec;
+ declarator= e.declarator;
+ backup(e.currToken);
+ }
+
+ final int endOffset = figureEndOffset(declSpec, declarator);
+ final IASTSimpleDeclaration decl= createSimpleDeclaration();
+ decl.setDeclSpecifier(declSpec);
+ decl.addDeclarator(declarator);
+ ((ASTNode) decl).setOffsetAndLength(startOffset, endOffset - startOffset);
+
+ return decl;
+ }
+
protected ICPPASTCatchHandler createCatchHandler() {
return new CPPASTCatchHandler();
}
@@ -4249,7 +4170,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (LT(1) == IToken.tEOC)
break;
int checkOffset = LA(1).hashCode();
- IASTDeclaration declaration = declaration();
+ IASTDeclaration declaration = declaration(DeclarationOptions.GLOBAL);
translationUnit.addDeclaration(declaration);
if (LA(1).hashCode() == checkOffset)
@@ -4299,14 +4220,16 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return new CPPASTTranslationUnit();
}
- protected void consumeArrayModifiers(List<IASTNode> collection)
+ protected void consumeArrayModifiers(DeclarationOptions option, List<IASTArrayModifier> collection)
throws EndOfFileException, BacktrackException {
+ boolean allowExpression= option == DeclarationOptions.TYPEID_NEW;
while (LT(1) == IToken.tLBRACKET) {
int o = consume().getOffset(); // eat the '['
IASTExpression exp = null;
if (LT(1) != IToken.tRBRACKET && LT(1) != IToken.tEOC) {
- exp = constantExpression();
+ exp = allowExpression ? expression() : constantExpression();
+ allowExpression= false;
}
int l;
switch (LT(1)) {
@@ -4546,7 +4469,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return parseLabelStatement();
}
- return parseDeclarationOrExpressionStatement();
+ return parseDeclarationOrExpressionStatement(DeclarationOptions.LOCAL);
}
}
@@ -4642,7 +4565,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
} catch (BacktrackException bt) {
backup(mark);
try {
- return simpleDeclaration(SimpleDeclarationStrategy.TRY_VARIABLE, true);
+ return simpleSingleDeclaration(DeclarationOptions.CONDITION);
} catch (BacktrackException b) {
failParse();
throw b;
@@ -4651,8 +4574,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return null;
}
- private static final ASTVisitor EMPTY_VISITOR = new ASTVisitor() {
- };
@Override
protected ASTVisitor createAmbiguityNodeVisitor() {
@@ -4768,16 +4689,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return result;
}
- @Override
- protected void checkTokenVsDeclarator(IToken la, IASTDeclarator d) throws FoundDeclaratorException {
- switch (la.getType()) {
- case IToken.tCOLON:
- case IToken.t_try:
- throw new FoundDeclaratorException( d, la );
- default:
- super.checkTokenVsDeclarator(la, d);
- }
- }
@Override
protected IASTStatement functionBody() throws EndOfFileException, BacktrackException {
@@ -4787,11 +4698,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return s;
}
- @Override
- protected IASTDeclaration simpleDeclaration() throws BacktrackException, EndOfFileException {
- return simpleDeclarationStrategyUnion();
- }
-
protected IASTExpression unaryOperatorCastExpression(int operator) throws EndOfFileException, BacktrackException {
IToken mark = mark();
int offset = consume().getOffset();
@@ -4850,7 +4756,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
int startOffset;
startOffset = consume().getOffset();
consume(IToken.tLPAREN);
- IASTStatement init = forInitStatement();
+ IASTStatement init = forInitStatement(DeclarationOptions.LOCAL);
IASTNode for_condition = null;
switch (LT(1)) {
case IToken.tSEMI:
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
index 5ba2156b968..06fc8e70fe3 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
@@ -39,6 +39,7 @@ import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
+import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
@@ -2439,4 +2440,54 @@ public class CPPVisitor {
}
return e1;
}
+
+ /**
+ * Returns the outermost declarator the given <code>declarator</code> nests within, or
+ * <code>declarator</code> itself.
+ * @since 5.0
+ */
+ public static IASTDeclarator findOutermostDeclarator(IASTDeclarator declarator) {
+ while(true) {
+ IASTNode parent= declarator.getParent();
+ if (parent instanceof IASTDeclarator) {
+ declarator= (IASTDeclarator) parent;
+ } else {
+ return declarator;
+ }
+ }
+ }
+
+ /**
+ * Returns the innermost declarator nested within the given <code>declarator</code>, or
+ * <code>declarator</code> itself.
+ * @since 5.1
+ */
+ public static IASTDeclarator findInnermostDeclarator(IASTDeclarator declarator) {
+ IASTDeclarator innermost= null;
+ while(declarator != null) {
+ innermost= declarator;
+ declarator= declarator.getNestedDeclarator();
+ }
+ return innermost;
+ }
+
+ /**
+ * Searches for the innermost declarator that contributes the the type declared.
+ * @since 5.1
+ */
+ public static IASTDeclarator findTypeRelevantDeclarator(IASTDeclarator declarator) {
+ IASTDeclarator result= findInnermostDeclarator(declarator);
+ while (result.getPointerOperators().length == 0
+ && result instanceof IASTFieldDeclarator == false
+ && result instanceof IASTFunctionDeclarator == false
+ && result instanceof IASTArrayModifier == false) {
+ final IASTNode parent= result.getParent();
+ if (parent instanceof IASTDeclarator) {
+ result= (IASTDeclarator) parent;
+ } else {
+ return result;
+ }
+ }
+ return result;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriter.java
index 22b013232f2..4205875e45b 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriter.java
@@ -11,6 +11,8 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.rewrite.astwriter;
+import org.eclipse.cdt.core.dom.ast.ASTVisitor;
+import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationStore;
import org.eclipse.cdt.internal.core.dom.rewrite.changegenerator.ChangeGeneratorWriterVisitor;
@@ -78,7 +80,16 @@ public class ASTWriter {
*/
public String write(IASTNode rootNode, String fileScope, NodeCommentMap commentMap) throws ProblemRuntimeException {
transformationVisitor = new ChangeGeneratorWriterVisitor(modificationStore, givenIndentation, fileScope, commentMap);
- rootNode.accept(transformationVisitor);
+
+ // mstodo: workaround for
+ if (rootNode instanceof IASTArrayModifier) {
+ int result= transformationVisitor.visit((IASTArrayModifier) rootNode);
+ if (result == ASTVisitor.PROCESS_CONTINUE) {
+ rootNode.accept(transformationVisitor);
+ }
+ } else {
+ rootNode.accept(transformationVisitor);
+ }
String str = transformationVisitor.toString();
transformationVisitor.cleanCache();
return str;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriterVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriterVisitor.java
index edb2af11c73..d87b5f93334 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriterVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriterVisitor.java
@@ -7,11 +7,13 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Institute for Software - initial API and implementation
+ * Institute for Software - initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.rewrite.astwriter;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
+import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.IASTComment;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
@@ -200,6 +202,12 @@ public class ASTWriterVisitor extends CPPASTVisitor {
return ASTVisitor.PROCESS_SKIP;
}
+ public int visit(IASTArrayModifier amod) {
+ if(!macroHandler.checkisMacroExpansionNode(amod)) {
+ declaratorWriter.writeArrayModifier(amod);
+ }
+ return ASTVisitor.PROCESS_SKIP;
+ }
@Override
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclaratorWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclaratorWriter.java
index 5fe4820ca77..d6b248ca4da 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclaratorWriter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclaratorWriter.java
@@ -7,7 +7,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Institute for Software - initial API and implementation
+ * Institute for Software - initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.rewrite.astwriter;
@@ -15,6 +16,7 @@ import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTName;
@@ -254,12 +256,18 @@ public class DeclaratorWriter extends NodeWriter {
protected void writeArrayModifiers(IASTArrayDeclarator arrDecl, IASTArrayModifier[] arrMods) {
for (IASTArrayModifier modifier : arrMods) {
- scribe.print('[');
- modifier.accept(visitor);
- scribe.print(']');
+ writeArrayModifier(modifier);
}
}
+ protected void writeArrayModifier(IASTArrayModifier modifier) {
+ scribe.print('[');
+ IASTExpression ex= modifier.getConstantExpression();
+ if (ex != null) {
+ ex.accept(visitor);
+ }
+ scribe.print(']');
+ }
private void writeFieldDeclarator(IASTFieldDeclarator fieldDecl) {
IASTPointerOperator[] pointOps = fieldDecl.getPointerOperators();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ExpressionWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ExpressionWriter.java
index 17556e7af79..241cb58a802 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ExpressionWriter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ExpressionWriter.java
@@ -353,25 +353,14 @@ public class ExpressionWriter extends NodeWriter{
IASTTypeId typeId = newExp.getTypeId();
visitNodeIfNotNull(typeId);
- IASTExpression[] arraySizeExpressions = getNewTypeIdArrayExpressions(newExp, newExp.getNewTypeIdArrayExpressions());
- for (IASTExpression expression : arraySizeExpressions) {
- scribe.print('[');
- expression.accept(visitor);
- scribe.print(']');
- }
- if (arraySizeExpressions.length == 0 ) {
+ IASTExpression initExp= getNewInitializer(newExp);
+ if (initExp != null) {
scribe.print('(');
- IASTExpression initExp = getNewInitializer(newExp);
- visitNodeIfNotNull(initExp);
+ initExp.accept(visitor);
scribe.print(')');
}
}
- protected IASTExpression[] getNewTypeIdArrayExpressions(
- ICPPASTNewExpression newExp, IASTExpression[] expressions) {
- return newExp.getNewTypeIdArrayExpressions();
- }
-
protected IASTExpression getNewInitializer(ICPPASTNewExpression newExp) {
return newExp.getNewInitializer();
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java
index 8901a868856..78ac97b3102 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java
@@ -7,7 +7,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Institute for Software - initial API and implementation
+ * Institute for Software - initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.rewrite.changegenerator;
@@ -16,6 +17,8 @@ import java.util.LinkedHashMap;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
+import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.IASTComment;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
@@ -26,10 +29,13 @@ import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.rewrite.ASTModification;
import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationMap;
import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationStore;
@@ -77,7 +83,7 @@ public class ChangeGenerator extends CPPASTVisitor {
shouldVisitDeclSpecifiers = true;
shouldVisitDeclarators = true;
-
+
shouldVisitInitializers = true;
shouldVisitBaseSpecifiers = true;
@@ -132,7 +138,7 @@ public class ChangeGenerator extends CPPASTVisitor {
private IASTNode determineParentToBeRewritten(IASTNode modifiedNode, List<ASTModification> modificationsForNode) {
IASTNode modifiedNodeParent = modifiedNode;
for(ASTModification currentModification : modificationsForNode){
- if(currentModification.getKind() != ASTModification.ModificationKind.APPEND_CHILD){
+ if(currentModification.getKind() == ASTModification.ModificationKind.REPLACE){
modifiedNodeParent = modifiedNode.getParent();
break;
}
@@ -385,9 +391,51 @@ public class ChangeGenerator extends CPPASTVisitor {
synthTreatment(declarator);
return ASTVisitor.PROCESS_SKIP;
}
+
+ // mstodo workaround
+ if (declarator instanceof IASTArrayDeclarator) {
+ IASTPointerOperator [] ptrOps = declarator.getPointerOperators();
+ for ( int i = 0; i < ptrOps.length; i++ ) {
+ if( !ptrOps[i].accept( this ) ) return PROCESS_ABORT;
+ }
+
+ IASTDeclarator nestedDeclarator= declarator.getNestedDeclarator();
+ IASTName name= declarator.getName();
+ if (nestedDeclarator == null && name != null) {
+ IASTDeclarator outermost= CPPVisitor.findOutermostDeclarator(declarator);
+ if (outermost.getPropertyInParent() != IASTTypeId.ABSTRACT_DECLARATOR) {
+ if (!name.accept(this)) return PROCESS_ABORT;
+ }
+ }
+
+ if (nestedDeclarator != null) {
+ if (!nestedDeclarator.accept(this)) return PROCESS_ABORT;
+ }
+
+ IASTArrayModifier [] mods = ((IASTArrayDeclarator) declarator).getArrayModifiers();
+ for ( int i = 0; i < mods.length; i++ ) {
+ int result= visit(mods[i]);
+ if (result != PROCESS_CONTINUE)
+ return result;
+
+ if( !mods[i].accept( this ) ) return PROCESS_ABORT;
+ }
+ IASTInitializer initializer = declarator.getInitializer();
+ if( initializer != null ) if( !initializer.accept( this ) ) return PROCESS_ABORT;
+ return PROCESS_CONTINUE;
+ }
+
return super.visit(declarator);
}
-
+
+ public int visit(IASTArrayModifier mod) {
+ if (hasChangedChild(mod)) {
+ synthTreatment(mod);
+ return ASTVisitor.PROCESS_SKIP;
+ }
+ return PROCESS_CONTINUE;
+ }
+
@Override
public int visit(ICPPASTNamespaceDefinition namespaceDefinition) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java
index 69b3ce6edd7..c60da015169 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java
@@ -7,10 +7,12 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Institute for Software - initial API and implementation
+ * Institute for Software - initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.rewrite.changegenerator;
+import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
@@ -271,6 +273,14 @@ public class ChangeGeneratorWriterVisitor extends ASTWriterVisitor {
}
@Override
+ public int visit(IASTArrayModifier arrayModifier) {
+ if (doBeforeEveryNode(arrayModifier) == PROCESS_CONTINUE) {
+ return super.visit(arrayModifier);
+ }
+ return PROCESS_SKIP;
+ }
+
+ @Override
public int visit(IASTExpression expression) {
if (doBeforeEveryNode(expression) == PROCESS_CONTINUE) {
return super.visit(expression);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTExpressionWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTExpressionWriter.java
index 00eb6ddcf81..7a5fb5c5459 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTExpressionWriter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTExpressionWriter.java
@@ -7,7 +7,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Institute for Software - initial API and implementation
+ * Institute for Software - initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.rewrite.changegenerator;
@@ -76,13 +77,4 @@ public class ModifiedASTExpressionWriter extends ExpressionWriter {
}
return initializer;
}
-
- @Override
- protected IASTExpression[] getNewTypeIdArrayExpressions(
- ICPPASTNewExpression newExp, IASTExpression[] expressions) {
- IASTExpression[] modifiedExpressions = modificationHelper.createModifiedChildArray(newExp, expressions, IASTExpression.class);
- return modifiedExpressions;
- }
-
-
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java
index 7ad3c74dc81..f9cb9681f41 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java
@@ -71,6 +71,9 @@ class ASTPreprocessorName extends ASTPreprocessorNode implements IASTName {
public int getRoleOfName(boolean allowResolution) {
return IASTNameOwner.r_unclear;
}
+ public IASTName getLastName() {
+ return this;
+ }
}
class ASTPreprocessorDefinition extends ASTPreprocessorName {
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
index f1757552a10..cbbb61e826f 100644
--- 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
@@ -33,8 +33,7 @@ public class BasicTokenDuple implements ITokenDuple {
lastToken = last;
}
- //TODO - move numSegments to a subclass
- private int numSegments = -1;
+ protected int numSegments = -1;
BasicTokenDuple( ITokenDuple firstDuple, ITokenDuple secondDuple ){
this( firstDuple.getFirstToken(), secondDuple.getLastToken() );
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
index d6dd032080b..0b16a583eb6 100644
--- 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
@@ -23,7 +23,6 @@ import org.eclipse.cdt.core.parser.ITokenDuple;
public class TemplateTokenDuple extends BasicTokenDuple {
protected final List [] argLists;
- private final int numSegments;
/**
* @param first
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java
index d8a2446c38c..8940be12267 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java
@@ -167,6 +167,10 @@ public class PDOMASTAdapter {
public String toString() {
return fDelegate.toString();
}
+
+ public IASTName getLastName() {
+ return this;
+ }
}
private static class AnonymousEnumeration implements IEnumeration {

Back to the top