1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 22:52:11 +02:00

Bug 487186 - Extraction of template type with function type argument

- Changed DeclarationGeneratorImpl to also consider the declarator for
template arguments instead of only the decl specifier.
- Adapted DeclarationGeneratorImpl to not add abstract pointer
.declarator for function type template arguments.
- Test case.

Change-Id: Iedec3e62f8234495003b74bfb463979e37c90bda
Signed-off-by: Thomas Corbat <tcorbat@hsr.ch>
This commit is contained in:
Thomas Corbat 2016-02-04 08:50:48 +01:00
parent c81aef4e42
commit 6b8482f866
2 changed files with 47 additions and 8 deletions

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010, 2014 Tomasz Wesolowski
* Copyright (c) 2010, 2016 Tomasz Wesolowski
* 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
@ -7,6 +7,7 @@
*
* Contributors:
* Tomasz Wesolowski - initial API and implementation
* Thomas Corbat (IFS)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.rewrite;
@ -51,6 +52,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.rewrite.DeclarationGenerator;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
/**
@ -126,6 +128,10 @@ public class DeclarationGeneratorImpl extends DeclarationGenerator {
@Override
public IASTDeclarator createDeclaratorFromType(IType type, char[] name) {
return createDeclaratorFromType(type, name, true);
}
public IASTDeclarator createDeclaratorFromType(IType type, char[] name, boolean changeInitialFunctionToFuncPtr) {
IASTDeclarator returnedDeclarator = null;
try {
@ -143,14 +149,14 @@ public class DeclarationGeneratorImpl extends DeclarationGenerator {
// If the type is a function, create a declaration of a pointer to this function
// (shorthand notation for function address).
boolean changeInitialFunctionToFuncPtr = true;
boolean changeNextFunctionToFuncPtr = changeInitialFunctionToFuncPtr;
while (typeNeedsNontrivialDeclarator(type)) {
if (replaceInitialArrayWithPointer && type instanceof IArrayType) {
returnedDeclarator = factory.newDeclarator(newName);
returnedDeclarator.addPointerOperator(factory.newPointer());
type = ((IArrayType) type).getType();
} else if (changeInitialFunctionToFuncPtr && type instanceof IFunctionType) {
} else if (changeNextFunctionToFuncPtr && type instanceof IFunctionType) {
returnedDeclarator = factory.newDeclarator(newName);
returnedDeclarator.addPointerOperator(factory.newPointer());
// Leave type as it is, next iteration will handle the function.
@ -204,7 +210,7 @@ public class DeclarationGeneratorImpl extends DeclarationGenerator {
type = funcType.getReturnType();
}
replaceInitialArrayWithPointer = false;
changeInitialFunctionToFuncPtr = false;
changeNextFunctionToFuncPtr = false;
}
finalizePointerOperators(pointerOperatorMap);
@ -313,14 +319,26 @@ public class DeclarationGeneratorImpl extends DeclarationGenerator {
ICPPNodeFactory cppFactory = (ICPPNodeFactory) factory;
ICPPASTTemplateId tempId = cppFactory.newTemplateId(templateName.copy(CopyStyle.withLocations));
for (ICPPTemplateArgument arg : type.getTemplateArguments()) {
IASTDeclSpecifier argDeclSpec = createDeclSpecFromType(arg.isTypeValue() ?
arg.getTypeValue() : arg.getTypeOfNonTypeValue());
IASTTypeId typeId = cppFactory.newTypeId(argDeclSpec, null);
IASTTypeId typeId = getTypeIdForTemplateArgument(arg);
tempId.addTemplateArgument(typeId);
}
return tempId;
}
private IASTTypeId getTypeIdForTemplateArgument(ICPPTemplateArgument argument) {
IASTDeclSpecifier argDeclSpec;
IASTDeclarator typeDeclarator = null;
if (argument.isTypeValue()) {
IType argumentType = argument.getTypeValue();
argDeclSpec = createDeclSpecFromType(argumentType);
typeDeclarator = createDeclaratorFromType(argumentType, CharArrayUtils.EMPTY, false);
} else {
argDeclSpec = createDeclSpecFromType(argument.getTypeOfNonTypeValue());
}
IASTTypeId typeId = factory.newTypeId(argDeclSpec, typeDeclarator);
return typeId;
}
private IASTNamedTypeSpecifier getDeclSpecForBinding(IBinding binding) {
IASTName name = getName(binding);
return factory.newTypedefNameSpecifier(name);

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2013 Institute for Software, HSR Hochschule fuer Technik
* Copyright (c) 2008, 2016 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
@ -10,6 +10,7 @@
* Institute for Software - initial API and implementation
* Sergey Prigogin (Google)
* Marc-Andre Laperle (Ericsson)
* Thomas Corbat (IFS)
*******************************************************************************/
package org.eclipse.cdt.ui.tests.refactoring.extractlocalvariable;
@ -571,4 +572,24 @@ public class ExtractLocalVariableRefactoringTest extends RefactoringTestBase {
assertRefactoringSuccess();
}
//A.cpp
//template<typename T>
//struct Tpl {};
//
//void func() {
// Tpl<int(const char*, long int (*)(float))> t;
// /*$*/t/*$$*/;
//}
//====================
//template<typename T>
//struct Tpl {};
//
//void func() {
// Tpl<int(const char*, long int (*)(float))> t;
// Tpl<int(const char*, long int (*)(float))> t0 = t;
// t0;
//}
public void testTemplateWithFunctionArgument_487186() throws Exception {
assertRefactoringSuccess();
}
}