Skip to content

Commit 3442fba

Browse files
authored
Merge pull request #76794 from xymus/move-avail-macro-cache
Sema: Move the availability macros cache to the ASTContext
2 parents 4b68c3f + edb0b92 commit 3442fba

File tree

6 files changed

+76
-38
lines changed

6 files changed

+76
-38
lines changed

include/swift/AST/ASTContext.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ namespace swift {
6969
class AbstractFunctionDecl;
7070
class ASTContext;
7171
enum class Associativity : unsigned char;
72+
class AvailabilityMacroMap;
7273
class AvailabilityRange;
7374
class BoundGenericType;
7475
class BuiltinTupleDecl;
@@ -987,6 +988,12 @@ class ASTContext final {
987988
return getMultiPayloadEnumTagSinglePayloadAvailability();
988989
}
989990

991+
/// Cache of the availability macros parsed from the command line arguments.
992+
///
993+
/// This is an implementation detail, access via
994+
/// \c Parser::parseAllAvailabilityMacroArguments.
995+
AvailabilityMacroMap &getAvailabilityMacroCache() const;
996+
990997
/// Test support utility for loading a platform remap file
991998
/// in case an SDK is not specified to the compilation.
992999
const clang::DarwinSDKInfo::RelatedTargetVersionMapping *

include/swift/AST/AvailabilitySpec.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,19 @@ class OtherPlatformAvailabilitySpec : public AvailabilitySpec {
215215
}
216216
};
217217

218+
/// Maps of macro name and version to availability specifications.
219+
/// Organized as two nested \c DenseMap keyed first on the macro name then
220+
/// the macro version. This structure allows to peek at macro names before
221+
/// parsing a version tuple.
222+
class AvailabilityMacroMap {
223+
public:
224+
typedef llvm::DenseMap<llvm::VersionTuple,
225+
SmallVector<AvailabilitySpec *, 4>> VersionEntry;
226+
227+
bool WasParsed = false;
228+
llvm::DenseMap<StringRef, VersionEntry> Impl;
229+
};
230+
218231
} // end namespace swift
219232

220233
#endif

include/swift/Parse/Parser.h

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -346,22 +346,6 @@ class Parser {
346346
/// This vector is managed by \c StructureMarkerRAII objects.
347347
llvm::SmallVector<StructureMarker, 16> StructureMarkers;
348348

349-
/// Maps of macro name and version to availability specifications.
350-
typedef llvm::DenseMap<llvm::VersionTuple,
351-
SmallVector<AvailabilitySpec *, 4>>
352-
AvailabilityMacroVersionMap;
353-
typedef llvm::DenseMap<StringRef, AvailabilityMacroVersionMap>
354-
AvailabilityMacroMap;
355-
356-
/// Cache of the availability macros parsed from the command line arguments.
357-
/// Organized as two nested \c DenseMap keyed first on the macro name then
358-
/// the macro version. This structure allows to peek at macro names before
359-
/// parsing a version tuple.
360-
AvailabilityMacroMap AvailabilityMacros;
361-
362-
/// Has \c AvailabilityMacros been computed?
363-
bool AvailabilityMacrosComputed = false;
364-
365349
public:
366350
Parser(unsigned BufferID, SourceFile &SF, DiagnosticEngine* LexerDiags,
367351
SILParserStateBase *SIL, PersistentParserState *PersistentState);
@@ -2080,7 +2064,7 @@ class Parser {
20802064
parseAvailabilityMacro(SmallVectorImpl<AvailabilitySpec *> &Specs);
20812065

20822066
/// Parse the availability macros definitions passed as arguments.
2083-
void parseAllAvailabilityMacroArguments();
2067+
AvailabilityMacroMap &parseAllAvailabilityMacroArguments();
20842068

20852069
/// Result of parsing an availability macro definition.
20862070
struct AvailabilityMacroDefinition {

lib/AST/ASTContext.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,9 @@ struct ASTContext::Implementation {
426426
/// Singleton used to cache the import graph.
427427
swift::namelookup::ImportCache TheImportCache;
428428

429+
/// Cache of availability macros parsed from the command line.
430+
AvailabilityMacroMap TheAvailabilityMacroCache;
431+
429432
/// The module loader used to load Clang modules.
430433
ClangModuleLoader *TheClangModuleLoader = nullptr;
431434

@@ -2281,6 +2284,10 @@ swift::namelookup::ImportCache &ASTContext::getImportCache() const {
22812284
return getImpl().TheImportCache;
22822285
}
22832286

2287+
AvailabilityMacroMap &ASTContext::getAvailabilityMacroCache() const {
2288+
return getImpl().TheAvailabilityMacroCache;
2289+
}
2290+
22842291
ClangModuleLoader *ASTContext::getClangModuleLoader() const {
22852292
return getImpl().TheClangModuleLoader;
22862293
}

lib/Parse/ParseDecl.cpp

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2063,22 +2063,20 @@ void Parser::parseObjCSelector(SmallVector<Identifier, 4> &Names,
20632063
}
20642064

20652065
bool Parser::peekAvailabilityMacroName() {
2066-
parseAllAvailabilityMacroArguments();
2067-
AvailabilityMacroMap Map = AvailabilityMacros;
2066+
AvailabilityMacroMap &Map = parseAllAvailabilityMacroArguments();
20682067

20692068
StringRef MacroName = Tok.getText();
2070-
return Map.find(MacroName) != Map.end();
2069+
return Map.Impl.find(MacroName) != Map.Impl.end();
20712070
}
20722071

20732072
ParserStatus
20742073
Parser::parseAvailabilityMacro(SmallVectorImpl<AvailabilitySpec *> &Specs) {
20752074
// Get the macros from the compiler arguments.
2076-
parseAllAvailabilityMacroArguments();
2077-
AvailabilityMacroMap Map = AvailabilityMacros;
2075+
AvailabilityMacroMap &Map = parseAllAvailabilityMacroArguments();
20782076

20792077
StringRef MacroName = Tok.getText();
2080-
auto NameMatch = Map.find(MacroName);
2081-
if (NameMatch == Map.end())
2078+
auto NameMatch = Map.Impl.find(MacroName);
2079+
if (NameMatch == Map.Impl.end())
20822080
return makeParserSuccess(); // No match, it could be a standard platform.
20832081

20842082
consumeToken();
@@ -2114,20 +2112,26 @@ Parser::parseAvailabilityMacro(SmallVectorImpl<AvailabilitySpec *> &Specs) {
21142112
return makeParserSuccess();
21152113
}
21162114

2117-
void Parser::parseAllAvailabilityMacroArguments() {
2118-
2119-
if (AvailabilityMacrosComputed) return;
2120-
2121-
AvailabilityMacroMap Map;
2115+
AvailabilityMacroMap &Parser::parseAllAvailabilityMacroArguments() {
2116+
AvailabilityMacroMap &Map = Context.getAvailabilityMacroCache();
2117+
if (Map.WasParsed)
2118+
return Map;
21222119

21232120
SourceManager &SM = Context.SourceMgr;
21242121
LangOptions LangOpts = Context.LangOpts;
21252122

2123+
// Allocate all buffers in one go to avoid repeating the sorting in
2124+
// findBufferContainingLocInternal.
2125+
llvm::SmallVector<unsigned, 4> bufferIDs;
21262126
for (StringRef macro: LangOpts.AvailabilityMacros) {
2127+
unsigned bufferID = SM.addMemBufferCopy(macro,
2128+
"-define-availability argument");
2129+
bufferIDs.push_back(bufferID);
2130+
}
21272131

2132+
// Parse each macro definition.
2133+
for (unsigned bufferID: bufferIDs) {
21282134
// Create temporary parser.
2129-
int bufferID = SM.addMemBufferCopy(macro,
2130-
"-define-availability argument");
21312135
swift::ParserUnit PU(SM, SourceFileKind::Main, bufferID, LangOpts,
21322136
TypeCheckerOptions(), SILOptions(), "unknown");
21332137

@@ -2156,9 +2160,9 @@ void Parser::parseAllAvailabilityMacroArguments() {
21562160
ParsedMacro.Specs = SpecsCopy;
21572161

21582162
// Find the macro info by name.
2159-
AvailabilityMacroVersionMap MacroDefinition;
2160-
auto NameMatch = Map.find(ParsedMacro.Name);
2161-
if (NameMatch != Map.end()) {
2163+
AvailabilityMacroMap::VersionEntry MacroDefinition;
2164+
auto NameMatch = Map.Impl.find(ParsedMacro.Name);
2165+
if (NameMatch != Map.Impl.end()) {
21622166
MacroDefinition = NameMatch->getSecond();
21632167
}
21642168

@@ -2171,12 +2175,12 @@ void Parser::parseAllAvailabilityMacroArguments() {
21712175
}
21722176

21732177
// Save back the macro spec.
2174-
Map.erase(ParsedMacro.Name);
2175-
Map.insert({ParsedMacro.Name, MacroDefinition});
2178+
Map.Impl.erase(ParsedMacro.Name);
2179+
Map.Impl.insert({ParsedMacro.Name, MacroDefinition});
21762180
}
21772181

2178-
AvailabilityMacros = Map;
2179-
AvailabilityMacrosComputed = true;
2182+
Map.WasParsed = true;
2183+
return Map;
21802184
}
21812185

21822186
ParserStatus Parser::parsePlatformVersionInList(StringRef AttrName,
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t --leading-lines
3+
4+
// RUN: not %target-swift-frontend -typecheck -diagnostic-style llvm \
5+
// RUN: %t/FileA.swift %t/FileB.swift \
6+
// RUN: -define-availability "_justAName" \
7+
// RUN: 2>&1 | %FileCheck %s
8+
9+
// CHECK: -define-availability argument:1:11: error: expected ':' after '_justAName' in availability macro definition
10+
// CHECK-NEXT: _justAName
11+
12+
/// It's parsed once so the diagnostic is produced once as well.
13+
// CHECK-NOT: _justAName
14+
15+
//--- FileA.swift
16+
17+
@available(_triggerParsingMacros)
18+
public func brokenPlatforms() {}
19+
20+
//--- FileB.swift
21+
22+
@available(_triggerParsingMacros)
23+
public func brokenPlatforms() {}

0 commit comments

Comments
 (0)