import cpp

class FunctionMonkeyPatch extends Function {
  language[monotonicAggregates]
  override string toString() {
    exists(string name, string templateArgs, string args |
         result = name + templateArgs + args
         and name = this.getQualifiedName()
         and if exists(this.getATemplateArgument())
             then templateArgs = "<" + concat(int i | exists(this.getTemplateArgument(i)) | this.getTemplateArgument(i).toString(), "," order by i) + ">"
             else templateArgs = ""
         and args = "(" + concat(int i | exists(this.getParameter(i)) | this.getParameter(i).getType().toString(), "," order by i) + ")")
  }
}

class ParameterMonkeyPatch extends Parameter {
  override string toString() {
    result = super.getType().getName() + " " + super.toString()
  }
}

from Element e, Element ti
where e.getLocation().getStartLine() != 0 // unhelpful
and not (function_instantiation(unresolveElement(e), _) and e = ti) // trivial
and not (class_instantiation(unresolveElement(e), _) and e = ti) // trivial
and not (variable_instantiation(unresolveElement(e), _) and e = ti) // trivial
and e.isFromTemplateInstantiation(ti)
select e, ti
