26#include "llvm/ADT/SmallVector.h"
27#include "llvm/IR/Module.h"
28#include "llvm/Support/CrashRecoveryContext.h"
29#include "llvm/Support/Error.h"
33#define DEBUG_TYPE "clang-repl"
41 std::list<PartialTranslationUnit> &
PTUs)
43 llvm::ErrorAsOutParameter EAO(&Err);
45 P.reset(
new Parser(
S.getPreprocessor(),
S,
false));
56IncrementalParser::ParseOrWrapTopLevelDecl() {
58 llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema(&
S);
65 C.addTranslationUnitDecl();
68 if (
P->getCurToken().is(tok::annot_repl_input_end)) {
81 for (
bool AtEOF =
P->ParseFirstTopLevelDecl(ADecl, ImportState); !AtEOF;
82 AtEOF =
P->ParseTopLevelDecl(ADecl, ImportState)) {
84 return llvm::make_error<llvm::StringError>(
"Parsing failed. "
85 "The consumer rejected a decl",
89 DiagnosticsEngine &Diags =
S.getDiagnostics();
90 if (Diags.hasErrorOccurred()) {
94 Diags.getClient()->clear();
95 return llvm::make_error<llvm::StringError>(
"Parsing failed.",
100 for (Decl *D :
S.WeakTopLevelDecls()) {
105 LocalInstantiations.perform();
106 GlobalInstantiations.perform();
110 return C.getTranslationUnitDecl();
118 std::ostringstream SourceName;
122 size_t InputSize = input.size();
124 std::unique_ptr<llvm::MemoryBuffer> MB(
125 llvm::WritableMemoryBuffer::getNewUninitMemBuffer(InputSize + 1,
127 char *MBStart =
const_cast<char *
>(MB->getBufferStart());
128 memcpy(MBStart, input.data(), InputSize);
129 MBStart[InputSize] =
'\n';
141 SourceName.str(), InputSize, 0 );
152 return llvm::make_error<llvm::StringError>(
"Parsing failed. "
153 "Cannot enter source file.",
156 auto PTU = ParseOrWrapTopLevelDecl();
158 return PTU.takeError();
168 }
while (
Tok.isNot(tok::annot_repl_input_end));
172 assert(AssertTok.
is(tok::annot_repl_input_end) &&
173 "Lexer must be EOF when starting incremental parse!");
179void IncrementalParser::withdrawMostRecentTU(
185 "Not the most recent translation unit!");
192 if (
C.TraversalScope.size() == 1 &&
C.TraversalScope.back() == MostRecentTU)
193 C.TraversalScope = {Prev};
204 if (
NamedDecl *Prev = findSurvivor(
static_cast<DeclT *
>(DBase)))
205 unlinkRedeclChain(S.getASTContext(), DBase, Prev);
214 return dyn_cast<NamedDecl>(Prev);
218 template <
typename DeclT>
221 auto *Latest =
static_cast<DeclT *
>(DBase);
226 Latest->getFirstDecl()->RedeclLink.setLatest(Survivor);
231 for (DeclT *Dead = Latest; Dead != Survivor;) {
232 DeclT *
Next = Dead->getPreviousDecl();
246 S.IdResolver.RemoveDecl(D);
251 if (It != Map->end())
252 It->second.remove(D);
261 for (
Decl *M : Members) {
262 if (
auto *ND = dyn_cast<NamedDecl>(M))
264 Survivors.push_back(Prev);
267 if (
auto *ND = dyn_cast<NamedDecl>(M))
268 removeFromLookups(ND);
280 : S(S), DiscardedTU(DiscardedTU) {}
283 if (
auto *DC = dyn_cast<DeclContext>(D))
284 VisitDeclContext(DC);
297 unlinkRedeclChain(S.getASTContext(), D, Prev);
301 auto *RD = dyn_cast<CXXRecordDecl>(Prev);
306 for (
auto *R : RD->redecls())
331 withdrawMostRecentTU(MostRecentTU);
336 std::unique_ptr<llvm::Module> M ) {
342 M =
Act->GenModule();
344 assert((!
Act->getCodeGen() || M) &&
"Must have a llvm::Module at this point");
347 LLVM_DEBUG(llvm::dbgs() <<
"compile-ptu " <<
PTUs.size() - 1
348 <<
": [TU=" << LastPTU.
TUPart);
350 LLVM_DEBUG(llvm::dbgs() <<
", M=" << LastPTU.
TheModule.get() <<
" ("
352 LLVM_DEBUG(llvm::dbgs() <<
"]\n");
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
__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 ...
ExternCContextDecl * getExternCContextDecl() const
Removes decls introduced in the discarding PTU and restores the redeclaration chain to previous state...
void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D)
void VisitVarDecl(VarDecl *D)
void VisitFunctionDecl(FunctionDecl *D)
ASTDeclUnmerger(Sema &S, TranslationUnitDecl *DiscardedTU)
void VisitTypedefNameDecl(TypedefNameDecl *D)
void VisitTranslationUnitDecl(TranslationUnitDecl *D)
void VisitNamespaceDecl(NamespaceDecl *D)
void VisitUsingShadowDecl(UsingShadowDecl *D)
void VisitTagDecl(TagDecl *D)
void VisitNamespaceAliasDecl(NamespaceAliasDecl *D)
Represents a C++ struct/union/class.
CXXRecordDecl * getDefinition() const
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
void makeDeclVisibleInContext(NamedDecl *D)
Makes a declaration visible within this context.
void removeDecl(Decl *D)
Removes a declaration from this context.
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.
A simple visitor class that helps create declaration visitors.
Decl - This represents one declaration (or definition), e.g.
Decl * getPreviousDecl()
Retrieve the previous declaration that declares the same entity as this declaration,...
ASTContext & getASTContext() const LLVM_READONLY
TranslationUnitDecl * getTranslationUnitDecl()
const LangOptions & getLangOpts() const LLVM_READONLY
Helper to get the language options from the ASTContext.
void * getFETokenInfo() const
Get and set FETokenInfo.
bool isEmpty() const
Evaluates true when this declaration name is empty.
bool isIdentifier() const
Predicate functions for querying what type of name this is.
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...
Represents a function declaration or definition.
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.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represents a C++ namespace alias.
Represent a C++ namespace.
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
Declaration of a redeclarable template.
Provides common interface for the Decls that can be redeclared.
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.
static DeclLink LatestDeclLink(const ASTContext &Ctx)
@ DeclScope
This is a scope that can contain a declaration.
Sema - This implements semantic analysis and AST building for C.
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.
Represents the declaration of a struct/union/class/enum.
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
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.
Base class for declarations which introduce a typedef-name.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Represents a variable declaration or definition.
Top level wrappers for InstallAPI frontend operations.
@ External
External linkage, which indicates that the entity can be referred to from other translation units.
U cast(CodeGen::Address addr)
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.