[ASTImporter] Implement some expression-related AST node import (part 2)

* Some code cleanup
* Add tests not present in http://reviews.llvm.org/D14286
* Integrate a test suite from Serge Pavlov (http://reviews.llvm.org/D14224)
* ArrayTypeTraitExpr: serialize sub-expression to avoid keeping it undefined
* Implement import of some nodes:
  - ArrayTypeTraitExpr
  - ExpressionTraitExpr
  - OpaqueValueExpr
  - ArraySubscriptExpr
  - ExplicitCastExpr
  - ImplicitValueInitExpr
  - OffsetOfExpr
  - CXXThisExpr
  - CXXThrowExpr
  - CXXNoexceptExpr
  - CXXDefaultArgExpr
  - CXXScalarValueInitExpr
  - CXXBindTemporaryExpr
  - CXXTemporaryObjectExpr
  - MaterializeTemporaryExpr
  - ExprWithCleanups

  - StaticAssertDecl
  - FriendDecl

  - DecayedType

Differential Revision: https://reviews.llvm.org/D14326

llvm-svn: 282572
diff --git a/clang/test/ASTMerge/Inputs/class3.cpp b/clang/test/ASTMerge/Inputs/class3.cpp
new file mode 100644
index 0000000..428acc3
--- /dev/null
+++ b/clang/test/ASTMerge/Inputs/class3.cpp
@@ -0,0 +1,26 @@
+class C1 {
+public:
+  C1();
+  ~C1();
+  C1 *method_1() {
+    return this;
+  }
+  C1 method_2() {
+    return C1();
+  }
+  void method_3() {
+    const C1 &ref = C1();
+  }
+};
+
+class C11 : public C1 {
+};
+
+class C2 {
+private:
+  int x;
+  friend class C3;
+public:
+  static_assert(sizeof(x) == sizeof(int), "Error");
+  typedef class C2::C2 InjType;
+};
diff --git a/clang/test/ASTMerge/Inputs/exprs3.cpp b/clang/test/ASTMerge/Inputs/exprs3.cpp
new file mode 100644
index 0000000..1fb667b
--- /dev/null
+++ b/clang/test/ASTMerge/Inputs/exprs3.cpp
@@ -0,0 +1,131 @@
+// Integer literals
+const char Ch1 = 'a';
+const signed char Ch2 = 'b';
+const unsigned char Ch3 = 'c';
+
+const wchar_t Ch4 = L'd';
+const signed wchar_t Ch5 = L'e';
+const unsigned wchar_t Ch6 = L'f';
+
+const short C1 = 12;
+const unsigned short C2 = 13;
+
+const int C3 = 12;
+const unsigned int C4 = 13;
+
+const long C5 = 22;
+const unsigned long C6 = 23;
+
+const long long C7 = 66;
+const unsigned long long C8 = 67;
+
+
+// String literals
+const char str1[] = "ABCD";
+const char str2[] = "ABCD" "0123";
+
+const wchar_t wstr1[] = L"DEF";
+const wchar_t wstr2[] = L"DEF" L"123";
+
+
+// Boolean literals
+const bool bval1 = true;
+const bool bval2 = false;
+
+// Floating Literals
+const float F1 = 12.2F;
+const double F2 = 1E4;
+const long double F3 = 1.2E-3L;
+
+
+// nullptr literal
+const void *vptr = nullptr;
+
+
+int glb_1[4] = { 10, 20, 30, 40 };
+
+struct S1 {
+  int a;
+  int b[3];
+};
+
+struct S2 {
+  int c;
+  S1 d;
+};
+
+S2 glb_2 = { 22, .d.a = 44, .d.b[0] = 55, .d.b[1] = 66 };
+
+void testNewThrowDelete() {
+  throw;
+  char *p = new char[10];
+  delete[] p;
+}
+
+int testArrayElement(int *x, int n) {
+  return x[n];
+}
+
+int testTernaryOp(int c, int x, int y) {
+  return c ? x : y;
+}
+
+S1 &testConstCast(const S1 &x) {
+  return const_cast<S1&>(x);
+}
+
+S1 &testStaticCast(S1 &x) {
+  return static_cast<S1&>(x);
+}
+
+S1 &testReinterpretCast(S1 &x) {
+  return reinterpret_cast<S1&>(x);
+}
+
+S1 &testDynamicCast(S1 &x) {
+  return dynamic_cast<S1&>(x);
+}
+
+int testScalarInit(int x) {
+  return int(x);
+}
+
+struct S {
+  float f;
+  double d;
+};
+struct T {
+  int i;
+  struct S s[10];
+};
+
+void testOffsetOf() {
+  __builtin_offsetof(struct T, s[2].d);
+}
+
+
+unsigned char asmFunc(unsigned char a, unsigned char b) {
+  unsigned int la = a;
+  unsigned int lb = b;
+  unsigned int bigres;
+  unsigned char res;
+  __asm__ ("0:\n1:\n" : [bigres] "=la"(bigres) : [la] "0"(la), [lb] "c"(lb) :
+                        "edx", "cc");
+  res = bigres;
+  return res;
+}
+
+int testDefaultArg(int a = 2*2) {
+  return a;
+}
+
+template <typename T> // T has TemplateTypeParmType
+void testTemplateTypeParmType(int i);
+
+void useTemplateType() {
+  testTemplateTypeParmType<char>(4);
+}
+
+const bool ExpressionTrait = __is_lvalue_expr(1);
+const unsigned ArrayRank = __array_rank(int[10][20]);
+const unsigned ArrayExtent = __array_extent(int[10][20], 1);
diff --git a/clang/test/ASTMerge/class2.cpp b/clang/test/ASTMerge/class2.cpp
new file mode 100644
index 0000000..6021403
--- /dev/null
+++ b/clang/test/ASTMerge/class2.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -emit-pch -o %t.1.ast %S/Inputs/class3.cpp
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -ast-merge %t.1.ast -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+class C3 {
+  int method_1(C2 *x) {
+    return x->x;
+  }
+};
diff --git a/clang/test/ASTMerge/exprs.cpp b/clang/test/ASTMerge/exprs.cpp
new file mode 100644
index 0000000..ba1f18b
--- /dev/null
+++ b/clang/test/ASTMerge/exprs.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -fcxx-exceptions -emit-pch -o %t.1.ast %S/Inputs/exprs3.cpp
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -fcxx-exceptions -ast-merge %t.1.ast -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+static_assert(Ch1 == 'a');
+static_assert(Ch2 == 'b');
+static_assert(Ch3 == 'c');
+
+static_assert(Ch4 == L'd');
+static_assert(Ch5 == L'e');
+static_assert(Ch6 == L'f');
+
+static_assert(C1 == 12);
+static_assert(C2 == 13);
+
+static_assert(C3 == 12);
+static_assert(C4 == 13);
+
+static_assert(C5 == 22L);
+static_assert(C6 == 23L);
+
+static_assert(C7 == 66LL);
+static_assert(C8 == 67ULL);
+
+static_assert(bval1 == true);
+static_assert(bval2 == false);
+
+static_assert(ExpressionTrait == false);
+
+static_assert(ArrayRank == 2);
+static_assert(ArrayExtent == 20);
+
+void testImport(int *x, const S1 &cs1, S1 &s1) {
+  testNewThrowDelete();
+  testArrayElement(nullptr, 12);
+  testTernaryOp(0, 1, 2);
+  testConstCast(cs1);
+  testStaticCast(s1);
+  testReinterpretCast(s1);
+  testDynamicCast(s1);
+  testScalarInit(42);
+  testOffsetOf();
+  testDefaultArg(12);
+  useTemplateType();
+}