a.sidorin updated the summary for this revision.
a.sidorin added a reviewer: spyffe.
a.sidorin removed rL LLVM as the repository for this revision.
a.sidorin updated this revision to Diff 56682.
a.sidorin added a comment.

- 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)
- Fix some issues pointed on review.


http://reviews.llvm.org/D14326

Files:
  include/clang/AST/ASTImporter.h
  include/clang/AST/DeclFriend.h
  lib/AST/ASTImporter.cpp
  test/ASTMerge/Inputs/class3.cpp
  test/ASTMerge/Inputs/exprs3.cpp
  test/ASTMerge/class2.cpp
  test/ASTMerge/exprs.cpp
  unittests/AST/ASTImporterTest.cpp

Index: unittests/AST/ASTImporterTest.cpp
===================================================================
--- unittests/AST/ASTImporterTest.cpp
+++ unittests/AST/ASTImporterTest.cpp
@@ -466,5 +466,48 @@
 }
 
 
+const internal::VariadicDynCastAllOfMatcher<Expr, VAArgExpr> vaArgExpr;
+
+/// \brief Matches the decayed type, whose original type matches \c InnerMatcher
+AST_MATCHER_P(DecayedType, hasOriginalType, internal::Matcher<QualType>,
+              InnerType) {
+  return InnerType.matches(Node.getOriginalType(), Finder, Builder);
+}
+
+TEST(ImportExpr, ImportVAArgExpr) {
+  MatchVerifier<Decl> Verifier;
+  EXPECT_TRUE(
+        testImport(
+          "void declToImport(__builtin_va_list list, ...) {"
+          "  (void)__builtin_va_arg(list, int); }",
+          Lang_CXX, "", Lang_CXX, Verifier,
+          functionDecl(
+            hasParameter(0,
+                         varDecl(
+                           hasName("list"),
+                           hasType(
+                             decayedType(
+                               hasOriginalType(
+                                 typedefType(
+                                   hasDeclaration(
+                                     typedefDecl(
+                                       hasName("__builtin_va_list"),
+                                       hasType(
+                                         constantArrayType(
+                                           hasSize(1),
+                                           hasElementType(
+                                             qualType(
+                                               recordType(),
+                                               asString("struct __va_list_tag"
+                                                          ))))))))))))),
+            hasBody(
+              compoundStmt(
+                has(
+                  cStyleCastExpr(
+                    hasSourceExpression(
+                      vaArgExpr()))))))));
+}
+
+
 } // end namespace ast_matchers
 } // end namespace clang
Index: test/ASTMerge/exprs.cpp
===================================================================
--- /dev/null
+++ test/ASTMerge/exprs.cpp
@@ -0,0 +1,40 @@
+// 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);
+
+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();
+}
Index: test/ASTMerge/class2.cpp
===================================================================
--- /dev/null
+++ 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;
+  }
+};
Index: test/ASTMerge/Inputs/exprs3.cpp
===================================================================
--- /dev/null
+++ test/ASTMerge/Inputs/exprs3.cpp
@@ -0,0 +1,127 @@
+// 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);
+}
Index: test/ASTMerge/Inputs/class3.cpp
===================================================================
--- /dev/null
+++ 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;
+};
Index: lib/AST/ASTImporter.cpp
===================================================================
--- lib/AST/ASTImporter.cpp
+++ lib/AST/ASTImporter.cpp
@@ -40,6 +40,7 @@
     // Importing types
     QualType VisitType(const Type *T);
     QualType VisitBuiltinType(const BuiltinType *T);
+    QualType VisitDecayedType(const DecayedType *T);
     QualType VisitComplexType(const ComplexType *T);
     QualType VisitPointerType(const PointerType *T);
     QualType VisitBlockPointerType(const BlockPointerType *T);
@@ -88,6 +89,8 @@
                                   DeclarationNameInfo& To);
     void ImportDeclContext(DeclContext *FromDC, bool ForceImport = false);
 
+    bool ImportCastPath(CastExpr *E, CXXCastPath &Path);
+
     typedef DesignatedInitExpr::Designator Designator;
     Designator ImportDesignator(const Designator &D);
 
@@ -123,6 +126,8 @@
     TemplateParameterList *ImportTemplateParameterList(
                                                  TemplateParameterList *Params);
     TemplateArgument ImportTemplateArgument(const TemplateArgument &From);
+    TemplateArgumentLoc ImportTemplateArgumentLoc(
+        const TemplateArgumentLoc &TALoc);
     bool ImportTemplateArguments(const TemplateArgument *FromArgs,
                                  unsigned NumFromArgs,
                                SmallVectorImpl<TemplateArgument> &ToArgs);
@@ -136,6 +141,7 @@
     bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To);
     Decl *VisitDecl(Decl *D);
     Decl *VisitAccessSpecDecl(AccessSpecDecl *D);
+    Decl *VisitStaticAssertDecl(StaticAssertDecl *D);
     Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D);
     Decl *VisitNamespaceDecl(NamespaceDecl *D);
     Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias);
@@ -152,6 +158,7 @@
     Decl *VisitCXXConversionDecl(CXXConversionDecl *D);
     Decl *VisitFieldDecl(FieldDecl *D);
     Decl *VisitIndirectFieldDecl(IndirectFieldDecl *D);
+    Decl *VisitFriendDecl(FriendDecl *D);
     Decl *VisitObjCIvarDecl(ObjCIvarDecl *D);
     Decl *VisitVarDecl(VarDecl *D);
     Decl *VisitImplicitParamDecl(ImplicitParamDecl *D);
@@ -242,11 +249,25 @@
     Expr *VisitConditionalOperator(ConditionalOperator *E);
     Expr *VisitBinaryConditionalOperator(BinaryConditionalOperator *E);
     Expr *VisitOpaqueValueExpr(OpaqueValueExpr *E);
+    Expr *VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
+    Expr *VisitExpressionTraitExpr(ExpressionTraitExpr *E);
+    Expr *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
     Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E);
     Expr *VisitImplicitCastExpr(ImplicitCastExpr *E);
-    Expr *VisitCStyleCastExpr(CStyleCastExpr *E);
+    Expr *VisitExplicitCastExpr(ExplicitCastExpr *E);
+    Expr *VisitOffsetOfExpr(OffsetOfExpr *OE);
+    Expr *VisitCXXThrowExpr(CXXThrowExpr *E);
+    Expr *VisitCXXNoexceptExpr(CXXNoexceptExpr *E);
+    Expr *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E);
+    Expr *VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
+    Expr *VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
+    Expr *VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *CE);
+    Expr *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E);
+    Expr *VisitCXXNewExpr(CXXNewExpr *CE);
+    Expr *VisitCXXDeleteExpr(CXXDeleteExpr *E);
     Expr *VisitCXXConstructExpr(CXXConstructExpr *E);
     Expr *VisitCXXMemberCallExpr(CXXMemberCallExpr *E);
+    Expr *VisitExprWithCleanups(ExprWithCleanups *EWC);
     Expr *VisitCXXThisExpr(CXXThisExpr *E);
     Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
     Expr *VisitMemberExpr(MemberExpr *E);
@@ -270,13 +291,26 @@
       bool Failed = false;
       std::transform(Ibegin, Iend, Obegin,
                      [&ImporterRef, &Failed](ItemT *From) -> ItemT * {
-                       ItemT *To = ImporterRef.Import(From);
+                       ItemT *To = cast_or_null<ItemT>(
+                             ImporterRef.Import(From));
                        if (!To && From)
                          Failed = true;
                        return To;
                      });
       return Failed;
     }
+
+    template<typename InContainerTy, typename OutContainerTy>
+    bool ImportContainerChecked(const InContainerTy &InContainer,
+                                OutContainerTy &OutContainer) {
+      return ImportArrayChecked(InContainer.begin(), InContainer.end(),
+                                OutContainer.begin());
+    }
+
+    template<typename InContainerTy, typename OIter>
+    bool ImportArrayChecked(const InContainerTy &InContainer, OIter Obegin) {
+      return ImportArrayChecked(InContainer.begin(), InContainer.end(), Obegin);
+    }
   };
 }
 
@@ -1576,6 +1610,14 @@
   llvm_unreachable("Invalid BuiltinType Kind!");
 }
 
+QualType ASTNodeImporter::VisitDecayedType(const DecayedType *T) {
+  QualType OrigT = Importer.Import(T->getOriginalType());
+  if (OrigT.isNull())
+    return QualType();
+
+  return Importer.getToContext().getDecayedType(OrigT);
+}
+
 QualType ASTNodeImporter::VisitComplexType(const ComplexType *T) {
   QualType ToElementType = Importer.Import(T->getElementType());
   if (ToElementType.isNull())
@@ -2231,18 +2273,10 @@
 
 TemplateParameterList *ASTNodeImporter::ImportTemplateParameterList(
                                                 TemplateParameterList *Params) {
-  SmallVector<NamedDecl *, 4> ToParams;
-  ToParams.reserve(Params->size());
-  for (TemplateParameterList::iterator P = Params->begin(), 
-                                    PEnd = Params->end();
-       P != PEnd; ++P) {
-    Decl *To = Importer.Import(*P);
-    if (!To)
-      return nullptr;
+  SmallVector<NamedDecl *, 4> ToParams(Params->size());
+  if (ImportContainerChecked(*Params, ToParams))
+    return nullptr;
 
-    ToParams.push_back(cast<NamedDecl>(To));
-  }
-  
   return TemplateParameterList::Create(Importer.getToContext(),
                                        Importer.Import(Params->getTemplateLoc()),
                                        Importer.Import(Params->getLAngleLoc()),
@@ -2321,6 +2355,26 @@
   llvm_unreachable("Invalid template argument kind");
 }
 
+TemplateArgumentLoc ASTNodeImporter::ImportTemplateArgumentLoc(
+    const TemplateArgumentLoc &TALoc) {
+  TemplateArgument Arg = ImportTemplateArgument(TALoc.getArgument());
+  TemplateArgumentLocInfo FromInfo = TALoc.getLocInfo();
+  TemplateArgumentLocInfo ToInfo;
+  if (Arg.getKind() == TemplateArgument::Expression) {
+    Expr *E = Importer.Import(FromInfo.getAsExpr());
+    ToInfo = TemplateArgumentLocInfo(E);
+  } else if (Arg.getKind() == TemplateArgument::Type) {
+    TypeSourceInfo *TSI = Importer.Import(FromInfo.getAsTypeSourceInfo());
+    ToInfo = TemplateArgumentLocInfo(TSI);
+  } else {
+    ToInfo = TemplateArgumentLocInfo(
+          Importer.Import(FromInfo.getTemplateQualifierLoc()),
+          Importer.Import(FromInfo.getTemplateNameLoc()),
+          Importer.Import(FromInfo.getTemplateEllipsisLoc()));
+  }
+  return TemplateArgumentLoc(Arg, ToInfo);
+}
+
 bool ASTNodeImporter::ImportTemplateArguments(const TemplateArgument *FromArgs,
                                               unsigned NumFromArgs,
                               SmallVectorImpl<TemplateArgument> &ToArgs) {
@@ -2435,6 +2489,40 @@
   return accessSpecDecl;
 }
 
+Decl *ASTNodeImporter::VisitStaticAssertDecl(StaticAssertDecl *D) {
+  DeclContext *DC = Importer.ImportContext(D->getDeclContext());
+  if (!DC)
+    return nullptr;
+
+  DeclContext *LexicalDC = DC;
+  if (D->getDeclContext() != D->getLexicalDeclContext()) {
+    LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
+    if (!LexicalDC)
+      return nullptr;
+  }
+
+  // Import the location of this declaration.
+  SourceLocation Loc = Importer.Import(D->getLocation());
+
+  Expr *AssertExpr = Importer.Import(D->getAssertExpr());
+  if (!AssertExpr)
+    return nullptr;
+
+  StringLiteral *Message = cast_or_null<StringLiteral>(
+        Importer.Import(D->getMessage()));
+  if (!Message)
+    return nullptr;
+
+  StaticAssertDecl *ToD = StaticAssertDecl::Create(
+        Importer.getToContext(), DC, Loc, AssertExpr, Message,
+        Importer.Import(D->getRParenLoc()), D->isFailed());
+
+  ToD->setLexicalDeclContext(LexicalDC);
+  LexicalDC->addDeclInternal(ToD);
+  Importer.Imported(D, ToD);
+  return ToD;
+}
+
 Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
   // Import the major distinguishing characteristics of this namespace.
   DeclContext *DC, *LexicalDC;
@@ -3259,6 +3347,70 @@
   return ToIndirectField;
 }
 
+Decl *ASTNodeImporter::VisitFriendDecl(FriendDecl *D) {
+  // Import the major distinguishing characteristics of a variable.
+  DeclContext *DC = Importer.ImportContext(D->getDeclContext());
+  DeclContext *LexicalDC = D->getDeclContext() == D->getLexicalDeclContext()
+      ? DC : Importer.ImportContext(D->getLexicalDeclContext());
+  if (!DC || !LexicalDC)
+    return nullptr;
+
+  // Determine whether we've already imported this decl.
+  // FriendDecl is not a NamedDecl so we cannot use localUncachedLookup.
+  CXXRecordDecl *RD = cast<CXXRecordDecl>(DC);
+  FriendDecl *ImportedFriend = RD->getFirstFriend();
+  StructuralEquivalenceContext Context(
+      Importer.getFromContext(), Importer.getToContext(),
+      Importer.getNonEquivalentDecls(), false, false);
+
+  while (ImportedFriend) {
+    if (D->getFriendDecl() && ImportedFriend->getFriendDecl()) {
+      if (Context.IsStructurallyEquivalent(D->getFriendDecl(),
+                                           ImportedFriend->getFriendDecl()))
+        return Importer.Imported(D, ImportedFriend);
+
+    } else if (D->getFriendType() && ImportedFriend->getFriendType()) {
+      if (Importer.IsStructurallyEquivalent(
+            D->getFriendType()->getType(),
+            ImportedFriend->getFriendType()->getType(), true))
+        return Importer.Imported(D, ImportedFriend);
+    }
+    ImportedFriend = ImportedFriend->getNextFriend();
+  }
+
+  // Not found. Create it.
+  FriendDecl::FriendUnion ToFU;
+  if (NamedDecl *FriendD = D->getFriendDecl())
+    ToFU = cast_or_null<NamedDecl>(Importer.Import(FriendD));
+  else
+    ToFU = Importer.Import(D->getFriendType());
+  if (!ToFU)
+    return nullptr;
+
+  SmallVector<TemplateParameterList *, 1> ToTPLists(D->NumTPLists);
+  TemplateParameterList **FromTPLists =
+      D->getTrailingObjects<TemplateParameterList *>();
+  for (int I = 0; I < D->NumTPLists; I++) {
+    TemplateParameterList *List = ImportTemplateParameterList(FromTPLists[I]);
+    if (!List)
+      return nullptr;
+    ToTPLists[I] = List;
+  }
+
+  FriendDecl *FrD = FriendDecl::Create(Importer.getToContext(), DC,
+                                       Importer.Import(D->getLocation()),
+                                       ToFU, Importer.Import(D->getFriendLoc()),
+                                       ToTPLists);
+
+  Importer.Imported(D, FrD);
+  RD->pushFriendDecl(FrD);
+
+  FrD->setAccess(D->getAccess());
+  FrD->setLexicalDeclContext(LexicalDC);
+  LexicalDC->addDeclInternal(FrD);
+  return FrD;
+}
+
 Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
   // Import the major distinguishing characteristics of an ivar.
   DeclContext *DC, *LexicalDC;
@@ -4816,11 +4968,10 @@
   }
 
   SmallVector<Expr *, 4> Exprs(S->getNumOutputs() + S->getNumInputs());
-  if (ImportArrayChecked(S->begin_outputs(), S->end_outputs(), Exprs.begin()))
+  if (ImportContainerChecked(S->outputs(), Exprs))
     return nullptr;
 
-  if (ImportArrayChecked(S->begin_inputs(), S->end_inputs(),
-                         Exprs.begin() + S->getNumOutputs()))
+  if (ImportArrayChecked(S->inputs(), Exprs.begin() + S->getNumOutputs()))
     return nullptr;
 
   StringLiteral *AsmStr = cast_or_null<StringLiteral>(
@@ -4863,8 +5014,8 @@
 
 Stmt *ASTNodeImporter::VisitCompoundStmt(CompoundStmt *S) {
   llvm::SmallVector<Stmt *, 8> ToStmts(S->size());
-    
-  if (ImportArrayChecked(S->body_begin(), S->body_end(), ToStmts.begin()))
+
+  if (ImportContainerChecked(S->body(), ToStmts))
     return nullptr;
 
   SourceLocation ToLBraceLoc = Importer.Import(S->getLBracLoc());
@@ -5310,7 +5461,7 @@
     return nullptr;
 
   return new (Importer.getToContext()) GNUNullExpr(
-        T, Importer.Import(E->getExprLoc()));
+        T, Importer.Import(E->getLocStart()));
 }
 
 Expr *ASTNodeImporter::VisitPredefinedExpr(PredefinedExpr *E) {
@@ -5324,7 +5475,7 @@
     return nullptr;
 
   return new (Importer.getToContext()) PredefinedExpr(
-        Importer.Import(E->getExprLoc()), T, E->getIdentType(), SL);
+        Importer.Import(E->getLocStart()), T, E->getIdentType(), SL);
 }
 
 Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
@@ -5343,6 +5494,18 @@
   if (T.isNull())
     return nullptr;
 
+
+  TemplateArgumentListInfo ToTAInfo;
+  TemplateArgumentListInfo *ResInfo = nullptr;
+  if (E->hasExplicitTemplateArgs()) {
+    const TemplateArgumentLoc *FromArgArray = E->getTemplateArgs();
+    for (unsigned i = 0, e = E->getNumTemplateArgs(); i < e; i++) {
+      const TemplateArgumentLoc &FromLoc = FromArgArray[i];
+      ToTAInfo.addArgument(ImportTemplateArgumentLoc(FromLoc));
+    }
+    ResInfo = &ToTAInfo;
+  }
+
   DeclRefExpr *DRE = DeclRefExpr::Create(Importer.getToContext(), 
                                          Importer.Import(E->getQualifierLoc()),
                                    Importer.Import(E->getTemplateKeywordLoc()),
@@ -5351,7 +5514,7 @@
                                          Importer.Import(E->getLocation()),
                                          T, E->getValueKind(),
                                          FoundD,
-                                         /*FIXME:TemplateArgs=*/nullptr);
+                                         /*TemplateArgs=*/ResInfo);
   if (E->hadMultipleCandidates())
     DRE->setHadMultipleCandidates(true);
   return DRE;
@@ -5360,7 +5523,7 @@
 Expr *ASTNodeImporter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
   QualType T = Importer.Import(E->getType());
   if (T.isNull())
-    return NULL;
+    return nullptr;
 
   return new (Importer.getToContext()) ImplicitValueInitExpr(T);
 }
@@ -5531,8 +5694,7 @@
 
 Expr *ASTNodeImporter::VisitParenListExpr(ParenListExpr *E) {
   SmallVector<Expr *, 4> Exprs(E->getNumExprs());
-  if (ImportArrayChecked(
-        E->getExprs(), E->getExprs() + E->getNumExprs(), Exprs.begin()))
+  if (ImportContainerChecked(E->exprs(), Exprs))
     return nullptr;
 
   return new (Importer.getToContext()) ParenListExpr(
@@ -5670,6 +5832,38 @@
         T, E->getValueKind(), E->getObjectKind());
 }
 
+Expr *ASTNodeImporter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+    return nullptr;
+
+  TypeSourceInfo *ToQueried = Importer.Import(E->getQueriedTypeSourceInfo());
+  if (!ToQueried)
+    return nullptr;
+
+  Expr *Dim = Importer.Import(E->getDimensionExpression());
+  if (!Dim && E->getDimensionExpression())
+    return nullptr;
+
+  return new (Importer.getToContext()) ArrayTypeTraitExpr(
+        Importer.Import(E->getLocStart()), E->getTrait(), ToQueried,
+        E->getValue(), Dim, Importer.Import(E->getLocEnd()), T);
+}
+
+Expr *ASTNodeImporter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+    return nullptr;
+
+  Expr *ToQueried = Importer.Import(E->getQueriedExpression());
+  if (!ToQueried)
+    return nullptr;
+
+  return new (Importer.getToContext()) ExpressionTraitExpr(
+        Importer.Import(E->getLocStart()), E->getTrait(), ToQueried,
+        E->getValue(), Importer.Import(E->getLocEnd()), T);
+}
+
 Expr *ASTNodeImporter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
   QualType T = Importer.Import(E->getType());
   if (T.isNull())
@@ -5680,10 +5874,28 @@
     return nullptr;
 
   return new (Importer.getToContext()) OpaqueValueExpr(
-        Importer.Import(E->getExprLoc()), T, E->getValueKind(),
+        Importer.Import(E->getLocation()), T, E->getValueKind(),
         E->getObjectKind(), SourceExpr);
 }
 
+Expr *ASTNodeImporter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+    return nullptr;
+
+  Expr *ToLHS = Importer.Import(E->getLHS());
+  if (!ToLHS)
+    return nullptr;
+
+  Expr *ToRHS = Importer.Import(E->getRHS());
+  if (!ToRHS)
+    return nullptr;
+
+  return new (Importer.getToContext()) ArraySubscriptExpr(
+        ToLHS, ToRHS, T, E->getValueKind(), E->getObjectKind(),
+        Importer.Import(E->getRBracketLoc()));
+}
+
 Expr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
   QualType T = Importer.Import(E->getType());
   if (T.isNull())
@@ -5714,11 +5926,14 @@
                                                E->isFPContractable());
 }
 
-static bool ImportCastPath(CastExpr *E, CXXCastPath &Path) {
-  if (E->path_empty()) return false;
-
-  // TODO: import cast paths
-  return true;
+bool ASTNodeImporter::ImportCastPath(CastExpr *CE, CXXCastPath &Path) {
+  for (auto I = CE->path_begin(), E = CE->path_end(); I != E; ++I) {
+    if (CXXBaseSpecifier *Spec = Importer.Import(*I))
+      Path.push_back(Spec);
+    else
+      return true;
+  }
+  return false;
 }
 
 Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
@@ -5738,7 +5953,7 @@
                                   SubExpr, &BasePath, E->getValueKind());
 }
 
-Expr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) {
+Expr *ASTNodeImporter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
   QualType T = Importer.Import(E->getType());
   if (T.isNull())
     return nullptr;
@@ -5755,11 +5970,320 @@
   if (ImportCastPath(E, BasePath))
     return nullptr;
 
-  return CStyleCastExpr::Create(Importer.getToContext(), T,
-                                E->getValueKind(), E->getCastKind(),
-                                SubExpr, &BasePath, TInfo,
-                                Importer.Import(E->getLParenLoc()),
-                                Importer.Import(E->getRParenLoc()));
+  switch (E->getStmtClass()) {
+  case Stmt::CStyleCastExprClass: {
+    CStyleCastExpr *CCE = cast<CStyleCastExpr>(E);
+    return CStyleCastExpr::Create(Importer.getToContext(), T,
+                                  E->getValueKind(), E->getCastKind(),
+                                  SubExpr, &BasePath, TInfo,
+                                  Importer.Import(CCE->getLParenLoc()),
+                                  Importer.Import(CCE->getRParenLoc()));
+  }
+
+  case Stmt::CXXFunctionalCastExprClass: {
+    CXXFunctionalCastExpr *FCE = cast<CXXFunctionalCastExpr>(E);
+    return CXXFunctionalCastExpr::Create(Importer.getToContext(), T,
+                                         E->getValueKind(), TInfo,
+                                         E->getCastKind(), SubExpr, &BasePath,
+                                         Importer.Import(FCE->getLParenLoc()),
+                                         Importer.Import(FCE->getRParenLoc()));
+  }
+
+  case Stmt::ObjCBridgedCastExprClass: {
+      ObjCBridgedCastExpr *OCE = cast<ObjCBridgedCastExpr>(E);
+      return new (Importer.getToContext()) ObjCBridgedCastExpr(
+            Importer.Import(OCE->getLParenLoc()), OCE->getBridgeKind(),
+            E->getCastKind(), Importer.Import(OCE->getBridgeKeywordLoc()),
+            TInfo, SubExpr);
+  }
+  default:
+    break; // just fall through
+  }
+
+  CXXNamedCastExpr *Named = cast<CXXNamedCastExpr>(E);
+  SourceLocation ExprLoc = Importer.Import(Named->getOperatorLoc()),
+      RParenLoc = Importer.Import(Named->getRParenLoc());
+  SourceRange Brackets = Importer.Import(Named->getAngleBrackets());
+
+  switch (E->getStmtClass()) {
+  case Stmt::CXXStaticCastExprClass:
+    return CXXStaticCastExpr::Create(Importer.getToContext(), T,
+                                     E->getValueKind(), E->getCastKind(),
+                                     SubExpr, &BasePath, TInfo,
+                                     ExprLoc, RParenLoc, Brackets);
+
+  case Stmt::CXXDynamicCastExprClass:
+    return CXXDynamicCastExpr::Create(Importer.getToContext(), T,
+                                      E->getValueKind(), E->getCastKind(),
+                                      SubExpr, &BasePath, TInfo,
+                                      ExprLoc, RParenLoc, Brackets);
+
+  case Stmt::CXXReinterpretCastExprClass:
+    return CXXReinterpretCastExpr::Create(Importer.getToContext(), T,
+                                          E->getValueKind(), E->getCastKind(),
+                                          SubExpr, &BasePath, TInfo,
+                                          ExprLoc, RParenLoc, Brackets);
+
+  case Stmt::CXXConstCastExprClass:
+    return CXXConstCastExpr::Create(Importer.getToContext(), T,
+                                    E->getValueKind(), SubExpr, TInfo, ExprLoc,
+                                    RParenLoc, Brackets);
+  default:
+    llvm_unreachable("Cast expression of unsupported type!");
+    return nullptr;
+  }
+}
+
+Expr *ASTNodeImporter::VisitOffsetOfExpr(OffsetOfExpr *OE) {
+  QualType T = Importer.Import(OE->getType());
+  if (T.isNull())
+    return nullptr;
+
+  SmallVector<OffsetOfNode, 4> Nodes;
+  for (int I = 0, E = OE->getNumComponents(); I < E; ++I) {
+    const OffsetOfNode &Node = OE->getComponent(I);
+
+    switch (Node.getKind()) {
+    case OffsetOfNode::Array:
+      Nodes.push_back(OffsetOfNode(Importer.Import(Node.getLocStart()),
+                                   Node.getArrayExprIndex(),
+                                   Importer.Import(Node.getLocEnd())));
+      break;
+
+    case OffsetOfNode::Base: {
+      CXXBaseSpecifier *BS = Importer.Import(Node.getBase());
+      if (!BS && Node.getBase())
+        return nullptr;
+      Nodes.push_back(OffsetOfNode(BS));
+      break;
+    }
+    case OffsetOfNode::Field: {
+      FieldDecl *FD = cast_or_null<FieldDecl>(Importer.Import(Node.getField()));
+      if (!FD)
+        return nullptr;
+      Nodes.push_back(OffsetOfNode(Importer.Import(Node.getLocStart()), FD,
+                                   Importer.Import(Node.getLocEnd())));
+      break;
+    }
+    case OffsetOfNode::Identifier: {
+      IdentifierInfo *ToII = Importer.Import(Node.getFieldName());
+      if (!ToII)
+        return nullptr;
+      Nodes.push_back(OffsetOfNode(Importer.Import(Node.getLocStart()), ToII,
+                                   Importer.Import(Node.getLocEnd())));
+      break;
+    }
+    }
+  }
+
+  SmallVector<Expr *, 4> Exprs(OE->getNumExpressions());
+  for (int I = 0, E = OE->getNumExpressions(); I < E; ++I) {
+    Expr *ToIndexExpr = Importer.Import(OE->getIndexExpr(I));
+    if (!ToIndexExpr)
+      return nullptr;
+    Exprs[I] = ToIndexExpr;
+  }
+
+  TypeSourceInfo *TInfo = Importer.Import(OE->getTypeSourceInfo());
+  if (!TInfo && OE->getTypeSourceInfo())
+    return nullptr;
+
+  return OffsetOfExpr::Create(Importer.getToContext(), T,
+                              Importer.Import(OE->getOperatorLoc()),
+                              TInfo, Nodes, Exprs,
+                              Importer.Import(OE->getRParenLoc()));
+}
+
+Expr *ASTNodeImporter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+    return nullptr;
+
+  Expr *Operand = Importer.Import(E->getOperand());
+  if (!Operand)
+    return nullptr;
+
+  CanThrowResult CanThrow;
+  if (E->isValueDependent())
+    CanThrow = CT_Dependent;
+  else
+    CanThrow = E->getValue() ? CT_Can : CT_Cannot;
+
+  return new (Importer.getToContext()) CXXNoexceptExpr(
+        T, Operand, CanThrow,
+        Importer.Import(E->getLocStart()), Importer.Import(E->getLocEnd()));
+}
+
+Expr *ASTNodeImporter::VisitCXXThrowExpr(CXXThrowExpr *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+    return nullptr;
+
+  Expr *SubExpr = Importer.Import(E->getSubExpr());
+  if (!SubExpr && E->getSubExpr())
+    return nullptr;
+
+  return new (Importer.getToContext()) CXXThrowExpr(
+        SubExpr, T, Importer.Import(E->getThrowLoc()),
+        E->isThrownVariableInScope());
+}
+
+Expr *ASTNodeImporter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
+  ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
+        Importer.Import(E->getParam()));
+  if (!Param)
+    return nullptr;
+
+  return CXXDefaultArgExpr::Create(
+        Importer.getToContext(), Importer.Import(E->getUsedLocation()), Param);
+}
+
+Expr *ASTNodeImporter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+    return nullptr;
+
+  TypeSourceInfo *TypeInfo = Importer.Import(E->getTypeSourceInfo());
+  if (!TypeInfo)
+    return nullptr;
+
+  return new (Importer.getToContext()) CXXScalarValueInitExpr(
+        T, TypeInfo, Importer.Import(E->getRParenLoc()));
+}
+
+Expr *ASTNodeImporter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
+  Expr *SubExpr = Importer.Import(E->getSubExpr());
+  if (!SubExpr)
+    return nullptr;
+
+  auto *Dtor = cast_or_null<CXXDestructorDecl>(
+        Importer.Import(const_cast<CXXDestructorDecl *>(
+                          E->getTemporary()->getDestructor())));
+  if (!Dtor)
+    return nullptr;
+
+  ASTContext &ToCtx = Importer.getToContext();
+  CXXTemporary *Temp = CXXTemporary::Create(ToCtx, Dtor);
+  return CXXBindTemporaryExpr::Create(ToCtx, Temp, SubExpr);
+}
+
+Expr *ASTNodeImporter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *CE) {
+  QualType T = Importer.Import(CE->getType());
+  if (T.isNull())
+    return nullptr;
+
+  SmallVector<Expr *, 8> Args(CE->getNumArgs());
+  if (ImportContainerChecked(CE->arguments(), Args))
+    return nullptr;
+
+  auto *Ctor = cast_or_null<CXXConstructorDecl>(
+        Importer.Import(CE->getConstructor()));
+  if (!Ctor)
+    return nullptr;
+
+  return CXXTemporaryObjectExpr::Create(
+        Importer.getToContext(), T,
+        Importer.Import(CE->getLocStart()),
+        Ctor,
+        CE->isElidable(),
+        Args,
+        CE->hadMultipleCandidates(),
+        CE->isListInitialization(),
+        CE->isStdInitListInitialization(),
+        CE->requiresZeroInitialization(),
+        CE->getConstructionKind(),
+        Importer.Import(CE->getParenOrBraceRange()));
+}
+
+Expr *
+ASTNodeImporter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+    return nullptr;
+
+  Expr *TempE = Importer.Import(E->GetTemporaryExpr());
+  if (!TempE)
+    return nullptr;
+
+  ValueDecl *ExtendedBy = cast_or_null<ValueDecl>(
+        Importer.Import(const_cast<ValueDecl *>(E->getExtendingDecl())));
+  if (!ExtendedBy && E->getExtendingDecl())
+    return nullptr;
+
+  auto *ToMTE =  new (Importer.getToContext()) MaterializeTemporaryExpr(
+        T, TempE, E->isBoundToLvalueReference());
+
+  // FIXME: Should ManglingNumber get numbers associated with 'to' context?
+  ToMTE->setExtendingDecl(ExtendedBy, E->getManglingNumber());
+  return ToMTE;
+}
+
+
+Expr *ASTNodeImporter::VisitCXXNewExpr(CXXNewExpr *CE) {
+  QualType T = Importer.Import(CE->getType());
+  if (T.isNull())
+    return nullptr;
+
+  SmallVector<Expr *, 4> PlacementArgs(CE->getNumPlacementArgs());
+  if (ImportContainerChecked(CE->placement_arguments(), PlacementArgs))
+    return nullptr;
+
+  FunctionDecl *OperatorNewDecl = cast_or_null<FunctionDecl>(
+        Importer.Import(CE->getOperatorNew()));
+  if (!OperatorNewDecl && CE->getOperatorNew())
+    return nullptr;
+
+  FunctionDecl *OperatorDeleteDecl = cast_or_null<FunctionDecl>(
+        Importer.Import(CE->getOperatorDelete()));
+  if (!OperatorDeleteDecl && CE->getOperatorDelete())
+    return nullptr;
+
+  Expr *ToInit = Importer.Import(CE->getInitializer());
+  if (!ToInit && CE->getInitializer())
+    return nullptr;
+
+  TypeSourceInfo *TInfo = Importer.Import(CE->getAllocatedTypeSourceInfo());
+  if (!TInfo)
+    return nullptr;
+
+  Expr *ToArrSize = Importer.Import(CE->getArraySize());
+  if (!ToArrSize && CE->getArraySize())
+    return nullptr;
+
+  return new (Importer.getToContext()) CXXNewExpr(
+        Importer.getToContext(),
+        CE->isGlobalNew(),
+        OperatorNewDecl, OperatorDeleteDecl,
+        CE->doesUsualArrayDeleteWantSize(),
+        PlacementArgs,
+        Importer.Import(CE->getTypeIdParens()),
+        ToArrSize, CE->getInitializationStyle(), ToInit, T, TInfo,
+        Importer.Import(CE->getSourceRange()),
+        Importer.Import(CE->getDirectInitRange()));
+}
+
+Expr *ASTNodeImporter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+    return nullptr;
+
+  FunctionDecl *OperatorDeleteDecl = cast_or_null<FunctionDecl>(
+        Importer.Import(E->getOperatorDelete()));
+  if (!OperatorDeleteDecl && E->getOperatorDelete())
+    return nullptr;
+
+  Expr *ToArg = Importer.Import(E->getArgument());
+  if (!ToArg && E->getArgument())
+    return nullptr;
+
+  return new (Importer.getToContext()) CXXDeleteExpr(
+        T, E->isGlobalDelete(),
+        E->isArrayForm(),
+        E->isArrayFormAsWritten(),
+        E->doesUsualArrayDeleteWantSize(),
+        OperatorDeleteDecl,
+        ToArg,
+        Importer.Import(E->getLocStart()));
 }
 
 Expr *ASTNodeImporter::VisitCXXConstructExpr(CXXConstructExpr *E) {
@@ -5773,8 +6297,7 @@
     return nullptr;
 
   SmallVector<Expr *, 6> ToArgs(E->getNumArgs());
-  if (ImportArrayChecked(E->getArgs(), E->getArgs() + E->getNumArgs(),
-                         ToArgs.begin()))
+  if (ImportContainerChecked(E->arguments(), ToArgs))
     return nullptr;
 
   return CXXConstructExpr::Create(Importer.getToContext(), T,
@@ -5788,6 +6311,22 @@
                                   Importer.Import(E->getParenOrBraceRange()));
 }
 
+Expr *ASTNodeImporter::VisitExprWithCleanups(ExprWithCleanups *EWC) {
+  Expr *SubExpr = Importer.Import(EWC->getSubExpr());
+  if (!SubExpr && EWC->getSubExpr())
+    return NULL;
+
+  SmallVector<ExprWithCleanups::CleanupObject, 8> Objs(EWC->getNumObjects());
+  for (unsigned I = 0, E = EWC->getNumObjects(); I < E; I++)
+    if (ExprWithCleanups::CleanupObject Obj =
+        cast_or_null<BlockDecl>(Importer.Import(EWC->getObject(I))))
+      Objs[I] = Obj;
+    else
+      return nullptr;
+
+  return ExprWithCleanups::Create(Importer.getToContext(), SubExpr, Objs);
+}
+
 Expr *ASTNodeImporter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
   QualType T = Importer.Import(E->getType());
   if (T.isNull())
@@ -5798,8 +6337,7 @@
     return nullptr;
   
   SmallVector<Expr *, 4> ToArgs(E->getNumArgs());
-  
-  if (ImportArrayChecked(E->arg_begin(), E->arg_end(), ToArgs.begin()))
+  if (ImportContainerChecked(E->arguments(), ToArgs))
     return nullptr;
 
   return new (Importer.getToContext()) CXXMemberCallExpr(
@@ -5900,8 +6438,7 @@
     return nullptr;
 
   llvm::SmallVector<Expr *, 4> Exprs(ILE->getNumInits());
-  if (ImportArrayChecked(
-        ILE->getInits(), ILE->getInits() + ILE->getNumInits(), Exprs.begin()))
+  if (ImportContainerChecked(ILE->inits(), Exprs))
     return nullptr;
 
   ASTContext &ToCtx = Importer.getToContext();
@@ -6344,6 +6881,21 @@
   return ToID;
 }
 
+CXXBaseSpecifier *ASTImporter::Import(const CXXBaseSpecifier *BaseSpec) {
+  auto Pos = ImportedCXXBaseSpecifiers.find(BaseSpec);
+  if (Pos != ImportedCXXBaseSpecifiers.end())
+    return Pos->second;
+
+  CXXBaseSpecifier *Imported = new (ToContext) CXXBaseSpecifier(
+        Import(BaseSpec->getSourceRange()),
+        BaseSpec->isVirtual(), BaseSpec->isBaseOfClass(),
+        BaseSpec->getAccessSpecifierAsWritten(),
+        Import(BaseSpec->getTypeSourceInfo()),
+        Import(BaseSpec->getEllipsisLoc()));
+  ImportedCXXBaseSpecifiers[BaseSpec] = Imported;
+  return Imported;
+}
+
 void ASTImporter::ImportDefinition(Decl *From) {
   Decl *To = Import(From);
   if (!To)
Index: include/clang/AST/DeclFriend.h
===================================================================
--- include/clang/AST/DeclFriend.h
+++ include/clang/AST/DeclFriend.h
@@ -166,6 +166,7 @@
 
   friend class ASTDeclReader;
   friend class ASTDeclWriter;
+  friend class ASTNodeImporter;
   friend TrailingObjects;
 };
 
Index: include/clang/AST/ASTImporter.h
===================================================================
--- include/clang/AST/ASTImporter.h
+++ include/clang/AST/ASTImporter.h
@@ -23,6 +23,7 @@
 
 namespace clang {
   class ASTContext;
+  class CXXBaseSpecifier;
   class Decl;
   class DeclContext;
   class DiagnosticsEngine;
@@ -38,7 +39,9 @@
   class ASTImporter {
   public:
     typedef llvm::DenseSet<std::pair<Decl *, Decl *> > NonEquivalentDeclSet;
-    
+    typedef llvm::DenseMap<const CXXBaseSpecifier *, CXXBaseSpecifier *>
+    ImportedCXXBaseSpecifierMap;
+
   private:
     /// \brief The contexts we're importing to and from.
     ASTContext &ToContext, &FromContext;
@@ -67,7 +70,12 @@
     /// \brief Mapping from the already-imported FileIDs in the "from" source
     /// manager to the corresponding FileIDs in the "to" source manager.
     llvm::DenseMap<FileID, FileID> ImportedFileIDs;
-    
+
+    /// \brief Mapping from the already-imported CXXBasesSpecifier in
+    ///  the "from" source manager to the corresponding CXXBasesSpecifier
+    ///  in the "to" source manager.
+    ImportedCXXBaseSpecifierMap ImportedCXXBaseSpecifiers;
+
     /// \brief Imported, anonymous tag declarations that are missing their 
     /// corresponding typedefs.
     SmallVector<TagDecl *, 4> AnonTagsWithPendingTypedefs;
@@ -204,7 +212,14 @@
     /// \returns the equivalent file ID in the source manager of the "to"
     /// context.
     FileID Import(FileID);
-    
+
+    /// \brief Import the given CXXBaseSpecifier from the "from" context into
+    /// the "to" context.
+    ///
+    /// \returns the equivalent CXXBaseSpecifier in the source manager of the
+    /// "to" context.
+    CXXBaseSpecifier *Import(const CXXBaseSpecifier *FromSpec);
+
     /// \brief Import the definition of the given declaration, including all of
     /// the declarations it contains.
     ///
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to