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/Frontend/CompilerInstance.h"
119bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor#include "clang/Frontend/FrontendActions.h"
129bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor#include "clang/AST/ASTContext.h"
13d343ff623eb11e277f1e70bca16073e424d8a30dDouglas Gregor#include "clang/AST/ASTDiagnostic.h"
149bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor#include "clang/AST/ASTImporter.h"
1528019772db70d4547be05a042eb950bc910f134fDouglas Gregor#include "clang/Basic/Diagnostic.h"
169bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
179bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorusing namespace clang;
189bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
199bed8798964d9f07599c2c9199701f86fbc70e20Douglas GregorASTConsumer *ASTMergeAction::CreateASTConsumer(CompilerInstance &CI,
205f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                               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(
374e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie                                         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>
44d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie        Diags(new DiagnosticsEngine(DiagIDs, CI.getDiagnostics().getClient(),
4533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis                             /*ShouldOwnClient=*/false));
46389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis    ASTUnit *Unit = ASTUnit::LoadFromASTFile(ASTFiles[I], Diags,
47389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis                                             CI.getFileSystemOpts(), false);
489bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor    if (!Unit)
499bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor      continue;
509bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
5133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    ASTImporter Importer(CI.getASTContext(),
52885237354fd902998c6ae9d7cc3dc8de96b123dcDouglas Gregor                         CI.getFileManager(),
53885237354fd902998c6ae9d7cc3dc8de96b123dcDouglas Gregor                         Unit->getASTContext(),
54d8868a634d4fd362243dc646e58c3cf956c81dcdDouglas Gregor                         Unit->getFileManager(),
55d8868a634d4fd362243dc646e58c3cf956c81dcdDouglas Gregor                         /*MinimalImport=*/false);
569bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
579bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor    TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
589bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor    for (DeclContext::decl_iterator D = TU->decls_begin(),
599bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor                                 DEnd = TU->decls_end();
609bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor         D != DEnd; ++D) {
619a945853ca0c2b4cac07056542b19f25a83f1288Douglas Gregor      // Don't re-import __va_list_tag, __builtin_va_list.
629a945853ca0c2b4cac07056542b19f25a83f1288Douglas Gregor      if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
639a945853ca0c2b4cac07056542b19f25a83f1288Douglas Gregor        if (IdentifierInfo *II = ND->getIdentifier())
649a945853ca0c2b4cac07056542b19f25a83f1288Douglas Gregor          if (II->isStr("__va_list_tag") || II->isStr("__builtin_va_list"))
659a945853ca0c2b4cac07056542b19f25a83f1288Douglas Gregor            continue;
669a945853ca0c2b4cac07056542b19f25a83f1288Douglas Gregor
6744703f59ed2ae7854a08cf67cb2474c31e0698ecDouglas Gregor      Importer.Import(*D);
689bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor    }
699bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
709bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor    delete Unit;
719bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  }
729bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
730f962a8e61e1c094a89df17f9d3ad947d31c4e5cDouglas Gregor  AdaptedAction->ExecuteAction();
740f962a8e61e1c094a89df17f9d3ad947d31c4e5cDouglas Gregor  CI.getDiagnostics().getClient()->EndSourceFile();
759bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
769bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
779bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorvoid ASTMergeAction::EndSourceFileAction() {
789bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  return AdaptedAction->EndSourceFileAction();
799bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
809bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
819bed8798964d9f07599c2c9199701f86fbc70e20Douglas GregorASTMergeAction::ASTMergeAction(FrontendAction *AdaptedAction,
82b3ca2637a9a3aeac5c7103eb4d612528680e7e20Argyrios Kyrtzidis                               ArrayRef<std::string> ASTFiles)
83b3ca2637a9a3aeac5c7103eb4d612528680e7e20Argyrios Kyrtzidis  : AdaptedAction(AdaptedAction), ASTFiles(ASTFiles.begin(), ASTFiles.end()) {
849bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  assert(AdaptedAction && "ASTMergeAction needs an action to adapt");
859bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
869bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
879bed8798964d9f07599c2c9199701f86fbc70e20Douglas GregorASTMergeAction::~ASTMergeAction() {
889bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  delete AdaptedAction;
899bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
909bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
919bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorbool ASTMergeAction::usesPreprocessorOnly() const {
929bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  return AdaptedAction->usesPreprocessorOnly();
939bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
949bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
95467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas GregorTranslationUnitKind ASTMergeAction::getTranslationUnitKind() {
96467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor  return AdaptedAction->getTranslationUnitKind();
979bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
989bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
999bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorbool ASTMergeAction::hasPCHSupport() const {
1009bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  return AdaptedAction->hasPCHSupport();
1019bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
1029bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
103eb58d831b283a9fa030a2eccc6e23480108d2fa1Daniel Dunbarbool ASTMergeAction::hasASTFileSupport() const {
104eb58d831b283a9fa030a2eccc6e23480108d2fa1Daniel Dunbar  return AdaptedAction->hasASTFileSupport();
1059bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
1069bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
1079bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorbool ASTMergeAction::hasCodeCompletionSupport() const {
1089bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  return AdaptedAction->hasCodeCompletionSupport();
1099bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
110