1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | #include "clang/Lex/Preprocessor.h" |
28 | #include "clang/Basic/FileManager.h" |
29 | #include "clang/Basic/FileSystemStatCache.h" |
30 | #include "clang/Basic/IdentifierTable.h" |
31 | #include "clang/Basic/LLVM.h" |
32 | #include "clang/Basic/LangOptions.h" |
33 | #include "clang/Basic/Module.h" |
34 | #include "clang/Basic/SourceLocation.h" |
35 | #include "clang/Basic/SourceManager.h" |
36 | #include "clang/Basic/TargetInfo.h" |
37 | #include "clang/Lex/CodeCompletionHandler.h" |
38 | #include "clang/Lex/ExternalPreprocessorSource.h" |
39 | #include "clang/Lex/HeaderSearch.h" |
40 | #include "clang/Lex/LexDiagnostic.h" |
41 | #include "clang/Lex/Lexer.h" |
42 | #include "clang/Lex/LiteralSupport.h" |
43 | #include "clang/Lex/MacroArgs.h" |
44 | #include "clang/Lex/MacroInfo.h" |
45 | #include "clang/Lex/ModuleLoader.h" |
46 | #include "clang/Lex/Pragma.h" |
47 | #include "clang/Lex/PreprocessingRecord.h" |
48 | #include "clang/Lex/PreprocessorLexer.h" |
49 | #include "clang/Lex/PreprocessorOptions.h" |
50 | #include "clang/Lex/ScratchBuffer.h" |
51 | #include "clang/Lex/Token.h" |
52 | #include "clang/Lex/TokenLexer.h" |
53 | #include "llvm/ADT/APInt.h" |
54 | #include "llvm/ADT/ArrayRef.h" |
55 | #include "llvm/ADT/DenseMap.h" |
56 | #include "llvm/ADT/SmallString.h" |
57 | #include "llvm/ADT/SmallVector.h" |
58 | #include "llvm/ADT/STLExtras.h" |
59 | #include "llvm/ADT/StringRef.h" |
60 | #include "llvm/ADT/StringSwitch.h" |
61 | #include "llvm/Support/Capacity.h" |
62 | #include "llvm/Support/ErrorHandling.h" |
63 | #include "llvm/Support/MemoryBuffer.h" |
64 | #include "llvm/Support/raw_ostream.h" |
65 | #include <algorithm> |
66 | #include <cassert> |
67 | #include <memory> |
68 | #include <string> |
69 | #include <utility> |
70 | #include <vector> |
71 | |
72 | using namespace clang; |
73 | |
74 | LLVM_INSTANTIATE_REGISTRY(PragmaHandlerRegistry) |
75 | |
76 | ExternalPreprocessorSource::~ExternalPreprocessorSource() = default; |
77 | |
78 | Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts, |
79 | DiagnosticsEngine &diags, LangOptions &opts, |
80 | SourceManager &SM, HeaderSearch &, |
81 | ModuleLoader &TheModuleLoader, |
82 | IdentifierInfoLookup *IILookup, bool , |
83 | TranslationUnitKind TUKind) |
84 | : PPOpts(std::move(PPOpts)), Diags(&diags), LangOpts(opts), |
85 | FileMgr(Headers.getFileMgr()), SourceMgr(SM), |
86 | ScratchBuf(new ScratchBuffer(SourceMgr)), HeaderInfo(Headers), |
87 | TheModuleLoader(TheModuleLoader), ExternalSource(nullptr), |
88 | |
89 | |
90 | |
91 | Identifiers(IILookup), PragmaHandlers(new PragmaNamespace(StringRef())), |
92 | TUKind(TUKind), SkipMainFilePreamble(0, true), |
93 | CurSubmoduleState(&NullSubmoduleState) { |
94 | OwnsHeaderSearch = OwnsHeaders; |
95 | |
96 | |
97 | KeepComments = false; |
98 | KeepMacroComments = false; |
99 | SuppressIncludeNotFoundError = false; |
100 | |
101 | |
102 | DisableMacroExpansion = false; |
103 | MacroExpansionInDirectivesOverride = false; |
104 | InMacroArgs = false; |
105 | ArgMacro = nullptr; |
106 | InMacroArgPreExpansion = false; |
107 | NumCachedTokenLexers = 0; |
108 | PragmasEnabled = true; |
109 | ParsingIfOrElifDirective = false; |
110 | PreprocessedOutput = false; |
111 | |
112 | |
113 | ReadMacrosFromExternalSource = false; |
114 | |
115 | |
116 | |
117 | (Ident__VA_ARGS__ = getIdentifierInfo("__VA_ARGS__"))->setIsPoisoned(); |
118 | SetPoisonReason(Ident__VA_ARGS__,diag::ext_pp_bad_vaargs_use); |
119 | if (getLangOpts().CPlusPlus2a) { |
120 | (Ident__VA_OPT__ = getIdentifierInfo("__VA_OPT__"))->setIsPoisoned(); |
121 | SetPoisonReason(Ident__VA_OPT__,diag::ext_pp_bad_vaopt_use); |
122 | } else { |
123 | Ident__VA_OPT__ = nullptr; |
124 | } |
125 | |
126 | |
127 | RegisterBuiltinPragmas(); |
128 | |
129 | |
130 | RegisterBuiltinMacros(); |
131 | |
132 | if(LangOpts.Borland) { |
133 | Ident__exception_info = getIdentifierInfo("_exception_info"); |
134 | Ident___exception_info = getIdentifierInfo("__exception_info"); |
135 | Ident_GetExceptionInfo = getIdentifierInfo("GetExceptionInformation"); |
136 | Ident__exception_code = getIdentifierInfo("_exception_code"); |
137 | Ident___exception_code = getIdentifierInfo("__exception_code"); |
138 | Ident_GetExceptionCode = getIdentifierInfo("GetExceptionCode"); |
139 | Ident__abnormal_termination = getIdentifierInfo("_abnormal_termination"); |
140 | Ident___abnormal_termination = getIdentifierInfo("__abnormal_termination"); |
141 | Ident_AbnormalTermination = getIdentifierInfo("AbnormalTermination"); |
142 | } else { |
143 | Ident__exception_info = Ident__exception_code = nullptr; |
144 | Ident__abnormal_termination = Ident___exception_info = nullptr; |
145 | Ident___exception_code = Ident___abnormal_termination = nullptr; |
146 | Ident_GetExceptionInfo = Ident_GetExceptionCode = nullptr; |
147 | Ident_AbnormalTermination = nullptr; |
148 | } |
149 | |
150 | |
151 | if (usingPCHWithPragmaHdrStop()) |
152 | SkippingUntilPragmaHdrStop = true; |
153 | |
154 | |
155 | if (!this->PPOpts->PCHThroughHeader.empty() && |
156 | !this->PPOpts->ImplicitPCHInclude.empty()) |
157 | SkippingUntilPCHThroughHeader = true; |
158 | |
159 | if (this->PPOpts->GeneratePreamble) |
160 | PreambleConditionalStack.startRecording(); |
161 | } |
162 | |
163 | Preprocessor::~Preprocessor() { |
164 | (0) . __assert_fail ("BacktrackPositions.empty() && \"EnableBacktrack/Backtrack imbalance!\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 164, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(BacktrackPositions.empty() && "EnableBacktrack/Backtrack imbalance!"); |
165 | |
166 | IncludeMacroStack.clear(); |
167 | |
168 | |
169 | while (MacroInfoChain *I = MIChainHead) { |
170 | MIChainHead = I->Next; |
171 | I->~MacroInfoChain(); |
172 | } |
173 | |
174 | |
175 | |
176 | |
177 | std::fill(TokenLexerCache, TokenLexerCache + NumCachedTokenLexers, nullptr); |
178 | CurTokenLexer.reset(); |
179 | |
180 | |
181 | for (MacroArgs *ArgList = MacroArgCache; ArgList;) |
182 | ArgList = ArgList->deallocate(); |
183 | |
184 | |
185 | if (OwnsHeaderSearch) |
186 | delete &HeaderInfo; |
187 | } |
188 | |
189 | void Preprocessor::Initialize(const TargetInfo &Target, |
190 | const TargetInfo *AuxTarget) { |
191 | (0) . __assert_fail ("(!this->Target || this->Target == &Target) && \"Invalid override of target information\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 192, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((!this->Target || this->Target == &Target) && |
192 | (0) . __assert_fail ("(!this->Target || this->Target == &Target) && \"Invalid override of target information\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 192, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Invalid override of target information"); |
193 | this->Target = &Target; |
194 | |
195 | (0) . __assert_fail ("(!this->AuxTarget || this->AuxTarget == AuxTarget) && \"Invalid override of aux target information.\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 196, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((!this->AuxTarget || this->AuxTarget == AuxTarget) && |
196 | (0) . __assert_fail ("(!this->AuxTarget || this->AuxTarget == AuxTarget) && \"Invalid override of aux target information.\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 196, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Invalid override of aux target information."); |
197 | this->AuxTarget = AuxTarget; |
198 | |
199 | |
200 | BuiltinInfo.InitializeTarget(Target, AuxTarget); |
201 | HeaderInfo.setTarget(Target); |
202 | |
203 | |
204 | Identifiers.AddKeywords(LangOpts); |
205 | } |
206 | |
207 | void Preprocessor::InitializeForModelFile() { |
208 | NumEnteredSourceFiles = 0; |
209 | |
210 | |
211 | PragmaHandlersBackup = std::move(PragmaHandlers); |
212 | PragmaHandlers = llvm::make_unique<PragmaNamespace>(StringRef()); |
213 | RegisterBuiltinPragmas(); |
214 | |
215 | |
216 | PredefinesFileID = FileID(); |
217 | } |
218 | |
219 | void Preprocessor::FinalizeForModelFile() { |
220 | NumEnteredSourceFiles = 1; |
221 | |
222 | PragmaHandlers = std::move(PragmaHandlersBackup); |
223 | } |
224 | |
225 | void Preprocessor::DumpToken(const Token &Tok, bool DumpFlags) const { |
226 | llvm::errs() << tok::getTokenName(Tok.getKind()) << " '" |
227 | << getSpelling(Tok) << "'"; |
228 | |
229 | if (!DumpFlags) return; |
230 | |
231 | llvm::errs() << "\t"; |
232 | if (Tok.isAtStartOfLine()) |
233 | llvm::errs() << " [StartOfLine]"; |
234 | if (Tok.hasLeadingSpace()) |
235 | llvm::errs() << " [LeadingSpace]"; |
236 | if (Tok.isExpandDisabled()) |
237 | llvm::errs() << " [ExpandDisabled]"; |
238 | if (Tok.needsCleaning()) { |
239 | const char *Start = SourceMgr.getCharacterData(Tok.getLocation()); |
240 | llvm::errs() << " [UnClean='" << StringRef(Start, Tok.getLength()) |
241 | << "']"; |
242 | } |
243 | |
244 | llvm::errs() << "\tLoc=<"; |
245 | DumpLocation(Tok.getLocation()); |
246 | llvm::errs() << ">"; |
247 | } |
248 | |
249 | void Preprocessor::DumpLocation(SourceLocation Loc) const { |
250 | Loc.print(llvm::errs(), SourceMgr); |
251 | } |
252 | |
253 | void Preprocessor::DumpMacro(const MacroInfo &MI) const { |
254 | llvm::errs() << "MACRO: "; |
255 | for (unsigned i = 0, e = MI.getNumTokens(); i != e; ++i) { |
256 | DumpToken(MI.getReplacementToken(i)); |
257 | llvm::errs() << " "; |
258 | } |
259 | llvm::errs() << "\n"; |
260 | } |
261 | |
262 | void Preprocessor::PrintStats() { |
263 | llvm::errs() << "\n*** Preprocessor Stats:\n"; |
264 | llvm::errs() << NumDirectives << " directives found:\n"; |
265 | llvm::errs() << " " << NumDefined << " #define.\n"; |
266 | llvm::errs() << " " << NumUndefined << " #undef.\n"; |
267 | llvm::errs() << " #include/#include_next/#import:\n"; |
268 | llvm::errs() << " " << NumEnteredSourceFiles << " source files entered.\n"; |
269 | llvm::errs() << " " << MaxIncludeStackDepth << " max include stack depth\n"; |
270 | llvm::errs() << " " << NumIf << " #if/#ifndef/#ifdef.\n"; |
271 | llvm::errs() << " " << NumElse << " #else/#elif.\n"; |
272 | llvm::errs() << " " << NumEndif << " #endif.\n"; |
273 | llvm::errs() << " " << NumPragma << " #pragma.\n"; |
274 | llvm::errs() << NumSkipped << " #if/#ifndef#ifdef regions skipped\n"; |
275 | |
276 | llvm::errs() << NumMacroExpanded << "/" << NumFnMacroExpanded << "/" |
277 | << NumBuiltinMacroExpanded << " obj/fn/builtin macros expanded, " |
278 | << NumFastMacroExpanded << " on the fast path.\n"; |
279 | llvm::errs() << (NumFastTokenPaste+NumTokenPaste) |
280 | << " token paste (##) operations performed, " |
281 | << NumFastTokenPaste << " on the fast path.\n"; |
282 | |
283 | llvm::errs() << "\nPreprocessor Memory: " << getTotalMemory() << "B total"; |
284 | |
285 | llvm::errs() << "\n BumpPtr: " << BP.getTotalMemory(); |
286 | llvm::errs() << "\n Macro Expanded Tokens: " |
287 | << llvm::capacity_in_bytes(MacroExpandedTokens); |
288 | llvm::errs() << "\n Predefines Buffer: " << Predefines.capacity(); |
289 | |
290 | llvm::errs() << "\n Macros: " |
291 | << llvm::capacity_in_bytes(CurSubmoduleState->Macros); |
292 | llvm::errs() << "\n #pragma push_macro Info: " |
293 | << llvm::capacity_in_bytes(PragmaPushMacroInfo); |
294 | llvm::errs() << "\n Poison Reasons: " |
295 | << llvm::capacity_in_bytes(PoisonReasons); |
296 | llvm::errs() << "\n Comment Handlers: " |
297 | << llvm::capacity_in_bytes(CommentHandlers) << "\n"; |
298 | } |
299 | |
300 | Preprocessor::macro_iterator |
301 | Preprocessor::macro_begin(bool IncludeExternalMacros) const { |
302 | if (IncludeExternalMacros && ExternalSource && |
303 | !ReadMacrosFromExternalSource) { |
304 | ReadMacrosFromExternalSource = true; |
305 | ExternalSource->ReadDefinedMacros(); |
306 | } |
307 | |
308 | |
309 | for (const ModuleMacro &Macro : ModuleMacros) |
310 | CurSubmoduleState->Macros.insert(std::make_pair(Macro.II, MacroState())); |
311 | |
312 | return CurSubmoduleState->Macros.begin(); |
313 | } |
314 | |
315 | size_t Preprocessor::getTotalMemory() const { |
316 | return BP.getTotalMemory() |
317 | + llvm::capacity_in_bytes(MacroExpandedTokens) |
318 | + Predefines.capacity() |
319 | |
320 | |
321 | + llvm::capacity_in_bytes(CurSubmoduleState->Macros) |
322 | + llvm::capacity_in_bytes(PragmaPushMacroInfo) |
323 | + llvm::capacity_in_bytes(PoisonReasons) |
324 | + llvm::capacity_in_bytes(CommentHandlers); |
325 | } |
326 | |
327 | Preprocessor::macro_iterator |
328 | Preprocessor::macro_end(bool IncludeExternalMacros) const { |
329 | if (IncludeExternalMacros && ExternalSource && |
330 | !ReadMacrosFromExternalSource) { |
331 | ReadMacrosFromExternalSource = true; |
332 | ExternalSource->ReadDefinedMacros(); |
333 | } |
334 | |
335 | return CurSubmoduleState->Macros.end(); |
336 | } |
337 | |
338 | |
339 | static bool MacroDefinitionEquals(const MacroInfo *MI, |
340 | ArrayRef<TokenValue> Tokens) { |
341 | return Tokens.size() == MI->getNumTokens() && |
342 | std::equal(Tokens.begin(), Tokens.end(), MI->tokens_begin()); |
343 | } |
344 | |
345 | StringRef Preprocessor::getLastMacroWithSpelling( |
346 | SourceLocation Loc, |
347 | ArrayRef<TokenValue> Tokens) const { |
348 | SourceLocation BestLocation; |
349 | StringRef BestSpelling; |
350 | for (Preprocessor::macro_iterator I = macro_begin(), E = macro_end(); |
351 | I != E; ++I) { |
352 | const MacroDirective::DefInfo |
353 | Def = I->second.findDirectiveAtLoc(Loc, SourceMgr); |
354 | if (!Def || !Def.getMacroInfo()) |
355 | continue; |
356 | if (!Def.getMacroInfo()->isObjectLike()) |
357 | continue; |
358 | if (!MacroDefinitionEquals(Def.getMacroInfo(), Tokens)) |
359 | continue; |
360 | SourceLocation Location = Def.getLocation(); |
361 | |
362 | if (BestLocation.isInvalid() || |
363 | (Location.isValid() && |
364 | SourceMgr.isBeforeInTranslationUnit(BestLocation, Location))) { |
365 | BestLocation = Location; |
366 | BestSpelling = I->first->getName(); |
367 | } |
368 | } |
369 | return BestSpelling; |
370 | } |
371 | |
372 | void Preprocessor::recomputeCurLexerKind() { |
373 | if (CurLexer) |
374 | CurLexerKind = CLK_Lexer; |
375 | else if (CurTokenLexer) |
376 | CurLexerKind = CLK_TokenLexer; |
377 | else |
378 | CurLexerKind = CLK_CachingLexer; |
379 | } |
380 | |
381 | bool Preprocessor::SetCodeCompletionPoint(const FileEntry *File, |
382 | unsigned CompleteLine, |
383 | unsigned CompleteColumn) { |
384 | assert(File); |
385 | (0) . __assert_fail ("CompleteLine && CompleteColumn && \"Starts from 1.1\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 385, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CompleteLine && CompleteColumn && "Starts from 1:1"); |
386 | (0) . __assert_fail ("!CodeCompletionFile && \"Already set\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 386, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!CodeCompletionFile && "Already set"); |
387 | |
388 | using llvm::MemoryBuffer; |
389 | |
390 | |
391 | bool Invalid = false; |
392 | const MemoryBuffer *Buffer = SourceMgr.getMemoryBufferForFile(File, &Invalid); |
393 | if (Invalid) |
394 | return true; |
395 | |
396 | |
397 | const char *Position = Buffer->getBufferStart(); |
398 | for (unsigned Line = 1; Line < CompleteLine; ++Line) { |
399 | for (; *Position; ++Position) { |
400 | if (*Position != '\r' && *Position != '\n') |
401 | continue; |
402 | |
403 | |
404 | if ((Position[1] == '\r' || Position[1] == '\n') && |
405 | Position[0] != Position[1]) |
406 | ++Position; |
407 | ++Position; |
408 | break; |
409 | } |
410 | } |
411 | |
412 | Position += CompleteColumn - 1; |
413 | |
414 | |
415 | |
416 | if (SkipMainFilePreamble.first && |
417 | SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()) == File) { |
418 | if (Position - Buffer->getBufferStart() < SkipMainFilePreamble.first) |
419 | Position = Buffer->getBufferStart() + SkipMainFilePreamble.first; |
420 | } |
421 | |
422 | if (Position > Buffer->getBufferEnd()) |
423 | Position = Buffer->getBufferEnd(); |
424 | |
425 | CodeCompletionFile = File; |
426 | CodeCompletionOffset = Position - Buffer->getBufferStart(); |
427 | |
428 | auto NewBuffer = llvm::WritableMemoryBuffer::getNewUninitMemBuffer( |
429 | Buffer->getBufferSize() + 1, Buffer->getBufferIdentifier()); |
430 | char *NewBuf = NewBuffer->getBufferStart(); |
431 | char *NewPos = std::copy(Buffer->getBufferStart(), Position, NewBuf); |
432 | *NewPos = '\0'; |
433 | std::copy(Position, Buffer->getBufferEnd(), NewPos+1); |
434 | SourceMgr.overrideFileContents(File, std::move(NewBuffer)); |
435 | |
436 | return false; |
437 | } |
438 | |
439 | void Preprocessor::CodeCompleteIncludedFile(llvm::StringRef Dir, |
440 | bool IsAngled) { |
441 | if (CodeComplete) |
442 | CodeComplete->CodeCompleteIncludedFile(Dir, IsAngled); |
443 | setCodeCompletionReached(); |
444 | } |
445 | |
446 | void Preprocessor::CodeCompleteNaturalLanguage() { |
447 | if (CodeComplete) |
448 | CodeComplete->CodeCompleteNaturalLanguage(); |
449 | setCodeCompletionReached(); |
450 | } |
451 | |
452 | |
453 | |
454 | |
455 | StringRef Preprocessor::getSpelling(const Token &Tok, |
456 | SmallVectorImpl<char> &Buffer, |
457 | bool *Invalid) const { |
458 | |
459 | if (Tok.isNot(tok::raw_identifier) && !Tok.hasUCN()) { |
460 | |
461 | if (const IdentifierInfo *II = Tok.getIdentifierInfo()) |
462 | return II->getName(); |
463 | } |
464 | |
465 | |
466 | if (Tok.needsCleaning()) |
467 | Buffer.resize(Tok.getLength()); |
468 | |
469 | const char *Ptr = Buffer.data(); |
470 | unsigned Len = getSpelling(Tok, Ptr, Invalid); |
471 | return StringRef(Ptr, Len); |
472 | } |
473 | |
474 | |
475 | |
476 | |
477 | void Preprocessor::CreateString(StringRef Str, Token &Tok, |
478 | SourceLocation ExpansionLocStart, |
479 | SourceLocation ExpansionLocEnd) { |
480 | Tok.setLength(Str.size()); |
481 | |
482 | const char *DestPtr; |
483 | SourceLocation Loc = ScratchBuf->getToken(Str.data(), Str.size(), DestPtr); |
484 | |
485 | if (ExpansionLocStart.isValid()) |
486 | Loc = SourceMgr.createExpansionLoc(Loc, ExpansionLocStart, |
487 | ExpansionLocEnd, Str.size()); |
488 | Tok.setLocation(Loc); |
489 | |
490 | |
491 | if (Tok.is(tok::raw_identifier)) |
492 | Tok.setRawIdentifierData(DestPtr); |
493 | else if (Tok.isLiteral()) |
494 | Tok.setLiteralData(DestPtr); |
495 | } |
496 | |
497 | SourceLocation Preprocessor::SplitToken(SourceLocation Loc, unsigned Length) { |
498 | auto &SM = getSourceManager(); |
499 | SourceLocation SpellingLoc = SM.getSpellingLoc(Loc); |
500 | std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellingLoc); |
501 | bool Invalid = false; |
502 | StringRef Buffer = SM.getBufferData(LocInfo.first, &Invalid); |
503 | if (Invalid) |
504 | return SourceLocation(); |
505 | |
506 | |
507 | const char *DestPtr; |
508 | SourceLocation Spelling = |
509 | ScratchBuf->getToken(Buffer.data() + LocInfo.second, Length, DestPtr); |
510 | return SM.createTokenSplitLoc(Spelling, Loc, Loc.getLocWithOffset(Length)); |
511 | } |
512 | |
513 | Module *Preprocessor::getCurrentModule() { |
514 | if (!getLangOpts().isCompilingModule()) |
515 | return nullptr; |
516 | |
517 | return getHeaderSearchInfo().lookupModule(getLangOpts().CurrentModule); |
518 | } |
519 | |
520 | |
521 | |
522 | |
523 | |
524 | |
525 | |
526 | void Preprocessor::EnterMainSourceFile() { |
527 | |
528 | |
529 | |
530 | (0) . __assert_fail ("NumEnteredSourceFiles == 0 && \"Cannot reenter the main file!\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 530, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(NumEnteredSourceFiles == 0 && "Cannot reenter the main file!"); |
531 | FileID MainFileID = SourceMgr.getMainFileID(); |
532 | |
533 | |
534 | |
535 | if (!SourceMgr.isLoadedFileID(MainFileID)) { |
536 | |
537 | EnterSourceFile(MainFileID, nullptr, SourceLocation()); |
538 | |
539 | |
540 | |
541 | if (SkipMainFilePreamble.first > 0) |
542 | CurLexer->SetByteOffset(SkipMainFilePreamble.first, |
543 | SkipMainFilePreamble.second); |
544 | |
545 | |
546 | |
547 | if (const FileEntry *FE = SourceMgr.getFileEntryForID(MainFileID)) |
548 | HeaderInfo.IncrementIncludeCount(FE); |
549 | } |
550 | |
551 | |
552 | std::unique_ptr<llvm::MemoryBuffer> SB = |
553 | llvm::MemoryBuffer::getMemBufferCopy(Predefines, "<built-in>"); |
554 | (0) . __assert_fail ("SB && \"Cannot create predefined source buffer\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 554, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(SB && "Cannot create predefined source buffer"); |
555 | FileID FID = SourceMgr.createFileID(std::move(SB)); |
556 | (0) . __assert_fail ("FID.isValid() && \"Could not create FileID for predefines?\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 556, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(FID.isValid() && "Could not create FileID for predefines?"); |
557 | setPredefinesFileID(FID); |
558 | |
559 | |
560 | EnterSourceFile(FID, nullptr, SourceLocation()); |
561 | |
562 | if (!PPOpts->PCHThroughHeader.empty()) { |
563 | |
564 | |
565 | const DirectoryLookup *CurDir; |
566 | const FileEntry *File = LookupFile( |
567 | SourceLocation(), PPOpts->PCHThroughHeader, |
568 | , , , CurDir, |
569 | , , |
570 | , , |
571 | ); |
572 | if (!File) { |
573 | Diag(SourceLocation(), diag::err_pp_through_header_not_found) |
574 | << PPOpts->PCHThroughHeader; |
575 | return; |
576 | } |
577 | setPCHThroughHeaderFileID( |
578 | SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User)); |
579 | } |
580 | |
581 | |
582 | if ((usingPCHWithThroughHeader() && SkippingUntilPCHThroughHeader) || |
583 | (usingPCHWithPragmaHdrStop() && SkippingUntilPragmaHdrStop)) |
584 | SkipTokensWhileUsingPCH(); |
585 | } |
586 | |
587 | void Preprocessor::(FileID FID) { |
588 | (0) . __assert_fail ("PCHThroughHeaderFileID.isInvalid() && \"PCHThroughHeaderFileID already set!\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 589, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(PCHThroughHeaderFileID.isInvalid() && |
589 | (0) . __assert_fail ("PCHThroughHeaderFileID.isInvalid() && \"PCHThroughHeaderFileID already set!\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 589, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "PCHThroughHeaderFileID already set!"); |
590 | PCHThroughHeaderFileID = FID; |
591 | } |
592 | |
593 | bool Preprocessor::(const FileEntry *FE) { |
594 | (0) . __assert_fail ("PCHThroughHeaderFileID.isValid() && \"Invalid PCH through header FileID\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 595, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(PCHThroughHeaderFileID.isValid() && |
595 | (0) . __assert_fail ("PCHThroughHeaderFileID.isValid() && \"Invalid PCH through header FileID\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 595, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Invalid PCH through header FileID"); |
596 | return FE == SourceMgr.getFileEntryForID(PCHThroughHeaderFileID); |
597 | } |
598 | |
599 | bool Preprocessor::() { |
600 | return TUKind == TU_Prefix && !PPOpts->PCHThroughHeader.empty() && |
601 | PCHThroughHeaderFileID.isValid(); |
602 | } |
603 | |
604 | bool Preprocessor::() { |
605 | return TUKind != TU_Prefix && !PPOpts->PCHThroughHeader.empty() && |
606 | PCHThroughHeaderFileID.isValid(); |
607 | } |
608 | |
609 | bool Preprocessor::creatingPCHWithPragmaHdrStop() { |
610 | return TUKind == TU_Prefix && PPOpts->PCHWithHdrStop; |
611 | } |
612 | |
613 | bool Preprocessor::usingPCHWithPragmaHdrStop() { |
614 | return TUKind != TU_Prefix && PPOpts->PCHWithHdrStop; |
615 | } |
616 | |
617 | |
618 | |
619 | |
620 | |
621 | |
622 | void Preprocessor::SkipTokensWhileUsingPCH() { |
623 | bool ReachedMainFileEOF = false; |
624 | bool = SkippingUntilPCHThroughHeader; |
625 | bool UsingPragmaHdrStop = SkippingUntilPragmaHdrStop; |
626 | Token Tok; |
627 | while (true) { |
628 | bool InPredefines = (CurLexer->getFileID() == getPredefinesFileID()); |
629 | CurLexer->Lex(Tok); |
630 | if (Tok.is(tok::eof) && !InPredefines) { |
631 | ReachedMainFileEOF = true; |
632 | break; |
633 | } |
634 | if (UsingPCHThroughHeader && !SkippingUntilPCHThroughHeader) |
635 | break; |
636 | if (UsingPragmaHdrStop && !SkippingUntilPragmaHdrStop) |
637 | break; |
638 | } |
639 | if (ReachedMainFileEOF) { |
640 | if (UsingPCHThroughHeader) |
641 | Diag(SourceLocation(), diag::err_pp_through_header_not_seen) |
642 | << PPOpts->PCHThroughHeader << 1; |
643 | else if (!PPOpts->PCHWithHdrStopCreate) |
644 | Diag(SourceLocation(), diag::err_pp_pragma_hdrstop_not_seen); |
645 | } |
646 | } |
647 | |
648 | void Preprocessor::replayPreambleConditionalStack() { |
649 | |
650 | if (PreambleConditionalStack.isReplaying()) { |
651 | (0) . __assert_fail ("CurPPLexer && \"CurPPLexer is null when calling replayPreambleConditionalStack.\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 652, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CurPPLexer && |
652 | (0) . __assert_fail ("CurPPLexer && \"CurPPLexer is null when calling replayPreambleConditionalStack.\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 652, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "CurPPLexer is null when calling replayPreambleConditionalStack."); |
653 | CurPPLexer->setConditionalLevels(PreambleConditionalStack.getStack()); |
654 | PreambleConditionalStack.doneReplaying(); |
655 | if (PreambleConditionalStack.reachedEOFWhileSkipping()) |
656 | SkipExcludedConditionalBlock( |
657 | PreambleConditionalStack.SkipInfo->HashTokenLoc, |
658 | PreambleConditionalStack.SkipInfo->IfTokenLoc, |
659 | PreambleConditionalStack.SkipInfo->FoundNonSkipPortion, |
660 | PreambleConditionalStack.SkipInfo->FoundElse, |
661 | PreambleConditionalStack.SkipInfo->ElseLoc); |
662 | } |
663 | } |
664 | |
665 | void Preprocessor::EndSourceFile() { |
666 | |
667 | if (Callbacks) |
668 | Callbacks->EndOfMainFile(); |
669 | } |
670 | |
671 | |
672 | |
673 | |
674 | |
675 | |
676 | |
677 | |
678 | IdentifierInfo *Preprocessor::LookUpIdentifierInfo(Token &Identifier) const { |
679 | (0) . __assert_fail ("!Identifier.getRawIdentifier().empty() && \"No raw identifier data!\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 679, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!Identifier.getRawIdentifier().empty() && "No raw identifier data!"); |
680 | |
681 | |
682 | IdentifierInfo *II; |
683 | if (!Identifier.needsCleaning() && !Identifier.hasUCN()) { |
684 | |
685 | II = getIdentifierInfo(Identifier.getRawIdentifier()); |
686 | } else { |
687 | |
688 | SmallString<64> IdentifierBuffer; |
689 | StringRef CleanedStr = getSpelling(Identifier, IdentifierBuffer); |
690 | |
691 | if (Identifier.hasUCN()) { |
692 | SmallString<64> UCNIdentifierBuffer; |
693 | expandUCNs(UCNIdentifierBuffer, CleanedStr); |
694 | II = getIdentifierInfo(UCNIdentifierBuffer); |
695 | } else { |
696 | II = getIdentifierInfo(CleanedStr); |
697 | } |
698 | } |
699 | |
700 | |
701 | Identifier.setIdentifierInfo(II); |
702 | if (getLangOpts().MSVCCompat && II->isCPlusPlusOperatorKeyword() && |
703 | getSourceManager().isInSystemHeader(Identifier.getLocation())) |
704 | Identifier.setKind(tok::identifier); |
705 | else |
706 | Identifier.setKind(II->getTokenID()); |
707 | |
708 | return II; |
709 | } |
710 | |
711 | void Preprocessor::SetPoisonReason(IdentifierInfo *II, unsigned DiagID) { |
712 | PoisonReasons[II] = DiagID; |
713 | } |
714 | |
715 | void Preprocessor::PoisonSEHIdentifiers(bool Poison) { |
716 | assert(Ident__exception_code && Ident__exception_info); |
717 | assert(Ident___exception_code && Ident___exception_info); |
718 | Ident__exception_code->setIsPoisoned(Poison); |
719 | Ident___exception_code->setIsPoisoned(Poison); |
720 | Ident_GetExceptionCode->setIsPoisoned(Poison); |
721 | Ident__exception_info->setIsPoisoned(Poison); |
722 | Ident___exception_info->setIsPoisoned(Poison); |
723 | Ident_GetExceptionInfo->setIsPoisoned(Poison); |
724 | Ident__abnormal_termination->setIsPoisoned(Poison); |
725 | Ident___abnormal_termination->setIsPoisoned(Poison); |
726 | Ident_AbnormalTermination->setIsPoisoned(Poison); |
727 | } |
728 | |
729 | void Preprocessor::HandlePoisonedIdentifier(Token & Identifier) { |
730 | (0) . __assert_fail ("Identifier.getIdentifierInfo() && \"Can't handle identifiers without identifier info!\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 731, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Identifier.getIdentifierInfo() && |
731 | (0) . __assert_fail ("Identifier.getIdentifierInfo() && \"Can't handle identifiers without identifier info!\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 731, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Can't handle identifiers without identifier info!"); |
732 | llvm::DenseMap<IdentifierInfo*,unsigned>::const_iterator it = |
733 | PoisonReasons.find(Identifier.getIdentifierInfo()); |
734 | if(it == PoisonReasons.end()) |
735 | Diag(Identifier, diag::err_pp_used_poisoned_id); |
736 | else |
737 | Diag(Identifier,it->second) << Identifier.getIdentifierInfo(); |
738 | } |
739 | |
740 | |
741 | |
742 | static diag::kind getFutureCompatDiagKind(const IdentifierInfo &II, |
743 | const LangOptions &LangOpts) { |
744 | (0) . __assert_fail ("II.isFutureCompatKeyword() && \"diagnostic should not be needed\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 744, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(II.isFutureCompatKeyword() && "diagnostic should not be needed"); |
745 | |
746 | if (LangOpts.CPlusPlus) |
747 | return llvm::StringSwitch<diag::kind>(II.getName()) |
748 | #define CXX11_KEYWORD(NAME, FLAGS) \ |
749 | .Case(#NAME, diag::warn_cxx11_keyword) |
750 | #define CXX2A_KEYWORD(NAME, FLAGS) \ |
751 | .Case(#NAME, diag::warn_cxx2a_keyword) |
752 | #include "clang/Basic/TokenKinds.def" |
753 | ; |
754 | |
755 | llvm_unreachable( |
756 | "Keyword not known to come from a newer Standard or proposed Standard"); |
757 | } |
758 | |
759 | void Preprocessor::updateOutOfDateIdentifier(IdentifierInfo &II) const { |
760 | (0) . __assert_fail ("II.isOutOfDate() && \"not out of date\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 760, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(II.isOutOfDate() && "not out of date"); |
761 | getExternalSource()->updateOutOfDateIdentifier(II); |
762 | } |
763 | |
764 | |
765 | |
766 | |
767 | |
768 | |
769 | |
770 | |
771 | |
772 | bool Preprocessor::HandleIdentifier(Token &Identifier) { |
773 | (0) . __assert_fail ("Identifier.getIdentifierInfo() && \"Can't handle identifiers without identifier info!\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 774, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Identifier.getIdentifierInfo() && |
774 | (0) . __assert_fail ("Identifier.getIdentifierInfo() && \"Can't handle identifiers without identifier info!\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 774, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Can't handle identifiers without identifier info!"); |
775 | |
776 | IdentifierInfo &II = *Identifier.getIdentifierInfo(); |
777 | |
778 | |
779 | |
780 | |
781 | |
782 | |
783 | if (II.isOutOfDate()) { |
784 | bool CurrentIsPoisoned = false; |
785 | const bool IsSpecialVariadicMacro = |
786 | &II == Ident__VA_ARGS__ || &II == Ident__VA_OPT__; |
787 | if (IsSpecialVariadicMacro) |
788 | CurrentIsPoisoned = II.isPoisoned(); |
789 | |
790 | updateOutOfDateIdentifier(II); |
791 | Identifier.setKind(II.getTokenID()); |
792 | |
793 | if (IsSpecialVariadicMacro) |
794 | II.setIsPoisoned(CurrentIsPoisoned); |
795 | } |
796 | |
797 | |
798 | |
799 | if (II.isPoisoned() && CurPPLexer) { |
800 | HandlePoisonedIdentifier(Identifier); |
801 | } |
802 | |
803 | |
804 | if (MacroDefinition MD = getMacroDefinition(&II)) { |
805 | auto *MI = MD.getMacroInfo(); |
806 | (0) . __assert_fail ("MI && \"macro definition with no macro info?\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 806, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(MI && "macro definition with no macro info?"); |
807 | if (!DisableMacroExpansion) { |
808 | if (!Identifier.isExpandDisabled() && MI->isEnabled()) { |
809 | |
810 | |
811 | if (!MI->isFunctionLike() || isNextPPTokenLParen()) |
812 | return HandleMacroExpandedIdentifier(Identifier, MD); |
813 | } else { |
814 | |
815 | |
816 | |
817 | Identifier.setFlag(Token::DisableExpand); |
818 | if (MI->isObjectLike() || isNextPPTokenLParen()) |
819 | Diag(Identifier, diag::pp_disabled_macro_expansion); |
820 | } |
821 | } |
822 | } |
823 | |
824 | |
825 | |
826 | |
827 | |
828 | |
829 | if (II.isFutureCompatKeyword() && !DisableMacroExpansion) { |
830 | Diag(Identifier, getFutureCompatDiagKind(II, getLangOpts())) |
831 | << II.getName(); |
832 | |
833 | II.setIsFutureCompatKeyword(false); |
834 | } |
835 | |
836 | |
837 | |
838 | |
839 | |
840 | if (II.isExtensionToken() && !DisableMacroExpansion) |
841 | Diag(Identifier, diag::ext_token_used); |
842 | |
843 | |
844 | |
845 | |
846 | |
847 | |
848 | |
849 | |
850 | |
851 | if (((LastTokenWasAt && II.isModulesImport()) || |
852 | Identifier.is(tok::kw_import)) && |
853 | !InMacroArgs && !DisableMacroExpansion && |
854 | (getLangOpts().Modules || getLangOpts().DebuggerSupport) && |
855 | CurLexerKind != CLK_CachingLexer) { |
856 | ModuleImportLoc = Identifier.getLocation(); |
857 | ModuleImportPath.clear(); |
858 | ModuleImportExpectsIdentifier = true; |
859 | CurLexerKind = CLK_LexAfterModuleImport; |
860 | } |
861 | return true; |
862 | } |
863 | |
864 | void Preprocessor::Lex(Token &Result) { |
865 | |
866 | bool ReturnedToken; |
867 | do { |
868 | switch (CurLexerKind) { |
869 | case CLK_Lexer: |
870 | ReturnedToken = CurLexer->Lex(Result); |
871 | break; |
872 | case CLK_TokenLexer: |
873 | ReturnedToken = CurTokenLexer->Lex(Result); |
874 | break; |
875 | case CLK_CachingLexer: |
876 | CachingLex(Result); |
877 | ReturnedToken = true; |
878 | break; |
879 | case CLK_LexAfterModuleImport: |
880 | LexAfterModuleImport(Result); |
881 | ReturnedToken = true; |
882 | break; |
883 | } |
884 | } while (!ReturnedToken); |
885 | |
886 | if (Result.is(tok::code_completion) && Result.getIdentifierInfo()) { |
887 | |
888 | setCodeCompletionIdentifierInfo(Result.getIdentifierInfo()); |
889 | setCodeCompletionTokenRange(Result.getLocation(), Result.getEndLoc()); |
890 | |
891 | |
892 | Result.setIdentifierInfo(nullptr); |
893 | } |
894 | |
895 | LastTokenWasAt = Result.is(tok::at); |
896 | } |
897 | |
898 | |
899 | |
900 | |
901 | |
902 | |
903 | |
904 | |
905 | |
906 | |
907 | |
908 | |
909 | bool Preprocessor::(Token &FilenameTok, bool AllowMacroExpansion) { |
910 | |
911 | |
912 | if (CurPPLexer) |
913 | CurPPLexer->LexIncludeFilename(FilenameTok); |
914 | else |
915 | Lex(FilenameTok); |
916 | |
917 | |
918 | |
919 | SmallString<128> FilenameBuffer; |
920 | if (FilenameTok.is(tok::less) && AllowMacroExpansion) { |
921 | SourceLocation Start = FilenameTok.getLocation(); |
922 | SourceLocation End; |
923 | FilenameBuffer.push_back('<'); |
924 | |
925 | |
926 | |
927 | |
928 | |
929 | while (FilenameTok.isNot(tok::greater)) { |
930 | Lex(FilenameTok); |
931 | if (FilenameTok.isOneOf(tok::eod, tok::eof)) { |
932 | Diag(FilenameTok.getLocation(), diag::err_expected) << tok::greater; |
933 | Diag(Start, diag::note_matching) << tok::less; |
934 | return true; |
935 | } |
936 | |
937 | End = FilenameTok.getLocation(); |
938 | |
939 | |
940 | if (FilenameTok.is(tok::code_completion)) { |
941 | setCodeCompletionReached(); |
942 | Lex(FilenameTok); |
943 | continue; |
944 | } |
945 | |
946 | |
947 | |
948 | if (FilenameTok.hasLeadingSpace()) |
949 | FilenameBuffer.push_back(' '); |
950 | |
951 | |
952 | |
953 | size_t PreAppendSize = FilenameBuffer.size(); |
954 | FilenameBuffer.resize(PreAppendSize + FilenameTok.getLength()); |
955 | |
956 | const char *BufPtr = &FilenameBuffer[PreAppendSize]; |
957 | unsigned ActualLen = getSpelling(FilenameTok, BufPtr); |
958 | |
959 | |
960 | if (BufPtr != &FilenameBuffer[PreAppendSize]) |
961 | memcpy(&FilenameBuffer[PreAppendSize], BufPtr, ActualLen); |
962 | |
963 | |
964 | if (FilenameTok.getLength() != ActualLen) |
965 | FilenameBuffer.resize(PreAppendSize + ActualLen); |
966 | } |
967 | |
968 | FilenameTok.startToken(); |
969 | FilenameTok.setKind(tok::header_name); |
970 | CreateString(FilenameBuffer, FilenameTok, Start, End); |
971 | } else if (FilenameTok.is(tok::string_literal) && AllowMacroExpansion) { |
972 | |
973 | |
974 | |
975 | |
976 | |
977 | |
978 | |
979 | |
980 | |
981 | |
982 | StringRef Str = getSpelling(FilenameTok, FilenameBuffer); |
983 | if (Str.size() >= 2 && Str.front() == '"' && Str.back() == '"') |
984 | FilenameTok.setKind(tok::header_name); |
985 | } |
986 | |
987 | return false; |
988 | } |
989 | |
990 | |
991 | |
992 | void Preprocessor::LexAfterModuleImport(Token &Result) { |
993 | |
994 | recomputeCurLexerKind(); |
995 | |
996 | |
997 | Lex(Result); |
998 | |
999 | |
1000 | |
1001 | |
1002 | |
1003 | |
1004 | |
1005 | if (ModuleImportExpectsIdentifier && Result.getKind() == tok::identifier) { |
1006 | |
1007 | |
1008 | ModuleImportPath.push_back(std::make_pair(Result.getIdentifierInfo(), |
1009 | Result.getLocation())); |
1010 | ModuleImportExpectsIdentifier = false; |
1011 | CurLexerKind = CLK_LexAfterModuleImport; |
1012 | return; |
1013 | } |
1014 | |
1015 | |
1016 | |
1017 | |
1018 | if (!ModuleImportExpectsIdentifier && Result.getKind() == tok::period) { |
1019 | ModuleImportExpectsIdentifier = true; |
1020 | CurLexerKind = CLK_LexAfterModuleImport; |
1021 | return; |
1022 | } |
1023 | |
1024 | |
1025 | if (!ModuleImportPath.empty()) { |
1026 | |
1027 | |
1028 | |
1029 | |
1030 | std::string FlatModuleName; |
1031 | if (getLangOpts().ModulesTS) { |
1032 | for (auto &Piece : ModuleImportPath) { |
1033 | if (!FlatModuleName.empty()) |
1034 | FlatModuleName += "."; |
1035 | FlatModuleName += Piece.first->getName(); |
1036 | } |
1037 | SourceLocation FirstPathLoc = ModuleImportPath[0].second; |
1038 | ModuleImportPath.clear(); |
1039 | ModuleImportPath.push_back( |
1040 | std::make_pair(getIdentifierInfo(FlatModuleName), FirstPathLoc)); |
1041 | } |
1042 | |
1043 | Module *Imported = nullptr; |
1044 | if (getLangOpts().Modules) { |
1045 | Imported = TheModuleLoader.loadModule(ModuleImportLoc, |
1046 | ModuleImportPath, |
1047 | Module::Hidden, |
1048 | ); |
1049 | if (Imported) |
1050 | makeModuleVisible(Imported, ModuleImportLoc); |
1051 | } |
1052 | if (Callbacks && (getLangOpts().Modules || getLangOpts().DebuggerSupport)) |
1053 | Callbacks->moduleImport(ModuleImportLoc, ModuleImportPath, Imported); |
1054 | } |
1055 | } |
1056 | |
1057 | void Preprocessor::makeModuleVisible(Module *M, SourceLocation Loc) { |
1058 | CurSubmoduleState->VisibleModules.setVisible( |
1059 | M, Loc, [](Module *) {}, |
1060 | [&](ArrayRef<Module *> Path, Module *Conflict, StringRef Message) { |
1061 | |
1062 | |
1063 | Diag(ModuleImportLoc, diag::warn_module_conflict) |
1064 | << Path[0]->getFullModuleName() |
1065 | << Conflict->getFullModuleName() |
1066 | << Message; |
1067 | }); |
1068 | |
1069 | |
1070 | if (!BuildingSubmoduleStack.empty() && M != BuildingSubmoduleStack.back().M) |
1071 | BuildingSubmoduleStack.back().M->Imports.insert(M); |
1072 | } |
1073 | |
1074 | bool Preprocessor::FinishLexStringLiteral(Token &Result, std::string &String, |
1075 | const char *DiagnosticTag, |
1076 | bool AllowMacroExpansion) { |
1077 | |
1078 | if (Result.isNot(tok::string_literal)) { |
1079 | Diag(Result, diag::err_expected_string_literal) |
1080 | << << DiagnosticTag; |
1081 | return false; |
1082 | } |
1083 | |
1084 | |
1085 | SmallVector<Token, 4> StrToks; |
1086 | do { |
1087 | StrToks.push_back(Result); |
1088 | |
1089 | if (Result.hasUDSuffix()) |
1090 | Diag(Result, diag::err_invalid_string_udl); |
1091 | |
1092 | if (AllowMacroExpansion) |
1093 | Lex(Result); |
1094 | else |
1095 | LexUnexpandedToken(Result); |
1096 | } while (Result.is(tok::string_literal)); |
1097 | |
1098 | |
1099 | StringLiteralParser Literal(StrToks, *this); |
1100 | (0) . __assert_fail ("Literal.isAscii() && \"Didn't allow wide strings in\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 1100, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Literal.isAscii() && "Didn't allow wide strings in"); |
1101 | |
1102 | if (Literal.hadError) |
1103 | return false; |
1104 | |
1105 | if (Literal.Pascal) { |
1106 | Diag(StrToks[0].getLocation(), diag::err_expected_string_literal) |
1107 | << << DiagnosticTag; |
1108 | return false; |
1109 | } |
1110 | |
1111 | String = Literal.GetString(); |
1112 | return true; |
1113 | } |
1114 | |
1115 | bool Preprocessor::parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value) { |
1116 | assert(Tok.is(tok::numeric_constant)); |
1117 | SmallString<8> IntegerBuffer; |
1118 | bool NumberInvalid = false; |
1119 | StringRef Spelling = getSpelling(Tok, IntegerBuffer, &NumberInvalid); |
1120 | if (NumberInvalid) |
1121 | return false; |
1122 | NumericLiteralParser Literal(Spelling, Tok.getLocation(), *this); |
1123 | if (Literal.hadError || !Literal.isIntegerLiteral() || Literal.hasUDSuffix()) |
1124 | return false; |
1125 | llvm::APInt APVal(64, 0); |
1126 | if (Literal.GetIntegerValue(APVal)) |
1127 | return false; |
1128 | Lex(Tok); |
1129 | Value = APVal.getLimitedValue(); |
1130 | return true; |
1131 | } |
1132 | |
1133 | void Preprocessor::addCommentHandler(CommentHandler *Handler) { |
1134 | (0) . __assert_fail ("Handler && \"NULL comment handler\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 1134, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Handler && "NULL comment handler"); |
1135 | (0) . __assert_fail ("std..find(CommentHandlers.begin(), CommentHandlers.end(), Handler) == CommentHandlers.end() && \"Comment handler already registered\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 1136, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(std::find(CommentHandlers.begin(), CommentHandlers.end(), Handler) == |
1136 | (0) . __assert_fail ("std..find(CommentHandlers.begin(), CommentHandlers.end(), Handler) == CommentHandlers.end() && \"Comment handler already registered\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 1136, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> CommentHandlers.end() && "Comment handler already registered"); |
1137 | CommentHandlers.push_back(Handler); |
1138 | } |
1139 | |
1140 | void Preprocessor::removeCommentHandler(CommentHandler *Handler) { |
1141 | std::vector<CommentHandler *>::iterator Pos = |
1142 | std::find(CommentHandlers.begin(), CommentHandlers.end(), Handler); |
1143 | (0) . __assert_fail ("Pos != CommentHandlers.end() && \"Comment handler not registered\"", "/home/seafit/code_projects/clang_source/clang/lib/Lex/Preprocessor.cpp", 1143, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Pos != CommentHandlers.end() && "Comment handler not registered"); |
1144 | CommentHandlers.erase(Pos); |
1145 | } |
1146 | |
1147 | bool Preprocessor::HandleComment(Token &result, SourceRange ) { |
1148 | bool AnyPendingTokens = false; |
1149 | for (std::vector<CommentHandler *>::iterator H = CommentHandlers.begin(), |
1150 | HEnd = CommentHandlers.end(); |
1151 | H != HEnd; ++H) { |
1152 | if ((*H)->HandleComment(*this, Comment)) |
1153 | AnyPendingTokens = true; |
1154 | } |
1155 | if (!AnyPendingTokens || getCommentRetentionState()) |
1156 | return false; |
1157 | Lex(result); |
1158 | return true; |
1159 | } |
1160 | |
1161 | ModuleLoader::~ModuleLoader() = default; |
1162 | |
1163 | CommentHandler::~CommentHandler() = default; |
1164 | |
1165 | CodeCompletionHandler::~CodeCompletionHandler() = default; |
1166 | |
1167 | void Preprocessor::createPreprocessingRecord() { |
1168 | if (Record) |
1169 | return; |
1170 | |
1171 | Record = new PreprocessingRecord(getSourceManager()); |
1172 | addPPCallbacks(std::unique_ptr<PPCallbacks>(Record)); |
1173 | } |
1174 | |