diff options
author | Markus Schorn | 2009-12-18 09:58:29 +0000 |
---|---|---|
committer | Markus Schorn | 2009-12-18 09:58:29 +0000 |
commit | 6ad255dfed8ad032c98564bbf729134ad0394fef (patch) | |
tree | f2dace8c663740cba1401d962616d9e35cd95602 /core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom | |
parent | 2a9515f36d66e2d225904de098c33b5e8c25d79e (diff) | |
download | org.eclipse.cdt-6ad255dfed8ad032c98564bbf729134ad0394fef.tar.gz org.eclipse.cdt-6ad255dfed8ad032c98564bbf729134ad0394fef.tar.xz org.eclipse.cdt-6ad255dfed8ad032c98564bbf729134ad0394fef.zip |
Bug 280909: Syntax and bindings for variadic templates.
Diffstat (limited to 'core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom')
56 files changed, 1372 insertions, 631 deletions
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 3f19de9a2f4..67ce8eb3dfb 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 @@ -67,6 +67,7 @@ import org.eclipse.cdt.core.dom.ast.IASTWhileStatement; import org.eclipse.cdt.core.dom.ast.INodeFactory; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPackExpansionExpression; import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression; import org.eclipse.cdt.core.dom.parser.IBuiltinBindingsProvider; import org.eclipse.cdt.core.dom.parser.ISourceCodeParser; @@ -515,6 +516,12 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { return n; } + protected final <T extends IASTNode> T setRange(T n, IASTNode from, int endOffset) { + final int offset = ((ASTNode) from).getOffset(); + ((ASTNode) n).setOffsetAndLength(offset, endOffset-offset); + return n; + } + protected final <T extends IASTNode> T setRange(T n, int offset, int endOffset) { ((ASTNode) n).setOffsetAndLength(offset, endOffset-offset); return n; @@ -525,9 +532,10 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { adjustEndOffset(n, endOffset); } - protected final void adjustEndOffset(IASTNode n, final int endOffset) { + protected final <T extends IASTNode> T adjustEndOffset(T n, final int endOffset) { final ASTNode node = (ASTNode) n; node.setLength(endOffset-node.getOffset()); + return n; } protected final int getEndOffset() { @@ -914,8 +922,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { IASTExpression fExpression; final CastAmbiguityMarker fAmbiguityMarker; - public BinaryOperator(BinaryOperator left, IASTExpression expression, int operatorToken, int leftPrecedence, int rightPrecedence) { - fNext= left; + public BinaryOperator(BinaryOperator nextOp, IASTExpression expression, int operatorToken, int leftPrecedence, int rightPrecedence) { + fNext= nextOp; fOperatorToken= operatorToken; fLeftPrecedence= leftPrecedence; fRightPrecedence= rightPrecedence; @@ -978,6 +986,17 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { } return conditionalEx; + case IToken.tELLIPSIS: + if (right instanceof ICPPASTPackExpansionExpression) { + ((ICPPASTPackExpansionExpression) right).setPattern(left); + int endOffset= ((ASTNode) right).getLength(); + setRange(right, left); + adjustEndOffset(right, endOffset); + return right; + } + assert false; + return left; + case IToken.tCOMMA: IASTExpressionList list; if (left instanceof IASTExpressionList) { 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 index c4f3435dec0..3f215de3c67 100644 --- 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 @@ -24,6 +24,7 @@ public class DeclarationOptions { final public static int NO_FUNCTIONS= 0x40; final public static int NO_ARRAYS= 0x80; final public static int NO_NESTED= 0x100; + final public static int ALLOW_PARAMETER_PACKS= 0x200; public static final DeclarationOptions GLOBAL= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | ALLOW_CONSTRUCTOR_INITIALIZER), @@ -31,7 +32,7 @@ public class DeclarationOptions { C_MEMBER= new DeclarationOptions(ALLOW_BITFIELD | ALLOW_ABSTRACT), CPP_MEMBER= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | ALLOW_BITFIELD), LOCAL= new DeclarationOptions(ALLOW_CONSTRUCTOR_INITIALIZER), - PARAMETER= new DeclarationOptions(ALLOW_ABSTRACT), + PARAMETER= new DeclarationOptions(ALLOW_ABSTRACT | ALLOW_PARAMETER_PACKS), 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), @@ -47,6 +48,7 @@ public class DeclarationOptions { final public boolean fAllowConstructorInitializer; final public boolean fAllowFunctions; final public boolean fAllowNested; + final public boolean fAllowParameterPacks; public DeclarationOptions(int options) { fAllowEmptySpecifier= (options & ALLOW_EMPTY_SPECIFIER) != 0; @@ -57,5 +59,6 @@ public class DeclarationOptions { fAllowConstructorInitializer= fAllowInitializer && (options & ALLOW_CONSTRUCTOR_INITIALIZER) != 0; fAllowFunctions= (options & NO_FUNCTIONS) == 0; fAllowNested= (options & NO_NESTED) == 0; + fAllowParameterPacks= (options & ALLOW_PARAMETER_PACKS) != 0; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java index a7d8d0e62ee..a25152b3397 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java @@ -25,6 +25,7 @@ public interface ITypeMarshalBuffer { final static byte FUNCTION_TYPE= 5; final static byte REFERENCE= 6; final static byte POINTER_TO_MEMBER= 7; + final static byte PACK_EXPANSION= 8; static final byte KIND_MASK = 0xf; final static int FLAG1 = 0x10; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java index 0f6c173b0eb..665fd600093 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java @@ -448,7 +448,8 @@ public class Value implements IValue { private static Object evaluateUnaryExpression(IASTUnaryExpression ue, Map<String, Integer> unknownSigs, List<ICPPUnknownBinding> unknowns, int maxdepth) throws UnknownValueException { final int unaryOp= ue.getOperator(); - if (unaryOp == IASTUnaryExpression.op_amper || unaryOp == IASTUnaryExpression.op_star) + if (unaryOp == IASTUnaryExpression.op_amper || unaryOp == IASTUnaryExpression.op_star || + unaryOp == IASTUnaryExpression.op_sizeof || unaryOp == IASTUnaryExpression.op_sizeofParameterPack) throw UNKNOWN_EX; final Object value= evaluate(ue.getOperand(), unknownSigs, unknowns, maxdepth); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/VariableReadWriteFlags.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/VariableReadWriteFlags.java index 76e37adcc82..3e80a5e342f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/VariableReadWriteFlags.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/VariableReadWriteFlags.java @@ -259,6 +259,7 @@ public abstract class VariableReadWriteFlags { return PDOMName.READ_ACCESS; case IASTUnaryExpression.op_sizeof: + case IASTUnaryExpression.op_sizeofParameterPack: case IGNUASTUnaryExpression.op_alignOf: case IGNUASTUnaryExpression.op_typeof: return 0; 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 index cc765d57694..64e6b882300 100644 --- 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 @@ -17,6 +17,7 @@ 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.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclarator; @@ -28,7 +29,7 @@ import org.eclipse.core.runtime.Assert; * <br> * Example: void f(int (D)); // is D a type? */ -public class CPPASTAmbiguousDeclarator extends ASTAmbiguousNode implements IASTAmbiguousDeclarator { +public class CPPASTAmbiguousDeclarator extends ASTAmbiguousNode implements IASTAmbiguousDeclarator, ICPPASTDeclarator { private IASTDeclarator[] dtors = new IASTDeclarator[2]; private int dtorPos=-1; @@ -124,4 +125,13 @@ public class CPPASTAmbiguousDeclarator extends ASTAmbiguousNode implements IASTA assertNotFrozen(); Assert.isLegal(false); } + + public boolean declaresParameterPack() { + return false; + } + + public void setDeclaresParameterPack(boolean val) { + assertNotFrozen(); + Assert.isLegal(false); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousParameterDeclaration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousParameterDeclaration.java new file mode 100644 index 00000000000..4bcc7fbe8aa --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousParameterDeclaration.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2008, 2009 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.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.core.dom.ast.IASTPointerOperator; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; +import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode; +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.IASTAmbiguousParameterDeclaration; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; +import org.eclipse.core.runtime.Assert; + +/** + * Handles ambiguities for ellipsis in parameter declaration. + * <br> + * template<typename... T> void function(T ...); // is T a parameter pack? + */ +public class CPPASTAmbiguousParameterDeclaration extends ASTAmbiguousNode implements + IASTAmbiguousParameterDeclaration, ICPPASTParameterDeclaration { + + private ICPPASTParameterDeclaration fParameterDecl; + + public CPPASTAmbiguousParameterDeclaration(ICPPASTParameterDeclaration decl) { + fParameterDecl= decl; + } + + public void addParameterDeclaration(IASTParameterDeclaration d) { + assert false; + } + + + @Override + public IASTNode resolveAmbiguity(ASTVisitor resolver) { + final IASTAmbiguityParent owner= (IASTAmbiguityParent) getParent(); + + // Setup the ast to use the alternative + owner.replace(this, fParameterDecl); + + IType t= CPPVisitor.createParameterType(fParameterDecl, true); + if (!(t instanceof ICPPParameterPackType) || + !SemanticUtil.containsParameterPack(((ICPPParameterPackType) t).getType())) { + final ICPPASTDeclarator dtor = fParameterDecl.getDeclarator(); + dtor.setDeclaresParameterPack(false); + adjustOffsets(dtor); + ((ICPPASTFunctionDeclarator) fParameterDecl.getParent()).setVarArgs(true); + } + return fParameterDecl; + } + + private void adjustOffsets(final ICPPASTDeclarator dtor) { + IASTPointerOperator[] ptrOps= dtor.getPointerOperators(); + final ASTNode asNode = (ASTNode) dtor; + if (ptrOps.length > 0) { + final ASTNode first = (ASTNode)ptrOps[0]; + final ASTNode last = (ASTNode)ptrOps[ptrOps.length-1]; + asNode.setOffsetAndLength(first.getOffset(), last.getOffset() + last.getLength()); + } else { + asNode.setOffsetAndLength(0, 0); + } + } + + public IASTParameterDeclaration[] getParameterDeclarations() { + return new IASTParameterDeclaration[] {fParameterDecl}; + } + + @Override + public IASTNode[] getNodes() { + return getParameterDeclarations(); + } + + public IASTDeclSpecifier getDeclSpecifier() { + return fParameterDecl.getDeclSpecifier(); + } + + public ICPPASTDeclarator getDeclarator() { + return fParameterDecl.getDeclarator(); + } + + public void setDeclSpecifier(IASTDeclSpecifier declSpec) { + Assert.isLegal(false); + } + + public void setDeclarator(IASTDeclarator declarator) { + Assert.isLegal(false); + } + + public ICPPASTParameterDeclaration copy() { + Assert.isLegal(false); + return null; + } + + public boolean isParameterPack() { + Assert.isLegal(false); + return true; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousTemplateArgument.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousTemplateArgument.java index e41dece1cd1..f38dbc9e6a2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousTemplateArgument.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousTemplateArgument.java @@ -12,17 +12,18 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; -import com.ibm.icu.text.MessageFormat; import java.util.ArrayList; import java.util.List; +import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAmbiguousTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPackExpansionExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode; -import org.eclipse.cdt.internal.core.parser.ParserMessages; +import org.eclipse.core.runtime.Assert; /** * Ambiguity node for deciding between type-id and id-expression in a template argument. @@ -32,21 +33,22 @@ public class CPPASTAmbiguousTemplateArgument extends ASTAmbiguousNode implements private List<IASTNode> fNodes; /** - * @param nodes nodes of type {@link IASTTypeId} or {@link IASTIdExpression} - */ - /* - * We can replace this with a version taking ICPPASTTemplateArgument... - * in the future + * @param nodes nodes of type {@link IASTTypeId}, {@link IASTIdExpression} or {@link ICPPASTPackExpansionExpression}. */ public CPPASTAmbiguousTemplateArgument(IASTNode... nodes) { fNodes= new ArrayList<IASTNode>(2); for(IASTNode node : nodes) { - if(node instanceof IASTTypeId || node instanceof IASTIdExpression) { + if (node instanceof IASTTypeId || node instanceof IASTIdExpression) { fNodes.add(node); + } else if (node instanceof ICPPASTPackExpansionExpression) { + final IASTExpression pattern = ((ICPPASTPackExpansionExpression) node).getPattern(); + if (pattern instanceof IASTIdExpression) { + fNodes.add(node); + } else { + Assert.isLegal(false, pattern == null ? "null" : pattern.getClass().getName()); //$NON-NLS-1$ + } } else { - String ns= node == null ? "null" : node.getClass().getName(); //$NON-NLS-1$ - String msg= MessageFormat.format(ParserMessages.getString("CPPASTAmbiguousTemplateArgument_InvalidConstruction"), new Object[] {ns}); //$NON-NLS-1$ - throw new IllegalArgumentException(msg); + Assert.isLegal(false, node == null ? "null" : node.getClass().getName()); //$NON-NLS-1$ } } } @@ -69,7 +71,12 @@ public class CPPASTAmbiguousTemplateArgument extends ASTAmbiguousNode implements assertNotFrozen(); addNode(idExpression); } - + + public void addIdExpression(IASTExpression idExpression) { + assertNotFrozen(); + addNode(idExpression); + } + private void addNode(IASTNode node) { fNodes.add(node); node.setParent(this); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArrayDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArrayDeclarator.java index bc606c885ff..9539f783f77 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArrayDeclarator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArrayDeclarator.java @@ -1,27 +1,27 @@ /******************************************************************************* - * Copyright (c) 2004, 2008 IBM Corporation and others. + * Copyright (c) 2004, 2009 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 + * John Camelon (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.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTArrayDeclarator; import org.eclipse.cdt.core.parser.util.ArrayUtil; /** - * @author jcamelon + * Array declarator for c++. */ -public class CPPASTArrayDeclarator extends CPPASTDeclarator implements IASTArrayDeclarator { +public class CPPASTArrayDeclarator extends CPPASTDeclarator implements ICPPASTArrayDeclarator { private IASTArrayModifier [] arrayMods = null; private int arrayModsPos=-1; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBaseSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBaseSpecifier.java index 8f24e23f8ab..4426121805a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBaseSpecifier.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBaseSpecifier.java @@ -1,12 +1,12 @@ /******************************************************************************* - * Copyright (c) 2004, 2008 IBM Corporation and others. + * Copyright (c) 2004, 2009 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 + * John Camelon (IBM) - Initial API and implementation * Bryan Wilkinson (QNX) * Markus Schorn (Wind River Systems) *******************************************************************************/ @@ -27,14 +27,14 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; /** - * @author jcamelon + * Base class specifier */ -public class CPPASTBaseSpecifier extends ASTNode implements - ICPPASTBaseSpecifier, IASTCompletionContext { +public class CPPASTBaseSpecifier extends ASTNode implements ICPPASTBaseSpecifier, IASTCompletionContext { private boolean isVirtual; private int visibility; private IASTName name; + private boolean fIsPackExpansion; public CPPASTBaseSpecifier() { @@ -54,6 +54,7 @@ public class CPPASTBaseSpecifier extends ASTNode implements CPPASTBaseSpecifier copy = new CPPASTBaseSpecifier(name == null ? null : name.copy()); copy.isVirtual = isVirtual; copy.visibility = visibility; + copy.fIsPackExpansion= fIsPackExpansion; copy.setOffsetAndLength(this); return copy; } @@ -129,9 +130,9 @@ public class CPPASTBaseSpecifier extends ASTNode implements } } - for (int i = 0; i < bindings.length; i++) { - if (bindings[i] instanceof ICPPClassType) { - ICPPClassType base = (ICPPClassType) bindings[i]; + for (IBinding binding : bindings) { + if (binding instanceof ICPPClassType) { + ICPPClassType base = (ICPPClassType) binding; try { int key = base.getKey(); if (key == ICPPClassType.k_class && @@ -145,4 +146,13 @@ public class CPPASTBaseSpecifier extends ASTNode implements return filtered.toArray(new IBinding[filtered.size()]); } + + public boolean isPackExpansion() { + return fIsPackExpansion; + } + + public void setIsPackExpansion(boolean val) { + assertNotFrozen(); + fIsPackExpansion= val; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java index f1969520b3e..f595db5c936 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java @@ -43,6 +43,7 @@ public class CPPASTConstructorChainInitializer extends ASTNode implements private IASTName name; private IASTExpression value; + private boolean fIsPackExpansion; public CPPASTConstructorChainInitializer() { @@ -58,6 +59,7 @@ public class CPPASTConstructorChainInitializer extends ASTNode implements copy.setMemberInitializerId(name == null ? null : name.copy()); copy.setInitializerValue(value == null ? null : value.copy()); copy.setOffsetAndLength(this); + copy.fIsPackExpansion= fIsPackExpansion; return copy; } @@ -173,4 +175,13 @@ public class CPPASTConstructorChainInitializer extends ASTNode implements return null; } + + public boolean isPackExpansion() { + return fIsPackExpansion; + } + + public void setIsPackExpansion(boolean val) { + assertNotFrozen(); + fIsPackExpansion= val; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorInitializer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorInitializer.java index ec68d7846ff..acc4f311e31 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorInitializer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorInitializer.java @@ -1,12 +1,13 @@ /******************************************************************************* - * Copyright (c) 2004, 2008 IBM Corporation and others. + * Copyright (c) 2004, 2009 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 + * John Camelon (IBM) - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -18,12 +19,13 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; /** - * @author jcamelon + * Initializer in parenthesis. */ public class CPPASTConstructorInitializer extends ASTNode implements ICPPASTConstructorInitializer, IASTAmbiguityParent { private IASTExpression exp; + private boolean fIsPackExpansion; public CPPASTConstructorInitializer() { @@ -36,6 +38,7 @@ public class CPPASTConstructorInitializer extends ASTNode implements public CPPASTConstructorInitializer copy() { CPPASTConstructorInitializer copy = new CPPASTConstructorInitializer(exp == null ? null : exp.copy()); copy.setOffsetAndLength(this); + copy.fIsPackExpansion= fIsPackExpansion; return copy; } @@ -79,4 +82,13 @@ public class CPPASTConstructorInitializer extends ASTNode implements exp = (IASTExpression) other; } } + + public boolean isPackExpansion() { + return fIsPackExpansion; + } + + public void setIsPackExpansion(boolean val) { + assertNotFrozen(); + fIsPackExpansion= val; + } } 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 b2a77f10b0f..d7d2035bc52 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 @@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; 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.dom.ast.cpp.ICPPASTDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.parser.util.ArrayUtil; @@ -34,12 +35,12 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; /** * C++ specific declarator. */ -public class CPPASTDeclarator extends ASTNode implements IASTDeclarator { +public class CPPASTDeclarator extends ASTNode implements ICPPASTDeclarator { private IASTInitializer initializer; private IASTName name; private IASTDeclarator nested; private IASTPointerOperator[] pointerOps = null; - private int pointerOpsPos= -1; + private boolean isPackExpansion; public CPPASTDeclarator() { } @@ -64,14 +65,19 @@ public class CPPASTDeclarator extends ASTNode implements IASTDeclarator { copy.setName(name == null ? null : name.copy()); copy.setInitializer(initializer == null ? null : initializer.copy()); copy.setNestedDeclarator(nested == null ? null : nested.copy()); + copy.isPackExpansion= isPackExpansion; for(IASTPointerOperator pointer : getPointerOperators()) copy.addPointerOperator(pointer == null ? null : pointer.copy()); copy.setOffsetAndLength(this); } + public boolean declaresParameterPack() { + return isPackExpansion; + } + public IASTPointerOperator[] getPointerOperators() { if (pointerOps == null) return IASTPointerOperator.EMPTY_ARRAY; - pointerOps = (IASTPointerOperator[]) ArrayUtil.removeNullsAfter(IASTPointerOperator.class, pointerOps, pointerOpsPos); + pointerOps = (IASTPointerOperator[]) ArrayUtil.trim(IASTPointerOperator.class, pointerOps); return pointerOps; } @@ -101,7 +107,7 @@ public class CPPASTDeclarator extends ASTNode implements IASTDeclarator { if (operator != null) { operator.setParent(this); operator.setPropertyInParent(POINTER_OPERATOR); - pointerOps = (IASTPointerOperator[]) ArrayUtil.append(IASTPointerOperator.class, pointerOps, ++pointerOpsPos, operator); + pointerOps = (IASTPointerOperator[]) ArrayUtil.append(IASTPointerOperator.class, pointerOps, operator); } } @@ -122,8 +128,13 @@ public class CPPASTDeclarator extends ASTNode implements IASTDeclarator { name.setPropertyInParent(DECLARATOR_NAME); } } + + public void setDeclaresParameterPack(boolean val) { + assertNotFrozen(); + isPackExpansion= val; + } - @Override + @Override public boolean accept(ASTVisitor action) { if (action.shouldVisitDeclarators) { switch(action.visit(this)) { @@ -133,9 +144,13 @@ public class CPPASTDeclarator extends ASTNode implements IASTDeclarator { } } - for (int i = 0; i <= pointerOpsPos; i++) { - if (!pointerOps[i].accept(action)) - return false; + if (pointerOps != null) { + for (IASTPointerOperator op : pointerOps) { + if (op == null) + break; + if (!op.accept(action)) + return false; + } } if (nested == null && name != null) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldDeclarator.java index 34ea4a14ca3..b4a0ca750dc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldDeclarator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldDeclarator.java @@ -1,32 +1,31 @@ /******************************************************************************* - * Copyright (c) 2004, 2008 IBM Corporation and others. + * Copyright (c) 2004, 2009 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 + * John Camelon (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.IASTExpression; -import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldDeclarator; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; /** - * @author jcamelon + * Field declarator for c++. */ public class CPPASTFieldDeclarator extends CPPASTDeclarator implements - IASTFieldDeclarator, IASTAmbiguityParent { + ICPPASTFieldDeclarator, IASTAmbiguityParent { private IASTExpression bitField; - - + public CPPASTFieldDeclarator() { } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionDeclarator.java index 22ac6d7e455..15a5010521f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionDeclarator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionDeclarator.java @@ -19,18 +19,19 @@ import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope; import org.eclipse.cdt.core.parser.util.ArrayUtil; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; +import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; +import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; /** * Represents a function declarator. */ -public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPASTFunctionDeclarator { - private IASTParameterDeclaration[] parameters = null; - private int parametersPos = -1; +public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPASTFunctionDeclarator, + IASTAmbiguityParent { + private ICPPASTParameterDeclaration[] parameters = null; private IASTTypeId[] typeIds = NO_EXCEPTION_SPECIFICATION; - private int typeIdsPos = -1; private boolean varArgs; private boolean pureVirtual; @@ -63,11 +64,11 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS return copy; } - public IASTParameterDeclaration[] getParameters() { + public ICPPASTParameterDeclaration[] getParameters() { if (parameters == null) - return IASTParameterDeclaration.EMPTY_PARAMETERDECLARATION_ARRAY; + return ICPPASTParameterDeclaration.EMPTY_CPPPARAMETERDECLARATION_ARRAY; - return parameters= ArrayUtil.trimAt(IASTParameterDeclaration.class, parameters, parametersPos); + return parameters= ArrayUtil.trim(parameters); } public void addParameterDeclaration(IASTParameterDeclaration parameter) { @@ -75,7 +76,7 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS if (parameter != null) { parameter.setParent(this); parameter.setPropertyInParent(FUNCTION_PARAMETER); - parameters = (IASTParameterDeclaration[]) ArrayUtil.append(IASTParameterDeclaration.class, parameters, ++parametersPos, parameter); + parameters = (ICPPASTParameterDeclaration[]) ArrayUtil.append(ICPPASTParameterDeclaration.class, parameters, parameter); } } @@ -107,7 +108,7 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS } public IASTTypeId[] getExceptionSpecification() { - return typeIds= ArrayUtil.trimAt(IASTTypeId.class, typeIds, typeIdsPos); + return typeIds= ArrayUtil.trim(typeIds); } public void setEmptyExceptionSpecification() { @@ -118,7 +119,8 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS public void addExceptionSpecificationTypeId(IASTTypeId typeId) { assertNotFrozen(); if (typeId != null) { - typeIds = (IASTTypeId[]) ArrayUtil.append(IASTTypeId.class, typeIds, ++typeIdsPos, typeId); + assert typeIds != null; + typeIds = ArrayUtil.append(typeIds, typeId); typeId.setParent(this); typeId.setPropertyInParent(EXCEPTION_TYPEID); } @@ -135,7 +137,7 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS @Deprecated public org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer[] getConstructorChain() { - if (CPPVisitor.findTypeRelevantDeclarator(this) == this) { + if (ASTQueries.findTypeRelevantDeclarator(this) == this) { IASTNode parent= getParent(); while(!(parent instanceof IASTDeclaration)) { if (parent == null) @@ -168,7 +170,7 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS if (node instanceof IASTParameterDeclaration) return null; - if (CPPVisitor.findTypeRelevantDeclarator(this) == this) { + if (ASTQueries.findTypeRelevantDeclarator(this) == this) { scope = new CPPFunctionScope(this); } return scope; @@ -190,4 +192,18 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS return super.postAccept(action); } + + 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] = (ICPPASTParameterDeclaration) other; + return; + } + } + } + assert false; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTInitializerExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTInitializerExpression.java index 3e65fab8672..cd9cf256770 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTInitializerExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTInitializerExpression.java @@ -1,29 +1,31 @@ /******************************************************************************* - * Copyright (c) 2004, 2008 IBM Corporation and others. + * Copyright (c) 2004, 2009 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 + * John Camelon (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.IASTExpression; -import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerExpression; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; /** - * @author jcamelon + * Initializer expression. */ public class CPPASTInitializerExpression extends ASTNode implements - IASTInitializerExpression, IASTAmbiguityParent { + ICPPASTInitializerExpression, IASTAmbiguityParent { private IASTExpression exp; + private boolean fIsPackExpansion; public CPPASTInitializerExpression() { @@ -36,6 +38,7 @@ public class CPPASTInitializerExpression extends ASTNode implements public CPPASTInitializerExpression copy() { CPPASTInitializerExpression copy = new CPPASTInitializerExpression(exp == null ? null : exp.copy()); copy.setOffsetAndLength(this); + copy.fIsPackExpansion= fIsPackExpansion; return copy; } @@ -80,5 +83,13 @@ public class CPPASTInitializerExpression extends ASTNode implements exp = (IASTExpression) other; } } + public boolean isPackExpansion() { + return fIsPackExpansion; + } + + public void setIsPackExpansion(boolean val) { + assertNotFrozen(); + fIsPackExpansion= val; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTInitializerList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTInitializerList.java index 125b8e1f196..aaafa5126ac 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTInitializerList.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTInitializerList.java @@ -13,17 +13,18 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTInitializer; -import org.eclipse.cdt.core.dom.ast.IASTInitializerList; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; /** * e.g.: int a[]= {1,2,3}; */ -public class CPPASTInitializerList extends ASTNode implements IASTInitializerList { +public class CPPASTInitializerList extends ASTNode implements ICPPASTInitializerList { private IASTInitializer [] initializers = null; private int initializersPos=-1; private int actualLength; + private boolean fIsPackExpansion; public CPPASTInitializerList copy() { CPPASTInitializerList copy = new CPPASTInitializerList(); @@ -31,6 +32,7 @@ public class CPPASTInitializerList extends ASTNode implements IASTInitializerLis copy.addInitializer(initializer == null ? null : initializer.copy()); copy.setOffsetAndLength(this); copy.actualLength= getSize(); + copy.fIsPackExpansion= fIsPackExpansion; return copy; } @@ -80,5 +82,14 @@ public class CPPASTInitializerList extends ASTNode implements IASTInitializerLis } return true; } + + public boolean isPackExpansion() { + return fIsPackExpansion; + } + + public void setIsPackExpansion(boolean val) { + assertNotFrozen(); + fIsPackExpansion= val; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTPackExpansionExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTPackExpansionExpression.java new file mode 100644 index 00000000000..4bb26e48e9c --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTPackExpansionExpression.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2009 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.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.IASTExpression; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPackExpansionExpression; +import org.eclipse.cdt.internal.core.dom.parser.ASTNode; +import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; + +/** + * Implementation of pack expansion expression. + */ +public class CPPASTPackExpansionExpression extends ASTNode implements ICPPASTPackExpansionExpression, IASTAmbiguityParent { + + private IASTExpression fPattern; + + public CPPASTPackExpansionExpression(IASTExpression pattern) { + setPattern(pattern); + } + + public void setPattern(IASTExpression pattern) { + assertNotFrozen(); + + fPattern= pattern; + if (pattern != null) { + pattern.setParent(this); + pattern.setPropertyInParent(ICPPASTPackExpansionExpression.PATTERN); + } + } + + + public IASTExpression getPattern() { + return fPattern; + } + + public IASTExpression copy() { + CPPASTPackExpansionExpression copy = new CPPASTPackExpansionExpression(fPattern.copy()); + copy.setOffsetAndLength(this); + return copy; + } + + public IType getExpressionType() { + return new CPPParameterPackType(fPattern.getExpressionType()); + } + + public boolean isLValue() { + return fPattern.isLValue(); + } + + @Override + public boolean accept(ASTVisitor visitor) { + if (visitor.shouldVisitExpressions) { + switch (visitor.visit(this)) { + case ASTVisitor.PROCESS_ABORT: return false; + case ASTVisitor.PROCESS_SKIP: return true; + default : break; + } + } + if (!fPattern.accept(visitor)) { + return false; + } + if (visitor.shouldVisitExpressions && visitor.leave(this) == ASTVisitor.PROCESS_ABORT) { + return false; + } + return true; + } + + public void replace(IASTNode child, IASTNode other) { + if (child == fPattern) { + other.setPropertyInParent(child.getPropertyInParent()); + other.setParent(child.getParent()); + fPattern = (IASTExpression) other; + } + } +} 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 f65910f0a29..e7b367ca3a8 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 @@ -1,12 +1,12 @@ /******************************************************************************* - * Copyright (c) 2004, 2008 IBM Corporation and others. + * Copyright (c) 2004, 2009 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 + * John Camelon (IBM) - Initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -15,18 +15,19 @@ 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.ICPPASTDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; 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; /** - * @author jcamelon + * Function parameter or non-type template parameter declaration. */ public class CPPASTParameterDeclaration extends ASTNode implements ICPPASTParameterDeclaration, IASTAmbiguityParent { - private IASTDeclSpecifier declSpec; - private IASTDeclarator declarator; - + private IASTDeclSpecifier fDeclSpec; + private ICPPASTDeclarator fDeclarator; public CPPASTParameterDeclaration() { } @@ -36,25 +37,29 @@ public class CPPASTParameterDeclaration extends ASTNode implements ICPPASTParame setDeclarator(declarator); } + public boolean isParameterPack() { + return fDeclarator != null && CPPVisitor.findInnermostDeclarator(fDeclarator).declaresParameterPack(); + } + public CPPASTParameterDeclaration copy() { CPPASTParameterDeclaration copy = new CPPASTParameterDeclaration(); - copy.setDeclSpecifier(declSpec == null ? null : declSpec.copy()); - copy.setDeclarator(declarator == null ? null : declarator.copy()); + copy.setDeclSpecifier(fDeclSpec == null ? null : fDeclSpec.copy()); + copy.setDeclarator(fDeclarator == null ? null : fDeclarator.copy()); copy.setOffsetAndLength(this); return copy; } public IASTDeclSpecifier getDeclSpecifier() { - return declSpec; + return fDeclSpec; } - public IASTDeclarator getDeclarator() { - return declarator; + public ICPPASTDeclarator getDeclarator() { + return fDeclarator; } public void setDeclSpecifier(IASTDeclSpecifier declSpec) { assertNotFrozen(); - this.declSpec = declSpec; + this.fDeclSpec = declSpec; if (declSpec != null) { declSpec.setParent(this); declSpec.setPropertyInParent(DECL_SPECIFIER); @@ -63,10 +68,12 @@ public class CPPASTParameterDeclaration extends ASTNode implements ICPPASTParame public void setDeclarator(IASTDeclarator declarator) { assertNotFrozen(); - this.declarator = declarator; - if (declarator != null) { + if (declarator instanceof ICPPASTDeclarator) { + fDeclarator = (ICPPASTDeclarator) declarator; declarator.setParent(this); declarator.setPropertyInParent(DECLARATOR); + } else { + fDeclarator= null; } } @@ -80,8 +87,8 @@ public class CPPASTParameterDeclaration extends ASTNode implements ICPPASTParame } } - if( declSpec != null ) if( !declSpec.accept( action ) ) return false; - if( declarator != null ) if( !declarator.accept( action ) ) return false; + if( fDeclSpec != null ) if( !fDeclSpec.accept( action ) ) return false; + if( fDeclarator != null ) if( !fDeclarator.accept( action ) ) return false; if( action.shouldVisitParameterDeclarations ){ switch( action.leave( this ) ){ @@ -94,10 +101,10 @@ public class CPPASTParameterDeclaration extends ASTNode implements ICPPASTParame } public void replace(IASTNode child, IASTNode other) { - if (child == declarator) { + if (child == fDeclarator) { other.setPropertyInParent(child.getPropertyInParent()); other.setParent(child.getParent()); - declarator= (IASTDeclarator) other; + fDeclarator= (ICPPASTDeclarator) other; } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeTemplateParameter.java index 9eb0d2b2427..5c928c1cac2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeTemplateParameter.java @@ -1,12 +1,12 @@ /******************************************************************************* - * Copyright (c) 2004, 2008 IBM Corporation and others. + * Copyright (c) 2004, 2009 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 + * John Camelon (IBM) - Initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -19,49 +19,60 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisitor; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; /** - * @author jcamelon + * Template type parameter as in <code>template <typename T> class X;</code> */ -public class CPPASTSimpleTypeTemplateParameter extends ASTNode implements - ICPPASTSimpleTypeTemplateParameter { +public class CPPASTSimpleTypeTemplateParameter extends ASTNode implements ICPPASTSimpleTypeTemplateParameter { - private int type; - private IASTName name; - private IASTTypeId typeId; + private IASTName fName; + private IASTTypeId fTypeId; + private boolean fUsesKeywordClass; + private boolean fIsParameterPack; public CPPASTSimpleTypeTemplateParameter() { } public CPPASTSimpleTypeTemplateParameter(int type, IASTName name, IASTTypeId typeId) { - this.type = type; + fUsesKeywordClass= type == st_class; setName(name); setDefaultType(typeId); } public CPPASTSimpleTypeTemplateParameter copy() { CPPASTSimpleTypeTemplateParameter copy = new CPPASTSimpleTypeTemplateParameter(); - copy.type = type; - copy.setName(name == null ? null : name.copy()); - copy.setDefaultType(typeId == null ? null : typeId.copy()); + copy.fUsesKeywordClass = fUsesKeywordClass; + copy.fIsParameterPack= fIsParameterPack; + copy.setName(fName == null ? null : fName.copy()); + copy.setDefaultType(fTypeId == null ? null : fTypeId.copy()); copy.setOffsetAndLength(this); return copy; } + + public boolean isParameterPack() { + return fIsParameterPack; + } + + public void setIsParameterPack(boolean val) { + assertNotFrozen(); + fIsParameterPack= val; + } + public int getParameterType() { - return type; + return fUsesKeywordClass ? st_class : st_typename; } public void setParameterType(int value) { assertNotFrozen(); - this.type = value; + fUsesKeywordClass = value == st_class; } public IASTName getName() { - return name; + return fName; } public void setName(IASTName name) { assertNotFrozen(); - this.name = name; + this.fName = name; if (name != null) { name.setParent(this); name.setPropertyInParent(PARAMETER_NAME); @@ -69,12 +80,12 @@ public class CPPASTSimpleTypeTemplateParameter extends ASTNode implements } public IASTTypeId getDefaultType() { - return typeId; + return fTypeId; } public void setDefaultType(IASTTypeId typeId) { assertNotFrozen(); - this.typeId = typeId; + this.fTypeId = typeId; if (typeId != null) { typeId.setParent(this); typeId.setPropertyInParent(DEFAULT_TYPE); @@ -91,8 +102,8 @@ public class CPPASTSimpleTypeTemplateParameter extends ASTNode implements } } - if (name != null) if (!name.accept(action)) return false; - if (typeId != null) if (!typeId.accept(action)) return false; + if (fName != null) if (!fName.accept(action)) return false; + if (fTypeId != null) if (!fTypeId.accept(action)) return false; if (action.shouldVisitTemplateParameters && action instanceof ICPPASTVisitor) { switch (((ICPPASTVisitor) action).leave(this)) { @@ -105,7 +116,7 @@ public class CPPASTSimpleTypeTemplateParameter extends ASTNode implements } public int getRoleForName(IASTName n) { - if (n == name) + if (n == fName) return r_declaration; return r_unclear; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplatedTypeTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplatedTypeTemplateParameter.java index f33661b4266..1684ba771ae 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplatedTypeTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplatedTypeTemplateParameter.java @@ -1,12 +1,12 @@ /******************************************************************************* - * Copyright (c) 2004, 2008 IBM Corporation and others. + * Copyright (c) 2004, 2009 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 + * John Camelon (IBM) - Initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -23,12 +23,16 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; /** - * @author jcamelon + * Template template parameter */ public class CPPASTTemplatedTypeTemplateParameter extends ASTNode implements ICPPASTTemplatedTypeTemplateParameter, IASTAmbiguityParent { - + private ICPPASTTemplateParameter [] fNestedParameters = null; + private boolean fIsParameterPack; + private IASTName fName; + private IASTExpression fDefaultValue; + public CPPASTTemplatedTypeTemplateParameter() { } @@ -39,8 +43,9 @@ public class CPPASTTemplatedTypeTemplateParameter extends ASTNode implements public CPPASTTemplatedTypeTemplateParameter copy() { CPPASTTemplatedTypeTemplateParameter copy = new CPPASTTemplatedTypeTemplateParameter(); - copy.setName(name == null ? null : name.copy()); - copy.setDefaultValue(defaultValue == null ? null : defaultValue.copy()); + copy.setName(fName == null ? null : fName.copy()); + copy.setDefaultValue(fDefaultValue == null ? null : fDefaultValue.copy()); + copy.fIsParameterPack= fIsParameterPack; for(ICPPASTTemplateParameter param : getTemplateParameters()) copy.addTemplateParamter(param == null ? null : param.copy()); copy.setOffsetAndLength(this); @@ -48,32 +53,39 @@ public class CPPASTTemplatedTypeTemplateParameter extends ASTNode implements } public ICPPASTTemplateParameter[] getTemplateParameters() { - if( parameters == null ) return ICPPASTTemplateParameter.EMPTY_TEMPLATEPARAMETER_ARRAY; - parameters = (ICPPASTTemplateParameter[]) ArrayUtil.removeNullsAfter( ICPPASTTemplateParameter.class, parameters, parametersPos ); - return parameters; - } + if (fNestedParameters == null) + return ICPPASTTemplateParameter.EMPTY_TEMPLATEPARAMETER_ARRAY; + fNestedParameters = (ICPPASTTemplateParameter[]) ArrayUtil.trim(ICPPASTTemplateParameter.class, fNestedParameters); + return fNestedParameters; + } - public void addTemplateParamter(ICPPASTTemplateParameter parm) { - assertNotFrozen(); - if(parm != null) { - parameters = (ICPPASTTemplateParameter[]) ArrayUtil.append( ICPPASTTemplateParameter.class, parameters, ++parametersPos, parm ); - parm.setParent(this); + public void addTemplateParamter(ICPPASTTemplateParameter parm) { + assertNotFrozen(); + if (parm != null) { + fNestedParameters = (ICPPASTTemplateParameter[]) ArrayUtil.append(ICPPASTTemplateParameter.class, + fNestedParameters, parm); + parm.setParent(this); parm.setPropertyInParent(PARAMETER); - } - } + } + } + + + public void setIsParameterPack(boolean val) { + assertNotFrozen(); + fIsParameterPack= val; + } - private ICPPASTTemplateParameter [] parameters = null; - private int parametersPos=-1; - private IASTName name; - private IASTExpression defaultValue; + public boolean isParameterPack() { + return fIsParameterPack; + } - public IASTName getName() { - return name; + public IASTName getName() { + return fName; } public void setName(IASTName name) { assertNotFrozen(); - this.name =name; + this.fName =name; if (name != null) { name.setParent(this); name.setPropertyInParent(PARAMETER_NAME); @@ -81,12 +93,12 @@ public class CPPASTTemplatedTypeTemplateParameter extends ASTNode implements } public IASTExpression getDefaultValue() { - return defaultValue; + return fDefaultValue; } public void setDefaultValue(IASTExpression expression) { assertNotFrozen(); - this.defaultValue = expression; + this.fDefaultValue = expression; if (expression != null) { expression.setParent(this); expression.setPropertyInParent(DEFAULT_VALUE); @@ -107,8 +119,8 @@ public class CPPASTTemplatedTypeTemplateParameter extends ASTNode implements for ( int i = 0; i < ps.length; i++ ) { if( !ps[i].accept( action ) ) return false; } - if( name != null ) if( !name.accept( action ) ) return false; - if( defaultValue != null ) if( !defaultValue.accept( action ) ) return false; + if( fName != null ) if( !fName.accept( action ) ) return false; + if( fDefaultValue != null ) if( !fDefaultValue.accept( action ) ) return false; if (action.shouldVisitTemplateParameters && action instanceof ICPPASTVisitor) { switch( ((ICPPASTVisitor)action).leave( this ) ){ @@ -121,17 +133,17 @@ public class CPPASTTemplatedTypeTemplateParameter extends ASTNode implements } public int getRoleForName(IASTName n) { - if( n == name ) + if( n == fName ) return r_declaration; return r_unclear; } public void replace(IASTNode child, IASTNode other) { - if( child == defaultValue ) + if( child == fDefaultValue ) { other.setPropertyInParent( child.getPropertyInParent() ); other.setParent( child.getParent() ); - defaultValue = (IASTExpression) other; + fDefaultValue = (IASTExpression) other; } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeId.java index db9a1ffccba..9bd8015d4da 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeId.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeId.java @@ -1,28 +1,30 @@ /******************************************************************************* - * Copyright (c) 2004, 2008 IBM Corporation and others. + * Copyright (c) 2004, 2009 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 + * John Camelon (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.IASTTypeId; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeId; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; /** - * @author jcamelon + * Type id for c++ */ -public class CPPASTTypeId extends ASTNode implements IASTTypeId { +public class CPPASTTypeId extends ASTNode implements ICPPASTTypeId { private IASTDeclSpecifier declSpec; private IASTDeclarator absDecl; + private boolean isPackExpansion; public CPPASTTypeId() { @@ -38,6 +40,7 @@ public class CPPASTTypeId extends ASTNode implements IASTTypeId { copy.setDeclSpecifier(declSpec == null ? null : declSpec.copy()); copy.setAbstractDeclarator(absDecl == null ? null : absDecl.copy()); copy.setOffsetAndLength(this); + copy.isPackExpansion= isPackExpansion; return copy; } @@ -68,7 +71,15 @@ public class CPPASTTypeId extends ASTNode implements IASTTypeId { } } - @Override + public boolean isPackExpansion() { + return isPackExpansion; + } + + public void setIsPackExpansion(boolean val) { + isPackExpansion= val; + } + + @Override public boolean accept( ASTVisitor action ){ if( action.shouldVisitTypeIds ){ switch( action.visit( this ) ){ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java index 0ce2d33aa31..c12f05b808a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java @@ -205,6 +205,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres final int op= getOperator(); switch (op) { case op_sizeof: + case op_sizeofParameterPack: return CPPVisitor.get_SIZE_T(this); case op_typeid: return CPPVisitor.get_type_info(this); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBuiltinParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBuiltinParameter.java index a87c445fc33..985117457bc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBuiltinParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBuiltinParameter.java @@ -107,4 +107,8 @@ public class CPPBuiltinParameter extends PlatformObject implements ICPPParameter public IValue getInitialValue() { return null; } + + public boolean isParameterPack() { + return false; + } }
\ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java index 6f486d8ac40..24042721dd2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2008 IBM Corporation and others. + * Copyright (c) 2005, 2009 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 @@ -32,7 +32,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; public class CPPClassInstance extends CPPClassSpecialization implements ICPPTemplateInstance { private ICPPTemplateArgument[] arguments; - public CPPClassInstance(IBinding owner, ICPPClassType orig, CPPTemplateParameterMap argMap, ICPPTemplateArgument[] args) { + public CPPClassInstance(ICPPClassType orig, IBinding owner, CPPTemplateParameterMap argMap, ICPPTemplateArgument[] args) { super(orig, owner, argMap); this.arguments= args; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java index 5b162214929..7d6f66f2368 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java @@ -277,7 +277,7 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements ICPPClass return false; } - public ICPPDeferredClassInstance asDeferredInstance() throws DOMException { + public final ICPPDeferredClassInstance asDeferredInstance() throws DOMException { if (fDeferredInstance == null) { fDeferredInstance= createDeferredInstance(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorInstance.java index e53fb6d70ba..4d36ad00929 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorInstance.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 QNX Software Systems and others. + * Copyright (c) 2007, 2009 QNX Software Systems 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 @@ -21,9 +21,9 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; */ public class CPPConstructorInstance extends CPPMethodInstance implements ICPPConstructor { - public CPPConstructorInstance(ICPPClassType owner, ICPPConstructor orig, + public CPPConstructorInstance(ICPPConstructor orig, ICPPClassType owner, CPPTemplateParameterMap tpmap, ICPPTemplateArgument[] args) { - super(owner, orig, tpmap, args); + super(orig, owner, tpmap, args); } public boolean isExplicit() throws DOMException { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorSpecialization.java index dbabf66e8f0..7b44b13adf5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorSpecialization.java @@ -1,5 +1,5 @@ /************************************************************************* - * Copyright (c) 2005, 2008 IBM Corporation and others. + * Copyright (c) 2005, 2009 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 @@ -12,7 +12,6 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.DOMException; -import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; @@ -23,7 +22,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; public class CPPConstructorSpecialization extends CPPMethodSpecialization implements ICPPConstructor { - public CPPConstructorSpecialization(IBinding orig, ICPPClassType owner, + public CPPConstructorSpecialization(ICPPConstructor orig, ICPPClassType owner, ICPPTemplateParameterMap argMap) { super(orig, owner, argMap); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorTemplateSpecialization.java index 7eec02e378c..d643f89abf9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorTemplateSpecialization.java @@ -1,5 +1,5 @@ /************************************************************************* - * Copyright (c) 2005, 2008 IBM Corporation and others. + * Copyright (c) 2005, 2009 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 @@ -12,7 +12,6 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.DOMException; -import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; @@ -23,9 +22,9 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; public class CPPConstructorTemplateSpecialization extends CPPMethodTemplateSpecialization implements ICPPConstructor { - public CPPConstructorTemplateSpecialization(IBinding specialized, + public CPPConstructorTemplateSpecialization(ICPPConstructor original, ICPPClassType owner, ICPPTemplateParameterMap tpmap) { - super(specialized, owner, tpmap); + super(original, owner, tpmap); } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java index 7a319b71192..dc19ada3def 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java @@ -48,6 +48,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.core.runtime.PlatformObject; /** @@ -107,6 +108,15 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt public IType[] getExceptionSpecification() throws DOMException { throw new DOMException(this); } + public int getRequiredArgumentCount() throws DOMException { + throw new DOMException(this); + } + public boolean hasParameterPack() { + return false; + } + public boolean hasSameFunctionParameterTypeList(ICPPFunction function) { + return false; + } } protected IASTDeclarator[] declarations; @@ -574,4 +584,29 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt } return null; } + + public int getRequiredArgumentCount() throws DOMException { + return getRequiredArgumentCount(getParameters()); + } + + public static int getRequiredArgumentCount(ICPPParameter[] pars) throws DOMException { + int result= pars.length; + while(result > 0) { + final ICPPParameter p = pars[result-1]; + if (p.hasDefaultValue() || p.isParameterPack()) { + result--; + } else { + if (pars.length == 1 && SemanticUtil.isVoidType(p.getType())) { + return 0; + } + return result; + } + } + return 0; + } + + public boolean hasParameterPack() { + ICPPParameter[] pars= getParameters(); + return pars.length > 0 && pars[pars.length-1].isParameterPack(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java index f187a36d640..1b84257783a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2008 IBM Corporation and others. + * Copyright (c) 2005, 2009 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 @@ -29,7 +29,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; public class CPPFunctionInstance extends CPPFunctionSpecialization implements ICPPTemplateInstance { private ICPPTemplateArgument[] fArguments; - public CPPFunctionInstance(IBinding owner, ICPPFunction orig, CPPTemplateParameterMap argMap, ICPPTemplateArgument[] args) { + public CPPFunctionInstance(ICPPFunction orig, IBinding owner, CPPTemplateParameterMap argMap, ICPPTemplateArgument[] args) { super(orig, owner, argMap); fArguments = args; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java index 0fb26af565d..de58803f982 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java @@ -40,10 +40,10 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; */ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPPFunction, ICPPInternalFunction { private ICPPFunctionType type = null; - private ICPPParameter[] specializedParams = null; + private ICPPParameter[] fParams = null; private IType[] specializedExceptionSpec = null; - public CPPFunctionSpecialization(IBinding orig, IBinding owner, ICPPTemplateParameterMap argMap) { + public CPPFunctionSpecialization(ICPPFunction orig, IBinding owner, ICPPTemplateParameterMap argMap) { super(orig, owner, argMap); } @@ -52,25 +52,38 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP } public ICPPParameter[] getParameters() throws DOMException { - if (specializedParams == null) { - ICPPFunction function = (ICPPFunction) getSpecializedBinding(); + if (fParams == null) { + ICPPFunction function = getFunction(); ICPPParameter[] params = function.getParameters(); - specializedParams = new ICPPParameter[params.length]; - for (int i = 0; i < params.length; i++) { - specializedParams[i] = new CPPParameterSpecialization(params[i], - this, getTemplateParameterMap()); + if (params.length == 0) { + fParams= params; + } else { + // Because of parameter packs there can be more or less parameters in the specialization + final ICPPTemplateParameterMap tparMap = getTemplateParameterMap(); + IType[] ptypes= getType().getParameterTypes(); + final int length = ptypes.length; + ICPPParameter par= null; + fParams = new ICPPParameter[length]; + for (int i = 0; i < length; i++) { + if (i < params.length) { + par= params[i]; + } // else reuse last parameter (which should be a pack) + fParams[i] = new CPPParameterSpecialization(par, this, ptypes[i], tparMap); + } } } - return specializedParams; + return fParams; + } + + public int getRequiredArgumentCount() throws DOMException { + return ((ICPPFunction) getSpecializedBinding()).getRequiredArgumentCount(); + } + + public boolean hasParameterPack() { + return ((ICPPFunction) getSpecializedBinding()).hasParameterPack(); } public IScope getFunctionScope() { -// resolveAllDeclarations(); -// if (definition != null) { -// return definition.getFunctionScope(); -// } -// -// return declarations[0].getFunctionScope(); return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java index 2a22fc3da3d..03469779805 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java @@ -103,6 +103,12 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition public IType[] getExceptionSpecification() throws DOMException { throw new DOMException( this ); } + public int getRequiredArgumentCount() throws DOMException { + throw new DOMException( this ); + } + public boolean hasParameterPack() { + return false; + } } protected ICPPFunctionType type = null; @@ -176,6 +182,16 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition return CPPBuiltinParameter.createParameterList(getType()); } + + public int getRequiredArgumentCount() throws DOMException { + return CPPFunction.getRequiredArgumentCount(getParameters()); + } + + public boolean hasParameterPack() { + ICPPParameter[] pars= getParameters(); + return pars.length > 0 && pars[pars.length-1].isParameterPack(); + } + public IScope getFunctionScope() { return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplateSpecialization.java index d1a26a37922..d976ad8323d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplateSpecialization.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2008 IBM Corporation and others. + * Copyright (c) 2005, 2009 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 @@ -15,6 +15,7 @@ import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; @@ -30,8 +31,8 @@ public class CPPFunctionTemplateSpecialization extends CPPFunctionSpecialization private ObjectMap instances = null; - public CPPFunctionTemplateSpecialization(IBinding specialized, ICPPClassType owner, ICPPTemplateParameterMap argumentMap) { - super(specialized, owner, argumentMap); + public CPPFunctionTemplateSpecialization(ICPPFunction original, ICPPClassType owner, ICPPTemplateParameterMap argumentMap) { + super(original, owner, argumentMap); } public ICPPTemplateParameter[] getTemplateParameters() throws DOMException { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionType.java index 48c66820f66..57e58e68e02 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionType.java @@ -12,11 +12,9 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; -import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; -import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.internal.core.dom.parser.ISerializableType; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; @@ -31,6 +29,7 @@ public class CPPFunctionType implements ICPPFunctionType, ISerializableType { private IType returnType; private boolean isConst; private boolean isVolatile; + private boolean takesVarargs; /** * @param returnType @@ -41,11 +40,13 @@ public class CPPFunctionType implements ICPPFunctionType, ISerializableType { this.parameters = types; } - public CPPFunctionType(IType returnType, IType[] types, boolean isConst, boolean isVolatile) { + public CPPFunctionType(IType returnType, IType[] types, boolean isConst, boolean isVolatile, + boolean takesVarargs) { this.returnType = returnType; this.parameters = types; this.isConst = isConst; this.isVolatile= isVolatile; + this.takesVarargs= takesVarargs; } public boolean isSameType(IType o) { @@ -53,6 +54,10 @@ public class CPPFunctionType implements ICPPFunctionType, ISerializableType { return o.isSameType(this); if (o instanceof ICPPFunctionType) { ICPPFunctionType ft = (ICPPFunctionType) o; + if (isConst() != ft.isConst() || isVolatile() != ft.isVolatile() || takesVarArgs() != ft.takesVarArgs()) { + return false; + } + IType[] fps; fps = ft.getParameterTypes(); //constructors & destructors have null return type @@ -62,12 +67,10 @@ public class CPPFunctionType implements ICPPFunctionType, ISerializableType { return false; if (parameters.length == 1 && fps.length == 0) { - IType p0= SemanticUtil.getNestedType(parameters[0], SemanticUtil.TDEF); - if (!(p0 instanceof IBasicType) || ((IBasicType) p0).getKind() != Kind.eVoid) + if (!SemanticUtil.isVoidType(parameters[0])) return false; } else if (fps.length == 1 && parameters.length == 0) { - IType p0= SemanticUtil.getNestedType(fps[0], SemanticUtil.TDEF); - if (!(p0 instanceof IBasicType) || ((IBasicType) p0).getKind() != Kind.eVoid) + if (!SemanticUtil.isVoidType(fps[0])) return false; } else if (parameters.length != fps.length) { return false; @@ -77,11 +80,7 @@ public class CPPFunctionType implements ICPPFunctionType, ISerializableType { return false; } } - - if (isConst() != ft.isConst() || isVolatile() != ft.isVolatile()) { - return false; - } - + return true; } return false; @@ -125,6 +124,10 @@ public class CPPFunctionType implements ICPPFunctionType, ISerializableType { return isVolatile; } + public boolean takesVarArgs() { + return takesVarargs; + } + @Override public String toString() { return ASTTypeUtil.getType(this); @@ -134,10 +137,11 @@ public class CPPFunctionType implements ICPPFunctionType, ISerializableType { int firstByte= ITypeMarshalBuffer.FUNCTION_TYPE; if (isConst()) firstByte |= ITypeMarshalBuffer.FLAG1; if (isVolatile()) firstByte |= ITypeMarshalBuffer.FLAG2; + if (takesVarArgs()) firstByte |= ITypeMarshalBuffer.FLAG3; int len= (parameters.length & 0xffff); if (len > 0xff) { - firstByte |= ITypeMarshalBuffer.FLAG3; + firstByte |= ITypeMarshalBuffer.FLAG4; buffer.putByte((byte) firstByte); buffer.putShort((short) len); } else { @@ -153,7 +157,7 @@ public class CPPFunctionType implements ICPPFunctionType, ISerializableType { public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { int len; - if (((firstByte & ITypeMarshalBuffer.FLAG3) != 0)) { + if (((firstByte & ITypeMarshalBuffer.FLAG4) != 0)) { len= buffer.getShort(); } else { len= buffer.getByte(); @@ -164,6 +168,6 @@ public class CPPFunctionType implements ICPPFunctionType, ISerializableType { pars[i]= buffer.unmarshalType(); } return new CPPFunctionType(rt, pars, (firstByte & ITypeMarshalBuffer.FLAG1) != 0, - (firstByte & ITypeMarshalBuffer.FLAG2) != 0); + (firstByte & ITypeMarshalBuffer.FLAG2) != 0, (firstByte & ITypeMarshalBuffer.FLAG3) != 0); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitMethod.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitMethod.java index b1a74485d4e..6635e53cd66 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitMethod.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitMethod.java @@ -19,11 +19,9 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; -import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IType; -import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; @@ -37,6 +35,7 @@ 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.ASTQueries; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; /** * Binding for implicit methods, base class for implicit constructors. @@ -139,9 +138,7 @@ public class CPPImplicitMethod extends CPPImplicitFunction implements ICPPMethod ok = idx == ps.length; } else if (ps.length == 0) { if (params.length == 1) { - IType t1 = params[0]; - ok = (t1 instanceof IBasicType) - && ((IBasicType) t1).getKind() == Kind.eVoid; + ok = SemanticUtil.isVoidType(params[0]); } } } else { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodInstance.java index e96611519e9..a24beb76902 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodInstance.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2008 IBM Corporation and others. + * Copyright (c) 2005, 2009 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 @@ -21,8 +21,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; */ public class CPPMethodInstance extends CPPFunctionInstance implements ICPPMethod { - public CPPMethodInstance(ICPPClassType owner, ICPPMethod orig, CPPTemplateParameterMap tpmap, ICPPTemplateArgument[] args) { - super(owner, orig, tpmap, args); + public CPPMethodInstance(ICPPMethod orig, ICPPClassType owner, CPPTemplateParameterMap tpmap, ICPPTemplateArgument[] args) { + super(orig, owner, tpmap, args); } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodSpecialization.java index c167d1217d5..d5531f13e80 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodSpecialization.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2008 IBM Corporation and others. + * Copyright (c) 2005, 2009 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 @@ -16,7 +16,6 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; -import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; @@ -29,7 +28,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; public class CPPMethodSpecialization extends CPPFunctionSpecialization implements ICPPMethod { - public CPPMethodSpecialization(IBinding orig, ICPPClassType owner, ICPPTemplateParameterMap argMap ) { + public CPPMethodSpecialization(ICPPMethod orig, ICPPClassType owner, ICPPTemplateParameterMap argMap ) { super(orig, owner, argMap ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodTemplateSpecialization.java index e75a17b0a5e..14058959a5d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodTemplateSpecialization.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2008 IBM Corporation and others. + * Copyright (c) 2005, 2009 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 @@ -23,7 +23,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; public class CPPMethodTemplateSpecialization extends CPPFunctionTemplateSpecialization implements ICPPMethod { - public CPPMethodTemplateSpecialization(IBinding specialized, ICPPClassType owner, + public CPPMethodTemplateSpecialization(ICPPMethod specialized, ICPPClassType owner, ICPPTemplateParameterMap ctmap) { super(specialized, owner, ctmap); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java index fd14a698f56..1fe4146c505 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java @@ -12,7 +12,6 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.IASTASMDeclaration; -import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator; import org.eclipse.cdt.core.dom.ast.IASTArrayModifier; import org.eclipse.cdt.core.dom.ast.IASTBreakStatement; import org.eclipse.cdt.core.dom.ast.IASTCaseStatement; @@ -28,13 +27,10 @@ import org.eclipse.cdt.core.dom.ast.IASTDoStatement; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement; -import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator; 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.IASTInitializer; -import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression; -import org.eclipse.cdt.core.dom.ast.IASTInitializerList; import org.eclipse.cdt.core.dom.ast.IASTLabelStatement; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNullStatement; @@ -50,6 +46,7 @@ import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeIdInitializerExpression; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTArrayDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTArraySubscriptExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression; @@ -58,10 +55,12 @@ 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.ICPPASTDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression; @@ -69,6 +68,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionWithTryBlock; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerExpression; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; @@ -76,6 +77,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPackExpansionExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; @@ -91,6 +93,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTryBlockStatement; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypenameExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression; @@ -324,11 +327,11 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory { return new CPPASTTypeIdExpression(operator, typeId); } - public IASTDeclarator newDeclarator(IASTName name) { + public ICPPASTDeclarator newDeclarator(IASTName name) { return new CPPASTDeclarator(name); } - public IASTTypeId newTypeId(IASTDeclSpecifier declSpecifier, IASTDeclarator declarator) { + public ICPPASTTypeId newTypeId(IASTDeclSpecifier declSpecifier, IASTDeclarator declarator) { return new CPPASTTypeId(declSpecifier, declarator); } @@ -340,7 +343,7 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory { return new CPPASTSimpleDeclaration(declSpecifier); } - public IASTInitializerExpression newInitializerExpression(IASTExpression expression) { + public ICPPASTInitializerExpression newInitializerExpression(IASTExpression expression) { return new CPPASTInitializerExpression(expression); } @@ -469,7 +472,7 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory { return new GPPASTPointerToMember(name); } - public IASTInitializerList newInitializerList() { + public ICPPASTInitializerList newInitializerList() { return new CPPASTInitializerList(); } @@ -481,7 +484,7 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory { return new CPPASTArrayModifier(expr); } - public IASTArrayDeclarator newArrayDeclarator(IASTName name) { + public ICPPASTArrayDeclarator newArrayDeclarator(IASTName name) { return new CPPASTArrayDeclarator(name); } @@ -498,7 +501,7 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory { return new CPPASTFunctionWithTryBlock(declSpecifier, declarator, bodyStatement); } - public IASTFieldDeclarator newFieldDeclarator(IASTName name, IASTExpression bitFieldSize) { + public ICPPASTFieldDeclarator newFieldDeclarator(IASTName name, IASTExpression bitFieldSize) { return new CPPASTFieldDeclarator(name, bitFieldSize); } @@ -522,4 +525,8 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory { ICPPASTLiteralExpression message) { return new CPPASTStaticAssertionDeclaration(condition, message); } + + public ICPPASTPackExpansionExpression newPackExpansionExpression(IASTExpression pattern) { + return new CPPASTPackExpansionExpression(pattern); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java index ccc28b74943..599e7495cfe 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java @@ -26,6 +26,8 @@ import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArrayUtils; @@ -34,7 +36,6 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.core.runtime.PlatformObject; /** @@ -81,28 +82,35 @@ public class CPPParameter extends PlatformObject implements ICPPParameter, ICPPI public IValue getInitialValue() { return null; } + public boolean isParameterPack() { + return false; + } } - private IType type = null; - private IASTName[] declarations = null; + private IType fType = null; + private IASTName[] fDeclarations = null; private int fPosition; public CPPParameter(IASTName name, int pos) { - this.declarations = new IASTName[] { name }; + this.fDeclarations = new IASTName[] { name }; fPosition= pos; } public CPPParameter(IType type, int pos) { - this.type = type; + this.fType = type; fPosition= pos; } - /* (non-Javadoc) + public boolean isParameterPack() { + return getType() instanceof ICPPParameterPackType; + } + + /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPBinding#getDeclarations() */ public IASTNode[] getDeclarations() { - return declarations; + return fDeclarations; } /* (non-Javadoc) @@ -116,29 +124,29 @@ public class CPPParameter extends PlatformObject implements ICPPParameter, ICPPI if (!(node instanceof IASTName)) return; IASTName name = (IASTName) node; - if (declarations == null) { - declarations = new IASTName[] { name }; + if (fDeclarations == null) { + fDeclarations = new IASTName[] { name }; } else { //keep the lowest offset declaration in[0] - if (declarations.length > 0 && ((ASTNode)node).getOffset() < ((ASTNode)declarations[0]).getOffset()) { - declarations = (IASTName[]) ArrayUtil.prepend(IASTName.class, declarations, name); + if (fDeclarations.length > 0 && ((ASTNode)node).getOffset() < ((ASTNode)fDeclarations[0]).getOffset()) { + fDeclarations = (IASTName[]) ArrayUtil.prepend(IASTName.class, fDeclarations, name); } else { - declarations = (IASTName[]) ArrayUtil.append(IASTName.class, declarations, name); + fDeclarations = (IASTName[]) ArrayUtil.append(IASTName.class, fDeclarations, name); } } } private IASTName getPrimaryDeclaration() { - if (declarations != null) { - for (int i = 0; i < declarations.length && declarations[i] != null; i++) { - IASTNode node = declarations[i].getParent(); + if (fDeclarations != null) { + for (int i = 0; i < fDeclarations.length && fDeclarations[i] != null; i++) { + IASTNode node = fDeclarations[i].getParent(); while (!(node instanceof IASTDeclaration)) node = node.getParent(); if (node instanceof IASTFunctionDefinition) - return declarations[i]; + return fDeclarations[i]; } - return declarations[0]; + return fDeclarations[0]; } return null; } @@ -170,8 +178,8 @@ public class CPPParameter extends PlatformObject implements ICPPParameter, ICPPI * @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode() */ public IASTNode getPhysicalNode() { - if (declarations != null) - return declarations[0]; + if (fDeclarations != null) + return fDeclarations[0]; return null; } @@ -179,11 +187,17 @@ public class CPPParameter extends PlatformObject implements ICPPParameter, ICPPI * @see org.eclipse.cdt.core.dom.ast.IVariable#getType() */ public IType getType() { - if (type == null && declarations != null) { - IType t= CPPVisitor.createType((IASTDeclarator) declarations[0].getParent()); - type= SemanticUtil.adjustParameterType(t, false); + if (fType == null && fDeclarations != null) { + IASTNode parent= fDeclarations[0].getParent(); + while (parent != null) { + if (parent instanceof ICPPASTParameterDeclaration) { + fType= CPPVisitor.createParameterType((ICPPASTParameterDeclaration) parent, false); + break; + } + parent= parent.getParent(); + } } - return type; + return fType; } /* (non-Javadoc) @@ -268,10 +282,10 @@ public class CPPParameter extends PlatformObject implements ICPPParameter, ICPPI } public IASTInitializer getDefaultValue() { - if (declarations == null) + if (fDeclarations == null) return null; - for (int i = 0; i < declarations.length && declarations[i] != null; i++) { - IASTNode parent = declarations[i].getParent(); + for (int i = 0; i < fDeclarations.length && fDeclarations[i] != null; i++) { + IASTNode parent = fDeclarations[i].getParent(); while (parent.getPropertyInParent() == IASTDeclarator.NESTED_DECLARATOR) parent = parent.getParent(); IASTInitializer init = ((IASTDeclarator)parent).getInitializer(); @@ -300,7 +314,7 @@ public class CPPParameter extends PlatformObject implements ICPPParameter, ICPPI } public IBinding getOwner() throws DOMException { - return CPPVisitor.findEnclosingFunction(declarations[0]); + return CPPVisitor.findEnclosingFunction(fDeclarations[0]); } public IValue getInitialValue() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterPackType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterPackType.java new file mode 100644 index 00000000000..67d8ba673c9 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterPackType.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2009 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn (Wind River Systems) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; +import org.eclipse.cdt.internal.core.dom.parser.ISerializableType; +import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; +import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; +import org.eclipse.core.runtime.CoreException; + +public class CPPParameterPackType implements ICPPParameterPackType, ITypeContainer, ISerializableType { + private IType fType = null; + + public CPPParameterPackType(IType type) { + setType(type); + } + + public IType getType() { + return fType; + } + + public void setType(IType t) { + fType= t; + } + + public boolean isSameType(IType obj) { + if (obj == this) + return true; + if (obj instanceof ITypedef) + return ((ITypedef)obj).isSameType(this); + + if (obj instanceof ICPPParameterPackType) { + final ICPPParameterPackType rhs = (ICPPParameterPackType) obj; + IType t1= getType(); + IType t2= rhs.getType(); + return t1 != null && t1.isSameType(t2); + } + return false; + } + + @Override + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + // not going to happen + return null; + } + } + + @Override + public String toString() { + return ASTTypeUtil.getType(this); + } + + public void marshal(ITypeMarshalBuffer buffer) throws CoreException { + int firstByte= ITypeMarshalBuffer.PACK_EXPANSION; + buffer.putByte((byte) firstByte); + buffer.marshalType(getType()); + } + + public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { + IType nested= buffer.unmarshalType(); + return new CPPParameterPackType(nested); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterSpecialization.java index a16f7a8be8d..b7bd1409b5d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterSpecialization.java @@ -15,19 +15,19 @@ import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; /** * Binding for a specialization of a parameter. */ public class CPPParameterSpecialization extends CPPSpecialization implements ICPPParameter { - private IType type = null; + private IType fType; - public CPPParameterSpecialization(ICPPParameter orig, IBinding owner, ICPPTemplateParameterMap tpmap) { + public CPPParameterSpecialization(ICPPParameter orig, IBinding owner, IType type, ICPPTemplateParameterMap tpmap) { super(orig, owner, tpmap); + fType= type; } private ICPPParameter getParameter(){ @@ -38,25 +38,17 @@ public class CPPParameterSpecialization extends CPPSpecialization implements ICP * @see org.eclipse.cdt.core.dom.ast.IVariable#getType() */ public IType getType() throws DOMException { - if( type == null ){ - type= specializeType(getParameter().getType()); - } - return type; + return fType; } + public boolean isParameterPack() { + return fType instanceof ICPPParameterPackType; + } + @Override public IType specializeType(IType type) { - IBinding owner= getOwner(); - if (owner != null) { - try { - owner= owner.getOwner(); - if (owner instanceof ICPPClassSpecialization) { - return CPPTemplates.instantiateType(type, getTemplateParameterMap(), (ICPPClassSpecialization) owner); - } - } catch (DOMException e) { - } - } - return CPPTemplates.instantiateType(type, getTemplateParameterMap(), null); + assert false; + return type; } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeParameter.java index 3482ce4a0dc..75cf9a85905 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeParameter.java @@ -20,6 +20,8 @@ import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; import org.eclipse.cdt.internal.core.dom.parser.Value; @@ -68,14 +70,23 @@ public class CPPTemplateNonTypeParameter extends CPPTemplateParameter implements } public IType getType() { - if( type == null ){ - IASTName name = getPrimaryDeclaration(); - IASTDeclarator dtor = (IASTDeclarator) name.getParent(); - type = CPPVisitor.createType( dtor ); + if (type == null) { + IASTNode parent= getPrimaryDeclaration().getParent(); + while (parent != null) { + if (parent instanceof ICPPASTParameterDeclaration) { + type= CPPVisitor.createParameterType((ICPPASTParameterDeclaration) parent, true); + break; + } + parent= parent.getParent(); + } } return type; } + public boolean isParameterPack() { + return getType() instanceof ICPPParameterPackType; + } + public boolean isStatic() throws DOMException { return false; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java index ed5a45b0361..8a1cea4e7af 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java @@ -50,9 +50,15 @@ public class CPPTemplateTemplateParameter extends CPPTemplateParameter implement private ICPPTemplateParameter[] templateParameters; private ObjectMap instances; private ICPPScope unknownScope; - - public CPPTemplateTemplateParameter(IASTName name) { + private final boolean fIsParameterPack; + + public CPPTemplateTemplateParameter(IASTName name, boolean isPack) { super(name); + fIsParameterPack= isPack; + } + + public final boolean isParameterPack() { + return fIsParameterPack; } public ICPPScope asScope() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeParameter.java index 98288c83a36..33a4d9141e5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeParameter.java @@ -29,9 +29,15 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; public class CPPTemplateTypeParameter extends CPPTemplateParameter implements ICPPTemplateTypeParameter, ICPPUnknownType, ICPPUnknownBinding { private ICPPScope unknownScope; + private final boolean fIsParameterPack; - public CPPTemplateTypeParameter(IASTName name) { + public CPPTemplateTypeParameter(IASTName name, boolean isPack) { super(name); + fIsParameterPack= isPack; + } + + public final boolean isParameterPack() { + return fIsParameterPack; } public ICPPScope asScope() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownFunction.java index 16a1f6ffa5a..0f77af4e1dc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownFunction.java @@ -89,4 +89,12 @@ public class CPPUnknownFunction extends CPPUnknownBinding implements ICPPFunctio public boolean takesVarArgs() throws DOMException { return false; } + + public int getRequiredArgumentCount() throws DOMException { + return 0; + } + + public boolean hasParameterPack() { + return false; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java index 26952c3e472..8dcc5004c87 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java @@ -29,7 +29,6 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; -import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IFunctionType; @@ -38,7 +37,6 @@ import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; -import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; @@ -669,8 +667,8 @@ public class ClassTypeHelper { if (params.length == 0) return KIND_DEFAULT_CTOR; if (params.length == 1) { - IType t= params[0]; - if (t instanceof IBasicType && ((IBasicType) t).getKind() == Kind.eVoid) + IType t= SemanticUtil.getNestedType(params[0], SemanticUtil.TDEF); + if (SemanticUtil.isVoidType(t)) return KIND_DEFAULT_CTOR; if (isRefToConstClass(ct, t)) 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 98d5a71f0af..2b351a9a233 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,6 +16,7 @@ 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; @@ -32,18 +33,14 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTExpression; -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.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTInitializer; -import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression; -import org.eclipse.cdt.core.dom.ast.IASTInitializerList; import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTNode; -import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTPointer; import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTProblem; @@ -60,6 +57,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.cpp.ICPPASTAmbiguousTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTArrayDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; @@ -67,15 +65,20 @@ 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.ICPPASTDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionWithTryBlock; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializer; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerExpression; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; @@ -98,6 +101,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTryBlockStatement; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypenameExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression; @@ -105,6 +109,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNodeFactory; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTExplicitTemplateInstantiation; @@ -129,6 +134,8 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; 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.IASTAmbiguityParent; +import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclarator; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousStatement; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; @@ -140,7 +147,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; */ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { private static final int DEFAULT_PARM_LIST_SIZE = 4; - private static final int DEFAULT_POINTEROPS_LIST_SIZE = 4; private static final int DEFAULT_CATCH_HANDLER_LIST_SIZE= 4; private static enum DtorStrategy {PREFER_FUNCTION, PREFER_NESTED} @@ -350,7 +356,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } /** - * Makes a fast check whether there could be template arguments. + * Makes a fast check whether there could be template arguments. + * -1: no, 0: ambiguous, 1: yes */ private int canBeTemplateArguments(CastExprCtx ctx) throws EndOfFileException, BacktrackException { if (LTcatchEOF(1) != IToken.tLT) @@ -390,11 +397,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { lt1= LTcatchEOF(2); } switch(lt1) { - // can be some cast-expression or continuation after template-id + // Can be some cast-expression or continuation after template-id case IToken.tCOLONCOLON: // CT<int>::member case IToken.tLPAREN: // ft<int>(args) return 0; - // end of an expression + // Start of other expressions (then we can't have a template) // unary expression case IToken.tMINUS: case IToken.tPLUS: @@ -450,6 +457,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { case IToken.tRBRACE: case IToken.tRBRACKET: case IToken.tRPAREN: + case IToken.tELLIPSIS: // pack-expansion return 1; // don't know default: @@ -505,82 +513,106 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } private List<IASTNode> templateArgumentList(boolean isAmbiguous) throws EndOfFileException, BacktrackException { - IToken start = LA(1); - int startingOffset = start.getOffset(); + int startingOffset = LA(1).getOffset(); int endOffset = 0; - start = null; - List<IASTNode> list = new ArrayList<IASTNode>(); + List<IASTNode> list= null; final BinaryExprCtx exprCtx = isAmbiguous ? BinaryExprCtx.eAmbigTmplID : BinaryExprCtx.eTmplID; - boolean failed = false; + boolean needComma= false; int lt1= LT(1); while (lt1 != IToken.tGT && lt1 != IToken.tGT_in_SHIFTR && lt1 != IToken.tEOC) { - IToken argStart = mark(); - IASTTypeId typeId = typeId(DeclarationOptions.TYPEID); - - lt1 = LT(1); - if(typeId != null && (lt1==IToken.tCOMMA || lt1==IToken.tGT || lt1 == IToken.tGT_in_SHIFTR || lt1==IToken.tEOC)) { - // potentially a type-id - check for id-expression ambiguity - IToken typeIdEnd= mark(); - try { - // consider ambiguity with id-expressions, only: - IASTDeclSpecifier declspec= typeId.getDeclSpecifier(); - if (!(declspec instanceof IASTNamedTypeSpecifier)) - throw backtrack; - IASTName name= ((IASTNamedTypeSpecifier) declspec).getName(); - if (!name.contains(typeId)) - throw backtrack; - - // A template-id cannot be used in an id-expression as a template argument - // 5.1-11 A template-id shall be used as an unqualified-id only as specified in - // 14.7.2, 14.7, and 14.5.4. - name= name.getLastName(); - if (name instanceof ICPPASTTemplateId) - throw backtrack; - - backup(argStart); - IASTExpression expression = expression(ExprKind.eAssignment, exprCtx); - if (expression instanceof IASTIdExpression) { - if (mark() != typeIdEnd) - throw backtrack; - - ICPPASTAmbiguousTemplateArgument ambiguity= createAmbiguousTemplateArgument(); - ambiguity.addTypeId(typeId); - ambiguity.addIdExpression((IASTIdExpression) expression); - list.add(ambiguity); - } else { - // prefer the typeId at this stage - throw backtrack; - } - } catch (BacktrackException e) { - // no ambiguity - its a type-id - list.add(typeId); - backup(typeIdEnd); - } - } else { - // not a type-id - try as expression - backup(argStart); - IASTExpression expression = expression(ExprKind.eAssignment, exprCtx); - list.add(expression); - } - + if (needComma) { + if (lt1 != IToken.tCOMMA) { + throwBacktrack(startingOffset, endOffset - startingOffset); + } + consume(); + } else { + needComma= true; + } + + IASTNode node= templateArgument(exprCtx); + if (list == null) { + list= new ArrayList<IASTNode>(); + } + list.add(node); lt1= LT(1); - if (lt1 == IToken.tCOMMA) { - consume(); - lt1= LT(1); - } else if (lt1 != IToken.tGT && lt1 != IToken.tGT_in_SHIFTR && lt1 != IToken.tEOC) { - failed = true; - endOffset = LA(1).getEndOffset(); - break; - } } - if (failed) - throwBacktrack(startingOffset, endOffset - startingOffset); - + if (list == null) { + return Collections.emptyList(); + } return list; } - private IASTName operatorId() throws BacktrackException, EndOfFileException { + private IASTNode templateArgument(BinaryExprCtx exprCtx) throws EndOfFileException, BacktrackException { + IToken argStart = mark(); + final ICPPASTTypeId typeId = typeId(DeclarationOptions.TYPEID); + + final int lt1 = LT(1); + if (typeId != null + && (lt1 == IToken.tCOMMA || lt1 == IToken.tGT || lt1 == IToken.tGT_in_SHIFTR + || lt1 == IToken.tEOC || lt1 == IToken.tELLIPSIS)) { + // This is potentially a type-id, now check ambiguity with id-expression + IASTDeclSpecifier declspec= typeId.getDeclSpecifier(); + if (declspec instanceof IASTNamedTypeSpecifier) { + IASTName name= ((IASTNamedTypeSpecifier) declspec).getName(); + if (name.contains(typeId)) { + // A template-id cannot be used in an id-expression as a template argument + // 5.1-11 A template-id shall be used as an unqualified-id only as specified in + // 14.7.2, 14.7, and 14.5.4. + name= name.getLastName(); + if (!(name instanceof ICPPASTTemplateId)) { + IToken typeIdEnd= mark(); + backup(argStart); + try { + IASTExpression expression = expression(ExprKind.eAssignment, exprCtx); + if (expression instanceof IASTIdExpression) { + if (mark() == typeIdEnd) { + if (LT(1) == IToken.tELLIPSIS) { + IToken ellipsis= consume(); + addPackExpansion(typeId, ellipsis); + expression= addPackExpansion(expression, ellipsis); + } + ICPPASTAmbiguousTemplateArgument ambiguity= createAmbiguousTemplateArgument(); + ambiguity.addTypeId(typeId); + ambiguity.addIdExpression(expression); + return ambiguity; + } + } + } catch (BacktrackException e) { + // Use the typeId + } + backup(typeIdEnd); + } + } + } + // There is no ambiguity, use the type-id + if (LT(1) == IToken.tELLIPSIS) { + addPackExpansion(typeId, consume()); + } + return typeId; + } + + // Not a type-id, parse as expression + backup(argStart); + IASTExpression expr= expression(ExprKind.eAssignment, exprCtx); + if (LT(1) == IToken.tELLIPSIS) { + expr= addPackExpansion(expr, consume()); + } + return expr; + } + + private void addPackExpansion(ICPPASTTypeId typeId, IToken consume) { + final int endOffset= consume.getEndOffset(); + adjustEndOffset(typeId, endOffset); + typeId.setIsPackExpansion(true); + } + + private IASTExpression addPackExpansion(IASTExpression expr, IToken ellipsis) { + IASTExpression result= nodeFactory.newPackExpansionExpression(expr); + return setRange(result, expr, ellipsis.getEndOffset()); + } + + private IASTName operatorId() throws BacktrackException, EndOfFileException { final IToken firstToken = consume(IToken.t_operator); int endOffset= firstToken.getEndOffset(); IASTTypeId typeId = null; @@ -705,6 +737,18 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { allowThrow= true; break; + case IToken.tELLIPSIS: + if ((!allowComma && conditionCount == 0)) + break loop; + + // Precedence: To the left just stronger than ',', to the right no other choice. + lastOperator= new BinaryOperator(lastOperator, expr, lt1, 12, Integer.MAX_VALUE); + expr= nodeFactory.newPackExpansionExpression(null); + setRange(expr, 0, consume().getEndOffset()); + if (LT(1) == IToken.tCOMMA) + continue loop; + break loop; + case IToken.tCOMMA: allowThrow= true; if (!allowComma && conditionCount == 0) @@ -1024,6 +1068,23 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { return postfixExpression(ctx); } case IToken.t_sizeof: + if (LTcatchEOF(2) == IToken.tELLIPSIS) { + int offset= consume().getOffset(); // sizeof + consume(); // ... + consume(IToken.tLPAREN); // ( + IASTName id= identifier(); + IASTIdExpression idexpr= nodeFactory.newIdExpression(id); + setRange(idexpr, id); + IASTUnaryExpression expr= nodeFactory.newUnaryExpression(IASTUnaryExpression.op_sizeofParameterPack, idexpr); + final int lt1= LT(1); + if (lt1 == IToken.tEOC) { + setRange(expr, offset, calculateEndOffset(id)); + } else { + final int endOffset = consume(IToken.tRPAREN).getEndOffset(); // ) + setRange(expr, offset, endOffset); + } + return expr; + } return parseTypeidInParenthesisOrUnaryExpression(false, consume().getOffset(), IASTTypeIdExpression.op_sizeof, IASTUnaryExpression.op_sizeof, ctx); case IGCCToken.t_typeof: @@ -1628,63 +1689,81 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { final int lt1= LT(1); if (lt1 == IToken.tGT || lt1 == IToken.tEOC || lt1 == IToken.tGT_in_SHIFTR) return returnValue; + + final int offset = LA(1).getOffset(); if (lt1 == IToken.t_class || lt1 == IToken.t_typename) { - IToken startingToken = LA(1); - int lastOffset = 0; int type = (lt1 == IToken.t_class ? ICPPASTSimpleTypeTemplateParameter.st_class : ICPPASTSimpleTypeTemplateParameter.st_typename); - lastOffset = consume().getEndOffset(); + boolean parameterPack= false; IASTName identifierName = null; - IASTTypeId typeId = null; - + IASTTypeId defaultValue = null; + int endOffset = consume().getEndOffset(); + + if (LT(1) == IToken.tELLIPSIS) { + parameterPack= true; + endOffset= consume().getOffset(); + } if (LT(1) == IToken.tIDENTIFIER) { // optional identifier identifierName = identifier(); - lastOffset = calculateEndOffset(identifierName); + endOffset = calculateEndOffset(identifierName); if (LT(1) == IToken.tASSIGN) { // optional = type-id + if (parameterPack) + throw backtrack; consume(); - typeId = typeId(DeclarationOptions.TYPEID); // type-id - if (typeId == null) + defaultValue = typeId(DeclarationOptions.TYPEID); // type-id + if (defaultValue == null) throw backtrack; - lastOffset = calculateEndOffset(typeId); + endOffset = calculateEndOffset(defaultValue); } } else { identifierName = nodeFactory.newName(); } - ICPPASTSimpleTypeTemplateParameter parm = nodeFactory.newSimpleTypeTemplateParameter(type, identifierName, typeId); - ((ASTNode) parm).setOffsetAndLength(startingToken.getOffset(), lastOffset - startingToken.getOffset()); - returnValue.add(parm); + ICPPASTSimpleTypeTemplateParameter tpar = nodeFactory.newSimpleTypeTemplateParameter(type, identifierName, defaultValue); + tpar.setIsParameterPack(parameterPack); + setRange(tpar, offset, endOffset); + returnValue.add(tpar); } else if (lt1 == IToken.t_template) { - IToken firstToken = consume(); - consume(IToken.tLT); + boolean parameterPack= false; + IASTName identifierName = null; + IASTExpression defaultValue = null; - List<ICPPASTTemplateParameter> subResult = templateParameterList(); + consume(); + consume(IToken.tLT); + List<ICPPASTTemplateParameter> tparList = templateParameterList(); consume(IToken.tGT, IToken.tGT_in_SHIFTR); - int last = consume(IToken.t_class).getEndOffset(); - IASTName identifierName = null; - IASTExpression optionalExpression = null; + int endOffset = consume(IToken.t_class).getEndOffset(); + + if (LT(1) == IToken.tELLIPSIS) { + parameterPack= true; + endOffset= consume().getOffset(); + } if (LT(1) == IToken.tIDENTIFIER) { // optional identifier identifierName = identifier(); - last = calculateEndOffset(identifierName); + endOffset = calculateEndOffset(identifierName); if (LT(1) == IToken.tASSIGN) { // optional = type-id + if (parameterPack) + throw backtrack; + consume(); - optionalExpression = primaryExpression(CastExprCtx.eNotBExpr); - last = calculateEndOffset(optionalExpression); + defaultValue = primaryExpression(CastExprCtx.eNotBExpr); + endOffset = calculateEndOffset(defaultValue); } - } else + } else { identifierName = nodeFactory.newName(); - - ICPPASTTemplatedTypeTemplateParameter parm = nodeFactory.newTemplatedTypeTemplateParameter(identifierName, optionalExpression); - ((ASTNode) parm).setOffsetAndLength(firstToken.getOffset(), last - firstToken.getOffset()); - - for (int i = 0; i < subResult.size(); ++i) { - ICPPASTTemplateParameter p = subResult.get(i); - parm.addTemplateParamter(p); } - returnValue.add(parm); + + ICPPASTTemplatedTypeTemplateParameter tpar = nodeFactory.newTemplatedTypeTemplateParameter(identifierName, defaultValue); + tpar.setIsParameterPack(parameterPack); + setRange(tpar, offset, endOffset); + for (int i = 0; i < tparList.size(); ++i) { + ICPPASTTemplateParameter p = tparList.get(i); + tpar.addTemplateParamter(p); + } + returnValue.add(tpar); } else if (lt1 == IToken.tCOMMA) { consume(); continue; @@ -2045,6 +2124,10 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } ICPPASTConstructorChainInitializer ctorInitializer = nodeFactory.newConstructorChainInitializer(name, expressionList); + if (LT(1) == IToken.tELLIPSIS) { + ctorInitializer.setIsPackExpansion(true); + endOffset= consume().getEndOffset(); + } setRange(ctorInitializer, offset, endOffset); fdef.addMemberInitializer(ctorInitializer); @@ -2753,36 +2836,10 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } - protected IASTInitializer initializerClause(boolean inAggregateInitializer) throws EndOfFileException, + protected ICPPASTInitializer initializerClause(boolean inAggregateInitializer) throws EndOfFileException, BacktrackException { if (LT(1) == IToken.tLBRACE) { - int startingOffset = consume().getOffset(); - - IASTInitializerList result = nodeFactory.newInitializerList(); - ((ASTNode) result).setOffset(startingOffset); - - if (LT(1) == (IToken.tRBRACE)) { - int endOffset = consume().getEndOffset(); - setRange(result, startingOffset, endOffset); - return result; - } - - // otherwise it is a list of initializer clauses - for (;;) { - if (LT(1) == IToken.tRBRACE) - break; - - // clause may be null, add to initializer anyways, such that the - // actual size can be computed. - IASTInitializer clause = initializerClause(true); - result.addInitializer(clause); - if (LT(1) == IToken.tRBRACE || LT(1) == IToken.tEOC) - break; - consume(IToken.tCOMMA); - } - int endOffset = consume().getEndOffset(); // tRBRACE - setRange(result, startingOffset, endOffset); - return result; + return initializerList(); } // no brace, so try an assignment expression @@ -2793,14 +2850,38 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { return null; } - IASTInitializerExpression result = nodeFactory.newInitializerExpression(assignmentExpression); + ICPPASTInitializerExpression result = nodeFactory.newInitializerExpression(assignmentExpression); setRange(result, assignmentExpression); return result; } + private ICPPASTInitializerList initializerList() throws EndOfFileException, BacktrackException { + int startingOffset = consume(IToken.tLBRACE).getOffset(); + + ICPPASTInitializerList result = nodeFactory.newInitializerList(); + + // List of initializer clauses + while (LT(1) != IToken.tRBRACE && LT(1) != IToken.tEOC) { + // Clause may be null, add to initializer anyways, such that the + // actual size can be computed. + ICPPASTInitializer clause = initializerClause(true); + if (LT(1) == IToken.tELLIPSIS) { + clause.setIsPackExpansion(true); + adjustEndOffset(clause, consume().getEndOffset()); + } + result.addInitializer(clause); + if (LT(1) == IToken.tRBRACE || LT(1) == IToken.tEOC) + break; + consume(IToken.tCOMMA); // Allow for trailing commas + } + int endOffset = consume().getEndOffset(); // tRBRACE + setRange(result, startingOffset, endOffset); + return result; + } + @Override - protected IASTTypeId typeId(DeclarationOptions option) throws EndOfFileException { + protected ICPPASTTypeId typeId(DeclarationOptions option) throws EndOfFileException { if (!canBeTypeSpecifier()) { return null; } @@ -2818,7 +2899,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } catch (BacktrackException bt) { return null; } - IASTTypeId result = nodeFactory.newTypeId(declSpecifier, declarator); + ICPPASTTypeId result = nodeFactory.newTypeId(declSpecifier, declarator); setRange(result, offset, figureEndOffset(declSpecifier, declarator)); return result; @@ -2845,9 +2926,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { final int startingOffset = LA(1).getOffset(); int endOffset = startingOffset; - List<IASTPointerOperator> pointerOps = new ArrayList<IASTPointerOperator>(DEFAULT_POINTEROPS_LIST_SIZE); - consumePointerOperators(pointerOps); - if (!pointerOps.isEmpty()) { + List<? extends IASTPointerOperator> pointerOps = consumePointerOperators(); + if (pointerOps != null) { endOffset = calculateEndOffset(pointerOps.get(pointerOps.size() - 1)); } @@ -2855,6 +2935,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers); // Look for identifier or nested declarator + boolean hasEllipsis= false; + if (option.fAllowParameterPacks && LT(1) == IToken.tELLIPSIS) { + consume(); + hasEllipsis= true; + } final int lt1= LT(1); switch (lt1) { case IToken.tBITCOMPLEMENT: @@ -2867,7 +2952,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { final IASTName declaratorName= qualifiedName(CastExprCtx.eNotBExpr); endOffset= calculateEndOffset(declaratorName); - return declarator(pointerOps, declaratorName, null, startingOffset, endOffset, strategy, option); + return declarator(pointerOps, hasEllipsis, declaratorName, null, startingOffset, endOffset, strategy, option); } if (lt1 == IToken.tLPAREN) { @@ -2877,8 +2962,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { if (option.fAllowAbstract && option.fAllowFunctions) { final IToken mark= mark(); try { - cand1= declarator(pointerOps, nodeFactory.newName(), null, startingOffset, endOffset, strategy, option); - if (option.fRequireAbstract || !option.fAllowNested) + cand1= declarator(pointerOps, hasEllipsis, nodeFactory.newName(), null, startingOffset, endOffset, strategy, option); + if (option.fRequireAbstract || !option.fAllowNested || hasEllipsis) return cand1; cand1End= LA(1); @@ -2888,9 +2973,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } // type-ids for new or operator-id: - if (!option.fAllowNested) { + if (!option.fAllowNested || hasEllipsis) { if (option.fAllowAbstract) { - return declarator(pointerOps, nodeFactory.newName(), null, startingOffset, endOffset, strategy, option); + return declarator(pointerOps, hasEllipsis, nodeFactory.newName(), null, startingOffset, endOffset, strategy, option); } throwBacktrack(LA(1)); } @@ -2903,7 +2988,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { final IASTDeclarator nested= declarator(DtorStrategy.PREFER_FUNCTION, option); endOffset= consume(IToken.tRPAREN).getEndOffset(); - final IASTDeclarator cand2= declarator(pointerOps, null, nested, startingOffset, endOffset, strategy, option); + final IASTDeclarator cand2= declarator(pointerOps, hasEllipsis, nodeFactory.newName(), nested, startingOffset, endOffset, strategy, option); if (cand1 == null || cand1End == null) return cand2; final IToken cand2End= LA(1); @@ -2930,7 +3015,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { if (!option.fAllowBitField || LT(1) != IToken.tCOLON) throwBacktrack(LA(1)); } - return declarator(pointerOps, nodeFactory.newName(), null, startingOffset, endOffset, strategy, option); + return declarator(pointerOps, hasEllipsis, nodeFactory.newName(), null, startingOffset, endOffset, strategy, option); } /** @@ -2940,9 +3025,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { * @throws BacktrackException * request a backtrack */ - private void consumePointerOperators(List<IASTPointerOperator> collection) - throws EndOfFileException, BacktrackException { - + private List<? extends IASTPointerOperator> consumePointerOperators() throws EndOfFileException, BacktrackException { + List<IASTPointerOperator> result= null; for (;;) { // __attribute__ in-between pointers __attribute_decl_seq(supportAttributeSpecifiers, false); @@ -2956,8 +3040,12 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { endToken= consume(); } ICPPASTReferenceOperator refOp = nodeFactory.newReferenceOperator(lt1 == IToken.tAND); - collection.add(setRange(refOp, offset, endToken.getEndOffset())); - return; + setRange(refOp, offset, endToken.getEndOffset()); + if (result != null) { + result.add(refOp); + return result; + } + return Collections.singletonList(refOp); } IToken mark = mark(); @@ -2983,16 +3071,16 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { name= qualifiedName(CastExprCtx.eNotBExpr); if (name.getLookupKey().length != 0) { backup(mark); - return; + return result; } } catch (BacktrackException bt) { backup(mark); - return; + return result; } } if (LTcatchEOF(1) != IToken.tSTAR) { backup(mark); - return; + return result; } int endOffset= consume().getEndOffset(); @@ -3039,28 +3127,31 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { pointer.setConst(isConst); pointer.setVolatile(isVolatile); setRange(pointer, startOffset, endOffset); - collection.add(pointer); + if (result == null) { + result= new ArrayList<IASTPointerOperator>(4); + } + result.add(pointer); } } - private IASTDeclarator declarator(List<IASTPointerOperator> pointerOps, + private IASTDeclarator declarator(List<? extends IASTPointerOperator> pointerOps, boolean hasEllipsis, IASTName declaratorName, IASTDeclarator nestedDeclarator, int startingOffset, int endOffset, DtorStrategy strategy, DeclarationOptions option) throws EndOfFileException, BacktrackException { - IASTDeclarator result= null; + ICPPASTDeclarator result= null; loop: while(true) { final int lt1= LTcatchEOF(1); switch (lt1) { case IToken.tLPAREN: if (option.fAllowFunctions && strategy == DtorStrategy.PREFER_FUNCTION) { result= functionDeclarator(); - setDeclaratorID(result, declaratorName, nestedDeclarator); + setDeclaratorID(result, hasEllipsis, declaratorName, nestedDeclarator); } break loop; case IToken.tLBRACKET: result= arrayDeclarator(option); - setDeclaratorID(result, declaratorName, nestedDeclarator); + setDeclaratorID(result, hasEllipsis, declaratorName, nestedDeclarator); break loop; case IToken.tCOLON: @@ -3068,7 +3159,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { break loop; // no backtrack because typeid can be followed by colon result= bitFieldDeclarator(); - setDeclaratorID(result, declaratorName, nestedDeclarator); + setDeclaratorID(result, hasEllipsis, declaratorName, nestedDeclarator); break loop; case IGCCToken.t__attribute__: // if __attribute__ is after a declarator @@ -3089,7 +3180,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { if (result == null) { result= nodeFactory.newDeclarator(null); - setDeclaratorID(result, declaratorName, nestedDeclarator); + setDeclaratorID(result, hasEllipsis, declaratorName, nestedDeclarator); } else { endOffset= calculateEndOffset(result); } @@ -3101,33 +3192,36 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers); } - for (IASTPointerOperator po : pointerOps) { - result.addPointerOperator(po); - } + if (pointerOps != null) { + for (IASTPointerOperator po : pointerOps) { + result.addPointerOperator(po); + } + } ((ASTNode) result).setOffsetAndLength(startingOffset, endOffset - startingOffset); return result; } - private void setDeclaratorID(IASTDeclarator declarator, IASTName declaratorName, IASTDeclarator nestedDeclarator) { + private void setDeclaratorID(ICPPASTDeclarator declarator, boolean hasEllipsis, IASTName declaratorName, IASTDeclarator nestedDeclarator) { if (nestedDeclarator != null) { declarator.setNestedDeclarator(nestedDeclarator); declarator.setName(nodeFactory.newName()); } else { declarator.setName(declaratorName); } + declarator.setDeclaresParameterPack(hasEllipsis); } /** * Parse a function declarator starting with the left parenthesis. */ - private IASTDeclarator functionDeclarator() throws EndOfFileException, BacktrackException { + private ICPPASTDeclarator functionDeclarator() throws EndOfFileException, BacktrackException { IToken last = consume(IToken.tLPAREN); int startOffset= last.getOffset(); - boolean seenParameter= false; int endOffset= last.getEndOffset(); final ICPPASTFunctionDeclarator fc = nodeFactory.newFunctionDeclarator(null); + ICPPASTParameterDeclaration pd= null; paramLoop: while(true) { switch (LT(1)) { case IToken.tRPAREN: @@ -3135,24 +3229,36 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { endOffset= consume().getEndOffset(); break paramLoop; case IToken.tELLIPSIS: - endOffset= consume().getEndOffset(); + consume(); + endOffset= consume(IToken.tRPAREN).getEndOffset(); fc.setVarArgs(true); - break; + break paramLoop; case IToken.tCOMMA: + if (pd == null) + throwBacktrack(LA(1)); endOffset= consume().getEndOffset(); - seenParameter = false; + pd= null; break; default: - if (seenParameter) + if (pd != null) throwBacktrack(startOffset, endOffset - startOffset); - IASTParameterDeclaration pd = parameterDeclaration(); + pd = parameterDeclaration(); fc.addParameterDeclaration(pd); endOffset = calculateEndOffset(pd); - seenParameter = true; break; } } + // Handle ambiguity between parameter pack and varargs. + if (pd != null) { + ICPPASTDeclarator dtor = pd.getDeclarator(); + if (!(dtor instanceof IASTAmbiguousDeclarator)) { + if (dtor.declaresParameterPack() && dtor.getNestedDeclarator() == null + && dtor.getInitializer() == null && dtor.getName().getSimpleID().length == 0) { + ((IASTAmbiguityParent) fc).replace(pd, new CPPASTAmbiguousParameterDeclaration(pd)); + } + } + } // Consume any number of __attribute__ tokens after the parameters __attribute_decl_seq(supportAttributeSpecifiers, false); @@ -3190,8 +3296,12 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { break; default: int thoffset = LA(1).getOffset(); - IASTTypeId typeId = typeId(DeclarationOptions.TYPEID); + ICPPASTTypeId typeId = typeId(DeclarationOptions.TYPEID); if (typeId != null) { + if (LT(1) == IToken.tELLIPSIS) { + typeId.setIsPackExpansion(true); + adjustEndOffset(typeId, consume().getEndOffset()); + } fc.addExceptionSpecificationTypeId(typeId); } else { int thendoffset = LA(1).getOffset(); @@ -3218,15 +3328,15 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { /** * 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); + private ICPPASTArrayDeclarator arrayDeclarator(DeclarationOptions option) throws EndOfFileException, BacktrackException { + ArrayList<IASTArrayModifier> arrayMods = new ArrayList<IASTArrayModifier>(4); 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 = nodeFactory.newArrayDeclarator(null); + final ICPPASTArrayDeclarator d = nodeFactory.newArrayDeclarator(null); for (IASTArrayModifier m : arrayMods) { d.addArrayModifier(m); } @@ -3239,13 +3349,13 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { /** * Parses for a bit field declarator starting with the colon */ - private IASTFieldDeclarator bitFieldDeclarator() throws EndOfFileException, BacktrackException { + private ICPPASTFieldDeclarator bitFieldDeclarator() throws EndOfFileException, BacktrackException { int start= consume(IToken.tCOLON).getOffset(); final IASTExpression bitField = constantExpression(); final int endOffset = calculateEndOffset(bitField); - IASTFieldDeclarator d = nodeFactory.newFieldDeclarator(null, bitField); + ICPPASTFieldDeclarator d = nodeFactory.newFieldDeclarator(null, bitField); ((ASTNode) d).setOffsetAndLength(start, endOffset-start); return d; } @@ -3298,7 +3408,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { // base clause if (LT(1) == IToken.tCOLON) { - baseSpecifier(astClassSpecifier); + baseClause(astClassSpecifier); // content assist within the base-clause if (LT(1) == IToken.tEOC) { return astClassSpecifier; @@ -3335,76 +3445,74 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } /** - * Parse the subclass-baseclauses for a class specification. baseclause: : - * basespecifierlist basespecifierlist: basespecifier basespecifierlist, - * basespecifier basespecifier: ::? nestednamespecifier? classname virtual - * accessspecifier? ::? nestednamespecifier? classname accessspecifier - * virtual? ::? nestednamespecifier? classname accessspecifier: private | - * protected | public - * - * @throws BacktrackException + * Parse a base clause for a class specification. + * base-clause: + * : base-specifier-list + * base-specifier-list: + * base-specifier + * base-specifier-list, base-specifier */ - protected void baseSpecifier(ICPPASTCompositeTypeSpecifier astClassSpec) throws EndOfFileException, BacktrackException { - int endOffset= consume().getEndOffset(); // tCOLON + private void baseClause(ICPPASTCompositeTypeSpecifier astClassSpec) throws EndOfFileException, BacktrackException { + consume(IToken.tCOLON); + for (;;) { + ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier baseSpec = baseSpecifier(); + astClassSpec.addBaseSpecifier(baseSpec); + + if (LT(1) == IToken.tELLIPSIS) { + baseSpec.setIsPackExpansion(true); + adjustEndOffset(baseSpec, consume().getEndOffset()); + } + + if (LT(1) != IToken.tCOMMA) { + return; + } + + consume(); + } + } + + /** + * base-specifier: + * ::? nested-name-specifier? class-name + * virtual access-specifier? ::? nested-name-specifier? class-name + * access-specifier virtual? ::? nested-name-specifier? class-name + * + * access-specifier: private | protected | public + * @return + */ + private ICPPASTBaseSpecifier baseSpecifier() throws EndOfFileException, BacktrackException { int startOffset= LA(1).getOffset(); - boolean isVirtual = false; int visibility = 0; IASTName name = null; - baseSpecifierLoop: for (;;) { + loop: for (;;) { switch (LT(1)) { case IToken.t_virtual: isVirtual = true; - endOffset= consume().getEndOffset(); + consume(); break; case IToken.t_public: visibility = ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.v_public; - endOffset= consume().getEndOffset(); + consume(); break; case IToken.t_protected: visibility = ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.v_protected; - endOffset= consume().getEndOffset(); + consume(); break; case IToken.t_private: visibility = ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.v_private; - endOffset= consume().getEndOffset(); - break; - case IToken.tCOLONCOLON: - case IToken.tIDENTIFIER: - case IToken.tCOMPLETION: - // to get templates right we need to use the class as the scope - name = qualifiedName(CastExprCtx.eNotBExpr); - endOffset= calculateEndOffset(name); + consume(); break; - case IToken.tCOMMA: - if (name == null) - name = nodeFactory.newName(); - consume(); - ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier baseSpec = nodeFactory.newBaseSpecifier(name, visibility, isVirtual); - setRange(baseSpec, startOffset, endOffset); - astClassSpec.addBaseSpecifier(baseSpec); - - isVirtual = false; - visibility = 0; - name = null; - startOffset= endOffset= LA(1).getOffset(); - continue baseSpecifierLoop; - case IToken.tLBRACE: - case IToken.tEOC: - if (name == null) - name = nodeFactory.newName(); - baseSpec = nodeFactory.newBaseSpecifier(name, visibility, isVirtual); - setRange(baseSpec, startOffset, endOffset); - astClassSpec.addBaseSpecifier(baseSpec); - break baseSpecifierLoop; - default: - break baseSpecifierLoop; + break loop; } } + name = qualifiedName(CastExprCtx.eNotBExpr); + ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier baseSpec = nodeFactory.newBaseSpecifier(name, visibility, isVirtual); + setRange(baseSpec, startOffset, calculateEndOffset(name)); + return baseSpec; } - protected void catchHandlerSequence(List<ICPPASTCatchHandler> collection) throws EndOfFileException, BacktrackException { if (LT(1) == IToken.tEOC) return; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index 4eb506bbdfa..f6231e4ee3e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -65,14 +65,12 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.IASTTypeIdInitializerExpression; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; -import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunctionType; -import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IQualifierType; @@ -87,6 +85,7 @@ 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.ICPPASTConversionName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement; @@ -106,6 +105,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement; @@ -446,6 +446,9 @@ public class CPPSemantics { IASTNode parent= name.getParent().getParent(); if (parent instanceof ICPPASTTemplatedTypeTemplateParameter) { // default for template template parameter is an id-expression, which is a type. + } else if (parent instanceof ICPPASTUnaryExpression + && ((ICPPASTUnaryExpression) parent).getOperator() == IASTUnaryExpression.op_sizeofParameterPack) { + // argument of sizeof... can be a type } else if (data.considerConstructors && (binding instanceof ICPPUnknownType || binding instanceof ITypedef || binding instanceof IEnumeration)) { // constructor or simple-type constructor @@ -959,6 +962,7 @@ public class CPPSemantics { if (expression instanceof IASTUnaryExpression) { switch (((IASTUnaryExpression) expression).getOperator()) { case IASTUnaryExpression.op_sizeof: + case IASTUnaryExpression.op_sizeofParameterPack: case IASTUnaryExpression.op_typeid: case IASTUnaryExpression.op_throw: return PROCESS_SKIP; @@ -1949,25 +1953,23 @@ public class CPPSemantics { if (def && argumentCount == 1) { // check for parameter of type void final IType[] argTypes = data.getFunctionArgumentTypes(); - if (argTypes.length == 1) { - IType t= getNestedType(argTypes[0], TDEF); - if (t instanceof IBasicType && ((IBasicType)t).getKind() == Kind.eVoid) { - argumentCount= 0; - } + if (argTypes.length == 1 && SemanticUtil.isVoidType(argTypes[0])) { + argumentCount= 0; } } // Trim the list down to the set of viable functions - IFunction function = null; + ICPPFunction function = null; int size = functions.length; for (int i = 0; i < size; i++) { - function = (IFunction) functions[i]; - if (function == null) - continue; - if (function instanceof IProblemBinding) { + if (functions[i] instanceof IProblemBinding) { functions[i]= null; continue; } + + function = (ICPPFunction) functions[i]; + if (function == null) + continue; if (function instanceof ICPPUnknownBinding) { if (def) { functions[i]= null; @@ -1979,47 +1981,31 @@ public class CPPSemantics { // as long as possible. final IType[] parameterTypes = function.getType().getParameterTypes(); int numPars = parameterTypes.length; + if (numPars == 1 && SemanticUtil.isVoidType(parameterTypes[0])) + numPars= 0; int numArgs = argumentCount; if (function instanceof ICPPMethod && data.firstArgIsImpliedMethodArg) numArgs--; - if (numArgs < 2 && numPars == 1) { - // check for void - IType t = getNestedType(parameterTypes[0], TDEF); - if (t instanceof IBasicType && ((IBasicType)t).getKind() == Kind.eVoid) - numPars= 0; - } - if (def) { if (numPars != numArgs || !isMatchingFunctionDeclaration(function, data)) { functions[i] = null; } } else { - // more arguments than parameters --> need ellipses + // more arguments than parameters --> need ellipsis if (numArgs > numPars) { - if (!function.takesVarArgs()) { + if (!function.takesVarArgs() && !function.hasParameterPack()) { functions[i] = null; } - } else if (numArgs < numPars) { - // fewer arguments than parameters --> need default values - IParameter[] params = function.getParameters(); - if (params.length < numPars) { - functions[i]= null; - } else { - for (int j = numArgs; j < numPars; j++) { - final ICPPParameter param = (ICPPParameter) params[j]; - if (param == null || !param.hasDefaultValue()) { - functions[i] = null; - break; - } - } - } + } else if (numArgs < function.getRequiredArgumentCount()) { + // fewer arguments than required + functions[i]= null; } } } } - static private boolean isMatchingFunctionDeclaration(IFunction candidate, LookupData data) { + static private boolean isMatchingFunctionDeclaration(ICPPFunction candidate, LookupData data) { IASTNode node = data.astName.getParent(); while (node instanceof IASTName) node = node.getParent(); @@ -3039,8 +3025,9 @@ public class CPPSemantics { return set.keyArray(IBinding.class); } - public static boolean isSameFunction(IFunction function, IASTDeclarator declarator) { - IASTName name = ASTQueries.findInnermostDeclarator(declarator).getName(); + public static boolean isSameFunction(ICPPFunction function, IASTDeclarator declarator) { + final ICPPASTDeclarator innerDtor = (ICPPASTDeclarator) ASTQueries.findInnermostDeclarator(declarator); + IASTName name = innerDtor.getName(); ICPPASTTemplateDeclaration templateDecl = CPPTemplates.getTemplateDeclaration(name); if (templateDecl != null) { if (templateDecl instanceof ICPPASTTemplateSpecialization) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index dd0bd9c3224..28f111e42b8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -74,6 +74,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; @@ -119,6 +120,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethodInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethodSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethodTemplateSpecialization; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPParameterPackType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType; @@ -400,8 +402,13 @@ public class CPPTemplates { for (int i = 0; i < templateParameters.length; i++) { final ICPPTemplateParameter tp = templateParameters[i]; if (tp instanceof IType) { - args[i] = new CPPTemplateArgument((IType) tp); + IType t= (IType) tp; + if (tp.isParameterPack()) { + t= new CPPParameterPackType(t); + } + args[i] = new CPPTemplateArgument(t); } else if (tp instanceof ICPPTemplateNonTypeParameter) { + // Non-type template parameter pack already has type 'ICPPParameterPackType' final ICPPTemplateNonTypeParameter nttp = (ICPPTemplateNonTypeParameter) tp; args[i] = new CPPTemplateArgument(Value.create(nttp), nttp.getType()); } else { @@ -490,15 +497,15 @@ public class CPPTemplates { return (binding instanceof ICPPTemplateDefinition) ? (ICPPTemplateDefinition) binding : null; } - public static IBinding createBinding(ICPPASTTemplateParameter templateParameter) { - if (templateParameter instanceof ICPPASTSimpleTypeTemplateParameter) { - return new CPPTemplateTypeParameter(((ICPPASTSimpleTypeTemplateParameter) templateParameter).getName()); + public static IBinding createBinding(ICPPASTTemplateParameter tp) { + if (tp instanceof ICPPASTSimpleTypeTemplateParameter) { + return new CPPTemplateTypeParameter(((ICPPASTSimpleTypeTemplateParameter) tp).getName(), tp.isParameterPack()); } - if (templateParameter instanceof ICPPASTTemplatedTypeTemplateParameter) { - return new CPPTemplateTemplateParameter(((ICPPASTTemplatedTypeTemplateParameter) templateParameter).getName()); + if (tp instanceof ICPPASTTemplatedTypeTemplateParameter) { + return new CPPTemplateTemplateParameter(((ICPPASTTemplatedTypeTemplateParameter) tp).getName(), tp.isParameterPack()); } - assert templateParameter instanceof ICPPASTParameterDeclaration; - final IASTDeclarator dtor = ((ICPPASTParameterDeclaration) templateParameter).getDeclarator(); + assert tp instanceof ICPPASTParameterDeclaration; + final IASTDeclarator dtor = ((ICPPASTParameterDeclaration) tp).getDeclarator(); return new CPPTemplateNonTypeParameter(ASTQueries.findInnermostDeclarator(dtor).getName()); } @@ -708,15 +715,15 @@ public class CPPTemplates { ICPPTemplateInstance instance = null; if (template instanceof ICPPClassType) { - instance = new CPPClassInstance(owner, (ICPPClassType) template, tpMap, args); + instance = new CPPClassInstance((ICPPClassType) template, owner, tpMap, args); } else if (owner instanceof ICPPClassType && template instanceof ICPPMethod) { if (template instanceof ICPPConstructor) { - instance = new CPPConstructorInstance((ICPPClassType) owner, (ICPPConstructor) template, tpMap, args); + instance = new CPPConstructorInstance((ICPPConstructor) template, (ICPPClassType) owner, tpMap, args); } else { - instance = new CPPMethodInstance((ICPPClassType) owner, (ICPPMethod) template, tpMap, args); + instance = new CPPMethodInstance((ICPPMethod) template, (ICPPClassType) owner, tpMap, args); } } else if (template instanceof ICPPFunction) { - instance = new CPPFunctionInstance(owner, (ICPPFunction) template, tpMap, args); + instance = new CPPFunctionInstance((ICPPFunction) template, owner, tpMap, args); } return instance; } @@ -739,17 +746,17 @@ public class CPPTemplates { spec = new CPPFieldSpecialization(decl, owner, tpMap); } else if (decl instanceof ICPPFunctionTemplate) { if (decl instanceof ICPPConstructor) - spec = new CPPConstructorTemplateSpecialization(decl, owner, tpMap); + spec = new CPPConstructorTemplateSpecialization((ICPPConstructor) decl, owner, tpMap); else if (decl instanceof ICPPMethod) - spec = new CPPMethodTemplateSpecialization(decl, owner, tpMap); + spec = new CPPMethodTemplateSpecialization((ICPPMethod) decl, owner, tpMap); else - spec = new CPPFunctionTemplateSpecialization(decl, owner, tpMap); + spec = new CPPFunctionTemplateSpecialization((ICPPFunctionTemplate) decl, owner, tpMap); } else if (decl instanceof ICPPConstructor) { - spec = new CPPConstructorSpecialization(decl, owner, tpMap); + spec = new CPPConstructorSpecialization((ICPPConstructor) decl, owner, tpMap); } else if (decl instanceof ICPPMethod) { - spec = new CPPMethodSpecialization(decl, owner, tpMap); + spec = new CPPMethodSpecialization((ICPPMethod) decl, owner, tpMap); } else if (decl instanceof ICPPFunction) { - spec = new CPPFunctionSpecialization(decl, owner, tpMap); + spec = new CPPFunctionSpecialization((ICPPFunction) decl, owner, tpMap); } else if (decl instanceof ITypedef) { spec = new CPPTypedefSpecialization(decl, owner, tpMap); } else if (decl instanceof IEnumeration || decl instanceof IEnumerator) { @@ -815,7 +822,7 @@ public class CPPTemplates { if (ret == r && params == ps) { return type; } - return new CPPFunctionType(ret, params, ft.isConst(), ft.isVolatile()); + return new CPPFunctionType(ret, params, ft.isConst(), ft.isVolatile(), ft.takesVarArgs()); } if (type instanceof ICPPTemplateParameter) { @@ -2105,7 +2112,16 @@ public class CPPTemplates { if (arg.isNonTypeValue()) return false; IType argType= arg.getTypeValue(); - if (argType == null || !argType.isSameType((IType) par)) + if (argType == null) + return false; + if (par.isParameterPack()) { + if (!(argType instanceof ICPPParameterPackType)) + return false; + argType= ((ICPPParameterPackType) argType).getType(); + if (argType == null) + return false; + } + if (!argType.isSameType((IType) par)) return false; } else { if (arg.isTypeValue()) 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 a0f33b20967..980727da09a 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 @@ -13,9 +13,7 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateType; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateTypeUptoPointers; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.DOMException; @@ -66,7 +64,6 @@ import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumerator; -import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.ILabel; import org.eclipse.cdt.core.dom.ast.IParameter; @@ -84,6 +81,7 @@ 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.ICPPASTConversionName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; @@ -106,6 +104,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypenameExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective; @@ -157,6 +156,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethodTemplate; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPNamespace; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPNamespaceAlias; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPParameter; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPParameterPackType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType; @@ -556,7 +556,7 @@ public class CPPVisitor extends ASTQueries { parent = param.getParent(); if (parent instanceof IASTStandardFunctionDeclarator) { IASTStandardFunctionDeclarator fdtor = (IASTStandardFunctionDeclarator) param.getParent(); - // if the fdtor does not declare a function we don't create a binding for the parameter. + // Create parameter bindings only if the declarator declares a function if (!(findOutermostDeclarator(fdtor).getParent() instanceof IASTDeclaration) || findTypeRelevantDeclarator(fdtor) != fdtor) return null; @@ -660,8 +660,8 @@ public class CPPVisitor extends ASTQueries { } if (isFunction) { - if (binding instanceof ICPPInternalBinding && binding instanceof IFunction && name.isActive()) { - IFunction function = (IFunction) binding; + if (binding instanceof ICPPInternalBinding && binding instanceof ICPPFunction && name.isActive()) { + ICPPFunction function = (ICPPFunction) binding; if (CPPSemantics.isSameFunction(function, typeRelevantDtor)) { binding= CPPSemantics.checkDeclSpecifier(binding, name, parent); if (binding instanceof IProblemBinding) @@ -1547,22 +1547,14 @@ public class CPPVisitor extends ASTQueries { pTypes[i] = pt; } - return new CPPFunctionType(returnType, pTypes, isConst, isVolatile); + return new CPPFunctionType(returnType, pTypes, isConst, isVolatile, false); } private static IType createType(IType returnType, ICPPASTFunctionDeclarator fnDtor) { - IASTParameterDeclaration[] params = fnDtor.getParameters(); + ICPPASTParameterDeclaration[] params = fnDtor.getParameters(); IType[] pTypes = new IType[params.length]; - IType pt = null; - for (int i = 0; i < params.length; i++) { - IASTDeclSpecifier pDeclSpec = params[i].getDeclSpecifier(); - IASTDeclarator pDtor = params[i].getDeclarator(); - pt = createType(pDeclSpec); - pt = createType(pt, pDtor); - - pt = SemanticUtil.adjustParameterType(pt, true); - pTypes[i] = pt; + pTypes[i]= createParameterType(params[i], true); } IASTName name = fnDtor.getName(); @@ -1576,13 +1568,55 @@ public class CPPVisitor extends ASTQueries { returnType = getPointerTypes(returnType, fnDtor); } - IType type = new CPPFunctionType(returnType, pTypes, fnDtor.isConst(), fnDtor.isVolatile()); + CPPFunctionType type = new CPPFunctionType(returnType, pTypes, fnDtor.isConst(), fnDtor.isVolatile(), + fnDtor.takesVarArgs()); final IASTDeclarator nested = fnDtor.getNestedDeclarator(); if (nested != null) { return createType(type, nested); } return type; } + + /** + * Creates the type for a parameter declaration. + */ + public static IType createParameterType(final ICPPASTParameterDeclaration pdecl, boolean forFuncType) { + IType pt; + IASTDeclSpecifier pDeclSpec = pdecl.getDeclSpecifier(); + ICPPASTDeclarator pDtor = pdecl.getDeclarator(); + pt = createType(pDeclSpec); + pt = createType(pt, pDtor); + pt= adjustParameterType(pt, forFuncType); + + if (CPPVisitor.findInnermostDeclarator(pDtor).declaresParameterPack()) { + pt= new CPPParameterPackType(pt); + } + return pt; + } + + /** + * Adjusts the parameter type according to 8.3.5-3: + * cv-qualifiers are deleted, arrays and function types are converted to pointers. + */ + private static IType adjustParameterType(final IType pt, boolean forFunctionType) { + // bug 239975 + IType t= SemanticUtil.getNestedType(pt, TDEF); + if (t instanceof IArrayType) { + IArrayType at = (IArrayType) t; + return new CPPPointerType(at.getType()); + } + if (t instanceof IFunctionType) { + return new CPPPointerType(pt); + } + + // 8.3.5-3 + // Any cv-qualifier modifying a parameter type is deleted. The parameter type remains + // to be qualified. + if (forFunctionType && SemanticUtil.getCVQualifier(t) != CVQualifier._) { + return SemanticUtil.getNestedType(t, TDEF | ALLCVQ); + } + return pt; + } /** * @param declarator @@ -1652,14 +1686,18 @@ public class CPPVisitor extends ASTQueries { IASTNode parent = declarator.getParent(); IASTDeclSpecifier declSpec = null; - if (parent instanceof IASTParameterDeclaration) { - declSpec = ((IASTParameterDeclaration) parent).getDeclSpecifier(); - } else if (parent instanceof IASTSimpleDeclaration) { + boolean isPackExpansion= false; + if (parent instanceof IASTSimpleDeclaration) { declSpec = ((IASTSimpleDeclaration)parent).getDeclSpecifier(); } else if (parent instanceof IASTFunctionDefinition) { declSpec = ((IASTFunctionDefinition)parent).getDeclSpecifier(); - } else if (parent instanceof IASTTypeId) { - declSpec = ((IASTTypeId)parent).getDeclSpecifier(); + } else if (parent instanceof ICPPASTTypeId) { + final ICPPASTTypeId typeId = (ICPPASTTypeId)parent; + declSpec = typeId.getDeclSpecifier(); + isPackExpansion= typeId.isPackExpansion(); + } else { + assert false; + return null; } IType type = createType(declSpec); @@ -1676,6 +1714,9 @@ public class CPPVisitor extends ASTQueries { } } } + if (isPackExpansion) { + type= new CPPParameterPackType(type); + } return type; } @@ -2154,4 +2195,8 @@ public class CPPVisitor extends ASTQueries { } return false; } + + public static ICPPASTDeclarator findInnermostDeclarator(ICPPASTDeclarator dtor) { + return (ICPPASTDeclarator) ASTQueries.findInnermostDeclarator(dtor); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java index f84916440a5..e6b580662fd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java @@ -27,7 +27,6 @@ import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IFunctionType; -import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IQualifierType; @@ -40,7 +39,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; @@ -136,13 +134,7 @@ public class Conversions { // shall be an rvalue. boolean ok; if (isLValueRef) { - // mstodo - // Special rule for implicit object type, 13.3.1-5: - // Even if the implicit object type is not const-qualified, an rvalue temporary can - // be bound to the parameter as long as in all other respects .... - // - final CVQualifier cvq = getCVQualifier(cv1T1); - ok = cvq == CVQualifier.c; + ok = getCVQualifier(cv1T1) == CVQualifier.c; } else { ok= !exprIsLValue; } @@ -467,16 +459,13 @@ public class Conversions { continue; } } else { - IType ptype= ptypes[0]; + IType ptype= SemanticUtil.getNestedType(ptypes[0], TDEF); // We don't need to check the implicit conversion sequence if the type is void - if (ptype instanceof ICPPBasicType && ((ICPPBasicType) ptype).getKind() == Kind.eVoid) + if (SemanticUtil.isVoidType(ptype)) continue; - if (ptypes.length > 1) { - IParameter[] pars = ctor.getParameters(); - if (pars.length < 2 || !((ICPPParameter) pars[1]).hasDefaultValue()) - continue; - - } + if (ctor.getRequiredArgumentCount() > 1) + continue; + c1= new FunctionCost(ctor, checkImplicitConversionSequence(ptype, source, sourceIsLValue, UDCMode.noUDC, false)); } int cmp= c1.compareTo(null, cost1); @@ -868,7 +857,7 @@ public class Conversions { // 4.10-2 an rvalue of type "pointer to cv T", where T is an object type can be // converted to an rvalue of type "pointer to cv void" IType tgtPtrTgt= getNestedType(tgtPtr.getType(), TDEF | CVTYPE | REF); - if (tgtPtrTgt instanceof IBasicType && ((IBasicType) tgtPtrTgt).getKind() == Kind.eVoid) { + if (SemanticUtil.isVoidType(tgtPtrTgt)) { cost.setRank(Rank.CONVERSION); cost.setInheritanceDistance(Short.MAX_VALUE); // mstodo add distance to last base class CVQualifier cv= getCVQualifier(srcPtr.getType()); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java index f5a54084b94..1311cbb2f77 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java @@ -36,7 +36,6 @@ import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTNode; -import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; @@ -56,6 +55,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; @@ -598,12 +598,12 @@ public class LookupData { public IType[] getFunctionArgumentTypes() { if (functionArgTypes == null && functionArgs != null) { - if (functionArgs instanceof IASTParameterDeclaration[]) { - IASTParameterDeclaration[] pdecls= (IASTParameterDeclaration[]) functionArgs; + if (functionArgs instanceof ICPPASTParameterDeclaration[]) { + ICPPASTParameterDeclaration[] pdecls= (ICPPASTParameterDeclaration[]) functionArgs; functionArgTypes= new IType[pdecls.length]; for (int i = 0; i < pdecls.length; i++) { - IASTParameterDeclaration p = pdecls[i]; - functionArgTypes[i]= SemanticUtil.getSimplifiedType(CPPVisitor.createType(p.getDeclarator())); + functionArgTypes[i] = SemanticUtil.getSimplifiedType(CPPVisitor.createParameterType( + pdecls[i], true)); } } else if (functionArgs instanceof IASTExpression[]) { IASTExpression[] exprs= (IASTExpression[]) functionArgs; @@ -647,7 +647,7 @@ public class LookupData { functionArgTypes= paramTypes; } - public void setFunctionParameters(IASTParameterDeclaration[] parameters) { + public void setFunctionParameters(ICPPASTParameterDeclaration[] parameters) { functionArgs= parameters; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java index 7fbb368181e..4bc27bba2e6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java @@ -20,6 +20,7 @@ import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IArrayType; +import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IPointerType; @@ -27,14 +28,17 @@ import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.parser.Keywords; import org.eclipse.cdt.core.parser.util.ArrayUtil; @@ -49,6 +53,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator; /** @@ -288,6 +293,7 @@ public class SemanticUtil { return replaceNestedType((ITypeContainer) rt, newNested); } } + // Pack expansion types are dependent types, there is no need to descend into those. if (t == null) return type; @@ -310,7 +316,7 @@ public class SemanticUtil { if (ret == r && params == ps) { return type; } - return new CPPFunctionType(ret, params, ft.isConst(), ft.isVolatile()); + return new CPPFunctionType(ret, params, ft.isConst(), ft.isVolatile(), ft.takesVarArgs()); } if (type instanceof ITypedef) { @@ -371,6 +377,50 @@ public class SemanticUtil { return type; } + public static boolean containsParameterPack(IType type) { + while (true) { + if (type instanceof ICPPTemplateParameter) { + return ((ICPPTemplateParameter) type).isParameterPack(); + } else if (type instanceof ICPPDeferredClassInstance) { + // mstodo check the deferred arguments. + return false; + } else if (type instanceof ICPPUnknownBinding) { + try { + IBinding owner= ((ICPPUnknownBinding) type).getOwner(); + if (owner instanceof IType) { + type= (IType) owner; + } else { + return false; + } + } catch (DOMException e) { + return false; + } + } else if (type instanceof IFunctionType) { + final ICPPFunctionType ft = (ICPPFunctionType) type; + final IType r = ft.getReturnType(); + if (containsParameterPack(r)) + return true; + final IType[] ps = ft.getParameterTypes(); + for (IType p : ps) { + if (containsParameterPack(p)) + return true; + } + + } else if (type instanceof ICPPParameterPackType) { + // A pack expansion expands all packs. + return false; + } else if (type instanceof IArrayType) { + final IArrayType atype= (IArrayType) type; + // mstodo check array size + type= atype.getType(); + } else if (type instanceof ITypeContainer) { + type= ((ITypeContainer) type).getType(); + } else { + return false; + } + } + } + public static IType mapToAST(IType type, IASTNode node) { if (type instanceof IFunctionType) { final ICPPFunctionType ft = (ICPPFunctionType) type; @@ -379,7 +429,7 @@ public class SemanticUtil { if (ret == r) { return type; } - return new CPPFunctionType(ret, ft.getParameterTypes(), ft.isConst(), ft.isVolatile()); + return new CPPFunctionType(ret, ft.getParameterTypes(), ft.isConst(), ft.isVolatile(), ft.takesVarArgs()); } if (type instanceof ITypeContainer) { final ITypeContainer tc = (ITypeContainer) type; @@ -453,30 +503,6 @@ public class SemanticUtil { return arg; } - /** - * Adjusts the parameter type according to 8.3.5-3: - * cv-qualifiers are deleted, arrays and function types are converted to pointers. - */ - public static IType adjustParameterType(final IType pt, boolean forFunctionType) { - // bug 239975 - IType t= SemanticUtil.getNestedType(pt, TDEF); - if (t instanceof IArrayType) { - IArrayType at = (IArrayType) t; - return new CPPPointerType(at.getType()); - } - if (t instanceof IFunctionType) { - return new CPPPointerType(pt); - } - - // 8.3.5-3 - // Any cv-qualifier modifying a parameter type is deleted. The parameter type remains - // to be qualified. - if (forFunctionType && SemanticUtil.getCVQualifier(t) != CVQualifier._) { - return SemanticUtil.getNestedType(t, TDEF | ALLCVQ); - } - return pt; - } - public static IType addQualifiers(IType baseType, boolean cnst, boolean vol) { if (cnst || vol) { if (baseType instanceof IQualifierType) { @@ -550,4 +576,14 @@ public class SemanticUtil { } return false; } + + public static boolean isVoidType(IType ptype) { + while (ptype instanceof ITypedef) { + ptype= ((ITypedef) ptype).getType(); + } + if (ptype instanceof IBasicType) { + return ((IBasicType) ptype).getKind() == Kind.eVoid; + } + return false; + } } 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 673529a4ef0..734ccd0dd5f 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 @@ -70,6 +70,7 @@ public class ExpressionWriter extends NodeWriter{ private static final String TYPEID_OP = "typeid ("; //$NON-NLS-1$ private static final String OPEN_BRACKET_OP = "("; //$NON-NLS-1$ private static final String SIZEOF_OP = "sizeof "; //$NON-NLS-1$ + private static final String SIZEOF_PARAMETER_PACK_OP = "sizeof... "; //$NON-NLS-1$ private static final String NOT_OP = "!"; //$NON-NLS-1$ private static final String TILDE_OP = "~"; //$NON-NLS-1$ private static final String AMPERSAND_OP = "&"; //$NON-NLS-1$ @@ -247,6 +248,7 @@ public class ExpressionWriter extends NodeWriter{ case IASTUnaryExpression.op_tilde: case IASTUnaryExpression.op_not: case IASTUnaryExpression.op_sizeof: + case IASTUnaryExpression.op_sizeofParameterPack: case IASTUnaryExpression.op_bracketedPrimary: case ICPPASTUnaryExpression.op_throw: case ICPPASTUnaryExpression.op_typeid: @@ -296,6 +298,8 @@ public class ExpressionWriter extends NodeWriter{ return NOT_OP; case IASTUnaryExpression.op_sizeof: return SIZEOF_OP; + case IASTUnaryExpression.op_sizeofParameterPack: + return SIZEOF_PARAMETER_PACK_OP; case IASTUnaryExpression.op_bracketedPrimary: return OPEN_BRACKET_OP; case ICPPASTUnaryExpression.op_throw: |