@@ -2011,18 +2011,25 @@ 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 ;
@@ -2049,53 +2056,44 @@ static bool isVisibleFromModule(const ClangModuleUnit *ModuleFilter,
2049
2056
return false ;
2050
2057
}
2051
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 ();
2052
2066
auto &ClangASTContext = ModuleFilter->getClangASTContext ();
2053
- auto OwningClangModule = getClangOwningModule (ClangNode, ClangASTContext);
2054
2067
2055
2068
// We don't handle Clang submodules; pop everything up to the top-level
2056
2069
// module.
2057
- if (OwningClangModule)
2058
- OwningClangModule = OwningClangModule->getTopLevelModule ();
2059
-
2070
+ auto OwningClangModule = getClangTopLevelOwningModule (ClangNode,
2071
+ ClangASTContext);
2060
2072
if (OwningClangModule == ModuleFilter->getClangModule ())
2061
2073
return true ;
2062
2074
2063
- if (auto D = ClangNode.getAsDecl ()) {
2064
- // Handle redeclared decls.
2065
- if (isa<clang::FunctionDecl>(D) || isa<clang::VarDecl>(D) ||
2066
- isa<clang::TypedefNameDecl>(D)) {
2067
- for (auto Redeclaration : D->redecls ()) {
2068
- if (Redeclaration == D)
2069
- continue ;
2070
- auto OwningClangModule = getClangOwningModule (Redeclaration,
2071
- ClangASTContext);
2072
- if (OwningClangModule)
2073
- 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
+ }
2074
2081
2075
- if (OwningClangModule == ModuleFilter->getClangModule ())
2076
- return true ;
2077
- }
2078
- } else if (isa<clang::TagDecl>(D)) {
2079
- for (auto Redeclaration : D->redecls ()) {
2080
- if (Redeclaration == D)
2081
- continue ;
2082
- if (!cast<clang::TagDecl>(Redeclaration)->isCompleteDefinition ())
2083
- continue ;
2084
- auto OwningClangModule = getClangOwningModule (Redeclaration,
2085
- ClangASTContext);
2086
- if (OwningClangModule)
2087
- OwningClangModule = OwningClangModule->getTopLevelModule ();
2082
+ for (auto Redeclaration : D->redecls ()) {
2083
+ if (Redeclaration == D)
2084
+ continue ;
2088
2085
2089
- if (OwningClangModule == ModuleFilter-> getClangModule ())
2090
- return true ;
2091
- }
2092
- }
2093
- }
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 ;
2094
2091
2095
- // Macros can be "redeclared" too, by putting an equivalent definition in two
2096
- // different modules.
2097
- if (ClangNode.getAsMacro ())
2098
- return true ;
2092
+ auto OwningClangModule = getClangTopLevelOwningModule (Redeclaration,
2093
+ ClangASTContext);
2094
+ if (OwningClangModule == ModuleFilter->getClangModule ())
2095
+ return true ;
2096
+ }
2099
2097
2100
2098
return false ;
2101
2099
}
@@ -2125,12 +2123,14 @@ class ClangVectorDeclConsumer : public clang::VisibleDeclConsumer {
2125
2123
2126
2124
class FilteringVisibleDeclConsumer : public swift ::VisibleDeclConsumer {
2127
2125
swift::VisibleDeclConsumer &NextConsumer;
2128
- const ClangModuleUnit *ModuleFilter = nullptr ;
2126
+ const ClangModuleUnit *ModuleFilter;
2129
2127
2130
2128
public:
2131
2129
FilteringVisibleDeclConsumer (swift::VisibleDeclConsumer &consumer,
2132
2130
const ClangModuleUnit *CMU)
2133
- : NextConsumer(consumer), ModuleFilter(CMU) {}
2131
+ : NextConsumer(consumer), ModuleFilter(CMU) {
2132
+ assert (CMU);
2133
+ }
2134
2134
2135
2135
void foundDecl (ValueDecl *VD, DeclVisibilityKind Reason) override {
2136
2136
if (isVisibleFromModule (ModuleFilter, VD))
@@ -2140,13 +2140,14 @@ class FilteringVisibleDeclConsumer : public swift::VisibleDeclConsumer {
2140
2140
2141
2141
class FilteringDeclaredDeclConsumer : public swift ::VisibleDeclConsumer {
2142
2142
swift::VisibleDeclConsumer &NextConsumer;
2143
- const ClangModuleUnit *ModuleFilter = nullptr ;
2143
+ const ClangModuleUnit *ModuleFilter;
2144
2144
2145
2145
public:
2146
2146
FilteringDeclaredDeclConsumer (swift::VisibleDeclConsumer &consumer,
2147
2147
const ClangModuleUnit *CMU)
2148
- : NextConsumer(consumer),
2149
- ModuleFilter (CMU) {}
2148
+ : NextConsumer(consumer), ModuleFilter(CMU) {
2149
+ assert (CMU);
2150
+ }
2150
2151
2151
2152
void foundDecl (ValueDecl *VD, DeclVisibilityKind Reason) override {
2152
2153
if (isDeclaredInModule (ModuleFilter, VD))
@@ -2887,10 +2888,7 @@ void ClangModuleUnit::lookupObjCMethods(
2887
2888
auto &clangCtx = clangSema.getASTContext ();
2888
2889
for (auto objcMethod : objcMethods) {
2889
2890
// Verify that this method came from this module.
2890
- auto owningClangModule = getClangOwningModule (objcMethod, clangCtx);
2891
- if (owningClangModule)
2892
- owningClangModule = owningClangModule->getTopLevelModule ();
2893
-
2891
+ auto owningClangModule = getClangTopLevelOwningModule (objcMethod, clangCtx);
2894
2892
if (owningClangModule != clangModule) continue ;
2895
2893
2896
2894
// If we found a property accessor, import the property.
0 commit comments