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 17 using namespace clang; 18 19 ASTConsumer *ASTMergeAction::CreateASTConsumer(CompilerInstance &CI, 20 llvm::StringRef InFile) { 21 return AdaptedAction->CreateASTConsumer(CI, InFile); 22 } 23 24 bool 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(), getCurrentFileKind(), 30 takeCurrentASTUnit()); 31 AdaptedAction->setCompilerInstance(&CI); 32 return AdaptedAction->BeginSourceFileAction(CI, Filename); 33 } 34 35 void ASTMergeAction::ExecuteAction() { 36 CompilerInstance &CI = getCompilerInstance(); 37 CI.getDiagnostics().getClient()->BeginSourceFile( 38 CI.getASTContext().getLangOptions()); 39 CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument, 40 &CI.getASTContext()); 41 llvm::IntrusiveRefCntPtr<DiagnosticIDs> 42 DiagIDs(CI.getDiagnostics().getDiagnosticIDs()); 43 for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) { 44 llvm::IntrusiveRefCntPtr<Diagnostic> 45 Diags(new Diagnostic(DiagIDs, 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 CI.getFileSystemOpts(), 55 Unit->getASTContext(), 56 Unit->getFileManager(), 57 Unit->getFileSystemOpts()); 58 59 TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl(); 60 for (DeclContext::decl_iterator D = TU->decls_begin(), 61 DEnd = TU->decls_end(); 62 D != DEnd; ++D) { 63 // Don't re-import __va_list_tag, __builtin_va_list. 64 if (NamedDecl *ND = dyn_cast<NamedDecl>(*D)) 65 if (IdentifierInfo *II = ND->getIdentifier()) 66 if (II->isStr("__va_list_tag") || II->isStr("__builtin_va_list")) 67 continue; 68 69 Importer.Import(*D); 70 } 71 72 // Aggregate the number of warnings/errors from all diagnostics so 73 // that at CompilerInstance::ExecuteAction we can report the total numbers. 74 // FIXME: This is hacky, maybe keep track of total number of warnings/errors 75 // in DiagnosticClient and have CompilerInstance query that ? 76 CI.getDiagnostics().setNumWarnings(CI.getDiagnostics().getNumWarnings() + 77 Diags->getNumWarnings()); 78 CI.getDiagnostics().setNumErrors(CI.getDiagnostics().getNumErrors() + 79 Diags->getNumErrors()); 80 81 delete Unit; 82 } 83 84 AdaptedAction->ExecuteAction(); 85 CI.getDiagnostics().getClient()->EndSourceFile(); 86 } 87 88 void ASTMergeAction::EndSourceFileAction() { 89 return AdaptedAction->EndSourceFileAction(); 90 } 91 92 ASTMergeAction::ASTMergeAction(FrontendAction *AdaptedAction, 93 std::string *ASTFiles, unsigned NumASTFiles) 94 : AdaptedAction(AdaptedAction), ASTFiles(ASTFiles, ASTFiles + NumASTFiles) { 95 assert(AdaptedAction && "ASTMergeAction needs an action to adapt"); 96 } 97 98 ASTMergeAction::~ASTMergeAction() { 99 delete AdaptedAction; 100 } 101 102 bool ASTMergeAction::usesPreprocessorOnly() const { 103 return AdaptedAction->usesPreprocessorOnly(); 104 } 105 106 bool ASTMergeAction::usesCompleteTranslationUnit() { 107 return AdaptedAction->usesCompleteTranslationUnit(); 108 } 109 110 bool ASTMergeAction::hasPCHSupport() const { 111 return AdaptedAction->hasPCHSupport(); 112 } 113 114 bool ASTMergeAction::hasASTFileSupport() const { 115 return AdaptedAction->hasASTFileSupport(); 116 } 117 118 bool ASTMergeAction::hasCodeCompletionSupport() const { 119 return AdaptedAction->hasCodeCompletionSupport(); 120 } 121