Bug 536160 - Rename refactoring a template function not updating source file
Summary: Rename refactoring a template function not updating source file
Status: NEW
Alias: None
Product: CDT
Classification: Tools
Component: cdt-refactoring (show other bugs)
Version: 9.4.2   Edit
Hardware: PC Windows 10
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact: Jonah Graham CLA
URL:
Whiteboard:
Keywords:
Depends on: 326070
Blocks:
  Show dependency tree
 
Reported: 2018-06-21 22:23 EDT by Zafer Dogan CLA
Modified: 2020-09-04 15:21 EDT (History)
3 users (show)

See Also:


Attachments
Bug example rename refactoring on template functions (131.52 KB, image/jpeg)
2018-06-21 22:23 EDT, Zafer Dogan CLA
no flags Details
The test project where I reproduced 536160 & 326070 (155.14 KB, application/x-zip-compressed)
2019-10-18 07:08 EDT, Lidia Popescu CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Zafer Dogan CLA 2018-06-21 22:23:58 EDT
Created attachment 274579 [details]
Bug example rename refactoring on template functions

I'm using the RenameSupport to init internal refactorings for various rename operations in C++ Code from within a plug-in I'm developing.

An example how it is used within the plug-in:

public Boolean performFor(IRule pRule) throws Exception {
  if(checkPreConditions()) {
  CRenameProcessor processor = prepareProcessor(applyTransformations(pRule));
  RenameSupport support = RenameSupport.create(processor);
  IWorkbenchWindow window =     
  PlatformUI.getWorkbench().getActiveWorkbenchWindow();
  if (!hasNameChanged(processor) || processor.getReplacementText().isEmpty())   
  {
    return support.openDialog(window.getShell());
  } else {
    return support.perform(window.getShell(), window);
  }
return false;
}

Initiating the Rename Refactoring via Alt + Shift + R initializes a similar procedure. I've noticed that for normal functions, the rename refactoring works without any problems, but when it is initiated on template functions, it doesn't update references in the source file (or vice versa). The difference can be seen in the dialog as well; the .cpp file isn't retrieved as a target for refactoring. It is normally when initiating it on normal functions.
Comment 1 Nathan Ridge CLA 2018-06-24 23:17:26 EDT
Chances are the root cause is the same as bug 326070, and if that's fixed, this will just start working.
Comment 2 Lidia Popescu CLA 2019-10-18 07:08:07 EDT
Created attachment 280316 [details]
The test project where I reproduced 536160 & 326070

Hello, 

I am attaching my CPP sample project where I also reproduced this issue in Eclipse oxygen/photon/orion (CDT 9.4.3/9.6.0/9.9.0).

I wanted to report this bug, but found that it was already reported and for a year there is not any progress on it.

Based on tests:
Rename refactor is not able to update all references for template functions, and for functions from template classes, even if the function is declared in same source file.
But still if I try to rename template class - it works. All references are properly updated.

The bug it depends on is also not solved.
https://bugs.eclipse.org/bugs/show_bug.cgi?id=326070

Could someone try to fix this in next future, please?

Thank you
Comment 3 Nathan Ridge CLA 2019-10-18 22:06:34 EDT
(In reply to Lidia Gutu from comment #2)
> Rename refactor is not able to update all references for template functions,
> and for functions from template classes, even if the function is declared in
> same source file.
> But still if I try to rename template class - it works. All references are
> properly updated.

That's because functions can be overloaded but classes can't.

So if we see "template <typename T> class A", and then later "A<T>", we know we're referring to the class template, even if T is dependent.

However, if we see "template <typename T> void foo(T)", and later "foo(t)", if t is dependent, we don't know that it's referring to the function template -- it could be referring to another overload of "foo", including one declared later and found by argument-dependent lookup.

Which makes me realize that bug 326070 is not sufficient for fixing this. Bug 326070 will allow us to find references in instantiated contexts, but a refactoring is performed on the uninstantiated source code. We'd have to reason about whether or not every instantiation references the same function template, which would at best be heuristic.

For example, consider:

  template <typename T>
  void foo(T);    // #1

  void foo(int);  // #2

  template <typename T>
  void waldo(T t) {
    foo(t);
  }

  int main() {
    waldo(42.0f);  // calls #1
    waldo(42);     // calls #2
  }

Here, if you renamed #1 from "foo" to "bar", and we updated the reference inside "waldo", we would silently change the behaviour of "waldo(42)", which previously called #2 but would now call #1.

> The bug it depends on is also not solved.
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=326070
> 
> Could someone try to fix this in next future, please?

I'm afraid I won't be working on it. I've largely moved on to clangd, and it makes more sense for me to focus my limited time on that.

However, it's open source, so perhaps someone else might. It could even be you :)