Skip to content

Commit 9501a69

Browse files
author
Nathan Hawes
authored
Merge pull request swiftlang#33594 from nathawes/fix-missing-include
[master-rebranch] Merge in master and fix missing include in Decl.cpp
2 parents bd02dc4 + 0034cab commit 9501a69

29 files changed

+472
-105
lines changed

include/swift/AST/ClangNode.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef SWIFT_CLANGNODE_H
1414
#define SWIFT_CLANGNODE_H
1515

16+
#include "swift/Basic/Debug.h"
1617
#include "llvm/ADT/PointerUnion.h"
1718

1819
namespace clang {
@@ -98,6 +99,8 @@ class ClangNode {
9899
clang::SourceLocation getLocation() const;
99100
clang::SourceRange getSourceRange() const;
100101

102+
SWIFT_DEBUG_DUMP;
103+
101104
void *getOpaqueValue() const { return Ptr.getOpaqueValue(); }
102105
static inline ClangNode getFromOpaqueValue(void *VP) {
103106
ClangNode N;

include/swift/AST/Decl.h

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ class alignas(1 << DeclAlignInBits) Decl {
283283
protected:
284284
union { uint64_t OpaqueBits;
285285

286-
SWIFT_INLINE_BITFIELD_BASE(Decl, bitmax(NumDeclKindBits,8)+1+1+1+1+1,
286+
SWIFT_INLINE_BITFIELD_BASE(Decl, bitmax(NumDeclKindBits,8)+1+1+1+1,
287287
Kind : bitmax(NumDeclKindBits,8),
288288

289289
/// Whether this declaration is invalid.
@@ -385,7 +385,7 @@ class alignas(1 << DeclAlignInBits) Decl {
385385
SWIFT_INLINE_BITFIELD(SubscriptDecl, VarDecl, 2,
386386
StaticSpelling : 2
387387
);
388-
SWIFT_INLINE_BITFIELD(AbstractFunctionDecl, ValueDecl, 3+8+1+1+1+1+1+1+1,
388+
SWIFT_INLINE_BITFIELD(AbstractFunctionDecl, ValueDecl, 3+8+1+1+1+1+1+1,
389389
/// \see AbstractFunctionDecl::BodyKind
390390
BodyKind : 3,
391391

@@ -2996,11 +2996,29 @@ class TypeAliasDecl : public GenericTypeDecl {
29962996
/// Retrieve a sugared interface type containing the structure of the interface
29972997
/// type before any semantic validation has occured.
29982998
Type getStructuralType() const;
2999-
2999+
3000+
/// Whether the typealias forwards perfectly to its underlying type.
3001+
///
3002+
/// If true, this typealias was created by ClangImporter to preserve source
3003+
/// compatibility with a previous language version's name for a type. Many
3004+
/// checks in Sema look through compatibility aliases even when they would
3005+
/// operate on other typealiases.
3006+
///
3007+
/// \warning This has absolutely nothing to do with the Objective-C
3008+
/// \c compatibility_alias keyword.
30003009
bool isCompatibilityAlias() const {
30013010
return Bits.TypeAliasDecl.IsCompatibilityAlias;
30023011
}
30033012

3013+
/// Sets whether the typealias forwards perfectly to its underlying type.
3014+
///
3015+
/// Marks this typealias as having been created by ClangImporter to preserve
3016+
/// source compatibility with a previous language version's name for a type.
3017+
/// Many checks in Sema look through compatibility aliases even when they
3018+
/// would operate on other typealiases.
3019+
///
3020+
/// \warning This has absolutely nothing to do with the Objective-C
3021+
/// \c compatibility_alias keyword.
30043022
void markAsCompatibilityAlias(bool newValue = true) {
30053023
Bits.TypeAliasDecl.IsCompatibilityAlias = newValue;
30063024
}

include/swift/AST/DiagnosticsCommon.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,5 +185,8 @@ WARNING(cross_imported_by_both_modules, none,
185185
ERROR(scanner_find_cycle, none,
186186
"dependency scanner detected dependency cycle: '%0'", (StringRef))
187187

188+
ERROR(scanner_arguments_invalid, none,
189+
"dependencies scanner cannot be configured with arguments: '%0'", (StringRef))
190+
188191
#define UNDEFINE_DIAGNOSTIC_MACROS
189192
#include "DefineDiagnosticMacros.h"

lib/AST/Decl.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
#include "swift/Demangling/ManglingMacros.h"
6060

6161
#include "clang/Basic/CharInfo.h"
62+
#include "clang/Basic/Module.h"
6263
#include "clang/AST/Attr.h"
6364
#include "clang/AST/DeclObjC.h"
6465

@@ -116,6 +117,17 @@ const clang::Module *ClangNode::getClangModule() const {
116117
return nullptr;
117118
}
118119

120+
void ClangNode::dump() const {
121+
if (auto D = getAsDecl())
122+
D->dump();
123+
else if (auto M = getAsMacro())
124+
M->dump();
125+
else if (auto M = getAsModule())
126+
M->dump();
127+
else
128+
llvm::errs() << "ClangNode contains nullptr\n";
129+
}
130+
119131
// Only allow allocation of Decls using the allocator in ASTContext.
120132
void *Decl::operator new(size_t Bytes, const ASTContext &C,
121133
unsigned Alignment) {

lib/FrontendTool/FrontendTool.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1752,7 +1752,8 @@ static void performEndOfPipelineActions(CompilerInstance &Instance) {
17521752
/// \param Instance Will be reset after performIRGeneration when the verifier
17531753
/// mode is NoVerify and there were no errors.
17541754
/// \returns true on error
1755-
static bool performCompile(CompilerInstance &Instance,
1755+
static bool performCompile(CompilerInvocation &Invok,
1756+
CompilerInstance &Instance,
17561757
ArrayRef<const char *> Args,
17571758
int &ReturnValue,
17581759
FrontendObserver *observer) {
@@ -1840,7 +1841,8 @@ static bool performCompile(CompilerInstance &Instance,
18401841
if (batchScanInput.empty())
18411842
return finishPipeline(scanDependencies(Instance));
18421843
else
1843-
return finishPipeline(batchScanModuleDependencies(Instance,
1844+
return finishPipeline(batchScanModuleDependencies(Invok,
1845+
Instance,
18441846
batchScanInput));
18451847
}
18461848

@@ -2653,7 +2655,7 @@ int swift::performFrontend(ArrayRef<const char *> Args,
26532655
}
26542656

26552657
int ReturnValue = 0;
2656-
bool HadError = performCompile(*Instance, Args, ReturnValue, observer);
2658+
bool HadError = performCompile(Invocation, *Instance, Args, ReturnValue, observer);
26572659

26582660
if (verifierEnabled) {
26592661
DiagnosticEngine &diags = Instance->getDiags();

lib/FrontendTool/ScanDependencies.cpp

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "llvm/ADT/StringMap.h"
3232
#include "llvm/ADT/StringRef.h"
3333
#include "llvm/ADT/StringSet.h"
34+
#include "llvm/Support/CommandLine.h"
3435
#include "llvm/Support/FileSystem.h"
3536
#include "llvm/Support/StringSaver.h"
3637
#include "llvm/Support/YAMLTraits.h"
@@ -626,7 +627,6 @@ static bool diagnoseCycle(CompilerInstance &instance,
626627

627628
static bool scanModuleDependencies(CompilerInstance &instance,
628629
StringRef moduleName,
629-
StringRef arguments,
630630
bool isClang,
631631
StringRef outputPath) {
632632
ASTContext &ctx = instance.getASTContext();
@@ -685,25 +685,58 @@ static bool scanModuleDependencies(CompilerInstance &instance,
685685
bool swift::scanClangDependencies(CompilerInstance &instance) {
686686
return scanModuleDependencies(instance,
687687
instance.getMainModule()->getNameStr(),
688-
StringRef(),
689688
/*isClang*/true,
690689
instance.getInvocation().getFrontendOptions()
691690
.InputsAndOutputs.getSingleOutputFilename());
692691
}
693692

694-
bool swift::batchScanModuleDependencies(CompilerInstance &instance,
695-
llvm::StringRef batchInputFile) {
693+
bool swift::batchScanModuleDependencies(CompilerInvocation &invok,
694+
CompilerInstance &instance,
695+
llvm::StringRef batchInputFile) {
696696
(void)instance.getMainModule();
697697
llvm::BumpPtrAllocator alloc;
698698
llvm::StringSaver saver(alloc);
699699
auto results = parseBatchScanInputFile(instance.getASTContext(),
700700
batchInputFile, saver);
701701
if (!results.hasValue())
702702
return true;
703+
auto &diags = instance.getDiags();
704+
ForwardingDiagnosticConsumer FDC(diags);
705+
// Keep track of all compiler instances we have created.
706+
llvm::StringMap<std::unique_ptr<CompilerInstance>> subInstanceMap;
703707
for (auto &entry: *results) {
704-
if (scanModuleDependencies(instance, entry.moduleName, entry.arguments,
705-
!entry.isSwift, entry.outputPath))
708+
CompilerInstance *pInstance = nullptr;
709+
if (entry.arguments.empty()) {
710+
// Use the compiler's instance if no arguments are specified.
711+
pInstance = &instance;
712+
} else if (subInstanceMap.count(entry.arguments)) {
713+
// Use the previously created instance if we've seen the arguments before.
714+
pInstance = subInstanceMap[entry.arguments].get();
715+
} else {
716+
// Create a new instance by the arguments and save it in the map.
717+
pInstance = subInstanceMap.insert({entry.arguments,
718+
std::make_unique<CompilerInstance>()}).first->getValue().get();
719+
SmallVector<const char*, 4> args;
720+
llvm::cl::TokenizeGNUCommandLine(entry.arguments, saver, args);
721+
CompilerInvocation subInvok = invok;
722+
pInstance->addDiagnosticConsumer(&FDC);
723+
if (subInvok.parseArgs(args, diags)) {
724+
instance.getDiags().diagnose(SourceLoc(), diag::scanner_arguments_invalid,
725+
entry.arguments);
726+
return true;
727+
}
728+
if (pInstance->setup(subInvok)) {
729+
instance.getDiags().diagnose(SourceLoc(), diag::scanner_arguments_invalid,
730+
entry.arguments);
731+
return true;
732+
}
733+
}
734+
assert(pInstance);
735+
// Scan using the chosen compiler instance.
736+
if (scanModuleDependencies(*pInstance, entry.moduleName, !entry.isSwift,
737+
entry.outputPath)) {
706738
return true;
739+
}
707740
}
708741
return false;
709742
}

lib/FrontendTool/ScanDependencies.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@
1717

1818
namespace swift {
1919

20+
class CompilerInvocation;
2021
class CompilerInstance;
2122

2223
/// Batch scan the dependencies for modules specified in \c batchInputFile.
23-
bool batchScanModuleDependencies(CompilerInstance &instance, llvm::StringRef batchInputFile);
24+
bool batchScanModuleDependencies(CompilerInvocation &invok,
25+
CompilerInstance &instance,
26+
llvm::StringRef batchInputFile);
2427

2528
/// Scans the dependencies of the main module of \c instance.
2629
bool scanDependencies(CompilerInstance &instance);

lib/PrintAsObjC/DeclAndTypePrinter.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1573,25 +1573,36 @@ class DeclAndTypePrinter::Implementation
15731573
}
15741574

15751575
bool printImportedAlias(const TypeAliasDecl *alias,
1576+
ArrayRef<Type> genericArgs,
15761577
Optional<OptionalTypeKind> optionalKind) {
15771578
if (!alias->hasClangNode())
15781579
return false;
15791580

15801581
if (auto *clangTypeDecl =
15811582
dyn_cast<clang::TypeDecl>(alias->getClangDecl())) {
1583+
assert(!alias->isGeneric()
1584+
&& "generic typealias backed by clang typedecl?");
1585+
15821586
maybePrintTagKeyword(alias);
15831587
os << getNameForObjC(alias);
15841588

15851589
if (isClangPointerType(clangTypeDecl))
15861590
printNullability(optionalKind);
15871591
} else if (auto *clangObjCClass
15881592
= dyn_cast<clang::ObjCInterfaceDecl>(alias->getClangDecl())){
1593+
assert(!alias->isGeneric()
1594+
&& "generic typealias backed by clang interface?");
1595+
15891596
os << clangObjCClass->getName() << " *";
15901597
printNullability(optionalKind);
15911598
} else {
15921599
auto *clangCompatAlias =
15931600
cast<clang::ObjCCompatibleAliasDecl>(alias->getClangDecl());
1594-
os << clangCompatAlias->getName() << " *";
1601+
1602+
os << clangCompatAlias->getName();
1603+
if (!genericArgs.empty())
1604+
printGenericArgs(genericArgs);
1605+
os << " *";
15951606
printNullability(optionalKind);
15961607
}
15971608

@@ -1601,10 +1612,12 @@ class DeclAndTypePrinter::Implementation
16011612
void visitTypeAliasType(TypeAliasType *aliasTy,
16021613
Optional<OptionalTypeKind> optionalKind) {
16031614
const TypeAliasDecl *alias = aliasTy->getDecl();
1615+
auto genericArgs = aliasTy->getDirectGenericArgs();
1616+
16041617
if (printIfKnownSimpleType(alias, optionalKind))
16051618
return;
16061619

1607-
if (printImportedAlias(alias, optionalKind))
1620+
if (printImportedAlias(alias, genericArgs, optionalKind))
16081621
return;
16091622

16101623
visitPart(aliasTy->getSinglyDesugaredType(), optionalKind);
@@ -1738,8 +1751,12 @@ class DeclAndTypePrinter::Implementation
17381751
}
17391752

17401753
void printGenericArgs(BoundGenericType *BGT) {
1754+
printGenericArgs(BGT->getGenericArgs());
1755+
}
1756+
1757+
void printGenericArgs(ArrayRef<Type> genericArgs) {
17411758
os << '<';
1742-
interleave(BGT->getGenericArgs(),
1759+
interleave(genericArgs,
17431760
[this](Type t) { print(t, None); },
17441761
[this] { os << ", "; });
17451762
os << '>';

lib/PrintAsObjC/ModuleContentsWriter.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ class ReferencedTypeFinder : public TypeDeclFinder {
5858
Action visitTypeAliasType(TypeAliasType *aliasTy) override {
5959
if (aliasTy->getDecl()->hasClangNode() &&
6060
!aliasTy->getDecl()->isCompatibilityAlias()) {
61-
assert(!aliasTy->getDecl()->isGeneric());
6261
Callback(*this, aliasTy->getDecl());
6362
} else {
6463
Type(aliasTy->getSinglyDesugaredType()).walk(*this);
@@ -320,8 +319,10 @@ class ModuleWriter {
320319
} else if (auto PD = dyn_cast<ProtocolDecl>(TD)) {
321320
forwardDeclare(PD);
322321
} else if (auto TAD = dyn_cast<TypeAliasDecl>(TD)) {
322+
bool imported = false;
323323
if (TAD->hasClangNode())
324-
(void)addImport(TD);
324+
imported = addImport(TD);
325+
assert((imported || !TAD->isGeneric()) && "referencing non-imported generic typealias?");
325326
} else if (addImport(TD)) {
326327
return;
327328
} else if (auto ED = dyn_cast<EnumDecl>(TD)) {

lib/SILGen/SILGenPattern.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,20 +1038,35 @@ void PatternMatchEmission::emitDispatch(ClauseMatrix &clauses, ArgArray args,
10381038
SGF.eraseBasicBlock(contBB);
10391039
return;
10401040
}
1041-
1041+
10421042
// Otherwise, if there is no fallthrough, then the next row is
1043-
// unreachable: emit a dead code diagnostic.
1043+
// unreachable: emit a dead code diagnostic if:
1044+
// 1) It's for a 'default' case (since Space Engine already handles
1045+
// unreachable enum case patterns) or it's for a enum case which
1046+
// has expression patterns since redundancy checking for such
1047+
// patterns isn't sufficiently done by the Space Engine.
1048+
// 2) It's for a case statement in a do-catch.
10441049
if (!clauses[firstRow].hasFallthroughTo()) {
10451050
SourceLoc Loc;
10461051
bool isDefault = false;
1052+
bool isParentDoCatch = false;
1053+
bool caseHasExprPattern = false;
10471054
if (auto *S = clauses[firstRow].getClientData<Stmt>()) {
10481055
Loc = S->getStartLoc();
1049-
if (auto *CS = dyn_cast<CaseStmt>(S))
1056+
if (auto *CS = dyn_cast<CaseStmt>(S)) {
1057+
caseHasExprPattern = llvm::any_of(
1058+
CS->getCaseLabelItems(), [&](const CaseLabelItem item) {
1059+
return item.getPattern()->getKind() == PatternKind::Expr;
1060+
});
1061+
isParentDoCatch = CS->getParentKind() == CaseParentKind::DoCatch;
10501062
isDefault = CS->isDefault();
1063+
}
10511064
} else {
10521065
Loc = clauses[firstRow].getCasePattern()->getStartLoc();
10531066
}
1054-
SGF.SGM.diagnose(Loc, diag::unreachable_case, isDefault);
1067+
if (isParentDoCatch || isDefault || caseHasExprPattern) {
1068+
SGF.SGM.diagnose(Loc, diag::unreachable_case, isDefault);
1069+
}
10551070
}
10561071
}
10571072
}

0 commit comments

Comments
 (0)