@@ -867,45 +867,6 @@ void Sema::ProcessAPINotes(Decl *D) {
867
867
return ;
868
868
}
869
869
870
- // Tags
871
- if (auto Tag = dyn_cast<TagDecl>(D)) {
872
- std::string LookupName = Tag->getName ().str ();
873
-
874
- // Use the source location to discern if this Tag is an OPTIONS macro.
875
- // For now we would like to limit this trick of looking up the APINote tag
876
- // using the EnumDecl's QualType in the case where the enum is anonymous.
877
- // This is only being used to support APINotes lookup for C++ NS/CF_OPTIONS
878
- // when C++-Interop is enabled.
879
- std::string MacroName =
880
- LookupName.empty () && Tag->getOuterLocStart ().isMacroID ()
881
- ? clang::Lexer::getImmediateMacroName (
882
- Tag->getOuterLocStart (),
883
- Tag->getASTContext ().getSourceManager (), LangOpts)
884
- .str ()
885
- : " " ;
886
-
887
- if (LookupName.empty () && isa<clang::EnumDecl>(Tag) &&
888
- (MacroName == " CF_OPTIONS" || MacroName == " NS_OPTIONS" ||
889
- MacroName == " OBJC_OPTIONS" || MacroName == " SWIFT_OPTIONS" )) {
890
-
891
- clang::QualType T = llvm::cast<clang::EnumDecl>(Tag)->getIntegerType ();
892
- LookupName = clang::QualType::getAsString (
893
- T.split (), getASTContext ().getPrintingPolicy ());
894
- }
895
-
896
- for (auto Reader : APINotes.findAPINotes (D->getLocation ())) {
897
- auto Info = Reader->lookupTag (LookupName);
898
- ProcessVersionedAPINotes (*this , Tag, Info);
899
- }
900
-
901
- for (auto Member : Tag->decls ()) {
902
- if (isa<CXXMethodDecl>(Member))
903
- ProcessAPINotes (Member);
904
- }
905
-
906
- return ;
907
- }
908
-
909
870
// Typedefs
910
871
if (auto Typedef = dyn_cast<TypedefNameDecl>(D)) {
911
872
for (auto Reader : APINotes.findAPINotes (D->getLocation ())) {
@@ -917,22 +878,84 @@ void Sema::ProcessAPINotes(Decl *D) {
917
878
}
918
879
}
919
880
881
+ // Tags
882
+ if (auto Tag = dyn_cast<TagDecl>(D)) {
883
+ std::string LookupName = Tag->getName ().str ();
884
+
885
+ auto parent = Tag->getParent ();
886
+ while (isa<clang::CXXRecordDecl>(parent) ||
887
+ isa<clang::NamespaceDecl>(parent)) {
888
+ if (auto Record = dyn_cast<clang::CXXRecordDecl>(parent)) {
889
+ LookupName = Record->getNameAsString () + " ." + LookupName;
890
+ } else if (auto Namespace = dyn_cast<clang::NamespaceDecl>(parent)) {
891
+ LookupName = Namespace->getNameAsString () + " ." + LookupName;
892
+ }
893
+
894
+ parent = parent->getParent ();
895
+ }
896
+
897
+ // Use the source location to discern if this Tag is an OPTIONS macro.
898
+ // For now we would like to limit this trick of looking up the APINote tag
899
+ // using the EnumDecl's QualType in the case where the enum is anonymous.
900
+ // This is only being used to support APINotes lookup for C++ NS/CF_OPTIONS
901
+ // when C++-Interop is enabled.
902
+ std::string MacroName =
903
+ LookupName.empty () && Tag->getOuterLocStart ().isMacroID ()
904
+ ? clang::Lexer::getImmediateMacroName (
905
+ Tag->getOuterLocStart (),
906
+ Tag->getASTContext ().getSourceManager (), LangOpts)
907
+ .str ()
908
+ : " " ;
909
+
910
+ if (LookupName.empty () && isa<clang::EnumDecl>(Tag) &&
911
+ (MacroName == " CF_OPTIONS" || MacroName == " NS_OPTIONS" ||
912
+ MacroName == " OBJC_OPTIONS" || MacroName == " SWIFT_OPTIONS" )) {
913
+
914
+ clang::QualType T = llvm::cast<clang::EnumDecl>(Tag)->getIntegerType ();
915
+ LookupName = clang::QualType::getAsString (
916
+ T.split (), getASTContext ().getPrintingPolicy ());
917
+ }
918
+
919
+ for (auto Reader : APINotes.findAPINotes (D->getLocation ())) {
920
+ auto Info = Reader->lookupTag (LookupName);
921
+ ProcessVersionedAPINotes (*this , Tag, Info);
922
+ }
923
+
924
+ for (auto Member : Tag->decls ()) {
925
+ ProcessAPINotes (Member);
926
+ }
927
+
928
+ return ;
929
+ }
930
+
920
931
if (auto Method = dyn_cast<CXXMethodDecl>(D)) {
921
932
for (auto Reader : APINotes.findAPINotes (D->getLocation ())) {
922
933
auto Name = Method->getNameAsString ();
923
- auto parent = Method->getParent ();
924
- std::string parents = parent->getNameAsString ();
925
- while (isa<clang::CXXRecordDecl>(parent->getParent ())) {
926
- parent = cast<clang::CXXRecordDecl>(parent->getParent ());
927
- parents += " ." + parent->getNameAsString ();
934
+ const clang::DeclContext *parent = Method->getParent ();
935
+ while (isa<clang::CXXRecordDecl>(parent) ||
936
+ isa<clang::NamespaceDecl>(parent)) {
937
+ if (auto Record = dyn_cast<clang::CXXRecordDecl>(parent)) {
938
+ Name = Record->getNameAsString () + " ." + Name;
939
+ } else if (auto Namespace = dyn_cast<clang::NamespaceDecl>(parent)) {
940
+ Name = Namespace->getNameAsString () + " ." + Name;
941
+ }
942
+
943
+ parent = parent->getParent ();
928
944
}
929
945
930
- auto FullName = parents + " ." + Name;
931
- auto Info = Reader->lookupMemberFunction (FullName);
946
+ auto Info = Reader->lookupMemberFunction (Name);
932
947
ProcessVersionedAPINotes (*this , Method, Info);
933
948
}
934
949
}
935
950
951
+ if (auto Namespace = dyn_cast<NamespaceDecl>(D)) {
952
+ for (auto Redecl : Namespace->redecls ()) {
953
+ for (auto Member : Redecl->decls ()) {
954
+ ProcessAPINotes (Member);
955
+ }
956
+ }
957
+ }
958
+
936
959
// Enumerators.
937
960
if (D->getDeclContext ()->getRedeclContext ()->isFileContext () ||
938
961
D->getDeclContext ()->getRedeclContext ()->isExternCContext ()) {
0 commit comments