10b57cec5SDimitry Andric //===- Preprocessor.cpp - C Language Family Preprocessor Implementation ---===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the Preprocessor interface. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric // 130b57cec5SDimitry Andric // Options to support: 140b57cec5SDimitry Andric // -H - Print the name of each header file used. 150b57cec5SDimitry Andric // -d[DNI] - Dump various things. 160b57cec5SDimitry Andric // -fworking-directory - #line's with preprocessor's working dir. 170b57cec5SDimitry Andric // -fpreprocessed 180b57cec5SDimitry Andric // -dependency-file,-M,-MM,-MF,-MG,-MP,-MT,-MQ,-MD,-MMD 190b57cec5SDimitry Andric // -W* 200b57cec5SDimitry Andric // -w 210b57cec5SDimitry Andric // 220b57cec5SDimitry Andric // Messages to emit: 230b57cec5SDimitry Andric // "Multiple include guards may be useful for:\n" 240b57cec5SDimitry Andric // 250b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric #include "clang/Lex/Preprocessor.h" 28480093f4SDimitry Andric #include "clang/Basic/Builtins.h" 290b57cec5SDimitry Andric #include "clang/Basic/FileManager.h" 300b57cec5SDimitry Andric #include "clang/Basic/FileSystemStatCache.h" 310b57cec5SDimitry Andric #include "clang/Basic/IdentifierTable.h" 320b57cec5SDimitry Andric #include "clang/Basic/LLVM.h" 330b57cec5SDimitry Andric #include "clang/Basic/LangOptions.h" 340b57cec5SDimitry Andric #include "clang/Basic/Module.h" 350b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h" 360b57cec5SDimitry Andric #include "clang/Basic/SourceManager.h" 370b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h" 380b57cec5SDimitry Andric #include "clang/Lex/CodeCompletionHandler.h" 390b57cec5SDimitry Andric #include "clang/Lex/ExternalPreprocessorSource.h" 400b57cec5SDimitry Andric #include "clang/Lex/HeaderSearch.h" 410b57cec5SDimitry Andric #include "clang/Lex/LexDiagnostic.h" 420b57cec5SDimitry Andric #include "clang/Lex/Lexer.h" 430b57cec5SDimitry Andric #include "clang/Lex/LiteralSupport.h" 440b57cec5SDimitry Andric #include "clang/Lex/MacroArgs.h" 450b57cec5SDimitry Andric #include "clang/Lex/MacroInfo.h" 460b57cec5SDimitry Andric #include "clang/Lex/ModuleLoader.h" 470b57cec5SDimitry Andric #include "clang/Lex/Pragma.h" 480b57cec5SDimitry Andric #include "clang/Lex/PreprocessingRecord.h" 490b57cec5SDimitry Andric #include "clang/Lex/PreprocessorLexer.h" 500b57cec5SDimitry Andric #include "clang/Lex/PreprocessorOptions.h" 510b57cec5SDimitry Andric #include "clang/Lex/ScratchBuffer.h" 520b57cec5SDimitry Andric #include "clang/Lex/Token.h" 530b57cec5SDimitry Andric #include "clang/Lex/TokenLexer.h" 540b57cec5SDimitry Andric #include "llvm/ADT/APInt.h" 550b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 560b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 57480093f4SDimitry Andric #include "llvm/ADT/STLExtras.h" 580b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h" 590b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 600b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 61*0fca6ea1SDimitry Andric #include "llvm/ADT/iterator_range.h" 620b57cec5SDimitry Andric #include "llvm/Support/Capacity.h" 630b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 640b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 650b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 660b57cec5SDimitry Andric #include <algorithm> 670b57cec5SDimitry Andric #include <cassert> 680b57cec5SDimitry Andric #include <memory> 69bdd1243dSDimitry Andric #include <optional> 700b57cec5SDimitry Andric #include <string> 710b57cec5SDimitry Andric #include <utility> 720b57cec5SDimitry Andric #include <vector> 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric using namespace clang; 750b57cec5SDimitry Andric 76*0fca6ea1SDimitry Andric /// Minimum distance between two check points, in tokens. 77*0fca6ea1SDimitry Andric static constexpr unsigned CheckPointStepSize = 1024; 78*0fca6ea1SDimitry Andric 790b57cec5SDimitry Andric LLVM_INSTANTIATE_REGISTRY(PragmaHandlerRegistry) 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric ExternalPreprocessorSource::~ExternalPreprocessorSource() = default; 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts, 845f757f3fSDimitry Andric DiagnosticsEngine &diags, const LangOptions &opts, 850b57cec5SDimitry Andric SourceManager &SM, HeaderSearch &Headers, 860b57cec5SDimitry Andric ModuleLoader &TheModuleLoader, 870b57cec5SDimitry Andric IdentifierInfoLookup *IILookup, bool OwnsHeaders, 880b57cec5SDimitry Andric TranslationUnitKind TUKind) 890b57cec5SDimitry Andric : PPOpts(std::move(PPOpts)), Diags(&diags), LangOpts(opts), 900b57cec5SDimitry Andric FileMgr(Headers.getFileMgr()), SourceMgr(SM), 910b57cec5SDimitry Andric ScratchBuf(new ScratchBuffer(SourceMgr)), HeaderInfo(Headers), 920b57cec5SDimitry Andric TheModuleLoader(TheModuleLoader), ExternalSource(nullptr), 930b57cec5SDimitry Andric // As the language options may have not been loaded yet (when 940b57cec5SDimitry Andric // deserializing an ASTUnit), adding keywords to the identifier table is 950b57cec5SDimitry Andric // deferred to Preprocessor::Initialize(). 960b57cec5SDimitry Andric Identifiers(IILookup), PragmaHandlers(new PragmaNamespace(StringRef())), 970b57cec5SDimitry Andric TUKind(TUKind), SkipMainFilePreamble(0, true), 980b57cec5SDimitry Andric CurSubmoduleState(&NullSubmoduleState) { 990b57cec5SDimitry Andric OwnsHeaderSearch = OwnsHeaders; 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric // Default to discarding comments. 1020b57cec5SDimitry Andric KeepComments = false; 1030b57cec5SDimitry Andric KeepMacroComments = false; 1040b57cec5SDimitry Andric SuppressIncludeNotFoundError = false; 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric // Macro expansion is enabled. 1070b57cec5SDimitry Andric DisableMacroExpansion = false; 1080b57cec5SDimitry Andric MacroExpansionInDirectivesOverride = false; 1090b57cec5SDimitry Andric InMacroArgs = false; 1100b57cec5SDimitry Andric ArgMacro = nullptr; 1110b57cec5SDimitry Andric InMacroArgPreExpansion = false; 1120b57cec5SDimitry Andric NumCachedTokenLexers = 0; 1130b57cec5SDimitry Andric PragmasEnabled = true; 1140b57cec5SDimitry Andric ParsingIfOrElifDirective = false; 1150b57cec5SDimitry Andric PreprocessedOutput = false; 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric // We haven't read anything from the external source. 1180b57cec5SDimitry Andric ReadMacrosFromExternalSource = false; 1190b57cec5SDimitry Andric 120480093f4SDimitry Andric BuiltinInfo = std::make_unique<Builtin::Context>(); 121480093f4SDimitry Andric 1220b57cec5SDimitry Andric // "Poison" __VA_ARGS__, __VA_OPT__ which can only appear in the expansion of 1230b57cec5SDimitry Andric // a macro. They get unpoisoned where it is allowed. 1240b57cec5SDimitry Andric (Ident__VA_ARGS__ = getIdentifierInfo("__VA_ARGS__"))->setIsPoisoned(); 1250b57cec5SDimitry Andric SetPoisonReason(Ident__VA_ARGS__,diag::ext_pp_bad_vaargs_use); 1260b57cec5SDimitry Andric (Ident__VA_OPT__ = getIdentifierInfo("__VA_OPT__"))->setIsPoisoned(); 1270b57cec5SDimitry Andric SetPoisonReason(Ident__VA_OPT__,diag::ext_pp_bad_vaopt_use); 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric // Initialize the pragma handlers. 1300b57cec5SDimitry Andric RegisterBuiltinPragmas(); 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric // Initialize builtin macros like __LINE__ and friends. 1330b57cec5SDimitry Andric RegisterBuiltinMacros(); 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric if(LangOpts.Borland) { 1360b57cec5SDimitry Andric Ident__exception_info = getIdentifierInfo("_exception_info"); 1370b57cec5SDimitry Andric Ident___exception_info = getIdentifierInfo("__exception_info"); 1380b57cec5SDimitry Andric Ident_GetExceptionInfo = getIdentifierInfo("GetExceptionInformation"); 1390b57cec5SDimitry Andric Ident__exception_code = getIdentifierInfo("_exception_code"); 1400b57cec5SDimitry Andric Ident___exception_code = getIdentifierInfo("__exception_code"); 1410b57cec5SDimitry Andric Ident_GetExceptionCode = getIdentifierInfo("GetExceptionCode"); 1420b57cec5SDimitry Andric Ident__abnormal_termination = getIdentifierInfo("_abnormal_termination"); 1430b57cec5SDimitry Andric Ident___abnormal_termination = getIdentifierInfo("__abnormal_termination"); 1440b57cec5SDimitry Andric Ident_AbnormalTermination = getIdentifierInfo("AbnormalTermination"); 1450b57cec5SDimitry Andric } else { 1460b57cec5SDimitry Andric Ident__exception_info = Ident__exception_code = nullptr; 1470b57cec5SDimitry Andric Ident__abnormal_termination = Ident___exception_info = nullptr; 1480b57cec5SDimitry Andric Ident___exception_code = Ident___abnormal_termination = nullptr; 1490b57cec5SDimitry Andric Ident_GetExceptionInfo = Ident_GetExceptionCode = nullptr; 1500b57cec5SDimitry Andric Ident_AbnormalTermination = nullptr; 1510b57cec5SDimitry Andric } 1520b57cec5SDimitry Andric 1535f757f3fSDimitry Andric // Default incremental processing to -fincremental-extensions, clients can 1545f757f3fSDimitry Andric // override with `enableIncrementalProcessing` if desired. 1555f757f3fSDimitry Andric IncrementalProcessing = LangOpts.IncrementalExtensions; 1565f757f3fSDimitry Andric 1570b57cec5SDimitry Andric // If using a PCH where a #pragma hdrstop is expected, start skipping tokens. 1580b57cec5SDimitry Andric if (usingPCHWithPragmaHdrStop()) 1590b57cec5SDimitry Andric SkippingUntilPragmaHdrStop = true; 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric // If using a PCH with a through header, start skipping tokens. 1620b57cec5SDimitry Andric if (!this->PPOpts->PCHThroughHeader.empty() && 1630b57cec5SDimitry Andric !this->PPOpts->ImplicitPCHInclude.empty()) 1640b57cec5SDimitry Andric SkippingUntilPCHThroughHeader = true; 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric if (this->PPOpts->GeneratePreamble) 1670b57cec5SDimitry Andric PreambleConditionalStack.startRecording(); 168a7dea167SDimitry Andric 1695ffd83dbSDimitry Andric MaxTokens = LangOpts.MaxTokens; 1700b57cec5SDimitry Andric } 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric Preprocessor::~Preprocessor() { 1730b57cec5SDimitry Andric assert(BacktrackPositions.empty() && "EnableBacktrack/Backtrack imbalance!"); 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric IncludeMacroStack.clear(); 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric // Free any cached macro expanders. 1780b57cec5SDimitry Andric // This populates MacroArgCache, so all TokenLexers need to be destroyed 1790b57cec5SDimitry Andric // before the code below that frees up the MacroArgCache list. 1800b57cec5SDimitry Andric std::fill(TokenLexerCache, TokenLexerCache + NumCachedTokenLexers, nullptr); 1810b57cec5SDimitry Andric CurTokenLexer.reset(); 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric // Free any cached MacroArgs. 1840b57cec5SDimitry Andric for (MacroArgs *ArgList = MacroArgCache; ArgList;) 1850b57cec5SDimitry Andric ArgList = ArgList->deallocate(); 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric // Delete the header search info, if we own it. 1880b57cec5SDimitry Andric if (OwnsHeaderSearch) 1890b57cec5SDimitry Andric delete &HeaderInfo; 1900b57cec5SDimitry Andric } 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric void Preprocessor::Initialize(const TargetInfo &Target, 1930b57cec5SDimitry Andric const TargetInfo *AuxTarget) { 1940b57cec5SDimitry Andric assert((!this->Target || this->Target == &Target) && 1950b57cec5SDimitry Andric "Invalid override of target information"); 1960b57cec5SDimitry Andric this->Target = &Target; 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric assert((!this->AuxTarget || this->AuxTarget == AuxTarget) && 1990b57cec5SDimitry Andric "Invalid override of aux target information."); 2000b57cec5SDimitry Andric this->AuxTarget = AuxTarget; 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric // Initialize information about built-ins. 203480093f4SDimitry Andric BuiltinInfo->InitializeTarget(Target, AuxTarget); 2040b57cec5SDimitry Andric HeaderInfo.setTarget(Target); 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric // Populate the identifier table with info about keywords for the current language. 2070b57cec5SDimitry Andric Identifiers.AddKeywords(LangOpts); 20881ad6265SDimitry Andric 20981ad6265SDimitry Andric // Initialize the __FTL_EVAL_METHOD__ macro to the TargetInfo. 21081ad6265SDimitry Andric setTUFPEvalMethod(getTargetInfo().getFPEvalMethod()); 21181ad6265SDimitry Andric 21281ad6265SDimitry Andric if (getLangOpts().getFPEvalMethod() == LangOptions::FEM_UnsetOnCommandLine) 21381ad6265SDimitry Andric // Use setting from TargetInfo. 21481ad6265SDimitry Andric setCurrentFPEvalMethod(SourceLocation(), Target.getFPEvalMethod()); 21581ad6265SDimitry Andric else 21681ad6265SDimitry Andric // Set initial value of __FLT_EVAL_METHOD__ from the command line. 21781ad6265SDimitry Andric setCurrentFPEvalMethod(SourceLocation(), getLangOpts().getFPEvalMethod()); 2180b57cec5SDimitry Andric } 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric void Preprocessor::InitializeForModelFile() { 2210b57cec5SDimitry Andric NumEnteredSourceFiles = 0; 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric // Reset pragmas 2240b57cec5SDimitry Andric PragmaHandlersBackup = std::move(PragmaHandlers); 225a7dea167SDimitry Andric PragmaHandlers = std::make_unique<PragmaNamespace>(StringRef()); 2260b57cec5SDimitry Andric RegisterBuiltinPragmas(); 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric // Reset PredefinesFileID 2290b57cec5SDimitry Andric PredefinesFileID = FileID(); 2300b57cec5SDimitry Andric } 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric void Preprocessor::FinalizeForModelFile() { 2330b57cec5SDimitry Andric NumEnteredSourceFiles = 1; 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric PragmaHandlers = std::move(PragmaHandlersBackup); 2360b57cec5SDimitry Andric } 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric void Preprocessor::DumpToken(const Token &Tok, bool DumpFlags) const { 23981ad6265SDimitry Andric llvm::errs() << tok::getTokenName(Tok.getKind()); 24081ad6265SDimitry Andric 24181ad6265SDimitry Andric if (!Tok.isAnnotation()) 24281ad6265SDimitry Andric llvm::errs() << " '" << getSpelling(Tok) << "'"; 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric if (!DumpFlags) return; 2450b57cec5SDimitry Andric 2460b57cec5SDimitry Andric llvm::errs() << "\t"; 2470b57cec5SDimitry Andric if (Tok.isAtStartOfLine()) 2480b57cec5SDimitry Andric llvm::errs() << " [StartOfLine]"; 2490b57cec5SDimitry Andric if (Tok.hasLeadingSpace()) 2500b57cec5SDimitry Andric llvm::errs() << " [LeadingSpace]"; 2510b57cec5SDimitry Andric if (Tok.isExpandDisabled()) 2520b57cec5SDimitry Andric llvm::errs() << " [ExpandDisabled]"; 2530b57cec5SDimitry Andric if (Tok.needsCleaning()) { 2540b57cec5SDimitry Andric const char *Start = SourceMgr.getCharacterData(Tok.getLocation()); 2550b57cec5SDimitry Andric llvm::errs() << " [UnClean='" << StringRef(Start, Tok.getLength()) 2560b57cec5SDimitry Andric << "']"; 2570b57cec5SDimitry Andric } 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric llvm::errs() << "\tLoc=<"; 2600b57cec5SDimitry Andric DumpLocation(Tok.getLocation()); 2610b57cec5SDimitry Andric llvm::errs() << ">"; 2620b57cec5SDimitry Andric } 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric void Preprocessor::DumpLocation(SourceLocation Loc) const { 2650b57cec5SDimitry Andric Loc.print(llvm::errs(), SourceMgr); 2660b57cec5SDimitry Andric } 2670b57cec5SDimitry Andric 2680b57cec5SDimitry Andric void Preprocessor::DumpMacro(const MacroInfo &MI) const { 2690b57cec5SDimitry Andric llvm::errs() << "MACRO: "; 2700b57cec5SDimitry Andric for (unsigned i = 0, e = MI.getNumTokens(); i != e; ++i) { 2710b57cec5SDimitry Andric DumpToken(MI.getReplacementToken(i)); 2720b57cec5SDimitry Andric llvm::errs() << " "; 2730b57cec5SDimitry Andric } 2740b57cec5SDimitry Andric llvm::errs() << "\n"; 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric void Preprocessor::PrintStats() { 2780b57cec5SDimitry Andric llvm::errs() << "\n*** Preprocessor Stats:\n"; 2790b57cec5SDimitry Andric llvm::errs() << NumDirectives << " directives found:\n"; 2800b57cec5SDimitry Andric llvm::errs() << " " << NumDefined << " #define.\n"; 2810b57cec5SDimitry Andric llvm::errs() << " " << NumUndefined << " #undef.\n"; 2820b57cec5SDimitry Andric llvm::errs() << " #include/#include_next/#import:\n"; 2830b57cec5SDimitry Andric llvm::errs() << " " << NumEnteredSourceFiles << " source files entered.\n"; 2840b57cec5SDimitry Andric llvm::errs() << " " << MaxIncludeStackDepth << " max include stack depth\n"; 2850b57cec5SDimitry Andric llvm::errs() << " " << NumIf << " #if/#ifndef/#ifdef.\n"; 286fe6060f1SDimitry Andric llvm::errs() << " " << NumElse << " #else/#elif/#elifdef/#elifndef.\n"; 2870b57cec5SDimitry Andric llvm::errs() << " " << NumEndif << " #endif.\n"; 2880b57cec5SDimitry Andric llvm::errs() << " " << NumPragma << " #pragma.\n"; 2890b57cec5SDimitry Andric llvm::errs() << NumSkipped << " #if/#ifndef#ifdef regions skipped\n"; 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric llvm::errs() << NumMacroExpanded << "/" << NumFnMacroExpanded << "/" 2920b57cec5SDimitry Andric << NumBuiltinMacroExpanded << " obj/fn/builtin macros expanded, " 2930b57cec5SDimitry Andric << NumFastMacroExpanded << " on the fast path.\n"; 2940b57cec5SDimitry Andric llvm::errs() << (NumFastTokenPaste+NumTokenPaste) 2950b57cec5SDimitry Andric << " token paste (##) operations performed, " 2960b57cec5SDimitry Andric << NumFastTokenPaste << " on the fast path.\n"; 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric llvm::errs() << "\nPreprocessor Memory: " << getTotalMemory() << "B total"; 2990b57cec5SDimitry Andric 3000b57cec5SDimitry Andric llvm::errs() << "\n BumpPtr: " << BP.getTotalMemory(); 3010b57cec5SDimitry Andric llvm::errs() << "\n Macro Expanded Tokens: " 3020b57cec5SDimitry Andric << llvm::capacity_in_bytes(MacroExpandedTokens); 3030b57cec5SDimitry Andric llvm::errs() << "\n Predefines Buffer: " << Predefines.capacity(); 3040b57cec5SDimitry Andric // FIXME: List information for all submodules. 3050b57cec5SDimitry Andric llvm::errs() << "\n Macros: " 3060b57cec5SDimitry Andric << llvm::capacity_in_bytes(CurSubmoduleState->Macros); 3070b57cec5SDimitry Andric llvm::errs() << "\n #pragma push_macro Info: " 3080b57cec5SDimitry Andric << llvm::capacity_in_bytes(PragmaPushMacroInfo); 3090b57cec5SDimitry Andric llvm::errs() << "\n Poison Reasons: " 3100b57cec5SDimitry Andric << llvm::capacity_in_bytes(PoisonReasons); 3110b57cec5SDimitry Andric llvm::errs() << "\n Comment Handlers: " 3120b57cec5SDimitry Andric << llvm::capacity_in_bytes(CommentHandlers) << "\n"; 3130b57cec5SDimitry Andric } 3140b57cec5SDimitry Andric 3150b57cec5SDimitry Andric Preprocessor::macro_iterator 3160b57cec5SDimitry Andric Preprocessor::macro_begin(bool IncludeExternalMacros) const { 3170b57cec5SDimitry Andric if (IncludeExternalMacros && ExternalSource && 3180b57cec5SDimitry Andric !ReadMacrosFromExternalSource) { 3190b57cec5SDimitry Andric ReadMacrosFromExternalSource = true; 3200b57cec5SDimitry Andric ExternalSource->ReadDefinedMacros(); 3210b57cec5SDimitry Andric } 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric // Make sure we cover all macros in visible modules. 3240b57cec5SDimitry Andric for (const ModuleMacro &Macro : ModuleMacros) 3250b57cec5SDimitry Andric CurSubmoduleState->Macros.insert(std::make_pair(Macro.II, MacroState())); 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andric return CurSubmoduleState->Macros.begin(); 3280b57cec5SDimitry Andric } 3290b57cec5SDimitry Andric 3300b57cec5SDimitry Andric size_t Preprocessor::getTotalMemory() const { 3310b57cec5SDimitry Andric return BP.getTotalMemory() 3320b57cec5SDimitry Andric + llvm::capacity_in_bytes(MacroExpandedTokens) 3330b57cec5SDimitry Andric + Predefines.capacity() /* Predefines buffer. */ 3340b57cec5SDimitry Andric // FIXME: Include sizes from all submodules, and include MacroInfo sizes, 3350b57cec5SDimitry Andric // and ModuleMacros. 3360b57cec5SDimitry Andric + llvm::capacity_in_bytes(CurSubmoduleState->Macros) 3370b57cec5SDimitry Andric + llvm::capacity_in_bytes(PragmaPushMacroInfo) 3380b57cec5SDimitry Andric + llvm::capacity_in_bytes(PoisonReasons) 3390b57cec5SDimitry Andric + llvm::capacity_in_bytes(CommentHandlers); 3400b57cec5SDimitry Andric } 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andric Preprocessor::macro_iterator 3430b57cec5SDimitry Andric Preprocessor::macro_end(bool IncludeExternalMacros) const { 3440b57cec5SDimitry Andric if (IncludeExternalMacros && ExternalSource && 3450b57cec5SDimitry Andric !ReadMacrosFromExternalSource) { 3460b57cec5SDimitry Andric ReadMacrosFromExternalSource = true; 3470b57cec5SDimitry Andric ExternalSource->ReadDefinedMacros(); 3480b57cec5SDimitry Andric } 3490b57cec5SDimitry Andric 3500b57cec5SDimitry Andric return CurSubmoduleState->Macros.end(); 3510b57cec5SDimitry Andric } 3520b57cec5SDimitry Andric 3530b57cec5SDimitry Andric /// Compares macro tokens with a specified token value sequence. 3540b57cec5SDimitry Andric static bool MacroDefinitionEquals(const MacroInfo *MI, 3550b57cec5SDimitry Andric ArrayRef<TokenValue> Tokens) { 3560b57cec5SDimitry Andric return Tokens.size() == MI->getNumTokens() && 3570b57cec5SDimitry Andric std::equal(Tokens.begin(), Tokens.end(), MI->tokens_begin()); 3580b57cec5SDimitry Andric } 3590b57cec5SDimitry Andric 3600b57cec5SDimitry Andric StringRef Preprocessor::getLastMacroWithSpelling( 3610b57cec5SDimitry Andric SourceLocation Loc, 3620b57cec5SDimitry Andric ArrayRef<TokenValue> Tokens) const { 3630b57cec5SDimitry Andric SourceLocation BestLocation; 3640b57cec5SDimitry Andric StringRef BestSpelling; 3650b57cec5SDimitry Andric for (Preprocessor::macro_iterator I = macro_begin(), E = macro_end(); 3660b57cec5SDimitry Andric I != E; ++I) { 3670b57cec5SDimitry Andric const MacroDirective::DefInfo 3680b57cec5SDimitry Andric Def = I->second.findDirectiveAtLoc(Loc, SourceMgr); 3690b57cec5SDimitry Andric if (!Def || !Def.getMacroInfo()) 3700b57cec5SDimitry Andric continue; 3710b57cec5SDimitry Andric if (!Def.getMacroInfo()->isObjectLike()) 3720b57cec5SDimitry Andric continue; 3730b57cec5SDimitry Andric if (!MacroDefinitionEquals(Def.getMacroInfo(), Tokens)) 3740b57cec5SDimitry Andric continue; 3750b57cec5SDimitry Andric SourceLocation Location = Def.getLocation(); 3760b57cec5SDimitry Andric // Choose the macro defined latest. 3770b57cec5SDimitry Andric if (BestLocation.isInvalid() || 3780b57cec5SDimitry Andric (Location.isValid() && 3790b57cec5SDimitry Andric SourceMgr.isBeforeInTranslationUnit(BestLocation, Location))) { 3800b57cec5SDimitry Andric BestLocation = Location; 3810b57cec5SDimitry Andric BestSpelling = I->first->getName(); 3820b57cec5SDimitry Andric } 3830b57cec5SDimitry Andric } 3840b57cec5SDimitry Andric return BestSpelling; 3850b57cec5SDimitry Andric } 3860b57cec5SDimitry Andric 3870b57cec5SDimitry Andric void Preprocessor::recomputeCurLexerKind() { 3880b57cec5SDimitry Andric if (CurLexer) 3895f757f3fSDimitry Andric CurLexerCallback = CurLexer->isDependencyDirectivesLexer() 39081ad6265SDimitry Andric ? CLK_DependencyDirectivesLexer 39181ad6265SDimitry Andric : CLK_Lexer; 3920b57cec5SDimitry Andric else if (CurTokenLexer) 3935f757f3fSDimitry Andric CurLexerCallback = CLK_TokenLexer; 3940b57cec5SDimitry Andric else 3955f757f3fSDimitry Andric CurLexerCallback = CLK_CachingLexer; 3960b57cec5SDimitry Andric } 3970b57cec5SDimitry Andric 3985f757f3fSDimitry Andric bool Preprocessor::SetCodeCompletionPoint(FileEntryRef File, 3990b57cec5SDimitry Andric unsigned CompleteLine, 4000b57cec5SDimitry Andric unsigned CompleteColumn) { 4010b57cec5SDimitry Andric assert(CompleteLine && CompleteColumn && "Starts from 1:1"); 4020b57cec5SDimitry Andric assert(!CodeCompletionFile && "Already set"); 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric // Load the actual file's contents. 405bdd1243dSDimitry Andric std::optional<llvm::MemoryBufferRef> Buffer = 406e8d8bef9SDimitry Andric SourceMgr.getMemoryBufferForFileOrNone(File); 407e8d8bef9SDimitry Andric if (!Buffer) 4080b57cec5SDimitry Andric return true; 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric // Find the byte position of the truncation point. 4110b57cec5SDimitry Andric const char *Position = Buffer->getBufferStart(); 4120b57cec5SDimitry Andric for (unsigned Line = 1; Line < CompleteLine; ++Line) { 4130b57cec5SDimitry Andric for (; *Position; ++Position) { 4140b57cec5SDimitry Andric if (*Position != '\r' && *Position != '\n') 4150b57cec5SDimitry Andric continue; 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andric // Eat \r\n or \n\r as a single line. 4180b57cec5SDimitry Andric if ((Position[1] == '\r' || Position[1] == '\n') && 4190b57cec5SDimitry Andric Position[0] != Position[1]) 4200b57cec5SDimitry Andric ++Position; 4210b57cec5SDimitry Andric ++Position; 4220b57cec5SDimitry Andric break; 4230b57cec5SDimitry Andric } 4240b57cec5SDimitry Andric } 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric Position += CompleteColumn - 1; 4270b57cec5SDimitry Andric 4280b57cec5SDimitry Andric // If pointing inside the preamble, adjust the position at the beginning of 4290b57cec5SDimitry Andric // the file after the preamble. 4300b57cec5SDimitry Andric if (SkipMainFilePreamble.first && 4310b57cec5SDimitry Andric SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()) == File) { 4320b57cec5SDimitry Andric if (Position - Buffer->getBufferStart() < SkipMainFilePreamble.first) 4330b57cec5SDimitry Andric Position = Buffer->getBufferStart() + SkipMainFilePreamble.first; 4340b57cec5SDimitry Andric } 4350b57cec5SDimitry Andric 4360b57cec5SDimitry Andric if (Position > Buffer->getBufferEnd()) 4370b57cec5SDimitry Andric Position = Buffer->getBufferEnd(); 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric CodeCompletionFile = File; 4400b57cec5SDimitry Andric CodeCompletionOffset = Position - Buffer->getBufferStart(); 4410b57cec5SDimitry Andric 4420b57cec5SDimitry Andric auto NewBuffer = llvm::WritableMemoryBuffer::getNewUninitMemBuffer( 4430b57cec5SDimitry Andric Buffer->getBufferSize() + 1, Buffer->getBufferIdentifier()); 4440b57cec5SDimitry Andric char *NewBuf = NewBuffer->getBufferStart(); 4450b57cec5SDimitry Andric char *NewPos = std::copy(Buffer->getBufferStart(), Position, NewBuf); 4460b57cec5SDimitry Andric *NewPos = '\0'; 4470b57cec5SDimitry Andric std::copy(Position, Buffer->getBufferEnd(), NewPos+1); 4480b57cec5SDimitry Andric SourceMgr.overrideFileContents(File, std::move(NewBuffer)); 4490b57cec5SDimitry Andric 4500b57cec5SDimitry Andric return false; 4510b57cec5SDimitry Andric } 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andric void Preprocessor::CodeCompleteIncludedFile(llvm::StringRef Dir, 4540b57cec5SDimitry Andric bool IsAngled) { 455fe6060f1SDimitry Andric setCodeCompletionReached(); 4560b57cec5SDimitry Andric if (CodeComplete) 4570b57cec5SDimitry Andric CodeComplete->CodeCompleteIncludedFile(Dir, IsAngled); 4580b57cec5SDimitry Andric } 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andric void Preprocessor::CodeCompleteNaturalLanguage() { 461fe6060f1SDimitry Andric setCodeCompletionReached(); 4620b57cec5SDimitry Andric if (CodeComplete) 4630b57cec5SDimitry Andric CodeComplete->CodeCompleteNaturalLanguage(); 4640b57cec5SDimitry Andric } 4650b57cec5SDimitry Andric 4660b57cec5SDimitry Andric /// getSpelling - This method is used to get the spelling of a token into a 4670b57cec5SDimitry Andric /// SmallVector. Note that the returned StringRef may not point to the 4680b57cec5SDimitry Andric /// supplied buffer if a copy can be avoided. 4690b57cec5SDimitry Andric StringRef Preprocessor::getSpelling(const Token &Tok, 4700b57cec5SDimitry Andric SmallVectorImpl<char> &Buffer, 4710b57cec5SDimitry Andric bool *Invalid) const { 4720b57cec5SDimitry Andric // NOTE: this has to be checked *before* testing for an IdentifierInfo. 4730b57cec5SDimitry Andric if (Tok.isNot(tok::raw_identifier) && !Tok.hasUCN()) { 4740b57cec5SDimitry Andric // Try the fast path. 4750b57cec5SDimitry Andric if (const IdentifierInfo *II = Tok.getIdentifierInfo()) 4760b57cec5SDimitry Andric return II->getName(); 4770b57cec5SDimitry Andric } 4780b57cec5SDimitry Andric 4790b57cec5SDimitry Andric // Resize the buffer if we need to copy into it. 4800b57cec5SDimitry Andric if (Tok.needsCleaning()) 4810b57cec5SDimitry Andric Buffer.resize(Tok.getLength()); 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric const char *Ptr = Buffer.data(); 4840b57cec5SDimitry Andric unsigned Len = getSpelling(Tok, Ptr, Invalid); 4850b57cec5SDimitry Andric return StringRef(Ptr, Len); 4860b57cec5SDimitry Andric } 4870b57cec5SDimitry Andric 4880b57cec5SDimitry Andric /// CreateString - Plop the specified string into a scratch buffer and return a 4890b57cec5SDimitry Andric /// location for it. If specified, the source location provides a source 4900b57cec5SDimitry Andric /// location for the token. 4910b57cec5SDimitry Andric void Preprocessor::CreateString(StringRef Str, Token &Tok, 4920b57cec5SDimitry Andric SourceLocation ExpansionLocStart, 4930b57cec5SDimitry Andric SourceLocation ExpansionLocEnd) { 4940b57cec5SDimitry Andric Tok.setLength(Str.size()); 4950b57cec5SDimitry Andric 4960b57cec5SDimitry Andric const char *DestPtr; 4970b57cec5SDimitry Andric SourceLocation Loc = ScratchBuf->getToken(Str.data(), Str.size(), DestPtr); 4980b57cec5SDimitry Andric 4990b57cec5SDimitry Andric if (ExpansionLocStart.isValid()) 5000b57cec5SDimitry Andric Loc = SourceMgr.createExpansionLoc(Loc, ExpansionLocStart, 5010b57cec5SDimitry Andric ExpansionLocEnd, Str.size()); 5020b57cec5SDimitry Andric Tok.setLocation(Loc); 5030b57cec5SDimitry Andric 5040b57cec5SDimitry Andric // If this is a raw identifier or a literal token, set the pointer data. 5050b57cec5SDimitry Andric if (Tok.is(tok::raw_identifier)) 5060b57cec5SDimitry Andric Tok.setRawIdentifierData(DestPtr); 5070b57cec5SDimitry Andric else if (Tok.isLiteral()) 5080b57cec5SDimitry Andric Tok.setLiteralData(DestPtr); 5090b57cec5SDimitry Andric } 5100b57cec5SDimitry Andric 5110b57cec5SDimitry Andric SourceLocation Preprocessor::SplitToken(SourceLocation Loc, unsigned Length) { 5120b57cec5SDimitry Andric auto &SM = getSourceManager(); 5130b57cec5SDimitry Andric SourceLocation SpellingLoc = SM.getSpellingLoc(Loc); 5140b57cec5SDimitry Andric std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellingLoc); 5150b57cec5SDimitry Andric bool Invalid = false; 5160b57cec5SDimitry Andric StringRef Buffer = SM.getBufferData(LocInfo.first, &Invalid); 5170b57cec5SDimitry Andric if (Invalid) 5180b57cec5SDimitry Andric return SourceLocation(); 5190b57cec5SDimitry Andric 5200b57cec5SDimitry Andric // FIXME: We could consider re-using spelling for tokens we see repeatedly. 5210b57cec5SDimitry Andric const char *DestPtr; 5220b57cec5SDimitry Andric SourceLocation Spelling = 5230b57cec5SDimitry Andric ScratchBuf->getToken(Buffer.data() + LocInfo.second, Length, DestPtr); 5240b57cec5SDimitry Andric return SM.createTokenSplitLoc(Spelling, Loc, Loc.getLocWithOffset(Length)); 5250b57cec5SDimitry Andric } 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric Module *Preprocessor::getCurrentModule() { 5280b57cec5SDimitry Andric if (!getLangOpts().isCompilingModule()) 5290b57cec5SDimitry Andric return nullptr; 5300b57cec5SDimitry Andric 5310b57cec5SDimitry Andric return getHeaderSearchInfo().lookupModule(getLangOpts().CurrentModule); 5320b57cec5SDimitry Andric } 5330b57cec5SDimitry Andric 534bdd1243dSDimitry Andric Module *Preprocessor::getCurrentModuleImplementation() { 535bdd1243dSDimitry Andric if (!getLangOpts().isCompilingModuleImplementation()) 536bdd1243dSDimitry Andric return nullptr; 537bdd1243dSDimitry Andric 538bdd1243dSDimitry Andric return getHeaderSearchInfo().lookupModule(getLangOpts().ModuleName); 539bdd1243dSDimitry Andric } 540bdd1243dSDimitry Andric 5410b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 5420b57cec5SDimitry Andric // Preprocessor Initialization Methods 5430b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 5440b57cec5SDimitry Andric 5450b57cec5SDimitry Andric /// EnterMainSourceFile - Enter the specified FileID as the main source file, 5460b57cec5SDimitry Andric /// which implicitly adds the builtin defines etc. 5470b57cec5SDimitry Andric void Preprocessor::EnterMainSourceFile() { 5480b57cec5SDimitry Andric // We do not allow the preprocessor to reenter the main file. Doing so will 5490b57cec5SDimitry Andric // cause FileID's to accumulate information from both runs (e.g. #line 5500b57cec5SDimitry Andric // information) and predefined macros aren't guaranteed to be set properly. 5510b57cec5SDimitry Andric assert(NumEnteredSourceFiles == 0 && "Cannot reenter the main file!"); 5520b57cec5SDimitry Andric FileID MainFileID = SourceMgr.getMainFileID(); 5530b57cec5SDimitry Andric 5540b57cec5SDimitry Andric // If MainFileID is loaded it means we loaded an AST file, no need to enter 5550b57cec5SDimitry Andric // a main file. 5560b57cec5SDimitry Andric if (!SourceMgr.isLoadedFileID(MainFileID)) { 5570b57cec5SDimitry Andric // Enter the main file source buffer. 5580b57cec5SDimitry Andric EnterSourceFile(MainFileID, nullptr, SourceLocation()); 5590b57cec5SDimitry Andric 5600b57cec5SDimitry Andric // If we've been asked to skip bytes in the main file (e.g., as part of a 5610b57cec5SDimitry Andric // precompiled preamble), do so now. 5620b57cec5SDimitry Andric if (SkipMainFilePreamble.first > 0) 5630b57cec5SDimitry Andric CurLexer->SetByteOffset(SkipMainFilePreamble.first, 5640b57cec5SDimitry Andric SkipMainFilePreamble.second); 5650b57cec5SDimitry Andric 5660b57cec5SDimitry Andric // Tell the header info that the main file was entered. If the file is later 5670b57cec5SDimitry Andric // #imported, it won't be re-entered. 5685f757f3fSDimitry Andric if (OptionalFileEntryRef FE = SourceMgr.getFileEntryRefForID(MainFileID)) 5695f757f3fSDimitry Andric markIncluded(*FE); 5700b57cec5SDimitry Andric } 5710b57cec5SDimitry Andric 5720b57cec5SDimitry Andric // Preprocess Predefines to populate the initial preprocessor state. 5730b57cec5SDimitry Andric std::unique_ptr<llvm::MemoryBuffer> SB = 5740b57cec5SDimitry Andric llvm::MemoryBuffer::getMemBufferCopy(Predefines, "<built-in>"); 5750b57cec5SDimitry Andric assert(SB && "Cannot create predefined source buffer"); 5760b57cec5SDimitry Andric FileID FID = SourceMgr.createFileID(std::move(SB)); 5770b57cec5SDimitry Andric assert(FID.isValid() && "Could not create FileID for predefines?"); 5780b57cec5SDimitry Andric setPredefinesFileID(FID); 5790b57cec5SDimitry Andric 5800b57cec5SDimitry Andric // Start parsing the predefines. 5810b57cec5SDimitry Andric EnterSourceFile(FID, nullptr, SourceLocation()); 5820b57cec5SDimitry Andric 5830b57cec5SDimitry Andric if (!PPOpts->PCHThroughHeader.empty()) { 5840b57cec5SDimitry Andric // Lookup and save the FileID for the through header. If it isn't found 5850b57cec5SDimitry Andric // in the search path, it's a fatal error. 586bdd1243dSDimitry Andric OptionalFileEntryRef File = LookupFile( 5870b57cec5SDimitry Andric SourceLocation(), PPOpts->PCHThroughHeader, 58804eeddc0SDimitry Andric /*isAngled=*/false, /*FromDir=*/nullptr, /*FromFile=*/nullptr, 58904eeddc0SDimitry Andric /*CurDir=*/nullptr, /*SearchPath=*/nullptr, /*RelativePath=*/nullptr, 5900b57cec5SDimitry Andric /*SuggestedModule=*/nullptr, /*IsMapped=*/nullptr, 5910b57cec5SDimitry Andric /*IsFrameworkFound=*/nullptr); 5920b57cec5SDimitry Andric if (!File) { 5930b57cec5SDimitry Andric Diag(SourceLocation(), diag::err_pp_through_header_not_found) 5940b57cec5SDimitry Andric << PPOpts->PCHThroughHeader; 5950b57cec5SDimitry Andric return; 5960b57cec5SDimitry Andric } 5970b57cec5SDimitry Andric setPCHThroughHeaderFileID( 598a7dea167SDimitry Andric SourceMgr.createFileID(*File, SourceLocation(), SrcMgr::C_User)); 5990b57cec5SDimitry Andric } 6000b57cec5SDimitry Andric 6010b57cec5SDimitry Andric // Skip tokens from the Predefines and if needed the main file. 6020b57cec5SDimitry Andric if ((usingPCHWithThroughHeader() && SkippingUntilPCHThroughHeader) || 6030b57cec5SDimitry Andric (usingPCHWithPragmaHdrStop() && SkippingUntilPragmaHdrStop)) 6040b57cec5SDimitry Andric SkipTokensWhileUsingPCH(); 6050b57cec5SDimitry Andric } 6060b57cec5SDimitry Andric 6070b57cec5SDimitry Andric void Preprocessor::setPCHThroughHeaderFileID(FileID FID) { 6080b57cec5SDimitry Andric assert(PCHThroughHeaderFileID.isInvalid() && 6090b57cec5SDimitry Andric "PCHThroughHeaderFileID already set!"); 6100b57cec5SDimitry Andric PCHThroughHeaderFileID = FID; 6110b57cec5SDimitry Andric } 6120b57cec5SDimitry Andric 6130b57cec5SDimitry Andric bool Preprocessor::isPCHThroughHeader(const FileEntry *FE) { 6140b57cec5SDimitry Andric assert(PCHThroughHeaderFileID.isValid() && 6150b57cec5SDimitry Andric "Invalid PCH through header FileID"); 6160b57cec5SDimitry Andric return FE == SourceMgr.getFileEntryForID(PCHThroughHeaderFileID); 6170b57cec5SDimitry Andric } 6180b57cec5SDimitry Andric 6190b57cec5SDimitry Andric bool Preprocessor::creatingPCHWithThroughHeader() { 6200b57cec5SDimitry Andric return TUKind == TU_Prefix && !PPOpts->PCHThroughHeader.empty() && 6210b57cec5SDimitry Andric PCHThroughHeaderFileID.isValid(); 6220b57cec5SDimitry Andric } 6230b57cec5SDimitry Andric 6240b57cec5SDimitry Andric bool Preprocessor::usingPCHWithThroughHeader() { 6250b57cec5SDimitry Andric return TUKind != TU_Prefix && !PPOpts->PCHThroughHeader.empty() && 6260b57cec5SDimitry Andric PCHThroughHeaderFileID.isValid(); 6270b57cec5SDimitry Andric } 6280b57cec5SDimitry Andric 6290b57cec5SDimitry Andric bool Preprocessor::creatingPCHWithPragmaHdrStop() { 6300b57cec5SDimitry Andric return TUKind == TU_Prefix && PPOpts->PCHWithHdrStop; 6310b57cec5SDimitry Andric } 6320b57cec5SDimitry Andric 6330b57cec5SDimitry Andric bool Preprocessor::usingPCHWithPragmaHdrStop() { 6340b57cec5SDimitry Andric return TUKind != TU_Prefix && PPOpts->PCHWithHdrStop; 6350b57cec5SDimitry Andric } 6360b57cec5SDimitry Andric 6370b57cec5SDimitry Andric /// Skip tokens until after the #include of the through header or 6380b57cec5SDimitry Andric /// until after a #pragma hdrstop is seen. Tokens in the predefines file 6390b57cec5SDimitry Andric /// and the main file may be skipped. If the end of the predefines file 6400b57cec5SDimitry Andric /// is reached, skipping continues into the main file. If the end of the 6410b57cec5SDimitry Andric /// main file is reached, it's a fatal error. 6420b57cec5SDimitry Andric void Preprocessor::SkipTokensWhileUsingPCH() { 6430b57cec5SDimitry Andric bool ReachedMainFileEOF = false; 6440b57cec5SDimitry Andric bool UsingPCHThroughHeader = SkippingUntilPCHThroughHeader; 6450b57cec5SDimitry Andric bool UsingPragmaHdrStop = SkippingUntilPragmaHdrStop; 6460b57cec5SDimitry Andric Token Tok; 6470b57cec5SDimitry Andric while (true) { 6480b57cec5SDimitry Andric bool InPredefines = 6490b57cec5SDimitry Andric (CurLexer && CurLexer->getFileID() == getPredefinesFileID()); 6505f757f3fSDimitry Andric CurLexerCallback(*this, Tok); 6510b57cec5SDimitry Andric if (Tok.is(tok::eof) && !InPredefines) { 6520b57cec5SDimitry Andric ReachedMainFileEOF = true; 6530b57cec5SDimitry Andric break; 6540b57cec5SDimitry Andric } 6550b57cec5SDimitry Andric if (UsingPCHThroughHeader && !SkippingUntilPCHThroughHeader) 6560b57cec5SDimitry Andric break; 6570b57cec5SDimitry Andric if (UsingPragmaHdrStop && !SkippingUntilPragmaHdrStop) 6580b57cec5SDimitry Andric break; 6590b57cec5SDimitry Andric } 6600b57cec5SDimitry Andric if (ReachedMainFileEOF) { 6610b57cec5SDimitry Andric if (UsingPCHThroughHeader) 6620b57cec5SDimitry Andric Diag(SourceLocation(), diag::err_pp_through_header_not_seen) 6630b57cec5SDimitry Andric << PPOpts->PCHThroughHeader << 1; 6640b57cec5SDimitry Andric else if (!PPOpts->PCHWithHdrStopCreate) 6650b57cec5SDimitry Andric Diag(SourceLocation(), diag::err_pp_pragma_hdrstop_not_seen); 6660b57cec5SDimitry Andric } 6670b57cec5SDimitry Andric } 6680b57cec5SDimitry Andric 6690b57cec5SDimitry Andric void Preprocessor::replayPreambleConditionalStack() { 6700b57cec5SDimitry Andric // Restore the conditional stack from the preamble, if there is one. 6710b57cec5SDimitry Andric if (PreambleConditionalStack.isReplaying()) { 6720b57cec5SDimitry Andric assert(CurPPLexer && 6730b57cec5SDimitry Andric "CurPPLexer is null when calling replayPreambleConditionalStack."); 6740b57cec5SDimitry Andric CurPPLexer->setConditionalLevels(PreambleConditionalStack.getStack()); 6750b57cec5SDimitry Andric PreambleConditionalStack.doneReplaying(); 6760b57cec5SDimitry Andric if (PreambleConditionalStack.reachedEOFWhileSkipping()) 6770b57cec5SDimitry Andric SkipExcludedConditionalBlock( 6780b57cec5SDimitry Andric PreambleConditionalStack.SkipInfo->HashTokenLoc, 6790b57cec5SDimitry Andric PreambleConditionalStack.SkipInfo->IfTokenLoc, 6800b57cec5SDimitry Andric PreambleConditionalStack.SkipInfo->FoundNonSkipPortion, 6810b57cec5SDimitry Andric PreambleConditionalStack.SkipInfo->FoundElse, 6820b57cec5SDimitry Andric PreambleConditionalStack.SkipInfo->ElseLoc); 6830b57cec5SDimitry Andric } 6840b57cec5SDimitry Andric } 6850b57cec5SDimitry Andric 6860b57cec5SDimitry Andric void Preprocessor::EndSourceFile() { 6870b57cec5SDimitry Andric // Notify the client that we reached the end of the source file. 6880b57cec5SDimitry Andric if (Callbacks) 6890b57cec5SDimitry Andric Callbacks->EndOfMainFile(); 6900b57cec5SDimitry Andric } 6910b57cec5SDimitry Andric 6920b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 6930b57cec5SDimitry Andric // Lexer Event Handling. 6940b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 6950b57cec5SDimitry Andric 6960b57cec5SDimitry Andric /// LookUpIdentifierInfo - Given a tok::raw_identifier token, look up the 6970b57cec5SDimitry Andric /// identifier information for the token and install it into the token, 6980b57cec5SDimitry Andric /// updating the token kind accordingly. 6990b57cec5SDimitry Andric IdentifierInfo *Preprocessor::LookUpIdentifierInfo(Token &Identifier) const { 7000b57cec5SDimitry Andric assert(!Identifier.getRawIdentifier().empty() && "No raw identifier data!"); 7010b57cec5SDimitry Andric 7020b57cec5SDimitry Andric // Look up this token, see if it is a macro, or if it is a language keyword. 7030b57cec5SDimitry Andric IdentifierInfo *II; 7040b57cec5SDimitry Andric if (!Identifier.needsCleaning() && !Identifier.hasUCN()) { 7050b57cec5SDimitry Andric // No cleaning needed, just use the characters from the lexed buffer. 7060b57cec5SDimitry Andric II = getIdentifierInfo(Identifier.getRawIdentifier()); 7070b57cec5SDimitry Andric } else { 7080b57cec5SDimitry Andric // Cleaning needed, alloca a buffer, clean into it, then use the buffer. 7090b57cec5SDimitry Andric SmallString<64> IdentifierBuffer; 7100b57cec5SDimitry Andric StringRef CleanedStr = getSpelling(Identifier, IdentifierBuffer); 7110b57cec5SDimitry Andric 7120b57cec5SDimitry Andric if (Identifier.hasUCN()) { 7130b57cec5SDimitry Andric SmallString<64> UCNIdentifierBuffer; 7140b57cec5SDimitry Andric expandUCNs(UCNIdentifierBuffer, CleanedStr); 7150b57cec5SDimitry Andric II = getIdentifierInfo(UCNIdentifierBuffer); 7160b57cec5SDimitry Andric } else { 7170b57cec5SDimitry Andric II = getIdentifierInfo(CleanedStr); 7180b57cec5SDimitry Andric } 7190b57cec5SDimitry Andric } 7200b57cec5SDimitry Andric 7210b57cec5SDimitry Andric // Update the token info (identifier info and appropriate token kind). 722349cc55cSDimitry Andric // FIXME: the raw_identifier may contain leading whitespace which is removed 723349cc55cSDimitry Andric // from the cleaned identifier token. The SourceLocation should be updated to 724349cc55cSDimitry Andric // refer to the non-whitespace character. For instance, the text "\\\nB" (a 725349cc55cSDimitry Andric // line continuation before 'B') is parsed as a single tok::raw_identifier and 726349cc55cSDimitry Andric // is cleaned to tok::identifier "B". After cleaning the token's length is 727349cc55cSDimitry Andric // still 3 and the SourceLocation refers to the location of the backslash. 7280b57cec5SDimitry Andric Identifier.setIdentifierInfo(II); 7290b57cec5SDimitry Andric Identifier.setKind(II->getTokenID()); 7300b57cec5SDimitry Andric 7310b57cec5SDimitry Andric return II; 7320b57cec5SDimitry Andric } 7330b57cec5SDimitry Andric 7340b57cec5SDimitry Andric void Preprocessor::SetPoisonReason(IdentifierInfo *II, unsigned DiagID) { 7350b57cec5SDimitry Andric PoisonReasons[II] = DiagID; 7360b57cec5SDimitry Andric } 7370b57cec5SDimitry Andric 7380b57cec5SDimitry Andric void Preprocessor::PoisonSEHIdentifiers(bool Poison) { 7390b57cec5SDimitry Andric assert(Ident__exception_code && Ident__exception_info); 7400b57cec5SDimitry Andric assert(Ident___exception_code && Ident___exception_info); 7410b57cec5SDimitry Andric Ident__exception_code->setIsPoisoned(Poison); 7420b57cec5SDimitry Andric Ident___exception_code->setIsPoisoned(Poison); 7430b57cec5SDimitry Andric Ident_GetExceptionCode->setIsPoisoned(Poison); 7440b57cec5SDimitry Andric Ident__exception_info->setIsPoisoned(Poison); 7450b57cec5SDimitry Andric Ident___exception_info->setIsPoisoned(Poison); 7460b57cec5SDimitry Andric Ident_GetExceptionInfo->setIsPoisoned(Poison); 7470b57cec5SDimitry Andric Ident__abnormal_termination->setIsPoisoned(Poison); 7480b57cec5SDimitry Andric Ident___abnormal_termination->setIsPoisoned(Poison); 7490b57cec5SDimitry Andric Ident_AbnormalTermination->setIsPoisoned(Poison); 7500b57cec5SDimitry Andric } 7510b57cec5SDimitry Andric 7520b57cec5SDimitry Andric void Preprocessor::HandlePoisonedIdentifier(Token & Identifier) { 7530b57cec5SDimitry Andric assert(Identifier.getIdentifierInfo() && 7540b57cec5SDimitry Andric "Can't handle identifiers without identifier info!"); 7550b57cec5SDimitry Andric llvm::DenseMap<IdentifierInfo*,unsigned>::const_iterator it = 7560b57cec5SDimitry Andric PoisonReasons.find(Identifier.getIdentifierInfo()); 7570b57cec5SDimitry Andric if(it == PoisonReasons.end()) 7580b57cec5SDimitry Andric Diag(Identifier, diag::err_pp_used_poisoned_id); 7590b57cec5SDimitry Andric else 7600b57cec5SDimitry Andric Diag(Identifier,it->second) << Identifier.getIdentifierInfo(); 7610b57cec5SDimitry Andric } 7620b57cec5SDimitry Andric 763*0fca6ea1SDimitry Andric void Preprocessor::updateOutOfDateIdentifier(const IdentifierInfo &II) const { 7640b57cec5SDimitry Andric assert(II.isOutOfDate() && "not out of date"); 7650b57cec5SDimitry Andric getExternalSource()->updateOutOfDateIdentifier(II); 7660b57cec5SDimitry Andric } 7670b57cec5SDimitry Andric 7680b57cec5SDimitry Andric /// HandleIdentifier - This callback is invoked when the lexer reads an 7690b57cec5SDimitry Andric /// identifier. This callback looks up the identifier in the map and/or 7700b57cec5SDimitry Andric /// potentially macro expands it or turns it into a named token (like 'for'). 7710b57cec5SDimitry Andric /// 7720b57cec5SDimitry Andric /// Note that callers of this method are guarded by checking the 7730b57cec5SDimitry Andric /// IdentifierInfo's 'isHandleIdentifierCase' bit. If this method changes, the 7740b57cec5SDimitry Andric /// IdentifierInfo methods that compute these properties will need to change to 7750b57cec5SDimitry Andric /// match. 7760b57cec5SDimitry Andric bool Preprocessor::HandleIdentifier(Token &Identifier) { 7770b57cec5SDimitry Andric assert(Identifier.getIdentifierInfo() && 7780b57cec5SDimitry Andric "Can't handle identifiers without identifier info!"); 7790b57cec5SDimitry Andric 7800b57cec5SDimitry Andric IdentifierInfo &II = *Identifier.getIdentifierInfo(); 7810b57cec5SDimitry Andric 7820b57cec5SDimitry Andric // If the information about this identifier is out of date, update it from 7830b57cec5SDimitry Andric // the external source. 7840b57cec5SDimitry Andric // We have to treat __VA_ARGS__ in a special way, since it gets 7850b57cec5SDimitry Andric // serialized with isPoisoned = true, but our preprocessor may have 7860b57cec5SDimitry Andric // unpoisoned it if we're defining a C99 macro. 7870b57cec5SDimitry Andric if (II.isOutOfDate()) { 7880b57cec5SDimitry Andric bool CurrentIsPoisoned = false; 7890b57cec5SDimitry Andric const bool IsSpecialVariadicMacro = 7900b57cec5SDimitry Andric &II == Ident__VA_ARGS__ || &II == Ident__VA_OPT__; 7910b57cec5SDimitry Andric if (IsSpecialVariadicMacro) 7920b57cec5SDimitry Andric CurrentIsPoisoned = II.isPoisoned(); 7930b57cec5SDimitry Andric 7940b57cec5SDimitry Andric updateOutOfDateIdentifier(II); 7950b57cec5SDimitry Andric Identifier.setKind(II.getTokenID()); 7960b57cec5SDimitry Andric 7970b57cec5SDimitry Andric if (IsSpecialVariadicMacro) 7980b57cec5SDimitry Andric II.setIsPoisoned(CurrentIsPoisoned); 7990b57cec5SDimitry Andric } 8000b57cec5SDimitry Andric 8010b57cec5SDimitry Andric // If this identifier was poisoned, and if it was not produced from a macro 8020b57cec5SDimitry Andric // expansion, emit an error. 8030b57cec5SDimitry Andric if (II.isPoisoned() && CurPPLexer) { 8040b57cec5SDimitry Andric HandlePoisonedIdentifier(Identifier); 8050b57cec5SDimitry Andric } 8060b57cec5SDimitry Andric 8070b57cec5SDimitry Andric // If this is a macro to be expanded, do it. 8085f757f3fSDimitry Andric if (const MacroDefinition MD = getMacroDefinition(&II)) { 8095f757f3fSDimitry Andric const auto *MI = MD.getMacroInfo(); 8100b57cec5SDimitry Andric assert(MI && "macro definition with no macro info?"); 8110b57cec5SDimitry Andric if (!DisableMacroExpansion) { 8120b57cec5SDimitry Andric if (!Identifier.isExpandDisabled() && MI->isEnabled()) { 8130b57cec5SDimitry Andric // C99 6.10.3p10: If the preprocessing token immediately after the 8140b57cec5SDimitry Andric // macro name isn't a '(', this macro should not be expanded. 8150b57cec5SDimitry Andric if (!MI->isFunctionLike() || isNextPPTokenLParen()) 8160b57cec5SDimitry Andric return HandleMacroExpandedIdentifier(Identifier, MD); 8170b57cec5SDimitry Andric } else { 8180b57cec5SDimitry Andric // C99 6.10.3.4p2 says that a disabled macro may never again be 8190b57cec5SDimitry Andric // expanded, even if it's in a context where it could be expanded in the 8200b57cec5SDimitry Andric // future. 8210b57cec5SDimitry Andric Identifier.setFlag(Token::DisableExpand); 8220b57cec5SDimitry Andric if (MI->isObjectLike() || isNextPPTokenLParen()) 8230b57cec5SDimitry Andric Diag(Identifier, diag::pp_disabled_macro_expansion); 8240b57cec5SDimitry Andric } 8250b57cec5SDimitry Andric } 8260b57cec5SDimitry Andric } 8270b57cec5SDimitry Andric 8280b57cec5SDimitry Andric // If this identifier is a keyword in a newer Standard or proposed Standard, 8290b57cec5SDimitry Andric // produce a warning. Don't warn if we're not considering macro expansion, 8300b57cec5SDimitry Andric // since this identifier might be the name of a macro. 8310b57cec5SDimitry Andric // FIXME: This warning is disabled in cases where it shouldn't be, like 8320b57cec5SDimitry Andric // "#define constexpr constexpr", "int constexpr;" 8330b57cec5SDimitry Andric if (II.isFutureCompatKeyword() && !DisableMacroExpansion) { 834bdd1243dSDimitry Andric Diag(Identifier, getIdentifierTable().getFutureCompatDiagKind(II, getLangOpts())) 8350b57cec5SDimitry Andric << II.getName(); 8360b57cec5SDimitry Andric // Don't diagnose this keyword again in this translation unit. 8370b57cec5SDimitry Andric II.setIsFutureCompatKeyword(false); 8380b57cec5SDimitry Andric } 8390b57cec5SDimitry Andric 8400b57cec5SDimitry Andric // If this is an extension token, diagnose its use. 8410b57cec5SDimitry Andric // We avoid diagnosing tokens that originate from macro definitions. 8420b57cec5SDimitry Andric // FIXME: This warning is disabled in cases where it shouldn't be, 8430b57cec5SDimitry Andric // like "#define TY typeof", "TY(1) x". 8440b57cec5SDimitry Andric if (II.isExtensionToken() && !DisableMacroExpansion) 8450b57cec5SDimitry Andric Diag(Identifier, diag::ext_token_used); 8460b57cec5SDimitry Andric 8470b57cec5SDimitry Andric // If this is the 'import' contextual keyword following an '@', note 8480b57cec5SDimitry Andric // that the next token indicates a module name. 8490b57cec5SDimitry Andric // 8500b57cec5SDimitry Andric // Note that we do not treat 'import' as a contextual 8510b57cec5SDimitry Andric // keyword when we're in a caching lexer, because caching lexers only get 8520b57cec5SDimitry Andric // used in contexts where import declarations are disallowed. 8530b57cec5SDimitry Andric // 85406c3fb27SDimitry Andric // Likewise if this is the standard C++ import keyword. 8550b57cec5SDimitry Andric if (((LastTokenWasAt && II.isModulesImport()) || 8560b57cec5SDimitry Andric Identifier.is(tok::kw_import)) && 8570b57cec5SDimitry Andric !InMacroArgs && !DisableMacroExpansion && 8580b57cec5SDimitry Andric (getLangOpts().Modules || getLangOpts().DebuggerSupport) && 8595f757f3fSDimitry Andric CurLexerCallback != CLK_CachingLexer) { 8600b57cec5SDimitry Andric ModuleImportLoc = Identifier.getLocation(); 861bdd1243dSDimitry Andric NamedModuleImportPath.clear(); 8621ac55f4cSDimitry Andric IsAtImport = true; 8630b57cec5SDimitry Andric ModuleImportExpectsIdentifier = true; 8645f757f3fSDimitry Andric CurLexerCallback = CLK_LexAfterModuleImport; 8650b57cec5SDimitry Andric } 8660b57cec5SDimitry Andric return true; 8670b57cec5SDimitry Andric } 8680b57cec5SDimitry Andric 8690b57cec5SDimitry Andric void Preprocessor::Lex(Token &Result) { 8700b57cec5SDimitry Andric ++LexLevel; 8710b57cec5SDimitry Andric 8720b57cec5SDimitry Andric // We loop here until a lex function returns a token; this avoids recursion. 8735f757f3fSDimitry Andric while (!CurLexerCallback(*this, Result)) 8745f757f3fSDimitry Andric ; 8750b57cec5SDimitry Andric 8765ffd83dbSDimitry Andric if (Result.is(tok::unknown) && TheModuleLoader.HadFatalFailure) 8775ffd83dbSDimitry Andric return; 8785ffd83dbSDimitry Andric 8790b57cec5SDimitry Andric if (Result.is(tok::code_completion) && Result.getIdentifierInfo()) { 8800b57cec5SDimitry Andric // Remember the identifier before code completion token. 8810b57cec5SDimitry Andric setCodeCompletionIdentifierInfo(Result.getIdentifierInfo()); 8820b57cec5SDimitry Andric setCodeCompletionTokenRange(Result.getLocation(), Result.getEndLoc()); 8830b57cec5SDimitry Andric // Set IdenfitierInfo to null to avoid confusing code that handles both 8840b57cec5SDimitry Andric // identifiers and completion tokens. 8850b57cec5SDimitry Andric Result.setIdentifierInfo(nullptr); 8860b57cec5SDimitry Andric } 8870b57cec5SDimitry Andric 888bdd1243dSDimitry Andric // Update StdCXXImportSeqState to track our position within a C++20 import-seq 8890b57cec5SDimitry Andric // if this token is being produced as a result of phase 4 of translation. 890753f127fSDimitry Andric // Update TrackGMFState to decide if we are currently in a Global Module 891bdd1243dSDimitry Andric // Fragment. GMF state updates should precede StdCXXImportSeq ones, since GMF state 892bdd1243dSDimitry Andric // depends on the prevailing StdCXXImportSeq state in two cases. 8930b57cec5SDimitry Andric if (getLangOpts().CPlusPlusModules && LexLevel == 1 && 8940b57cec5SDimitry Andric !Result.getFlag(Token::IsReinjected)) { 8950b57cec5SDimitry Andric switch (Result.getKind()) { 8960b57cec5SDimitry Andric case tok::l_paren: case tok::l_square: case tok::l_brace: 897bdd1243dSDimitry Andric StdCXXImportSeqState.handleOpenBracket(); 8980b57cec5SDimitry Andric break; 8990b57cec5SDimitry Andric case tok::r_paren: case tok::r_square: 900bdd1243dSDimitry Andric StdCXXImportSeqState.handleCloseBracket(); 9010b57cec5SDimitry Andric break; 9020b57cec5SDimitry Andric case tok::r_brace: 903bdd1243dSDimitry Andric StdCXXImportSeqState.handleCloseBrace(); 9040b57cec5SDimitry Andric break; 905753f127fSDimitry Andric // This token is injected to represent the translation of '#include "a.h"' 906753f127fSDimitry Andric // into "import a.h;". Mimic the notional ';'. 907753f127fSDimitry Andric case tok::annot_module_include: 9080b57cec5SDimitry Andric case tok::semi: 909753f127fSDimitry Andric TrackGMFState.handleSemi(); 910bdd1243dSDimitry Andric StdCXXImportSeqState.handleSemi(); 9111ac55f4cSDimitry Andric ModuleDeclState.handleSemi(); 9120b57cec5SDimitry Andric break; 9130b57cec5SDimitry Andric case tok::header_name: 9140b57cec5SDimitry Andric case tok::annot_header_unit: 915bdd1243dSDimitry Andric StdCXXImportSeqState.handleHeaderName(); 9160b57cec5SDimitry Andric break; 9170b57cec5SDimitry Andric case tok::kw_export: 918753f127fSDimitry Andric TrackGMFState.handleExport(); 919bdd1243dSDimitry Andric StdCXXImportSeqState.handleExport(); 9201ac55f4cSDimitry Andric ModuleDeclState.handleExport(); 9211ac55f4cSDimitry Andric break; 9221ac55f4cSDimitry Andric case tok::colon: 9231ac55f4cSDimitry Andric ModuleDeclState.handleColon(); 9241ac55f4cSDimitry Andric break; 9251ac55f4cSDimitry Andric case tok::period: 9261ac55f4cSDimitry Andric ModuleDeclState.handlePeriod(); 9270b57cec5SDimitry Andric break; 9280b57cec5SDimitry Andric case tok::identifier: 9295f757f3fSDimitry Andric // Check "import" and "module" when there is no open bracket. The two 9305f757f3fSDimitry Andric // identifiers are not meaningful with open brackets. 9315f757f3fSDimitry Andric if (StdCXXImportSeqState.atTopLevel()) { 9320b57cec5SDimitry Andric if (Result.getIdentifierInfo()->isModulesImport()) { 933bdd1243dSDimitry Andric TrackGMFState.handleImport(StdCXXImportSeqState.afterTopLevelSeq()); 934bdd1243dSDimitry Andric StdCXXImportSeqState.handleImport(); 935bdd1243dSDimitry Andric if (StdCXXImportSeqState.afterImportSeq()) { 9360b57cec5SDimitry Andric ModuleImportLoc = Result.getLocation(); 937bdd1243dSDimitry Andric NamedModuleImportPath.clear(); 9381ac55f4cSDimitry Andric IsAtImport = false; 9390b57cec5SDimitry Andric ModuleImportExpectsIdentifier = true; 9405f757f3fSDimitry Andric CurLexerCallback = CLK_LexAfterModuleImport; 9410b57cec5SDimitry Andric } 9420b57cec5SDimitry Andric break; 943753f127fSDimitry Andric } else if (Result.getIdentifierInfo() == getIdentifierInfo("module")) { 944bdd1243dSDimitry Andric TrackGMFState.handleModule(StdCXXImportSeqState.afterTopLevelSeq()); 9451ac55f4cSDimitry Andric ModuleDeclState.handleModule(); 9461ac55f4cSDimitry Andric break; 9475f757f3fSDimitry Andric } 9485f757f3fSDimitry Andric } 9491ac55f4cSDimitry Andric ModuleDeclState.handleIdentifier(Result.getIdentifierInfo()); 9501ac55f4cSDimitry Andric if (ModuleDeclState.isModuleCandidate()) 951753f127fSDimitry Andric break; 952bdd1243dSDimitry Andric [[fallthrough]]; 9530b57cec5SDimitry Andric default: 954753f127fSDimitry Andric TrackGMFState.handleMisc(); 955bdd1243dSDimitry Andric StdCXXImportSeqState.handleMisc(); 9561ac55f4cSDimitry Andric ModuleDeclState.handleMisc(); 9570b57cec5SDimitry Andric break; 9580b57cec5SDimitry Andric } 9590b57cec5SDimitry Andric } 9600b57cec5SDimitry Andric 961*0fca6ea1SDimitry Andric if (CurLexer && ++CheckPointCounter == CheckPointStepSize) { 962*0fca6ea1SDimitry Andric CheckPoints[CurLexer->getFileID()].push_back(CurLexer->BufferPtr); 963*0fca6ea1SDimitry Andric CheckPointCounter = 0; 964*0fca6ea1SDimitry Andric } 965*0fca6ea1SDimitry Andric 9660b57cec5SDimitry Andric LastTokenWasAt = Result.is(tok::at); 9670b57cec5SDimitry Andric --LexLevel; 9685ffd83dbSDimitry Andric 969e8d8bef9SDimitry Andric if ((LexLevel == 0 || PreprocessToken) && 970e8d8bef9SDimitry Andric !Result.getFlag(Token::IsReinjected)) { 971e8d8bef9SDimitry Andric if (LexLevel == 0) 9725ffd83dbSDimitry Andric ++TokenCount; 9735ffd83dbSDimitry Andric if (OnToken) 9740b57cec5SDimitry Andric OnToken(Result); 9750b57cec5SDimitry Andric } 9765ffd83dbSDimitry Andric } 9770b57cec5SDimitry Andric 9785f757f3fSDimitry Andric void Preprocessor::LexTokensUntilEOF(std::vector<Token> *Tokens) { 9795f757f3fSDimitry Andric while (1) { 9805f757f3fSDimitry Andric Token Tok; 9815f757f3fSDimitry Andric Lex(Tok); 9825f757f3fSDimitry Andric if (Tok.isOneOf(tok::unknown, tok::eof, tok::eod, 9835f757f3fSDimitry Andric tok::annot_repl_input_end)) 9845f757f3fSDimitry Andric break; 9855f757f3fSDimitry Andric if (Tokens != nullptr) 9865f757f3fSDimitry Andric Tokens->push_back(Tok); 9875f757f3fSDimitry Andric } 9885f757f3fSDimitry Andric } 9895f757f3fSDimitry Andric 9900b57cec5SDimitry Andric /// Lex a header-name token (including one formed from header-name-tokens if 991*0fca6ea1SDimitry Andric /// \p AllowMacroExpansion is \c true). 9920b57cec5SDimitry Andric /// 9930b57cec5SDimitry Andric /// \param FilenameTok Filled in with the next token. On success, this will 9940b57cec5SDimitry Andric /// be either a header_name token. On failure, it will be whatever other 9950b57cec5SDimitry Andric /// token was found instead. 9960b57cec5SDimitry Andric /// \param AllowMacroExpansion If \c true, allow the header name to be formed 9970b57cec5SDimitry Andric /// by macro expansion (concatenating tokens as necessary if the first 9980b57cec5SDimitry Andric /// token is a '<'). 9990b57cec5SDimitry Andric /// \return \c true if we reached EOD or EOF while looking for a > token in 10000b57cec5SDimitry Andric /// a concatenated header name and diagnosed it. \c false otherwise. 10010b57cec5SDimitry Andric bool Preprocessor::LexHeaderName(Token &FilenameTok, bool AllowMacroExpansion) { 10020b57cec5SDimitry Andric // Lex using header-name tokenization rules if tokens are being lexed from 10030b57cec5SDimitry Andric // a file. Just grab a token normally if we're in a macro expansion. 10040b57cec5SDimitry Andric if (CurPPLexer) 10050b57cec5SDimitry Andric CurPPLexer->LexIncludeFilename(FilenameTok); 10060b57cec5SDimitry Andric else 10070b57cec5SDimitry Andric Lex(FilenameTok); 10080b57cec5SDimitry Andric 10090b57cec5SDimitry Andric // This could be a <foo/bar.h> file coming from a macro expansion. In this 10100b57cec5SDimitry Andric // case, glue the tokens together into an angle_string_literal token. 10110b57cec5SDimitry Andric SmallString<128> FilenameBuffer; 10120b57cec5SDimitry Andric if (FilenameTok.is(tok::less) && AllowMacroExpansion) { 10130b57cec5SDimitry Andric bool StartOfLine = FilenameTok.isAtStartOfLine(); 10140b57cec5SDimitry Andric bool LeadingSpace = FilenameTok.hasLeadingSpace(); 10150b57cec5SDimitry Andric bool LeadingEmptyMacro = FilenameTok.hasLeadingEmptyMacro(); 10160b57cec5SDimitry Andric 10170b57cec5SDimitry Andric SourceLocation Start = FilenameTok.getLocation(); 10180b57cec5SDimitry Andric SourceLocation End; 10190b57cec5SDimitry Andric FilenameBuffer.push_back('<'); 10200b57cec5SDimitry Andric 10210b57cec5SDimitry Andric // Consume tokens until we find a '>'. 10220b57cec5SDimitry Andric // FIXME: A header-name could be formed starting or ending with an 10230b57cec5SDimitry Andric // alternative token. It's not clear whether that's ill-formed in all 10240b57cec5SDimitry Andric // cases. 10250b57cec5SDimitry Andric while (FilenameTok.isNot(tok::greater)) { 10260b57cec5SDimitry Andric Lex(FilenameTok); 10270b57cec5SDimitry Andric if (FilenameTok.isOneOf(tok::eod, tok::eof)) { 10280b57cec5SDimitry Andric Diag(FilenameTok.getLocation(), diag::err_expected) << tok::greater; 10290b57cec5SDimitry Andric Diag(Start, diag::note_matching) << tok::less; 10300b57cec5SDimitry Andric return true; 10310b57cec5SDimitry Andric } 10320b57cec5SDimitry Andric 10330b57cec5SDimitry Andric End = FilenameTok.getLocation(); 10340b57cec5SDimitry Andric 10350b57cec5SDimitry Andric // FIXME: Provide code completion for #includes. 10360b57cec5SDimitry Andric if (FilenameTok.is(tok::code_completion)) { 10370b57cec5SDimitry Andric setCodeCompletionReached(); 10380b57cec5SDimitry Andric Lex(FilenameTok); 10390b57cec5SDimitry Andric continue; 10400b57cec5SDimitry Andric } 10410b57cec5SDimitry Andric 10420b57cec5SDimitry Andric // Append the spelling of this token to the buffer. If there was a space 10430b57cec5SDimitry Andric // before it, add it now. 10440b57cec5SDimitry Andric if (FilenameTok.hasLeadingSpace()) 10450b57cec5SDimitry Andric FilenameBuffer.push_back(' '); 10460b57cec5SDimitry Andric 10470b57cec5SDimitry Andric // Get the spelling of the token, directly into FilenameBuffer if 10480b57cec5SDimitry Andric // possible. 10490b57cec5SDimitry Andric size_t PreAppendSize = FilenameBuffer.size(); 10500b57cec5SDimitry Andric FilenameBuffer.resize(PreAppendSize + FilenameTok.getLength()); 10510b57cec5SDimitry Andric 10520b57cec5SDimitry Andric const char *BufPtr = &FilenameBuffer[PreAppendSize]; 10530b57cec5SDimitry Andric unsigned ActualLen = getSpelling(FilenameTok, BufPtr); 10540b57cec5SDimitry Andric 10550b57cec5SDimitry Andric // If the token was spelled somewhere else, copy it into FilenameBuffer. 10560b57cec5SDimitry Andric if (BufPtr != &FilenameBuffer[PreAppendSize]) 10570b57cec5SDimitry Andric memcpy(&FilenameBuffer[PreAppendSize], BufPtr, ActualLen); 10580b57cec5SDimitry Andric 10590b57cec5SDimitry Andric // Resize FilenameBuffer to the correct size. 10600b57cec5SDimitry Andric if (FilenameTok.getLength() != ActualLen) 10610b57cec5SDimitry Andric FilenameBuffer.resize(PreAppendSize + ActualLen); 10620b57cec5SDimitry Andric } 10630b57cec5SDimitry Andric 10640b57cec5SDimitry Andric FilenameTok.startToken(); 10650b57cec5SDimitry Andric FilenameTok.setKind(tok::header_name); 10660b57cec5SDimitry Andric FilenameTok.setFlagValue(Token::StartOfLine, StartOfLine); 10670b57cec5SDimitry Andric FilenameTok.setFlagValue(Token::LeadingSpace, LeadingSpace); 10680b57cec5SDimitry Andric FilenameTok.setFlagValue(Token::LeadingEmptyMacro, LeadingEmptyMacro); 10690b57cec5SDimitry Andric CreateString(FilenameBuffer, FilenameTok, Start, End); 10700b57cec5SDimitry Andric } else if (FilenameTok.is(tok::string_literal) && AllowMacroExpansion) { 10710b57cec5SDimitry Andric // Convert a string-literal token of the form " h-char-sequence " 10720b57cec5SDimitry Andric // (produced by macro expansion) into a header-name token. 10730b57cec5SDimitry Andric // 10740b57cec5SDimitry Andric // The rules for header-names don't quite match the rules for 10750b57cec5SDimitry Andric // string-literals, but all the places where they differ result in 10760b57cec5SDimitry Andric // undefined behavior, so we can and do treat them the same. 10770b57cec5SDimitry Andric // 10780b57cec5SDimitry Andric // A string-literal with a prefix or suffix is not translated into a 10790b57cec5SDimitry Andric // header-name. This could theoretically be observable via the C++20 10800b57cec5SDimitry Andric // context-sensitive header-name formation rules. 10810b57cec5SDimitry Andric StringRef Str = getSpelling(FilenameTok, FilenameBuffer); 10820b57cec5SDimitry Andric if (Str.size() >= 2 && Str.front() == '"' && Str.back() == '"') 10830b57cec5SDimitry Andric FilenameTok.setKind(tok::header_name); 10840b57cec5SDimitry Andric } 10850b57cec5SDimitry Andric 10860b57cec5SDimitry Andric return false; 10870b57cec5SDimitry Andric } 10880b57cec5SDimitry Andric 10890b57cec5SDimitry Andric /// Collect the tokens of a C++20 pp-import-suffix. 10900b57cec5SDimitry Andric void Preprocessor::CollectPpImportSuffix(SmallVectorImpl<Token> &Toks) { 10910b57cec5SDimitry Andric // FIXME: For error recovery, consider recognizing attribute syntax here 10920b57cec5SDimitry Andric // and terminating / diagnosing a missing semicolon if we find anything 10930b57cec5SDimitry Andric // else? (Can we leave that to the parser?) 10940b57cec5SDimitry Andric unsigned BracketDepth = 0; 10950b57cec5SDimitry Andric while (true) { 10960b57cec5SDimitry Andric Toks.emplace_back(); 10970b57cec5SDimitry Andric Lex(Toks.back()); 10980b57cec5SDimitry Andric 10990b57cec5SDimitry Andric switch (Toks.back().getKind()) { 11000b57cec5SDimitry Andric case tok::l_paren: case tok::l_square: case tok::l_brace: 11010b57cec5SDimitry Andric ++BracketDepth; 11020b57cec5SDimitry Andric break; 11030b57cec5SDimitry Andric 11040b57cec5SDimitry Andric case tok::r_paren: case tok::r_square: case tok::r_brace: 11050b57cec5SDimitry Andric if (BracketDepth == 0) 11060b57cec5SDimitry Andric return; 11070b57cec5SDimitry Andric --BracketDepth; 11080b57cec5SDimitry Andric break; 11090b57cec5SDimitry Andric 11100b57cec5SDimitry Andric case tok::semi: 11110b57cec5SDimitry Andric if (BracketDepth == 0) 11120b57cec5SDimitry Andric return; 11130b57cec5SDimitry Andric break; 11140b57cec5SDimitry Andric 11150b57cec5SDimitry Andric case tok::eof: 11160b57cec5SDimitry Andric return; 11170b57cec5SDimitry Andric 11180b57cec5SDimitry Andric default: 11190b57cec5SDimitry Andric break; 11200b57cec5SDimitry Andric } 11210b57cec5SDimitry Andric } 11220b57cec5SDimitry Andric } 11230b57cec5SDimitry Andric 11240b57cec5SDimitry Andric 11250b57cec5SDimitry Andric /// Lex a token following the 'import' contextual keyword. 11260b57cec5SDimitry Andric /// 11270b57cec5SDimitry Andric /// pp-import: [C++20] 11280b57cec5SDimitry Andric /// import header-name pp-import-suffix[opt] ; 11290b57cec5SDimitry Andric /// import header-name-tokens pp-import-suffix[opt] ; 11300b57cec5SDimitry Andric /// [ObjC] @ import module-name ; 11310b57cec5SDimitry Andric /// [Clang] import module-name ; 11320b57cec5SDimitry Andric /// 11330b57cec5SDimitry Andric /// header-name-tokens: 11340b57cec5SDimitry Andric /// string-literal 11350b57cec5SDimitry Andric /// < [any sequence of preprocessing-tokens other than >] > 11360b57cec5SDimitry Andric /// 11370b57cec5SDimitry Andric /// module-name: 11380b57cec5SDimitry Andric /// module-name-qualifier[opt] identifier 11390b57cec5SDimitry Andric /// 11400b57cec5SDimitry Andric /// module-name-qualifier 11410b57cec5SDimitry Andric /// module-name-qualifier[opt] identifier . 11420b57cec5SDimitry Andric /// 11430b57cec5SDimitry Andric /// We respond to a pp-import by importing macros from the named module. 11440b57cec5SDimitry Andric bool Preprocessor::LexAfterModuleImport(Token &Result) { 11450b57cec5SDimitry Andric // Figure out what kind of lexer we actually have. 11460b57cec5SDimitry Andric recomputeCurLexerKind(); 11470b57cec5SDimitry Andric 11480b57cec5SDimitry Andric // Lex the next token. The header-name lexing rules are used at the start of 11490b57cec5SDimitry Andric // a pp-import. 11500b57cec5SDimitry Andric // 11510b57cec5SDimitry Andric // For now, we only support header-name imports in C++20 mode. 11520b57cec5SDimitry Andric // FIXME: Should we allow this in all language modes that support an import 11530b57cec5SDimitry Andric // declaration as an extension? 1154bdd1243dSDimitry Andric if (NamedModuleImportPath.empty() && getLangOpts().CPlusPlusModules) { 11550b57cec5SDimitry Andric if (LexHeaderName(Result)) 11560b57cec5SDimitry Andric return true; 11571ac55f4cSDimitry Andric 11581ac55f4cSDimitry Andric if (Result.is(tok::colon) && ModuleDeclState.isNamedModule()) { 11591ac55f4cSDimitry Andric std::string Name = ModuleDeclState.getPrimaryName().str(); 11601ac55f4cSDimitry Andric Name += ":"; 11611ac55f4cSDimitry Andric NamedModuleImportPath.push_back( 11621ac55f4cSDimitry Andric {getIdentifierInfo(Name), Result.getLocation()}); 11635f757f3fSDimitry Andric CurLexerCallback = CLK_LexAfterModuleImport; 11641ac55f4cSDimitry Andric return true; 11651ac55f4cSDimitry Andric } 11660b57cec5SDimitry Andric } else { 11670b57cec5SDimitry Andric Lex(Result); 11680b57cec5SDimitry Andric } 11690b57cec5SDimitry Andric 11700b57cec5SDimitry Andric // Allocate a holding buffer for a sequence of tokens and introduce it into 11710b57cec5SDimitry Andric // the token stream. 11720b57cec5SDimitry Andric auto EnterTokens = [this](ArrayRef<Token> Toks) { 1173a7dea167SDimitry Andric auto ToksCopy = std::make_unique<Token[]>(Toks.size()); 11740b57cec5SDimitry Andric std::copy(Toks.begin(), Toks.end(), ToksCopy.get()); 11750b57cec5SDimitry Andric EnterTokenStream(std::move(ToksCopy), Toks.size(), 11760b57cec5SDimitry Andric /*DisableMacroExpansion*/ true, /*IsReinject*/ false); 11770b57cec5SDimitry Andric }; 11780b57cec5SDimitry Andric 11791ac55f4cSDimitry Andric bool ImportingHeader = Result.is(tok::header_name); 11800b57cec5SDimitry Andric // Check for a header-name. 11810b57cec5SDimitry Andric SmallVector<Token, 32> Suffix; 11821ac55f4cSDimitry Andric if (ImportingHeader) { 11830b57cec5SDimitry Andric // Enter the header-name token into the token stream; a Lex action cannot 11840b57cec5SDimitry Andric // both return a token and cache tokens (doing so would corrupt the token 11850b57cec5SDimitry Andric // cache if the call to Lex comes from CachingLex / PeekAhead). 11860b57cec5SDimitry Andric Suffix.push_back(Result); 11870b57cec5SDimitry Andric 11880b57cec5SDimitry Andric // Consume the pp-import-suffix and expand any macros in it now. We'll add 11890b57cec5SDimitry Andric // it back into the token stream later. 11900b57cec5SDimitry Andric CollectPpImportSuffix(Suffix); 11910b57cec5SDimitry Andric if (Suffix.back().isNot(tok::semi)) { 11920b57cec5SDimitry Andric // This is not a pp-import after all. 11930b57cec5SDimitry Andric EnterTokens(Suffix); 11940b57cec5SDimitry Andric return false; 11950b57cec5SDimitry Andric } 11960b57cec5SDimitry Andric 11970b57cec5SDimitry Andric // C++2a [cpp.module]p1: 11980b57cec5SDimitry Andric // The ';' preprocessing-token terminating a pp-import shall not have 11990b57cec5SDimitry Andric // been produced by macro replacement. 12000b57cec5SDimitry Andric SourceLocation SemiLoc = Suffix.back().getLocation(); 12010b57cec5SDimitry Andric if (SemiLoc.isMacroID()) 12020b57cec5SDimitry Andric Diag(SemiLoc, diag::err_header_import_semi_in_macro); 12030b57cec5SDimitry Andric 12040b57cec5SDimitry Andric // Reconstitute the import token. 12050b57cec5SDimitry Andric Token ImportTok; 12060b57cec5SDimitry Andric ImportTok.startToken(); 12070b57cec5SDimitry Andric ImportTok.setKind(tok::kw_import); 12080b57cec5SDimitry Andric ImportTok.setLocation(ModuleImportLoc); 12090b57cec5SDimitry Andric ImportTok.setIdentifierInfo(getIdentifierInfo("import")); 12100b57cec5SDimitry Andric ImportTok.setLength(6); 12110b57cec5SDimitry Andric 12120b57cec5SDimitry Andric auto Action = HandleHeaderIncludeOrImport( 12130b57cec5SDimitry Andric /*HashLoc*/ SourceLocation(), ImportTok, Suffix.front(), SemiLoc); 12140b57cec5SDimitry Andric switch (Action.Kind) { 12150b57cec5SDimitry Andric case ImportAction::None: 12160b57cec5SDimitry Andric break; 12170b57cec5SDimitry Andric 12180b57cec5SDimitry Andric case ImportAction::ModuleBegin: 12190b57cec5SDimitry Andric // Let the parser know we're textually entering the module. 12200b57cec5SDimitry Andric Suffix.emplace_back(); 12210b57cec5SDimitry Andric Suffix.back().startToken(); 12220b57cec5SDimitry Andric Suffix.back().setKind(tok::annot_module_begin); 12230b57cec5SDimitry Andric Suffix.back().setLocation(SemiLoc); 12240b57cec5SDimitry Andric Suffix.back().setAnnotationEndLoc(SemiLoc); 12250b57cec5SDimitry Andric Suffix.back().setAnnotationValue(Action.ModuleForHeader); 1226bdd1243dSDimitry Andric [[fallthrough]]; 12270b57cec5SDimitry Andric 12280b57cec5SDimitry Andric case ImportAction::ModuleImport: 1229753f127fSDimitry Andric case ImportAction::HeaderUnitImport: 12300b57cec5SDimitry Andric case ImportAction::SkippedModuleImport: 12310b57cec5SDimitry Andric // We chose to import (or textually enter) the file. Convert the 12320b57cec5SDimitry Andric // header-name token into a header unit annotation token. 12330b57cec5SDimitry Andric Suffix[0].setKind(tok::annot_header_unit); 12340b57cec5SDimitry Andric Suffix[0].setAnnotationEndLoc(Suffix[0].getLocation()); 12350b57cec5SDimitry Andric Suffix[0].setAnnotationValue(Action.ModuleForHeader); 12360b57cec5SDimitry Andric // FIXME: Call the moduleImport callback? 12370b57cec5SDimitry Andric break; 12385ffd83dbSDimitry Andric case ImportAction::Failure: 12395ffd83dbSDimitry Andric assert(TheModuleLoader.HadFatalFailure && 12405ffd83dbSDimitry Andric "This should be an early exit only to a fatal error"); 12415ffd83dbSDimitry Andric Result.setKind(tok::eof); 12425ffd83dbSDimitry Andric CurLexer->cutOffLexing(); 12435ffd83dbSDimitry Andric EnterTokens(Suffix); 12445ffd83dbSDimitry Andric return true; 12450b57cec5SDimitry Andric } 12460b57cec5SDimitry Andric 12470b57cec5SDimitry Andric EnterTokens(Suffix); 12480b57cec5SDimitry Andric return false; 12490b57cec5SDimitry Andric } 12500b57cec5SDimitry Andric 12510b57cec5SDimitry Andric // The token sequence 12520b57cec5SDimitry Andric // 12530b57cec5SDimitry Andric // import identifier (. identifier)* 12540b57cec5SDimitry Andric // 12550b57cec5SDimitry Andric // indicates a module import directive. We already saw the 'import' 12560b57cec5SDimitry Andric // contextual keyword, so now we're looking for the identifiers. 12570b57cec5SDimitry Andric if (ModuleImportExpectsIdentifier && Result.getKind() == tok::identifier) { 12580b57cec5SDimitry Andric // We expected to see an identifier here, and we did; continue handling 12590b57cec5SDimitry Andric // identifiers. 12601ac55f4cSDimitry Andric NamedModuleImportPath.push_back( 12611ac55f4cSDimitry Andric std::make_pair(Result.getIdentifierInfo(), Result.getLocation())); 12620b57cec5SDimitry Andric ModuleImportExpectsIdentifier = false; 12635f757f3fSDimitry Andric CurLexerCallback = CLK_LexAfterModuleImport; 12640b57cec5SDimitry Andric return true; 12650b57cec5SDimitry Andric } 12660b57cec5SDimitry Andric 12670b57cec5SDimitry Andric // If we're expecting a '.' or a ';', and we got a '.', then wait until we 12680b57cec5SDimitry Andric // see the next identifier. (We can also see a '[[' that begins an 126906c3fb27SDimitry Andric // attribute-specifier-seq here under the Standard C++ Modules.) 12700b57cec5SDimitry Andric if (!ModuleImportExpectsIdentifier && Result.getKind() == tok::period) { 12710b57cec5SDimitry Andric ModuleImportExpectsIdentifier = true; 12725f757f3fSDimitry Andric CurLexerCallback = CLK_LexAfterModuleImport; 12730b57cec5SDimitry Andric return true; 12740b57cec5SDimitry Andric } 12750b57cec5SDimitry Andric 12760b57cec5SDimitry Andric // If we didn't recognize a module name at all, this is not a (valid) import. 1277bdd1243dSDimitry Andric if (NamedModuleImportPath.empty() || Result.is(tok::eof)) 12780b57cec5SDimitry Andric return true; 12790b57cec5SDimitry Andric 12800b57cec5SDimitry Andric // Consume the pp-import-suffix and expand any macros in it now, if we're not 12810b57cec5SDimitry Andric // at the semicolon already. 12820b57cec5SDimitry Andric SourceLocation SemiLoc = Result.getLocation(); 12830b57cec5SDimitry Andric if (Result.isNot(tok::semi)) { 12840b57cec5SDimitry Andric Suffix.push_back(Result); 12850b57cec5SDimitry Andric CollectPpImportSuffix(Suffix); 12860b57cec5SDimitry Andric if (Suffix.back().isNot(tok::semi)) { 12870b57cec5SDimitry Andric // This is not an import after all. 12880b57cec5SDimitry Andric EnterTokens(Suffix); 12890b57cec5SDimitry Andric return false; 12900b57cec5SDimitry Andric } 12910b57cec5SDimitry Andric SemiLoc = Suffix.back().getLocation(); 12920b57cec5SDimitry Andric } 12930b57cec5SDimitry Andric 129406c3fb27SDimitry Andric // Under the standard C++ Modules, the dot is just part of the module name, 129506c3fb27SDimitry Andric // and not a real hierarchy separator. Flatten such module names now. 12960b57cec5SDimitry Andric // 12970b57cec5SDimitry Andric // FIXME: Is this the right level to be performing this transformation? 12980b57cec5SDimitry Andric std::string FlatModuleName; 129906c3fb27SDimitry Andric if (getLangOpts().CPlusPlusModules) { 1300bdd1243dSDimitry Andric for (auto &Piece : NamedModuleImportPath) { 13011ac55f4cSDimitry Andric // If the FlatModuleName ends with colon, it implies it is a partition. 13021ac55f4cSDimitry Andric if (!FlatModuleName.empty() && FlatModuleName.back() != ':') 13030b57cec5SDimitry Andric FlatModuleName += "."; 13040b57cec5SDimitry Andric FlatModuleName += Piece.first->getName(); 13050b57cec5SDimitry Andric } 1306bdd1243dSDimitry Andric SourceLocation FirstPathLoc = NamedModuleImportPath[0].second; 1307bdd1243dSDimitry Andric NamedModuleImportPath.clear(); 1308bdd1243dSDimitry Andric NamedModuleImportPath.push_back( 13090b57cec5SDimitry Andric std::make_pair(getIdentifierInfo(FlatModuleName), FirstPathLoc)); 13100b57cec5SDimitry Andric } 13110b57cec5SDimitry Andric 13120b57cec5SDimitry Andric Module *Imported = nullptr; 13131ac55f4cSDimitry Andric // We don't/shouldn't load the standard c++20 modules when preprocessing. 13141ac55f4cSDimitry Andric if (getLangOpts().Modules && !isInImportingCXXNamedModules()) { 13150b57cec5SDimitry Andric Imported = TheModuleLoader.loadModule(ModuleImportLoc, 1316bdd1243dSDimitry Andric NamedModuleImportPath, 13170b57cec5SDimitry Andric Module::Hidden, 13180b57cec5SDimitry Andric /*IsInclusionDirective=*/false); 13190b57cec5SDimitry Andric if (Imported) 13200b57cec5SDimitry Andric makeModuleVisible(Imported, SemiLoc); 13210b57cec5SDimitry Andric } 13221ac55f4cSDimitry Andric 13230b57cec5SDimitry Andric if (Callbacks) 1324bdd1243dSDimitry Andric Callbacks->moduleImport(ModuleImportLoc, NamedModuleImportPath, Imported); 13250b57cec5SDimitry Andric 13260b57cec5SDimitry Andric if (!Suffix.empty()) { 13270b57cec5SDimitry Andric EnterTokens(Suffix); 13280b57cec5SDimitry Andric return false; 13290b57cec5SDimitry Andric } 13300b57cec5SDimitry Andric return true; 13310b57cec5SDimitry Andric } 13320b57cec5SDimitry Andric 13330b57cec5SDimitry Andric void Preprocessor::makeModuleVisible(Module *M, SourceLocation Loc) { 13340b57cec5SDimitry Andric CurSubmoduleState->VisibleModules.setVisible( 13350b57cec5SDimitry Andric M, Loc, [](Module *) {}, 13360b57cec5SDimitry Andric [&](ArrayRef<Module *> Path, Module *Conflict, StringRef Message) { 13370b57cec5SDimitry Andric // FIXME: Include the path in the diagnostic. 13380b57cec5SDimitry Andric // FIXME: Include the import location for the conflicting module. 13390b57cec5SDimitry Andric Diag(ModuleImportLoc, diag::warn_module_conflict) 13400b57cec5SDimitry Andric << Path[0]->getFullModuleName() 13410b57cec5SDimitry Andric << Conflict->getFullModuleName() 13420b57cec5SDimitry Andric << Message; 13430b57cec5SDimitry Andric }); 13440b57cec5SDimitry Andric 13450b57cec5SDimitry Andric // Add this module to the imports list of the currently-built submodule. 13460b57cec5SDimitry Andric if (!BuildingSubmoduleStack.empty() && M != BuildingSubmoduleStack.back().M) 13470b57cec5SDimitry Andric BuildingSubmoduleStack.back().M->Imports.insert(M); 13480b57cec5SDimitry Andric } 13490b57cec5SDimitry Andric 13500b57cec5SDimitry Andric bool Preprocessor::FinishLexStringLiteral(Token &Result, std::string &String, 13510b57cec5SDimitry Andric const char *DiagnosticTag, 13520b57cec5SDimitry Andric bool AllowMacroExpansion) { 13530b57cec5SDimitry Andric // We need at least one string literal. 13540b57cec5SDimitry Andric if (Result.isNot(tok::string_literal)) { 13550b57cec5SDimitry Andric Diag(Result, diag::err_expected_string_literal) 13560b57cec5SDimitry Andric << /*Source='in...'*/0 << DiagnosticTag; 13570b57cec5SDimitry Andric return false; 13580b57cec5SDimitry Andric } 13590b57cec5SDimitry Andric 13600b57cec5SDimitry Andric // Lex string literal tokens, optionally with macro expansion. 13610b57cec5SDimitry Andric SmallVector<Token, 4> StrToks; 13620b57cec5SDimitry Andric do { 13630b57cec5SDimitry Andric StrToks.push_back(Result); 13640b57cec5SDimitry Andric 13650b57cec5SDimitry Andric if (Result.hasUDSuffix()) 13660b57cec5SDimitry Andric Diag(Result, diag::err_invalid_string_udl); 13670b57cec5SDimitry Andric 13680b57cec5SDimitry Andric if (AllowMacroExpansion) 13690b57cec5SDimitry Andric Lex(Result); 13700b57cec5SDimitry Andric else 13710b57cec5SDimitry Andric LexUnexpandedToken(Result); 13720b57cec5SDimitry Andric } while (Result.is(tok::string_literal)); 13730b57cec5SDimitry Andric 13740b57cec5SDimitry Andric // Concatenate and parse the strings. 13750b57cec5SDimitry Andric StringLiteralParser Literal(StrToks, *this); 137681ad6265SDimitry Andric assert(Literal.isOrdinary() && "Didn't allow wide strings in"); 13770b57cec5SDimitry Andric 13780b57cec5SDimitry Andric if (Literal.hadError) 13790b57cec5SDimitry Andric return false; 13800b57cec5SDimitry Andric 13810b57cec5SDimitry Andric if (Literal.Pascal) { 13820b57cec5SDimitry Andric Diag(StrToks[0].getLocation(), diag::err_expected_string_literal) 13830b57cec5SDimitry Andric << /*Source='in...'*/0 << DiagnosticTag; 13840b57cec5SDimitry Andric return false; 13850b57cec5SDimitry Andric } 13860b57cec5SDimitry Andric 13875ffd83dbSDimitry Andric String = std::string(Literal.GetString()); 13880b57cec5SDimitry Andric return true; 13890b57cec5SDimitry Andric } 13900b57cec5SDimitry Andric 13910b57cec5SDimitry Andric bool Preprocessor::parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value) { 13920b57cec5SDimitry Andric assert(Tok.is(tok::numeric_constant)); 13930b57cec5SDimitry Andric SmallString<8> IntegerBuffer; 13940b57cec5SDimitry Andric bool NumberInvalid = false; 13950b57cec5SDimitry Andric StringRef Spelling = getSpelling(Tok, IntegerBuffer, &NumberInvalid); 13960b57cec5SDimitry Andric if (NumberInvalid) 13970b57cec5SDimitry Andric return false; 13985ffd83dbSDimitry Andric NumericLiteralParser Literal(Spelling, Tok.getLocation(), getSourceManager(), 13995ffd83dbSDimitry Andric getLangOpts(), getTargetInfo(), 14005ffd83dbSDimitry Andric getDiagnostics()); 14010b57cec5SDimitry Andric if (Literal.hadError || !Literal.isIntegerLiteral() || Literal.hasUDSuffix()) 14020b57cec5SDimitry Andric return false; 14030b57cec5SDimitry Andric llvm::APInt APVal(64, 0); 14040b57cec5SDimitry Andric if (Literal.GetIntegerValue(APVal)) 14050b57cec5SDimitry Andric return false; 14060b57cec5SDimitry Andric Lex(Tok); 14070b57cec5SDimitry Andric Value = APVal.getLimitedValue(); 14080b57cec5SDimitry Andric return true; 14090b57cec5SDimitry Andric } 14100b57cec5SDimitry Andric 14110b57cec5SDimitry Andric void Preprocessor::addCommentHandler(CommentHandler *Handler) { 14120b57cec5SDimitry Andric assert(Handler && "NULL comment handler"); 1413349cc55cSDimitry Andric assert(!llvm::is_contained(CommentHandlers, Handler) && 14140b57cec5SDimitry Andric "Comment handler already registered"); 14150b57cec5SDimitry Andric CommentHandlers.push_back(Handler); 14160b57cec5SDimitry Andric } 14170b57cec5SDimitry Andric 14180b57cec5SDimitry Andric void Preprocessor::removeCommentHandler(CommentHandler *Handler) { 14190b57cec5SDimitry Andric std::vector<CommentHandler *>::iterator Pos = 14200b57cec5SDimitry Andric llvm::find(CommentHandlers, Handler); 14210b57cec5SDimitry Andric assert(Pos != CommentHandlers.end() && "Comment handler not registered"); 14220b57cec5SDimitry Andric CommentHandlers.erase(Pos); 14230b57cec5SDimitry Andric } 14240b57cec5SDimitry Andric 14250b57cec5SDimitry Andric bool Preprocessor::HandleComment(Token &result, SourceRange Comment) { 14260b57cec5SDimitry Andric bool AnyPendingTokens = false; 14270b57cec5SDimitry Andric for (std::vector<CommentHandler *>::iterator H = CommentHandlers.begin(), 14280b57cec5SDimitry Andric HEnd = CommentHandlers.end(); 14290b57cec5SDimitry Andric H != HEnd; ++H) { 14300b57cec5SDimitry Andric if ((*H)->HandleComment(*this, Comment)) 14310b57cec5SDimitry Andric AnyPendingTokens = true; 14320b57cec5SDimitry Andric } 14330b57cec5SDimitry Andric if (!AnyPendingTokens || getCommentRetentionState()) 14340b57cec5SDimitry Andric return false; 14350b57cec5SDimitry Andric Lex(result); 14360b57cec5SDimitry Andric return true; 14370b57cec5SDimitry Andric } 14380b57cec5SDimitry Andric 1439349cc55cSDimitry Andric void Preprocessor::emitMacroDeprecationWarning(const Token &Identifier) const { 1440349cc55cSDimitry Andric const MacroAnnotations &A = 1441349cc55cSDimitry Andric getMacroAnnotations(Identifier.getIdentifierInfo()); 1442349cc55cSDimitry Andric assert(A.DeprecationInfo && 1443349cc55cSDimitry Andric "Macro deprecation warning without recorded annotation!"); 1444349cc55cSDimitry Andric const MacroAnnotationInfo &Info = *A.DeprecationInfo; 1445349cc55cSDimitry Andric if (Info.Message.empty()) 1446349cc55cSDimitry Andric Diag(Identifier, diag::warn_pragma_deprecated_macro_use) 1447349cc55cSDimitry Andric << Identifier.getIdentifierInfo() << 0; 1448349cc55cSDimitry Andric else 1449349cc55cSDimitry Andric Diag(Identifier, diag::warn_pragma_deprecated_macro_use) 1450349cc55cSDimitry Andric << Identifier.getIdentifierInfo() << 1 << Info.Message; 1451349cc55cSDimitry Andric Diag(Info.Location, diag::note_pp_macro_annotation) << 0; 1452349cc55cSDimitry Andric } 1453349cc55cSDimitry Andric 1454349cc55cSDimitry Andric void Preprocessor::emitRestrictExpansionWarning(const Token &Identifier) const { 1455349cc55cSDimitry Andric const MacroAnnotations &A = 1456349cc55cSDimitry Andric getMacroAnnotations(Identifier.getIdentifierInfo()); 1457349cc55cSDimitry Andric assert(A.RestrictExpansionInfo && 1458349cc55cSDimitry Andric "Macro restricted expansion warning without recorded annotation!"); 1459349cc55cSDimitry Andric const MacroAnnotationInfo &Info = *A.RestrictExpansionInfo; 1460349cc55cSDimitry Andric if (Info.Message.empty()) 1461349cc55cSDimitry Andric Diag(Identifier, diag::warn_pragma_restrict_expansion_macro_use) 1462349cc55cSDimitry Andric << Identifier.getIdentifierInfo() << 0; 1463349cc55cSDimitry Andric else 1464349cc55cSDimitry Andric Diag(Identifier, diag::warn_pragma_restrict_expansion_macro_use) 1465349cc55cSDimitry Andric << Identifier.getIdentifierInfo() << 1 << Info.Message; 1466349cc55cSDimitry Andric Diag(Info.Location, diag::note_pp_macro_annotation) << 1; 1467349cc55cSDimitry Andric } 1468349cc55cSDimitry Andric 14697a6dacacSDimitry Andric void Preprocessor::emitRestrictInfNaNWarning(const Token &Identifier, 14707a6dacacSDimitry Andric unsigned DiagSelection) const { 14717a6dacacSDimitry Andric Diag(Identifier, diag::warn_fp_nan_inf_when_disabled) << DiagSelection << 1; 14727a6dacacSDimitry Andric } 14737a6dacacSDimitry Andric 1474349cc55cSDimitry Andric void Preprocessor::emitFinalMacroWarning(const Token &Identifier, 1475349cc55cSDimitry Andric bool IsUndef) const { 1476349cc55cSDimitry Andric const MacroAnnotations &A = 1477349cc55cSDimitry Andric getMacroAnnotations(Identifier.getIdentifierInfo()); 1478349cc55cSDimitry Andric assert(A.FinalAnnotationLoc && 1479349cc55cSDimitry Andric "Final macro warning without recorded annotation!"); 1480349cc55cSDimitry Andric 1481349cc55cSDimitry Andric Diag(Identifier, diag::warn_pragma_final_macro) 1482349cc55cSDimitry Andric << Identifier.getIdentifierInfo() << (IsUndef ? 0 : 1); 1483349cc55cSDimitry Andric Diag(*A.FinalAnnotationLoc, diag::note_pp_macro_annotation) << 2; 1484349cc55cSDimitry Andric } 1485349cc55cSDimitry Andric 148606c3fb27SDimitry Andric bool Preprocessor::isSafeBufferOptOut(const SourceManager &SourceMgr, 148706c3fb27SDimitry Andric const SourceLocation &Loc) const { 1488*0fca6ea1SDimitry Andric // The lambda that tests if a `Loc` is in an opt-out region given one opt-out 1489*0fca6ea1SDimitry Andric // region map: 1490*0fca6ea1SDimitry Andric auto TestInMap = [&SourceMgr](const SafeBufferOptOutRegionsTy &Map, 1491*0fca6ea1SDimitry Andric const SourceLocation &Loc) -> bool { 149206c3fb27SDimitry Andric // Try to find a region in `SafeBufferOptOutMap` where `Loc` is in: 149306c3fb27SDimitry Andric auto FirstRegionEndingAfterLoc = llvm::partition_point( 1494*0fca6ea1SDimitry Andric Map, [&SourceMgr, 149506c3fb27SDimitry Andric &Loc](const std::pair<SourceLocation, SourceLocation> &Region) { 149606c3fb27SDimitry Andric return SourceMgr.isBeforeInTranslationUnit(Region.second, Loc); 149706c3fb27SDimitry Andric }); 149806c3fb27SDimitry Andric 1499*0fca6ea1SDimitry Andric if (FirstRegionEndingAfterLoc != Map.end()) { 150006c3fb27SDimitry Andric // To test if the start location of the found region precedes `Loc`: 1501*0fca6ea1SDimitry Andric return SourceMgr.isBeforeInTranslationUnit( 1502*0fca6ea1SDimitry Andric FirstRegionEndingAfterLoc->first, Loc); 150306c3fb27SDimitry Andric } 150406c3fb27SDimitry Andric // If we do not find a region whose end location passes `Loc`, we want to 150506c3fb27SDimitry Andric // check if the current region is still open: 1506*0fca6ea1SDimitry Andric if (!Map.empty() && Map.back().first == Map.back().second) 1507*0fca6ea1SDimitry Andric return SourceMgr.isBeforeInTranslationUnit(Map.back().first, Loc); 1508*0fca6ea1SDimitry Andric return false; 1509*0fca6ea1SDimitry Andric }; 1510*0fca6ea1SDimitry Andric 1511*0fca6ea1SDimitry Andric // What the following does: 1512*0fca6ea1SDimitry Andric // 1513*0fca6ea1SDimitry Andric // If `Loc` belongs to the local TU, we just look up `SafeBufferOptOutMap`. 1514*0fca6ea1SDimitry Andric // Otherwise, `Loc` is from a loaded AST. We look up the 1515*0fca6ea1SDimitry Andric // `LoadedSafeBufferOptOutMap` first to get the opt-out region map of the 1516*0fca6ea1SDimitry Andric // loaded AST where `Loc` is at. Then we find if `Loc` is in an opt-out 1517*0fca6ea1SDimitry Andric // region w.r.t. the region map. If the region map is absent, it means there 1518*0fca6ea1SDimitry Andric // is no opt-out pragma in that loaded AST. 1519*0fca6ea1SDimitry Andric // 1520*0fca6ea1SDimitry Andric // Opt-out pragmas in the local TU or a loaded AST is not visible to another 1521*0fca6ea1SDimitry Andric // one of them. That means if you put the pragmas around a `#include 1522*0fca6ea1SDimitry Andric // "module.h"`, where module.h is a module, it is not actually suppressing 1523*0fca6ea1SDimitry Andric // warnings in module.h. This is fine because warnings in module.h will be 1524*0fca6ea1SDimitry Andric // reported when module.h is compiled in isolation and nothing in module.h 1525*0fca6ea1SDimitry Andric // will be analyzed ever again. So you will not see warnings from the file 1526*0fca6ea1SDimitry Andric // that imports module.h anyway. And you can't even do the same thing for PCHs 1527*0fca6ea1SDimitry Andric // because they can only be included from the command line. 1528*0fca6ea1SDimitry Andric 1529*0fca6ea1SDimitry Andric if (SourceMgr.isLocalSourceLocation(Loc)) 1530*0fca6ea1SDimitry Andric return TestInMap(SafeBufferOptOutMap, Loc); 1531*0fca6ea1SDimitry Andric 1532*0fca6ea1SDimitry Andric const SafeBufferOptOutRegionsTy *LoadedRegions = 1533*0fca6ea1SDimitry Andric LoadedSafeBufferOptOutMap.lookupLoadedOptOutMap(Loc, SourceMgr); 1534*0fca6ea1SDimitry Andric 1535*0fca6ea1SDimitry Andric if (LoadedRegions) 1536*0fca6ea1SDimitry Andric return TestInMap(*LoadedRegions, Loc); 153706c3fb27SDimitry Andric return false; 153806c3fb27SDimitry Andric } 153906c3fb27SDimitry Andric 154006c3fb27SDimitry Andric bool Preprocessor::enterOrExitSafeBufferOptOutRegion( 154106c3fb27SDimitry Andric bool isEnter, const SourceLocation &Loc) { 154206c3fb27SDimitry Andric if (isEnter) { 154306c3fb27SDimitry Andric if (isPPInSafeBufferOptOutRegion()) 154406c3fb27SDimitry Andric return true; // invalid enter action 154506c3fb27SDimitry Andric InSafeBufferOptOutRegion = true; 154606c3fb27SDimitry Andric CurrentSafeBufferOptOutStart = Loc; 154706c3fb27SDimitry Andric 154806c3fb27SDimitry Andric // To set the start location of a new region: 154906c3fb27SDimitry Andric 155006c3fb27SDimitry Andric if (!SafeBufferOptOutMap.empty()) { 155106c3fb27SDimitry Andric [[maybe_unused]] auto *PrevRegion = &SafeBufferOptOutMap.back(); 155206c3fb27SDimitry Andric assert(PrevRegion->first != PrevRegion->second && 155306c3fb27SDimitry Andric "Shall not begin a safe buffer opt-out region before closing the " 155406c3fb27SDimitry Andric "previous one."); 155506c3fb27SDimitry Andric } 155606c3fb27SDimitry Andric // If the start location equals to the end location, we call the region a 155706c3fb27SDimitry Andric // open region or a unclosed region (i.e., end location has not been set 155806c3fb27SDimitry Andric // yet). 155906c3fb27SDimitry Andric SafeBufferOptOutMap.emplace_back(Loc, Loc); 156006c3fb27SDimitry Andric } else { 156106c3fb27SDimitry Andric if (!isPPInSafeBufferOptOutRegion()) 156206c3fb27SDimitry Andric return true; // invalid enter action 156306c3fb27SDimitry Andric InSafeBufferOptOutRegion = false; 156406c3fb27SDimitry Andric 156506c3fb27SDimitry Andric // To set the end location of the current open region: 156606c3fb27SDimitry Andric 156706c3fb27SDimitry Andric assert(!SafeBufferOptOutMap.empty() && 156806c3fb27SDimitry Andric "Misordered safe buffer opt-out regions"); 156906c3fb27SDimitry Andric auto *CurrRegion = &SafeBufferOptOutMap.back(); 157006c3fb27SDimitry Andric assert(CurrRegion->first == CurrRegion->second && 157106c3fb27SDimitry Andric "Set end location to a closed safe buffer opt-out region"); 157206c3fb27SDimitry Andric CurrRegion->second = Loc; 157306c3fb27SDimitry Andric } 157406c3fb27SDimitry Andric return false; 157506c3fb27SDimitry Andric } 157606c3fb27SDimitry Andric 157706c3fb27SDimitry Andric bool Preprocessor::isPPInSafeBufferOptOutRegion() { 157806c3fb27SDimitry Andric return InSafeBufferOptOutRegion; 157906c3fb27SDimitry Andric } 158006c3fb27SDimitry Andric bool Preprocessor::isPPInSafeBufferOptOutRegion(SourceLocation &StartLoc) { 158106c3fb27SDimitry Andric StartLoc = CurrentSafeBufferOptOutStart; 158206c3fb27SDimitry Andric return InSafeBufferOptOutRegion; 158306c3fb27SDimitry Andric } 158406c3fb27SDimitry Andric 1585*0fca6ea1SDimitry Andric SmallVector<SourceLocation, 64> 1586*0fca6ea1SDimitry Andric Preprocessor::serializeSafeBufferOptOutMap() const { 1587*0fca6ea1SDimitry Andric assert(!InSafeBufferOptOutRegion && 1588*0fca6ea1SDimitry Andric "Attempt to serialize safe buffer opt-out regions before file being " 1589*0fca6ea1SDimitry Andric "completely preprocessed"); 1590*0fca6ea1SDimitry Andric 1591*0fca6ea1SDimitry Andric SmallVector<SourceLocation, 64> SrcSeq; 1592*0fca6ea1SDimitry Andric 1593*0fca6ea1SDimitry Andric for (const auto &[begin, end] : SafeBufferOptOutMap) { 1594*0fca6ea1SDimitry Andric SrcSeq.push_back(begin); 1595*0fca6ea1SDimitry Andric SrcSeq.push_back(end); 1596*0fca6ea1SDimitry Andric } 1597*0fca6ea1SDimitry Andric // Only `SafeBufferOptOutMap` gets serialized. No need to serialize 1598*0fca6ea1SDimitry Andric // `LoadedSafeBufferOptOutMap` because if this TU loads a pch/module, every 1599*0fca6ea1SDimitry Andric // pch/module in the pch-chain/module-DAG will be loaded one by one in order. 1600*0fca6ea1SDimitry Andric // It means that for each loading pch/module m, it just needs to load m's own 1601*0fca6ea1SDimitry Andric // `SafeBufferOptOutMap`. 1602*0fca6ea1SDimitry Andric return SrcSeq; 1603*0fca6ea1SDimitry Andric } 1604*0fca6ea1SDimitry Andric 1605*0fca6ea1SDimitry Andric bool Preprocessor::setDeserializedSafeBufferOptOutMap( 1606*0fca6ea1SDimitry Andric const SmallVectorImpl<SourceLocation> &SourceLocations) { 1607*0fca6ea1SDimitry Andric if (SourceLocations.size() == 0) 1608*0fca6ea1SDimitry Andric return false; 1609*0fca6ea1SDimitry Andric 1610*0fca6ea1SDimitry Andric assert(SourceLocations.size() % 2 == 0 && 1611*0fca6ea1SDimitry Andric "ill-formed SourceLocation sequence"); 1612*0fca6ea1SDimitry Andric 1613*0fca6ea1SDimitry Andric auto It = SourceLocations.begin(); 1614*0fca6ea1SDimitry Andric SafeBufferOptOutRegionsTy &Regions = 1615*0fca6ea1SDimitry Andric LoadedSafeBufferOptOutMap.findAndConsLoadedOptOutMap(*It, SourceMgr); 1616*0fca6ea1SDimitry Andric 1617*0fca6ea1SDimitry Andric do { 1618*0fca6ea1SDimitry Andric SourceLocation Begin = *It++; 1619*0fca6ea1SDimitry Andric SourceLocation End = *It++; 1620*0fca6ea1SDimitry Andric 1621*0fca6ea1SDimitry Andric Regions.emplace_back(Begin, End); 1622*0fca6ea1SDimitry Andric } while (It != SourceLocations.end()); 1623*0fca6ea1SDimitry Andric return true; 1624*0fca6ea1SDimitry Andric } 1625*0fca6ea1SDimitry Andric 16260b57cec5SDimitry Andric ModuleLoader::~ModuleLoader() = default; 16270b57cec5SDimitry Andric 16280b57cec5SDimitry Andric CommentHandler::~CommentHandler() = default; 16290b57cec5SDimitry Andric 1630e8d8bef9SDimitry Andric EmptylineHandler::~EmptylineHandler() = default; 1631e8d8bef9SDimitry Andric 16320b57cec5SDimitry Andric CodeCompletionHandler::~CodeCompletionHandler() = default; 16330b57cec5SDimitry Andric 16340b57cec5SDimitry Andric void Preprocessor::createPreprocessingRecord() { 16350b57cec5SDimitry Andric if (Record) 16360b57cec5SDimitry Andric return; 16370b57cec5SDimitry Andric 16380b57cec5SDimitry Andric Record = new PreprocessingRecord(getSourceManager()); 16390b57cec5SDimitry Andric addPPCallbacks(std::unique_ptr<PPCallbacks>(Record)); 16400b57cec5SDimitry Andric } 1641*0fca6ea1SDimitry Andric 1642*0fca6ea1SDimitry Andric const char *Preprocessor::getCheckPoint(FileID FID, const char *Start) const { 1643*0fca6ea1SDimitry Andric if (auto It = CheckPoints.find(FID); It != CheckPoints.end()) { 1644*0fca6ea1SDimitry Andric const SmallVector<const char *> &FileCheckPoints = It->second; 1645*0fca6ea1SDimitry Andric const char *Last = nullptr; 1646*0fca6ea1SDimitry Andric // FIXME: Do better than a linear search. 1647*0fca6ea1SDimitry Andric for (const char *P : FileCheckPoints) { 1648*0fca6ea1SDimitry Andric if (P > Start) 1649*0fca6ea1SDimitry Andric break; 1650*0fca6ea1SDimitry Andric Last = P; 1651*0fca6ea1SDimitry Andric } 1652*0fca6ea1SDimitry Andric return Last; 1653*0fca6ea1SDimitry Andric } 1654*0fca6ea1SDimitry Andric 1655*0fca6ea1SDimitry Andric return nullptr; 1656*0fca6ea1SDimitry Andric } 1657