10b57cec5SDimitry Andric //===--- PPDirectives.cpp - Directive Handling for Preprocessor -----------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric ///
90b57cec5SDimitry Andric /// \file
100b57cec5SDimitry Andric /// Implements # directive processing for the Preprocessor.
110b57cec5SDimitry Andric ///
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric #include "clang/Basic/CharInfo.h"
155f757f3fSDimitry Andric #include "clang/Basic/DirectoryEntry.h"
160b57cec5SDimitry Andric #include "clang/Basic/FileManager.h"
170b57cec5SDimitry Andric #include "clang/Basic/IdentifierTable.h"
180b57cec5SDimitry Andric #include "clang/Basic/LangOptions.h"
190b57cec5SDimitry Andric #include "clang/Basic/Module.h"
200b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h"
210b57cec5SDimitry Andric #include "clang/Basic/SourceManager.h"
22*0fca6ea1SDimitry Andric #include "clang/Basic/TargetInfo.h"
230b57cec5SDimitry Andric #include "clang/Basic/TokenKinds.h"
240b57cec5SDimitry Andric #include "clang/Lex/CodeCompletionHandler.h"
250b57cec5SDimitry Andric #include "clang/Lex/HeaderSearch.h"
265f757f3fSDimitry Andric #include "clang/Lex/HeaderSearchOptions.h"
270b57cec5SDimitry Andric #include "clang/Lex/LexDiagnostic.h"
280b57cec5SDimitry Andric #include "clang/Lex/LiteralSupport.h"
290b57cec5SDimitry Andric #include "clang/Lex/MacroInfo.h"
300b57cec5SDimitry Andric #include "clang/Lex/ModuleLoader.h"
310b57cec5SDimitry Andric #include "clang/Lex/ModuleMap.h"
320b57cec5SDimitry Andric #include "clang/Lex/PPCallbacks.h"
330b57cec5SDimitry Andric #include "clang/Lex/Pragma.h"
340b57cec5SDimitry Andric #include "clang/Lex/Preprocessor.h"
350b57cec5SDimitry Andric #include "clang/Lex/PreprocessorOptions.h"
360b57cec5SDimitry Andric #include "clang/Lex/Token.h"
370b57cec5SDimitry Andric #include "clang/Lex/VariadicMacroSupport.h"
380b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
3981ad6265SDimitry Andric #include "llvm/ADT/STLExtras.h"
400b57cec5SDimitry Andric #include "llvm/ADT/ScopeExit.h"
410b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
420b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
43*0fca6ea1SDimitry Andric #include "llvm/ADT/StringExtras.h"
440b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
4581ad6265SDimitry Andric #include "llvm/ADT/StringSwitch.h"
460b57cec5SDimitry Andric #include "llvm/Support/AlignOf.h"
470b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
480b57cec5SDimitry Andric #include "llvm/Support/Path.h"
4981ad6265SDimitry Andric #include "llvm/Support/SaveAndRestore.h"
500b57cec5SDimitry Andric #include <algorithm>
510b57cec5SDimitry Andric #include <cassert>
520b57cec5SDimitry Andric #include <cstring>
530b57cec5SDimitry Andric #include <new>
54bdd1243dSDimitry Andric #include <optional>
550b57cec5SDimitry Andric #include <string>
560b57cec5SDimitry Andric #include <utility>
570b57cec5SDimitry Andric
580b57cec5SDimitry Andric using namespace clang;
590b57cec5SDimitry Andric
600b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
610b57cec5SDimitry Andric // Utility Methods for Preprocessor Directive Handling.
620b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
630b57cec5SDimitry Andric
AllocateMacroInfo(SourceLocation L)640b57cec5SDimitry Andric MacroInfo *Preprocessor::AllocateMacroInfo(SourceLocation L) {
65bdd1243dSDimitry Andric static_assert(std::is_trivially_destructible_v<MacroInfo>, "");
66bdd1243dSDimitry Andric return new (BP) MacroInfo(L);
670b57cec5SDimitry Andric }
680b57cec5SDimitry Andric
AllocateDefMacroDirective(MacroInfo * MI,SourceLocation Loc)690b57cec5SDimitry Andric DefMacroDirective *Preprocessor::AllocateDefMacroDirective(MacroInfo *MI,
700b57cec5SDimitry Andric SourceLocation Loc) {
710b57cec5SDimitry Andric return new (BP) DefMacroDirective(MI, Loc);
720b57cec5SDimitry Andric }
730b57cec5SDimitry Andric
740b57cec5SDimitry Andric UndefMacroDirective *
AllocateUndefMacroDirective(SourceLocation UndefLoc)750b57cec5SDimitry Andric Preprocessor::AllocateUndefMacroDirective(SourceLocation UndefLoc) {
760b57cec5SDimitry Andric return new (BP) UndefMacroDirective(UndefLoc);
770b57cec5SDimitry Andric }
780b57cec5SDimitry Andric
790b57cec5SDimitry Andric VisibilityMacroDirective *
AllocateVisibilityMacroDirective(SourceLocation Loc,bool isPublic)800b57cec5SDimitry Andric Preprocessor::AllocateVisibilityMacroDirective(SourceLocation Loc,
810b57cec5SDimitry Andric bool isPublic) {
820b57cec5SDimitry Andric return new (BP) VisibilityMacroDirective(Loc, isPublic);
830b57cec5SDimitry Andric }
840b57cec5SDimitry Andric
850b57cec5SDimitry Andric /// Read and discard all tokens remaining on the current line until
860b57cec5SDimitry Andric /// the tok::eod token is found.
DiscardUntilEndOfDirective(Token & Tmp)87*0fca6ea1SDimitry Andric SourceRange Preprocessor::DiscardUntilEndOfDirective(Token &Tmp) {
880b57cec5SDimitry Andric SourceRange Res;
890b57cec5SDimitry Andric
900b57cec5SDimitry Andric LexUnexpandedToken(Tmp);
910b57cec5SDimitry Andric Res.setBegin(Tmp.getLocation());
920b57cec5SDimitry Andric while (Tmp.isNot(tok::eod)) {
930b57cec5SDimitry Andric assert(Tmp.isNot(tok::eof) && "EOF seen while discarding directive tokens");
940b57cec5SDimitry Andric LexUnexpandedToken(Tmp);
950b57cec5SDimitry Andric }
960b57cec5SDimitry Andric Res.setEnd(Tmp.getLocation());
970b57cec5SDimitry Andric return Res;
980b57cec5SDimitry Andric }
990b57cec5SDimitry Andric
1000b57cec5SDimitry Andric /// Enumerates possible cases of #define/#undef a reserved identifier.
1010b57cec5SDimitry Andric enum MacroDiag {
1020b57cec5SDimitry Andric MD_NoWarn, //> Not a reserved identifier
1030b57cec5SDimitry Andric MD_KeywordDef, //> Macro hides keyword, enabled by default
1040b57cec5SDimitry Andric MD_ReservedMacro //> #define of #undef reserved id, disabled by default
1050b57cec5SDimitry Andric };
1060b57cec5SDimitry Andric
107fe6060f1SDimitry Andric /// Enumerates possible %select values for the pp_err_elif_after_else and
108fe6060f1SDimitry Andric /// pp_err_elif_without_if diagnostics.
109fe6060f1SDimitry Andric enum PPElifDiag {
110fe6060f1SDimitry Andric PED_Elif,
111fe6060f1SDimitry Andric PED_Elifdef,
112fe6060f1SDimitry Andric PED_Elifndef
113fe6060f1SDimitry Andric };
1140b57cec5SDimitry Andric
isFeatureTestMacro(StringRef MacroName)11506c3fb27SDimitry Andric static bool isFeatureTestMacro(StringRef MacroName) {
116fe6060f1SDimitry Andric // list from:
11706c3fb27SDimitry Andric // * https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_macros.html
11806c3fb27SDimitry Andric // * https://docs.microsoft.com/en-us/cpp/c-runtime-library/security-features-in-the-crt?view=msvc-160
11906c3fb27SDimitry Andric // * man 7 feature_test_macros
120fe6060f1SDimitry Andric // The list must be sorted for correct binary search.
121fe6060f1SDimitry Andric static constexpr StringRef ReservedMacro[] = {
122fe6060f1SDimitry Andric "_ATFILE_SOURCE",
123fe6060f1SDimitry Andric "_BSD_SOURCE",
124fe6060f1SDimitry Andric "_CRT_NONSTDC_NO_WARNINGS",
125fe6060f1SDimitry Andric "_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES",
126fe6060f1SDimitry Andric "_CRT_SECURE_NO_WARNINGS",
127fe6060f1SDimitry Andric "_FILE_OFFSET_BITS",
128fe6060f1SDimitry Andric "_FORTIFY_SOURCE",
129fe6060f1SDimitry Andric "_GLIBCXX_ASSERTIONS",
130fe6060f1SDimitry Andric "_GLIBCXX_CONCEPT_CHECKS",
131fe6060f1SDimitry Andric "_GLIBCXX_DEBUG",
132fe6060f1SDimitry Andric "_GLIBCXX_DEBUG_PEDANTIC",
133fe6060f1SDimitry Andric "_GLIBCXX_PARALLEL",
134fe6060f1SDimitry Andric "_GLIBCXX_PARALLEL_ASSERTIONS",
135fe6060f1SDimitry Andric "_GLIBCXX_SANITIZE_VECTOR",
136fe6060f1SDimitry Andric "_GLIBCXX_USE_CXX11_ABI",
137fe6060f1SDimitry Andric "_GLIBCXX_USE_DEPRECATED",
138fe6060f1SDimitry Andric "_GNU_SOURCE",
139fe6060f1SDimitry Andric "_ISOC11_SOURCE",
140fe6060f1SDimitry Andric "_ISOC95_SOURCE",
141fe6060f1SDimitry Andric "_ISOC99_SOURCE",
142fe6060f1SDimitry Andric "_LARGEFILE64_SOURCE",
143fe6060f1SDimitry Andric "_POSIX_C_SOURCE",
144fe6060f1SDimitry Andric "_REENTRANT",
145fe6060f1SDimitry Andric "_SVID_SOURCE",
146fe6060f1SDimitry Andric "_THREAD_SAFE",
147fe6060f1SDimitry Andric "_XOPEN_SOURCE",
148fe6060f1SDimitry Andric "_XOPEN_SOURCE_EXTENDED",
149fe6060f1SDimitry Andric "__STDCPP_WANT_MATH_SPEC_FUNCS__",
150fe6060f1SDimitry Andric "__STDC_FORMAT_MACROS",
151fe6060f1SDimitry Andric };
15206c3fb27SDimitry Andric return std::binary_search(std::begin(ReservedMacro), std::end(ReservedMacro),
15306c3fb27SDimitry Andric MacroName);
154fe6060f1SDimitry Andric }
15506c3fb27SDimitry Andric
isLanguageDefinedBuiltin(const SourceManager & SourceMgr,const MacroInfo * MI,const StringRef MacroName)15606c3fb27SDimitry Andric static bool isLanguageDefinedBuiltin(const SourceManager &SourceMgr,
15706c3fb27SDimitry Andric const MacroInfo *MI,
15806c3fb27SDimitry Andric const StringRef MacroName) {
15906c3fb27SDimitry Andric // If this is a macro with special handling (like __LINE__) then it's language
16006c3fb27SDimitry Andric // defined.
16106c3fb27SDimitry Andric if (MI->isBuiltinMacro())
16206c3fb27SDimitry Andric return true;
16306c3fb27SDimitry Andric // Builtin macros are defined in the builtin file
16406c3fb27SDimitry Andric if (!SourceMgr.isWrittenInBuiltinFile(MI->getDefinitionLoc()))
16506c3fb27SDimitry Andric return false;
16606c3fb27SDimitry Andric // C defines macros starting with __STDC, and C++ defines macros starting with
16706c3fb27SDimitry Andric // __STDCPP
1685f757f3fSDimitry Andric if (MacroName.starts_with("__STDC"))
16906c3fb27SDimitry Andric return true;
17006c3fb27SDimitry Andric // C++ defines the __cplusplus macro
17106c3fb27SDimitry Andric if (MacroName == "__cplusplus")
17206c3fb27SDimitry Andric return true;
17306c3fb27SDimitry Andric // C++ defines various feature-test macros starting with __cpp
1745f757f3fSDimitry Andric if (MacroName.starts_with("__cpp"))
17506c3fb27SDimitry Andric return true;
17606c3fb27SDimitry Andric // Anything else isn't language-defined
17706c3fb27SDimitry Andric return false;
17806c3fb27SDimitry Andric }
17906c3fb27SDimitry Andric
shouldWarnOnMacroDef(Preprocessor & PP,IdentifierInfo * II)18006c3fb27SDimitry Andric static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II) {
18106c3fb27SDimitry Andric const LangOptions &Lang = PP.getLangOpts();
182fe6060f1SDimitry Andric StringRef Text = II->getName();
18306c3fb27SDimitry Andric if (isReservedInAllContexts(II->isReserved(Lang)))
18406c3fb27SDimitry Andric return isFeatureTestMacro(Text) ? MD_NoWarn : MD_ReservedMacro;
1850b57cec5SDimitry Andric if (II->isKeyword(Lang))
1860b57cec5SDimitry Andric return MD_KeywordDef;
187*0fca6ea1SDimitry Andric if (Lang.CPlusPlus11 && (Text == "override" || Text == "final"))
1880b57cec5SDimitry Andric return MD_KeywordDef;
1890b57cec5SDimitry Andric return MD_NoWarn;
1900b57cec5SDimitry Andric }
1910b57cec5SDimitry Andric
shouldWarnOnMacroUndef(Preprocessor & PP,IdentifierInfo * II)1920b57cec5SDimitry Andric static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, IdentifierInfo *II) {
1930b57cec5SDimitry Andric const LangOptions &Lang = PP.getLangOpts();
1940b57cec5SDimitry Andric // Do not warn on keyword undef. It is generally harmless and widely used.
195349cc55cSDimitry Andric if (isReservedInAllContexts(II->isReserved(Lang)))
1960b57cec5SDimitry Andric return MD_ReservedMacro;
1970b57cec5SDimitry Andric return MD_NoWarn;
1980b57cec5SDimitry Andric }
1990b57cec5SDimitry Andric
2000b57cec5SDimitry Andric // Return true if we want to issue a diagnostic by default if we
2010b57cec5SDimitry Andric // encounter this name in a #include with the wrong case. For now,
2020b57cec5SDimitry Andric // this includes the standard C and C++ headers, Posix headers,
2030b57cec5SDimitry Andric // and Boost headers. Improper case for these #includes is a
2040b57cec5SDimitry Andric // potential portability issue.
warnByDefaultOnWrongCase(StringRef Include)2050b57cec5SDimitry Andric static bool warnByDefaultOnWrongCase(StringRef Include) {
2060b57cec5SDimitry Andric // If the first component of the path is "boost", treat this like a standard header
2070b57cec5SDimitry Andric // for the purposes of diagnostics.
208fe6060f1SDimitry Andric if (::llvm::sys::path::begin(Include)->equals_insensitive("boost"))
2090b57cec5SDimitry Andric return true;
2100b57cec5SDimitry Andric
2110b57cec5SDimitry Andric // "condition_variable" is the longest standard header name at 18 characters.
2120b57cec5SDimitry Andric // If the include file name is longer than that, it can't be a standard header.
2130b57cec5SDimitry Andric static const size_t MaxStdHeaderNameLen = 18u;
2140b57cec5SDimitry Andric if (Include.size() > MaxStdHeaderNameLen)
2150b57cec5SDimitry Andric return false;
2160b57cec5SDimitry Andric
2170b57cec5SDimitry Andric // Lowercase and normalize the search string.
2180b57cec5SDimitry Andric SmallString<32> LowerInclude{Include};
2190b57cec5SDimitry Andric for (char &Ch : LowerInclude) {
2200b57cec5SDimitry Andric // In the ASCII range?
2210b57cec5SDimitry Andric if (static_cast<unsigned char>(Ch) > 0x7f)
2220b57cec5SDimitry Andric return false; // Can't be a standard header
2230b57cec5SDimitry Andric // ASCII lowercase:
2240b57cec5SDimitry Andric if (Ch >= 'A' && Ch <= 'Z')
2250b57cec5SDimitry Andric Ch += 'a' - 'A';
2260b57cec5SDimitry Andric // Normalize path separators for comparison purposes.
2270b57cec5SDimitry Andric else if (::llvm::sys::path::is_separator(Ch))
2280b57cec5SDimitry Andric Ch = '/';
2290b57cec5SDimitry Andric }
2300b57cec5SDimitry Andric
2310b57cec5SDimitry Andric // The standard C/C++ and Posix headers
2320b57cec5SDimitry Andric return llvm::StringSwitch<bool>(LowerInclude)
2330b57cec5SDimitry Andric // C library headers
2340b57cec5SDimitry Andric .Cases("assert.h", "complex.h", "ctype.h", "errno.h", "fenv.h", true)
2350b57cec5SDimitry Andric .Cases("float.h", "inttypes.h", "iso646.h", "limits.h", "locale.h", true)
2360b57cec5SDimitry Andric .Cases("math.h", "setjmp.h", "signal.h", "stdalign.h", "stdarg.h", true)
2375f757f3fSDimitry Andric .Cases("stdatomic.h", "stdbool.h", "stdckdint.h", "stddef.h", true)
2385f757f3fSDimitry Andric .Cases("stdint.h", "stdio.h", "stdlib.h", "stdnoreturn.h", true)
2395f757f3fSDimitry Andric .Cases("string.h", "tgmath.h", "threads.h", "time.h", "uchar.h", true)
2405f757f3fSDimitry Andric .Cases("wchar.h", "wctype.h", true)
2410b57cec5SDimitry Andric
2420b57cec5SDimitry Andric // C++ headers for C library facilities
2430b57cec5SDimitry Andric .Cases("cassert", "ccomplex", "cctype", "cerrno", "cfenv", true)
2440b57cec5SDimitry Andric .Cases("cfloat", "cinttypes", "ciso646", "climits", "clocale", true)
2450b57cec5SDimitry Andric .Cases("cmath", "csetjmp", "csignal", "cstdalign", "cstdarg", true)
2460b57cec5SDimitry Andric .Cases("cstdbool", "cstddef", "cstdint", "cstdio", "cstdlib", true)
2470b57cec5SDimitry Andric .Cases("cstring", "ctgmath", "ctime", "cuchar", "cwchar", true)
2480b57cec5SDimitry Andric .Case("cwctype", true)
2490b57cec5SDimitry Andric
2500b57cec5SDimitry Andric // C++ library headers
2510b57cec5SDimitry Andric .Cases("algorithm", "fstream", "list", "regex", "thread", true)
2520b57cec5SDimitry Andric .Cases("array", "functional", "locale", "scoped_allocator", "tuple", true)
2530b57cec5SDimitry Andric .Cases("atomic", "future", "map", "set", "type_traits", true)
2540b57cec5SDimitry Andric .Cases("bitset", "initializer_list", "memory", "shared_mutex", "typeindex", true)
2550b57cec5SDimitry Andric .Cases("chrono", "iomanip", "mutex", "sstream", "typeinfo", true)
2560b57cec5SDimitry Andric .Cases("codecvt", "ios", "new", "stack", "unordered_map", true)
2570b57cec5SDimitry Andric .Cases("complex", "iosfwd", "numeric", "stdexcept", "unordered_set", true)
2580b57cec5SDimitry Andric .Cases("condition_variable", "iostream", "ostream", "streambuf", "utility", true)
2590b57cec5SDimitry Andric .Cases("deque", "istream", "queue", "string", "valarray", true)
2600b57cec5SDimitry Andric .Cases("exception", "iterator", "random", "strstream", "vector", true)
2610b57cec5SDimitry Andric .Cases("forward_list", "limits", "ratio", "system_error", true)
2620b57cec5SDimitry Andric
2630b57cec5SDimitry Andric // POSIX headers (which aren't also C headers)
2640b57cec5SDimitry Andric .Cases("aio.h", "arpa/inet.h", "cpio.h", "dirent.h", "dlfcn.h", true)
2650b57cec5SDimitry Andric .Cases("fcntl.h", "fmtmsg.h", "fnmatch.h", "ftw.h", "glob.h", true)
2660b57cec5SDimitry Andric .Cases("grp.h", "iconv.h", "langinfo.h", "libgen.h", "monetary.h", true)
2670b57cec5SDimitry Andric .Cases("mqueue.h", "ndbm.h", "net/if.h", "netdb.h", "netinet/in.h", true)
2680b57cec5SDimitry Andric .Cases("netinet/tcp.h", "nl_types.h", "poll.h", "pthread.h", "pwd.h", true)
2690b57cec5SDimitry Andric .Cases("regex.h", "sched.h", "search.h", "semaphore.h", "spawn.h", true)
2700b57cec5SDimitry Andric .Cases("strings.h", "stropts.h", "sys/ipc.h", "sys/mman.h", "sys/msg.h", true)
2710b57cec5SDimitry Andric .Cases("sys/resource.h", "sys/select.h", "sys/sem.h", "sys/shm.h", "sys/socket.h", true)
2720b57cec5SDimitry Andric .Cases("sys/stat.h", "sys/statvfs.h", "sys/time.h", "sys/times.h", "sys/types.h", true)
2730b57cec5SDimitry Andric .Cases("sys/uio.h", "sys/un.h", "sys/utsname.h", "sys/wait.h", "syslog.h", true)
2740b57cec5SDimitry Andric .Cases("tar.h", "termios.h", "trace.h", "ulimit.h", true)
2750b57cec5SDimitry Andric .Cases("unistd.h", "utime.h", "utmpx.h", "wordexp.h", true)
2760b57cec5SDimitry Andric .Default(false);
2770b57cec5SDimitry Andric }
2780b57cec5SDimitry Andric
27981ad6265SDimitry Andric /// Find a similar string in `Candidates`.
28081ad6265SDimitry Andric ///
28181ad6265SDimitry Andric /// \param LHS a string for a similar string in `Candidates`
28281ad6265SDimitry Andric ///
28381ad6265SDimitry Andric /// \param Candidates the candidates to find a similar string.
28481ad6265SDimitry Andric ///
28581ad6265SDimitry Andric /// \returns a similar string if exists. If no similar string exists,
286bdd1243dSDimitry Andric /// returns std::nullopt.
287bdd1243dSDimitry Andric static std::optional<StringRef>
findSimilarStr(StringRef LHS,const std::vector<StringRef> & Candidates)288bdd1243dSDimitry Andric findSimilarStr(StringRef LHS, const std::vector<StringRef> &Candidates) {
28981ad6265SDimitry Andric // We need to check if `Candidates` has the exact case-insensitive string
29081ad6265SDimitry Andric // because the Levenshtein distance match does not care about it.
29181ad6265SDimitry Andric for (StringRef C : Candidates) {
29281ad6265SDimitry Andric if (LHS.equals_insensitive(C)) {
29381ad6265SDimitry Andric return C;
29481ad6265SDimitry Andric }
29581ad6265SDimitry Andric }
29681ad6265SDimitry Andric
29781ad6265SDimitry Andric // Keep going with the Levenshtein distance match.
29881ad6265SDimitry Andric // If the LHS size is less than 3, use the LHS size minus 1 and if not,
29981ad6265SDimitry Andric // use the LHS size divided by 3.
30081ad6265SDimitry Andric size_t Length = LHS.size();
30181ad6265SDimitry Andric size_t MaxDist = Length < 3 ? Length - 1 : Length / 3;
30281ad6265SDimitry Andric
303bdd1243dSDimitry Andric std::optional<std::pair<StringRef, size_t>> SimilarStr;
30481ad6265SDimitry Andric for (StringRef C : Candidates) {
30581ad6265SDimitry Andric size_t CurDist = LHS.edit_distance(C, true);
30681ad6265SDimitry Andric if (CurDist <= MaxDist) {
30781ad6265SDimitry Andric if (!SimilarStr) {
30881ad6265SDimitry Andric // The first similar string found.
30981ad6265SDimitry Andric SimilarStr = {C, CurDist};
31081ad6265SDimitry Andric } else if (CurDist < SimilarStr->second) {
31181ad6265SDimitry Andric // More similar string found.
31281ad6265SDimitry Andric SimilarStr = {C, CurDist};
31381ad6265SDimitry Andric }
31481ad6265SDimitry Andric }
31581ad6265SDimitry Andric }
31681ad6265SDimitry Andric
31781ad6265SDimitry Andric if (SimilarStr) {
31881ad6265SDimitry Andric return SimilarStr->first;
31981ad6265SDimitry Andric } else {
320bdd1243dSDimitry Andric return std::nullopt;
32181ad6265SDimitry Andric }
32281ad6265SDimitry Andric }
32381ad6265SDimitry Andric
CheckMacroName(Token & MacroNameTok,MacroUse isDefineUndef,bool * ShadowFlag)3240b57cec5SDimitry Andric bool Preprocessor::CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef,
3250b57cec5SDimitry Andric bool *ShadowFlag) {
3260b57cec5SDimitry Andric // Missing macro name?
3270b57cec5SDimitry Andric if (MacroNameTok.is(tok::eod))
3280b57cec5SDimitry Andric return Diag(MacroNameTok, diag::err_pp_missing_macro_name);
3290b57cec5SDimitry Andric
3300b57cec5SDimitry Andric IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
3310b57cec5SDimitry Andric if (!II)
3320b57cec5SDimitry Andric return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
3330b57cec5SDimitry Andric
3340b57cec5SDimitry Andric if (II->isCPlusPlusOperatorKeyword()) {
3350b57cec5SDimitry Andric // C++ 2.5p2: Alternative tokens behave the same as its primary token
3360b57cec5SDimitry Andric // except for their spellings.
3370b57cec5SDimitry Andric Diag(MacroNameTok, getLangOpts().MicrosoftExt
3380b57cec5SDimitry Andric ? diag::ext_pp_operator_used_as_macro_name
3390b57cec5SDimitry Andric : diag::err_pp_operator_used_as_macro_name)
3400b57cec5SDimitry Andric << II << MacroNameTok.getKind();
3410b57cec5SDimitry Andric // Allow #defining |and| and friends for Microsoft compatibility or
3420b57cec5SDimitry Andric // recovery when legacy C headers are included in C++.
3430b57cec5SDimitry Andric }
3440b57cec5SDimitry Andric
3450b57cec5SDimitry Andric if ((isDefineUndef != MU_Other) && II->getPPKeywordID() == tok::pp_defined) {
3460b57cec5SDimitry Andric // Error if defining "defined": C99 6.10.8/4, C++ [cpp.predefined]p4.
3470b57cec5SDimitry Andric return Diag(MacroNameTok, diag::err_defined_macro_name);
3480b57cec5SDimitry Andric }
3490b57cec5SDimitry Andric
3500b57cec5SDimitry Andric // If defining/undefining reserved identifier or a keyword, we need to issue
3510b57cec5SDimitry Andric // a warning.
3520b57cec5SDimitry Andric SourceLocation MacroNameLoc = MacroNameTok.getLocation();
3530b57cec5SDimitry Andric if (ShadowFlag)
3540b57cec5SDimitry Andric *ShadowFlag = false;
3550b57cec5SDimitry Andric if (!SourceMgr.isInSystemHeader(MacroNameLoc) &&
3560b57cec5SDimitry Andric (SourceMgr.getBufferName(MacroNameLoc) != "<built-in>")) {
3570b57cec5SDimitry Andric MacroDiag D = MD_NoWarn;
3580b57cec5SDimitry Andric if (isDefineUndef == MU_Define) {
3590b57cec5SDimitry Andric D = shouldWarnOnMacroDef(*this, II);
3600b57cec5SDimitry Andric }
3610b57cec5SDimitry Andric else if (isDefineUndef == MU_Undef)
3620b57cec5SDimitry Andric D = shouldWarnOnMacroUndef(*this, II);
3630b57cec5SDimitry Andric if (D == MD_KeywordDef) {
3640b57cec5SDimitry Andric // We do not want to warn on some patterns widely used in configuration
3650b57cec5SDimitry Andric // scripts. This requires analyzing next tokens, so do not issue warnings
3660b57cec5SDimitry Andric // now, only inform caller.
3670b57cec5SDimitry Andric if (ShadowFlag)
3680b57cec5SDimitry Andric *ShadowFlag = true;
3690b57cec5SDimitry Andric }
3700b57cec5SDimitry Andric if (D == MD_ReservedMacro)
3710b57cec5SDimitry Andric Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);
3720b57cec5SDimitry Andric }
3730b57cec5SDimitry Andric
3740b57cec5SDimitry Andric // Okay, we got a good identifier.
3750b57cec5SDimitry Andric return false;
3760b57cec5SDimitry Andric }
3770b57cec5SDimitry Andric
3780b57cec5SDimitry Andric /// Lex and validate a macro name, which occurs after a
3790b57cec5SDimitry Andric /// \#define or \#undef.
3800b57cec5SDimitry Andric ///
3810b57cec5SDimitry Andric /// This sets the token kind to eod and discards the rest of the macro line if
3820b57cec5SDimitry Andric /// the macro name is invalid.
3830b57cec5SDimitry Andric ///
3840b57cec5SDimitry Andric /// \param MacroNameTok Token that is expected to be a macro name.
3850b57cec5SDimitry Andric /// \param isDefineUndef Context in which macro is used.
3860b57cec5SDimitry Andric /// \param ShadowFlag Points to a flag that is set if macro shadows a keyword.
ReadMacroName(Token & MacroNameTok,MacroUse isDefineUndef,bool * ShadowFlag)3870b57cec5SDimitry Andric void Preprocessor::ReadMacroName(Token &MacroNameTok, MacroUse isDefineUndef,
3880b57cec5SDimitry Andric bool *ShadowFlag) {
3890b57cec5SDimitry Andric // Read the token, don't allow macro expansion on it.
3900b57cec5SDimitry Andric LexUnexpandedToken(MacroNameTok);
3910b57cec5SDimitry Andric
3920b57cec5SDimitry Andric if (MacroNameTok.is(tok::code_completion)) {
3930b57cec5SDimitry Andric if (CodeComplete)
3940b57cec5SDimitry Andric CodeComplete->CodeCompleteMacroName(isDefineUndef == MU_Define);
3950b57cec5SDimitry Andric setCodeCompletionReached();
3960b57cec5SDimitry Andric LexUnexpandedToken(MacroNameTok);
3970b57cec5SDimitry Andric }
3980b57cec5SDimitry Andric
3990b57cec5SDimitry Andric if (!CheckMacroName(MacroNameTok, isDefineUndef, ShadowFlag))
4000b57cec5SDimitry Andric return;
4010b57cec5SDimitry Andric
4020b57cec5SDimitry Andric // Invalid macro name, read and discard the rest of the line and set the
4030b57cec5SDimitry Andric // token kind to tok::eod if necessary.
4040b57cec5SDimitry Andric if (MacroNameTok.isNot(tok::eod)) {
4050b57cec5SDimitry Andric MacroNameTok.setKind(tok::eod);
4060b57cec5SDimitry Andric DiscardUntilEndOfDirective();
4070b57cec5SDimitry Andric }
4080b57cec5SDimitry Andric }
4090b57cec5SDimitry Andric
4100b57cec5SDimitry Andric /// Ensure that the next token is a tok::eod token.
4110b57cec5SDimitry Andric ///
4120b57cec5SDimitry Andric /// If not, emit a diagnostic and consume up until the eod. If EnableMacros is
4130b57cec5SDimitry Andric /// true, then we consider macros that expand to zero tokens as being ok.
4140b57cec5SDimitry Andric ///
4150b57cec5SDimitry Andric /// Returns the location of the end of the directive.
CheckEndOfDirective(const char * DirType,bool EnableMacros)4160b57cec5SDimitry Andric SourceLocation Preprocessor::CheckEndOfDirective(const char *DirType,
4170b57cec5SDimitry Andric bool EnableMacros) {
4180b57cec5SDimitry Andric Token Tmp;
4190b57cec5SDimitry Andric // Lex unexpanded tokens for most directives: macros might expand to zero
4200b57cec5SDimitry Andric // tokens, causing us to miss diagnosing invalid lines. Some directives (like
4210b57cec5SDimitry Andric // #line) allow empty macros.
4220b57cec5SDimitry Andric if (EnableMacros)
4230b57cec5SDimitry Andric Lex(Tmp);
4240b57cec5SDimitry Andric else
4250b57cec5SDimitry Andric LexUnexpandedToken(Tmp);
4260b57cec5SDimitry Andric
4270b57cec5SDimitry Andric // There should be no tokens after the directive, but we allow them as an
4280b57cec5SDimitry Andric // extension.
4290b57cec5SDimitry Andric while (Tmp.is(tok::comment)) // Skip comments in -C mode.
4300b57cec5SDimitry Andric LexUnexpandedToken(Tmp);
4310b57cec5SDimitry Andric
4320b57cec5SDimitry Andric if (Tmp.is(tok::eod))
4330b57cec5SDimitry Andric return Tmp.getLocation();
4340b57cec5SDimitry Andric
4350b57cec5SDimitry Andric // Add a fixit in GNU/C99/C++ mode. Don't offer a fixit for strict-C89,
4360b57cec5SDimitry Andric // or if this is a macro-style preprocessing directive, because it is more
4370b57cec5SDimitry Andric // trouble than it is worth to insert /**/ and check that there is no /**/
4380b57cec5SDimitry Andric // in the range also.
4390b57cec5SDimitry Andric FixItHint Hint;
4400b57cec5SDimitry Andric if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
4410b57cec5SDimitry Andric !CurTokenLexer)
4420b57cec5SDimitry Andric Hint = FixItHint::CreateInsertion(Tmp.getLocation(),"//");
4430b57cec5SDimitry Andric Diag(Tmp, diag::ext_pp_extra_tokens_at_eol) << DirType << Hint;
4440b57cec5SDimitry Andric return DiscardUntilEndOfDirective().getEnd();
4450b57cec5SDimitry Andric }
4460b57cec5SDimitry Andric
SuggestTypoedDirective(const Token & Tok,StringRef Directive) const44781ad6265SDimitry Andric void Preprocessor::SuggestTypoedDirective(const Token &Tok,
44881ad6265SDimitry Andric StringRef Directive) const {
44981ad6265SDimitry Andric // If this is a `.S` file, treat unknown # directives as non-preprocessor
45081ad6265SDimitry Andric // directives.
45181ad6265SDimitry Andric if (getLangOpts().AsmPreprocessor) return;
452a7dea167SDimitry Andric
45381ad6265SDimitry Andric std::vector<StringRef> Candidates = {
45481ad6265SDimitry Andric "if", "ifdef", "ifndef", "elif", "else", "endif"
45581ad6265SDimitry Andric };
4565f757f3fSDimitry Andric if (LangOpts.C23 || LangOpts.CPlusPlus23)
45781ad6265SDimitry Andric Candidates.insert(Candidates.end(), {"elifdef", "elifndef"});
458a7dea167SDimitry Andric
459bdd1243dSDimitry Andric if (std::optional<StringRef> Sugg = findSimilarStr(Directive, Candidates)) {
46081ad6265SDimitry Andric // Directive cannot be coming from macro.
46181ad6265SDimitry Andric assert(Tok.getLocation().isFileID());
46281ad6265SDimitry Andric CharSourceRange DirectiveRange = CharSourceRange::getCharRange(
46381ad6265SDimitry Andric Tok.getLocation(),
46481ad6265SDimitry Andric Tok.getLocation().getLocWithOffset(Directive.size()));
46581ad6265SDimitry Andric StringRef SuggValue = *Sugg;
466a7dea167SDimitry Andric
46781ad6265SDimitry Andric auto Hint = FixItHint::CreateReplacement(DirectiveRange, SuggValue);
46881ad6265SDimitry Andric Diag(Tok, diag::warn_pp_invalid_directive) << 1 << SuggValue << Hint;
46981ad6265SDimitry Andric }
470a7dea167SDimitry Andric }
471a7dea167SDimitry Andric
4720b57cec5SDimitry Andric /// SkipExcludedConditionalBlock - We just read a \#if or related directive and
4730b57cec5SDimitry Andric /// decided that the subsequent tokens are in the \#if'd out portion of the
4740b57cec5SDimitry Andric /// file. Lex the rest of the file, until we see an \#endif. If
4750b57cec5SDimitry Andric /// FoundNonSkipPortion is true, then we have already emitted code for part of
4760b57cec5SDimitry Andric /// this \#if directive, so \#else/\#elif blocks should never be entered.
4770b57cec5SDimitry Andric /// If ElseOk is true, then \#else directives are ok, if not, then we have
4780b57cec5SDimitry Andric /// already seen one so a \#else directive is a duplicate. When this returns,
4790b57cec5SDimitry Andric /// the caller can lex the first valid token.
SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,SourceLocation IfTokenLoc,bool FoundNonSkipPortion,bool FoundElse,SourceLocation ElseLoc)4800b57cec5SDimitry Andric void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
4810b57cec5SDimitry Andric SourceLocation IfTokenLoc,
4820b57cec5SDimitry Andric bool FoundNonSkipPortion,
4830b57cec5SDimitry Andric bool FoundElse,
4840b57cec5SDimitry Andric SourceLocation ElseLoc) {
48581ad6265SDimitry Andric // In SkippingRangeStateTy we are depending on SkipExcludedConditionalBlock()
48681ad6265SDimitry Andric // not getting called recursively by storing the RecordedSkippedRanges
48781ad6265SDimitry Andric // DenseMap lookup pointer (field SkipRangePtr). SkippingRangeStateTy expects
48881ad6265SDimitry Andric // that RecordedSkippedRanges won't get modified and SkipRangePtr won't be
48981ad6265SDimitry Andric // invalidated. If this changes and there is a need to call
49081ad6265SDimitry Andric // SkipExcludedConditionalBlock() recursively, SkippingRangeStateTy should
49181ad6265SDimitry Andric // change to do a second lookup in endLexPass function instead of reusing the
49281ad6265SDimitry Andric // lookup pointer.
49381ad6265SDimitry Andric assert(!SkippingExcludedConditionalBlock &&
49481ad6265SDimitry Andric "calling SkipExcludedConditionalBlock recursively");
495bdd1243dSDimitry Andric llvm::SaveAndRestore SARSkipping(SkippingExcludedConditionalBlock, true);
49681ad6265SDimitry Andric
4970b57cec5SDimitry Andric ++NumSkipped;
4985f757f3fSDimitry Andric assert(!CurTokenLexer && "Conditional PP block cannot appear in a macro!");
4995f757f3fSDimitry Andric assert(CurPPLexer && "Conditional PP block must be in a file!");
5005f757f3fSDimitry Andric assert(CurLexer && "Conditional PP block but no current lexer set!");
5010b57cec5SDimitry Andric
5020b57cec5SDimitry Andric if (PreambleConditionalStack.reachedEOFWhileSkipping())
5030b57cec5SDimitry Andric PreambleConditionalStack.clearSkipInfo();
5040b57cec5SDimitry Andric else
5050b57cec5SDimitry Andric CurPPLexer->pushConditionalLevel(IfTokenLoc, /*isSkipping*/ false,
5060b57cec5SDimitry Andric FoundNonSkipPortion, FoundElse);
5070b57cec5SDimitry Andric
5080b57cec5SDimitry Andric // Enter raw mode to disable identifier lookup (and thus macro expansion),
5090b57cec5SDimitry Andric // disabling warnings, etc.
5100b57cec5SDimitry Andric CurPPLexer->LexingRawMode = true;
5110b57cec5SDimitry Andric Token Tok;
5125ffd83dbSDimitry Andric SourceLocation endLoc;
51381ad6265SDimitry Andric
51481ad6265SDimitry Andric /// Keeps track and caches skipped ranges and also retrieves a prior skipped
51581ad6265SDimitry Andric /// range if the same block is re-visited.
51681ad6265SDimitry Andric struct SkippingRangeStateTy {
51781ad6265SDimitry Andric Preprocessor &PP;
51881ad6265SDimitry Andric
51981ad6265SDimitry Andric const char *BeginPtr = nullptr;
52081ad6265SDimitry Andric unsigned *SkipRangePtr = nullptr;
52181ad6265SDimitry Andric
52281ad6265SDimitry Andric SkippingRangeStateTy(Preprocessor &PP) : PP(PP) {}
52381ad6265SDimitry Andric
52481ad6265SDimitry Andric void beginLexPass() {
52581ad6265SDimitry Andric if (BeginPtr)
52681ad6265SDimitry Andric return; // continue skipping a block.
52781ad6265SDimitry Andric
52881ad6265SDimitry Andric // Initiate a skipping block and adjust the lexer if we already skipped it
52981ad6265SDimitry Andric // before.
53081ad6265SDimitry Andric BeginPtr = PP.CurLexer->getBufferLocation();
53181ad6265SDimitry Andric SkipRangePtr = &PP.RecordedSkippedRanges[BeginPtr];
53281ad6265SDimitry Andric if (*SkipRangePtr) {
53381ad6265SDimitry Andric PP.CurLexer->seek(PP.CurLexer->getCurrentBufferOffset() + *SkipRangePtr,
53481ad6265SDimitry Andric /*IsAtStartOfLine*/ true);
53581ad6265SDimitry Andric }
53681ad6265SDimitry Andric }
53781ad6265SDimitry Andric
53881ad6265SDimitry Andric void endLexPass(const char *Hashptr) {
53981ad6265SDimitry Andric if (!BeginPtr) {
54081ad6265SDimitry Andric // Not doing normal lexing.
54181ad6265SDimitry Andric assert(PP.CurLexer->isDependencyDirectivesLexer());
54281ad6265SDimitry Andric return;
54381ad6265SDimitry Andric }
54481ad6265SDimitry Andric
54581ad6265SDimitry Andric // Finished skipping a block, record the range if it's first time visited.
54681ad6265SDimitry Andric if (!*SkipRangePtr) {
54781ad6265SDimitry Andric *SkipRangePtr = Hashptr - BeginPtr;
54881ad6265SDimitry Andric }
549*0fca6ea1SDimitry Andric assert(*SkipRangePtr == unsigned(Hashptr - BeginPtr));
55081ad6265SDimitry Andric BeginPtr = nullptr;
55181ad6265SDimitry Andric SkipRangePtr = nullptr;
55281ad6265SDimitry Andric }
55381ad6265SDimitry Andric } SkippingRangeState(*this);
55481ad6265SDimitry Andric
55581ad6265SDimitry Andric while (true) {
55681ad6265SDimitry Andric if (CurLexer->isDependencyDirectivesLexer()) {
55781ad6265SDimitry Andric CurLexer->LexDependencyDirectiveTokenWhileSkipping(Tok);
55881ad6265SDimitry Andric } else {
55981ad6265SDimitry Andric SkippingRangeState.beginLexPass();
5600b57cec5SDimitry Andric while (true) {
5610b57cec5SDimitry Andric CurLexer->Lex(Tok);
5620b57cec5SDimitry Andric
5630b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) {
564fe6060f1SDimitry Andric setCodeCompletionReached();
5650b57cec5SDimitry Andric if (CodeComplete)
5660b57cec5SDimitry Andric CodeComplete->CodeCompleteInConditionalExclusion();
5670b57cec5SDimitry Andric continue;
5680b57cec5SDimitry Andric }
5690b57cec5SDimitry Andric
5700b57cec5SDimitry Andric // If this is the end of the buffer, we have an error.
5710b57cec5SDimitry Andric if (Tok.is(tok::eof)) {
5720b57cec5SDimitry Andric // We don't emit errors for unterminated conditionals here,
5730b57cec5SDimitry Andric // Lexer::LexEndOfFile can do that properly.
5740b57cec5SDimitry Andric // Just return and let the caller lex after this #include.
5750b57cec5SDimitry Andric if (PreambleConditionalStack.isRecording())
57681ad6265SDimitry Andric PreambleConditionalStack.SkipInfo.emplace(HashTokenLoc, IfTokenLoc,
57781ad6265SDimitry Andric FoundNonSkipPortion,
57881ad6265SDimitry Andric FoundElse, ElseLoc);
5790b57cec5SDimitry Andric break;
5800b57cec5SDimitry Andric }
5810b57cec5SDimitry Andric
5820b57cec5SDimitry Andric // If this token is not a preprocessor directive, just skip it.
5830b57cec5SDimitry Andric if (Tok.isNot(tok::hash) || !Tok.isAtStartOfLine())
5840b57cec5SDimitry Andric continue;
5850b57cec5SDimitry Andric
58681ad6265SDimitry Andric break;
58781ad6265SDimitry Andric }
58881ad6265SDimitry Andric }
58981ad6265SDimitry Andric if (Tok.is(tok::eof))
59081ad6265SDimitry Andric break;
59181ad6265SDimitry Andric
5920b57cec5SDimitry Andric // We just parsed a # character at the start of a line, so we're in
5930b57cec5SDimitry Andric // directive mode. Tell the lexer this so any newlines we see will be
5940b57cec5SDimitry Andric // converted into an EOD token (this terminates the macro).
5950b57cec5SDimitry Andric CurPPLexer->ParsingPreprocessorDirective = true;
5960b57cec5SDimitry Andric if (CurLexer) CurLexer->SetKeepWhitespaceMode(false);
5970b57cec5SDimitry Andric
59881ad6265SDimitry Andric assert(Tok.is(tok::hash));
59981ad6265SDimitry Andric const char *Hashptr = CurLexer->getBufferLocation() - Tok.getLength();
60081ad6265SDimitry Andric assert(CurLexer->getSourceLocation(Hashptr) == Tok.getLocation());
6010b57cec5SDimitry Andric
6020b57cec5SDimitry Andric // Read the next token, the directive flavor.
6030b57cec5SDimitry Andric LexUnexpandedToken(Tok);
6040b57cec5SDimitry Andric
6050b57cec5SDimitry Andric // If this isn't an identifier directive (e.g. is "# 1\n" or "#\n", or
6060b57cec5SDimitry Andric // something bogus), skip it.
6070b57cec5SDimitry Andric if (Tok.isNot(tok::raw_identifier)) {
6080b57cec5SDimitry Andric CurPPLexer->ParsingPreprocessorDirective = false;
6090b57cec5SDimitry Andric // Restore comment saving mode.
6100b57cec5SDimitry Andric if (CurLexer) CurLexer->resetExtendedTokenMode();
6110b57cec5SDimitry Andric continue;
6120b57cec5SDimitry Andric }
6130b57cec5SDimitry Andric
6140b57cec5SDimitry Andric // If the first letter isn't i or e, it isn't intesting to us. We know that
6150b57cec5SDimitry Andric // this is safe in the face of spelling differences, because there is no way
6160b57cec5SDimitry Andric // to spell an i/e in a strange way that is another letter. Skipping this
6170b57cec5SDimitry Andric // allows us to avoid looking up the identifier info for #define/#undef and
6180b57cec5SDimitry Andric // other common directives.
6190b57cec5SDimitry Andric StringRef RI = Tok.getRawIdentifier();
6200b57cec5SDimitry Andric
6210b57cec5SDimitry Andric char FirstChar = RI[0];
6220b57cec5SDimitry Andric if (FirstChar >= 'a' && FirstChar <= 'z' &&
6230b57cec5SDimitry Andric FirstChar != 'i' && FirstChar != 'e') {
6240b57cec5SDimitry Andric CurPPLexer->ParsingPreprocessorDirective = false;
6250b57cec5SDimitry Andric // Restore comment saving mode.
6260b57cec5SDimitry Andric if (CurLexer) CurLexer->resetExtendedTokenMode();
6270b57cec5SDimitry Andric continue;
6280b57cec5SDimitry Andric }
6290b57cec5SDimitry Andric
6300b57cec5SDimitry Andric // Get the identifier name without trigraphs or embedded newlines. Note
6310b57cec5SDimitry Andric // that we can't use Tok.getIdentifierInfo() because its lookup is disabled
6320b57cec5SDimitry Andric // when skipping.
6330b57cec5SDimitry Andric char DirectiveBuf[20];
6340b57cec5SDimitry Andric StringRef Directive;
6350b57cec5SDimitry Andric if (!Tok.needsCleaning() && RI.size() < 20) {
6360b57cec5SDimitry Andric Directive = RI;
6370b57cec5SDimitry Andric } else {
6380b57cec5SDimitry Andric std::string DirectiveStr = getSpelling(Tok);
6390b57cec5SDimitry Andric size_t IdLen = DirectiveStr.size();
6400b57cec5SDimitry Andric if (IdLen >= 20) {
6410b57cec5SDimitry Andric CurPPLexer->ParsingPreprocessorDirective = false;
6420b57cec5SDimitry Andric // Restore comment saving mode.
6430b57cec5SDimitry Andric if (CurLexer) CurLexer->resetExtendedTokenMode();
6440b57cec5SDimitry Andric continue;
6450b57cec5SDimitry Andric }
6460b57cec5SDimitry Andric memcpy(DirectiveBuf, &DirectiveStr[0], IdLen);
6470b57cec5SDimitry Andric Directive = StringRef(DirectiveBuf, IdLen);
6480b57cec5SDimitry Andric }
6490b57cec5SDimitry Andric
6505f757f3fSDimitry Andric if (Directive.starts_with("if")) {
6510b57cec5SDimitry Andric StringRef Sub = Directive.substr(2);
6520b57cec5SDimitry Andric if (Sub.empty() || // "if"
6530b57cec5SDimitry Andric Sub == "def" || // "ifdef"
6540b57cec5SDimitry Andric Sub == "ndef") { // "ifndef"
6550b57cec5SDimitry Andric // We know the entire #if/#ifdef/#ifndef block will be skipped, don't
6560b57cec5SDimitry Andric // bother parsing the condition.
6570b57cec5SDimitry Andric DiscardUntilEndOfDirective();
6580b57cec5SDimitry Andric CurPPLexer->pushConditionalLevel(Tok.getLocation(), /*wasskipping*/true,
6590b57cec5SDimitry Andric /*foundnonskip*/false,
6600b57cec5SDimitry Andric /*foundelse*/false);
66181ad6265SDimitry Andric } else {
66281ad6265SDimitry Andric SuggestTypoedDirective(Tok, Directive);
6630b57cec5SDimitry Andric }
6640b57cec5SDimitry Andric } else if (Directive[0] == 'e') {
6650b57cec5SDimitry Andric StringRef Sub = Directive.substr(1);
6660b57cec5SDimitry Andric if (Sub == "ndif") { // "endif"
6670b57cec5SDimitry Andric PPConditionalInfo CondInfo;
6680b57cec5SDimitry Andric CondInfo.WasSkipping = true; // Silence bogus warning.
6690b57cec5SDimitry Andric bool InCond = CurPPLexer->popConditionalLevel(CondInfo);
6700b57cec5SDimitry Andric (void)InCond; // Silence warning in no-asserts mode.
6710b57cec5SDimitry Andric assert(!InCond && "Can't be skipping if not in a conditional!");
6720b57cec5SDimitry Andric
6730b57cec5SDimitry Andric // If we popped the outermost skipping block, we're done skipping!
6740b57cec5SDimitry Andric if (!CondInfo.WasSkipping) {
67581ad6265SDimitry Andric SkippingRangeState.endLexPass(Hashptr);
6760b57cec5SDimitry Andric // Restore the value of LexingRawMode so that trailing comments
6770b57cec5SDimitry Andric // are handled correctly, if we've reached the outermost block.
6780b57cec5SDimitry Andric CurPPLexer->LexingRawMode = false;
6795ffd83dbSDimitry Andric endLoc = CheckEndOfDirective("endif");
6800b57cec5SDimitry Andric CurPPLexer->LexingRawMode = true;
6810b57cec5SDimitry Andric if (Callbacks)
6820b57cec5SDimitry Andric Callbacks->Endif(Tok.getLocation(), CondInfo.IfLoc);
6830b57cec5SDimitry Andric break;
6840b57cec5SDimitry Andric } else {
6850b57cec5SDimitry Andric DiscardUntilEndOfDirective();
6860b57cec5SDimitry Andric }
6870b57cec5SDimitry Andric } else if (Sub == "lse") { // "else".
6880b57cec5SDimitry Andric // #else directive in a skipping conditional. If not in some other
6890b57cec5SDimitry Andric // skipping conditional, and if #else hasn't already been seen, enter it
6900b57cec5SDimitry Andric // as a non-skipping conditional.
6910b57cec5SDimitry Andric PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
6920b57cec5SDimitry Andric
69381ad6265SDimitry Andric if (!CondInfo.WasSkipping)
69481ad6265SDimitry Andric SkippingRangeState.endLexPass(Hashptr);
69581ad6265SDimitry Andric
6960b57cec5SDimitry Andric // If this is a #else with a #else before it, report the error.
697fe6060f1SDimitry Andric if (CondInfo.FoundElse)
698fe6060f1SDimitry Andric Diag(Tok, diag::pp_err_else_after_else);
6990b57cec5SDimitry Andric
7000b57cec5SDimitry Andric // Note that we've seen a #else in this conditional.
7010b57cec5SDimitry Andric CondInfo.FoundElse = true;
7020b57cec5SDimitry Andric
7030b57cec5SDimitry Andric // If the conditional is at the top level, and the #if block wasn't
7040b57cec5SDimitry Andric // entered, enter the #else block now.
7050b57cec5SDimitry Andric if (!CondInfo.WasSkipping && !CondInfo.FoundNonSkip) {
7060b57cec5SDimitry Andric CondInfo.FoundNonSkip = true;
7070b57cec5SDimitry Andric // Restore the value of LexingRawMode so that trailing comments
7080b57cec5SDimitry Andric // are handled correctly.
7090b57cec5SDimitry Andric CurPPLexer->LexingRawMode = false;
7105ffd83dbSDimitry Andric endLoc = CheckEndOfDirective("else");
7110b57cec5SDimitry Andric CurPPLexer->LexingRawMode = true;
7120b57cec5SDimitry Andric if (Callbacks)
7130b57cec5SDimitry Andric Callbacks->Else(Tok.getLocation(), CondInfo.IfLoc);
7140b57cec5SDimitry Andric break;
7150b57cec5SDimitry Andric } else {
7160b57cec5SDimitry Andric DiscardUntilEndOfDirective(); // C99 6.10p4.
7170b57cec5SDimitry Andric }
7180b57cec5SDimitry Andric } else if (Sub == "lif") { // "elif".
7190b57cec5SDimitry Andric PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
7200b57cec5SDimitry Andric
72181ad6265SDimitry Andric if (!CondInfo.WasSkipping)
72281ad6265SDimitry Andric SkippingRangeState.endLexPass(Hashptr);
72381ad6265SDimitry Andric
7240b57cec5SDimitry Andric // If this is a #elif with a #else before it, report the error.
725fe6060f1SDimitry Andric if (CondInfo.FoundElse)
726fe6060f1SDimitry Andric Diag(Tok, diag::pp_err_elif_after_else) << PED_Elif;
7270b57cec5SDimitry Andric
7280b57cec5SDimitry Andric // If this is in a skipping block or if we're already handled this #if
7290b57cec5SDimitry Andric // block, don't bother parsing the condition.
7300b57cec5SDimitry Andric if (CondInfo.WasSkipping || CondInfo.FoundNonSkip) {
731349cc55cSDimitry Andric // FIXME: We should probably do at least some minimal parsing of the
732349cc55cSDimitry Andric // condition to verify that it is well-formed. The current state
733349cc55cSDimitry Andric // allows #elif* directives with completely malformed (or missing)
734349cc55cSDimitry Andric // conditions.
7350b57cec5SDimitry Andric DiscardUntilEndOfDirective();
7360b57cec5SDimitry Andric } else {
7370b57cec5SDimitry Andric // Restore the value of LexingRawMode so that identifiers are
7380b57cec5SDimitry Andric // looked up, etc, inside the #elif expression.
7390b57cec5SDimitry Andric assert(CurPPLexer->LexingRawMode && "We have to be skipping here!");
7400b57cec5SDimitry Andric CurPPLexer->LexingRawMode = false;
7410b57cec5SDimitry Andric IdentifierInfo *IfNDefMacro = nullptr;
7420b57cec5SDimitry Andric DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
743fe6060f1SDimitry Andric // Stop if Lexer became invalid after hitting code completion token.
744fe6060f1SDimitry Andric if (!CurPPLexer)
745fe6060f1SDimitry Andric return;
7460b57cec5SDimitry Andric const bool CondValue = DER.Conditional;
7470b57cec5SDimitry Andric CurPPLexer->LexingRawMode = true;
7480b57cec5SDimitry Andric if (Callbacks) {
7490b57cec5SDimitry Andric Callbacks->Elif(
7500b57cec5SDimitry Andric Tok.getLocation(), DER.ExprRange,
7510b57cec5SDimitry Andric (CondValue ? PPCallbacks::CVK_True : PPCallbacks::CVK_False),
7520b57cec5SDimitry Andric CondInfo.IfLoc);
7530b57cec5SDimitry Andric }
7540b57cec5SDimitry Andric // If this condition is true, enter it!
7550b57cec5SDimitry Andric if (CondValue) {
7560b57cec5SDimitry Andric CondInfo.FoundNonSkip = true;
7570b57cec5SDimitry Andric break;
7580b57cec5SDimitry Andric }
7590b57cec5SDimitry Andric }
760fe6060f1SDimitry Andric } else if (Sub == "lifdef" || // "elifdef"
761fe6060f1SDimitry Andric Sub == "lifndef") { // "elifndef"
762fe6060f1SDimitry Andric bool IsElifDef = Sub == "lifdef";
763fe6060f1SDimitry Andric PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
764fe6060f1SDimitry Andric Token DirectiveToken = Tok;
765fe6060f1SDimitry Andric
76681ad6265SDimitry Andric if (!CondInfo.WasSkipping)
76781ad6265SDimitry Andric SkippingRangeState.endLexPass(Hashptr);
76881ad6265SDimitry Andric
7695f757f3fSDimitry Andric // Warn if using `#elifdef` & `#elifndef` in not C23 & C++23 mode even
77081ad6265SDimitry Andric // if this branch is in a skipping block.
77181ad6265SDimitry Andric unsigned DiagID;
77281ad6265SDimitry Andric if (LangOpts.CPlusPlus)
77306c3fb27SDimitry Andric DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
77406c3fb27SDimitry Andric : diag::ext_cxx23_pp_directive;
77581ad6265SDimitry Andric else
7765f757f3fSDimitry Andric DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
7775f757f3fSDimitry Andric : diag::ext_c23_pp_directive;
77881ad6265SDimitry Andric Diag(Tok, DiagID) << (IsElifDef ? PED_Elifdef : PED_Elifndef);
77981ad6265SDimitry Andric
780fe6060f1SDimitry Andric // If this is a #elif with a #else before it, report the error.
781fe6060f1SDimitry Andric if (CondInfo.FoundElse)
782fe6060f1SDimitry Andric Diag(Tok, diag::pp_err_elif_after_else)
783fe6060f1SDimitry Andric << (IsElifDef ? PED_Elifdef : PED_Elifndef);
784fe6060f1SDimitry Andric
785fe6060f1SDimitry Andric // If this is in a skipping block or if we're already handled this #if
786fe6060f1SDimitry Andric // block, don't bother parsing the condition.
787fe6060f1SDimitry Andric if (CondInfo.WasSkipping || CondInfo.FoundNonSkip) {
788349cc55cSDimitry Andric // FIXME: We should probably do at least some minimal parsing of the
789349cc55cSDimitry Andric // condition to verify that it is well-formed. The current state
790349cc55cSDimitry Andric // allows #elif* directives with completely malformed (or missing)
791349cc55cSDimitry Andric // conditions.
792fe6060f1SDimitry Andric DiscardUntilEndOfDirective();
793fe6060f1SDimitry Andric } else {
794fe6060f1SDimitry Andric // Restore the value of LexingRawMode so that identifiers are
795fe6060f1SDimitry Andric // looked up, etc, inside the #elif[n]def expression.
796fe6060f1SDimitry Andric assert(CurPPLexer->LexingRawMode && "We have to be skipping here!");
797fe6060f1SDimitry Andric CurPPLexer->LexingRawMode = false;
798fe6060f1SDimitry Andric Token MacroNameTok;
799fe6060f1SDimitry Andric ReadMacroName(MacroNameTok);
800fe6060f1SDimitry Andric CurPPLexer->LexingRawMode = true;
801fe6060f1SDimitry Andric
802fe6060f1SDimitry Andric // If the macro name token is tok::eod, there was an error that was
803fe6060f1SDimitry Andric // already reported.
804fe6060f1SDimitry Andric if (MacroNameTok.is(tok::eod)) {
805fe6060f1SDimitry Andric // Skip code until we get to #endif. This helps with recovery by
806fe6060f1SDimitry Andric // not emitting an error when the #endif is reached.
807fe6060f1SDimitry Andric continue;
808fe6060f1SDimitry Andric }
809fe6060f1SDimitry Andric
810349cc55cSDimitry Andric emitMacroExpansionWarnings(MacroNameTok);
811349cc55cSDimitry Andric
812fe6060f1SDimitry Andric CheckEndOfDirective(IsElifDef ? "elifdef" : "elifndef");
813fe6060f1SDimitry Andric
814fe6060f1SDimitry Andric IdentifierInfo *MII = MacroNameTok.getIdentifierInfo();
815fe6060f1SDimitry Andric auto MD = getMacroDefinition(MII);
816fe6060f1SDimitry Andric MacroInfo *MI = MD.getMacroInfo();
817fe6060f1SDimitry Andric
818fe6060f1SDimitry Andric if (Callbacks) {
819fe6060f1SDimitry Andric if (IsElifDef) {
820fe6060f1SDimitry Andric Callbacks->Elifdef(DirectiveToken.getLocation(), MacroNameTok,
821fe6060f1SDimitry Andric MD);
822fe6060f1SDimitry Andric } else {
823fe6060f1SDimitry Andric Callbacks->Elifndef(DirectiveToken.getLocation(), MacroNameTok,
824fe6060f1SDimitry Andric MD);
825fe6060f1SDimitry Andric }
826fe6060f1SDimitry Andric }
827fe6060f1SDimitry Andric // If this condition is true, enter it!
828fe6060f1SDimitry Andric if (static_cast<bool>(MI) == IsElifDef) {
829fe6060f1SDimitry Andric CondInfo.FoundNonSkip = true;
830fe6060f1SDimitry Andric break;
831fe6060f1SDimitry Andric }
832fe6060f1SDimitry Andric }
83381ad6265SDimitry Andric } else {
83481ad6265SDimitry Andric SuggestTypoedDirective(Tok, Directive);
8350b57cec5SDimitry Andric }
83681ad6265SDimitry Andric } else {
83781ad6265SDimitry Andric SuggestTypoedDirective(Tok, Directive);
8380b57cec5SDimitry Andric }
8390b57cec5SDimitry Andric
8400b57cec5SDimitry Andric CurPPLexer->ParsingPreprocessorDirective = false;
8410b57cec5SDimitry Andric // Restore comment saving mode.
8420b57cec5SDimitry Andric if (CurLexer) CurLexer->resetExtendedTokenMode();
8430b57cec5SDimitry Andric }
8440b57cec5SDimitry Andric
8450b57cec5SDimitry Andric // Finally, if we are out of the conditional (saw an #endif or ran off the end
8460b57cec5SDimitry Andric // of the file, just stop skipping and return to lexing whatever came after
8470b57cec5SDimitry Andric // the #if block.
8480b57cec5SDimitry Andric CurPPLexer->LexingRawMode = false;
8490b57cec5SDimitry Andric
8500b57cec5SDimitry Andric // The last skipped range isn't actually skipped yet if it's truncated
8510b57cec5SDimitry Andric // by the end of the preamble; we'll resume parsing after the preamble.
8520b57cec5SDimitry Andric if (Callbacks && (Tok.isNot(tok::eof) || !isRecordingPreamble()))
8530b57cec5SDimitry Andric Callbacks->SourceRangeSkipped(
8545ffd83dbSDimitry Andric SourceRange(HashTokenLoc, endLoc.isValid()
8555ffd83dbSDimitry Andric ? endLoc
8565ffd83dbSDimitry Andric : CurPPLexer->getSourceLocation()),
8570b57cec5SDimitry Andric Tok.getLocation());
8580b57cec5SDimitry Andric }
8590b57cec5SDimitry Andric
getModuleForLocation(SourceLocation Loc,bool AllowTextual)860bdd1243dSDimitry Andric Module *Preprocessor::getModuleForLocation(SourceLocation Loc,
861bdd1243dSDimitry Andric bool AllowTextual) {
8620b57cec5SDimitry Andric if (!SourceMgr.isInMainFile(Loc)) {
8630b57cec5SDimitry Andric // Try to determine the module of the include directive.
8640b57cec5SDimitry Andric // FIXME: Look into directly passing the FileEntry from LookupFile instead.
8650b57cec5SDimitry Andric FileID IDOfIncl = SourceMgr.getFileID(SourceMgr.getExpansionLoc(Loc));
86606c3fb27SDimitry Andric if (auto EntryOfIncl = SourceMgr.getFileEntryRefForID(IDOfIncl)) {
8670b57cec5SDimitry Andric // The include comes from an included file.
8680b57cec5SDimitry Andric return HeaderInfo.getModuleMap()
86906c3fb27SDimitry Andric .findModuleForHeader(*EntryOfIncl, AllowTextual)
8700b57cec5SDimitry Andric .getModule();
8710b57cec5SDimitry Andric }
8720b57cec5SDimitry Andric }
8730b57cec5SDimitry Andric
8740b57cec5SDimitry Andric // This is either in the main file or not in a file at all. It belongs
8750b57cec5SDimitry Andric // to the current module, if there is one.
8760b57cec5SDimitry Andric return getLangOpts().CurrentModule.empty()
8770b57cec5SDimitry Andric ? nullptr
878349cc55cSDimitry Andric : HeaderInfo.lookupModule(getLangOpts().CurrentModule, Loc);
8790b57cec5SDimitry Andric }
8800b57cec5SDimitry Andric
8815f757f3fSDimitry Andric OptionalFileEntryRef
getHeaderToIncludeForDiagnostics(SourceLocation IncLoc,SourceLocation Loc)8825ffd83dbSDimitry Andric Preprocessor::getHeaderToIncludeForDiagnostics(SourceLocation IncLoc,
8830b57cec5SDimitry Andric SourceLocation Loc) {
884bdd1243dSDimitry Andric Module *IncM = getModuleForLocation(
885bdd1243dSDimitry Andric IncLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
8860b57cec5SDimitry Andric
8870b57cec5SDimitry Andric // Walk up through the include stack, looking through textual headers of M
8880b57cec5SDimitry Andric // until we hit a non-textual header that we can #include. (We assume textual
8890b57cec5SDimitry Andric // headers of a module with non-textual headers aren't meant to be used to
8900b57cec5SDimitry Andric // import entities from the module.)
8910b57cec5SDimitry Andric auto &SM = getSourceManager();
8920b57cec5SDimitry Andric while (!Loc.isInvalid() && !SM.isInMainFile(Loc)) {
8930b57cec5SDimitry Andric auto ID = SM.getFileID(SM.getExpansionLoc(Loc));
89406c3fb27SDimitry Andric auto FE = SM.getFileEntryRefForID(ID);
8950b57cec5SDimitry Andric if (!FE)
8960b57cec5SDimitry Andric break;
8970b57cec5SDimitry Andric
8985ffd83dbSDimitry Andric // We want to find all possible modules that might contain this header, so
8995ffd83dbSDimitry Andric // search all enclosing directories for module maps and load them.
9005ffd83dbSDimitry Andric HeaderInfo.hasModuleMap(FE->getName(), /*Root*/ nullptr,
9015ffd83dbSDimitry Andric SourceMgr.isInSystemHeader(Loc));
9020b57cec5SDimitry Andric
9035ffd83dbSDimitry Andric bool InPrivateHeader = false;
90406c3fb27SDimitry Andric for (auto Header : HeaderInfo.findAllModulesForHeader(*FE)) {
9055ffd83dbSDimitry Andric if (!Header.isAccessibleFrom(IncM)) {
9060b57cec5SDimitry Andric // It's in a private header; we can't #include it.
9070b57cec5SDimitry Andric // FIXME: If there's a public header in some module that re-exports it,
9080b57cec5SDimitry Andric // then we could suggest including that, but it's not clear that's the
9090b57cec5SDimitry Andric // expected way to make this entity visible.
9105ffd83dbSDimitry Andric InPrivateHeader = true;
9110b57cec5SDimitry Andric continue;
9120b57cec5SDimitry Andric }
9130b57cec5SDimitry Andric
914bdd1243dSDimitry Andric // Don't suggest explicitly excluded headers.
915bdd1243dSDimitry Andric if (Header.getRole() == ModuleMap::ExcludedHeader)
916bdd1243dSDimitry Andric continue;
917bdd1243dSDimitry Andric
9185ffd83dbSDimitry Andric // We'll suggest including textual headers below if they're
9195ffd83dbSDimitry Andric // include-guarded.
9205ffd83dbSDimitry Andric if (Header.getRole() & ModuleMap::TextualHeader)
9215ffd83dbSDimitry Andric continue;
9225ffd83dbSDimitry Andric
9235ffd83dbSDimitry Andric // If we have a module import syntax, we shouldn't include a header to
9245ffd83dbSDimitry Andric // make a particular module visible. Let the caller know they should
9255ffd83dbSDimitry Andric // suggest an import instead.
92606c3fb27SDimitry Andric if (getLangOpts().ObjC || getLangOpts().CPlusPlusModules)
9275f757f3fSDimitry Andric return std::nullopt;
9285ffd83dbSDimitry Andric
9295ffd83dbSDimitry Andric // If this is an accessible, non-textual header of M's top-level module
9305ffd83dbSDimitry Andric // that transitively includes the given location and makes the
9315ffd83dbSDimitry Andric // corresponding module visible, this is the thing to #include.
93206c3fb27SDimitry Andric return *FE;
9330b57cec5SDimitry Andric }
9340b57cec5SDimitry Andric
9355ffd83dbSDimitry Andric // FIXME: If we're bailing out due to a private header, we shouldn't suggest
9365ffd83dbSDimitry Andric // an import either.
9375ffd83dbSDimitry Andric if (InPrivateHeader)
9385f757f3fSDimitry Andric return std::nullopt;
9395ffd83dbSDimitry Andric
9405ffd83dbSDimitry Andric // If the header is includable and has an include guard, assume the
9415ffd83dbSDimitry Andric // intended way to expose its contents is by #include, not by importing a
9425ffd83dbSDimitry Andric // module that transitively includes it.
94306c3fb27SDimitry Andric if (getHeaderSearchInfo().isFileMultipleIncludeGuarded(*FE))
94406c3fb27SDimitry Andric return *FE;
9450b57cec5SDimitry Andric
9460b57cec5SDimitry Andric Loc = SM.getIncludeLoc(ID);
9470b57cec5SDimitry Andric }
9480b57cec5SDimitry Andric
9495f757f3fSDimitry Andric return std::nullopt;
9500b57cec5SDimitry Andric }
9510b57cec5SDimitry Andric
LookupFile(SourceLocation FilenameLoc,StringRef Filename,bool isAngled,ConstSearchDirIterator FromDir,const FileEntry * FromFile,ConstSearchDirIterator * CurDirArg,SmallVectorImpl<char> * SearchPath,SmallVectorImpl<char> * RelativePath,ModuleMap::KnownHeader * SuggestedModule,bool * IsMapped,bool * IsFrameworkFound,bool SkipCache,bool OpenFile,bool CacheFailures)952bdd1243dSDimitry Andric OptionalFileEntryRef Preprocessor::LookupFile(
9530b57cec5SDimitry Andric SourceLocation FilenameLoc, StringRef Filename, bool isAngled,
95481ad6265SDimitry Andric ConstSearchDirIterator FromDir, const FileEntry *FromFile,
95581ad6265SDimitry Andric ConstSearchDirIterator *CurDirArg, SmallVectorImpl<char> *SearchPath,
9560b57cec5SDimitry Andric SmallVectorImpl<char> *RelativePath,
9570b57cec5SDimitry Andric ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped,
958bdd1243dSDimitry Andric bool *IsFrameworkFound, bool SkipCache, bool OpenFile, bool CacheFailures) {
95981ad6265SDimitry Andric ConstSearchDirIterator CurDirLocal = nullptr;
96081ad6265SDimitry Andric ConstSearchDirIterator &CurDir = CurDirArg ? *CurDirArg : CurDirLocal;
96104eeddc0SDimitry Andric
962bdd1243dSDimitry Andric Module *RequestingModule = getModuleForLocation(
963bdd1243dSDimitry Andric FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
9640b57cec5SDimitry Andric
9650b57cec5SDimitry Andric // If the header lookup mechanism may be relative to the current inclusion
9660b57cec5SDimitry Andric // stack, record the parent #includes.
9675f757f3fSDimitry Andric SmallVector<std::pair<OptionalFileEntryRef, DirectoryEntryRef>, 16> Includers;
9680b57cec5SDimitry Andric bool BuildSystemModule = false;
9690b57cec5SDimitry Andric if (!FromDir && !FromFile) {
9700b57cec5SDimitry Andric FileID FID = getCurrentFileLexer()->getFileID();
97106c3fb27SDimitry Andric OptionalFileEntryRef FileEnt = SourceMgr.getFileEntryRefForID(FID);
9720b57cec5SDimitry Andric
9730b57cec5SDimitry Andric // If there is no file entry associated with this file, it must be the
9740b57cec5SDimitry Andric // predefines buffer or the module includes buffer. Any other file is not
9750b57cec5SDimitry Andric // lexed with a normal lexer, so it won't be scanned for preprocessor
9760b57cec5SDimitry Andric // directives.
9770b57cec5SDimitry Andric //
9780b57cec5SDimitry Andric // If we have the predefines buffer, resolve #include references (which come
9790b57cec5SDimitry Andric // from the -include command line argument) from the current working
9800b57cec5SDimitry Andric // directory instead of relative to the main file.
9810b57cec5SDimitry Andric //
9820b57cec5SDimitry Andric // If we have the module includes buffer, resolve #include references (which
9830b57cec5SDimitry Andric // come from header declarations in the module map) relative to the module
9840b57cec5SDimitry Andric // map file.
9850b57cec5SDimitry Andric if (!FileEnt) {
9860b57cec5SDimitry Andric if (FID == SourceMgr.getMainFileID() && MainFileDir) {
9875f757f3fSDimitry Andric auto IncludeDir =
9885f757f3fSDimitry Andric HeaderInfo.getModuleMap().shouldImportRelativeToBuiltinIncludeDir(
9895f757f3fSDimitry Andric Filename, getCurrentModule())
9905f757f3fSDimitry Andric ? HeaderInfo.getModuleMap().getBuiltinDir()
9915f757f3fSDimitry Andric : MainFileDir;
9925f757f3fSDimitry Andric Includers.push_back(std::make_pair(std::nullopt, *IncludeDir));
9930b57cec5SDimitry Andric BuildSystemModule = getCurrentModule()->IsSystem;
99406c3fb27SDimitry Andric } else if ((FileEnt = SourceMgr.getFileEntryRefForID(
99506c3fb27SDimitry Andric SourceMgr.getMainFileID()))) {
99606c3fb27SDimitry Andric auto CWD = FileMgr.getOptionalDirectoryRef(".");
99706c3fb27SDimitry Andric Includers.push_back(std::make_pair(*FileEnt, *CWD));
99806c3fb27SDimitry Andric }
9990b57cec5SDimitry Andric } else {
100006c3fb27SDimitry Andric Includers.push_back(std::make_pair(*FileEnt, FileEnt->getDir()));
10010b57cec5SDimitry Andric }
10020b57cec5SDimitry Andric
10030b57cec5SDimitry Andric // MSVC searches the current include stack from top to bottom for
10040b57cec5SDimitry Andric // headers included by quoted include directives.
10050b57cec5SDimitry Andric // See: http://msdn.microsoft.com/en-us/library/36k2cdd4.aspx
10060b57cec5SDimitry Andric if (LangOpts.MSVCCompat && !isAngled) {
10070b57cec5SDimitry Andric for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
10080b57cec5SDimitry Andric if (IsFileLexer(ISEntry))
10090b57cec5SDimitry Andric if ((FileEnt = ISEntry.ThePPLexer->getFileEntry()))
101006c3fb27SDimitry Andric Includers.push_back(std::make_pair(*FileEnt, FileEnt->getDir()));
10110b57cec5SDimitry Andric }
10120b57cec5SDimitry Andric }
10130b57cec5SDimitry Andric }
10140b57cec5SDimitry Andric
10150b57cec5SDimitry Andric CurDir = CurDirLookup;
10160b57cec5SDimitry Andric
10170b57cec5SDimitry Andric if (FromFile) {
10180b57cec5SDimitry Andric // We're supposed to start looking from after a particular file. Search
10190b57cec5SDimitry Andric // the include path until we find that file or run out of files.
102081ad6265SDimitry Andric ConstSearchDirIterator TmpCurDir = CurDir;
102181ad6265SDimitry Andric ConstSearchDirIterator TmpFromDir = nullptr;
1022bdd1243dSDimitry Andric while (OptionalFileEntryRef FE = HeaderInfo.LookupFile(
102304eeddc0SDimitry Andric Filename, FilenameLoc, isAngled, TmpFromDir, &TmpCurDir,
10240b57cec5SDimitry Andric Includers, SearchPath, RelativePath, RequestingModule,
10250b57cec5SDimitry Andric SuggestedModule, /*IsMapped=*/nullptr,
10260b57cec5SDimitry Andric /*IsFrameworkFound=*/nullptr, SkipCache)) {
10270b57cec5SDimitry Andric // Keep looking as if this file did a #include_next.
10280b57cec5SDimitry Andric TmpFromDir = TmpCurDir;
10290b57cec5SDimitry Andric ++TmpFromDir;
1030a7dea167SDimitry Andric if (&FE->getFileEntry() == FromFile) {
10310b57cec5SDimitry Andric // Found it.
10320b57cec5SDimitry Andric FromDir = TmpFromDir;
10330b57cec5SDimitry Andric CurDir = TmpCurDir;
10340b57cec5SDimitry Andric break;
10350b57cec5SDimitry Andric }
10360b57cec5SDimitry Andric }
10370b57cec5SDimitry Andric }
10380b57cec5SDimitry Andric
10390b57cec5SDimitry Andric // Do a standard file entry lookup.
1040bdd1243dSDimitry Andric OptionalFileEntryRef FE = HeaderInfo.LookupFile(
104104eeddc0SDimitry Andric Filename, FilenameLoc, isAngled, FromDir, &CurDir, Includers, SearchPath,
10420b57cec5SDimitry Andric RelativePath, RequestingModule, SuggestedModule, IsMapped,
1043bdd1243dSDimitry Andric IsFrameworkFound, SkipCache, BuildSystemModule, OpenFile, CacheFailures);
10445f757f3fSDimitry Andric if (FE)
10450b57cec5SDimitry Andric return FE;
10460b57cec5SDimitry Andric
10475f757f3fSDimitry Andric OptionalFileEntryRef CurFileEnt;
10480b57cec5SDimitry Andric // Otherwise, see if this is a subframework header. If so, this is relative
10490b57cec5SDimitry Andric // to one of the headers on the #include stack. Walk the list of the current
10500b57cec5SDimitry Andric // headers on the #include stack and pass them to HeaderInfo.
10510b57cec5SDimitry Andric if (IsFileLexer()) {
10520b57cec5SDimitry Andric if ((CurFileEnt = CurPPLexer->getFileEntry())) {
1053bdd1243dSDimitry Andric if (OptionalFileEntryRef FE = HeaderInfo.LookupSubframeworkHeader(
10545f757f3fSDimitry Andric Filename, *CurFileEnt, SearchPath, RelativePath, RequestingModule,
1055a7dea167SDimitry Andric SuggestedModule)) {
10560b57cec5SDimitry Andric return FE;
10570b57cec5SDimitry Andric }
10580b57cec5SDimitry Andric }
10590b57cec5SDimitry Andric }
10600b57cec5SDimitry Andric
10610b57cec5SDimitry Andric for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
10620b57cec5SDimitry Andric if (IsFileLexer(ISEntry)) {
10630b57cec5SDimitry Andric if ((CurFileEnt = ISEntry.ThePPLexer->getFileEntry())) {
1064bdd1243dSDimitry Andric if (OptionalFileEntryRef FE = HeaderInfo.LookupSubframeworkHeader(
10655f757f3fSDimitry Andric Filename, *CurFileEnt, SearchPath, RelativePath,
1066a7dea167SDimitry Andric RequestingModule, SuggestedModule)) {
10670b57cec5SDimitry Andric return FE;
10680b57cec5SDimitry Andric }
10690b57cec5SDimitry Andric }
10700b57cec5SDimitry Andric }
10710b57cec5SDimitry Andric }
10720b57cec5SDimitry Andric
10730b57cec5SDimitry Andric // Otherwise, we really couldn't find the file.
1074bdd1243dSDimitry Andric return std::nullopt;
10750b57cec5SDimitry Andric }
10760b57cec5SDimitry Andric
1077*0fca6ea1SDimitry Andric OptionalFileEntryRef
LookupEmbedFile(StringRef Filename,bool isAngled,bool OpenFile,const FileEntry * LookupFromFile)1078*0fca6ea1SDimitry Andric Preprocessor::LookupEmbedFile(StringRef Filename, bool isAngled, bool OpenFile,
1079*0fca6ea1SDimitry Andric const FileEntry *LookupFromFile) {
1080*0fca6ea1SDimitry Andric FileManager &FM = this->getFileManager();
1081*0fca6ea1SDimitry Andric if (llvm::sys::path::is_absolute(Filename)) {
1082*0fca6ea1SDimitry Andric // lookup path or immediately fail
1083*0fca6ea1SDimitry Andric llvm::Expected<FileEntryRef> ShouldBeEntry =
1084*0fca6ea1SDimitry Andric FM.getFileRef(Filename, OpenFile);
1085*0fca6ea1SDimitry Andric return llvm::expectedToOptional(std::move(ShouldBeEntry));
1086*0fca6ea1SDimitry Andric }
1087*0fca6ea1SDimitry Andric
1088*0fca6ea1SDimitry Andric auto SeparateComponents = [](SmallVectorImpl<char> &LookupPath,
1089*0fca6ea1SDimitry Andric StringRef StartingFrom, StringRef FileName,
1090*0fca6ea1SDimitry Andric bool RemoveInitialFileComponentFromLookupPath) {
1091*0fca6ea1SDimitry Andric llvm::sys::path::native(StartingFrom, LookupPath);
1092*0fca6ea1SDimitry Andric if (RemoveInitialFileComponentFromLookupPath)
1093*0fca6ea1SDimitry Andric llvm::sys::path::remove_filename(LookupPath);
1094*0fca6ea1SDimitry Andric if (!LookupPath.empty() &&
1095*0fca6ea1SDimitry Andric !llvm::sys::path::is_separator(LookupPath.back())) {
1096*0fca6ea1SDimitry Andric LookupPath.push_back(llvm::sys::path::get_separator().front());
1097*0fca6ea1SDimitry Andric }
1098*0fca6ea1SDimitry Andric LookupPath.append(FileName.begin(), FileName.end());
1099*0fca6ea1SDimitry Andric };
1100*0fca6ea1SDimitry Andric
1101*0fca6ea1SDimitry Andric // Otherwise, it's search time!
1102*0fca6ea1SDimitry Andric SmallString<512> LookupPath;
1103*0fca6ea1SDimitry Andric // Non-angled lookup
1104*0fca6ea1SDimitry Andric if (!isAngled) {
1105*0fca6ea1SDimitry Andric if (LookupFromFile) {
1106*0fca6ea1SDimitry Andric // Use file-based lookup.
1107*0fca6ea1SDimitry Andric StringRef FullFileDir = LookupFromFile->tryGetRealPathName();
1108*0fca6ea1SDimitry Andric if (!FullFileDir.empty()) {
1109*0fca6ea1SDimitry Andric SeparateComponents(LookupPath, FullFileDir, Filename, true);
1110*0fca6ea1SDimitry Andric llvm::Expected<FileEntryRef> ShouldBeEntry =
1111*0fca6ea1SDimitry Andric FM.getFileRef(LookupPath, OpenFile);
1112*0fca6ea1SDimitry Andric if (ShouldBeEntry)
1113*0fca6ea1SDimitry Andric return llvm::expectedToOptional(std::move(ShouldBeEntry));
1114*0fca6ea1SDimitry Andric llvm::consumeError(ShouldBeEntry.takeError());
1115*0fca6ea1SDimitry Andric }
1116*0fca6ea1SDimitry Andric }
1117*0fca6ea1SDimitry Andric
1118*0fca6ea1SDimitry Andric // Otherwise, do working directory lookup.
1119*0fca6ea1SDimitry Andric LookupPath.clear();
1120*0fca6ea1SDimitry Andric auto MaybeWorkingDirEntry = FM.getDirectoryRef(".");
1121*0fca6ea1SDimitry Andric if (MaybeWorkingDirEntry) {
1122*0fca6ea1SDimitry Andric DirectoryEntryRef WorkingDirEntry = *MaybeWorkingDirEntry;
1123*0fca6ea1SDimitry Andric StringRef WorkingDir = WorkingDirEntry.getName();
1124*0fca6ea1SDimitry Andric if (!WorkingDir.empty()) {
1125*0fca6ea1SDimitry Andric SeparateComponents(LookupPath, WorkingDir, Filename, false);
1126*0fca6ea1SDimitry Andric llvm::Expected<FileEntryRef> ShouldBeEntry =
1127*0fca6ea1SDimitry Andric FM.getFileRef(LookupPath, OpenFile);
1128*0fca6ea1SDimitry Andric if (ShouldBeEntry)
1129*0fca6ea1SDimitry Andric return llvm::expectedToOptional(std::move(ShouldBeEntry));
1130*0fca6ea1SDimitry Andric llvm::consumeError(ShouldBeEntry.takeError());
1131*0fca6ea1SDimitry Andric }
1132*0fca6ea1SDimitry Andric }
1133*0fca6ea1SDimitry Andric }
1134*0fca6ea1SDimitry Andric
1135*0fca6ea1SDimitry Andric for (const auto &Entry : PPOpts->EmbedEntries) {
1136*0fca6ea1SDimitry Andric LookupPath.clear();
1137*0fca6ea1SDimitry Andric SeparateComponents(LookupPath, Entry, Filename, false);
1138*0fca6ea1SDimitry Andric llvm::Expected<FileEntryRef> ShouldBeEntry =
1139*0fca6ea1SDimitry Andric FM.getFileRef(LookupPath, OpenFile);
1140*0fca6ea1SDimitry Andric if (ShouldBeEntry)
1141*0fca6ea1SDimitry Andric return llvm::expectedToOptional(std::move(ShouldBeEntry));
1142*0fca6ea1SDimitry Andric llvm::consumeError(ShouldBeEntry.takeError());
1143*0fca6ea1SDimitry Andric }
1144*0fca6ea1SDimitry Andric return std::nullopt;
1145*0fca6ea1SDimitry Andric }
1146*0fca6ea1SDimitry Andric
11470b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11480b57cec5SDimitry Andric // Preprocessor Directive Handling.
11490b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11500b57cec5SDimitry Andric
11510b57cec5SDimitry Andric class Preprocessor::ResetMacroExpansionHelper {
11520b57cec5SDimitry Andric public:
ResetMacroExpansionHelper(Preprocessor * pp)11530b57cec5SDimitry Andric ResetMacroExpansionHelper(Preprocessor *pp)
11540b57cec5SDimitry Andric : PP(pp), save(pp->DisableMacroExpansion) {
11550b57cec5SDimitry Andric if (pp->MacroExpansionInDirectivesOverride)
11560b57cec5SDimitry Andric pp->DisableMacroExpansion = false;
11570b57cec5SDimitry Andric }
11580b57cec5SDimitry Andric
~ResetMacroExpansionHelper()11590b57cec5SDimitry Andric ~ResetMacroExpansionHelper() {
11600b57cec5SDimitry Andric PP->DisableMacroExpansion = save;
11610b57cec5SDimitry Andric }
11620b57cec5SDimitry Andric
11630b57cec5SDimitry Andric private:
11640b57cec5SDimitry Andric Preprocessor *PP;
11650b57cec5SDimitry Andric bool save;
11660b57cec5SDimitry Andric };
11670b57cec5SDimitry Andric
11680b57cec5SDimitry Andric /// Process a directive while looking for the through header or a #pragma
11690b57cec5SDimitry Andric /// hdrstop. The following directives are handled:
11700b57cec5SDimitry Andric /// #include (to check if it is the through header)
11710b57cec5SDimitry Andric /// #define (to warn about macros that don't match the PCH)
11720b57cec5SDimitry Andric /// #pragma (to check for pragma hdrstop).
11730b57cec5SDimitry Andric /// All other directives are completely discarded.
HandleSkippedDirectiveWhileUsingPCH(Token & Result,SourceLocation HashLoc)11740b57cec5SDimitry Andric void Preprocessor::HandleSkippedDirectiveWhileUsingPCH(Token &Result,
11750b57cec5SDimitry Andric SourceLocation HashLoc) {
11760b57cec5SDimitry Andric if (const IdentifierInfo *II = Result.getIdentifierInfo()) {
11770b57cec5SDimitry Andric if (II->getPPKeywordID() == tok::pp_define) {
11780b57cec5SDimitry Andric return HandleDefineDirective(Result,
11790b57cec5SDimitry Andric /*ImmediatelyAfterHeaderGuard=*/false);
11800b57cec5SDimitry Andric }
11810b57cec5SDimitry Andric if (SkippingUntilPCHThroughHeader &&
11820b57cec5SDimitry Andric II->getPPKeywordID() == tok::pp_include) {
11830b57cec5SDimitry Andric return HandleIncludeDirective(HashLoc, Result);
11840b57cec5SDimitry Andric }
11850b57cec5SDimitry Andric if (SkippingUntilPragmaHdrStop && II->getPPKeywordID() == tok::pp_pragma) {
11860b57cec5SDimitry Andric Lex(Result);
11870b57cec5SDimitry Andric auto *II = Result.getIdentifierInfo();
11880b57cec5SDimitry Andric if (II && II->getName() == "hdrstop")
11890b57cec5SDimitry Andric return HandlePragmaHdrstop(Result);
11900b57cec5SDimitry Andric }
11910b57cec5SDimitry Andric }
11920b57cec5SDimitry Andric DiscardUntilEndOfDirective();
11930b57cec5SDimitry Andric }
11940b57cec5SDimitry Andric
11950b57cec5SDimitry Andric /// HandleDirective - This callback is invoked when the lexer sees a # token
11960b57cec5SDimitry Andric /// at the start of a line. This consumes the directive, modifies the
11970b57cec5SDimitry Andric /// lexer/preprocessor state, and advances the lexer(s) so that the next token
11980b57cec5SDimitry Andric /// read is the correct one.
HandleDirective(Token & Result)11990b57cec5SDimitry Andric void Preprocessor::HandleDirective(Token &Result) {
12000b57cec5SDimitry Andric // FIXME: Traditional: # with whitespace before it not recognized by K&R?
12010b57cec5SDimitry Andric
12020b57cec5SDimitry Andric // We just parsed a # character at the start of a line, so we're in directive
12030b57cec5SDimitry Andric // mode. Tell the lexer this so any newlines we see will be converted into an
12040b57cec5SDimitry Andric // EOD token (which terminates the directive).
12050b57cec5SDimitry Andric CurPPLexer->ParsingPreprocessorDirective = true;
12060b57cec5SDimitry Andric if (CurLexer) CurLexer->SetKeepWhitespaceMode(false);
12070b57cec5SDimitry Andric
12080b57cec5SDimitry Andric bool ImmediatelyAfterTopLevelIfndef =
12090b57cec5SDimitry Andric CurPPLexer->MIOpt.getImmediatelyAfterTopLevelIfndef();
12100b57cec5SDimitry Andric CurPPLexer->MIOpt.resetImmediatelyAfterTopLevelIfndef();
12110b57cec5SDimitry Andric
12120b57cec5SDimitry Andric ++NumDirectives;
12130b57cec5SDimitry Andric
12140b57cec5SDimitry Andric // We are about to read a token. For the multiple-include optimization FA to
12150b57cec5SDimitry Andric // work, we have to remember if we had read any tokens *before* this
12160b57cec5SDimitry Andric // pp-directive.
12170b57cec5SDimitry Andric bool ReadAnyTokensBeforeDirective =CurPPLexer->MIOpt.getHasReadAnyTokensVal();
12180b57cec5SDimitry Andric
12190b57cec5SDimitry Andric // Save the '#' token in case we need to return it later.
12200b57cec5SDimitry Andric Token SavedHash = Result;
12210b57cec5SDimitry Andric
12220b57cec5SDimitry Andric // Read the next token, the directive flavor. This isn't expanded due to
12230b57cec5SDimitry Andric // C99 6.10.3p8.
12240b57cec5SDimitry Andric LexUnexpandedToken(Result);
12250b57cec5SDimitry Andric
12260b57cec5SDimitry Andric // C99 6.10.3p11: Is this preprocessor directive in macro invocation? e.g.:
12270b57cec5SDimitry Andric // #define A(x) #x
12280b57cec5SDimitry Andric // A(abc
12290b57cec5SDimitry Andric // #warning blah
12300b57cec5SDimitry Andric // def)
12310b57cec5SDimitry Andric // If so, the user is relying on undefined behavior, emit a diagnostic. Do
12320b57cec5SDimitry Andric // not support this for #include-like directives, since that can result in
12330b57cec5SDimitry Andric // terrible diagnostics, and does not work in GCC.
12340b57cec5SDimitry Andric if (InMacroArgs) {
12350b57cec5SDimitry Andric if (IdentifierInfo *II = Result.getIdentifierInfo()) {
12360b57cec5SDimitry Andric switch (II->getPPKeywordID()) {
12370b57cec5SDimitry Andric case tok::pp_include:
12380b57cec5SDimitry Andric case tok::pp_import:
12390b57cec5SDimitry Andric case tok::pp_include_next:
12400b57cec5SDimitry Andric case tok::pp___include_macros:
12410b57cec5SDimitry Andric case tok::pp_pragma:
1242*0fca6ea1SDimitry Andric case tok::pp_embed:
12430b57cec5SDimitry Andric Diag(Result, diag::err_embedded_directive) << II->getName();
12440b57cec5SDimitry Andric Diag(*ArgMacro, diag::note_macro_expansion_here)
12450b57cec5SDimitry Andric << ArgMacro->getIdentifierInfo();
12460b57cec5SDimitry Andric DiscardUntilEndOfDirective();
12470b57cec5SDimitry Andric return;
12480b57cec5SDimitry Andric default:
12490b57cec5SDimitry Andric break;
12500b57cec5SDimitry Andric }
12510b57cec5SDimitry Andric }
12520b57cec5SDimitry Andric Diag(Result, diag::ext_embedded_directive);
12530b57cec5SDimitry Andric }
12540b57cec5SDimitry Andric
12550b57cec5SDimitry Andric // Temporarily enable macro expansion if set so
12560b57cec5SDimitry Andric // and reset to previous state when returning from this function.
12570b57cec5SDimitry Andric ResetMacroExpansionHelper helper(this);
12580b57cec5SDimitry Andric
12590b57cec5SDimitry Andric if (SkippingUntilPCHThroughHeader || SkippingUntilPragmaHdrStop)
12600b57cec5SDimitry Andric return HandleSkippedDirectiveWhileUsingPCH(Result, SavedHash.getLocation());
12610b57cec5SDimitry Andric
12620b57cec5SDimitry Andric switch (Result.getKind()) {
12630b57cec5SDimitry Andric case tok::eod:
126406c3fb27SDimitry Andric // Ignore the null directive with regards to the multiple-include
126506c3fb27SDimitry Andric // optimization, i.e. allow the null directive to appear outside of the
126606c3fb27SDimitry Andric // include guard and still enable the multiple-include optimization.
126706c3fb27SDimitry Andric CurPPLexer->MIOpt.SetReadToken(ReadAnyTokensBeforeDirective);
12680b57cec5SDimitry Andric return; // null directive.
12690b57cec5SDimitry Andric case tok::code_completion:
1270fe6060f1SDimitry Andric setCodeCompletionReached();
12710b57cec5SDimitry Andric if (CodeComplete)
12720b57cec5SDimitry Andric CodeComplete->CodeCompleteDirective(
12730b57cec5SDimitry Andric CurPPLexer->getConditionalStackDepth() > 0);
12740b57cec5SDimitry Andric return;
12750b57cec5SDimitry Andric case tok::numeric_constant: // # 7 GNU line marker directive.
127606c3fb27SDimitry Andric // In a .S file "# 4" may be a comment so don't treat it as a preprocessor
127706c3fb27SDimitry Andric // directive. However do permit it in the predefines file, as we use line
127806c3fb27SDimitry Andric // markers to mark the builtin macros as being in a system header.
127906c3fb27SDimitry Andric if (getLangOpts().AsmPreprocessor &&
128006c3fb27SDimitry Andric SourceMgr.getFileID(SavedHash.getLocation()) != getPredefinesFileID())
128106c3fb27SDimitry Andric break;
12820b57cec5SDimitry Andric return HandleDigitDirective(Result);
12830b57cec5SDimitry Andric default:
12840b57cec5SDimitry Andric IdentifierInfo *II = Result.getIdentifierInfo();
12850b57cec5SDimitry Andric if (!II) break; // Not an identifier.
12860b57cec5SDimitry Andric
12870b57cec5SDimitry Andric // Ask what the preprocessor keyword ID is.
12880b57cec5SDimitry Andric switch (II->getPPKeywordID()) {
12890b57cec5SDimitry Andric default: break;
12900b57cec5SDimitry Andric // C99 6.10.1 - Conditional Inclusion.
12910b57cec5SDimitry Andric case tok::pp_if:
12920b57cec5SDimitry Andric return HandleIfDirective(Result, SavedHash, ReadAnyTokensBeforeDirective);
12930b57cec5SDimitry Andric case tok::pp_ifdef:
12940b57cec5SDimitry Andric return HandleIfdefDirective(Result, SavedHash, false,
12950b57cec5SDimitry Andric true /*not valid for miopt*/);
12960b57cec5SDimitry Andric case tok::pp_ifndef:
12970b57cec5SDimitry Andric return HandleIfdefDirective(Result, SavedHash, true,
12980b57cec5SDimitry Andric ReadAnyTokensBeforeDirective);
12990b57cec5SDimitry Andric case tok::pp_elif:
1300fe6060f1SDimitry Andric case tok::pp_elifdef:
1301fe6060f1SDimitry Andric case tok::pp_elifndef:
1302fe6060f1SDimitry Andric return HandleElifFamilyDirective(Result, SavedHash, II->getPPKeywordID());
1303fe6060f1SDimitry Andric
13040b57cec5SDimitry Andric case tok::pp_else:
13050b57cec5SDimitry Andric return HandleElseDirective(Result, SavedHash);
13060b57cec5SDimitry Andric case tok::pp_endif:
13070b57cec5SDimitry Andric return HandleEndifDirective(Result);
13080b57cec5SDimitry Andric
13090b57cec5SDimitry Andric // C99 6.10.2 - Source File Inclusion.
13100b57cec5SDimitry Andric case tok::pp_include:
13110b57cec5SDimitry Andric // Handle #include.
13120b57cec5SDimitry Andric return HandleIncludeDirective(SavedHash.getLocation(), Result);
13130b57cec5SDimitry Andric case tok::pp___include_macros:
13140b57cec5SDimitry Andric // Handle -imacros.
13150b57cec5SDimitry Andric return HandleIncludeMacrosDirective(SavedHash.getLocation(), Result);
13160b57cec5SDimitry Andric
13170b57cec5SDimitry Andric // C99 6.10.3 - Macro Replacement.
13180b57cec5SDimitry Andric case tok::pp_define:
13190b57cec5SDimitry Andric return HandleDefineDirective(Result, ImmediatelyAfterTopLevelIfndef);
13200b57cec5SDimitry Andric case tok::pp_undef:
13210b57cec5SDimitry Andric return HandleUndefDirective();
13220b57cec5SDimitry Andric
13230b57cec5SDimitry Andric // C99 6.10.4 - Line Control.
13240b57cec5SDimitry Andric case tok::pp_line:
13250b57cec5SDimitry Andric return HandleLineDirective();
13260b57cec5SDimitry Andric
13270b57cec5SDimitry Andric // C99 6.10.5 - Error Directive.
13280b57cec5SDimitry Andric case tok::pp_error:
13290b57cec5SDimitry Andric return HandleUserDiagnosticDirective(Result, false);
13300b57cec5SDimitry Andric
13310b57cec5SDimitry Andric // C99 6.10.6 - Pragma Directive.
13320b57cec5SDimitry Andric case tok::pp_pragma:
13330b57cec5SDimitry Andric return HandlePragmaDirective({PIK_HashPragma, SavedHash.getLocation()});
13340b57cec5SDimitry Andric
13350b57cec5SDimitry Andric // GNU Extensions.
13360b57cec5SDimitry Andric case tok::pp_import:
13370b57cec5SDimitry Andric return HandleImportDirective(SavedHash.getLocation(), Result);
13380b57cec5SDimitry Andric case tok::pp_include_next:
13390b57cec5SDimitry Andric return HandleIncludeNextDirective(SavedHash.getLocation(), Result);
13400b57cec5SDimitry Andric
13410b57cec5SDimitry Andric case tok::pp_warning:
1342fcaf7f86SDimitry Andric if (LangOpts.CPlusPlus)
134306c3fb27SDimitry Andric Diag(Result, LangOpts.CPlusPlus23
134406c3fb27SDimitry Andric ? diag::warn_cxx23_compat_warning_directive
1345fcaf7f86SDimitry Andric : diag::ext_pp_warning_directive)
134606c3fb27SDimitry Andric << /*C++23*/ 1;
1347fcaf7f86SDimitry Andric else
13485f757f3fSDimitry Andric Diag(Result, LangOpts.C23 ? diag::warn_c23_compat_warning_directive
1349fcaf7f86SDimitry Andric : diag::ext_pp_warning_directive)
13505f757f3fSDimitry Andric << /*C23*/ 0;
1351fcaf7f86SDimitry Andric
13520b57cec5SDimitry Andric return HandleUserDiagnosticDirective(Result, true);
13530b57cec5SDimitry Andric case tok::pp_ident:
13540b57cec5SDimitry Andric return HandleIdentSCCSDirective(Result);
13550b57cec5SDimitry Andric case tok::pp_sccs:
13560b57cec5SDimitry Andric return HandleIdentSCCSDirective(Result);
1357*0fca6ea1SDimitry Andric case tok::pp_embed:
1358*0fca6ea1SDimitry Andric return HandleEmbedDirective(SavedHash.getLocation(), Result,
1359*0fca6ea1SDimitry Andric getCurrentFileLexer()
1360*0fca6ea1SDimitry Andric ? *getCurrentFileLexer()->getFileEntry()
1361*0fca6ea1SDimitry Andric : static_cast<FileEntry *>(nullptr));
13620b57cec5SDimitry Andric case tok::pp_assert:
13630b57cec5SDimitry Andric //isExtension = true; // FIXME: implement #assert
13640b57cec5SDimitry Andric break;
13650b57cec5SDimitry Andric case tok::pp_unassert:
13660b57cec5SDimitry Andric //isExtension = true; // FIXME: implement #unassert
13670b57cec5SDimitry Andric break;
13680b57cec5SDimitry Andric
13690b57cec5SDimitry Andric case tok::pp___public_macro:
1370fe6060f1SDimitry Andric if (getLangOpts().Modules || getLangOpts().ModulesLocalVisibility)
13710b57cec5SDimitry Andric return HandleMacroPublicDirective(Result);
13720b57cec5SDimitry Andric break;
13730b57cec5SDimitry Andric
13740b57cec5SDimitry Andric case tok::pp___private_macro:
1375fe6060f1SDimitry Andric if (getLangOpts().Modules || getLangOpts().ModulesLocalVisibility)
13760b57cec5SDimitry Andric return HandleMacroPrivateDirective();
13770b57cec5SDimitry Andric break;
13780b57cec5SDimitry Andric }
13790b57cec5SDimitry Andric break;
13800b57cec5SDimitry Andric }
13810b57cec5SDimitry Andric
13820b57cec5SDimitry Andric // If this is a .S file, treat unknown # directives as non-preprocessor
13830b57cec5SDimitry Andric // directives. This is important because # may be a comment or introduce
13840b57cec5SDimitry Andric // various pseudo-ops. Just return the # token and push back the following
13850b57cec5SDimitry Andric // token to be lexed next time.
13860b57cec5SDimitry Andric if (getLangOpts().AsmPreprocessor) {
1387a7dea167SDimitry Andric auto Toks = std::make_unique<Token[]>(2);
13880b57cec5SDimitry Andric // Return the # and the token after it.
13890b57cec5SDimitry Andric Toks[0] = SavedHash;
13900b57cec5SDimitry Andric Toks[1] = Result;
13910b57cec5SDimitry Andric
13920b57cec5SDimitry Andric // If the second token is a hashhash token, then we need to translate it to
13930b57cec5SDimitry Andric // unknown so the token lexer doesn't try to perform token pasting.
13940b57cec5SDimitry Andric if (Result.is(tok::hashhash))
13950b57cec5SDimitry Andric Toks[1].setKind(tok::unknown);
13960b57cec5SDimitry Andric
13970b57cec5SDimitry Andric // Enter this token stream so that we re-lex the tokens. Make sure to
13980b57cec5SDimitry Andric // enable macro expansion, in case the token after the # is an identifier
13990b57cec5SDimitry Andric // that is expanded.
14000b57cec5SDimitry Andric EnterTokenStream(std::move(Toks), 2, false, /*IsReinject*/false);
14010b57cec5SDimitry Andric return;
14020b57cec5SDimitry Andric }
14030b57cec5SDimitry Andric
14040b57cec5SDimitry Andric // If we reached here, the preprocessing token is not valid!
140581ad6265SDimitry Andric // Start suggesting if a similar directive found.
140681ad6265SDimitry Andric Diag(Result, diag::err_pp_invalid_directive) << 0;
14070b57cec5SDimitry Andric
14080b57cec5SDimitry Andric // Read the rest of the PP line.
14090b57cec5SDimitry Andric DiscardUntilEndOfDirective();
14100b57cec5SDimitry Andric
14110b57cec5SDimitry Andric // Okay, we're done parsing the directive.
14120b57cec5SDimitry Andric }
14130b57cec5SDimitry Andric
14140b57cec5SDimitry Andric /// GetLineValue - Convert a numeric token into an unsigned value, emitting
14150b57cec5SDimitry Andric /// Diagnostic DiagID if it is invalid, and returning the value in Val.
GetLineValue(Token & DigitTok,unsigned & Val,unsigned DiagID,Preprocessor & PP,bool IsGNULineDirective=false)14160b57cec5SDimitry Andric static bool GetLineValue(Token &DigitTok, unsigned &Val,
14170b57cec5SDimitry Andric unsigned DiagID, Preprocessor &PP,
14180b57cec5SDimitry Andric bool IsGNULineDirective=false) {
14190b57cec5SDimitry Andric if (DigitTok.isNot(tok::numeric_constant)) {
14200b57cec5SDimitry Andric PP.Diag(DigitTok, DiagID);
14210b57cec5SDimitry Andric
14220b57cec5SDimitry Andric if (DigitTok.isNot(tok::eod))
14230b57cec5SDimitry Andric PP.DiscardUntilEndOfDirective();
14240b57cec5SDimitry Andric return true;
14250b57cec5SDimitry Andric }
14260b57cec5SDimitry Andric
14270b57cec5SDimitry Andric SmallString<64> IntegerBuffer;
14280b57cec5SDimitry Andric IntegerBuffer.resize(DigitTok.getLength());
14290b57cec5SDimitry Andric const char *DigitTokBegin = &IntegerBuffer[0];
14300b57cec5SDimitry Andric bool Invalid = false;
14310b57cec5SDimitry Andric unsigned ActualLength = PP.getSpelling(DigitTok, DigitTokBegin, &Invalid);
14320b57cec5SDimitry Andric if (Invalid)
14330b57cec5SDimitry Andric return true;
14340b57cec5SDimitry Andric
14350b57cec5SDimitry Andric // Verify that we have a simple digit-sequence, and compute the value. This
14360b57cec5SDimitry Andric // is always a simple digit string computed in decimal, so we do this manually
14370b57cec5SDimitry Andric // here.
14380b57cec5SDimitry Andric Val = 0;
14390b57cec5SDimitry Andric for (unsigned i = 0; i != ActualLength; ++i) {
14400b57cec5SDimitry Andric // C++1y [lex.fcon]p1:
14410b57cec5SDimitry Andric // Optional separating single quotes in a digit-sequence are ignored
14420b57cec5SDimitry Andric if (DigitTokBegin[i] == '\'')
14430b57cec5SDimitry Andric continue;
14440b57cec5SDimitry Andric
14450b57cec5SDimitry Andric if (!isDigit(DigitTokBegin[i])) {
14460b57cec5SDimitry Andric PP.Diag(PP.AdvanceToTokenCharacter(DigitTok.getLocation(), i),
14470b57cec5SDimitry Andric diag::err_pp_line_digit_sequence) << IsGNULineDirective;
14480b57cec5SDimitry Andric PP.DiscardUntilEndOfDirective();
14490b57cec5SDimitry Andric return true;
14500b57cec5SDimitry Andric }
14510b57cec5SDimitry Andric
14520b57cec5SDimitry Andric unsigned NextVal = Val*10+(DigitTokBegin[i]-'0');
14530b57cec5SDimitry Andric if (NextVal < Val) { // overflow.
14540b57cec5SDimitry Andric PP.Diag(DigitTok, DiagID);
14550b57cec5SDimitry Andric PP.DiscardUntilEndOfDirective();
14560b57cec5SDimitry Andric return true;
14570b57cec5SDimitry Andric }
14580b57cec5SDimitry Andric Val = NextVal;
14590b57cec5SDimitry Andric }
14600b57cec5SDimitry Andric
14610b57cec5SDimitry Andric if (DigitTokBegin[0] == '0' && Val)
14620b57cec5SDimitry Andric PP.Diag(DigitTok.getLocation(), diag::warn_pp_line_decimal)
14630b57cec5SDimitry Andric << IsGNULineDirective;
14640b57cec5SDimitry Andric
14650b57cec5SDimitry Andric return false;
14660b57cec5SDimitry Andric }
14670b57cec5SDimitry Andric
14680b57cec5SDimitry Andric /// Handle a \#line directive: C99 6.10.4.
14690b57cec5SDimitry Andric ///
14700b57cec5SDimitry Andric /// The two acceptable forms are:
14710b57cec5SDimitry Andric /// \verbatim
14720b57cec5SDimitry Andric /// # line digit-sequence
14730b57cec5SDimitry Andric /// # line digit-sequence "s-char-sequence"
14740b57cec5SDimitry Andric /// \endverbatim
HandleLineDirective()14750b57cec5SDimitry Andric void Preprocessor::HandleLineDirective() {
14760b57cec5SDimitry Andric // Read the line # and string argument. Per C99 6.10.4p5, these tokens are
14770b57cec5SDimitry Andric // expanded.
14780b57cec5SDimitry Andric Token DigitTok;
14790b57cec5SDimitry Andric Lex(DigitTok);
14800b57cec5SDimitry Andric
14810b57cec5SDimitry Andric // Validate the number and convert it to an unsigned.
14820b57cec5SDimitry Andric unsigned LineNo;
14830b57cec5SDimitry Andric if (GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*this))
14840b57cec5SDimitry Andric return;
14850b57cec5SDimitry Andric
14860b57cec5SDimitry Andric if (LineNo == 0)
14870b57cec5SDimitry Andric Diag(DigitTok, diag::ext_pp_line_zero);
14880b57cec5SDimitry Andric
14890b57cec5SDimitry Andric // Enforce C99 6.10.4p3: "The digit sequence shall not specify ... a
14900b57cec5SDimitry Andric // number greater than 2147483647". C90 requires that the line # be <= 32767.
14910b57cec5SDimitry Andric unsigned LineLimit = 32768U;
14920b57cec5SDimitry Andric if (LangOpts.C99 || LangOpts.CPlusPlus11)
14930b57cec5SDimitry Andric LineLimit = 2147483648U;
14940b57cec5SDimitry Andric if (LineNo >= LineLimit)
14950b57cec5SDimitry Andric Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
14960b57cec5SDimitry Andric else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)
14970b57cec5SDimitry Andric Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
14980b57cec5SDimitry Andric
14990b57cec5SDimitry Andric int FilenameID = -1;
15000b57cec5SDimitry Andric Token StrTok;
15010b57cec5SDimitry Andric Lex(StrTok);
15020b57cec5SDimitry Andric
15030b57cec5SDimitry Andric // If the StrTok is "eod", then it wasn't present. Otherwise, it must be a
15040b57cec5SDimitry Andric // string followed by eod.
15050b57cec5SDimitry Andric if (StrTok.is(tok::eod))
15060b57cec5SDimitry Andric ; // ok
15070b57cec5SDimitry Andric else if (StrTok.isNot(tok::string_literal)) {
15080b57cec5SDimitry Andric Diag(StrTok, diag::err_pp_line_invalid_filename);
15090b57cec5SDimitry Andric DiscardUntilEndOfDirective();
15100b57cec5SDimitry Andric return;
15110b57cec5SDimitry Andric } else if (StrTok.hasUDSuffix()) {
15120b57cec5SDimitry Andric Diag(StrTok, diag::err_invalid_string_udl);
15130b57cec5SDimitry Andric DiscardUntilEndOfDirective();
15140b57cec5SDimitry Andric return;
15150b57cec5SDimitry Andric } else {
15160b57cec5SDimitry Andric // Parse and validate the string, converting it into a unique ID.
15170b57cec5SDimitry Andric StringLiteralParser Literal(StrTok, *this);
151881ad6265SDimitry Andric assert(Literal.isOrdinary() && "Didn't allow wide strings in");
15190b57cec5SDimitry Andric if (Literal.hadError) {
15200b57cec5SDimitry Andric DiscardUntilEndOfDirective();
15210b57cec5SDimitry Andric return;
15220b57cec5SDimitry Andric }
15230b57cec5SDimitry Andric if (Literal.Pascal) {
15240b57cec5SDimitry Andric Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
15250b57cec5SDimitry Andric DiscardUntilEndOfDirective();
15260b57cec5SDimitry Andric return;
15270b57cec5SDimitry Andric }
15280b57cec5SDimitry Andric FilenameID = SourceMgr.getLineTableFilenameID(Literal.GetString());
15290b57cec5SDimitry Andric
15300b57cec5SDimitry Andric // Verify that there is nothing after the string, other than EOD. Because
15310b57cec5SDimitry Andric // of C99 6.10.4p5, macros that expand to empty tokens are ok.
15320b57cec5SDimitry Andric CheckEndOfDirective("line", true);
15330b57cec5SDimitry Andric }
15340b57cec5SDimitry Andric
15350b57cec5SDimitry Andric // Take the file kind of the file containing the #line directive. #line
15360b57cec5SDimitry Andric // directives are often used for generated sources from the same codebase, so
15370b57cec5SDimitry Andric // the new file should generally be classified the same way as the current
15380b57cec5SDimitry Andric // file. This is visible in GCC's pre-processed output, which rewrites #line
15390b57cec5SDimitry Andric // to GNU line markers.
15400b57cec5SDimitry Andric SrcMgr::CharacteristicKind FileKind =
15410b57cec5SDimitry Andric SourceMgr.getFileCharacteristic(DigitTok.getLocation());
15420b57cec5SDimitry Andric
15430b57cec5SDimitry Andric SourceMgr.AddLineNote(DigitTok.getLocation(), LineNo, FilenameID, false,
15440b57cec5SDimitry Andric false, FileKind);
15450b57cec5SDimitry Andric
15460b57cec5SDimitry Andric if (Callbacks)
15470b57cec5SDimitry Andric Callbacks->FileChanged(CurPPLexer->getSourceLocation(),
15480b57cec5SDimitry Andric PPCallbacks::RenameFile, FileKind);
15490b57cec5SDimitry Andric }
15500b57cec5SDimitry Andric
15510b57cec5SDimitry Andric /// ReadLineMarkerFlags - Parse and validate any flags at the end of a GNU line
15520b57cec5SDimitry Andric /// marker directive.
ReadLineMarkerFlags(bool & IsFileEntry,bool & IsFileExit,SrcMgr::CharacteristicKind & FileKind,Preprocessor & PP)15530b57cec5SDimitry Andric static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit,
15540b57cec5SDimitry Andric SrcMgr::CharacteristicKind &FileKind,
15550b57cec5SDimitry Andric Preprocessor &PP) {
15560b57cec5SDimitry Andric unsigned FlagVal;
15570b57cec5SDimitry Andric Token FlagTok;
15580b57cec5SDimitry Andric PP.Lex(FlagTok);
15590b57cec5SDimitry Andric if (FlagTok.is(tok::eod)) return false;
15600b57cec5SDimitry Andric if (GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
15610b57cec5SDimitry Andric return true;
15620b57cec5SDimitry Andric
15630b57cec5SDimitry Andric if (FlagVal == 1) {
15640b57cec5SDimitry Andric IsFileEntry = true;
15650b57cec5SDimitry Andric
15660b57cec5SDimitry Andric PP.Lex(FlagTok);
15670b57cec5SDimitry Andric if (FlagTok.is(tok::eod)) return false;
15680b57cec5SDimitry Andric if (GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
15690b57cec5SDimitry Andric return true;
15700b57cec5SDimitry Andric } else if (FlagVal == 2) {
15710b57cec5SDimitry Andric IsFileExit = true;
15720b57cec5SDimitry Andric
15730b57cec5SDimitry Andric SourceManager &SM = PP.getSourceManager();
15740b57cec5SDimitry Andric // If we are leaving the current presumed file, check to make sure the
15750b57cec5SDimitry Andric // presumed include stack isn't empty!
15760b57cec5SDimitry Andric FileID CurFileID =
15770b57cec5SDimitry Andric SM.getDecomposedExpansionLoc(FlagTok.getLocation()).first;
15780b57cec5SDimitry Andric PresumedLoc PLoc = SM.getPresumedLoc(FlagTok.getLocation());
15790b57cec5SDimitry Andric if (PLoc.isInvalid())
15800b57cec5SDimitry Andric return true;
15810b57cec5SDimitry Andric
15820b57cec5SDimitry Andric // If there is no include loc (main file) or if the include loc is in a
15830b57cec5SDimitry Andric // different physical file, then we aren't in a "1" line marker flag region.
15840b57cec5SDimitry Andric SourceLocation IncLoc = PLoc.getIncludeLoc();
15850b57cec5SDimitry Andric if (IncLoc.isInvalid() ||
15860b57cec5SDimitry Andric SM.getDecomposedExpansionLoc(IncLoc).first != CurFileID) {
15870b57cec5SDimitry Andric PP.Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);
15880b57cec5SDimitry Andric PP.DiscardUntilEndOfDirective();
15890b57cec5SDimitry Andric return true;
15900b57cec5SDimitry Andric }
15910b57cec5SDimitry Andric
15920b57cec5SDimitry Andric PP.Lex(FlagTok);
15930b57cec5SDimitry Andric if (FlagTok.is(tok::eod)) return false;
15940b57cec5SDimitry Andric if (GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))
15950b57cec5SDimitry Andric return true;
15960b57cec5SDimitry Andric }
15970b57cec5SDimitry Andric
15980b57cec5SDimitry Andric // We must have 3 if there are still flags.
15990b57cec5SDimitry Andric if (FlagVal != 3) {
16000b57cec5SDimitry Andric PP.Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
16010b57cec5SDimitry Andric PP.DiscardUntilEndOfDirective();
16020b57cec5SDimitry Andric return true;
16030b57cec5SDimitry Andric }
16040b57cec5SDimitry Andric
16050b57cec5SDimitry Andric FileKind = SrcMgr::C_System;
16060b57cec5SDimitry Andric
16070b57cec5SDimitry Andric PP.Lex(FlagTok);
16080b57cec5SDimitry Andric if (FlagTok.is(tok::eod)) return false;
16090b57cec5SDimitry Andric if (GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))
16100b57cec5SDimitry Andric return true;
16110b57cec5SDimitry Andric
16120b57cec5SDimitry Andric // We must have 4 if there is yet another flag.
16130b57cec5SDimitry Andric if (FlagVal != 4) {
16140b57cec5SDimitry Andric PP.Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
16150b57cec5SDimitry Andric PP.DiscardUntilEndOfDirective();
16160b57cec5SDimitry Andric return true;
16170b57cec5SDimitry Andric }
16180b57cec5SDimitry Andric
16190b57cec5SDimitry Andric FileKind = SrcMgr::C_ExternCSystem;
16200b57cec5SDimitry Andric
16210b57cec5SDimitry Andric PP.Lex(FlagTok);
16220b57cec5SDimitry Andric if (FlagTok.is(tok::eod)) return false;
16230b57cec5SDimitry Andric
16240b57cec5SDimitry Andric // There are no more valid flags here.
16250b57cec5SDimitry Andric PP.Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);
16260b57cec5SDimitry Andric PP.DiscardUntilEndOfDirective();
16270b57cec5SDimitry Andric return true;
16280b57cec5SDimitry Andric }
16290b57cec5SDimitry Andric
16300b57cec5SDimitry Andric /// HandleDigitDirective - Handle a GNU line marker directive, whose syntax is
16310b57cec5SDimitry Andric /// one of the following forms:
16320b57cec5SDimitry Andric ///
16330b57cec5SDimitry Andric /// # 42
16340b57cec5SDimitry Andric /// # 42 "file" ('1' | '2')?
16350b57cec5SDimitry Andric /// # 42 "file" ('1' | '2')? '3' '4'?
16360b57cec5SDimitry Andric ///
HandleDigitDirective(Token & DigitTok)16370b57cec5SDimitry Andric void Preprocessor::HandleDigitDirective(Token &DigitTok) {
16380b57cec5SDimitry Andric // Validate the number and convert it to an unsigned. GNU does not have a
16390b57cec5SDimitry Andric // line # limit other than it fit in 32-bits.
16400b57cec5SDimitry Andric unsigned LineNo;
16410b57cec5SDimitry Andric if (GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
16420b57cec5SDimitry Andric *this, true))
16430b57cec5SDimitry Andric return;
16440b57cec5SDimitry Andric
16450b57cec5SDimitry Andric Token StrTok;
16460b57cec5SDimitry Andric Lex(StrTok);
16470b57cec5SDimitry Andric
16480b57cec5SDimitry Andric bool IsFileEntry = false, IsFileExit = false;
16490b57cec5SDimitry Andric int FilenameID = -1;
16500b57cec5SDimitry Andric SrcMgr::CharacteristicKind FileKind = SrcMgr::C_User;
16510b57cec5SDimitry Andric
16520b57cec5SDimitry Andric // If the StrTok is "eod", then it wasn't present. Otherwise, it must be a
16530b57cec5SDimitry Andric // string followed by eod.
16540b57cec5SDimitry Andric if (StrTok.is(tok::eod)) {
165581ad6265SDimitry Andric Diag(StrTok, diag::ext_pp_gnu_line_directive);
16560b57cec5SDimitry Andric // Treat this like "#line NN", which doesn't change file characteristics.
16570b57cec5SDimitry Andric FileKind = SourceMgr.getFileCharacteristic(DigitTok.getLocation());
16580b57cec5SDimitry Andric } else if (StrTok.isNot(tok::string_literal)) {
16590b57cec5SDimitry Andric Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
16600b57cec5SDimitry Andric DiscardUntilEndOfDirective();
16610b57cec5SDimitry Andric return;
16620b57cec5SDimitry Andric } else if (StrTok.hasUDSuffix()) {
16630b57cec5SDimitry Andric Diag(StrTok, diag::err_invalid_string_udl);
16640b57cec5SDimitry Andric DiscardUntilEndOfDirective();
16650b57cec5SDimitry Andric return;
16660b57cec5SDimitry Andric } else {
16670b57cec5SDimitry Andric // Parse and validate the string, converting it into a unique ID.
16680b57cec5SDimitry Andric StringLiteralParser Literal(StrTok, *this);
166981ad6265SDimitry Andric assert(Literal.isOrdinary() && "Didn't allow wide strings in");
16700b57cec5SDimitry Andric if (Literal.hadError) {
16710b57cec5SDimitry Andric DiscardUntilEndOfDirective();
16720b57cec5SDimitry Andric return;
16730b57cec5SDimitry Andric }
16740b57cec5SDimitry Andric if (Literal.Pascal) {
16750b57cec5SDimitry Andric Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
16760b57cec5SDimitry Andric DiscardUntilEndOfDirective();
16770b57cec5SDimitry Andric return;
16780b57cec5SDimitry Andric }
16790b57cec5SDimitry Andric
16800b57cec5SDimitry Andric // If a filename was present, read any flags that are present.
16810b57cec5SDimitry Andric if (ReadLineMarkerFlags(IsFileEntry, IsFileExit, FileKind, *this))
16820b57cec5SDimitry Andric return;
168381ad6265SDimitry Andric if (!SourceMgr.isWrittenInBuiltinFile(DigitTok.getLocation()) &&
168481ad6265SDimitry Andric !SourceMgr.isWrittenInCommandLineFile(DigitTok.getLocation()))
168581ad6265SDimitry Andric Diag(StrTok, diag::ext_pp_gnu_line_directive);
1686349cc55cSDimitry Andric
1687349cc55cSDimitry Andric // Exiting to an empty string means pop to the including file, so leave
1688349cc55cSDimitry Andric // FilenameID as -1 in that case.
1689349cc55cSDimitry Andric if (!(IsFileExit && Literal.GetString().empty()))
1690349cc55cSDimitry Andric FilenameID = SourceMgr.getLineTableFilenameID(Literal.GetString());
16910b57cec5SDimitry Andric }
16920b57cec5SDimitry Andric
16930b57cec5SDimitry Andric // Create a line note with this information.
16940b57cec5SDimitry Andric SourceMgr.AddLineNote(DigitTok.getLocation(), LineNo, FilenameID, IsFileEntry,
16950b57cec5SDimitry Andric IsFileExit, FileKind);
16960b57cec5SDimitry Andric
16970b57cec5SDimitry Andric // If the preprocessor has callbacks installed, notify them of the #line
16980b57cec5SDimitry Andric // change. This is used so that the line marker comes out in -E mode for
16990b57cec5SDimitry Andric // example.
17000b57cec5SDimitry Andric if (Callbacks) {
17010b57cec5SDimitry Andric PPCallbacks::FileChangeReason Reason = PPCallbacks::RenameFile;
17020b57cec5SDimitry Andric if (IsFileEntry)
17030b57cec5SDimitry Andric Reason = PPCallbacks::EnterFile;
17040b57cec5SDimitry Andric else if (IsFileExit)
17050b57cec5SDimitry Andric Reason = PPCallbacks::ExitFile;
17060b57cec5SDimitry Andric
17070b57cec5SDimitry Andric Callbacks->FileChanged(CurPPLexer->getSourceLocation(), Reason, FileKind);
17080b57cec5SDimitry Andric }
17090b57cec5SDimitry Andric }
17100b57cec5SDimitry Andric
17110b57cec5SDimitry Andric /// HandleUserDiagnosticDirective - Handle a #warning or #error directive.
17120b57cec5SDimitry Andric ///
HandleUserDiagnosticDirective(Token & Tok,bool isWarning)17130b57cec5SDimitry Andric void Preprocessor::HandleUserDiagnosticDirective(Token &Tok,
17140b57cec5SDimitry Andric bool isWarning) {
17150b57cec5SDimitry Andric // Read the rest of the line raw. We do this because we don't want macros
17160b57cec5SDimitry Andric // to be expanded and we don't require that the tokens be valid preprocessing
17170b57cec5SDimitry Andric // tokens. For example, this is allowed: "#warning ` 'foo". GCC does
17180b57cec5SDimitry Andric // collapse multiple consecutive white space between tokens, but this isn't
17190b57cec5SDimitry Andric // specified by the standard.
17200b57cec5SDimitry Andric SmallString<128> Message;
17210b57cec5SDimitry Andric CurLexer->ReadToEndOfLine(&Message);
17220b57cec5SDimitry Andric
17230b57cec5SDimitry Andric // Find the first non-whitespace character, so that we can make the
17240b57cec5SDimitry Andric // diagnostic more succinct.
1725fe6060f1SDimitry Andric StringRef Msg = Message.str().ltrim(' ');
17260b57cec5SDimitry Andric
17270b57cec5SDimitry Andric if (isWarning)
17280b57cec5SDimitry Andric Diag(Tok, diag::pp_hash_warning) << Msg;
17290b57cec5SDimitry Andric else
17300b57cec5SDimitry Andric Diag(Tok, diag::err_pp_hash_error) << Msg;
17310b57cec5SDimitry Andric }
17320b57cec5SDimitry Andric
17330b57cec5SDimitry Andric /// HandleIdentSCCSDirective - Handle a #ident/#sccs directive.
17340b57cec5SDimitry Andric ///
HandleIdentSCCSDirective(Token & Tok)17350b57cec5SDimitry Andric void Preprocessor::HandleIdentSCCSDirective(Token &Tok) {
17360b57cec5SDimitry Andric // Yes, this directive is an extension.
17370b57cec5SDimitry Andric Diag(Tok, diag::ext_pp_ident_directive);
17380b57cec5SDimitry Andric
17390b57cec5SDimitry Andric // Read the string argument.
17400b57cec5SDimitry Andric Token StrTok;
17410b57cec5SDimitry Andric Lex(StrTok);
17420b57cec5SDimitry Andric
17430b57cec5SDimitry Andric // If the token kind isn't a string, it's a malformed directive.
17440b57cec5SDimitry Andric if (StrTok.isNot(tok::string_literal) &&
17450b57cec5SDimitry Andric StrTok.isNot(tok::wide_string_literal)) {
17460b57cec5SDimitry Andric Diag(StrTok, diag::err_pp_malformed_ident);
17470b57cec5SDimitry Andric if (StrTok.isNot(tok::eod))
17480b57cec5SDimitry Andric DiscardUntilEndOfDirective();
17490b57cec5SDimitry Andric return;
17500b57cec5SDimitry Andric }
17510b57cec5SDimitry Andric
17520b57cec5SDimitry Andric if (StrTok.hasUDSuffix()) {
17530b57cec5SDimitry Andric Diag(StrTok, diag::err_invalid_string_udl);
17540b57cec5SDimitry Andric DiscardUntilEndOfDirective();
17550b57cec5SDimitry Andric return;
17560b57cec5SDimitry Andric }
17570b57cec5SDimitry Andric
17580b57cec5SDimitry Andric // Verify that there is nothing after the string, other than EOD.
17590b57cec5SDimitry Andric CheckEndOfDirective("ident");
17600b57cec5SDimitry Andric
17610b57cec5SDimitry Andric if (Callbacks) {
17620b57cec5SDimitry Andric bool Invalid = false;
17630b57cec5SDimitry Andric std::string Str = getSpelling(StrTok, &Invalid);
17640b57cec5SDimitry Andric if (!Invalid)
17650b57cec5SDimitry Andric Callbacks->Ident(Tok.getLocation(), Str);
17660b57cec5SDimitry Andric }
17670b57cec5SDimitry Andric }
17680b57cec5SDimitry Andric
17690b57cec5SDimitry Andric /// Handle a #public directive.
HandleMacroPublicDirective(Token & Tok)17700b57cec5SDimitry Andric void Preprocessor::HandleMacroPublicDirective(Token &Tok) {
17710b57cec5SDimitry Andric Token MacroNameTok;
17720b57cec5SDimitry Andric ReadMacroName(MacroNameTok, MU_Undef);
17730b57cec5SDimitry Andric
17740b57cec5SDimitry Andric // Error reading macro name? If so, diagnostic already issued.
17750b57cec5SDimitry Andric if (MacroNameTok.is(tok::eod))
17760b57cec5SDimitry Andric return;
17770b57cec5SDimitry Andric
17780b57cec5SDimitry Andric // Check to see if this is the last token on the #__public_macro line.
17790b57cec5SDimitry Andric CheckEndOfDirective("__public_macro");
17800b57cec5SDimitry Andric
17810b57cec5SDimitry Andric IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
17820b57cec5SDimitry Andric // Okay, we finally have a valid identifier to undef.
17830b57cec5SDimitry Andric MacroDirective *MD = getLocalMacroDirective(II);
17840b57cec5SDimitry Andric
17850b57cec5SDimitry Andric // If the macro is not defined, this is an error.
17860b57cec5SDimitry Andric if (!MD) {
17870b57cec5SDimitry Andric Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
17880b57cec5SDimitry Andric return;
17890b57cec5SDimitry Andric }
17900b57cec5SDimitry Andric
17910b57cec5SDimitry Andric // Note that this macro has now been exported.
17920b57cec5SDimitry Andric appendMacroDirective(II, AllocateVisibilityMacroDirective(
17930b57cec5SDimitry Andric MacroNameTok.getLocation(), /*isPublic=*/true));
17940b57cec5SDimitry Andric }
17950b57cec5SDimitry Andric
17960b57cec5SDimitry Andric /// Handle a #private directive.
HandleMacroPrivateDirective()17970b57cec5SDimitry Andric void Preprocessor::HandleMacroPrivateDirective() {
17980b57cec5SDimitry Andric Token MacroNameTok;
17990b57cec5SDimitry Andric ReadMacroName(MacroNameTok, MU_Undef);
18000b57cec5SDimitry Andric
18010b57cec5SDimitry Andric // Error reading macro name? If so, diagnostic already issued.
18020b57cec5SDimitry Andric if (MacroNameTok.is(tok::eod))
18030b57cec5SDimitry Andric return;
18040b57cec5SDimitry Andric
18050b57cec5SDimitry Andric // Check to see if this is the last token on the #__private_macro line.
18060b57cec5SDimitry Andric CheckEndOfDirective("__private_macro");
18070b57cec5SDimitry Andric
18080b57cec5SDimitry Andric IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
18090b57cec5SDimitry Andric // Okay, we finally have a valid identifier to undef.
18100b57cec5SDimitry Andric MacroDirective *MD = getLocalMacroDirective(II);
18110b57cec5SDimitry Andric
18120b57cec5SDimitry Andric // If the macro is not defined, this is an error.
18130b57cec5SDimitry Andric if (!MD) {
18140b57cec5SDimitry Andric Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
18150b57cec5SDimitry Andric return;
18160b57cec5SDimitry Andric }
18170b57cec5SDimitry Andric
18180b57cec5SDimitry Andric // Note that this macro has now been marked private.
18190b57cec5SDimitry Andric appendMacroDirective(II, AllocateVisibilityMacroDirective(
18200b57cec5SDimitry Andric MacroNameTok.getLocation(), /*isPublic=*/false));
18210b57cec5SDimitry Andric }
18220b57cec5SDimitry Andric
18230b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
18240b57cec5SDimitry Andric // Preprocessor Include Directive Handling.
18250b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
18260b57cec5SDimitry Andric
18270b57cec5SDimitry Andric /// GetIncludeFilenameSpelling - Turn the specified lexer token into a fully
18280b57cec5SDimitry Andric /// checked and spelled filename, e.g. as an operand of \#include. This returns
18290b57cec5SDimitry Andric /// true if the input filename was in <>'s or false if it were in ""'s. The
18300b57cec5SDimitry Andric /// caller is expected to provide a buffer that is large enough to hold the
18310b57cec5SDimitry Andric /// spelling of the filename, but is also expected to handle the case when
18320b57cec5SDimitry Andric /// this method decides to use a different buffer.
GetIncludeFilenameSpelling(SourceLocation Loc,StringRef & Buffer)18330b57cec5SDimitry Andric bool Preprocessor::GetIncludeFilenameSpelling(SourceLocation Loc,
18340b57cec5SDimitry Andric StringRef &Buffer) {
18350b57cec5SDimitry Andric // Get the text form of the filename.
18360b57cec5SDimitry Andric assert(!Buffer.empty() && "Can't have tokens with empty spellings!");
18370b57cec5SDimitry Andric
18380b57cec5SDimitry Andric // FIXME: Consider warning on some of the cases described in C11 6.4.7/3 and
18390b57cec5SDimitry Andric // C++20 [lex.header]/2:
18400b57cec5SDimitry Andric //
18410b57cec5SDimitry Andric // If `"`, `'`, `\`, `/*`, or `//` appears in a header-name, then
18420b57cec5SDimitry Andric // in C: behavior is undefined
18430b57cec5SDimitry Andric // in C++: program is conditionally-supported with implementation-defined
18440b57cec5SDimitry Andric // semantics
18450b57cec5SDimitry Andric
18460b57cec5SDimitry Andric // Make sure the filename is <x> or "x".
18470b57cec5SDimitry Andric bool isAngled;
18480b57cec5SDimitry Andric if (Buffer[0] == '<') {
18490b57cec5SDimitry Andric if (Buffer.back() != '>') {
18500b57cec5SDimitry Andric Diag(Loc, diag::err_pp_expects_filename);
18510b57cec5SDimitry Andric Buffer = StringRef();
18520b57cec5SDimitry Andric return true;
18530b57cec5SDimitry Andric }
18540b57cec5SDimitry Andric isAngled = true;
18550b57cec5SDimitry Andric } else if (Buffer[0] == '"') {
18560b57cec5SDimitry Andric if (Buffer.back() != '"') {
18570b57cec5SDimitry Andric Diag(Loc, diag::err_pp_expects_filename);
18580b57cec5SDimitry Andric Buffer = StringRef();
18590b57cec5SDimitry Andric return true;
18600b57cec5SDimitry Andric }
18610b57cec5SDimitry Andric isAngled = false;
18620b57cec5SDimitry Andric } else {
18630b57cec5SDimitry Andric Diag(Loc, diag::err_pp_expects_filename);
18640b57cec5SDimitry Andric Buffer = StringRef();
18650b57cec5SDimitry Andric return true;
18660b57cec5SDimitry Andric }
18670b57cec5SDimitry Andric
18680b57cec5SDimitry Andric // Diagnose #include "" as invalid.
18690b57cec5SDimitry Andric if (Buffer.size() <= 2) {
18700b57cec5SDimitry Andric Diag(Loc, diag::err_pp_empty_filename);
18710b57cec5SDimitry Andric Buffer = StringRef();
18720b57cec5SDimitry Andric return true;
18730b57cec5SDimitry Andric }
18740b57cec5SDimitry Andric
18750b57cec5SDimitry Andric // Skip the brackets.
18760b57cec5SDimitry Andric Buffer = Buffer.substr(1, Buffer.size()-2);
18770b57cec5SDimitry Andric return isAngled;
18780b57cec5SDimitry Andric }
18790b57cec5SDimitry Andric
18800b57cec5SDimitry Andric /// Push a token onto the token stream containing an annotation.
EnterAnnotationToken(SourceRange Range,tok::TokenKind Kind,void * AnnotationVal)18810b57cec5SDimitry Andric void Preprocessor::EnterAnnotationToken(SourceRange Range,
18820b57cec5SDimitry Andric tok::TokenKind Kind,
18830b57cec5SDimitry Andric void *AnnotationVal) {
18840b57cec5SDimitry Andric // FIXME: Produce this as the current token directly, rather than
18850b57cec5SDimitry Andric // allocating a new token for it.
1886a7dea167SDimitry Andric auto Tok = std::make_unique<Token[]>(1);
18870b57cec5SDimitry Andric Tok[0].startToken();
18880b57cec5SDimitry Andric Tok[0].setKind(Kind);
18890b57cec5SDimitry Andric Tok[0].setLocation(Range.getBegin());
18900b57cec5SDimitry Andric Tok[0].setAnnotationEndLoc(Range.getEnd());
18910b57cec5SDimitry Andric Tok[0].setAnnotationValue(AnnotationVal);
18920b57cec5SDimitry Andric EnterTokenStream(std::move(Tok), 1, true, /*IsReinject*/ false);
18930b57cec5SDimitry Andric }
18940b57cec5SDimitry Andric
18950b57cec5SDimitry Andric /// Produce a diagnostic informing the user that a #include or similar
18960b57cec5SDimitry Andric /// was implicitly treated as a module import.
diagnoseAutoModuleImport(Preprocessor & PP,SourceLocation HashLoc,Token & IncludeTok,ArrayRef<std::pair<IdentifierInfo *,SourceLocation>> Path,SourceLocation PathEnd)18970b57cec5SDimitry Andric static void diagnoseAutoModuleImport(
18980b57cec5SDimitry Andric Preprocessor &PP, SourceLocation HashLoc, Token &IncludeTok,
18990b57cec5SDimitry Andric ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> Path,
19000b57cec5SDimitry Andric SourceLocation PathEnd) {
19010b57cec5SDimitry Andric SmallString<128> PathString;
19020b57cec5SDimitry Andric for (size_t I = 0, N = Path.size(); I != N; ++I) {
19030b57cec5SDimitry Andric if (I)
19040b57cec5SDimitry Andric PathString += '.';
19050b57cec5SDimitry Andric PathString += Path[I].first->getName();
19060b57cec5SDimitry Andric }
19070b57cec5SDimitry Andric
1908fcaf7f86SDimitry Andric int IncludeKind = 0;
19090b57cec5SDimitry Andric switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) {
19100b57cec5SDimitry Andric case tok::pp_include:
19110b57cec5SDimitry Andric IncludeKind = 0;
19120b57cec5SDimitry Andric break;
19130b57cec5SDimitry Andric
19140b57cec5SDimitry Andric case tok::pp_import:
19150b57cec5SDimitry Andric IncludeKind = 1;
19160b57cec5SDimitry Andric break;
19170b57cec5SDimitry Andric
19180b57cec5SDimitry Andric case tok::pp_include_next:
19190b57cec5SDimitry Andric IncludeKind = 2;
19200b57cec5SDimitry Andric break;
19210b57cec5SDimitry Andric
19220b57cec5SDimitry Andric case tok::pp___include_macros:
19230b57cec5SDimitry Andric IncludeKind = 3;
19240b57cec5SDimitry Andric break;
19250b57cec5SDimitry Andric
19260b57cec5SDimitry Andric default:
19270b57cec5SDimitry Andric llvm_unreachable("unknown include directive kind");
19280b57cec5SDimitry Andric }
19290b57cec5SDimitry Andric
1930fcaf7f86SDimitry Andric PP.Diag(HashLoc, diag::remark_pp_include_directive_modular_translation)
1931fcaf7f86SDimitry Andric << IncludeKind << PathString;
19320b57cec5SDimitry Andric }
19330b57cec5SDimitry Andric
19340b57cec5SDimitry Andric // Given a vector of path components and a string containing the real
19350b57cec5SDimitry Andric // path to the file, build a properly-cased replacement in the vector,
19360b57cec5SDimitry Andric // and return true if the replacement should be suggested.
trySimplifyPath(SmallVectorImpl<StringRef> & Components,StringRef RealPathName,llvm::sys::path::Style Separator)19370b57cec5SDimitry Andric static bool trySimplifyPath(SmallVectorImpl<StringRef> &Components,
1938cb14a3feSDimitry Andric StringRef RealPathName,
1939cb14a3feSDimitry Andric llvm::sys::path::Style Separator) {
19400b57cec5SDimitry Andric auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
19410b57cec5SDimitry Andric auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
19420b57cec5SDimitry Andric int Cnt = 0;
19430b57cec5SDimitry Andric bool SuggestReplacement = false;
1944cb14a3feSDimitry Andric
1945cb14a3feSDimitry Andric auto IsSep = [Separator](StringRef Component) {
1946cb14a3feSDimitry Andric return Component.size() == 1 &&
1947cb14a3feSDimitry Andric llvm::sys::path::is_separator(Component[0], Separator);
1948cb14a3feSDimitry Andric };
1949cb14a3feSDimitry Andric
19500b57cec5SDimitry Andric // Below is a best-effort to handle ".." in paths. It is admittedly
19510b57cec5SDimitry Andric // not 100% correct in the presence of symlinks.
19520b57cec5SDimitry Andric for (auto &Component : llvm::reverse(Components)) {
19530b57cec5SDimitry Andric if ("." == Component) {
19540b57cec5SDimitry Andric } else if (".." == Component) {
19550b57cec5SDimitry Andric ++Cnt;
19560b57cec5SDimitry Andric } else if (Cnt) {
19570b57cec5SDimitry Andric --Cnt;
19580b57cec5SDimitry Andric } else if (RealPathComponentIter != RealPathComponentEnd) {
1959cb14a3feSDimitry Andric if (!IsSep(Component) && !IsSep(*RealPathComponentIter) &&
1960cb14a3feSDimitry Andric Component != *RealPathComponentIter) {
1961cb14a3feSDimitry Andric // If these non-separator path components differ by more than just case,
1962cb14a3feSDimitry Andric // then we may be looking at symlinked paths. Bail on this diagnostic to
1963cb14a3feSDimitry Andric // avoid noisy false positives.
1964fe6060f1SDimitry Andric SuggestReplacement =
1965fe6060f1SDimitry Andric RealPathComponentIter->equals_insensitive(Component);
19660b57cec5SDimitry Andric if (!SuggestReplacement)
19670b57cec5SDimitry Andric break;
19680b57cec5SDimitry Andric Component = *RealPathComponentIter;
19690b57cec5SDimitry Andric }
19700b57cec5SDimitry Andric ++RealPathComponentIter;
19710b57cec5SDimitry Andric }
19720b57cec5SDimitry Andric }
19730b57cec5SDimitry Andric return SuggestReplacement;
19740b57cec5SDimitry Andric }
19750b57cec5SDimitry Andric
checkModuleIsAvailable(const LangOptions & LangOpts,const TargetInfo & TargetInfo,const Module & M,DiagnosticsEngine & Diags)19760b57cec5SDimitry Andric bool Preprocessor::checkModuleIsAvailable(const LangOptions &LangOpts,
19770b57cec5SDimitry Andric const TargetInfo &TargetInfo,
19785f757f3fSDimitry Andric const Module &M,
19795f757f3fSDimitry Andric DiagnosticsEngine &Diags) {
19800b57cec5SDimitry Andric Module::Requirement Requirement;
19810b57cec5SDimitry Andric Module::UnresolvedHeaderDirective MissingHeader;
19820b57cec5SDimitry Andric Module *ShadowingModule = nullptr;
19835f757f3fSDimitry Andric if (M.isAvailable(LangOpts, TargetInfo, Requirement, MissingHeader,
19840b57cec5SDimitry Andric ShadowingModule))
19850b57cec5SDimitry Andric return false;
19860b57cec5SDimitry Andric
19870b57cec5SDimitry Andric if (MissingHeader.FileNameLoc.isValid()) {
19880b57cec5SDimitry Andric Diags.Report(MissingHeader.FileNameLoc, diag::err_module_header_missing)
19890b57cec5SDimitry Andric << MissingHeader.IsUmbrella << MissingHeader.FileName;
19900b57cec5SDimitry Andric } else if (ShadowingModule) {
19915f757f3fSDimitry Andric Diags.Report(M.DefinitionLoc, diag::err_module_shadowed) << M.Name;
19920b57cec5SDimitry Andric Diags.Report(ShadowingModule->DefinitionLoc,
19930b57cec5SDimitry Andric diag::note_previous_definition);
19940b57cec5SDimitry Andric } else {
19950b57cec5SDimitry Andric // FIXME: Track the location at which the requirement was specified, and
19960b57cec5SDimitry Andric // use it here.
19975f757f3fSDimitry Andric Diags.Report(M.DefinitionLoc, diag::err_module_unavailable)
1998*0fca6ea1SDimitry Andric << M.getFullModuleName() << Requirement.RequiredState
1999*0fca6ea1SDimitry Andric << Requirement.FeatureName;
20000b57cec5SDimitry Andric }
20010b57cec5SDimitry Andric return true;
20020b57cec5SDimitry Andric }
20030b57cec5SDimitry Andric
200481ad6265SDimitry Andric std::pair<ConstSearchDirIterator, const FileEntry *>
getIncludeNextStart(const Token & IncludeNextTok) const200581ad6265SDimitry Andric Preprocessor::getIncludeNextStart(const Token &IncludeNextTok) const {
200681ad6265SDimitry Andric // #include_next is like #include, except that we start searching after
200781ad6265SDimitry Andric // the current found directory. If we can't do this, issue a
200881ad6265SDimitry Andric // diagnostic.
200981ad6265SDimitry Andric ConstSearchDirIterator Lookup = CurDirLookup;
201081ad6265SDimitry Andric const FileEntry *LookupFromFile = nullptr;
201181ad6265SDimitry Andric
201281ad6265SDimitry Andric if (isInPrimaryFile() && LangOpts.IsHeaderFile) {
201381ad6265SDimitry Andric // If the main file is a header, then it's either for PCH/AST generation,
201481ad6265SDimitry Andric // or libclang opened it. Either way, handle it as a normal include below
201581ad6265SDimitry Andric // and do not complain about include_next.
201681ad6265SDimitry Andric } else if (isInPrimaryFile()) {
201781ad6265SDimitry Andric Lookup = nullptr;
201881ad6265SDimitry Andric Diag(IncludeNextTok, diag::pp_include_next_in_primary);
201981ad6265SDimitry Andric } else if (CurLexerSubmodule) {
202081ad6265SDimitry Andric // Start looking up in the directory *after* the one in which the current
202181ad6265SDimitry Andric // file would be found, if any.
202281ad6265SDimitry Andric assert(CurPPLexer && "#include_next directive in macro?");
20235f757f3fSDimitry Andric if (auto FE = CurPPLexer->getFileEntry())
20245f757f3fSDimitry Andric LookupFromFile = *FE;
202581ad6265SDimitry Andric Lookup = nullptr;
202681ad6265SDimitry Andric } else if (!Lookup) {
202781ad6265SDimitry Andric // The current file was not found by walking the include path. Either it
202881ad6265SDimitry Andric // is the primary file (handled above), or it was found by absolute path,
202981ad6265SDimitry Andric // or it was found relative to such a file.
203081ad6265SDimitry Andric // FIXME: Track enough information so we know which case we're in.
203181ad6265SDimitry Andric Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
203281ad6265SDimitry Andric } else {
203381ad6265SDimitry Andric // Start looking up in the next directory.
203481ad6265SDimitry Andric ++Lookup;
203581ad6265SDimitry Andric }
203681ad6265SDimitry Andric
203781ad6265SDimitry Andric return {Lookup, LookupFromFile};
203881ad6265SDimitry Andric }
203981ad6265SDimitry Andric
20400b57cec5SDimitry Andric /// HandleIncludeDirective - The "\#include" tokens have just been read, read
20410b57cec5SDimitry Andric /// the file to be included from the lexer, then include it! This is a common
20420b57cec5SDimitry Andric /// routine with functionality shared between \#include, \#include_next and
20430b57cec5SDimitry Andric /// \#import. LookupFrom is set when this is a \#include_next directive, it
20440b57cec5SDimitry Andric /// specifies the file to start searching from.
HandleIncludeDirective(SourceLocation HashLoc,Token & IncludeTok,ConstSearchDirIterator LookupFrom,const FileEntry * LookupFromFile)20450b57cec5SDimitry Andric void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
20460b57cec5SDimitry Andric Token &IncludeTok,
204781ad6265SDimitry Andric ConstSearchDirIterator LookupFrom,
20480b57cec5SDimitry Andric const FileEntry *LookupFromFile) {
20490b57cec5SDimitry Andric Token FilenameTok;
20500b57cec5SDimitry Andric if (LexHeaderName(FilenameTok))
20510b57cec5SDimitry Andric return;
20520b57cec5SDimitry Andric
20530b57cec5SDimitry Andric if (FilenameTok.isNot(tok::header_name)) {
20540b57cec5SDimitry Andric Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename);
20550b57cec5SDimitry Andric if (FilenameTok.isNot(tok::eod))
20560b57cec5SDimitry Andric DiscardUntilEndOfDirective();
20570b57cec5SDimitry Andric return;
20580b57cec5SDimitry Andric }
20590b57cec5SDimitry Andric
20600b57cec5SDimitry Andric // Verify that there is nothing after the filename, other than EOD. Note
20610b57cec5SDimitry Andric // that we allow macros that expand to nothing after the filename, because
20620b57cec5SDimitry Andric // this falls into the category of "#include pp-tokens new-line" specified
20630b57cec5SDimitry Andric // in C99 6.10.2p4.
20640b57cec5SDimitry Andric SourceLocation EndLoc =
20650b57cec5SDimitry Andric CheckEndOfDirective(IncludeTok.getIdentifierInfo()->getNameStart(), true);
20660b57cec5SDimitry Andric
20670b57cec5SDimitry Andric auto Action = HandleHeaderIncludeOrImport(HashLoc, IncludeTok, FilenameTok,
20680b57cec5SDimitry Andric EndLoc, LookupFrom, LookupFromFile);
20690b57cec5SDimitry Andric switch (Action.Kind) {
20700b57cec5SDimitry Andric case ImportAction::None:
20710b57cec5SDimitry Andric case ImportAction::SkippedModuleImport:
20720b57cec5SDimitry Andric break;
20730b57cec5SDimitry Andric case ImportAction::ModuleBegin:
20740b57cec5SDimitry Andric EnterAnnotationToken(SourceRange(HashLoc, EndLoc),
20750b57cec5SDimitry Andric tok::annot_module_begin, Action.ModuleForHeader);
20760b57cec5SDimitry Andric break;
2077753f127fSDimitry Andric case ImportAction::HeaderUnitImport:
2078753f127fSDimitry Andric EnterAnnotationToken(SourceRange(HashLoc, EndLoc), tok::annot_header_unit,
2079753f127fSDimitry Andric Action.ModuleForHeader);
2080753f127fSDimitry Andric break;
20810b57cec5SDimitry Andric case ImportAction::ModuleImport:
20820b57cec5SDimitry Andric EnterAnnotationToken(SourceRange(HashLoc, EndLoc),
20830b57cec5SDimitry Andric tok::annot_module_include, Action.ModuleForHeader);
20840b57cec5SDimitry Andric break;
20855ffd83dbSDimitry Andric case ImportAction::Failure:
20865ffd83dbSDimitry Andric assert(TheModuleLoader.HadFatalFailure &&
20875ffd83dbSDimitry Andric "This should be an early exit only to a fatal error");
20885ffd83dbSDimitry Andric TheModuleLoader.HadFatalFailure = true;
20895ffd83dbSDimitry Andric IncludeTok.setKind(tok::eof);
20905ffd83dbSDimitry Andric CurLexer->cutOffLexing();
20915ffd83dbSDimitry Andric return;
20920b57cec5SDimitry Andric }
20930b57cec5SDimitry Andric }
20940b57cec5SDimitry Andric
LookupHeaderIncludeOrImport(ConstSearchDirIterator * CurDir,StringRef & Filename,SourceLocation FilenameLoc,CharSourceRange FilenameRange,const Token & FilenameTok,bool & IsFrameworkFound,bool IsImportDecl,bool & IsMapped,ConstSearchDirIterator LookupFrom,const FileEntry * LookupFromFile,StringRef & LookupFilename,SmallVectorImpl<char> & RelativePath,SmallVectorImpl<char> & SearchPath,ModuleMap::KnownHeader & SuggestedModule,bool isAngled)2095bdd1243dSDimitry Andric OptionalFileEntryRef Preprocessor::LookupHeaderIncludeOrImport(
209681ad6265SDimitry Andric ConstSearchDirIterator *CurDir, StringRef &Filename,
2097a7dea167SDimitry Andric SourceLocation FilenameLoc, CharSourceRange FilenameRange,
2098a7dea167SDimitry Andric const Token &FilenameTok, bool &IsFrameworkFound, bool IsImportDecl,
209981ad6265SDimitry Andric bool &IsMapped, ConstSearchDirIterator LookupFrom,
21005ffd83dbSDimitry Andric const FileEntry *LookupFromFile, StringRef &LookupFilename,
2101a7dea167SDimitry Andric SmallVectorImpl<char> &RelativePath, SmallVectorImpl<char> &SearchPath,
2102a7dea167SDimitry Andric ModuleMap::KnownHeader &SuggestedModule, bool isAngled) {
21035f757f3fSDimitry Andric auto DiagnoseHeaderInclusion = [&](FileEntryRef FE) {
21045f757f3fSDimitry Andric if (LangOpts.AsmPreprocessor)
21055f757f3fSDimitry Andric return;
21065f757f3fSDimitry Andric
21075f757f3fSDimitry Andric Module *RequestingModule = getModuleForLocation(
21085f757f3fSDimitry Andric FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);
21095f757f3fSDimitry Andric bool RequestingModuleIsModuleInterface =
21105f757f3fSDimitry Andric !SourceMgr.isInMainFile(FilenameLoc);
21115f757f3fSDimitry Andric
21125f757f3fSDimitry Andric HeaderInfo.getModuleMap().diagnoseHeaderInclusion(
21135f757f3fSDimitry Andric RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,
21145f757f3fSDimitry Andric Filename, FE);
21155f757f3fSDimitry Andric };
21165f757f3fSDimitry Andric
2117bdd1243dSDimitry Andric OptionalFileEntryRef File = LookupFile(
2118bdd1243dSDimitry Andric FilenameLoc, LookupFilename, isAngled, LookupFrom, LookupFromFile, CurDir,
2119a7dea167SDimitry Andric Callbacks ? &SearchPath : nullptr, Callbacks ? &RelativePath : nullptr,
2120a7dea167SDimitry Andric &SuggestedModule, &IsMapped, &IsFrameworkFound);
21215f757f3fSDimitry Andric if (File) {
21225f757f3fSDimitry Andric DiagnoseHeaderInclusion(*File);
2123a7dea167SDimitry Andric return File;
21245f757f3fSDimitry Andric }
2125a7dea167SDimitry Andric
2126bdd1243dSDimitry Andric // Give the clients a chance to silently skip this include.
2127bdd1243dSDimitry Andric if (Callbacks && Callbacks->FileNotFound(Filename))
2128bdd1243dSDimitry Andric return std::nullopt;
2129bdd1243dSDimitry Andric
2130a7dea167SDimitry Andric if (SuppressIncludeNotFoundError)
2131bdd1243dSDimitry Andric return std::nullopt;
2132a7dea167SDimitry Andric
2133a7dea167SDimitry Andric // If the file could not be located and it was included via angle
2134a7dea167SDimitry Andric // brackets, we can attempt a lookup as though it were a quoted path to
2135a7dea167SDimitry Andric // provide the user with a possible fixit.
2136a7dea167SDimitry Andric if (isAngled) {
2137bdd1243dSDimitry Andric OptionalFileEntryRef File = LookupFile(
2138bdd1243dSDimitry Andric FilenameLoc, LookupFilename, false, LookupFrom, LookupFromFile, CurDir,
2139a7dea167SDimitry Andric Callbacks ? &SearchPath : nullptr, Callbacks ? &RelativePath : nullptr,
2140a7dea167SDimitry Andric &SuggestedModule, &IsMapped,
2141a7dea167SDimitry Andric /*IsFrameworkFound=*/nullptr);
2142a7dea167SDimitry Andric if (File) {
21435f757f3fSDimitry Andric DiagnoseHeaderInclusion(*File);
2144a7dea167SDimitry Andric Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal)
2145a7dea167SDimitry Andric << Filename << IsImportDecl
2146a7dea167SDimitry Andric << FixItHint::CreateReplacement(FilenameRange,
2147a7dea167SDimitry Andric "\"" + Filename.str() + "\"");
2148a7dea167SDimitry Andric return File;
2149a7dea167SDimitry Andric }
2150a7dea167SDimitry Andric }
2151a7dea167SDimitry Andric
2152a7dea167SDimitry Andric // Check for likely typos due to leading or trailing non-isAlphanumeric
2153a7dea167SDimitry Andric // characters
2154a7dea167SDimitry Andric StringRef OriginalFilename = Filename;
2155a7dea167SDimitry Andric if (LangOpts.SpellChecking) {
2156a7dea167SDimitry Andric // A heuristic to correct a typo file name by removing leading and
2157a7dea167SDimitry Andric // trailing non-isAlphanumeric characters.
2158a7dea167SDimitry Andric auto CorrectTypoFilename = [](llvm::StringRef Filename) {
2159a7dea167SDimitry Andric Filename = Filename.drop_until(isAlphanumeric);
2160a7dea167SDimitry Andric while (!Filename.empty() && !isAlphanumeric(Filename.back())) {
2161a7dea167SDimitry Andric Filename = Filename.drop_back();
2162a7dea167SDimitry Andric }
2163a7dea167SDimitry Andric return Filename;
2164a7dea167SDimitry Andric };
2165a7dea167SDimitry Andric StringRef TypoCorrectionName = CorrectTypoFilename(Filename);
21665ffd83dbSDimitry Andric StringRef TypoCorrectionLookupName = CorrectTypoFilename(LookupFilename);
2167a7dea167SDimitry Andric
2168bdd1243dSDimitry Andric OptionalFileEntryRef File = LookupFile(
2169bdd1243dSDimitry Andric FilenameLoc, TypoCorrectionLookupName, isAngled, LookupFrom,
2170bdd1243dSDimitry Andric LookupFromFile, CurDir, Callbacks ? &SearchPath : nullptr,
2171a7dea167SDimitry Andric Callbacks ? &RelativePath : nullptr, &SuggestedModule, &IsMapped,
2172a7dea167SDimitry Andric /*IsFrameworkFound=*/nullptr);
2173a7dea167SDimitry Andric if (File) {
21745f757f3fSDimitry Andric DiagnoseHeaderInclusion(*File);
2175a7dea167SDimitry Andric auto Hint =
2176a7dea167SDimitry Andric isAngled ? FixItHint::CreateReplacement(
2177a7dea167SDimitry Andric FilenameRange, "<" + TypoCorrectionName.str() + ">")
2178a7dea167SDimitry Andric : FixItHint::CreateReplacement(
2179a7dea167SDimitry Andric FilenameRange, "\"" + TypoCorrectionName.str() + "\"");
2180a7dea167SDimitry Andric Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
2181a7dea167SDimitry Andric << OriginalFilename << TypoCorrectionName << Hint;
2182a7dea167SDimitry Andric // We found the file, so set the Filename to the name after typo
2183a7dea167SDimitry Andric // correction.
2184a7dea167SDimitry Andric Filename = TypoCorrectionName;
21855ffd83dbSDimitry Andric LookupFilename = TypoCorrectionLookupName;
2186a7dea167SDimitry Andric return File;
2187a7dea167SDimitry Andric }
2188a7dea167SDimitry Andric }
2189a7dea167SDimitry Andric
2190a7dea167SDimitry Andric // If the file is still not found, just go with the vanilla diagnostic
219181ad6265SDimitry Andric assert(!File && "expected missing file");
2192a7dea167SDimitry Andric Diag(FilenameTok, diag::err_pp_file_not_found)
2193a7dea167SDimitry Andric << OriginalFilename << FilenameRange;
2194a7dea167SDimitry Andric if (IsFrameworkFound) {
2195a7dea167SDimitry Andric size_t SlashPos = OriginalFilename.find('/');
2196a7dea167SDimitry Andric assert(SlashPos != StringRef::npos &&
2197a7dea167SDimitry Andric "Include with framework name should have '/' in the filename");
2198a7dea167SDimitry Andric StringRef FrameworkName = OriginalFilename.substr(0, SlashPos);
2199a7dea167SDimitry Andric FrameworkCacheEntry &CacheEntry =
2200a7dea167SDimitry Andric HeaderInfo.LookupFrameworkCache(FrameworkName);
2201a7dea167SDimitry Andric assert(CacheEntry.Directory && "Found framework should be in cache");
2202a7dea167SDimitry Andric Diag(FilenameTok, diag::note_pp_framework_without_header)
2203a7dea167SDimitry Andric << OriginalFilename.substr(SlashPos + 1) << FrameworkName
2204a7dea167SDimitry Andric << CacheEntry.Directory->getName();
2205a7dea167SDimitry Andric }
2206a7dea167SDimitry Andric
2207bdd1243dSDimitry Andric return std::nullopt;
2208a7dea167SDimitry Andric }
2209a7dea167SDimitry Andric
22100b57cec5SDimitry Andric /// Handle either a #include-like directive or an import declaration that names
22110b57cec5SDimitry Andric /// a header file.
22120b57cec5SDimitry Andric ///
22130b57cec5SDimitry Andric /// \param HashLoc The location of the '#' token for an include, or
22140b57cec5SDimitry Andric /// SourceLocation() for an import declaration.
22150b57cec5SDimitry Andric /// \param IncludeTok The include / include_next / import token.
22160b57cec5SDimitry Andric /// \param FilenameTok The header-name token.
22170b57cec5SDimitry Andric /// \param EndLoc The location at which any imported macros become visible.
22180b57cec5SDimitry Andric /// \param LookupFrom For #include_next, the starting directory for the
22190b57cec5SDimitry Andric /// directory lookup.
22200b57cec5SDimitry Andric /// \param LookupFromFile For #include_next, the starting file for the directory
22210b57cec5SDimitry Andric /// lookup.
HandleHeaderIncludeOrImport(SourceLocation HashLoc,Token & IncludeTok,Token & FilenameTok,SourceLocation EndLoc,ConstSearchDirIterator LookupFrom,const FileEntry * LookupFromFile)22220b57cec5SDimitry Andric Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
22230b57cec5SDimitry Andric SourceLocation HashLoc, Token &IncludeTok, Token &FilenameTok,
222481ad6265SDimitry Andric SourceLocation EndLoc, ConstSearchDirIterator LookupFrom,
22250b57cec5SDimitry Andric const FileEntry *LookupFromFile) {
22260b57cec5SDimitry Andric SmallString<128> FilenameBuffer;
22270b57cec5SDimitry Andric StringRef Filename = getSpelling(FilenameTok, FilenameBuffer);
22280b57cec5SDimitry Andric SourceLocation CharEnd = FilenameTok.getEndLoc();
22290b57cec5SDimitry Andric
22300b57cec5SDimitry Andric CharSourceRange FilenameRange
22310b57cec5SDimitry Andric = CharSourceRange::getCharRange(FilenameTok.getLocation(), CharEnd);
22320b57cec5SDimitry Andric StringRef OriginalFilename = Filename;
22330b57cec5SDimitry Andric bool isAngled =
22340b57cec5SDimitry Andric GetIncludeFilenameSpelling(FilenameTok.getLocation(), Filename);
22350b57cec5SDimitry Andric
22360b57cec5SDimitry Andric // If GetIncludeFilenameSpelling set the start ptr to null, there was an
22370b57cec5SDimitry Andric // error.
22380b57cec5SDimitry Andric if (Filename.empty())
22390b57cec5SDimitry Andric return {ImportAction::None};
22400b57cec5SDimitry Andric
22410b57cec5SDimitry Andric bool IsImportDecl = HashLoc.isInvalid();
22420b57cec5SDimitry Andric SourceLocation StartLoc = IsImportDecl ? IncludeTok.getLocation() : HashLoc;
22430b57cec5SDimitry Andric
22440b57cec5SDimitry Andric // Complain about attempts to #include files in an audit pragma.
2245a7dea167SDimitry Andric if (PragmaARCCFCodeAuditedInfo.second.isValid()) {
22460b57cec5SDimitry Andric Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;
2247a7dea167SDimitry Andric Diag(PragmaARCCFCodeAuditedInfo.second, diag::note_pragma_entered_here);
22480b57cec5SDimitry Andric
22490b57cec5SDimitry Andric // Immediately leave the pragma.
2250a7dea167SDimitry Andric PragmaARCCFCodeAuditedInfo = {nullptr, SourceLocation()};
22510b57cec5SDimitry Andric }
22520b57cec5SDimitry Andric
22530b57cec5SDimitry Andric // Complain about attempts to #include files in an assume-nonnull pragma.
22540b57cec5SDimitry Andric if (PragmaAssumeNonNullLoc.isValid()) {
22550b57cec5SDimitry Andric Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;
22560b57cec5SDimitry Andric Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
22570b57cec5SDimitry Andric
22580b57cec5SDimitry Andric // Immediately leave the pragma.
22590b57cec5SDimitry Andric PragmaAssumeNonNullLoc = SourceLocation();
22600b57cec5SDimitry Andric }
22610b57cec5SDimitry Andric
22620b57cec5SDimitry Andric if (HeaderInfo.HasIncludeAliasMap()) {
22630b57cec5SDimitry Andric // Map the filename with the brackets still attached. If the name doesn't
22640b57cec5SDimitry Andric // map to anything, fall back on the filename we've already gotten the
22650b57cec5SDimitry Andric // spelling for.
22660b57cec5SDimitry Andric StringRef NewName = HeaderInfo.MapHeaderToIncludeAlias(OriginalFilename);
22670b57cec5SDimitry Andric if (!NewName.empty())
22680b57cec5SDimitry Andric Filename = NewName;
22690b57cec5SDimitry Andric }
22700b57cec5SDimitry Andric
22710b57cec5SDimitry Andric // Search include directories.
22720b57cec5SDimitry Andric bool IsMapped = false;
22730b57cec5SDimitry Andric bool IsFrameworkFound = false;
227481ad6265SDimitry Andric ConstSearchDirIterator CurDir = nullptr;
22750b57cec5SDimitry Andric SmallString<1024> SearchPath;
22760b57cec5SDimitry Andric SmallString<1024> RelativePath;
22770b57cec5SDimitry Andric // We get the raw path only if we have 'Callbacks' to which we later pass
22780b57cec5SDimitry Andric // the path.
22790b57cec5SDimitry Andric ModuleMap::KnownHeader SuggestedModule;
22800b57cec5SDimitry Andric SourceLocation FilenameLoc = FilenameTok.getLocation();
2281a7dea167SDimitry Andric StringRef LookupFilename = Filename;
2282a7dea167SDimitry Andric
2283a7dea167SDimitry Andric // Normalize slashes when compiling with -fms-extensions on non-Windows. This
2284a7dea167SDimitry Andric // is unnecessary on Windows since the filesystem there handles backslashes.
22850b57cec5SDimitry Andric SmallString<128> NormalizedPath;
2286349cc55cSDimitry Andric llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::native;
2287349cc55cSDimitry Andric if (is_style_posix(BackslashStyle) && LangOpts.MicrosoftExt) {
22880b57cec5SDimitry Andric NormalizedPath = Filename.str();
22890b57cec5SDimitry Andric llvm::sys::path::native(NormalizedPath);
2290a7dea167SDimitry Andric LookupFilename = NormalizedPath;
22915ffd83dbSDimitry Andric BackslashStyle = llvm::sys::path::Style::windows;
2292a7dea167SDimitry Andric }
22930b57cec5SDimitry Andric
2294bdd1243dSDimitry Andric OptionalFileEntryRef File = LookupHeaderIncludeOrImport(
229504eeddc0SDimitry Andric &CurDir, Filename, FilenameLoc, FilenameRange, FilenameTok,
2296a7dea167SDimitry Andric IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,
2297a7dea167SDimitry Andric LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);
22980b57cec5SDimitry Andric
22990b57cec5SDimitry Andric if (usingPCHWithThroughHeader() && SkippingUntilPCHThroughHeader) {
2300a7dea167SDimitry Andric if (File && isPCHThroughHeader(&File->getFileEntry()))
23010b57cec5SDimitry Andric SkippingUntilPCHThroughHeader = false;
23020b57cec5SDimitry Andric return {ImportAction::None};
23030b57cec5SDimitry Andric }
23040b57cec5SDimitry Andric
23050b57cec5SDimitry Andric // Should we enter the source file? Set to Skip if either the source file is
23060b57cec5SDimitry Andric // known to have no effect beyond its effect on module visibility -- that is,
23070b57cec5SDimitry Andric // if it's got an include guard that is already defined, set to Import if it
23080b57cec5SDimitry Andric // is a modular header we've already built and should import.
2309753f127fSDimitry Andric
2310753f127fSDimitry Andric // For C++20 Modules
2311753f127fSDimitry Andric // [cpp.include]/7 If the header identified by the header-name denotes an
2312753f127fSDimitry Andric // importable header, it is implementation-defined whether the #include
2313753f127fSDimitry Andric // preprocessing directive is instead replaced by an import directive.
2314753f127fSDimitry Andric // For this implementation, the translation is permitted when we are parsing
2315753f127fSDimitry Andric // the Global Module Fragment, and not otherwise (the cases where it would be
2316753f127fSDimitry Andric // valid to replace an include with an import are highly constrained once in
2317753f127fSDimitry Andric // named module purview; this choice avoids considerable complexity in
2318753f127fSDimitry Andric // determining valid cases).
2319753f127fSDimitry Andric
23200b57cec5SDimitry Andric enum { Enter, Import, Skip, IncludeLimitReached } Action = Enter;
23210b57cec5SDimitry Andric
23220b57cec5SDimitry Andric if (PPOpts->SingleFileParseMode)
23230b57cec5SDimitry Andric Action = IncludeLimitReached;
23240b57cec5SDimitry Andric
23250b57cec5SDimitry Andric // If we've reached the max allowed include depth, it is usually due to an
23260b57cec5SDimitry Andric // include cycle. Don't enter already processed files again as it can lead to
23270b57cec5SDimitry Andric // reaching the max allowed include depth again.
23280b57cec5SDimitry Andric if (Action == Enter && HasReachedMaxIncludeDepth && File &&
232904eeddc0SDimitry Andric alreadyIncluded(*File))
23300b57cec5SDimitry Andric Action = IncludeLimitReached;
23310b57cec5SDimitry Andric
2332753f127fSDimitry Andric // FIXME: We do not have a good way to disambiguate C++ clang modules from
2333753f127fSDimitry Andric // C++ standard modules (other than use/non-use of Header Units).
2334bdd1243dSDimitry Andric
2335*0fca6ea1SDimitry Andric Module *ModuleToImport = SuggestedModule.getModule();
2336*0fca6ea1SDimitry Andric
2337*0fca6ea1SDimitry Andric bool MaybeTranslateInclude = Action == Enter && File && ModuleToImport &&
2338*0fca6ea1SDimitry Andric !ModuleToImport->isForBuilding(getLangOpts());
2339bdd1243dSDimitry Andric
2340753f127fSDimitry Andric // Maybe a usable Header Unit
2341753f127fSDimitry Andric bool UsableHeaderUnit = false;
2342*0fca6ea1SDimitry Andric if (getLangOpts().CPlusPlusModules && ModuleToImport &&
2343*0fca6ea1SDimitry Andric ModuleToImport->isHeaderUnit()) {
2344753f127fSDimitry Andric if (TrackGMFState.inGMF() || IsImportDecl)
2345753f127fSDimitry Andric UsableHeaderUnit = true;
2346753f127fSDimitry Andric else if (!IsImportDecl) {
2347753f127fSDimitry Andric // This is a Header Unit that we do not include-translate
2348*0fca6ea1SDimitry Andric ModuleToImport = nullptr;
2349753f127fSDimitry Andric }
2350753f127fSDimitry Andric }
2351753f127fSDimitry Andric // Maybe a usable clang header module.
2352bdd1243dSDimitry Andric bool UsableClangHeaderModule =
2353*0fca6ea1SDimitry Andric (getLangOpts().CPlusPlusModules || getLangOpts().Modules) &&
2354*0fca6ea1SDimitry Andric ModuleToImport && !ModuleToImport->isHeaderUnit();
2355753f127fSDimitry Andric
23560b57cec5SDimitry Andric // Determine whether we should try to import the module for this #include, if
23570b57cec5SDimitry Andric // there is one. Don't do so if precompiled module support is disabled or we
23580b57cec5SDimitry Andric // are processing this module textually (because we're building the module).
2359bdd1243dSDimitry Andric if (MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule)) {
23600b57cec5SDimitry Andric // If this include corresponds to a module but that module is
23610b57cec5SDimitry Andric // unavailable, diagnose the situation and bail out.
23620b57cec5SDimitry Andric // FIXME: Remove this; loadModule does the same check (but produces
23630b57cec5SDimitry Andric // slightly worse diagnostics).
2364*0fca6ea1SDimitry Andric if (checkModuleIsAvailable(getLangOpts(), getTargetInfo(), *ModuleToImport,
23655f757f3fSDimitry Andric getDiagnostics())) {
23660b57cec5SDimitry Andric Diag(FilenameTok.getLocation(),
23670b57cec5SDimitry Andric diag::note_implicit_top_level_module_import_here)
2368*0fca6ea1SDimitry Andric << ModuleToImport->getTopLevelModuleName();
23690b57cec5SDimitry Andric return {ImportAction::None};
23700b57cec5SDimitry Andric }
23710b57cec5SDimitry Andric
23720b57cec5SDimitry Andric // Compute the module access path corresponding to this module.
23730b57cec5SDimitry Andric // FIXME: Should we have a second loadModule() overload to avoid this
23740b57cec5SDimitry Andric // extra lookup step?
23750b57cec5SDimitry Andric SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path;
2376*0fca6ea1SDimitry Andric for (Module *Mod = ModuleToImport; Mod; Mod = Mod->Parent)
23770b57cec5SDimitry Andric Path.push_back(std::make_pair(getIdentifierInfo(Mod->Name),
23780b57cec5SDimitry Andric FilenameTok.getLocation()));
23790b57cec5SDimitry Andric std::reverse(Path.begin(), Path.end());
23800b57cec5SDimitry Andric
23810b57cec5SDimitry Andric // Warn that we're replacing the include/import with a module import.
23820b57cec5SDimitry Andric if (!IsImportDecl)
23830b57cec5SDimitry Andric diagnoseAutoModuleImport(*this, StartLoc, IncludeTok, Path, CharEnd);
23840b57cec5SDimitry Andric
23850b57cec5SDimitry Andric // Load the module to import its macros. We'll make the declarations
23860b57cec5SDimitry Andric // visible when the parser gets here.
2387*0fca6ea1SDimitry Andric // FIXME: Pass ModuleToImport in here rather than converting it to a path
23880b57cec5SDimitry Andric // and making the module loader convert it back again.
23890b57cec5SDimitry Andric ModuleLoadResult Imported = TheModuleLoader.loadModule(
23900b57cec5SDimitry Andric IncludeTok.getLocation(), Path, Module::Hidden,
23910b57cec5SDimitry Andric /*IsInclusionDirective=*/true);
2392*0fca6ea1SDimitry Andric assert((Imported == nullptr || Imported == ModuleToImport) &&
23930b57cec5SDimitry Andric "the imported module is different than the suggested one");
23940b57cec5SDimitry Andric
23950b57cec5SDimitry Andric if (Imported) {
23960b57cec5SDimitry Andric Action = Import;
23970b57cec5SDimitry Andric } else if (Imported.isMissingExpected()) {
2398bdd1243dSDimitry Andric markClangModuleAsAffecting(
2399bdd1243dSDimitry Andric static_cast<Module *>(Imported)->getTopLevelModule());
24000b57cec5SDimitry Andric // We failed to find a submodule that we assumed would exist (because it
24010b57cec5SDimitry Andric // was in the directory of an umbrella header, for instance), but no
24020b57cec5SDimitry Andric // actual module containing it exists (because the umbrella header is
24030b57cec5SDimitry Andric // incomplete). Treat this as a textual inclusion.
2404*0fca6ea1SDimitry Andric ModuleToImport = nullptr;
24050b57cec5SDimitry Andric } else if (Imported.isConfigMismatch()) {
24060b57cec5SDimitry Andric // On a configuration mismatch, enter the header textually. We still know
24070b57cec5SDimitry Andric // that it's part of the corresponding module.
24080b57cec5SDimitry Andric } else {
24090b57cec5SDimitry Andric // We hit an error processing the import. Bail out.
24100b57cec5SDimitry Andric if (hadModuleLoaderFatalFailure()) {
24110b57cec5SDimitry Andric // With a fatal failure in the module loader, we abort parsing.
24120b57cec5SDimitry Andric Token &Result = IncludeTok;
24130b57cec5SDimitry Andric assert(CurLexer && "#include but no current lexer set!");
24140b57cec5SDimitry Andric Result.startToken();
24150b57cec5SDimitry Andric CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd, tok::eof);
24160b57cec5SDimitry Andric CurLexer->cutOffLexing();
24170b57cec5SDimitry Andric }
24180b57cec5SDimitry Andric return {ImportAction::None};
24190b57cec5SDimitry Andric }
24200b57cec5SDimitry Andric }
24210b57cec5SDimitry Andric
24220b57cec5SDimitry Andric // The #included file will be considered to be a system header if either it is
24230b57cec5SDimitry Andric // in a system include directory, or if the #includer is a system include
24240b57cec5SDimitry Andric // header.
24250b57cec5SDimitry Andric SrcMgr::CharacteristicKind FileCharacter =
24260b57cec5SDimitry Andric SourceMgr.getFileCharacteristic(FilenameTok.getLocation());
24270b57cec5SDimitry Andric if (File)
24285f757f3fSDimitry Andric FileCharacter = std::max(HeaderInfo.getFileDirFlavor(*File), FileCharacter);
24290b57cec5SDimitry Andric
24300b57cec5SDimitry Andric // If this is a '#import' or an import-declaration, don't re-enter the file.
24310b57cec5SDimitry Andric //
24320b57cec5SDimitry Andric // FIXME: If we have a suggested module for a '#include', and we've already
24330b57cec5SDimitry Andric // visited this file, don't bother entering it again. We know it has no
24340b57cec5SDimitry Andric // further effect.
24350b57cec5SDimitry Andric bool EnterOnce =
24360b57cec5SDimitry Andric IsImportDecl ||
24370b57cec5SDimitry Andric IncludeTok.getIdentifierInfo()->getPPKeywordID() == tok::pp_import;
24380b57cec5SDimitry Andric
2439349cc55cSDimitry Andric bool IsFirstIncludeOfFile = false;
2440349cc55cSDimitry Andric
24410b57cec5SDimitry Andric // Ask HeaderInfo if we should enter this #include file. If not, #including
24420b57cec5SDimitry Andric // this file will have no effect.
24430b57cec5SDimitry Andric if (Action == Enter && File &&
24445f757f3fSDimitry Andric !HeaderInfo.ShouldEnterIncludeFile(*this, *File, EnterOnce,
2445*0fca6ea1SDimitry Andric getLangOpts().Modules, ModuleToImport,
2446753f127fSDimitry Andric IsFirstIncludeOfFile)) {
2447753f127fSDimitry Andric // C++ standard modules:
2448753f127fSDimitry Andric // If we are not in the GMF, then we textually include only
2449753f127fSDimitry Andric // clang modules:
24500b57cec5SDimitry Andric // Even if we've already preprocessed this header once and know that we
24510b57cec5SDimitry Andric // don't need to see its contents again, we still need to import it if it's
24520b57cec5SDimitry Andric // modular because we might not have imported it from this submodule before.
24530b57cec5SDimitry Andric //
24540b57cec5SDimitry Andric // FIXME: We don't do this when compiling a PCH because the AST
24550b57cec5SDimitry Andric // serialization layer can't cope with it. This means we get local
24560b57cec5SDimitry Andric // submodule visibility semantics wrong in that case.
2457753f127fSDimitry Andric if (UsableHeaderUnit && !getLangOpts().CompilingPCH)
2458753f127fSDimitry Andric Action = TrackGMFState.inGMF() ? Import : Skip;
2459753f127fSDimitry Andric else
2460*0fca6ea1SDimitry Andric Action = (ModuleToImport && !getLangOpts().CompilingPCH) ? Import : Skip;
24610b57cec5SDimitry Andric }
24620b57cec5SDimitry Andric
24635ffd83dbSDimitry Andric // Check for circular inclusion of the main file.
24645ffd83dbSDimitry Andric // We can't generate a consistent preamble with regard to the conditional
24655ffd83dbSDimitry Andric // stack if the main file is included again as due to the preamble bounds
24665ffd83dbSDimitry Andric // some directives (e.g. #endif of a header guard) will never be seen.
24675ffd83dbSDimitry Andric // Since this will lead to confusing errors, avoid the inclusion.
24685ffd83dbSDimitry Andric if (Action == Enter && File && PreambleConditionalStack.isRecording() &&
2469e8d8bef9SDimitry Andric SourceMgr.isMainFile(File->getFileEntry())) {
24705ffd83dbSDimitry Andric Diag(FilenameTok.getLocation(),
24715ffd83dbSDimitry Andric diag::err_pp_including_mainfile_in_preamble);
24725ffd83dbSDimitry Andric return {ImportAction::None};
24735ffd83dbSDimitry Andric }
24745ffd83dbSDimitry Andric
24750b57cec5SDimitry Andric if (Callbacks && !IsImportDecl) {
24760b57cec5SDimitry Andric // Notify the callback object that we've seen an inclusion directive.
24770b57cec5SDimitry Andric // FIXME: Use a different callback for a pp-import?
247881ad6265SDimitry Andric Callbacks->InclusionDirective(HashLoc, IncludeTok, LookupFilename, isAngled,
247981ad6265SDimitry Andric FilenameRange, File, SearchPath, RelativePath,
2480*0fca6ea1SDimitry Andric SuggestedModule.getModule(), Action == Import,
24810b57cec5SDimitry Andric FileCharacter);
2482a7dea167SDimitry Andric if (Action == Skip && File)
24830b57cec5SDimitry Andric Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
24840b57cec5SDimitry Andric }
24850b57cec5SDimitry Andric
24860b57cec5SDimitry Andric if (!File)
24870b57cec5SDimitry Andric return {ImportAction::None};
24880b57cec5SDimitry Andric
24890b57cec5SDimitry Andric // If this is a C++20 pp-import declaration, diagnose if we didn't find any
24900b57cec5SDimitry Andric // module corresponding to the named header.
2491*0fca6ea1SDimitry Andric if (IsImportDecl && !ModuleToImport) {
24920b57cec5SDimitry Andric Diag(FilenameTok, diag::err_header_import_not_header_unit)
24930b57cec5SDimitry Andric << OriginalFilename << File->getName();
24940b57cec5SDimitry Andric return {ImportAction::None};
24950b57cec5SDimitry Andric }
24960b57cec5SDimitry Andric
24970b57cec5SDimitry Andric // Issue a diagnostic if the name of the file on disk has a different case
24980b57cec5SDimitry Andric // than the one we're about to open.
24990b57cec5SDimitry Andric const bool CheckIncludePathPortability =
2500a7dea167SDimitry Andric !IsMapped && !File->getFileEntry().tryGetRealPathName().empty();
25010b57cec5SDimitry Andric
25020b57cec5SDimitry Andric if (CheckIncludePathPortability) {
2503a7dea167SDimitry Andric StringRef Name = LookupFilename;
25045ffd83dbSDimitry Andric StringRef NameWithoriginalSlashes = Filename;
25055ffd83dbSDimitry Andric #if defined(_WIN32)
25065ffd83dbSDimitry Andric // Skip UNC prefix if present. (tryGetRealPathName() always
25075ffd83dbSDimitry Andric // returns a path with the prefix skipped.)
25085ffd83dbSDimitry Andric bool NameWasUNC = Name.consume_front("\\\\?\\");
25095ffd83dbSDimitry Andric NameWithoriginalSlashes.consume_front("\\\\?\\");
25105ffd83dbSDimitry Andric #endif
2511a7dea167SDimitry Andric StringRef RealPathName = File->getFileEntry().tryGetRealPathName();
25120b57cec5SDimitry Andric SmallVector<StringRef, 16> Components(llvm::sys::path::begin(Name),
25130b57cec5SDimitry Andric llvm::sys::path::end(Name));
25145ffd83dbSDimitry Andric #if defined(_WIN32)
25155ffd83dbSDimitry Andric // -Wnonportable-include-path is designed to diagnose includes using
25165ffd83dbSDimitry Andric // case even on systems with a case-insensitive file system.
25175ffd83dbSDimitry Andric // On Windows, RealPathName always starts with an upper-case drive
25185ffd83dbSDimitry Andric // letter for absolute paths, but Name might start with either
25195ffd83dbSDimitry Andric // case depending on if `cd c:\foo` or `cd C:\foo` was used in the shell.
25205ffd83dbSDimitry Andric // ("foo" will always have on-disk case, no matter which case was
25215ffd83dbSDimitry Andric // used in the cd command). To not emit this warning solely for
25225ffd83dbSDimitry Andric // the drive letter, whose case is dependent on if `cd` is used
25235ffd83dbSDimitry Andric // with upper- or lower-case drive letters, always consider the
25245ffd83dbSDimitry Andric // given drive letter case as correct for the purpose of this warning.
25255ffd83dbSDimitry Andric SmallString<128> FixedDriveRealPath;
25265ffd83dbSDimitry Andric if (llvm::sys::path::is_absolute(Name) &&
25275ffd83dbSDimitry Andric llvm::sys::path::is_absolute(RealPathName) &&
25285ffd83dbSDimitry Andric toLowercase(Name[0]) == toLowercase(RealPathName[0]) &&
25295ffd83dbSDimitry Andric isLowercase(Name[0]) != isLowercase(RealPathName[0])) {
25305ffd83dbSDimitry Andric assert(Components.size() >= 3 && "should have drive, backslash, name");
25315ffd83dbSDimitry Andric assert(Components[0].size() == 2 && "should start with drive");
25325ffd83dbSDimitry Andric assert(Components[0][1] == ':' && "should have colon");
25335ffd83dbSDimitry Andric FixedDriveRealPath = (Name.substr(0, 1) + RealPathName.substr(1)).str();
25345ffd83dbSDimitry Andric RealPathName = FixedDriveRealPath;
25355ffd83dbSDimitry Andric }
25365ffd83dbSDimitry Andric #endif
25370b57cec5SDimitry Andric
2538cb14a3feSDimitry Andric if (trySimplifyPath(Components, RealPathName, BackslashStyle)) {
25390b57cec5SDimitry Andric SmallString<128> Path;
25400b57cec5SDimitry Andric Path.reserve(Name.size()+2);
25410b57cec5SDimitry Andric Path.push_back(isAngled ? '<' : '"');
25425ffd83dbSDimitry Andric
25435ffd83dbSDimitry Andric const auto IsSep = [BackslashStyle](char c) {
25445ffd83dbSDimitry Andric return llvm::sys::path::is_separator(c, BackslashStyle);
25455ffd83dbSDimitry Andric };
25465ffd83dbSDimitry Andric
25470b57cec5SDimitry Andric for (auto Component : Components) {
25485ffd83dbSDimitry Andric // On POSIX, Components will contain a single '/' as first element
25495ffd83dbSDimitry Andric // exactly if Name is an absolute path.
25505ffd83dbSDimitry Andric // On Windows, it will contain "C:" followed by '\' for absolute paths.
25515ffd83dbSDimitry Andric // The drive letter is optional for absolute paths on Windows, but
25525ffd83dbSDimitry Andric // clang currently cannot process absolute paths in #include lines that
25535ffd83dbSDimitry Andric // don't have a drive.
25545ffd83dbSDimitry Andric // If the first entry in Components is a directory separator,
25555ffd83dbSDimitry Andric // then the code at the bottom of this loop that keeps the original
25565ffd83dbSDimitry Andric // directory separator style copies it. If the second entry is
25575ffd83dbSDimitry Andric // a directory separator (the C:\ case), then that separator already
25585ffd83dbSDimitry Andric // got copied when the C: was processed and we want to skip that entry.
25595ffd83dbSDimitry Andric if (!(Component.size() == 1 && IsSep(Component[0])))
25600b57cec5SDimitry Andric Path.append(Component);
2561cb14a3feSDimitry Andric else if (Path.size() != 1)
25625ffd83dbSDimitry Andric continue;
25635ffd83dbSDimitry Andric
25645ffd83dbSDimitry Andric // Append the separator(s) the user used, or the close quote
25655ffd83dbSDimitry Andric if (Path.size() > NameWithoriginalSlashes.size()) {
25665ffd83dbSDimitry Andric Path.push_back(isAngled ? '>' : '"');
25675ffd83dbSDimitry Andric continue;
25680b57cec5SDimitry Andric }
25695ffd83dbSDimitry Andric assert(IsSep(NameWithoriginalSlashes[Path.size()-1]));
25705ffd83dbSDimitry Andric do
25715ffd83dbSDimitry Andric Path.push_back(NameWithoriginalSlashes[Path.size()-1]);
25725ffd83dbSDimitry Andric while (Path.size() <= NameWithoriginalSlashes.size() &&
25735ffd83dbSDimitry Andric IsSep(NameWithoriginalSlashes[Path.size()-1]));
25745ffd83dbSDimitry Andric }
25755ffd83dbSDimitry Andric
25765ffd83dbSDimitry Andric #if defined(_WIN32)
25775ffd83dbSDimitry Andric // Restore UNC prefix if it was there.
25785ffd83dbSDimitry Andric if (NameWasUNC)
25795ffd83dbSDimitry Andric Path = (Path.substr(0, 1) + "\\\\?\\" + Path.substr(1)).str();
25805ffd83dbSDimitry Andric #endif
25815ffd83dbSDimitry Andric
25825ffd83dbSDimitry Andric // For user files and known standard headers, issue a diagnostic.
25835ffd83dbSDimitry Andric // For other system headers, don't. They can be controlled separately.
25845ffd83dbSDimitry Andric auto DiagId =
25855ffd83dbSDimitry Andric (FileCharacter == SrcMgr::C_User || warnByDefaultOnWrongCase(Name))
25865ffd83dbSDimitry Andric ? diag::pp_nonportable_path
25875ffd83dbSDimitry Andric : diag::pp_nonportable_system_path;
25880b57cec5SDimitry Andric Diag(FilenameTok, DiagId) << Path <<
25890b57cec5SDimitry Andric FixItHint::CreateReplacement(FilenameRange, Path);
25900b57cec5SDimitry Andric }
25910b57cec5SDimitry Andric }
25920b57cec5SDimitry Andric
25930b57cec5SDimitry Andric switch (Action) {
25940b57cec5SDimitry Andric case Skip:
25950b57cec5SDimitry Andric // If we don't need to enter the file, stop now.
2596*0fca6ea1SDimitry Andric if (ModuleToImport)
2597*0fca6ea1SDimitry Andric return {ImportAction::SkippedModuleImport, ModuleToImport};
25980b57cec5SDimitry Andric return {ImportAction::None};
25990b57cec5SDimitry Andric
26000b57cec5SDimitry Andric case IncludeLimitReached:
26010b57cec5SDimitry Andric // If we reached our include limit and don't want to enter any more files,
26020b57cec5SDimitry Andric // don't go any further.
26030b57cec5SDimitry Andric return {ImportAction::None};
26040b57cec5SDimitry Andric
26050b57cec5SDimitry Andric case Import: {
26060b57cec5SDimitry Andric // If this is a module import, make it visible if needed.
2607*0fca6ea1SDimitry Andric assert(ModuleToImport && "no module to import");
26080b57cec5SDimitry Andric
2609*0fca6ea1SDimitry Andric makeModuleVisible(ModuleToImport, EndLoc);
26100b57cec5SDimitry Andric
26110b57cec5SDimitry Andric if (IncludeTok.getIdentifierInfo()->getPPKeywordID() ==
26120b57cec5SDimitry Andric tok::pp___include_macros)
26130b57cec5SDimitry Andric return {ImportAction::None};
26140b57cec5SDimitry Andric
2615*0fca6ea1SDimitry Andric return {ImportAction::ModuleImport, ModuleToImport};
26160b57cec5SDimitry Andric }
26170b57cec5SDimitry Andric
26180b57cec5SDimitry Andric case Enter:
26190b57cec5SDimitry Andric break;
26200b57cec5SDimitry Andric }
26210b57cec5SDimitry Andric
26220b57cec5SDimitry Andric // Check that we don't have infinite #include recursion.
26230b57cec5SDimitry Andric if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
26240b57cec5SDimitry Andric Diag(FilenameTok, diag::err_pp_include_too_deep);
26250b57cec5SDimitry Andric HasReachedMaxIncludeDepth = true;
26260b57cec5SDimitry Andric return {ImportAction::None};
26270b57cec5SDimitry Andric }
26280b57cec5SDimitry Andric
26295f757f3fSDimitry Andric if (isAngled && isInNamedModule())
26305f757f3fSDimitry Andric Diag(FilenameTok, diag::warn_pp_include_angled_in_module_purview)
26315f757f3fSDimitry Andric << getNamedModuleName();
26325f757f3fSDimitry Andric
26330b57cec5SDimitry Andric // Look up the file, create a File ID for it.
26340b57cec5SDimitry Andric SourceLocation IncludePos = FilenameTok.getLocation();
26350b57cec5SDimitry Andric // If the filename string was the result of macro expansions, set the include
26360b57cec5SDimitry Andric // position on the file where it will be included and after the expansions.
26370b57cec5SDimitry Andric if (IncludePos.isMacroID())
26380b57cec5SDimitry Andric IncludePos = SourceMgr.getExpansionRange(IncludePos).getEnd();
2639a7dea167SDimitry Andric FileID FID = SourceMgr.createFileID(*File, IncludePos, FileCharacter);
26405ffd83dbSDimitry Andric if (!FID.isValid()) {
26415ffd83dbSDimitry Andric TheModuleLoader.HadFatalFailure = true;
26425ffd83dbSDimitry Andric return ImportAction::Failure;
26435ffd83dbSDimitry Andric }
26440b57cec5SDimitry Andric
26450b57cec5SDimitry Andric // If all is good, enter the new file!
2646349cc55cSDimitry Andric if (EnterSourceFile(FID, CurDir, FilenameTok.getLocation(),
2647349cc55cSDimitry Andric IsFirstIncludeOfFile))
26480b57cec5SDimitry Andric return {ImportAction::None};
26490b57cec5SDimitry Andric
26500b57cec5SDimitry Andric // Determine if we're switching to building a new submodule, and which one.
2651753f127fSDimitry Andric // This does not apply for C++20 modules header units.
2652*0fca6ea1SDimitry Andric if (ModuleToImport && !ModuleToImport->isHeaderUnit()) {
2653*0fca6ea1SDimitry Andric if (ModuleToImport->getTopLevelModule()->ShadowingModule) {
26540b57cec5SDimitry Andric // We are building a submodule that belongs to a shadowed module. This
26550b57cec5SDimitry Andric // means we find header files in the shadowed module.
2656*0fca6ea1SDimitry Andric Diag(ModuleToImport->DefinitionLoc,
2657*0fca6ea1SDimitry Andric diag::err_module_build_shadowed_submodule)
2658*0fca6ea1SDimitry Andric << ModuleToImport->getFullModuleName();
2659*0fca6ea1SDimitry Andric Diag(ModuleToImport->getTopLevelModule()->ShadowingModule->DefinitionLoc,
26600b57cec5SDimitry Andric diag::note_previous_definition);
26610b57cec5SDimitry Andric return {ImportAction::None};
26620b57cec5SDimitry Andric }
26630b57cec5SDimitry Andric // When building a pch, -fmodule-name tells the compiler to textually
26640b57cec5SDimitry Andric // include headers in the specified module. We are not building the
26650b57cec5SDimitry Andric // specified module.
26660b57cec5SDimitry Andric //
26670b57cec5SDimitry Andric // FIXME: This is the wrong way to handle this. We should produce a PCH
26680b57cec5SDimitry Andric // that behaves the same as the header would behave in a compilation using
26690b57cec5SDimitry Andric // that PCH, which means we should enter the submodule. We need to teach
26700b57cec5SDimitry Andric // the AST serialization layer to deal with the resulting AST.
2671*0fca6ea1SDimitry Andric if (getLangOpts().CompilingPCH &&
2672*0fca6ea1SDimitry Andric ModuleToImport->isForBuilding(getLangOpts()))
26730b57cec5SDimitry Andric return {ImportAction::None};
26740b57cec5SDimitry Andric
26750b57cec5SDimitry Andric assert(!CurLexerSubmodule && "should not have marked this as a module yet");
2676*0fca6ea1SDimitry Andric CurLexerSubmodule = ModuleToImport;
26770b57cec5SDimitry Andric
26780b57cec5SDimitry Andric // Let the macro handling code know that any future macros are within
26790b57cec5SDimitry Andric // the new submodule.
2680*0fca6ea1SDimitry Andric EnterSubmodule(ModuleToImport, EndLoc, /*ForPragma*/ false);
26810b57cec5SDimitry Andric
26820b57cec5SDimitry Andric // Let the parser know that any future declarations are within the new
26830b57cec5SDimitry Andric // submodule.
26840b57cec5SDimitry Andric // FIXME: There's no point doing this if we're handling a #__include_macros
26850b57cec5SDimitry Andric // directive.
2686*0fca6ea1SDimitry Andric return {ImportAction::ModuleBegin, ModuleToImport};
26870b57cec5SDimitry Andric }
26880b57cec5SDimitry Andric
26890b57cec5SDimitry Andric assert(!IsImportDecl && "failed to diagnose missing module for import decl");
26900b57cec5SDimitry Andric return {ImportAction::None};
26910b57cec5SDimitry Andric }
26920b57cec5SDimitry Andric
26930b57cec5SDimitry Andric /// HandleIncludeNextDirective - Implements \#include_next.
26940b57cec5SDimitry Andric ///
HandleIncludeNextDirective(SourceLocation HashLoc,Token & IncludeNextTok)26950b57cec5SDimitry Andric void Preprocessor::HandleIncludeNextDirective(SourceLocation HashLoc,
26960b57cec5SDimitry Andric Token &IncludeNextTok) {
26970b57cec5SDimitry Andric Diag(IncludeNextTok, diag::ext_pp_include_next_directive);
26980b57cec5SDimitry Andric
269981ad6265SDimitry Andric ConstSearchDirIterator Lookup = nullptr;
270081ad6265SDimitry Andric const FileEntry *LookupFromFile;
270181ad6265SDimitry Andric std::tie(Lookup, LookupFromFile) = getIncludeNextStart(IncludeNextTok);
27020b57cec5SDimitry Andric
27030b57cec5SDimitry Andric return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,
27040b57cec5SDimitry Andric LookupFromFile);
27050b57cec5SDimitry Andric }
27060b57cec5SDimitry Andric
27070b57cec5SDimitry Andric /// HandleMicrosoftImportDirective - Implements \#import for Microsoft Mode
HandleMicrosoftImportDirective(Token & Tok)27080b57cec5SDimitry Andric void Preprocessor::HandleMicrosoftImportDirective(Token &Tok) {
27090b57cec5SDimitry Andric // The Microsoft #import directive takes a type library and generates header
27100b57cec5SDimitry Andric // files from it, and includes those. This is beyond the scope of what clang
27110b57cec5SDimitry Andric // does, so we ignore it and error out. However, #import can optionally have
27120b57cec5SDimitry Andric // trailing attributes that span multiple lines. We're going to eat those
27130b57cec5SDimitry Andric // so we can continue processing from there.
27140b57cec5SDimitry Andric Diag(Tok, diag::err_pp_import_directive_ms );
27150b57cec5SDimitry Andric
27160b57cec5SDimitry Andric // Read tokens until we get to the end of the directive. Note that the
27170b57cec5SDimitry Andric // directive can be split over multiple lines using the backslash character.
27180b57cec5SDimitry Andric DiscardUntilEndOfDirective();
27190b57cec5SDimitry Andric }
27200b57cec5SDimitry Andric
27210b57cec5SDimitry Andric /// HandleImportDirective - Implements \#import.
27220b57cec5SDimitry Andric ///
HandleImportDirective(SourceLocation HashLoc,Token & ImportTok)27230b57cec5SDimitry Andric void Preprocessor::HandleImportDirective(SourceLocation HashLoc,
27240b57cec5SDimitry Andric Token &ImportTok) {
27250b57cec5SDimitry Andric if (!LangOpts.ObjC) { // #import is standard for ObjC.
27260b57cec5SDimitry Andric if (LangOpts.MSVCCompat)
27270b57cec5SDimitry Andric return HandleMicrosoftImportDirective(ImportTok);
27280b57cec5SDimitry Andric Diag(ImportTok, diag::ext_pp_import_directive);
27290b57cec5SDimitry Andric }
27300b57cec5SDimitry Andric return HandleIncludeDirective(HashLoc, ImportTok);
27310b57cec5SDimitry Andric }
27320b57cec5SDimitry Andric
27330b57cec5SDimitry Andric /// HandleIncludeMacrosDirective - The -imacros command line option turns into a
27340b57cec5SDimitry Andric /// pseudo directive in the predefines buffer. This handles it by sucking all
27350b57cec5SDimitry Andric /// tokens through the preprocessor and discarding them (only keeping the side
27360b57cec5SDimitry Andric /// effects on the preprocessor).
HandleIncludeMacrosDirective(SourceLocation HashLoc,Token & IncludeMacrosTok)27370b57cec5SDimitry Andric void Preprocessor::HandleIncludeMacrosDirective(SourceLocation HashLoc,
27380b57cec5SDimitry Andric Token &IncludeMacrosTok) {
27390b57cec5SDimitry Andric // This directive should only occur in the predefines buffer. If not, emit an
27400b57cec5SDimitry Andric // error and reject it.
27410b57cec5SDimitry Andric SourceLocation Loc = IncludeMacrosTok.getLocation();
27420b57cec5SDimitry Andric if (SourceMgr.getBufferName(Loc) != "<built-in>") {
27430b57cec5SDimitry Andric Diag(IncludeMacrosTok.getLocation(),
27440b57cec5SDimitry Andric diag::pp_include_macros_out_of_predefines);
27450b57cec5SDimitry Andric DiscardUntilEndOfDirective();
27460b57cec5SDimitry Andric return;
27470b57cec5SDimitry Andric }
27480b57cec5SDimitry Andric
27490b57cec5SDimitry Andric // Treat this as a normal #include for checking purposes. If this is
27500b57cec5SDimitry Andric // successful, it will push a new lexer onto the include stack.
27510b57cec5SDimitry Andric HandleIncludeDirective(HashLoc, IncludeMacrosTok);
27520b57cec5SDimitry Andric
27530b57cec5SDimitry Andric Token TmpTok;
27540b57cec5SDimitry Andric do {
27550b57cec5SDimitry Andric Lex(TmpTok);
27560b57cec5SDimitry Andric assert(TmpTok.isNot(tok::eof) && "Didn't find end of -imacros!");
27570b57cec5SDimitry Andric } while (TmpTok.isNot(tok::hashhash));
27580b57cec5SDimitry Andric }
27590b57cec5SDimitry Andric
27600b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
27610b57cec5SDimitry Andric // Preprocessor Macro Directive Handling.
27620b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
27630b57cec5SDimitry Andric
27640b57cec5SDimitry Andric /// ReadMacroParameterList - The ( starting a parameter list of a macro
27650b57cec5SDimitry Andric /// definition has just been read. Lex the rest of the parameters and the
27660b57cec5SDimitry Andric /// closing ), updating MI with what we learn. Return true if an error occurs
27670b57cec5SDimitry Andric /// parsing the param list.
ReadMacroParameterList(MacroInfo * MI,Token & Tok)27680b57cec5SDimitry Andric bool Preprocessor::ReadMacroParameterList(MacroInfo *MI, Token &Tok) {
27690b57cec5SDimitry Andric SmallVector<IdentifierInfo*, 32> Parameters;
27700b57cec5SDimitry Andric
27710b57cec5SDimitry Andric while (true) {
277206c3fb27SDimitry Andric LexUnexpandedNonComment(Tok);
27730b57cec5SDimitry Andric switch (Tok.getKind()) {
27740b57cec5SDimitry Andric case tok::r_paren:
27750b57cec5SDimitry Andric // Found the end of the parameter list.
27760b57cec5SDimitry Andric if (Parameters.empty()) // #define FOO()
27770b57cec5SDimitry Andric return false;
27780b57cec5SDimitry Andric // Otherwise we have #define FOO(A,)
27790b57cec5SDimitry Andric Diag(Tok, diag::err_pp_expected_ident_in_arg_list);
27800b57cec5SDimitry Andric return true;
27810b57cec5SDimitry Andric case tok::ellipsis: // #define X(... -> C99 varargs
27820b57cec5SDimitry Andric if (!LangOpts.C99)
27830b57cec5SDimitry Andric Diag(Tok, LangOpts.CPlusPlus11 ?
27840b57cec5SDimitry Andric diag::warn_cxx98_compat_variadic_macro :
27850b57cec5SDimitry Andric diag::ext_variadic_macro);
27860b57cec5SDimitry Andric
27870b57cec5SDimitry Andric // OpenCL v1.2 s6.9.e: variadic macros are not supported.
2788e8d8bef9SDimitry Andric if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus) {
27890b57cec5SDimitry Andric Diag(Tok, diag::ext_pp_opencl_variadic_macros);
27900b57cec5SDimitry Andric }
27910b57cec5SDimitry Andric
27920b57cec5SDimitry Andric // Lex the token after the identifier.
279306c3fb27SDimitry Andric LexUnexpandedNonComment(Tok);
27940b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) {
27950b57cec5SDimitry Andric Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
27960b57cec5SDimitry Andric return true;
27970b57cec5SDimitry Andric }
27980b57cec5SDimitry Andric // Add the __VA_ARGS__ identifier as a parameter.
27990b57cec5SDimitry Andric Parameters.push_back(Ident__VA_ARGS__);
28000b57cec5SDimitry Andric MI->setIsC99Varargs();
28010b57cec5SDimitry Andric MI->setParameterList(Parameters, BP);
28020b57cec5SDimitry Andric return false;
28030b57cec5SDimitry Andric case tok::eod: // #define X(
28040b57cec5SDimitry Andric Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
28050b57cec5SDimitry Andric return true;
28060b57cec5SDimitry Andric default:
28070b57cec5SDimitry Andric // Handle keywords and identifiers here to accept things like
28080b57cec5SDimitry Andric // #define Foo(for) for.
28090b57cec5SDimitry Andric IdentifierInfo *II = Tok.getIdentifierInfo();
28100b57cec5SDimitry Andric if (!II) {
28110b57cec5SDimitry Andric // #define X(1
28120b57cec5SDimitry Andric Diag(Tok, diag::err_pp_invalid_tok_in_arg_list);
28130b57cec5SDimitry Andric return true;
28140b57cec5SDimitry Andric }
28150b57cec5SDimitry Andric
28160b57cec5SDimitry Andric // If this is already used as a parameter, it is used multiple times (e.g.
28170b57cec5SDimitry Andric // #define X(A,A.
2818349cc55cSDimitry Andric if (llvm::is_contained(Parameters, II)) { // C99 6.10.3p6
28190b57cec5SDimitry Andric Diag(Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
28200b57cec5SDimitry Andric return true;
28210b57cec5SDimitry Andric }
28220b57cec5SDimitry Andric
28230b57cec5SDimitry Andric // Add the parameter to the macro info.
28240b57cec5SDimitry Andric Parameters.push_back(II);
28250b57cec5SDimitry Andric
28260b57cec5SDimitry Andric // Lex the token after the identifier.
282706c3fb27SDimitry Andric LexUnexpandedNonComment(Tok);
28280b57cec5SDimitry Andric
28290b57cec5SDimitry Andric switch (Tok.getKind()) {
28300b57cec5SDimitry Andric default: // #define X(A B
28310b57cec5SDimitry Andric Diag(Tok, diag::err_pp_expected_comma_in_arg_list);
28320b57cec5SDimitry Andric return true;
28330b57cec5SDimitry Andric case tok::r_paren: // #define X(A)
28340b57cec5SDimitry Andric MI->setParameterList(Parameters, BP);
28350b57cec5SDimitry Andric return false;
28360b57cec5SDimitry Andric case tok::comma: // #define X(A,
28370b57cec5SDimitry Andric break;
28380b57cec5SDimitry Andric case tok::ellipsis: // #define X(A... -> GCC extension
28390b57cec5SDimitry Andric // Diagnose extension.
28400b57cec5SDimitry Andric Diag(Tok, diag::ext_named_variadic_macro);
28410b57cec5SDimitry Andric
28420b57cec5SDimitry Andric // Lex the token after the identifier.
284306c3fb27SDimitry Andric LexUnexpandedNonComment(Tok);
28440b57cec5SDimitry Andric if (Tok.isNot(tok::r_paren)) {
28450b57cec5SDimitry Andric Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
28460b57cec5SDimitry Andric return true;
28470b57cec5SDimitry Andric }
28480b57cec5SDimitry Andric
28490b57cec5SDimitry Andric MI->setIsGNUVarargs();
28500b57cec5SDimitry Andric MI->setParameterList(Parameters, BP);
28510b57cec5SDimitry Andric return false;
28520b57cec5SDimitry Andric }
28530b57cec5SDimitry Andric }
28540b57cec5SDimitry Andric }
28550b57cec5SDimitry Andric }
28560b57cec5SDimitry Andric
isConfigurationPattern(Token & MacroName,MacroInfo * MI,const LangOptions & LOptions)28570b57cec5SDimitry Andric static bool isConfigurationPattern(Token &MacroName, MacroInfo *MI,
28580b57cec5SDimitry Andric const LangOptions &LOptions) {
28590b57cec5SDimitry Andric if (MI->getNumTokens() == 1) {
28600b57cec5SDimitry Andric const Token &Value = MI->getReplacementToken(0);
28610b57cec5SDimitry Andric
28620b57cec5SDimitry Andric // Macro that is identity, like '#define inline inline' is a valid pattern.
28630b57cec5SDimitry Andric if (MacroName.getKind() == Value.getKind())
28640b57cec5SDimitry Andric return true;
28650b57cec5SDimitry Andric
28660b57cec5SDimitry Andric // Macro that maps a keyword to the same keyword decorated with leading/
28670b57cec5SDimitry Andric // trailing underscores is a valid pattern:
28680b57cec5SDimitry Andric // #define inline __inline
28690b57cec5SDimitry Andric // #define inline __inline__
28700b57cec5SDimitry Andric // #define inline _inline (in MS compatibility mode)
28710b57cec5SDimitry Andric StringRef MacroText = MacroName.getIdentifierInfo()->getName();
28720b57cec5SDimitry Andric if (IdentifierInfo *II = Value.getIdentifierInfo()) {
28730b57cec5SDimitry Andric if (!II->isKeyword(LOptions))
28740b57cec5SDimitry Andric return false;
28750b57cec5SDimitry Andric StringRef ValueText = II->getName();
28760b57cec5SDimitry Andric StringRef TrimmedValue = ValueText;
28775f757f3fSDimitry Andric if (!ValueText.starts_with("__")) {
28785f757f3fSDimitry Andric if (ValueText.starts_with("_"))
28790b57cec5SDimitry Andric TrimmedValue = TrimmedValue.drop_front(1);
28800b57cec5SDimitry Andric else
28810b57cec5SDimitry Andric return false;
28820b57cec5SDimitry Andric } else {
28830b57cec5SDimitry Andric TrimmedValue = TrimmedValue.drop_front(2);
28845f757f3fSDimitry Andric if (TrimmedValue.ends_with("__"))
28850b57cec5SDimitry Andric TrimmedValue = TrimmedValue.drop_back(2);
28860b57cec5SDimitry Andric }
2887*0fca6ea1SDimitry Andric return TrimmedValue == MacroText;
28880b57cec5SDimitry Andric } else {
28890b57cec5SDimitry Andric return false;
28900b57cec5SDimitry Andric }
28910b57cec5SDimitry Andric }
28920b57cec5SDimitry Andric
28930b57cec5SDimitry Andric // #define inline
28940b57cec5SDimitry Andric return MacroName.isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,
28950b57cec5SDimitry Andric tok::kw_const) &&
28960b57cec5SDimitry Andric MI->getNumTokens() == 0;
28970b57cec5SDimitry Andric }
28980b57cec5SDimitry Andric
28990b57cec5SDimitry Andric // ReadOptionalMacroParameterListAndBody - This consumes all (i.e. the
29000b57cec5SDimitry Andric // entire line) of the macro's tokens and adds them to MacroInfo, and while
29010b57cec5SDimitry Andric // doing so performs certain validity checks including (but not limited to):
29020b57cec5SDimitry Andric // - # (stringization) is followed by a macro parameter
29030b57cec5SDimitry Andric //
29040b57cec5SDimitry Andric // Returns a nullptr if an invalid sequence of tokens is encountered or returns
29050b57cec5SDimitry Andric // a pointer to a MacroInfo object.
29060b57cec5SDimitry Andric
ReadOptionalMacroParameterListAndBody(const Token & MacroNameTok,const bool ImmediatelyAfterHeaderGuard)29070b57cec5SDimitry Andric MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
29080b57cec5SDimitry Andric const Token &MacroNameTok, const bool ImmediatelyAfterHeaderGuard) {
29090b57cec5SDimitry Andric
29100b57cec5SDimitry Andric Token LastTok = MacroNameTok;
29110b57cec5SDimitry Andric // Create the new macro.
29120b57cec5SDimitry Andric MacroInfo *const MI = AllocateMacroInfo(MacroNameTok.getLocation());
29130b57cec5SDimitry Andric
29140b57cec5SDimitry Andric Token Tok;
29150b57cec5SDimitry Andric LexUnexpandedToken(Tok);
29160b57cec5SDimitry Andric
29170b57cec5SDimitry Andric // Ensure we consume the rest of the macro body if errors occur.
29180b57cec5SDimitry Andric auto _ = llvm::make_scope_exit([&]() {
29190b57cec5SDimitry Andric // The flag indicates if we are still waiting for 'eod'.
29200b57cec5SDimitry Andric if (CurLexer->ParsingPreprocessorDirective)
29210b57cec5SDimitry Andric DiscardUntilEndOfDirective();
29220b57cec5SDimitry Andric });
29230b57cec5SDimitry Andric
29240b57cec5SDimitry Andric // Used to un-poison and then re-poison identifiers of the __VA_ARGS__ ilk
29250b57cec5SDimitry Andric // within their appropriate context.
29260b57cec5SDimitry Andric VariadicMacroScopeGuard VariadicMacroScopeGuard(*this);
29270b57cec5SDimitry Andric
29280b57cec5SDimitry Andric // If this is a function-like macro definition, parse the argument list,
29290b57cec5SDimitry Andric // marking each of the identifiers as being used as macro arguments. Also,
29300b57cec5SDimitry Andric // check other constraints on the first token of the macro body.
29310b57cec5SDimitry Andric if (Tok.is(tok::eod)) {
29320b57cec5SDimitry Andric if (ImmediatelyAfterHeaderGuard) {
29330b57cec5SDimitry Andric // Save this macro information since it may part of a header guard.
29340b57cec5SDimitry Andric CurPPLexer->MIOpt.SetDefinedMacro(MacroNameTok.getIdentifierInfo(),
29350b57cec5SDimitry Andric MacroNameTok.getLocation());
29360b57cec5SDimitry Andric }
29370b57cec5SDimitry Andric // If there is no body to this macro, we have no special handling here.
29380b57cec5SDimitry Andric } else if (Tok.hasLeadingSpace()) {
29390b57cec5SDimitry Andric // This is a normal token with leading space. Clear the leading space
29400b57cec5SDimitry Andric // marker on the first token to get proper expansion.
29410b57cec5SDimitry Andric Tok.clearFlag(Token::LeadingSpace);
29420b57cec5SDimitry Andric } else if (Tok.is(tok::l_paren)) {
29430b57cec5SDimitry Andric // This is a function-like macro definition. Read the argument list.
29440b57cec5SDimitry Andric MI->setIsFunctionLike();
29450b57cec5SDimitry Andric if (ReadMacroParameterList(MI, LastTok))
29460b57cec5SDimitry Andric return nullptr;
29470b57cec5SDimitry Andric
29480b57cec5SDimitry Andric // If this is a definition of an ISO C/C++ variadic function-like macro (not
29490b57cec5SDimitry Andric // using the GNU named varargs extension) inform our variadic scope guard
29500b57cec5SDimitry Andric // which un-poisons and re-poisons certain identifiers (e.g. __VA_ARGS__)
29510b57cec5SDimitry Andric // allowed only within the definition of a variadic macro.
29520b57cec5SDimitry Andric
29530b57cec5SDimitry Andric if (MI->isC99Varargs()) {
29540b57cec5SDimitry Andric VariadicMacroScopeGuard.enterScope();
29550b57cec5SDimitry Andric }
29560b57cec5SDimitry Andric
29570b57cec5SDimitry Andric // Read the first token after the arg list for down below.
29580b57cec5SDimitry Andric LexUnexpandedToken(Tok);
29590b57cec5SDimitry Andric } else if (LangOpts.C99 || LangOpts.CPlusPlus11) {
29600b57cec5SDimitry Andric // C99 requires whitespace between the macro definition and the body. Emit
29610b57cec5SDimitry Andric // a diagnostic for something like "#define X+".
29620b57cec5SDimitry Andric Diag(Tok, diag::ext_c99_whitespace_required_after_macro_name);
29630b57cec5SDimitry Andric } else {
29640b57cec5SDimitry Andric // C90 6.8 TC1 says: "In the definition of an object-like macro, if the
29650b57cec5SDimitry Andric // first character of a replacement list is not a character required by
29660b57cec5SDimitry Andric // subclause 5.2.1, then there shall be white-space separation between the
29670b57cec5SDimitry Andric // identifier and the replacement list.". 5.2.1 lists this set:
29680b57cec5SDimitry Andric // "A-Za-z0-9!"#%&'()*+,_./:;<=>?[\]^_{|}~" as well as whitespace, which
29690b57cec5SDimitry Andric // is irrelevant here.
29700b57cec5SDimitry Andric bool isInvalid = false;
29710b57cec5SDimitry Andric if (Tok.is(tok::at)) // @ is not in the list above.
29720b57cec5SDimitry Andric isInvalid = true;
29730b57cec5SDimitry Andric else if (Tok.is(tok::unknown)) {
29740b57cec5SDimitry Andric // If we have an unknown token, it is something strange like "`". Since
29750b57cec5SDimitry Andric // all of valid characters would have lexed into a single character
29760b57cec5SDimitry Andric // token of some sort, we know this is not a valid case.
29770b57cec5SDimitry Andric isInvalid = true;
29780b57cec5SDimitry Andric }
29790b57cec5SDimitry Andric if (isInvalid)
29800b57cec5SDimitry Andric Diag(Tok, diag::ext_missing_whitespace_after_macro_name);
29810b57cec5SDimitry Andric else
29820b57cec5SDimitry Andric Diag(Tok, diag::warn_missing_whitespace_after_macro_name);
29830b57cec5SDimitry Andric }
29840b57cec5SDimitry Andric
29850b57cec5SDimitry Andric if (!Tok.is(tok::eod))
29860b57cec5SDimitry Andric LastTok = Tok;
29870b57cec5SDimitry Andric
298881ad6265SDimitry Andric SmallVector<Token, 16> Tokens;
298981ad6265SDimitry Andric
29900b57cec5SDimitry Andric // Read the rest of the macro body.
29910b57cec5SDimitry Andric if (MI->isObjectLike()) {
29920b57cec5SDimitry Andric // Object-like macros are very simple, just read their body.
29930b57cec5SDimitry Andric while (Tok.isNot(tok::eod)) {
29940b57cec5SDimitry Andric LastTok = Tok;
299581ad6265SDimitry Andric Tokens.push_back(Tok);
29960b57cec5SDimitry Andric // Get the next token of the macro.
29970b57cec5SDimitry Andric LexUnexpandedToken(Tok);
29980b57cec5SDimitry Andric }
29990b57cec5SDimitry Andric } else {
30000b57cec5SDimitry Andric // Otherwise, read the body of a function-like macro. While we are at it,
30010b57cec5SDimitry Andric // check C99 6.10.3.2p1: ensure that # operators are followed by macro
30020b57cec5SDimitry Andric // parameters in function-like macro expansions.
30030b57cec5SDimitry Andric
30040b57cec5SDimitry Andric VAOptDefinitionContext VAOCtx(*this);
30050b57cec5SDimitry Andric
30060b57cec5SDimitry Andric while (Tok.isNot(tok::eod)) {
30070b57cec5SDimitry Andric LastTok = Tok;
30080b57cec5SDimitry Andric
30090b57cec5SDimitry Andric if (!Tok.isOneOf(tok::hash, tok::hashat, tok::hashhash)) {
301081ad6265SDimitry Andric Tokens.push_back(Tok);
30110b57cec5SDimitry Andric
30120b57cec5SDimitry Andric if (VAOCtx.isVAOptToken(Tok)) {
30130b57cec5SDimitry Andric // If we're already within a VAOPT, emit an error.
30140b57cec5SDimitry Andric if (VAOCtx.isInVAOpt()) {
30150b57cec5SDimitry Andric Diag(Tok, diag::err_pp_vaopt_nested_use);
30160b57cec5SDimitry Andric return nullptr;
30170b57cec5SDimitry Andric }
30180b57cec5SDimitry Andric // Ensure VAOPT is followed by a '(' .
30190b57cec5SDimitry Andric LexUnexpandedToken(Tok);
30200b57cec5SDimitry Andric if (Tok.isNot(tok::l_paren)) {
30210b57cec5SDimitry Andric Diag(Tok, diag::err_pp_missing_lparen_in_vaopt_use);
30220b57cec5SDimitry Andric return nullptr;
30230b57cec5SDimitry Andric }
302481ad6265SDimitry Andric Tokens.push_back(Tok);
30250b57cec5SDimitry Andric VAOCtx.sawVAOptFollowedByOpeningParens(Tok.getLocation());
30260b57cec5SDimitry Andric LexUnexpandedToken(Tok);
30270b57cec5SDimitry Andric if (Tok.is(tok::hashhash)) {
30280b57cec5SDimitry Andric Diag(Tok, diag::err_vaopt_paste_at_start);
30290b57cec5SDimitry Andric return nullptr;
30300b57cec5SDimitry Andric }
30310b57cec5SDimitry Andric continue;
30320b57cec5SDimitry Andric } else if (VAOCtx.isInVAOpt()) {
30330b57cec5SDimitry Andric if (Tok.is(tok::r_paren)) {
30340b57cec5SDimitry Andric if (VAOCtx.sawClosingParen()) {
303581ad6265SDimitry Andric assert(Tokens.size() >= 3 &&
303681ad6265SDimitry Andric "Must have seen at least __VA_OPT__( "
30370b57cec5SDimitry Andric "and a subsequent tok::r_paren");
303881ad6265SDimitry Andric if (Tokens[Tokens.size() - 2].is(tok::hashhash)) {
30390b57cec5SDimitry Andric Diag(Tok, diag::err_vaopt_paste_at_end);
30400b57cec5SDimitry Andric return nullptr;
30410b57cec5SDimitry Andric }
30420b57cec5SDimitry Andric }
30430b57cec5SDimitry Andric } else if (Tok.is(tok::l_paren)) {
30440b57cec5SDimitry Andric VAOCtx.sawOpeningParen(Tok.getLocation());
30450b57cec5SDimitry Andric }
30460b57cec5SDimitry Andric }
30470b57cec5SDimitry Andric // Get the next token of the macro.
30480b57cec5SDimitry Andric LexUnexpandedToken(Tok);
30490b57cec5SDimitry Andric continue;
30500b57cec5SDimitry Andric }
30510b57cec5SDimitry Andric
30520b57cec5SDimitry Andric // If we're in -traditional mode, then we should ignore stringification
30530b57cec5SDimitry Andric // and token pasting. Mark the tokens as unknown so as not to confuse
30540b57cec5SDimitry Andric // things.
30550b57cec5SDimitry Andric if (getLangOpts().TraditionalCPP) {
30560b57cec5SDimitry Andric Tok.setKind(tok::unknown);
305781ad6265SDimitry Andric Tokens.push_back(Tok);
30580b57cec5SDimitry Andric
30590b57cec5SDimitry Andric // Get the next token of the macro.
30600b57cec5SDimitry Andric LexUnexpandedToken(Tok);
30610b57cec5SDimitry Andric continue;
30620b57cec5SDimitry Andric }
30630b57cec5SDimitry Andric
30640b57cec5SDimitry Andric if (Tok.is(tok::hashhash)) {
30650b57cec5SDimitry Andric // If we see token pasting, check if it looks like the gcc comma
30660b57cec5SDimitry Andric // pasting extension. We'll use this information to suppress
30670b57cec5SDimitry Andric // diagnostics later on.
30680b57cec5SDimitry Andric
30690b57cec5SDimitry Andric // Get the next token of the macro.
30700b57cec5SDimitry Andric LexUnexpandedToken(Tok);
30710b57cec5SDimitry Andric
30720b57cec5SDimitry Andric if (Tok.is(tok::eod)) {
307381ad6265SDimitry Andric Tokens.push_back(LastTok);
30740b57cec5SDimitry Andric break;
30750b57cec5SDimitry Andric }
30760b57cec5SDimitry Andric
307781ad6265SDimitry Andric if (!Tokens.empty() && Tok.getIdentifierInfo() == Ident__VA_ARGS__ &&
307881ad6265SDimitry Andric Tokens[Tokens.size() - 1].is(tok::comma))
30790b57cec5SDimitry Andric MI->setHasCommaPasting();
30800b57cec5SDimitry Andric
30810b57cec5SDimitry Andric // Things look ok, add the '##' token to the macro.
308281ad6265SDimitry Andric Tokens.push_back(LastTok);
30830b57cec5SDimitry Andric continue;
30840b57cec5SDimitry Andric }
30850b57cec5SDimitry Andric
30860b57cec5SDimitry Andric // Our Token is a stringization operator.
30870b57cec5SDimitry Andric // Get the next token of the macro.
30880b57cec5SDimitry Andric LexUnexpandedToken(Tok);
30890b57cec5SDimitry Andric
30900b57cec5SDimitry Andric // Check for a valid macro arg identifier or __VA_OPT__.
30910b57cec5SDimitry Andric if (!VAOCtx.isVAOptToken(Tok) &&
30920b57cec5SDimitry Andric (Tok.getIdentifierInfo() == nullptr ||
30930b57cec5SDimitry Andric MI->getParameterNum(Tok.getIdentifierInfo()) == -1)) {
30940b57cec5SDimitry Andric
30950b57cec5SDimitry Andric // If this is assembler-with-cpp mode, we accept random gibberish after
30960b57cec5SDimitry Andric // the '#' because '#' is often a comment character. However, change
30970b57cec5SDimitry Andric // the kind of the token to tok::unknown so that the preprocessor isn't
30980b57cec5SDimitry Andric // confused.
30990b57cec5SDimitry Andric if (getLangOpts().AsmPreprocessor && Tok.isNot(tok::eod)) {
31000b57cec5SDimitry Andric LastTok.setKind(tok::unknown);
310181ad6265SDimitry Andric Tokens.push_back(LastTok);
31020b57cec5SDimitry Andric continue;
31030b57cec5SDimitry Andric } else {
31040b57cec5SDimitry Andric Diag(Tok, diag::err_pp_stringize_not_parameter)
31050b57cec5SDimitry Andric << LastTok.is(tok::hashat);
31060b57cec5SDimitry Andric return nullptr;
31070b57cec5SDimitry Andric }
31080b57cec5SDimitry Andric }
31090b57cec5SDimitry Andric
31100b57cec5SDimitry Andric // Things look ok, add the '#' and param name tokens to the macro.
311181ad6265SDimitry Andric Tokens.push_back(LastTok);
31120b57cec5SDimitry Andric
31130b57cec5SDimitry Andric // If the token following '#' is VAOPT, let the next iteration handle it
31140b57cec5SDimitry Andric // and check it for correctness, otherwise add the token and prime the
31150b57cec5SDimitry Andric // loop with the next one.
31160b57cec5SDimitry Andric if (!VAOCtx.isVAOptToken(Tok)) {
311781ad6265SDimitry Andric Tokens.push_back(Tok);
31180b57cec5SDimitry Andric LastTok = Tok;
31190b57cec5SDimitry Andric
31200b57cec5SDimitry Andric // Get the next token of the macro.
31210b57cec5SDimitry Andric LexUnexpandedToken(Tok);
31220b57cec5SDimitry Andric }
31230b57cec5SDimitry Andric }
31240b57cec5SDimitry Andric if (VAOCtx.isInVAOpt()) {
31250b57cec5SDimitry Andric assert(Tok.is(tok::eod) && "Must be at End Of preprocessing Directive");
31260b57cec5SDimitry Andric Diag(Tok, diag::err_pp_expected_after)
31270b57cec5SDimitry Andric << LastTok.getKind() << tok::r_paren;
31280b57cec5SDimitry Andric Diag(VAOCtx.getUnmatchedOpeningParenLoc(), diag::note_matching) << tok::l_paren;
31290b57cec5SDimitry Andric return nullptr;
31300b57cec5SDimitry Andric }
31310b57cec5SDimitry Andric }
31320b57cec5SDimitry Andric MI->setDefinitionEndLoc(LastTok.getLocation());
313381ad6265SDimitry Andric
313481ad6265SDimitry Andric MI->setTokens(Tokens, BP);
31350b57cec5SDimitry Andric return MI;
31360b57cec5SDimitry Andric }
313706c3fb27SDimitry Andric
isObjCProtectedMacro(const IdentifierInfo * II)313806c3fb27SDimitry Andric static bool isObjCProtectedMacro(const IdentifierInfo *II) {
313906c3fb27SDimitry Andric return II->isStr("__strong") || II->isStr("__weak") ||
314006c3fb27SDimitry Andric II->isStr("__unsafe_unretained") || II->isStr("__autoreleasing");
314106c3fb27SDimitry Andric }
314206c3fb27SDimitry Andric
31430b57cec5SDimitry Andric /// HandleDefineDirective - Implements \#define. This consumes the entire macro
31440b57cec5SDimitry Andric /// line then lets the caller lex the next real token.
HandleDefineDirective(Token & DefineTok,const bool ImmediatelyAfterHeaderGuard)31450b57cec5SDimitry Andric void Preprocessor::HandleDefineDirective(
31460b57cec5SDimitry Andric Token &DefineTok, const bool ImmediatelyAfterHeaderGuard) {
31470b57cec5SDimitry Andric ++NumDefined;
31480b57cec5SDimitry Andric
31490b57cec5SDimitry Andric Token MacroNameTok;
31500b57cec5SDimitry Andric bool MacroShadowsKeyword;
31510b57cec5SDimitry Andric ReadMacroName(MacroNameTok, MU_Define, &MacroShadowsKeyword);
31520b57cec5SDimitry Andric
31530b57cec5SDimitry Andric // Error reading macro name? If so, diagnostic already issued.
31540b57cec5SDimitry Andric if (MacroNameTok.is(tok::eod))
31550b57cec5SDimitry Andric return;
31560b57cec5SDimitry Andric
3157349cc55cSDimitry Andric IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
3158349cc55cSDimitry Andric // Issue a final pragma warning if we're defining a macro that was has been
3159349cc55cSDimitry Andric // undefined and is being redefined.
3160349cc55cSDimitry Andric if (!II->hasMacroDefinition() && II->hadMacroDefinition() && II->isFinal())
3161349cc55cSDimitry Andric emitFinalMacroWarning(MacroNameTok, /*IsUndef=*/false);
3162349cc55cSDimitry Andric
31630b57cec5SDimitry Andric // If we are supposed to keep comments in #defines, reenable comment saving
31640b57cec5SDimitry Andric // mode.
31650b57cec5SDimitry Andric if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
31660b57cec5SDimitry Andric
31670b57cec5SDimitry Andric MacroInfo *const MI = ReadOptionalMacroParameterListAndBody(
31680b57cec5SDimitry Andric MacroNameTok, ImmediatelyAfterHeaderGuard);
31690b57cec5SDimitry Andric
31700b57cec5SDimitry Andric if (!MI) return;
31710b57cec5SDimitry Andric
31720b57cec5SDimitry Andric if (MacroShadowsKeyword &&
31730b57cec5SDimitry Andric !isConfigurationPattern(MacroNameTok, MI, getLangOpts())) {
31740b57cec5SDimitry Andric Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
31750b57cec5SDimitry Andric }
31760b57cec5SDimitry Andric // Check that there is no paste (##) operator at the beginning or end of the
31770b57cec5SDimitry Andric // replacement list.
31780b57cec5SDimitry Andric unsigned NumTokens = MI->getNumTokens();
31790b57cec5SDimitry Andric if (NumTokens != 0) {
31800b57cec5SDimitry Andric if (MI->getReplacementToken(0).is(tok::hashhash)) {
31810b57cec5SDimitry Andric Diag(MI->getReplacementToken(0), diag::err_paste_at_start);
31820b57cec5SDimitry Andric return;
31830b57cec5SDimitry Andric }
31840b57cec5SDimitry Andric if (MI->getReplacementToken(NumTokens-1).is(tok::hashhash)) {
31850b57cec5SDimitry Andric Diag(MI->getReplacementToken(NumTokens-1), diag::err_paste_at_end);
31860b57cec5SDimitry Andric return;
31870b57cec5SDimitry Andric }
31880b57cec5SDimitry Andric }
31890b57cec5SDimitry Andric
31900b57cec5SDimitry Andric // When skipping just warn about macros that do not match.
31910b57cec5SDimitry Andric if (SkippingUntilPCHThroughHeader) {
31920b57cec5SDimitry Andric const MacroInfo *OtherMI = getMacroInfo(MacroNameTok.getIdentifierInfo());
31930b57cec5SDimitry Andric if (!OtherMI || !MI->isIdenticalTo(*OtherMI, *this,
31940b57cec5SDimitry Andric /*Syntactic=*/LangOpts.MicrosoftExt))
31950b57cec5SDimitry Andric Diag(MI->getDefinitionLoc(), diag::warn_pp_macro_def_mismatch_with_pch)
31960b57cec5SDimitry Andric << MacroNameTok.getIdentifierInfo();
3197480093f4SDimitry Andric // Issue the diagnostic but allow the change if msvc extensions are enabled
3198480093f4SDimitry Andric if (!LangOpts.MicrosoftExt)
31990b57cec5SDimitry Andric return;
32000b57cec5SDimitry Andric }
32010b57cec5SDimitry Andric
32020b57cec5SDimitry Andric // Finally, if this identifier already had a macro defined for it, verify that
32030b57cec5SDimitry Andric // the macro bodies are identical, and issue diagnostics if they are not.
32040b57cec5SDimitry Andric if (const MacroInfo *OtherMI=getMacroInfo(MacroNameTok.getIdentifierInfo())) {
3205349cc55cSDimitry Andric // Final macros are hard-mode: they always warn. Even if the bodies are
3206349cc55cSDimitry Andric // identical. Even if they are in system headers. Even if they are things we
3207349cc55cSDimitry Andric // would silently allow in the past.
3208349cc55cSDimitry Andric if (MacroNameTok.getIdentifierInfo()->isFinal())
3209349cc55cSDimitry Andric emitFinalMacroWarning(MacroNameTok, /*IsUndef=*/false);
3210349cc55cSDimitry Andric
32110b57cec5SDimitry Andric // In Objective-C, ignore attempts to directly redefine the builtin
32120b57cec5SDimitry Andric // definitions of the ownership qualifiers. It's still possible to
32130b57cec5SDimitry Andric // #undef them.
32140b57cec5SDimitry Andric if (getLangOpts().ObjC &&
321506c3fb27SDimitry Andric SourceMgr.getFileID(OtherMI->getDefinitionLoc()) ==
321606c3fb27SDimitry Andric getPredefinesFileID() &&
32170b57cec5SDimitry Andric isObjCProtectedMacro(MacroNameTok.getIdentifierInfo())) {
32180b57cec5SDimitry Andric // Warn if it changes the tokens.
32190b57cec5SDimitry Andric if ((!getDiagnostics().getSuppressSystemWarnings() ||
32200b57cec5SDimitry Andric !SourceMgr.isInSystemHeader(DefineTok.getLocation())) &&
32210b57cec5SDimitry Andric !MI->isIdenticalTo(*OtherMI, *this,
32220b57cec5SDimitry Andric /*Syntactic=*/LangOpts.MicrosoftExt)) {
32230b57cec5SDimitry Andric Diag(MI->getDefinitionLoc(), diag::warn_pp_objc_macro_redef_ignored);
32240b57cec5SDimitry Andric }
32250b57cec5SDimitry Andric assert(!OtherMI->isWarnIfUnused());
32260b57cec5SDimitry Andric return;
32270b57cec5SDimitry Andric }
32280b57cec5SDimitry Andric
32290b57cec5SDimitry Andric // It is very common for system headers to have tons of macro redefinitions
32300b57cec5SDimitry Andric // and for warnings to be disabled in system headers. If this is the case,
32310b57cec5SDimitry Andric // then don't bother calling MacroInfo::isIdenticalTo.
32320b57cec5SDimitry Andric if (!getDiagnostics().getSuppressSystemWarnings() ||
32330b57cec5SDimitry Andric !SourceMgr.isInSystemHeader(DefineTok.getLocation())) {
3234349cc55cSDimitry Andric
32350b57cec5SDimitry Andric if (!OtherMI->isUsed() && OtherMI->isWarnIfUnused())
32360b57cec5SDimitry Andric Diag(OtherMI->getDefinitionLoc(), diag::pp_macro_not_used);
32370b57cec5SDimitry Andric
32380b57cec5SDimitry Andric // Warn if defining "__LINE__" and other builtins, per C99 6.10.8/4 and
32390b57cec5SDimitry Andric // C++ [cpp.predefined]p4, but allow it as an extension.
324006c3fb27SDimitry Andric if (isLanguageDefinedBuiltin(SourceMgr, OtherMI, II->getName()))
32410b57cec5SDimitry Andric Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
32420b57cec5SDimitry Andric // Macros must be identical. This means all tokens and whitespace
32430b57cec5SDimitry Andric // separation must be the same. C99 6.10.3p2.
32440b57cec5SDimitry Andric else if (!OtherMI->isAllowRedefinitionsWithoutWarning() &&
32450b57cec5SDimitry Andric !MI->isIdenticalTo(*OtherMI, *this, /*Syntactic=*/LangOpts.MicrosoftExt)) {
32460b57cec5SDimitry Andric Diag(MI->getDefinitionLoc(), diag::ext_pp_macro_redef)
32470b57cec5SDimitry Andric << MacroNameTok.getIdentifierInfo();
32480b57cec5SDimitry Andric Diag(OtherMI->getDefinitionLoc(), diag::note_previous_definition);
32490b57cec5SDimitry Andric }
32500b57cec5SDimitry Andric }
32510b57cec5SDimitry Andric if (OtherMI->isWarnIfUnused())
32520b57cec5SDimitry Andric WarnUnusedMacroLocs.erase(OtherMI->getDefinitionLoc());
32530b57cec5SDimitry Andric }
32540b57cec5SDimitry Andric
32550b57cec5SDimitry Andric DefMacroDirective *MD =
32560b57cec5SDimitry Andric appendDefMacroDirective(MacroNameTok.getIdentifierInfo(), MI);
32570b57cec5SDimitry Andric
32580b57cec5SDimitry Andric assert(!MI->isUsed());
32590b57cec5SDimitry Andric // If we need warning for not using the macro, add its location in the
32600b57cec5SDimitry Andric // warn-because-unused-macro set. If it gets used it will be removed from set.
32610b57cec5SDimitry Andric if (getSourceManager().isInMainFile(MI->getDefinitionLoc()) &&
3262a7dea167SDimitry Andric !Diags->isIgnored(diag::pp_macro_not_used, MI->getDefinitionLoc()) &&
32635ffd83dbSDimitry Andric !MacroExpansionInDirectivesOverride &&
32645ffd83dbSDimitry Andric getSourceManager().getFileID(MI->getDefinitionLoc()) !=
32655ffd83dbSDimitry Andric getPredefinesFileID()) {
32660b57cec5SDimitry Andric MI->setIsWarnIfUnused(true);
32670b57cec5SDimitry Andric WarnUnusedMacroLocs.insert(MI->getDefinitionLoc());
32680b57cec5SDimitry Andric }
32690b57cec5SDimitry Andric
32700b57cec5SDimitry Andric // If the callbacks want to know, tell them about the macro definition.
32710b57cec5SDimitry Andric if (Callbacks)
32720b57cec5SDimitry Andric Callbacks->MacroDefined(MacroNameTok, MD);
3273fe6060f1SDimitry Andric
3274fe6060f1SDimitry Andric // If we're in MS compatibility mode and the macro being defined is the
3275fe6060f1SDimitry Andric // assert macro, implicitly add a macro definition for static_assert to work
3276fe6060f1SDimitry Andric // around their broken assert.h header file in C. Only do so if there isn't
3277fe6060f1SDimitry Andric // already a static_assert macro defined.
3278fe6060f1SDimitry Andric if (!getLangOpts().CPlusPlus && getLangOpts().MSVCCompat &&
3279fe6060f1SDimitry Andric MacroNameTok.getIdentifierInfo()->isStr("assert") &&
3280fe6060f1SDimitry Andric !isMacroDefined("static_assert")) {
3281fe6060f1SDimitry Andric MacroInfo *MI = AllocateMacroInfo(SourceLocation());
3282fe6060f1SDimitry Andric
3283fe6060f1SDimitry Andric Token Tok;
3284fe6060f1SDimitry Andric Tok.startToken();
3285fe6060f1SDimitry Andric Tok.setKind(tok::kw__Static_assert);
3286fe6060f1SDimitry Andric Tok.setIdentifierInfo(getIdentifierInfo("_Static_assert"));
328781ad6265SDimitry Andric MI->setTokens({Tok}, BP);
3288fe6060f1SDimitry Andric (void)appendDefMacroDirective(getIdentifierInfo("static_assert"), MI);
3289fe6060f1SDimitry Andric }
32900b57cec5SDimitry Andric }
32910b57cec5SDimitry Andric
32920b57cec5SDimitry Andric /// HandleUndefDirective - Implements \#undef.
32930b57cec5SDimitry Andric ///
HandleUndefDirective()32940b57cec5SDimitry Andric void Preprocessor::HandleUndefDirective() {
32950b57cec5SDimitry Andric ++NumUndefined;
32960b57cec5SDimitry Andric
32970b57cec5SDimitry Andric Token MacroNameTok;
32980b57cec5SDimitry Andric ReadMacroName(MacroNameTok, MU_Undef);
32990b57cec5SDimitry Andric
33000b57cec5SDimitry Andric // Error reading macro name? If so, diagnostic already issued.
33010b57cec5SDimitry Andric if (MacroNameTok.is(tok::eod))
33020b57cec5SDimitry Andric return;
33030b57cec5SDimitry Andric
33040b57cec5SDimitry Andric // Check to see if this is the last token on the #undef line.
33050b57cec5SDimitry Andric CheckEndOfDirective("undef");
33060b57cec5SDimitry Andric
33070b57cec5SDimitry Andric // Okay, we have a valid identifier to undef.
33080b57cec5SDimitry Andric auto *II = MacroNameTok.getIdentifierInfo();
33090b57cec5SDimitry Andric auto MD = getMacroDefinition(II);
33100b57cec5SDimitry Andric UndefMacroDirective *Undef = nullptr;
33110b57cec5SDimitry Andric
3312349cc55cSDimitry Andric if (II->isFinal())
3313349cc55cSDimitry Andric emitFinalMacroWarning(MacroNameTok, /*IsUndef=*/true);
3314349cc55cSDimitry Andric
33150b57cec5SDimitry Andric // If the macro is not defined, this is a noop undef.
33160b57cec5SDimitry Andric if (const MacroInfo *MI = MD.getMacroInfo()) {
33170b57cec5SDimitry Andric if (!MI->isUsed() && MI->isWarnIfUnused())
33180b57cec5SDimitry Andric Diag(MI->getDefinitionLoc(), diag::pp_macro_not_used);
33190b57cec5SDimitry Andric
332006c3fb27SDimitry Andric // Warn if undefining "__LINE__" and other builtins, per C99 6.10.8/4 and
332106c3fb27SDimitry Andric // C++ [cpp.predefined]p4, but allow it as an extension.
332206c3fb27SDimitry Andric if (isLanguageDefinedBuiltin(SourceMgr, MI, II->getName()))
332306c3fb27SDimitry Andric Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
332406c3fb27SDimitry Andric
33250b57cec5SDimitry Andric if (MI->isWarnIfUnused())
33260b57cec5SDimitry Andric WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
33270b57cec5SDimitry Andric
33280b57cec5SDimitry Andric Undef = AllocateUndefMacroDirective(MacroNameTok.getLocation());
33290b57cec5SDimitry Andric }
33300b57cec5SDimitry Andric
33310b57cec5SDimitry Andric // If the callbacks want to know, tell them about the macro #undef.
33320b57cec5SDimitry Andric // Note: no matter if the macro was defined or not.
33330b57cec5SDimitry Andric if (Callbacks)
33340b57cec5SDimitry Andric Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
33350b57cec5SDimitry Andric
33360b57cec5SDimitry Andric if (Undef)
33370b57cec5SDimitry Andric appendMacroDirective(II, Undef);
33380b57cec5SDimitry Andric }
33390b57cec5SDimitry Andric
33400b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
33410b57cec5SDimitry Andric // Preprocessor Conditional Directive Handling.
33420b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
33430b57cec5SDimitry Andric
33440b57cec5SDimitry Andric /// HandleIfdefDirective - Implements the \#ifdef/\#ifndef directive. isIfndef
33450b57cec5SDimitry Andric /// is true when this is a \#ifndef directive. ReadAnyTokensBeforeDirective is
33460b57cec5SDimitry Andric /// true if any tokens have been returned or pp-directives activated before this
33470b57cec5SDimitry Andric /// \#ifndef has been lexed.
33480b57cec5SDimitry Andric ///
HandleIfdefDirective(Token & Result,const Token & HashToken,bool isIfndef,bool ReadAnyTokensBeforeDirective)33490b57cec5SDimitry Andric void Preprocessor::HandleIfdefDirective(Token &Result,
33500b57cec5SDimitry Andric const Token &HashToken,
33510b57cec5SDimitry Andric bool isIfndef,
33520b57cec5SDimitry Andric bool ReadAnyTokensBeforeDirective) {
33530b57cec5SDimitry Andric ++NumIf;
33540b57cec5SDimitry Andric Token DirectiveTok = Result;
33550b57cec5SDimitry Andric
33560b57cec5SDimitry Andric Token MacroNameTok;
33570b57cec5SDimitry Andric ReadMacroName(MacroNameTok);
33580b57cec5SDimitry Andric
33590b57cec5SDimitry Andric // Error reading macro name? If so, diagnostic already issued.
33600b57cec5SDimitry Andric if (MacroNameTok.is(tok::eod)) {
33610b57cec5SDimitry Andric // Skip code until we get to #endif. This helps with recovery by not
33620b57cec5SDimitry Andric // emitting an error when the #endif is reached.
33630b57cec5SDimitry Andric SkipExcludedConditionalBlock(HashToken.getLocation(),
33640b57cec5SDimitry Andric DirectiveTok.getLocation(),
33650b57cec5SDimitry Andric /*Foundnonskip*/ false, /*FoundElse*/ false);
33660b57cec5SDimitry Andric return;
33670b57cec5SDimitry Andric }
33680b57cec5SDimitry Andric
3369b3edf446SDimitry Andric emitMacroExpansionWarnings(MacroNameTok, /*IsIfnDef=*/true);
3370349cc55cSDimitry Andric
33710b57cec5SDimitry Andric // Check to see if this is the last token on the #if[n]def line.
33720b57cec5SDimitry Andric CheckEndOfDirective(isIfndef ? "ifndef" : "ifdef");
33730b57cec5SDimitry Andric
33740b57cec5SDimitry Andric IdentifierInfo *MII = MacroNameTok.getIdentifierInfo();
33750b57cec5SDimitry Andric auto MD = getMacroDefinition(MII);
33760b57cec5SDimitry Andric MacroInfo *MI = MD.getMacroInfo();
33770b57cec5SDimitry Andric
33780b57cec5SDimitry Andric if (CurPPLexer->getConditionalStackDepth() == 0) {
33790b57cec5SDimitry Andric // If the start of a top-level #ifdef and if the macro is not defined,
33800b57cec5SDimitry Andric // inform MIOpt that this might be the start of a proper include guard.
33810b57cec5SDimitry Andric // Otherwise it is some other form of unknown conditional which we can't
33820b57cec5SDimitry Andric // handle.
33830b57cec5SDimitry Andric if (!ReadAnyTokensBeforeDirective && !MI) {
33840b57cec5SDimitry Andric assert(isIfndef && "#ifdef shouldn't reach here");
33850b57cec5SDimitry Andric CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.getLocation());
33860b57cec5SDimitry Andric } else
33870b57cec5SDimitry Andric CurPPLexer->MIOpt.EnterTopLevelConditional();
33880b57cec5SDimitry Andric }
33890b57cec5SDimitry Andric
33900b57cec5SDimitry Andric // If there is a macro, process it.
33910b57cec5SDimitry Andric if (MI) // Mark it used.
33920b57cec5SDimitry Andric markMacroAsUsed(MI);
33930b57cec5SDimitry Andric
33940b57cec5SDimitry Andric if (Callbacks) {
33950b57cec5SDimitry Andric if (isIfndef)
33960b57cec5SDimitry Andric Callbacks->Ifndef(DirectiveTok.getLocation(), MacroNameTok, MD);
33970b57cec5SDimitry Andric else
33980b57cec5SDimitry Andric Callbacks->Ifdef(DirectiveTok.getLocation(), MacroNameTok, MD);
33990b57cec5SDimitry Andric }
34000b57cec5SDimitry Andric
3401a7dea167SDimitry Andric bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3402a7dea167SDimitry Andric getSourceManager().isInMainFile(DirectiveTok.getLocation());
3403a7dea167SDimitry Andric
34040b57cec5SDimitry Andric // Should we include the stuff contained by this directive?
34050b57cec5SDimitry Andric if (PPOpts->SingleFileParseMode && !MI) {
34060b57cec5SDimitry Andric // In 'single-file-parse mode' undefined identifiers trigger parsing of all
34070b57cec5SDimitry Andric // the directive blocks.
34080b57cec5SDimitry Andric CurPPLexer->pushConditionalLevel(DirectiveTok.getLocation(),
34090b57cec5SDimitry Andric /*wasskip*/false, /*foundnonskip*/false,
34100b57cec5SDimitry Andric /*foundelse*/false);
3411a7dea167SDimitry Andric } else if (!MI == isIfndef || RetainExcludedCB) {
34120b57cec5SDimitry Andric // Yes, remember that we are inside a conditional, then lex the next token.
34130b57cec5SDimitry Andric CurPPLexer->pushConditionalLevel(DirectiveTok.getLocation(),
34140b57cec5SDimitry Andric /*wasskip*/false, /*foundnonskip*/true,
34150b57cec5SDimitry Andric /*foundelse*/false);
34160b57cec5SDimitry Andric } else {
34170b57cec5SDimitry Andric // No, skip the contents of this block.
34180b57cec5SDimitry Andric SkipExcludedConditionalBlock(HashToken.getLocation(),
34190b57cec5SDimitry Andric DirectiveTok.getLocation(),
34200b57cec5SDimitry Andric /*Foundnonskip*/ false,
34210b57cec5SDimitry Andric /*FoundElse*/ false);
34220b57cec5SDimitry Andric }
34230b57cec5SDimitry Andric }
34240b57cec5SDimitry Andric
34250b57cec5SDimitry Andric /// HandleIfDirective - Implements the \#if directive.
34260b57cec5SDimitry Andric ///
HandleIfDirective(Token & IfToken,const Token & HashToken,bool ReadAnyTokensBeforeDirective)34270b57cec5SDimitry Andric void Preprocessor::HandleIfDirective(Token &IfToken,
34280b57cec5SDimitry Andric const Token &HashToken,
34290b57cec5SDimitry Andric bool ReadAnyTokensBeforeDirective) {
34300b57cec5SDimitry Andric ++NumIf;
34310b57cec5SDimitry Andric
34320b57cec5SDimitry Andric // Parse and evaluate the conditional expression.
34330b57cec5SDimitry Andric IdentifierInfo *IfNDefMacro = nullptr;
34340b57cec5SDimitry Andric const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
34350b57cec5SDimitry Andric const bool ConditionalTrue = DER.Conditional;
3436fe6060f1SDimitry Andric // Lexer might become invalid if we hit code completion point while evaluating
3437fe6060f1SDimitry Andric // expression.
3438fe6060f1SDimitry Andric if (!CurPPLexer)
3439fe6060f1SDimitry Andric return;
34400b57cec5SDimitry Andric
34410b57cec5SDimitry Andric // If this condition is equivalent to #ifndef X, and if this is the first
34420b57cec5SDimitry Andric // directive seen, handle it for the multiple-include optimization.
34430b57cec5SDimitry Andric if (CurPPLexer->getConditionalStackDepth() == 0) {
34440b57cec5SDimitry Andric if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
34450b57cec5SDimitry Andric // FIXME: Pass in the location of the macro name, not the 'if' token.
34460b57cec5SDimitry Andric CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, IfToken.getLocation());
34470b57cec5SDimitry Andric else
34480b57cec5SDimitry Andric CurPPLexer->MIOpt.EnterTopLevelConditional();
34490b57cec5SDimitry Andric }
34500b57cec5SDimitry Andric
34510b57cec5SDimitry Andric if (Callbacks)
34520b57cec5SDimitry Andric Callbacks->If(
34530b57cec5SDimitry Andric IfToken.getLocation(), DER.ExprRange,
34540b57cec5SDimitry Andric (ConditionalTrue ? PPCallbacks::CVK_True : PPCallbacks::CVK_False));
34550b57cec5SDimitry Andric
3456a7dea167SDimitry Andric bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3457a7dea167SDimitry Andric getSourceManager().isInMainFile(IfToken.getLocation());
3458a7dea167SDimitry Andric
34590b57cec5SDimitry Andric // Should we include the stuff contained by this directive?
34600b57cec5SDimitry Andric if (PPOpts->SingleFileParseMode && DER.IncludedUndefinedIds) {
34610b57cec5SDimitry Andric // In 'single-file-parse mode' undefined identifiers trigger parsing of all
34620b57cec5SDimitry Andric // the directive blocks.
34630b57cec5SDimitry Andric CurPPLexer->pushConditionalLevel(IfToken.getLocation(), /*wasskip*/false,
34640b57cec5SDimitry Andric /*foundnonskip*/false, /*foundelse*/false);
3465a7dea167SDimitry Andric } else if (ConditionalTrue || RetainExcludedCB) {
34660b57cec5SDimitry Andric // Yes, remember that we are inside a conditional, then lex the next token.
34670b57cec5SDimitry Andric CurPPLexer->pushConditionalLevel(IfToken.getLocation(), /*wasskip*/false,
34680b57cec5SDimitry Andric /*foundnonskip*/true, /*foundelse*/false);
34690b57cec5SDimitry Andric } else {
34700b57cec5SDimitry Andric // No, skip the contents of this block.
34710b57cec5SDimitry Andric SkipExcludedConditionalBlock(HashToken.getLocation(), IfToken.getLocation(),
34720b57cec5SDimitry Andric /*Foundnonskip*/ false,
34730b57cec5SDimitry Andric /*FoundElse*/ false);
34740b57cec5SDimitry Andric }
34750b57cec5SDimitry Andric }
34760b57cec5SDimitry Andric
34770b57cec5SDimitry Andric /// HandleEndifDirective - Implements the \#endif directive.
34780b57cec5SDimitry Andric ///
HandleEndifDirective(Token & EndifToken)34790b57cec5SDimitry Andric void Preprocessor::HandleEndifDirective(Token &EndifToken) {
34800b57cec5SDimitry Andric ++NumEndif;
34810b57cec5SDimitry Andric
34820b57cec5SDimitry Andric // Check that this is the whole directive.
34830b57cec5SDimitry Andric CheckEndOfDirective("endif");
34840b57cec5SDimitry Andric
34850b57cec5SDimitry Andric PPConditionalInfo CondInfo;
34860b57cec5SDimitry Andric if (CurPPLexer->popConditionalLevel(CondInfo)) {
34870b57cec5SDimitry Andric // No conditionals on the stack: this is an #endif without an #if.
34880b57cec5SDimitry Andric Diag(EndifToken, diag::err_pp_endif_without_if);
34890b57cec5SDimitry Andric return;
34900b57cec5SDimitry Andric }
34910b57cec5SDimitry Andric
34920b57cec5SDimitry Andric // If this the end of a top-level #endif, inform MIOpt.
34930b57cec5SDimitry Andric if (CurPPLexer->getConditionalStackDepth() == 0)
34940b57cec5SDimitry Andric CurPPLexer->MIOpt.ExitTopLevelConditional();
34950b57cec5SDimitry Andric
34960b57cec5SDimitry Andric assert(!CondInfo.WasSkipping && !CurPPLexer->LexingRawMode &&
34970b57cec5SDimitry Andric "This code should only be reachable in the non-skipping case!");
34980b57cec5SDimitry Andric
34990b57cec5SDimitry Andric if (Callbacks)
35000b57cec5SDimitry Andric Callbacks->Endif(EndifToken.getLocation(), CondInfo.IfLoc);
35010b57cec5SDimitry Andric }
35020b57cec5SDimitry Andric
35030b57cec5SDimitry Andric /// HandleElseDirective - Implements the \#else directive.
35040b57cec5SDimitry Andric ///
HandleElseDirective(Token & Result,const Token & HashToken)35050b57cec5SDimitry Andric void Preprocessor::HandleElseDirective(Token &Result, const Token &HashToken) {
35060b57cec5SDimitry Andric ++NumElse;
35070b57cec5SDimitry Andric
35080b57cec5SDimitry Andric // #else directive in a non-skipping conditional... start skipping.
35090b57cec5SDimitry Andric CheckEndOfDirective("else");
35100b57cec5SDimitry Andric
35110b57cec5SDimitry Andric PPConditionalInfo CI;
35120b57cec5SDimitry Andric if (CurPPLexer->popConditionalLevel(CI)) {
35130b57cec5SDimitry Andric Diag(Result, diag::pp_err_else_without_if);
35140b57cec5SDimitry Andric return;
35150b57cec5SDimitry Andric }
35160b57cec5SDimitry Andric
35170b57cec5SDimitry Andric // If this is a top-level #else, inform the MIOpt.
35180b57cec5SDimitry Andric if (CurPPLexer->getConditionalStackDepth() == 0)
35190b57cec5SDimitry Andric CurPPLexer->MIOpt.EnterTopLevelConditional();
35200b57cec5SDimitry Andric
35210b57cec5SDimitry Andric // If this is a #else with a #else before it, report the error.
35220b57cec5SDimitry Andric if (CI.FoundElse) Diag(Result, diag::pp_err_else_after_else);
35230b57cec5SDimitry Andric
35240b57cec5SDimitry Andric if (Callbacks)
35250b57cec5SDimitry Andric Callbacks->Else(Result.getLocation(), CI.IfLoc);
35260b57cec5SDimitry Andric
3527a7dea167SDimitry Andric bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3528a7dea167SDimitry Andric getSourceManager().isInMainFile(Result.getLocation());
3529a7dea167SDimitry Andric
3530a7dea167SDimitry Andric if ((PPOpts->SingleFileParseMode && !CI.FoundNonSkip) || RetainExcludedCB) {
35310b57cec5SDimitry Andric // In 'single-file-parse mode' undefined identifiers trigger parsing of all
35320b57cec5SDimitry Andric // the directive blocks.
35330b57cec5SDimitry Andric CurPPLexer->pushConditionalLevel(CI.IfLoc, /*wasskip*/false,
35340b57cec5SDimitry Andric /*foundnonskip*/false, /*foundelse*/true);
35350b57cec5SDimitry Andric return;
35360b57cec5SDimitry Andric }
35370b57cec5SDimitry Andric
35380b57cec5SDimitry Andric // Finally, skip the rest of the contents of this block.
35390b57cec5SDimitry Andric SkipExcludedConditionalBlock(HashToken.getLocation(), CI.IfLoc,
35400b57cec5SDimitry Andric /*Foundnonskip*/ true,
35410b57cec5SDimitry Andric /*FoundElse*/ true, Result.getLocation());
35420b57cec5SDimitry Andric }
35430b57cec5SDimitry Andric
3544fe6060f1SDimitry Andric /// Implements the \#elif, \#elifdef, and \#elifndef directives.
HandleElifFamilyDirective(Token & ElifToken,const Token & HashToken,tok::PPKeywordKind Kind)3545fe6060f1SDimitry Andric void Preprocessor::HandleElifFamilyDirective(Token &ElifToken,
3546fe6060f1SDimitry Andric const Token &HashToken,
3547fe6060f1SDimitry Andric tok::PPKeywordKind Kind) {
3548fe6060f1SDimitry Andric PPElifDiag DirKind = Kind == tok::pp_elif ? PED_Elif
3549fe6060f1SDimitry Andric : Kind == tok::pp_elifdef ? PED_Elifdef
3550fe6060f1SDimitry Andric : PED_Elifndef;
35510b57cec5SDimitry Andric ++NumElse;
35520b57cec5SDimitry Andric
35535f757f3fSDimitry Andric // Warn if using `#elifdef` & `#elifndef` in not C23 & C++23 mode.
355481ad6265SDimitry Andric switch (DirKind) {
355581ad6265SDimitry Andric case PED_Elifdef:
355681ad6265SDimitry Andric case PED_Elifndef:
355781ad6265SDimitry Andric unsigned DiagID;
355881ad6265SDimitry Andric if (LangOpts.CPlusPlus)
355906c3fb27SDimitry Andric DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
356006c3fb27SDimitry Andric : diag::ext_cxx23_pp_directive;
356181ad6265SDimitry Andric else
35625f757f3fSDimitry Andric DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
35635f757f3fSDimitry Andric : diag::ext_c23_pp_directive;
356481ad6265SDimitry Andric Diag(ElifToken, DiagID) << DirKind;
356581ad6265SDimitry Andric break;
356681ad6265SDimitry Andric default:
356781ad6265SDimitry Andric break;
356881ad6265SDimitry Andric }
356981ad6265SDimitry Andric
35700b57cec5SDimitry Andric // #elif directive in a non-skipping conditional... start skipping.
35710b57cec5SDimitry Andric // We don't care what the condition is, because we will always skip it (since
35720b57cec5SDimitry Andric // the block immediately before it was included).
35730b57cec5SDimitry Andric SourceRange ConditionRange = DiscardUntilEndOfDirective();
35740b57cec5SDimitry Andric
35750b57cec5SDimitry Andric PPConditionalInfo CI;
35760b57cec5SDimitry Andric if (CurPPLexer->popConditionalLevel(CI)) {
3577fe6060f1SDimitry Andric Diag(ElifToken, diag::pp_err_elif_without_if) << DirKind;
35780b57cec5SDimitry Andric return;
35790b57cec5SDimitry Andric }
35800b57cec5SDimitry Andric
35810b57cec5SDimitry Andric // If this is a top-level #elif, inform the MIOpt.
35820b57cec5SDimitry Andric if (CurPPLexer->getConditionalStackDepth() == 0)
35830b57cec5SDimitry Andric CurPPLexer->MIOpt.EnterTopLevelConditional();
35840b57cec5SDimitry Andric
35850b57cec5SDimitry Andric // If this is a #elif with a #else before it, report the error.
3586fe6060f1SDimitry Andric if (CI.FoundElse)
3587fe6060f1SDimitry Andric Diag(ElifToken, diag::pp_err_elif_after_else) << DirKind;
35880b57cec5SDimitry Andric
3589fe6060f1SDimitry Andric if (Callbacks) {
3590fe6060f1SDimitry Andric switch (Kind) {
3591fe6060f1SDimitry Andric case tok::pp_elif:
35920b57cec5SDimitry Andric Callbacks->Elif(ElifToken.getLocation(), ConditionRange,
35930b57cec5SDimitry Andric PPCallbacks::CVK_NotEvaluated, CI.IfLoc);
3594fe6060f1SDimitry Andric break;
3595fe6060f1SDimitry Andric case tok::pp_elifdef:
3596fe6060f1SDimitry Andric Callbacks->Elifdef(ElifToken.getLocation(), ConditionRange, CI.IfLoc);
3597fe6060f1SDimitry Andric break;
3598fe6060f1SDimitry Andric case tok::pp_elifndef:
3599fe6060f1SDimitry Andric Callbacks->Elifndef(ElifToken.getLocation(), ConditionRange, CI.IfLoc);
3600fe6060f1SDimitry Andric break;
3601fe6060f1SDimitry Andric default:
3602fe6060f1SDimitry Andric assert(false && "unexpected directive kind");
3603fe6060f1SDimitry Andric break;
3604fe6060f1SDimitry Andric }
3605fe6060f1SDimitry Andric }
36060b57cec5SDimitry Andric
3607a7dea167SDimitry Andric bool RetainExcludedCB = PPOpts->RetainExcludedConditionalBlocks &&
3608a7dea167SDimitry Andric getSourceManager().isInMainFile(ElifToken.getLocation());
3609a7dea167SDimitry Andric
3610a7dea167SDimitry Andric if ((PPOpts->SingleFileParseMode && !CI.FoundNonSkip) || RetainExcludedCB) {
36110b57cec5SDimitry Andric // In 'single-file-parse mode' undefined identifiers trigger parsing of all
36120b57cec5SDimitry Andric // the directive blocks.
36130b57cec5SDimitry Andric CurPPLexer->pushConditionalLevel(ElifToken.getLocation(), /*wasskip*/false,
36140b57cec5SDimitry Andric /*foundnonskip*/false, /*foundelse*/false);
36150b57cec5SDimitry Andric return;
36160b57cec5SDimitry Andric }
36170b57cec5SDimitry Andric
36180b57cec5SDimitry Andric // Finally, skip the rest of the contents of this block.
36190b57cec5SDimitry Andric SkipExcludedConditionalBlock(
36200b57cec5SDimitry Andric HashToken.getLocation(), CI.IfLoc, /*Foundnonskip*/ true,
36210b57cec5SDimitry Andric /*FoundElse*/ CI.FoundElse, ElifToken.getLocation());
36220b57cec5SDimitry Andric }
3623*0fca6ea1SDimitry Andric
3624*0fca6ea1SDimitry Andric std::optional<LexEmbedParametersResult>
LexEmbedParameters(Token & CurTok,bool ForHasEmbed)3625*0fca6ea1SDimitry Andric Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) {
3626*0fca6ea1SDimitry Andric LexEmbedParametersResult Result{};
3627*0fca6ea1SDimitry Andric SmallVector<Token, 2> ParameterTokens;
3628*0fca6ea1SDimitry Andric tok::TokenKind EndTokenKind = ForHasEmbed ? tok::r_paren : tok::eod;
3629*0fca6ea1SDimitry Andric
3630*0fca6ea1SDimitry Andric auto DiagMismatchedBracesAndSkipToEOD =
3631*0fca6ea1SDimitry Andric [&](tok::TokenKind Expected,
3632*0fca6ea1SDimitry Andric std::pair<tok::TokenKind, SourceLocation> Matches) {
3633*0fca6ea1SDimitry Andric Diag(CurTok, diag::err_expected) << Expected;
3634*0fca6ea1SDimitry Andric Diag(Matches.second, diag::note_matching) << Matches.first;
3635*0fca6ea1SDimitry Andric if (CurTok.isNot(tok::eod))
3636*0fca6ea1SDimitry Andric DiscardUntilEndOfDirective(CurTok);
3637*0fca6ea1SDimitry Andric };
3638*0fca6ea1SDimitry Andric
3639*0fca6ea1SDimitry Andric auto ExpectOrDiagAndSkipToEOD = [&](tok::TokenKind Kind) {
3640*0fca6ea1SDimitry Andric if (CurTok.isNot(Kind)) {
3641*0fca6ea1SDimitry Andric Diag(CurTok, diag::err_expected) << Kind;
3642*0fca6ea1SDimitry Andric if (CurTok.isNot(tok::eod))
3643*0fca6ea1SDimitry Andric DiscardUntilEndOfDirective(CurTok);
3644*0fca6ea1SDimitry Andric return false;
3645*0fca6ea1SDimitry Andric }
3646*0fca6ea1SDimitry Andric return true;
3647*0fca6ea1SDimitry Andric };
3648*0fca6ea1SDimitry Andric
3649*0fca6ea1SDimitry Andric // C23 6.10:
3650*0fca6ea1SDimitry Andric // pp-parameter-name:
3651*0fca6ea1SDimitry Andric // pp-standard-parameter
3652*0fca6ea1SDimitry Andric // pp-prefixed-parameter
3653*0fca6ea1SDimitry Andric //
3654*0fca6ea1SDimitry Andric // pp-standard-parameter:
3655*0fca6ea1SDimitry Andric // identifier
3656*0fca6ea1SDimitry Andric //
3657*0fca6ea1SDimitry Andric // pp-prefixed-parameter:
3658*0fca6ea1SDimitry Andric // identifier :: identifier
3659*0fca6ea1SDimitry Andric auto LexPPParameterName = [&]() -> std::optional<std::string> {
3660*0fca6ea1SDimitry Andric // We expect the current token to be an identifier; if it's not, things
3661*0fca6ea1SDimitry Andric // have gone wrong.
3662*0fca6ea1SDimitry Andric if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3663*0fca6ea1SDimitry Andric return std::nullopt;
3664*0fca6ea1SDimitry Andric
3665*0fca6ea1SDimitry Andric const IdentifierInfo *Prefix = CurTok.getIdentifierInfo();
3666*0fca6ea1SDimitry Andric
3667*0fca6ea1SDimitry Andric // Lex another token; it is either a :: or we're done with the parameter
3668*0fca6ea1SDimitry Andric // name.
3669*0fca6ea1SDimitry Andric LexNonComment(CurTok);
3670*0fca6ea1SDimitry Andric if (CurTok.is(tok::coloncolon)) {
3671*0fca6ea1SDimitry Andric // We found a ::, so lex another identifier token.
3672*0fca6ea1SDimitry Andric LexNonComment(CurTok);
3673*0fca6ea1SDimitry Andric if (!ExpectOrDiagAndSkipToEOD(tok::identifier))
3674*0fca6ea1SDimitry Andric return std::nullopt;
3675*0fca6ea1SDimitry Andric
3676*0fca6ea1SDimitry Andric const IdentifierInfo *Suffix = CurTok.getIdentifierInfo();
3677*0fca6ea1SDimitry Andric
3678*0fca6ea1SDimitry Andric // Lex another token so we're past the name.
3679*0fca6ea1SDimitry Andric LexNonComment(CurTok);
3680*0fca6ea1SDimitry Andric return (llvm::Twine(Prefix->getName()) + "::" + Suffix->getName()).str();
3681*0fca6ea1SDimitry Andric }
3682*0fca6ea1SDimitry Andric return Prefix->getName().str();
3683*0fca6ea1SDimitry Andric };
3684*0fca6ea1SDimitry Andric
3685*0fca6ea1SDimitry Andric // C23 6.10p5: In all aspects, a preprocessor standard parameter specified by
3686*0fca6ea1SDimitry Andric // this document as an identifier pp_param and an identifier of the form
3687*0fca6ea1SDimitry Andric // __pp_param__ shall behave the same when used as a preprocessor parameter,
3688*0fca6ea1SDimitry Andric // except for the spelling.
3689*0fca6ea1SDimitry Andric auto NormalizeParameterName = [](StringRef Name) {
3690*0fca6ea1SDimitry Andric if (Name.size() > 4 && Name.starts_with("__") && Name.ends_with("__"))
3691*0fca6ea1SDimitry Andric return Name.substr(2, Name.size() - 4);
3692*0fca6ea1SDimitry Andric return Name;
3693*0fca6ea1SDimitry Andric };
3694*0fca6ea1SDimitry Andric
3695*0fca6ea1SDimitry Andric auto LexParenthesizedIntegerExpr = [&]() -> std::optional<size_t> {
3696*0fca6ea1SDimitry Andric // we have a limit parameter and its internals are processed using
3697*0fca6ea1SDimitry Andric // evaluation rules from #if.
3698*0fca6ea1SDimitry Andric if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3699*0fca6ea1SDimitry Andric return std::nullopt;
3700*0fca6ea1SDimitry Andric
3701*0fca6ea1SDimitry Andric // We do not consume the ( because EvaluateDirectiveExpression will lex
3702*0fca6ea1SDimitry Andric // the next token for us.
3703*0fca6ea1SDimitry Andric IdentifierInfo *ParameterIfNDef = nullptr;
3704*0fca6ea1SDimitry Andric bool EvaluatedDefined;
3705*0fca6ea1SDimitry Andric DirectiveEvalResult LimitEvalResult = EvaluateDirectiveExpression(
3706*0fca6ea1SDimitry Andric ParameterIfNDef, CurTok, EvaluatedDefined, /*CheckForEOD=*/false);
3707*0fca6ea1SDimitry Andric
3708*0fca6ea1SDimitry Andric if (!LimitEvalResult.Value) {
3709*0fca6ea1SDimitry Andric // If there was an error evaluating the directive expression, we expect
3710*0fca6ea1SDimitry Andric // to be at the end of directive token.
3711*0fca6ea1SDimitry Andric assert(CurTok.is(tok::eod) && "expect to be at the end of directive");
3712*0fca6ea1SDimitry Andric return std::nullopt;
3713*0fca6ea1SDimitry Andric }
3714*0fca6ea1SDimitry Andric
3715*0fca6ea1SDimitry Andric if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3716*0fca6ea1SDimitry Andric return std::nullopt;
3717*0fca6ea1SDimitry Andric
3718*0fca6ea1SDimitry Andric // Eat the ).
3719*0fca6ea1SDimitry Andric LexNonComment(CurTok);
3720*0fca6ea1SDimitry Andric
3721*0fca6ea1SDimitry Andric // C23 6.10.3.2p2: The token defined shall not appear within the constant
3722*0fca6ea1SDimitry Andric // expression.
3723*0fca6ea1SDimitry Andric if (EvaluatedDefined) {
3724*0fca6ea1SDimitry Andric Diag(CurTok, diag::err_defined_in_pp_embed);
3725*0fca6ea1SDimitry Andric return std::nullopt;
3726*0fca6ea1SDimitry Andric }
3727*0fca6ea1SDimitry Andric
3728*0fca6ea1SDimitry Andric if (LimitEvalResult.Value) {
3729*0fca6ea1SDimitry Andric const llvm::APSInt &Result = *LimitEvalResult.Value;
3730*0fca6ea1SDimitry Andric if (Result.isNegative()) {
3731*0fca6ea1SDimitry Andric Diag(CurTok, diag::err_requires_positive_value)
3732*0fca6ea1SDimitry Andric << toString(Result, 10) << /*positive*/ 0;
3733*0fca6ea1SDimitry Andric return std::nullopt;
3734*0fca6ea1SDimitry Andric }
3735*0fca6ea1SDimitry Andric return Result.getLimitedValue();
3736*0fca6ea1SDimitry Andric }
3737*0fca6ea1SDimitry Andric return std::nullopt;
3738*0fca6ea1SDimitry Andric };
3739*0fca6ea1SDimitry Andric
3740*0fca6ea1SDimitry Andric auto GetMatchingCloseBracket = [](tok::TokenKind Kind) {
3741*0fca6ea1SDimitry Andric switch (Kind) {
3742*0fca6ea1SDimitry Andric case tok::l_paren:
3743*0fca6ea1SDimitry Andric return tok::r_paren;
3744*0fca6ea1SDimitry Andric case tok::l_brace:
3745*0fca6ea1SDimitry Andric return tok::r_brace;
3746*0fca6ea1SDimitry Andric case tok::l_square:
3747*0fca6ea1SDimitry Andric return tok::r_square;
3748*0fca6ea1SDimitry Andric default:
3749*0fca6ea1SDimitry Andric llvm_unreachable("should not get here");
3750*0fca6ea1SDimitry Andric }
3751*0fca6ea1SDimitry Andric };
3752*0fca6ea1SDimitry Andric
3753*0fca6ea1SDimitry Andric auto LexParenthesizedBalancedTokenSoup =
3754*0fca6ea1SDimitry Andric [&](llvm::SmallVectorImpl<Token> &Tokens) {
3755*0fca6ea1SDimitry Andric std::vector<std::pair<tok::TokenKind, SourceLocation>> BracketStack;
3756*0fca6ea1SDimitry Andric
3757*0fca6ea1SDimitry Andric // We expect the current token to be a left paren.
3758*0fca6ea1SDimitry Andric if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))
3759*0fca6ea1SDimitry Andric return false;
3760*0fca6ea1SDimitry Andric LexNonComment(CurTok); // Eat the (
3761*0fca6ea1SDimitry Andric
3762*0fca6ea1SDimitry Andric bool WaitingForInnerCloseParen = false;
3763*0fca6ea1SDimitry Andric while (CurTok.isNot(tok::eod) &&
3764*0fca6ea1SDimitry Andric (WaitingForInnerCloseParen || CurTok.isNot(tok::r_paren))) {
3765*0fca6ea1SDimitry Andric switch (CurTok.getKind()) {
3766*0fca6ea1SDimitry Andric default: // Shutting up diagnostics about not fully-covered switch.
3767*0fca6ea1SDimitry Andric break;
3768*0fca6ea1SDimitry Andric case tok::l_paren:
3769*0fca6ea1SDimitry Andric WaitingForInnerCloseParen = true;
3770*0fca6ea1SDimitry Andric [[fallthrough]];
3771*0fca6ea1SDimitry Andric case tok::l_brace:
3772*0fca6ea1SDimitry Andric case tok::l_square:
3773*0fca6ea1SDimitry Andric BracketStack.push_back({CurTok.getKind(), CurTok.getLocation()});
3774*0fca6ea1SDimitry Andric break;
3775*0fca6ea1SDimitry Andric case tok::r_paren:
3776*0fca6ea1SDimitry Andric WaitingForInnerCloseParen = false;
3777*0fca6ea1SDimitry Andric [[fallthrough]];
3778*0fca6ea1SDimitry Andric case tok::r_brace:
3779*0fca6ea1SDimitry Andric case tok::r_square: {
3780*0fca6ea1SDimitry Andric tok::TokenKind Matching =
3781*0fca6ea1SDimitry Andric GetMatchingCloseBracket(BracketStack.back().first);
3782*0fca6ea1SDimitry Andric if (BracketStack.empty() || CurTok.getKind() != Matching) {
3783*0fca6ea1SDimitry Andric DiagMismatchedBracesAndSkipToEOD(Matching, BracketStack.back());
3784*0fca6ea1SDimitry Andric return false;
3785*0fca6ea1SDimitry Andric }
3786*0fca6ea1SDimitry Andric BracketStack.pop_back();
3787*0fca6ea1SDimitry Andric } break;
3788*0fca6ea1SDimitry Andric }
3789*0fca6ea1SDimitry Andric Tokens.push_back(CurTok);
3790*0fca6ea1SDimitry Andric LexNonComment(CurTok);
3791*0fca6ea1SDimitry Andric }
3792*0fca6ea1SDimitry Andric
3793*0fca6ea1SDimitry Andric // When we're done, we want to eat the closing paren.
3794*0fca6ea1SDimitry Andric if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))
3795*0fca6ea1SDimitry Andric return false;
3796*0fca6ea1SDimitry Andric
3797*0fca6ea1SDimitry Andric LexNonComment(CurTok); // Eat the )
3798*0fca6ea1SDimitry Andric return true;
3799*0fca6ea1SDimitry Andric };
3800*0fca6ea1SDimitry Andric
3801*0fca6ea1SDimitry Andric LexNonComment(CurTok); // Prime the pump.
3802*0fca6ea1SDimitry Andric while (!CurTok.isOneOf(EndTokenKind, tok::eod)) {
3803*0fca6ea1SDimitry Andric SourceLocation ParamStartLoc = CurTok.getLocation();
3804*0fca6ea1SDimitry Andric std::optional<std::string> ParamName = LexPPParameterName();
3805*0fca6ea1SDimitry Andric if (!ParamName)
3806*0fca6ea1SDimitry Andric return std::nullopt;
3807*0fca6ea1SDimitry Andric StringRef Parameter = NormalizeParameterName(*ParamName);
3808*0fca6ea1SDimitry Andric
3809*0fca6ea1SDimitry Andric // Lex the parameters (dependent on the parameter type we want!).
3810*0fca6ea1SDimitry Andric //
3811*0fca6ea1SDimitry Andric // C23 6.10.3.Xp1: The X standard embed parameter may appear zero times or
3812*0fca6ea1SDimitry Andric // one time in the embed parameter sequence.
3813*0fca6ea1SDimitry Andric if (Parameter == "limit") {
3814*0fca6ea1SDimitry Andric if (Result.MaybeLimitParam)
3815*0fca6ea1SDimitry Andric Diag(CurTok, diag::err_pp_embed_dup_params) << Parameter;
3816*0fca6ea1SDimitry Andric
3817*0fca6ea1SDimitry Andric std::optional<size_t> Limit = LexParenthesizedIntegerExpr();
3818*0fca6ea1SDimitry Andric if (!Limit)
3819*0fca6ea1SDimitry Andric return std::nullopt;
3820*0fca6ea1SDimitry Andric Result.MaybeLimitParam =
3821*0fca6ea1SDimitry Andric PPEmbedParameterLimit{*Limit, {ParamStartLoc, CurTok.getLocation()}};
3822*0fca6ea1SDimitry Andric } else if (Parameter == "clang::offset") {
3823*0fca6ea1SDimitry Andric if (Result.MaybeOffsetParam)
3824*0fca6ea1SDimitry Andric Diag(CurTok, diag::err_pp_embed_dup_params) << Parameter;
3825*0fca6ea1SDimitry Andric
3826*0fca6ea1SDimitry Andric std::optional<size_t> Offset = LexParenthesizedIntegerExpr();
3827*0fca6ea1SDimitry Andric if (!Offset)
3828*0fca6ea1SDimitry Andric return std::nullopt;
3829*0fca6ea1SDimitry Andric Result.MaybeOffsetParam = PPEmbedParameterOffset{
3830*0fca6ea1SDimitry Andric *Offset, {ParamStartLoc, CurTok.getLocation()}};
3831*0fca6ea1SDimitry Andric } else if (Parameter == "prefix") {
3832*0fca6ea1SDimitry Andric if (Result.MaybePrefixParam)
3833*0fca6ea1SDimitry Andric Diag(CurTok, diag::err_pp_embed_dup_params) << Parameter;
3834*0fca6ea1SDimitry Andric
3835*0fca6ea1SDimitry Andric SmallVector<Token, 4> Soup;
3836*0fca6ea1SDimitry Andric if (!LexParenthesizedBalancedTokenSoup(Soup))
3837*0fca6ea1SDimitry Andric return std::nullopt;
3838*0fca6ea1SDimitry Andric Result.MaybePrefixParam = PPEmbedParameterPrefix{
3839*0fca6ea1SDimitry Andric std::move(Soup), {ParamStartLoc, CurTok.getLocation()}};
3840*0fca6ea1SDimitry Andric } else if (Parameter == "suffix") {
3841*0fca6ea1SDimitry Andric if (Result.MaybeSuffixParam)
3842*0fca6ea1SDimitry Andric Diag(CurTok, diag::err_pp_embed_dup_params) << Parameter;
3843*0fca6ea1SDimitry Andric
3844*0fca6ea1SDimitry Andric SmallVector<Token, 4> Soup;
3845*0fca6ea1SDimitry Andric if (!LexParenthesizedBalancedTokenSoup(Soup))
3846*0fca6ea1SDimitry Andric return std::nullopt;
3847*0fca6ea1SDimitry Andric Result.MaybeSuffixParam = PPEmbedParameterSuffix{
3848*0fca6ea1SDimitry Andric std::move(Soup), {ParamStartLoc, CurTok.getLocation()}};
3849*0fca6ea1SDimitry Andric } else if (Parameter == "if_empty") {
3850*0fca6ea1SDimitry Andric if (Result.MaybeIfEmptyParam)
3851*0fca6ea1SDimitry Andric Diag(CurTok, diag::err_pp_embed_dup_params) << Parameter;
3852*0fca6ea1SDimitry Andric
3853*0fca6ea1SDimitry Andric SmallVector<Token, 4> Soup;
3854*0fca6ea1SDimitry Andric if (!LexParenthesizedBalancedTokenSoup(Soup))
3855*0fca6ea1SDimitry Andric return std::nullopt;
3856*0fca6ea1SDimitry Andric Result.MaybeIfEmptyParam = PPEmbedParameterIfEmpty{
3857*0fca6ea1SDimitry Andric std::move(Soup), {ParamStartLoc, CurTok.getLocation()}};
3858*0fca6ea1SDimitry Andric } else {
3859*0fca6ea1SDimitry Andric ++Result.UnrecognizedParams;
3860*0fca6ea1SDimitry Andric
3861*0fca6ea1SDimitry Andric // If there's a left paren, we need to parse a balanced token sequence
3862*0fca6ea1SDimitry Andric // and just eat those tokens.
3863*0fca6ea1SDimitry Andric if (CurTok.is(tok::l_paren)) {
3864*0fca6ea1SDimitry Andric SmallVector<Token, 4> Soup;
3865*0fca6ea1SDimitry Andric if (!LexParenthesizedBalancedTokenSoup(Soup))
3866*0fca6ea1SDimitry Andric return std::nullopt;
3867*0fca6ea1SDimitry Andric }
3868*0fca6ea1SDimitry Andric if (!ForHasEmbed) {
3869*0fca6ea1SDimitry Andric Diag(CurTok, diag::err_pp_unknown_parameter) << 1 << Parameter;
3870*0fca6ea1SDimitry Andric return std::nullopt;
3871*0fca6ea1SDimitry Andric }
3872*0fca6ea1SDimitry Andric }
3873*0fca6ea1SDimitry Andric }
3874*0fca6ea1SDimitry Andric return Result;
3875*0fca6ea1SDimitry Andric }
3876*0fca6ea1SDimitry Andric
HandleEmbedDirectiveImpl(SourceLocation HashLoc,const LexEmbedParametersResult & Params,StringRef BinaryContents)3877*0fca6ea1SDimitry Andric void Preprocessor::HandleEmbedDirectiveImpl(
3878*0fca6ea1SDimitry Andric SourceLocation HashLoc, const LexEmbedParametersResult &Params,
3879*0fca6ea1SDimitry Andric StringRef BinaryContents) {
3880*0fca6ea1SDimitry Andric if (BinaryContents.empty()) {
3881*0fca6ea1SDimitry Andric // If we have no binary contents, the only thing we need to emit are the
3882*0fca6ea1SDimitry Andric // if_empty tokens, if any.
3883*0fca6ea1SDimitry Andric // FIXME: this loses AST fidelity; nothing in the compiler will see that
3884*0fca6ea1SDimitry Andric // these tokens came from #embed. We have to hack around this when printing
3885*0fca6ea1SDimitry Andric // preprocessed output. The same is true for prefix and suffix tokens.
3886*0fca6ea1SDimitry Andric if (Params.MaybeIfEmptyParam) {
3887*0fca6ea1SDimitry Andric ArrayRef<Token> Toks = Params.MaybeIfEmptyParam->Tokens;
3888*0fca6ea1SDimitry Andric size_t TokCount = Toks.size();
3889*0fca6ea1SDimitry Andric auto NewToks = std::make_unique<Token[]>(TokCount);
3890*0fca6ea1SDimitry Andric llvm::copy(Toks, NewToks.get());
3891*0fca6ea1SDimitry Andric EnterTokenStream(std::move(NewToks), TokCount, true, true);
3892*0fca6ea1SDimitry Andric }
3893*0fca6ea1SDimitry Andric return;
3894*0fca6ea1SDimitry Andric }
3895*0fca6ea1SDimitry Andric
3896*0fca6ea1SDimitry Andric size_t NumPrefixToks = Params.PrefixTokenCount(),
3897*0fca6ea1SDimitry Andric NumSuffixToks = Params.SuffixTokenCount();
3898*0fca6ea1SDimitry Andric size_t TotalNumToks = 1 + NumPrefixToks + NumSuffixToks;
3899*0fca6ea1SDimitry Andric size_t CurIdx = 0;
3900*0fca6ea1SDimitry Andric auto Toks = std::make_unique<Token[]>(TotalNumToks);
3901*0fca6ea1SDimitry Andric
3902*0fca6ea1SDimitry Andric // Add the prefix tokens, if any.
3903*0fca6ea1SDimitry Andric if (Params.MaybePrefixParam) {
3904*0fca6ea1SDimitry Andric llvm::copy(Params.MaybePrefixParam->Tokens, &Toks[CurIdx]);
3905*0fca6ea1SDimitry Andric CurIdx += NumPrefixToks;
3906*0fca6ea1SDimitry Andric }
3907*0fca6ea1SDimitry Andric
3908*0fca6ea1SDimitry Andric EmbedAnnotationData *Data = new (BP) EmbedAnnotationData;
3909*0fca6ea1SDimitry Andric Data->BinaryData = BinaryContents;
3910*0fca6ea1SDimitry Andric
3911*0fca6ea1SDimitry Andric Toks[CurIdx].startToken();
3912*0fca6ea1SDimitry Andric Toks[CurIdx].setKind(tok::annot_embed);
3913*0fca6ea1SDimitry Andric Toks[CurIdx].setAnnotationRange(HashLoc);
3914*0fca6ea1SDimitry Andric Toks[CurIdx++].setAnnotationValue(Data);
3915*0fca6ea1SDimitry Andric
3916*0fca6ea1SDimitry Andric // Now add the suffix tokens, if any.
3917*0fca6ea1SDimitry Andric if (Params.MaybeSuffixParam) {
3918*0fca6ea1SDimitry Andric llvm::copy(Params.MaybeSuffixParam->Tokens, &Toks[CurIdx]);
3919*0fca6ea1SDimitry Andric CurIdx += NumSuffixToks;
3920*0fca6ea1SDimitry Andric }
3921*0fca6ea1SDimitry Andric
3922*0fca6ea1SDimitry Andric assert(CurIdx == TotalNumToks && "Calculated the incorrect number of tokens");
3923*0fca6ea1SDimitry Andric EnterTokenStream(std::move(Toks), TotalNumToks, true, true);
3924*0fca6ea1SDimitry Andric }
3925*0fca6ea1SDimitry Andric
HandleEmbedDirective(SourceLocation HashLoc,Token & EmbedTok,const FileEntry * LookupFromFile)3926*0fca6ea1SDimitry Andric void Preprocessor::HandleEmbedDirective(SourceLocation HashLoc, Token &EmbedTok,
3927*0fca6ea1SDimitry Andric const FileEntry *LookupFromFile) {
3928*0fca6ea1SDimitry Andric // Give the usual extension/compatibility warnings.
3929*0fca6ea1SDimitry Andric if (LangOpts.C23)
3930*0fca6ea1SDimitry Andric Diag(EmbedTok, diag::warn_compat_pp_embed_directive);
3931*0fca6ea1SDimitry Andric else
3932*0fca6ea1SDimitry Andric Diag(EmbedTok, diag::ext_pp_embed_directive)
3933*0fca6ea1SDimitry Andric << (LangOpts.CPlusPlus ? /*Clang*/ 1 : /*C23*/ 0);
3934*0fca6ea1SDimitry Andric
3935*0fca6ea1SDimitry Andric // Parse the filename header
3936*0fca6ea1SDimitry Andric Token FilenameTok;
3937*0fca6ea1SDimitry Andric if (LexHeaderName(FilenameTok))
3938*0fca6ea1SDimitry Andric return;
3939*0fca6ea1SDimitry Andric
3940*0fca6ea1SDimitry Andric if (FilenameTok.isNot(tok::header_name)) {
3941*0fca6ea1SDimitry Andric Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename);
3942*0fca6ea1SDimitry Andric if (FilenameTok.isNot(tok::eod))
3943*0fca6ea1SDimitry Andric DiscardUntilEndOfDirective();
3944*0fca6ea1SDimitry Andric return;
3945*0fca6ea1SDimitry Andric }
3946*0fca6ea1SDimitry Andric
3947*0fca6ea1SDimitry Andric // Parse the optional sequence of
3948*0fca6ea1SDimitry Andric // directive-parameters:
3949*0fca6ea1SDimitry Andric // identifier parameter-name-list[opt] directive-argument-list[opt]
3950*0fca6ea1SDimitry Andric // directive-argument-list:
3951*0fca6ea1SDimitry Andric // '(' balanced-token-sequence ')'
3952*0fca6ea1SDimitry Andric // parameter-name-list:
3953*0fca6ea1SDimitry Andric // '::' identifier parameter-name-list[opt]
3954*0fca6ea1SDimitry Andric Token CurTok;
3955*0fca6ea1SDimitry Andric std::optional<LexEmbedParametersResult> Params =
3956*0fca6ea1SDimitry Andric LexEmbedParameters(CurTok, /*ForHasEmbed=*/false);
3957*0fca6ea1SDimitry Andric
3958*0fca6ea1SDimitry Andric assert((Params || CurTok.is(tok::eod)) &&
3959*0fca6ea1SDimitry Andric "expected success or to be at the end of the directive");
3960*0fca6ea1SDimitry Andric if (!Params)
3961*0fca6ea1SDimitry Andric return;
3962*0fca6ea1SDimitry Andric
3963*0fca6ea1SDimitry Andric // Now, splat the data out!
3964*0fca6ea1SDimitry Andric SmallString<128> FilenameBuffer;
3965*0fca6ea1SDimitry Andric StringRef Filename = getSpelling(FilenameTok, FilenameBuffer);
3966*0fca6ea1SDimitry Andric StringRef OriginalFilename = Filename;
3967*0fca6ea1SDimitry Andric bool isAngled =
3968*0fca6ea1SDimitry Andric GetIncludeFilenameSpelling(FilenameTok.getLocation(), Filename);
3969*0fca6ea1SDimitry Andric // If GetIncludeFilenameSpelling set the start ptr to null, there was an
3970*0fca6ea1SDimitry Andric // error.
3971*0fca6ea1SDimitry Andric assert(!Filename.empty());
3972*0fca6ea1SDimitry Andric OptionalFileEntryRef MaybeFileRef =
3973*0fca6ea1SDimitry Andric this->LookupEmbedFile(Filename, isAngled, true, LookupFromFile);
3974*0fca6ea1SDimitry Andric if (!MaybeFileRef) {
3975*0fca6ea1SDimitry Andric // could not find file
3976*0fca6ea1SDimitry Andric if (Callbacks && Callbacks->EmbedFileNotFound(OriginalFilename)) {
3977*0fca6ea1SDimitry Andric return;
3978*0fca6ea1SDimitry Andric }
3979*0fca6ea1SDimitry Andric Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
3980*0fca6ea1SDimitry Andric return;
3981*0fca6ea1SDimitry Andric }
3982*0fca6ea1SDimitry Andric std::optional<llvm::MemoryBufferRef> MaybeFile =
3983*0fca6ea1SDimitry Andric getSourceManager().getMemoryBufferForFileOrNone(*MaybeFileRef);
3984*0fca6ea1SDimitry Andric if (!MaybeFile) {
3985*0fca6ea1SDimitry Andric // could not find file
3986*0fca6ea1SDimitry Andric Diag(FilenameTok, diag::err_cannot_open_file)
3987*0fca6ea1SDimitry Andric << Filename << "a buffer to the contents could not be created";
3988*0fca6ea1SDimitry Andric return;
3989*0fca6ea1SDimitry Andric }
3990*0fca6ea1SDimitry Andric StringRef BinaryContents = MaybeFile->getBuffer();
3991*0fca6ea1SDimitry Andric
3992*0fca6ea1SDimitry Andric // The order is important between 'offset' and 'limit'; we want to offset
3993*0fca6ea1SDimitry Andric // first and then limit second; otherwise we may reduce the notional resource
3994*0fca6ea1SDimitry Andric // size to something too small to offset into.
3995*0fca6ea1SDimitry Andric if (Params->MaybeOffsetParam) {
3996*0fca6ea1SDimitry Andric // FIXME: just like with the limit() and if_empty() parameters, this loses
3997*0fca6ea1SDimitry Andric // source fidelity in the AST; it has no idea that there was an offset
3998*0fca6ea1SDimitry Andric // involved.
3999*0fca6ea1SDimitry Andric // offsets all the way to the end of the file make for an empty file.
4000*0fca6ea1SDimitry Andric BinaryContents = BinaryContents.substr(Params->MaybeOffsetParam->Offset);
4001*0fca6ea1SDimitry Andric }
4002*0fca6ea1SDimitry Andric
4003*0fca6ea1SDimitry Andric if (Params->MaybeLimitParam) {
4004*0fca6ea1SDimitry Andric // FIXME: just like with the clang::offset() and if_empty() parameters,
4005*0fca6ea1SDimitry Andric // this loses source fidelity in the AST; it has no idea there was a limit
4006*0fca6ea1SDimitry Andric // involved.
4007*0fca6ea1SDimitry Andric BinaryContents = BinaryContents.substr(0, Params->MaybeLimitParam->Limit);
4008*0fca6ea1SDimitry Andric }
4009*0fca6ea1SDimitry Andric
4010*0fca6ea1SDimitry Andric if (Callbacks)
4011*0fca6ea1SDimitry Andric Callbacks->EmbedDirective(HashLoc, Filename, isAngled, MaybeFileRef,
4012*0fca6ea1SDimitry Andric *Params);
4013*0fca6ea1SDimitry Andric HandleEmbedDirectiveImpl(HashLoc, *Params, BinaryContents);
4014*0fca6ea1SDimitry Andric }
4015