Skip to content

Commit 473ecd8

Browse files
authored
Merge pull request swiftlang#40645 from rintaro/sourcekit-compilerserver
[SourceKit] Add a request to generate object files in SourceKit
2 parents d8a3123 + 7c92a8e commit 473ecd8

36 files changed

+1000
-84
lines changed

include/swift/AST/ASTTypeIDZone.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
SWIFT_TYPEID(ActorIsolation)
1919
SWIFT_TYPEID(AncestryFlags)
20+
SWIFT_TYPEID(BodyAndFingerprint)
2021
SWIFT_TYPEID(BodyInitKind)
2122
SWIFT_TYPEID(BodyInitKindAndExpr)
2223
SWIFT_TYPEID(CtorInitializerKind)

include/swift/AST/ASTTypeIDs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ enum class AncestryFlags : uint8_t;
8181
enum class ImplicitMemberAction : uint8_t;
8282
struct FingerprintAndMembers;
8383
class Identifier;
84+
class BodyAndFingerprint;
8485

8586
// Define the AST type zone (zone 1)
8687
#define SWIFT_TYPEID_ZONE AST

include/swift/AST/Decl.h

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5904,6 +5904,38 @@ class ImportAsMemberStatus {
59045904
}
59055905
};
59065906

5907+
class BodyAndFingerprint {
5908+
llvm::PointerIntPair<BraceStmt *, 1, bool> BodyAndHasFp;
5909+
Fingerprint Fp;
5910+
5911+
public:
5912+
BodyAndFingerprint(BraceStmt *body, Optional<Fingerprint> fp)
5913+
: BodyAndHasFp(body, fp.hasValue()),
5914+
Fp(fp.hasValue() ? *fp : Fingerprint::ZERO()) {}
5915+
BodyAndFingerprint() : BodyAndFingerprint(nullptr, None) {}
5916+
5917+
BraceStmt *getBody() const { return BodyAndHasFp.getPointer(); }
5918+
5919+
Optional<Fingerprint> getFingerprint() const {
5920+
if (BodyAndHasFp.getInt())
5921+
return Fp;
5922+
else
5923+
return None;
5924+
}
5925+
5926+
void setFingerprint(Optional<Fingerprint> fp) {
5927+
if (fp.hasValue()) {
5928+
Fp = *fp;
5929+
BodyAndHasFp.setInt(true);
5930+
} else {
5931+
Fp = Fingerprint::ZERO();
5932+
BodyAndHasFp.setInt(false);
5933+
}
5934+
}
5935+
};
5936+
5937+
void simple_display(llvm::raw_ostream &out, BodyAndFingerprint value);
5938+
59075939
/// Base class for function-like declarations.
59085940
class AbstractFunctionDecl : public GenericContext, public ValueDecl {
59095941
friend class NeedsNewVTableEntryRequest;
@@ -5986,7 +6018,7 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
59866018
union {
59876019
/// This enum member is active if getBodyKind() is BodyKind::Parsed or
59886020
/// BodyKind::TypeChecked.
5989-
BraceStmt *Body;
6021+
BodyAndFingerprint BodyAndFP;
59906022

59916023
/// This enum member is active if getBodyKind() is BodyKind::Deserialized.
59926024
StringRef BodyStringRepresentation;
@@ -6022,9 +6054,10 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
60226054
bool Throws, SourceLoc ThrowsLoc,
60236055
bool HasImplicitSelfDecl,
60246056
GenericParamList *GenericParams)
6025-
: GenericContext(DeclContextKind::AbstractFunctionDecl, Parent, GenericParams),
6026-
ValueDecl(Kind, Parent, Name, NameLoc),
6027-
Body(nullptr), AsyncLoc(AsyncLoc), ThrowsLoc(ThrowsLoc) {
6057+
: GenericContext(DeclContextKind::AbstractFunctionDecl, Parent,
6058+
GenericParams),
6059+
ValueDecl(Kind, Parent, Name, NameLoc), BodyAndFP(), AsyncLoc(AsyncLoc),
6060+
ThrowsLoc(ThrowsLoc) {
60286061
setBodyKind(BodyKind::None);
60296062
Bits.AbstractFunctionDecl.HasImplicitSelfDecl = HasImplicitSelfDecl;
60306063
Bits.AbstractFunctionDecl.Overridden = false;
@@ -6195,8 +6228,9 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
61956228
void setBodyToBeReparsed(SourceRange bodyRange);
61966229

61976230
/// Provide the parsed body for the function.
6198-
void setBodyParsed(BraceStmt *S) {
6231+
void setBodyParsed(BraceStmt *S, Optional<Fingerprint> fp = None) {
61996232
setBody(S, BodyKind::Parsed);
6233+
BodyAndFP.setFingerprint(fp);
62006234
}
62016235

62026236
/// Was there a nested type declaration detected when parsing this
@@ -6286,6 +6320,15 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
62866320
/// itself.
62876321
void keepOriginalBodySourceRange();
62886322

6323+
/// Retrieve the fingerprint of the body. Note that this is not affected by
6324+
/// the body of the local functions or the members of the local types in this
6325+
/// function.
6326+
Optional<Fingerprint> getBodyFingerprint() const;
6327+
6328+
/// Retrieve the fingerprint of the body including the local type members and
6329+
/// the local funcition bodies.
6330+
Optional<Fingerprint> getBodyFingerprintIncludingLocalTypeMembers() const;
6331+
62896332
/// Retrieve the source range of the *original* function body.
62906333
///
62916334
/// This may be different from \c getBodySourceRange() that returns the source

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ ERROR(error_immediate_mode_primary_file,none,
102102
"immediate mode is incompatible with -primary-file", ())
103103
ERROR(error_missing_frontend_action,none,
104104
"no frontend action was selected", ())
105+
ERROR(error_unsupported_frontend_action, none,
106+
"unsupported action: %0", (StringRef))
105107
ERROR(error_invalid_source_location_str,none,
106108
"invalid source location string '%0'", (StringRef))
107109
ERROR(error_no_source_location_scope_map,none,

include/swift/AST/ParseRequests.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,25 +63,25 @@ class ParseMembersRequest
6363
};
6464

6565
/// Parse the body of a function, initializer, or deinitializer.
66-
class ParseAbstractFunctionBodyRequest :
67-
public SimpleRequest<ParseAbstractFunctionBodyRequest,
68-
BraceStmt *(AbstractFunctionDecl *),
69-
RequestFlags::SeparatelyCached>
70-
{
66+
class ParseAbstractFunctionBodyRequest
67+
: public SimpleRequest<ParseAbstractFunctionBodyRequest,
68+
BodyAndFingerprint(AbstractFunctionDecl *),
69+
RequestFlags::SeparatelyCached> {
7170
public:
7271
using SimpleRequest::SimpleRequest;
7372

7473
private:
7574
friend SimpleRequest;
7675

7776
// Evaluation.
78-
BraceStmt *evaluate(Evaluator &evaluator, AbstractFunctionDecl *afd) const;
77+
BodyAndFingerprint evaluate(Evaluator &evaluator,
78+
AbstractFunctionDecl *afd) const;
7979

8080
public:
8181
// Caching
8282
bool isCached() const { return true; }
83-
Optional<BraceStmt *> getCachedResult() const;
84-
void cacheResult(BraceStmt *value) const;
83+
Optional<BodyAndFingerprint> getCachedResult() const;
84+
void cacheResult(BodyAndFingerprint value) const;
8585
};
8686

8787
struct SourceFileParsingResult {

include/swift/AST/ParseTypeIDZone.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ SWIFT_REQUEST(Parse, CodeCompletionSecondPassRequest,
2020
SWIFT_REQUEST(Parse, ParseMembersRequest,
2121
FingerprintAndMembers(IterableDeclContext *), Cached, NoLocationInfo)
2222
SWIFT_REQUEST(Parse, ParseAbstractFunctionBodyRequest,
23-
BraceStmt *(AbstractFunctionDecl *), SeparatelyCached,
23+
BodyAndFingerprint(AbstractFunctionDecl *), SeparatelyCached,
2424
NoLocationInfo)
2525
SWIFT_REQUEST(Parse, ParseSourceFileRequest,
2626
SourceFileParsingResult(SourceFile *), SeparatelyCached,

include/swift/Basic/SourceManager.h

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,10 @@ class SourceManager {
5050
/// to speed up stats.
5151
mutable llvm::DenseMap<StringRef, llvm::vfs::Status> StatusCache;
5252

53-
struct ReplacedRangeType {
54-
SourceRange Original;
55-
SourceRange New;
56-
ReplacedRangeType() {}
57-
ReplacedRangeType(NoneType) {}
58-
ReplacedRangeType(SourceRange Original, SourceRange New)
59-
: Original(Original), New(New) {
60-
assert(Original.isValid() && New.isValid());
61-
}
62-
63-
explicit operator bool() const { return Original.isValid(); }
64-
};
65-
ReplacedRangeType ReplacedRange;
53+
/// Holds replaced ranges. Keys are orignal ranges, and values are new ranges
54+
/// in different buffers. This is used for code completion and ASTContext
55+
/// reusing compilation.
56+
llvm::DenseMap<SourceRange, SourceRange> ReplacedRanges;
6657

6758
std::map<const char *, VirtualFile> VirtualFiles;
6859
mutable std::pair<const char *, const VirtualFile*> CachedVFile = {nullptr, nullptr};
@@ -109,8 +100,12 @@ class SourceManager {
109100

110101
SourceLoc getCodeCompletionLoc() const;
111102

112-
const ReplacedRangeType &getReplacedRange() const { return ReplacedRange; }
113-
void setReplacedRange(const ReplacedRangeType &val) { ReplacedRange = val; }
103+
const llvm::DenseMap<SourceRange, SourceRange> &getReplacedRanges() const {
104+
return ReplacedRanges;
105+
}
106+
void setReplacedRange(SourceRange Orig, SourceRange New) {
107+
ReplacedRanges[Orig] = New;
108+
}
114109

115110
/// Returns true if \c LHS is before \c RHS in the source buffer.
116111
bool isBeforeInBuffer(SourceLoc LHS, SourceLoc RHS) const {

include/swift/Frontend/Frontend.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353

5454
namespace swift {
5555

56+
class FrontendObserver;
5657
class SerializedModuleLoaderBase;
5758
class MemoryBufferSerializedModuleLoader;
5859
class SILModule;
@@ -666,6 +667,9 @@ class CompilerInstance {
666667
/// library, returning \c false if we should continue, i.e. no error.
667668
bool loadStdlibIfNeeded();
668669

670+
/// If \p fn returns true, exits early and returns true.
671+
bool forEachFileToTypeCheck(llvm::function_ref<bool(SourceFile &)> fn);
672+
669673
private:
670674
/// Compute the parsing options for a source file in the main module.
671675
SourceFile::ParsingOptions getSourceFileParsingOptions(bool forPrimary) const;
@@ -679,8 +683,6 @@ class CompilerInstance {
679683
bool loadPartialModulesAndImplicitImports(
680684
ModuleDecl *mod, SmallVectorImpl<FileUnit *> &partialModules) const;
681685

682-
void forEachFileToTypeCheck(llvm::function_ref<void(SourceFile &)> fn);
683-
684686
void finishTypeChecking();
685687

686688
public:

include/swift/Frontend/FrontendOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,10 @@ class FrontendOptions {
438438
/// Whether to include symbols with SPI information in the symbol graph.
439439
bool IncludeSPISymbolsInSymbolGraph = false;
440440

441+
/// Whether to reuse a frontend (i.e. compiler instance) for multiple
442+
/// compiletions. This prevents ASTContext being freed.
443+
bool ReuseFrontendForMutipleCompilations = false;
444+
441445
/// This is used to obfuscate the serialized search paths so we don't have
442446
/// to encode the actual paths into the .swiftmodule file.
443447
PathObfuscator serializedPathObfuscator;

include/swift/FrontendTool/FrontendTool.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ int performFrontend(ArrayRef<const char *> args,
7878
void *mainAddr,
7979
FrontendObserver *observer = nullptr);
8080

81+
bool performCompileStepsPostSema(CompilerInstance &Instance, int &ReturnValue,
82+
FrontendObserver *observer);
8183

8284
} // namespace swift
8385

0 commit comments

Comments
 (0)