Skip to content

[ClangImporter] Predefine __swift__ in imported (Obj)C code. #4510

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
Aug 26, 2016
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
14 changes: 8 additions & 6 deletions include/swift/Basic/Version.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,15 @@ class Version {

/// Return a string to be used as an internal preprocessor define.
///
/// Assuming the project version is at most X.Y.Z.a.b, the integral constant
/// representing the version is:
/// The components of the version are multiplied element-wise by
/// \p componentWeights, then added together (a dot product operation).
/// If either array is longer than the other, the missing elements are
/// treated as zero.
///
/// X*1000*1000*1000 + Z*1000*1000 + a*1000 + b
///
/// The second version component is not used.
std::string preprocessorDefinition() const;
/// The resulting string will have the form "-DMACRO_NAME=XYYZZ".
/// The combined value must fit in a uint64_t.
std::string preprocessorDefinition(StringRef macroName,
ArrayRef<uint64_t> componentWeights) const;

/// Return the ith version component.
unsigned operator[](size_t i) const {
Expand Down
27 changes: 11 additions & 16 deletions lib/Basic/Version.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,25 +269,20 @@ raw_ostream &operator<<(raw_ostream &os, const Version &version) {
return os;
}

std::string Version::preprocessorDefinition() const {
SmallString<64> define("-D__SWIFT_COMPILER_VERSION=");
llvm::raw_svector_ostream OS(define);
std::string
Version::preprocessorDefinition(StringRef macroName,
ArrayRef<uint64_t> componentWeights) const {
uint64_t versionConstant = 0;

auto NumComponents = Components.size();

if (NumComponents > 0)
versionConstant += Components[0] * 1000 * 1000 * 1000;
// Component 2 is not used.
if (NumComponents > 2)
versionConstant += Components[2] * 1000 * 1000;
if (NumComponents > 3)
versionConstant += Components[3] * 1000;
if (NumComponents > 4)
versionConstant += Components[4];
for (size_t i = 0, e = std::min(componentWeights.size(), Components.size());
i < e; ++i) {
versionConstant += componentWeights[i] * Components[i];
}

OS << versionConstant;
return OS.str().str();
std::string define("-D");
llvm::raw_string_ostream(define) << macroName << '=' << versionConstant;
// This isn't using stream.str() so that we get move semantics.
return define;
}

bool operator>=(const class Version &lhs,
Expand Down
9 changes: 7 additions & 2 deletions lib/ClangImporter/ClangImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,8 @@ getNormalInvocationArguments(std::vector<std::string> &invocationArgStrs,
const llvm::Triple &triple = ctx.LangOpts.Target;
SearchPathOptions &searchPathOpts = ctx.SearchPathOpts;

auto languageVersion = swift::version::Version::getCurrentLanguageVersion();

// Construct the invocation arguments for the current target.
// Add target-independent options first.
invocationArgStrs.insert(
Expand All @@ -332,9 +334,11 @@ getNormalInvocationArguments(std::vector<std::string> &invocationArgStrs,
// Don't emit LLVM IR.
"-fsyntax-only",

// enable block support
// Enable block support.
"-fblocks",

languageVersion.preprocessorDefinition("__swift__", {10000, 100, 1}),

"-fretain-comments-from-system-headers",

SHIMS_INCLUDE_FLAG, searchPathOpts.RuntimeResourcePath,
Expand Down Expand Up @@ -396,7 +400,8 @@ getNormalInvocationArguments(std::vector<std::string> &invocationArgStrs,
auto V = version::Version::getCurrentCompilerVersion();
if (!V.empty()) {
invocationArgStrs.insert(invocationArgStrs.end(), {
V.preprocessorDefinition(),
V.preprocessorDefinition("__SWIFT_COMPILER_VERSION",
{1000000000, /*ignored*/0, 1000000, 1000, 1}),
});
}
} else {
Expand Down
9 changes: 9 additions & 0 deletions test/ClangModules/Inputs/custom-modules/PredefinedMacros.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#if !defined(__swift__)
# error "__swift__ not defined"
#elif __swift__ < 30000
# error "Why are you using such an old version of Swift?"
#elif __swift__ >= 810000
# error "Is Swift 81 out already? If so, please update this test."
#else
void swift3ReadyToGo();
#endif
5 changes: 5 additions & 0 deletions test/ClangModules/Inputs/custom-modules/module.map
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ module ObjCSubscripts {
export *
}

module PredefinedMacros {
header "PredefinedMacros.h"
export *
}

module ProtoWithInitializer {
header "ProtoWithInitializer.h"
export *
Expand Down
5 changes: 5 additions & 0 deletions test/ClangModules/predefined_macros.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse -verify -I %S/Inputs/custom-modules/ %s

import PredefinedMacros

swift3ReadyToGo()