I != E; ++I)
dumpCXXCtorInitializer(*I);
+ if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D))
+ if (MD->size_overridden_methods() != 0) {
+ auto dumpOverride =
+ [=](const CXXMethodDecl *D) {
+ SplitQualType T_split = D->getType().split();
+ OS << D << " " << D->getParent()->getName() << "::"
+ << D->getName() << " '"
+ << QualType::getAsString(T_split) << "'";
+ };
+
+ dumpChild([=] {
+ auto FirstOverrideItr = MD->begin_overridden_methods();
+ OS << "Overrides: [ ";
+ dumpOverride(*FirstOverrideItr);
+ for (const auto *Override :
+ llvm::make_range(FirstOverrideItr + 1,
+ MD->end_overridden_methods()))
+ dumpOverride(Override);
+ OS << " ]";
+ });
+ }
+
if (D->doesThisDeclarationHaveABody())
dumpStmt(D->getBody());
}
bool ImportArrayChecked(const InContainerTy &InContainer, OIter Obegin) {
return ImportArrayChecked(InContainer.begin(), InContainer.end(), Obegin);
}
+
+ // Importing overrides.
+ void ImportOverrides(CXXMethodDecl *ToMethod, CXXMethodDecl *FromMethod);
};
}
// Add this function to the lexical context.
LexicalDC->addDeclInternal(ToFunction);
+ if (auto *FromCXXMethod = dyn_cast<CXXMethodDecl>(D))
+ ImportOverrides(cast<CXXMethodDecl>(ToFunction), FromCXXMethod);
+
return ToFunction;
}
Replacement);
}
+void ASTNodeImporter::ImportOverrides(CXXMethodDecl *ToMethod,
+ CXXMethodDecl *FromMethod) {
+ for (auto *FromOverriddenMethod : FromMethod->overridden_methods())
+ ToMethod->addOverriddenMethod(
+ cast<CXXMethodDecl>(Importer.Import(const_cast<CXXMethodDecl*>(
+ FromOverriddenMethod))));
+}
+
ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
ASTContext &FromContext, FileManager &FromFileManager,
bool MinimalImport)
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/CodeGen/ModuleBuilder.h"
+#include "clang/Frontend/ASTConsumers.h"
#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/MultiplexConsumer.h"
#include "clang/Frontend/TextDiagnosticBuffer.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/Preprocessor.h"
llvm::cl::desc("Argument to pass to the CompilerInvocation"),
llvm::cl::CommaSeparated);
+static llvm::cl::opt<bool>
+DumpAST("dump-ast", llvm::cl::init(false),
+ llvm::cl::desc("Dump combined AST"));
+
namespace init_convenience {
class TestDiagnosticConsumer : public DiagnosticConsumer {
private:
}
llvm::Error ParseSource(const std::string &Path, CompilerInstance &CI,
- CodeGenerator &CG) {
+ ASTConsumer &Consumer) {
SourceManager &SM = CI.getSourceManager();
const FileEntry *FE = CI.getFileManager().getFile(Path);
if (!FE) {
llvm::Twine("Couldn't open ", Path), std::error_code());
}
SM.setMainFileID(SM.createFileID(FE, SourceLocation(), SrcMgr::C_User));
- ParseAST(CI.getPreprocessor(), &CG, CI.getASTContext());
+ ParseAST(CI.getPreprocessor(), &Consumer, CI.getASTContext());
return llvm::Error::success();
}
llvm::Expected<std::unique_ptr<CompilerInstance>>
Parse(const std::string &Path,
- llvm::ArrayRef<std::unique_ptr<CompilerInstance>> Imports) {
+ llvm::ArrayRef<std::unique_ptr<CompilerInstance>> Imports,
+ bool ShouldDumpAST) {
std::vector<const char *> ClangArgv(ClangArgs.size());
std::transform(ClangArgs.begin(), ClangArgs.end(), ClangArgv.begin(),
[](const std::string &s) -> const char * { return s.data(); });
if (Imports.size())
AddExternalSource(*CI, Imports);
+ std::vector<std::unique_ptr<ASTConsumer>> ASTConsumers;
+
auto LLVMCtx = llvm::make_unique<llvm::LLVMContext>();
- std::unique_ptr<CodeGenerator> CG =
- init_convenience::BuildCodeGen(*CI, *LLVMCtx);
- CG->Initialize(CI->getASTContext());
+ ASTConsumers.push_back(init_convenience::BuildCodeGen(*CI, *LLVMCtx));
+
+ if (ShouldDumpAST)
+ ASTConsumers.push_back(CreateASTDumper("", true, false, false));
CI->getDiagnosticClient().BeginSourceFile(CI->getLangOpts(),
&CI->getPreprocessor());
- if (llvm::Error PE = ParseSource(Path, *CI, *CG)) {
+ MultiplexConsumer Consumers(std::move(ASTConsumers));
+ Consumers.Initialize(CI->getASTContext());
+
+ if (llvm::Error PE = ParseSource(Path, *CI, Consumers)) {
return std::move(PE);
}
CI->getDiagnosticClient().EndSourceFile();
llvm::cl::ParseCommandLineOptions(argc, argv);
std::vector<std::unique_ptr<CompilerInstance>> ImportCIs;
for (auto I : Imports) {
- llvm::Expected<std::unique_ptr<CompilerInstance>> ImportCI = Parse(I, {});
+ llvm::Expected<std::unique_ptr<CompilerInstance>> ImportCI =
+ Parse(I, {}, false);
if (auto E = ImportCI.takeError()) {
llvm::errs() << llvm::toString(std::move(E));
exit(-1);
}
}
llvm::Expected<std::unique_ptr<CompilerInstance>> ExpressionCI =
- Parse(Expression, Direct ? ImportCIs : IndirectCIs);
+ Parse(Expression, Direct ? ImportCIs : IndirectCIs, DumpAST);
if (auto E = ExpressionCI.takeError()) {
llvm::errs() << llvm::toString(std::move(E));
exit(-1);