Skip to content

Commit 32260e6

Browse files
authored
Merge pull request #7588 from hughbe/swiftSyntax-win32
Port swiftSyntax to Windows
2 parents bb884f5 + b564a91 commit 32260e6

File tree

5 files changed

+233
-26
lines changed

5 files changed

+233
-26
lines changed

Diff for: include/swift/Basic/OwnedString.h

+31-17
Original file line numberDiff line numberDiff line change
@@ -44,28 +44,43 @@ class OwnedString {
4444
size_t Length;
4545
StringOwnership Ownership;
4646

47+
OwnedString(const char* Data, size_t Length, StringOwnership Ownership)
48+
: Length(Length), Ownership(Ownership) {
49+
assert(Length >= 0 && "expected length to be non-negative");
50+
51+
if (Ownership == StringOwnership::Copied && Data) {
52+
assert(
53+
Length <= strlen(Data) &&
54+
"expected length to be a valid index, within the length of the string");
55+
56+
char *substring = static_cast<char *>(malloc(Length + 1));
57+
assert(substring && "expected successful malloc of copy");
58+
59+
memcpy(substring, Data, Length);
60+
substring[Length] = '\0';
61+
62+
this->Data = substring;
63+
}
64+
else
65+
this->Data = Data;
66+
}
67+
4768
public:
48-
OwnedString()
49-
: Data(nullptr), Length(0), Ownership(StringOwnership::Unowned) {}
69+
OwnedString() : OwnedString(nullptr, 0, StringOwnership::Unowned) {}
5070

51-
OwnedString(const char *Data, size_t Length, StringOwnership Ownership)
52-
: Data(Ownership == StringOwnership::Copied ? strndup(Data, Length) : Data),
53-
Length(Length), Ownership(Ownership) {}
71+
OwnedString(const char *Data, size_t Length)
72+
: OwnedString(Data, Length, StringOwnership::Unowned) {}
5473

55-
OwnedString(StringRef Str, StringOwnership Ownership)
56-
: OwnedString(Ownership == StringOwnership::Copied
57-
? strndup(Str.data(), Str.size())
58-
: Str.data(),
59-
Str.size(), Ownership) {}
74+
OwnedString(StringRef Str) : OwnedString(Str.data(), Str.size()) {}
6075

61-
OwnedString(const char *Data)
62-
: OwnedString(StringRef(Data), StringOwnership::Unowned) {}
76+
OwnedString(const char *Data) : OwnedString(StringRef(Data)) {}
6377

6478
OwnedString(const OwnedString &Other)
65-
: Data(Other.Ownership == StringOwnership::Copied
66-
? strndup(Other.Data, Other.Length)
67-
: Other.Data),
68-
Length(Other.Length), Ownership(Other.Ownership) {}
79+
: OwnedString(Other.Data, Other.Length, Other.Ownership) {}
80+
81+
OwnedString copy() {
82+
return OwnedString(Data, Length, StringOwnership::Copied);
83+
}
6984

7085
/// Returns the length of the string in bytes.
7186
size_t size() const {
@@ -96,4 +111,3 @@ class OwnedString {
96111
} // end namespace swift
97112

98113
#endif // SWIFT_BASIC_OWNEDSTRING_H
99-

Diff for: lib/Parse/Lexer.cpp

+6-7
Original file line numberDiff line numberDiff line change
@@ -737,8 +737,7 @@ syntax::RC<syntax::TokenSyntax> Lexer::fullLex() {
737737
TrailingTrivia.push_front(syntax::TriviaPiece::backtick());
738738
}
739739
auto Result = syntax::TokenSyntax::make(NextToken.getKind(),
740-
OwnedString(NextToken.getText(),
741-
StringOwnership::Copied),
740+
OwnedString(NextToken.getText()).copy(),
742741
syntax::SourcePresence::Present,
743742
{LeadingTrivia}, {TrailingTrivia});
744743
LeadingTrivia.clear();
@@ -1951,19 +1950,19 @@ Optional<syntax::TriviaPiece> Lexer::lexWhitespace(bool StopAtFirstNewline) {
19511950
return syntax::TriviaPiece {
19521951
syntax::TriviaKind::Newline,
19531952
Length,
1954-
OwnedString(Start, Length, StringOwnership::Unowned),
1953+
OwnedString(Start, Length),
19551954
};
19561955
case ' ':
19571956
return syntax::TriviaPiece {
19581957
syntax::TriviaKind::Space,
19591958
Length,
1960-
OwnedString(Start, Length, StringOwnership::Unowned),
1959+
OwnedString(Start, Length),
19611960
};
19621961
case '\t':
19631962
return syntax::TriviaPiece {
19641963
syntax::TriviaKind::Tab,
19651964
Length,
1966-
OwnedString(Start, Length, StringOwnership::Unowned),
1965+
OwnedString(Start, Length),
19671966
};
19681967
default:
19691968
return None;
@@ -1982,7 +1981,7 @@ Optional<syntax::TriviaPiece> Lexer::lexSingleLineComment(syntax::TriviaKind Kin
19821981
return Optional<syntax::TriviaPiece>({
19831982
Kind,
19841983
Length,
1985-
OwnedString(Start, Length, StringOwnership::Unowned)
1984+
OwnedString(Start, Length)
19861985
});
19871986
}
19881987

@@ -1997,7 +1996,7 @@ Lexer::lexBlockComment(syntax::TriviaKind Kind) {
19971996
return Optional<syntax::TriviaPiece>({
19981997
Kind,
19991998
Length,
2000-
OwnedString(Start, Length, StringOwnership::Unowned)
1999+
OwnedString(Start, Length)
20012000
});
20022001
}
20032002

Diff for: lib/Syntax/LegacyASTTransformer.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,7 @@ LegacyASTTransformer::visitStructDecl(StructDecl *D,
297297

298298
if (D->getNameLoc().isValid()) {
299299
auto Identifier = findTokenSyntax(tok::identifier,
300-
OwnedString(D->getName().str(),
301-
StringOwnership::Unowned),
300+
OwnedString(D->getName().str()),
302301
SourceMgr, D->getNameLoc(), BufferID,
303302
Tokens);
304303
StructBuilder.useIdentifier(Identifier);

Diff for: unittests/Basic/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ add_swift_unittest(SwiftBasicTests
1515
FileSystemTest.cpp
1616
ImmutablePointerSetTest.cpp
1717
OptionSetTest.cpp
18+
OwnedStringTest.cpp
1819
PointerIntEnumTest.cpp
1920
PrefixMapTest.cpp
2021
RangeTest.cpp

Diff for: unittests/Basic/OwnedStringTest.cpp

+194
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
//===--- OwnedStringTest.cpp ----------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "swift/Basic/OwnedString.h"
14+
#include "gtest/gtest.h"
15+
16+
using namespace swift;
17+
18+
TEST(OwnedStringTest, char_pointer_empty) {
19+
const char *data = "";
20+
const size_t length = strlen(data);
21+
OwnedString ownedString(data);
22+
23+
EXPECT_EQ(length, ownedString.size());
24+
EXPECT_TRUE(ownedString.empty());
25+
26+
OwnedString copy = ownedString.copy();
27+
EXPECT_EQ(length, copy.size());
28+
EXPECT_TRUE(copy.empty());
29+
30+
StringRef str = copy.str();
31+
EXPECT_EQ("", str);
32+
EXPECT_EQ(length, str.size());
33+
}
34+
35+
TEST(OwnedStringTest, char_pointer_non_empty) {
36+
const char *data = "string";
37+
const size_t length = strlen(data);
38+
OwnedString ownedString(data);
39+
40+
EXPECT_EQ(length, ownedString.size());
41+
EXPECT_FALSE(ownedString.empty());
42+
43+
OwnedString copy = ownedString.copy();
44+
EXPECT_EQ(length, copy.size());
45+
EXPECT_FALSE(copy.empty());
46+
47+
StringRef str = copy.str();
48+
EXPECT_EQ("string", str);
49+
EXPECT_EQ(length, strlen(str.data()));
50+
}
51+
52+
TEST(OwnedStringTest, char_pointer_length_equal) {
53+
const char *data = "string";
54+
size_t length = strlen(data);
55+
OwnedString ownedString(data, length);
56+
57+
EXPECT_EQ(length, ownedString.size());
58+
EXPECT_FALSE(ownedString.empty());
59+
60+
OwnedString copy = ownedString.copy();
61+
EXPECT_EQ(length, copy.size());
62+
EXPECT_FALSE(copy.empty());
63+
64+
// Make sure we correctly copied the data and that it is null
65+
// terminated.
66+
StringRef str = copy.str();
67+
EXPECT_EQ("string", str);
68+
EXPECT_EQ(length, strlen(str.data()));
69+
}
70+
71+
TEST(OwnedStringTest, char_pointer_length_nonzero) {
72+
const char *data = "string";
73+
const size_t length = 1;
74+
OwnedString ownedString(data, length);
75+
76+
EXPECT_EQ(length, ownedString.size());
77+
EXPECT_FALSE(ownedString.empty());
78+
79+
OwnedString copy = ownedString.copy();
80+
EXPECT_EQ(length, copy.size());
81+
EXPECT_FALSE(copy.empty());
82+
83+
// Make sure we correctly copied the data and that it is null
84+
// terminated.
85+
StringRef str = copy.str();
86+
EXPECT_EQ("s", str);
87+
EXPECT_EQ(1, strlen(str.data()));
88+
}
89+
90+
TEST(OwnedStringTest, char_pointer_length_zero) {
91+
const char *data = "string";
92+
const size_t length = 0;
93+
OwnedString ownedString(data, length);
94+
95+
EXPECT_EQ(length, ownedString.size());
96+
EXPECT_TRUE(ownedString.empty());
97+
98+
OwnedString copy = ownedString.copy();
99+
EXPECT_EQ(length, copy.size());
100+
EXPECT_TRUE(copy.empty());
101+
}
102+
103+
TEST(OwnedStringTest, copy_original_new_different) {
104+
// Initialize a mutable string.
105+
const char *original = "string";
106+
const size_t length = strlen(original);
107+
char *data = static_cast<char *>(malloc(length + 1));
108+
memcpy(data, original, length);
109+
data[length] = '\0';
110+
111+
// Create an OwnedString.
112+
OwnedString ownedString(data, length);
113+
114+
EXPECT_EQ(length, ownedString.size());
115+
EXPECT_FALSE(ownedString.empty());
116+
117+
// Copy the string
118+
OwnedString copy = ownedString.copy();
119+
EXPECT_EQ(length, copy.size());
120+
EXPECT_FALSE(copy.empty());
121+
122+
// Make sure we correctly copied the data and that it is null
123+
// terminated.
124+
StringRef str = copy.str();
125+
EXPECT_EQ("string", str);
126+
EXPECT_EQ(length, strlen(str.data()));
127+
128+
// Make sure updating the original pointer doesn't affect the copy.
129+
data[0] = 'a';
130+
131+
EXPECT_EQ("string", str);
132+
}
133+
134+
TEST(OwnedStringTest, copy_constructor_original_not_copy) {
135+
// Initialize a mutable string.
136+
const char *original = "string";
137+
const size_t length = strlen(original);
138+
char *data = static_cast<char *>(malloc(length + 1));
139+
memcpy(data, original, length);
140+
data[length] = '\0';
141+
142+
// Create an OwnedString.
143+
OwnedString ownedString(data, length);
144+
145+
EXPECT_EQ(length, ownedString.size());
146+
EXPECT_FALSE(ownedString.empty());
147+
148+
// Copy the string
149+
OwnedString copy = OwnedString(ownedString);
150+
EXPECT_EQ(length, copy.size());
151+
EXPECT_FALSE(copy.empty());
152+
153+
// Make sure we correctly copied the data and that it is null
154+
// terminated.
155+
StringRef str = copy.str();
156+
EXPECT_EQ("string", str);
157+
EXPECT_EQ(length, strlen(str.data()));
158+
159+
// Make sure updating the original pointer doesn't affect the copy.
160+
data[0] = 'a';
161+
162+
EXPECT_EQ("atring", str);
163+
}
164+
165+
TEST(OwnedStringTest, copy_constructor_original_copy) {
166+
// Initialize a mutable string.
167+
const char *original = "string";
168+
const size_t length = strlen(original);
169+
char *data = static_cast<char *>(malloc(length + 1));
170+
memcpy(data, original, length);
171+
data[length] = '\0';
172+
173+
// Create an OwnedString.
174+
OwnedString ownedString(data, length);
175+
176+
EXPECT_EQ(length, ownedString.size());
177+
EXPECT_FALSE(ownedString.empty());
178+
179+
// Copy the string
180+
OwnedString copy = OwnedString(ownedString.copy());
181+
EXPECT_EQ(length, copy.size());
182+
EXPECT_FALSE(copy.empty());
183+
184+
// Make sure we correctly copied the data and that it is null
185+
// terminated.
186+
StringRef str = copy.str();
187+
EXPECT_EQ("string", str);
188+
EXPECT_EQ(length, strlen(str.data()));
189+
190+
// Make sure updating the original pointer doesn't affect the copy.
191+
data[0] = 'a';
192+
193+
EXPECT_EQ("string", str);
194+
}

0 commit comments

Comments
 (0)