diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Lex')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp | 47 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/Lexer.cpp | 12 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/LiteralSupport.cpp | 90 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/MacroArgs.cpp | 7 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/MacroInfo.cpp | 17 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp | 184 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/PPConditionalDirectiveRecord.cpp | 4 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/PPDirectives.cpp | 325 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/PPExpressions.cpp | 25 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/PPLexerChange.cpp | 130 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp | 293 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/Pragma.cpp | 67 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/PreprocessingRecord.cpp | 74 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp | 82 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/ScratchBuffer.cpp | 5 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/TokenLexer.cpp | 9 |
16 files changed, 894 insertions, 477 deletions
diff --git a/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp b/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp index d6b255fb014e..ad7d3449ac4a 100644 --- a/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp @@ -18,6 +18,7 @@ #include "clang/Lex/HeaderSearchOptions.h" #include "clang/Lex/LexDiagnostic.h" #include "clang/Lex/Lexer.h" +#include "clang/Lex/Preprocessor.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/SmallString.h" @@ -149,7 +150,7 @@ std::string HeaderSearch::getModuleFileName(StringRef ModuleName, SmallString<128> HashStr; llvm::APInt(64, size_t(Hash)).toStringUnsigned(HashStr, /*Radix*/36); - llvm::sys::path::append(Result, ModuleName + "-" + HashStr.str() + ".pcm"); + llvm::sys::path::append(Result, ModuleName + "-" + HashStr + ".pcm"); } return Result.str().str(); } @@ -297,7 +298,7 @@ const FileEntry *DirectoryLookup::LookupFile( RelativePath->append(Filename.begin(), Filename.end()); } - return getFileAndSuggestModule(HS, TmpDir.str(), getDir(), + return getFileAndSuggestModule(HS, TmpDir, getDir(), isSystemHeaderDirectory(), SuggestedModule); } @@ -438,7 +439,7 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup( HS.IncrementFrameworkLookupCount(); // If the framework dir doesn't exist, we fail. - const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str()); + const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName); if (!Dir) return nullptr; // Otherwise, if it does, remember that this is the right direntry for this @@ -450,7 +451,7 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup( if (getDirCharacteristic() == SrcMgr::C_User) { SmallString<1024> SystemFrameworkMarker(FrameworkName); SystemFrameworkMarker += ".system_framework"; - if (llvm::sys::fs::exists(SystemFrameworkMarker.str())) { + if (llvm::sys::fs::exists(SystemFrameworkMarker)) { CacheEntry.IsUserSpecifiedSystemFramework = true; } } @@ -476,7 +477,7 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup( } FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end()); - const FileEntry *FE = FileMgr.getFile(FrameworkName.str(), + const FileEntry *FE = FileMgr.getFile(FrameworkName, /*openFile=*/!SuggestedModule); if (!FE) { // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h" @@ -487,7 +488,7 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup( SearchPath->insert(SearchPath->begin()+OrigSize, Private, Private+strlen(Private)); - FE = FileMgr.getFile(FrameworkName.str(), /*openFile=*/!SuggestedModule); + FE = FileMgr.getFile(FrameworkName, /*openFile=*/!SuggestedModule); } // If we found the header and are allowed to suggest a module, do so now. @@ -594,7 +595,13 @@ const FileEntry *HeaderSearch::LookupFile( RelativePath->append(Filename.begin(), Filename.end()); } // Otherwise, just return the file. - return FileMgr.getFile(Filename, /*openFile=*/true); + const FileEntry *File = FileMgr.getFile(Filename, /*openFile=*/true); + if (File && SuggestedModule) { + // If there is a module that corresponds to this header, suggest it. + hasModuleMap(Filename, File->getDir(), /*SystemHeaderDir*/false); + *SuggestedModule = findModuleForHeader(File); + } + return File; } // This is the header that MSVC's header search would have found. @@ -628,7 +635,7 @@ const FileEntry *HeaderSearch::LookupFile( bool IncluderIsSystemHeader = Includer && getFileInfo(Includer).DirInfo != SrcMgr::C_User; if (const FileEntry *FE = getFileAndSuggestModule( - *this, TmpDir.str(), IncluderAndDir.second, + *this, TmpDir, IncluderAndDir.second, IncluderIsSystemHeader, SuggestedModule)) { if (!Includer) { assert(First && "only first includer can have no file"); @@ -865,7 +872,7 @@ LookupSubframeworkHeader(StringRef Filename, ++NumSubFrameworkLookups; // If the framework dir doesn't exist, we fail. - const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str()); + const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName); if (!Dir) return nullptr; // Otherwise, if it does, remember that this is the right direntry for this @@ -890,7 +897,7 @@ LookupSubframeworkHeader(StringRef Filename, } HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); - if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) { + if (!(FE = FileMgr.getFile(HeadersFilename, /*openFile=*/true))) { // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h" HeadersFilename = FrameworkName; @@ -902,7 +909,7 @@ LookupSubframeworkHeader(StringRef Filename, } HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); - if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) + if (!(FE = FileMgr.getFile(HeadersFilename, /*openFile=*/true))) return nullptr; } @@ -1016,7 +1023,9 @@ void HeaderSearch::MarkFileModuleHeader(const FileEntry *FE, HFI.setHeaderRole(Role); } -bool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){ +bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP, + const FileEntry *File, + bool isImport) { ++NumIncluded; // Count # of attempted #includes. // Get information about this file. @@ -1041,7 +1050,7 @@ bool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){ // if the macro that guards it is defined, we know the #include has no effect. if (const IdentifierInfo *ControllingMacro = FileInfo.getControllingMacro(ExternalLookup)) - if (ControllingMacro->hasMacroDefinition()) { + if (PP.isMacroDefined(ControllingMacro)) { ++NumMultiIncludeFileOptzn; return false; } @@ -1067,7 +1076,7 @@ StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) { bool HeaderSearch::hasModuleMap(StringRef FileName, const DirectoryEntry *Root, bool IsSystem) { - if (!enabledModules() || !LangOpts.ModulesImplicitMaps) + if (!HSOpts->ModuleMaps || !LangOpts.ModulesImplicitMaps) return false; SmallVector<const DirectoryEntry *, 2> FixUpDirectories; @@ -1284,7 +1293,7 @@ void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) { DirNative); // Search each of the ".framework" directories to load them as modules. - for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; + for (llvm::sys::fs::directory_iterator Dir(DirNative, EC), DirEnd; Dir != DirEnd && !EC; Dir.increment(EC)) { if (llvm::sys::path::extension(Dir->path()) != ".framework") continue; @@ -1351,10 +1360,12 @@ void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) { std::error_code EC; SmallString<128> DirNative; llvm::sys::path::native(SearchDir.getDir()->getName(), DirNative); - for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; + for (llvm::sys::fs::directory_iterator Dir(DirNative, EC), DirEnd; Dir != DirEnd && !EC; Dir.increment(EC)) { - loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory(), - SearchDir.isFramework()); + bool IsFramework = llvm::sys::path::extension(Dir->path()) == ".framework"; + if (IsFramework == SearchDir.isFramework()) + loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory(), + SearchDir.isFramework()); } SearchDir.setSearchedAllModuleMaps(true); diff --git a/contrib/llvm/tools/clang/lib/Lex/Lexer.cpp b/contrib/llvm/tools/clang/lib/Lex/Lexer.cpp index ca5252e1c9ce..3f89ea649cbb 100644 --- a/contrib/llvm/tools/clang/lib/Lex/Lexer.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/Lexer.cpp @@ -143,14 +143,8 @@ Lexer::Lexer(SourceLocation fileloc, const LangOptions &langOpts, /// range will outlive it, so it doesn't take ownership of it. Lexer::Lexer(FileID FID, const llvm::MemoryBuffer *FromFile, const SourceManager &SM, const LangOptions &langOpts) - : FileLoc(SM.getLocForStartOfFile(FID)), LangOpts(langOpts) { - - InitLexer(FromFile->getBufferStart(), FromFile->getBufferStart(), - FromFile->getBufferEnd()); - - // We *are* in raw mode. - LexingRawMode = true; -} + : Lexer(SM.getLocForStartOfFile(FID), langOpts, FromFile->getBufferStart(), + FromFile->getBufferStart(), FromFile->getBufferEnd()) {} /// Create_PragmaLexer: Lexer constructor - Create a new lexer object for /// _Pragma expansion. This has a variety of magic semantics that this method @@ -1860,7 +1854,7 @@ bool Lexer::LexAngledStringLiteral(Token &Result, const char *CurPtr) { char C = getAndAdvanceChar(CurPtr, Result); while (C != '>') { // Skip escaped characters. - if (C == '\\') { + if (C == '\\' && CurPtr < BufferEnd) { // Skip the escaped character. getAndAdvanceChar(CurPtr, Result); } else if (C == '\n' || C == '\r' || // Newline. diff --git a/contrib/llvm/tools/clang/lib/Lex/LiteralSupport.cpp b/contrib/llvm/tools/clang/lib/Lex/LiteralSupport.cpp index 03331fb33eb2..aed91648799b 100644 --- a/contrib/llvm/tools/clang/lib/Lex/LiteralSupport.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/LiteralSupport.cpp @@ -144,7 +144,8 @@ static unsigned ProcessCharEscape(const char *ThisTokBegin, int CharVal = llvm::hexDigitValue(ThisTokBuf[0]); if (CharVal == -1) break; // About to shift out a digit? - Overflow |= (ResultChar & 0xF0000000) ? true : false; + if (ResultChar & 0xF0000000) + Overflow = true; ResultChar <<= 4; ResultChar |= CharVal; } @@ -596,7 +597,8 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, if (isFloat) break; // LF invalid. // Check for long long. The L's need to be adjacent and the same case. - if (s+1 != ThisTokEnd && s[1] == s[0]) { + if (s[1] == s[0]) { + assert(s + 1 < ThisTokEnd && "didn't maximally munch?"); if (isFPConstant) break; // long long invalid for floats. isLongLong = true; ++s; // Eat both of them. @@ -610,54 +612,45 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, if (isLong || isLongLong || MicrosoftInteger) break; - // Allow i8, i16, i32, i64, and i128. - if (s + 1 != ThisTokEnd) { + if (!isFPConstant) { + // Allow i8, i16, i32, i64, and i128. switch (s[1]) { - case '8': - if (isFPConstant) break; - s += 2; // i8 suffix - MicrosoftInteger = 8; - break; - case '1': - if (isFPConstant) break; - if (s + 2 == ThisTokEnd) break; - if (s[2] == '6') { - s += 3; // i16 suffix - MicrosoftInteger = 16; - } - else if (s[2] == '2') { - if (s + 3 == ThisTokEnd) break; - if (s[3] == '8') { - s += 4; // i128 suffix - MicrosoftInteger = 128; - } - } - break; - case '3': - if (isFPConstant) break; - if (s + 2 == ThisTokEnd) break; - if (s[2] == '2') { - s += 3; // i32 suffix - MicrosoftInteger = 32; - } - break; - case '6': - if (isFPConstant) break; - if (s + 2 == ThisTokEnd) break; - if (s[2] == '4') { - s += 3; // i64 suffix - MicrosoftInteger = 64; - } - break; - default: - break; - } - if (MicrosoftInteger) + case '8': + s += 2; // i8 suffix + MicrosoftInteger = 8; + break; + case '1': + if (s[2] == '6') { + s += 3; // i16 suffix + MicrosoftInteger = 16; + } else if (s[2] == '2' && s[3] == '8') { + s += 4; // i128 suffix + MicrosoftInteger = 128; + } + break; + case '3': + if (s[2] == '2') { + s += 3; // i32 suffix + MicrosoftInteger = 32; + } + break; + case '6': + if (s[2] == '4') { + s += 3; // i64 suffix + MicrosoftInteger = 64; + } break; + default: + break; + } + } + if (MicrosoftInteger) { + assert(s <= ThisTokEnd && "didn't maximally munch?"); + break; } } // "i", "if", and "il" are user-defined suffixes in C++1y. - if (PP.getLangOpts().CPlusPlus14 && *s == 'i') + if (*s == 'i' && PP.getLangOpts().CPlusPlus14) break; // fall through. case 'j': @@ -755,11 +748,11 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) { s++; int c1 = s[0]; - int c2 = s[1]; // Handle a hex number like 0x1234. - if ((c1 == 'x' || c1 == 'X') && (isHexDigit(c2) || c2 == '.')) { + if ((c1 == 'x' || c1 == 'X') && (isHexDigit(s[1]) || s[1] == '.')) { s++; + assert(s < ThisTokEnd && "didn't maximally munch?"); radix = 16; DigitsBegin = s; s = SkipHexDigits(s); @@ -811,7 +804,7 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) { } // Handle simple binary numbers 0b01010 - if ((c1 == 'b' || c1 == 'B') && (c2 == '0' || c2 == '1')) { + if ((c1 == 'b' || c1 == 'B') && (s[1] == '0' || s[1] == '1')) { // 0b101010 is a C++1y / GCC extension. PP.Diag(TokLoc, PP.getLangOpts().CPlusPlus14 @@ -820,6 +813,7 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) { ? diag::ext_binary_literal_cxx14 : diag::ext_binary_literal); ++s; + assert(s < ThisTokEnd && "didn't maximally munch?"); radix = 2; DigitsBegin = s; s = SkipBinaryDigits(s); diff --git a/contrib/llvm/tools/clang/lib/Lex/MacroArgs.cpp b/contrib/llvm/tools/clang/lib/Lex/MacroArgs.cpp index 9967f3f0e493..1c1979d8e83d 100644 --- a/contrib/llvm/tools/clang/lib/Lex/MacroArgs.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/MacroArgs.cpp @@ -133,12 +133,11 @@ bool MacroArgs::ArgNeedsPreexpansion(const Token *ArgTok, // If there are no identifiers in the argument list, or if the identifiers are // known to not be macros, pre-expansion won't modify it. for (; ArgTok->isNot(tok::eof); ++ArgTok) - if (IdentifierInfo *II = ArgTok->getIdentifierInfo()) { - if (II->hasMacroDefinition() && PP.getMacroInfo(II)->isEnabled()) + if (IdentifierInfo *II = ArgTok->getIdentifierInfo()) + if (II->hasMacroDefinition()) // Return true even though the macro could be a function-like macro - // without a following '(' token. + // without a following '(' token, or could be disabled, or not visible. return true; - } return false; } diff --git a/contrib/llvm/tools/clang/lib/Lex/MacroInfo.cpp b/contrib/llvm/tools/clang/lib/Lex/MacroInfo.cpp index 5416886cc9f7..109b6c12b89b 100644 --- a/contrib/llvm/tools/clang/lib/Lex/MacroInfo.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/MacroInfo.cpp @@ -218,13 +218,9 @@ void MacroDirective::dump() const { if (auto *Prev = getPrevious()) Out << " prev " << Prev; if (IsFromPCH) Out << " from_pch"; - if (IsImported) Out << " imported"; - if (IsAmbiguous) Out << " ambiguous"; - if (IsPublic) - Out << " public"; - else if (isa<VisibilityMacroDirective>(this)) - Out << " private"; + if (isa<VisibilityMacroDirective>(this)) + Out << (IsPublic ? " public" : " private"); if (auto *DMD = dyn_cast<DefMacroDirective>(this)) { if (auto *Info = DMD->getInfo()) { @@ -234,3 +230,12 @@ void MacroDirective::dump() const { } Out << "\n"; } + +ModuleMacro *ModuleMacro::create(Preprocessor &PP, Module *OwningModule, + IdentifierInfo *II, MacroInfo *Macro, + ArrayRef<ModuleMacro *> Overrides) { + void *Mem = PP.getPreprocessorAllocator().Allocate( + sizeof(ModuleMacro) + sizeof(ModuleMacro *) * Overrides.size(), + llvm::alignOf<ModuleMacro>()); + return new (Mem) ModuleMacro(OwningModule, II, Macro, Overrides); +} diff --git a/contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp b/contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp index ef322d8cdc4c..412918362d32 100644 --- a/contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp @@ -89,7 +89,9 @@ ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, HeaderSearch &HeaderInfo) : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target), HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr), - CompilingModule(nullptr), SourceModule(nullptr) {} + CompilingModule(nullptr), SourceModule(nullptr), NumCreatedModules(0) { + MMapLangOpts.LineComment = true; +} ModuleMap::~ModuleMap() { for (llvm::StringMap<Module *>::iterator I = Modules.begin(), @@ -203,35 +205,32 @@ ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File, return KnownHeader(); } -// Returns true if RequestingModule directly uses RequestedModule. -static bool directlyUses(const Module *RequestingModule, - const Module *RequestedModule) { - return std::find(RequestingModule->DirectUses.begin(), - RequestingModule->DirectUses.end(), - RequestedModule) != RequestingModule->DirectUses.end(); -} - static bool violatesPrivateInclude(Module *RequestingModule, const FileEntry *IncFileEnt, ModuleMap::ModuleHeaderRole Role, Module *RequestedModule) { 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. - 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"); + if (IsPrivateRole) { + // 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. + bool IsPrivate = false; + SmallVectorImpl<Module::Header> *HeaderList[] = { + &RequestedModule->Headers[Module::HK_Private], + &RequestedModule->Headers[Module::HK_PrivateTextual]}; + for (auto *Hs : HeaderList) + IsPrivate |= + std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) { + return H.Entry == IncFileEnt; + }) != Hs->end(); + assert((!IsPrivateRole || IsPrivate) && "inconsistent headers and roles"); + } #endif return IsPrivateRole && + // FIXME: Should we map RequestingModule to its top-level module here + // too? This check is redundant with the isSubModuleOf check in + // diagnoseHeaderInclusion. RequestedModule->getTopLevelModule() != RequestingModule; } @@ -259,7 +258,8 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule, if (Known != Headers.end()) { for (const KnownHeader &Header : Known->second) { // If 'File' is part of 'RequestingModule' we can definitely include it. - if (Header.getModule() == RequestingModule) + if (Header.getModule() && + Header.getModule()->isSubModuleOf(RequestingModule)) return; // Remember private headers for later printing of a diagnostic. @@ -272,7 +272,7 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule, // If uses need to be specified explicitly, we are only allowed to return // modules that are explicitly used by the requesting module. if (RequestingModule && LangOpts.ModulesDeclUse && - !directlyUses(RequestingModule, Header.getModule())) { + !RequestingModule->directlyUses(Header.getModule())) { NotUsed = Header.getModule(); continue; } @@ -286,14 +286,14 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule, // We have found a header, but it is private. if (Private) { - Diags.Report(FilenameLoc, diag::error_use_of_private_header_outside_module) + Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module) << Filename; return; } // We have found a module, but we don't use it. if (NotUsed) { - Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module) + Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module) << RequestingModule->getFullModuleName() << Filename; return; } @@ -304,7 +304,7 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule, // At this point, only non-modular includes remain. if (LangOpts.ModulesStrictDeclUse) { - Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module) + Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module) << RequestingModule->getFullModuleName() << Filename; } else if (RequestingModule) { diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ? @@ -314,6 +314,22 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule, } } +static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New, + const ModuleMap::KnownHeader &Old) { + // Prefer a public header over a private header. + if ((New.getRole() & ModuleMap::PrivateHeader) != + (Old.getRole() & ModuleMap::PrivateHeader)) + return !(New.getRole() & ModuleMap::PrivateHeader); + + // Prefer a non-textual header over a textual header. + if ((New.getRole() & ModuleMap::TextualHeader) != + (Old.getRole() & ModuleMap::TextualHeader)) + return !(New.getRole() & ModuleMap::TextualHeader); + + // Don't have a reason to choose between these. Just keep the first one. + return false; +} + ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File, Module *RequestingModule, @@ -345,11 +361,10 @@ ModuleMap::findModuleForHeader(const FileEntry *File, // If uses need to be specified explicitly, we are only allowed to return // modules that are explicitly used by the requesting module. if (RequestingModule && LangOpts.ModulesDeclUse && - !directlyUses(RequestingModule, I->getModule())) + !RequestingModule->directlyUses(I->getModule())) continue; - // Prefer a public header over a private header. - if (!Result || (Result.getRole() & ModuleMap::PrivateHeader)) + if (!Result || isBetterKnownHeader(*I, Result)) Result = *I; } return MakeResult(Result); @@ -548,7 +563,7 @@ ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, // Create a new module with this name. Module *Result = new Module(Name, SourceLocation(), Parent, - IsFramework, IsExplicit); + IsFramework, IsExplicit, NumCreatedModules++); if (LangOpts.CurrentModule == Name) { SourceModule = Result; SourceModuleName = Name; @@ -678,7 +693,8 @@ Module *ModuleMap::inferFrameworkModule(StringRef ModuleName, return nullptr; Module *Result = new Module(ModuleName, SourceLocation(), Parent, - /*IsFramework=*/true, /*IsExplicit=*/false); + /*IsFramework=*/true, /*IsExplicit=*/false, + NumCreatedModules++); InferredModuleAllowedBy[Result] = ModuleMapFile; Result->IsInferred = true; if (LangOpts.CurrentModule == ModuleName) { @@ -689,14 +705,16 @@ Module *ModuleMap::inferFrameworkModule(StringRef ModuleName, Result->IsSystem |= Attrs.IsSystem; Result->IsExternC |= Attrs.IsExternC; Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive; + Result->Directory = FrameworkDir; if (!Parent) Modules[ModuleName] = Result; // umbrella header "umbrella-header-name" - Result->Umbrella = UmbrellaHeader; - Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader)); - UmbrellaDirs[UmbrellaHeader->getDir()] = Result; + // + // The "Headers/" component of the name is implied because this is + // a framework module. + setUmbrellaHeader(Result, UmbrellaHeader, ModuleName + ".h"); // export * Result->Exports.push_back(Module::ExportDecl(nullptr, true)); @@ -711,8 +729,7 @@ Module *ModuleMap::inferFrameworkModule(StringRef ModuleName, = StringRef(FrameworkDir->getName()); llvm::sys::path::append(SubframeworksDirName, "Frameworks"); llvm::sys::path::native(SubframeworksDirName); - for (llvm::sys::fs::directory_iterator - Dir(SubframeworksDirName.str(), EC), DirEnd; + for (llvm::sys::fs::directory_iterator Dir(SubframeworksDirName, EC), DirEnd; Dir != DirEnd && !EC; Dir.increment(EC)) { if (!StringRef(Dir->path()).endswith(".framework")) continue; @@ -758,14 +775,18 @@ Module *ModuleMap::inferFrameworkModule(StringRef ModuleName, return Result; } -void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){ +void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader, + Twine NameAsWritten) { Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader)); Mod->Umbrella = UmbrellaHeader; + Mod->UmbrellaAsWritten = NameAsWritten.str(); UmbrellaDirs[UmbrellaHeader->getDir()] = Mod; } -void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) { +void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir, + Twine NameAsWritten) { Mod->Umbrella = UmbrellaDir; + Mod->UmbrellaAsWritten = NameAsWritten.str(); UmbrellaDirs[UmbrellaDir] = Mod; } @@ -850,50 +871,44 @@ void ModuleMap::dump() { } bool ModuleMap::resolveExports(Module *Mod, bool Complain) { - bool HadError = false; - for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) { - Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I], - Complain); + auto Unresolved = std::move(Mod->UnresolvedExports); + Mod->UnresolvedExports.clear(); + for (auto &UE : Unresolved) { + Module::ExportDecl Export = resolveExport(Mod, UE, Complain); if (Export.getPointer() || Export.getInt()) Mod->Exports.push_back(Export); else - HadError = true; + Mod->UnresolvedExports.push_back(UE); } - Mod->UnresolvedExports.clear(); - return HadError; + return !Mod->UnresolvedExports.empty(); } bool ModuleMap::resolveUses(Module *Mod, bool Complain) { - bool HadError = false; - for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) { - Module *DirectUse = - resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain); + auto Unresolved = std::move(Mod->UnresolvedDirectUses); + Mod->UnresolvedDirectUses.clear(); + for (auto &UDU : Unresolved) { + Module *DirectUse = resolveModuleId(UDU, Mod, Complain); if (DirectUse) Mod->DirectUses.push_back(DirectUse); else - HadError = true; + Mod->UnresolvedDirectUses.push_back(UDU); } - Mod->UnresolvedDirectUses.clear(); - return HadError; + return !Mod->UnresolvedDirectUses.empty(); } bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) { - bool HadError = false; - for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) { - Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id, - Mod, Complain); - if (!OtherMod) { - HadError = true; - continue; - } - - Module::Conflict Conflict; - Conflict.Other = OtherMod; - Conflict.Message = Mod->UnresolvedConflicts[I].Message; - Mod->Conflicts.push_back(Conflict); - } + auto Unresolved = std::move(Mod->UnresolvedConflicts); Mod->UnresolvedConflicts.clear(); - return HadError; + for (auto &UC : Unresolved) { + if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) { + Module::Conflict Conflict; + Conflict.Other = OtherMod; + Conflict.Message = UC.Message; + Mod->Conflicts.push_back(Conflict); + } else + Mod->UnresolvedConflicts.push_back(UC); + } + return !Mod->UnresolvedConflicts.empty(); } Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) { @@ -1565,7 +1580,7 @@ void ModuleMapParser::parseExternModuleDecl() { if (llvm::sys::path::is_relative(FileNameRef)) { ModuleMapFileName += Directory->getName(); llvm::sys::path::append(ModuleMapFileName, FileName); - FileNameRef = ModuleMapFileName.str(); + FileNameRef = ModuleMapFileName; } if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef)) Map.parseModuleMapFile( @@ -1712,7 +1727,7 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, // Check whether this file is in the public headers. llvm::sys::path::append(RelativePathName, "Headers", Header.FileName); - llvm::sys::path::append(FullPathName, RelativePathName.str()); + llvm::sys::path::append(FullPathName, RelativePathName); File = SourceMgr.getFileManager().getFile(FullPathName); if (!File) { @@ -1722,13 +1737,13 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, FullPathName.resize(FullPathLength); llvm::sys::path::append(RelativePathName, "PrivateHeaders", Header.FileName); - llvm::sys::path::append(FullPathName, RelativePathName.str()); + llvm::sys::path::append(FullPathName, RelativePathName); File = SourceMgr.getFileManager().getFile(FullPathName); } } else { // Lookup for normal headers. llvm::sys::path::append(RelativePathName, Header.FileName); - llvm::sys::path::append(FullPathName, RelativePathName.str()); + llvm::sys::path::append(FullPathName, RelativePathName); File = SourceMgr.getFileManager().getFile(FullPathName); // If this is a system module with a top-level header, this header @@ -1744,7 +1759,13 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, // 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) { + // + // For local visibility, entirely replace the system file with our + // one and textually include the system one. We need to pass macros + // from our header to the system one if we #include_next it. + // + // FIXME: Can we do this in all cases? + if (BuiltinFile && (!File || Map.LangOpts.ModulesLocalVisibility)) { File = BuiltinFile; RelativePathName = BuiltinPathName; BuiltinFile = nullptr; @@ -1764,7 +1785,7 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, HadError = true; } else { // Record this umbrella header. - Map.setUmbrellaHeader(ActiveModule, File); + Map.setUmbrellaHeader(ActiveModule, File, RelativePathName.str()); } } else if (LeadingToken == MMToken::ExcludeKeyword) { Module::Header H = {RelativePathName.str(), File}; @@ -1846,7 +1867,7 @@ void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { } // Record this umbrella directory. - Map.setUmbrellaDir(ActiveModule, Dir); + Map.setUmbrellaDir(ActiveModule, Dir, DirName); } /// \brief Parse a module export declaration. @@ -1897,18 +1918,21 @@ void ModuleMapParser::parseExportDecl() { ActiveModule->UnresolvedExports.push_back(Unresolved); } -/// \brief Parse a module uses declaration. +/// \brief Parse a module use declaration. /// -/// uses-declaration: -/// 'uses' wildcard-module-id +/// use-declaration: +/// 'use' wildcard-module-id void ModuleMapParser::parseUseDecl() { assert(Tok.is(MMToken::UseKeyword)); - consumeToken(); + auto KWLoc = consumeToken(); // Parse the module-id. ModuleId ParsedModuleId; parseModuleId(ParsedModuleId); - ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId); + if (ActiveModule->Parent) + Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule); + else + ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId); } /// \brief Parse a link declaration. diff --git a/contrib/llvm/tools/clang/lib/Lex/PPConditionalDirectiveRecord.cpp b/contrib/llvm/tools/clang/lib/Lex/PPConditionalDirectiveRecord.cpp index 99b87a0a1525..12a77849b8b3 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PPConditionalDirectiveRecord.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/PPConditionalDirectiveRecord.cpp @@ -84,14 +84,14 @@ void PPConditionalDirectiveRecord::If(SourceLocation Loc, void PPConditionalDirectiveRecord::Ifdef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDirective *MD) { + const MacroDefinition &MD) { addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); CondDirectiveStack.push_back(Loc); } void PPConditionalDirectiveRecord::Ifndef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDirective *MD) { + const MacroDefinition &MD) { addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); CondDirectiveStack.push_back(Loc); } diff --git a/contrib/llvm/tools/clang/lib/Lex/PPDirectives.cpp b/contrib/llvm/tools/clang/lib/Lex/PPDirectives.cpp index bf0ce72f6668..ec06e790f018 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PPDirectives.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/PPDirectives.cpp @@ -62,26 +62,14 @@ MacroInfo *Preprocessor::AllocateDeserializedMacroInfo(SourceLocation L, return MI; } -DefMacroDirective * -Preprocessor::AllocateDefMacroDirective(MacroInfo *MI, SourceLocation Loc, - 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); +DefMacroDirective *Preprocessor::AllocateDefMacroDirective(MacroInfo *MI, + SourceLocation Loc) { + return new (BP) DefMacroDirective(MI, Loc); } UndefMacroDirective * -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); +Preprocessor::AllocateUndefMacroDirective(SourceLocation UndefLoc) { + return new (BP) UndefMacroDirective(UndefLoc); } VisibilityMacroDirective * @@ -182,11 +170,13 @@ bool Preprocessor::CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, return Diag(MacroNameTok, diag::err_defined_macro_name); } - 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 (isDefineUndef == MU_Undef) { + auto *MI = getMacroInfo(II); + if (MI && MI->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 @@ -585,16 +575,16 @@ void Preprocessor::PTHSkipExcludedConditionalBlock() { } } -Module *Preprocessor::getModuleForLocation(SourceLocation FilenameLoc) { +Module *Preprocessor::getModuleForLocation(SourceLocation Loc) { ModuleMap &ModMap = HeaderInfo.getModuleMap(); - if (SourceMgr.isInMainFile(FilenameLoc)) { + if (SourceMgr.isInMainFile(Loc)) { if (Module *CurMod = getCurrentModule()) return CurMod; // Compiling a module. return HeaderInfo.getModuleMap().SourceModule; // Compiling a source. } // Try to determine the module of the include directive. // FIXME: Look into directly passing the FileEntry from LookupFile instead. - FileID IDOfIncl = SourceMgr.getFileID(SourceMgr.getExpansionLoc(FilenameLoc)); + FileID IDOfIncl = SourceMgr.getFileID(SourceMgr.getExpansionLoc(Loc)); if (const FileEntry *EntryOfIncl = SourceMgr.getFileEntryForID(IDOfIncl)) { // The include comes from a file. return ModMap.findModuleForHeader(EntryOfIncl).getModule(); @@ -605,6 +595,11 @@ Module *Preprocessor::getModuleForLocation(SourceLocation FilenameLoc) { } } +Module *Preprocessor::getModuleContainingLocation(SourceLocation Loc) { + return HeaderInfo.getModuleMap().inferModuleFromLocation( + FullSourceLoc(Loc, SourceMgr)); +} + const FileEntry *Preprocessor::LookupFile( SourceLocation FilenameLoc, StringRef Filename, @@ -1233,7 +1228,7 @@ void Preprocessor::HandleUserDiagnosticDirective(Token &Tok, // Find the first non-whitespace character, so that we can make the // diagnostic more succinct. - StringRef Msg = Message.str().ltrim(" "); + StringRef Msg = StringRef(Message).ltrim(" "); if (isWarning) Diag(Tok, diag::pp_hash_warning) << Msg; @@ -1290,7 +1285,7 @@ void Preprocessor::HandleMacroPublicDirective(Token &Tok) { IdentifierInfo *II = MacroNameTok.getIdentifierInfo(); // Okay, we finally have a valid identifier to undef. - MacroDirective *MD = getMacroDirective(II); + MacroDirective *MD = getLocalMacroDirective(II); // If the macro is not defined, this is an error. if (!MD) { @@ -1317,7 +1312,7 @@ void Preprocessor::HandleMacroPrivateDirective(Token &Tok) { IdentifierInfo *II = MacroNameTok.getIdentifierInfo(); // Okay, we finally have a valid identifier to undef. - MacroDirective *MD = getMacroDirective(II); + MacroDirective *MD = getLocalMacroDirective(II); // If the macro is not defined, this is an error. if (!MD) { @@ -1444,6 +1439,8 @@ bool Preprocessor::ConcatenateIncludeName(SmallString<128> &FilenameBuffer, static void EnterAnnotationToken(Preprocessor &PP, SourceLocation Begin, SourceLocation End, tok::TokenKind Kind, void *AnnotationVal) { + // FIXME: Produce this as the current token directly, rather than + // allocating a new token for it. Token *Tok = new Token[1]; Tok[0].startToken(); Tok[0].setKind(Kind); @@ -1453,6 +1450,51 @@ static void EnterAnnotationToken(Preprocessor &PP, PP.EnterTokenStream(Tok, 1, true, true); } +/// \brief Produce a diagnostic informing the user that a #include or similar +/// was implicitly treated as a module import. +static void diagnoseAutoModuleImport( + Preprocessor &PP, SourceLocation HashLoc, Token &IncludeTok, + ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> Path, + SourceLocation PathEnd) { + assert(PP.getLangOpts().ObjC2 && "no import syntax available"); + + SmallString<128> PathString; + for (unsigned I = 0, N = Path.size(); I != N; ++I) { + if (I) + PathString += '.'; + PathString += Path[I].first->getName(); + } + int IncludeKind = 0; + + switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) { + case tok::pp_include: + IncludeKind = 0; + break; + + case tok::pp_import: + IncludeKind = 1; + break; + + case tok::pp_include_next: + IncludeKind = 2; + break; + + case tok::pp___include_macros: + IncludeKind = 3; + break; + + default: + llvm_unreachable("unknown include directive kind"); + } + + CharSourceRange ReplaceRange(SourceRange(HashLoc, PathEnd), + /*IsTokenRange=*/false); + PP.Diag(HashLoc, diag::warn_auto_module_import) + << IncludeKind << PathString + << FixItHint::CreateReplacement(ReplaceRange, + ("@import " + PathString + ";").str()); +} + /// HandleIncludeDirective - The "\#include" tokens have just been read, read /// the file to be included from the lexer, then include it! This is a common /// routine with functionality shared between \#include, \#include_next and @@ -1491,7 +1533,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, FilenameBuffer.push_back('<'); if (ConcatenateIncludeName(FilenameBuffer, End)) return; // Found <eod> but no ">"? Diagnostic already emitted. - Filename = FilenameBuffer.str(); + Filename = FilenameBuffer; CharEnd = End.getLocWithOffset(1); break; default: @@ -1563,8 +1605,8 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, Callbacks ? &SearchPath : nullptr, Callbacks ? &RelativePath : nullptr, HeaderInfo.getHeaderSearchOpts().ModuleMaps ? &SuggestedModule : nullptr); - if (Callbacks) { - if (!File) { + if (!File) { + if (Callbacks) { // Give the clients a chance to recover. SmallString<128> RecoveryPath; if (Callbacks->FileNotFound(Filename, RecoveryPath)) { @@ -1584,18 +1626,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, } } } - - if (!SuggestedModule || !getLangOpts().Modules) { - // Notify the callback object that we've seen an inclusion directive. - Callbacks->InclusionDirective(HashLoc, IncludeTok, - LangOpts.MSVCCompat ? NormalizedPath.c_str() - : Filename, - isAngled, FilenameRange, File, SearchPath, - RelativePath, /*ImportedModule=*/nullptr); - } - } - if (!File) { if (!SuppressIncludeNotFoundError) { // If the file could not be located and it was included via angle // brackets, we can attempt a lookup as though it were a quoted path to @@ -1616,19 +1647,27 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, FixItHint::CreateReplacement(Range, "\"" + Filename.str() + "\""); } } + // If the file is still not found, just go with the vanilla diagnostic if (!File) Diag(FilenameTok, diag::err_pp_file_not_found) << Filename; } - if (!File) - return; } - // If we are supposed to import a module rather than including the header, - // do so now. - if (SuggestedModule && getLangOpts().Modules && + // Should we enter the source file? Set to false if either the source file is + // known to have no effect beyond its effect on module visibility -- that is, + // if it's got an include guard that is already defined or is a modular header + // we've imported or already built. + bool ShouldEnter = true; + + // Determine whether we should try to import the module for this #include, if + // there is one. Don't do so if precompiled module support is disabled or we + // are processing this module textually (because we're building the module). + if (File && SuggestedModule && getLangOpts().Modules && SuggestedModule.getModule()->getTopLevelModuleName() != - getLangOpts().ImplementationOfModule) { + getLangOpts().CurrentModule && + 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? @@ -1639,111 +1678,57 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, std::reverse(Path.begin(), Path.end()); // Warn that we're replacing the include/import with a module import. - SmallString<128> PathString; - for (unsigned I = 0, N = Path.size(); I != N; ++I) { - if (I) - PathString += '.'; - PathString += Path[I].first->getName(); - } - int IncludeKind = 0; - - switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) { - case tok::pp_include: - IncludeKind = 0; - break; - - case tok::pp_import: - IncludeKind = 1; - break; - - case tok::pp_include_next: - IncludeKind = 2; - break; - - case tok::pp___include_macros: - IncludeKind = 3; - break; - - default: - llvm_unreachable("unknown include directive kind"); - } - - // Determine whether we are actually building the module that this - // include directive maps to. - bool BuildingImportedModule - = Path[0].first->getName() == getLangOpts().CurrentModule; - - if (!BuildingImportedModule && getLangOpts().ObjC2) { - // If we're not building the imported module, warn that we're going - // to automatically turn this inclusion directive into a module import. - // We only do this in Objective-C, where we have a module-import syntax. - CharSourceRange ReplaceRange(SourceRange(HashLoc, CharEnd), - /*IsTokenRange=*/false); - Diag(HashLoc, diag::warn_auto_module_import) - << IncludeKind << PathString - << FixItHint::CreateReplacement(ReplaceRange, - "@import " + PathString.str().str() + ";"); - } + // We only do this in Objective-C, where we have a module-import syntax. + if (getLangOpts().ObjC2) + diagnoseAutoModuleImport(*this, HashLoc, IncludeTok, Path, CharEnd); - // Load the module. Only make macros visible. We'll make the declarations + // Load the module to import its macros. We'll make the declarations // visible when the parser gets here. - Module::NameVisibilityKind Visibility = Module::MacrosVisible; - ModuleLoadResult Imported - = TheModuleLoader.loadModule(IncludeTok.getLocation(), Path, Visibility, - /*IsIncludeDirective=*/true); + // FIXME: Pass SuggestedModule in here rather than converting it to a path + // and making the module loader convert it back again. + ModuleLoadResult Imported = TheModuleLoader.loadModule( + IncludeTok.getLocation(), Path, Module::Hidden, + /*IsIncludeDirective=*/true); assert((Imported == nullptr || Imported == SuggestedModule.getModule()) && "the imported module is different than the suggested one"); - if (!Imported && hadModuleLoaderFatalFailure()) { - // With a fatal failure in the module loader, we abort parsing. - Token &Result = IncludeTok; - if (CurLexer) { - Result.startToken(); - CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd, tok::eof); - CurLexer->cutOffLexing(); - } else { - assert(CurPTHLexer && "#include but no current lexer set!"); - CurPTHLexer->getEOF(Result); - } - return; - } - - // If this header isn't part of the module we're building, we're done. - if (!BuildingImportedModule && Imported) { - if (Callbacks) { - Callbacks->InclusionDirective(HashLoc, IncludeTok, Filename, isAngled, - FilenameRange, File, - SearchPath, RelativePath, Imported); - } - - if (IncludeKind != 3) { - // Let the parser know that we hit a module import, and it should - // make the module visible. - // FIXME: Produce this as the current token directly, rather than - // allocating a new token for it. - EnterAnnotationToken(*this, HashLoc, End, tok::annot_module_include, - Imported); + if (Imported) + ShouldEnter = false; + else if (Imported.isMissingExpected()) { + // We failed to find a submodule that we assumed would exist (because it + // was in the directory of an umbrella header, for instance), but no + // actual module exists for it (because the umbrella header is + // incomplete). Treat this as a textual inclusion. + SuggestedModule = ModuleMap::KnownHeader(); + } else { + // We hit an error processing the import. Bail out. + if (hadModuleLoaderFatalFailure()) { + // With a fatal failure in the module loader, we abort parsing. + Token &Result = IncludeTok; + if (CurLexer) { + Result.startToken(); + CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd, tok::eof); + CurLexer->cutOffLexing(); + } else { + assert(CurPTHLexer && "#include but no current lexer set!"); + CurPTHLexer->getEOF(Result); + } } return; } - - // If we failed to find a submodule that we expected to find, we can - // continue. Otherwise, there's an error in the included file, so we - // don't want to include it. - if (!BuildingImportedModule && !Imported.isMissingExpected()) { - return; - } } - if (Callbacks && SuggestedModule) { - // We didn't notify the callback object that we've seen an inclusion - // directive before. Now that we are parsing the include normally and not - // turning it to a module import, notify the callback object. - Callbacks->InclusionDirective(HashLoc, IncludeTok, Filename, isAngled, - FilenameRange, File, - SearchPath, RelativePath, - /*ImportedModule=*/nullptr); + if (Callbacks) { + // Notify the callback object that we've seen an inclusion directive. + Callbacks->InclusionDirective( + HashLoc, IncludeTok, + LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, isAngled, + FilenameRange, File, SearchPath, RelativePath, + ShouldEnter ? nullptr : SuggestedModule.getModule()); } + + if (!File) + return; // The #included file will be considered to be a system header if either it is // in a system include directory, or if the #includer is a system include @@ -1752,11 +1737,28 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, std::max(HeaderInfo.getFileDirFlavor(File), SourceMgr.getFileCharacteristic(FilenameTok.getLocation())); + // FIXME: If we have a suggested module, and we've already visited this file, + // don't bother entering it again. We know it has no further effect. + // Ask HeaderInfo if we should enter this #include file. If not, #including // this file will have no effect. - if (!HeaderInfo.ShouldEnterIncludeFile(File, isImport)) { + if (ShouldEnter && + !HeaderInfo.ShouldEnterIncludeFile(*this, File, isImport)) { + ShouldEnter = false; if (Callbacks) Callbacks->FileSkipped(*File, FilenameTok, FileCharacter); + } + + // If we don't need to enter the file, stop now. + if (!ShouldEnter) { + // If this is a module import, make it visible if needed. + if (auto *M = SuggestedModule.getModule()) { + makeModuleVisible(M, HashLoc); + + if (IncludeTok.getIdentifierInfo()->getPPKeywordID() != + tok::pp___include_macros) + EnterAnnotationToken(*this, HashLoc, End, tok::annot_module_include, M); + } return; } @@ -1769,26 +1771,24 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, FileID FID = SourceMgr.createFileID(File, IncludePos, FileCharacter); assert(!FID.isInvalid() && "Expected valid file ID"); - // Determine if we're switching to building a new submodule, and which one. - ModuleMap::KnownHeader BuildingModule; - if (getLangOpts().Modules && !getLangOpts().CurrentModule.empty()) { - Module *RequestingModule = getModuleForLocation(FilenameLoc); - BuildingModule = - HeaderInfo.getModuleMap().findModuleForHeader(File, RequestingModule); - } - // If all is good, enter the new file! if (EnterSourceFile(FID, CurDir, FilenameTok.getLocation())) return; - // If we're walking into another part of the same module, let the parser - // know that any future declarations are within that other submodule. - if (BuildingModule) { + // Determine if we're switching to building a new submodule, and which one. + if (auto *M = SuggestedModule.getModule()) { assert(!CurSubmodule && "should not have marked this as a module yet"); - CurSubmodule = BuildingModule.getModule(); + CurSubmodule = M; - EnterAnnotationToken(*this, HashLoc, End, tok::annot_module_begin, - CurSubmodule); + // Let the macro handling code know that any future macros are within + // the new submodule. + EnterSubmodule(M, HashLoc); + + // Let the parser know that any future declarations are within the new + // submodule. + // FIXME: There's no point doing this if we're handling a #__include_macros + // directive. + EnterAnnotationToken(*this, HashLoc, End, tok::annot_module_begin, M); } } @@ -2290,9 +2290,9 @@ void Preprocessor::HandleUndefDirective(Token &UndefTok) { // Check to see if this is the last token on the #undef line. CheckEndOfDirective("undef"); - // Okay, we finally have a valid identifier to undef. - MacroDirective *MD = getMacroDirective(MacroNameTok.getIdentifierInfo()); - const MacroInfo *MI = MD ? MD->getMacroInfo() : nullptr; + // Okay, we have a valid identifier to undef. + auto *II = MacroNameTok.getIdentifierInfo(); + auto MD = getMacroDefinition(II); // If the callbacks want to know, tell them about the macro #undef. // Note: no matter if the macro was defined or not. @@ -2300,6 +2300,7 @@ void Preprocessor::HandleUndefDirective(Token &UndefTok) { Callbacks->MacroUndefined(MacroNameTok, MD); // If the macro is not defined, this is a noop undef, just return. + const MacroInfo *MI = MD.getMacroInfo(); if (!MI) return; @@ -2344,8 +2345,8 @@ void Preprocessor::HandleIfdefDirective(Token &Result, bool isIfndef, CheckEndOfDirective(isIfndef ? "ifndef" : "ifdef"); IdentifierInfo *MII = MacroNameTok.getIdentifierInfo(); - MacroDirective *MD = getMacroDirective(MII); - MacroInfo *MI = MD ? MD->getMacroInfo() : nullptr; + auto MD = getMacroDefinition(MII); + MacroInfo *MI = MD.getMacroInfo(); if (CurPPLexer->getConditionalStackDepth() == 0) { // If the start of a top-level #ifdef and if the macro is not defined, diff --git a/contrib/llvm/tools/clang/lib/Lex/PPExpressions.cpp b/contrib/llvm/tools/clang/lib/Lex/PPExpressions.cpp index 9cf72cf8f8fb..44513023395d 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PPExpressions.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/PPExpressions.cpp @@ -108,15 +108,13 @@ static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT, // Otherwise, we got an identifier, is it defined to something? IdentifierInfo *II = PeekTok.getIdentifierInfo(); - Result.Val = II->hasMacroDefinition(); - Result.Val.setIsUnsigned(false); // Result is signed intmax_t. + MacroDefinition Macro = PP.getMacroDefinition(II); + Result.Val = !!Macro; + Result.Val.setIsUnsigned(false); // Result is signed intmax_t. - MacroDirective *Macro = nullptr; // If there is a macro, mark it used. - if (Result.Val != 0 && ValueLive) { - Macro = PP.getMacroDirective(II); - PP.markMacroAsUsed(Macro->getMacroInfo()); - } + if (Result.Val != 0 && ValueLive) + PP.markMacroAsUsed(Macro.getMacroInfo()); // Save macro token for callback. Token macroToken(PeekTok); @@ -144,11 +142,7 @@ static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT, // Invoke the 'defined' callback. if (PPCallbacks *Callbacks = PP.getPPCallbacks()) { - MacroDirective *MD = Macro; - // Pass the MacroInfo for the macro name even if the value is dead. - if (!MD && Result.Val != 0) - MD = PP.getMacroDirective(II); - Callbacks->Defined(macroToken, MD, + Callbacks->Defined(macroToken, Macro, SourceRange(beginLoc, PeekTok.getLocation())); } @@ -310,7 +304,9 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, // Set the value. Val = Literal.getValue(); // Set the signedness. UTF-16 and UTF-32 are always unsigned - if (!Literal.isUTF16() && !Literal.isUTF32()) + if (Literal.isWide()) + Val.setIsUnsigned(!TargetInfo::isTypeSigned(TI.getWCharType())); + else if (!Literal.isUTF16() && !Literal.isUTF32()) Val.setIsUnsigned(!PP.getLangOpts().CharIsSigned); if (Result.Val.getBitWidth() > Val.getBitWidth()) { @@ -732,8 +728,7 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, /// EvaluateDirectiveExpression - Evaluate an integer constant expression that /// may occur after a #if or #elif directive. If the expression is equivalent /// to "!defined(X)" return X in IfNDefMacro. -bool Preprocessor:: -EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) { +bool Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) { SaveAndRestore<bool> PPDir(ParsingIfOrElifDirective, true); // Save the current state of 'DisableMacroExpansion' and reset it to false. If // 'DisableMacroExpansion' is true, then we must be in a macro argument list diff --git a/contrib/llvm/tools/clang/lib/Lex/PPLexerChange.cpp b/contrib/llvm/tools/clang/lib/Lex/PPLexerChange.cpp index fb5e2b05808c..e68fb7df8e88 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PPLexerChange.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/PPLexerChange.cpp @@ -309,7 +309,7 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { } if (const IdentifierInfo *DefinedMacro = CurPPLexer->MIOpt.GetDefinedMacro()) { - if (!ControllingMacro->hasMacroDefinition() && + if (!isMacroDefined(ControllingMacro) && DefinedMacro != ControllingMacro && HeaderInfo.FirstTimeLexingFile(FE)) { @@ -400,6 +400,9 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { CurLexer->FormTokenWithChars(Result, EndPos, tok::annot_module_end); Result.setAnnotationEndLoc(Result.getLocation()); Result.setAnnotationValue(CurSubmodule); + + // We're done with this submodule. + LeaveSubmodule(); } // We're done with the #included file. @@ -471,7 +474,7 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { if (!getDiagnostics().isIgnored(diag::warn_uncovered_module_header, StartLoc)) { ModuleMap &ModMap = getHeaderSearchInfo().getModuleMap(); - const DirectoryEntry *Dir = Mod->getUmbrellaDir(); + const DirectoryEntry *Dir = Mod->getUmbrellaDir().Entry; vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem(); std::error_code EC; for (vfs::recursive_directory_iterator Entry(FS, Dir->getName(), EC), End; @@ -605,3 +608,126 @@ void Preprocessor::HandleMicrosoftCommentPaste(Token &Tok) { // preprocessor directive mode), so just return EOF as our token. assert(!FoundLexer && "Lexer should return EOD before EOF in PP mode"); } + +void Preprocessor::EnterSubmodule(Module *M, SourceLocation ImportLoc) { + if (!getLangOpts().ModulesLocalVisibility) { + // Just track that we entered this submodule. + BuildingSubmoduleStack.push_back( + BuildingSubmoduleInfo(M, ImportLoc, CurSubmoduleState)); + return; + } + + // Resolve as much of the module definition as we can now, before we enter + // one of its headers. + // FIXME: Can we enable Complain here? + // FIXME: Can we do this when local visibility is disabled? + ModuleMap &ModMap = getHeaderSearchInfo().getModuleMap(); + ModMap.resolveExports(M, /*Complain=*/false); + ModMap.resolveUses(M, /*Complain=*/false); + ModMap.resolveConflicts(M, /*Complain=*/false); + + // If this is the first time we've entered this module, set up its state. + auto R = Submodules.insert(std::make_pair(M, SubmoduleState())); + auto &State = R.first->second; + bool FirstTime = R.second; + if (FirstTime) { + // Determine the set of starting macros for this submodule; take these + // from the "null" module (the predefines buffer). + auto &StartingMacros = NullSubmoduleState.Macros; + + // Restore to the starting state. + // FIXME: Do this lazily, when each macro name is first referenced. + for (auto &Macro : StartingMacros) { + MacroState MS(Macro.second.getLatest()); + MS.setOverriddenMacros(*this, Macro.second.getOverriddenMacros()); + State.Macros.insert(std::make_pair(Macro.first, std::move(MS))); + } + } + + // Track that we entered this module. + BuildingSubmoduleStack.push_back( + BuildingSubmoduleInfo(M, ImportLoc, CurSubmoduleState)); + + // Switch to this submodule as the current submodule. + CurSubmoduleState = &State; + + // This module is visible to itself. + if (FirstTime) + makeModuleVisible(M, ImportLoc); +} + +void Preprocessor::LeaveSubmodule() { + auto &Info = BuildingSubmoduleStack.back(); + + Module *LeavingMod = Info.M; + SourceLocation ImportLoc = Info.ImportLoc; + + // Create ModuleMacros for any macros defined in this submodule. + for (auto &Macro : CurSubmoduleState->Macros) { + auto *II = const_cast<IdentifierInfo*>(Macro.first); + + // Find the starting point for the MacroDirective chain in this submodule. + MacroDirective *OldMD = nullptr; + if (getLangOpts().ModulesLocalVisibility) { + // FIXME: It'd be better to start at the state from when we most recently + // entered this submodule, but it doesn't really matter. + auto &PredefMacros = NullSubmoduleState.Macros; + auto PredefMacroIt = PredefMacros.find(Macro.first); + if (PredefMacroIt == PredefMacros.end()) + OldMD = nullptr; + else + OldMD = PredefMacroIt->second.getLatest(); + } + + // This module may have exported a new macro. If so, create a ModuleMacro + // representing that fact. + bool ExplicitlyPublic = false; + for (auto *MD = Macro.second.getLatest(); MD != OldMD; + MD = MD->getPrevious()) { + assert(MD && "broken macro directive chain"); + + // Stop on macros defined in other submodules we #included along the way. + // There's no point doing this if we're tracking local submodule + // visibility, since there can be no such directives in our list. + if (!getLangOpts().ModulesLocalVisibility) { + Module *Mod = getModuleContainingLocation(MD->getLocation()); + if (Mod != LeavingMod) + break; + } + + if (auto *VisMD = dyn_cast<VisibilityMacroDirective>(MD)) { + // The latest visibility directive for a name in a submodule affects + // all the directives that come before it. + if (VisMD->isPublic()) + ExplicitlyPublic = true; + else if (!ExplicitlyPublic) + // Private with no following public directive: not exported. + break; + } else { + MacroInfo *Def = nullptr; + if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) + Def = DefMD->getInfo(); + + // FIXME: Issue a warning if multiple headers for the same submodule + // define a macro, rather than silently ignoring all but the first. + bool IsNew; + // Don't bother creating a module macro if it would represent a #undef + // that doesn't override anything. + if (Def || !Macro.second.getOverriddenMacros().empty()) + addModuleMacro(LeavingMod, II, Def, + Macro.second.getOverriddenMacros(), IsNew); + break; + } + } + } + + // Put back the outer module's state, if we're tracking it. + if (getLangOpts().ModulesLocalVisibility) + CurSubmoduleState = Info.OuterSubmoduleState; + + BuildingSubmoduleStack.pop_back(); + + // A nested #include makes the included submodule visible. + if (!BuildingSubmoduleStack.empty() || !getLangOpts().ModulesLocalVisibility) + makeModuleVisible(LeavingMod, ImportLoc); +} diff --git a/contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp b/contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp index cd05d06633f2..9046ad51c14a 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp @@ -34,44 +34,234 @@ using namespace clang; MacroDirective * -Preprocessor::getMacroDirectiveHistory(const IdentifierInfo *II) const { - assert(II->hadMacroDefinition() && "Identifier has not been not a macro!"); - - macro_iterator Pos = Macros.find(II); - assert(Pos != Macros.end() && "Identifier macro info is missing!"); - return Pos->second; +Preprocessor::getLocalMacroDirectiveHistory(const IdentifierInfo *II) const { + if (!II->hadMacroDefinition()) + return nullptr; + auto Pos = CurSubmoduleState->Macros.find(II); + return Pos == CurSubmoduleState->Macros.end() ? nullptr + : Pos->second.getLatest(); } void Preprocessor::appendMacroDirective(IdentifierInfo *II, MacroDirective *MD){ assert(MD && "MacroDirective should be non-zero!"); assert(!MD->getPrevious() && "Already attached to a MacroDirective history."); - MacroDirective *&StoredMD = Macros[II]; - MD->setPrevious(StoredMD); - StoredMD = MD; - // Setup the identifier as having associated macro history. + MacroState &StoredMD = CurSubmoduleState->Macros[II]; + auto *OldMD = StoredMD.getLatest(); + MD->setPrevious(OldMD); + StoredMD.setLatest(MD); + StoredMD.overrideActiveModuleMacros(*this, II); + + // Set up the identifier as having associated macro history. II->setHasMacroDefinition(true); - if (!MD->isDefined()) + if (!MD->isDefined() && LeafModuleMacros.find(II) == LeafModuleMacros.end()) II->setHasMacroDefinition(false); - bool isImportedMacro = isa<DefMacroDirective>(MD) && - cast<DefMacroDirective>(MD)->isImported(); - if (II->isFromAST() && !isImportedMacro) + if (II->isFromAST()) II->setChangedSinceDeserialization(); } void Preprocessor::setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD) { assert(II && MD); - MacroDirective *&StoredMD = Macros[II]; - assert(!StoredMD && + MacroState &StoredMD = CurSubmoduleState->Macros[II]; + assert(!StoredMD.getLatest() && "the macro history was modified before initializing it from a pch"); StoredMD = MD; // Setup the identifier as having associated macro history. II->setHasMacroDefinition(true); - if (!MD->isDefined()) + if (!MD->isDefined() && LeafModuleMacros.find(II) == LeafModuleMacros.end()) II->setHasMacroDefinition(false); } +ModuleMacro *Preprocessor::addModuleMacro(Module *Mod, IdentifierInfo *II, + MacroInfo *Macro, + ArrayRef<ModuleMacro *> Overrides, + bool &New) { + llvm::FoldingSetNodeID ID; + ModuleMacro::Profile(ID, Mod, II); + + void *InsertPos; + if (auto *MM = ModuleMacros.FindNodeOrInsertPos(ID, InsertPos)) { + New = false; + return MM; + } + + auto *MM = ModuleMacro::create(*this, Mod, II, Macro, Overrides); + ModuleMacros.InsertNode(MM, InsertPos); + + // Each overridden macro is now overridden by one more macro. + bool HidAny = false; + for (auto *O : Overrides) { + HidAny |= (O->NumOverriddenBy == 0); + ++O->NumOverriddenBy; + } + + // If we were the first overrider for any macro, it's no longer a leaf. + auto &LeafMacros = LeafModuleMacros[II]; + if (HidAny) { + LeafMacros.erase(std::remove_if(LeafMacros.begin(), LeafMacros.end(), + [](ModuleMacro *MM) { + return MM->NumOverriddenBy != 0; + }), + LeafMacros.end()); + } + + // The new macro is always a leaf macro. + LeafMacros.push_back(MM); + // The identifier now has defined macros (that may or may not be visible). + II->setHasMacroDefinition(true); + + New = true; + return MM; +} + +ModuleMacro *Preprocessor::getModuleMacro(Module *Mod, IdentifierInfo *II) { + llvm::FoldingSetNodeID ID; + ModuleMacro::Profile(ID, Mod, II); + + void *InsertPos; + return ModuleMacros.FindNodeOrInsertPos(ID, InsertPos); +} + +void Preprocessor::updateModuleMacroInfo(const IdentifierInfo *II, + ModuleMacroInfo &Info) { + assert(Info.ActiveModuleMacrosGeneration != + CurSubmoduleState->VisibleModules.getGeneration() && + "don't need to update this macro name info"); + Info.ActiveModuleMacrosGeneration = + CurSubmoduleState->VisibleModules.getGeneration(); + + auto Leaf = LeafModuleMacros.find(II); + if (Leaf == LeafModuleMacros.end()) { + // No imported macros at all: nothing to do. + return; + } + + Info.ActiveModuleMacros.clear(); + + // Every macro that's locally overridden is overridden by a visible macro. + llvm::DenseMap<ModuleMacro *, int> NumHiddenOverrides; + for (auto *O : Info.OverriddenMacros) + NumHiddenOverrides[O] = -1; + + // Collect all macros that are not overridden by a visible macro. + llvm::SmallVector<ModuleMacro *, 16> Worklist(Leaf->second.begin(), + Leaf->second.end()); + while (!Worklist.empty()) { + auto *MM = Worklist.pop_back_val(); + if (CurSubmoduleState->VisibleModules.isVisible(MM->getOwningModule())) { + // We only care about collecting definitions; undefinitions only act + // to override other definitions. + if (MM->getMacroInfo()) + Info.ActiveModuleMacros.push_back(MM); + } else { + for (auto *O : MM->overrides()) + if ((unsigned)++NumHiddenOverrides[O] == O->getNumOverridingMacros()) + Worklist.push_back(O); + } + } + // Our reverse postorder walk found the macros in reverse order. + std::reverse(Info.ActiveModuleMacros.begin(), Info.ActiveModuleMacros.end()); + + // Determine whether the macro name is ambiguous. + MacroInfo *MI = nullptr; + bool IsSystemMacro = true; + bool IsAmbiguous = false; + if (auto *MD = Info.MD) { + while (MD && isa<VisibilityMacroDirective>(MD)) + MD = MD->getPrevious(); + if (auto *DMD = dyn_cast_or_null<DefMacroDirective>(MD)) { + MI = DMD->getInfo(); + IsSystemMacro &= SourceMgr.isInSystemHeader(DMD->getLocation()); + } + } + for (auto *Active : Info.ActiveModuleMacros) { + auto *NewMI = Active->getMacroInfo(); + + // Before marking the macro as ambiguous, check if this is a case where + // both macros are in system headers. If so, we trust that the system + // did not get it wrong. This also handles cases where Clang's own + // headers have a different spelling of certain system macros: + // #define LONG_MAX __LONG_MAX__ (clang's limits.h) + // #define LONG_MAX 0x7fffffffffffffffL (system's limits.h) + // + // FIXME: Remove the defined-in-system-headers check. clang's limits.h + // overrides the system limits.h's macros, so there's no conflict here. + if (MI && NewMI != MI && + !MI->isIdenticalTo(*NewMI, *this, /*Syntactically=*/true)) + IsAmbiguous = true; + IsSystemMacro &= Active->getOwningModule()->IsSystem || + SourceMgr.isInSystemHeader(NewMI->getDefinitionLoc()); + MI = NewMI; + } + Info.IsAmbiguous = IsAmbiguous && !IsSystemMacro; +} + +void Preprocessor::dumpMacroInfo(const IdentifierInfo *II) { + ArrayRef<ModuleMacro*> Leaf; + auto LeafIt = LeafModuleMacros.find(II); + if (LeafIt != LeafModuleMacros.end()) + Leaf = LeafIt->second; + const MacroState *State = nullptr; + auto Pos = CurSubmoduleState->Macros.find(II); + if (Pos != CurSubmoduleState->Macros.end()) + State = &Pos->second; + + llvm::errs() << "MacroState " << State << " " << II->getNameStart(); + if (State && State->isAmbiguous(*this, II)) + llvm::errs() << " ambiguous"; + if (State && !State->getOverriddenMacros().empty()) { + llvm::errs() << " overrides"; + for (auto *O : State->getOverriddenMacros()) + llvm::errs() << " " << O->getOwningModule()->getFullModuleName(); + } + llvm::errs() << "\n"; + + // Dump local macro directives. + for (auto *MD = State ? State->getLatest() : nullptr; MD; + MD = MD->getPrevious()) { + llvm::errs() << " "; + MD->dump(); + } + + // Dump module macros. + llvm::DenseSet<ModuleMacro*> Active; + for (auto *MM : State ? State->getActiveModuleMacros(*this, II) : None) + Active.insert(MM); + llvm::DenseSet<ModuleMacro*> Visited; + llvm::SmallVector<ModuleMacro *, 16> Worklist(Leaf.begin(), Leaf.end()); + while (!Worklist.empty()) { + auto *MM = Worklist.pop_back_val(); + llvm::errs() << " ModuleMacro " << MM << " " + << MM->getOwningModule()->getFullModuleName(); + if (!MM->getMacroInfo()) + llvm::errs() << " undef"; + + if (Active.count(MM)) + llvm::errs() << " active"; + else if (!CurSubmoduleState->VisibleModules.isVisible( + MM->getOwningModule())) + llvm::errs() << " hidden"; + else if (MM->getMacroInfo()) + llvm::errs() << " overridden"; + + if (!MM->overrides().empty()) { + llvm::errs() << " overrides"; + for (auto *O : MM->overrides()) { + llvm::errs() << " " << O->getOwningModule()->getFullModuleName(); + if (Visited.insert(O).second) + Worklist.push_back(O); + } + } + llvm::errs() << "\n"; + if (auto *MI = MM->getMacroInfo()) { + llvm::errs() << " "; + MI->dump(); + llvm::errs() << "\n"; + } + } +} + /// RegisterBuiltinMacro - Register the specified identifier in the identifier /// table and mark it as a builtin macro to be expanded. static IdentifierInfo *RegisterBuiltinMacro(Preprocessor &PP, const char *Name){ @@ -97,7 +287,11 @@ void Preprocessor::RegisterBuiltinMacros() { Ident_Pragma = RegisterBuiltinMacro(*this, "_Pragma"); // C++ Standing Document Extensions. - Ident__has_cpp_attribute = RegisterBuiltinMacro(*this, "__has_cpp_attribute"); + if (LangOpts.CPlusPlus) + Ident__has_cpp_attribute = + RegisterBuiltinMacro(*this, "__has_cpp_attribute"); + else + Ident__has_cpp_attribute = nullptr; // GCC Extensions. Ident__BASE_FILE__ = RegisterBuiltinMacro(*this, "__BASE_FILE__"); @@ -156,10 +350,11 @@ static bool isTrivialSingleTokenExpansion(const MacroInfo *MI, // If the identifier is a macro, and if that macro is enabled, it may be // expanded so it's not a trivial expansion. - if (II->hasMacroDefinition() && PP.getMacroInfo(II)->isEnabled() && - // Fast expanding "#define X X" is ok, because X would be disabled. - II != MacroIdent) - return false; + if (auto *ExpansionMI = PP.getMacroInfo(II)) + if (ExpansionMI->isEnabled() && + // Fast expanding "#define X X" is ok, because X would be disabled. + II != MacroIdent) + return false; // If this is an object-like macro invocation, it is safe to trivially expand // it. @@ -222,10 +417,8 @@ bool Preprocessor::isNextPPTokenLParen() { /// HandleMacroExpandedIdentifier - If an identifier token is read that is to be /// expanded as a macro, handle it and return the next token as 'Identifier'. bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier, - MacroDirective *MD) { - MacroDirective::DefInfo Def = MD->getDefinition(); - assert(Def.isValid()); - MacroInfo *MI = Def.getMacroInfo(); + const MacroDefinition &M) { + MacroInfo *MI = M.getMacroInfo(); // If this is a macro expansion in the "#if !defined(x)" line for the file, // then the macro could expand to different things in other contexts, we need @@ -234,9 +427,9 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier, // If this is a builtin macro, like __LINE__ or _Pragma, handle it specially. if (MI->isBuiltinMacro()) { - if (Callbacks) Callbacks->MacroExpands(Identifier, MD, - Identifier.getLocation(), - /*Args=*/nullptr); + if (Callbacks) + Callbacks->MacroExpands(Identifier, M, Identifier.getLocation(), + /*Args=*/nullptr); ExpandBuiltinMacro(Identifier); return true; } @@ -283,9 +476,9 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier, // MacroExpands callbacks still happen in source order, queue this // callback to have it happen after the function macro callback. DelayedMacroExpandsCallbacks.push_back( - MacroExpandsInfo(Identifier, MD, ExpansionRange)); + MacroExpandsInfo(Identifier, M, ExpansionRange)); } else { - Callbacks->MacroExpands(Identifier, MD, ExpansionRange, Args); + Callbacks->MacroExpands(Identifier, M, ExpansionRange, Args); if (!DelayedMacroExpandsCallbacks.empty()) { for (unsigned i=0, e = DelayedMacroExpandsCallbacks.size(); i!=e; ++i) { MacroExpandsInfo &Info = DelayedMacroExpandsCallbacks[i]; @@ -299,20 +492,16 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier, } // If the macro definition is ambiguous, complain. - if (Def.getDirective()->isAmbiguous()) { + if (M.isAmbiguous()) { Diag(Identifier, diag::warn_pp_ambiguous_macro) << Identifier.getIdentifierInfo(); Diag(MI->getDefinitionLoc(), diag::note_pp_ambiguous_macro_chosen) << Identifier.getIdentifierInfo(); - for (MacroDirective::DefInfo PrevDef = Def.getPreviousDefinition(); - PrevDef && !PrevDef.isUndefined(); - PrevDef = PrevDef.getPreviousDefinition()) { - Diag(PrevDef.getMacroInfo()->getDefinitionLoc(), - diag::note_pp_ambiguous_macro_other) - << Identifier.getIdentifierInfo(); - if (!PrevDef.getDirective()->isAmbiguous()) - break; - } + M.forAllDefinitions([&](const MacroInfo *OtherMI) { + if (OtherMI != MI) + Diag(OtherMI->getDefinitionLoc(), diag::note_pp_ambiguous_macro_other) + << Identifier.getIdentifierInfo(); + }); } // If we started lexing a macro, enter the macro expansion body. @@ -598,7 +787,7 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName, // If this is a comment token in the argument list and we're just in // -C mode (not -CC mode), discard the comment. continue; - } else if (Tok.getIdentifierInfo() != nullptr) { + } else if (!Tok.isAnnotation() && Tok.getIdentifierInfo() != nullptr) { // Reading macro arguments can cause macros that we are currently // expanding from to be popped off the expansion stack. Doing so causes // them to be reenabled for expansion. Here we record whether any @@ -868,6 +1057,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) { .Case("attribute_analyzer_noreturn", true) .Case("attribute_availability", true) .Case("attribute_availability_with_message", true) + .Case("attribute_availability_app_extension", true) .Case("attribute_cf_returns_not_retained", true) .Case("attribute_cf_returns_retained", true) .Case("attribute_deprecated_with_message", true) @@ -912,7 +1102,8 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) { .Case("objc_dictionary_literals", LangOpts.ObjC2) .Case("objc_boxed_expressions", LangOpts.ObjC2) .Case("arc_cf_code_audited", true) - .Case("objc_bridge_id", LangOpts.ObjC2) + .Case("objc_bridge_id", true) + .Case("objc_bridge_id_on_typedefs", true) // C11 features .Case("c_alignas", LangOpts.C11) .Case("c_alignof", LangOpts.C11) @@ -1050,6 +1241,7 @@ static bool HasExtension(const Preprocessor &PP, const IdentifierInfo *II) { .Case("cxx_range_for", LangOpts.CPlusPlus) .Case("cxx_reference_qualified_functions", LangOpts.CPlusPlus) .Case("cxx_rvalue_references", LangOpts.CPlusPlus) + .Case("cxx_variadic_templates", LangOpts.CPlusPlus) // C++1y features supported by other languages as extensions. .Case("cxx_binary_literals", true) .Case("cxx_init_captures", LangOpts.CPlusPlus11) @@ -1071,6 +1263,9 @@ static bool EvaluateHasIncludeCommon(Token &Tok, // These expressions are only allowed within a preprocessor directive. if (!PP.isParsingIfOrElifDirective()) { PP.Diag(LParenLoc, diag::err_pp_directive_required) << II->getName(); + // Return a valid identifier token. + assert(Tok.is(tok::identifier)); + Tok.setIdentifierInfo(II); return false; } @@ -1129,7 +1324,7 @@ static bool EvaluateHasIncludeCommon(Token &Tok, Tok.setKind(tok::eod); return false; // Found <eod> but no ">"? Diagnostic already emitted. } - Filename = FilenameBuffer.str(); + Filename = FilenameBuffer; break; default: PP.Diag(Tok.getLocation(), diag::err_pp_expects_filename); @@ -1179,7 +1374,7 @@ 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 + // FIXME: Factor out duplication with // Preprocessor::HandleIncludeNextDirective. const DirectoryLookup *Lookup = PP.GetCurDirLookup(); const FileEntry *LookupFromFile = nullptr; @@ -1312,7 +1507,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { if (PLoc.isValid()) { FN += PLoc.getFilename(); Lexer::Stringify(FN); - OS << '"' << FN.str() << '"'; + OS << '"' << FN << '"'; } Tok.setKind(tok::string_literal); } else if (II == Ident__DATE__) { @@ -1459,9 +1654,11 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { Value = EvaluateHasInclude(Tok, II, *this); else Value = EvaluateHasIncludeNext(Tok, II, *this); + + if (Tok.isNot(tok::r_paren)) + return; OS << (int)Value; - if (Tok.is(tok::r_paren)) - Tok.setKind(tok::numeric_constant); + Tok.setKind(tok::numeric_constant); } else if (II == Ident__has_warning) { // The argument should be a parenthesized string literal. // The argument to these builtins should be a parenthesized identifier. diff --git a/contrib/llvm/tools/clang/lib/Lex/Pragma.cpp b/contrib/llvm/tools/clang/lib/Lex/Pragma.cpp index 8ed832893771..26ed674f65aa 100644 --- a/contrib/llvm/tools/clang/lib/Lex/Pragma.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/Pragma.cpp @@ -22,6 +22,7 @@ #include "clang/Lex/Preprocessor.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Support/CrashRecoveryContext.h" #include "llvm/Support/ErrorHandling.h" #include <algorithm> @@ -400,7 +401,7 @@ void Preprocessor::HandlePragmaPoison(Token &PoisonTok) { if (II->isPoisoned()) continue; // If this is a macro identifier, emit a warning. - if (II->hasMacroDefinition()) + if (isMacroDefined(II)) Diag(Tok, diag::pp_poisoning_existing_macro); // Finally, poison it! @@ -590,8 +591,7 @@ void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) { PragmaPushMacroInfo.find(IdentInfo); if (iter != PragmaPushMacroInfo.end()) { // Forget the MacroInfo currently associated with IdentInfo. - if (MacroDirective *CurrentMD = getMacroDirective(IdentInfo)) { - MacroInfo *MI = CurrentMD->getMacroInfo(); + if (MacroInfo *MI = getMacroInfo(IdentInfo)) { if (MI->isWarnIfUnused()) WarnUnusedMacroLocs.erase(MI->getDefinitionLoc()); appendMacroDirective(IdentInfo, AllocateUndefMacroDirective(MessageLoc)); @@ -600,11 +600,9 @@ void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) { // Get the MacroInfo we want to reinstall. MacroInfo *MacroToReInstall = iter->second.back(); - if (MacroToReInstall) { + if (MacroToReInstall) // Reinstall the previously pushed macro. - appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc, - /*isImported=*/false, /*Overrides*/None); - } + appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc); // Pop PragmaPushMacroInfo stack. iter->second.pop_back(); @@ -648,7 +646,7 @@ void Preprocessor::HandlePragmaIncludeAlias(Token &Tok) { SourceLocation End; if (ConcatenateIncludeName(FileNameBuffer, End)) return; // Diagnostic already emitted - SourceFileName = FileNameBuffer.str(); + SourceFileName = FileNameBuffer; } else { Diag(Tok, diag::warn_pragma_include_alias_expected_filename); return; @@ -679,7 +677,7 @@ void Preprocessor::HandlePragmaIncludeAlias(Token &Tok) { SourceLocation End; if (ConcatenateIncludeName(FileNameBuffer, End)) return; // Diagnostic already emitted - ReplaceFileName = FileNameBuffer.str(); + ReplaceFileName = FileNameBuffer; } else { Diag(Tok, diag::warn_pragma_include_alias_expected_filename); return; @@ -870,12 +868,22 @@ struct PragmaDebugHandler : public PragmaHandler { LLVM_BUILTIN_TRAP; } else if (II->isStr("parser_crash")) { Token Crasher; + Crasher.startToken(); Crasher.setKind(tok::annot_pragma_parser_crash); + Crasher.setAnnotationRange(SourceRange(Tok.getLocation())); PP.EnterToken(Crasher); } else if (II->isStr("llvm_fatal_error")) { llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error"); } else if (II->isStr("llvm_unreachable")) { llvm_unreachable("#pragma clang __debug llvm_unreachable"); + } else if (II->isStr("macro")) { + Token MacroName; + PP.LexUnexpandedToken(MacroName); + auto *MacroII = MacroName.getIdentifierInfo(); + if (MacroII) + PP.dumpMacroInfo(MacroII); + else + PP.Diag(MacroName, diag::warn_pragma_diagnostic_invalid); } else if (II->isStr("overflow_stack")) { DebugOverflowStack(); } else if (II->isStr("handle_crash")) { @@ -1029,12 +1037,8 @@ struct PragmaWarningHandler : public PragmaHandler { PP.Lex(Tok); IdentifierInfo *II = Tok.getIdentifierInfo(); - if (!II) { - PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid); - return; - } - if (II->isStr("push")) { + if (II && II->isStr("push")) { // #pragma warning( push[ ,n ] ) int Level = -1; PP.Lex(Tok); @@ -1051,7 +1055,7 @@ struct PragmaWarningHandler : public PragmaHandler { } if (Callbacks) Callbacks->PragmaWarningPush(DiagLoc, Level); - } else if (II->isStr("pop")) { + } else if (II && II->isStr("pop")) { // #pragma warning( pop ) PP.Lex(Tok); if (Callbacks) @@ -1061,23 +1065,40 @@ struct PragmaWarningHandler : public PragmaHandler { // [; warning-specifier : warning-number-list...] ) while (true) { II = Tok.getIdentifierInfo(); - if (!II) { + if (!II && !Tok.is(tok::numeric_constant)) { PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid); return; } // Figure out which warning specifier this is. - StringRef Specifier = II->getName(); - bool SpecifierValid = - llvm::StringSwitch<bool>(Specifier) - .Cases("1", "2", "3", "4", true) - .Cases("default", "disable", "error", "once", "suppress", true) - .Default(false); + bool SpecifierValid; + StringRef Specifier; + llvm::SmallString<1> SpecifierBuf; + if (II) { + Specifier = II->getName(); + SpecifierValid = llvm::StringSwitch<bool>(Specifier) + .Cases("default", "disable", "error", "once", + "suppress", true) + .Default(false); + // If we read a correct specifier, snatch next token (that should be + // ":", checked later). + if (SpecifierValid) + PP.Lex(Tok); + } else { + // Token is a numeric constant. It should be either 1, 2, 3 or 4. + uint64_t Value; + Specifier = PP.getSpelling(Tok, SpecifierBuf); + if (PP.parseSimpleIntegerLiteral(Tok, Value)) { + SpecifierValid = (Value >= 1) && (Value <= 4); + } else + SpecifierValid = false; + // Next token already snatched by parseSimpleIntegerLiteral. + } + if (!SpecifierValid) { PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid); return; } - PP.Lex(Tok); if (Tok.isNot(tok::colon)) { PP.Diag(Tok, diag::warn_pragma_warning_expected) << ":"; return; diff --git a/contrib/llvm/tools/clang/lib/Lex/PreprocessingRecord.cpp b/contrib/llvm/tools/clang/lib/Lex/PreprocessingRecord.cpp index 41bb581bb0aa..a423041a2d95 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PreprocessingRecord.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/PreprocessingRecord.cpp @@ -45,22 +45,23 @@ PreprocessingRecord::PreprocessingRecord(SourceManager &SM) /// \brief Returns a pair of [Begin, End) iterators of preprocessed entities /// that source range \p Range encompasses. -std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> +llvm::iterator_range<PreprocessingRecord::iterator> PreprocessingRecord::getPreprocessedEntitiesInRange(SourceRange Range) { if (Range.isInvalid()) - return std::make_pair(iterator(), iterator()); + return llvm::make_range(iterator(), iterator()); if (CachedRangeQuery.Range == Range) { - return std::make_pair(iterator(this, CachedRangeQuery.Result.first), - iterator(this, CachedRangeQuery.Result.second)); + return llvm::make_range(iterator(this, CachedRangeQuery.Result.first), + iterator(this, CachedRangeQuery.Result.second)); } std::pair<int, int> Res = getPreprocessedEntitiesInRangeSlow(Range); CachedRangeQuery.Range = Range; CachedRangeQuery.Result = Res; - - return std::make_pair(iterator(this, Res.first), iterator(this, Res.second)); + + return llvm::make_range(iterator(this, Res.first), + iterator(this, Res.second)); } static bool isPreprocessedEntityIfInFileID(PreprocessedEntity *PPE, FileID FID, @@ -72,11 +73,8 @@ static bool isPreprocessedEntityIfInFileID(PreprocessedEntity *PPE, FileID FID, SourceLocation Loc = PPE->getSourceRange().getBegin(); if (Loc.isInvalid()) return false; - - if (SM.isInFileID(SM.getFileLoc(Loc), FID)) - return true; - else - return false; + + return SM.isInFileID(SM.getFileLoc(Loc), FID); } /// \brief Returns true if the preprocessed entity that \arg PPEI iterator @@ -90,7 +88,7 @@ bool PreprocessingRecord::isEntityInFileID(iterator PPEI, FileID FID) { if (FID.isInvalid()) return false; - int Pos = PPEI.Position; + int Pos = std::distance(iterator(this, 0), PPEI); if (Pos < 0) { if (unsigned(-Pos-1) >= LoadedPreprocessedEntities.size()) { assert(0 && "Out-of bounds loaded preprocessed entity"); @@ -248,10 +246,11 @@ PreprocessingRecord::addPreprocessedEntity(PreprocessedEntity *Entity) { assert(Entity); SourceLocation BeginLoc = Entity->getSourceRange().getBegin(); - if (isa<MacroDefinition>(Entity)) { + if (isa<MacroDefinitionRecord>(Entity)) { assert((PreprocessedEntities.empty() || - !SourceMgr.isBeforeInTranslationUnit(BeginLoc, - PreprocessedEntities.back()->getSourceRange().getBegin())) && + !SourceMgr.isBeforeInTranslationUnit( + BeginLoc, + PreprocessedEntities.back()->getSourceRange().getBegin())) && "a macro definition was encountered out-of-order"); PreprocessedEntities.push_back(Entity); return getPPEntityID(PreprocessedEntities.size()-1, /*isLoaded=*/false); @@ -320,7 +319,7 @@ unsigned PreprocessingRecord::allocateLoadedEntities(unsigned NumEntities) { } void PreprocessingRecord::RegisterMacroDefinition(MacroInfo *Macro, - MacroDefinition *Def) { + MacroDefinitionRecord *Def) { MacroDefinitions[Macro] = Def; } @@ -357,9 +356,10 @@ PreprocessingRecord::getLoadedPreprocessedEntity(unsigned Index) { return Entity; } -MacroDefinition *PreprocessingRecord::findMacroDefinition(const MacroInfo *MI) { - llvm::DenseMap<const MacroInfo *, MacroDefinition *>::iterator Pos - = MacroDefinitions.find(MI); +MacroDefinitionRecord * +PreprocessingRecord::findMacroDefinition(const MacroInfo *MI) { + llvm::DenseMap<const MacroInfo *, MacroDefinitionRecord *>::iterator Pos = + MacroDefinitions.find(MI); if (Pos == MacroDefinitions.end()) return nullptr; @@ -374,35 +374,34 @@ void PreprocessingRecord::addMacroExpansion(const Token &Id, return; if (MI->isBuiltinMacro()) - addPreprocessedEntity( - new (*this) MacroExpansion(Id.getIdentifierInfo(),Range)); - else if (MacroDefinition *Def = findMacroDefinition(MI)) - addPreprocessedEntity( - new (*this) MacroExpansion(Def, Range)); + addPreprocessedEntity(new (*this) + MacroExpansion(Id.getIdentifierInfo(), Range)); + else if (MacroDefinitionRecord *Def = findMacroDefinition(MI)) + addPreprocessedEntity(new (*this) MacroExpansion(Def, Range)); } void PreprocessingRecord::Ifdef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDirective *MD) { + const MacroDefinition &MD) { // This is not actually a macro expansion but record it as a macro reference. if (MD) - addMacroExpansion(MacroNameTok, MD->getMacroInfo(), + addMacroExpansion(MacroNameTok, MD.getMacroInfo(), MacroNameTok.getLocation()); } void PreprocessingRecord::Ifndef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDirective *MD) { + const MacroDefinition &MD) { // This is not actually a macro expansion but record it as a macro reference. if (MD) - addMacroExpansion(MacroNameTok, MD->getMacroInfo(), + addMacroExpansion(MacroNameTok, MD.getMacroInfo(), MacroNameTok.getLocation()); } void PreprocessingRecord::Defined(const Token &MacroNameTok, - const MacroDirective *MD, + const MacroDefinition &MD, SourceRange Range) { // This is not actually a macro expansion but record it as a macro reference. if (MD) - addMacroExpansion(MacroNameTok, MD->getMacroInfo(), + addMacroExpansion(MacroNameTok, MD.getMacroInfo(), MacroNameTok.getLocation()); } @@ -410,27 +409,26 @@ void PreprocessingRecord::SourceRangeSkipped(SourceRange Range) { SkippedRanges.push_back(Range); } -void PreprocessingRecord::MacroExpands(const Token &Id,const MacroDirective *MD, +void PreprocessingRecord::MacroExpands(const Token &Id, + const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) { - addMacroExpansion(Id, MD->getMacroInfo(), Range); + addMacroExpansion(Id, MD.getMacroInfo(), Range); } void PreprocessingRecord::MacroDefined(const Token &Id, const MacroDirective *MD) { const MacroInfo *MI = MD->getMacroInfo(); SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc()); - MacroDefinition *Def - = new (*this) MacroDefinition(Id.getIdentifierInfo(), R); + MacroDefinitionRecord *Def = + new (*this) MacroDefinitionRecord(Id.getIdentifierInfo(), R); addPreprocessedEntity(Def); MacroDefinitions[MI] = Def; } void PreprocessingRecord::MacroUndefined(const Token &Id, - const MacroDirective *MD) { - // Note: MI may be null (when #undef'ining an undefined macro). - if (MD) - MacroDefinitions.erase(MD->getMacroInfo()); + const MacroDefinition &MD) { + MD.forAllDefinitions([&](MacroInfo *MI) { MacroDefinitions.erase(MI); }); } void PreprocessingRecord::InclusionDirective( diff --git a/contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp b/contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp index b2a6d933a0f2..7e33f1ccb487 100644 --- a/contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp @@ -73,7 +73,8 @@ Preprocessor::Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts, ModuleImportExpectsIdentifier(false), CodeCompletionReached(0), MainFileDir(nullptr), SkipMainFilePreamble(0, true), CurPPLexer(nullptr), CurDirLookup(nullptr), CurLexerKind(CLK_Lexer), CurSubmodule(nullptr), - Callbacks(nullptr), MacroArgCache(nullptr), Record(nullptr), + Callbacks(nullptr), CurSubmoduleState(&NullSubmoduleState), + MacroArgCache(nullptr), Record(nullptr), MIChainHead(nullptr), DeserialMIChainHead(nullptr) { OwnsHeaderSearch = OwnsHeaders; @@ -266,7 +267,9 @@ void Preprocessor::PrintStats() { llvm::errs() << "\n Macro Expanded Tokens: " << llvm::capacity_in_bytes(MacroExpandedTokens); llvm::errs() << "\n Predefines Buffer: " << Predefines.capacity(); - llvm::errs() << "\n Macros: " << llvm::capacity_in_bytes(Macros); + // FIXME: List information for all submodules. + llvm::errs() << "\n Macros: " + << llvm::capacity_in_bytes(CurSubmoduleState->Macros); llvm::errs() << "\n #pragma push_macro Info: " << llvm::capacity_in_bytes(PragmaPushMacroInfo); llvm::errs() << "\n Poison Reasons: " @@ -283,14 +286,16 @@ Preprocessor::macro_begin(bool IncludeExternalMacros) const { ExternalSource->ReadDefinedMacros(); } - return Macros.begin(); + return CurSubmoduleState->Macros.begin(); } size_t Preprocessor::getTotalMemory() const { return BP.getTotalMemory() + llvm::capacity_in_bytes(MacroExpandedTokens) + Predefines.capacity() /* Predefines buffer. */ - + llvm::capacity_in_bytes(Macros) + // FIXME: Include sizes from all submodules, and include MacroInfo sizes, + // and ModuleMacros. + + llvm::capacity_in_bytes(CurSubmoduleState->Macros) + llvm::capacity_in_bytes(PragmaPushMacroInfo) + llvm::capacity_in_bytes(PoisonReasons) + llvm::capacity_in_bytes(CommentHandlers); @@ -304,7 +309,7 @@ Preprocessor::macro_end(bool IncludeExternalMacros) const { ExternalSource->ReadDefinedMacros(); } - return Macros.end(); + return CurSubmoduleState->Macros.end(); } /// \brief Compares macro tokens with a specified token value sequence. @@ -321,11 +326,11 @@ StringRef Preprocessor::getLastMacroWithSpelling( StringRef BestSpelling; for (Preprocessor::macro_iterator I = macro_begin(), E = macro_end(); I != E; ++I) { - if (!I->second->getMacroInfo()->isObjectLike()) - continue; const MacroDirective::DefInfo - Def = I->second->findDirectiveAtLoc(Loc, SourceMgr); - if (!Def) + Def = I->second.findDirectiveAtLoc(Loc, SourceMgr); + if (!Def || !Def.getMacroInfo()) + continue; + if (!Def.getMacroInfo()->isObjectLike()) continue; if (!MacroDefinitionEquals(Def.getMacroInfo(), Tokens)) continue; @@ -584,6 +589,23 @@ void Preprocessor::HandlePoisonedIdentifier(Token & Identifier) { Diag(Identifier,it->second) << Identifier.getIdentifierInfo(); } +/// \brief Returns a diagnostic message kind for reporting a future keyword as +/// appropriate for the identifier and specified language. +static diag::kind getFutureCompatDiagKind(const IdentifierInfo &II, + const LangOptions &LangOpts) { + assert(II.isFutureCompatKeyword() && "diagnostic should not be needed"); + + if (LangOpts.CPlusPlus) + return llvm::StringSwitch<diag::kind>(II.getName()) +#define CXX11_KEYWORD(NAME, FLAGS) \ + .Case(#NAME, diag::warn_cxx11_keyword) +#include "clang/Basic/TokenKinds.def" + ; + + llvm_unreachable( + "Keyword not known to come from a newer Standard or proposed Standard"); +} + /// HandleIdentifier - This callback is invoked when the lexer reads an /// identifier. This callback looks up the identifier in the map and/or /// potentially macro expands it or turns it into a named token (like 'for'). @@ -622,8 +644,9 @@ bool Preprocessor::HandleIdentifier(Token &Identifier) { } // If this is a macro to be expanded, do it. - if (MacroDirective *MD = getMacroDirective(&II)) { - MacroInfo *MI = MD->getMacroInfo(); + if (MacroDefinition MD = getMacroDefinition(&II)) { + auto *MI = MD.getMacroInfo(); + assert(MI && "macro definition with no macro info?"); if (!DisableMacroExpansion) { if (!Identifier.isExpandDisabled() && MI->isEnabled()) { // C99 6.10.3p10: If the preprocessing token immediately after the @@ -641,15 +664,16 @@ bool Preprocessor::HandleIdentifier(Token &Identifier) { } } - // If this identifier is a keyword in C++11, produce a warning. Don't warn if - // we're not considering macro expansion, since this identifier might be the - // name of a macro. + // If this identifier is a keyword in a newer Standard or proposed Standard, + // produce a warning. Don't warn if we're not considering macro expansion, + // since this identifier might be the name of a macro. // FIXME: This warning is disabled in cases where it shouldn't be, like // "#define constexpr constexpr", "int constexpr;" - if (II.isCXX11CompatKeyword() && !DisableMacroExpansion) { - Diag(Identifier, diag::warn_cxx11_keyword) << II.getName(); + if (II.isFutureCompatKeyword() && !DisableMacroExpansion) { + Diag(Identifier, getFutureCompatDiagKind(II, getLangOpts())) + << II.getName(); // Don't diagnose this keyword again in this translation unit. - II.setIsCXX11CompatKeyword(false); + II.setIsFutureCompatKeyword(false); } // C++ 2.11p2: If this is an alternative representation of a C++ operator, @@ -748,16 +772,36 @@ void Preprocessor::LexAfterModuleImport(Token &Result) { // If we have a non-empty module path, load the named module. if (!ModuleImportPath.empty()) { Module *Imported = nullptr; - if (getLangOpts().Modules) + if (getLangOpts().Modules) { Imported = TheModuleLoader.loadModule(ModuleImportLoc, ModuleImportPath, - Module::MacrosVisible, + Module::Hidden, /*IsIncludeDirective=*/false); + if (Imported) + makeModuleVisible(Imported, ModuleImportLoc); + } if (Callbacks && (getLangOpts().Modules || getLangOpts().DebuggerSupport)) Callbacks->moduleImport(ModuleImportLoc, ModuleImportPath, Imported); } } +void Preprocessor::makeModuleVisible(Module *M, SourceLocation Loc) { + CurSubmoduleState->VisibleModules.setVisible( + M, Loc, [](Module *) {}, + [&](ArrayRef<Module *> Path, Module *Conflict, StringRef Message) { + // FIXME: Include the path in the diagnostic. + // FIXME: Include the import location for the conflicting module. + Diag(ModuleImportLoc, diag::warn_module_conflict) + << Path[0]->getFullModuleName() + << Conflict->getFullModuleName() + << Message; + }); + + // Add this module to the imports list of the currently-built submodule. + if (!BuildingSubmoduleStack.empty() && M != BuildingSubmoduleStack.back().M) + BuildingSubmoduleStack.back().M->Imports.insert(M); +} + bool Preprocessor::FinishLexStringLiteral(Token &Result, std::string &String, const char *DiagnosticTag, bool AllowMacroExpansion) { diff --git a/contrib/llvm/tools/clang/lib/Lex/ScratchBuffer.cpp b/contrib/llvm/tools/clang/lib/Lex/ScratchBuffer.cpp index 3bac8891c646..cd8a27e76c28 100644 --- a/contrib/llvm/tools/clang/lib/Lex/ScratchBuffer.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/ScratchBuffer.cpp @@ -64,12 +64,13 @@ void ScratchBuffer::AllocScratchBuffer(unsigned RequestLen) { if (RequestLen < ScratchBufSize) RequestLen = ScratchBufSize; + // Get scratch buffer. Zero-initialize it so it can be dumped into a PCH file + // deterministically. 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()); - BytesUsed = 1; - CurBuffer[0] = '0'; // Start out with a \0 for cleanliness. + BytesUsed = 0; } diff --git a/contrib/llvm/tools/clang/lib/Lex/TokenLexer.cpp b/contrib/llvm/tools/clang/lib/Lex/TokenLexer.cpp index 5f4705eff697..83efbab76139 100644 --- a/contrib/llvm/tools/clang/lib/Lex/TokenLexer.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/TokenLexer.cpp @@ -521,6 +521,13 @@ bool TokenLexer::Lex(Token &Tok) { /// are more ## after it, chomp them iteratively. Return the result as Tok. /// If this returns true, the caller should immediately return the token. bool TokenLexer::PasteTokens(Token &Tok) { + // MSVC: If previous token was pasted, this must be a recovery from an invalid + // paste operation. Ignore spaces before this token to mimic MSVC output. + // Required for generating valid UUID strings in some MS headers. + if (PP.getLangOpts().MicrosoftExt && (CurToken >= 2) && + Tokens[CurToken - 2].is(tok::hashhash)) + Tok.clearFlag(Token::LeadingSpace); + SmallString<128> Buffer; const char *ResultTokStrPtr = nullptr; SourceLocation StartLoc = Tok.getLocation(); @@ -637,7 +644,7 @@ bool TokenLexer::PasteTokens(Token &Tok) { // disabling it. PP.Diag(Loc, PP.getLangOpts().MicrosoftExt ? diag::ext_pp_bad_paste_ms : diag::err_pp_bad_paste) - << Buffer.str(); + << Buffer; } // An error has occurred so exit loop. |