1*67e74705SXin Li //===-- ASTMerge.cpp - AST Merging Frontent Action --------------*- C++ -*-===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li #include "clang/Frontend/ASTUnit.h"
10*67e74705SXin Li #include "clang/AST/ASTContext.h"
11*67e74705SXin Li #include "clang/AST/ASTDiagnostic.h"
12*67e74705SXin Li #include "clang/AST/ASTImporter.h"
13*67e74705SXin Li #include "clang/Basic/Diagnostic.h"
14*67e74705SXin Li #include "clang/Frontend/CompilerInstance.h"
15*67e74705SXin Li #include "clang/Frontend/FrontendActions.h"
16*67e74705SXin Li
17*67e74705SXin Li using namespace clang;
18*67e74705SXin Li
19*67e74705SXin Li std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)20*67e74705SXin Li ASTMergeAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
21*67e74705SXin Li return AdaptedAction->CreateASTConsumer(CI, InFile);
22*67e74705SXin Li }
23*67e74705SXin Li
BeginSourceFileAction(CompilerInstance & CI,StringRef Filename)24*67e74705SXin Li bool ASTMergeAction::BeginSourceFileAction(CompilerInstance &CI,
25*67e74705SXin Li StringRef Filename) {
26*67e74705SXin Li // FIXME: This is a hack. We need a better way to communicate the
27*67e74705SXin Li // AST file, compiler instance, and file name than member variables
28*67e74705SXin Li // of FrontendAction.
29*67e74705SXin Li AdaptedAction->setCurrentInput(getCurrentInput(), takeCurrentASTUnit());
30*67e74705SXin Li AdaptedAction->setCompilerInstance(&CI);
31*67e74705SXin Li return AdaptedAction->BeginSourceFileAction(CI, Filename);
32*67e74705SXin Li }
33*67e74705SXin Li
ExecuteAction()34*67e74705SXin Li void ASTMergeAction::ExecuteAction() {
35*67e74705SXin Li CompilerInstance &CI = getCompilerInstance();
36*67e74705SXin Li CI.getDiagnostics().getClient()->BeginSourceFile(
37*67e74705SXin Li CI.getASTContext().getLangOpts());
38*67e74705SXin Li CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument,
39*67e74705SXin Li &CI.getASTContext());
40*67e74705SXin Li IntrusiveRefCntPtr<DiagnosticIDs>
41*67e74705SXin Li DiagIDs(CI.getDiagnostics().getDiagnosticIDs());
42*67e74705SXin Li for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) {
43*67e74705SXin Li IntrusiveRefCntPtr<DiagnosticsEngine>
44*67e74705SXin Li Diags(new DiagnosticsEngine(DiagIDs, &CI.getDiagnosticOpts(),
45*67e74705SXin Li new ForwardingDiagnosticConsumer(
46*67e74705SXin Li *CI.getDiagnostics().getClient()),
47*67e74705SXin Li /*ShouldOwnClient=*/true));
48*67e74705SXin Li std::unique_ptr<ASTUnit> Unit =
49*67e74705SXin Li ASTUnit::LoadFromASTFile(ASTFiles[I], CI.getPCHContainerReader(),
50*67e74705SXin Li Diags, CI.getFileSystemOpts(), false);
51*67e74705SXin Li
52*67e74705SXin Li if (!Unit)
53*67e74705SXin Li continue;
54*67e74705SXin Li
55*67e74705SXin Li ASTImporter Importer(CI.getASTContext(),
56*67e74705SXin Li CI.getFileManager(),
57*67e74705SXin Li Unit->getASTContext(),
58*67e74705SXin Li Unit->getFileManager(),
59*67e74705SXin Li /*MinimalImport=*/false);
60*67e74705SXin Li
61*67e74705SXin Li TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
62*67e74705SXin Li for (auto *D : TU->decls()) {
63*67e74705SXin Li // Don't re-import __va_list_tag, __builtin_va_list.
64*67e74705SXin Li if (const auto *ND = dyn_cast<NamedDecl>(D))
65*67e74705SXin Li if (IdentifierInfo *II = ND->getIdentifier())
66*67e74705SXin Li if (II->isStr("__va_list_tag") || II->isStr("__builtin_va_list"))
67*67e74705SXin Li continue;
68*67e74705SXin Li
69*67e74705SXin Li Decl *ToD = Importer.Import(D);
70*67e74705SXin Li
71*67e74705SXin Li if (ToD) {
72*67e74705SXin Li DeclGroupRef DGR(ToD);
73*67e74705SXin Li CI.getASTConsumer().HandleTopLevelDecl(DGR);
74*67e74705SXin Li }
75*67e74705SXin Li }
76*67e74705SXin Li }
77*67e74705SXin Li
78*67e74705SXin Li AdaptedAction->ExecuteAction();
79*67e74705SXin Li CI.getDiagnostics().getClient()->EndSourceFile();
80*67e74705SXin Li }
81*67e74705SXin Li
EndSourceFileAction()82*67e74705SXin Li void ASTMergeAction::EndSourceFileAction() {
83*67e74705SXin Li return AdaptedAction->EndSourceFileAction();
84*67e74705SXin Li }
85*67e74705SXin Li
ASTMergeAction(std::unique_ptr<FrontendAction> adaptedAction,ArrayRef<std::string> ASTFiles)86*67e74705SXin Li ASTMergeAction::ASTMergeAction(std::unique_ptr<FrontendAction> adaptedAction,
87*67e74705SXin Li ArrayRef<std::string> ASTFiles)
88*67e74705SXin Li : AdaptedAction(std::move(adaptedAction)), ASTFiles(ASTFiles.begin(), ASTFiles.end()) {
89*67e74705SXin Li assert(AdaptedAction && "ASTMergeAction needs an action to adapt");
90*67e74705SXin Li }
91*67e74705SXin Li
~ASTMergeAction()92*67e74705SXin Li ASTMergeAction::~ASTMergeAction() {
93*67e74705SXin Li }
94*67e74705SXin Li
usesPreprocessorOnly() const95*67e74705SXin Li bool ASTMergeAction::usesPreprocessorOnly() const {
96*67e74705SXin Li return AdaptedAction->usesPreprocessorOnly();
97*67e74705SXin Li }
98*67e74705SXin Li
getTranslationUnitKind()99*67e74705SXin Li TranslationUnitKind ASTMergeAction::getTranslationUnitKind() {
100*67e74705SXin Li return AdaptedAction->getTranslationUnitKind();
101*67e74705SXin Li }
102*67e74705SXin Li
hasPCHSupport() const103*67e74705SXin Li bool ASTMergeAction::hasPCHSupport() const {
104*67e74705SXin Li return AdaptedAction->hasPCHSupport();
105*67e74705SXin Li }
106*67e74705SXin Li
hasASTFileSupport() const107*67e74705SXin Li bool ASTMergeAction::hasASTFileSupport() const {
108*67e74705SXin Li return AdaptedAction->hasASTFileSupport();
109*67e74705SXin Li }
110*67e74705SXin Li
hasCodeCompletionSupport() const111*67e74705SXin Li bool ASTMergeAction::hasCodeCompletionSupport() const {
112*67e74705SXin Li return AdaptedAction->hasCodeCompletionSupport();
113*67e74705SXin Li }
114