diff options
author | Sean Callanan <scallanan@apple.com> | 2017-05-13 00:46:33 +0000 |
---|---|---|
committer | Sean Callanan <scallanan@apple.com> | 2017-05-13 00:46:33 +0000 |
commit | 848b631d3a1e857e2ad2fe61f09ad6de50e89c25 (patch) | |
tree | a028b8cccb5b573b0fe77c7e7b27bc72387e8d29 /tools | |
parent | ab2094bec03b5d0c32f484bd3730e1f47846e3e8 (diff) |
[ASTImporter] Improve handling of incomplete types
ASTImporter has some bugs when it's importing types
that themselves come from an ExternalASTSource. This
is exposed particularly in the behavior when
comparing complete TagDecls with forward
declarations. This patch does several things:
- Adds a test case making sure that conflicting
forward-declarations are resolved correctly;
- Extends the clang-import-test harness to test
two-level importing, so that we make sure we
complete types when necessary; and
- Fixes a few bugs I found this way. Failure to
complete types was one; however, I also discovered
that complete RecordDecls aren't properly added to
the redecls chain for existing forward
declarations.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@302975 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools')
-rw-r--r-- | tools/clang-import-test/clang-import-test.cpp | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/tools/clang-import-test/clang-import-test.cpp b/tools/clang-import-test/clang-import-test.cpp index d7ab18478c..567a4bb4f0 100644 --- a/tools/clang-import-test/clang-import-test.cpp +++ b/tools/clang-import-test/clang-import-test.cpp @@ -42,6 +42,10 @@ static llvm::cl::list<std::string> Imports("import", llvm::cl::ZeroOrMore, llvm::cl::desc("Path to a file containing declarations to import")); +static llvm::cl::opt<bool> + Direct("direct", llvm::cl::Optional, + llvm::cl::desc("Use the parsed declarations without indirection")); + static llvm::cl::list<std::string> ClangArgs("Xcc", llvm::cl::ZeroOrMore, llvm::cl::desc("Argument to pass to the CompilerInvocation"), @@ -172,6 +176,14 @@ BuildCompilerInstance(ArrayRef<const char *> ClangArgv) { return Ins; } +std::unique_ptr<CompilerInstance> +BuildCompilerInstance(ArrayRef<std::string> ClangArgs) { + std::vector<const char *> ClangArgv(ClangArgs.size()); + std::transform(ClangArgs.begin(), ClangArgs.end(), ClangArgv.begin(), + [](const std::string &s) -> const char * { return s.data(); }); + return init_convenience::BuildCompilerInstance(ClangArgv); +} + std::unique_ptr<ASTContext> BuildASTContext(CompilerInstance &CI, SelectorTable &ST, Builtin::Context &BC) { auto AST = llvm::make_unique<ASTContext>( @@ -205,6 +217,21 @@ void AddExternalSource( CI.getASTContext().getTranslationUnitDecl()->setHasExternalVisibleStorage(); } +std::unique_ptr<CompilerInstance> BuildIndirect(std::unique_ptr<CompilerInstance> &CI) { + std::vector<const char *> ClangArgv(ClangArgs.size()); + std::transform(ClangArgs.begin(), ClangArgs.end(), ClangArgv.begin(), + [](const std::string &s) -> const char * { return s.data(); }); + std::unique_ptr<CompilerInstance> IndirectCI = + init_convenience::BuildCompilerInstance(ClangArgv); + auto ST = llvm::make_unique<SelectorTable>(); + auto BC = llvm::make_unique<Builtin::Context>(); + std::unique_ptr<ASTContext> AST = + init_convenience::BuildASTContext(*IndirectCI, *ST, *BC); + IndirectCI->setASTContext(AST.release()); + AddExternalSource(*IndirectCI, CI); + return IndirectCI; +} + llvm::Error ParseSource(const std::string &Path, CompilerInstance &CI, CodeGenerator &CG) { SourceManager &SM = CI.getSourceManager(); @@ -231,7 +258,8 @@ Parse(const std::string &Path, std::unique_ptr<ASTContext> AST = init_convenience::BuildASTContext(*CI, *ST, *BC); CI->setASTContext(AST.release()); - AddExternalSource(*CI, Imports); + if (Imports.size()) + AddExternalSource(*CI, Imports); auto LLVMCtx = llvm::make_unique<llvm::LLVMContext>(); std::unique_ptr<CodeGenerator> CG = @@ -268,8 +296,21 @@ int main(int argc, const char **argv) { ImportCIs.push_back(std::move(*ImportCI)); } } + std::vector<std::unique_ptr<CompilerInstance>> IndirectCIs; + if (!Direct) { + for (auto &ImportCI : ImportCIs) { + llvm::Expected<std::unique_ptr<CompilerInstance>> IndirectCI = + BuildIndirect(ImportCI); + if (auto E = IndirectCI.takeError()) { + llvm::errs() << llvm::toString(std::move(E)); + exit(-1); + } else { + IndirectCIs.push_back(std::move(*IndirectCI)); + } + } + } llvm::Expected<std::unique_ptr<CompilerInstance>> ExpressionCI = - Parse(Expression, ImportCIs); + Parse(Expression, Direct ? ImportCIs : IndirectCIs); if (auto E = ExpressionCI.takeError()) { llvm::errs() << llvm::toString(std::move(E)); exit(-1); @@ -277,3 +318,4 @@ int main(int argc, const char **argv) { return 0; } } + |