diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Lex')
17 files changed, 1074 insertions, 774 deletions
diff --git a/contrib/llvm/tools/clang/lib/Lex/HeaderMap.cpp b/contrib/llvm/tools/clang/lib/Lex/HeaderMap.cpp index f6c658e..09d5384 100644 --- a/contrib/llvm/tools/clang/lib/Lex/HeaderMap.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/HeaderMap.cpp @@ -81,9 +81,9 @@ const HeaderMap *HeaderMap::Create(const FileEntry *FE, FileManager &FM) { unsigned FileSize = FE->getSize(); if (FileSize <= sizeof(HMapHeader)) return nullptr; - std::unique_ptr<const llvm::MemoryBuffer> FileBuffer(FM.getBufferForFile(FE)); + auto FileBuffer = FM.getBufferForFile(FE); if (!FileBuffer) return nullptr; // Unreadable file? - const char *FileStart = FileBuffer->getBufferStart(); + const char *FileStart = (*FileBuffer)->getBufferStart(); // We know the file is at least as big as the header, check it now. const HMapHeader *Header = reinterpret_cast<const HMapHeader*>(FileStart); @@ -103,11 +103,7 @@ const HeaderMap *HeaderMap::Create(const FileEntry *FE, FileManager &FM) { if (Header->Reserved != 0) return nullptr; // Okay, everything looks good, create the header map. - return new HeaderMap(FileBuffer.release(), NeedsByteSwap); -} - -HeaderMap::~HeaderMap() { - delete FileBuffer; + return new HeaderMap(std::move(*FileBuffer), NeedsByteSwap); } //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp b/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp index c12d731..d6b255f 100644 --- a/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp @@ -50,7 +50,8 @@ HeaderSearch::HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts, const LangOptions &LangOpts, const TargetInfo *Target) : HSOpts(HSOpts), Diags(Diags), FileMgr(SourceMgr.getFileManager()), - FrameworkMap(64), ModMap(SourceMgr, Diags, LangOpts, Target, *this) { + FrameworkMap(64), ModMap(SourceMgr, Diags, LangOpts, Target, *this), + LangOpts(LangOpts) { AngledDirIdx = 0; SystemDirIdx = 0; NoCurDirSearch = false; @@ -60,8 +61,6 @@ HeaderSearch::HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts, NumIncluded = 0; NumMultiIncludeFileOptzn = 0; NumFrameworkLookups = NumSubFrameworkLookups = 0; - - EnabledModules = LangOpts.Modules; } HeaderSearch::~HeaderSearch() { @@ -114,7 +113,9 @@ const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) { } std::string HeaderSearch::getModuleFileName(Module *Module) { - return getModuleFileName(Module->Name, Module->ModuleMap->getName()); + const FileEntry *ModuleMap = + getModuleMap().getModuleMapFileForUniquing(Module); + return getModuleFileName(Module->Name, ModuleMap->getName()); } std::string HeaderSearch::getModuleFileName(StringRef ModuleName, @@ -130,15 +131,24 @@ std::string HeaderSearch::getModuleFileName(StringRef ModuleName, llvm::sys::path::append(Result, ModuleName + ".pcm"); } else { // Construct the name <ModuleName>-<hash of ModuleMapPath>.pcm which should - // be globally unique to this particular module. To avoid false-negatives - // on case-insensitive filesystems, we use lower-case, which is safe because - // to cause a collision the modules must have the same name, which is an - // error if they are imported in the same translation. - SmallString<256> AbsModuleMapPath(ModuleMapPath); - llvm::sys::fs::make_absolute(AbsModuleMapPath); - llvm::APInt Code(64, llvm::hash_value(AbsModuleMapPath.str().lower())); + // ideally be globally unique to this particular module. Name collisions + // in the hash are safe (because any translation unit can only import one + // module with each name), but result in a loss of caching. + // + // To avoid false-negatives, we form as canonical a path as we can, and map + // to lower-case in case we're on a case-insensitive file system. + auto *Dir = + FileMgr.getDirectory(llvm::sys::path::parent_path(ModuleMapPath)); + if (!Dir) + return std::string(); + auto DirName = FileMgr.getCanonicalName(Dir); + auto FileName = llvm::sys::path::filename(ModuleMapPath); + + llvm::hash_code Hash = + llvm::hash_combine(DirName.lower(), FileName.lower()); + SmallString<128> HashStr; - Code.toStringUnsigned(HashStr, /*Radix*/36); + llvm::APInt(64, size_t(Hash)).toStringUnsigned(HashStr, /*Radix*/36); llvm::sys::path::append(Result, ModuleName + "-" + HashStr.str() + ".pcm"); } return Result.str().str(); @@ -147,7 +157,7 @@ std::string HeaderSearch::getModuleFileName(StringRef ModuleName, Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) { // Look in the module map to determine if there is a module by this name. Module *Module = ModMap.findModule(ModuleName); - if (Module || !AllowSearch) + if (Module || !AllowSearch || !LangOpts.ModulesImplicitMaps) return Module; // Look through the various header search paths to load any available module @@ -564,27 +574,9 @@ static const char *copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) { const FileEntry *HeaderSearch::LookupFile( StringRef Filename, SourceLocation IncludeLoc, bool isAngled, const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, - ArrayRef<const FileEntry *> Includers, SmallVectorImpl<char> *SearchPath, - SmallVectorImpl<char> *RelativePath, + ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers, + SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool SkipCache) { - if (!HSOpts->ModuleMapFiles.empty()) { - // Preload all explicitly specified module map files. This enables modules - // map files lying in a directory structure separate from the header files - // that they describe. These cannot be loaded lazily upon encountering a - // header file, as there is no other known mapping from a header file to its - // module map file. - for (llvm::SetVector<std::string>::iterator - I = HSOpts->ModuleMapFiles.begin(), - E = HSOpts->ModuleMapFiles.end(); - I != E; ++I) { - const FileEntry *File = FileMgr.getFile(*I); - if (!File) - continue; - loadModuleMapFile(File, /*IsSystem=*/false); - } - HSOpts->ModuleMapFiles.clear(); - } - if (SuggestedModule) *SuggestedModule = ModuleMap::KnownHeader(); @@ -616,25 +608,33 @@ const FileEntry *HeaderSearch::LookupFile( // This search is not done for <> headers. if (!Includers.empty() && !isAngled && !NoCurDirSearch) { SmallString<1024> TmpDir; - for (ArrayRef<const FileEntry *>::iterator I = Includers.begin(), - E = Includers.end(); - I != E; ++I) { - const FileEntry *Includer = *I; + bool First = true; + for (const auto &IncluderAndDir : Includers) { + const FileEntry *Includer = IncluderAndDir.first; + // Concatenate the requested file onto the directory. // FIXME: Portability. Filename concatenation should be in sys::Path. - TmpDir = Includer->getDir()->getName(); + TmpDir = IncluderAndDir.second->getName(); TmpDir.push_back('/'); TmpDir.append(Filename.begin(), Filename.end()); // FIXME: We don't cache the result of getFileInfo across the call to // getFileAndSuggestModule, because it's a reference to an element of // a container that could be reallocated across this call. + // + // FIXME: If we have no includer, that means we're processing a #include + // from a module build. We should treat this as a system header if we're + // building a [system] module. bool IncluderIsSystemHeader = - getFileInfo(Includer).DirInfo != SrcMgr::C_User; - if (const FileEntry *FE = - getFileAndSuggestModule(*this, TmpDir.str(), Includer->getDir(), - IncluderIsSystemHeader, - SuggestedModule)) { + Includer && getFileInfo(Includer).DirInfo != SrcMgr::C_User; + if (const FileEntry *FE = getFileAndSuggestModule( + *this, TmpDir.str(), IncluderAndDir.second, + IncluderIsSystemHeader, SuggestedModule)) { + if (!Includer) { + assert(First && "only first includer can have no file"); + return FE; + } + // Leave CurDir unset. // This file is a system header or C++ unfriendly if the old file is. // @@ -652,7 +652,7 @@ const FileEntry *HeaderSearch::LookupFile( ToHFI.Framework = Framework; if (SearchPath) { - StringRef SearchPathRef(Includer->getDir()->getName()); + StringRef SearchPathRef(IncluderAndDir.second->getName()); SearchPath->clear(); SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); } @@ -660,7 +660,7 @@ const FileEntry *HeaderSearch::LookupFile( RelativePath->clear(); RelativePath->append(Filename.begin(), Filename.end()); } - if (I == Includers.begin()) + if (First) return FE; // Otherwise, we found the path via MSVC header search rules. If @@ -677,6 +677,7 @@ const FileEntry *HeaderSearch::LookupFile( break; } } + First = false; } } @@ -694,8 +695,7 @@ const FileEntry *HeaderSearch::LookupFile( // multiply included, and the "pragma once" optimization prevents them from // being relex/pp'd, but they would still have to search through a // (potentially huge) series of SearchDirs to find it. - LookupFileCacheInfo &CacheLookup = - LookupFileCache.GetOrCreateValue(Filename).getValue(); + LookupFileCacheInfo &CacheLookup = LookupFileCache[Filename]; // If the entry has been previously looked up, the first value will be // non-zero. If the value is equal to i (the start point of our search), then @@ -776,9 +776,9 @@ const FileEntry *HeaderSearch::LookupFile( // a header in a framework that is currently being built, and we couldn't // resolve "foo.h" any other way, change the include to <Foo/foo.h>, where // "Foo" is the name of the framework in which the including header was found. - if (!Includers.empty() && !isAngled && + if (!Includers.empty() && Includers.front().first && !isAngled && Filename.find('/') == StringRef::npos) { - HeaderFileInfo &IncludingHFI = getFileInfo(Includers.front()); + HeaderFileInfo &IncludingHFI = getFileInfo(Includers.front().first); if (IncludingHFI.IndexHeaderMapHeader) { SmallString<128> ScratchFilename; ScratchFilename += IncludingHFI.Framework; @@ -795,10 +795,8 @@ const FileEntry *HeaderSearch::LookupFile( return MSFE; } - LookupFileCacheInfo &CacheLookup - = LookupFileCache.GetOrCreateValue(Filename).getValue(); - CacheLookup.HitIdx - = LookupFileCache.GetOrCreateValue(ScratchFilename).getValue().HitIdx; + LookupFileCacheInfo &CacheLookup = LookupFileCache[Filename]; + CacheLookup.HitIdx = LookupFileCache[ScratchFilename].HitIdx; // FIXME: SuggestedModule. return FE; } @@ -851,18 +849,19 @@ LookupSubframeworkHeader(StringRef Filename, FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos); FrameworkName += ".framework/"; - llvm::StringMapEntry<FrameworkCacheEntry> &CacheLookup = - FrameworkMap.GetOrCreateValue(Filename.substr(0, SlashPos)); + auto &CacheLookup = + *FrameworkMap.insert(std::make_pair(Filename.substr(0, SlashPos), + FrameworkCacheEntry())).first; // Some other location? - if (CacheLookup.getValue().Directory && - CacheLookup.getKeyLength() == FrameworkName.size() && - memcmp(CacheLookup.getKeyData(), &FrameworkName[0], - CacheLookup.getKeyLength()) != 0) + if (CacheLookup.second.Directory && + CacheLookup.first().size() == FrameworkName.size() && + memcmp(CacheLookup.first().data(), &FrameworkName[0], + CacheLookup.first().size()) != 0) return nullptr; // Cache subframework. - if (!CacheLookup.getValue().Directory) { + if (!CacheLookup.second.Directory) { ++NumSubFrameworkLookups; // If the framework dir doesn't exist, we fail. @@ -871,7 +870,7 @@ LookupSubframeworkHeader(StringRef Filename, // Otherwise, if it does, remember that this is the right direntry for this // framework. - CacheLookup.getValue().Directory = Dir; + CacheLookup.second.Directory = Dir; } const FileEntry *FE = nullptr; @@ -937,28 +936,6 @@ LookupSubframeworkHeader(StringRef Filename, return FE; } -/// \brief Helper static function to normalize a path for injection into -/// a synthetic header. -/*static*/ std::string -HeaderSearch::NormalizeDashIncludePath(StringRef File, FileManager &FileMgr) { - // Implicit include paths should be resolved relative to the current - // working directory first, and then use the regular header search - // mechanism. The proper way to handle this is to have the - // predefines buffer located at the current working directory, but - // it has no file entry. For now, workaround this by using an - // absolute path if we find the file here, and otherwise letting - // header search handle it. - SmallString<128> Path(File); - llvm::sys::fs::make_absolute(Path); - bool exists; - if (llvm::sys::fs::exists(Path.str(), exists) || !exists) - Path = File; - else if (exists) - FileMgr.getFile(File); - - return Lexer::Stringify(Path.str()); -} - //===----------------------------------------------------------------------===// // File Info Management. //===----------------------------------------------------------------------===// @@ -1084,13 +1061,13 @@ size_t HeaderSearch::getTotalMemory() const { } StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) { - return FrameworkNames.GetOrCreateValue(Framework).getKey(); + return FrameworkNames.insert(Framework).first->first(); } bool HeaderSearch::hasModuleMap(StringRef FileName, const DirectoryEntry *Root, bool IsSystem) { - if (!enabledModules()) + if (!enabledModules() || !LangOpts.ModulesImplicitMaps) return false; SmallVector<const DirectoryEntry *, 2> FixUpDirectories; @@ -1108,7 +1085,9 @@ bool HeaderSearch::hasModuleMap(StringRef FileName, return false; // Try to load the module map file in this directory. - switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/false)) { + switch (loadModuleMapFile(Dir, IsSystem, + llvm::sys::path::extension(Dir->getName()) == + ".framework")) { case LMM_NewlyLoaded: case LMM_AlreadyLoaded: // Success. All of the directories we stepped through inherit this module @@ -1142,11 +1121,10 @@ HeaderSearch::findModuleForHeader(const FileEntry *File) const { return ModMap.findModuleForHeader(File); } -static const FileEntry *getPrivateModuleMap(StringRef ModuleMapPath, - const DirectoryEntry *Directory, +static const FileEntry *getPrivateModuleMap(const FileEntry *File, FileManager &FileMgr) { - StringRef Filename = llvm::sys::path::filename(ModuleMapPath); - SmallString<128> PrivateFilename(Directory->getName()); + StringRef Filename = llvm::sys::path::filename(File->getName()); + SmallString<128> PrivateFilename(File->getDir()->getName()); if (Filename == "module.map") llvm::sys::path::append(PrivateFilename, "module_private.map"); else if (Filename == "module.modulemap") @@ -1157,7 +1135,25 @@ static const FileEntry *getPrivateModuleMap(StringRef ModuleMapPath, } bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem) { - switch (loadModuleMapFileImpl(File, IsSystem)) { + // Find the directory for the module. For frameworks, that may require going + // up from the 'Modules' directory. + const DirectoryEntry *Dir = nullptr; + if (getHeaderSearchOpts().ModuleMapFileHomeIsCwd) + Dir = FileMgr.getDirectory("."); + else { + Dir = File->getDir(); + StringRef DirName(Dir->getName()); + if (llvm::sys::path::filename(DirName) == "Modules") { + DirName = llvm::sys::path::parent_path(DirName); + if (DirName.endswith(".framework")) + Dir = FileMgr.getDirectory(DirName); + // FIXME: This assert can fail if there's a race between the above check + // and the removal of the directory. + assert(Dir && "parent must exist"); + } + } + + switch (loadModuleMapFileImpl(File, IsSystem, Dir)) { case LMM_AlreadyLoaded: case LMM_NewlyLoaded: return false; @@ -1169,35 +1165,37 @@ bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem) { } HeaderSearch::LoadModuleMapResult -HeaderSearch::loadModuleMapFileImpl(const FileEntry *File, bool IsSystem) { +HeaderSearch::loadModuleMapFileImpl(const FileEntry *File, bool IsSystem, + const DirectoryEntry *Dir) { assert(File && "expected FileEntry"); - const DirectoryEntry *Dir = File->getDir(); - auto KnownDir = DirectoryHasModuleMap.find(Dir); - if (KnownDir != DirectoryHasModuleMap.end()) - return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap; + // Check whether we've already loaded this module map, and mark it as being + // loaded in case we recursively try to load it from itself. + auto AddResult = LoadedModuleMaps.insert(std::make_pair(File, true)); + if (!AddResult.second) + return AddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap; - if (ModMap.parseModuleMapFile(File, IsSystem)) { - DirectoryHasModuleMap[Dir] = false; + if (ModMap.parseModuleMapFile(File, IsSystem, Dir)) { + LoadedModuleMaps[File] = false; return LMM_InvalidModuleMap; } // Try to load a corresponding private module map. - if (const FileEntry *PMMFile = - getPrivateModuleMap(File->getName(), Dir, FileMgr)) { - if (ModMap.parseModuleMapFile(PMMFile, IsSystem)) { - DirectoryHasModuleMap[Dir] = false; + if (const FileEntry *PMMFile = getPrivateModuleMap(File, FileMgr)) { + if (ModMap.parseModuleMapFile(PMMFile, IsSystem, Dir)) { + LoadedModuleMaps[File] = false; return LMM_InvalidModuleMap; } } // This directory has a module map. - DirectoryHasModuleMap[Dir] = true; return LMM_NewlyLoaded; } const FileEntry * HeaderSearch::lookupModuleMapFile(const DirectoryEntry *Dir, bool IsFramework) { + if (!LangOpts.ModulesImplicitMaps) + return nullptr; // For frameworks, the preferred spelling is Modules/module.modulemap, but // module.map at the framework root is also accepted. SmallString<128> ModuleMapFileName(Dir->getName()); @@ -1218,12 +1216,12 @@ Module *HeaderSearch::loadFrameworkModule(StringRef Name, bool IsSystem) { if (Module *Module = ModMap.findModule(Name)) return Module; - + // Try to load a module map file. switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/true)) { case LMM_InvalidModuleMap: break; - + case LMM_AlreadyLoaded: case LMM_NoDirectory: return nullptr; @@ -1234,7 +1232,10 @@ Module *HeaderSearch::loadFrameworkModule(StringRef Name, // Try to infer a module map from the framework directory. - return ModMap.inferFrameworkModule(Name, Dir, IsSystem, /*Parent=*/nullptr); + if (LangOpts.ModulesImplicitMaps) + return ModMap.inferFrameworkModule(Name, Dir, IsSystem, /*Parent=*/nullptr); + + return nullptr; } @@ -1252,15 +1253,18 @@ HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir, bool IsSystem, bool IsFramework) { auto KnownDir = DirectoryHasModuleMap.find(Dir); if (KnownDir != DirectoryHasModuleMap.end()) - return KnownDir->second? LMM_AlreadyLoaded : LMM_InvalidModuleMap; + return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap; if (const FileEntry *ModuleMapFile = lookupModuleMapFile(Dir, IsFramework)) { - LoadModuleMapResult Result = loadModuleMapFileImpl(ModuleMapFile, IsSystem); + LoadModuleMapResult Result = + loadModuleMapFileImpl(ModuleMapFile, IsSystem, Dir); // Add Dir explicitly in case ModuleMapFile is in a subdirectory. // E.g. Foo.framework/Modules/module.modulemap // ^Dir ^ModuleMapFile if (Result == LMM_NewlyLoaded) DirectoryHasModuleMap[Dir] = true; + else if (Result == LMM_InvalidModuleMap) + DirectoryHasModuleMap[Dir] = false; return Result; } return LMM_InvalidModuleMap; @@ -1268,45 +1272,49 @@ HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir, bool IsSystem, void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) { Modules.clear(); - - // Load module maps for each of the header search directories. - for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { - bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory(); - if (SearchDirs[Idx].isFramework()) { - std::error_code EC; - SmallString<128> DirNative; - llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->getName(), - DirNative); - - // Search each of the ".framework" directories to load them as modules. - for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; - Dir != DirEnd && !EC; Dir.increment(EC)) { - if (llvm::sys::path::extension(Dir->path()) != ".framework") - continue; - - const DirectoryEntry *FrameworkDir = FileMgr.getDirectory(Dir->path()); - if (!FrameworkDir) - continue; - - // Load this framework module. - loadFrameworkModule(llvm::sys::path::stem(Dir->path()), FrameworkDir, - IsSystem); + + if (LangOpts.ModulesImplicitMaps) { + // Load module maps for each of the header search directories. + for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { + bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory(); + if (SearchDirs[Idx].isFramework()) { + std::error_code EC; + SmallString<128> DirNative; + llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->getName(), + DirNative); + + // Search each of the ".framework" directories to load them as modules. + for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; + Dir != DirEnd && !EC; Dir.increment(EC)) { + if (llvm::sys::path::extension(Dir->path()) != ".framework") + continue; + + const DirectoryEntry *FrameworkDir = + FileMgr.getDirectory(Dir->path()); + if (!FrameworkDir) + continue; + + // Load this framework module. + loadFrameworkModule(llvm::sys::path::stem(Dir->path()), FrameworkDir, + IsSystem); + } + continue; } - continue; + + // FIXME: Deal with header maps. + if (SearchDirs[Idx].isHeaderMap()) + continue; + + // Try to load a module map file for the search directory. + loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem, + /*IsFramework*/ false); + + // Try to load module map files for immediate subdirectories of this + // search directory. + loadSubdirectoryModuleMaps(SearchDirs[Idx]); } - - // FIXME: Deal with header maps. - if (SearchDirs[Idx].isHeaderMap()) - continue; - - // Try to load a module map file for the search directory. - loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem, /*IsFramework*/false); - - // Try to load module map files for immediate subdirectories of this search - // directory. - loadSubdirectoryModuleMaps(SearchDirs[Idx]); } - + // Populate the list of modules. for (ModuleMap::module_iterator M = ModMap.module_begin(), MEnd = ModMap.module_end(); @@ -1316,6 +1324,9 @@ void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) { } void HeaderSearch::loadTopLevelSystemModules() { + if (!LangOpts.ModulesImplicitMaps) + return; + // Load module maps for each of the header search directories. for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { // We only care about normal header directories. @@ -1331,6 +1342,9 @@ void HeaderSearch::loadTopLevelSystemModules() { } void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) { + assert(LangOpts.ModulesImplicitMaps && + "Should not be loading subdirectory module maps"); + if (SearchDir.haveSearchedAllModuleMaps()) return; diff --git a/contrib/llvm/tools/clang/lib/Lex/Lexer.cpp b/contrib/llvm/tools/clang/lib/Lex/Lexer.cpp index 6f6b50b..ca5252e 100644 --- a/contrib/llvm/tools/clang/lib/Lex/Lexer.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/Lexer.cpp @@ -540,16 +540,16 @@ namespace { }; } -std::pair<unsigned, bool> -Lexer::ComputePreamble(const llvm::MemoryBuffer *Buffer, - const LangOptions &LangOpts, unsigned MaxLines) { +std::pair<unsigned, bool> Lexer::ComputePreamble(StringRef Buffer, + const LangOptions &LangOpts, + unsigned MaxLines) { // Create a lexer starting at the beginning of the file. Note that we use a // "fake" file source location at offset 1 so that the lexer will track our // position within the file. const unsigned StartOffset = 1; SourceLocation FileLoc = SourceLocation::getFromRawEncoding(StartOffset); - Lexer TheLexer(FileLoc, LangOpts, Buffer->getBufferStart(), - Buffer->getBufferStart(), Buffer->getBufferEnd()); + Lexer TheLexer(FileLoc, LangOpts, Buffer.begin(), Buffer.begin(), + Buffer.end()); TheLexer.SetCommentRetentionState(true); // StartLoc will differ from FileLoc if there is a BOM that was skipped. @@ -563,9 +563,9 @@ Lexer::ComputePreamble(const llvm::MemoryBuffer *Buffer, unsigned MaxLineOffset = 0; if (MaxLines) { - const char *CurPtr = Buffer->getBufferStart(); + const char *CurPtr = Buffer.begin(); unsigned CurLine = 0; - while (CurPtr != Buffer->getBufferEnd()) { + while (CurPtr != Buffer.end()) { char ch = *CurPtr++; if (ch == '\n') { ++CurLine; @@ -573,8 +573,8 @@ Lexer::ComputePreamble(const llvm::MemoryBuffer *Buffer, break; } } - if (CurPtr != Buffer->getBufferEnd()) - MaxLineOffset = CurPtr - Buffer->getBufferStart(); + if (CurPtr != Buffer.end()) + MaxLineOffset = CurPtr - Buffer.begin(); } do { @@ -1597,7 +1597,7 @@ bool Lexer::LexNumericConstant(Token &Result, const char *CurPtr) { } // If we have a digit separator, continue. - if (C == '\'' && getLangOpts().CPlusPlus1y) { + if (C == '\'' && getLangOpts().CPlusPlus14) { unsigned NextSize; char Next = getCharAndSizeNoWarn(CurPtr + Size, NextSize, getLangOpts()); if (isIdentifierBody(Next)) { @@ -1660,7 +1660,7 @@ const char *Lexer::LexUDSuffix(Token &Result, const char *CurPtr, bool IsUDSuffix = false; if (C == '_') IsUDSuffix = true; - else if (IsStringLiteral && getLangOpts().CPlusPlus1y) { + else if (IsStringLiteral && getLangOpts().CPlusPlus14) { // In C++1y, we need to look ahead a few characters to see if this is a // valid suffix for a string literal or a numeric literal (this could be // the 'operator""if' defining a numeric literal operator). @@ -1889,17 +1889,20 @@ bool Lexer::LexAngledStringLiteral(Token &Result, const char *CurPtr) { /// LexCharConstant - Lex the remainder of a character constant, after having -/// lexed either ' or L' or u' or U'. +/// lexed either ' or L' or u8' or u' or U'. bool Lexer::LexCharConstant(Token &Result, const char *CurPtr, tok::TokenKind Kind) { // Does this character contain the \0 character? const char *NulCharacter = nullptr; - if (!isLexingRawMode() && - (Kind == tok::utf16_char_constant || Kind == tok::utf32_char_constant)) - Diag(BufferPtr, getLangOpts().CPlusPlus - ? diag::warn_cxx98_compat_unicode_literal - : diag::warn_c99_compat_unicode_literal); + if (!isLexingRawMode()) { + if (Kind == tok::utf16_char_constant || Kind == tok::utf32_char_constant) + Diag(BufferPtr, getLangOpts().CPlusPlus + ? diag::warn_cxx98_compat_unicode_literal + : diag::warn_c99_compat_unicode_literal); + else if (Kind == tok::utf8_char_constant) + Diag(BufferPtr, diag::warn_cxx14_compat_u8_character_literal); + } char C = getAndAdvanceChar(CurPtr, Result); if (C == '\'') { @@ -2319,7 +2322,7 @@ bool Lexer::SkipBlockComment(Token &Result, const char *CurPtr, '/', '/', '/', '/', '/', '/', '/', '/' }; while (CurPtr+16 <= BufferEnd && - !vec_any_eq(*(vector unsigned char*)CurPtr, Slashes)) + !vec_any_eq(*(const vector unsigned char*)CurPtr, Slashes)) CurPtr += 16; #else // Scan for '/' quickly. Many block comments are very large. @@ -2585,8 +2588,8 @@ static const char *FindConflictEnd(const char *CurPtr, const char *BufferEnd, size_t Pos = RestOfBuffer.find(Terminator); while (Pos != StringRef::npos) { // Must occur at start of line. - if (RestOfBuffer[Pos-1] != '\r' && - RestOfBuffer[Pos-1] != '\n') { + if (Pos == 0 || + (RestOfBuffer[Pos - 1] != '\r' && RestOfBuffer[Pos - 1] != '\n')) { RestOfBuffer = RestOfBuffer.substr(Pos+TermLen); Pos = RestOfBuffer.find(Terminator); continue; @@ -3068,6 +3071,11 @@ LexNextToken: ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result), SizeTmp2, Result), tok::utf8_string_literal); + if (Char2 == '\'' && LangOpts.CPlusPlus1z) + return LexCharConstant( + Result, ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result), + SizeTmp2, Result), + tok::utf8_char_constant); if (Char2 == 'R' && LangOpts.CPlusPlus11) { unsigned SizeTmp3; diff --git a/contrib/llvm/tools/clang/lib/Lex/LiteralSupport.cpp b/contrib/llvm/tools/clang/lib/Lex/LiteralSupport.cpp index 6417d0f..03331fb 100644 --- a/contrib/llvm/tools/clang/lib/Lex/LiteralSupport.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/LiteralSupport.cpp @@ -28,6 +28,7 @@ static unsigned getCharWidth(tok::TokenKind kind, const TargetInfo &Target) { default: llvm_unreachable("Unknown token type!"); case tok::char_constant: case tok::string_literal: + case tok::utf8_char_constant: case tok::utf8_string_literal: return Target.getCharWidth(); case tok::wide_char_constant: @@ -656,7 +657,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, } } // "i", "if", and "il" are user-defined suffixes in C++1y. - if (PP.getLangOpts().CPlusPlus1y && *s == 'i') + if (PP.getLangOpts().CPlusPlus14 && *s == 'i') break; // fall through. case 'j': @@ -716,7 +717,7 @@ bool NumericLiteralParser::isValidUDSuffix(const LangOptions &LangOpts, return true; // In C++11, there are no library suffixes. - if (!LangOpts.CPlusPlus1y) + if (!LangOpts.CPlusPlus14) return false; // In C++1y, "s", "h", "min", "ms", "us", and "ns" are used in the library. @@ -813,10 +814,10 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) { if ((c1 == 'b' || c1 == 'B') && (c2 == '0' || c2 == '1')) { // 0b101010 is a C++1y / GCC extension. PP.Diag(TokLoc, - PP.getLangOpts().CPlusPlus1y + PP.getLangOpts().CPlusPlus14 ? diag::warn_cxx11_compat_binary_literal : PP.getLangOpts().CPlusPlus - ? diag::ext_binary_literal_cxx1y + ? diag::ext_binary_literal_cxx14 : diag::ext_binary_literal); ++s; radix = 2; @@ -1031,9 +1032,10 @@ CharLiteralParser::CharLiteralParser(const char *begin, const char *end, const char *TokBegin = begin; // Skip over wide character determinant. - if (Kind != tok::char_constant) { + if (Kind != tok::char_constant) + ++begin; + if (Kind == tok::utf8_char_constant) ++begin; - } // Skip over the entry quote. assert(begin[0] == '\'' && "Invalid token lexed"); @@ -1077,6 +1079,8 @@ CharLiteralParser::CharLiteralParser(const char *begin, const char *end, if (tok::wide_char_constant == Kind) { largest_character_for_kind = 0xFFFFFFFFu >> (32-PP.getTargetInfo().getWCharWidth()); + } else if (tok::utf8_char_constant == Kind) { + largest_character_for_kind = 0x7F; } else if (tok::utf16_char_constant == Kind) { largest_character_for_kind = 0xFFFF; } else if (tok::utf32_char_constant == Kind) { diff --git a/contrib/llvm/tools/clang/lib/Lex/MacroArgs.cpp b/contrib/llvm/tools/clang/lib/Lex/MacroArgs.cpp index a746fb7..9967f3f 100644 --- a/contrib/llvm/tools/clang/lib/Lex/MacroArgs.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/MacroArgs.cpp @@ -218,6 +218,7 @@ Token MacroArgs::StringifyArgument(const Token *ArgToks, if (tok::isStringLiteral(Tok.getKind()) || // "foo", u8R"x(foo)x"_bar, etc. Tok.is(tok::char_constant) || // 'x' Tok.is(tok::wide_char_constant) || // L'x'. + Tok.is(tok::utf8_char_constant) || // u8'x'. Tok.is(tok::utf16_char_constant) || // u'x'. Tok.is(tok::utf32_char_constant)) { // U'x'. bool Invalid = false; @@ -233,14 +234,14 @@ Token MacroArgs::StringifyArgument(const Token *ArgToks, // in place and avoid copies where possible. unsigned CurStrLen = Result.size(); Result.resize(CurStrLen+Tok.getLength()); - const char *BufPtr = &Result[CurStrLen]; + const char *BufPtr = Result.data() + CurStrLen; bool Invalid = false; unsigned ActualTokLen = PP.getSpelling(Tok, BufPtr, &Invalid); if (!Invalid) { // If getSpelling returned a pointer to an already uniqued version of // the string instead of filling in BufPtr, memcpy it onto our string. - if (BufPtr != &Result[CurStrLen]) + if (ActualTokLen && BufPtr != &Result[CurStrLen]) memcpy(&Result[CurStrLen], BufPtr, ActualTokLen); // If the token was dirty, the spelling may be shorter than the token. diff --git a/contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp b/contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp index 8fae9c9..ef322d8 100644 --- a/contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp @@ -19,6 +19,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" #include "clang/Lex/HeaderSearch.h" +#include "clang/Lex/HeaderSearchOptions.h" #include "clang/Lex/LexDiagnostic.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/LiteralSupport.h" @@ -202,7 +203,7 @@ ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File, return KnownHeader(); } -// Returns 'true' if 'RequestingModule directly uses 'RequestedModule'. +// Returns true if RequestingModule directly uses RequestedModule. static bool directlyUses(const Module *RequestingModule, const Module *RequestedModule) { return std::find(RequestingModule->DirectUses.begin(), @@ -214,19 +215,23 @@ static bool violatesPrivateInclude(Module *RequestingModule, const FileEntry *IncFileEnt, ModuleMap::ModuleHeaderRole Role, Module *RequestedModule) { - #ifndef NDEBUG + bool IsPrivateRole = Role & ModuleMap::PrivateHeader; +#ifndef NDEBUG // Check for consistency between the module header role // as obtained from the lookup and as obtained from the module. // This check is not cheap, so enable it only for debugging. - SmallVectorImpl<const FileEntry *> &PvtHdrs - = RequestedModule->PrivateHeaders; - SmallVectorImpl<const FileEntry *>::iterator Look - = std::find(PvtHdrs.begin(), PvtHdrs.end(), IncFileEnt); - bool IsPrivate = Look != PvtHdrs.end(); - assert((IsPrivate && Role == ModuleMap::PrivateHeader) - || (!IsPrivate && Role != ModuleMap::PrivateHeader)); - #endif - return Role == ModuleMap::PrivateHeader && + bool IsPrivate = false; + SmallVectorImpl<Module::Header> *HeaderList[] = + {&RequestedModule->Headers[Module::HK_Private], + &RequestedModule->Headers[Module::HK_PrivateTextual]}; + for (auto *Hdrs : HeaderList) + IsPrivate |= + std::find_if(Hdrs->begin(), Hdrs->end(), [&](const Module::Header &H) { + return H.Entry == IncFileEnt; + }) != Hdrs->end(); + assert(IsPrivate == IsPrivateRole && "inconsistent headers and roles"); +#endif + return IsPrivateRole && RequestedModule->getTopLevelModule() != RequestingModule; } @@ -253,12 +258,6 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule, HeadersMap::iterator Known = findKnownHeader(File); if (Known != Headers.end()) { for (const KnownHeader &Header : Known->second) { - // Excluded headers don't really belong to a module. - if (Header.getRole() == ModuleMap::ExcludedHeader) { - Excluded = true; - continue; - } - // If 'File' is part of 'RequestingModule' we can definitely include it. if (Header.getModule() == RequestingModule) return; @@ -281,6 +280,8 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule, // We have found a module that we can happily use. return; } + + Excluded = true; } // We have found a header, but it is private. @@ -315,20 +316,23 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule, ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File, - Module *RequestingModule) { + Module *RequestingModule, + bool IncludeTextualHeaders) { HeadersMap::iterator Known = findKnownHeader(File); + auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader { + if (!IncludeTextualHeaders && (R.getRole() & ModuleMap::TextualHeader)) + return ModuleMap::KnownHeader(); + return R; + }; + if (Known != Headers.end()) { - ModuleMap::KnownHeader Result = KnownHeader(); + ModuleMap::KnownHeader Result; // Iterate over all modules that 'File' is part of to find the best fit. for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(), E = Known->second.end(); I != E; ++I) { - // Cannot use a module if the header is excluded in it. - if (I->getRole() == ModuleMap::ExcludedHeader) - continue; - // Cannot use a module if it is unavailable. if (!I->getModule()->isAvailable()) continue; @@ -336,7 +340,7 @@ ModuleMap::findModuleForHeader(const FileEntry *File, // If 'File' is part of 'RequestingModule', 'RequestingModule' is the // module we are looking for. if (I->getModule() == RequestingModule) - return *I; + return MakeResult(*I); // If uses need to be specified explicitly, we are only allowed to return // modules that are explicitly used by the requesting module. @@ -344,15 +348,11 @@ ModuleMap::findModuleForHeader(const FileEntry *File, !directlyUses(RequestingModule, I->getModule())) continue; - Result = *I; - // If 'File' is a public header of this module, this is as good as we - // are going to get. - // FIXME: If we have a RequestingModule, we should prefer the header from - // that module. - if (I->getRole() == ModuleMap::NormalHeader) - break; + // Prefer a public header over a private header. + if (!Result || (Result.getRole() & ModuleMap::PrivateHeader)) + Result = *I; } - return Result; + return MakeResult(Result); } SmallVector<const DirectoryEntry *, 2> SkippedDirs; @@ -367,6 +367,9 @@ ModuleMap::findModuleForHeader(const FileEntry *File, UmbrellaModule = UmbrellaModule->Parent; if (UmbrellaModule->InferSubmodules) { + const FileEntry *UmbrellaModuleMap = + getModuleMapFileForUniquing(UmbrellaModule); + // Infer submodules for each of the directories we found between // the directory of the umbrella header and the directory where // the actual header is located. @@ -377,8 +380,9 @@ ModuleMap::findModuleForHeader(const FileEntry *File, SmallString<32> NameBuf; StringRef Name = sanitizeFilenameAsIdentifier( llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf); - Result = findOrCreateModule(Name, Result, UmbrellaModule->ModuleMap, - /*IsFramework=*/false, Explicit).first; + Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, + Explicit).first; + InferredModuleAllowedBy[Result] = UmbrellaModuleMap; Result->IsInferred = true; // Associate the module and the directory. @@ -394,8 +398,9 @@ ModuleMap::findModuleForHeader(const FileEntry *File, SmallString<32> NameBuf; StringRef Name = sanitizeFilenameAsIdentifier( llvm::sys::path::stem(File->getName()), NameBuf); - Result = findOrCreateModule(Name, Result, UmbrellaModule->ModuleMap, - /*IsFramework=*/false, Explicit).first; + Result = findOrCreateModule(Name, Result, /*IsFramework=*/false, + Explicit).first; + InferredModuleAllowedBy[Result] = UmbrellaModuleMap; Result->IsInferred = true; Result->addTopHeader(File); @@ -417,9 +422,9 @@ ModuleMap::findModuleForHeader(const FileEntry *File, if (!Result->isAvailable()) return KnownHeader(); - return Headers[File].back(); + return MakeResult(Headers[File].back()); } - + return KnownHeader(); } @@ -535,15 +540,14 @@ Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{ } std::pair<Module *, bool> -ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, - const FileEntry *ModuleMap, bool IsFramework, +ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit) { // Try to find an existing module with this name. if (Module *Sub = lookupModuleQualified(Name, Parent)) return std::make_pair(Sub, false); // Create a new module with this name. - Module *Result = new Module(Name, SourceLocation(), Parent, ModuleMap, + Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework, IsExplicit); if (LangOpts.CurrentModule == Name) { SourceModule = Result; @@ -559,30 +563,6 @@ ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, return std::make_pair(Result, true); } -bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir, - StringRef Name, bool &IsSystem) const { - // Check whether we have already looked into the parent directory - // for a module map. - llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator - inferred = InferredDirectories.find(ParentDir); - if (inferred == InferredDirectories.end()) - return false; - - if (!inferred->second.InferModules) - return false; - - // We're allowed to infer for this directory, but make sure it's okay - // to infer this particular module. - bool canInfer = std::find(inferred->second.ExcludedModules.begin(), - inferred->second.ExcludedModules.end(), - Name) == inferred->second.ExcludedModules.end(); - - if (canInfer && inferred->second.InferSystemModules) - IsSystem = true; - - return canInfer; -} - /// \brief For a framework module, infer the framework against which we /// should link. static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir, @@ -605,6 +585,15 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName, const DirectoryEntry *FrameworkDir, bool IsSystem, Module *Parent) { + Attributes Attrs; + Attrs.IsSystem = IsSystem; + return inferFrameworkModule(ModuleName, FrameworkDir, Attrs, Parent); +} + +Module *ModuleMap::inferFrameworkModule(StringRef ModuleName, + const DirectoryEntry *FrameworkDir, + Attributes Attrs, Module *Parent) { + // Check whether we've already found this module. if (Module *Mod = lookupModuleQualified(ModuleName, Parent)) return Mod; @@ -645,7 +634,7 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName, bool IsFrameworkDir = Parent.endswith(".framework"); if (const FileEntry *ModMapFile = HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) { - parseModuleMapFile(ModMapFile, IsSystem); + parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir); inferred = InferredDirectories.find(ParentDir); } @@ -662,8 +651,9 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName, inferred->second.ExcludedModules.end(), Name) == inferred->second.ExcludedModules.end(); - if (inferred->second.InferSystemModules) - IsSystem = true; + Attrs.IsSystem |= inferred->second.Attrs.IsSystem; + Attrs.IsExternC |= inferred->second.Attrs.IsExternC; + Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive; ModuleMapFile = inferred->second.ModuleMapFile; } } @@ -673,7 +663,7 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName, if (!canInfer) return nullptr; } else - ModuleMapFile = Parent->ModuleMap; + ModuleMapFile = getModuleMapFileForUniquing(Parent); // Look for an umbrella header. @@ -687,15 +677,19 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName, if (!UmbrellaHeader) return nullptr; - Module *Result = new Module(ModuleName, SourceLocation(), Parent, ModuleMapFile, + Module *Result = new Module(ModuleName, SourceLocation(), Parent, /*IsFramework=*/true, /*IsExplicit=*/false); + InferredModuleAllowedBy[Result] = ModuleMapFile; + Result->IsInferred = true; if (LangOpts.CurrentModule == ModuleName) { SourceModule = Result; SourceModuleName = ModuleName; } - if (IsSystem) - Result->IsSystem = IsSystem; - + + Result->IsSystem |= Attrs.IsSystem; + Result->IsExternC |= Attrs.IsExternC; + Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive; + if (!Parent) Modules[ModuleName] = Result; @@ -750,8 +744,8 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName, // FIXME: Do we want to warn about subframeworks without umbrella headers? SmallString<32> NameBuf; inferFrameworkModule(sanitizeFilenameAsIdentifier( - llvm::sys::path::stem(Dir->path()), NameBuf), - SubframeworkDir, IsSystem, Result); + llvm::sys::path::stem(Dir->path()), NameBuf), + SubframeworkDir, Attrs, Result); } } @@ -775,23 +769,44 @@ void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) { UmbrellaDirs[UmbrellaDir] = Mod; } -void ModuleMap::addHeader(Module *Mod, const FileEntry *Header, +static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) { + switch ((int)Role) { + default: llvm_unreachable("unknown header role"); + case ModuleMap::NormalHeader: + return Module::HK_Normal; + case ModuleMap::PrivateHeader: + return Module::HK_Private; + case ModuleMap::TextualHeader: + return Module::HK_Textual; + case ModuleMap::PrivateHeader | ModuleMap::TextualHeader: + return Module::HK_PrivateTextual; + } +} + +void ModuleMap::addHeader(Module *Mod, Module::Header Header, ModuleHeaderRole Role) { - if (Role == ExcludedHeader) { - Mod->ExcludedHeaders.push_back(Header); - } else { - if (Role == PrivateHeader) - Mod->PrivateHeaders.push_back(Header); - else - Mod->NormalHeaders.push_back(Header); + if (!(Role & TextualHeader)) { bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule; - HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader); + HeaderInfo.MarkFileModuleHeader(Header.Entry, Role, + isCompilingModuleHeader); } - Headers[Header].push_back(KnownHeader(Mod, Role)); + Headers[Header.Entry].push_back(KnownHeader(Mod, Role)); + + Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header)); +} + +void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) { + // Add this as a known header so we won't implicitly add it to any + // umbrella directory module. + // FIXME: Should we only exclude it from umbrella modules within the + // specified module? + (void) Headers[Header.Entry]; + + Mod->Headers[Module::HK_Excluded].push_back(std::move(Header)); } const FileEntry * -ModuleMap::getContainingModuleMapFile(Module *Module) const { +ModuleMap::getContainingModuleMapFile(const Module *Module) const { if (Module->DefinitionLoc.isInvalid()) return nullptr; @@ -799,6 +814,19 @@ ModuleMap::getContainingModuleMapFile(Module *Module) const { SourceMgr.getFileID(Module->DefinitionLoc)); } +const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const { + if (M->IsInferred) { + assert(InferredModuleAllowedBy.count(M) && "missing inferred module map"); + return InferredModuleAllowedBy.find(M)->second; + } + return getContainingModuleMapFile(M); +} + +void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) { + assert(M->IsInferred && "module not inferred"); + InferredModuleAllowedBy[M] = ModMap; +} + void ModuleMap::dump() { llvm::errs() << "Modules:"; for (llvm::StringMap<Module *>::iterator M = Modules.begin(), @@ -927,6 +955,7 @@ namespace clang { RequiresKeyword, Star, StringLiteral, + TextualKeyword, LBrace, RBrace, LSquare, @@ -955,21 +984,6 @@ namespace clang { } }; - /// \brief The set of attributes that can be attached to a module. - struct Attributes { - Attributes() : IsSystem(), IsExternC(), IsExhaustive() { } - - /// \brief Whether this is a system module. - unsigned IsSystem : 1; - - /// \brief Whether this is an extern "C" module. - unsigned IsExternC : 1; - - /// \brief Whether this is an exhaustive set of configuration macros. - unsigned IsExhaustive : 1; - }; - - class ModuleMapParser { Lexer &L; SourceManager &SourceMgr; @@ -984,7 +998,8 @@ namespace clang { /// \brief The current module map file. const FileEntry *ModuleMapFile; - /// \brief The directory that this module map resides in. + /// \brief The directory that file names in this module map file should + /// be resolved relative to. const DirectoryEntry *Directory; /// \brief The directory containing Clang-supplied headers. @@ -1027,6 +1042,8 @@ namespace clang { void parseConfigMacros(); void parseConflict(); void parseInferredModuleDecl(bool Framework, bool Explicit); + + typedef ModuleMap::Attributes Attributes; bool parseOptionalAttributes(Attributes &Attrs); public: @@ -1077,6 +1094,7 @@ retry: .Case("module", MMToken::ModuleKeyword) .Case("private", MMToken::PrivateKeyword) .Case("requires", MMToken::RequiresKeyword) + .Case("textual", MMToken::TextualKeyword) .Case("umbrella", MMToken::UmbrellaKeyword) .Case("use", MMToken::UseKeyword) .Default(MMToken::Identifier); @@ -1328,8 +1346,11 @@ void ModuleMapParser::parseModuleDecl() { // This module map defines a submodule. Go find the module of which it // is a submodule. ActiveModule = nullptr; + const Module *TopLevelModule = nullptr; for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) { if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) { + if (I == 0) + TopLevelModule = Next; ActiveModule = Next; continue; } @@ -1344,7 +1365,14 @@ void ModuleMapParser::parseModuleDecl() { HadError = true; return; } - } + + if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) { + assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) && + "submodule defined in same file as 'module *' that allowed its " + "top-level module"); + Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile); + } + } StringRef ModuleName = Id.back().first; SourceLocation ModuleNameLoc = Id.back().second; @@ -1390,19 +1418,15 @@ void ModuleMapParser::parseModuleDecl() { return; } - // If this is a submodule, use the parent's module map, since we don't want - // the private module map file. - const FileEntry *ModuleMap = ActiveModule ? ActiveModule->ModuleMap - : ModuleMapFile; - // Start defining this module. - ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, ModuleMap, - Framework, Explicit).first; + ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework, + Explicit).first; ActiveModule->DefinitionLoc = ModuleNameLoc; if (Attrs.IsSystem || IsSystem) ActiveModule->IsSystem = true; if (Attrs.IsExternC) ActiveModule->IsExternC = true; + ActiveModule->Directory = Directory; bool Done = false; do { @@ -1439,6 +1463,10 @@ void ModuleMapParser::parseModuleDecl() { parseRequiresDecl(); break; + case MMToken::TextualKeyword: + parseHeaderDecl(MMToken::TextualKeyword, consumeToken()); + break; + case MMToken::UmbrellaKeyword: { SourceLocation UmbrellaLoc = consumeToken(); if (Tok.is(MMToken::HeaderKeyword)) @@ -1447,31 +1475,17 @@ void ModuleMapParser::parseModuleDecl() { parseUmbrellaDirDecl(UmbrellaLoc); break; } - - case MMToken::ExcludeKeyword: { - SourceLocation ExcludeLoc = consumeToken(); - if (Tok.is(MMToken::HeaderKeyword)) { - parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc); - } else { - Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) - << "exclude"; - } + + case MMToken::ExcludeKeyword: + parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken()); break; - } - - case MMToken::PrivateKeyword: { - SourceLocation PrivateLoc = consumeToken(); - if (Tok.is(MMToken::HeaderKeyword)) { - parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc); - } else { - Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) - << "private"; - } + + case MMToken::PrivateKeyword: + parseHeaderDecl(MMToken::PrivateKeyword, consumeToken()); break; - } - + case MMToken::HeaderKeyword: - parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation()); + parseHeaderDecl(MMToken::HeaderKeyword, consumeToken()); break; case MMToken::LinkKeyword: @@ -1554,7 +1568,11 @@ void ModuleMapParser::parseExternModuleDecl() { FileNameRef = ModuleMapFileName.str(); } if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef)) - Map.parseModuleMapFile(File, /*IsSystem=*/false); + Map.parseModuleMapFile( + File, /*IsSystem=*/false, + Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd + ? Directory + : File->getDir()); } /// \brief Parse a requires declaration. @@ -1626,12 +1644,37 @@ static void appendSubframeworkPaths(Module *Mod, /// \brief Parse a header declaration. /// /// header-declaration: -/// 'umbrella'[opt] 'header' string-literal -/// 'exclude'[opt] 'header' string-literal +/// 'textual'[opt] 'header' string-literal +/// 'private' 'textual'[opt] 'header' string-literal +/// 'exclude' 'header' string-literal +/// 'umbrella' 'header' string-literal +/// +/// FIXME: Support 'private textual header'. void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, SourceLocation LeadingLoc) { - assert(Tok.is(MMToken::HeaderKeyword)); - consumeToken(); + // We've already consumed the first token. + ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; + if (LeadingToken == MMToken::PrivateKeyword) { + Role = ModuleMap::PrivateHeader; + // 'private' may optionally be followed by 'textual'. + if (Tok.is(MMToken::TextualKeyword)) { + LeadingToken = Tok.Kind; + consumeToken(); + } + } + if (LeadingToken == MMToken::TextualKeyword) + Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); + + if (LeadingToken != MMToken::HeaderKeyword) { + if (!Tok.is(MMToken::HeaderKeyword)) { + Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) + << (LeadingToken == MMToken::PrivateKeyword ? "private" : + LeadingToken == MMToken::ExcludeKeyword ? "exclude" : + LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella"); + return; + } + consumeToken(); + } // Parse the header name. if (!Tok.is(MMToken::StringLiteral)) { @@ -1640,7 +1683,7 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, HadError = true; return; } - Module::HeaderDirective Header; + Module::UnresolvedHeaderDirective Header; Header.FileName = Tok.getString(); Header.FileNameLoc = consumeToken(); @@ -1655,33 +1698,39 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, // Look for this file. const FileEntry *File = nullptr; const FileEntry *BuiltinFile = nullptr; - SmallString<128> PathName; + SmallString<128> RelativePathName; if (llvm::sys::path::is_absolute(Header.FileName)) { - PathName = Header.FileName; - File = SourceMgr.getFileManager().getFile(PathName); + RelativePathName = Header.FileName; + File = SourceMgr.getFileManager().getFile(RelativePathName); } else { // Search for the header file within the search directory. - PathName = Directory->getName(); - unsigned PathLength = PathName.size(); + SmallString<128> FullPathName(Directory->getName()); + unsigned FullPathLength = FullPathName.size(); if (ActiveModule->isPartOfFramework()) { - appendSubframeworkPaths(ActiveModule, PathName); + appendSubframeworkPaths(ActiveModule, RelativePathName); // Check whether this file is in the public headers. - llvm::sys::path::append(PathName, "Headers", Header.FileName); - File = SourceMgr.getFileManager().getFile(PathName); + llvm::sys::path::append(RelativePathName, "Headers", Header.FileName); + llvm::sys::path::append(FullPathName, RelativePathName.str()); + File = SourceMgr.getFileManager().getFile(FullPathName); if (!File) { // Check whether this file is in the private headers. - PathName.resize(PathLength); - llvm::sys::path::append(PathName, "PrivateHeaders", Header.FileName); - File = SourceMgr.getFileManager().getFile(PathName); + // FIXME: Should we retain the subframework paths here? + RelativePathName.clear(); + FullPathName.resize(FullPathLength); + llvm::sys::path::append(RelativePathName, "PrivateHeaders", + Header.FileName); + llvm::sys::path::append(FullPathName, RelativePathName.str()); + File = SourceMgr.getFileManager().getFile(FullPathName); } } else { // Lookup for normal headers. - llvm::sys::path::append(PathName, Header.FileName); - File = SourceMgr.getFileManager().getFile(PathName); - + llvm::sys::path::append(RelativePathName, Header.FileName); + llvm::sys::path::append(FullPathName, RelativePathName.str()); + File = SourceMgr.getFileManager().getFile(FullPathName); + // If this is a system module with a top-level header, this header // may have a counterpart (or replacement) in the set of headers // supplied by Clang. Find that builtin header. @@ -1691,18 +1740,19 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName()); llvm::sys::path::append(BuiltinPathName, Header.FileName); BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName); - + // If Clang supplies this header but the underlying system does not, // just silently swap in our builtin version. Otherwise, we'll end // up adding both (later). if (!File && BuiltinFile) { File = BuiltinFile; + RelativePathName = BuiltinPathName; BuiltinFile = nullptr; } } } } - + // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. // Come up with a lazy way to do this. if (File) { @@ -1716,21 +1766,24 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, // Record this umbrella header. Map.setUmbrellaHeader(ActiveModule, File); } + } else if (LeadingToken == MMToken::ExcludeKeyword) { + Module::Header H = {RelativePathName.str(), File}; + Map.excludeHeader(ActiveModule, H); } else { + // If there is a builtin counterpart to this file, add it now, before + // the "real" header, so we build the built-in one first when building + // the module. + if (BuiltinFile) { + // FIXME: Taking the name from the FileEntry is unstable and can give + // different results depending on how we've previously named that file + // in this build. + Module::Header H = { BuiltinFile->getName(), BuiltinFile }; + Map.addHeader(ActiveModule, H, Role); + } + // Record this header. - ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; - if (LeadingToken == MMToken::ExcludeKeyword) - Role = ModuleMap::ExcludedHeader; - else if (LeadingToken == MMToken::PrivateKeyword) - Role = ModuleMap::PrivateHeader; - else - assert(LeadingToken == MMToken::HeaderKeyword); - - Map.addHeader(ActiveModule, File, Role); - - // If there is a builtin counterpart to this file, add it now. - if (BuiltinFile) - Map.addHeader(ActiveModule, BuiltinFile, Role); + Module::Header H = { RelativePathName.str(), File }; + Map.addHeader(ActiveModule, H, Role); } } else if (LeadingToken != MMToken::ExcludeKeyword) { // Ignore excluded header files. They're optional anyway. @@ -1813,6 +1866,7 @@ void ModuleMapParser::parseExportDecl() { ModuleId ParsedModuleId; bool Wildcard = false; do { + // FIXME: Support string-literal module names here. if (Tok.is(MMToken::Identifier)) { ParsedModuleId.push_back(std::make_pair(Tok.getString(), Tok.getLocation())); @@ -1910,6 +1964,7 @@ void ModuleMapParser::parseConfigMacros() { } // If we don't have an identifier, we're done. + // FIXME: Support macros with the same name as a keyword here. if (!Tok.is(MMToken::Identifier)) return; @@ -1926,6 +1981,7 @@ void ModuleMapParser::parseConfigMacros() { consumeToken(); // We expect to see a macro name here. + // FIXME: Support macros with the same name as a keyword here. if (!Tok.is(MMToken::Identifier)) { Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro); break; @@ -2060,7 +2116,7 @@ void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { } else { // We'll be inferring framework modules for this directory. Map.InferredDirectories[Directory].InferModules = true; - Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem; + Map.InferredDirectories[Directory].Attrs = Attrs; Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile; // FIXME: Handle the 'framework' keyword. } @@ -2091,6 +2147,7 @@ void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { } consumeToken(); + // FIXME: Support string-literal module names here. if (!Tok.is(MMToken::Identifier)) { Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name); break; @@ -2246,6 +2303,7 @@ bool ModuleMapParser::parseModuleMapFile() { case MMToken::RequiresKeyword: case MMToken::Star: case MMToken::StringLiteral: + case MMToken::TextualKeyword: case MMToken::UmbrellaKeyword: case MMToken::UseKeyword: Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module); @@ -2256,7 +2314,8 @@ bool ModuleMapParser::parseModuleMapFile() { } while (true); } -bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) { +bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem, + const DirectoryEntry *Dir) { llvm::DenseMap<const FileEntry *, bool>::iterator Known = ParsedModuleMap.find(File); if (Known != ParsedModuleMap.end()) @@ -2269,17 +2328,6 @@ bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) { if (!Buffer) return ParsedModuleMap[File] = true; - // Find the directory for the module. For frameworks, that may require going - // up from the 'Modules' directory. - const DirectoryEntry *Dir = File->getDir(); - StringRef DirName(Dir->getName()); - if (llvm::sys::path::filename(DirName) == "Modules") { - DirName = llvm::sys::path::parent_path(DirName); - if (DirName.endswith(".framework")) - Dir = SourceMgr.getFileManager().getDirectory(DirName); - assert(Dir && "parent must exist"); - } - // Parse this module map file. Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts); ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir, diff --git a/contrib/llvm/tools/clang/lib/Lex/PPDirectives.cpp b/contrib/llvm/tools/clang/lib/Lex/PPDirectives.cpp index 1741c30..bf0ce72 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PPDirectives.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/PPDirectives.cpp @@ -25,7 +25,7 @@ #include "clang/Lex/Pragma.h" #include "llvm/ADT/APInt.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" #include "llvm/Support/SaveAndRestore.h" using namespace clang; @@ -34,23 +34,10 @@ using namespace clang; //===----------------------------------------------------------------------===// MacroInfo *Preprocessor::AllocateMacroInfo() { - MacroInfoChain *MIChain; - - if (MICache) { - MIChain = MICache; - MICache = MICache->Next; - } - else { - MIChain = BP.Allocate<MacroInfoChain>(); - } - + MacroInfoChain *MIChain = BP.Allocate<MacroInfoChain>(); MIChain->Next = MIChainHead; - MIChain->Prev = nullptr; - if (MIChainHead) - MIChainHead->Prev = MIChain; MIChainHead = MIChain; - - return &(MIChain->MI); + return &MIChain->MI; } MacroInfo *Preprocessor::AllocateMacroInfo(SourceLocation L) { @@ -77,45 +64,30 @@ MacroInfo *Preprocessor::AllocateDeserializedMacroInfo(SourceLocation L, DefMacroDirective * Preprocessor::AllocateDefMacroDirective(MacroInfo *MI, SourceLocation Loc, - bool isImported) { - DefMacroDirective *MD = BP.Allocate<DefMacroDirective>(); - new (MD) DefMacroDirective(MI, Loc, isImported); - return MD; + unsigned ImportedFromModuleID, + ArrayRef<unsigned> Overrides) { + unsigned NumExtra = (ImportedFromModuleID ? 1 : 0) + Overrides.size(); + return new (BP.Allocate(sizeof(DefMacroDirective) + + sizeof(unsigned) * NumExtra, + llvm::alignOf<DefMacroDirective>())) + DefMacroDirective(MI, Loc, ImportedFromModuleID, Overrides); } UndefMacroDirective * -Preprocessor::AllocateUndefMacroDirective(SourceLocation UndefLoc) { - UndefMacroDirective *MD = BP.Allocate<UndefMacroDirective>(); - new (MD) UndefMacroDirective(UndefLoc); - return MD; +Preprocessor::AllocateUndefMacroDirective(SourceLocation UndefLoc, + unsigned ImportedFromModuleID, + ArrayRef<unsigned> Overrides) { + unsigned NumExtra = (ImportedFromModuleID ? 1 : 0) + Overrides.size(); + return new (BP.Allocate(sizeof(UndefMacroDirective) + + sizeof(unsigned) * NumExtra, + llvm::alignOf<UndefMacroDirective>())) + UndefMacroDirective(UndefLoc, ImportedFromModuleID, Overrides); } VisibilityMacroDirective * Preprocessor::AllocateVisibilityMacroDirective(SourceLocation Loc, bool isPublic) { - VisibilityMacroDirective *MD = BP.Allocate<VisibilityMacroDirective>(); - new (MD) VisibilityMacroDirective(Loc, isPublic); - return MD; -} - -/// \brief Release the specified MacroInfo to be reused for allocating -/// new MacroInfo objects. -void Preprocessor::ReleaseMacroInfo(MacroInfo *MI) { - MacroInfoChain *MIChain = (MacroInfoChain *)MI; - if (MacroInfoChain *Prev = MIChain->Prev) { - MacroInfoChain *Next = MIChain->Next; - Prev->Next = Next; - if (Next) - Next->Prev = Prev; - } else { - assert(MIChainHead == MIChain); - MIChainHead = MIChain->Next; - MIChainHead->Prev = nullptr; - } - MIChain->Next = MICache; - MICache = MIChain; - - MI->Destroy(); + return new (BP) VisibilityMacroDirective(Loc, isPublic); } /// \brief Read and discard all tokens remaining on the current line until @@ -128,7 +100,56 @@ void Preprocessor::DiscardUntilEndOfDirective() { } while (Tmp.isNot(tok::eod)); } -bool Preprocessor::CheckMacroName(Token &MacroNameTok, char isDefineUndef) { +/// \brief Enumerates possible cases of #define/#undef a reserved identifier. +enum MacroDiag { + MD_NoWarn, //> Not a reserved identifier + MD_KeywordDef, //> Macro hides keyword, enabled by default + MD_ReservedMacro //> #define of #undef reserved id, disabled by default +}; + +/// \brief Checks if the specified identifier is reserved in the specified +/// language. +/// This function does not check if the identifier is a keyword. +static bool isReservedId(StringRef Text, const LangOptions &Lang) { + // C++ [macro.names], C11 7.1.3: + // All identifiers that begin with an underscore and either an uppercase + // letter or another underscore are always reserved for any use. + if (Text.size() >= 2 && Text[0] == '_' && + (isUppercase(Text[1]) || Text[1] == '_')) + return true; + // C++ [global.names] + // Each name that contains a double underscore ... is reserved to the + // implementation for any use. + if (Lang.CPlusPlus) { + if (Text.find("__") != StringRef::npos) + return true; + } + return false; +} + +static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II) { + const LangOptions &Lang = PP.getLangOpts(); + StringRef Text = II->getName(); + if (isReservedId(Text, Lang)) + return MD_ReservedMacro; + if (II->isKeyword(Lang)) + return MD_KeywordDef; + if (Lang.CPlusPlus11 && (Text.equals("override") || Text.equals("final"))) + return MD_KeywordDef; + return MD_NoWarn; +} + +static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, IdentifierInfo *II) { + const LangOptions &Lang = PP.getLangOpts(); + StringRef Text = II->getName(); + // Do not warn on keyword undef. It is generally harmless and widely used. + if (isReservedId(Text, Lang)) + return MD_ReservedMacro; + return MD_NoWarn; +} + +bool Preprocessor::CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, + bool *ShadowFlag) { // Missing macro name? if (MacroNameTok.is(tok::eod)) return Diag(MacroNameTok, diag::err_pp_missing_macro_name); @@ -156,18 +177,42 @@ bool Preprocessor::CheckMacroName(Token &MacroNameTok, char isDefineUndef) { MacroNameTok.setIdentifierInfo(II); } - if (isDefineUndef && II->getPPKeywordID() == tok::pp_defined) { + if ((isDefineUndef != MU_Other) && II->getPPKeywordID() == tok::pp_defined) { // Error if defining "defined": C99 6.10.8/4, C++ [cpp.predefined]p4. return Diag(MacroNameTok, diag::err_defined_macro_name); } - if (isDefineUndef == 2 && II->hasMacroDefinition() && + if (isDefineUndef == MU_Undef && II->hasMacroDefinition() && getMacroInfo(II)->isBuiltinMacro()) { // Warn if undefining "__LINE__" and other builtins, per C99 6.10.8/4 // and C++ [cpp.predefined]p4], but allow it as an extension. Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro); } + // If defining/undefining reserved identifier or a keyword, we need to issue + // a warning. + SourceLocation MacroNameLoc = MacroNameTok.getLocation(); + if (ShadowFlag) + *ShadowFlag = false; + if (!SourceMgr.isInSystemHeader(MacroNameLoc) && + (strcmp(SourceMgr.getBufferName(MacroNameLoc), "<built-in>") != 0)) { + MacroDiag D = MD_NoWarn; + if (isDefineUndef == MU_Define) { + D = shouldWarnOnMacroDef(*this, II); + } + else if (isDefineUndef == MU_Undef) + D = shouldWarnOnMacroUndef(*this, II); + if (D == MD_KeywordDef) { + // We do not want to warn on some patterns widely used in configuration + // scripts. This requires analyzing next tokens, so do not issue warnings + // now, only inform caller. + if (ShadowFlag) + *ShadowFlag = true; + } + if (D == MD_ReservedMacro) + Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id); + } + // Okay, we got a good identifier. return false; } @@ -175,22 +220,25 @@ bool Preprocessor::CheckMacroName(Token &MacroNameTok, char isDefineUndef) { /// \brief Lex and validate a macro name, which occurs after a /// \#define or \#undef. /// -/// This sets the token kind to eod and discards the rest -/// of the macro line if the macro name is invalid. \p isDefineUndef is 1 if -/// this is due to a a \#define, 2 if \#undef directive, 0 if it is something -/// else (e.g. \#ifdef). -void Preprocessor::ReadMacroName(Token &MacroNameTok, char isDefineUndef) { +/// This sets the token kind to eod and discards the rest of the macro line if +/// the macro name is invalid. +/// +/// \param MacroNameTok Token that is expected to be a macro name. +/// \param isDefineUndef Context in which macro is used. +/// \param ShadowFlag Points to a flag that is set if macro shadows a keyword. +void Preprocessor::ReadMacroName(Token &MacroNameTok, MacroUse isDefineUndef, + bool *ShadowFlag) { // Read the token, don't allow macro expansion on it. LexUnexpandedToken(MacroNameTok); if (MacroNameTok.is(tok::code_completion)) { if (CodeComplete) - CodeComplete->CodeCompleteMacroName(isDefineUndef == 1); + CodeComplete->CodeCompleteMacroName(isDefineUndef == MU_Define); setCodeCompletionReached(); LexUnexpandedToken(MacroNameTok); } - if (!CheckMacroName(MacroNameTok, isDefineUndef)) + if (!CheckMacroName(MacroNameTok, isDefineUndef, ShadowFlag)) return; // Invalid macro name, read and discard the rest of the line and set the @@ -562,6 +610,7 @@ const FileEntry *Preprocessor::LookupFile( StringRef Filename, bool isAngled, const DirectoryLookup *FromDir, + const FileEntry *FromFile, const DirectoryLookup *&CurDir, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, @@ -569,22 +618,33 @@ const FileEntry *Preprocessor::LookupFile( bool SkipCache) { // If the header lookup mechanism may be relative to the current inclusion // stack, record the parent #includes. - SmallVector<const FileEntry *, 16> Includers; - if (!FromDir) { + SmallVector<std::pair<const FileEntry *, const DirectoryEntry *>, 16> + Includers; + if (!FromDir && !FromFile) { FileID FID = getCurrentFileLexer()->getFileID(); const FileEntry *FileEnt = SourceMgr.getFileEntryForID(FID); // If there is no file entry associated with this file, it must be the - // predefines buffer. Any other file is not lexed with a normal lexer, so - // it won't be scanned for preprocessor directives. If we have the - // predefines buffer, resolve #include references (which come from the - // -include command line argument) as if they came from the main file, this - // affects file lookup etc. - if (!FileEnt) - FileEnt = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()); - - if (FileEnt) - Includers.push_back(FileEnt); + // predefines buffer or the module includes buffer. Any other file is not + // lexed with a normal lexer, so it won't be scanned for preprocessor + // directives. + // + // If we have the predefines buffer, resolve #include references (which come + // from the -include command line argument) from the current working + // directory instead of relative to the main file. + // + // If we have the module includes buffer, resolve #include references (which + // come from header declarations in the module map) relative to the module + // map file. + if (!FileEnt) { + if (FID == SourceMgr.getMainFileID() && MainFileDir) + Includers.push_back(std::make_pair(nullptr, MainFileDir)); + else if ((FileEnt = + SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()))) + Includers.push_back(std::make_pair(FileEnt, FileMgr.getDirectory("."))); + } else { + Includers.push_back(std::make_pair(FileEnt, FileEnt->getDir())); + } // MSVC searches the current include stack from top to bottom for // headers included by quoted include directives. @@ -595,13 +655,35 @@ const FileEntry *Preprocessor::LookupFile( if (IsFileLexer(ISEntry)) if ((FileEnt = SourceMgr.getFileEntryForID( ISEntry.ThePPLexer->getFileID()))) - Includers.push_back(FileEnt); + Includers.push_back(std::make_pair(FileEnt, FileEnt->getDir())); } } } - // Do a standard file entry lookup. CurDir = CurDirLookup; + + if (FromFile) { + // We're supposed to start looking from after a particular file. Search + // the include path until we find that file or run out of files. + const DirectoryLookup *TmpCurDir = CurDir; + const DirectoryLookup *TmpFromDir = nullptr; + while (const FileEntry *FE = HeaderInfo.LookupFile( + Filename, FilenameLoc, isAngled, TmpFromDir, TmpCurDir, + Includers, SearchPath, RelativePath, SuggestedModule, + SkipCache)) { + // Keep looking as if this file did a #include_next. + TmpFromDir = TmpCurDir; + ++TmpFromDir; + if (FE == FromFile) { + // Found it. + FromDir = TmpFromDir; + CurDir = TmpCurDir; + break; + } + } + } + + // Do a standard file entry lookup. const FileEntry *FE = HeaderInfo.LookupFile( Filename, FilenameLoc, isAngled, FromDir, CurDir, Includers, SearchPath, RelativePath, SuggestedModule, SkipCache); @@ -716,7 +798,8 @@ void Preprocessor::HandleDirective(Token &Result) { case tok::pp_import: case tok::pp_include_next: case tok::pp___include_macros: - Diag(Result, diag::err_embedded_include) << II->getName(); + case tok::pp_pragma: + Diag(Result, diag::err_embedded_directive) << II->getName(); DiscardUntilEndOfDirective(); return; default: @@ -1196,7 +1279,7 @@ void Preprocessor::HandleIdentSCCSDirective(Token &Tok) { /// \brief Handle a #public directive. void Preprocessor::HandleMacroPublicDirective(Token &Tok) { Token MacroNameTok; - ReadMacroName(MacroNameTok, 2); + ReadMacroName(MacroNameTok, MU_Undef); // Error reading macro name? If so, diagnostic already issued. if (MacroNameTok.is(tok::eod)) @@ -1223,7 +1306,7 @@ void Preprocessor::HandleMacroPublicDirective(Token &Tok) { /// \brief Handle a #private directive. void Preprocessor::HandleMacroPrivateDirective(Token &Tok) { Token MacroNameTok; - ReadMacroName(MacroNameTok, 2); + ReadMacroName(MacroNameTok, MU_Undef); // Error reading macro name? If so, diagnostic already issued. if (MacroNameTok.is(tok::eod)) @@ -1378,6 +1461,7 @@ static void EnterAnnotationToken(Preprocessor &PP, void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, Token &IncludeTok, const DirectoryLookup *LookupFrom, + const FileEntry *LookupFromFile, bool isImport) { Token FilenameTok; @@ -1469,12 +1553,14 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, SmallString<128> NormalizedPath; if (LangOpts.MSVCCompat) { NormalizedPath = Filename.str(); - llvm::sys::fs::normalize_separators(NormalizedPath); +#ifndef LLVM_ON_WIN32 + llvm::sys::path::native(NormalizedPath); +#endif } const FileEntry *File = LookupFile( FilenameLoc, LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, - isAngled, LookupFrom, CurDir, Callbacks ? &SearchPath : nullptr, - Callbacks ? &RelativePath : nullptr, + isAngled, LookupFrom, LookupFromFile, CurDir, + Callbacks ? &SearchPath : nullptr, Callbacks ? &RelativePath : nullptr, HeaderInfo.getHeaderSearchOpts().ModuleMaps ? &SuggestedModule : nullptr); if (Callbacks) { @@ -1488,14 +1574,13 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, HeaderInfo.AddSearchPath(DL, isAngled); // Try the lookup again, skipping the cache. - File = LookupFile(FilenameLoc, - LangOpts.MSVCCompat ? NormalizedPath.c_str() - : Filename, - isAngled, LookupFrom, CurDir, nullptr, nullptr, - HeaderInfo.getHeaderSearchOpts().ModuleMaps - ? &SuggestedModule - : nullptr, - /*SkipCache*/ true); + File = LookupFile( + FilenameLoc, + LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, isAngled, + LookupFrom, LookupFromFile, CurDir, nullptr, nullptr, + HeaderInfo.getHeaderSearchOpts().ModuleMaps ? &SuggestedModule + : nullptr, + /*SkipCache*/ true); } } } @@ -1517,8 +1602,10 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, // provide the user with a possible fixit. if (isAngled) { File = LookupFile( - FilenameLoc, LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, - false, LookupFrom, CurDir, Callbacks ? &SearchPath : nullptr, + FilenameLoc, + LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, false, + LookupFrom, LookupFromFile, CurDir, + Callbacks ? &SearchPath : nullptr, Callbacks ? &RelativePath : nullptr, HeaderInfo.getHeaderSearchOpts().ModuleMaps ? &SuggestedModule : nullptr); @@ -1539,7 +1626,9 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, // If we are supposed to import a module rather than including the header, // do so now. - if (SuggestedModule && getLangOpts().Modules) { + if (SuggestedModule && getLangOpts().Modules && + SuggestedModule.getModule()->getTopLevelModuleName() != + getLangOpts().ImplementationOfModule) { // Compute the module access path corresponding to this module. // FIXME: Should we have a second loadModule() overload to avoid this // extra lookup step? @@ -1713,9 +1802,16 @@ void Preprocessor::HandleIncludeNextDirective(SourceLocation HashLoc, // the current found directory. If we can't do this, issue a // diagnostic. const DirectoryLookup *Lookup = CurDirLookup; + const FileEntry *LookupFromFile = nullptr; if (isInPrimaryFile()) { Lookup = nullptr; Diag(IncludeNextTok, diag::pp_include_next_in_primary); + } else if (CurSubmodule) { + // Start looking up in the directory *after* the one in which the current + // file would be found, if any. + assert(CurPPLexer && "#include_next directive in macro?"); + LookupFromFile = CurPPLexer->getFileEntry(); + Lookup = nullptr; } else if (!Lookup) { Diag(IncludeNextTok, diag::pp_include_next_absolute_path); } else { @@ -1723,7 +1819,8 @@ void Preprocessor::HandleIncludeNextDirective(SourceLocation HashLoc, ++Lookup; } - return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup); + return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup, + LookupFromFile); } /// HandleMicrosoftImportDirective - Implements \#import for Microsoft Mode @@ -1749,7 +1846,7 @@ void Preprocessor::HandleImportDirective(SourceLocation HashLoc, return HandleMicrosoftImportDirective(ImportTok); Diag(ImportTok, diag::ext_pp_import_directive); } - return HandleIncludeDirective(HashLoc, ImportTok, nullptr, true); + return HandleIncludeDirective(HashLoc, ImportTok, nullptr, nullptr, true); } /// HandleIncludeMacrosDirective - The -imacros command line option turns into a @@ -1770,7 +1867,7 @@ void Preprocessor::HandleIncludeMacrosDirective(SourceLocation HashLoc, // Treat this as a normal #include for checking purposes. If this is // successful, it will push a new lexer onto the include stack. - HandleIncludeDirective(HashLoc, IncludeMacrosTok, nullptr, false); + HandleIncludeDirective(HashLoc, IncludeMacrosTok); Token TmpTok; do { @@ -1878,6 +1975,52 @@ bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI, Token &Tok) { } } +static bool isConfigurationPattern(Token &MacroName, MacroInfo *MI, + const LangOptions &LOptions) { + if (MI->getNumTokens() == 1) { + const Token &Value = MI->getReplacementToken(0); + + // Macro that is identity, like '#define inline inline' is a valid pattern. + if (MacroName.getKind() == Value.getKind()) + return true; + + // Macro that maps a keyword to the same keyword decorated with leading/ + // trailing underscores is a valid pattern: + // #define inline __inline + // #define inline __inline__ + // #define inline _inline (in MS compatibility mode) + StringRef MacroText = MacroName.getIdentifierInfo()->getName(); + if (IdentifierInfo *II = Value.getIdentifierInfo()) { + if (!II->isKeyword(LOptions)) + return false; + StringRef ValueText = II->getName(); + StringRef TrimmedValue = ValueText; + if (!ValueText.startswith("__")) { + if (ValueText.startswith("_")) + TrimmedValue = TrimmedValue.drop_front(1); + else + return false; + } else { + TrimmedValue = TrimmedValue.drop_front(2); + if (TrimmedValue.endswith("__")) + TrimmedValue = TrimmedValue.drop_back(2); + } + return TrimmedValue.equals(MacroText); + } else { + return false; + } + } + + // #define inline + if ((MacroName.is(tok::kw_extern) || MacroName.is(tok::kw_inline) || + MacroName.is(tok::kw_static) || MacroName.is(tok::kw_const)) && + MI->getNumTokens() == 0) { + return true; + } + + return false; +} + /// HandleDefineDirective - Implements \#define. This consumes the entire macro /// line then lets the caller lex the next real token. void Preprocessor::HandleDefineDirective(Token &DefineTok, @@ -1885,7 +2028,8 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok, ++NumDefined; Token MacroNameTok; - ReadMacroName(MacroNameTok, 1); + bool MacroShadowsKeyword; + ReadMacroName(MacroNameTok, MU_Define, &MacroShadowsKeyword); // Error reading macro name? If so, diagnostic already issued. if (MacroNameTok.is(tok::eod)) @@ -1921,8 +2065,6 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok, // This is a function-like macro definition. Read the argument list. MI->setIsFunctionLike(); if (ReadMacroDefinitionArgList(MI, LastTok)) { - // Forget about MI. - ReleaseMacroInfo(MI); // Throw away the rest of the line. if (CurPPLexer->ParsingPreprocessorDirective) DiscardUntilEndOfDirective(); @@ -2047,7 +2189,6 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok, continue; } else { Diag(Tok, diag::err_pp_stringize_not_parameter); - ReleaseMacroInfo(MI); // Disable __VA_ARGS__ again. Ident__VA_ARGS__->setIsPoisoned(true); @@ -2065,6 +2206,10 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok, } } + if (MacroShadowsKeyword && + !isConfigurationPattern(MacroNameTok, MI, getLangOpts())) { + Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword); + } // Disable __VA_ARGS__ again. Ident__VA_ARGS__->setIsPoisoned(true); @@ -2075,12 +2220,10 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok, if (NumTokens != 0) { if (MI->getReplacementToken(0).is(tok::hashhash)) { Diag(MI->getReplacementToken(0), diag::err_paste_at_start); - ReleaseMacroInfo(MI); return; } if (MI->getReplacementToken(NumTokens-1).is(tok::hashhash)) { Diag(MI->getReplacementToken(NumTokens-1), diag::err_paste_at_end); - ReleaseMacroInfo(MI); return; } } @@ -2138,7 +2281,7 @@ void Preprocessor::HandleUndefDirective(Token &UndefTok) { ++NumUndefined; Token MacroNameTok; - ReadMacroName(MacroNameTok, 2); + ReadMacroName(MacroNameTok, MU_Undef); // Error reading macro name? If so, diagnostic already issued. if (MacroNameTok.is(tok::eod)) diff --git a/contrib/llvm/tools/clang/lib/Lex/PPExpressions.cpp b/contrib/llvm/tools/clang/lib/Lex/PPExpressions.cpp index 2260bf9..9cf72cf 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PPExpressions.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/PPExpressions.cpp @@ -103,7 +103,7 @@ static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT, } // If we don't have a pp-identifier now, this is an error. - if (PP.CheckMacroName(PeekTok, 0)) + if (PP.CheckMacroName(PeekTok, MU_Other)) return true; // Otherwise, we got an identifier, is it defined to something? @@ -244,7 +244,9 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, // Parse the integer literal into Result. if (Literal.GetIntegerValue(Result.Val)) { // Overflow parsing integer literal. - if (ValueLive) PP.Diag(PeekTok, diag::err_integer_too_large); + if (ValueLive) + PP.Diag(PeekTok, diag::err_integer_literal_too_large) + << /* Unsigned */ 1; Result.Val.setIsUnsigned(true); } else { // Set the signedness of the result to match whether there was a U suffix @@ -259,7 +261,7 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, // Octal, hexadecimal, and binary literals are implicitly unsigned if // the value does not fit into a signed integer type. if (ValueLive && Literal.getRadix() == 10) - PP.Diag(PeekTok, diag::ext_integer_too_large_for_signed); + PP.Diag(PeekTok, diag::ext_integer_literal_too_large_for_signed); Result.Val.setIsUnsigned(true); } } @@ -271,6 +273,7 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, } case tok::char_constant: // 'x' case tok::wide_char_constant: // L'x' + case tok::utf8_char_constant: // u8'x' case tok::utf16_char_constant: // u'x' case tok::utf32_char_constant: { // U'x' // Complain about, and drop, any ud-suffix. @@ -597,15 +600,10 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, break; case tok::lessless: { // Determine whether overflow is about to happen. - unsigned ShAmt = static_cast<unsigned>(RHS.Val.getLimitedValue()); - if (LHS.isUnsigned()) { - Overflow = ShAmt >= LHS.Val.getBitWidth(); - if (Overflow) - ShAmt = LHS.Val.getBitWidth()-1; - Res = LHS.Val << ShAmt; - } else { - Res = llvm::APSInt(LHS.Val.sshl_ov(ShAmt, Overflow), false); - } + if (LHS.isUnsigned()) + Res = LHS.Val.ushl_ov(RHS.Val, Overflow); + else + Res = llvm::APSInt(LHS.Val.sshl_ov(RHS.Val, Overflow), false); break; } case tok::greatergreater: { diff --git a/contrib/llvm/tools/clang/lib/Lex/PPLexerChange.cpp b/contrib/llvm/tools/clang/lib/Lex/PPLexerChange.cpp index 22ee971..fb5e2b0 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PPLexerChange.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/PPLexerChange.cpp @@ -160,17 +160,17 @@ void Preprocessor::EnterSourceFileWithPTH(PTHLexer *PL, /// tokens from it instead of the current buffer. void Preprocessor::EnterMacro(Token &Tok, SourceLocation ILEnd, MacroInfo *Macro, MacroArgs *Args) { - TokenLexer *TokLexer; + std::unique_ptr<TokenLexer> TokLexer; if (NumCachedTokenLexers == 0) { - TokLexer = new TokenLexer(Tok, ILEnd, Macro, Args, *this); + TokLexer = llvm::make_unique<TokenLexer>(Tok, ILEnd, Macro, Args, *this); } else { - TokLexer = TokenLexerCache[--NumCachedTokenLexers]; + TokLexer = std::move(TokenLexerCache[--NumCachedTokenLexers]); TokLexer->Init(Tok, ILEnd, Macro, Args); } PushIncludeMacroStack(); CurDirLookup = nullptr; - CurTokenLexer.reset(TokLexer); + CurTokenLexer = std::move(TokLexer); if (CurLexerKind != CLK_LexAfterModuleImport) CurLexerKind = CLK_TokenLexer; } @@ -190,20 +190,39 @@ void Preprocessor::EnterMacro(Token &Tok, SourceLocation ILEnd, void Preprocessor::EnterTokenStream(const Token *Toks, unsigned NumToks, bool DisableMacroExpansion, bool OwnsTokens) { + if (CurLexerKind == CLK_CachingLexer) { + if (CachedLexPos < CachedTokens.size()) { + // We're entering tokens into the middle of our cached token stream. We + // can't represent that, so just insert the tokens into the buffer. + CachedTokens.insert(CachedTokens.begin() + CachedLexPos, + Toks, Toks + NumToks); + if (OwnsTokens) + delete [] Toks; + return; + } + + // New tokens are at the end of the cached token sequnece; insert the + // token stream underneath the caching lexer. + ExitCachingLexMode(); + EnterTokenStream(Toks, NumToks, DisableMacroExpansion, OwnsTokens); + EnterCachingLexMode(); + return; + } + // Create a macro expander to expand from the specified token stream. - TokenLexer *TokLexer; + std::unique_ptr<TokenLexer> TokLexer; if (NumCachedTokenLexers == 0) { - TokLexer = new TokenLexer(Toks, NumToks, DisableMacroExpansion, - OwnsTokens, *this); + TokLexer = llvm::make_unique<TokenLexer>( + Toks, NumToks, DisableMacroExpansion, OwnsTokens, *this); } else { - TokLexer = TokenLexerCache[--NumCachedTokenLexers]; + TokLexer = std::move(TokenLexerCache[--NumCachedTokenLexers]); TokLexer->Init(Toks, NumToks, DisableMacroExpansion, OwnsTokens); } // Save our current state. PushIncludeMacroStack(); CurDirLookup = nullptr; - CurTokenLexer.reset(TokLexer); + CurTokenLexer = std::move(TokLexer); if (CurLexerKind != CLK_LexAfterModuleImport) CurLexerKind = CLK_TokenLexer; } @@ -480,33 +499,6 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { } } } - - // 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; @@ -526,7 +518,7 @@ bool Preprocessor::HandleEndOfTokenLexer(Token &Result) { if (NumCachedTokenLexers == TokenLexerCacheSize) CurTokenLexer.reset(); else - TokenLexerCache[NumCachedTokenLexers++] = CurTokenLexer.release(); + TokenLexerCache[NumCachedTokenLexers++] = std::move(CurTokenLexer); // Handle this like a #include file being popped off the stack. return HandleEndOfFile(Result, true); @@ -543,7 +535,7 @@ void Preprocessor::RemoveTopOfLexerStack() { if (NumCachedTokenLexers == TokenLexerCacheSize) CurTokenLexer.reset(); else - TokenLexerCache[NumCachedTokenLexers++] = CurTokenLexer.release(); + TokenLexerCache[NumCachedTokenLexers++] = std::move(CurTokenLexer); } PopIncludeMacroStack(); diff --git a/contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp b/contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp index 2d7c6d4..cd05d06 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp @@ -49,7 +49,10 @@ void Preprocessor::appendMacroDirective(IdentifierInfo *II, MacroDirective *MD){ MacroDirective *&StoredMD = Macros[II]; MD->setPrevious(StoredMD); StoredMD = MD; - II->setHasMacroDefinition(MD->isDefined()); + // Setup the identifier as having associated macro history. + II->setHasMacroDefinition(true); + if (!MD->isDefined()) + II->setHasMacroDefinition(false); bool isImportedMacro = isa<DefMacroDirective>(MD) && cast<DefMacroDirective>(MD)->isImported(); if (II->isFromAST() && !isImportedMacro) @@ -93,6 +96,9 @@ void Preprocessor::RegisterBuiltinMacros() { Ident__COUNTER__ = RegisterBuiltinMacro(*this, "__COUNTER__"); Ident_Pragma = RegisterBuiltinMacro(*this, "_Pragma"); + // C++ Standing Document Extensions. + Ident__has_cpp_attribute = RegisterBuiltinMacro(*this, "__has_cpp_attribute"); + // GCC Extensions. Ident__BASE_FILE__ = RegisterBuiltinMacro(*this, "__BASE_FILE__"); Ident__INCLUDE_LEVEL__ = RegisterBuiltinMacro(*this, "__INCLUDE_LEVEL__"); @@ -112,6 +118,7 @@ void Preprocessor::RegisterBuiltinMacros() { Ident__has_extension = RegisterBuiltinMacro(*this, "__has_extension"); Ident__has_builtin = RegisterBuiltinMacro(*this, "__has_builtin"); Ident__has_attribute = RegisterBuiltinMacro(*this, "__has_attribute"); + Ident__has_declspec = RegisterBuiltinMacro(*this, "__has_declspec_attribute"); Ident__has_include = RegisterBuiltinMacro(*this, "__has_include"); Ident__has_include_next = RegisterBuiltinMacro(*this, "__has_include_next"); Ident__has_warning = RegisterBuiltinMacro(*this, "__has_warning"); @@ -857,144 +864,148 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) { Feature = Feature.substr(2, Feature.size() - 4); return llvm::StringSwitch<bool>(Feature) - .Case("address_sanitizer", LangOpts.Sanitize.Address) - .Case("attribute_analyzer_noreturn", true) - .Case("attribute_availability", true) - .Case("attribute_availability_with_message", true) - .Case("attribute_cf_returns_not_retained", true) - .Case("attribute_cf_returns_retained", true) - .Case("attribute_deprecated_with_message", true) - .Case("attribute_ext_vector_type", true) - .Case("attribute_ns_returns_not_retained", true) - .Case("attribute_ns_returns_retained", true) - .Case("attribute_ns_consumes_self", true) - .Case("attribute_ns_consumed", true) - .Case("attribute_cf_consumed", true) - .Case("attribute_objc_ivar_unused", true) - .Case("attribute_objc_method_family", true) - .Case("attribute_overloadable", true) - .Case("attribute_unavailable_with_message", true) - .Case("attribute_unused_on_fields", true) - .Case("blocks", LangOpts.Blocks) - .Case("c_thread_safety_attributes", true) - .Case("cxx_exceptions", LangOpts.CXXExceptions) - .Case("cxx_rtti", LangOpts.RTTI) - .Case("enumerator_attributes", true) - .Case("memory_sanitizer", LangOpts.Sanitize.Memory) - .Case("thread_sanitizer", LangOpts.Sanitize.Thread) - .Case("dataflow_sanitizer", LangOpts.Sanitize.DataFlow) - // Objective-C features - .Case("objc_arr", LangOpts.ObjCAutoRefCount) // FIXME: REMOVE? - .Case("objc_arc", LangOpts.ObjCAutoRefCount) - .Case("objc_arc_weak", LangOpts.ObjCARCWeak) - .Case("objc_default_synthesize_properties", LangOpts.ObjC2) - .Case("objc_fixed_enum", LangOpts.ObjC2) - .Case("objc_instancetype", LangOpts.ObjC2) - .Case("objc_modules", LangOpts.ObjC2 && LangOpts.Modules) - .Case("objc_nonfragile_abi", LangOpts.ObjCRuntime.isNonFragile()) - .Case("objc_property_explicit_atomic", true) // Does clang support explicit "atomic" keyword? - .Case("objc_protocol_qualifier_mangling", true) - .Case("objc_weak_class", LangOpts.ObjCRuntime.hasWeakClassImport()) - .Case("ownership_holds", true) - .Case("ownership_returns", true) - .Case("ownership_takes", true) - .Case("objc_bool", true) - .Case("objc_subscripting", LangOpts.ObjCRuntime.isNonFragile()) - .Case("objc_array_literals", LangOpts.ObjC2) - .Case("objc_dictionary_literals", LangOpts.ObjC2) - .Case("objc_boxed_expressions", LangOpts.ObjC2) - .Case("arc_cf_code_audited", true) - // C11 features - .Case("c_alignas", LangOpts.C11) - .Case("c_atomic", LangOpts.C11) - .Case("c_generic_selections", LangOpts.C11) - .Case("c_static_assert", LangOpts.C11) - .Case("c_thread_local", - LangOpts.C11 && PP.getTargetInfo().isTLSSupported()) - // C++11 features - .Case("cxx_access_control_sfinae", LangOpts.CPlusPlus11) - .Case("cxx_alias_templates", LangOpts.CPlusPlus11) - .Case("cxx_alignas", LangOpts.CPlusPlus11) - .Case("cxx_atomic", LangOpts.CPlusPlus11) - .Case("cxx_attributes", LangOpts.CPlusPlus11) - .Case("cxx_auto_type", LangOpts.CPlusPlus11) - .Case("cxx_constexpr", LangOpts.CPlusPlus11) - .Case("cxx_decltype", LangOpts.CPlusPlus11) - .Case("cxx_decltype_incomplete_return_types", LangOpts.CPlusPlus11) - .Case("cxx_default_function_template_args", LangOpts.CPlusPlus11) - .Case("cxx_defaulted_functions", LangOpts.CPlusPlus11) - .Case("cxx_delegating_constructors", LangOpts.CPlusPlus11) - .Case("cxx_deleted_functions", LangOpts.CPlusPlus11) - .Case("cxx_explicit_conversions", LangOpts.CPlusPlus11) - .Case("cxx_generalized_initializers", LangOpts.CPlusPlus11) - .Case("cxx_implicit_moves", LangOpts.CPlusPlus11) - .Case("cxx_inheriting_constructors", LangOpts.CPlusPlus11) - .Case("cxx_inline_namespaces", LangOpts.CPlusPlus11) - .Case("cxx_lambdas", LangOpts.CPlusPlus11) - .Case("cxx_local_type_template_args", LangOpts.CPlusPlus11) - .Case("cxx_nonstatic_member_init", LangOpts.CPlusPlus11) - .Case("cxx_noexcept", LangOpts.CPlusPlus11) - .Case("cxx_nullptr", LangOpts.CPlusPlus11) - .Case("cxx_override_control", LangOpts.CPlusPlus11) - .Case("cxx_range_for", LangOpts.CPlusPlus11) - .Case("cxx_raw_string_literals", LangOpts.CPlusPlus11) - .Case("cxx_reference_qualified_functions", LangOpts.CPlusPlus11) - .Case("cxx_rvalue_references", LangOpts.CPlusPlus11) - .Case("cxx_strong_enums", LangOpts.CPlusPlus11) - .Case("cxx_static_assert", LangOpts.CPlusPlus11) - .Case("cxx_thread_local", - LangOpts.CPlusPlus11 && PP.getTargetInfo().isTLSSupported()) - .Case("cxx_trailing_return", LangOpts.CPlusPlus11) - .Case("cxx_unicode_literals", LangOpts.CPlusPlus11) - .Case("cxx_unrestricted_unions", LangOpts.CPlusPlus11) - .Case("cxx_user_literals", LangOpts.CPlusPlus11) - .Case("cxx_variadic_templates", LangOpts.CPlusPlus11) - // C++1y features - .Case("cxx_aggregate_nsdmi", LangOpts.CPlusPlus1y) - .Case("cxx_binary_literals", LangOpts.CPlusPlus1y) - .Case("cxx_contextual_conversions", LangOpts.CPlusPlus1y) - .Case("cxx_decltype_auto", LangOpts.CPlusPlus1y) - .Case("cxx_generic_lambdas", LangOpts.CPlusPlus1y) - .Case("cxx_init_captures", LangOpts.CPlusPlus1y) - .Case("cxx_relaxed_constexpr", LangOpts.CPlusPlus1y) - .Case("cxx_return_type_deduction", LangOpts.CPlusPlus1y) - .Case("cxx_variable_templates", LangOpts.CPlusPlus1y) - // C++ TSes - //.Case("cxx_runtime_arrays", LangOpts.CPlusPlusTSArrays) - //.Case("cxx_concepts", LangOpts.CPlusPlusTSConcepts) - // FIXME: Should this be __has_feature or __has_extension? - //.Case("raw_invocation_type", LangOpts.CPlusPlus) - // Type traits - .Case("has_nothrow_assign", LangOpts.CPlusPlus) - .Case("has_nothrow_copy", LangOpts.CPlusPlus) - .Case("has_nothrow_constructor", LangOpts.CPlusPlus) - .Case("has_trivial_assign", LangOpts.CPlusPlus) - .Case("has_trivial_copy", LangOpts.CPlusPlus) - .Case("has_trivial_constructor", LangOpts.CPlusPlus) - .Case("has_trivial_destructor", LangOpts.CPlusPlus) - .Case("has_virtual_destructor", LangOpts.CPlusPlus) - .Case("is_abstract", LangOpts.CPlusPlus) - .Case("is_base_of", LangOpts.CPlusPlus) - .Case("is_class", LangOpts.CPlusPlus) - .Case("is_constructible", LangOpts.CPlusPlus) - .Case("is_convertible_to", LangOpts.CPlusPlus) - .Case("is_empty", LangOpts.CPlusPlus) - .Case("is_enum", LangOpts.CPlusPlus) - .Case("is_final", LangOpts.CPlusPlus) - .Case("is_literal", LangOpts.CPlusPlus) - .Case("is_standard_layout", LangOpts.CPlusPlus) - .Case("is_pod", LangOpts.CPlusPlus) - .Case("is_polymorphic", LangOpts.CPlusPlus) - .Case("is_sealed", LangOpts.MicrosoftExt) - .Case("is_trivial", LangOpts.CPlusPlus) - .Case("is_trivially_assignable", LangOpts.CPlusPlus) - .Case("is_trivially_constructible", LangOpts.CPlusPlus) - .Case("is_trivially_copyable", LangOpts.CPlusPlus) - .Case("is_union", LangOpts.CPlusPlus) - .Case("modules", LangOpts.Modules) - .Case("tls", PP.getTargetInfo().isTLSSupported()) - .Case("underlying_type", LangOpts.CPlusPlus) - .Default(false); + .Case("address_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Address)) + .Case("attribute_analyzer_noreturn", true) + .Case("attribute_availability", true) + .Case("attribute_availability_with_message", true) + .Case("attribute_cf_returns_not_retained", true) + .Case("attribute_cf_returns_retained", true) + .Case("attribute_deprecated_with_message", true) + .Case("attribute_ext_vector_type", true) + .Case("attribute_ns_returns_not_retained", true) + .Case("attribute_ns_returns_retained", true) + .Case("attribute_ns_consumes_self", true) + .Case("attribute_ns_consumed", true) + .Case("attribute_cf_consumed", true) + .Case("attribute_objc_ivar_unused", true) + .Case("attribute_objc_method_family", true) + .Case("attribute_overloadable", true) + .Case("attribute_unavailable_with_message", true) + .Case("attribute_unused_on_fields", true) + .Case("blocks", LangOpts.Blocks) + .Case("c_thread_safety_attributes", true) + .Case("cxx_exceptions", LangOpts.CXXExceptions) + .Case("cxx_rtti", LangOpts.RTTI) + .Case("enumerator_attributes", true) + .Case("memory_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Memory)) + .Case("thread_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Thread)) + .Case("dataflow_sanitizer", LangOpts.Sanitize.has(SanitizerKind::DataFlow)) + // Objective-C features + .Case("objc_arr", LangOpts.ObjCAutoRefCount) // FIXME: REMOVE? + .Case("objc_arc", LangOpts.ObjCAutoRefCount) + .Case("objc_arc_weak", LangOpts.ObjCARCWeak) + .Case("objc_default_synthesize_properties", LangOpts.ObjC2) + .Case("objc_fixed_enum", LangOpts.ObjC2) + .Case("objc_instancetype", LangOpts.ObjC2) + .Case("objc_modules", LangOpts.ObjC2 && LangOpts.Modules) + .Case("objc_nonfragile_abi", LangOpts.ObjCRuntime.isNonFragile()) + .Case("objc_property_explicit_atomic", + true) // Does clang support explicit "atomic" keyword? + .Case("objc_protocol_qualifier_mangling", true) + .Case("objc_weak_class", LangOpts.ObjCRuntime.hasWeakClassImport()) + .Case("ownership_holds", true) + .Case("ownership_returns", true) + .Case("ownership_takes", true) + .Case("objc_bool", true) + .Case("objc_subscripting", LangOpts.ObjCRuntime.isNonFragile()) + .Case("objc_array_literals", LangOpts.ObjC2) + .Case("objc_dictionary_literals", LangOpts.ObjC2) + .Case("objc_boxed_expressions", LangOpts.ObjC2) + .Case("arc_cf_code_audited", true) + .Case("objc_bridge_id", LangOpts.ObjC2) + // C11 features + .Case("c_alignas", LangOpts.C11) + .Case("c_alignof", LangOpts.C11) + .Case("c_atomic", LangOpts.C11) + .Case("c_generic_selections", LangOpts.C11) + .Case("c_static_assert", LangOpts.C11) + .Case("c_thread_local", + LangOpts.C11 && PP.getTargetInfo().isTLSSupported()) + // C++11 features + .Case("cxx_access_control_sfinae", LangOpts.CPlusPlus11) + .Case("cxx_alias_templates", LangOpts.CPlusPlus11) + .Case("cxx_alignas", LangOpts.CPlusPlus11) + .Case("cxx_alignof", LangOpts.CPlusPlus11) + .Case("cxx_atomic", LangOpts.CPlusPlus11) + .Case("cxx_attributes", LangOpts.CPlusPlus11) + .Case("cxx_auto_type", LangOpts.CPlusPlus11) + .Case("cxx_constexpr", LangOpts.CPlusPlus11) + .Case("cxx_decltype", LangOpts.CPlusPlus11) + .Case("cxx_decltype_incomplete_return_types", LangOpts.CPlusPlus11) + .Case("cxx_default_function_template_args", LangOpts.CPlusPlus11) + .Case("cxx_defaulted_functions", LangOpts.CPlusPlus11) + .Case("cxx_delegating_constructors", LangOpts.CPlusPlus11) + .Case("cxx_deleted_functions", LangOpts.CPlusPlus11) + .Case("cxx_explicit_conversions", LangOpts.CPlusPlus11) + .Case("cxx_generalized_initializers", LangOpts.CPlusPlus11) + .Case("cxx_implicit_moves", LangOpts.CPlusPlus11) + .Case("cxx_inheriting_constructors", LangOpts.CPlusPlus11) + .Case("cxx_inline_namespaces", LangOpts.CPlusPlus11) + .Case("cxx_lambdas", LangOpts.CPlusPlus11) + .Case("cxx_local_type_template_args", LangOpts.CPlusPlus11) + .Case("cxx_nonstatic_member_init", LangOpts.CPlusPlus11) + .Case("cxx_noexcept", LangOpts.CPlusPlus11) + .Case("cxx_nullptr", LangOpts.CPlusPlus11) + .Case("cxx_override_control", LangOpts.CPlusPlus11) + .Case("cxx_range_for", LangOpts.CPlusPlus11) + .Case("cxx_raw_string_literals", LangOpts.CPlusPlus11) + .Case("cxx_reference_qualified_functions", LangOpts.CPlusPlus11) + .Case("cxx_rvalue_references", LangOpts.CPlusPlus11) + .Case("cxx_strong_enums", LangOpts.CPlusPlus11) + .Case("cxx_static_assert", LangOpts.CPlusPlus11) + .Case("cxx_thread_local", + LangOpts.CPlusPlus11 && PP.getTargetInfo().isTLSSupported()) + .Case("cxx_trailing_return", LangOpts.CPlusPlus11) + .Case("cxx_unicode_literals", LangOpts.CPlusPlus11) + .Case("cxx_unrestricted_unions", LangOpts.CPlusPlus11) + .Case("cxx_user_literals", LangOpts.CPlusPlus11) + .Case("cxx_variadic_templates", LangOpts.CPlusPlus11) + // C++1y features + .Case("cxx_aggregate_nsdmi", LangOpts.CPlusPlus14) + .Case("cxx_binary_literals", LangOpts.CPlusPlus14) + .Case("cxx_contextual_conversions", LangOpts.CPlusPlus14) + .Case("cxx_decltype_auto", LangOpts.CPlusPlus14) + .Case("cxx_generic_lambdas", LangOpts.CPlusPlus14) + .Case("cxx_init_captures", LangOpts.CPlusPlus14) + .Case("cxx_relaxed_constexpr", LangOpts.CPlusPlus14) + .Case("cxx_return_type_deduction", LangOpts.CPlusPlus14) + .Case("cxx_variable_templates", LangOpts.CPlusPlus14) + // C++ TSes + //.Case("cxx_runtime_arrays", LangOpts.CPlusPlusTSArrays) + //.Case("cxx_concepts", LangOpts.CPlusPlusTSConcepts) + // FIXME: Should this be __has_feature or __has_extension? + //.Case("raw_invocation_type", LangOpts.CPlusPlus) + // Type traits + .Case("has_nothrow_assign", LangOpts.CPlusPlus) + .Case("has_nothrow_copy", LangOpts.CPlusPlus) + .Case("has_nothrow_constructor", LangOpts.CPlusPlus) + .Case("has_trivial_assign", LangOpts.CPlusPlus) + .Case("has_trivial_copy", LangOpts.CPlusPlus) + .Case("has_trivial_constructor", LangOpts.CPlusPlus) + .Case("has_trivial_destructor", LangOpts.CPlusPlus) + .Case("has_virtual_destructor", LangOpts.CPlusPlus) + .Case("is_abstract", LangOpts.CPlusPlus) + .Case("is_base_of", LangOpts.CPlusPlus) + .Case("is_class", LangOpts.CPlusPlus) + .Case("is_constructible", LangOpts.CPlusPlus) + .Case("is_convertible_to", LangOpts.CPlusPlus) + .Case("is_empty", LangOpts.CPlusPlus) + .Case("is_enum", LangOpts.CPlusPlus) + .Case("is_final", LangOpts.CPlusPlus) + .Case("is_literal", LangOpts.CPlusPlus) + .Case("is_standard_layout", LangOpts.CPlusPlus) + .Case("is_pod", LangOpts.CPlusPlus) + .Case("is_polymorphic", LangOpts.CPlusPlus) + .Case("is_sealed", LangOpts.MicrosoftExt) + .Case("is_trivial", LangOpts.CPlusPlus) + .Case("is_trivially_assignable", LangOpts.CPlusPlus) + .Case("is_trivially_constructible", LangOpts.CPlusPlus) + .Case("is_trivially_copyable", LangOpts.CPlusPlus) + .Case("is_union", LangOpts.CPlusPlus) + .Case("modules", LangOpts.Modules) + .Case("tls", PP.getTargetInfo().isTLSSupported()) + .Case("underlying_type", LangOpts.CPlusPlus) + .Default(false); } /// HasExtension - Return true if we recognize and implement the feature @@ -1023,6 +1034,7 @@ static bool HasExtension(const Preprocessor &PP, const IdentifierInfo *II) { return llvm::StringSwitch<bool>(Extension) // C11 features supported by other languages as extensions. .Case("c_alignas", true) + .Case("c_alignof", true) .Case("c_atomic", true) .Case("c_generic_selections", true) .Case("c_static_assert", true) @@ -1050,7 +1062,8 @@ static bool HasExtension(const Preprocessor &PP, const IdentifierInfo *II) { /// Returns true if successful. static bool EvaluateHasIncludeCommon(Token &Tok, IdentifierInfo *II, Preprocessor &PP, - const DirectoryLookup *LookupFrom) { + const DirectoryLookup *LookupFrom, + const FileEntry *LookupFromFile) { // Save the location of the current token. If a '(' is later found, use // that location. If not, use the end of this location instead. SourceLocation LParenLoc = Tok.getLocation(); @@ -1145,8 +1158,8 @@ static bool EvaluateHasIncludeCommon(Token &Tok, // Search include directories. const DirectoryLookup *CurDir; const FileEntry *File = - PP.LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, CurDir, - nullptr, nullptr, nullptr); + PP.LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, LookupFromFile, + CurDir, nullptr, nullptr, nullptr); // Get the result value. A result of true means the file exists. return File != nullptr; @@ -1156,7 +1169,7 @@ static bool EvaluateHasIncludeCommon(Token &Tok, /// Returns true if successful. static bool EvaluateHasInclude(Token &Tok, IdentifierInfo *II, Preprocessor &PP) { - return EvaluateHasIncludeCommon(Tok, II, PP, nullptr); + return EvaluateHasIncludeCommon(Tok, II, PP, nullptr, nullptr); } /// EvaluateHasIncludeNext - Process '__has_include_next("path")' expression. @@ -1166,10 +1179,19 @@ static bool EvaluateHasIncludeNext(Token &Tok, // __has_include_next is like __has_include, except that we start // searching after the current found directory. If we can't do this, // issue a diagnostic. + // FIXME: Factor out duplication wiht + // Preprocessor::HandleIncludeNextDirective. const DirectoryLookup *Lookup = PP.GetCurDirLookup(); + const FileEntry *LookupFromFile = nullptr; if (PP.isInPrimaryFile()) { Lookup = nullptr; PP.Diag(Tok, diag::pp_include_next_in_primary); + } else if (PP.getCurrentSubmodule()) { + // Start looking up in the directory *after* the one in which the current + // file would be found, if any. + assert(PP.getCurrentLexer() && "#include_next directive in macro?"); + LookupFromFile = PP.getCurrentLexer()->getFileEntry(); + Lookup = nullptr; } else if (!Lookup) { PP.Diag(Tok, diag::pp_include_next_absolute_path); } else { @@ -1177,7 +1199,7 @@ static bool EvaluateHasIncludeNext(Token &Tok, ++Lookup; } - return EvaluateHasIncludeCommon(Tok, II, PP, Lookup); + return EvaluateHasIncludeCommon(Tok, II, PP, Lookup, LookupFromFile); } /// \brief Process __building_module(identifier) expression. @@ -1360,12 +1382,15 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { II == Ident__has_extension || II == Ident__has_builtin || II == Ident__is_identifier || - II == Ident__has_attribute) { + II == Ident__has_attribute || + II == Ident__has_declspec || + II == Ident__has_cpp_attribute) { // The argument to these builtins should be a parenthesized identifier. SourceLocation StartLoc = Tok.getLocation(); bool IsValid = false; IdentifierInfo *FeatureII = nullptr; + IdentifierInfo *ScopeII = nullptr; // Read the '('. LexUnexpandedToken(Tok); @@ -1373,14 +1398,30 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { // Read the identifier LexUnexpandedToken(Tok); if ((FeatureII = Tok.getIdentifierInfo())) { - // Read the ')'. + // If we're checking __has_cpp_attribute, it is possible to receive a + // scope token. Read the "::", if it's available. LexUnexpandedToken(Tok); - if (Tok.is(tok::r_paren)) + bool IsScopeValid = true; + if (II == Ident__has_cpp_attribute && Tok.is(tok::coloncolon)) { + LexUnexpandedToken(Tok); + // The first thing we read was not the feature, it was the scope. + ScopeII = FeatureII; + if ((FeatureII = Tok.getIdentifierInfo())) + LexUnexpandedToken(Tok); + else + IsScopeValid = false; + } + // Read the closing paren. + if (IsScopeValid && Tok.is(tok::r_paren)) IsValid = true; } + // Eat tokens until ')'. + while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::eod) && + Tok.isNot(tok::eof)) + LexUnexpandedToken(Tok); } - bool Value = false; + int Value = 0; if (!IsValid) Diag(StartLoc, diag::err_feature_check_malformed); else if (II == Ident__is_identifier) @@ -1389,7 +1430,13 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { // Check for a builtin is trivial. Value = FeatureII->getBuiltinID() != 0; } else if (II == Ident__has_attribute) - Value = hasAttribute(AttrSyntax::Generic, nullptr, FeatureII, + Value = hasAttribute(AttrSyntax::GNU, nullptr, FeatureII, + getTargetInfo().getTriple(), getLangOpts()); + else if (II == Ident__has_cpp_attribute) + Value = hasAttribute(AttrSyntax::CXX, ScopeII, FeatureII, + getTargetInfo().getTriple(), getLangOpts()); + else if (II == Ident__has_declspec) + Value = hasAttribute(AttrSyntax::Declspec, nullptr, FeatureII, getTargetInfo().getTriple(), getLangOpts()); else if (II == Ident__has_extension) Value = HasExtension(*this, FeatureII); @@ -1398,9 +1445,10 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { Value = HasFeature(*this, FeatureII); } - OS << (int)Value; - if (IsValid) - Tok.setKind(tok::numeric_constant); + if (!IsValid) + return; + OS << Value; + Tok.setKind(tok::numeric_constant); } else if (II == Ident__has_include || II == Ident__has_include_next) { // The argument to these two builtins should be a parenthesized @@ -1464,9 +1512,10 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { WarningName.substr(2), Diags); } while (false); + if (!IsValid) + return; OS << (int)Value; - if (IsValid) - Tok.setKind(tok::numeric_constant); + Tok.setKind(tok::numeric_constant); } else if (II == Ident__building_module) { // The argument to this builtin should be an identifier. The // builtin evaluates to 1 when that identifier names the module we are diff --git a/contrib/llvm/tools/clang/lib/Lex/PTHLexer.cpp b/contrib/llvm/tools/clang/lib/Lex/PTHLexer.cpp index fce31c4..af7a153 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PTHLexer.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/PTHLexer.cpp @@ -24,7 +24,6 @@ #include "llvm/ADT/StringMap.h" #include "llvm/Support/EndianStream.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/OnDiskHashTable.h" #include <memory> #include <system_error> using namespace clang; @@ -342,7 +341,9 @@ public: } }; -class PTHFileLookupTrait : public PTHFileLookupCommonTrait { +} // end anonymous namespace + +class PTHManager::PTHFileLookupTrait : public PTHFileLookupCommonTrait { public: typedef const FileEntry* external_key_type; typedef PTHFileData data_type; @@ -365,7 +366,7 @@ public: } }; -class PTHStringLookupTrait { +class PTHManager::PTHStringLookupTrait { public: typedef uint32_t data_type; typedef const std::pair<const char*, unsigned> external_key_type; @@ -408,31 +409,22 @@ public: } }; -} // end anonymous namespace - -typedef llvm::OnDiskChainedHashTable<PTHFileLookupTrait> PTHFileLookup; -typedef llvm::OnDiskChainedHashTable<PTHStringLookupTrait> PTHStringIdLookup; - //===----------------------------------------------------------------------===// // PTHManager methods. //===----------------------------------------------------------------------===// -PTHManager::PTHManager(const llvm::MemoryBuffer* buf, void* fileLookup, - const unsigned char* idDataTable, - IdentifierInfo** perIDCache, - void* stringIdLookup, unsigned numIds, - const unsigned char* spellingBase, - const char* originalSourceFile) -: Buf(buf), PerIDCache(perIDCache), FileLookup(fileLookup), - IdDataTable(idDataTable), StringIdLookup(stringIdLookup), - NumIds(numIds), PP(nullptr), SpellingBase(spellingBase), - OriginalSourceFile(originalSourceFile) {} +PTHManager::PTHManager( + std::unique_ptr<const llvm::MemoryBuffer> buf, + std::unique_ptr<PTHFileLookup> fileLookup, const unsigned char *idDataTable, + std::unique_ptr<IdentifierInfo *[], llvm::FreeDeleter> perIDCache, + std::unique_ptr<PTHStringIdLookup> stringIdLookup, unsigned numIds, + const unsigned char *spellingBase, const char *originalSourceFile) + : Buf(std::move(buf)), PerIDCache(std::move(perIDCache)), + FileLookup(std::move(fileLookup)), IdDataTable(idDataTable), + StringIdLookup(std::move(stringIdLookup)), NumIds(numIds), PP(nullptr), + SpellingBase(spellingBase), OriginalSourceFile(originalSourceFile) {} PTHManager::~PTHManager() { - delete Buf; - delete (PTHFileLookup*) FileLookup; - delete (PTHStringIdLookup*) StringIdLookup; - free(PerIDCache); } static void InvalidPTH(DiagnosticsEngine &Diags, const char *Msg) { @@ -543,10 +535,10 @@ PTHManager *PTHManager::Create(const std::string &file, // Pre-allocate the persistent ID -> IdentifierInfo* cache. We use calloc() // so that we in the best case only zero out memory once when the OS returns // us new pages. - IdentifierInfo **PerIDCache = nullptr; + std::unique_ptr<IdentifierInfo *[], llvm::FreeDeleter> PerIDCache; if (NumIds) { - PerIDCache = (IdentifierInfo**)calloc(NumIds, sizeof(*PerIDCache)); + PerIDCache.reset((IdentifierInfo **)calloc(NumIds, sizeof(PerIDCache[0]))); if (!PerIDCache) { InvalidPTH(Diags, "Could not allocate memory for processing PTH file"); return nullptr; @@ -560,9 +552,9 @@ PTHManager *PTHManager::Create(const std::string &file, if (!len) originalSourceBase = nullptr; // Create the new PTHManager. - return new PTHManager(File.release(), FL.release(), IData, PerIDCache, - SL.release(), NumIds, spellingBase, - (const char *)originalSourceBase); + return new PTHManager(std::move(File), std::move(FL), IData, + std::move(PerIDCache), std::move(SL), NumIds, + spellingBase, (const char *)originalSourceBase); } IdentifierInfo* PTHManager::LazilyCreateIdentifierInfo(unsigned PersistentID) { @@ -589,12 +581,11 @@ IdentifierInfo* PTHManager::LazilyCreateIdentifierInfo(unsigned PersistentID) { } IdentifierInfo* PTHManager::get(StringRef Name) { - PTHStringIdLookup& SL = *((PTHStringIdLookup*)StringIdLookup); // Double check our assumption that the last character isn't '\0'. assert(Name.empty() || Name.back() != '\0'); - PTHStringIdLookup::iterator I = SL.find(std::make_pair(Name.data(), - Name.size())); - if (I == SL.end()) // No identifier found? + PTHStringIdLookup::iterator I = + StringIdLookup->find(std::make_pair(Name.data(), Name.size())); + if (I == StringIdLookup->end()) // No identifier found? return nullptr; // Match found. Return the identifier! @@ -612,10 +603,9 @@ PTHLexer *PTHManager::CreateLexer(FileID FID) { // Lookup the FileEntry object in our file lookup data structure. It will // return a variant that indicates whether or not there is an offset within // the PTH file that contains cached tokens. - PTHFileLookup& PFL = *((PTHFileLookup*)FileLookup); - PTHFileLookup::iterator I = PFL.find(FE); + PTHFileLookup::iterator I = FileLookup->find(FE); - if (I == PFL.end()) // No tokens available? + if (I == FileLookup->end()) // No tokens available? return nullptr; const PTHFileData& FileData = *I; @@ -684,7 +674,7 @@ public: uint64_t File = endian::readNext<uint64_t, little, unaligned>(d); uint64_t Device = endian::readNext<uint64_t, little, unaligned>(d); - llvm::sys::fs::UniqueID UniqueID(File, Device); + llvm::sys::fs::UniqueID UniqueID(Device, File); time_t ModTime = endian::readNext<uint64_t, little, unaligned>(d); uint64_t Size = endian::readNext<uint64_t, little, unaligned>(d); return data_type(Size, ModTime, UniqueID, IsDirectory); @@ -694,15 +684,17 @@ public: return data_type(); } }; +} // end anonymous namespace +namespace clang { class PTHStatCache : public FileSystemStatCache { typedef llvm::OnDiskChainedHashTable<PTHStatLookupTrait> CacheTy; CacheTy Cache; public: - PTHStatCache(PTHFileLookup &FL) : - Cache(FL.getNumBuckets(), FL.getNumEntries(), FL.getBuckets(), - FL.getBase()) {} + PTHStatCache(PTHManager::PTHFileLookup &FL) + : Cache(FL.getNumBuckets(), FL.getNumEntries(), FL.getBuckets(), + FL.getBase()) {} LookupResult getStat(const char *Path, FileData &Data, bool isFile, std::unique_ptr<vfs::File> *F, @@ -730,8 +722,8 @@ public: return CacheExists; } }; -} // end anonymous namespace +} -FileSystemStatCache *PTHManager::createStatCache() { - return new PTHStatCache(*((PTHFileLookup*) FileLookup)); +std::unique_ptr<FileSystemStatCache> PTHManager::createStatCache() { + return llvm::make_unique<PTHStatCache>(*FileLookup); } diff --git a/contrib/llvm/tools/clang/lib/Lex/Pragma.cpp b/contrib/llvm/tools/clang/lib/Lex/Pragma.cpp index cf76bdb..8ed8328 100644 --- a/contrib/llvm/tools/clang/lib/Lex/Pragma.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/Pragma.cpp @@ -65,9 +65,7 @@ PragmaHandler *PragmaNamespace::FindHandler(StringRef Name, void PragmaNamespace::AddPragma(PragmaHandler *Handler) { assert(!Handlers.lookup(Handler->getName()) && "A handler with this name is already registered in this namespace"); - llvm::StringMapEntry<PragmaHandler *> &Entry = - Handlers.GetOrCreateValue(Handler->getName()); - Entry.setValue(Handler); + Handlers[Handler->getName()] = Handler; } void PragmaNamespace::RemovePragmaHandler(PragmaHandler *Handler) { @@ -193,7 +191,7 @@ void Preprocessor::Handle_Pragma(Token &Tok) { if (!tok::isStringLiteral(Tok.getKind())) { Diag(PragmaLoc, diag::err__Pragma_malformed); // Skip this token, and the ')', if present. - if (Tok.isNot(tok::r_paren)) + if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::eof)) Lex(Tok); if (Tok.is(tok::r_paren)) Lex(Tok); @@ -472,9 +470,9 @@ void Preprocessor::HandlePragmaDependency(Token &DependencyTok) { // Search include directories for this file. const DirectoryLookup *CurDir; - const FileEntry *File = LookupFile(FilenameTok.getLocation(), Filename, - isAngled, nullptr, CurDir, nullptr, - nullptr, nullptr); + const FileEntry *File = + LookupFile(FilenameTok.getLocation(), Filename, isAngled, nullptr, + nullptr, CurDir, nullptr, nullptr, nullptr); if (!File) { if (!SuppressIncludeNotFoundError) Diag(FilenameTok, diag::err_pp_file_not_found) << Filename; @@ -605,7 +603,7 @@ void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) { if (MacroToReInstall) { // Reinstall the previously pushed macro. appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc, - /*isImported=*/false); + /*isImported=*/false, /*Overrides*/None); } // Pop PragmaPushMacroInfo stack. @@ -728,7 +726,7 @@ void Preprocessor::HandlePragmaIncludeAlias(Token &Tok) { /// pragma line before the pragma string starts, e.g. "STDC" or "GCC". void Preprocessor::AddPragmaHandler(StringRef Namespace, PragmaHandler *Handler) { - PragmaNamespace *InsertNS = PragmaHandlers; + PragmaNamespace *InsertNS = PragmaHandlers.get(); // If this is specified to be in a namespace, step down into it. if (!Namespace.empty()) { @@ -759,7 +757,7 @@ void Preprocessor::AddPragmaHandler(StringRef Namespace, /// a handler that has not been registered. void Preprocessor::RemovePragmaHandler(StringRef Namespace, PragmaHandler *Handler) { - PragmaNamespace *NS = PragmaHandlers; + PragmaNamespace *NS = PragmaHandlers.get(); // If this is specified to be in a namespace, step down into it. if (!Namespace.empty()) { @@ -772,9 +770,8 @@ void Preprocessor::RemovePragmaHandler(StringRef Namespace, NS->RemovePragmaHandler(Handler); - // If this is a non-default namespace and it is now empty, remove - // it. - if (NS != PragmaHandlers && NS->IsEmpty()) { + // If this is a non-default namespace and it is now empty, remove it. + if (NS != PragmaHandlers.get() && NS->IsEmpty()) { PragmaHandlers->RemovePragmaHandler(NS); delete NS; } diff --git a/contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp b/contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp index 4a11803..b2a6d93 100644 --- a/contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp @@ -27,6 +27,7 @@ #include "clang/Lex/Preprocessor.h" #include "clang/Basic/FileManager.h" +#include "clang/Basic/FileSystemStatCache.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/Lex/CodeCompletionHandler.h" @@ -61,19 +62,21 @@ Preprocessor::Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts, IdentifierInfoLookup *IILookup, bool OwnsHeaders, TranslationUnitKind TUKind) : PPOpts(PPOpts), Diags(&diags), LangOpts(opts), Target(nullptr), - FileMgr(Headers.getFileMgr()), SourceMgr(SM), HeaderInfo(Headers), + FileMgr(Headers.getFileMgr()), SourceMgr(SM), + ScratchBuf(new ScratchBuffer(SourceMgr)),HeaderInfo(Headers), TheModuleLoader(TheModuleLoader), ExternalSource(nullptr), - Identifiers(opts, IILookup), IncrementalProcessing(false), TUKind(TUKind), + Identifiers(opts, IILookup), + PragmaHandlers(new PragmaNamespace(StringRef())), + IncrementalProcessing(false), TUKind(TUKind), CodeComplete(nullptr), CodeCompletionFile(nullptr), CodeCompletionOffset(0), LastTokenWasAt(false), ModuleImportExpectsIdentifier(false), CodeCompletionReached(0), - SkipMainFilePreamble(0, true), CurPPLexer(nullptr), + MainFileDir(nullptr), SkipMainFilePreamble(0, true), CurPPLexer(nullptr), CurDirLookup(nullptr), CurLexerKind(CLK_Lexer), CurSubmodule(nullptr), Callbacks(nullptr), MacroArgCache(nullptr), Record(nullptr), - MIChainHead(nullptr), MICache(nullptr), DeserialMIChainHead(nullptr) { + MIChainHead(nullptr), DeserialMIChainHead(nullptr) { OwnsHeaderSearch = OwnsHeaders; - ScratchBuf = new ScratchBuffer(SourceMgr); CounterValue = 0; // __COUNTER__ starts at 0. // Clear stats. @@ -111,7 +114,6 @@ Preprocessor::Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts, SetPoisonReason(Ident__VA_ARGS__,diag::ext_pp_bad_vaargs_use); // Initialize the pragma handlers. - PragmaHandlers = new PragmaNamespace(StringRef()); RegisterBuiltinPragmas(); // Initialize builtin macros like __LINE__ and friends. @@ -141,35 +143,30 @@ Preprocessor::~Preprocessor() { IncludeMacroStack.clear(); - // Free any macro definitions. - for (MacroInfoChain *I = MIChainHead ; I ; I = I->Next) - I->MI.Destroy(); + // Destroy any macro definitions. + while (MacroInfoChain *I = MIChainHead) { + MIChainHead = I->Next; + I->~MacroInfoChain(); + } // Free any cached macro expanders. // This populates MacroArgCache, so all TokenLexers need to be destroyed // before the code below that frees up the MacroArgCache list. - for (unsigned i = 0, e = NumCachedTokenLexers; i != e; ++i) - delete TokenLexerCache[i]; + std::fill(TokenLexerCache, TokenLexerCache + NumCachedTokenLexers, nullptr); CurTokenLexer.reset(); - for (DeserializedMacroInfoChain *I = DeserialMIChainHead ; I ; I = I->Next) - I->MI.Destroy(); + while (DeserializedMacroInfoChain *I = DeserialMIChainHead) { + DeserialMIChainHead = I->Next; + I->~DeserializedMacroInfoChain(); + } // Free any cached MacroArgs. for (MacroArgs *ArgList = MacroArgCache; ArgList;) ArgList = ArgList->deallocate(); - // Release pragma information. - delete PragmaHandlers; - - // Delete the scratch buffer info. - delete ScratchBuf; - // Delete the header search info, if we own it. if (OwnsHeaderSearch) delete &HeaderInfo; - - delete Callbacks; } void Preprocessor::Initialize(const TargetInfo &Target) { @@ -182,6 +179,24 @@ void Preprocessor::Initialize(const TargetInfo &Target) { HeaderInfo.setTarget(Target); } +void Preprocessor::InitializeForModelFile() { + NumEnteredSourceFiles = 0; + + // Reset pragmas + PragmaHandlersBackup = std::move(PragmaHandlers); + PragmaHandlers = llvm::make_unique<PragmaNamespace>(StringRef()); + RegisterBuiltinPragmas(); + + // Reset PredefinesFileID + PredefinesFileID = FileID(); +} + +void Preprocessor::FinalizeForModelFile() { + NumEnteredSourceFiles = 1; + + PragmaHandlers = std::move(PragmaHandlersBackup); +} + void Preprocessor::setPTHManager(PTHManager* pm) { PTH.reset(pm); FileMgr.addStatCache(PTH->createStatCache()); @@ -370,21 +385,29 @@ bool Preprocessor::SetCodeCompletionPoint(const FileEntry *File, Position += CompleteColumn - 1; - // Insert '\0' at the code-completion point. - if (Position < Buffer->getBufferEnd()) { - CodeCompletionFile = File; - CodeCompletionOffset = Position - Buffer->getBufferStart(); - - MemoryBuffer *NewBuffer = - MemoryBuffer::getNewUninitMemBuffer(Buffer->getBufferSize() + 1, - Buffer->getBufferIdentifier()); - char *NewBuf = const_cast<char*>(NewBuffer->getBufferStart()); - char *NewPos = std::copy(Buffer->getBufferStart(), Position, NewBuf); - *NewPos = '\0'; - std::copy(Position, Buffer->getBufferEnd(), NewPos+1); - SourceMgr.overrideFileContents(File, NewBuffer); + // If pointing inside the preamble, adjust the position at the beginning of + // the file after the preamble. + if (SkipMainFilePreamble.first && + SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()) == File) { + if (Position - Buffer->getBufferStart() < SkipMainFilePreamble.first) + Position = Buffer->getBufferStart() + SkipMainFilePreamble.first; } + if (Position > Buffer->getBufferEnd()) + Position = Buffer->getBufferEnd(); + + CodeCompletionFile = File; + CodeCompletionOffset = Position - Buffer->getBufferStart(); + + std::unique_ptr<MemoryBuffer> NewBuffer = + MemoryBuffer::getNewUninitMemBuffer(Buffer->getBufferSize() + 1, + Buffer->getBufferIdentifier()); + char *NewBuf = const_cast<char*>(NewBuffer->getBufferStart()); + char *NewPos = std::copy(Buffer->getBufferStart(), Position, NewBuf); + *NewPos = '\0'; + std::copy(Position, Buffer->getBufferEnd(), NewPos+1); + SourceMgr.overrideFileContents(File, std::move(NewBuffer)); + return false; } @@ -479,10 +502,10 @@ void Preprocessor::EnterMainSourceFile() { } // Preprocess Predefines to populate the initial preprocessor state. - llvm::MemoryBuffer *SB = + std::unique_ptr<llvm::MemoryBuffer> SB = llvm::MemoryBuffer::getMemBufferCopy(Predefines, "<built-in>"); assert(SB && "Cannot create predefined source buffer"); - FileID FID = SourceMgr.createFileID(SB); + FileID FID = SourceMgr.createFileID(std::move(SB)); assert(!FID.isInvalid() && "Could not create FileID for predefines?"); setPredefinesFileID(FID); @@ -649,7 +672,8 @@ bool Preprocessor::HandleIdentifier(Token &Identifier) { // keyword when we're in a caching lexer, because caching lexers only get // used in contexts where import declarations are disallowed. if (LastTokenWasAt && II.isModulesImport() && !InMacroArgs && - !DisableMacroExpansion && getLangOpts().Modules && + !DisableMacroExpansion && + (getLangOpts().Modules || getLangOpts().DebuggerSupport) && CurLexerKind != CLK_CachingLexer) { ModuleImportLoc = Identifier.getLocation(); ModuleImportPath.clear(); @@ -722,12 +746,14 @@ void Preprocessor::LexAfterModuleImport(Token &Result) { } // If we have a non-empty module path, load the named module. - if (!ModuleImportPath.empty() && getLangOpts().Modules) { - Module *Imported = TheModuleLoader.loadModule(ModuleImportLoc, - ModuleImportPath, - Module::MacrosVisible, - /*IsIncludeDirective=*/false); - if (Callbacks) + if (!ModuleImportPath.empty()) { + Module *Imported = nullptr; + if (getLangOpts().Modules) + Imported = TheModuleLoader.loadModule(ModuleImportLoc, + ModuleImportPath, + Module::MacrosVisible, + /*IsIncludeDirective=*/false); + if (Callbacks && (getLangOpts().Modules || getLangOpts().DebuggerSupport)) Callbacks->moduleImport(ModuleImportLoc, ModuleImportPath, Imported); } } @@ -830,5 +856,5 @@ void Preprocessor::createPreprocessingRecord() { return; Record = new PreprocessingRecord(getSourceManager()); - addPPCallbacks(Record); + addPPCallbacks(std::unique_ptr<PPCallbacks>(Record)); } diff --git a/contrib/llvm/tools/clang/lib/Lex/ScratchBuffer.cpp b/contrib/llvm/tools/clang/lib/Lex/ScratchBuffer.cpp index d7104b1..3bac889 100644 --- a/contrib/llvm/tools/clang/lib/Lex/ScratchBuffer.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/ScratchBuffer.cpp @@ -64,11 +64,12 @@ void ScratchBuffer::AllocScratchBuffer(unsigned RequestLen) { if (RequestLen < ScratchBufSize) RequestLen = ScratchBufSize; - llvm::MemoryBuffer *Buf = - llvm::MemoryBuffer::getNewMemBuffer(RequestLen, "<scratch space>"); - FileID FID = SourceMgr.createFileID(Buf); + std::unique_ptr<llvm::MemoryBuffer> OwnBuf = + llvm::MemoryBuffer::getNewMemBuffer(RequestLen, "<scratch space>"); + llvm::MemoryBuffer &Buf = *OwnBuf; + FileID FID = SourceMgr.createFileID(std::move(OwnBuf)); BufferStartLoc = SourceMgr.getLocForStartOfFile(FID); - CurBuffer = const_cast<char*>(Buf->getBufferStart()); + CurBuffer = const_cast<char*>(Buf.getBufferStart()); BytesUsed = 1; CurBuffer[0] = '0'; // Start out with a \0 for cleanliness. } diff --git a/contrib/llvm/tools/clang/lib/Lex/TokenConcatenation.cpp b/contrib/llvm/tools/clang/lib/Lex/TokenConcatenation.cpp index 0a66bba..0832749 100644 --- a/contrib/llvm/tools/clang/lib/Lex/TokenConcatenation.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/TokenConcatenation.cpp @@ -99,6 +99,10 @@ TokenConcatenation::TokenConcatenation(Preprocessor &pp) : PP(pp) { TokenInfo[tok::utf32_char_constant ] |= aci_custom; } + // These tokens have custom code in C++1z mode. + if (PP.getLangOpts().CPlusPlus1z) + TokenInfo[tok::utf8_char_constant] |= aci_custom; + // These tokens change behavior if followed by an '='. TokenInfo[tok::amp ] |= aci_avoid_equal; // &= TokenInfo[tok::plus ] |= aci_avoid_equal; // += @@ -163,8 +167,8 @@ bool TokenConcatenation::AvoidConcat(const Token &PrevPrevTok, return false; tok::TokenKind PrevKind = PrevTok.getKind(); - if (PrevTok.getIdentifierInfo()) // Language keyword or named operator. - PrevKind = tok::identifier; + if (!PrevTok.isAnnotation() && PrevTok.getIdentifierInfo()) + PrevKind = tok::identifier; // Language keyword or named operator. // Look up information on when we should avoid concatenation with prevtok. unsigned ConcatInfo = TokenInfo[PrevKind]; @@ -178,6 +182,14 @@ bool TokenConcatenation::AvoidConcat(const Token &PrevPrevTok, return true; ConcatInfo &= ~aci_avoid_equal; } + if (Tok.isAnnotation()) { + // Modules annotation can show up when generated automatically for includes. + assert((Tok.is(tok::annot_module_include) || + Tok.is(tok::annot_module_begin) || + Tok.is(tok::annot_module_end)) && + "unexpected annotation in AvoidConcat"); + ConcatInfo = 0; + } if (ConcatInfo == 0) return false; @@ -205,6 +217,7 @@ bool TokenConcatenation::AvoidConcat(const Token &PrevPrevTok, case tok::utf32_string_literal: case tok::char_constant: case tok::wide_char_constant: + case tok::utf8_char_constant: case tok::utf16_char_constant: case tok::utf32_char_constant: if (!PP.getLangOpts().CPlusPlus11) @@ -228,7 +241,8 @@ bool TokenConcatenation::AvoidConcat(const Token &PrevPrevTok, if (Tok.getIdentifierInfo() || Tok.is(tok::wide_string_literal) || Tok.is(tok::utf8_string_literal) || Tok.is(tok::utf16_string_literal) || Tok.is(tok::utf32_string_literal) || Tok.is(tok::wide_char_constant) || - Tok.is(tok::utf16_char_constant) || Tok.is(tok::utf32_char_constant)) + Tok.is(tok::utf8_char_constant) || Tok.is(tok::utf16_char_constant) || + Tok.is(tok::utf32_char_constant)) return true; // If this isn't identifier + string, we're done. diff --git a/contrib/llvm/tools/clang/lib/Lex/TokenLexer.cpp b/contrib/llvm/tools/clang/lib/Lex/TokenLexer.cpp index 9d03e8d..5f4705e 100644 --- a/contrib/llvm/tools/clang/lib/Lex/TokenLexer.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/TokenLexer.cpp @@ -206,6 +206,7 @@ void TokenLexer::ExpandFunctionArguments() { ExpansionLocStart, ExpansionLocEnd); } + Res.setFlag(Token::StringifiedInMacro); // The stringified/charified string leading space flag gets set to match // the #/#@ operator. @@ -405,6 +406,14 @@ void TokenLexer::ExpandFunctionArguments() { } } +/// \brief Checks if two tokens form wide string literal. +static bool isWideStringLiteralFromMacro(const Token &FirstTok, + const Token &SecondTok) { + return FirstTok.is(tok::identifier) && + FirstTok.getIdentifierInfo()->isStr("L") && SecondTok.isLiteral() && + SecondTok.stringifiedInMacro(); +} + /// Lex - Lex and return a token from this macro stream. /// bool TokenLexer::Lex(Token &Tok) { @@ -435,7 +444,13 @@ bool TokenLexer::Lex(Token &Tok) { // If this token is followed by a token paste (##) operator, paste the tokens! // Note that ## is a normal token when not expanding a macro. - if (!isAtEnd() && Tokens[CurToken].is(tok::hashhash) && Macro) { + if (!isAtEnd() && Macro && + (Tokens[CurToken].is(tok::hashhash) || + // Special processing of L#x macros in -fms-compatibility mode. + // Microsoft compiler is able to form a wide string literal from + // 'L#macro_arg' construct in a function-like macro. + (PP.getLangOpts().MSVCCompat && + isWideStringLiteralFromMacro(Tok, Tokens[CurToken])))) { // When handling the microsoft /##/ extension, the final token is // returned by PasteTokens, not the pasted token. if (PasteTokens(Tok)) @@ -511,9 +526,10 @@ bool TokenLexer::PasteTokens(Token &Tok) { SourceLocation StartLoc = Tok.getLocation(); SourceLocation PasteOpLoc; do { - // Consume the ## operator. + // Consume the ## operator if any. PasteOpLoc = Tokens[CurToken].getLocation(); - ++CurToken; + if (Tokens[CurToken].is(tok::hashhash)) + ++CurToken; assert(!isAtEnd() && "No token on the RHS of a paste operator!"); // Get the RHS token. @@ -531,12 +547,13 @@ bool TokenLexer::PasteTokens(Token &Tok) { memcpy(&Buffer[0], BufPtr, LHSLen); if (Invalid) return true; - - BufPtr = &Buffer[LHSLen]; + + BufPtr = Buffer.data() + LHSLen; unsigned RHSLen = PP.getSpelling(RHS, BufPtr, &Invalid); if (Invalid) return true; - if (BufPtr != &Buffer[LHSLen]) // Really, we want the chars in Buffer! + if (RHSLen && BufPtr != &Buffer[LHSLen]) + // Really, we want the chars in Buffer! memcpy(&Buffer[LHSLen], BufPtr, RHSLen); // Trim excess space. diff --git a/contrib/llvm/tools/clang/lib/Lex/UnicodeCharSets.h b/contrib/llvm/tools/clang/lib/Lex/UnicodeCharSets.h index 12b2456..116d553 100644 --- a/contrib/llvm/tools/clang/lib/Lex/UnicodeCharSets.h +++ b/contrib/llvm/tools/clang/lib/Lex/UnicodeCharSets.h @@ -6,8 +6,8 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef CLANG_LEX_UNICODECHARSETS_H -#define CLANG_LEX_UNICODECHARSETS_H +#ifndef LLVM_CLANG_LIB_LEX_UNICODECHARSETS_H +#define LLVM_CLANG_LIB_LEX_UNICODECHARSETS_H #include "llvm/Support/UnicodeCharRanges.h" |