ASTMerge.cpp revision 02c23ebf41ae2f70da0ba7337e05c51fbfe35f7f
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===-- ASTMerge.cpp - AST Merging Frontent Action --------------*- C++ -*-===// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// This file is distributed under the University of Illinois Open Source 658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// License. See LICENSE.TXT for details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/Frontend/ASTUnit.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/Frontend/CompilerInstance.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/Frontend/FrontendActions.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/AST/ASTContext.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/AST/ASTDiagnostic.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/AST/ASTImporter.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/Basic/Diagnostic.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace clang; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASTConsumer *ASTMergeAction::CreateASTConsumer(CompilerInstance &CI, 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringRef InFile) { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AdaptedAction->CreateASTConsumer(CI, InFile); 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ASTMergeAction::BeginSourceFileAction(CompilerInstance &CI, 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringRef Filename) { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FIXME: This is a hack. We need a better way to communicate the 2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // AST file, compiler instance, and file name than member variables 28 // of FrontendAction. 29 AdaptedAction->setCurrentInput(getCurrentInput(), 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().getLangOpts()); 38 CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument, 39 &CI.getASTContext()); 40 IntrusiveRefCntPtr<DiagnosticIDs> 41 DiagIDs(CI.getDiagnostics().getDiagnosticIDs()); 42 for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) { 43 IntrusiveRefCntPtr<DiagnosticsEngine> 44 Diags(new DiagnosticsEngine(DiagIDs, &CI.getDiagnosticOpts(), 45 CI.getDiagnostics().getClient(), 46 /*ShouldOwnClient=*/false)); 47 ASTUnit *Unit = ASTUnit::LoadFromASTFile(ASTFiles[I], Diags, 48 CI.getFileSystemOpts(), false); 49 if (!Unit) 50 continue; 51 52 ASTImporter Importer(CI.getASTContext(), 53 CI.getFileManager(), 54 Unit->getASTContext(), 55 Unit->getFileManager(), 56 /*MinimalImport=*/false); 57 58 TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl(); 59 for (DeclContext::decl_iterator D = TU->decls_begin(), 60 DEnd = TU->decls_end(); 61 D != DEnd; ++D) { 62 // Don't re-import __va_list_tag, __builtin_va_list. 63 if (NamedDecl *ND = dyn_cast<NamedDecl>(*D)) 64 if (IdentifierInfo *II = ND->getIdentifier()) 65 if (II->isStr("__va_list_tag") || II->isStr("__builtin_va_list")) 66 continue; 67 68 Importer.Import(*D); 69 } 70 71 delete Unit; 72 } 73 74 AdaptedAction->ExecuteAction(); 75 CI.getDiagnostics().getClient()->EndSourceFile(); 76} 77 78void ASTMergeAction::EndSourceFileAction() { 79 return AdaptedAction->EndSourceFileAction(); 80} 81 82ASTMergeAction::ASTMergeAction(FrontendAction *AdaptedAction, 83 ArrayRef<std::string> ASTFiles) 84 : AdaptedAction(AdaptedAction), ASTFiles(ASTFiles.begin(), ASTFiles.end()) { 85 assert(AdaptedAction && "ASTMergeAction needs an action to adapt"); 86} 87 88ASTMergeAction::~ASTMergeAction() { 89 delete AdaptedAction; 90} 91 92bool ASTMergeAction::usesPreprocessorOnly() const { 93 return AdaptedAction->usesPreprocessorOnly(); 94} 95 96TranslationUnitKind ASTMergeAction::getTranslationUnitKind() { 97 return AdaptedAction->getTranslationUnitKind(); 98} 99 100bool ASTMergeAction::hasPCHSupport() const { 101 return AdaptedAction->hasPCHSupport(); 102} 103 104bool ASTMergeAction::hasASTFileSupport() const { 105 return AdaptedAction->hasASTFileSupport(); 106} 107 108bool ASTMergeAction::hasCodeCompletionSupport() const { 109 return AdaptedAction->hasCodeCompletionSupport(); 110} 111