static unsigned getCallEditDistance(DeclName writtenName, DeclName correctedName, unsigned maxEditDistance) { // TODO: consider arguments. // TODO: maybe ignore certain kinds of missing / present labels for the // first argument label? // TODO: word-based rather than character-based? if (writtenName.getBaseName().getKind() != correctedName.getBaseName().getKind()) { return UnreasonableCallEditDistance; } if (writtenName.getBaseName().getKind() != DeclBaseName::Kind::Normal) { return 0; } StringRef writtenBase = writtenName.getBaseName().userFacingName(); StringRef correctedBase = correctedName.getBaseName().userFacingName(); unsigned distance = writtenBase.edit_distance(correctedBase, maxEditDistance); // Bound the distance to UnreasonableCallEditDistance. if (distance >= maxEditDistance || distance > (correctedBase.size() + 2) / 3) { return UnreasonableCallEditDistance; } return distance; }
unsigned Pattern::ComputeMatchDistance(StringRef Buffer, const StringMap<StringRef> &VariableTable) const { // Just compute the number of matching characters. For regular expressions, we // just compare against the regex itself and hope for the best. // // FIXME: One easy improvement here is have the regex lib generate a single // example regular expression which matches, and use that as the example // string. StringRef ExampleString(FixedStr); if (ExampleString.empty()) ExampleString = RegExStr; // Only compare up to the first line in the buffer, or the string size. StringRef BufferPrefix = Buffer.substr(0, ExampleString.size()); BufferPrefix = BufferPrefix.split('\n').first; return BufferPrefix.edit_distance(ExampleString); }
static unsigned getCallEditDistance(DeclName argName, DeclName paramName, unsigned maxEditDistance) { // TODO: consider arguments. // TODO: maybe ignore certain kinds of missing / present labels for the // first argument label? // TODO: word-based rather than character-based? StringRef argBase = argName.getBaseName().str(); StringRef paramBase = paramName.getBaseName().str(); unsigned distance = argBase.edit_distance(paramBase, maxEditDistance); // Bound the distance to UnreasonableCallEditDistance. if (distance >= maxEditDistance || distance > (paramBase.size() + 2) / 3) { return UnreasonableCallEditDistance; } return distance; }
static void HelperTypoCorrectCommandInfo(SmallVectorImpl<const CommandInfo *> &BestCommand, StringRef Typo, const CommandInfo *Command) { const unsigned MaxEditDistance = 1; unsigned BestEditDistance = MaxEditDistance + 1; StringRef Name = Command->Name; unsigned MinPossibleEditDistance = abs((int)Name.size() - (int)Typo.size()); if (MinPossibleEditDistance > 0 && Typo.size() / MinPossibleEditDistance < 1) return; unsigned EditDistance = Typo.edit_distance(Name, true, MaxEditDistance); if (EditDistance > MaxEditDistance) return; if (EditDistance == BestEditDistance) BestCommand.push_back(Command); else if (EditDistance < BestEditDistance) { BestCommand.clear(); BestCommand.push_back(Command); BestEditDistance = EditDistance; } }
ModuleLoadResult CompilerInstance::loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective) { // If we've already handled this import, just return the cached result. // This one-element cache is important to eliminate redundant diagnostics // when both the preprocessor and parser see the same import declaration. if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc) { // Make the named module visible. if (LastModuleImportResult) ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility); return LastModuleImportResult; } // Determine what file we're searching from. StringRef ModuleName = Path[0].first->getName(); SourceLocation ModuleNameLoc = Path[0].second; clang::Module *Module = 0; // If we don't already have information on this module, load the module now. llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known = KnownModules.find(Path[0].first); if (Known != KnownModules.end()) { // Retrieve the cached top-level module. Module = Known->second; } else if (ModuleName == getLangOpts().CurrentModule) { // This is the module we're building. Module = PP->getHeaderSearchInfo().getModuleMap().findModule(ModuleName); Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; } else { // Search for a module with the given name. Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); std::string ModuleFileName; if (Module) ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module); else ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(ModuleName); if (ModuleFileName.empty()) { getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found) << ModuleName << SourceRange(ImportLoc, ModuleNameLoc); LastModuleImportLoc = ImportLoc; LastModuleImportResult = ModuleLoadResult(); return LastModuleImportResult; } const FileEntry *ModuleFile = getFileManager().getFile(ModuleFileName, /*OpenFile=*/false, /*CacheFailure=*/false); bool BuildingModule = false; if (!ModuleFile && Module) { // The module is not cached, but we have a module map from which we can // build the module. // Check whether there is a cycle in the module graph. ModuleBuildStack Path = getSourceManager().getModuleBuildStack(); ModuleBuildStack::iterator Pos = Path.begin(), PosEnd = Path.end(); for (; Pos != PosEnd; ++Pos) { if (Pos->first == ModuleName) break; } if (Pos != PosEnd) { SmallString<256> CyclePath; for (; Pos != PosEnd; ++Pos) { CyclePath += Pos->first; CyclePath += " -> "; } CyclePath += ModuleName; getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle) << ModuleName << CyclePath; return ModuleLoadResult(); } // Check whether we have already attempted to build this module (but // failed). if (getPreprocessorOpts().FailedModules && getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) { getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built) << ModuleName << SourceRange(ImportLoc, ModuleNameLoc); return ModuleLoadResult(); } BuildingModule = true; compileModule(*this, ModuleNameLoc, Module, ModuleFileName); ModuleFile = FileMgr->getFile(ModuleFileName); if (!ModuleFile && getPreprocessorOpts().FailedModules) getPreprocessorOpts().FailedModules->addFailed(ModuleName); } if (!ModuleFile) { getDiagnostics().Report(ModuleNameLoc, BuildingModule? diag::err_module_not_built : diag::err_module_not_found) << ModuleName << SourceRange(ImportLoc, ModuleNameLoc); return ModuleLoadResult(); } // If we don't already have an ASTReader, create one now. if (!ModuleManager) { if (!hasASTContext()) createASTContext(); std::string Sysroot = getHeaderSearchOpts().Sysroot; const PreprocessorOptions &PPOpts = getPreprocessorOpts(); ModuleManager = new ASTReader(getPreprocessor(), *Context, Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation); if (hasASTConsumer()) { ModuleManager->setDeserializationListener( getASTConsumer().GetASTDeserializationListener()); getASTContext().setASTMutationListener( getASTConsumer().GetASTMutationListener()); getPreprocessor().setPPMutationListener( getASTConsumer().GetPPMutationListener()); } OwningPtr<ExternalASTSource> Source; Source.reset(ModuleManager); getASTContext().setExternalSource(Source); if (hasSema()) ModuleManager->InitializeSema(getSema()); if (hasASTConsumer()) ModuleManager->StartTranslationUnit(&getASTConsumer()); } // Try to load the module we found. unsigned ARRFlags = ASTReader::ARR_None; if (Module) ARRFlags |= ASTReader::ARR_OutOfDate; switch (ModuleManager->ReadAST(ModuleFile->getName(), serialization::MK_Module, ImportLoc, ARRFlags)) { case ASTReader::Success: break; case ASTReader::OutOfDate: { // The module file is out-of-date. Rebuild it. getFileManager().invalidateCache(ModuleFile); bool Existed; llvm::sys::fs::remove(ModuleFileName, Existed); // Check whether we have already attempted to build this module (but // failed). if (getPreprocessorOpts().FailedModules && getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) { getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built) << ModuleName << SourceRange(ImportLoc, ModuleNameLoc); return ModuleLoadResult(); } compileModule(*this, ModuleNameLoc, Module, ModuleFileName); // Try loading the module again. ModuleFile = FileMgr->getFile(ModuleFileName); if (!ModuleFile || ModuleManager->ReadAST(ModuleFileName, serialization::MK_Module, ImportLoc, ASTReader::ARR_None) != ASTReader::Success) { if (getPreprocessorOpts().FailedModules) getPreprocessorOpts().FailedModules->addFailed(ModuleName); KnownModules[Path[0].first] = 0; return ModuleLoadResult(); } // Okay, we've rebuilt and now loaded the module. break; } case ASTReader::VersionMismatch: case ASTReader::ConfigurationMismatch: case ASTReader::HadErrors: // FIXME: The ASTReader will already have complained, but can we showhorn // that diagnostic information into a more useful form? KnownModules[Path[0].first] = 0; return ModuleLoadResult(); case ASTReader::Failure: // Already complained, but note now that we failed. KnownModules[Path[0].first] = 0; return ModuleLoadResult(); } if (!Module) { // If we loaded the module directly, without finding a module map first, // we'll have loaded the module's information from the module itself. Module = PP->getHeaderSearchInfo().getModuleMap() .findModule((Path[0].first->getName())); } if (Module) Module->setASTFile(ModuleFile); // Cache the result of this top-level module lookup for later. Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; } // If we never found the module, fail. if (!Module) return ModuleLoadResult(); // Verify that the rest of the module path actually corresponds to // a submodule. if (Path.size() > 1) { for (unsigned I = 1, N = Path.size(); I != N; ++I) { StringRef Name = Path[I].first->getName(); clang::Module *Sub = Module->findSubmodule(Name); if (!Sub) { // Attempt to perform typo correction to find a module name that works. llvm::SmallVector<StringRef, 2> Best; unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)(); for (clang::Module::submodule_iterator J = Module->submodule_begin(), JEnd = Module->submodule_end(); J != JEnd; ++J) { unsigned ED = Name.edit_distance((*J)->Name, /*AllowReplacements=*/true, BestEditDistance); if (ED <= BestEditDistance) { if (ED < BestEditDistance) { Best.clear(); BestEditDistance = ED; } Best.push_back((*J)->Name); } } // If there was a clear winner, user it. if (Best.size() == 1) { getDiagnostics().Report(Path[I].second, diag::err_no_submodule_suggest) << Path[I].first << Module->getFullModuleName() << Best[0] << SourceRange(Path[0].second, Path[I-1].second) << FixItHint::CreateReplacement(SourceRange(Path[I].second), Best[0]); Sub = Module->findSubmodule(Best[0]); } } if (!Sub) { // No submodule by this name. Complain, and don't look for further // submodules. getDiagnostics().Report(Path[I].second, diag::err_no_submodule) << Path[I].first << Module->getFullModuleName() << SourceRange(Path[0].second, Path[I-1].second); break; } Module = Sub; } } // Make the named module visible, if it's not already part of the module // we are parsing. if (ModuleName != getLangOpts().CurrentModule) { if (!Module->IsFromModuleFile) { // We have an umbrella header or directory that doesn't actually include // all of the headers within the directory it covers. Complain about // this missing submodule and recover by forgetting that we ever saw // this submodule. // FIXME: Should we detect this at module load time? It seems fairly // expensive (and rare). getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule) << Module->getFullModuleName() << SourceRange(Path.front().second, Path.back().second); return ModuleLoadResult(0, true); } // Check whether this module is available. StringRef Feature; if (!Module->isAvailable(getLangOpts(), getTarget(), Feature)) { getDiagnostics().Report(ImportLoc, diag::err_module_unavailable) << Module->getFullModuleName() << Feature << SourceRange(Path.front().second, Path.back().second); LastModuleImportLoc = ImportLoc; LastModuleImportResult = ModuleLoadResult(); return ModuleLoadResult(); } ModuleManager->makeModuleVisible(Module, Visibility); } // If this module import was due to an inclusion directive, create an // implicit import declaration to capture it in the AST. if (IsInclusionDirective && hasASTContext()) { TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl(); ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU, ImportLoc, Module, Path.back().second); TU->addDecl(ImportD); if (Consumer) Consumer->HandleImplicitImportDecl(ImportD); } LastModuleImportLoc = ImportLoc; LastModuleImportResult = ModuleLoadResult(Module, false); return LastModuleImportResult; }
/// HandleEndOfFile - This callback is invoked when the lexer hits the end of /// the current file. This either returns the EOF token or pops a level off /// the include stack and keeps going. bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { assert(!CurTokenLexer && "Ending a file when currently in a macro!"); // See if this file had a controlling macro. if (CurPPLexer) { // Not ending a macro, ignore it. if (const IdentifierInfo *ControllingMacro = CurPPLexer->MIOpt.GetControllingMacroAtEndOfFile()) { // Okay, this has a controlling macro, remember in HeaderFileInfo. if (const FileEntry *FE = SourceMgr.getFileEntryForID(CurPPLexer->getFileID())) { HeaderInfo.SetFileControllingMacro(FE, ControllingMacro); if (MacroInfo *MI = getMacroInfo(const_cast<IdentifierInfo*>(ControllingMacro))) { MI->UsedForHeaderGuard = true; } if (const IdentifierInfo *DefinedMacro = CurPPLexer->MIOpt.GetDefinedMacro()) { if (!ControllingMacro->hasMacroDefinition() && DefinedMacro != ControllingMacro && HeaderInfo.FirstTimeLexingFile(FE)) { // If the edit distance between the two macros is more than 50%, // DefinedMacro may not be header guard, or can be header guard of // another header file. Therefore, it maybe defining something // completely different. This can be observed in the wild when // handling feature macros or header guards in different files. const StringRef ControllingMacroName = ControllingMacro->getName(); const StringRef DefinedMacroName = DefinedMacro->getName(); const size_t MaxHalfLength = std::max(ControllingMacroName.size(), DefinedMacroName.size()) / 2; const unsigned ED = ControllingMacroName.edit_distance( DefinedMacroName, true, MaxHalfLength); if (ED <= MaxHalfLength) { // Emit a warning for a bad header guard. Diag(CurPPLexer->MIOpt.GetMacroLocation(), diag::warn_header_guard) << CurPPLexer->MIOpt.GetMacroLocation() << ControllingMacro; Diag(CurPPLexer->MIOpt.GetDefinedLocation(), diag::note_header_guard) << CurPPLexer->MIOpt.GetDefinedLocation() << DefinedMacro << ControllingMacro << FixItHint::CreateReplacement( CurPPLexer->MIOpt.GetDefinedLocation(), ControllingMacro->getName()); } } } } } } // Complain about reaching a true EOF within arc_cf_code_audited. // We don't want to complain about reaching the end of a macro // instantiation or a _Pragma. if (PragmaARCCFCodeAuditedLoc.isValid() && !isEndOfMacro && !(CurLexer && CurLexer->Is_PragmaLexer)) { Diag(PragmaARCCFCodeAuditedLoc, diag::err_pp_eof_in_arc_cf_code_audited); // Recover by leaving immediately. PragmaARCCFCodeAuditedLoc = SourceLocation(); } // If this is a #include'd file, pop it off the include stack and continue // lexing the #includer file. if (!IncludeMacroStack.empty()) { // If we lexed the code-completion file, act as if we reached EOF. if (isCodeCompletionEnabled() && CurPPLexer && SourceMgr.getLocForStartOfFile(CurPPLexer->getFileID()) == CodeCompletionFileLoc) { if (CurLexer) { Result.startToken(); CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd, tok::eof); CurLexer.reset(); } else { assert(CurPTHLexer && "Got EOF but no current lexer set!"); CurPTHLexer->getEOF(Result); CurPTHLexer.reset(); } CurPPLexer = nullptr; return true; } if (!isEndOfMacro && CurPPLexer && SourceMgr.getIncludeLoc(CurPPLexer->getFileID()).isValid()) { // Notify SourceManager to record the number of FileIDs that were created // during lexing of the #include'd file. unsigned NumFIDs = SourceMgr.local_sloc_entry_size() - CurPPLexer->getInitialNumSLocEntries() + 1/*#include'd file*/; SourceMgr.setNumCreatedFIDsForFileID(CurPPLexer->getFileID(), NumFIDs); } FileID ExitedFID; if (Callbacks && !isEndOfMacro && CurPPLexer) ExitedFID = CurPPLexer->getFileID(); bool LeavingSubmodule = CurSubmodule && CurLexer; if (LeavingSubmodule) { // Notify the parser that we've left the module. const char *EndPos = getCurLexerEndPos(); Result.startToken(); CurLexer->BufferPtr = EndPos; CurLexer->FormTokenWithChars(Result, EndPos, tok::annot_module_end); Result.setAnnotationEndLoc(Result.getLocation()); Result.setAnnotationValue(CurSubmodule); } // We're done with the #included file. RemoveTopOfLexerStack(); // Propagate info about start-of-line/leading white-space/etc. PropagateLineStartLeadingSpaceInfo(Result); // Notify the client, if desired, that we are in a new source file. if (Callbacks && !isEndOfMacro && CurPPLexer) { SrcMgr::CharacteristicKind FileType = SourceMgr.getFileCharacteristic(CurPPLexer->getSourceLocation()); Callbacks->FileChanged(CurPPLexer->getSourceLocation(), PPCallbacks::ExitFile, FileType, ExitedFID); } // Client should lex another token unless we generated an EOM. return LeavingSubmodule; } // If this is the end of the main file, form an EOF token. if (CurLexer) { const char *EndPos = getCurLexerEndPos(); Result.startToken(); CurLexer->BufferPtr = EndPos; CurLexer->FormTokenWithChars(Result, EndPos, tok::eof); if (isCodeCompletionEnabled()) { // Inserting the code-completion point increases the source buffer by 1, // but the main FileID was created before inserting the point. // Compensate by reducing the EOF location by 1, otherwise the location // will point to the next FileID. // FIXME: This is hacky, the code-completion point should probably be // inserted before the main FileID is created. if (CurLexer->getFileLoc() == CodeCompletionFileLoc) Result.setLocation(Result.getLocation().getLocWithOffset(-1)); } if (!isIncrementalProcessingEnabled()) // We're done with lexing. CurLexer.reset(); } else { assert(CurPTHLexer && "Got EOF but no current lexer set!"); CurPTHLexer->getEOF(Result); CurPTHLexer.reset(); } if (!isIncrementalProcessingEnabled()) CurPPLexer = nullptr; if (TUKind == TU_Complete) { // This is the end of the top-level file. 'WarnUnusedMacroLocs' has // collected all macro locations that we need to warn because they are not // used. for (WarnUnusedMacroLocsTy::iterator I=WarnUnusedMacroLocs.begin(), E=WarnUnusedMacroLocs.end(); I!=E; ++I) Diag(*I, diag::pp_macro_not_used); } // If we are building a module that has an umbrella header, make sure that // each of the headers within the directory covered by the umbrella header // was actually included by the umbrella header. if (Module *Mod = getCurrentModule()) { if (Mod->getUmbrellaHeader()) { SourceLocation StartLoc = SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()); if (!getDiagnostics().isIgnored(diag::warn_uncovered_module_header, StartLoc)) { ModuleMap &ModMap = getHeaderSearchInfo().getModuleMap(); const DirectoryEntry *Dir = Mod->getUmbrellaDir(); vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem(); std::error_code EC; for (vfs::recursive_directory_iterator Entry(FS, Dir->getName(), EC), End; Entry != End && !EC; Entry.increment(EC)) { using llvm::StringSwitch; // Check whether this entry has an extension typically associated with // headers. if (!StringSwitch<bool>(llvm::sys::path::extension(Entry->getName())) .Cases(".h", ".H", ".hh", ".hpp", true) .Default(false)) continue; if (const FileEntry *Header = getFileManager().getFile(Entry->getName())) if (!getSourceManager().hasFileInfo(Header)) { if (!ModMap.isHeaderInUnavailableModule(Header)) { // Find the relative path that would access this header. SmallString<128> RelativePath; computeRelativePath(FileMgr, Dir, Header, RelativePath); Diag(StartLoc, diag::warn_uncovered_module_header) << Mod->getFullModuleName() << RelativePath; } } } } } // Check whether there are any headers that were included, but not // mentioned at all in the module map. Such headers SourceLocation StartLoc = SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()); if (!getDiagnostics().isIgnored(diag::warn_forgotten_module_header, StartLoc)) { ModuleMap &ModMap = getHeaderSearchInfo().getModuleMap(); for (unsigned I = 0, N = SourceMgr.local_sloc_entry_size(); I != N; ++I) { // We only care about file entries. const SrcMgr::SLocEntry &Entry = SourceMgr.getLocalSLocEntry(I); if (!Entry.isFile()) continue; // Dig out the actual file. const FileEntry *File = Entry.getFile().getContentCache()->OrigEntry; if (!File) continue; // If it's not part of a module and not unknown, complain. if (!ModMap.findModuleForHeader(File) && !ModMap.isHeaderInUnavailableModule(File)) { Diag(StartLoc, diag::warn_forgotten_module_header) << File->getName() << Mod->getFullModuleName(); } } } } return true; }
/// HandleEndOfFile - This callback is invoked when the lexer hits the end of /// the current file. This either returns the EOF token or pops a level off /// the include stack and keeps going. bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { assert(!CurTokenLexer && "Ending a file when currently in a macro!"); // If we have an unclosed module region from a pragma at the end of a // module, complain and close it now. // FIXME: This is not correct if we are building a module from PTH. const bool LeavingSubmodule = CurLexer && CurLexerSubmodule; if ((LeavingSubmodule || IncludeMacroStack.empty()) && !BuildingSubmoduleStack.empty() && BuildingSubmoduleStack.back().IsPragma) { Diag(BuildingSubmoduleStack.back().ImportLoc, diag::err_pp_module_begin_without_module_end); Module *M = LeaveSubmodule(/*ForPragma*/true); Result.startToken(); const char *EndPos = getCurLexerEndPos(); CurLexer->BufferPtr = EndPos; CurLexer->FormTokenWithChars(Result, EndPos, tok::annot_module_end); Result.setAnnotationEndLoc(Result.getLocation()); Result.setAnnotationValue(M); return true; } // See if this file had a controlling macro. if (CurPPLexer) { // Not ending a macro, ignore it. if (const IdentifierInfo *ControllingMacro = CurPPLexer->MIOpt.GetControllingMacroAtEndOfFile()) { // Okay, this has a controlling macro, remember in HeaderFileInfo. if (const FileEntry *FE = CurPPLexer->getFileEntry()) { HeaderInfo.SetFileControllingMacro(FE, ControllingMacro); if (MacroInfo *MI = getMacroInfo(const_cast<IdentifierInfo*>(ControllingMacro))) MI->setUsedForHeaderGuard(true); if (const IdentifierInfo *DefinedMacro = CurPPLexer->MIOpt.GetDefinedMacro()) { if (!isMacroDefined(ControllingMacro) && DefinedMacro != ControllingMacro && HeaderInfo.FirstTimeLexingFile(FE)) { // If the edit distance between the two macros is more than 50%, // DefinedMacro may not be header guard, or can be header guard of // another header file. Therefore, it maybe defining something // completely different. This can be observed in the wild when // handling feature macros or header guards in different files. const StringRef ControllingMacroName = ControllingMacro->getName(); const StringRef DefinedMacroName = DefinedMacro->getName(); const size_t MaxHalfLength = std::max(ControllingMacroName.size(), DefinedMacroName.size()) / 2; const unsigned ED = ControllingMacroName.edit_distance( DefinedMacroName, true, MaxHalfLength); if (ED <= MaxHalfLength) { // Emit a warning for a bad header guard. Diag(CurPPLexer->MIOpt.GetMacroLocation(), diag::warn_header_guard) << CurPPLexer->MIOpt.GetMacroLocation() << ControllingMacro; Diag(CurPPLexer->MIOpt.GetDefinedLocation(), diag::note_header_guard) << CurPPLexer->MIOpt.GetDefinedLocation() << DefinedMacro << ControllingMacro << FixItHint::CreateReplacement( CurPPLexer->MIOpt.GetDefinedLocation(), ControllingMacro->getName()); } } } } } } // Complain about reaching a true EOF within arc_cf_code_audited. // We don't want to complain about reaching the end of a macro // instantiation or a _Pragma. if (PragmaARCCFCodeAuditedLoc.isValid() && !isEndOfMacro && !(CurLexer && CurLexer->Is_PragmaLexer)) { Diag(PragmaARCCFCodeAuditedLoc, diag::err_pp_eof_in_arc_cf_code_audited); // Recover by leaving immediately. PragmaARCCFCodeAuditedLoc = SourceLocation(); } // Complain about reaching a true EOF within assume_nonnull. // We don't want to complain about reaching the end of a macro // instantiation or a _Pragma. if (PragmaAssumeNonNullLoc.isValid() && !isEndOfMacro && !(CurLexer && CurLexer->Is_PragmaLexer)) { Diag(PragmaAssumeNonNullLoc, diag::err_pp_eof_in_assume_nonnull); // Recover by leaving immediately. PragmaAssumeNonNullLoc = SourceLocation(); } bool LeavingPCHThroughHeader = false; // If this is a #include'd file, pop it off the include stack and continue // lexing the #includer file. if (!IncludeMacroStack.empty()) { // If we lexed the code-completion file, act as if we reached EOF. if (isCodeCompletionEnabled() && CurPPLexer && SourceMgr.getLocForStartOfFile(CurPPLexer->getFileID()) == CodeCompletionFileLoc) { if (CurLexer) { Result.startToken(); CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd, tok::eof); CurLexer.reset(); } else { assert(CurPTHLexer && "Got EOF but no current lexer set!"); CurPTHLexer->getEOF(Result); CurPTHLexer.reset(); } CurPPLexer = nullptr; recomputeCurLexerKind(); return true; } if (!isEndOfMacro && CurPPLexer && SourceMgr.getIncludeLoc(CurPPLexer->getFileID()).isValid()) { // Notify SourceManager to record the number of FileIDs that were created // during lexing of the #include'd file. unsigned NumFIDs = SourceMgr.local_sloc_entry_size() - CurPPLexer->getInitialNumSLocEntries() + 1/*#include'd file*/; SourceMgr.setNumCreatedFIDsForFileID(CurPPLexer->getFileID(), NumFIDs); } bool ExitedFromPredefinesFile = false; FileID ExitedFID; if (!isEndOfMacro && CurPPLexer) { ExitedFID = CurPPLexer->getFileID(); assert(PredefinesFileID.isValid() && "HandleEndOfFile is called before PredefinesFileId is set"); ExitedFromPredefinesFile = (PredefinesFileID == ExitedFID); } if (LeavingSubmodule) { // We're done with this submodule. Module *M = LeaveSubmodule(/*ForPragma*/false); // Notify the parser that we've left the module. const char *EndPos = getCurLexerEndPos(); Result.startToken(); CurLexer->BufferPtr = EndPos; CurLexer->FormTokenWithChars(Result, EndPos, tok::annot_module_end); Result.setAnnotationEndLoc(Result.getLocation()); Result.setAnnotationValue(M); } bool FoundPCHThroughHeader = false; if (CurPPLexer && creatingPCHWithThroughHeader() && isPCHThroughHeader( SourceMgr.getFileEntryForID(CurPPLexer->getFileID()))) FoundPCHThroughHeader = true; // We're done with the #included file. RemoveTopOfLexerStack(); // Propagate info about start-of-line/leading white-space/etc. PropagateLineStartLeadingSpaceInfo(Result); // Notify the client, if desired, that we are in a new source file. if (Callbacks && !isEndOfMacro && CurPPLexer) { SrcMgr::CharacteristicKind FileType = SourceMgr.getFileCharacteristic(CurPPLexer->getSourceLocation()); Callbacks->FileChanged(CurPPLexer->getSourceLocation(), PPCallbacks::ExitFile, FileType, ExitedFID); } // Restore conditional stack from the preamble right after exiting from the // predefines file. if (ExitedFromPredefinesFile) replayPreambleConditionalStack(); if (!isEndOfMacro && CurPPLexer && FoundPCHThroughHeader && (isInPrimaryFile() || CurPPLexer->getFileID() == getPredefinesFileID())) { // Leaving the through header. Continue directly to end of main file // processing. LeavingPCHThroughHeader = true; } else { // Client should lex another token unless we generated an EOM. return LeavingSubmodule; } } // If this is the end of the main file, form an EOF token. if (CurLexer) { const char *EndPos = getCurLexerEndPos(); Result.startToken(); CurLexer->BufferPtr = EndPos; CurLexer->FormTokenWithChars(Result, EndPos, tok::eof); if (isCodeCompletionEnabled()) { // Inserting the code-completion point increases the source buffer by 1, // but the main FileID was created before inserting the point. // Compensate by reducing the EOF location by 1, otherwise the location // will point to the next FileID. // FIXME: This is hacky, the code-completion point should probably be // inserted before the main FileID is created. if (CurLexer->getFileLoc() == CodeCompletionFileLoc) Result.setLocation(Result.getLocation().getLocWithOffset(-1)); } if (creatingPCHWithThroughHeader() && !LeavingPCHThroughHeader) { // Reached the end of the compilation without finding the through header. Diag(CurLexer->getFileLoc(), diag::err_pp_through_header_not_seen) << PPOpts->PCHThroughHeader << 0; } if (!isIncrementalProcessingEnabled()) // We're done with lexing. CurLexer.reset(); } else { assert(CurPTHLexer && "Got EOF but no current lexer set!"); CurPTHLexer->getEOF(Result); CurPTHLexer.reset(); } if (!isIncrementalProcessingEnabled()) CurPPLexer = nullptr; if (TUKind == TU_Complete) { // This is the end of the top-level file. 'WarnUnusedMacroLocs' has // collected all macro locations that we need to warn because they are not // used. for (WarnUnusedMacroLocsTy::iterator I=WarnUnusedMacroLocs.begin(), E=WarnUnusedMacroLocs.end(); I!=E; ++I) Diag(*I, diag::pp_macro_not_used); } // If we are building a module that has an umbrella header, make sure that // each of the headers within the directory, including all submodules, is // covered by the umbrella header was actually included by the umbrella // header. if (Module *Mod = getCurrentModule()) { llvm::SmallVector<const Module *, 4> AllMods; collectAllSubModulesWithUmbrellaHeader(*Mod, AllMods); for (auto *M : AllMods) diagnoseMissingHeaderInUmbrellaDir(*M); } return true; }