// We may already have a record of the same name; try to find and match it.
RecordDecl *AdoptDecl = nullptr;
+ RecordDecl *PrevDecl = nullptr;
if (!DC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
SmallVector<NamedDecl *, 2> FoundDecls;
DC->getRedeclContext()->localUncachedLookup(SearchName, FoundDecls);
+
+ if (!FoundDecls.empty()) {
+ // We're going to have to compare D against potentially conflicting Decls, so complete it.
+ if (D->hasExternalLexicalStorage() && !D->isCompleteDefinition())
+ D->getASTContext().getExternalSource()->CompleteType(D);
+ }
+
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
continue;
}
}
+ PrevDecl = FoundRecord;
+
if (RecordDecl *FoundDef = FoundRecord->getDefinition()) {
if ((SearchName && !D->isCompleteDefinition())
|| (D->isCompleteDefinition() &&
LexicalDC->addDeclInternal(D2);
if (D->isAnonymousStructOrUnion())
D2->setAnonymousStructOrUnion(true);
+ if (PrevDecl) {
+ // FIXME: do this for all Redeclarables, not just RecordDecls.
+ D2->setPreviousDecl(PrevDecl);
+ }
}
Importer.Imported(D, D2);
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"),
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>(
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();
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 =
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);
return 0;
}
}
+