@@ -2013,72 +2013,89 @@ getClangOwningModule(ClangNode Node, const clang::ASTContext &ClangCtx) {
2013
2013
return nullptr ;
2014
2014
}
2015
2015
2016
+ static const clang::Module *
2017
+ getClangTopLevelOwningModule (ClangNode Node,
2018
+ const clang::ASTContext &ClangCtx) {
2019
+ const clang::Module *OwningModule = getClangOwningModule (Node, ClangCtx);
2020
+ if (!OwningModule)
2021
+ return nullptr ;
2022
+ return OwningModule->getTopLevelModule ();
2023
+ }
2024
+
2016
2025
static bool isVisibleFromModule (const ClangModuleUnit *ModuleFilter,
2017
2026
const ValueDecl *VD) {
2018
- // Include a value from module X if:
2019
- // * no particular module was requested, or
2020
- // * module X was specifically requested.
2021
- if (!ModuleFilter)
2022
- return true ;
2027
+ assert (ModuleFilter);
2023
2028
2024
2029
auto ContainingUnit = VD->getDeclContext ()->getModuleScopeContext ();
2025
2030
if (ModuleFilter == ContainingUnit)
2026
2031
return true ;
2027
2032
2033
+ // The rest of this function is looking to see if the Clang entity that
2034
+ // caused VD to be imported has redeclarations in the filter module.
2028
2035
auto Wrapper = dyn_cast<ClangModuleUnit>(ContainingUnit);
2029
2036
if (!Wrapper)
2030
2037
return false ;
2031
2038
2032
2039
auto ClangNode = VD->getClangNode ();
2033
- assert (ClangNode);
2040
+ if (!ClangNode) {
2041
+ // If we synthesized a ValueDecl, it won't have a Clang node. But so far
2042
+ // all the situations where we synthesize top-level declarations are
2043
+ // situations where we don't have to worry about C redeclarations.
2044
+ // We should only consider the declaration visible from its owning module.
2045
+ auto *SynthesizedTypeAttr =
2046
+ VD->getAttrs ().getAttribute <ClangImporterSynthesizedTypeAttr>();
2047
+ assert (SynthesizedTypeAttr);
2048
+
2049
+ // When adding new ClangImporterSynthesizedTypeAttr::Kinds, make sure that
2050
+ // the above statement still holds: "we don't want to allow these
2051
+ // declarations to be treated as present in multiple modules".
2052
+ switch (SynthesizedTypeAttr->getKind ()) {
2053
+ case ClangImporterSynthesizedTypeAttr::Kind::NSErrorWrapper:
2054
+ case ClangImporterSynthesizedTypeAttr::Kind::NSErrorWrapperAnon:
2055
+ break ;
2056
+ }
2034
2057
2058
+ return false ;
2059
+ }
2060
+
2061
+ // Macros can be "redeclared" by putting an equivalent definition in two
2062
+ // different modules. (We don't actually check the equivalence.)
2063
+ // FIXME: We're also not checking if the redeclaration is in /this/ module.
2064
+ if (ClangNode.getAsMacro ())
2065
+ return true ;
2066
+
2067
+ const clang::Decl *D = ClangNode.castAsDecl ();
2035
2068
auto &ClangASTContext = ModuleFilter->getClangASTContext ();
2036
- auto OwningClangModule = getClangOwningModule (ClangNode, ClangASTContext);
2037
2069
2038
2070
// We don't handle Clang submodules; pop everything up to the top-level
2039
2071
// module.
2040
- if (OwningClangModule)
2041
- OwningClangModule = OwningClangModule->getTopLevelModule ();
2042
-
2072
+ auto OwningClangModule = getClangTopLevelOwningModule (ClangNode,
2073
+ ClangASTContext);
2043
2074
if (OwningClangModule == ModuleFilter->getClangModule ())
2044
2075
return true ;
2045
2076
2046
- if (auto D = ClangNode.getAsDecl ()) {
2047
- // Handle redeclared decls.
2048
- if (isa<clang::FunctionDecl>(D) || isa<clang::VarDecl>(D) ||
2049
- isa<clang::TypedefNameDecl>(D)) {
2050
- for (auto Redeclaration : D->redecls ()) {
2051
- if (Redeclaration == D)
2052
- continue ;
2053
- auto OwningClangModule = getClangOwningModule (Redeclaration,
2054
- ClangASTContext);
2055
- if (OwningClangModule)
2056
- OwningClangModule = OwningClangModule->getTopLevelModule ();
2077
+ // Handle redeclarable Clang decls by checking each redeclaration.
2078
+ bool IsTagDecl = isa<clang::TagDecl>(D);
2079
+ if (!(IsTagDecl || isa<clang::FunctionDecl>(D) || isa<clang::VarDecl>(D) ||
2080
+ isa<clang::TypedefNameDecl>(D))) {
2081
+ return false ;
2082
+ }
2057
2083
2058
- if (OwningClangModule == ModuleFilter->getClangModule ())
2059
- return true ;
2060
- }
2061
- } else if (isa<clang::TagDecl>(D)) {
2062
- for (auto Redeclaration : D->redecls ()) {
2063
- if (Redeclaration == D)
2064
- continue ;
2065
- if (!cast<clang::TagDecl>(Redeclaration)->isCompleteDefinition ())
2066
- continue ;
2067
- auto OwningClangModule = getClangOwningModule (Redeclaration,
2068
- ClangASTContext);
2069
- if (OwningClangModule)
2070
- OwningClangModule = OwningClangModule->getTopLevelModule ();
2084
+ for (auto Redeclaration : D->redecls ()) {
2085
+ if (Redeclaration == D)
2086
+ continue ;
2071
2087
2072
- if (OwningClangModule == ModuleFilter-> getClangModule ())
2073
- return true ;
2074
- }
2075
- }
2076
- }
2088
+ // For enums, structs, and unions, only count definitions when looking to
2089
+ // see what other modules they appear in.
2090
+ if (IsTagDecl)
2091
+ if (!cast<clang::TagDecl>(Redeclaration)-> isCompleteDefinition ())
2092
+ continue ;
2077
2093
2078
- // Macros can be "redeclared" too, by putting an equivalent definition in two
2079
- // different modules.
2080
- if (ClangNode.getAsMacro ())
2081
- return true ;
2094
+ auto OwningClangModule = getClangTopLevelOwningModule (Redeclaration,
2095
+ ClangASTContext);
2096
+ if (OwningClangModule == ModuleFilter->getClangModule ())
2097
+ return true ;
2098
+ }
2082
2099
2083
2100
return false ;
2084
2101
}
@@ -2108,12 +2125,14 @@ class ClangVectorDeclConsumer : public clang::VisibleDeclConsumer {
2108
2125
2109
2126
class FilteringVisibleDeclConsumer : public swift ::VisibleDeclConsumer {
2110
2127
swift::VisibleDeclConsumer &NextConsumer;
2111
- const ClangModuleUnit *ModuleFilter = nullptr ;
2128
+ const ClangModuleUnit *ModuleFilter;
2112
2129
2113
2130
public:
2114
2131
FilteringVisibleDeclConsumer (swift::VisibleDeclConsumer &consumer,
2115
2132
const ClangModuleUnit *CMU)
2116
- : NextConsumer(consumer), ModuleFilter(CMU) {}
2133
+ : NextConsumer(consumer), ModuleFilter(CMU) {
2134
+ assert (CMU);
2135
+ }
2117
2136
2118
2137
void foundDecl (ValueDecl *VD, DeclVisibilityKind Reason) override {
2119
2138
if (isVisibleFromModule (ModuleFilter, VD))
@@ -2123,13 +2142,14 @@ class FilteringVisibleDeclConsumer : public swift::VisibleDeclConsumer {
2123
2142
2124
2143
class FilteringDeclaredDeclConsumer : public swift ::VisibleDeclConsumer {
2125
2144
swift::VisibleDeclConsumer &NextConsumer;
2126
- const ClangModuleUnit *ModuleFilter = nullptr ;
2145
+ const ClangModuleUnit *ModuleFilter;
2127
2146
2128
2147
public:
2129
2148
FilteringDeclaredDeclConsumer (swift::VisibleDeclConsumer &consumer,
2130
2149
const ClangModuleUnit *CMU)
2131
- : NextConsumer(consumer),
2132
- ModuleFilter (CMU) {}
2150
+ : NextConsumer(consumer), ModuleFilter(CMU) {
2151
+ assert (CMU);
2152
+ }
2133
2153
2134
2154
void foundDecl (ValueDecl *VD, DeclVisibilityKind Reason) override {
2135
2155
if (isDeclaredInModule (ModuleFilter, VD))
@@ -2870,10 +2890,7 @@ void ClangModuleUnit::lookupObjCMethods(
2870
2890
auto &clangCtx = clangSema.getASTContext ();
2871
2891
for (auto objcMethod : objcMethods) {
2872
2892
// Verify that this method came from this module.
2873
- auto owningClangModule = getClangOwningModule (objcMethod, clangCtx);
2874
- if (owningClangModule)
2875
- owningClangModule = owningClangModule->getTopLevelModule ();
2876
-
2893
+ auto owningClangModule = getClangTopLevelOwningModule (objcMethod, clangCtx);
2877
2894
if (owningClangModule != clangModule) continue ;
2878
2895
2879
2896
// If we found a property accessor, import the property.
0 commit comments