19bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor//===-- ASTMerge.cpp - AST Merging Frontent Action --------------*- C++ -*-===//
29bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor//
39bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor//                     The LLVM Compiler Infrastructure
49bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor//
59bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor// This file is distributed under the University of Illinois Open Source
69bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor// License. See LICENSE.TXT for details.
79bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor//
89bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor//===----------------------------------------------------------------------===//
99bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor#include "clang/Frontend/ASTUnit.h"
109bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor#include "clang/AST/ASTContext.h"
11d343ff623eb11e277f1e70bca16073e424d8a30dDouglas Gregor#include "clang/AST/ASTDiagnostic.h"
129bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor#include "clang/AST/ASTImporter.h"
1328019772db70d4547be05a042eb950bc910f134fDouglas Gregor#include "clang/Basic/Diagnostic.h"
1455fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Frontend/CompilerInstance.h"
1555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Frontend/FrontendActions.h"
169bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
179bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorusing namespace clang;
189bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
19176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstd::unique_ptr<ASTConsumer>
20176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesASTMergeAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
219bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  return AdaptedAction->CreateASTConsumer(CI, InFile);
229bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
239bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
249bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorbool ASTMergeAction::BeginSourceFileAction(CompilerInstance &CI,
255f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                           StringRef Filename) {
269bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  // FIXME: This is a hack. We need a better way to communicate the
279bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  // AST file, compiler instance, and file name than member variables
289bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  // of FrontendAction.
291f6b2b5c82b2d2d3935b0db76352a04e9877b73fDouglas Gregor  AdaptedAction->setCurrentInput(getCurrentInput(), takeCurrentASTUnit());
309bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  AdaptedAction->setCompilerInstance(&CI);
319bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  return AdaptedAction->BeginSourceFileAction(CI, Filename);
329bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
339bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
349bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorvoid ASTMergeAction::ExecuteAction() {
359bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  CompilerInstance &CI = getCompilerInstance();
360f962a8e61e1c094a89df17f9d3ad947d31c4e5cDouglas Gregor  CI.getDiagnostics().getClient()->BeginSourceFile(
37a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor                                             CI.getASTContext().getLangOpts());
38d343ff623eb11e277f1e70bca16073e424d8a30dDouglas Gregor  CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument,
39d343ff623eb11e277f1e70bca16073e424d8a30dDouglas Gregor                                       &CI.getASTContext());
40c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith  IntrusiveRefCntPtr<DiagnosticIDs>
4133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      DiagIDs(CI.getDiagnostics().getDiagnosticIDs());
429bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) {
43c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith    IntrusiveRefCntPtr<DiagnosticsEngine>
4402c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor        Diags(new DiagnosticsEngine(DiagIDs, &CI.getDiagnosticOpts(),
45a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor                                    new ForwardingDiagnosticConsumer(
46a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor                                          *CI.getDiagnostics().getClient()),
47a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor                                    /*ShouldOwnClient=*/true));
4887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    std::unique_ptr<ASTUnit> Unit =
4987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar        ASTUnit::LoadFromASTFile(ASTFiles[I], CI.getPCHContainerReader(),
5087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                 Diags, CI.getFileSystemOpts(), false);
5187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
529bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor    if (!Unit)
539bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor      continue;
549bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
5533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    ASTImporter Importer(CI.getASTContext(),
56885237354fd902998c6ae9d7cc3dc8de96b123dcDouglas Gregor                         CI.getFileManager(),
57885237354fd902998c6ae9d7cc3dc8de96b123dcDouglas Gregor                         Unit->getASTContext(),
58d8868a634d4fd362243dc646e58c3cf956c81dcdDouglas Gregor                         Unit->getFileManager(),
59d8868a634d4fd362243dc646e58c3cf956c81dcdDouglas Gregor                         /*MinimalImport=*/false);
609bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
619bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor    TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
62651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (auto *D : TU->decls()) {
639a945853ca0c2b4cac07056542b19f25a83f1288Douglas Gregor      // Don't re-import __va_list_tag, __builtin_va_list.
64651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (const auto *ND = dyn_cast<NamedDecl>(D))
659a945853ca0c2b4cac07056542b19f25a83f1288Douglas Gregor        if (IdentifierInfo *II = ND->getIdentifier())
669a945853ca0c2b4cac07056542b19f25a83f1288Douglas Gregor          if (II->isStr("__va_list_tag") || II->isStr("__builtin_va_list"))
679a945853ca0c2b4cac07056542b19f25a83f1288Douglas Gregor            continue;
689a945853ca0c2b4cac07056542b19f25a83f1288Douglas Gregor
69b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      Decl *ToD = Importer.Import(D);
70b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar
71b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      if (ToD) {
72b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        DeclGroupRef DGR(ToD);
73b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar        CI.getASTConsumer().HandleTopLevelDecl(DGR);
74b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar      }
759bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor    }
769bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  }
779bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
780f962a8e61e1c094a89df17f9d3ad947d31c4e5cDouglas Gregor  AdaptedAction->ExecuteAction();
790f962a8e61e1c094a89df17f9d3ad947d31c4e5cDouglas Gregor  CI.getDiagnostics().getClient()->EndSourceFile();
809bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
819bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
829bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorvoid ASTMergeAction::EndSourceFileAction() {
839bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  return AdaptedAction->EndSourceFileAction();
849bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
859bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
864967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarASTMergeAction::ASTMergeAction(std::unique_ptr<FrontendAction> adaptedAction,
87b3ca2637a9a3aeac5c7103eb4d612528680e7e20Argyrios Kyrtzidis                               ArrayRef<std::string> ASTFiles)
884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar: AdaptedAction(std::move(adaptedAction)), ASTFiles(ASTFiles.begin(), ASTFiles.end()) {
899bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  assert(AdaptedAction && "ASTMergeAction needs an action to adapt");
909bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
919bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
929bed8798964d9f07599c2c9199701f86fbc70e20Douglas GregorASTMergeAction::~ASTMergeAction() {
939bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
949bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
959bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorbool ASTMergeAction::usesPreprocessorOnly() const {
969bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  return AdaptedAction->usesPreprocessorOnly();
979bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
989bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
99467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas GregorTranslationUnitKind ASTMergeAction::getTranslationUnitKind() {
100467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor  return AdaptedAction->getTranslationUnitKind();
1019bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
1029bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
1039bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorbool ASTMergeAction::hasPCHSupport() const {
1049bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  return AdaptedAction->hasPCHSupport();
1059bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
1069bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
107eb58d831b283a9fa030a2eccc6e23480108d2fa1Daniel Dunbarbool ASTMergeAction::hasASTFileSupport() const {
108eb58d831b283a9fa030a2eccc6e23480108d2fa1Daniel Dunbar  return AdaptedAction->hasASTFileSupport();
1099bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
1109bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
1119bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorbool ASTMergeAction::hasCodeCompletionSupport() const {
1129bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  return AdaptedAction->hasCodeCompletionSupport();
1139bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
114