21#include "llvm/IR/Module.h"
22#include "llvm/Support/CrashRecoveryContext.h"
23#include "llvm/Support/Error.h"
27#define DEBUG_TYPE "clang-repl"
35 std::list<PartialTranslationUnit> &PTUs)
36 : S(Instance.getSema()), Act(Act), PTUs(PTUs) {
37 llvm::ErrorAsOutParameter EAO(&Err);
46IncrementalParser::ParseOrWrapTopLevelDecl() {
48 llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema(&
S);
55 C.addTranslationUnitDecl();
58 if (
P->getCurToken().is(tok::annot_repl_input_end)) {
71 for (
bool AtEOF =
P->ParseFirstTopLevelDecl(ADecl, ImportState); !AtEOF;
72 AtEOF =
P->ParseTopLevelDecl(ADecl, ImportState)) {
74 return llvm::make_error<llvm::StringError>(
"Parsing failed. "
75 "The consumer rejected a decl",
80 if (Diags.hasErrorOccurred()) {
84 Diags.getClient()->clear();
85 return llvm::make_error<llvm::StringError>(
"Parsing failed.",
95 LocalInstantiations.perform();
96 GlobalInstantiations.perform();
100 return C.getTranslationUnitDecl();
108 std::ostringstream SourceName;
112 size_t InputSize = input.size();
114 std::unique_ptr<llvm::MemoryBuffer> MB(
115 llvm::WritableMemoryBuffer::getNewUninitMemBuffer(InputSize + 1,
117 char *MBStart =
const_cast<char *
>(MB->getBufferStart());
118 memcpy(MBStart, input.data(), InputSize);
119 MBStart[InputSize] =
'\n';
133 return llvm::make_error<llvm::StringError>(
"Parsing failed. "
134 "Cannot enter source file.",
137 auto PTU = ParseOrWrapTopLevelDecl();
139 return PTU.takeError();
149 }
while (Tok.
isNot(tok::annot_repl_input_end));
153 assert(AssertTok.
is(tok::annot_repl_input_end) &&
154 "Lexer must be EOF when starting incremental parse!");
162 for (
auto &&[Key, List] : *Map) {
164 std::vector<NamedDecl *> NamedDeclsToRemove;
165 bool RemoveAll =
true;
167 if (
D->getTranslationUnitDecl() == MostRecentTU)
168 NamedDeclsToRemove.push_back(
D);
172 if (LLVM_LIKELY(RemoveAll)) {
183 auto *ND = dyn_cast<NamedDecl>(
D);
184 if (!ND || ND->getDeclName().isEmpty())
187 if (ND->getDeclName().getFETokenInfo() && !
D->getLangOpts().ObjC &&
188 !
D->getLangOpts().CPlusPlus)
195 std::unique_ptr<llvm::Module> M ) {
203 assert((!
Act->
getCodeGen() || M) &&
"Must have a llvm::Module at this point");
206 LLVM_DEBUG(llvm::dbgs() <<
"compile-ptu " <<
PTUs.size() - 1
207 <<
": [TU=" << LastPTU.
TUPart);
209 LLVM_DEBUG(llvm::dbgs() <<
", M=" << LastPTU.
TheModule.get() <<
" ("
211 LLVM_DEBUG(llvm::dbgs() <<
"]\n");
__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 ...
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
The results of name lookup within a DeclContext.
DeclContext * getPrimaryContext()
getPrimaryContext - There may be many different declarations of the same entity (including forward de...
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
StoredDeclsMap * getLookupPtr() const
Retrieve the internal representation of the lookup structure.
Decl - This represents one declaration (or definition), e.g.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
void RemoveDecl(NamedDecl *D)
RemoveDecl - Unlink the decl from its shadowed decl chain.
A custom action enabling the incremental processing functionality.
CodeGenerator * getCodeGen() const
Access the current code generator.
std::unique_ptr< llvm::Module > GenModule()
Generate an LLVM module for the most recent parsed input.
IncrementalParser(CompilerInstance &Instance, IncrementalAction *Act, llvm::Error &Err, std::list< PartialTranslationUnit > &PTUs)
IncrementalAction * Act
The FrontendAction used during incremental parsing.
std::list< PartialTranslationUnit > & PTUs
virtual ~IncrementalParser()
unsigned InputCount
Counts the number of direct user input lines that have been parsed.
void CleanUpPTU(TranslationUnitDecl *MostRecentTU)
PartialTranslationUnit & RegisterPTU(TranslationUnitDecl *TU, std::unique_ptr< llvm::Module > M={})
Register a PTU produced by Parse.
virtual llvm::Expected< TranslationUnitDecl * > Parse(llvm::StringRef Input)
Parses incremental input by creating an in-memory file.
std::unique_ptr< Parser > P
Parser.
ASTConsumer * Consumer
Consumer to process the produced top level decls. Owned by Act.
Sema & S
The Sema performing the incremental compilation.
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...
const LangOptions & getLangOpts() const
@ DeclScope
This is a scope that can contain a declaration.
Preprocessor & getPreprocessor() const
void ActOnTranslationUnitScope(Scope *S)
Scope actions.
DiagnosticsEngine & getDiagnostics() const
ASTContext & getASTContext() const
SmallVectorImpl< Decl * > & WeakTopLevelDecls()
WeakTopLevelDeclDecls - access to #pragma weak-generated Decls.
ASTConsumer & getASTConsumer() const
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
SourceManager & getSourceManager() const
ModuleImportState
An enumeration to represent the transition of states in parsing module fragments and imports.
IdentifierResolver IdResolver
Encodes a location in the source.
This class handles loading and caching of source files into memory.
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.
The JSON file list parser is used to communicate input to InstallAPI.
The class keeps track of various objects created as part of processing incremental inputs.
TranslationUnitDecl * TUPart
std::unique_ptr< llvm::Module > TheModule
The llvm IR produced for the input.