diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/ClassTypeHelperTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/ClassTypeHelperTests.java index 89ee0e71ebc..f3454e8e5cd 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/ClassTypeHelperTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/ClassTypeHelperTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010 Google, Inc and others. + * Copyright (c) 2011 Google, Inc and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/rewrite/TypeHelper.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/rewrite/TypeHelper.java new file mode 100644 index 00000000000..d3c7d53c6e7 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/rewrite/TypeHelper.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2011 Google, Inc and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sergey Prigogin (Google) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.dom.rewrite; + +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit; +import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator; +import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; + +/** + * A collection of static methods related to types. + * @since 5.4 + */ +public class TypeHelper { + + // Do not instantiate - all methods are static. + private TypeHelper() { + } + + /** + * Returns true if it is preferable to pass parameters of the given type to methods + * by reference, not by value. A parameter should be passed by reference if it is + * a class, struct, or union, and either has a nontrivial + * copy constructor or nontrivial destructor, or is larger than pointer. + * + * @param type the type in question. + * @param ast the AST used as a context. + * @return true is passing by reverence is preferable. + */ + public static boolean shouldBePassedByReference(IType type, IASTTranslationUnit ast) { + type = SemanticUtil.getNestedType(type, SemanticUtil.CVTYPE | SemanticUtil.TDEF); + if (type instanceof ICompositeType) { + if (type instanceof ICPPClassType) { + ICPPClassType classType = ((ICPPClassType) type); + if (!ClassTypeHelper.hasTrivialCopyCtor(classType) || + !ClassTypeHelper.hasTrivialDestructor(classType)) { + return true; + } + } + SizeofCalculator calc = ((ASTTranslationUnit) ast).getSizeofCalculator(); + SizeAndAlignment sizeofPointer = calc.sizeAndAlignmentOfPointer(); + if (sizeofPointer == null) + return true; + SizeAndAlignment sizeofType = calc.sizeAndAlignment(type); + if (sizeofType == null || sizeofType.size > sizeofPointer.size) + return true; + } + return false; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/SizeofCalculator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/SizeofCalculator.java index 8499a973a28..6d05a310554 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/SizeofCalculator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/SizeofCalculator.java @@ -34,7 +34,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; /** - * Calculator of in-memory size and of types. + * Calculator of in-memory size and alignment of types. */ public class SizeofCalculator { /** Size and alignment pair */ @@ -95,16 +95,16 @@ public class SizeofCalculator { sizeof_bool = getSize(sizeofMacros, "__SIZEOF_BOOL__", maxAlignment); //$NON-NLS-1$ sizeof_wchar_t = getSize(sizeofMacros, "__SIZEOF_WCHAR_T__", maxAlignment); //$NON-NLS-1$ sizeof_float = getSize(sizeofMacros, "__SIZEOF_FLOAT__", maxAlignment); //$NON-NLS-1$ - sizeof_complex_float = getDoubleSize(sizeof_float); + sizeof_complex_float = getSizeOfPair(sizeof_float); sizeof_double = getSize(sizeofMacros, "__SIZEOF_DOUBLE__", maxAlignment); //$NON-NLS-1$ - sizeof_complex_double = getDoubleSize(sizeof_double); + sizeof_complex_double = getSizeOfPair(sizeof_double); sizeof_long_double = getSize(sizeofMacros, "__SIZEOF_LONG_DOUBLE__", maxAlignment); //$NON-NLS-1$ - sizeof_complex_long_double = getDoubleSize(sizeof_long_double); + sizeof_complex_long_double = getSizeOfPair(sizeof_long_double); } /** * Calculates size and alignment for the given type. - * @param type + * @param type the type to get size and alignment for. * @return size and alignment, or null if could not be calculated. */ public SizeAndAlignment sizeAndAlignment(IType type) { @@ -130,6 +130,14 @@ public class SizeofCalculator { return null; } + /** + * Returns size and alignment of pointer types. + * @return size and alignment of pointer types, or null if unknown. + */ + public SizeAndAlignment sizeAndAlignmentOfPointer() { + return sizeof_pointer; + } + private SizeAndAlignment sizeAndAlignment(IBasicType type) { Kind kind = type.getKind(); switch (kind) { @@ -262,7 +270,7 @@ public class SizeofCalculator { } } - private SizeAndAlignment getDoubleSize(SizeAndAlignment sizeAndAlignment) { + private SizeAndAlignment getSizeOfPair(SizeAndAlignment sizeAndAlignment) { return sizeAndAlignment == null ? null : new SizeAndAlignment(sizeAndAlignment.size * 2, sizeAndAlignment.alignment); } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/FunctionFactory.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/FunctionFactory.java index 83fed4468a9..fa5f8886718 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/FunctionFactory.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/FunctionFactory.java @@ -15,6 +15,7 @@ package org.eclipse.cdt.internal.ui.refactoring.gettersandsetters; import java.util.Arrays; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; +import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; @@ -181,7 +182,13 @@ public class FunctionFactory { public static IASTSimpleDeclaration createGetterDeclaration(IASTName fieldName, IASTSimpleDeclaration fieldDeclaration) { IASTSimpleDeclaration getter = new CPPASTSimpleDeclaration(); - getter.setDeclSpecifier(fieldDeclaration.getDeclSpecifier().copy(CopyStyle.withLocations)); + IASTDeclSpecifier declSpec = fieldDeclaration.getDeclSpecifier(); + getter.setDeclSpecifier(declSpec.copy(CopyStyle.withLocations)); + // TODO(sprigogin): Implement return by reference +// IType type = CPPVisitor.createType(declSpec); +// if (TypeHelper.shouldBePassedByReference(type, fieldDeclaration.getTranslationUnit())) { +// declSpec.s +// } getter.addDeclarator(getGetterDeclarator(fieldName, fieldDeclaration, null)); return getter; }