Index: lib/AST/CMakeLists.txt =================================================================== --- lib/AST/CMakeLists.txt +++ lib/AST/CMakeLists.txt @@ -31,6 +31,7 @@ ExprConstant.cpp ExprCXX.cpp ExprObjC.cpp + ExternalASTMerger.cpp ExternalASTSource.cpp InheritViz.cpp ItaniumCXXABI.cpp Index: test/Import/forward-declared-struct/Inputs/S1.c =================================================================== --- test/Import/forward-declared-struct/Inputs/S1.c +++ test/Import/forward-declared-struct/Inputs/S1.c @@ -0,0 +1 @@ +struct S; Index: test/Import/forward-declared-struct/Inputs/S2.c =================================================================== --- test/Import/forward-declared-struct/Inputs/S2.c +++ test/Import/forward-declared-struct/Inputs/S2.c @@ -0,0 +1,3 @@ +struct S { + int a; +}; Index: test/Import/forward-declared-struct/test.c =================================================================== --- test/Import/forward-declared-struct/test.c +++ test/Import/forward-declared-struct/test.c @@ -0,0 +1,5 @@ +// RUN: clang-import-test -import %S/Inputs/S1.c --import %S/Inputs/S2.c -expression %s +void expr() { + struct S MyS; + MyS.a = 3; +} Index: test/Import/member-in-struct/Inputs/S.c =================================================================== --- test/Import/member-in-struct/Inputs/S.c +++ test/Import/member-in-struct/Inputs/S.c @@ -0,0 +1,3 @@ +struct S { + int a; +}; Index: test/Import/member-in-struct/test.c =================================================================== --- test/Import/member-in-struct/test.c +++ test/Import/member-in-struct/test.c @@ -0,0 +1,5 @@ +// RUN: clang-import-test -import %S/Inputs/S.c -expression %s +void expr() { + struct S MyS; + MyS.a = 3; +} Index: test/Import/multiple-forward-declarations/Inputs/S1.c =================================================================== --- test/Import/multiple-forward-declarations/Inputs/S1.c +++ test/Import/multiple-forward-declarations/Inputs/S1.c @@ -0,0 +1 @@ +struct S; Index: test/Import/multiple-forward-declarations/Inputs/S2.c =================================================================== --- test/Import/multiple-forward-declarations/Inputs/S2.c +++ test/Import/multiple-forward-declarations/Inputs/S2.c @@ -0,0 +1 @@ +struct S; Index: test/Import/multiple-forward-declarations/test.c =================================================================== --- test/Import/multiple-forward-declarations/test.c +++ test/Import/multiple-forward-declarations/test.c @@ -0,0 +1,4 @@ +// RUN: clang-import-test -import %S/Inputs/S1.c --import %S/Inputs/S2.c -expression %s +void expr() { + struct S *MySPtr; +} Index: test/Import/overloaded-function/Inputs/F1.c =================================================================== --- test/Import/overloaded-function/Inputs/F1.c +++ test/Import/overloaded-function/Inputs/F1.c @@ -0,0 +1 @@ +void f(int arg) { } Index: test/Import/overloaded-function/Inputs/F2.c =================================================================== --- test/Import/overloaded-function/Inputs/F2.c +++ test/Import/overloaded-function/Inputs/F2.c @@ -0,0 +1,4 @@ +struct S { int a; }; + +void f(const char *arg) { } +void f(S arg) { } Index: test/Import/overloaded-function/test.c =================================================================== --- test/Import/overloaded-function/test.c +++ test/Import/overloaded-function/test.c @@ -0,0 +1,7 @@ +// RUN: clang-import-test -import %S/Inputs/F1.c -import %S/Inputs/F2.c -expression %s +void expr() { + f(2); + f("world"); + S s; + f(s); +} Index: test/Import/struct-in-namespace/Inputs/N1.cpp =================================================================== --- test/Import/struct-in-namespace/Inputs/N1.cpp +++ test/Import/struct-in-namespace/Inputs/N1.cpp @@ -0,0 +1,11 @@ +namespace N { + struct S { + int a; + }; +} + +namespace N { + struct T { + int b; + }; +} Index: test/Import/struct-in-namespace/Inputs/N2.cpp =================================================================== --- test/Import/struct-in-namespace/Inputs/N2.cpp +++ test/Import/struct-in-namespace/Inputs/N2.cpp @@ -0,0 +1,5 @@ +namespace N { + struct U { + int c; + }; +} Index: test/Import/struct-in-namespace/Inputs/N3.cpp =================================================================== --- test/Import/struct-in-namespace/Inputs/N3.cpp +++ test/Import/struct-in-namespace/Inputs/N3.cpp @@ -0,0 +1,5 @@ +namespace M { + struct V { + int d; + }; +} Index: test/Import/struct-in-namespace/test.cpp =================================================================== --- test/Import/struct-in-namespace/test.cpp +++ test/Import/struct-in-namespace/test.cpp @@ -0,0 +1,7 @@ +// RUN: clang-import-test -import %S/Inputs/N1.cpp -import %S/Inputs/N2.cpp -import %S/Inputs/N3.cpp -expression %s +void expr() { + N::S s; + N::T t; + N::U u; + int d = s.a + t.b + u.c; +} Index: test/Import/template-specialization/Inputs/T.cpp =================================================================== --- test/Import/template-specialization/Inputs/T.cpp +++ test/Import/template-specialization/Inputs/T.cpp @@ -0,0 +1,14 @@ +template struct A { +}; + +template <> struct A { + struct B { + int f; + }; +}; + +template <> struct A { + struct B { + int g; + }; +}; Index: test/Import/template-specialization/test.cpp =================================================================== --- test/Import/template-specialization/test.cpp +++ test/Import/template-specialization/test.cpp @@ -0,0 +1,7 @@ +// RUN: clang-import-test -import %S/Inputs/T.cpp -expression %s +// XFAIL: * +void expr() { + A::B b1; + A::B b2; + b1.f + b2.g; +} Index: tools/clang-import-test/clang-import-test.cpp =================================================================== --- tools/clang-import-test/clang-import-test.cpp +++ tools/clang-import-test/clang-import-test.cpp @@ -9,6 +9,8 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/ASTImporter.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/ExternalASTMerger.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/SourceLocation.h" @@ -189,61 +191,18 @@ } // end namespace namespace { -class TestExternalASTSource : public ExternalASTSource { -private: - llvm::ArrayRef> ImportCIs; - std::map> ForwardImporters; - std::map> ReverseImporters; - -public: - TestExternalASTSource( - CompilerInstance &ExpressionCI, - llvm::ArrayRef> ImportCIs) - : ImportCIs(ImportCIs) { - for (const std::unique_ptr &ImportCI : ImportCIs) { - ForwardImporters[ImportCI.get()] = llvm::make_unique( - ExpressionCI.getASTContext(), ExpressionCI.getFileManager(), - ImportCI->getASTContext(), ImportCI->getFileManager(), - /*MinimalImport=*/true); - ReverseImporters[ImportCI.get()] = llvm::make_unique( - ImportCI->getASTContext(), ImportCI->getFileManager(), - ExpressionCI.getASTContext(), ExpressionCI.getFileManager(), - /*MinimalImport=*/true); - } - } - - bool FindExternalVisibleDeclsByName(const DeclContext *DC, - DeclarationName Name) override { - llvm::SmallVector Decls; - - if (isa(DC)) { - for (const std::unique_ptr &I : ImportCIs) { - DeclarationName FromName = ReverseImporters[I.get()]->Import(Name); - DeclContextLookupResult Result = - I->getASTContext().getTranslationUnitDecl()->lookup(FromName); - for (NamedDecl *FromD : Result) { - NamedDecl *D = - llvm::cast(ForwardImporters[I.get()]->Import(FromD)); - Decls.push_back(D); - } - } - } - if (Decls.empty()) { - return false; - } else { - SetExternalVisibleDeclsForName(DC, Name, Decls); - return true; - } - } -}; - + void AddExternalSource( CompilerInstance &CI, llvm::ArrayRef> Imports) { - ASTContext &AST = CI.getASTContext(); - auto ES = llvm::make_unique(CI, Imports); - AST.setExternalSource(ES.release()); - AST.getTranslationUnitDecl()->setHasExternalVisibleStorage(); + ExternalASTMerger::ImporterEndpoint Target({CI.getASTContext(), CI.getFileManager()}); + llvm::SmallVector Sources; + for (const std::unique_ptr &CI : Imports) { + Sources.push_back({CI->getASTContext(), CI->getFileManager()}); + } + auto ES = llvm::make_unique(Target, Sources); + CI.getASTContext().setExternalSource(ES.release()); + CI.getASTContext().getTranslationUnitDecl()->setHasExternalVisibleStorage(); } llvm::Error ParseSource(const std::string &Path, CompilerInstance &CI, @@ -292,6 +251,7 @@ return std::move(CI); } } + } // end namespace int main(int argc, const char **argv) {