Skip to content

Commit dac71d2

Browse files
authored
Merge pull request #7540 from bnbarham/591-macros
[5.9.1] Enable macros for Windows in 5.9.1
2 parents 8ee3f51 + a6d42b4 commit dac71d2

File tree

19 files changed

+182
-96
lines changed

19 files changed

+182
-96
lines changed

clang/include/clang/Basic/FileManager.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,13 @@ class FileManager : public RefCountedBase<FileManager> {
339339
/// required, which is (almost) never.
340340
StringRef getCanonicalName(const FileEntry *File);
341341

342+
private:
343+
/// Retrieve the canonical name for a given file or directory.
344+
///
345+
/// The first param is a key in the CanonicalNames array.
346+
StringRef getCanonicalName(const void *Entry, StringRef Name);
347+
348+
public:
342349
void PrintStats() const;
343350
};
344351

clang/lib/Basic/FileManager.cpp

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -651,34 +651,48 @@ void FileManager::GetUniqueIDMapping(
651651
}
652652

653653
StringRef FileManager::getCanonicalName(const DirectoryEntry *Dir) {
654-
llvm::DenseMap<const void *, llvm::StringRef>::iterator Known
655-
= CanonicalNames.find(Dir);
656-
if (Known != CanonicalNames.end())
657-
return Known->second;
658-
659-
StringRef CanonicalName(Dir->getName());
660-
661-
SmallString<4096> CanonicalNameBuf;
662-
if (!FS->getRealPath(Dir->getName(), CanonicalNameBuf))
663-
CanonicalName = CanonicalNameBuf.str().copy(CanonicalNameStorage);
664-
665-
CanonicalNames.insert({Dir, CanonicalName});
666-
return CanonicalName;
654+
return getCanonicalName(Dir, Dir->getName());
667655
}
668656

669657
StringRef FileManager::getCanonicalName(const FileEntry *File) {
670-
llvm::DenseMap<const void *, llvm::StringRef>::iterator Known
671-
= CanonicalNames.find(File);
658+
return getCanonicalName(File, File->getName());
659+
}
660+
661+
StringRef FileManager::getCanonicalName(const void *Entry, StringRef Name) {
662+
llvm::DenseMap<const void *, llvm::StringRef>::iterator Known =
663+
CanonicalNames.find(Entry);
672664
if (Known != CanonicalNames.end())
673665
return Known->second;
674666

675-
StringRef CanonicalName(File->getName());
676-
677-
SmallString<4096> CanonicalNameBuf;
678-
if (!FS->getRealPath(File->getName(), CanonicalNameBuf))
679-
CanonicalName = CanonicalNameBuf.str().copy(CanonicalNameStorage);
667+
// Name comes from FileEntry/DirectoryEntry::getName(), so it is safe to
668+
// store it in the DenseMap below.
669+
StringRef CanonicalName(Name);
670+
671+
SmallString<256> AbsPathBuf;
672+
SmallString<256> RealPathBuf;
673+
if (!FS->getRealPath(Name, RealPathBuf)) {
674+
if (is_style_windows(llvm::sys::path::Style::native)) {
675+
// For Windows paths, only use the real path if it doesn't resolve
676+
// a substitute drive, as those are used to avoid MAX_PATH issues.
677+
AbsPathBuf = Name;
678+
if (!FS->makeAbsolute(AbsPathBuf)) {
679+
if (llvm::sys::path::root_name(RealPathBuf) ==
680+
llvm::sys::path::root_name(AbsPathBuf)) {
681+
CanonicalName = RealPathBuf.str().copy(CanonicalNameStorage);
682+
} else {
683+
// Fallback to using the absolute path.
684+
// Simplifying /../ is semantically valid on Windows even in the
685+
// presence of symbolic links.
686+
llvm::sys::path::remove_dots(AbsPathBuf, /*remove_dot_dot=*/true);
687+
CanonicalName = AbsPathBuf.str().copy(CanonicalNameStorage);
688+
}
689+
}
690+
} else {
691+
CanonicalName = RealPathBuf.str().copy(CanonicalNameStorage);
692+
}
693+
}
680694

681-
CanonicalNames.insert({File, CanonicalName});
695+
CanonicalNames.insert({Entry, CanonicalName});
682696
return CanonicalName;
683697
}
684698

clang/lib/ExtractAPI/ExtractAPIConsumer.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,7 @@ struct LocationFileChecker {
184184
if (ExternalFileEntries.count(File))
185185
return false;
186186

187-
StringRef FileName = File->tryGetRealPathName().empty()
188-
? File->getName()
189-
: File->tryGetRealPathName();
187+
StringRef FileName = SM.getFileManager().getCanonicalName(File);
190188

191189
// Try to reduce the include name the same way we tried to include it.
192190
bool IsQuoted = false;

clang/test/Lexer/case-insensitive-include-win.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@
22
// This file should only include code that really needs a Windows host OS to
33
// run.
44

5+
// Note: We must use the real path here, because the logic to detect case
6+
// mismatches must resolve the real path to figure out the original casing.
7+
// If we use %t and we are on a substitute drive S: mapping to C:\subst,
8+
// then we will compare "S:\test.dir\FOO.h" to "C:\subst\test.dir\foo.h"
9+
// and avoid emitting the diagnostic because the structure is different.
10+
511
// REQUIRES: system-windows
612
// RUN: mkdir -p %t.dir
713
// RUN: touch %t.dir/foo.h
8-
// RUN: not %clang_cl /FI\\?\%t.dir\FOO.h /WX -fsyntax-only %s 2>&1 | FileCheck %s
14+
// RUN: not %clang_cl /FI \\?\%{t:real}.dir\FOO.h /WX -fsyntax-only %s 2>&1 | FileCheck %s
915

1016
// CHECK: non-portable path to file '"\\?\

lldb/cmake/modules/AddLLDB.cmake

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,17 +190,27 @@ function(add_properties_for_swift_modules target reldir)
190190
# Workaround for a linker crash related to autolinking: rdar://77839981
191191
set_property(TARGET ${target} APPEND_STRING PROPERTY
192192
LINK_FLAGS " -lobjc ")
193+
194+
set_property(TARGET ${target} APPEND PROPERTY BUILD_RPATH "${SWIFT_BUILD_RPATH}")
195+
set_property(TARGET ${target} APPEND PROPERTY INSTALL_RPATH "${SWIFT_INSTALL_RPATH}")
193196
elseif (CMAKE_SYSTEM_NAME MATCHES "Linux|Android|OpenBSD|FreeBSD")
194197
string(REGEX MATCH "^[^-]*" arch ${LLVM_TARGET_TRIPLE})
195198
target_link_libraries(${target} PRIVATE swiftCore-linux-${arch})
196199
string(TOLOWER ${CMAKE_SYSTEM_NAME} platform)
197200
set(SWIFT_BUILD_RPATH "${LLDB_SWIFT_LIBS}/${platform}")
198201
set(SWIFT_INSTALL_RPATH "$ORIGIN/${reldir}lib/swift/${platform}")
202+
set_property(TARGET ${target} APPEND PROPERTY BUILD_RPATH "${SWIFT_BUILD_RPATH}")
203+
set_property(TARGET ${target} APPEND PROPERTY INSTALL_RPATH "${SWIFT_INSTALL_RPATH}")
204+
elseif(CMAKE_SYSTEM_NAME MATCHES Windows)
205+
if(CMAKE_SYSTEM_PROCESSOR MATCHES AMD64|amd64|x86_64)
206+
target_link_directories(${target} PRIVATE
207+
${SWIFT_PATH_TO_SWIFT_SDK}/usr/lib/swift/windows/x86_64)
208+
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES ARM64|arm64|aarch64)
209+
target_link_directories(${target} PRIVATE
210+
${SWIFT_PATH_TO_SWIFT_SDK}/usr/lib/swift/windows/aarch64)
211+
endif()
199212
endif()
200213

201-
set_property(TARGET ${target} APPEND PROPERTY BUILD_RPATH "${SWIFT_BUILD_RPATH}")
202-
set_property(TARGET ${target} APPEND PROPERTY INSTALL_RPATH "${SWIFT_INSTALL_RPATH}")
203-
204214
if (SWIFT_SWIFT_PARSER)
205215
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
206216
set_property(TARGET ${target}

llvm/cmake/modules/AddLLVM.cmake

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1688,10 +1688,15 @@ endfunction()
16881688
# use it and can't be in a lit module. Use with make_paths_relative().
16891689
string(CONCAT LLVM_LIT_PATH_FUNCTION
16901690
"# Allow generated file to be relocatable.\n"
1691-
"from pathlib import Path\n"
1691+
"import os\n"
1692+
"import platform\n"
16921693
"def path(p):\n"
16931694
" if not p: return ''\n"
1694-
" return str((Path(__file__).parent / p).resolve())\n"
1695+
" # Follows lit.util.abs_path_preserve_drive, which cannot be imported here.\n"
1696+
" if platform.system() == 'Windows':\n"
1697+
" return os.path.abspath(os.path.join(os.path.dirname(__file__), p))\n"
1698+
" else:\n"
1699+
" return os.path.realpath(os.path.join(os.path.dirname(__file__), p))\n"
16951700
)
16961701

16971702
# This function provides an automatic way to 'configure'-like generate a file

llvm/docs/CommandGuide/lit.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,16 @@ TestRunner.py:
541541
%/p %p but ``\`` is replaced by ``/``
542542
%/t %t but ``\`` is replaced by ``/``
543543
%/T %T but ``\`` is replaced by ``/``
544+
%{s:real} %s after expanding all symbolic links and substitute drives
545+
%{S:real} %S after expanding all symbolic links and substitute drives
546+
%{p:real} %p after expanding all symbolic links and substitute drives
547+
%{t:real} %t after expanding all symbolic links and substitute drives
548+
%{T:real} %T after expanding all symbolic links and substitute drives
549+
%{/s:real} %/s after expanding all symbolic links and substitute drives
550+
%{/S:real} %/S after expanding all symbolic links and substitute drives
551+
%{/p:real} %/p after expanding all symbolic links and substitute drives
552+
%{/t:real} %/t after expanding all symbolic links and substitute drives
553+
%{/T:real} %/T after expanding all symbolic links and substitute drives
544554
%{/s:regex_replacement} %/s but escaped for use in the replacement of a ``s@@@`` command in sed
545555
%{/S:regex_replacement} %/S but escaped for use in the replacement of a ``s@@@`` command in sed
546556
%{/p:regex_replacement} %/p but escaped for use in the replacement of a ``s@@@`` command in sed

llvm/docs/TestingGuide.rst

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ RUN lines:
581581
``${fs-sep}``
582582
Expands to the file system separator, i.e. ``/`` or ``\`` on Windows.
583583

584-
``%/s, %/S, %/t, %/T:``
584+
``%/s, %/S, %/t, %/T``
585585

586586
Act like the corresponding substitution above but replace any ``\``
587587
character with a ``/``. This is useful to normalize path separators.
@@ -590,7 +590,17 @@ RUN lines:
590590

591591
Example: ``%/s: C:/Desktop Files/foo_test.s.tmp``
592592

593-
``%:s, %:S, %:t, %:T:``
593+
``%{s:real}, %{S:real}, %{t:real}, %{T:real}``
594+
``%{/s:real}, %{/S:real}, %{/t:real}, %{/T:real}``
595+
596+
Act like the corresponding substitution, including with ``/``, but use
597+
the real path by expanding all symbolic links and substitute drives.
598+
599+
Example: ``%s: S:\foo_test.s.tmp``
600+
601+
Example: ``%{/s:real}: C:/SDrive/foo_test.s.tmp``
602+
603+
``%:s, %:S, %:t, %:T``
594604

595605
Act like the corresponding substitution above but remove colons at
596606
the beginning of Windows paths. This is useful to allow concatenation

llvm/include/llvm/Support/DynamicLibrary.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ class DynamicLibrary {
4545
/// Returns true if the object refers to a valid library.
4646
bool isValid() const { return Data != &Invalid; }
4747

48+
/// Return the OS specific handle value.
49+
void *getOSSpecificHandle() const { return Data; }
50+
4851
/// Searches through the library for the symbol \p symbolName. If it is
4952
/// found, the address of that symbol is returned. If not, NULL is returned.
5053
/// Note that NULL will also be returned if the library failed to load.

llvm/lib/Support/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ endif( MSVC OR MINGW )
8181
# Delay load shell32.dll if possible to speed up process startup.
8282
set (delayload_flags)
8383
if (MSVC)
84-
set (delayload_flags delayimp -delayload:shell32.dll -delayload:ole32.dll)
84+
set (delayload_flags $<$<NOT:$<LINK_LANGUAGE:Swift>>:delayimp -delayload:shell32.dll -delayload:ole32.dll>)
8585
endif()
8686

8787
# Link Z3 if the user wants to build it.

llvm/utils/lit/lit/TestRunner.py

Lines changed: 52 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def change_dir(self, newdir):
7070
if os.path.isabs(newdir):
7171
self.cwd = newdir
7272
else:
73-
self.cwd = os.path.realpath(os.path.join(self.cwd, newdir))
73+
self.cwd = lit.util.abs_path_preserve_drive(os.path.join(self.cwd, newdir))
7474

7575
class TimeoutHelper(object):
7676
"""
@@ -401,7 +401,7 @@ def executeBuiltinMkdir(cmd, cmd_shenv):
401401
dir = to_unicode(dir) if kIsWindows else to_bytes(dir)
402402
cwd = to_unicode(cwd) if kIsWindows else to_bytes(cwd)
403403
if not os.path.isabs(dir):
404-
dir = os.path.realpath(os.path.join(cwd, dir))
404+
dir = lit.util.abs_path_preserve_drive(os.path.join(cwd, dir))
405405
if parent:
406406
lit.util.mkdir_p(dir)
407407
else:
@@ -446,7 +446,7 @@ def on_rm_error(func, path, exc_info):
446446
path = to_unicode(path) if kIsWindows else to_bytes(path)
447447
cwd = to_unicode(cwd) if kIsWindows else to_bytes(cwd)
448448
if not os.path.isabs(path):
449-
path = os.path.realpath(os.path.join(cwd, path))
449+
path = lit.util.abs_path_preserve_drive(os.path.join(cwd, path))
450450
if force and not os.path.exists(path):
451451
continue
452452
try:
@@ -1153,58 +1153,59 @@ def getDefaultSubstitutions(test, tmpDir, tmpBase, normalize_slashes=False):
11531153
substitutions.extend(test.config.substitutions)
11541154
tmpName = tmpBase + '.tmp'
11551155
baseName = os.path.basename(tmpBase)
1156-
substitutions.extend([('%s', sourcepath),
1157-
('%S', sourcedir),
1158-
('%p', sourcedir),
1159-
('%{pathsep}', os.pathsep),
1160-
('%t', tmpName),
1161-
('%basename_t', baseName),
1162-
('%T', tmpDir)])
1163-
1164-
substitutions.extend([
1165-
('%{fs-src-root}', pathlib.Path(sourcedir).anchor),
1166-
('%{fs-tmp-root}', pathlib.Path(tmpBase).anchor),
1167-
('%{fs-sep}', os.path.sep),
1168-
])
1169-
1170-
# "%/[STpst]" should be normalized.
1171-
substitutions.extend([
1172-
('%/s', sourcepath.replace('\\', '/')),
1173-
('%/S', sourcedir.replace('\\', '/')),
1174-
('%/p', sourcedir.replace('\\', '/')),
1175-
('%/t', tmpBase.replace('\\', '/') + '.tmp'),
1176-
('%/T', tmpDir.replace('\\', '/')),
1177-
('%/et',tmpName.replace('\\', '\\\\\\\\\\\\\\\\')),
1178-
])
1179-
1180-
# "%{/[STpst]:regex_replacement}" should be normalized like "%/[STpst]" but we're
1181-
# also in a regex replacement context of a s@@@ regex.
1156+
1157+
substitutions.append(("%{pathsep}", os.pathsep))
1158+
substitutions.append(("%basename_t", baseName))
1159+
1160+
substitutions.extend(
1161+
[
1162+
("%{fs-src-root}", pathlib.Path(sourcedir).anchor),
1163+
("%{fs-tmp-root}", pathlib.Path(tmpBase).anchor),
1164+
("%{fs-sep}", os.path.sep),
1165+
]
1166+
)
1167+
1168+
substitutions.append(("%/et", tmpName.replace("\\", "\\\\\\\\\\\\\\\\")))
1169+
11821170
def regex_escape(s):
11831171
s = s.replace('@', r'\@')
11841172
s = s.replace('&', r'\&')
11851173
return s
1186-
substitutions.extend([
1187-
('%{/s:regex_replacement}',
1188-
regex_escape(sourcepath.replace('\\', '/'))),
1189-
('%{/S:regex_replacement}',
1190-
regex_escape(sourcedir.replace('\\', '/'))),
1191-
('%{/p:regex_replacement}',
1192-
regex_escape(sourcedir.replace('\\', '/'))),
1193-
('%{/t:regex_replacement}',
1194-
regex_escape(tmpBase.replace('\\', '/')) + '.tmp'),
1195-
('%{/T:regex_replacement}',
1196-
regex_escape(tmpDir.replace('\\', '/'))),
1197-
])
1198-
1199-
# "%:[STpst]" are normalized paths without colons and without a leading
1200-
# slash.
1201-
substitutions.extend([
1202-
('%:s', colonNormalizePath(sourcepath)),
1203-
('%:S', colonNormalizePath(sourcedir)),
1204-
('%:p', colonNormalizePath(sourcedir)),
1205-
('%:t', colonNormalizePath(tmpBase + '.tmp')),
1206-
('%:T', colonNormalizePath(tmpDir)),
1207-
])
1174+
1175+
path_substitutions = [
1176+
("s", sourcepath), ("S", sourcedir), ("p", sourcedir),
1177+
("t", tmpName), ("T", tmpDir)
1178+
]
1179+
for path_substitution in path_substitutions:
1180+
letter = path_substitution[0]
1181+
path = path_substitution[1]
1182+
1183+
# Original path variant
1184+
substitutions.append(("%" + letter, path))
1185+
1186+
# Normalized path separator variant
1187+
substitutions.append(("%/" + letter, path.replace("\\", "/")))
1188+
1189+
# realpath variants
1190+
# Windows paths with substitute drives are not expanded by default
1191+
# as they are used to avoid MAX_PATH issues, but sometimes we do
1192+
# need the fully expanded path.
1193+
real_path = os.path.realpath(path)
1194+
substitutions.append(("%{" + letter + ":real}", real_path))
1195+
substitutions.append(("%{/" + letter + ":real}",
1196+
real_path.replace("\\", "/")))
1197+
1198+
# "%{/[STpst]:regex_replacement}" should be normalized like
1199+
# "%/[STpst]" but we're also in a regex replacement context
1200+
# of a s@@@ regex.
1201+
substitutions.append(
1202+
("%{/" + letter + ":regex_replacement}",
1203+
regex_escape(path.replace("\\", "/"))))
1204+
1205+
# "%:[STpst]" are normalized paths without colons and without
1206+
# a leading slash.
1207+
substitutions.append(("%:" + letter, colonNormalizePath(path)))
1208+
12081209
return substitutions
12091210

12101211
def _memoize(f):

llvm/utils/lit/lit/builtin_commands/diff.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ def main(argv):
229229
try:
230230
for file in args:
231231
if file != "-" and not os.path.isabs(file):
232-
file = os.path.realpath(os.path.join(os.getcwd(), file))
232+
file = util.abs_path_preserve_drive(file)
233233

234234
if flags.recursive_diff:
235235
if file == "-":

0 commit comments

Comments
 (0)