@@ -2646,31 +2646,44 @@ ArgumentAttrs ClangImporter::Implementation::inferDefaultArgument(
2646
2646
}
2647
2647
} else if (const clang::TypedefType *typedefType =
2648
2648
type->getAs <clang::TypedefType>()) {
2649
- clang::TypedefNameDecl *typedefDecl = typedefType->getDecl ();
2650
- // Find the next decl in the same context. If this typedef is a part of an
2651
- // NS/CF_OPTIONS declaration, the next decl will be an enum.
2652
- auto declsInContext = typedefDecl->getDeclContext ()->decls ();
2653
- auto declIter = llvm::find (declsInContext, typedefDecl);
2654
- if (declIter != declsInContext.end ())
2655
- declIter++;
2656
- if (declIter != declsInContext.end ()) {
2657
- if (auto enumDecl = dyn_cast<clang::EnumDecl>(*declIter)) {
2658
- if (auto cfOptionsTy =
2659
- nameImporter.getContext ()
2660
- .getClangModuleLoader ()
2661
- ->getTypeDefForCXXCFOptionsDefinition (enumDecl)) {
2662
- if (cfOptionsTy->getDecl () == typedefDecl) {
2663
- auto enumName = typedefDecl->getName ();
2664
- ArgumentAttrs argumentAttrs (DefaultArgumentKind::None, true ,
2665
- enumName);
2666
- for (auto word : llvm::reverse (camel_case::getWords (enumName))) {
2667
- if (camel_case::sameWordIgnoreFirstCase (word, " options" )) {
2668
- argumentAttrs.argumentKind = DefaultArgumentKind::EmptyArray;
2669
- }
2670
- }
2671
- return argumentAttrs;
2672
- }
2649
+ // Get the AvailabilityAttr that would be set from CF/NS_OPTIONS
2650
+ if (importer::isUnavailableInSwift (typedefType->getDecl (), nullptr , true )) {
2651
+ // If we've taken this branch it means we have an enum type, and it is
2652
+ // likely an integer or NSInteger that is being used by NS/CF_OPTIONS to
2653
+ // behave like a C enum in the presence of C++.
2654
+ auto enumName = typedefType->getDecl ()->getName ();
2655
+ ArgumentAttrs argumentAttrs (DefaultArgumentKind::None, true , enumName);
2656
+ auto camelCaseWords = camel_case::getWords (enumName);
2657
+ for (auto it = camelCaseWords.rbegin (); it != camelCaseWords.rend ();
2658
+ ++it) {
2659
+ auto word = *it;
2660
+ auto next = std::next (it);
2661
+ if (camel_case::sameWordIgnoreFirstCase (word, " options" )) {
2662
+ argumentAttrs.argumentKind = DefaultArgumentKind::EmptyArray;
2663
+ return argumentAttrs;
2673
2664
}
2665
+ if (camel_case::sameWordIgnoreFirstCase (word, " units" ))
2666
+ return argumentAttrs;
2667
+ if (camel_case::sameWordIgnoreFirstCase (word, " domain" ))
2668
+ return argumentAttrs;
2669
+ if (camel_case::sameWordIgnoreFirstCase (word, " action" ))
2670
+ return argumentAttrs;
2671
+ if (camel_case::sameWordIgnoreFirstCase (word, " event" ))
2672
+ return argumentAttrs;
2673
+ if (camel_case::sameWordIgnoreFirstCase (word, " events" ) &&
2674
+ next != camelCaseWords.rend () &&
2675
+ camel_case::sameWordIgnoreFirstCase (*next, " control" ))
2676
+ return argumentAttrs;
2677
+ if (camel_case::sameWordIgnoreFirstCase (word, " state" ))
2678
+ return argumentAttrs;
2679
+ if (camel_case::sameWordIgnoreFirstCase (word, " unit" ))
2680
+ return argumentAttrs;
2681
+ if (camel_case::sameWordIgnoreFirstCase (word, " position" ) &&
2682
+ next != camelCaseWords.rend () &&
2683
+ camel_case::sameWordIgnoreFirstCase (*next, " scroll" ))
2684
+ return argumentAttrs;
2685
+ if (camel_case::sameWordIgnoreFirstCase (word, " edge" ))
2686
+ return argumentAttrs;
2674
2687
}
2675
2688
}
2676
2689
}
0 commit comments