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