From 116a84832cb84a3eb720096b63eae38f117cfd5d Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Tue, 16 Mar 2010 16:36:03 +0000 Subject: [PATCH] Bug 305972: [C++0x] New function declarator syntax. --- .../ast/cpp/ICPPASTFunctionDeclarator.java | 27 ++++--- .../parser/AbstractGNUSourceCodeParser.java | 10 ++- .../core/dom/parser/DeclarationOptions.java | 6 +- .../core/dom/parser/c/GNUCSourceParser.java | 20 +++--- .../parser/cpp/CPPASTFunctionDeclarator.java | 26 ++++++- .../dom/parser/cpp/GNUCPPSourceParser.java | 72 +++++++++---------- .../parser/cpp/semantics/CPPSemantics.java | 8 +-- .../dom/parser/cpp/semantics/CPPVisitor.java | 65 ++++++++++------- .../core/pdom/dom/cpp/PDOMClassUtil.java | 15 +++- 9 files changed, 151 insertions(+), 98 deletions(-) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTFunctionDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTFunctionDeclarator.java index 8874b708494..2cc6b8828f5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTFunctionDeclarator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTFunctionDeclarator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2009 IBM Corporation and others. + * Copyright (c) 2004, 2010 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,13 +29,12 @@ public interface ICPPASTFunctionDeclarator extends IASTStandardFunctionDeclarato */ public static final IASTTypeId[] NO_EXCEPTION_SPECIFICATION = {}; - /** - * EXCEPTION_TYPEID represents the type IDs throws in the - * exception specification. - */ public static final ASTNodeProperty EXCEPTION_TYPEID = new ASTNodeProperty( - "ICPPASTFunctionDeclarator.EXCEPTION_TYPEID - TypeId throws in the exception specification"); //$NON-NLS-1$ - + "ICPPASTFunctionDeclarator.EXCEPTION_TYPEID [IASTTypeId]"); //$NON-NLS-1$ + /** @since 5.2*/ + public static final ASTNodeProperty TRAILING_RETURN_TYPE = new ASTNodeProperty( + "ICPPASTFunctionDeclarator.TRAILING_RETURN_TYPE [IASTTypeId]"); //$NON-NLS-1$ + /** * Is this a const method? */ @@ -89,7 +88,19 @@ public interface ICPPASTFunctionDeclarator extends IASTStandardFunctionDeclarato * @since 5.1 */ public void setEmptyExceptionSpecification(); - + + /** + * Returns the trailing return type as in auto f() -> int , or null. + * @since 5.2 + */ + public IASTTypeId getTrailingReturnType(); + + /** + * Trailing return type as in auto f() -> int . + * @since 5.2 + */ + public void setTrailingReturnType(IASTTypeId typeId); + /** * Get function scope this node represents. Returns null, if this declarator does not * declare a function-prototype or function-definition. 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 7cbcdf1933f..6a3767650c5 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 @@ -35,6 +35,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement; import org.eclipse.cdt.core.dom.ast.IASTDoStatement; import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpressionList; import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement; @@ -66,7 +67,6 @@ import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; 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.gnu.IGNUASTCompoundStatementExpression; import org.eclipse.cdt.core.dom.parser.IBuiltinBindingsProvider; import org.eclipse.cdt.core.dom.parser.ISourceCodeParser; @@ -1121,7 +1121,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { protected abstract IASTExpression constantExpression() throws BacktrackException, EndOfFileException; protected abstract IASTExpression unaryExpression(CastExprCtx ctx) throws BacktrackException, EndOfFileException; protected abstract IASTExpression primaryExpression(CastExprCtx ctx) throws BacktrackException, EndOfFileException; - protected abstract IASTTypeId typeId(DeclarationOptions option) throws EndOfFileException; + protected abstract IASTTypeId typeId(DeclarationOptions option) throws EndOfFileException, BacktrackException; private final static class CastAmbiguityMarker extends ASTNode implements IASTExpression { private IASTExpression fExpression; @@ -1169,7 +1169,11 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { final IToken mark= mark(); final int startingOffset= mark.getOffset(); consume(); - IASTTypeId typeId = typeId(DeclarationOptions.TYPEID); + IASTTypeId typeId= null; + try { + typeId= typeId(DeclarationOptions.TYPEID); + } catch (BacktrackException e) { + } if (typeId != null && LT(1) == IToken.tRPAREN) { consume(); boolean unaryFailed= false; 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 ac5294f63e8..31345c55536 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 @@ -26,6 +26,7 @@ public class DeclarationOptions { final public static int NO_NESTED= 0x200; final public static int ALLOW_PARAMETER_PACKS= 0x400; final public static int REQUIRE_SIMPLE_NAME= 0x800; + final public static int ALLOW_FOLLOWED_BY_BRACE= 0x1000; public static final DeclarationOptions GLOBAL= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER), @@ -35,7 +36,8 @@ public class DeclarationOptions { LOCAL= new DeclarationOptions(0), PARAMETER= new DeclarationOptions(ALLOW_ABSTRACT | ALLOW_PARAMETER_PACKS | REQUIRE_SIMPLE_NAME | NO_BRACED_INITIALIZER | NO_CTOR_STYLE_INITIALIZER), TYPEID= new DeclarationOptions(REQUIRE_ABSTRACT | NO_INITIALIZER), - TYPEID_NEW= new DeclarationOptions(REQUIRE_ABSTRACT | NO_INITIALIZER | NO_FUNCTIONS | NO_NESTED), + TYPEID_TRAILING_RETURN_TYPE= new DeclarationOptions(REQUIRE_ABSTRACT | NO_INITIALIZER | ALLOW_FOLLOWED_BY_BRACE), + TYPEID_NEW= new DeclarationOptions(REQUIRE_ABSTRACT | NO_INITIALIZER | NO_FUNCTIONS | NO_NESTED | ALLOW_FOLLOWED_BY_BRACE), TYPEID_CONVERSION= new DeclarationOptions(REQUIRE_ABSTRACT | NO_INITIALIZER | NO_FUNCTIONS | NO_NESTED), EXCEPTION= new DeclarationOptions(ALLOW_ABSTRACT | NO_INITIALIZER), CONDITION= new DeclarationOptions(NO_CTOR_STYLE_INITIALIZER), @@ -47,6 +49,7 @@ public class DeclarationOptions { final public boolean fAllowBitField; final public boolean fAllowInitializer; final public boolean fAllowBracedInitializer; + final public boolean fCanBeFollowedByBrace; final public boolean fAllowCtorStyleInitializer; final public boolean fAllowFunctions; final public boolean fAllowNested; @@ -65,5 +68,6 @@ public class DeclarationOptions { fAllowNested= (options & NO_NESTED) == 0; fAllowParameterPacks= (options & ALLOW_PARAMETER_PACKS) != 0; fRequireSimpleName= (options & REQUIRE_SIMPLE_NAME) != 0; + fCanBeFollowedByBrace= fAllowBracedInitializer || (options & ALLOW_FOLLOWED_BY_BRACE) != 0; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java index 47870d6824b..d7a750bc41b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java @@ -618,14 +618,12 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { try { int offset = consume().getOffset(); IASTTypeId t= typeId(DeclarationOptions.TYPEID); - if (t != null) { - consume(IToken.tRPAREN); - if (LT(1) == IToken.tLBRACE) { - IASTInitializer i = (IASTInitializerList) initClause(false); - firstExpression= nodeFactory.newTypeIdInitializerExpression(t, i); - setRange(firstExpression, offset, calculateEndOffset(i)); - break; - } + consume(IToken.tRPAREN); + if (LT(1) == IToken.tLBRACE) { + IASTInitializer i = (IASTInitializerList) initClause(false); + firstExpression= nodeFactory.newTypeIdInitializerExpression(t, i); + setRange(firstExpression, offset, calculateEndOffset(i)); + break; } } catch (BacktrackException bt) { } @@ -812,7 +810,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { @Override - protected IASTTypeId typeId(DeclarationOptions option) throws EndOfFileException { + protected IASTTypeId typeId(DeclarationOptions option) throws EndOfFileException, BacktrackException { if (!canBeTypeSpecifier()) { return null; } @@ -827,9 +825,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { declarator= decl.fDtor1; } catch (FoundAggregateInitializer lie) { // type-ids have not compound initializers - return null; - } catch (BacktrackException bt) { - return null; + throwBacktrack(lie.fDeclarator); } finally { fPreventKnrCheck--; } 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 15a5010521f..b78302e6c77 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2008 IBM Corporation and others. + * Copyright (c) 2004, 2010 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,6 +32,7 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS IASTAmbiguityParent { private ICPPASTParameterDeclaration[] parameters = null; private IASTTypeId[] typeIds = NO_EXCEPTION_SPECIFICATION; + private IASTTypeId trailingReturnType= null; private boolean varArgs; private boolean pureVirtual; @@ -60,7 +61,9 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS copy.addParameterDeclaration(param == null ? null : param.copy()); for(IASTTypeId typeId : getExceptionSpecification()) copy.addExceptionSpecificationTypeId(typeId == null ? null : typeId.copy()); - + if (trailingReturnType != null) { + copy.setTrailingReturnType(trailingReturnType.copy()); + } return copy; } @@ -126,7 +129,21 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS } } - public boolean isPureVirtual() { + + public IASTTypeId getTrailingReturnType() { + return trailingReturnType; + } + + public void setTrailingReturnType(IASTTypeId typeId) { + assertNotFrozen(); + trailingReturnType= typeId; + if (typeId != null) { + typeId.setParent(this); + typeId.setPropertyInParent(TRAILING_RETURN_TYPE); + } + } + + public boolean isPureVirtual() { return pureVirtual; } @@ -189,6 +206,9 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS if (!ids[i].accept(action)) return false; } + + if (trailingReturnType != null && !trailingReturnType.accept(action)) + return false; return super.postAccept(action); } 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 f31ee287c42..88f5df13c79 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 @@ -64,6 +64,7 @@ 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; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; 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; @@ -110,7 +111,6 @@ 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.cpp.IGPPASTPointer; import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointerToMember; @@ -542,9 +542,14 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { private IASTNode templateArgument(BinaryExprCtx exprCtx) throws EndOfFileException, BacktrackException { IToken argStart = mark(); - final ICPPASTTypeId typeId = typeId(DeclarationOptions.TYPEID); + ICPPASTTypeId typeId= null; + int lt1= 0; + try { + typeId= typeId(DeclarationOptions.TYPEID); + lt1 = LT(1); + } catch (BacktrackException e) { + } - 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)) { @@ -659,10 +664,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } // must be a conversion function - IToken t = LA(1); typeId= typeId(DeclarationOptions.TYPEID_CONVERSION); - if (typeId == null) - throwBacktrack(t); IASTName name = nodeFactory.newConversionName(typeId); setRange(name, firstToken.getOffset(), calculateEndOffset(typeId)); @@ -937,14 +939,10 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { isNewTypeId= false; consume(IToken.tLPAREN); typeid= typeId(DeclarationOptions.TYPEID); - if (typeid == null) - throw backtrack; endOffset= consumeOrEOC(IToken.tRPAREN).getEndOffset(); } else { // (P) T ... typeid= typeId(DeclarationOptions.TYPEID_NEW); - if (typeid == null) - throw backtrack; endOffset= calculateEndOffset(typeid); } end= LA(1); @@ -968,8 +966,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { int endOffset2; try { typeid2= typeId(DeclarationOptions.TYPEID); - if (typeid2 == null) - throw backtrack; endOffset2= consumeOrEOC(IToken.tRPAREN).getEndOffset(); lt1= LT(1); @@ -1009,10 +1005,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } // T ... - final IASTTypeId typeid = typeId(DeclarationOptions.TYPEID_NEW); - if (typeid == null) - throw backtrack; - + final IASTTypeId typeid = typeId(DeclarationOptions.TYPEID_NEW); int endOffset = calculateEndOffset(typeid); IASTInitializer init= null; final int lt1= LT(1); @@ -1161,14 +1154,12 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { try { int offset = consume().getOffset(); IASTTypeId t= typeId(DeclarationOptions.TYPEID); - if (t != null) { - consume(IToken.tRPAREN); - if (LT(1) == IToken.tLBRACE) { - IASTInitializer i = bracedInitList(false); - firstExpression= nodeFactory.newTypeIdInitializerExpression(t, i); - setRange(firstExpression, offset, calculateEndOffset(i)); - break; - } + consume(IToken.tRPAREN); + if (LT(1) == IToken.tLBRACE) { + IASTInitializer i = bracedInitList(false); + firstExpression= nodeFactory.newTypeIdInitializerExpression(t, i); + setRange(firstExpression, offset, calculateEndOffset(i)); + break; } } catch (BacktrackException bt) { } @@ -1430,8 +1421,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { final int optype= consume().getType(); consume(IToken.tLT); final IASTTypeId typeID = typeId(DeclarationOptions.TYPEID); - if (typeID == null) - throw backtrack; consumeOrEOC(IToken.tGT); consumeOrEOC(IToken.tLPAREN); IASTExpression operand= null; @@ -1693,8 +1682,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { throw backtrack; consume(); defaultValue = typeId(DeclarationOptions.TYPEID); // type-id - if (defaultValue == null) - throw backtrack; endOffset = calculateEndOffset(defaultValue); } } else { @@ -2199,7 +2186,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { if (supportAutoTypeSpecifier) { if (encounteredTypename) break declSpecifiers; - simpleType = ICPPASTSimpleDeclSpecifier.t_auto; + simpleType = IASTSimpleDeclSpecifier.t_auto; encounteredRawType= true; endOffset= consume().getEndOffset(); break; @@ -2596,7 +2583,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { return dtor1; case IToken.tLBRACE: - if (option.fAllowBracedInitializer || option == DeclarationOptions.TYPEID_NEW + if (option.fCanBeFollowedByBrace || ASTQueries.findTypeRelevantDeclarator(dtor1) instanceof IASTFunctionDeclarator) return dtor1; @@ -2611,6 +2598,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { //$FALL-THROUGH$ case IToken.t_throw: case IToken.t_try: case IToken.t_const: case IToken.t_volatile: + case IToken.tARROW: if (ASTQueries.findTypeRelevantDeclarator(dtor1) instanceof IASTFunctionDeclarator) { return dtor1; } else { @@ -2949,11 +2937,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } @Override - protected ICPPASTTypeId typeId(DeclarationOptions option) throws EndOfFileException { + protected ICPPASTTypeId typeId(DeclarationOptions option) throws EndOfFileException, BacktrackException { if (!canBeTypeSpecifier()) { - return null; + throwBacktrack(LA(1)); } - final int offset = mark().getOffset(); + final int offset = LA().getOffset(); IASTDeclSpecifier declSpecifier = null; IASTDeclarator declarator = null; @@ -2963,14 +2951,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { declarator= decl.fDtor1; } catch (FoundAggregateInitializer lie) { // type-ids have no initializers - return null; - } catch (BacktrackException bt) { - return null; + throwBacktrack(lie.fDeclarator); } ICPPASTTypeId result = nodeFactory.newTypeId(declSpecifier, declarator); setRange(result, offset, figureEndOffset(declSpecifier, declarator)); return result; - } /** @@ -3364,14 +3349,14 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { break; default: int thoffset = LA(1).getOffset(); - ICPPASTTypeId typeId = typeId(DeclarationOptions.TYPEID); - if (typeId != null) { + try { + ICPPASTTypeId typeId = typeId(DeclarationOptions.TYPEID); if (LT(1) == IToken.tELLIPSIS) { typeId.setIsPackExpansion(true); adjustEndOffset(typeId, consume().getEndOffset()); } fc.addExceptionSpecificationTypeId(typeId); - } else { + } catch (BacktrackException e) { int thendoffset = LA(1).getOffset(); if (thoffset == thendoffset) { thendoffset = consume().getEndOffset(); @@ -3388,6 +3373,13 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { // more __attribute__ after throws __attribute_decl_seq(supportAttributeSpecifiers, false); } + + if (LT(1) == IToken.tARROW) { + consume(); + IASTTypeId typeId= typeId(DeclarationOptions.TYPEID_TRAILING_RETURN_TYPE); + fc.setTrailingReturnType(typeId); + endOffset= calculateEndOffset(typeId); + } setRange(fc, startOffset, endOffset); return fc; 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 9458efa0d6c..da4c58662f1 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 @@ -41,6 +41,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTFieldReference; @@ -65,6 +66,7 @@ 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.Kind; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.IEnumeration; @@ -78,10 +80,9 @@ 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.IVariable; -import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; -import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; 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; @@ -140,7 +141,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective; import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.cdt.core.index.IIndexFileSet; @@ -361,7 +361,7 @@ public class CPPSemantics { } } } - if (cls instanceof ICPPDeferredClassInstance) { + if (cls instanceof ICPPUnknownBinding) { binding= new CPPUnknownConstructor(cls); } else { binding= CPPSemantics.resolveFunction(data, cls.getConstructors(), true); 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 72b1b07e1b3..a6d490161f5 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 @@ -31,6 +31,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTFieldReference; @@ -62,6 +63,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IBasicType; +import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.IEnumeration; @@ -76,11 +78,10 @@ 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.IVariable; -import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; -import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; 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; @@ -133,7 +134,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointer; import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointerToMember; import org.eclipse.cdt.core.index.IIndexBinding; @@ -165,7 +165,6 @@ 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; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument; @@ -1734,14 +1733,28 @@ public class CPPVisitor extends ASTQueries { return null; } - IType type = createType(declSpec); - type = createType(type, declarator); - - // C++ specification 8.3.4.3 and 8.5.1.4 IASTNode initClause= declarator.getInitializer(); if (initClause instanceof IASTEqualsInitializer) { initClause= ((IASTEqualsInitializer) initClause).getInitializerClause(); } + + if (declSpec instanceof ICPPASTSimpleDeclSpecifier && + ((ICPPASTSimpleDeclSpecifier) declSpec).getType() == IASTSimpleDeclSpecifier.t_auto) { + parent = parent.getParent(); + if (parent instanceof ICPPASTNewExpression) { + IASTInitializer initializer = ((ICPPASTNewExpression) parent).getInitializer(); + IASTInitializerClause[] arguments = ((ICPPASTConstructorInitializer) initializer).getArguments(); + if (arguments.length == 1) { + initClause = arguments[0]; + } + } + return createAutoType(initClause, declSpec, declarator); + } + + IType type = createType(declSpec); + type = createType(type, declarator); + + // C++ specification 8.3.4.3 and 8.5.1.4 if (initClause instanceof IASTInitializerList) { IType t= SemanticUtil.getNestedType(type, TDEF); if (t instanceof IArrayType) { @@ -1751,18 +1764,7 @@ public class CPPVisitor extends ASTQueries { } } } - if (declSpec instanceof ICPPASTSimpleDeclSpecifier && - ((ICPPASTSimpleDeclSpecifier) declSpec).getType() == ICPPASTSimpleDeclSpecifier.t_auto) { - parent = parent.getParent(); - if (parent instanceof ICPPASTNewExpression) { - IASTInitializer initializer = ((ICPPASTNewExpression) parent).getInitializer(); - IASTInitializerClause[] arguments = ((ICPPASTConstructorInitializer) initializer).getArguments(); - if (arguments.length == 1) { - initClause = arguments[0]; - } - } - type = createAutoType(initClause, declSpec, declarator); - } + if (type != null && isPackExpansion) { type= new CPPParameterPackType(type); } @@ -1771,6 +1773,10 @@ public class CPPVisitor extends ASTQueries { private static IType createAutoType(IASTNode initClause, IASTDeclSpecifier declSpec, IASTDeclarator declarator) { // C++0x: 7.1.6.4 + if (declarator instanceof ICPPASTFunctionDeclarator) { + return createAutoFunctionType(declSpec, (ICPPASTFunctionDeclarator) declarator); + } + IType type = AutoTypeResolver.AUTO_TYPE; ICPPClassTemplate initializer_list_template = null; if (initClause instanceof ICPPASTInitializerList) { @@ -1808,6 +1814,18 @@ public class CPPVisitor extends ASTQueries { return decorateType(type, declSpec, declarator); } + /** + * C++0x: [8.3.5-2] + */ + private static IType createAutoFunctionType(IASTDeclSpecifier declSpec, ICPPASTFunctionDeclarator declarator) { + IASTTypeId id= declarator.getTrailingReturnType(); + if (id == null) + return null; + IType t= createType(id.getAbstractDeclarator()); + t= qualifyType(t, declSpec); + return createType(t, declarator); + } + public static IType createType(IASTDeclSpecifier declSpec) { IType type = getBaseType(declSpec); if (type == null) { @@ -1831,7 +1849,7 @@ public class CPPVisitor extends ASTQueries { ICPPASTSimpleDeclSpecifier spec = (ICPPASTSimpleDeclSpecifier) declSpec; // Check for decltype(expr) type = getDeclType(spec); - if (type == null && spec.getType() != ICPPASTSimpleDeclSpecifier.t_auto) { + if (type == null && spec.getType() != IASTSimpleDeclSpecifier.t_auto) { type = new CPPBasicType(spec); } } @@ -1871,10 +1889,7 @@ public class CPPVisitor extends ASTQueries { } private static IType qualifyType(IType type, IASTDeclSpecifier declSpec) { - if (declSpec.isConst() || declSpec.isVolatile()) { - type = new CPPQualifierType(type, declSpec.isConst(), declSpec.isVolatile()); - } - return type; + return SemanticUtil.addQualifiers(type, declSpec.isConst(), declSpec.isVolatile()); } /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMClassUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMClassUtil.java index def69d443be..70f0f3d3cb7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMClassUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMClassUtil.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 QNX Software Systems and others. + * Copyright (c) 2007, 2010 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 @@ -16,10 +16,12 @@ import java.util.List; import org.eclipse.cdt.core.dom.IPDOMNode; import org.eclipse.cdt.core.dom.IPDOMVisitor; +import org.eclipse.cdt.core.dom.ast.DOMException; 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.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.core.runtime.CoreException; @@ -52,7 +54,16 @@ class PDOMClassUtil { if (node instanceof ICPPConstructor) { ICPPConstructor cons= (ICPPConstructor) node; if (IndexFilter.ALL_DECLARED_OR_IMPLICIT.acceptBinding(cons)) { - fConstructors.add(cons); + try { + if (cons instanceof ICPPTemplateInstance) { + ICPPClassType owner = cons.getClassOwner(); + if (owner == null || owner.equals(((ICPPTemplateInstance) cons).getSpecializedBinding().getOwner())) { + return false; + } + } + fConstructors.add(cons); + } catch (DOMException e) { + } } } return false;