xref: /llvm-project/clang/lib/Frontend/ASTMerge.cpp (revision c88deb100f1d4a1d14dbcc42de01d325919ebec6)
1 //===-- ASTMerge.cpp - AST Merging Frontend 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/AST/ASTContext.h"
10 #include "clang/AST/ASTDiagnostic.h"
11 #include "clang/AST/ASTImporter.h"
12 #include "clang/Basic/Diagnostic.h"
13 #include "clang/Frontend/ASTUnit.h"
14 #include "clang/Frontend/CompilerInstance.h"
15 #include "clang/Frontend/FrontendActions.h"
16 #include "llvm/Support/Timer.h"
17 
18 using namespace clang;
19 
20 std::unique_ptr<ASTConsumer>
21 ASTMergeAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
22   return AdaptedAction->CreateASTConsumer(CI, InFile);
23 }
24 
25 bool ASTMergeAction::BeginSourceFileAction(CompilerInstance &CI) {
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->setCurrentInput(getCurrentInput(), takeCurrentASTUnit());
30   AdaptedAction->setCompilerInstance(&CI);
31   return AdaptedAction->BeginSourceFileAction(CI);
32 }
33 
34 void ASTMergeAction::ExecuteAction() {
35   llvm::NamedRegionTimer T("astmerge", "AST Merge actions", GroupName,
36                            GroupDescription, llvm::TimePassesIsEnabled);
37   CompilerInstance &CI = getCompilerInstance();
38   CI.getDiagnostics().getClient()->BeginSourceFile(
39                                              CI.getASTContext().getLangOpts());
40   CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument,
41                                        &CI.getASTContext());
42   IntrusiveRefCntPtr<DiagnosticIDs>
43       DiagIDs(CI.getDiagnostics().getDiagnosticIDs());
44   for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) {
45     IntrusiveRefCntPtr<DiagnosticsEngine>
46         Diags(new DiagnosticsEngine(DiagIDs, &CI.getDiagnosticOpts(),
47                                     new ForwardingDiagnosticConsumer(
48                                           *CI.getDiagnostics().getClient()),
49                                     /*ShouldOwnClient=*/true));
50     std::unique_ptr<ASTUnit> Unit = ASTUnit::LoadFromASTFile(
51         ASTFiles[I], CI.getPCHContainerReader(), ASTUnit::LoadEverything, Diags,
52         CI.getFileSystemOpts(), false);
53 
54     if (!Unit)
55       continue;
56 
57     ASTImporter Importer(CI.getASTContext(),
58                          CI.getFileManager(),
59                          Unit->getASTContext(),
60                          Unit->getFileManager(),
61                          /*MinimalImport=*/false);
62 
63     TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
64     for (auto *D : TU->decls()) {
65       // Don't re-import __va_list_tag, __builtin_va_list.
66       if (const auto *ND = dyn_cast<NamedDecl>(D))
67         if (IdentifierInfo *II = ND->getIdentifier())
68           if (II->isStr("__va_list_tag") || II->isStr("__builtin_va_list"))
69             continue;
70 
71       Decl *ToD = Importer.Import(D);
72 
73       if (ToD) {
74         DeclGroupRef DGR(ToD);
75         CI.getASTConsumer().HandleTopLevelDecl(DGR);
76       }
77     }
78   }
79 
80   AdaptedAction->ExecuteAction();
81   CI.getDiagnostics().getClient()->EndSourceFile();
82 }
83 
84 void ASTMergeAction::EndSourceFileAction() {
85   return AdaptedAction->EndSourceFileAction();
86 }
87 
88 ASTMergeAction::ASTMergeAction(std::unique_ptr<FrontendAction> adaptedAction,
89                                ArrayRef<std::string> ASTFiles)
90 : AdaptedAction(std::move(adaptedAction)), ASTFiles(ASTFiles.begin(), ASTFiles.end()) {
91   assert(AdaptedAction && "ASTMergeAction needs an action to adapt");
92 }
93 
94 ASTMergeAction::~ASTMergeAction() {
95 }
96 
97 bool ASTMergeAction::usesPreprocessorOnly() const {
98   return AdaptedAction->usesPreprocessorOnly();
99 }
100 
101 TranslationUnitKind ASTMergeAction::getTranslationUnitKind() {
102   return AdaptedAction->getTranslationUnitKind();
103 }
104 
105 bool ASTMergeAction::hasPCHSupport() const {
106   return AdaptedAction->hasPCHSupport();
107 }
108 
109 bool ASTMergeAction::hasASTFileSupport() const {
110   return AdaptedAction->hasASTFileSupport();
111 }
112 
113 bool ASTMergeAction::hasCodeCompletionSupport() const {
114   return AdaptedAction->hasCodeCompletionSupport();
115 }
116