Skip to content

[clang][PP] Add extension to predefine target OS macros #74676

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ FEATURE(blocks, LangOpts.Blocks)
FEATURE(c_thread_safety_attributes, true)
FEATURE(cxx_exceptions, LangOpts.CXXExceptions)
FEATURE(cxx_rtti, LangOpts.RTTI &&LangOpts.RTTIData)
EXTENSION(define_target_os_macros,
PP.getPreprocessorOpts().DefineTargetOSMacros)
FEATURE(enumerator_attributes, true)
FEATURE(nullability, true)
FEATURE(nullability_on_arrays, true)
Expand Down
55 changes: 55 additions & 0 deletions clang/include/clang/Basic/TargetOSMacros.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//===--- TargetOSMacros.def - Target OS macros ------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file specifies the predefined TARGET_OS_* conditional macros.
// A target macro `Name` should be defined if `Predicate` evaluates to true.
// The macro expects `const llvm::Triple &Triple` and the class `llvm::Triple`
// to be available for the predicate.
//
//===----------------------------------------------------------------------===//

#ifndef TARGET_OS
#define TARGET_OS(Name, Predicate)
#endif

// Windows targets.
TARGET_OS(TARGET_OS_WIN32, Triple.isOSWindows())
TARGET_OS(TARGET_OS_WINDOWS, Triple.isOSWindows())

// Linux target.
TARGET_OS(TARGET_OS_LINUX, Triple.isOSLinux())

// Unix target.
TARGET_OS(TARGET_OS_UNIX, Triple.isOSNetBSD() ||
Triple.isOSFreeBSD() ||
Triple.isOSOpenBSD() ||
Triple.isOSSolaris())

// Apple (Mac) targets.
TARGET_OS(TARGET_OS_MAC, Triple.isOSDarwin())
TARGET_OS(TARGET_OS_OSX, Triple.isMacOSX())
TARGET_OS(TARGET_OS_IPHONE, Triple.isiOS() || Triple.isTvOS() ||
Triple.isWatchOS())
// Triple::isiOS() also includes tvOS
TARGET_OS(TARGET_OS_IOS, Triple.getOS() == llvm::Triple::IOS)
TARGET_OS(TARGET_OS_TV, Triple.isTvOS())
TARGET_OS(TARGET_OS_WATCH, Triple.isWatchOS())
TARGET_OS(TARGET_OS_DRIVERKIT, Triple.isDriverKit())
TARGET_OS(TARGET_OS_MACCATALYST, Triple.isMacCatalystEnvironment())
TARGET_OS(TARGET_OS_SIMULATOR, Triple.isSimulatorEnvironment())

// Deprecated Apple target conditionals.
TARGET_OS(TARGET_OS_EMBEDDED, (Triple.isiOS() || Triple.isTvOS() \
|| Triple.isWatchOS()) \
&& !Triple.isMacCatalystEnvironment() \
&& !Triple.isSimulatorEnvironment())
TARGET_OS(TARGET_OS_NANO, Triple.isWatchOS())
TARGET_OS(TARGET_IPHONE_SIMULATOR, Triple.isSimulatorEnvironment())
TARGET_OS(TARGET_OS_UIKITFORMAC, Triple.isMacCatalystEnvironment())

#undef TARGET_OS
3 changes: 3 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1818,6 +1818,9 @@ def fcomment_block_commands : CommaJoined<["-"], "fcomment-block-commands=">, Gr
Visibility<[ClangOption, CC1Option]>,
HelpText<"Treat each comma separated argument in <arg> as a documentation comment block command">,
MetaVarName<"<arg>">, MarshallingInfoStringVector<LangOpts<"CommentOpts.BlockCommandNames">>;
defm define_target_os_macros : OptInCC1FFlag<"define-target-os-macros",
"Enable", "Disable", " predefined target OS macros",
[ClangOption, CC1Option]>;
def fparse_all_comments : Flag<["-"], "fparse-all-comments">, Group<f_clang_Group>,
Visibility<[ClangOption, CC1Option]>,
MarshallingInfoFlag<LangOpts<"CommentOpts.ParseAllComments">>;
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Lex/PreprocessorOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ class PreprocessorOptions {
/// predefines.
bool UsePredefines = true;

/// Indicates whether to predefine target OS macros.
bool DefineTargetOSMacros = false;

/// Whether we should maintain a detailed record of all macro
/// definitions and expansions.
bool DetailedRecord = false;
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,9 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-source-date-epoch");
CmdArgs.push_back(Args.MakeArgString(Epoch));
}

Args.addOptInFlag(CmdArgs, options::OPT_fdefine_target_os_macros,
options::OPT_fno_define_target_os_macros);
}

// FIXME: Move to target hook.
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Driver/ToolChains/Darwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2916,6 +2916,10 @@ void Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
// to fix the same problem with C++ headers, and is generally fragile.
if (!sdkSupportsBuiltinModules(TargetPlatform, SDKInfo))
CC1Args.push_back("-fbuiltin-headers-in-system-modules");

if (!DriverArgs.hasArgNoClaim(options::OPT_fdefine_target_os_macros,
options::OPT_fno_define_target_os_macros))
CC1Args.push_back("-fdefine-target-os-macros");
}

void Darwin::addClangCC1ASTargetOptions(
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4365,6 +4365,9 @@ static void GeneratePreprocessorArgs(const PreprocessorOptions &Opts,
if (Opts.SourceDateEpoch)
GenerateArg(Consumer, OPT_source_date_epoch, Twine(*Opts.SourceDateEpoch));

if (Opts.DefineTargetOSMacros)
GenerateArg(Consumer, OPT_fdefine_target_os_macros);

// Don't handle LexEditorPlaceholders. It is implied by the action that is
// generated elsewhere.
}
Expand Down Expand Up @@ -4463,6 +4466,10 @@ static bool ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
if (isStrictlyPreprocessorAction(Action))
Opts.LexEditorPlaceholders = false;

Opts.DefineTargetOSMacros =
Args.hasFlag(OPT_fdefine_target_os_macros,
OPT_fno_define_target_os_macros, Opts.DefineTargetOSMacros);

return Diags.getNumErrors() == NumErrorsBefore;
}

Expand Down
9 changes: 9 additions & 0 deletions clang/lib/Frontend/InitPreprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1344,6 +1344,15 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
if (TI.getTriple().isOSBinFormatELF())
Builder.defineMacro("__ELF__");

// Target OS macro definitions.
if (PPOpts.DefineTargetOSMacros) {
const llvm::Triple &Triple = TI.getTriple();
#define TARGET_OS(Name, Predicate) \
Builder.defineMacro(#Name, (Predicate) ? "1" : "0");
#include "clang/Basic/TargetOSMacros.def"
#undef TARGET_OS
}

// Get other target #defines.
TI.getTargetDefines(LangOpts, Builder);
}
Expand Down
241 changes: 241 additions & 0 deletions clang/test/Driver/fdefine-target-os-macros.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
// RUN: %clang -### --target=arm64-apple-darwin %s 2>&1 | FileCheck %s --check-prefix=DARWIN-DEFAULT
// DARWIN-DEFAULT: "-fdefine-target-os-macros"

// RUN: %clang -### --target=arm-none-linux-gnu %s 2>&1 | FileCheck %s --check-prefix=NON-DARWIN-DEFAULT
// RUN: %clang -### --target=x86_64-pc-win32 %s 2>&1 | FileCheck %s --check-prefix=NON-DARWIN-DEFAULT
// NON-DARWIN-DEFAULT-NOT: "-fdefine-target-os-macros"

// RUN: %clang -dM -E --target=arm64-apple-macos %s 2>&1 \
// RUN: | FileCheck %s -DMAC=1 \
// RUN: -DOSX=1 \
// RUN: -DIPHONE=0 \
// RUN: -DIOS=0 \
// RUN: -DTV=0 \
// RUN: -DWATCH=0 \
// RUN: -DDRIVERKIT=0 \
// RUN: -DMACCATALYST=0 \
// RUN: -DEMBEDDED=0 \
// RUN: -DSIMULATOR=0 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
// RUN: -DUNIX=0

// RUN: %clang -dM -E --target=arm64-apple-ios %s 2>&1 \
// RUN: | FileCheck %s -DMAC=1 \
// RUN: -DOSX=0 \
// RUN: -DIPHONE=1 \
// RUN: -DIOS=1 \
// RUN: -DTV=0 \
// RUN: -DWATCH=0 \
// RUN: -DDRIVERKIT=0 \
// RUN: -DMACCATALYST=0 \
// RUN: -DEMBEDDED=1 \
// RUN: -DSIMULATOR=0 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
// RUN: -DUNIX=0

// RUN: %clang -dM -E --target=arm64-apple-ios-macabi %s 2>&1 \
// RUN: | FileCheck %s -DMAC=1 \
// RUN: -DOSX=0 \
// RUN: -DIPHONE=1 \
// RUN: -DIOS=1 \
// RUN: -DTV=0 \
// RUN: -DWATCH=0 \
// RUN: -DDRIVERKIT=0 \
// RUN: -DMACCATALYST=1 \
// RUN: -DEMBEDDED=0 \
// RUN: -DSIMULATOR=0 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
// RUN: -DUNIX=0

// RUN: %clang -dM -E --target=arm64-apple-ios-simulator %s 2>&1 \
// RUN: | FileCheck %s -DMAC=1 \
// RUN: -DOSX=0 \
// RUN: -DIPHONE=1 \
// RUN: -DIOS=1 \
// RUN: -DTV=0 \
// RUN: -DWATCH=0 \
// RUN: -DDRIVERKIT=0 \
// RUN: -DMACCATALYST=0 \
// RUN: -DEMBEDDED=0 \
// RUN: -DSIMULATOR=1 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
// RUN: -DUNIX=0

// RUN: %clang -dM -E --target=arm64-apple-tvos %s 2>&1 \
// RUN: | FileCheck %s -DMAC=1 \
// RUN: -DOSX=0 \
// RUN: -DIPHONE=1 \
// RUN: -DIOS=0 \
// RUN: -DTV=1 \
// RUN: -DWATCH=0 \
// RUN: -DDRIVERKIT=0 \
// RUN: -DMACCATALYST=0 \
// RUN: -DEMBEDDED=1 \
// RUN: -DSIMULATOR=0 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
// RUN: -DUNIX=0

// RUN: %clang -dM -E --target=arm64-apple-tvos-simulator %s 2>&1 \
// RUN: | FileCheck %s -DMAC=1 \
// RUN: -DOSX=0 \
// RUN: -DIPHONE=1 \
// RUN: -DIOS=0 \
// RUN: -DTV=1 \
// RUN: -DWATCH=0 \
// RUN: -DDRIVERKIT=0 \
// RUN: -DMACCATALYST=0 \
// RUN: -DEMBEDDED=0 \
// RUN: -DSIMULATOR=1 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
// RUN: -DUNIX=0

// RUN: %clang -dM -E --target=arm64-apple-watchos %s 2>&1 \
// RUN: | FileCheck %s -DMAC=1 \
// RUN: -DOSX=0 \
// RUN: -DIPHONE=1 \
// RUN: -DIOS=0 \
// RUN: -DTV=0 \
// RUN: -DWATCH=1 \
// RUN: -DDRIVERKIT=0 \
// RUN: -DMACCATALYST=0 \
// RUN: -DEMBEDDED=1 \
// RUN: -DSIMULATOR=0 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
// RUN: -DUNIX=0

// RUN: %clang -dM -E --target=arm64-apple-watchos-simulator %s 2>&1 \
// RUN: | FileCheck %s -DMAC=1 \
// RUN: -DOSX=0 \
// RUN: -DIPHONE=1 \
// RUN: -DIOS=0 \
// RUN: -DTV=0 \
// RUN: -DWATCH=1 \
// RUN: -DDRIVERKIT=0 \
// RUN: -DMACCATALYST=0 \
// RUN: -DEMBEDDED=0 \
// RUN: -DSIMULATOR=1 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
// RUN: -DUNIX=0

// RUN: %clang -dM -E --target=arm64-apple-driverkit %s 2>&1 \
// RUN: | FileCheck %s -DMAC=1 \
// RUN: -DOSX=0 \
// RUN: -DIPHONE=0 \
// RUN: -DIOS=0 \
// RUN: -DTV=0 \
// RUN: -DWATCH=0 \
// RUN: -DDRIVERKIT=1 \
// RUN: -DMACCATALYST=0 \
// RUN: -DEMBEDDED=0 \
// RUN: -DSIMULATOR=0 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
// RUN: -DUNIX=0

// RUN: %clang -dM -E --target=x86_64-pc-linux-gnu \
// RUN: -fdefine-target-os-macros %s 2>&1 \
// RUN: | FileCheck %s -DMAC=0 \
// RUN: -DOSX=0 \
// RUN: -DIPHONE=0 \
// RUN: -DIOS=0 \
// RUN: -DTV=0 \
// RUN: -DWATCH=0 \
// RUN: -DDRIVERKIT=0 \
// RUN: -DMACCATALYST=0 \
// RUN: -DEMBEDDED=0 \
// RUN: -DSIMULATOR=0 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=1 \
// RUN: -DUNIX=0

// RUN: %clang -dM -E --target=x86_64-pc-win32 \
// RUN: -fdefine-target-os-macros %s 2>&1 \
// RUN: | FileCheck %s -DMAC=0 \
// RUN: -DOSX=0 \
// RUN: -DIPHONE=0 \
// RUN: -DIOS=0 \
// RUN: -DTV=0 \
// RUN: -DWATCH=0 \
// RUN: -DDRIVERKIT=0 \
// RUN: -DMACCATALYST=0 \
// RUN: -DEMBEDDED=0 \
// RUN: -DSIMULATOR=0 \
// RUN: -DWINDOWS=1 \
// RUN: -DLINUX=0 \
// RUN: -DUNIX=0

// RUN: %clang -dM -E --target=x86_64-pc-windows-gnu \
// RUN: -fdefine-target-os-macros %s 2>&1 \
// RUN: | FileCheck %s -DMAC=0 \
// RUN: -DOSX=0 \
// RUN: -DIPHONE=0 \
// RUN: -DIOS=0 \
// RUN: -DTV=0 \
// RUN: -DWATCH=0 \
// RUN: -DDRIVERKIT=0 \
// RUN: -DMACCATALYST=0 \
// RUN: -DEMBEDDED=0 \
// RUN: -DSIMULATOR=0 \
// RUN: -DWINDOWS=1 \
// RUN: -DLINUX=0 \
// RUN: -DUNIX=0

// RUN: %clang -dM -E --target=sparc-none-solaris \
// RUN: -fdefine-target-os-macros %s 2>&1 \
// RUN: | FileCheck %s -DMAC=0 \
// RUN: -DOSX=0 \
// RUN: -DIPHONE=0 \
// RUN: -DIOS=0 \
// RUN: -DTV=0 \
// RUN: -DWATCH=0 \
// RUN: -DDRIVERKIT=0 \
// RUN: -DMACCATALYST=0 \
// RUN: -DEMBEDDED=0 \
// RUN: -DSIMULATOR=0 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
// RUN: -DUNIX=1

// RUN: %clang -dM -E --target=arm64-apple-macos \
// RUN: -fno-define-target-os-macros %s 2>&1 \
// RUN: | FileCheck %s --check-prefix=NEG

// RUN: %clang -dM -E --target=arm64-apple-macos \
// RUN: -fdefine-target-os-macros \
// RUN: -fno-define-target-os-macros %s 2>&1 \
// RUN: | FileCheck %s --check-prefix=NEG

// RUN: %clang -dM -E --target=x86_64-pc-windows \
// RUN: -fdefine-target-os-macros \
// RUN: -fno-define-target-os-macros %s 2>&1 \
// RUN: | FileCheck %s --check-prefix=NEG

// NEG-NOT: #define TARGET_OS_

// CHECK-DAG: #define TARGET_OS_MAC [[MAC]]
// CHECK-DAG: #define TARGET_OS_OSX [[OSX]]
// CHECK-DAG: #define TARGET_OS_IPHONE [[IPHONE]]
// CHECK-DAG: #define TARGET_OS_IOS [[IOS]]
// CHECK-DAG: #define TARGET_OS_TV [[TV]]
// CHECK-DAG: #define TARGET_OS_WATCH [[WATCH]]
// CHECK-DAG: #define TARGET_OS_DRIVERKIT [[DRIVERKIT]]
// CHECK-DAG: #define TARGET_OS_MACCATALYST [[MACCATALYST]]
// CHECK-DAG: #define TARGET_OS_SIMULATOR [[SIMULATOR]]
// Deprecated
// CHECK-DAG: #define TARGET_OS_EMBEDDED [[EMBEDDED]]
// CHECK-DAG: #define TARGET_OS_NANO [[WATCH]]
// CHECK-DAG: #define TARGET_IPHONE_SIMULATOR [[SIMULATOR]]
// CHECK-DAG: #define TARGET_OS_UIKITFORMAC [[MACCATALYST]]
// Non-darwin OSes
// CHECK-DAG: #define TARGET_OS_WIN32 [[WINDOWS]]
// CHECK-DAG: #define TARGET_OS_WINDOWS [[WINDOWS]]
// CHECK-DAG: #define TARGET_OS_LINUX [[LINUX]]
// CHECK-DAG: #define TARGET_OS_UNIX [[UNIX]]