clang API Documentation
00001 //===-- ASTMerge.cpp - AST Merging Frontent Action --------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 #include "clang/Frontend/ASTUnit.h" 00010 #include "clang/Frontend/CompilerInstance.h" 00011 #include "clang/Frontend/FrontendActions.h" 00012 #include "clang/AST/ASTContext.h" 00013 #include "clang/AST/ASTDiagnostic.h" 00014 #include "clang/AST/ASTImporter.h" 00015 #include "clang/Basic/Diagnostic.h" 00016 00017 using namespace clang; 00018 00019 ASTConsumer *ASTMergeAction::CreateASTConsumer(CompilerInstance &CI, 00020 StringRef InFile) { 00021 return AdaptedAction->CreateASTConsumer(CI, InFile); 00022 } 00023 00024 bool ASTMergeAction::BeginSourceFileAction(CompilerInstance &CI, 00025 StringRef Filename) { 00026 // FIXME: This is a hack. We need a better way to communicate the 00027 // AST file, compiler instance, and file name than member variables 00028 // of FrontendAction. 00029 AdaptedAction->setCurrentInput(getCurrentInput(), takeCurrentASTUnit()); 00030 AdaptedAction->setCompilerInstance(&CI); 00031 return AdaptedAction->BeginSourceFileAction(CI, Filename); 00032 } 00033 00034 void ASTMergeAction::ExecuteAction() { 00035 CompilerInstance &CI = getCompilerInstance(); 00036 CI.getDiagnostics().getClient()->BeginSourceFile( 00037 CI.getASTContext().getLangOpts()); 00038 CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument, 00039 &CI.getASTContext()); 00040 IntrusiveRefCntPtr<DiagnosticIDs> 00041 DiagIDs(CI.getDiagnostics().getDiagnosticIDs()); 00042 for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) { 00043 IntrusiveRefCntPtr<DiagnosticsEngine> 00044 Diags(new DiagnosticsEngine(DiagIDs, CI.getDiagnostics().getClient(), 00045 /*ShouldOwnClient=*/false)); 00046 ASTUnit *Unit = ASTUnit::LoadFromASTFile(ASTFiles[I], Diags, 00047 CI.getFileSystemOpts(), false); 00048 if (!Unit) 00049 continue; 00050 00051 ASTImporter Importer(CI.getASTContext(), 00052 CI.getFileManager(), 00053 Unit->getASTContext(), 00054 Unit->getFileManager(), 00055 /*MinimalImport=*/false); 00056 00057 TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl(); 00058 for (DeclContext::decl_iterator D = TU->decls_begin(), 00059 DEnd = TU->decls_end(); 00060 D != DEnd; ++D) { 00061 // Don't re-import __va_list_tag, __builtin_va_list. 00062 if (NamedDecl *ND = dyn_cast<NamedDecl>(*D)) 00063 if (IdentifierInfo *II = ND->getIdentifier()) 00064 if (II->isStr("__va_list_tag") || II->isStr("__builtin_va_list")) 00065 continue; 00066 00067 Importer.Import(*D); 00068 } 00069 00070 delete Unit; 00071 } 00072 00073 AdaptedAction->ExecuteAction(); 00074 CI.getDiagnostics().getClient()->EndSourceFile(); 00075 } 00076 00077 void ASTMergeAction::EndSourceFileAction() { 00078 return AdaptedAction->EndSourceFileAction(); 00079 } 00080 00081 ASTMergeAction::ASTMergeAction(FrontendAction *AdaptedAction, 00082 ArrayRef<std::string> ASTFiles) 00083 : AdaptedAction(AdaptedAction), ASTFiles(ASTFiles.begin(), ASTFiles.end()) { 00084 assert(AdaptedAction && "ASTMergeAction needs an action to adapt"); 00085 } 00086 00087 ASTMergeAction::~ASTMergeAction() { 00088 delete AdaptedAction; 00089 } 00090 00091 bool ASTMergeAction::usesPreprocessorOnly() const { 00092 return AdaptedAction->usesPreprocessorOnly(); 00093 } 00094 00095 TranslationUnitKind ASTMergeAction::getTranslationUnitKind() { 00096 return AdaptedAction->getTranslationUnitKind(); 00097 } 00098 00099 bool ASTMergeAction::hasPCHSupport() const { 00100 return AdaptedAction->hasPCHSupport(); 00101 } 00102 00103 bool ASTMergeAction::hasASTFileSupport() const { 00104 return AdaptedAction->hasASTFileSupport(); 00105 } 00106 00107 bool ASTMergeAction::hasCodeCompletionSupport() const { 00108 return AdaptedAction->hasCodeCompletionSupport(); 00109 }