clang: lib/Interpreter/IncrementalParser.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
14
20#include "llvm/Support/CrashRecoveryContext.h"
21#include "llvm/Support/Error.h"
22
23#include
24
26
27
28
30 llvm::Error &Err)
31 : S(Instance.getSema()) {
32 llvm::ErrorAsOutParameter EAO(&Err);
35 P->Initialize();
36}
37
39
41IncrementalParser::ParseOrWrapTopLevelDecl() {
42
43 llvm::CrashRecoveryContextCleanupRegistrar CleanupSema(&S);
46
47
49 C.addTranslationUnitDecl();
50
51
52 if (P->getCurToken().is(tok::annot_repl_input_end)) {
53 P->ConsumeAnyToken();
54
55
56 P->ExitScope();
58
61 }
62
65 for (bool AtEOF = P->ParseFirstTopLevelDecl(ADecl, ImportState); !AtEOF;
66 AtEOF = P->ParseTopLevelDecl(ADecl, ImportState)) {
68 return llvm::make_errorllvm::StringError("Parsing failed. "
69 "The consumer rejected a decl",
70 std::error_code());
71 }
72
74 if (Diags.hasErrorOccurred()) {
76
77 Diags.Reset(true);
78 Diags.getClient()->clear();
79 return llvm::make_errorllvm::StringError("Parsing failed.",
80 std::error_code());
81 }
82
83
85 DeclGroupRef DGR(D);
87 }
88
89 LocalInstantiations.perform();
90 GlobalInstantiations.perform();
91
93
94 return C.getTranslationUnitDecl();
95}
96
101
102 std::ostringstream SourceName;
103 SourceName << "input_line_" << InputCount++;
104
105
106 size_t InputSize = input.size();
107
108 std::unique_ptrllvm::MemoryBuffer MB(
109 llvm::WritableMemoryBuffer::getNewUninitMemBuffer(InputSize + 1,
110 SourceName.str()));
111 char *MBStart = const_cast<char *>(MB->getBufferStart());
112 memcpy(MBStart, input.data(), InputSize);
113 MBStart[InputSize] = '\n';
114
116
117
118
120
121
123 0, NewLoc);
124
125
126 if (PP.EnterSourceFile(FID, nullptr, NewLoc))
127 return llvm::make_errorllvm::StringError("Parsing failed. "
128 "Cannot enter source file.",
129 std::error_code());
130
131 auto PTU = ParseOrWrapTopLevelDecl();
132 if (!PTU)
133 return PTU.takeError();
134
135 if (PP.getLangOpts().DelayedTemplateParsing) {
136
137
138
139
141 do {
142 PP.Lex(Tok);
143 } while (Tok.isNot(tok::annot_repl_input_end));
144 } else {
146 PP.Lex(AssertTok);
147 assert(AssertTok.is(tok::annot_repl_input_end) &&
148 "Lexer must be EOF when starting incremental parse!");
149 }
150
151 return PTU;
152}
153
156 for (auto &&[Key, List] : *Map) {
158 std::vector<NamedDecl *> NamedDeclsToRemove;
159 bool RemoveAll = true;
161 if (D->getTranslationUnitDecl() == MostRecentTU)
162 NamedDeclsToRemove.push_back(D);
163 else
164 RemoveAll = false;
165 }
166 if (LLVM_LIKELY(RemoveAll)) {
167 Map->erase(Key);
168 } else {
169 for (NamedDecl *D : NamedDeclsToRemove)
170 List.remove(D);
171 }
172 }
173 }
174
175
176 for (Decl *D : MostRecentTU->decls()) {
177 auto *ND = dyn_cast(D);
178 if (!ND)
179 continue;
180
181 if (ND->getDeclName().getFETokenInfo() && ->getLangOpts().ObjC &&
182 ->getLangOpts().CPlusPlus)
184 }
185}
186
187}
__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.
IncrementalParser(CompilerInstance &Instance, llvm::Error &Err)
virtual ~IncrementalParser()
unsigned InputCount
Counts the number of direct user input lines that have been parsed.
void CleanUpPTU(TranslationUnitDecl *MostRecentTU)
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.