Introduce the notion of instantiation dependence into Clang's AST. A
type/expression/template argument/etc. is instantiation-dependent if
it somehow involves a template parameter, even if it doesn't meet the
requirements for the more common kinds of dependence (dependent type,
type-dependent expression, value-dependent expression).

When we see an instantiation-dependent type, we know we always need to
perform substitution into that instantiation-dependent type. This
keeps us from short-circuiting evaluation in places where we
shouldn't, and lets us properly implement C++0x [temp.type]p2.

In theory, this would also allow us to properly mangle
instantiation-dependent-but-not-dependent decltype types per the
Itanium C++ ABI, but we aren't quite there because we still mangle
based on the canonical type in cases like, e.g.,

  template<unsigned> struct A { };
  template<typename T>
    void f(A<sizeof(sizeof(decltype(T() + T())))>) { }
  template void f<int>(A<sizeof(sizeof(int))>);

and therefore get the wrong answer.

llvm-svn: 134225
diff --git a/clang/test/CodeGenCXX/mangle.cpp b/clang/test/CodeGenCXX/mangle.cpp
index e76dfb1..8363528 100644
--- a/clang/test/CodeGenCXX/mangle.cpp
+++ b/clang/test/CodeGenCXX/mangle.cpp
@@ -751,3 +751,22 @@
     // CHECK: call void @_ZN6test301AINS_1BEE3fooIiEEvDTclsrS1_IT_EE2fnEE(
   }
 }
+
+namespace test31 { // instantiation-dependent mangling of decltype
+  int x;
+  template<class T> auto f1(T p)->decltype(x) { return 0; }
+  // The return type in the mangling of the template signature
+  // is encoded as "i".
+  template<class T> auto f2(T p)->decltype(p) { return 0; }
+  // The return type in the mangling of the template signature
+  // is encoded as "Dtfp_E".
+  void g(int);
+  template<class T> auto f3(T p)->decltype(g(p)) {}
+
+  // CHECK: define weak_odr i32 @_ZN6test312f1IiEEiT_(
+  template int f1(int);
+  // CHECK: define weak_odr i32 @_ZN6test312f2IiEEDtfp_ET_
+  template int f2(int);
+  // CHECK: define weak_odr void @_ZN6test312f3IiEEDTcl1gfp_EET_
+  template void f3(int);
+}