//
//===----------------------------------------------------------------------===//
#include "clang/Frontend/ASTUnit.h"
-#include "clang/Frontend/CompilerInstance.h"
-#include "clang/Frontend/FrontendActions.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/ASTImporter.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendActions.h"
using namespace clang;
-ASTConsumer *ASTMergeAction::CreateASTConsumer(CompilerInstance &CI,
- llvm::StringRef InFile) {
+std::unique_ptr<ASTConsumer>
+ASTMergeAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
return AdaptedAction->CreateASTConsumer(CI, InFile);
}
-bool ASTMergeAction::BeginSourceFileAction(CompilerInstance &CI,
- llvm::StringRef Filename) {
+bool ASTMergeAction::BeginSourceFileAction(CompilerInstance &CI) {
// FIXME: This is a hack. We need a better way to communicate the
// AST file, compiler instance, and file name than member variables
// of FrontendAction.
- AdaptedAction->setCurrentFile(getCurrentFile(), takeCurrentASTUnit());
+ AdaptedAction->setCurrentInput(getCurrentInput(), takeCurrentASTUnit());
AdaptedAction->setCompilerInstance(&CI);
- return AdaptedAction->BeginSourceFileAction(CI, Filename);
+ return AdaptedAction->BeginSourceFileAction(CI);
}
void ASTMergeAction::ExecuteAction() {
CompilerInstance &CI = getCompilerInstance();
CI.getDiagnostics().getClient()->BeginSourceFile(
- CI.getASTContext().getLangOptions());
+ CI.getASTContext().getLangOpts());
CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument,
&CI.getASTContext());
+ IntrusiveRefCntPtr<DiagnosticIDs>
+ DiagIDs(CI.getDiagnostics().getDiagnosticIDs());
for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) {
- ASTUnit *Unit = ASTUnit::LoadFromPCHFile(ASTFiles[I], CI.getDiagnostics(),
- false, true);
+ IntrusiveRefCntPtr<DiagnosticsEngine>
+ Diags(new DiagnosticsEngine(DiagIDs, &CI.getDiagnosticOpts(),
+ new ForwardingDiagnosticConsumer(
+ *CI.getDiagnostics().getClient()),
+ /*ShouldOwnClient=*/true));
+ std::unique_ptr<ASTUnit> Unit =
+ ASTUnit::LoadFromASTFile(ASTFiles[I], CI.getPCHContainerReader(),
+ Diags, CI.getFileSystemOpts(), false);
+
if (!Unit)
continue;
- ASTImporter Importer(CI.getDiagnostics(),
- CI.getASTContext(),
+ ASTImporter Importer(CI.getASTContext(),
CI.getFileManager(),
Unit->getASTContext(),
- Unit->getFileManager());
+ Unit->getFileManager(),
+ /*MinimalImport=*/false);
TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
- for (DeclContext::decl_iterator D = TU->decls_begin(),
- DEnd = TU->decls_end();
- D != DEnd; ++D) {
- // FIXME: We only merge variables whose names start with x and functions
- // whose names start with 'f'. Why would anyone want anything else?
- if (VarDecl *VD = dyn_cast<VarDecl>(*D)) {
- if (VD->getIdentifier() &&
- *VD->getIdentifier()->getNameStart() == 'x') {
- Decl *Merged = Importer.Import(VD);
- (void)Merged;
- }
- } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*D)) {
- if (FD->getIdentifier() &&
- *FD->getIdentifier()->getNameStart() == 'f') {
- Decl *Merged = Importer.Import(FD);
- (void)Merged;
- }
+ for (auto *D : TU->decls()) {
+ // Don't re-import __va_list_tag, __builtin_va_list.
+ if (const auto *ND = dyn_cast<NamedDecl>(D))
+ if (IdentifierInfo *II = ND->getIdentifier())
+ if (II->isStr("__va_list_tag") || II->isStr("__builtin_va_list"))
+ continue;
+
+ Decl *ToD = Importer.Import(D);
+
+ if (ToD) {
+ DeclGroupRef DGR(ToD);
+ CI.getASTConsumer().HandleTopLevelDecl(DGR);
}
}
-
- delete Unit;
}
AdaptedAction->ExecuteAction();
return AdaptedAction->EndSourceFileAction();
}
-ASTMergeAction::ASTMergeAction(FrontendAction *AdaptedAction,
- std::string *ASTFiles, unsigned NumASTFiles)
- : AdaptedAction(AdaptedAction), ASTFiles(ASTFiles, ASTFiles + NumASTFiles) {
+ASTMergeAction::ASTMergeAction(std::unique_ptr<FrontendAction> adaptedAction,
+ ArrayRef<std::string> ASTFiles)
+: AdaptedAction(std::move(adaptedAction)), ASTFiles(ASTFiles.begin(), ASTFiles.end()) {
assert(AdaptedAction && "ASTMergeAction needs an action to adapt");
}
ASTMergeAction::~ASTMergeAction() {
- delete AdaptedAction;
}
bool ASTMergeAction::usesPreprocessorOnly() const {
return AdaptedAction->usesPreprocessorOnly();
}
-bool ASTMergeAction::usesCompleteTranslationUnit() {
- return AdaptedAction->usesCompleteTranslationUnit();
+TranslationUnitKind ASTMergeAction::getTranslationUnitKind() {
+ return AdaptedAction->getTranslationUnitKind();
}
bool ASTMergeAction::hasPCHSupport() const {
return AdaptedAction->hasPCHSupport();
}
-bool ASTMergeAction::hasASTSupport() const {
- return AdaptedAction->hasASTSupport();
+bool ASTMergeAction::hasASTFileSupport() const {
+ return AdaptedAction->hasASTFileSupport();
}
bool ASTMergeAction::hasCodeCompletionSupport() const {