Merge remote-tracking branch 'origin/swift-3.0-branch' into stable
* origin/swift-3.0-branch:
PCH + module: make sure we write out macros associated with builtin identifiers.
ObjC lifetime: pull sugar off when the qualifiers conflict.
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 906a228..6ff4adf 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -5361,11 +5361,13 @@
}
// Otherwise, if the qualifiers actually conflict, pull sugar off
- // until we reach a type that is directly qualified.
+ // and remove the ObjCLifetime qualifiers.
if (previousLifetime != lifetime) {
- // This should always terminate: the canonical type is
- // qualified, so some bit of sugar must be hiding it.
- while (!underlyingType.Quals.hasObjCLifetime()) {
+ // It's possible to have multiple local ObjCLifetime qualifiers. We
+ // can't stop after we reach a type that is directly qualified.
+ const Type *prevTy = nullptr;
+ while (!prevTy || prevTy != underlyingType.Ty) {
+ prevTy = underlyingType.Ty;
underlyingType = underlyingType.getSingleStepDesugaredType();
}
underlyingType.Quals.removeObjCLifetime();
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 5677184..62c60a0 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -2131,30 +2131,29 @@
// Write out any exported module macros.
bool EmittedModuleMacros = false;
- if (IsModule) {
- auto Leafs = PP.getLeafModuleMacros(Name);
- SmallVector<ModuleMacro*, 8> Worklist(Leafs.begin(), Leafs.end());
- llvm::DenseMap<ModuleMacro*, unsigned> Visits;
- while (!Worklist.empty()) {
- auto *Macro = Worklist.pop_back_val();
+ // We write out exported module macros for PCH as well.
+ auto Leafs = PP.getLeafModuleMacros(Name);
+ SmallVector<ModuleMacro*, 8> Worklist(Leafs.begin(), Leafs.end());
+ llvm::DenseMap<ModuleMacro*, unsigned> Visits;
+ while (!Worklist.empty()) {
+ auto *Macro = Worklist.pop_back_val();
- // Emit a record indicating this submodule exports this macro.
- ModuleMacroRecord.push_back(
- getSubmoduleID(Macro->getOwningModule()));
- ModuleMacroRecord.push_back(getMacroRef(Macro->getMacroInfo(), Name));
- for (auto *M : Macro->overrides())
- ModuleMacroRecord.push_back(getSubmoduleID(M->getOwningModule()));
+ // Emit a record indicating this submodule exports this macro.
+ ModuleMacroRecord.push_back(
+ getSubmoduleID(Macro->getOwningModule()));
+ ModuleMacroRecord.push_back(getMacroRef(Macro->getMacroInfo(), Name));
+ for (auto *M : Macro->overrides())
+ ModuleMacroRecord.push_back(getSubmoduleID(M->getOwningModule()));
- Stream.EmitRecord(PP_MODULE_MACRO, ModuleMacroRecord);
- ModuleMacroRecord.clear();
+ Stream.EmitRecord(PP_MODULE_MACRO, ModuleMacroRecord);
+ ModuleMacroRecord.clear();
- // Enqueue overridden macros once we've visited all their ancestors.
- for (auto *M : Macro->overrides())
- if (++Visits[M] == M->getNumOverridingMacros())
- Worklist.push_back(M);
+ // Enqueue overridden macros once we've visited all their ancestors.
+ for (auto *M : Macro->overrides())
+ if (++Visits[M] == M->getNumOverridingMacros())
+ Worklist.push_back(M);
- EmittedModuleMacros = true;
- }
+ EmittedModuleMacros = true;
}
if (Record.empty() && !EmittedModuleMacros)
diff --git a/test/Modules/Inputs/MacroFabs1.h b/test/Modules/Inputs/MacroFabs1.h
new file mode 100644
index 0000000..a78c553
--- /dev/null
+++ b/test/Modules/Inputs/MacroFabs1.h
@@ -0,0 +1,6 @@
+
+#undef fabs
+#define fabs(x) (x)
+
+#undef my_fabs
+#define my_fabs(x) (x)
diff --git a/test/Modules/Inputs/module.map b/test/Modules/Inputs/module.map
index 66b52e9..fc47d42 100644
--- a/test/Modules/Inputs/module.map
+++ b/test/Modules/Inputs/module.map
@@ -412,3 +412,7 @@
}
module Empty {}
+
+module MacroFabs1 {
+ header "MacroFabs1.h"
+}
diff --git a/test/Modules/Inputs/pch-import-module-with-macro.pch b/test/Modules/Inputs/pch-import-module-with-macro.pch
new file mode 100644
index 0000000..c06d772
--- /dev/null
+++ b/test/Modules/Inputs/pch-import-module-with-macro.pch
@@ -0,0 +1,3 @@
+
+@import MacroFabs1;
+
diff --git a/test/Modules/pch-module-macro.m b/test/Modules/pch-module-macro.m
new file mode 100644
index 0000000..cc9f687
--- /dev/null
+++ b/test/Modules/pch-module-macro.m
@@ -0,0 +1,9 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -emit-pch -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -o %t.pch -I %S/Inputs -x objective-c-header %S/Inputs/pch-import-module-with-macro.pch
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -fsyntax-only -I %S/Inputs -include-pch %t.pch %s -verify
+// expected-no-diagnostics
+
+int test(int x) {
+ return my_fabs(x) + fabs(x);
+}
+
diff --git a/test/SemaObjC/arc-objc-lifetime-conflict.m b/test/SemaObjC/arc-objc-lifetime-conflict.m
new file mode 100644
index 0000000..218950c
--- /dev/null
+++ b/test/SemaObjC/arc-objc-lifetime-conflict.m
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-arc -fobjc-runtime-has-weak %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: bitcast {{.*}} %self_weak_s_w_s
+// CHECK-NEXT: objc_destroyWeak
+// CHECK-NEXT: bitcast {{.*}} %self_strong_w_s
+// CHECK-NEXT: objc_storeStrong
+// CHECK-NEXT: bitcast {{.*}} %self_weak_s
+// CHECK-NEXT: objc_destroyWeak
+// CHECK-NEXT: bitcast {{.*}} %self_weak_s3
+// CHECK-NEXT: objc_destroyWeak
+// CHECK-NEXT: bitcast {{.*}} %self_strong3
+// CHECK-NEXT: objc_storeStrong
+// CHECK-NEXT: bitcast {{.*}} %self_strong2
+// CHECK-NEXT: objc_storeStrong
+// CHECK-NEXT: bitcast {{.*}} %self_strong
+// CHECK-NEXT: objc_storeStrong
+@interface NSObject
+@end
+@interface A : NSObject
+@end
+@implementation A
+- (void)test {
+ __attribute__((objc_ownership(strong))) __typeof__(self) self_strong;
+ __attribute__((objc_ownership(strong))) __typeof__(self_strong) self_strong2;
+ __attribute__((objc_ownership(strong))) __typeof__(self_strong2) self_strong3;
+ __attribute__((objc_ownership(weak))) __typeof__(self_strong3) self_weak_s3;
+
+ __attribute__((objc_ownership(weak))) __typeof__(self_strong) self_weak_s;
+ __attribute__((objc_ownership(strong))) __typeof__(self_weak_s) self_strong_w_s;
+ __attribute__((objc_ownership(weak))) __typeof__(self_strong_w_s) self_weak_s_w_s;
+}
+@end