25#include "llvm/Option/ArgList.h"
26#include "llvm/Support/CrashRecoveryContext.h"
27#include "llvm/Support/Error.h"
28#include "llvm/Support/Timer.h"
45 bool IsTerminating =
false;
51 llvm::ErrorAsOutParameter EAO(&Err);
52 std::unique_ptr<FrontendAction> Act;
55 Err = llvm::createStringError(
56 std::errc::state_not_recoverable,
57 "Driver initialization failed. "
58 "Incremental mode for action %d is not supported",
119 assert(!IsTerminating &&
"Already finalized!");
120 IsTerminating =
true;
126 llvm::LLVMContext &LLVMCtx,
128 : CI(
std::move(Instance)) {
129 llvm::ErrorAsOutParameter EAO(&Err);
130 Act = std::make_unique<IncrementalAction>(*CI, LLVMCtx, Err);
133 CI->ExecuteAction(*Act);
134 Consumer = &CI->getASTConsumer();
136 new Parser(CI->getPreprocessor(), CI->getSema(),
false));
142 Act->FinalizeAction();
146IncrementalParser::ParseOrWrapTopLevelDecl() {
148 Sema &S = CI->getSema();
149 llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema(&S);
157 C.addTranslationUnitDecl();
158 LastPTU.
TUPart =
C.getTranslationUnitDecl();
161 if (P->getCurToken().is(tok::eof)) {
166 S.CurContext =
nullptr;
169 S.ActOnTranslationUnitScope(P->getCurScope());
174 for (
bool AtEOF = P->ParseFirstTopLevelDecl(ADecl, ImportState); !AtEOF;
175 AtEOF = P->ParseTopLevelDecl(ADecl, ImportState)) {
177 return llvm::make_error<llvm::StringError>(
"Parsing failed. "
178 "The consumer rejected a decl",
183 if (Diags.hasErrorOccurred()) {
184 PartialTranslationUnit MostRecentPTU = {
C.getTranslationUnitDecl(),
189 Diags.getClient()->clear();
190 return llvm::make_error<llvm::StringError>(
"Parsing failed.",
195 for (Decl *D : S.WeakTopLevelDecls()) {
200 LocalInstantiations.perform();
201 GlobalInstantiations.perform();
213 return static_cast<CodeGenAction *
>(WrappedAct)->getCodeGenerator();
221 std::ostringstream SourceName;
222 SourceName <<
"input_line_" << InputCount++;
225 size_t InputSize = input.size();
227 std::unique_ptr<llvm::MemoryBuffer> MB(
228 llvm::WritableMemoryBuffer::getNewUninitMemBuffer(InputSize + 1,
230 char *MBStart =
const_cast<char *
>(MB->getBufferStart());
231 memcpy(MBStart, input.data(), InputSize);
232 MBStart[InputSize] =
'\n';
246 return llvm::make_error<llvm::StringError>(
"Parsing failed. "
247 "Cannot enter source file.",
250 auto PTU = ParseOrWrapTopLevelDecl();
252 return PTU.takeError();
262 }
while (Tok.
isNot(tok::eof));
267 assert(AssertTok.
is(tok::eof) &&
268 "Lexer must be EOF when starting incremental parse!");
271 std::unique_ptr<llvm::Module> M(CG->ReleaseModule());
272 CG->StartModule(
"incr_module_" + std::to_string(PTUs.size()),
275 PTU->TheModule = std::move(M);
285 for (
auto I = Map->begin(); I != Map->end(); ++I) {
289 if (D->getTranslationUnitDecl() == MostRecentTU) {
Defines the clang::FrontendAction interface and various convenience abstract classes (clang::ASTFront...
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
virtual void HandleTranslationUnit(ASTContext &Ctx)
HandleTranslationUnit - This method is called when the ASTs for entire translation unit have been par...
virtual bool HandleTopLevelDecl(DeclGroupRef D)
HandleTopLevelDecl - Handle the specified top-level declaration.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Abstract interface for a consumer of code-completion information.
The primary public interface to the Clang code generator.
llvm::StringRef GetMangledName(GlobalDecl GD)
Given a global declaration, return a mangled name for this declaration which has been added to this c...
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
Preprocessor & getPreprocessor() const
Return the current preprocessor.
FrontendOptions & getFrontendOpts()
bool hasCodeCompletionConsumer() const
void createCodeCompletionConsumer()
Create a code completion consumer using the invocation; note that this will cause the source manager ...
CodeCompleteConsumer & getCodeCompletionConsumer() const
bool hasPreprocessor() const
void createSema(TranslationUnitKind TUKind, CodeCompleteConsumer *CompletionConsumer)
Create the Sema object to be used for parsing.
The results of name lookup within a DeclContext.
DeclContext * getPrimaryContext()
getPrimaryContext - There may be many different declarations of the same entity (including forward de...
StoredDeclsMap * getLookupPtr() const
Retrieve the internal representation of the lookup structure.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Abstract base class for actions which can be performed by the frontend.
virtual bool hasIRSupport() const
Does this action support use with IR files?
CompilerInstance & getCompilerInstance() const
ParsedSourceLocation CodeCompletionAt
If given, enable code completion at the provided location.
frontend::ActionKind ProgramAction
The frontend action to perform.
GlobalDecl - represents a global declaration.
A custom action enabling the incremental processing functionality.
void ExecuteAction() override
Callback to run the program action, using the initialized compiler instance.
TranslationUnitKind getTranslationUnitKind() override
For AST-based actions, the kind of translation unit we're handling.
IncrementalAction(CompilerInstance &CI, llvm::LLVMContext &LLVMCtx, llvm::Error &Err)
FrontendAction * getWrapped() const
void EndSourceFile() override
Perform any per-file post processing, deallocate per-file objects, and run statistics and output file...
llvm::StringRef GetMangledName(GlobalDecl GD) const
Uses the CodeGenModule mangled name cache and avoids recomputing.
IncrementalParser(std::unique_ptr< CompilerInstance > Instance, llvm::LLVMContext &LLVMCtx, llvm::Error &Err)
llvm::Expected< PartialTranslationUnit & > Parse(llvm::StringRef Input)
Parses incremental input by creating an in-memory file.
void CleanUpPTU(PartialTranslationUnit &PTU)
const CompilerInstance * getCI() const
This represents a decl that may have a name.
Parser - This implements a parser for the C family of languages.
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
bool isIncrementalProcessingEnabled() const
Returns true if incremental processing is enabled.
void Lex(Token &Result)
Lex the next token for this preprocessor.
bool EnterSourceFile(FileID FID, ConstSearchDirIterator Dir, SourceLocation Loc, bool IsFirstIncludeOfFile=true)
Add a source file to the top of the include stack and start lexing tokens from it instead of the curr...
void EnterMainSourceFile()
Enter the specified FileID as the main source file, which implicitly adds the builtin defines etc.
const LangOptions & getLangOpts() const
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
@ DeclScope
This is a scope that can contain a declaration.
Sema - This implements semantic analysis and AST building for C.
ModuleImportState
An enumeration to represent the transition of states in parsing module fragments and imports.
Encodes a location in the source.
This class handles loading and caching of source files into memory.
An array of decls optimized for the common case of only containing one entry.
Token - This structure provides full information about a lexed token.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
bool isNot(tok::TokenKind K) const
The top declaration context.
A frontend action which simply wraps some other runtime-specified frontend action.
bool hasCodeCompletionSupport() const override
Does this action support use with code completion?
std::unique_ptr< FrontendAction > WrappedAction
void EndSourceFile() override
Perform any per-file post processing, deallocate per-file objects, and run statistics and output file...
@ PrintPreprocessedInput
-E mode.
@ ParseSyntaxOnly
Parse and perform semantic analysis.
@ PluginAction
Run a plugin action,.
@ ASTPrint
Parse ASTs and print them.
@ ASTDump
Parse ASTs and dump them.
@ EmitAssembly
Emit a .s file.
@ EmitLLVMOnly
Generate LLVM IR, but do not emit anything.
static CodeGenerator * getCodeGen(FrontendAction *Act)
std::unique_ptr< FrontendAction > CreateFrontendAction(CompilerInstance &CI)
Construct the FrontendAction of a compiler invocation based on the options specified for the compiler...
@ C
Languages that the frontend can parse and compile.
TranslationUnitKind
Describes the kind of translation unit being processed.
@ TU_Incremental
The translation unit is a is a complete translation unit that we might incrementally extend later.
The class keeps track of various objects created as part of processing incremental inputs.
TranslationUnitDecl * TUPart