Path: blob/main/contrib/llvm-project/clang/lib/Frontend/ASTMerge.cpp
35232 views
//===-- ASTMerge.cpp - AST Merging Frontend Action --------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7#include "clang/Frontend/ASTUnit.h"8#include "clang/AST/ASTContext.h"9#include "clang/AST/ASTDiagnostic.h"10#include "clang/AST/ASTImporter.h"11#include "clang/AST/ASTImporterSharedState.h"12#include "clang/Basic/Diagnostic.h"13#include "clang/Frontend/CompilerInstance.h"14#include "clang/Frontend/FrontendActions.h"1516using namespace clang;1718std::unique_ptr<ASTConsumer>19ASTMergeAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {20return AdaptedAction->CreateASTConsumer(CI, InFile);21}2223bool ASTMergeAction::BeginSourceFileAction(CompilerInstance &CI) {24// FIXME: This is a hack. We need a better way to communicate the25// AST file, compiler instance, and file name than member variables26// of FrontendAction.27AdaptedAction->setCurrentInput(getCurrentInput(), takeCurrentASTUnit());28AdaptedAction->setCompilerInstance(&CI);29return AdaptedAction->BeginSourceFileAction(CI);30}3132void ASTMergeAction::ExecuteAction() {33CompilerInstance &CI = getCompilerInstance();34CI.getDiagnostics().getClient()->BeginSourceFile(35CI.getASTContext().getLangOpts());36CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument,37&CI.getASTContext());38IntrusiveRefCntPtr<DiagnosticIDs>39DiagIDs(CI.getDiagnostics().getDiagnosticIDs());40auto SharedState = std::make_shared<ASTImporterSharedState>(41*CI.getASTContext().getTranslationUnitDecl());42for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) {43IntrusiveRefCntPtr<DiagnosticsEngine>44Diags(new DiagnosticsEngine(DiagIDs, &CI.getDiagnosticOpts(),45new ForwardingDiagnosticConsumer(46*CI.getDiagnostics().getClient()),47/*ShouldOwnClient=*/true));48std::unique_ptr<ASTUnit> Unit = ASTUnit::LoadFromASTFile(49ASTFiles[I], CI.getPCHContainerReader(), ASTUnit::LoadEverything, Diags,50CI.getFileSystemOpts(), CI.getHeaderSearchOptsPtr());5152if (!Unit)53continue;5455ASTImporter Importer(CI.getASTContext(), CI.getFileManager(),56Unit->getASTContext(), Unit->getFileManager(),57/*MinimalImport=*/false, SharedState);5859TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();60for (auto *D : TU->decls()) {61// Don't re-import __va_list_tag, __builtin_va_list.62if (const auto *ND = dyn_cast<NamedDecl>(D))63if (IdentifierInfo *II = ND->getIdentifier())64if (II->isStr("__va_list_tag") || II->isStr("__builtin_va_list"))65continue;6667llvm::Expected<Decl *> ToDOrError = Importer.Import(D);6869if (ToDOrError) {70DeclGroupRef DGR(*ToDOrError);71CI.getASTConsumer().HandleTopLevelDecl(DGR);72} else {73llvm::consumeError(ToDOrError.takeError());74}75}76}7778AdaptedAction->ExecuteAction();79CI.getDiagnostics().getClient()->EndSourceFile();80}8182void ASTMergeAction::EndSourceFileAction() {83return AdaptedAction->EndSourceFileAction();84}8586ASTMergeAction::ASTMergeAction(std::unique_ptr<FrontendAction> adaptedAction,87ArrayRef<std::string> ASTFiles)88: AdaptedAction(std::move(adaptedAction)), ASTFiles(ASTFiles.begin(), ASTFiles.end()) {89assert(AdaptedAction && "ASTMergeAction needs an action to adapt");90}9192ASTMergeAction::~ASTMergeAction() {93}9495bool ASTMergeAction::usesPreprocessorOnly() const {96return AdaptedAction->usesPreprocessorOnly();97}9899TranslationUnitKind ASTMergeAction::getTranslationUnitKind() {100return AdaptedAction->getTranslationUnitKind();101}102103bool ASTMergeAction::hasPCHSupport() const {104return AdaptedAction->hasPCHSupport();105}106107bool ASTMergeAction::hasASTFileSupport() const {108return AdaptedAction->hasASTFileSupport();109}110111bool ASTMergeAction::hasCodeCompletionSupport() const {112return AdaptedAction->hasCodeCompletionSupport();113}114115116