From bed21120a477088a880d38cab4d8aac41437d103 Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Fri, 18 Apr 2014 16:27:13 -0700 Subject: [PATCH] Code streamlining. --- .../core/dom/parser/cpp/CPPBasicType.java | 1 + .../core/dom/parser/cpp/CPPClassScope.java | 187 ++---------------- .../core/dom/parser/cpp/CPPClosureType.java | 7 +- .../parser/cpp/CPPImplicitConstructor.java | 11 +- .../dom/parser/cpp/ImplicitsAnalysis.java | 152 ++++++++++++++ .../dom/parser/cpp/semantics/CPPVisitor.java | 3 +- 6 files changed, 174 insertions(+), 187 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ImplicitsAnalysis.java diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBasicType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBasicType.java index d9fc9e1a99a..b448baf4c3c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBasicType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBasicType.java @@ -34,6 +34,7 @@ public class CPPBasicType implements ICPPBasicType, ISerializableType { private static final int FROM_STRING_LITERAL = 1 << 31; public static final CPPBasicType BOOLEAN = new CPPBasicType(Kind.eBoolean, 0, null); public static final CPPBasicType NULL_PTR = new CPPBasicType(Kind.eNullPtr, 0, null); + public static final CPPBasicType UNSPECIFIED_TYPE = new CPPBasicType(Kind.eUnspecified, 0); private final Kind fKind; private final int fModifiers; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java index ac9e42786ef..395c38ddb2d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2011 IBM Corporation and others. + * Copyright (c) 2004, 2014 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,36 +16,23 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import static org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter.EMPTY_CPPPARAMETER_ARRAY; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; - -import java.util.ArrayList; -import java.util.List; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType.UNSPECIFIED_TYPE; import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.ast.EScopeKind; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; -import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFieldReference; -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.IASTParameterDeclaration; -import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier; -import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTTypeId; -import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; 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.ICPPASTNameSpecifier; 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.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; @@ -55,13 +42,11 @@ 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.ICPPReferenceType; import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.ObjectSet; -import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; @@ -71,7 +56,10 @@ import org.eclipse.cdt.internal.core.parser.util.ContentAssistMatcherFactory; * Base implementation for c++ scopes. */ public class CPPClassScope extends CPPScope implements ICPPClassScope { - private ICPPMethod[] implicits; + private static final ICPPFunctionType DESTRUCTOR_FUNCTION_TYPE = + CPPVisitor.createImplicitFunctionType(UNSPECIFIED_TYPE, EMPTY_CPPPARAMETER_ARRAY, false, false); + + private ICPPMethod[] implicits; public CPPClassScope(ICPPASTCompositeTypeSpecifier physicalNode) { super(physicalNode); @@ -83,13 +71,13 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { } /** - * Add in default constructor, copy constructor, copy assignment operator and destructor, + * Adds in default constructor, copy constructor, copy assignment operator and destructor, * if appropriate. * Method will be called after ambiguity resolution. */ public void createImplicitMembers() { - //create bindings for the implicit members, if the user declared them then those declarations - //will resolve to these bindings. + // Create bindings for the implicit members, if the user declared them then those + // declarations will resolve to these bindings. ICPPASTCompositeTypeSpecifier compTypeSpec = (ICPPASTCompositeTypeSpecifier) getPhysicalNode(); IASTName name = compTypeSpec.getName().getLastName(); @@ -135,9 +123,8 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { if (!ia.hasUserDeclaredDestructor()) { // Destructor: ~A() - ICPPFunctionType ft= CPPVisitor.createImplicitFunctionType(new CPPBasicType(Kind.eUnspecified, 0), EMPTY_CPPPARAMETER_ARRAY, false, false); char[] dtorName = CharArrayUtils.concat("~".toCharArray(), className); //$NON-NLS-1$ - ICPPMethod m = new CPPImplicitMethod(this, dtorName, ft, EMPTY_CPPPARAMETER_ARRAY); + ICPPMethod m = new CPPImplicitMethod(this, dtorName, DESTRUCTOR_FUNCTION_TYPE, EMPTY_CPPPARAMETER_ARRAY); implicits[i++] = m; addBinding(m); } @@ -329,7 +316,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { } if (CharArrayUtils.equals(compName.getLookupKey(), n)) { - return new IBinding[] {compName.resolveBinding()}; + return new IBinding[] { compName.resolveBinding() }; } return super.find(name); @@ -389,156 +376,4 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { } return null; } -} - -/** - * Helps analysis of the class declaration for user declared members relevant - * to deciding which implicit bindings to declare. - * - * @see chapter 12 of the ISO specification - */ -class ImplicitsAnalysis { - private final boolean hasUserDeclaredConstructor; - private boolean hasUserDeclaredCopyConstructor; - private boolean hasUserDeclaredCopyAssignmentOperator; - private final boolean hasUserDeclaredDestructor; - private final ICPPClassType classType; - - ImplicitsAnalysis(ICPPASTCompositeTypeSpecifier compSpec, ICPPClassType clsType) { - classType= clsType; - - ICPPASTFunctionDeclarator[] ctors= getUserDeclaredCtorOrDtor(compSpec, true); - hasUserDeclaredConstructor= ctors.length> 0; - hasUserDeclaredCopyConstructor= false; - hasUserDeclaredCopyAssignmentOperator= false; - hasUserDeclaredDestructor= getUserDeclaredCtorOrDtor(compSpec, false).length>0; - - outer: for (int i= 0; i < ctors.length; i++) { - ICPPASTFunctionDeclarator dcltor= ctors[i]; - IASTParameterDeclaration[] ps = dcltor.getParameters(); - if (ps.length >= 1) { - if (hasTypeReferenceToClassType(ps[0])) { - // All remaining arguments have initializers. - for (int j = 1; j < ps.length; j++) { - if (ps[j].getDeclarator().getInitializer() == null) { - continue outer; - } - } - hasUserDeclaredCopyConstructor= true; - } - } - } - - boolean hasUserDeclaredCAO= getUserDeclaredCopyAssignmentOperators(compSpec).length > 0; - hasUserDeclaredCopyAssignmentOperator= hasUserDeclaredCAO; - } - - public int getImplicitsToDeclareCount() { - return (!hasUserDeclaredDestructor ? 1 : 0) - + (!hasUserDeclaredConstructor ? 1 : 0) - + (!hasUserDeclaredCopyConstructor ? 1 : 0) - + (!hasUserDeclaredCopyAssignmentOperator ? 1 : 0); - } - - private ICPPASTFunctionDeclarator[] getUserDeclaredCtorOrDtor(ICPPASTCompositeTypeSpecifier compSpec, boolean constructor) { - List result= new ArrayList(); - IASTDeclaration[] members = compSpec.getMembers(); - char[] name = compSpec.getName().getLookupKey(); - IASTDeclarator dcltor = null; - IASTDeclSpecifier spec = null; - for (IASTDeclaration member : members) { - if (member instanceof IASTSimpleDeclaration) { - IASTDeclarator[] dtors = ((IASTSimpleDeclaration)member).getDeclarators(); - if (dtors.length == 0 || dtors.length > 1) - continue; - dcltor = dtors[0]; - spec = ((IASTSimpleDeclaration)member).getDeclSpecifier(); - } else if (member instanceof IASTFunctionDefinition) { - dcltor = ((IASTFunctionDefinition)member).getDeclarator(); - spec = ((IASTFunctionDefinition)member).getDeclSpecifier(); - } - - if (!(dcltor instanceof ICPPASTFunctionDeclarator) || !(spec instanceof IASTSimpleDeclSpecifier) || - ((IASTSimpleDeclSpecifier)spec).getType() != IASTSimpleDeclSpecifier.t_unspecified) { - continue; - } - - boolean nameEquals= false; - char[] dtorname= ASTQueries.findInnermostDeclarator(dcltor).getName().getLookupKey(); - if (constructor) { - nameEquals= CharArrayUtils.equals(dtorname, name); - } else { - if (dtorname.length > 0 && dtorname[0] == '~') { - nameEquals= CharArrayUtils.equals(dtorname, 1, name.length, name); - } - } - - if (!nameEquals) - continue; - - result.add((ICPPASTFunctionDeclarator) dcltor); - } - return result.toArray(new ICPPASTFunctionDeclarator[result.size()]); - } - - private ICPPASTFunctionDeclarator[] getUserDeclaredCopyAssignmentOperators(ICPPASTCompositeTypeSpecifier compSpec) { - List result= new ArrayList(); - IASTDeclaration[] members = compSpec.getMembers(); - IASTDeclarator dcltor = null; - for (IASTDeclaration member : members) { - if (member instanceof IASTSimpleDeclaration) { - IASTDeclarator[] dtors = ((IASTSimpleDeclaration)member).getDeclarators(); - if (dtors.length == 0 || dtors.length > 1) - continue; - dcltor = dtors[0]; - } else if (member instanceof IASTFunctionDefinition) { - dcltor = ((IASTFunctionDefinition)member).getDeclarator(); - } - if (!(dcltor instanceof ICPPASTFunctionDeclarator)) - continue; - - final char[] nchars= ASTQueries.findInnermostDeclarator(dcltor).getName().getLookupKey(); - if (!CharArrayUtils.equals(nchars, OverloadableOperator.ASSIGN.toCharArray())) - continue; - - IASTParameterDeclaration[] ps = ((ICPPASTFunctionDeclarator)dcltor).getParameters(); - if (ps.length != 1 || !hasTypeReferenceToClassType(ps[0])) - continue; - - result.add((ICPPASTFunctionDeclarator)dcltor); - } - return result.toArray(new ICPPASTFunctionDeclarator[result.size()]); - } - - private boolean hasTypeReferenceToClassType(IASTParameterDeclaration dec) { - if (dec instanceof ICPPASTParameterDeclaration) { - IType t= CPPVisitor.createType((ICPPASTParameterDeclaration) dec, false); - if (t != null) { - t= SemanticUtil.getNestedType(t, TDEF); - if (t instanceof ICPPReferenceType) { - if (!((ICPPReferenceType) t).isRValueReference()) { - t= SemanticUtil.getNestedType(t, TDEF|REF|CVTYPE); - return classType.isSameType(t); - } - } - } - } - return false; - } - - public boolean hasUserDeclaredConstructor() { - return hasUserDeclaredConstructor; - } - - public boolean hasUserDeclaredCopyConstructor() { - return hasUserDeclaredCopyConstructor; - } - - public boolean hasUserDeclaredCopyAssignmentOperator() { - return hasUserDeclaredCopyAssignmentOperator; - } - - public boolean hasUserDeclaredDestructor() { - return hasUserDeclaredDestructor; - } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java index a3d3cca204c..01f86a3ef0a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java @@ -13,6 +13,8 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType.UNSPECIFIED_TYPE; + import java.util.ArrayList; import java.util.List; @@ -26,7 +28,6 @@ import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTReturnStatement; import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTTypeId; -import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IScope; @@ -60,8 +61,6 @@ import org.eclipse.core.runtime.PlatformObject; * Binding for a class type. */ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICPPInternalBinding { - private static final CPPBasicType NO_RETURN_TYPE = new CPPBasicType(Kind.eUnspecified, 0); - private final ICPPASTLambdaExpression fLambdaExpression; private ICPPMethod[] fMethods; private ClassScope fScope; @@ -96,7 +95,7 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP result[2]= m; // Destructor: ~A() - ft= CPPVisitor.createImplicitFunctionType(NO_RETURN_TYPE, ICPPParameter.EMPTY_CPPPARAMETER_ARRAY, false, false); + ft= CPPVisitor.createImplicitFunctionType(UNSPECIFIED_TYPE, ICPPParameter.EMPTY_CPPPARAMETER_ARRAY, false, false); m = new CPPImplicitMethod(scope, new char[] {'~'}, ft, ICPPParameter.EMPTY_CPPPARAMETER_ARRAY); result[3]= m; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitConstructor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitConstructor.java index 1385172e8b7..1e6d2007f16 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitConstructor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitConstructor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2010 IBM Corporation and others. + * Copyright (c) 2004, 2014 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 @@ -11,9 +11,9 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; -import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType.UNSPECIFIED_TYPE; + import org.eclipse.cdt.core.dom.ast.IParameter; -import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; @@ -25,12 +25,11 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; */ public class CPPImplicitConstructor extends CPPImplicitMethod implements ICPPConstructor { - public CPPImplicitConstructor(ICPPClassScope scope, char[] name, ICPPParameter[] params) { + public CPPImplicitConstructor(ICPPClassScope scope, char[] name, ICPPParameter[] params) { super(scope, name, createFunctionType(scope, params), params); } private static ICPPFunctionType createFunctionType(ICPPClassScope scope, IParameter[] params) { - IType returnType= new CPPBasicType(Kind.eUnspecified, 0); - return CPPVisitor.createImplicitFunctionType(returnType, params, false, false); + return CPPVisitor.createImplicitFunctionType(UNSPECIFIED_TYPE, params, false, false); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ImplicitsAnalysis.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ImplicitsAnalysis.java new file mode 100644 index 00000000000..7e09ae75f6d --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ImplicitsAnalysis.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright (c) 2007, 2014 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: + * Andrew Ferguson (Symbian) - initial API and implementation + * Markus Schorn (Wind River Systems) + * Sergey Prigogin (Google) + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; + +import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; +import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +import org.eclipse.cdt.core.dom.ast.IType; +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.ICPPASTParameterDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; +import org.eclipse.cdt.core.parser.util.CharArrayUtils; +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; + +/** + * Helps analysis of the class declaration for user declared members relevant + * to deciding which implicit bindings to declare. + * + * @see chapter 12 of the ISO specification + */ +class ImplicitsAnalysis { + private boolean hasUserDeclaredConstructor; + private boolean hasUserDeclaredCopyConstructor; + private boolean hasUserDeclaredCopyAssignmentOperator; + private boolean hasUserDeclaredDestructor; + private final ICPPClassType classType; + + ImplicitsAnalysis(ICPPASTCompositeTypeSpecifier compositeTypeSpecifier, ICPPClassType classType) { + this.classType= classType; + analyzeMembers(compositeTypeSpecifier); + } + + public boolean hasUserDeclaredConstructor() { + return hasUserDeclaredConstructor; + } + + public boolean hasUserDeclaredCopyConstructor() { + return hasUserDeclaredCopyConstructor; + } + + public boolean hasUserDeclaredCopyAssignmentOperator() { + return hasUserDeclaredCopyAssignmentOperator; + } + + public boolean hasUserDeclaredDestructor() { + return hasUserDeclaredDestructor; + } + + public int getImplicitsToDeclareCount() { + return (!hasUserDeclaredDestructor ? 1 : 0) + + (!hasUserDeclaredConstructor ? 1 : 0) + + (!hasUserDeclaredCopyConstructor ? 1 : 0) + + (!hasUserDeclaredCopyAssignmentOperator ? 1 : 0); + } + + private void analyzeMembers(ICPPASTCompositeTypeSpecifier compositeTypeSpecifier) { + IASTDeclaration[] members = compositeTypeSpecifier.getMembers(); + char[] name = compositeTypeSpecifier.getName().getLookupKey(); + for (IASTDeclaration member : members) { + IASTDeclarator dcltor = null; + IASTDeclSpecifier spec = null; + if (member instanceof IASTSimpleDeclaration) { + IASTDeclarator[] dtors = ((IASTSimpleDeclaration) member).getDeclarators(); + if (dtors.length == 0 || dtors.length > 1) + continue; + dcltor = dtors[0]; + spec = ((IASTSimpleDeclaration) member).getDeclSpecifier(); + } else if (member instanceof IASTFunctionDefinition) { + dcltor = ((IASTFunctionDefinition) member).getDeclarator(); + spec = ((IASTFunctionDefinition) member).getDeclSpecifier(); + } + + if (!(dcltor instanceof ICPPASTFunctionDeclarator)) + continue; + + char[] declName= ASTQueries.findInnermostDeclarator(dcltor).getName().getLookupKey(); + + if (spec instanceof IASTSimpleDeclSpecifier && + ((IASTSimpleDeclSpecifier) spec).getType() == IASTSimpleDeclSpecifier.t_unspecified) { + if (CharArrayUtils.equals(declName, name)) { + hasUserDeclaredConstructor = true; + IASTParameterDeclaration[] ps = ((ICPPASTFunctionDeclarator) dcltor).getParameters(); + if (ps.length >= 1) { + if (hasTypeReferenceToClassType(ps[0]) && parametersHaveInitializers(ps, 1)) { + hasUserDeclaredCopyConstructor= true; + } + } + } if (declName.length > 0 && declName[0] == '~' && + CharArrayUtils.equals(declName, 1, name.length, name)) { + hasUserDeclaredDestructor = true; + } + } if (CharArrayUtils.equals(declName, OverloadableOperator.ASSIGN.toCharArray())) { + IASTParameterDeclaration[] ps = ((ICPPASTFunctionDeclarator) dcltor).getParameters(); + if (ps.length == 1 && hasTypeReferenceToClassType(ps[0])) + hasUserDeclaredCopyAssignmentOperator = true; + } + + if (hasUserDeclaredCopyConstructor && hasUserDeclaredDestructor && hasUserDeclaredCopyAssignmentOperator) + break; + } + } + + private boolean hasTypeReferenceToClassType(IASTParameterDeclaration dec) { + if (dec instanceof ICPPASTParameterDeclaration) { + IType t= CPPVisitor.createType((ICPPASTParameterDeclaration) dec, false); + if (t != null) { + t= SemanticUtil.getNestedType(t, TDEF); + if (t instanceof ICPPReferenceType) { + if (!((ICPPReferenceType) t).isRValueReference()) { + t= SemanticUtil.getNestedType(t, TDEF|REF|CVTYPE); + return classType.isSameType(t); + } + } + } + } + return false; + } + + /** + * Checks whether all parameters starting at offset have initializers. + */ + private boolean parametersHaveInitializers(IASTParameterDeclaration[] params, int offset) { + for (int i = offset; i < params.length; i++) { + if (params[i].getDeclarator().getInitializer() == null) { + return false; + } + } + return true; + } +} \ No newline at end of file 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 ff07f68b304..d53de7db449 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 @@ -1760,7 +1760,8 @@ public class CPPVisitor extends ASTQueries { * Generate a function type for an implicit function. * NOTE: This does not correctly handle parameters with typedef types. */ - public static ICPPFunctionType createImplicitFunctionType(IType returnType, IParameter[] parameters, boolean isConst, boolean isVolatile) { + public static ICPPFunctionType createImplicitFunctionType(IType returnType, IParameter[] parameters, + boolean isConst, boolean isVolatile) { IType[] pTypes = new IType[parameters.length]; IType pt = null;