23#include "llvm/ADT/SmallVector.h"
24#include "llvm/IR/Module.h"
25#include "llvm/Support/CrashRecoveryContext.h"
26#include "llvm/Support/Error.h"
30#define DEBUG_TYPE "clang-repl"
38 std::list<PartialTranslationUnit> &
PTUs)
40 llvm::ErrorAsOutParameter EAO(&Err);
42 P.reset(
new Parser(
S.getPreprocessor(),
S,
false));
53IncrementalParser::ParseOrWrapTopLevelDecl() {
55 llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema(&
S);
62 C.addTranslationUnitDecl();
65 if (
P->getCurToken().is(tok::annot_repl_input_end)) {
78 for (
bool AtEOF =
P->ParseFirstTopLevelDecl(ADecl, ImportState); !AtEOF;
79 AtEOF =
P->ParseTopLevelDecl(ADecl, ImportState)) {
81 return llvm::make_error<llvm::StringError>(
"Parsing failed. "
82 "The consumer rejected a decl",
86 DiagnosticsEngine &Diags =
S.getDiagnostics();
87 if (Diags.hasErrorOccurred()) {
91 Diags.getClient()->clear();
92 return llvm::make_error<llvm::StringError>(
"Parsing failed.",
97 for (Decl *D :
S.WeakTopLevelDecls()) {
102 LocalInstantiations.perform();
103 GlobalInstantiations.perform();
107 return C.getTranslationUnitDecl();
115 std::ostringstream SourceName;
119 size_t InputSize = input.size();
121 std::unique_ptr<llvm::MemoryBuffer> MB(
122 llvm::WritableMemoryBuffer::getNewUninitMemBuffer(InputSize + 1,
124 char *MBStart =
const_cast<char *
>(MB->getBufferStart());
125 memcpy(MBStart, input.data(), InputSize);
126 MBStart[InputSize] =
'\n';
138 SourceName.str(), InputSize, 0 );
149 return llvm::make_error<llvm::StringError>(
"Parsing failed. "
150 "Cannot enter source file.",
153 auto PTU = ParseOrWrapTopLevelDecl();
155 return PTU.takeError();
165 }
while (
Tok.isNot(tok::annot_repl_input_end));
169 assert(AssertTok.
is(tok::annot_repl_input_end) &&
170 "Lexer must be EOF when starting incremental parse!");
176void IncrementalParser::withdrawMostRecentTU(
182 "Not the most recent translation unit!");
189 if (
C.TraversalScope.size() == 1 &&
C.TraversalScope.back() == MostRecentTU)
190 C.TraversalScope = {Prev};
199 for (
auto &&[Key, List] : *Map) {
201 std::vector<NamedDecl *> NamedDeclsToRemove;
202 bool RemoveAll =
true;
204 if (D->getTranslationUnitDecl() == MostRecentTU)
205 NamedDeclsToRemove.push_back(D);
209 if (LLVM_LIKELY(RemoveAll)) {
210 KeysToErase.push_back(Key);
221 auto RemoveFromIdResolver = [&](
NamedDecl *D) {
222 if (D->getDeclName().getFETokenInfo() && !D->getLangOpts().ObjC &&
223 !D->getLangOpts().CPlusPlus)
224 S.IdResolver.RemoveDecl(D);
229 for (
auto &&[Key, List] : *Map) {
240 if (TopTU == MostRecentTU)
241 NamedDeclsToRemove.push_back(D);
243 for (
NamedDecl *D : NamedDeclsToRemove) {
245 RemoveFromIdResolver(D);
251 auto *ND = dyn_cast<NamedDecl>(D);
252 if (!ND || ND->getDeclName().isEmpty())
254 RemoveFromIdResolver(ND);
258 withdrawMostRecentTU(MostRecentTU);
263 std::unique_ptr<llvm::Module> M ) {
269 M =
Act->GenModule();
271 assert((!
Act->getCodeGen() || M) &&
"Must have a llvm::Module at this point");
274 LLVM_DEBUG(llvm::dbgs() <<
"compile-ptu " <<
PTUs.size() - 1
275 <<
": [TU=" << LastPTU.
TUPart);
277 LLVM_DEBUG(llvm::dbgs() <<
", M=" << LastPTU.
TheModule.get() <<
" ("
279 LLVM_DEBUG(llvm::dbgs() <<
"]\n");
Defines the clang::ASTContext interface.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
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 - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical 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.
The name of a declaration.
Declaration context for names declared as extern "C" in C++.
Abstract interface for external sources of AST nodes.
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
FileEntryRef getVirtualFileRef(StringRef Filename, off_t Size, time_t ModificationTime)
Retrieve a file entry for a "virtual" file that acts as if there were a file with the given name on d...
A custom action enabling the incremental processing functionality.
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...
HeaderSearch & getHeaderSearchInfo() const
const LangOptions & getLangOpts() const
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
DeclLink RedeclLink
Points to the next redeclaration in the chain.
@ DeclScope
This is a scope that can contain a declaration.
void ActOnTranslationUnitScope(Scope *S)
Scope actions.
ASTContext & getASTContext() const
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
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.
FileID createFileID(FileEntryRef SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID=0, SourceLocation::UIntTy LoadedOffset=0)
Create a new FileID that represents the specified file being #included from the specified IncludePosi...
FileManager & getFileManager() const
FileID getMainFileID() const
Returns the FileID of the main source file.
void overrideFileContents(FileEntryRef SourceFile, const llvm::MemoryBufferRef &Buffer)
Override the contents of the given source file by providing an already-allocated buffer.
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file.
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)) {....
The top declaration context.
TranslationUnitDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
TranslationUnitDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
@ External
External linkage, which indicates that the entity can be referred to from other translation units.
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.