mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 01:15:29 +02:00
Code streamlining.
This commit is contained in:
parent
bbc8a48c8c
commit
bed21120a4
6 changed files with 174 additions and 187 deletions
|
@ -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;
|
||||
|
|
|
@ -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<ICPPASTFunctionDeclarator> result= new ArrayList<ICPPASTFunctionDeclarator>();
|
||||
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<ICPPASTFunctionDeclarator> result= new ArrayList<ICPPASTFunctionDeclarator>();
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue