ASTMerge.cpp revision 885237354fd902998c6ae9d7cc3dc8de96b123dc
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"
159bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
169bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorusing namespace clang;
179bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
189bed8798964d9f07599c2c9199701f86fbc70e20Douglas GregorASTConsumer *ASTMergeAction::CreateASTConsumer(CompilerInstance &CI,
199bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor                                               llvm::StringRef InFile) {
209bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  return AdaptedAction->CreateASTConsumer(CI, InFile);
219bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
229bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
239bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorbool ASTMergeAction::BeginSourceFileAction(CompilerInstance &CI,
249bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor                                           llvm::StringRef Filename) {
259bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  // FIXME: This is a hack. We need a better way to communicate the
269bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  // AST file, compiler instance, and file name than member variables
279bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  // of FrontendAction.
289bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  AdaptedAction->setCurrentFile(getCurrentFile(), takeCurrentASTUnit());
299bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  AdaptedAction->setCompilerInstance(&CI);
309bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  return AdaptedAction->BeginSourceFileAction(CI, Filename);
319bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
329bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
339bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorvoid ASTMergeAction::ExecuteAction() {
349bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  CompilerInstance &CI = getCompilerInstance();
35d343ff623eb11e277f1e70bca16073e424d8a30dDouglas Gregor  CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument,
36d343ff623eb11e277f1e70bca16073e424d8a30dDouglas Gregor                                       &CI.getASTContext());
379bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) {
38d343ff623eb11e277f1e70bca16073e424d8a30dDouglas Gregor    Diagnostic ASTDiags(CI.getDiagnostics().getClient());
39d343ff623eb11e277f1e70bca16073e424d8a30dDouglas Gregor
40d343ff623eb11e277f1e70bca16073e424d8a30dDouglas Gregor    ASTUnit *Unit = ASTUnit::LoadFromPCHFile(ASTFiles[I], ASTDiags,
419bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor                                             false, true);
429bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor    if (!Unit)
439bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor      continue;
449bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
45d343ff623eb11e277f1e70bca16073e424d8a30dDouglas Gregor    ASTDiags.SetArgToStringFn(&FormatASTNodeDiagnosticArgument,
46d343ff623eb11e277f1e70bca16073e424d8a30dDouglas Gregor                              &Unit->getASTContext());
47885237354fd902998c6ae9d7cc3dc8de96b123dcDouglas Gregor    ASTImporter Importer(CI.getASTContext(),
48885237354fd902998c6ae9d7cc3dc8de96b123dcDouglas Gregor                         CI.getFileManager(),
49885237354fd902998c6ae9d7cc3dc8de96b123dcDouglas Gregor                         CI.getDiagnostics(),
50885237354fd902998c6ae9d7cc3dc8de96b123dcDouglas Gregor                         Unit->getASTContext(),
51885237354fd902998c6ae9d7cc3dc8de96b123dcDouglas Gregor                         Unit->getFileManager(),
52885237354fd902998c6ae9d7cc3dc8de96b123dcDouglas Gregor                         ASTDiags);
539bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
549bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor    TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
559bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor    for (DeclContext::decl_iterator D = TU->decls_begin(),
569bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor                                 DEnd = TU->decls_end();
579bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor         D != DEnd; ++D) {
589bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor      // FIXME: We only merge variables whose names start with x. Why
599bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor      // would anyone want anything else?
609bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor      if (VarDecl *VD = dyn_cast<VarDecl>(*D))
619bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor        if (VD->getIdentifier() &&
629bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor            *VD->getIdentifier()->getNameStart() == 'x') {
639bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor          Decl *Merged = Importer.Import(VD);
64d343ff623eb11e277f1e70bca16073e424d8a30dDouglas Gregor          (void)Merged;
659bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor        }
669bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor    }
679bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
689bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor    delete Unit;
699bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  }
709bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
719bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
729bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  return AdaptedAction->ExecuteAction();
739bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
749bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
759bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorvoid ASTMergeAction::EndSourceFileAction() {
769bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  return AdaptedAction->EndSourceFileAction();
779bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
789bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
799bed8798964d9f07599c2c9199701f86fbc70e20Douglas GregorASTMergeAction::ASTMergeAction(FrontendAction *AdaptedAction,
809bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor                               std::string *ASTFiles, unsigned NumASTFiles)
819bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  : AdaptedAction(AdaptedAction), ASTFiles(ASTFiles, ASTFiles + NumASTFiles) {
829bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  assert(AdaptedAction && "ASTMergeAction needs an action to adapt");
839bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
849bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
859bed8798964d9f07599c2c9199701f86fbc70e20Douglas GregorASTMergeAction::~ASTMergeAction() {
869bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  delete AdaptedAction;
879bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
889bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
899bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorbool ASTMergeAction::usesPreprocessorOnly() const {
909bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  return AdaptedAction->usesPreprocessorOnly();
919bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
929bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
939bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorbool ASTMergeAction::usesCompleteTranslationUnit() {
949bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  return AdaptedAction->usesCompleteTranslationUnit();
959bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
969bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
979bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorbool ASTMergeAction::hasPCHSupport() const {
989bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  return AdaptedAction->hasPCHSupport();
999bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
1009bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
1019bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorbool ASTMergeAction::hasASTSupport() const {
1029bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  return AdaptedAction->hasASTSupport();
1039bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
1049bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor
1059bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorbool ASTMergeAction::hasCodeCompletionSupport() const {
1069bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor  return AdaptedAction->hasCodeCompletionSupport();
1079bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor}
108