Files
clang-p2996/lldb/test/API/lang/cpp/template-function/main.cpp
shafik 9e2715aaac [lldb] Remove template parameters from FunctionTemplateDecl names
Fix to get the AST we generate for function templates closer to what clang generates and expects.
We fix which FuntionDecl we are passing to CreateFunctionTemplateSpecializationInfo and we strip
template parameters from the name when creating the FunctionDecl and FunctionTemplateDecl.

These two fixes together fix asserts and ambiguous lookup issues for several cases which are added to the already existing small function template test.
This fixes issues with overloads, overloads and ADL, variadic function templates and templated operator overloads.

Differential Revision: https://reviews.llvm.org/D75761
2020-03-17 11:00:23 -07:00

69 lines
2.1 KiB
C++

template<typename T>
int foo(T t1) {
return int(t1);
}
// Some cases to cover ADL, we have two cases:
//
// - f which will have a overload in the global namespace if unqualified lookup
// find f(int) and f(T) is found via ADL.
//
// - g which does not have an overload in the global namespace.
namespace A {
struct C {};
template <typename T> int f(T) { return 4; }
template <typename T> int g(T) { return 4; }
} // namespace A
// Meant to overload A::f(T) which may be found via ADL
int f(int) { return 1; }
// Regular overloaded functions case h(T) and h(double).
template <class T> int h(T x) { return x; }
int h(double d) { return 5; }
template <class... Us> int var(Us... pargs) { return 10; }
// Having the templated overloaded operators in a namespace effects the
// mangled name generated in the IR e.g. _ZltRK1BS1_ Vs _ZN1AltERKNS_1BES2_
// One will be in the symbol table but the other won't. This results in a
// different code path that will result in CPlusPlusNameParser being used.
// This allows us to cover that code as well.
namespace A {
template <typename T> bool operator<(const T &, const T &) { return true; }
template <typename T> bool operator>(const T &, const T &) { return true; }
template <typename T> bool operator<<(const T &, const T &) { return true; }
template <typename T> bool operator>>(const T &, const T &) { return true; }
template <typename T> bool operator==(const T &, const T &) { return true; }
struct B {};
} // namespace A
struct D {};
// Make sure we cover more straight forward cases as well.
bool operator<(const D &, const D &) { return true; }
bool operator>(const D &, const D &) { return true; }
bool operator>>(const D &, const D &) { return true; }
bool operator<<(const D &, const D &) { return true; }
bool operator==(const D &, const D &) { return true; }
int main() {
A::B b1;
A::B b2;
D d1;
D d2;
bool result_b = b1 < b2 && b1 << b2 && b1 == b2 && b1 > b2 && b1 >> b2;
bool result_c = d1 < d2 && d1 << d2 && d1 == d2 && d1 > d2 && d1 >> d2;
return foo(42) + result_b + result_c + f(A::C{}) + g(A::C{}) + h(10) + h(1.) +
var(1) + var(1, 2); // break here
}