From d89b672a9733d8fe40258958573673321519ef5e Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Fri, 17 Aug 2012 10:46:12 -0700 Subject: Bug 327300. Parsing support for noexcept operators and noexcept specifications in function declarators. --- .../core/parser/tests/ast2/AST2CPPSpecTest.java | 24 ++++++++++++- .../cdt/internal/core/model/ASTStringUtil.java | 3 ++ .../eclipse/cdt/core/dom/ast/ASTSignatureUtil.java | 7 ++-- .../cdt/core/dom/ast/IASTUnaryExpression.java | 10 ++++-- .../dom/ast/cpp/ICPPASTFunctionDeclarator.java | 37 +++++++++++++++++--- .../dom/parser/cpp/CPPASTFunctionDeclarator.java | 39 +++++++++++++++++++--- .../core/dom/parser/cpp/GNUCPPSourceParser.java | 38 +++++++++++++++++---- .../core/dom/parser/cpp/semantics/CPPVisitor.java | 3 +- .../core/dom/parser/cpp/semantics/EvalUnary.java | 6 ++++ .../dom/rewrite/astwriter/DeclaratorWriter.java | 20 ++++++++--- .../ModifiedASTDeclaratorWriter.java | 18 ++++++---- .../internal/core/parser/token/KeywordSets.java | 1 + .../tests/refactoring/utils/KeywordCaseTest.java | 7 ++-- 13 files changed, 175 insertions(+), 38 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java index ebce79f3774..ef4f48076d4 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2009 IBM Corporation and others. + * Copyright (c) 2005, 2012 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 @@ -8,6 +8,7 @@ * Contributors: * Devin Steffler (IBM Corporation) - initial API and implementation * Markus Schorn (Wind River Systems) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.core.parser.tests.ast2; @@ -859,6 +860,12 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest { parse(getAboveComment(), ParserLanguage.CPP, true, 0); } + // const char* strchr(const char* s, int c); + // bool b = noexcept (strchr("abc", 'b')); + public void test5_3_7() throws Exception { + parse(getAboveComment(), ParserLanguage.CPP, true, 0); + } + // struct A {}; // struct I1 : A {}; // struct I2 : A {}; @@ -6386,6 +6393,21 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest { parse(getAboveComment(), ParserLanguage.CPP, true, 0); } + // template + // void f(T p); + // + // template + // void g(T p) noexcept; + // + // template + // void fg(T a) noexcept (noexcept(f(a)) && noexcept(g(a))) { + // f(a); + // g(a); + // } + public void test15_4s1c() throws Exception { + parse(getAboveComment(), ParserLanguage.CPP, true, 0); + } + // struct B { // virtual void f() throw (int, double); // virtual void g(); diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ASTStringUtil.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ASTStringUtil.java index 06ecc55e5a2..b7d37b494cd 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ASTStringUtil.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ASTStringUtil.java @@ -945,6 +945,7 @@ public class ASTStringUtil { // need to add a space to the unary expression if it is a specific operator switch (expression.getOperator()) { case IASTUnaryExpression.op_sizeof: + case ICPPASTUnaryExpression.op_noexcept: case ICPPASTUnaryExpression.op_throw: case ICPPASTUnaryExpression.op_typeid: buffer.append(SPACE); @@ -986,6 +987,8 @@ public class ASTStringUtil { public static char[] getUnaryOperatorString(IASTUnaryExpression ue) { int op = ue.getOperator(); switch (op) { + case IASTUnaryExpression.op_noexcept: + return Keywords.cNOEXCEPT; case IASTUnaryExpression.op_throw: return Keywords.cTHROW; case IASTUnaryExpression.op_typeid: diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTSignatureUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTSignatureUtil.java index 7be75b33a5f..4754e8f09e8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTSignatureUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTSignatureUtil.java @@ -48,7 +48,6 @@ import org.eclipse.cdt.internal.core.model.ASTStringUtil; */ @Deprecated public class ASTSignatureUtil { - private static final String COMMA_SPACE = ", "; //$NON-NLS-1$ private static final String EMPTY_STRING = ""; //$NON-NLS-1$ private static final String SPACE = " "; //$NON-NLS-1$ @@ -1044,9 +1043,10 @@ public class ASTSignatureUtil { if (!postOperator && !primaryBracketed) buffer.append(getUnaryOperatorString(expression)); - // need to add a space to the unary expression if it is a specific operator + // Need to add a space to the unary expression if it is a specific operator switch (expression.getOperator()) { case IASTUnaryExpression.op_sizeof: + case ICPPASTUnaryExpression.op_noexcept: case ICPPASTUnaryExpression.op_throw: case ICPPASTUnaryExpression.op_typeid: buffer.append(SPACE); @@ -1117,6 +1117,9 @@ public class ASTSignatureUtil { if (ue instanceof ICPPASTUnaryExpression) { switch (op) { + case ICPPASTUnaryExpression.op_noexcept: + opString = Keywords.NOEXCEPT; + break; case ICPPASTUnaryExpression.op_throw: opString = Keywords.THROW; break; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTUnaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTUnaryExpression.java index b17b1667a35..919ac7a9814 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTUnaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTUnaryExpression.java @@ -106,17 +106,23 @@ public interface IASTUnaryExpression extends IASTExpression { public static final int op_typeof = 14; /** - * for gnu parsers, only. op_alignOf is used for __alignOf( unaryExpression ) type + * For gnu parsers, only. op_alignOf is used for __alignOf( unaryExpression ) type * expressions. */ public static final int op_alignOf = 15; /** - * For c++, only: 'sizeof...(parameterPack)' + * For c++, only: 'sizeof... ( parameterPack )' * @since 5.2 */ public static final int op_sizeofParameterPack = 16; + /** + * For c++, only: noexcept ( expression ) + * @since 5.5 + */ + public static final int op_noexcept = 17; + /** * op_last is made available for subclasses. * @deprecated all constants must be defined in this interface 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 8b35d5a0d46..d9f1542c734 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, 2011 IBM Corporation and others. + * Copyright (c) 2004, 2012 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 @@ -8,12 +8,15 @@ * Contributors: * IBM - Initial API and implementation * Markus Schorn (Wind River Systems) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.core.dom.ast.cpp; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTTypeId; +import org.eclipse.cdt.core.parser.Keywords; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLiteralExpression; /** * C++ adds a few things to function declarators. @@ -28,9 +31,19 @@ public interface ICPPASTFunctionDeclarator extends IASTStandardFunctionDeclarato */ public static final IASTTypeId[] NO_EXCEPTION_SPECIFICATION = {}; + /** + * Represents a 'noexcept' specification without an expression. + * @since 5.5 + */ + public static final ICPPASTLiteralExpression NOEXCEPT_DEFAULT = + new CPPASTLiteralExpression(ICPPASTLiteralExpression.lk_true, Keywords.cTRUE); + public static final ASTNodeProperty EXCEPTION_TYPEID = new ASTNodeProperty( "ICPPASTFunctionDeclarator.EXCEPTION_TYPEID [IASTTypeId]"); //$NON-NLS-1$ - /** @since 5.2*/ + /** @since 5.5 */ + public static final ASTNodeProperty NOEXCEPT_EXPRESSION = new ASTNodeProperty( + "ICPPASTFunctionDeclarator.NOEXCEPT_EXPRESSION [ICPPASTExpression]"); //$NON-NLS-1$ + /** @since 5.2 */ public static final ASTNodeProperty TRAILING_RETURN_TYPE = new ASTNodeProperty( "ICPPASTFunctionDeclarator.TRAILING_RETURN_TYPE [IASTTypeId]"); //$NON-NLS-1$ @@ -40,7 +53,7 @@ public interface ICPPASTFunctionDeclarator extends IASTStandardFunctionDeclarato public boolean isConst(); /** - * Set the method to be const or not. + * Sets the method to be const or not. */ public void setConst(boolean value); @@ -50,7 +63,7 @@ public interface ICPPASTFunctionDeclarator extends IASTStandardFunctionDeclarato public boolean isVolatile(); /** - * Set the method to be volatile or not. + * Sets the method to be volatile or not. */ public void setVolatile(boolean value); @@ -72,7 +85,7 @@ public interface ICPPASTFunctionDeclarator extends IASTStandardFunctionDeclarato public boolean isPureVirtual(); /** - * Set this method to be pure virtual. + * Sets this method to be pure virtual. */ public void setPureVirtual(boolean isPureVirtual); @@ -101,6 +114,20 @@ public interface ICPPASTFunctionDeclarator extends IASTStandardFunctionDeclarato */ public void setEmptyExceptionSpecification(); + /** + * Returns the noexcept expression, {@link #NOEXCEPT_DEFAULT} if the noexcept specification + * does not contain an expression, or {@code null} the noexcept specification is not present. + * See C++11 5.4.1. + * @since 5.5 + */ + public ICPPASTExpression getNoexceptExpression(); + + /** + * Sets the noexcept expression. + * @since 5.5 + */ + public void setNoexceptExpression(ICPPASTExpression expression); + /** * Returns the trailing return type as in auto f() -> int , or null. * @since 5.2 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 4e86529c2cc..649fdc88797 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, 2011 IBM Corporation and others. + * Copyright (c) 2004, 2012 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 @@ -8,6 +8,7 @@ * Contributors: * IBM - Initial API and implementation * Markus Schorn (Wind River Systems) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -17,6 +18,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTTypeId; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; 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; @@ -32,6 +34,7 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS IASTAmbiguityParent { private ICPPASTParameterDeclaration[] parameters; private IASTTypeId[] typeIds = NO_EXCEPTION_SPECIFICATION; + private ICPPASTExpression noexceptExpression; private IASTTypeId trailingReturnType; private boolean varArgs; @@ -64,10 +67,16 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS copy.isConst = isConst; copy.isMutable = isMutable; - for (IASTParameterDeclaration param : getParameters()) + for (IASTParameterDeclaration param : getParameters()) { copy.addParameterDeclaration(param == null ? null : param.copy(style)); - for (IASTTypeId typeId : getExceptionSpecification()) + } + for (IASTTypeId typeId : getExceptionSpecification()) { copy.addExceptionSpecificationTypeId(typeId == null ? null : typeId.copy(style)); + } + if (noexceptExpression != null) { + copy.setNoexceptExpression(noexceptExpression == NOEXCEPT_DEFAULT ? + noexceptExpression : (ICPPASTExpression) noexceptExpression.copy(style)); + } if (trailingReturnType != null) { copy.setTrailingReturnType(trailingReturnType.copy(style)); } @@ -160,8 +169,23 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS typeId.setPropertyInParent(EXCEPTION_TYPEID); } } - - @Override + + @Override + public ICPPASTExpression getNoexceptExpression() { + return noexceptExpression; + } + + @Override + public void setNoexceptExpression(ICPPASTExpression expression) { + assertNotFrozen(); + noexceptExpression = expression; + if (expression != null && expression != NOEXCEPT_DEFAULT) { + expression.setParent(this); + expression.setPropertyInParent(NOEXCEPT_EXPRESSION); + } + } + + @Override public IASTTypeId getTrailingReturnType() { return trailingReturnType; } @@ -244,6 +268,11 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS if (!ids[i].accept(action)) return false; } + + if (noexceptExpression != null && noexceptExpression != NOEXCEPT_DEFAULT) { + if (!noexceptExpression.accept(action)) + return false; + } if (trailingReturnType != null && !trailingReturnType.accept(action)) return false; 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 709e4fdc1ba..2c960038b66 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 @@ -80,6 +80,7 @@ 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.ICPPASTEnumerationSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; 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; @@ -176,9 +177,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { this(scanner, mode, log, config, null); } - public GNUCPPSourceParser(IScanner scanner, ParserMode mode, - IParserLogService log, ICPPParserExtensionConfiguration config, - IIndex index) { + public GNUCPPSourceParser(IScanner scanner, ParserMode mode, IParserLogService log, + ICPPParserExtensionConfiguration config, IIndex index) { super(scanner, log, mode, CPPNodeFactory.getDefault(), config.supportStatementsInExpressions(), config.supportTypeofUnaryExpressions(), @@ -1429,6 +1429,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { private IASTExpression postfixExpression(CastExprCtx ctx, ITemplateIdStrategy strat) throws EndOfFileException, BacktrackException { IASTExpression firstExpression = null; boolean isTemplate = false; + int offset; switch (LT(1)) { case IToken.t_dynamic_cast: @@ -1447,11 +1448,20 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { case IToken.t_typeid: // 'typeid' ( expression ) // 'typeid' ( type-id ) - int so = consume().getOffset(); - firstExpression = parseTypeidInParenthesisOrUnaryExpression(true, so, + firstExpression = parseTypeidInParenthesisOrUnaryExpression(true, consume().getOffset(), ICPPASTTypeIdExpression.op_typeid, ICPPASTUnaryExpression.op_typeid, ctx, strat); break; + case IToken.t_noexcept: + // 'noexcept' ( expression ) + offset= consume().getOffset(); // noexcept + consume(IToken.tLPAREN); // ( + firstExpression= expression(); + firstExpression= nodeFactory.newUnaryExpression(IASTUnaryExpression.op_noexcept, firstExpression); + final int endOffset = consume(IToken.tRPAREN).getEndOffset(); // ) + setRange(firstExpression, offset, endOffset); + break; + case IToken.tLPAREN: // Gnu-extension: compound literals in c++ // ( type-name ) { initializer-list } @@ -1459,7 +1469,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { IToken m = mark(); try { if (canBeCompoundLiteral()) { - int offset = consume().getOffset(); + offset = consume().getOffset(); IASTTypeId t= typeId(DeclarationOptions.TYPEID); consume(IToken.tRPAREN); if (LT(1) == IToken.tLBRACE) { @@ -3931,7 +3941,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { if (thoffset == thendoffset) { thendoffset = consume().getEndOffset(); } - IASTProblem p = createProblem(IProblem.SYNTAX_ERROR, thoffset, thendoffset-thoffset); + IASTProblem p = createProblem(IProblem.SYNTAX_ERROR, thoffset, thendoffset - thoffset); IASTProblemTypeId typeIdProblem = nodeFactory.newProblemTypeId(p); ((ASTNode) typeIdProblem).setOffsetAndLength(((ASTNode) p)); fc.addExceptionSpecificationTypeId(typeIdProblem); @@ -3945,6 +3955,20 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { __attribute_decl_seq(supportAttributeSpecifiers, false)); } + // noexcept specification + if (LT(1) == IToken.t_noexcept) { + consume(); // noexcept + IASTExpression expression; + if (LT(1) == IToken.tLPAREN) { + consume(); // ( + expression = expression(); + endOffset = consume(IToken.tRPAREN).getEndOffset(); // ) + } else { + expression = ICPPASTFunctionDeclarator.NOEXCEPT_DEFAULT; + } + fc.setNoexceptExpression((ICPPASTExpression) expression); + } + if (LT(1) == IToken.tARROW) { consume(); IASTTypeId typeId= typeId(DeclarationOptions.TYPEID_TRAILING_RETURN_TYPE); 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 4ea01916b56..330b4c9d173 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 @@ -1001,7 +1001,8 @@ public class CPPVisitor extends ASTQueries { return result; } - } else if (node instanceof IASTParameterDeclaration) { + } else if (node instanceof IASTParameterDeclaration || + node.getPropertyInParent() == ICPPASTFunctionDeclarator.NOEXCEPT_EXPRESSION) { IASTNode parent = node.getParent(); if (parent instanceof ICPPASTFunctionDeclarator) { IScope result = scopeViaFunctionDtor((ICPPASTFunctionDeclarator) parent); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java index cde19a8c8d8..7a74dc34041 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java @@ -16,6 +16,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_alignOf; import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_amper; import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_minus; +import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_noexcept; import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_not; import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_plus; import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_postFixDecr; @@ -116,6 +117,8 @@ public class EvalUnary extends CPPEvaluation { case op_sizeofParameterPack: case op_typeid: return fArgument.isTypeDependent(); + case op_noexcept: + return fArgument.referencesTemplateParameter(); case op_throw: return false; default: @@ -187,6 +190,7 @@ public class EvalUnary extends CPPEvaluation { return type; } return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); + case op_noexcept: case op_not: return CPPBasicType.BOOLEAN; case op_postFixDecr: @@ -222,6 +226,8 @@ public class EvalUnary extends CPPEvaluation { SizeAndAlignment info = getSizeAndAlignment(fArgument.getTypeOrFunctionSet(point), point); return info == null ? Value.UNKNOWN : Value.create(info.alignment); } + case op_noexcept: + return Value.UNKNOWN; // TODO(sprigogin): Implement case op_sizeofParameterPack: return Value.UNKNOWN; // TODO(sprigogin): Implement case op_typeid: diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclaratorWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclaratorWriter.java index bf7a28e139c..37ed8922ed2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclaratorWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclaratorWriter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2010 Institute for Software, HSR Hochschule fuer Technik + * Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik * Rapperswil, University of applied sciences and others * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -26,6 +26,7 @@ import org.eclipse.cdt.core.dom.ast.IASTPointer; import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTTypeId; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator; @@ -142,7 +143,7 @@ public class DeclaratorWriter extends NodeWriter { if (funcDec.isPureVirtual()) { scribe.print(PURE_VIRTUAL); } - writeExceptionSpecification(funcDec, funcDec.getExceptionSpecification()); + writeExceptionSpecification(funcDec, funcDec.getExceptionSpecification(), funcDec.getNoexceptExpression()); if (funcDec.getTrailingReturnType() != null) { scribe.printSpace(); scribe.print(ARROW_OPERATOR); @@ -151,7 +152,8 @@ public class DeclaratorWriter extends NodeWriter { } } - protected void writeExceptionSpecification(ICPPASTFunctionDeclarator funcDec, IASTTypeId[] exceptions) { + protected void writeExceptionSpecification(ICPPASTFunctionDeclarator funcDec, IASTTypeId[] exceptions, + ICPPASTExpression noexceptExpression) { if (exceptions != ICPPASTFunctionDeclarator.NO_EXCEPTION_SPECIFICATION) { scribe.printSpace(); scribe.printStringSpace(Keywords.THROW); @@ -159,6 +161,16 @@ public class DeclaratorWriter extends NodeWriter { writeNodeList(exceptions); scribe.print(')'); } + if (noexceptExpression != null) { + scribe.printSpace(); + scribe.print(Keywords.NOEXCEPT); + if (noexceptExpression != ICPPASTFunctionDeclarator.NOEXCEPT_DEFAULT) { + scribe.printSpace(); + scribe.print('('); + noexceptExpression.accept(visitor); + scribe.print(')'); + } + } } protected void writeParameterDeclarations(IASTStandardFunctionDeclarator funcDec, IASTParameterDeclaration[] paramDecls) { @@ -266,7 +278,7 @@ public class DeclaratorWriter extends NodeWriter { protected void writeKnRParameterDeclarations(ICASTKnRFunctionDeclarator knrFunct, IASTDeclaration[] knrDeclarations) { - for (int i = 0; i < knrDeclarations.length; ++i) { + for (int i = 0; i < knrDeclarations.length; ++i) { scribe.noNewLines(); knrDeclarations[i].accept(visitor); scribe.newLines(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclaratorWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclaratorWriter.java index b5d416a7721..88d8869e8f3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclaratorWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModifiedASTDeclaratorWriter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2011 Institute for Software, HSR Hochschule fuer Technik + * Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik * Rapperswil, University of applied sciences and others * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -9,6 +9,7 @@ * Contributors: * Institute for Software - initial API and implementation * Markus Schorn (Wind River Systems) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.rewrite.changegenerator; @@ -22,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTTypeId; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ASTWriterVisitor; @@ -62,19 +64,21 @@ public class ModifiedASTDeclaratorWriter extends DeclaratorWriter { @Override protected void writeExceptionSpecification(ICPPASTFunctionDeclarator funcDec, - IASTTypeId[] exceptions) { + IASTTypeId[] exceptions, ICPPASTExpression noexceptExpression) { IASTTypeId[] modifiedExceptions = modificationHelper.createModifiedChildArray(funcDec, exceptions, IASTTypeId.class, commentMap); - // it makes a difference whether the exception array is identical to - // ICPPASTFunctionDeclarator.NO_EXCEPTION_SPECIFICATION + // It makes a difference whether the exception array is identical to + // ICPPASTFunctionDeclarator.NO_EXCEPTION_SPECIFICATION or not. if (modifiedExceptions.length == 0 && exceptions == ICPPASTFunctionDeclarator.NO_EXCEPTION_SPECIFICATION) { modifiedExceptions= ICPPASTFunctionDeclarator.NO_EXCEPTION_SPECIFICATION; } - - super.writeExceptionSpecification(funcDec, modifiedExceptions); + + noexceptExpression = modificationHelper.getNodeAfterReplacement(noexceptExpression); + + super.writeExceptionSpecification(funcDec, modifiedExceptions, noexceptExpression); } - + @Override protected void writeKnRParameterDeclarations(ICASTKnRFunctionDeclarator knrFunct, IASTDeclaration[] knrDeclarations) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/KeywordSets.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/KeywordSets.java index 2328b67a60d..3d3915eae69 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/KeywordSets.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/KeywordSets.java @@ -189,6 +189,7 @@ public class KeywordSets { EXPRESSION_CPP.add(Keywords.REINTERPRET_CAST); EXPRESSION_CPP.add(Keywords.CONST_CAST); EXPRESSION_CPP.add(Keywords.TYPEID); + EXPRESSION_CPP.add(Keywords.NOEXCEPT); EXPRESSION_CPP.add(Keywords.TRUE); EXPRESSION_CPP.add(Keywords.FALSE); EXPRESSION_CPP.add(Keywords.THIS); diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/KeywordCaseTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/KeywordCaseTest.java index 8cfd6feea5c..20ec7501b0c 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/KeywordCaseTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/KeywordCaseTest.java @@ -7,7 +7,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Institute for Software - initial API and implementation + * Institute for Software - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.ui.tests.refactoring.utils; @@ -18,7 +18,6 @@ import org.eclipse.cdt.internal.ui.refactoring.utils.IdentifierResult; /** * @author Thomas Corbat - * */ public class KeywordCaseTest extends TestCase { @@ -122,6 +121,8 @@ public class KeywordCaseTest extends TestCase { assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); result = IdentifierHelper.checkIdentifierName("typeid"); //$NON-NLS-1$ assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); + result = IdentifierHelper.checkIdentifierName("noexcept"); //$NON-NLS-1$ + assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); result = IdentifierHelper.checkIdentifierName("inline"); //$NON-NLS-1$ assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); result = IdentifierHelper.checkIdentifierName("compl"); //$NON-NLS-1$ @@ -158,7 +159,5 @@ public class KeywordCaseTest extends TestCase { assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); result = IdentifierHelper.checkIdentifierName("public"); //$NON-NLS-1$ assertTrue(result.getMessage(), IdentifierResult.KEYWORD == result.getResult()); - } - } -- cgit v1.2.3