xref: /freebsd/contrib/llvm-project/clang/lib/Frontend/ASTMerge.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric //===-- ASTMerge.cpp - AST Merging Frontend Action --------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric #include "clang/Frontend/ASTUnit.h"
90b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
100b57cec5SDimitry Andric #include "clang/AST/ASTDiagnostic.h"
110b57cec5SDimitry Andric #include "clang/AST/ASTImporter.h"
120b57cec5SDimitry Andric #include "clang/AST/ASTImporterSharedState.h"
130b57cec5SDimitry Andric #include "clang/Basic/Diagnostic.h"
140b57cec5SDimitry Andric #include "clang/Frontend/CompilerInstance.h"
150b57cec5SDimitry Andric #include "clang/Frontend/FrontendActions.h"
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric using namespace clang;
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric std::unique_ptr<ASTConsumer>
200b57cec5SDimitry Andric ASTMergeAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
210b57cec5SDimitry Andric   return AdaptedAction->CreateASTConsumer(CI, InFile);
220b57cec5SDimitry Andric }
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric bool ASTMergeAction::BeginSourceFileAction(CompilerInstance &CI) {
250b57cec5SDimitry Andric   // FIXME: This is a hack. We need a better way to communicate the
260b57cec5SDimitry Andric   // AST file, compiler instance, and file name than member variables
270b57cec5SDimitry Andric   // of FrontendAction.
280b57cec5SDimitry Andric   AdaptedAction->setCurrentInput(getCurrentInput(), takeCurrentASTUnit());
290b57cec5SDimitry Andric   AdaptedAction->setCompilerInstance(&CI);
300b57cec5SDimitry Andric   return AdaptedAction->BeginSourceFileAction(CI);
310b57cec5SDimitry Andric }
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric void ASTMergeAction::ExecuteAction() {
340b57cec5SDimitry Andric   CompilerInstance &CI = getCompilerInstance();
350b57cec5SDimitry Andric   CI.getDiagnostics().getClient()->BeginSourceFile(
360b57cec5SDimitry Andric                                              CI.getASTContext().getLangOpts());
370b57cec5SDimitry Andric   CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument,
380b57cec5SDimitry Andric                                        &CI.getASTContext());
390b57cec5SDimitry Andric   IntrusiveRefCntPtr<DiagnosticIDs>
400b57cec5SDimitry Andric       DiagIDs(CI.getDiagnostics().getDiagnosticIDs());
410b57cec5SDimitry Andric   auto SharedState = std::make_shared<ASTImporterSharedState>(
420b57cec5SDimitry Andric       *CI.getASTContext().getTranslationUnitDecl());
430b57cec5SDimitry Andric   for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) {
440b57cec5SDimitry Andric     IntrusiveRefCntPtr<DiagnosticsEngine>
450b57cec5SDimitry Andric         Diags(new DiagnosticsEngine(DiagIDs, &CI.getDiagnosticOpts(),
460b57cec5SDimitry Andric                                     new ForwardingDiagnosticConsumer(
470b57cec5SDimitry Andric                                           *CI.getDiagnostics().getClient()),
480b57cec5SDimitry Andric                                     /*ShouldOwnClient=*/true));
490b57cec5SDimitry Andric     std::unique_ptr<ASTUnit> Unit = ASTUnit::LoadFromASTFile(
500b57cec5SDimitry Andric         ASTFiles[I], CI.getPCHContainerReader(), ASTUnit::LoadEverything, Diags,
51*5f757f3fSDimitry Andric         CI.getFileSystemOpts(), CI.getHeaderSearchOptsPtr());
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric     if (!Unit)
540b57cec5SDimitry Andric       continue;
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric     ASTImporter Importer(CI.getASTContext(), CI.getFileManager(),
570b57cec5SDimitry Andric                          Unit->getASTContext(), Unit->getFileManager(),
580b57cec5SDimitry Andric                          /*MinimalImport=*/false, SharedState);
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric     TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
610b57cec5SDimitry Andric     for (auto *D : TU->decls()) {
620b57cec5SDimitry Andric       // Don't re-import __va_list_tag, __builtin_va_list.
630b57cec5SDimitry Andric       if (const auto *ND = dyn_cast<NamedDecl>(D))
640b57cec5SDimitry Andric         if (IdentifierInfo *II = ND->getIdentifier())
650b57cec5SDimitry Andric           if (II->isStr("__va_list_tag") || II->isStr("__builtin_va_list"))
660b57cec5SDimitry Andric             continue;
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric       llvm::Expected<Decl *> ToDOrError = Importer.Import(D);
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric       if (ToDOrError) {
710b57cec5SDimitry Andric         DeclGroupRef DGR(*ToDOrError);
720b57cec5SDimitry Andric         CI.getASTConsumer().HandleTopLevelDecl(DGR);
730b57cec5SDimitry Andric       } else {
740b57cec5SDimitry Andric         llvm::consumeError(ToDOrError.takeError());
750b57cec5SDimitry Andric       }
760b57cec5SDimitry Andric     }
770b57cec5SDimitry Andric   }
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric   AdaptedAction->ExecuteAction();
800b57cec5SDimitry Andric   CI.getDiagnostics().getClient()->EndSourceFile();
810b57cec5SDimitry Andric }
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric void ASTMergeAction::EndSourceFileAction() {
840b57cec5SDimitry Andric   return AdaptedAction->EndSourceFileAction();
850b57cec5SDimitry Andric }
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric ASTMergeAction::ASTMergeAction(std::unique_ptr<FrontendAction> adaptedAction,
880b57cec5SDimitry Andric                                ArrayRef<std::string> ASTFiles)
890b57cec5SDimitry Andric : AdaptedAction(std::move(adaptedAction)), ASTFiles(ASTFiles.begin(), ASTFiles.end()) {
900b57cec5SDimitry Andric   assert(AdaptedAction && "ASTMergeAction needs an action to adapt");
910b57cec5SDimitry Andric }
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric ASTMergeAction::~ASTMergeAction() {
940b57cec5SDimitry Andric }
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric bool ASTMergeAction::usesPreprocessorOnly() const {
970b57cec5SDimitry Andric   return AdaptedAction->usesPreprocessorOnly();
980b57cec5SDimitry Andric }
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric TranslationUnitKind ASTMergeAction::getTranslationUnitKind() {
1010b57cec5SDimitry Andric   return AdaptedAction->getTranslationUnitKind();
1020b57cec5SDimitry Andric }
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric bool ASTMergeAction::hasPCHSupport() const {
1050b57cec5SDimitry Andric   return AdaptedAction->hasPCHSupport();
1060b57cec5SDimitry Andric }
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric bool ASTMergeAction::hasASTFileSupport() const {
1090b57cec5SDimitry Andric   return AdaptedAction->hasASTFileSupport();
1100b57cec5SDimitry Andric }
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric bool ASTMergeAction::hasCodeCompletionSupport() const {
1130b57cec5SDimitry Andric   return AdaptedAction->hasCodeCompletionSupport();
1140b57cec5SDimitry Andric }
115