19bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor//===-- ASTMerge.cpp - AST Merging Frontent Action --------------*- C++ -*-===// 29bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor// 39bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor// The LLVM Compiler Infrastructure 49bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor// 59bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor// This file is distributed under the University of Illinois Open Source 69bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor// License. See LICENSE.TXT for details. 79bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor// 89bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor//===----------------------------------------------------------------------===// 99bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor#include "clang/Frontend/ASTUnit.h" 109bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor#include "clang/AST/ASTContext.h" 11d343ff623eb11e277f1e70bca16073e424d8a30dDouglas Gregor#include "clang/AST/ASTDiagnostic.h" 129bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor#include "clang/AST/ASTImporter.h" 1328019772db70d4547be05a042eb950bc910f134fDouglas Gregor#include "clang/Basic/Diagnostic.h" 1455fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Frontend/CompilerInstance.h" 1555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Frontend/FrontendActions.h" 169bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor 179bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorusing namespace clang; 189bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor 19176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstd::unique_ptr<ASTConsumer> 20176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesASTMergeAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 219bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor return AdaptedAction->CreateASTConsumer(CI, InFile); 229bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor} 239bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor 249bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorbool ASTMergeAction::BeginSourceFileAction(CompilerInstance &CI, 255f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Filename) { 269bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor // FIXME: This is a hack. We need a better way to communicate the 279bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor // AST file, compiler instance, and file name than member variables 289bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor // of FrontendAction. 291f6b2b5c82b2d2d3935b0db76352a04e9877b73fDouglas Gregor AdaptedAction->setCurrentInput(getCurrentInput(), takeCurrentASTUnit()); 309bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor AdaptedAction->setCompilerInstance(&CI); 319bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor return AdaptedAction->BeginSourceFileAction(CI, Filename); 329bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor} 339bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor 349bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorvoid ASTMergeAction::ExecuteAction() { 359bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor CompilerInstance &CI = getCompilerInstance(); 360f962a8e61e1c094a89df17f9d3ad947d31c4e5cDouglas Gregor CI.getDiagnostics().getClient()->BeginSourceFile( 37a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor CI.getASTContext().getLangOpts()); 38d343ff623eb11e277f1e70bca16073e424d8a30dDouglas Gregor CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument, 39d343ff623eb11e277f1e70bca16073e424d8a30dDouglas Gregor &CI.getASTContext()); 40c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<DiagnosticIDs> 4133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis DiagIDs(CI.getDiagnostics().getDiagnosticIDs()); 429bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) { 43c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine> 4402c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor Diags(new DiagnosticsEngine(DiagIDs, &CI.getDiagnosticOpts(), 45a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor new ForwardingDiagnosticConsumer( 46a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor *CI.getDiagnostics().getClient()), 47a4a90cabfa15c900016a7cfaea51a6d4e8ebf4dbDouglas Gregor /*ShouldOwnClient=*/true)); 4887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar std::unique_ptr<ASTUnit> Unit = 4987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ASTUnit::LoadFromASTFile(ASTFiles[I], CI.getPCHContainerReader(), 5087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Diags, CI.getFileSystemOpts(), false); 5187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 529bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor if (!Unit) 539bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor continue; 549bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor 5533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis ASTImporter Importer(CI.getASTContext(), 56885237354fd902998c6ae9d7cc3dc8de96b123dcDouglas Gregor CI.getFileManager(), 57885237354fd902998c6ae9d7cc3dc8de96b123dcDouglas Gregor Unit->getASTContext(), 58d8868a634d4fd362243dc646e58c3cf956c81dcdDouglas Gregor Unit->getFileManager(), 59d8868a634d4fd362243dc646e58c3cf956c81dcdDouglas Gregor /*MinimalImport=*/false); 609bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor 619bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl(); 62651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *D : TU->decls()) { 639a945853ca0c2b4cac07056542b19f25a83f1288Douglas Gregor // Don't re-import __va_list_tag, __builtin_va_list. 64651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const auto *ND = dyn_cast<NamedDecl>(D)) 659a945853ca0c2b4cac07056542b19f25a83f1288Douglas Gregor if (IdentifierInfo *II = ND->getIdentifier()) 669a945853ca0c2b4cac07056542b19f25a83f1288Douglas Gregor if (II->isStr("__va_list_tag") || II->isStr("__builtin_va_list")) 679a945853ca0c2b4cac07056542b19f25a83f1288Douglas Gregor continue; 689a945853ca0c2b4cac07056542b19f25a83f1288Douglas Gregor 69b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar Decl *ToD = Importer.Import(D); 70b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar 71b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar if (ToD) { 72b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar DeclGroupRef DGR(ToD); 73b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar CI.getASTConsumer().HandleTopLevelDecl(DGR); 74b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar } 759bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor } 769bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor } 779bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor 780f962a8e61e1c094a89df17f9d3ad947d31c4e5cDouglas Gregor AdaptedAction->ExecuteAction(); 790f962a8e61e1c094a89df17f9d3ad947d31c4e5cDouglas Gregor CI.getDiagnostics().getClient()->EndSourceFile(); 809bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor} 819bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor 829bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorvoid ASTMergeAction::EndSourceFileAction() { 839bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor return AdaptedAction->EndSourceFileAction(); 849bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor} 859bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor 864967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarASTMergeAction::ASTMergeAction(std::unique_ptr<FrontendAction> adaptedAction, 87b3ca2637a9a3aeac5c7103eb4d612528680e7e20Argyrios Kyrtzidis ArrayRef<std::string> ASTFiles) 884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar: AdaptedAction(std::move(adaptedAction)), ASTFiles(ASTFiles.begin(), ASTFiles.end()) { 899bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor assert(AdaptedAction && "ASTMergeAction needs an action to adapt"); 909bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor} 919bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor 929bed8798964d9f07599c2c9199701f86fbc70e20Douglas GregorASTMergeAction::~ASTMergeAction() { 939bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor} 949bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor 959bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorbool ASTMergeAction::usesPreprocessorOnly() const { 969bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor return AdaptedAction->usesPreprocessorOnly(); 979bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor} 989bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor 99467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas GregorTranslationUnitKind ASTMergeAction::getTranslationUnitKind() { 100467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor return AdaptedAction->getTranslationUnitKind(); 1019bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor} 1029bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor 1039bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorbool ASTMergeAction::hasPCHSupport() const { 1049bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor return AdaptedAction->hasPCHSupport(); 1059bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor} 1069bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor 107eb58d831b283a9fa030a2eccc6e23480108d2fa1Daniel Dunbarbool ASTMergeAction::hasASTFileSupport() const { 108eb58d831b283a9fa030a2eccc6e23480108d2fa1Daniel Dunbar return AdaptedAction->hasASTFileSupport(); 1099bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor} 1109bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor 1119bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregorbool ASTMergeAction::hasCodeCompletionSupport() const { 1129bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor return AdaptedAction->hasCodeCompletionSupport(); 1139bed8798964d9f07599c2c9199701f86fbc70e20Douglas Gregor} 114