diff options
author | dim <dim@FreeBSD.org> | 2017-09-26 19:56:36 +0000 |
---|---|---|
committer | Luiz Souza <luiz@netgate.com> | 2018-02-21 15:12:19 -0300 |
commit | 1dcd2e8d24b295bc73e513acec2ed1514bb66be4 (patch) | |
tree | 4bd13a34c251e980e1a6b13584ca1f63b0dfe670 /contrib/llvm/tools/clang/lib/Lex | |
parent | f45541ca2a56a1ba1202f94c080b04e96c1fa239 (diff) | |
download | FreeBSD-src-1dcd2e8d24b295bc73e513acec2ed1514bb66be4.zip FreeBSD-src-1dcd2e8d24b295bc73e513acec2ed1514bb66be4.tar.gz |
Merge clang, llvm, lld, lldb, compiler-rt and libc++ 5.0.0 release.
MFC r309126 (by emaste):
Correct lld llvm-tblgen dependency file name
MFC r309169:
Get rid of separate Subversion mergeinfo properties for llvm-dwarfdump
and llvm-lto. The mergeinfo confuses Subversion enormously, and these
directories will just use the mergeinfo for llvm itself.
MFC r312765:
Pull in r276136 from upstream llvm trunk (by Wei Mi):
Use ValueOffsetPair to enhance value reuse during SCEV expansion.
In D12090, the ExprValueMap was added to reuse existing value during
SCEV expansion. However, const folding and sext/zext distribution can
make the reuse still difficult.
A simplified case is: suppose we know S1 expands to V1 in
ExprValueMap, and
S1 = S2 + C_a
S3 = S2 + C_b
where C_a and C_b are different SCEVConstants. Then we'd like to
expand S3 as V1 - C_a + C_b instead of expanding S2 literally. It is
helpful when S2 is a complex SCEV expr and S2 has no entry in
ExprValueMap, which is usually caused by the fact that S3 is
generated from S1 after const folding.
In order to do that, we represent ExprValueMap as a mapping from SCEV
to ValueOffsetPair. We will save both S1->{V1, 0} and S2->{V1, C_a}
into the ExprValueMap when we create SCEV for V1. When S3 is
expanded, it will first expand S2 to V1 - C_a because of S2->{V1,
C_a} in the map, then expand S3 to V1 - C_a + C_b.
Differential Revision: https://reviews.llvm.org/D21313
This should fix assertion failures when building OpenCV >= 3.1.
PR: 215649
MFC r312831:
Revert r312765 for now, since it causes assertions when building
lang/spidermonkey24.
Reported by: antoine
PR: 215649
MFC r316511 (by jhb):
Add an implementation of __ffssi2() derived from __ffsdi2().
Newer versions of GCC include an __ffssi2() symbol in libgcc and the
compiler can emit calls to it in generated code. This is true for at
least GCC 6.2 when compiling world for mips and mips64.
Reviewed by: jmallett, dim
Sponsored by: DARPA / AFRL
Differential Revision: https://reviews.freebsd.org/D10086
MFC r318601 (by adrian):
[libcompiler-rt] add bswapdi2/bswapsi2
This is required for mips gcc 6.3 userland to build/run.
Reviewed by: emaste, dim
Approved by: emaste
Differential Revision: https://reviews.freebsd.org/D10838
MFC r318884 (by emaste):
lldb: map TRAP_CAP to a trace trap
In the absense of a more specific handler for TRAP_CAP (generated by
ENOTCAPABLE or ECAPMODE while in capability mode) treat it as a trace
trap.
Example usage (testing the bug in PR219173):
% proccontrol -m trapcap lldb usr.bin/hexdump/obj/hexdump -- -Cv -s 1 /bin/ls
...
(lldb) run
Process 12980 launching
Process 12980 launched: '.../usr.bin/hexdump/obj/hexdump' (x86_64)
Process 12980 stopped
* thread #1, stop reason = trace
frame #0: 0x0000004b80c65f1a libc.so.7`__sys_lseek + 10
...
In the future we should have LLDB control the trapcap procctl itself
(as it does with ASLR), as well as report a specific stop reason.
This change eliminates an assertion failure from LLDB for now.
MFC r319796:
Remove a few unneeded files from libllvm, libclang and liblldb.
MFC r319885 (by emaste):
lld: ELF: Fix ICF crash on absolute symbol relocations.
If two sections contained relocations to absolute symbols with the same
value we would crash when trying to access their sections. Add a check that
both symbols point to sections before accessing their sections, and treat
absolute symbols as equal if their values are equal.
Obtained from: LLD commit r292578
MFC r319918:
Revert r319796 for now, it can cause undefined references when linking
in some circumstances.
Reported by: Shawn Webb <shawn.webb@hardenedbsd.org>
MFC r319957 (by emaste):
lld: Add armelf emulation mode
Obtained from: LLD r305375
MFC r321369:
Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to
5.0.0 (trunk r308421). Upstream has branched for the 5.0.0 release,
which should be in about a month. Please report bugs and regressions,
so we can get them into the release.
Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11
support to build; see UPDATING for more information.
MFC r321420:
Add a few more object files to liblldb, which should solve errors when
linking the lldb executable in some cases. In particular, when the
-ffunction-sections -fdata-sections options are turned off, or
ineffective.
Reported by: Shawn Webb, Mark Millard
MFC r321433:
Cleanup stale Options.inc files from the previous libllvm build for
clang 4.0.0. Otherwise, these can get included before the two newly
generated ones (which are different) for clang 5.0.0.
Reported by: Mark Millard
MFC r321439 (by bdrewery):
Move llvm Options.inc hack from r321433 for NO_CLEAN to lib/clang/libllvm.
The files are only ever generated to .OBJDIR, not to WORLDTMP (as a
sysroot) and are only ever included from a compilation. So using
a beforebuild target here removes the file before the compilation
tries to include it.
MFC r321664:
Pull in r308891 from upstream llvm trunk (by Benjamin Kramer):
[CodeGenPrepare] Cut off FindAllMemoryUses if there are too many uses.
This avoids excessive compile time. The case I'm looking at is
Function.cpp from an old version of LLVM that still had the giant
memcmp string matcher in it. Before r308322 this compiled in about 2
minutes, after it, clang takes infinite* time to compile it. With
this patch we're at 5 min, which is still bad but this is a
pathological case.
The cut off at 20 uses was chosen by looking at other cut-offs in LLVM
for user scanning. It's probably too high, but does the job and is
very unlikely to regress anything.
Fixes PR33900.
* I'm impatient and aborted after 15 minutes, on the bug report it was
killed after 2h.
Pull in r308986 from upstream llvm trunk (by Simon Pilgrim):
[X86][CGP] Reduce memcmp() expansion to 2 load pairs (PR33914)
D35067/rL308322 attempted to support up to 4 load pairs for memcmp
inlining which resulted in regressions for some optimized libc memcmp
implementations (PR33914).
Until we can match these more optimal cases, this patch reduces the
memcmp expansion to a maximum of 2 load pairs (which matches what we
do for -Os).
This patch should be considered for the 5.0.0 release branch as well
Differential Revision: https://reviews.llvm.org/D35830
These fix a hang (or extremely long compile time) when building older
LLVM ports.
Reported by: antoine
PR: 219139
MFC r321719:
Pull in r309503 from upstream clang trunk (by Richard Smith):
PR33902: Invalidate line number cache when adding more text to
existing buffer.
This led to crashes as the line number cache would report a bogus
line number for a line of code, and we'd try to find a nonexistent
column within the line when printing diagnostics.
This fixes an assertion when building the graphics/champlain port.
Reported by: antoine, kwm
PR: 219139
MFC r321723:
Upgrade our copies of clang, llvm, lld and lldb to r309439 from the
upstream release_50 branch. This is just after upstream's 5.0.0-rc1.
MFC r322320:
Upgrade our copies of clang, llvm and libc++ to r310316 from the
upstream release_50 branch.
MFC r322326 (by emaste):
lldb: Make i386-*-freebsd expression work on JIT path
* Enable i386 ABI creation for freebsd
* Added an extra argument in ABISysV_i386::PrepareTrivialCall for mmap
syscall
* Unlike linux, the last argument of mmap is actually 64-bit(off_t).
This requires us to push an additional word for the higher order bits.
* Prior to this change, ktrace dump will show mmap failures due to
invalid argument coming from the 6th mmap argument.
Submitted by: Karnajit Wangkhem
Differential Revision: https://reviews.llvm.org/D34776
MFC r322360 (by emaste):
lldb: Report inferior signals as signals, not exceptions, on FreeBSD
This is the FreeBSD equivalent of LLVM r238549.
This serves 2 purposes:
* LLDB should handle inferior process signals SIGSEGV/SIGILL/SIGBUS/
SIGFPE the way it is suppose to be handled. Prior to this fix these
signals will neither create a coredump, nor exit from the debugger
or work for signal handling scenario.
* eInvalidCrashReason need not report "unknown crash reason" if we have
a valid si_signo
llvm.org/pr23699
Patch by Karnajit Wangkhem
Differential Revision: https://reviews.llvm.org/D35223
Submitted by: Karnajit Wangkhem
Obtained from: LLVM r310591
MFC r322474 (by emaste):
lld: Add `-z muldefs` option.
Obtained from: LLVM r310757
MFC r322740:
Upgrade our copies of clang, llvm, lld and libc++ to r311219 from the
upstream release_50 branch.
MFC r322855:
Upgrade our copies of clang, llvm, lldb and compiler-rt to r311606 from
the upstream release_50 branch.
As of this version, lib/msun's trig test should also work correctly
again (see bug 220989 for more information).
PR: 220989
MFC r323112:
Upgrade our copies of clang, llvm, lldb and compiler-rt to r312293 from
the upstream release_50 branch. This corresponds to 5.0.0 rc4.
As of this version, the cad/stepcode port should now compile in a more
reasonable time on i386 (see bug 221836 for more information).
PR: 221836
MFC r323245:
Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to
5.0.0 release (upstream r312559).
Release notes for llvm, clang and lld will be available here soon:
<http://releases.llvm.org/5.0.0/docs/ReleaseNotes.html>
<http://releases.llvm.org/5.0.0/tools/clang/docs/ReleaseNotes.html>
<http://releases.llvm.org/5.0.0/tools/lld/docs/ReleaseNotes.html>
Relnotes: yes
(cherry picked from commit 12cd91cf4c6b96a24427c0de5374916f2808d263)
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 | 199 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/LiteralSupport.cpp | 20 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/MacroArgs.cpp | 26 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/MacroInfo.cpp | 23 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp | 582 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/PPCaching.cpp | 30 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/PPDirectives.cpp | 395 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/PPExpressions.cpp | 84 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/PPLexerChange.cpp | 181 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp | 18 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/Pragma.cpp | 306 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/PreprocessingRecord.cpp | 3 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp | 48 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/ScratchBuffer.cpp | 8 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Lex/TokenLexer.cpp | 42 |
16 files changed, 1365 insertions, 647 deletions
diff --git a/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp b/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp index c667f4b..1ebcc0a 100644 --- a/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/HeaderSearch.cpp @@ -172,8 +172,10 @@ std::string HeaderSearch::getModuleFileName(StringRef ModuleName, // // To avoid false-negatives, we form as canonical a path as we can, and map // to lower-case in case we're on a case-insensitive file system. - auto *Dir = - FileMgr.getDirectory(llvm::sys::path::parent_path(ModuleMapPath)); + std::string Parent = llvm::sys::path::parent_path(ModuleMapPath); + if (Parent.empty()) + Parent = "."; + auto *Dir = FileMgr.getDirectory(Parent); if (!Dir) return std::string(); auto DirName = FileMgr.getCanonicalName(Dir); @@ -622,7 +624,10 @@ const FileEntry *HeaderSearch::LookupFile( ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, - bool SkipCache, bool BuildSystemModule) { + bool *IsMapped, bool SkipCache, bool BuildSystemModule) { + if (IsMapped) + *IsMapped = false; + if (SuggestedModule) *SuggestedModule = ModuleMap::KnownHeader(); @@ -752,8 +757,11 @@ const FileEntry *HeaderSearch::LookupFile( if (!SkipCache && CacheLookup.StartIdx == i+1) { // Skip querying potentially lots of directories for this lookup. i = CacheLookup.HitIdx; - if (CacheLookup.MappedName) + if (CacheLookup.MappedName) { Filename = CacheLookup.MappedName; + if (IsMapped) + *IsMapped = true; + } } else { // Otherwise, this is the first query, or the previous query didn't match // our search start. We will fill in our found location below, so prime the @@ -774,6 +782,8 @@ const FileEntry *HeaderSearch::LookupFile( if (HasBeenMapped) { CacheLookup.MappedName = copyString(Filename, LookupFileCache.getAllocator()); + if (IsMapped) + *IsMapped = true; } if (!FE) continue; @@ -837,7 +847,7 @@ const FileEntry *HeaderSearch::LookupFile( const FileEntry *FE = LookupFile(ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir, CurDir, Includers.front(), SearchPath, RelativePath, - RequestingModule, SuggestedModule); + RequestingModule, SuggestedModule, IsMapped); if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc)) { if (SuggestedModule) @@ -1104,6 +1114,8 @@ bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP, auto TryEnterImported = [&](void) -> bool { if (!ModulesEnabled) return false; + // Ensure FileInfo bits are up to date. + ModMap.resolveHeaderDirectives(File); // Modules with builtins are special; multiple modules use builtins as // modular headers, example: // @@ -1315,14 +1327,28 @@ static const FileEntry *getPrivateModuleMap(const FileEntry *File, return FileMgr.getFile(PrivateFilename); } -bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem) { +bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem, + FileID ID, unsigned *Offset, + StringRef OriginalModuleMapFile) { // Find the directory for the module. For frameworks, that may require going // up from the 'Modules' directory. const DirectoryEntry *Dir = nullptr; if (getHeaderSearchOpts().ModuleMapFileHomeIsCwd) Dir = FileMgr.getDirectory("."); else { - Dir = File->getDir(); + if (!OriginalModuleMapFile.empty()) { + // We're building a preprocessed module map. Find or invent the directory + // that it originally occupied. + Dir = FileMgr.getDirectory( + llvm::sys::path::parent_path(OriginalModuleMapFile)); + if (!Dir) { + auto *FakeFile = FileMgr.getVirtualFile(OriginalModuleMapFile, 0, 0); + Dir = FakeFile->getDir(); + } + } else { + Dir = File->getDir(); + } + StringRef DirName(Dir->getName()); if (llvm::sys::path::filename(DirName) == "Modules") { DirName = llvm::sys::path::parent_path(DirName); @@ -1334,7 +1360,7 @@ bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem) { } } - switch (loadModuleMapFileImpl(File, IsSystem, Dir)) { + switch (loadModuleMapFileImpl(File, IsSystem, Dir, ID, Offset)) { case LMM_AlreadyLoaded: case LMM_NewlyLoaded: return false; @@ -1347,7 +1373,8 @@ bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem) { HeaderSearch::LoadModuleMapResult HeaderSearch::loadModuleMapFileImpl(const FileEntry *File, bool IsSystem, - const DirectoryEntry *Dir) { + const DirectoryEntry *Dir, FileID ID, + unsigned *Offset) { assert(File && "expected FileEntry"); // Check whether we've already loaded this module map, and mark it as being @@ -1356,7 +1383,7 @@ HeaderSearch::loadModuleMapFileImpl(const FileEntry *File, bool IsSystem, if (!AddResult.second) return AddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap; - if (ModMap.parseModuleMapFile(File, IsSystem, Dir)) { + if (ModMap.parseModuleMapFile(File, IsSystem, Dir, ID, Offset)) { LoadedModuleMaps[File] = false; return LMM_InvalidModuleMap; } diff --git a/contrib/llvm/tools/clang/lib/Lex/Lexer.cpp b/contrib/llvm/tools/clang/lib/Lex/Lexer.cpp index 6025a66..61bcef8 100644 --- a/contrib/llvm/tools/clang/lib/Lex/Lexer.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/Lexer.cpp @@ -19,6 +19,7 @@ #include "clang/Lex/LexDiagnostic.h" #include "clang/Lex/LiteralSupport.h" #include "clang/Lex/Preprocessor.h" +#include "clang/Lex/PreprocessorOptions.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/Compiler.h" @@ -43,6 +44,8 @@ using namespace clang; /// isObjCAtKeyword - Return true if we have an ObjC keyword identifier. bool Token::isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const { + if (isAnnotation()) + return false; if (IdentifierInfo *II = getIdentifierInfo()) return II->getObjCKeywordID() == objcKey; return false; @@ -50,6 +53,8 @@ bool Token::isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const { /// getObjCKeywordID - Return the ObjC keyword kind. tok::ObjCKeywordKind Token::getObjCKeywordID() const { + if (isAnnotation()) + return tok::objc_not_keyword; IdentifierInfo *specId = getIdentifierInfo(); return specId ? specId->getObjCKeywordID() : tok::objc_not_keyword; } @@ -452,6 +457,29 @@ bool Lexer::getRawToken(SourceLocation Loc, Token &Result, return false; } +/// Returns the pointer that points to the beginning of line that contains +/// the given offset, or null if the offset if invalid. +static const char *findBeginningOfLine(StringRef Buffer, unsigned Offset) { + const char *BufStart = Buffer.data(); + if (Offset >= Buffer.size()) + return nullptr; + const char *StrData = BufStart + Offset; + + if (StrData[0] == '\n' || StrData[0] == '\r') + return StrData; + + const char *LexStart = StrData; + while (LexStart != BufStart) { + if (LexStart[0] == '\n' || LexStart[0] == '\r') { + ++LexStart; + break; + } + + --LexStart; + } + return LexStart; +} + static SourceLocation getBeginningOfFileToken(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts) { @@ -467,27 +495,15 @@ static SourceLocation getBeginningOfFileToken(SourceLocation Loc, // Back up from the current location until we hit the beginning of a line // (or the buffer). We'll relex from that point. - const char *BufStart = Buffer.data(); - if (LocInfo.second >= Buffer.size()) - return Loc; - - const char *StrData = BufStart+LocInfo.second; - if (StrData[0] == '\n' || StrData[0] == '\r') + const char *StrData = Buffer.data() + LocInfo.second; + const char *LexStart = findBeginningOfLine(Buffer, LocInfo.second); + if (!LexStart || LexStart == StrData) return Loc; - - const char *LexStart = StrData; - while (LexStart != BufStart) { - if (LexStart[0] == '\n' || LexStart[0] == '\r') { - ++LexStart; - break; - } - - --LexStart; - } // Create a lexer starting at the beginning of this token. SourceLocation LexerStartLoc = Loc.getLocWithOffset(-LocInfo.second); - Lexer TheLexer(LexerStartLoc, LangOpts, BufStart, LexStart, Buffer.end()); + Lexer TheLexer(LexerStartLoc, LangOpts, Buffer.data(), LexStart, + Buffer.end()); TheLexer.SetCommentRetentionState(true); // Lex tokens until we find the token that contains the source location. @@ -535,8 +551,6 @@ namespace { enum PreambleDirectiveKind { PDK_Skipped, - PDK_StartIf, - PDK_EndIf, PDK_Unknown }; @@ -559,8 +573,6 @@ std::pair<unsigned, bool> Lexer::ComputePreamble(StringRef Buffer, bool InPreprocessorDirective = false; Token TheTok; - Token IfStartTok; - unsigned IfCount = 0; SourceLocation ActiveCommentLoc; unsigned MaxLineOffset = 0; @@ -643,33 +655,18 @@ std::pair<unsigned, bool> Lexer::ComputePreamble(StringRef Buffer, .Case("sccs", PDK_Skipped) .Case("assert", PDK_Skipped) .Case("unassert", PDK_Skipped) - .Case("if", PDK_StartIf) - .Case("ifdef", PDK_StartIf) - .Case("ifndef", PDK_StartIf) + .Case("if", PDK_Skipped) + .Case("ifdef", PDK_Skipped) + .Case("ifndef", PDK_Skipped) .Case("elif", PDK_Skipped) .Case("else", PDK_Skipped) - .Case("endif", PDK_EndIf) + .Case("endif", PDK_Skipped) .Default(PDK_Unknown); switch (PDK) { case PDK_Skipped: continue; - case PDK_StartIf: - if (IfCount == 0) - IfStartTok = HashTok; - - ++IfCount; - continue; - - case PDK_EndIf: - // Mismatched #endif. The preamble ends here. - if (IfCount == 0) - break; - - --IfCount; - continue; - case PDK_Unknown: // We don't know what this directive is; stop at the '#'. break; @@ -690,16 +687,13 @@ std::pair<unsigned, bool> Lexer::ComputePreamble(StringRef Buffer, } while (true); SourceLocation End; - if (IfCount) - End = IfStartTok.getLocation(); - else if (ActiveCommentLoc.isValid()) + if (ActiveCommentLoc.isValid()) End = ActiveCommentLoc; // don't truncate a decl comment. else End = TheTok.getLocation(); return std::make_pair(End.getRawEncoding() - StartLoc.getRawEncoding(), - IfCount? IfStartTok.isAtStartOfLine() - : TheTok.isAtStartOfLine()); + TheTok.isAtStartOfLine()); } /// AdvanceToTokenCharacter - Given a location that specifies the start of a @@ -1038,6 +1032,27 @@ bool Lexer::isIdentifierBodyChar(char c, const LangOptions &LangOpts) { return isIdentifierBody(c, LangOpts.DollarIdents); } +StringRef Lexer::getIndentationForLine(SourceLocation Loc, + const SourceManager &SM) { + if (Loc.isInvalid() || Loc.isMacroID()) + return ""; + std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc); + if (LocInfo.first.isInvalid()) + return ""; + bool Invalid = false; + StringRef Buffer = SM.getBufferData(LocInfo.first, &Invalid); + if (Invalid) + return ""; + const char *Line = findBeginningOfLine(Buffer, LocInfo.second); + if (!Line) + return ""; + StringRef Rest = Buffer.substr(Line - Buffer.data()); + size_t NumWhitespaceChars = Rest.find_first_not_of(" \t"); + return NumWhitespaceChars == StringRef::npos + ? "" + : Rest.take_front(NumWhitespaceChars); +} + //===----------------------------------------------------------------------===// // Diagnostics forwarding code. //===----------------------------------------------------------------------===// @@ -1171,6 +1186,8 @@ const char *Lexer::SkipEscapedNewLines(const char *P) { // If not a trigraph for escape, bail out. if (P[1] != '?' || P[2] != '/') return P; + // FIXME: Take LangOpts into account; the language might not + // support trigraphs. AfterEscape = P+3; } else { return P; @@ -1282,12 +1299,6 @@ Slash: Size += EscapedNewLineSize; Ptr += EscapedNewLineSize; - // If the char that we finally got was a \n, then we must have had - // something like \<newline><newline>. We don't want to consume the - // second newline. - if (*Ptr == '\n' || *Ptr == '\r' || *Ptr == '\0') - return ' '; - // Use slow version to accumulate a correct size field. return getCharAndSizeSlow(Ptr, Size, Tok); } @@ -1338,12 +1349,6 @@ Slash: Size += EscapedNewLineSize; Ptr += EscapedNewLineSize; - // If the char that we finally got was a \n, then we must have had - // something like \<newline><newline>. We don't want to consume the - // second newline. - if (*Ptr == '\n' || *Ptr == '\r' || *Ptr == '\0') - return ' '; - // Use slow version to accumulate a correct size field. return getCharAndSizeSlowNoWarn(Ptr, Size, LangOpts); } @@ -2070,8 +2075,11 @@ bool Lexer::SkipLineComment(Token &Result, const char *CurPtr, // Scan over the body of the comment. The common case, when scanning, is that // the comment contains normal ascii characters with nothing interesting in // them. As such, optimize for this case with the inner loop. + // + // This loop terminates with CurPtr pointing at the newline (or end of buffer) + // character that ends the line comment. char C; - do { + while (true) { C = *CurPtr; // Skip over characters in the fast loop. while (C != 0 && // Potentially EOF. @@ -2088,10 +2096,12 @@ bool Lexer::SkipLineComment(Token &Result, const char *CurPtr, HasSpace = true; } - if (*EscapePtr == '\\') // Escaped newline. + if (*EscapePtr == '\\') + // Escaped newline. CurPtr = EscapePtr; else if (EscapePtr[0] == '/' && EscapePtr[-1] == '?' && - EscapePtr[-2] == '?') // Trigraph-escaped newline. + EscapePtr[-2] == '?' && LangOpts.Trigraphs) + // Trigraph-escaped newline. CurPtr = EscapePtr-2; else break; // This is a newline, we're done. @@ -2140,9 +2150,9 @@ bool Lexer::SkipLineComment(Token &Result, const char *CurPtr, } } - if (CurPtr == BufferEnd+1) { - --CurPtr; - break; + if (C == '\r' || C == '\n' || CurPtr == BufferEnd + 1) { + --CurPtr; + break; } if (C == '\0' && isCodeCompletionPoint(CurPtr-1)) { @@ -2150,8 +2160,7 @@ bool Lexer::SkipLineComment(Token &Result, const char *CurPtr, cutOffLexing(); return false; } - - } while (C != '\n' && C != '\r'); + } // Found but did not consume the newline. Notify comment handlers about the // comment unless we're in a #if 0 block. @@ -2490,6 +2499,7 @@ void Lexer::ReadToEndOfLine(SmallVectorImpl<char> *Result) { break; } // FALL THROUGH. + LLVM_FALLTHROUGH; case '\r': case '\n': // Okay, we found the end of the line. First, back up past the \0, \r, \n. @@ -2540,6 +2550,11 @@ bool Lexer::LexEndOfFile(Token &Result, const char *CurPtr) { return true; } + if (PP->isRecordingPreamble() && PP->isInPrimaryFile()) { + PP->setRecordedPreambleConditionalStack(ConditionalStack); + ConditionalStack.clear(); + } + // Issue diagnostics for unterminated #if and missing newline. // If we are in a #if directive, emit an error. @@ -2722,6 +2737,37 @@ bool Lexer::HandleEndOfConflictMarker(const char *CurPtr) { return false; } +static const char *findPlaceholderEnd(const char *CurPtr, + const char *BufferEnd) { + if (CurPtr == BufferEnd) + return nullptr; + BufferEnd -= 1; // Scan until the second last character. + for (; CurPtr != BufferEnd; ++CurPtr) { + if (CurPtr[0] == '#' && CurPtr[1] == '>') + return CurPtr + 2; + } + return nullptr; +} + +bool Lexer::lexEditorPlaceholder(Token &Result, const char *CurPtr) { + assert(CurPtr[-1] == '<' && CurPtr[0] == '#' && "Not a placeholder!"); + if (!PP || !PP->getPreprocessorOpts().LexEditorPlaceholders || LexingRawMode) + return false; + const char *End = findPlaceholderEnd(CurPtr + 1, BufferEnd); + if (!End) + return false; + const char *Start = CurPtr - 1; + if (!LangOpts.AllowEditorPlaceholders) + Diag(Start, diag::err_placeholder_in_source); + Result.startToken(); + FormTokenWithChars(Result, End, tok::raw_identifier); + Result.setRawIdentifierData(Start); + PP->LookUpIdentifierInfo(Result); + Result.setFlag(Token::IsEditorPlaceholder); + BufferPtr = End; + return true; +} + bool Lexer::isCodeCompletionPoint(const char *CurPtr) const { if (PP && PP->isCodeCompletionEnabled()) { SourceLocation Loc = FileLoc.getLocWithOffset(CurPtr-BufferStart); @@ -3203,6 +3249,7 @@ LexNextToken: return LexCharConstant(Result, ConsumeChar(CurPtr, SizeTmp, Result), tok::wide_char_constant); // FALL THROUGH, treating L like the start of an identifier. + LLVM_FALLTHROUGH; // C99 6.4.2: Identifiers. case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': @@ -3479,6 +3526,8 @@ LexNextToken: } else if (LangOpts.Digraphs && Char == '%') { // '<%' -> '{' CurPtr = ConsumeChar(CurPtr, SizeTmp, Result); Kind = tok::l_brace; + } else if (Char == '#' && lexEditorPlaceholder(Result, CurPtr)) { + return true; } else { Kind = tok::less; } @@ -3603,17 +3652,19 @@ LexNextToken: // UCNs (C99 6.4.3, C++11 [lex.charset]p2) case '\\': - if (uint32_t CodePoint = tryReadUCN(CurPtr, BufferPtr, &Result)) { - if (CheckUnicodeWhitespace(Result, CodePoint, CurPtr)) { - if (SkipWhitespace(Result, CurPtr, TokAtPhysicalStartOfLine)) - return true; // KeepWhitespaceMode + if (!LangOpts.AsmPreprocessor) { + if (uint32_t CodePoint = tryReadUCN(CurPtr, BufferPtr, &Result)) { + if (CheckUnicodeWhitespace(Result, CodePoint, CurPtr)) { + if (SkipWhitespace(Result, CurPtr, TokAtPhysicalStartOfLine)) + return true; // KeepWhitespaceMode + + // We only saw whitespace, so just try again with this lexer. + // (We manually eliminate the tail call to avoid recursion.) + goto LexNextToken; + } - // We only saw whitespace, so just try again with this lexer. - // (We manually eliminate the tail call to avoid recursion.) - goto LexNextToken; + return LexUnicode(Result, CodePoint, CurPtr); } - - return LexUnicode(Result, CodePoint, CurPtr); } Kind = tok::unknown; diff --git a/contrib/llvm/tools/clang/lib/Lex/LiteralSupport.cpp b/contrib/llvm/tools/clang/lib/Lex/LiteralSupport.cpp index fbfd3fe..a598a46 100644 --- a/contrib/llvm/tools/clang/lib/Lex/LiteralSupport.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/LiteralSupport.cpp @@ -456,10 +456,17 @@ static void EncodeUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf, // Finally, we write the bytes into ResultBuf. ResultBuf += bytesToWrite; switch (bytesToWrite) { // note: everything falls through. - case 4: *--ResultBuf = (UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6; - case 3: *--ResultBuf = (UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6; - case 2: *--ResultBuf = (UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6; - case 1: *--ResultBuf = (UTF8) (UcnVal | firstByteMark[bytesToWrite]); + case 4: + *--ResultBuf = (UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6; + LLVM_FALLTHROUGH; + case 3: + *--ResultBuf = (UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6; + LLVM_FALLTHROUGH; + case 2: + *--ResultBuf = (UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6; + LLVM_FALLTHROUGH; + case 1: + *--ResultBuf = (UTF8) (UcnVal | firstByteMark[bytesToWrite]); } // Update the buffer. ResultBuf += bytesToWrite; @@ -563,7 +570,6 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, // Parse the suffix. At this point we can classify whether we have an FP or // integer constant. bool isFPConstant = isFloatingLiteral(); - const char *ImaginarySuffixLoc = nullptr; // Loop over all of the characters of the suffix. If we see something bad, // we break out of the loop. @@ -660,7 +666,6 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, case 'J': if (isImaginary) break; // Cannot be repeated. isImaginary = true; - ImaginarySuffixLoc = s; continue; // Success. } // If we reached here, there was an error or a ud-suffix. @@ -694,8 +699,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, } if (isImaginary) { - PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, - ImaginarySuffixLoc - ThisTokBegin), + PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, SuffixBegin - ThisTokBegin), diag::ext_imaginary_constant); } } diff --git a/contrib/llvm/tools/clang/lib/Lex/MacroArgs.cpp b/contrib/llvm/tools/clang/lib/Lex/MacroArgs.cpp index 1c1979d..f791d8d 100644 --- a/contrib/llvm/tools/clang/lib/Lex/MacroArgs.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/MacroArgs.cpp @@ -44,20 +44,22 @@ MacroArgs *MacroArgs::create(const MacroInfo *MI, // Otherwise, use the best fit. ClosestMatch = (*Entry)->NumUnexpArgTokens; } - + MacroArgs *Result; if (!ResultEnt) { // Allocate memory for a MacroArgs object with the lexer tokens at the end. - Result = (MacroArgs*)malloc(sizeof(MacroArgs) + - UnexpArgTokens.size() * sizeof(Token)); + Result = (MacroArgs *)malloc(sizeof(MacroArgs) + + UnexpArgTokens.size() * sizeof(Token)); // Construct the MacroArgs object. - new (Result) MacroArgs(UnexpArgTokens.size(), VarargsElided); + new (Result) + MacroArgs(UnexpArgTokens.size(), VarargsElided, MI->getNumParams()); } else { Result = *ResultEnt; // Unlink this node from the preprocessors singly linked list. *ResultEnt = Result->ArgCache; Result->NumUnexpArgTokens = UnexpArgTokens.size(); Result->VarargsElided = VarargsElided; + Result->NumMacroArgs = MI->getNumParams(); } // Copy the actual unexpanded tokens to immediately after the result ptr. @@ -146,11 +148,11 @@ bool MacroArgs::ArgNeedsPreexpansion(const Token *ArgTok, const std::vector<Token> & MacroArgs::getPreExpArgument(unsigned Arg, const MacroInfo *MI, Preprocessor &PP) { - assert(Arg < MI->getNumArgs() && "Invalid argument number!"); + assert(Arg < MI->getNumParams() && "Invalid argument number!"); // If we have already computed this, return it. - if (PreExpArgTokens.size() < MI->getNumArgs()) - PreExpArgTokens.resize(MI->getNumArgs()); + if (PreExpArgTokens.size() < MI->getNumParams()) + PreExpArgTokens.resize(MI->getNumParams()); std::vector<Token> &Result = PreExpArgTokens[Arg]; if (!Result.empty()) return Result; @@ -298,12 +300,10 @@ const Token &MacroArgs::getStringifiedArgument(unsigned ArgNo, Preprocessor &PP, SourceLocation ExpansionLocStart, SourceLocation ExpansionLocEnd) { - assert(ArgNo < NumUnexpArgTokens && "Invalid argument number!"); - if (StringifiedArgs.empty()) { - StringifiedArgs.resize(getNumArguments()); - memset((void*)&StringifiedArgs[0], 0, - sizeof(StringifiedArgs[0])*getNumArguments()); - } + assert(ArgNo < getNumMacroArguments() && "Invalid argument number!"); + if (StringifiedArgs.empty()) + StringifiedArgs.resize(getNumMacroArguments(), {}); + if (StringifiedArgs[ArgNo].isNot(tok::string_literal)) StringifiedArgs[ArgNo] = StringifyArgument(getUnexpArgument(ArgNo), PP, /*Charify=*/false, diff --git a/contrib/llvm/tools/clang/lib/Lex/MacroInfo.cpp b/contrib/llvm/tools/clang/lib/Lex/MacroInfo.cpp index 924613d..6dc7841 100644 --- a/contrib/llvm/tools/clang/lib/Lex/MacroInfo.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/MacroInfo.cpp @@ -17,8 +17,8 @@ using namespace clang; MacroInfo::MacroInfo(SourceLocation DefLoc) : Location(DefLoc), - ArgumentList(nullptr), - NumArguments(0), + ParameterList(nullptr), + NumParameters(0), IsDefinitionLengthCached(false), IsFunctionLike(false), IsC99Varargs(false), @@ -29,11 +29,10 @@ MacroInfo::MacroInfo(SourceLocation DefLoc) IsUsed(false), IsAllowRedefinitionsWithoutWarning(false), IsWarnIfUnused(false), - FromASTFile(false), UsedForHeaderGuard(false) { } -unsigned MacroInfo::getDefinitionLengthSlow(SourceManager &SM) const { +unsigned MacroInfo::getDefinitionLengthSlow(const SourceManager &SM) const { assert(!IsDefinitionLengthCached); IsDefinitionLengthCached = true; @@ -75,7 +74,7 @@ bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP, // Check # tokens in replacement, number of args, and various flags all match. if (ReplacementTokens.size() != Other.ReplacementTokens.size() || - getNumArgs() != Other.getNumArgs() || + getNumParams() != Other.getNumParams() || isFunctionLike() != Other.isFunctionLike() || isC99Varargs() != Other.isC99Varargs() || isGNUVarargs() != Other.isGNUVarargs()) @@ -83,7 +82,8 @@ bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP, if (Lexically) { // Check arguments. - for (arg_iterator I = arg_begin(), OI = Other.arg_begin(), E = arg_end(); + for (param_iterator I = param_begin(), OI = Other.param_begin(), + E = param_end(); I != E; ++I, ++OI) if (*I != *OI) return false; } @@ -110,10 +110,10 @@ bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP, return false; // With syntactic equivalence the parameter names can be different as long // as they are used in the same place. - int AArgNum = getArgumentNum(A.getIdentifierInfo()); + int AArgNum = getParameterNum(A.getIdentifierInfo()); if (AArgNum == -1) return false; - if (AArgNum != Other.getArgumentNum(B.getIdentifierInfo())) + if (AArgNum != Other.getParameterNum(B.getIdentifierInfo())) return false; continue; } @@ -137,18 +137,17 @@ LLVM_DUMP_METHOD void MacroInfo::dump() const { if (IsAllowRedefinitionsWithoutWarning) Out << " allow_redefinitions_without_warning"; if (IsWarnIfUnused) Out << " warn_if_unused"; - if (FromASTFile) Out << " imported"; if (UsedForHeaderGuard) Out << " header_guard"; Out << "\n #define <macro>"; if (IsFunctionLike) { Out << "("; - for (unsigned I = 0; I != NumArguments; ++I) { + for (unsigned I = 0; I != NumParameters; ++I) { if (I) Out << ", "; - Out << ArgumentList[I]->getName(); + Out << ParameterList[I]->getName(); } if (IsC99Varargs || IsGNUVarargs) { - if (NumArguments && IsC99Varargs) Out << ", "; + if (NumParameters && IsC99Varargs) Out << ", "; Out << "..."; } Out << ")"; diff --git a/contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp b/contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp index 1488f62..40f78ce 100644 --- a/contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/ModuleMap.cpp @@ -36,6 +36,37 @@ #endif using namespace clang; +Module::HeaderKind ModuleMap::headerRoleToKind(ModuleHeaderRole Role) { + switch ((int)Role) { + default: llvm_unreachable("unknown header role"); + case NormalHeader: + return Module::HK_Normal; + case PrivateHeader: + return Module::HK_Private; + case TextualHeader: + return Module::HK_Textual; + case PrivateHeader | TextualHeader: + return Module::HK_PrivateTextual; + } +} + +ModuleMap::ModuleHeaderRole +ModuleMap::headerKindToRole(Module::HeaderKind Kind) { + switch ((int)Kind) { + case Module::HK_Normal: + return NormalHeader; + case Module::HK_Private: + return PrivateHeader; + case Module::HK_Textual: + return TextualHeader; + case Module::HK_PrivateTextual: + return ModuleHeaderRole(PrivateHeader | TextualHeader); + case Module::HK_Excluded: + llvm_unreachable("unexpected header kind"); + } + llvm_unreachable("unknown header kind"); +} + Module::ExportDecl ModuleMap::resolveExport(Module *Mod, const Module::UnresolvedExportDecl &Unresolved, @@ -84,6 +115,143 @@ Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod, return Context; } +/// \brief Append to \p Paths the set of paths needed to get to the +/// subframework in which the given module lives. +static void appendSubframeworkPaths(Module *Mod, + SmallVectorImpl<char> &Path) { + // Collect the framework names from the given module to the top-level module. + SmallVector<StringRef, 2> Paths; + for (; Mod; Mod = Mod->Parent) { + if (Mod->IsFramework) + Paths.push_back(Mod->Name); + } + + if (Paths.empty()) + return; + + // Add Frameworks/Name.framework for each subframework. + for (unsigned I = Paths.size() - 1; I != 0; --I) + llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework"); +} + +const FileEntry * +ModuleMap::findHeader(Module *M, + const Module::UnresolvedHeaderDirective &Header, + SmallVectorImpl<char> &RelativePathName) { + auto GetFile = [&](StringRef Filename) -> const FileEntry * { + auto *File = SourceMgr.getFileManager().getFile(Filename); + if (!File || + (Header.Size && File->getSize() != *Header.Size) || + (Header.ModTime && File->getModificationTime() != *Header.ModTime)) + return nullptr; + return File; + }; + + if (llvm::sys::path::is_absolute(Header.FileName)) { + RelativePathName.clear(); + RelativePathName.append(Header.FileName.begin(), Header.FileName.end()); + return GetFile(Header.FileName); + } + + // Search for the header file within the module's home directory. + auto *Directory = M->Directory; + SmallString<128> FullPathName(Directory->getName()); + unsigned FullPathLength = FullPathName.size(); + + if (M->isPartOfFramework()) { + appendSubframeworkPaths(M, RelativePathName); + unsigned RelativePathLength = RelativePathName.size(); + + // Check whether this file is in the public headers. + llvm::sys::path::append(RelativePathName, "Headers", Header.FileName); + llvm::sys::path::append(FullPathName, RelativePathName); + if (auto *File = GetFile(FullPathName)) + return File; + + // Check whether this file is in the private headers. + // Ideally, private modules in the form 'FrameworkName.Private' should + // be defined as 'module FrameworkName.Private', and not as + // 'framework module FrameworkName.Private', since a 'Private.Framework' + // does not usually exist. However, since both are currently widely used + // for private modules, make sure we find the right path in both cases. + if (M->IsFramework && M->Name == "Private") + RelativePathName.clear(); + else + RelativePathName.resize(RelativePathLength); + FullPathName.resize(FullPathLength); + llvm::sys::path::append(RelativePathName, "PrivateHeaders", + Header.FileName); + llvm::sys::path::append(FullPathName, RelativePathName); + return GetFile(FullPathName); + } + + // Lookup for normal headers. + llvm::sys::path::append(RelativePathName, Header.FileName); + llvm::sys::path::append(FullPathName, RelativePathName); + return GetFile(FullPathName); +} + +void ModuleMap::resolveHeader(Module *Mod, + const Module::UnresolvedHeaderDirective &Header) { + SmallString<128> RelativePathName; + if (const FileEntry *File = findHeader(Mod, Header, RelativePathName)) { + if (Header.IsUmbrella) { + const DirectoryEntry *UmbrellaDir = File->getDir(); + if (Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir]) + Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash) + << UmbrellaMod->getFullModuleName(); + else + // Record this umbrella header. + setUmbrellaHeader(Mod, File, RelativePathName.str()); + } else { + Module::Header H = {RelativePathName.str(), File}; + if (Header.Kind == Module::HK_Excluded) + excludeHeader(Mod, H); + else + addHeader(Mod, H, headerKindToRole(Header.Kind)); + } + } else if (Header.HasBuiltinHeader && !Header.Size && !Header.ModTime) { + // There's a builtin header but no corresponding on-disk header. Assume + // this was supposed to modularize the builtin header alone. + } else if (Header.Kind == Module::HK_Excluded) { + // Ignore missing excluded header files. They're optional anyway. + } else { + // If we find a module that has a missing header, we mark this module as + // unavailable and store the header directive for displaying diagnostics. + Mod->MissingHeaders.push_back(Header); + // A missing header with stat information doesn't make the module + // unavailable; this keeps our behavior consistent as headers are lazily + // resolved. (Such a module still can't be built though, except from + // preprocessed source.) + if (!Header.Size && !Header.ModTime) + Mod->markUnavailable(); + } +} + +bool ModuleMap::resolveAsBuiltinHeader( + Module *Mod, const Module::UnresolvedHeaderDirective &Header) { + if (Header.Kind == Module::HK_Excluded || + llvm::sys::path::is_absolute(Header.FileName) || + Mod->isPartOfFramework() || !Mod->IsSystem || Header.IsUmbrella || + !BuiltinIncludeDir || BuiltinIncludeDir == Mod->Directory || + !isBuiltinHeader(Header.FileName)) + return false; + + // This is a system module with a top-level header. This header + // may have a counterpart (or replacement) in the set of headers + // supplied by Clang. Find that builtin header. + SmallString<128> Path; + llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.FileName); + auto *File = SourceMgr.getFileManager().getFile(Path); + if (!File) + return false; + + auto Role = headerKindToRole(Header.Kind); + Module::Header H = {Path.str(), File}; + addHeader(Mod, H, Role); + return true; +} + ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const TargetInfo *Target, HeaderSearch &HeaderInfo) @@ -162,6 +330,7 @@ bool ModuleMap::isBuiltinHeader(StringRef FileName) { ModuleMap::HeadersMap::iterator ModuleMap::findKnownHeader(const FileEntry *File) { + resolveHeaderDirectives(File); HeadersMap::iterator Known = Headers.find(File); if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps && Known == Headers.end() && File->getDir() == BuiltinIncludeDir && @@ -244,8 +413,10 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule, if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule)) return; - if (RequestingModule) + if (RequestingModule) { resolveUses(RequestingModule, /*Complain=*/false); + resolveHeaderDirectives(RequestingModule); + } bool Excluded = false; Module *Private = nullptr; @@ -427,6 +598,7 @@ ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) { ArrayRef<ModuleMap::KnownHeader> ModuleMap::findAllModulesForHeader(const FileEntry *File) const { + resolveHeaderDirectives(File); auto It = Headers.find(File); if (It == Headers.end()) return None; @@ -440,6 +612,7 @@ bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const { bool ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header, const Module *RequestingModule) const { + resolveHeaderDirectives(Header); HeadersMap::const_iterator Known = Headers.find(Header); if (Known != Headers.end()) { for (SmallVectorImpl<KnownHeader>::const_iterator @@ -554,16 +727,17 @@ Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{ return Context->findSubmodule(Name); } -std::pair<Module *, bool> -ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, - bool IsExplicit) { +std::pair<Module *, bool> ModuleMap::findOrCreateModule(StringRef Name, + Module *Parent, + bool IsFramework, + bool IsExplicit) { // Try to find an existing module with this name. if (Module *Sub = lookupModuleQualified(Name, Parent)) return std::make_pair(Sub, false); // Create a new module with this name. - Module *Result = new Module(Name, SourceLocation(), Parent, - IsFramework, IsExplicit, NumCreatedModules++); + Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework, + IsExplicit, NumCreatedModules++); if (!Parent) { if (LangOpts.CurrentModule == Name) SourceModule = Result; @@ -580,6 +754,7 @@ Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc, auto *Result = new Module(Name, Loc, nullptr, /*IsFramework*/ false, /*IsExplicit*/ false, NumCreatedModules++); + Result->Kind = Module::ModuleInterfaceUnit; Modules[Name] = SourceModule = Result; // Mark the main source file as being within the newly-created module so that @@ -810,18 +985,63 @@ void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir, UmbrellaDirs[UmbrellaDir] = Mod; } -static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) { - switch ((int)Role) { - default: llvm_unreachable("unknown header role"); - case ModuleMap::NormalHeader: - return Module::HK_Normal; - case ModuleMap::PrivateHeader: - return Module::HK_Private; - case ModuleMap::TextualHeader: - return Module::HK_Textual; - case ModuleMap::PrivateHeader | ModuleMap::TextualHeader: - return Module::HK_PrivateTextual; +void ModuleMap::addUnresolvedHeader(Module *Mod, + Module::UnresolvedHeaderDirective Header) { + // If there is a builtin counterpart to this file, add it now so it can + // wrap the system header. + if (resolveAsBuiltinHeader(Mod, Header)) { + // If we have both a builtin and system version of the file, the + // builtin version may want to inject macros into the system header, so + // force the system header to be treated as a textual header in this + // case. + Header.Kind = headerRoleToKind(ModuleMap::ModuleHeaderRole( + headerKindToRole(Header.Kind) | ModuleMap::TextualHeader)); + Header.HasBuiltinHeader = true; + } + + // If possible, don't stat the header until we need to. This requires the + // user to have provided us with some stat information about the file. + // FIXME: Add support for lazily stat'ing umbrella headers and excluded + // headers. + if ((Header.Size || Header.ModTime) && !Header.IsUmbrella && + Header.Kind != Module::HK_Excluded) { + // We expect more variation in mtime than size, so if we're given both, + // use the mtime as the key. + if (Header.ModTime) + LazyHeadersByModTime[*Header.ModTime].push_back(Mod); + else + LazyHeadersBySize[*Header.Size].push_back(Mod); + Mod->UnresolvedHeaders.push_back(Header); + return; } + + // We don't have stat information or can't defer looking this file up. + // Perform the lookup now. + resolveHeader(Mod, Header); +} + +void ModuleMap::resolveHeaderDirectives(const FileEntry *File) const { + auto BySize = LazyHeadersBySize.find(File->getSize()); + if (BySize != LazyHeadersBySize.end()) { + for (auto *M : BySize->second) + resolveHeaderDirectives(M); + LazyHeadersBySize.erase(BySize); + } + + auto ByModTime = LazyHeadersByModTime.find(File->getModificationTime()); + if (ByModTime != LazyHeadersByModTime.end()) { + for (auto *M : ByModTime->second) + resolveHeaderDirectives(M); + LazyHeadersByModTime.erase(ByModTime); + } +} + +void ModuleMap::resolveHeaderDirectives(Module *Mod) const { + for (auto &Header : Mod->UnresolvedHeaders) + // This operation is logically const; we're just changing how we represent + // the header information for this file. + const_cast<ModuleMap*>(this)->resolveHeader(Mod, Header); + Mod->UnresolvedHeaders.clear(); } void ModuleMap::addHeader(Module *Mod, Module::Header Header, @@ -948,39 +1168,6 @@ bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) { return !Mod->UnresolvedConflicts.empty(); } -Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) { - if (Loc.isInvalid()) - return nullptr; - - if (UmbrellaDirs.empty() && Headers.empty()) - return nullptr; - - // Use the expansion location to determine which module we're in. - FullSourceLoc ExpansionLoc = Loc.getExpansionLoc(); - if (!ExpansionLoc.isFileID()) - return nullptr; - - const SourceManager &SrcMgr = Loc.getManager(); - FileID ExpansionFileID = ExpansionLoc.getFileID(); - - while (const FileEntry *ExpansionFile - = SrcMgr.getFileEntryForID(ExpansionFileID)) { - // Find the module that owns this header (if any). - if (Module *Mod = findModuleForHeader(ExpansionFile).getModule()) - return Mod; - - // No module owns this header, so look up the inclusion chain to see if - // any included header has an associated module. - SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID); - if (IncludeLoc.isInvalid()) - return nullptr; - - ExpansionFileID = SrcMgr.getFileID(IncludeLoc); - } - - return nullptr; -} - //----------------------------------------------------------------------------// // Module map file parser //----------------------------------------------------------------------------// @@ -1010,6 +1197,7 @@ namespace clang { RequiresKeyword, Star, StringLiteral, + IntegerLiteral, TextualKeyword, LBrace, RBrace, @@ -1019,7 +1207,12 @@ namespace clang { unsigned Location; unsigned StringLength; - const char *StringData; + union { + // If Kind != IntegerLiteral. + const char *StringData; + // If Kind == IntegerLiteral. + uint64_t IntegerValue; + }; void clear() { Kind = EndOfFile; @@ -1033,9 +1226,14 @@ namespace clang { SourceLocation getLocation() const { return SourceLocation::getFromRawEncoding(Location); } + + uint64_t getInteger() const { + return Kind == IntegerLiteral ? IntegerValue : 0; + } StringRef getString() const { - return StringRef(StringData, StringLength); + return Kind == IntegerLiteral ? StringRef() + : StringRef(StringData, StringLength); } }; @@ -1057,9 +1255,6 @@ namespace clang { /// be resolved relative to. const DirectoryEntry *Directory; - /// \brief The directory containing Clang-supplied headers. - const DirectoryEntry *BuiltinIncludeDir; - /// \brief Whether this module map is in a system header directory. bool IsSystem; @@ -1118,26 +1313,27 @@ namespace clang { ModuleMap &Map, const FileEntry *ModuleMapFile, const DirectoryEntry *Directory, - const DirectoryEntry *BuiltinIncludeDir, bool IsSystem) : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), ModuleMapFile(ModuleMapFile), Directory(Directory), - BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem), - HadError(false), ActiveModule(nullptr) + IsSystem(IsSystem), HadError(false), ActiveModule(nullptr) { Tok.clear(); consumeToken(); } bool parseModuleMapFile(); + + bool terminatedByDirective() { return false; } + SourceLocation getLocation() { return Tok.getLocation(); } }; } SourceLocation ModuleMapParser::consumeToken() { -retry: SourceLocation Result = Tok.getLocation(); + +retry: Tok.clear(); - Token LToken; L.LexFromRawLexer(LToken); Tok.Location = LToken.getLocation().getRawEncoding(); @@ -1227,12 +1423,50 @@ retry: Tok.StringLength = Length; break; } + + case tok::numeric_constant: { + // We don't support any suffixes or other complications. + SmallString<32> SpellingBuffer; + SpellingBuffer.resize(LToken.getLength() + 1); + const char *Start = SpellingBuffer.data(); + unsigned Length = + Lexer::getSpelling(LToken, Start, SourceMgr, L.getLangOpts()); + uint64_t Value; + if (StringRef(Start, Length).getAsInteger(0, Value)) { + Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token); + HadError = true; + goto retry; + } + + Tok.Kind = MMToken::IntegerLiteral; + Tok.IntegerValue = Value; + break; + } case tok::comment: goto retry; - + + case tok::hash: + // A module map can be terminated prematurely by + // #pragma clang module contents + // When building the module, we'll treat the rest of the file as the + // contents of the module. + { + auto NextIsIdent = [&](StringRef Str) -> bool { + L.LexFromRawLexer(LToken); + return !LToken.isAtStartOfLine() && LToken.is(tok::raw_identifier) && + LToken.getRawIdentifier() == Str; + }; + if (NextIsIdent("pragma") && NextIsIdent("clang") && + NextIsIdent("module") && NextIsIdent("contents")) { + Tok.Kind = MMToken::EndOfFile; + break; + } + } + LLVM_FALLTHROUGH; + default: - Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token); + Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token); HadError = true; goto retry; } @@ -1461,7 +1695,19 @@ void ModuleMapParser::parseModuleDecl() { // Determine whether this (sub)module has already been defined. if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { - if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) { + // We might see a (re)definition of a module that we already have a + // definition for in two cases: + // - If we loaded one definition from an AST file and we've just found a + // corresponding definition in a module map file, or + bool LoadedFromASTFile = Existing->DefinitionLoc.isInvalid(); + // - If we're building a (preprocessed) module and we've just loaded the + // module map file from which it was created. + bool ParsedAsMainInput = + Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap && + Map.LangOpts.CurrentModule == ModuleName && + SourceMgr.getDecomposedLoc(ModuleNameLoc).first != + SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first; + if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) { // Skip the module definition. skipUntil(MMToken::RBrace); if (Tok.is(MMToken::RBrace)) @@ -1680,7 +1926,8 @@ void ModuleMapParser::parseExternModuleDecl() { File, /*IsSystem=*/false, Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd ? Directory - : File->getDir(), ExternLoc); + : File->getDir(), + FileID(), nullptr, ExternLoc); } /// Whether to add the requirement \p Feature to the module \p M. @@ -1768,25 +2015,6 @@ void ModuleMapParser::parseRequiresDecl() { } while (true); } -/// \brief Append to \p Paths the set of paths needed to get to the -/// subframework in which the given module lives. -static void appendSubframeworkPaths(Module *Mod, - SmallVectorImpl<char> &Path) { - // Collect the framework names from the given module to the top-level module. - SmallVector<StringRef, 2> Paths; - for (; Mod; Mod = Mod->Parent) { - if (Mod->IsFramework) - Paths.push_back(Mod->Name); - } - - if (Paths.empty()) - return; - - // Add Frameworks/Name.framework for each subframework. - for (unsigned I = Paths.size() - 1; I != 0; --I) - llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework"); -} - /// \brief Parse a header declaration. /// /// header-declaration: @@ -1839,119 +2067,75 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, Module::UnresolvedHeaderDirective Header; Header.FileName = Tok.getString(); Header.FileNameLoc = consumeToken(); - + Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword; + Header.Kind = + (LeadingToken == MMToken::ExcludeKeyword ? Module::HK_Excluded + : Map.headerRoleToKind(Role)); + // Check whether we already have an umbrella. - if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) { + if (Header.IsUmbrella && ActiveModule->Umbrella) { Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash) << ActiveModule->getFullModuleName(); HadError = true; return; } - // Look for this file. - const FileEntry *File = nullptr; - const FileEntry *BuiltinFile = nullptr; - SmallString<128> RelativePathName; - if (llvm::sys::path::is_absolute(Header.FileName)) { - RelativePathName = Header.FileName; - File = SourceMgr.getFileManager().getFile(RelativePathName); - } else { - // Search for the header file within the search directory. - SmallString<128> FullPathName(Directory->getName()); - unsigned FullPathLength = FullPathName.size(); - - if (ActiveModule->isPartOfFramework()) { - appendSubframeworkPaths(ActiveModule, RelativePathName); - - // Check whether this file is in the public headers. - llvm::sys::path::append(RelativePathName, "Headers", Header.FileName); - llvm::sys::path::append(FullPathName, RelativePathName); - File = SourceMgr.getFileManager().getFile(FullPathName); - - if (!File) { - // Check whether this file is in the private headers. - // FIXME: Should we retain the subframework paths here? - RelativePathName.clear(); - FullPathName.resize(FullPathLength); - llvm::sys::path::append(RelativePathName, "PrivateHeaders", - Header.FileName); - llvm::sys::path::append(FullPathName, RelativePathName); - File = SourceMgr.getFileManager().getFile(FullPathName); - } - } else { - // Lookup for normal headers. - llvm::sys::path::append(RelativePathName, Header.FileName); - llvm::sys::path::append(FullPathName, RelativePathName); - File = SourceMgr.getFileManager().getFile(FullPathName); - - // If this is a system module with a top-level header, this header - // may have a counterpart (or replacement) in the set of headers - // supplied by Clang. Find that builtin header. - if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword && - BuiltinIncludeDir && BuiltinIncludeDir != Directory && - ModuleMap::isBuiltinHeader(Header.FileName)) { - SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName()); - llvm::sys::path::append(BuiltinPathName, Header.FileName); - BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName); - - // If Clang supplies this header but the underlying system does not, - // just silently swap in our builtin version. Otherwise, we'll end - // up adding both (later). - if (BuiltinFile && !File) { - File = BuiltinFile; - RelativePathName = BuiltinPathName; - BuiltinFile = nullptr; + // If we were given stat information, parse it so we can skip looking for + // the file. + if (Tok.is(MMToken::LBrace)) { + SourceLocation LBraceLoc = consumeToken(); + + while (!Tok.is(MMToken::RBrace) && !Tok.is(MMToken::EndOfFile)) { + enum Attribute { Size, ModTime, Unknown }; + StringRef Str = Tok.getString(); + SourceLocation Loc = consumeToken(); + switch (llvm::StringSwitch<Attribute>(Str) + .Case("size", Size) + .Case("mtime", ModTime) + .Default(Unknown)) { + case Size: + if (Header.Size) + Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str; + if (!Tok.is(MMToken::IntegerLiteral)) { + Diags.Report(Tok.getLocation(), + diag::err_mmap_invalid_header_attribute_value) << Str; + skipUntil(MMToken::RBrace); + break; } - } - } - } + Header.Size = Tok.getInteger(); + consumeToken(); + break; - // FIXME: We shouldn't be eagerly stat'ing every file named in a module map. - // Come up with a lazy way to do this. - if (File) { - if (LeadingToken == MMToken::UmbrellaKeyword) { - const DirectoryEntry *UmbrellaDir = File->getDir(); - if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) { - Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash) - << UmbrellaModule->getFullModuleName(); - HadError = true; - } else { - // Record this umbrella header. - Map.setUmbrellaHeader(ActiveModule, File, RelativePathName.str()); - } - } else if (LeadingToken == MMToken::ExcludeKeyword) { - Module::Header H = {RelativePathName.str(), File}; - Map.excludeHeader(ActiveModule, H); - } else { - // If there is a builtin counterpart to this file, add it now so it can - // wrap the system header. - if (BuiltinFile) { - // FIXME: Taking the name from the FileEntry is unstable and can give - // different results depending on how we've previously named that file - // in this build. - Module::Header H = { BuiltinFile->getName(), BuiltinFile }; - Map.addHeader(ActiveModule, H, Role); - - // If we have both a builtin and system version of the file, the - // builtin version may want to inject macros into the system header, so - // force the system header to be treated as a textual header in this - // case. - Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); - } + case ModTime: + if (Header.ModTime) + Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str; + if (!Tok.is(MMToken::IntegerLiteral)) { + Diags.Report(Tok.getLocation(), + diag::err_mmap_invalid_header_attribute_value) << Str; + skipUntil(MMToken::RBrace); + break; + } + Header.ModTime = Tok.getInteger(); + consumeToken(); + break; - // Record this header. - Module::Header H = { RelativePathName.str(), File }; - Map.addHeader(ActiveModule, H, Role); + case Unknown: + Diags.Report(Loc, diag::err_mmap_expected_header_attribute); + skipUntil(MMToken::RBrace); + break; + } } - } else if (LeadingToken != MMToken::ExcludeKeyword) { - // Ignore excluded header files. They're optional anyway. - // If we find a module that has a missing header, we mark this module as - // unavailable and store the header directive for displaying diagnostics. - Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword; - ActiveModule->markUnavailable(); - ActiveModule->MissingHeaders.push_back(Header); + if (Tok.is(MMToken::RBrace)) + consumeToken(); + else { + Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace); + Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match); + HadError = true; + } } + + Map.addUnresolvedHeader(ActiveModule, std::move(Header)); } static int compareModuleHeaders(const Module::Header *A, @@ -1995,9 +2179,8 @@ void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) { } if (!Dir) { - Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found) + Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found) << DirName; - HadError = true; return; } @@ -2503,6 +2686,7 @@ bool ModuleMapParser::parseModuleMapFile() { case MMToken::RequiresKeyword: case MMToken::Star: case MMToken::StringLiteral: + case MMToken::IntegerLiteral: case MMToken::TextualKeyword: case MMToken::UmbrellaKeyword: case MMToken::UseKeyword: @@ -2515,28 +2699,46 @@ bool ModuleMapParser::parseModuleMapFile() { } bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem, - const DirectoryEntry *Dir, + const DirectoryEntry *Dir, FileID ID, + unsigned *Offset, SourceLocation ExternModuleLoc) { + assert(Target && "Missing target information"); llvm::DenseMap<const FileEntry *, bool>::iterator Known = ParsedModuleMap.find(File); if (Known != ParsedModuleMap.end()) return Known->second; + // If the module map file wasn't already entered, do so now. + if (ID.isInvalid()) { + auto FileCharacter = + IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap; + ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter); + } + assert(Target && "Missing target information"); - auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User; - FileID ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter); const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID); if (!Buffer) return ParsedModuleMap[File] = true; + assert((!Offset || *Offset <= Buffer->getBufferSize()) && + "invalid buffer offset"); // Parse this module map file. - Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts); + Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts, + Buffer->getBufferStart(), + Buffer->getBufferStart() + (Offset ? *Offset : 0), + Buffer->getBufferEnd()); SourceLocation Start = L.getSourceLocation(); ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir, - BuiltinIncludeDir, IsSystem); + IsSystem); bool Result = Parser.parseModuleMapFile(); ParsedModuleMap[File] = Result; + if (Offset) { + auto Loc = SourceMgr.getDecomposedLoc(Parser.getLocation()); + assert(Loc.first == ID && "stopped in a different file?"); + *Offset = Loc.second; + } + // Notify callbacks that we parsed it. for (const auto &Cb : Callbacks) Cb->moduleMapFileRead(Start, *File, IsSystem); diff --git a/contrib/llvm/tools/clang/lib/Lex/PPCaching.cpp b/contrib/llvm/tools/clang/lib/Lex/PPCaching.cpp index 45bdce3..f5e8cdc 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PPCaching.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/PPCaching.cpp @@ -35,6 +35,29 @@ void Preprocessor::CommitBacktrackedTokens() { BacktrackPositions.pop_back(); } +Preprocessor::CachedTokensRange Preprocessor::LastCachedTokenRange() { + assert(isBacktrackEnabled()); + auto PrevCachedLexPos = BacktrackPositions.back(); + return CachedTokensRange{PrevCachedLexPos, CachedLexPos}; +} + +void Preprocessor::EraseCachedTokens(CachedTokensRange TokenRange) { + assert(TokenRange.Begin <= TokenRange.End); + if (CachedLexPos == TokenRange.Begin && TokenRange.Begin != TokenRange.End) { + // We have backtracked to the start of the token range as we want to consume + // them again. Erase the tokens only after consuming then. + assert(!CachedTokenRangeToErase); + CachedTokenRangeToErase = TokenRange; + return; + } + // The cached tokens were committed, so they should be erased now. + assert(TokenRange.End == CachedLexPos); + CachedTokens.erase(CachedTokens.begin() + TokenRange.Begin, + CachedTokens.begin() + TokenRange.End); + CachedLexPos = TokenRange.Begin; + ExitCachingLexMode(); +} + // Make Preprocessor re-lex the tokens that were lexed since // EnableBacktrackAtThisPos() was previously called. void Preprocessor::Backtrack() { @@ -51,6 +74,13 @@ void Preprocessor::CachingLex(Token &Result) { if (CachedLexPos < CachedTokens.size()) { Result = CachedTokens[CachedLexPos++]; + // Erase the some of the cached tokens after they are consumed when + // asked to do so. + if (CachedTokenRangeToErase && + CachedTokenRangeToErase->End == CachedLexPos) { + EraseCachedTokens(*CachedTokenRangeToErase); + CachedTokenRangeToErase = None; + } return; } diff --git a/contrib/llvm/tools/clang/lib/Lex/PPDirectives.cpp b/contrib/llvm/tools/clang/lib/Lex/PPDirectives.cpp index 322c580..b2450f5 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PPDirectives.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/PPDirectives.cpp @@ -30,6 +30,7 @@ #include "clang/Lex/PPCallbacks.h" #include "clang/Lex/Pragma.h" #include "clang/Lex/Preprocessor.h" +#include "clang/Lex/PreprocessorOptions.h" #include "clang/Lex/PTHLexer.h" #include "clang/Lex/Token.h" #include "llvm/ADT/ArrayRef.h" @@ -54,35 +55,12 @@ using namespace clang; // Utility Methods for Preprocessor Directive Handling. //===----------------------------------------------------------------------===// -MacroInfo *Preprocessor::AllocateMacroInfo() { - MacroInfoChain *MIChain = BP.Allocate<MacroInfoChain>(); - MIChain->Next = MIChainHead; +MacroInfo *Preprocessor::AllocateMacroInfo(SourceLocation L) { + auto *MIChain = new (BP) MacroInfoChain{L, MIChainHead}; MIChainHead = MIChain; return &MIChain->MI; } -MacroInfo *Preprocessor::AllocateMacroInfo(SourceLocation L) { - MacroInfo *MI = AllocateMacroInfo(); - new (MI) MacroInfo(L); - return MI; -} - -MacroInfo *Preprocessor::AllocateDeserializedMacroInfo(SourceLocation L, - unsigned SubModuleID) { - static_assert(alignof(MacroInfo) >= sizeof(SubModuleID), - "alignment for MacroInfo is less than the ID"); - DeserializedMacroInfoChain *MIChain = - BP.Allocate<DeserializedMacroInfoChain>(); - MIChain->Next = DeserialMIChainHead; - DeserialMIChainHead = MIChain; - - MacroInfo *MI = &MIChain->MI; - new (MI) MacroInfo(L); - MI->FromASTFile = true; - MI->setOwningModuleID(SubModuleID); - return MI; -} - DefMacroDirective *Preprocessor::AllocateDefMacroDirective(MacroInfo *MI, SourceLocation Loc) { return new (BP) DefMacroDirective(MI, Loc); @@ -242,26 +220,18 @@ bool Preprocessor::CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, return Diag(MacroNameTok, diag::err_pp_missing_macro_name); IdentifierInfo *II = MacroNameTok.getIdentifierInfo(); - if (!II) { - bool Invalid = false; - std::string Spelling = getSpelling(MacroNameTok, &Invalid); - if (Invalid) - return Diag(MacroNameTok, diag::err_pp_macro_not_identifier); - II = getIdentifierInfo(Spelling); - - if (!II->isCPlusPlusOperatorKeyword()) - return Diag(MacroNameTok, diag::err_pp_macro_not_identifier); + if (!II) + return Diag(MacroNameTok, diag::err_pp_macro_not_identifier); + if (II->isCPlusPlusOperatorKeyword()) { // C++ 2.5p2: Alternative tokens behave the same as its primary token // except for their spellings. Diag(MacroNameTok, getLangOpts().MicrosoftExt ? diag::ext_pp_operator_used_as_macro_name : diag::err_pp_operator_used_as_macro_name) << II << MacroNameTok.getKind(); - // Allow #defining |and| and friends for Microsoft compatibility or // recovery when legacy C headers are included in C++. - MacroNameTok.setIdentifierInfo(II); } if ((isDefineUndef != MU_Other) && II->getPPKeywordID() == tok::pp_defined) { @@ -560,7 +530,7 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc, assert(CurPPLexer->LexingRawMode && "We have to be skipping here!"); CurPPLexer->LexingRawMode = false; IdentifierInfo *IfNDefMacro = nullptr; - const bool CondValue = EvaluateDirectiveExpression(IfNDefMacro); + const bool CondValue = EvaluateDirectiveExpression(IfNDefMacro).Conditional; CurPPLexer->LexingRawMode = true; if (Callbacks) { const SourceLocation CondEnd = CurPPLexer->getSourceLocation(); @@ -657,7 +627,7 @@ void Preprocessor::PTHSkipExcludedConditionalBlock() { // Evaluate the condition of the #elif. IdentifierInfo *IfNDefMacro = nullptr; CurPTHLexer->ParsingPreprocessorDirective = true; - bool ShouldEnter = EvaluateDirectiveExpression(IfNDefMacro); + bool ShouldEnter = EvaluateDirectiveExpression(IfNDefMacro).Conditional; CurPTHLexer->ParsingPreprocessorDirective = false; // If this condition is true, enter it! @@ -690,24 +660,17 @@ Module *Preprocessor::getModuleForLocation(SourceLocation Loc) { : HeaderInfo.lookupModule(getLangOpts().CurrentModule); } -Module *Preprocessor::getModuleContainingLocation(SourceLocation Loc) { - return HeaderInfo.getModuleMap().inferModuleFromLocation( - FullSourceLoc(Loc, SourceMgr)); -} - const FileEntry * Preprocessor::getModuleHeaderToIncludeForDiagnostics(SourceLocation IncLoc, + Module *M, SourceLocation Loc) { + assert(M && "no module to include"); + // If we have a module import syntax, we shouldn't include a header to // make a particular module visible. if (getLangOpts().ObjC2) return nullptr; - // Figure out which module we'd want to import. - Module *M = getModuleContainingLocation(Loc); - if (!M) - return nullptr; - Module *TopM = M->getTopLevelModule(); Module *IncM = getModuleForLocation(IncLoc); @@ -719,6 +682,8 @@ Preprocessor::getModuleHeaderToIncludeForDiagnostics(SourceLocation IncLoc, while (!Loc.isInvalid() && !SM.isInMainFile(Loc)) { auto ID = SM.getFileID(SM.getExpansionLoc(Loc)); auto *FE = SM.getFileEntryForID(ID); + if (!FE) + break; bool InTextualHeader = false; for (auto Header : HeaderInfo.getModuleMap().findAllModulesForHeader(FE)) { @@ -752,16 +717,11 @@ Preprocessor::getModuleHeaderToIncludeForDiagnostics(SourceLocation IncLoc, } const FileEntry *Preprocessor::LookupFile( - SourceLocation FilenameLoc, - StringRef Filename, - bool isAngled, - const DirectoryLookup *FromDir, - const FileEntry *FromFile, - const DirectoryLookup *&CurDir, - SmallVectorImpl<char> *SearchPath, + SourceLocation FilenameLoc, StringRef Filename, bool isAngled, + const DirectoryLookup *FromDir, const FileEntry *FromFile, + const DirectoryLookup *&CurDir, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, - ModuleMap::KnownHeader *SuggestedModule, - bool SkipCache) { + ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool SkipCache) { Module *RequestingModule = getModuleForLocation(FilenameLoc); bool RequestingModuleIsModuleInterface = !SourceMgr.isInMainFile(FilenameLoc); @@ -819,7 +779,7 @@ const FileEntry *Preprocessor::LookupFile( while (const FileEntry *FE = HeaderInfo.LookupFile( Filename, FilenameLoc, isAngled, TmpFromDir, TmpCurDir, Includers, SearchPath, RelativePath, RequestingModule, - SuggestedModule, SkipCache)) { + SuggestedModule, /*IsMapped=*/nullptr, SkipCache)) { // Keep looking as if this file did a #include_next. TmpFromDir = TmpCurDir; ++TmpFromDir; @@ -835,7 +795,7 @@ const FileEntry *Preprocessor::LookupFile( // Do a standard file entry lookup. const FileEntry *FE = HeaderInfo.LookupFile( Filename, FilenameLoc, isAngled, FromDir, CurDir, Includers, SearchPath, - RelativePath, RequestingModule, SuggestedModule, SkipCache, + RelativePath, RequestingModule, SuggestedModule, IsMapped, SkipCache, BuildSystemModule); if (FE) { if (SuggestedModule && !LangOpts.AsmPreprocessor) @@ -1206,18 +1166,26 @@ void Preprocessor::HandleLineDirective() { CheckEndOfDirective("line", true); } - SourceMgr.AddLineNote(DigitTok.getLocation(), LineNo, FilenameID); + // Take the file kind of the file containing the #line directive. #line + // directives are often used for generated sources from the same codebase, so + // the new file should generally be classified the same way as the current + // file. This is visible in GCC's pre-processed output, which rewrites #line + // to GNU line markers. + SrcMgr::CharacteristicKind FileKind = + SourceMgr.getFileCharacteristic(DigitTok.getLocation()); + + SourceMgr.AddLineNote(DigitTok.getLocation(), LineNo, FilenameID, false, + false, FileKind); if (Callbacks) Callbacks->FileChanged(CurPPLexer->getSourceLocation(), - PPCallbacks::RenameFile, - SrcMgr::C_User); + PPCallbacks::RenameFile, FileKind); } /// ReadLineMarkerFlags - Parse and validate any flags at the end of a GNU line /// marker directive. static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit, - bool &IsSystemHeader, bool &IsExternCHeader, + SrcMgr::CharacteristicKind &FileKind, Preprocessor &PP) { unsigned FlagVal; Token FlagTok; @@ -1268,7 +1236,7 @@ static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit, return true; } - IsSystemHeader = true; + FileKind = SrcMgr::C_System; PP.Lex(FlagTok); if (FlagTok.is(tok::eod)) return false; @@ -1282,7 +1250,7 @@ static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit, return true; } - IsExternCHeader = true; + FileKind = SrcMgr::C_ExternCSystem; PP.Lex(FlagTok); if (FlagTok.is(tok::eod)) return false; @@ -1312,14 +1280,15 @@ void Preprocessor::HandleDigitDirective(Token &DigitTok) { Lex(StrTok); bool IsFileEntry = false, IsFileExit = false; - bool IsSystemHeader = false, IsExternCHeader = false; int FilenameID = -1; + SrcMgr::CharacteristicKind FileKind = SrcMgr::C_User; // If the StrTok is "eod", then it wasn't present. Otherwise, it must be a // string followed by eod. - if (StrTok.is(tok::eod)) - ; // ok - else if (StrTok.isNot(tok::string_literal)) { + if (StrTok.is(tok::eod)) { + // Treat this like "#line NN", which doesn't change file characteristics. + FileKind = SourceMgr.getFileCharacteristic(DigitTok.getLocation()); + } else if (StrTok.isNot(tok::string_literal)) { Diag(StrTok, diag::err_pp_linemarker_invalid_filename); return DiscardUntilEndOfDirective(); } else if (StrTok.hasUDSuffix()) { @@ -1338,15 +1307,13 @@ void Preprocessor::HandleDigitDirective(Token &DigitTok) { FilenameID = SourceMgr.getLineTableFilenameID(Literal.GetString()); // If a filename was present, read any flags that are present. - if (ReadLineMarkerFlags(IsFileEntry, IsFileExit, - IsSystemHeader, IsExternCHeader, *this)) + if (ReadLineMarkerFlags(IsFileEntry, IsFileExit, FileKind, *this)) return; } // Create a line note with this information. - SourceMgr.AddLineNote(DigitTok.getLocation(), LineNo, FilenameID, - IsFileEntry, IsFileExit, - IsSystemHeader, IsExternCHeader); + SourceMgr.AddLineNote(DigitTok.getLocation(), LineNo, FilenameID, IsFileEntry, + IsFileExit, FileKind); // If the preprocessor has callbacks installed, notify them of the #line // change. This is used so that the line marker comes out in -E mode for @@ -1357,11 +1324,6 @@ void Preprocessor::HandleDigitDirective(Token &DigitTok) { Reason = PPCallbacks::EnterFile; else if (IsFileExit) Reason = PPCallbacks::ExitFile; - SrcMgr::CharacteristicKind FileKind = SrcMgr::C_User; - if (IsExternCHeader) - FileKind = SrcMgr::C_ExternCSystem; - else if (IsSystemHeader) - FileKind = SrcMgr::C_System; Callbacks->FileChanged(CurPPLexer->getSourceLocation(), Reason, FileKind); } @@ -1593,18 +1555,18 @@ bool Preprocessor::ConcatenateIncludeName(SmallString<128> &FilenameBuffer, } /// \brief Push a token onto the token stream containing an annotation. -static void EnterAnnotationToken(Preprocessor &PP, - SourceLocation Begin, SourceLocation End, - tok::TokenKind Kind, void *AnnotationVal) { +void Preprocessor::EnterAnnotationToken(SourceRange Range, + tok::TokenKind Kind, + void *AnnotationVal) { // FIXME: Produce this as the current token directly, rather than // allocating a new token for it. auto Tok = llvm::make_unique<Token[]>(1); Tok[0].startToken(); Tok[0].setKind(Kind); - Tok[0].setLocation(Begin); - Tok[0].setAnnotationEndLoc(End); + Tok[0].setLocation(Range.getBegin()); + Tok[0].setAnnotationEndLoc(Range.getEnd()); Tok[0].setAnnotationValue(AnnotationVal); - PP.EnterTokenStream(std::move(Tok), 1, true); + EnterTokenStream(std::move(Tok), 1, true); } /// \brief Produce a diagnostic informing the user that a #include or similar @@ -1685,6 +1647,26 @@ static bool trySimplifyPath(SmallVectorImpl<StringRef> &Components, return SuggestReplacement; } +bool Preprocessor::checkModuleIsAvailable(const LangOptions &LangOpts, + const TargetInfo &TargetInfo, + DiagnosticsEngine &Diags, Module *M) { + Module::Requirement Requirement; + Module::UnresolvedHeaderDirective MissingHeader; + if (M->isAvailable(LangOpts, TargetInfo, Requirement, MissingHeader)) + return false; + + if (MissingHeader.FileNameLoc.isValid()) { + Diags.Report(MissingHeader.FileNameLoc, diag::err_module_header_missing) + << MissingHeader.IsUmbrella << MissingHeader.FileName; + } else { + // FIXME: Track the location at which the requirement was specified, and + // use it here. + Diags.Report(M->DefinitionLoc, diag::err_module_unavailable) + << M->getFullModuleName() << Requirement.second << Requirement.first; + } + return true; +} + /// 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 @@ -1783,6 +1765,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, } // Search include directories. + bool IsMapped = false; const DirectoryLookup *CurDir; SmallString<1024> SearchPath; SmallString<1024> RelativePath; @@ -1801,7 +1784,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, FilenameLoc, LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, isAngled, LookupFrom, LookupFromFile, CurDir, Callbacks ? &SearchPath : nullptr, Callbacks ? &RelativePath : nullptr, - &SuggestedModule); + &SuggestedModule, &IsMapped); if (!File) { if (Callbacks) { @@ -1818,7 +1801,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, FilenameLoc, LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, isAngled, LookupFrom, LookupFromFile, CurDir, nullptr, nullptr, - &SuggestedModule, /*SkipCache*/ true); + &SuggestedModule, &IsMapped, /*SkipCache*/ true); } } } @@ -1833,8 +1816,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, false, LookupFrom, LookupFromFile, CurDir, Callbacks ? &SearchPath : nullptr, - Callbacks ? &RelativePath : nullptr, - &SuggestedModule); + Callbacks ? &RelativePath : nullptr, &SuggestedModule, &IsMapped); if (File) { SourceRange Range(FilenameTok.getLocation(), CharEnd); Diag(FilenameTok, diag::err_pp_file_not_found_not_fatal) << @@ -1856,33 +1838,24 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, // we've imported or already built. bool ShouldEnter = true; + if (PPOpts->SingleFileParseMode) + ShouldEnter = false; + // 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 && + if (ShouldEnter && File && SuggestedModule && getLangOpts().Modules && SuggestedModule.getModule()->getTopLevelModuleName() != getLangOpts().CurrentModule) { // If this include corresponds to a module but that module is // unavailable, diagnose the situation and bail out. // FIXME: Remove this; loadModule does the same check (but produces // slightly worse diagnostics). - if (!SuggestedModule.getModule()->isAvailable()) { - Module::Requirement Requirement; - Module::UnresolvedHeaderDirective MissingHeader; - Module *M = SuggestedModule.getModule(); - // Identify the cause. - (void)M->isAvailable(getLangOpts(), getTargetInfo(), Requirement, - MissingHeader); - if (MissingHeader.FileNameLoc.isValid()) { - Diag(MissingHeader.FileNameLoc, diag::err_module_header_missing) - << MissingHeader.IsUmbrella << MissingHeader.FileName; - } else { - Diag(M->DefinitionLoc, diag::err_module_unavailable) - << M->getFullModuleName() << Requirement.second << Requirement.first; - } + if (checkModuleIsAvailable(getLangOpts(), getTargetInfo(), getDiagnostics(), + SuggestedModule.getModule())) { Diag(FilenameTok.getLocation(), diag::note_implicit_top_level_module_import_here) - << M->getTopLevelModuleName(); + << SuggestedModule.getModule()->getTopLevelModuleName(); return; } @@ -1939,6 +1912,25 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, } } + // 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 + // header. + SrcMgr::CharacteristicKind FileCharacter = + SourceMgr.getFileCharacteristic(FilenameTok.getLocation()); + if (File) + FileCharacter = std::max(HeaderInfo.getFileDirFlavor(File), FileCharacter); + + // Ask HeaderInfo if we should enter this #include file. If not, #including + // this file will have no effect. + bool SkipHeader = false; + if (ShouldEnter && File && + !HeaderInfo.ShouldEnterIncludeFile(*this, File, isImport, + getLangOpts().Modules, + SuggestedModule.getModule())) { + ShouldEnter = false; + SkipHeader = true; + } + if (Callbacks) { // Notify the callback object that we've seen an inclusion directive. Callbacks->InclusionDirective( @@ -1946,25 +1938,20 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, isAngled, FilenameRange, File, SearchPath, RelativePath, ShouldEnter ? nullptr : SuggestedModule.getModule()); + if (SkipHeader && !SuggestedModule.getModule()) + Callbacks->FileSkipped(*File, FilenameTok, FileCharacter); } 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 - // header. - SrcMgr::CharacteristicKind FileCharacter = - 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. // Issue a diagnostic if the name of the file on disk has a different case // than the one we're about to open. const bool CheckIncludePathPortability = - File && !File->tryGetRealPathName().empty(); + !IsMapped && File && !File->tryGetRealPathName().empty(); if (CheckIncludePathPortability) { StringRef Name = LangOpts.MSVCCompat ? NormalizedPath.str() : Filename; @@ -1976,37 +1963,27 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, SmallString<128> Path; Path.reserve(Name.size()+2); Path.push_back(isAngled ? '<' : '"'); + bool isLeadingSeparator = llvm::sys::path::is_absolute(Name); for (auto Component : Components) { - Path.append(Component); + if (isLeadingSeparator) + isLeadingSeparator = false; + else + Path.append(Component); // Append the separator the user used, or the close quote Path.push_back( Path.size() <= Filename.size() ? Filename[Path.size()-1] : (isAngled ? '>' : '"')); } - auto Replacement = Path.str().str(); // For user files and known standard headers, by default we issue a diagnostic. // For other system headers, we don't. They can be controlled separately. auto DiagId = (FileCharacter == SrcMgr::C_User || warnByDefaultOnWrongCase(Name)) ? diag::pp_nonportable_path : diag::pp_nonportable_system_path; SourceRange Range(FilenameTok.getLocation(), CharEnd); - Diag(FilenameTok, DiagId) << Replacement << - FixItHint::CreateReplacement(Range, Replacement); + Diag(FilenameTok, DiagId) << Path << + FixItHint::CreateReplacement(Range, Path); } } - // Ask HeaderInfo if we should enter this #include file. If not, #including - // this file will have no effect. - bool SkipHeader = false; - if (ShouldEnter && - !HeaderInfo.ShouldEnterIncludeFile(*this, File, isImport, - getLangOpts().Modules, - SuggestedModule.getModule())) { - ShouldEnter = false; - SkipHeader = true; - 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. @@ -2023,7 +2000,8 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, if (IncludeTok.getIdentifierInfo()->getPPKeywordID() != tok::pp___include_macros) - EnterAnnotationToken(*this, HashLoc, End, tok::annot_module_include, M); + EnterAnnotationToken(SourceRange(HashLoc, End), + tok::annot_module_include, M); } return; } @@ -2050,18 +2028,18 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, M->getTopLevelModuleName() == getLangOpts().CurrentModule) return; - assert(!CurSubmodule && "should not have marked this as a module yet"); - CurSubmodule = M; + assert(!CurLexerSubmodule && "should not have marked this as a module yet"); + CurLexerSubmodule = M; // Let the macro handling code know that any future macros are within // the new submodule. - EnterSubmodule(M, HashLoc); + EnterSubmodule(M, HashLoc, /*ForPragma*/false); // 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); + EnterAnnotationToken(SourceRange(HashLoc, End), tok::annot_module_begin, M); } } @@ -2083,7 +2061,7 @@ void Preprocessor::HandleIncludeNextDirective(SourceLocation HashLoc, } else if (isInPrimaryFile()) { Lookup = nullptr; Diag(IncludeNextTok, diag::pp_include_next_in_primary); - } else if (CurSubmodule) { + } else if (CurLexerSubmodule) { // Start looking up in the directory *after* the one in which the current // file would be found, if any. assert(CurPPLexer && "#include_next directive in macro?"); @@ -2157,11 +2135,11 @@ void Preprocessor::HandleIncludeMacrosDirective(SourceLocation HashLoc, // Preprocessor Macro Directive Handling. //===----------------------------------------------------------------------===// -/// ReadMacroDefinitionArgList - The ( starting an argument list of a macro +/// ReadMacroParameterList - The ( starting an argument list of a macro /// definition has just been read. Lex the rest of the arguments and the /// closing ), updating MI with what we learn. Return true if an error occurs /// parsing the arg list. -bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI, Token &Tok) { +bool Preprocessor::ReadMacroParameterList(MacroInfo *MI, Token &Tok) { SmallVector<IdentifierInfo*, 32> Arguments; while (true) { @@ -2195,7 +2173,7 @@ bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI, Token &Tok) { // Add the __VA_ARGS__ identifier as an argument. Arguments.push_back(Ident__VA_ARGS__); MI->setIsC99Varargs(); - MI->setArgumentList(Arguments, BP); + MI->setParameterList(Arguments, BP); return false; case tok::eod: // #define X( Diag(Tok, diag::err_pp_missing_rparen_in_macro_def); @@ -2229,7 +2207,7 @@ bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI, Token &Tok) { Diag(Tok, diag::err_pp_expected_comma_in_arg_list); return true; case tok::r_paren: // #define X(A) - MI->setArgumentList(Arguments, BP); + MI->setParameterList(Arguments, BP); return false; case tok::comma: // #define X(A, break; @@ -2245,7 +2223,7 @@ bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI, Token &Tok) { } MI->setIsGNUVarargs(); - MI->setArgumentList(Arguments, BP); + MI->setParameterList(Arguments, BP); return false; } } @@ -2294,28 +2272,20 @@ static bool isConfigurationPattern(Token &MacroName, MacroInfo *MI, MI->getNumTokens() == 0; } -/// HandleDefineDirective - Implements \#define. This consumes the entire macro -/// line then lets the caller lex the next real token. -void Preprocessor::HandleDefineDirective(Token &DefineTok, - bool ImmediatelyAfterHeaderGuard) { - ++NumDefined; - - Token MacroNameTok; - bool MacroShadowsKeyword; - ReadMacroName(MacroNameTok, MU_Define, &MacroShadowsKeyword); +// ReadOptionalMacroParameterListAndBody - This consumes all (i.e. the +// entire line) of the macro's tokens and adds them to MacroInfo, and while +// doing so performs certain validity checks including (but not limited to): +// - # (stringization) is followed by a macro parameter +// +// Returns a nullptr if an invalid sequence of tokens is encountered or returns +// a pointer to a MacroInfo object. - // Error reading macro name? If so, diagnostic already issued. - if (MacroNameTok.is(tok::eod)) - return; +MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody( + const Token &MacroNameTok, const bool ImmediatelyAfterHeaderGuard) { Token LastTok = MacroNameTok; - - // If we are supposed to keep comments in #defines, reenable comment saving - // mode. - if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments); - // Create the new macro. - MacroInfo *MI = AllocateMacroInfo(MacroNameTok.getLocation()); + MacroInfo *const MI = AllocateMacroInfo(MacroNameTok.getLocation()); Token Tok; LexUnexpandedToken(Tok); @@ -2337,11 +2307,11 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok, } else if (Tok.is(tok::l_paren)) { // This is a function-like macro definition. Read the argument list. MI->setIsFunctionLike(); - if (ReadMacroDefinitionArgList(MI, LastTok)) { + if (ReadMacroParameterList(MI, LastTok)) { // Throw away the rest of the line. if (CurPPLexer->ParsingPreprocessorDirective) DiscardUntilEndOfDirective(); - return; + return nullptr; } // If this is a definition of a variadic C99 function-like macro, not using @@ -2448,7 +2418,7 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok, // Check for a valid macro arg identifier. if (Tok.getIdentifierInfo() == nullptr || - MI->getArgumentNum(Tok.getIdentifierInfo()) == -1) { + MI->getParameterNum(Tok.getIdentifierInfo()) == -1) { // If this is assembler-with-cpp mode, we accept random gibberish after // the '#' because '#' is often a comment character. However, change @@ -2464,7 +2434,7 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok, // Disable __VA_ARGS__ again. Ident__VA_ARGS__->setIsPoisoned(true); - return; + return nullptr; } } @@ -2477,15 +2447,39 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok, LexUnexpandedToken(Tok); } } + MI->setDefinitionEndLoc(LastTok.getLocation()); + // Disable __VA_ARGS__ again. + Ident__VA_ARGS__->setIsPoisoned(true); + + return MI; +} +/// HandleDefineDirective - Implements \#define. This consumes the entire macro +/// line then lets the caller lex the next real token. +void Preprocessor::HandleDefineDirective( + Token &DefineTok, const bool ImmediatelyAfterHeaderGuard) { + ++NumDefined; + + Token MacroNameTok; + bool MacroShadowsKeyword; + ReadMacroName(MacroNameTok, MU_Define, &MacroShadowsKeyword); + + // Error reading macro name? If so, diagnostic already issued. + if (MacroNameTok.is(tok::eod)) + return; + + // If we are supposed to keep comments in #defines, reenable comment saving + // mode. + if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments); + + MacroInfo *const MI = ReadOptionalMacroParameterListAndBody( + MacroNameTok, ImmediatelyAfterHeaderGuard); + + if (!MI) return; if (MacroShadowsKeyword && !isConfigurationPattern(MacroNameTok, MI, getLangOpts())) { Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword); - } - - // Disable __VA_ARGS__ again. - Ident__VA_ARGS__->setIsPoisoned(true); - + } // Check that there is no paste (##) operator at the beginning or end of the // replacement list. unsigned NumTokens = MI->getNumTokens(); @@ -2500,7 +2494,7 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok, } } - MI->setDefinitionEndLoc(LastTok.getLocation()); + // Finally, if this identifier already had a macro defined for it, verify that // the macro bodies are identical, and issue diagnostics if they are not. @@ -2589,25 +2583,26 @@ void Preprocessor::HandleUndefDirective() { // Okay, we have a valid identifier to undef. auto *II = MacroNameTok.getIdentifierInfo(); auto MD = getMacroDefinition(II); + UndefMacroDirective *Undef = nullptr; + + // If the macro is not defined, this is a noop undef. + if (const MacroInfo *MI = MD.getMacroInfo()) { + if (!MI->isUsed() && MI->isWarnIfUnused()) + Diag(MI->getDefinitionLoc(), diag::pp_macro_not_used); + + if (MI->isWarnIfUnused()) + WarnUnusedMacroLocs.erase(MI->getDefinitionLoc()); + + Undef = AllocateUndefMacroDirective(MacroNameTok.getLocation()); + } // If the callbacks want to know, tell them about the macro #undef. // Note: no matter if the macro was defined or not. if (Callbacks) - 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; + Callbacks->MacroUndefined(MacroNameTok, MD, Undef); - if (!MI->isUsed() && MI->isWarnIfUnused()) - Diag(MI->getDefinitionLoc(), diag::pp_macro_not_used); - - if (MI->isWarnIfUnused()) - WarnUnusedMacroLocs.erase(MI->getDefinitionLoc()); - - appendMacroDirective(MacroNameTok.getIdentifierInfo(), - AllocateUndefMacroDirective(MacroNameTok.getLocation())); + if (Undef) + appendMacroDirective(II, Undef); } //===----------------------------------------------------------------------===// @@ -2667,7 +2662,13 @@ void Preprocessor::HandleIfdefDirective(Token &Result, bool isIfndef, } // Should we include the stuff contained by this directive? - if (!MI == isIfndef) { + if (PPOpts->SingleFileParseMode && !MI) { + // In 'single-file-parse mode' undefined identifiers trigger parsing of all + // the directive blocks. + CurPPLexer->pushConditionalLevel(DirectiveTok.getLocation(), + /*wasskip*/false, /*foundnonskip*/false, + /*foundelse*/false); + } else if (!MI == isIfndef) { // Yes, remember that we are inside a conditional, then lex the next token. CurPPLexer->pushConditionalLevel(DirectiveTok.getLocation(), /*wasskip*/false, /*foundnonskip*/true, @@ -2689,7 +2690,8 @@ void Preprocessor::HandleIfDirective(Token &IfToken, // Parse and evaluate the conditional expression. IdentifierInfo *IfNDefMacro = nullptr; const SourceLocation ConditionalBegin = CurPPLexer->getSourceLocation(); - const bool ConditionalTrue = EvaluateDirectiveExpression(IfNDefMacro); + const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro); + const bool ConditionalTrue = DER.Conditional; const SourceLocation ConditionalEnd = CurPPLexer->getSourceLocation(); // If this condition is equivalent to #ifndef X, and if this is the first @@ -2708,7 +2710,12 @@ void Preprocessor::HandleIfDirective(Token &IfToken, (ConditionalTrue ? PPCallbacks::CVK_True : PPCallbacks::CVK_False)); // Should we include the stuff contained by this directive? - if (ConditionalTrue) { + if (PPOpts->SingleFileParseMode && DER.IncludedUndefinedIds) { + // In 'single-file-parse mode' undefined identifiers trigger parsing of all + // the directive blocks. + CurPPLexer->pushConditionalLevel(IfToken.getLocation(), /*wasskip*/false, + /*foundnonskip*/false, /*foundelse*/false); + } else if (ConditionalTrue) { // Yes, remember that we are inside a conditional, then lex the next token. CurPPLexer->pushConditionalLevel(IfToken.getLocation(), /*wasskip*/false, /*foundnonskip*/true, /*foundelse*/false); @@ -2769,6 +2776,14 @@ void Preprocessor::HandleElseDirective(Token &Result) { if (Callbacks) Callbacks->Else(Result.getLocation(), CI.IfLoc); + if (PPOpts->SingleFileParseMode && !CI.FoundNonSkip) { + // In 'single-file-parse mode' undefined identifiers trigger parsing of all + // the directive blocks. + CurPPLexer->pushConditionalLevel(CI.IfLoc, /*wasskip*/false, + /*foundnonskip*/false, /*foundelse*/true); + return; + } + // Finally, skip the rest of the contents of this block. SkipExcludedConditionalBlock(CI.IfLoc, /*Foundnonskip*/true, /*FoundElse*/true, Result.getLocation()); @@ -2804,6 +2819,14 @@ void Preprocessor::HandleElifDirective(Token &ElifToken) { SourceRange(ConditionalBegin, ConditionalEnd), PPCallbacks::CVK_NotEvaluated, CI.IfLoc); + if (PPOpts->SingleFileParseMode && !CI.FoundNonSkip) { + // In 'single-file-parse mode' undefined identifiers trigger parsing of all + // the directive blocks. + CurPPLexer->pushConditionalLevel(ElifToken.getLocation(), /*wasskip*/false, + /*foundnonskip*/false, /*foundelse*/false); + return; + } + // Finally, skip the rest of the contents of this block. SkipExcludedConditionalBlock(CI.IfLoc, /*Foundnonskip*/true, /*FoundElse*/CI.FoundElse, diff --git a/contrib/llvm/tools/clang/lib/Lex/PPExpressions.cpp b/contrib/llvm/tools/clang/lib/Lex/PPExpressions.cpp index 862a471..d843182 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PPExpressions.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/PPExpressions.cpp @@ -73,6 +73,7 @@ public: static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, Token &PeekTok, bool ValueLive, + bool &IncludedUndefinedIds, Preprocessor &PP); /// DefinedTracker - This struct is used while parsing expressions to keep track @@ -93,6 +94,7 @@ struct DefinedTracker { /// TheMacro - When the state is DefinedMacro or NotDefinedMacro, this /// indicates the macro that was checked. IdentifierInfo *TheMacro; + bool IncludedUndefinedIds = false; }; /// EvaluateDefined - Process a 'defined(sym)' expression. @@ -128,6 +130,7 @@ static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT, MacroDefinition Macro = PP.getMacroDefinition(II); Result.Val = !!Macro; Result.Val.setIsUnsigned(false); // Result is signed intmax_t. + DT.IncludedUndefinedIds = !Macro; // If there is a macro, mark it used. if (Result.Val != 0 && ValueLive) @@ -234,33 +237,32 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, PP.setCodeCompletionReached(); PP.LexNonComment(PeekTok); } - - // If this token's spelling is a pp-identifier, check to see if it is - // 'defined' or if it is a macro. Note that we check here because many - // keywords are pp-identifiers, so we can't check the kind. - if (IdentifierInfo *II = PeekTok.getIdentifierInfo()) { - // Handle "defined X" and "defined(X)". - if (II->isStr("defined")) - return EvaluateDefined(Result, PeekTok, DT, ValueLive, PP); - - // If this identifier isn't 'defined' or one of the special - // preprocessor keywords and it wasn't macro expanded, it turns - // into a simple 0, unless it is the C++ keyword "true", in which case it - // turns into "1". - if (ValueLive && - II->getTokenID() != tok::kw_true && - II->getTokenID() != tok::kw_false) - PP.Diag(PeekTok, diag::warn_pp_undef_identifier) << II; - Result.Val = II->getTokenID() == tok::kw_true; - Result.Val.setIsUnsigned(false); // "0" is signed intmax_t 0. - Result.setIdentifier(II); - Result.setRange(PeekTok.getLocation()); - PP.LexNonComment(PeekTok); - return false; - } switch (PeekTok.getKind()) { - default: // Non-value token. + default: + // If this token's spelling is a pp-identifier, check to see if it is + // 'defined' or if it is a macro. Note that we check here because many + // keywords are pp-identifiers, so we can't check the kind. + if (IdentifierInfo *II = PeekTok.getIdentifierInfo()) { + // Handle "defined X" and "defined(X)". + if (II->isStr("defined")) + return EvaluateDefined(Result, PeekTok, DT, ValueLive, PP); + + if (!II->isCPlusPlusOperatorKeyword()) { + // If this identifier isn't 'defined' or one of the special + // preprocessor keywords and it wasn't macro expanded, it turns + // into a simple 0 + if (ValueLive) + PP.Diag(PeekTok, diag::warn_pp_undef_identifier) << II; + Result.Val = 0; + Result.Val.setIsUnsigned(false); // "0" is signed intmax_t 0. + Result.setIdentifier(II); + Result.setRange(PeekTok.getLocation()); + DT.IncludedUndefinedIds = true; + PP.LexNonComment(PeekTok); + return false; + } + } PP.Diag(PeekTok, diag::err_pp_expr_bad_token_start_expr); return true; case tok::eod: @@ -400,7 +402,8 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, // Just use DT unmodified as our result. } else { // Otherwise, we have something like (x+y), and we consumed '(x'. - if (EvaluateDirectiveSubExpr(Result, 1, PeekTok, ValueLive, PP)) + if (EvaluateDirectiveSubExpr(Result, 1, PeekTok, ValueLive, + DT.IncludedUndefinedIds, PP)) return true; if (PeekTok.isNot(tok::r_paren)) { @@ -475,6 +478,14 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, DT.State = DefinedTracker::DefinedMacro; return false; } + case tok::kw_true: + case tok::kw_false: + Result.Val = PeekTok.getKind() == tok::kw_true; + Result.Val.setIsUnsigned(false); // "0" is signed intmax_t 0. + Result.setIdentifier(PeekTok.getIdentifierInfo()); + Result.setRange(PeekTok.getLocation()); + PP.LexNonComment(PeekTok); + return false; // FIXME: Handle #assert } @@ -532,6 +543,7 @@ static void diagnoseUnexpectedOperator(Preprocessor &PP, PPValue &LHS, /// evaluation, such as division by zero warnings. static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, Token &PeekTok, bool ValueLive, + bool &IncludedUndefinedIds, Preprocessor &PP) { unsigned PeekPrec = getPrecedence(PeekTok.getKind()); // If this token isn't valid, report the error. @@ -571,6 +583,7 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, // Parse the RHS of the operator. DefinedTracker DT; if (EvaluateValue(RHS, PeekTok, DT, RHSIsLive, PP)) return true; + IncludedUndefinedIds = DT.IncludedUndefinedIds; // Remember the precedence of this operator and get the precedence of the // operator immediately to the right of the RHS. @@ -601,7 +614,8 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, RHSPrec = ThisPrec+1; if (PeekPrec >= RHSPrec) { - if (EvaluateDirectiveSubExpr(RHS, RHSPrec, PeekTok, RHSIsLive, PP)) + if (EvaluateDirectiveSubExpr(RHS, RHSPrec, PeekTok, RHSIsLive, + IncludedUndefinedIds, PP)) return true; PeekPrec = getPrecedence(PeekTok.getKind()); } @@ -769,7 +783,8 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, // Parse anything after the : with the same precedence as ?. We allow // things of equal precedence because ?: is right associative. if (EvaluateDirectiveSubExpr(AfterColonVal, ThisPrec, - PeekTok, AfterColonLive, PP)) + PeekTok, AfterColonLive, + IncludedUndefinedIds, PP)) return true; // Now that we have the condition, the LHS and the RHS of the :, evaluate. @@ -806,7 +821,8 @@ 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) { +Preprocessor::DirectiveEvalResult +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 @@ -833,7 +849,7 @@ bool Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) { // Restore 'DisableMacroExpansion'. DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective; - return false; + return {false, DT.IncludedUndefinedIds}; } // If we are at the end of the expression after just parsing a value, there @@ -847,20 +863,20 @@ bool Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) { // Restore 'DisableMacroExpansion'. DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective; - return ResVal.Val != 0; + return {ResVal.Val != 0, DT.IncludedUndefinedIds}; } // Otherwise, we must have a binary operator (e.g. "#if 1 < 2"), so parse the // operator and the stuff after it. if (EvaluateDirectiveSubExpr(ResVal, getPrecedence(tok::question), - Tok, true, *this)) { + Tok, true, DT.IncludedUndefinedIds, *this)) { // Parse error, skip the rest of the macro line. if (Tok.isNot(tok::eod)) DiscardUntilEndOfDirective(); // Restore 'DisableMacroExpansion'. DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective; - return false; + return {false, DT.IncludedUndefinedIds}; } // If we aren't at the tok::eod token, something bad happened, like an extra @@ -872,5 +888,5 @@ bool Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) { // Restore 'DisableMacroExpansion'. DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective; - return ResVal.Val != 0; + return {ResVal.Val != 0, DT.IncludedUndefinedIds}; } diff --git a/contrib/llvm/tools/clang/lib/Lex/PPLexerChange.cpp b/contrib/llvm/tools/clang/lib/Lex/PPLexerChange.cpp index 4db17c3..36d7028 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PPLexerChange.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/PPLexerChange.cpp @@ -117,7 +117,7 @@ void Preprocessor::EnterSourceFileWithLexer(Lexer *TheLexer, CurLexer.reset(TheLexer); CurPPLexer = TheLexer; CurDirLookup = CurDir; - CurSubmodule = nullptr; + CurLexerSubmodule = nullptr; if (CurLexerKind != CLK_LexAfterModuleImport) CurLexerKind = CLK_Lexer; @@ -142,7 +142,7 @@ void Preprocessor::EnterSourceFileWithPTH(PTHLexer *PL, CurDirLookup = CurDir; CurPTHLexer.reset(PL); CurPPLexer = CurPTHLexer.get(); - CurSubmodule = nullptr; + CurLexerSubmodule = nullptr; if (CurLexerKind != CLK_LexAfterModuleImport) CurLexerKind = CLK_PTHLexer; @@ -287,6 +287,48 @@ const char *Preprocessor::getCurLexerEndPos() { return EndPos; } +static void collectAllSubModulesWithUmbrellaHeader( + const Module &Mod, SmallVectorImpl<const Module *> &SubMods) { + if (Mod.getUmbrellaHeader()) + SubMods.push_back(&Mod); + for (auto *M : Mod.submodules()) + collectAllSubModulesWithUmbrellaHeader(*M, SubMods); +} + +void Preprocessor::diagnoseMissingHeaderInUmbrellaDir(const Module &Mod) { + assert(Mod.getUmbrellaHeader() && "Module must use umbrella header"); + SourceLocation StartLoc = + SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()); + if (getDiagnostics().isIgnored(diag::warn_uncovered_module_header, StartLoc)) + return; + + ModuleMap &ModMap = getHeaderSearchInfo().getModuleMap(); + 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; + Entry != End && !EC; Entry.increment(EC)) { + using llvm::StringSwitch; + + // Check whether this entry has an extension typically associated with + // headers. + if (!StringSwitch<bool>(llvm::sys::path::extension(Entry->getName())) + .Cases(".h", ".H", ".hh", ".hpp", true) + .Default(false)) + continue; + + if (const FileEntry *Header = getFileManager().getFile(Entry->getName())) + if (!getSourceManager().hasFileInfo(Header)) { + if (!ModMap.isHeaderInUnavailableModule(Header)) { + // Find the relative path that would access this header. + SmallString<128> RelativePath; + computeRelativePath(FileMgr, Dir, Header, RelativePath); + Diag(StartLoc, diag::warn_uncovered_module_header) + << Mod.getFullModuleName() << RelativePath; + } + } + } +} /// HandleEndOfFile - This callback is invoked when the lexer hits the end of /// the current file. This either returns the EOF token or pops a level off @@ -295,6 +337,26 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { assert(!CurTokenLexer && "Ending a file when currently in a macro!"); + // If we have an unclosed module region from a pragma at the end of a + // module, complain and close it now. + // FIXME: This is not correct if we are building a module from PTH. + const bool LeavingSubmodule = CurLexer && CurLexerSubmodule; + if ((LeavingSubmodule || IncludeMacroStack.empty()) && + !BuildingSubmoduleStack.empty() && + BuildingSubmoduleStack.back().IsPragma) { + Diag(BuildingSubmoduleStack.back().ImportLoc, + diag::err_pp_module_begin_without_module_end); + Module *M = LeaveSubmodule(/*ForPragma*/true); + + Result.startToken(); + const char *EndPos = getCurLexerEndPos(); + CurLexer->BufferPtr = EndPos; + CurLexer->FormTokenWithChars(Result, EndPos, tok::annot_module_end); + Result.setAnnotationEndLoc(Result.getLocation()); + Result.setAnnotationValue(M); + return true; + } + // See if this file had a controlling macro. if (CurPPLexer) { // Not ending a macro, ignore it. if (const IdentifierInfo *ControllingMacro = @@ -303,9 +365,8 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { if (const FileEntry *FE = CurPPLexer->getFileEntry()) { HeaderInfo.SetFileControllingMacro(FE, ControllingMacro); if (MacroInfo *MI = - getMacroInfo(const_cast<IdentifierInfo*>(ControllingMacro))) { - MI->UsedForHeaderGuard = true; - } + getMacroInfo(const_cast<IdentifierInfo*>(ControllingMacro))) + MI->setUsedForHeaderGuard(true); if (const IdentifierInfo *DefinedMacro = CurPPLexer->MIOpt.GetDefinedMacro()) { if (!isMacroDefined(ControllingMacro) && @@ -397,22 +458,27 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { SourceMgr.setNumCreatedFIDsForFileID(CurPPLexer->getFileID(), NumFIDs); } + bool ExitedFromPredefinesFile = false; FileID ExitedFID; - if (Callbacks && !isEndOfMacro && CurPPLexer) + if (!isEndOfMacro && CurPPLexer) { ExitedFID = CurPPLexer->getFileID(); - bool LeavingSubmodule = CurSubmodule && CurLexer; + assert(PredefinesFileID.isValid() && + "HandleEndOfFile is called before PredefinesFileId is set"); + ExitedFromPredefinesFile = (PredefinesFileID == ExitedFID); + } + if (LeavingSubmodule) { + // We're done with this submodule. + Module *M = LeaveSubmodule(/*ForPragma*/false); + // Notify the parser that we've left the module. const char *EndPos = getCurLexerEndPos(); Result.startToken(); CurLexer->BufferPtr = EndPos; CurLexer->FormTokenWithChars(Result, EndPos, tok::annot_module_end); Result.setAnnotationEndLoc(Result.getLocation()); - Result.setAnnotationValue(CurSubmodule); - - // We're done with this submodule. - LeaveSubmodule(); + Result.setAnnotationValue(M); } // We're done with the #included file. @@ -429,6 +495,11 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { PPCallbacks::ExitFile, FileType, ExitedFID); } + // Restore conditional stack from the preamble right after exiting from the + // predefines file. + if (ExitedFromPredefinesFile) + replayPreambleConditionalStack(); + // Client should lex another token unless we generated an EOM. return LeavingSubmodule; } @@ -474,44 +545,14 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { } // If we are building a module that has an umbrella header, make sure that - // each of the headers within the directory covered by the umbrella header - // was actually included by the umbrella header. + // each of the headers within the directory, including all submodules, is + // covered by the umbrella header was actually included by the umbrella + // header. if (Module *Mod = getCurrentModule()) { - if (Mod->getUmbrellaHeader()) { - SourceLocation StartLoc - = SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()); - - if (!getDiagnostics().isIgnored(diag::warn_uncovered_module_header, - StartLoc)) { - ModuleMap &ModMap = getHeaderSearchInfo().getModuleMap(); - const DirectoryEntry *Dir = Mod->getUmbrellaDir().Entry; - vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem(); - std::error_code EC; - for (vfs::recursive_directory_iterator Entry(FS, Dir->getName(), EC), End; - Entry != End && !EC; Entry.increment(EC)) { - using llvm::StringSwitch; - - // Check whether this entry has an extension typically associated with - // headers. - if (!StringSwitch<bool>(llvm::sys::path::extension(Entry->getName())) - .Cases(".h", ".H", ".hh", ".hpp", true) - .Default(false)) - continue; - - if (const FileEntry *Header = - getFileManager().getFile(Entry->getName())) - if (!getSourceManager().hasFileInfo(Header)) { - if (!ModMap.isHeaderInUnavailableModule(Header)) { - // Find the relative path that would access this header. - SmallString<128> RelativePath; - computeRelativePath(FileMgr, Dir, Header, RelativePath); - Diag(StartLoc, diag::warn_uncovered_module_header) - << Mod->getFullModuleName() << RelativePath; - } - } - } - } - } + llvm::SmallVector<const Module *, 4> AllMods; + collectAllSubModulesWithUmbrellaHeader(*Mod, AllMods); + for (auto *M : AllMods) + diagnoseMissingHeaderInUmbrellaDir(*M); } return true; @@ -617,11 +658,13 @@ void Preprocessor::HandleMicrosoftCommentPaste(Token &Tok) { assert(!FoundLexer && "Lexer should return EOD before EOF in PP mode"); } -void Preprocessor::EnterSubmodule(Module *M, SourceLocation ImportLoc) { +void Preprocessor::EnterSubmodule(Module *M, SourceLocation ImportLoc, + bool ForPragma) { if (!getLangOpts().ModulesLocalVisibility) { // Just track that we entered this submodule. - BuildingSubmoduleStack.push_back(BuildingSubmoduleInfo( - M, ImportLoc, CurSubmoduleState, PendingModuleMacroNames.size())); + BuildingSubmoduleStack.push_back( + BuildingSubmoduleInfo(M, ImportLoc, ForPragma, CurSubmoduleState, + PendingModuleMacroNames.size())); return; } @@ -662,8 +705,9 @@ void Preprocessor::EnterSubmodule(Module *M, SourceLocation ImportLoc) { } // Track that we entered this module. - BuildingSubmoduleStack.push_back(BuildingSubmoduleInfo( - M, ImportLoc, CurSubmoduleState, PendingModuleMacroNames.size())); + BuildingSubmoduleStack.push_back( + BuildingSubmoduleInfo(M, ImportLoc, ForPragma, CurSubmoduleState, + PendingModuleMacroNames.size())); // Switch to this submodule as the current submodule. CurSubmoduleState = &State; @@ -686,13 +730,19 @@ bool Preprocessor::needModuleMacros() const { return getLangOpts().isCompilingModule(); } -void Preprocessor::LeaveSubmodule() { +Module *Preprocessor::LeaveSubmodule(bool ForPragma) { + if (BuildingSubmoduleStack.empty() || + BuildingSubmoduleStack.back().IsPragma != ForPragma) { + assert(ForPragma && "non-pragma module enter/leave mismatch"); + return nullptr; + } + auto &Info = BuildingSubmoduleStack.back(); Module *LeavingMod = Info.M; SourceLocation ImportLoc = Info.ImportLoc; - if (!needModuleMacros() || + if (!needModuleMacros() || (!getLangOpts().ModulesLocalVisibility && LeavingMod->getTopLevelModuleName() != getLangOpts().CurrentModule)) { // If we don't need module macros, or this is not a module for which we @@ -700,7 +750,7 @@ void Preprocessor::LeaveSubmodule() { // of pending names for the surrounding submodule. BuildingSubmoduleStack.pop_back(); makeModuleVisible(LeavingMod, ImportLoc); - return; + return LeavingMod; } // Create ModuleMacros for any macros defined in this submodule. @@ -738,17 +788,6 @@ void Preprocessor::LeaveSubmodule() { for (auto *MD = Macro.getLatest(); MD != OldMD; MD = MD->getPrevious()) { assert(MD && "broken macro directive chain"); - // Stop on macros defined in other submodules of this module that 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 && - Mod->getTopLevelModule() == LeavingMod->getTopLevelModule()) - 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. @@ -770,6 +809,13 @@ void Preprocessor::LeaveSubmodule() { if (Def || !Macro.getOverriddenMacros().empty()) addModuleMacro(LeavingMod, II, Def, Macro.getOverriddenMacros(), IsNew); + + if (!getLangOpts().ModulesLocalVisibility) { + // This macro is exposed to the rest of this compilation as a + // ModuleMacro; we don't need to track its MacroDirective any more. + Macro.setLatest(nullptr); + Macro.setOverriddenMacros(*this, {}); + } break; } } @@ -789,4 +835,5 @@ void Preprocessor::LeaveSubmodule() { // A nested #include makes the included submodule visible. makeModuleVisible(LeavingMod, ImportLoc); + return LeavingMod; } diff --git a/contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp b/contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp index de166c7..3f8ede2 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/PPMacroExpansion.cpp @@ -412,7 +412,7 @@ static bool isTrivialSingleTokenExpansion(const MacroInfo *MI, // If this is a function-like macro invocation, it's safe to trivially expand // as long as the identifier is not a macro argument. - return std::find(MI->arg_begin(), MI->arg_end(), II) == MI->arg_end(); + return std::find(MI->param_begin(), MI->param_end(), II) == MI->param_end(); } /// isNextPPTokenLParen - Determine whether the next preprocessor token to be @@ -492,7 +492,7 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier, // Preprocessor directives used inside macro arguments are not portable, and // this enables the warning. InMacroArgs = true; - Args = ReadFunctionLikeMacroArgs(Identifier, MI, ExpansionEnd); + Args = ReadMacroCallArgumentList(Identifier, MI, ExpansionEnd); // Finished parsing args. InMacroArgs = false; @@ -745,11 +745,11 @@ static bool GenerateNewArgTokens(Preprocessor &PP, /// token is the '(' of the macro, this method is invoked to read all of the /// actual arguments specified for the macro invocation. This returns null on /// error. -MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName, +MacroArgs *Preprocessor::ReadMacroCallArgumentList(Token &MacroName, MacroInfo *MI, SourceLocation &MacroEnd) { // The number of fixed arguments to parse. - unsigned NumFixedArgsLeft = MI->getNumArgs(); + unsigned NumFixedArgsLeft = MI->getNumParams(); bool isVariadic = MI->isVariadic(); // Outer loop, while there are more arguments, keep reading them. @@ -889,7 +889,7 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName, // Okay, we either found the r_paren. Check to see if we parsed too few // arguments. - unsigned MinArgsExpected = MI->getNumArgs(); + unsigned MinArgsExpected = MI->getNumParams(); // If this is not a variadic macro, and too many args were specified, emit // an error. @@ -1125,6 +1125,7 @@ static bool HasFeature(const Preprocessor &PP, StringRef Feature) { .Case("attribute_overloadable", true) .Case("attribute_unavailable_with_message", true) .Case("attribute_unused_on_fields", true) + .Case("attribute_diagnose_if_objc", true) .Case("blocks", LangOpts.Blocks) .Case("c_thread_safety_attributes", true) .Case("cxx_exceptions", LangOpts.CXXExceptions) @@ -1314,6 +1315,8 @@ static bool HasExtension(const Preprocessor &PP, StringRef Extension) { .Case("cxx_binary_literals", true) .Case("cxx_init_captures", LangOpts.CPlusPlus11) .Case("cxx_variable_templates", LangOpts.CPlusPlus) + // Miscellaneous language extensions + .Case("overloadable_unmarked", true) .Default(false); } @@ -1422,7 +1425,7 @@ static bool EvaluateHasIncludeCommon(Token &Tok, const DirectoryLookup *CurDir; const FileEntry *File = PP.LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, LookupFromFile, - CurDir, nullptr, nullptr, nullptr); + CurDir, nullptr, nullptr, nullptr, nullptr); // Get the result value. A result of true means the file exists. return File != nullptr; @@ -1453,7 +1456,7 @@ static bool EvaluateHasIncludeNext(Token &Tok, } else if (PP.isInPrimaryFile()) { Lookup = nullptr; PP.Diag(Tok, diag::pp_include_next_in_primary); - } else if (PP.getCurrentSubmodule()) { + } else if (PP.getCurrentLexerSubmodule()) { // Start looking up in the directory *after* the one in which the current // file would be found, if any. assert(PP.getCurrentLexer() && "#include_next directive in macro?"); @@ -1746,6 +1749,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { return llvm::StringSwitch<bool>(II->getName()) .Case("__make_integer_seq", LangOpts.CPlusPlus) .Case("__type_pack_element", LangOpts.CPlusPlus) + .Case("__builtin_available", true) .Default(false); } }); diff --git a/contrib/llvm/tools/clang/lib/Lex/Pragma.cpp b/contrib/llvm/tools/clang/lib/Lex/Pragma.cpp index 100da51..bf2363a 100644 --- a/contrib/llvm/tools/clang/lib/Lex/Pragma.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/Pragma.cpp @@ -20,6 +20,7 @@ #include "clang/Basic/TokenKinds.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/LexDiagnostic.h" +#include "clang/Lex/LiteralSupport.h" #include "clang/Lex/MacroInfo.h" #include "clang/Lex/PPCallbacks.h" #include "clang/Lex/Preprocessor.h" @@ -160,12 +161,23 @@ public: ~LexingFor_PragmaRAII() { if (InMacroArgPreExpansion) { + // When committing/backtracking the cached pragma tokens in a macro + // argument pre-expansion we want to ensure that either the tokens which + // have been committed will be removed from the cache or that the tokens + // over which we just backtracked won't remain in the cache after they're + // consumed and that the caching will stop after consuming them. + // Otherwise the caching will interfere with the way macro expansion + // works, because we will continue to cache tokens after consuming the + // backtracked tokens, which shouldn't happen when we're dealing with + // macro argument pre-expansion. + auto CachedTokenRange = PP.LastCachedTokenRange(); if (Failed) { PP.CommitBacktrackedTokens(); } else { PP.Backtrack(); OutTok = PragmaTok; } + PP.EraseCachedTokens(CachedTokenRange); } } @@ -464,9 +476,9 @@ void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) { // Emit a line marker. This will change any source locations from this point // forward to realize they are in a system header. // Create a line note with this information. - SourceMgr.AddLineNote(SysHeaderTok.getLocation(), PLoc.getLine()+1, + SourceMgr.AddLineNote(SysHeaderTok.getLocation(), PLoc.getLine() + 1, FilenameID, /*IsEntry=*/false, /*IsExit=*/false, - /*IsSystem=*/true, /*IsExternC=*/false); + SrcMgr::C_System); } /// HandlePragmaDependency - Handle \#pragma GCC dependency "foo" blah. @@ -497,7 +509,7 @@ void Preprocessor::HandlePragmaDependency(Token &DependencyTok) { const DirectoryLookup *CurDir; const FileEntry *File = LookupFile(FilenameTok.getLocation(), Filename, isAngled, nullptr, - nullptr, CurDir, nullptr, nullptr, nullptr); + nullptr, CurDir, nullptr, nullptr, nullptr, nullptr); if (!File) { if (!SuppressIncludeNotFoundError) Diag(FilenameTok, diag::err_pp_file_not_found) << Filename; @@ -743,6 +755,125 @@ void Preprocessor::HandlePragmaIncludeAlias(Token &Tok) { getHeaderSearchInfo().AddIncludeAlias(OriginalSource, ReplaceFileName); } +// Lex a component of a module name: either an identifier or a string literal; +// for components that can be expressed both ways, the two forms are equivalent. +static bool LexModuleNameComponent( + Preprocessor &PP, Token &Tok, + std::pair<IdentifierInfo *, SourceLocation> &ModuleNameComponent, + bool First) { + PP.LexUnexpandedToken(Tok); + if (Tok.is(tok::string_literal) && !Tok.hasUDSuffix()) { + StringLiteralParser Literal(Tok, PP); + if (Literal.hadError) + return true; + ModuleNameComponent = std::make_pair( + PP.getIdentifierInfo(Literal.GetString()), Tok.getLocation()); + } else if (!Tok.isAnnotation() && Tok.getIdentifierInfo()) { + ModuleNameComponent = + std::make_pair(Tok.getIdentifierInfo(), Tok.getLocation()); + } else { + PP.Diag(Tok.getLocation(), diag::err_pp_expected_module_name) << First; + return true; + } + return false; +} + +static bool LexModuleName( + Preprocessor &PP, Token &Tok, + llvm::SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>> + &ModuleName) { + while (true) { + std::pair<IdentifierInfo*, SourceLocation> NameComponent; + if (LexModuleNameComponent(PP, Tok, NameComponent, ModuleName.empty())) + return true; + ModuleName.push_back(NameComponent); + + PP.LexUnexpandedToken(Tok); + if (Tok.isNot(tok::period)) + return false; + } +} + +void Preprocessor::HandlePragmaModuleBuild(Token &Tok) { + SourceLocation Loc = Tok.getLocation(); + + std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc; + if (LexModuleNameComponent(*this, Tok, ModuleNameLoc, true)) + return; + IdentifierInfo *ModuleName = ModuleNameLoc.first; + + LexUnexpandedToken(Tok); + if (Tok.isNot(tok::eod)) { + Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma"; + DiscardUntilEndOfDirective(); + } + + if (CurPTHLexer) { + // FIXME: Support this somehow? + Diag(Loc, diag::err_pp_module_build_pth); + return; + } + + CurLexer->LexingRawMode = true; + + auto TryConsumeIdentifier = [&](StringRef Ident) -> bool { + if (Tok.getKind() != tok::raw_identifier || + Tok.getRawIdentifier() != Ident) + return false; + CurLexer->Lex(Tok); + return true; + }; + + // Scan forward looking for the end of the module. + const char *Start = CurLexer->getBufferLocation(); + const char *End = nullptr; + unsigned NestingLevel = 1; + while (true) { + End = CurLexer->getBufferLocation(); + CurLexer->Lex(Tok); + + if (Tok.is(tok::eof)) { + Diag(Loc, diag::err_pp_module_build_missing_end); + break; + } + + if (Tok.isNot(tok::hash) || !Tok.isAtStartOfLine()) { + // Token was part of module; keep going. + continue; + } + + // We hit something directive-shaped; check to see if this is the end + // of the module build. + CurLexer->ParsingPreprocessorDirective = true; + CurLexer->Lex(Tok); + if (TryConsumeIdentifier("pragma") && TryConsumeIdentifier("clang") && + TryConsumeIdentifier("module")) { + if (TryConsumeIdentifier("build")) + // #pragma clang module build -> entering a nested module build. + ++NestingLevel; + else if (TryConsumeIdentifier("endbuild")) { + // #pragma clang module endbuild -> leaving a module build. + if (--NestingLevel == 0) + break; + } + // We should either be looking at the EOD or more of the current directive + // preceding the EOD. Either way we can ignore this token and keep going. + assert(Tok.getKind() != tok::eof && "missing EOD before EOF"); + } + } + + CurLexer->LexingRawMode = false; + + // Load the extracted text as a preprocessed module. + assert(CurLexer->getBuffer().begin() <= Start && + Start <= CurLexer->getBuffer().end() && + CurLexer->getBuffer().begin() <= End && + End <= CurLexer->getBuffer().end() && + "module source range not contained within same file buffer"); + TheModuleLoader.loadModuleFromSource(Loc, ModuleName->getName(), + StringRef(Start, End - Start)); +} + /// AddPragmaHandler - Add the specified pragma handler to the preprocessor. /// If 'Namespace' is non-null, then it is a token required to exist on the /// pragma line before the pragma string starts, e.g. "STDC" or "GCC". @@ -978,9 +1109,9 @@ struct PragmaDebugHandler : public PragmaHandler { #ifdef _MSC_VER #pragma warning(disable : 4717) #endif - static void DebugOverflowStack() { - void (*volatile Self)() = DebugOverflowStack; - Self(); + static void DebugOverflowStack(void (*P)() = nullptr) { + void (*volatile Self)(void(*P)()) = DebugOverflowStack; + Self(reinterpret_cast<void(*)()>(Self)); } #ifdef _MSC_VER #pragma warning(default : 4717) @@ -1290,6 +1421,160 @@ public: } }; +/// Handle the clang \#pragma module import extension. The syntax is: +/// \code +/// #pragma clang module import some.module.name +/// \endcode +struct PragmaModuleImportHandler : public PragmaHandler { + PragmaModuleImportHandler() : PragmaHandler("import") {} + + void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &Tok) override { + SourceLocation ImportLoc = Tok.getLocation(); + + // Read the module name. + llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 8> + ModuleName; + if (LexModuleName(PP, Tok, ModuleName)) + return; + + if (Tok.isNot(tok::eod)) + PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma"; + + // If we have a non-empty module path, load the named module. + Module *Imported = + PP.getModuleLoader().loadModule(ImportLoc, ModuleName, Module::Hidden, + /*IsIncludeDirective=*/false); + if (!Imported) + return; + + PP.makeModuleVisible(Imported, ImportLoc); + PP.EnterAnnotationToken(SourceRange(ImportLoc, ModuleName.back().second), + tok::annot_module_include, Imported); + if (auto *CB = PP.getPPCallbacks()) + CB->moduleImport(ImportLoc, ModuleName, Imported); + } +}; + +/// Handle the clang \#pragma module begin extension. The syntax is: +/// \code +/// #pragma clang module begin some.module.name +/// ... +/// #pragma clang module end +/// \endcode +struct PragmaModuleBeginHandler : public PragmaHandler { + PragmaModuleBeginHandler() : PragmaHandler("begin") {} + + void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &Tok) override { + SourceLocation BeginLoc = Tok.getLocation(); + + // Read the module name. + llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 8> + ModuleName; + if (LexModuleName(PP, Tok, ModuleName)) + return; + + if (Tok.isNot(tok::eod)) + PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma"; + + // We can only enter submodules of the current module. + StringRef Current = PP.getLangOpts().CurrentModule; + if (ModuleName.front().first->getName() != Current) { + PP.Diag(ModuleName.front().second, diag::err_pp_module_begin_wrong_module) + << ModuleName.front().first << (ModuleName.size() > 1) + << Current.empty() << Current; + return; + } + + // Find the module we're entering. We require that a module map for it + // be loaded or implicitly loadable. + // FIXME: We could create the submodule here. We'd need to know whether + // it's supposed to be explicit, but not much else. + Module *M = PP.getHeaderSearchInfo().lookupModule(Current); + if (!M) { + PP.Diag(ModuleName.front().second, + diag::err_pp_module_begin_no_module_map) << Current; + return; + } + for (unsigned I = 1; I != ModuleName.size(); ++I) { + auto *NewM = M->findSubmodule(ModuleName[I].first->getName()); + if (!NewM) { + PP.Diag(ModuleName[I].second, diag::err_pp_module_begin_no_submodule) + << M->getFullModuleName() << ModuleName[I].first; + return; + } + M = NewM; + } + + // If the module isn't available, it doesn't make sense to enter it. + if (Preprocessor::checkModuleIsAvailable( + PP.getLangOpts(), PP.getTargetInfo(), PP.getDiagnostics(), M)) { + PP.Diag(BeginLoc, diag::note_pp_module_begin_here) + << M->getTopLevelModuleName(); + return; + } + + // Enter the scope of the submodule. + PP.EnterSubmodule(M, BeginLoc, /*ForPragma*/true); + PP.EnterAnnotationToken(SourceRange(BeginLoc, ModuleName.back().second), + tok::annot_module_begin, M); + } +}; + +/// Handle the clang \#pragma module end extension. +struct PragmaModuleEndHandler : public PragmaHandler { + PragmaModuleEndHandler() : PragmaHandler("end") {} + + void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &Tok) override { + SourceLocation Loc = Tok.getLocation(); + + PP.LexUnexpandedToken(Tok); + if (Tok.isNot(tok::eod)) + PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma"; + + Module *M = PP.LeaveSubmodule(/*ForPragma*/true); + if (M) + PP.EnterAnnotationToken(SourceRange(Loc), tok::annot_module_end, M); + else + PP.Diag(Loc, diag::err_pp_module_end_without_module_begin); + } +}; + +/// Handle the clang \#pragma module build extension. +struct PragmaModuleBuildHandler : public PragmaHandler { + PragmaModuleBuildHandler() : PragmaHandler("build") {} + + void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &Tok) override { + PP.HandlePragmaModuleBuild(Tok); + } +}; + +/// Handle the clang \#pragma module load extension. +struct PragmaModuleLoadHandler : public PragmaHandler { + PragmaModuleLoadHandler() : PragmaHandler("load") {} + + void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &Tok) override { + SourceLocation Loc = Tok.getLocation(); + + // Read the module name. + llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 8> + ModuleName; + if (LexModuleName(PP, Tok, ModuleName)) + return; + + if (Tok.isNot(tok::eod)) + PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma"; + + // Load the module, don't make it visible. + PP.getModuleLoader().loadModule(Loc, ModuleName, Module::Hidden, + /*IsIncludeDirective=*/false); + } +}; + /// PragmaPushMacroHandler - "\#pragma push_macro" saves the value of the /// macro on the top of the stack. struct PragmaPushMacroHandler : public PragmaHandler { @@ -1513,6 +1798,15 @@ void Preprocessor::RegisterBuiltinPragmas() { AddPragmaHandler("clang", new PragmaARCCFCodeAuditedHandler()); AddPragmaHandler("clang", new PragmaAssumeNonNullHandler()); + // #pragma clang module ... + auto *ModuleHandler = new PragmaNamespace("module"); + AddPragmaHandler("clang", ModuleHandler); + ModuleHandler->AddPragma(new PragmaModuleImportHandler()); + ModuleHandler->AddPragma(new PragmaModuleBeginHandler()); + ModuleHandler->AddPragma(new PragmaModuleEndHandler()); + ModuleHandler->AddPragma(new PragmaModuleBuildHandler()); + ModuleHandler->AddPragma(new PragmaModuleLoadHandler()); + AddPragmaHandler("STDC", new PragmaSTDC_FENV_ACCESSHandler()); AddPragmaHandler("STDC", new PragmaSTDC_CX_LIMITED_RANGEHandler()); AddPragmaHandler("STDC", new PragmaSTDC_UnknownHandler()); diff --git a/contrib/llvm/tools/clang/lib/Lex/PreprocessingRecord.cpp b/contrib/llvm/tools/clang/lib/Lex/PreprocessingRecord.cpp index 13e15f3..03c4cbe 100644 --- a/contrib/llvm/tools/clang/lib/Lex/PreprocessingRecord.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/PreprocessingRecord.cpp @@ -422,7 +422,8 @@ void PreprocessingRecord::MacroDefined(const Token &Id, } void PreprocessingRecord::MacroUndefined(const Token &Id, - const MacroDefinition &MD) { + const MacroDefinition &MD, + const MacroDirective *Undef) { MD.forAllDefinitions([&](MacroInfo *MI) { MacroDefinitions.erase(MI); }); } diff --git a/contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp b/contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp index 91319be..7979be7 100644 --- a/contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/Preprocessor.cpp @@ -70,25 +70,25 @@ ExternalPreprocessorSource::~ExternalPreprocessorSource() { } Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts, DiagnosticsEngine &diags, LangOptions &opts, - SourceManager &SM, HeaderSearch &Headers, - ModuleLoader &TheModuleLoader, + SourceManager &SM, MemoryBufferCache &PCMCache, + HeaderSearch &Headers, ModuleLoader &TheModuleLoader, IdentifierInfoLookup *IILookup, bool OwnsHeaders, TranslationUnitKind TUKind) : PPOpts(std::move(PPOpts)), Diags(&diags), LangOpts(opts), Target(nullptr), AuxTarget(nullptr), FileMgr(Headers.getFileMgr()), SourceMgr(SM), - ScratchBuf(new ScratchBuffer(SourceMgr)), HeaderInfo(Headers), - TheModuleLoader(TheModuleLoader), ExternalSource(nullptr), - Identifiers(opts, IILookup), + PCMCache(PCMCache), ScratchBuf(new ScratchBuffer(SourceMgr)), + HeaderInfo(Headers), TheModuleLoader(TheModuleLoader), + ExternalSource(nullptr), Identifiers(opts, IILookup), PragmaHandlers(new PragmaNamespace(StringRef())), IncrementalProcessing(false), TUKind(TUKind), CodeComplete(nullptr), CodeCompletionFile(nullptr), CodeCompletionOffset(0), LastTokenWasAt(false), ModuleImportExpectsIdentifier(false), CodeCompletionReached(false), CodeCompletionII(nullptr), MainFileDir(nullptr), SkipMainFilePreamble(0, true), CurPPLexer(nullptr), - CurDirLookup(nullptr), CurLexerKind(CLK_Lexer), CurSubmodule(nullptr), - Callbacks(nullptr), CurSubmoduleState(&NullSubmoduleState), - MacroArgCache(nullptr), Record(nullptr), MIChainHead(nullptr), - DeserialMIChainHead(nullptr) { + CurDirLookup(nullptr), CurLexerKind(CLK_Lexer), + CurLexerSubmodule(nullptr), Callbacks(nullptr), + CurSubmoduleState(&NullSubmoduleState), MacroArgCache(nullptr), + Record(nullptr), MIChainHead(nullptr) { OwnsHeaderSearch = OwnsHeaders; CounterValue = 0; // __COUNTER__ starts at 0. @@ -150,6 +150,9 @@ Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts, Ident_GetExceptionInfo = Ident_GetExceptionCode = nullptr; Ident_AbnormalTermination = nullptr; } + + if (this->PPOpts->GeneratePreamble) + PreambleConditionalStack.startRecording(); } Preprocessor::~Preprocessor() { @@ -169,11 +172,6 @@ Preprocessor::~Preprocessor() { std::fill(TokenLexerCache, TokenLexerCache + NumCachedTokenLexers, nullptr); CurTokenLexer.reset(); - while (DeserializedMacroInfoChain *I = DeserialMIChainHead) { - DeserialMIChainHead = I->Next; - I->~DeserializedMacroInfoChain(); - } - // Free any cached MacroArgs. for (MacroArgs *ArgList = MacroArgCache; ArgList;) ArgList = ArgList->deallocate(); @@ -539,6 +537,16 @@ void Preprocessor::EnterMainSourceFile() { EnterSourceFile(FID, nullptr, SourceLocation()); } +void Preprocessor::replayPreambleConditionalStack() { + // Restore the conditional stack from the preamble, if there is one. + if (PreambleConditionalStack.isReplaying()) { + assert(CurPPLexer && + "CurPPLexer is null when calling replayPreambleConditionalStack."); + CurPPLexer->setConditionalLevels(PreambleConditionalStack.getStack()); + PreambleConditionalStack.doneReplaying(); + } +} + void Preprocessor::EndSourceFile() { // Notify the client that we reached the end of the source file. if (Callbacks) @@ -576,7 +584,11 @@ IdentifierInfo *Preprocessor::LookUpIdentifierInfo(Token &Identifier) const { // Update the token info (identifier info and appropriate token kind). Identifier.setIdentifierInfo(II); - Identifier.setKind(II->getTokenID()); + if (getLangOpts().MSVCCompat && II->isCPlusPlusOperatorKeyword() && + getSourceManager().isInSystemHeader(Identifier.getLocation())) + Identifier.setKind(clang::tok::identifier); + else + Identifier.setKind(II->getTokenID()); return II; } @@ -702,12 +714,6 @@ bool Preprocessor::HandleIdentifier(Token &Identifier) { II.setIsFutureCompatKeyword(false); } - // C++ 2.11p2: If this is an alternative representation of a C++ operator, - // then we act as if it is the actual operator and not the textual - // representation of it. - if (II.isCPlusPlusOperatorKeyword()) - Identifier.setIdentifierInfo(nullptr); - // If this is an extension token, diagnose its use. // We avoid diagnosing tokens that originate from macro definitions. // FIXME: This warning is disabled in cases where it shouldn't be, diff --git a/contrib/llvm/tools/clang/lib/Lex/ScratchBuffer.cpp b/contrib/llvm/tools/clang/lib/Lex/ScratchBuffer.cpp index cd8a27e..e0f3966 100644 --- a/contrib/llvm/tools/clang/lib/Lex/ScratchBuffer.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/ScratchBuffer.cpp @@ -35,6 +35,14 @@ SourceLocation ScratchBuffer::getToken(const char *Buf, unsigned Len, const char *&DestPtr) { if (BytesUsed+Len+2 > ScratchBufSize) AllocScratchBuffer(Len+2); + else { + // Clear out the source line cache if it's already been computed. + // FIXME: Allow this to be incrementally extended. + auto *ContentCache = const_cast<SrcMgr::ContentCache *>( + SourceMgr.getSLocEntry(SourceMgr.getFileID(BufferStartLoc)) + .getFile().getContentCache()); + ContentCache->SourceLineCache = nullptr; + } // Prefix the token with a \n, so that it looks like it is the first thing on // its own virtual line in caret diagnostics. diff --git a/contrib/llvm/tools/clang/lib/Lex/TokenLexer.cpp b/contrib/llvm/tools/clang/lib/Lex/TokenLexer.cpp index a53c801..c2e49ba 100644 --- a/contrib/llvm/tools/clang/lib/Lex/TokenLexer.cpp +++ b/contrib/llvm/tools/clang/lib/Lex/TokenLexer.cpp @@ -67,7 +67,7 @@ void TokenLexer::Init(Token &Tok, SourceLocation ELEnd, MacroInfo *MI, // If this is a function-like macro, expand the arguments and change // Tokens to point to the expanded tokens. - if (Macro->isFunctionLike() && Macro->getNumArgs()) + if (Macro->isFunctionLike() && Macro->getNumParams()) ExpandFunctionArguments(); // Mark the macro as currently disabled, so that it is not recursively @@ -122,7 +122,7 @@ bool TokenLexer::MaybeRemoveCommaBeforeVaArgs( SmallVectorImpl<Token> &ResultToks, bool HasPasteOperator, MacroInfo *Macro, unsigned MacroArgNo, Preprocessor &PP) { // Is the macro argument __VA_ARGS__? - if (!Macro->isVariadic() || MacroArgNo != Macro->getNumArgs()-1) + if (!Macro->isVariadic() || MacroArgNo != Macro->getNumParams()-1) return false; // In Microsoft-compatibility mode, a comma is removed in the expansion @@ -137,7 +137,7 @@ bool TokenLexer::MaybeRemoveCommaBeforeVaArgs( // with GNU extensions, it is removed regardless of named arguments. // Microsoft also appears to support this extension, unofficially. if (PP.getLangOpts().C99 && !PP.getLangOpts().GNUMode - && Macro->getNumArgs() < 2) + && Macro->getNumParams() < 2) return false; // Is a comma available to be removed? @@ -183,11 +183,17 @@ void TokenLexer::ExpandFunctionArguments() { // preprocessor already verified that the following token is a macro name // when the #define was parsed. const Token &CurTok = Tokens[i]; + // We don't want a space for the next token after a paste + // operator. In valid code, the token will get smooshed onto the + // preceding one anyway. In assembler-with-cpp mode, invalid + // pastes are allowed through: in this case, we do not want the + // extra whitespace to be added. For example, we want ". ## foo" + // -> ".foo" not ". foo". if (i != 0 && !Tokens[i-1].is(tok::hashhash) && CurTok.hasLeadingSpace()) NextTokGetsSpace = true; if (CurTok.isOneOf(tok::hash, tok::hashat)) { - int ArgNo = Macro->getArgumentNum(Tokens[i+1].getIdentifierInfo()); + int ArgNo = Macro->getParameterNum(Tokens[i+1].getIdentifierInfo()); assert(ArgNo != -1 && "Token following # is not an argument?"); SourceLocation ExpansionLocStart = @@ -231,7 +237,7 @@ void TokenLexer::ExpandFunctionArguments() { // Otherwise, if this is not an argument token, just add the token to the // output buffer. IdentifierInfo *II = CurTok.getIdentifierInfo(); - int ArgNo = II ? Macro->getArgumentNum(II) : -1; + int ArgNo = II ? Macro->getParameterNum(II) : -1; if (ArgNo == -1) { // This isn't an argument, just add it. ResultToks.push_back(CurTok); @@ -317,14 +323,16 @@ void TokenLexer::ExpandFunctionArguments() { const Token *ArgToks = ActualArgs->getUnexpArgument(ArgNo); unsigned NumToks = MacroArgs::getArgLength(ArgToks); if (NumToks) { // Not an empty argument? + bool VaArgsPseudoPaste = false; // If this is the GNU ", ## __VA_ARGS__" extension, and we just learned // that __VA_ARGS__ expands to multiple tokens, avoid a pasting error when // the expander trys to paste ',' with the first token of the __VA_ARGS__ // expansion. if (NonEmptyPasteBefore && ResultToks.size() >= 2 && ResultToks[ResultToks.size()-2].is(tok::comma) && - (unsigned)ArgNo == Macro->getNumArgs()-1 && + (unsigned)ArgNo == Macro->getNumParams()-1 && Macro->isVariadic()) { + VaArgsPseudoPaste = true; // Remove the paste operator, report use of the extension. PP.Diag(ResultToks.pop_back_val().getLocation(), diag::ext_paste_comma); } @@ -344,18 +352,16 @@ void TokenLexer::ExpandFunctionArguments() { ResultToks.end()-NumToks, ResultToks.end()); } - // If this token (the macro argument) was supposed to get leading - // whitespace, transfer this information onto the first token of the - // expansion. - // - // Do not do this if the paste operator occurs before the macro argument, - // as in "A ## MACROARG". In valid code, the first token will get - // smooshed onto the preceding one anyway (forming AMACROARG). In - // assembler-with-cpp mode, invalid pastes are allowed through: in this - // case, we do not want the extra whitespace to be added. For example, - // we want ". ## foo" -> ".foo" not ". foo". - if (NextTokGetsSpace) - ResultToks[ResultToks.size()-NumToks].setFlag(Token::LeadingSpace); + // Transfer the leading whitespace information from the token + // (the macro argument) onto the first token of the + // expansion. Note that we don't do this for the GNU + // pseudo-paste extension ", ## __VA_ARGS__". + if (!VaArgsPseudoPaste) { + ResultToks[ResultToks.size() - NumToks].setFlagValue(Token::StartOfLine, + false); + ResultToks[ResultToks.size() - NumToks].setFlagValue( + Token::LeadingSpace, NextTokGetsSpace); + } NextTokGetsSpace = false; continue; |