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