Merge pull request #5656 from Gankro/xfail
diff --git a/include/swift/Basic/Version.h b/include/swift/Basic/Version.h
index f577923..a8e0add 100644
--- a/include/swift/Basic/Version.h
+++ b/include/swift/Basic/Version.h
@@ -149,6 +149,10 @@
std::string getSwiftFullVersion(Version effectiveLanguageVersion =
Version::getCurrentLanguageVersion());
+/// Retrieves the repository revision number (or identifer) from which
+/// this Swift was built.
+std::string getSwiftRevision();
+
} // end namespace version
} // end namespace swift
diff --git a/include/swift/IDE/Utils.h b/include/swift/IDE/Utils.h
index 25d3139..5b318c9 100644
--- a/include/swift/IDE/Utils.h
+++ b/include/swift/IDE/Utils.h
@@ -198,8 +198,11 @@
enum class RangeKind : int8_t{
Invalid = -1,
- Expression,
+ SingleExpression,
SingleStatement,
+ SingleDecl,
+
+ MultiStatement,
};
struct ResolvedRangeInfo {
diff --git a/lib/Basic/Version.cpp b/lib/Basic/Version.cpp
index 87a99ca..379c571 100644
--- a/lib/Basic/Version.cpp
+++ b/lib/Basic/Version.cpp
@@ -406,6 +406,14 @@
return OS.str();
}
+std::string getSwiftRevision() {
+#ifdef SWIFT_REVISION
+ return SWIFT_REVISION;
+#else
+ return "";
+#endif
+}
+
} // end namespace version
} // end namespace swift
diff --git a/lib/ClangImporter/ImportName.cpp b/lib/ClangImporter/ImportName.cpp
index 8d17f21..b08eba8 100644
--- a/lib/ClangImporter/ImportName.cpp
+++ b/lib/ClangImporter/ImportName.cpp
@@ -793,9 +793,10 @@
return baseName;
}
-EffectiveClangContext NameImporter::determineEffectiveContext(
- const clang::NamedDecl *decl, const clang::DeclContext *dc,
- ImportNameOptions options, clang::Sema &clangSema) {
+EffectiveClangContext
+NameImporter::determineEffectiveContext(const clang::NamedDecl *decl,
+ const clang::DeclContext *dc,
+ ImportNameOptions options) {
EffectiveClangContext res;
// Enumerators can end up within their enclosing enum or in the global
@@ -841,8 +842,7 @@
bool NameImporter::hasNamingConflict(const clang::NamedDecl *decl,
const clang::IdentifierInfo *proposedName,
- const clang::TypedefNameDecl *cfTypedef,
- clang::Sema &clangSema) {
+ const clang::TypedefNameDecl *cfTypedef) {
// Test to see if there is a value with the same name as 'proposedName'
// in the same module as the decl
// FIXME: This will miss macros.
@@ -1101,7 +1101,7 @@
// Compute the effective context.
auto dc = const_cast<clang::DeclContext *>(D->getDeclContext());
- auto effectiveCtx = determineEffectiveContext(D, dc, options, clangSema);
+ auto effectiveCtx = determineEffectiveContext(D, dc, options);
if (!effectiveCtx)
return {};
result.EffectiveContext = effectiveCtx;
@@ -1455,8 +1455,7 @@
SmallString<16> baseNameWithProtocolSuffix;
if (auto objcProto = dyn_cast<clang::ObjCProtocolDecl>(D)) {
if (objcProto->hasDefinition()) {
- if (hasNamingConflict(D, objcProto->getIdentifier(), nullptr,
- clangSema)) {
+ if (hasNamingConflict(D, objcProto->getIdentifier(), nullptr)) {
baseNameWithProtocolSuffix = baseName;
baseNameWithProtocolSuffix += SWIFT_PROTOCOL_SUFFIX;
baseName = baseNameWithProtocolSuffix;
@@ -1472,7 +1471,7 @@
auto swiftName = getCFTypeName(typedefNameDecl);
if (!swiftName.empty() &&
!hasNamingConflict(D, &clangCtx.Idents.get(swiftName),
- typedefNameDecl, clangSema)) {
+ typedefNameDecl)) {
// Adopt the requested name.
baseName = swiftName;
}
diff --git a/lib/ClangImporter/ImportName.h b/lib/ClangImporter/ImportName.h
index 901771a..7a2e82c 100644
--- a/lib/ClangImporter/ImportName.h
+++ b/lib/ClangImporter/ImportName.h
@@ -226,8 +226,7 @@
/// the same module as the decl
bool hasNamingConflict(const clang::NamedDecl *decl,
const clang::IdentifierInfo *proposedName,
- const clang::TypedefNameDecl *cfTypedef,
- clang::Sema &clangSema);
+ const clang::TypedefNameDecl *cfTypedef);
Optional<ImportedErrorInfo>
considerErrorImport(const clang::ObjCMethodDecl *clangDecl,
@@ -241,8 +240,7 @@
EffectiveClangContext determineEffectiveContext(const clang::NamedDecl *,
const clang::DeclContext *,
- ImportNameOptions options,
- clang::Sema &clangSema);
+ ImportNameOptions options);
ImportedName importNameImpl(const clang::NamedDecl *,
ImportNameOptions options);
diff --git a/lib/IDE/SwiftSourceDocInfo.cpp b/lib/IDE/SwiftSourceDocInfo.cpp
index 29fc717..961a246 100644
--- a/lib/IDE/SwiftSourceDocInfo.cpp
+++ b/lib/IDE/SwiftSourceDocInfo.cpp
@@ -176,35 +176,102 @@
struct RangeResolver::Implementation {
SourceFile &File;
+private:
+ enum class RangeMatchKind : int8_t {
+ NoneMatch,
+ StartMatch,
+ EndMatch,
+ RangeMatch,
+ };
+
+ struct ContextInfo {
+ ASTNode Parent;
+ std::vector<ASTNode> StartMatches;
+ std::vector<ASTNode> EndMatches;
+ ContextInfo(ASTNode Parent) : Parent(Parent) {}
+ };
+
SourceLoc Start;
SourceLoc End;
+ StringRef Content;
Optional<ResolvedRangeInfo> Result;
- Implementation(SourceFile &File, SourceLoc Start, SourceLoc End) :
- File(File), Start(Start), End(End) {}
-
- bool isRangeMatch(SourceRange Input) {
- return Input.Start == Start && Input.End == End;
+ std::vector<ContextInfo> ContextStack;
+ ContextInfo &getCurrentDC() {
+ assert(!ContextStack.empty());
+ return ContextStack.back();
}
- bool shouldEnter(SourceRange Input) {
+ ResolvedRangeInfo getSingleNodeKind(ASTNode Node) {
+ assert(!Node.isNull());
+ if (Node.is<Expr*>())
+ return ResolvedRangeInfo(RangeKind::SingleExpression,
+ Node.get<Expr*>()->getType(), Content);
+ else if (Node.is<Stmt*>())
+ return ResolvedRangeInfo(RangeKind::SingleStatement, Type(), Content);
+ else {
+ assert(Node.is<Decl*>());
+ return ResolvedRangeInfo(RangeKind::SingleDecl, Type(), Content);
+ }
+ }
+
+public:
+ Implementation(SourceFile &File, SourceLoc Start, SourceLoc End) :
+ File(File), Start(Start), End(End), Content(getContent()) {}
+ ~Implementation() { assert(ContextStack.empty()); }
+ bool hasResult() { return Result.hasValue(); }
+ void enter(ASTNode Node) { ContextStack.emplace_back(Node); }
+ void leave() { ContextStack.pop_back(); }
+
+ void analyze(ASTNode Node) {
+ auto &DCInfo = getCurrentDC();
+ switch (getRangeMatchKind(Node.getSourceRange())) {
+ case RangeMatchKind::NoneMatch:
+ return;
+ case RangeMatchKind::RangeMatch:
+ Result = getSingleNodeKind(Node);
+ return;
+ case RangeMatchKind::StartMatch:
+ DCInfo.StartMatches.emplace_back(Node);
+ break;
+ case RangeMatchKind::EndMatch:
+ DCInfo.EndMatches.emplace_back(Node);
+ break;
+ }
+ if (!DCInfo.StartMatches.empty() && !DCInfo.EndMatches.empty()) {
+ Result = {RangeKind::MultiStatement, Type(), Content};
+ return;
+ }
+ }
+
+ bool shouldEnter(ASTNode Node) {
SourceManager &SM = File.getASTContext().SourceMgr;
- if (SM.isBeforeInBuffer(End, Input.Start))
+ if (SM.isBeforeInBuffer(End, Node.getSourceRange().Start))
return false;
- if (SM.isBeforeInBuffer(Input.End, Start))
+ if (SM.isBeforeInBuffer(Node.getSourceRange().End, Start))
return false;
return true;
}
- bool hasResult() {
- return Result.hasValue();
- }
-
ResolvedRangeInfo getResult() {
if (Result.hasValue())
return Result.getValue();
return ResolvedRangeInfo(RangeKind::Invalid, Type(), getContent());
}
+private:
+ RangeMatchKind getRangeMatchKind(SourceRange Input) {
+ bool StartMatch = Input.Start == Start;
+ bool EndMatch = Input.End == End;
+ if (StartMatch && EndMatch)
+ return RangeMatchKind::RangeMatch;
+ else if (StartMatch)
+ return RangeMatchKind::StartMatch;
+ else if (EndMatch)
+ return RangeMatchKind::EndMatch;
+ else
+ return RangeMatchKind::NoneMatch;
+ }
+
StringRef getContent() {
SourceManager &SM = File.getASTContext().SourceMgr;
return CharSourceRange(SM, Start, Lexer::getLocForEndOfToken(SM, End)).str();
@@ -217,45 +284,48 @@
RangeResolver::~RangeResolver() { delete &Impl; }
bool RangeResolver::walkToExprPre(Expr *E) {
- if (!Impl.shouldEnter(E->getSourceRange()))
+ if (!Impl.shouldEnter(E))
return false;
- if (Impl.isRangeMatch(E->getSourceRange())) {
- Impl.Result = ResolvedRangeInfo(RangeKind::Expression, E->getType(),
- Impl.getContent());
- }
+ Impl.analyze(E);
+ Impl.enter(E);
return !Impl.hasResult();
}
bool RangeResolver::walkToStmtPre(Stmt *S) {
- if (!Impl.shouldEnter(S->getSourceRange()))
+ if (!Impl.shouldEnter(S))
return false;
- if (Impl.isRangeMatch(S->getSourceRange())) {
- Impl.Result = ResolvedRangeInfo(RangeKind::SingleStatement, Type(),
- Impl.getContent());
- }
+ Impl.analyze(S);
+ Impl.enter(S);
return !Impl.hasResult();
};
-
bool RangeResolver::walkToDeclPre(Decl *D, CharSourceRange Range) {
- return Impl.shouldEnter(D->getSourceRange());
+ if (!Impl.shouldEnter(D))
+ return false;
+ Impl.analyze(D);
+ Impl.enter(D);
+ return !Impl.hasResult();
}
bool RangeResolver::walkToExprPost(Expr *E) {
+ Impl.leave();
return !Impl.hasResult();
}
bool RangeResolver::walkToStmtPost(Stmt *S) {
+ Impl.leave();
return !Impl.hasResult();
};
bool RangeResolver::walkToDeclPost(Decl *D) {
+ Impl.leave();
return !Impl.hasResult();
}
-ResolvedRangeInfo
-RangeResolver::resolve() {
+ResolvedRangeInfo RangeResolver::resolve() {
+ Impl.enter(ASTNode());
walk(Impl.File);
+ Impl.leave();
return Impl.getResult();
}
diff --git a/test/SourceKit/RangeInfo/basic.swift b/test/SourceKit/RangeInfo/basic.swift
index 95f3cac..425eb4a 100644
--- a/test/SourceKit/RangeInfo/basic.swift
+++ b/test/SourceKit/RangeInfo/basic.swift
@@ -1,37 +1,83 @@
func foo() -> Int{
var aaa = 1 + 2
aaa = aaa + 3
- if aaa = 3 { aaa = 4 }
+ if aaa == 3 { aaa = 4 }
return aaa
}
+func foo1() -> Int { return 0 }
+class C { func foo() {} }
+struct S { func foo() {} }
+
// RUN: %sourcekitd-test -req=range -pos=2:13 -length 5 %s -- %s | %FileCheck %s -check-prefix=CHECK1
// RUN: %sourcekitd-test -req=range -pos=3:3 -length 13 %s -- %s | %FileCheck %s -check-prefix=CHECK2
// RUN: %sourcekitd-test -req=range -pos=3:1 -length 15 %s -- %s | %FileCheck %s -check-prefix=CHECK2
-// RUN: %sourcekitd-test -req=range -pos=4:1 -length 24 %s -- %s | %FileCheck %s -check-prefix=CHECK3
// RUN: %sourcekitd-test -req=range -pos=4:1 -length 25 %s -- %s | %FileCheck %s -check-prefix=CHECK3
// RUN: %sourcekitd-test -req=range -pos=4:1 -length 26 %s -- %s | %FileCheck %s -check-prefix=CHECK3
-// RUN: %sourcekitd-test -req=range -pos=4:4 -length 21 %s -- %s | %FileCheck %s -check-prefix=CHECK3
+// RUN: %sourcekitd-test -req=range -pos=4:1 -length 27 %s -- %s | %FileCheck %s -check-prefix=CHECK3
+// RUN: %sourcekitd-test -req=range -pos=4:4 -length 22 %s -- %s | %FileCheck %s -check-prefix=CHECK3
// RUN: %sourcekitd-test -req=range -pos=5:1 -length 12 %s -- %s | %FileCheck %s -check-prefix=CHECK4
// RUN: %sourcekitd-test -req=range -pos=5:2 -length 11 %s -- %s | %FileCheck %s -check-prefix=CHECK4
// RUN: %sourcekitd-test -req=range -pos=5:5 -length 8 %s -- %s | %FileCheck %s -check-prefix=CHECK4
// RUN: %sourcekitd-test -req=range -pos=5:5 -length 9 %s -- %s | %FileCheck %s -check-prefix=CHECK4
-// CHECK1-DAG: <kind>source.lang.swift.range.expression</kind>
+// RUN: %sourcekitd-test -req=range -pos=8:1 -length 31 %s -- %s | %FileCheck %s -check-prefix=CHECK5
+// RUN: %sourcekitd-test -req=range -pos=9:1 -length 25 %s -- %s | %FileCheck %s -check-prefix=CHECK6
+// RUN: %sourcekitd-test -req=range -pos=10:1 -length 26 %s -- %s | %FileCheck %s -check-prefix=CHECK7
+// RUN: %sourcekitd-test -req=range -pos=3:1 -length 42 %s -- %s | %FileCheck %s -check-prefix=CHECK8
+// RUN: %sourcekitd-test -req=range -pos=3:1 -length 55 %s -- %s | %FileCheck %s -check-prefix=CHECK9
+// RUN: %sourcekitd-test -req=range -pos=4:1 -length 36 %s -- %s | %FileCheck %s -check-prefix=CHECK10
+
+// RUN: %sourcekitd-test -req=range -pos=8:1 -end-pos 8:32 %s -- %s | %FileCheck %s -check-prefix=CHECK5
+// RUN: %sourcekitd-test -req=range -pos=9:1 -end-pos 9:26 %s -- %s | %FileCheck %s -check-prefix=CHECK6
+// RUN: %sourcekitd-test -req=range -pos=10:1 -end-pos 10:27 %s -- %s | %FileCheck %s -check-prefix=CHECK7
+// RUN: %sourcekitd-test -req=range -pos=3:1 -end-pos=4:26 %s -- %s | %FileCheck %s -check-prefix=CHECK8
+// RUN: %sourcekitd-test -req=range -pos=3:1 -end-pos=5:13 %s -- %s | %FileCheck %s -check-prefix=CHECK9
+// RUN: %sourcekitd-test -req=range -pos=4:1 -end-pos=5:13 %s -- %s | %FileCheck %s -check-prefix=CHECK10
+
+// CHECK1-DAG: <kind>source.lang.swift.range.singleexpression</kind>
// CHECK1-DAG: <content>1 + 2</content>
// CHECK1-DAG: <type>Int</type>
-// CHECK2-DAG: <kind>source.lang.swift.range.expression</kind>
+// CHECK2-DAG: <kind>source.lang.swift.range.singleexpression</kind>
// CHECK2-DAG: <content>aaa = aaa + 3</content>
// CHECK2-DAG: <type>()</type>
// CHECK3-DAG: <kind>source.lang.swift.range.singlestatement</kind>
-// CHECK3-DAG: <content>if aaa = 3 { aaa = 4 }</content>
+// CHECK3-DAG: <content>if aaa == 3 { aaa = 4 }</content>
// CHECK3-DAG: <type></type>
// CHECK4-DAG: <kind>source.lang.swift.range.singlestatement</kind>
// CHECK4-DAG: <content>return aaa</content>
// CHECK4-DAG: <type></type>
+
+// CHECK5-DAG: <kind>source.lang.swift.range.singledeclaration</kind>
+// CHECK5-DAG: <content>func foo1() -> Int { return 0 }</content>
+// CHECK5-DAG: <type></type>
+
+// CHECK6-DAG: <kind>source.lang.swift.range.singledeclaration</kind>
+// CHECK6-DAG: <content>class C { func foo() {} }</content>
+// CHECK6-DAG: <type></type>
+
+// CHECK7-DAG: <kind>source.lang.swift.range.singledeclaration</kind>
+// CHECK7-DAG: <content>struct S { func foo() {} }</content>
+// CHECK7-DAG: <type></type>
+
+// CHECK8-DAG: <kind>source.lang.swift.range.multistatement</kind>
+// CHECK8-DAG: <content>aaa = aaa + 3
+// CHECK8-DAG: if aaa == 3 { aaa = 4 }</content>
+// CHECK8-DAG: <type></type>
+
+// CHECK9-DAG: <kind>source.lang.swift.range.multistatement</kind>
+// CHECK9-DAG: <content>aaa = aaa + 3
+// CHECK9-DAG: if aaa == 3 { aaa = 4 }
+// CHECK9-DAG: return aaa</content>
+// CHECK9-DAG: <type></type>
+
+// CHECK10-DAG: <kind>source.lang.swift.range.multistatement</kind>
+// CHECK10-DAG: <content>if aaa == 3 { aaa = 4 }
+// CHECK10-DAG: return aaa</content>
+// CHECK10-DAG: <type></type>
diff --git a/test/lit.cfg b/test/lit.cfg
index 70ab538..0459030 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -976,8 +976,9 @@
config.substitutions.append(('%line-directive', config.line_directive))
config.substitutions.append(('%gyb', config.gyb))
config.substitutions.append(('%rth', config.rth))
-config.substitutions.append(('%scale-test', config.scale_test))
-
+config.substitutions.append(('%scale-test',
+ '{} --swiftc-binary={} --tmpdir=%t'.format(
+ config.scale_test, config.swiftc)))
config.substitutions.append(('%target-sil-opt', config.target_sil_opt))
config.substitutions.append(('%target-sil-extract', config.target_sil_extract))
config.substitutions.append(
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
index f7983a8..9f3a45e 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
@@ -154,7 +154,11 @@
static UIdent KindStructureElemTypeRef("source.lang.swift.structure.elem.typeref");
static UIdent KindRangeSingleStatement("source.lang.swift.range.singlestatement");
-static UIdent KindRangeExpression("source.lang.swift.range.expression");
+static UIdent KindRangeSingleExpression("source.lang.swift.range.singleexpression");
+static UIdent KindRangeSingleDeclaration("source.lang.swift.range.singledeclaration");
+
+static UIdent KindRangeMultiStatement("source.lang.swift.range.multistatement");
+
static UIdent KindRangeInvalid("source.lang.swift.range.invalid");
std::unique_ptr<LangSupport>
@@ -536,8 +540,10 @@
SourceKit::UIdent SwiftLangSupport::
getUIDForRangeKind(swift::ide::RangeKind Kind) {
switch (Kind) {
- case swift::ide::RangeKind::Expression: return KindRangeExpression;
+ case swift::ide::RangeKind::SingleExpression: return KindRangeSingleExpression;
case swift::ide::RangeKind::SingleStatement: return KindRangeSingleStatement;
+ case swift::ide::RangeKind::SingleDecl: return KindRangeSingleDeclaration;
+ case swift::ide::RangeKind::MultiStatement: return KindRangeMultiStatement;
case swift::ide::RangeKind::Invalid: return KindRangeInvalid;
}
}
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp
index 1e05e0f..ac30634 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp
@@ -1097,7 +1097,7 @@
Result.RangeKind = Lang.getUIDForRangeKind(Info.Kind);
Result.RangeContent = Info.Content;
switch (Info.Kind) {
- case RangeKind::Expression: {
+ case RangeKind::SingleExpression: {
SmallString<64> SS;
llvm::raw_svector_ostream OS(SS);
Info.Ty.print(OS);
@@ -1105,6 +1105,8 @@
Receiver(Result);
return;
}
+ case RangeKind::SingleDecl:
+ case RangeKind::MultiStatement:
case RangeKind::SingleStatement: {
Receiver(Result);
return;
diff --git a/tools/SourceKit/tools/sourcekitd-test/Options.td b/tools/SourceKit/tools/sourcekitd-test/Options.td
index 2d17e78..3c08285 100644
--- a/tools/SourceKit/tools/sourcekitd-test/Options.td
+++ b/tools/SourceKit/tools/sourcekitd-test/Options.td
@@ -87,3 +87,6 @@
def async : Flag<["-"], "async">,
HelpText<"Perform request asynchronously">;
+
+def end_pos : Separate<["-"], "end-pos">, HelpText<"line:col">;
+def end_pos_EQ : Joined<["-"], "end-pos=">, Alias<end_pos>;
\ No newline at end of file
diff --git a/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp b/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp
index 17741fe..d26fa4d 100644
--- a/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp
+++ b/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp
@@ -164,6 +164,13 @@
break;
}
+ case OPT_end_pos: {
+ auto linecol = parseLineCol(InputArg->getValue());
+ EndLine = linecol.first;
+ EndCol = linecol.second;
+ break;
+ }
+
case OPT_line:
if (StringRef(InputArg->getValue()).getAsInteger(10, Line)) {
llvm::errs() << "error: expected integer for 'line'\n";
diff --git a/tools/SourceKit/tools/sourcekitd-test/TestOptions.h b/tools/SourceKit/tools/sourcekitd-test/TestOptions.h
index fed522a..5dc3739 100644
--- a/tools/SourceKit/tools/sourcekitd-test/TestOptions.h
+++ b/tools/SourceKit/tools/sourcekitd-test/TestOptions.h
@@ -63,6 +63,8 @@
std::string InterestedUSR;
unsigned Line = 0;
unsigned Col = 0;
+ unsigned EndLine = 0;
+ unsigned EndCol = 0;
unsigned Offset = 0;
unsigned Length = 0;
llvm::Optional<std::string> ReplaceText;
diff --git a/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp b/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
index cf8fcde..d98e69c 100644
--- a/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
+++ b/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
@@ -543,12 +543,17 @@
sourcekitd_request_dictionary_set_int64(Req, KeyOffset, ByteOffset);
}
break;
- case SourceKitRequest::RangeInfo:
+ case SourceKitRequest::RangeInfo: {
sourcekitd_request_dictionary_set_uid(Req, KeyRequest, RequestRangeInfo);
sourcekitd_request_dictionary_set_int64(Req, KeyOffset, ByteOffset);
- sourcekitd_request_dictionary_set_int64(Req, KeyLength, Opts.Length);
+ auto Length = Opts.Length;
+ if (Opts.Length == 0 && Opts.EndLine > 0) {
+ auto EndOff = resolveFromLineCol(Opts.EndLine, Opts.EndCol, SourceFile);
+ Length = EndOff - ByteOffset;
+ }
+ sourcekitd_request_dictionary_set_int64(Req, KeyLength, Length);
break;
-
+ }
case SourceKitRequest::RelatedIdents:
sourcekitd_request_dictionary_set_uid(Req, KeyRequest, RequestRelatedIdents);
sourcekitd_request_dictionary_set_int64(Req, KeyOffset, ByteOffset);
diff --git a/tools/swift-api-digester/swift-api-digester.cpp b/tools/swift-api-digester/swift-api-digester.cpp
index 5c1b265..ebaf953 100644
--- a/tools/swift-api-digester/swift-api-digester.cpp
+++ b/tools/swift-api-digester/swift-api-digester.cpp
@@ -314,6 +314,8 @@
bool operator==(const SDKNode &Other) const;
bool operator!=(const SDKNode &Other) const { return !((*this) == Other); }
+ ArrayRef<NodeAnnotation>
+ getAnnotations(std::vector<NodeAnnotation> &Scrach) const;
bool isLeaf() const { return Children.empty(); }
SDKNodeKind getKind() const { return SDKNodeKind(TheKind); }
StringRef getName() const { return Name; }
@@ -364,10 +366,10 @@
bool isObjc() const { return Usr.startswith("c:"); }
static bool classof(const SDKNode *N);
DeclKind getDeclKind() const { return DKind; }
- void printFullyQualifiedName(llvm::raw_ostream &OS);
- StringRef getFullyQualifiedName();
- bool isSDKPrivate();
- bool isDeprecated();
+ void printFullyQualifiedName(llvm::raw_ostream &OS) const;
+ StringRef getFullyQualifiedName() const;
+ bool isSDKPrivate() const;
+ bool isDeprecated() const;
bool isStatic() const { return IsStatic; };
};
@@ -431,9 +433,9 @@
}
NodePtr SDKNode::getOnlyChild() const {
- assert(Children.size() == 1 && "more that one child.");
- return (*Children.begin()).get();
- }
+ assert(Children.size() == 1 && "more that one child.");
+ return (*Children.begin()).get();
+}
void SDKNode::addChild(NodeUniquePtr Child) {
Child->Parent = this;
@@ -468,6 +470,13 @@
return AnnotateComments.find(Anno)->second;
}
+ArrayRef<NodeAnnotation> SDKNode::
+getAnnotations(std::vector<NodeAnnotation> &Scratch) const {
+ for(auto Ann : Annotations)
+ Scratch.push_back(Ann);
+ return llvm::makeArrayRef(Scratch);
+}
+
bool SDKNode::isAnnotatedAs(NodeAnnotation Anno) const {
return Annotations.find(Anno) != Annotations.end();;
}
@@ -588,11 +597,11 @@
return Instance.get();
}
-bool SDKNodeDecl::isDeprecated() {
+bool SDKNodeDecl::isDeprecated() const {
return hasDeclAttribute(SDKDeclAttrKind::DAK_deprecated);
}
-bool SDKNodeDecl::isSDKPrivate() {
+bool SDKNodeDecl::isSDKPrivate() const {
if (getName().startswith("__"))
return true;
if (auto *PD = dyn_cast<SDKNodeDecl>(getParent()))
@@ -600,7 +609,7 @@
return false;
}
-void SDKNodeDecl::printFullyQualifiedName(llvm::raw_ostream &OS) {
+void SDKNodeDecl::printFullyQualifiedName(llvm::raw_ostream &OS) const {
std::vector<NodePtr> Parent;
for (auto *P = getParent(); isa<SDKNodeDecl>(P); P = P->getParent())
Parent.push_back(P);
@@ -609,7 +618,7 @@
OS << getPrintedName();
}
-StringRef SDKNodeDecl::getFullyQualifiedName() {
+StringRef SDKNodeDecl::getFullyQualifiedName() const {
llvm::SmallString<32> Buffer;
llvm::raw_svector_ostream OS(Buffer);
printFullyQualifiedName(OS);
@@ -1936,7 +1945,7 @@
MapImpl.push_back(std::make_pair(Left, Right));
}
- NodePtr findUpdateCounterpart(NodePtr Node) const {
+ NodePtr findUpdateCounterpart(const SDKNode *Node) const {
assert(Node->isAnnotatedAs(NodeAnnotation::Updated) && "Not update operation.");
auto FoundPair = std::find_if(MapImpl.begin(), MapImpl.end(),
[&](std::pair<NodePtr, NodePtr> Pair) {
@@ -2688,10 +2697,11 @@
};
class DiagnosisEmitter : public SDKNodeVisitor {
+ void handle(const SDKNodeDecl *D, NodeAnnotation Anno);
void visitType(SDKNodeType *T);
void visitDecl(SDKNodeDecl *D);
void visit(NodePtr Node) override;
- SDKNodeDecl *findAddedDecl(SDKNodeDecl *Node);
+ SDKNodeDecl *findAddedDecl(const SDKNodeDecl *Node);
static StringRef printName(StringRef Name);
static StringRef printDiagKeyword(StringRef Name);
static void collectAddedDecls(NodePtr Root, std::set<SDKNodeDecl*> &Results);
@@ -2805,7 +2815,7 @@
collectAddedDecls(C.get(), Results);
}
-SDKNodeDecl *DiagnosisEmitter::findAddedDecl(SDKNodeDecl *Root) {
+SDKNodeDecl *DiagnosisEmitter::findAddedDecl(const SDKNodeDecl *Root) {
for (auto *Added : AddedDecls) {
if (Root->getKind() == Added->getKind() &&
Root->getPrintedName() == Added->getPrintedName())
@@ -2904,11 +2914,10 @@
SDKNode::postorderVisit(LeftRoot, Emitter);
}
-void DiagnosisEmitter::visitDecl(SDKNodeDecl *Node) {
- if (Node->isSDKPrivate())
- return;
- if (Node->isAnnotatedAs(NodeAnnotation::Removed) &&
- !Node->isAnnotatedAs(NodeAnnotation::Rename)) {
+void DiagnosisEmitter::handle(const SDKNodeDecl *Node, NodeAnnotation Anno) {
+ assert(Node->isAnnotatedAs(Anno));
+ switch(Anno) {
+ case NodeAnnotation::Removed: {
if (auto *Added = findAddedDecl(Node)) {
MovedDecls.Diags.emplace_back(Node->getDeclKind(),
Added->getDeclKind(),
@@ -2919,29 +2928,34 @@
Node->getFullyQualifiedName(),
Node->isDeprecated());
}
+ return;
}
- if (Node->isAnnotatedAs(NodeAnnotation::Rename)) {
+ case NodeAnnotation::Rename: {
auto *Count = UpdateMap.findUpdateCounterpart(Node)->getAs<SDKNodeDecl>();
RenamedDecls.Diags.emplace_back(Node->getDeclKind(), Count->getDeclKind(),
Node->getFullyQualifiedName(),
Count->getFullyQualifiedName());
+ return;
}
- if (Node->isAnnotatedAs(NodeAnnotation::NowMutating)) {
+ case NodeAnnotation::NowMutating: {
AttrChangedDecls.Diags.emplace_back(Node->getDeclKind(),
Node->getFullyQualifiedName(),
InsertToBuffer("mutating"));
+ return;
}
- if (Node->isAnnotatedAs(NodeAnnotation::NowThrowing)) {
+ case NodeAnnotation::NowThrowing: {
AttrChangedDecls.Diags.emplace_back(Node->getDeclKind(),
Node->getFullyQualifiedName(),
InsertToBuffer("throwing"));
+ return;
}
- if (Node->isAnnotatedAs(NodeAnnotation::StaticChange)) {
+ case NodeAnnotation::StaticChange: {
AttrChangedDecls.Diags.emplace_back(Node->getDeclKind(),
Node->getFullyQualifiedName(),
InsertToBuffer(Node->isStatic() ? "not static" : "static"));
+ return;
}
- if (Node->isAnnotatedAs(NodeAnnotation::OwnershipChange)) {
+ case NodeAnnotation::OwnershipChange: {
auto getOwnershipDescription = [](swift::Ownership O) {
switch (O) {
case Ownership::Strong: return InsertToBuffer("strong");
@@ -2955,8 +2969,21 @@
Node->getFullyQualifiedName(),
getOwnershipDescription(Node->getOwnership()),
getOwnershipDescription(Count->getOwnership()));
+ return;
+ }
+ default:
+ return;
}
}
+
+void DiagnosisEmitter::visitDecl(SDKNodeDecl *Node) {
+ if (Node->isSDKPrivate())
+ return;
+ std::vector<NodeAnnotation> Scratch;
+ for (auto Anno : Node->getAnnotations(Scratch))
+ handle(Node, Anno);
+}
+
void DiagnosisEmitter::visitType(SDKNodeType *Node) {
auto *Parent = Node->getParent()->getAs<SDKNodeDecl>();
if (!Parent || Parent->isSDKPrivate())
diff --git a/utils/scale-test b/utils/scale-test
index 6986ec7..fcba9a5 100755
--- a/utils/scale-test
+++ b/utils/scale-test
@@ -12,15 +12,25 @@
# values.
#
-import gyb, os, os.path, subprocess
+import argparse
+import json
+import os
+import os.path
+import shutil
+import subprocess
+import sys
+import tempfile
+import gyb
+
def find_which(p):
for d in os.environ["PATH"].split(os.pathsep):
- full = os.path.join(d,p)
+ full = os.path.join(d, p)
if os.path.isfile(full) and os.access(full, os.X_OK):
return full
return p
+
# Evidently the debug-symbol reader in dtrace is sufficiently slow and/or buggy
# that attempting to inject probes into a binary w/ debuginfo is asking for a
# failed run (possibly racing with probe insertion, or probing the stabs
@@ -28,7 +38,8 @@
# so we sniff the presence of debug symbols here.
def has_debuginfo(swiftc):
swiftc = find_which(swiftc)
- for line in subprocess.check_output(["dwarfdump", "--file-stats", swiftc]).splitlines():
+ for line in subprocess.check_output(
+ ["dwarfdump", "--file-stats", swiftc]).splitlines():
if '%' not in line:
continue
fields = line.split()
@@ -38,20 +49,22 @@
def write_input_file(args, ast, d, n):
- ifile = os.path.join(d, "in%d.swift" % n)
- with open(ifile,'w+') as f:
+ fname = "in%d.swift" % n
+ pathname = os.path.join(d, fname)
+ with open(pathname, 'w+') as f:
f.write(gyb.execute_template(ast, '', N=n))
- return ifile
+ return fname
def run_once_with_primary(args, ast, rng, primary_idx):
- import sys, shutil, tempfile, json
r = {}
try:
- d = tempfile.mkdtemp()
+ if args.tmpdir is not None and not os.path.exists(args.tmpdir):
+ os.makedirs(args.tmpdir, 0700)
+ d = tempfile.mkdtemp(dir=args.tmpdir)
inputs = [write_input_file(args, ast, d, i) for i in rng]
primary = inputs[primary_idx]
- ofile = os.path.join(d, "out.o")
+ ofile = "out.o"
mode = "-c"
if args.parse:
@@ -81,31 +94,32 @@
print "running: " + " ".join(command)
if args.dtrace:
- trace = os.path.join(d, "trace.txt")
- script = "pid$target:swiftc:*%s*:entry { @[probefunc] = count() }" % args.select
+ trace = "trace.txt"
+ script = ("pid$target:swiftc:*%s*:entry { @[probefunc] = count() }"
+ % args.select)
subprocess.check_call(
["sudo", "dtrace", "-q",
"-o", trace,
"-b", "256",
"-n", script,
- "-c", " ".join(command)])
+ "-c", " ".join(command)], cwd=d)
r = {fields[0]: int(fields[1]) for fields in
- [line.split() for line in open(trace)]
+ [line.split() for line in open(os.path.join(d, trace))]
if len(fields) == 2}
else:
if args.debug:
command = ["lldb", "--"] + command
- stats = os.path.join(d, "stats.json")
+ stats = "stats.json"
argv = command + ["-Xllvm", "-stats",
"-Xllvm", "-stats-json",
"-Xllvm", "-info-output-file=" + stats]
- subprocess.check_call(argv)
- with open(stats) as f:
+ subprocess.check_call(argv, cwd=d)
+ with open(os.path.join(d, stats)) as f:
r = json.load(f)
finally:
shutil.rmtree(d)
- return {k:v for (k,v) in r.items() if args.select in k}
+ return {k: v for (k, v) in r.items() if args.select in k}
def run_once(args, ast, rng):
@@ -122,6 +136,7 @@
else:
return run_once_with_primary(args, ast, rng, -1)
+
def run_many(args):
if args.dtrace and has_debuginfo(args.swiftc_binary):
@@ -145,25 +160,24 @@
def linear_regression(x, y):
- # By the book: https://en.wikipedia.org/wiki/Simple_linear_regression
- n = len(x)
- assert n == len(y)
- if n == 0:
- return 0, 0
- prod_sum = 0
- sum_x = sum(x)
- sum_y = sum(y)
- sum_prod = sum(a * b for a, b in zip(x, y))
- sum_x_sq = sum(a ** 2 for a in x)
- mean_x = sum_x/n
- mean_y = sum_y/n
- mean_prod = sum_prod/n
- mean_x_sq = sum_x_sq/n
- covar_xy = mean_prod - mean_x * mean_y
- var_x = mean_x_sq - mean_x**2
- slope = covar_xy / var_x
- inter = mean_y - slope * mean_x
- return slope, inter
+ # By the book: https://en.wikipedia.org/wiki/Simple_linear_regression
+ n = len(x)
+ assert n == len(y)
+ if n == 0:
+ return 0, 0
+ sum_x = sum(x)
+ sum_y = sum(y)
+ sum_prod = sum(a * b for a, b in zip(x, y))
+ sum_x_sq = sum(a ** 2 for a in x)
+ mean_x = sum_x/n
+ mean_y = sum_y/n
+ mean_prod = sum_prod/n
+ mean_x_sq = sum_x_sq/n
+ covar_xy = mean_prod - mean_x * mean_y
+ var_x = mean_x_sq - mean_x**2
+ slope = covar_xy / var_x
+ inter = mean_y - slope * mean_x
+ return slope, inter
def report(args, rng, runs):
@@ -196,7 +210,6 @@
def main():
- import argparse, sys
parser = argparse.ArgumentParser()
parser.add_argument(
'file', type=argparse.FileType(),
@@ -242,8 +255,11 @@
'--swiftc-binary',
default="swiftc", help='swift binary to execute')
parser.add_argument(
+ '--tmpdir', type=str,
+ default=None, help='directory to create tempfiles in')
+ parser.add_argument(
'--select',
- default="", help='substring of counters/symbols to restrict attention to')
+ default="", help='substring of counters/symbols to limit attention to')
parser.add_argument(
'--debug', action='store_true',
default=False, help='invoke lldb on each scale test')
@@ -273,5 +289,6 @@
exit(1)
exit(0)
+
if __name__ == '__main__':
main()
diff --git a/validation-test/compiler_scale/scale_neighbouring_getset.gyb b/validation-test/compiler_scale/scale_neighbouring_getset.gyb
index 51edbf3..c4317b7 100644
--- a/validation-test/compiler_scale/scale_neighbouring_getset.gyb
+++ b/validation-test/compiler_scale/scale_neighbouring_getset.gyb
@@ -1,9 +1,6 @@
// RUN: %scale-test --sum-multi --parse --begin 5 --end 16 --step 5 --select typeCheckAbstractFunctionBody %s
// REQUIRES: OS=macosx, tools-release
-// FIXME: this test has been failing in CI
-// REQUIRES: rdar29090287
-
struct Struct${N} {
% if int(N) > 1:
var Field : Struct${int(N)-1}?