Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 56 additions & 23 deletions core/dictgen/src/LinkdefReader.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@
#include "clang/AST/ASTContext.h"

#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"

#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Lex/Pragma.h"

#include "cling/Interpreter/CIFactory.h"
Expand Down Expand Up @@ -1056,34 +1058,65 @@ bool LinkdefReader::Parse(SelectionRules &sr, llvm::StringRef code, const std::v
parserArgsC.push_back(parserArgs[i].c_str());
}

// Extract all #pragmas
std::unique_ptr<llvm::MemoryBuffer> memBuf = llvm::MemoryBuffer::getMemBuffer(code, "CLING #pragma extraction");
clang::CompilerInstance *pragmaCI =
cling::CIFactory::createCI(std::move(memBuf), parserArgsC.size(), &parserArgsC[0], llvmdir,
std::nullopt /*Consumer*/, {} /*ModuleFileExtension*/, true /*OnlyLex*/);
cling::CompilerOptions COpts(parserArgsC.size(), &parserArgsC[0]);
struct PragmaCollectAction : public clang::SyntaxOnlyAction {
bool isError = false;
LinkdefReader &fLDR;
cling::CompilerOptions COpts;
PragmaCollectAction(LinkdefReader &ldr, cling::CompilerOptions &COpts) : fLDR(ldr), COpts(COpts) {}
bool BeginSourceFileAction(clang::CompilerInstance &CI) override
{
if (COpts.CxxModules)
cling::CIFactory::collectModule(CI);
clang::Preprocessor &PP = CI.getPreprocessor();
// Attach the handlers before we have started. PP takes the ownership.
PP.AddPragmaHandler(new PragmaLinkCollector(fLDR));
PP.AddPragmaHandler(new PragmaCreateCollector(fLDR));
PP.AddPragmaHandler(new PragmaExtraInclude(fLDR));
PP.AddPragmaHandler(new PragmaIoReadInclude(fLDR));
return clang::SyntaxOnlyAction::BeginSourceFileAction(CI);
}

clang::Preprocessor &PP = pragmaCI->getPreprocessor();
clang::DiagnosticConsumer &DClient = pragmaCI->getDiagnosticClient();
DClient.BeginSourceFile(pragmaCI->getLangOpts(), &PP);

// FIXME: Reduce the code duplication across these collector classes.
PragmaLinkCollector pragmaLinkCollector(*this);
PragmaCreateCollector pragmaCreateCollector(*this);
PragmaExtraInclude pragmaExtraInclude(*this);
PragmaIoReadInclude pragmaIoReadInclude(*this);

PP.AddPragmaHandler(&pragmaLinkCollector);
PP.AddPragmaHandler(&pragmaCreateCollector);
PP.AddPragmaHandler(&pragmaExtraInclude);
PP.AddPragmaHandler(&pragmaIoReadInclude);

// Start parsing the specified input file.
PP.EnterMainSourceFile();
clang::Token tok;
do {
PP.Lex(tok);
} while (tok.isNot(clang::tok::annot_repl_input_end));
void ExecuteAction() override
{
clang::CompilerInstance &CI = getCompilerInstance();
if (!CI.hasPreprocessor())
return;

// FIXME: Move the truncation aspect of this into Sema, we delayed this
// till here so the source manager would be initialized.
// if (hasCodeCompletionSupport() && !CI.getFrontendOpts().CodeCompletionAt.FileName.empty())
// CI.createCodeCompletionConsumer();

// // Use a code completion consumer?
// clang::CodeCompleteConsumer *CompletionConsumer = nullptr;
// if (CI.hasCodeCompletionConsumer())
// CompletionConsumer = &CI.getCodeCompletionConsumer();

// if (!CI.hasSema())
// CI.createSema(getTranslationUnitKind(), CompletionConsumer);

clang::Preprocessor &PP = CI.getPreprocessor();

PP.EnterMainSourceFile();
clang::Token tok;
do {
PP.Lex(tok);
} while (tok.isNot(clang::tok::annot_repl_input_end));

if ((0 != CI.getDiagnosticClient().getNumErrors()) && !isError)
isError = true;
}

bool usesPreprocessorOnly() const override { return true; }
} Act(*this, COpts);

pragmaCI->ExecuteAction(Act);

fSelectionRules = nullptr;
return 0 == DClient.getNumErrors();
return !Act.isError;
}
2 changes: 1 addition & 1 deletion core/dictgen/src/rootcling_impl.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -4986,7 +4986,7 @@ int RootClingMain(int argc,
// module file that we currently generate.
{
cling::Interpreter::PushTransactionRAII RAII(&interp);
CI->getSema().getASTConsumer().HandleTranslationUnit(CI->getSema().getASTContext());
interp.GeneratePCH();
}

// Add the warnings
Expand Down
2 changes: 2 additions & 0 deletions interpreter/cling/include/cling/Interpreter/CIFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ namespace cling {
using ModuleFileExtensions =
std::vector<std::shared_ptr<clang::ModuleFileExtension>>;

void collectModule(clang::CompilerInstance &CI);
// TODO: Add overload that takes file not MemoryBuffer

clang::CompilerInstance*
Expand All @@ -48,6 +49,7 @@ namespace cling {
std::optional<std::unique_ptr<clang::ASTConsumer>> consumerOpt,
const ModuleFileExtensions& moduleExtensions,
bool OnlyLex = false);
unsigned CxxStdCompiledWith();
} // namespace CIFactory
} // namespace cling
#endif // CLING_CIFACTORY_H
12 changes: 12 additions & 0 deletions interpreter/cling/include/cling/Interpreter/Interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ namespace cling {
class CompilationOptions;
class DynamicLibraryManager;
class IncrementalCUDADeviceCompiler;
class IncrementalAction;
class IncrementalExecutor;
class IncrementalParser;
class InterpreterCallbacks;
Expand Down Expand Up @@ -184,6 +185,14 @@ namespace cling {
///
std::unique_ptr<llvm::orc::ThreadSafeContext> TSCtx;

///\brief compiler instance.
///
std::unique_ptr<clang::CompilerInstance> m_CI;

///\brief The FrontendAction
///
std::unique_ptr<IncrementalAction> m_Act;

///\brief Cling's execution engine - a well wrapped llvm execution engine.
///
std::unique_ptr<IncrementalExecutor> m_Executor;
Expand Down Expand Up @@ -388,6 +397,9 @@ namespace cling {
///
bool isValid() const;

/// Generate PCH file.
void GeneratePCH();

const InvocationOptions& getOptions() const { return m_Opts; }
InvocationOptions& getOptions() { return m_Opts; }

Expand Down
Loading