Strictly speaking, hiddenDependency is not deprecated, and [[deprecated]] in OldApi warns hiddenDependency that OldApi is deprecated and it should be updated/replaced, but the body of hiddenDependency is still valid, unless the code has not been designed properly (and same declaration but different definition in OldApi affects hiddenDependency). Nonetheless, if there is some kind of relation between OldApi and hiddenDependency, they may or might be scoped in a namespace (or should have been), so the solution is to deprecate the namespace instead of the class and trying to "inherit" [[deprecated]]:
namespace [[deprecated("Use NewFunctionality instead")]] OldFunctionality {
class OldApi {
public:
OldApi(){
}
};
void foo() {
OldApi bar;
}
}
Assuming that you are able to deprecate the caller, what's the limit? Should only be the caller of the deprecated method considered as deprecated? Should be the caller of the caller considered as deprecated as well? How many levels of deprecation are expected? Because the compiler warns that hiddenDependency is calling a deprecated method, it points out the reason and the affected line in hiddenDependency. What's the criteria to not move up the warning until the main? Going further, is the criteria to deprecate all the functions which call OldApi? (if so, you already have a group, hence you can encapsulate it i.e. namespace) Or is the criteria all the functions which call OldApi and some extra requirements? (if so, there is not a clear procedure and it has to be done manually).
Even if parsing the whole text looking for the pattern "hiddenDependency calls OldApi" is an option (and probably the most valid one considering your example), it doesn't look like a clean and easy to maintain (or even justify/document) solution.