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