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