[PATCH] PR13236 - Microsoft compatibility: support __super specifier to access members of base classes

Reid Kleckner rnk at google.com
Thu Sep 4 14:34:39 PDT 2014


================
Comment at: include/clang/AST/DataRecursiveASTVisitor.h:627
@@ -626,2 +626,3 @@
   case NestedNameSpecifier::Global:
+  case NestedNameSpecifier::MsSuper:
     return true;
----------------
I would drop the "Ms" prefix, and just have a NestedNameSpecifier::Super enumerator. If gcc adds an incompatible super-like NNS we can cross that bridge when we get there.

================
Comment at: include/clang/Sema/Sema.h:2611
@@ -2610,2 +2610,3 @@
                                      = NotForRedeclaration);
+  void LookupInMsSuper(LookupResult &R, CXXRecordDecl *Class);
 
----------------
"LookupInSuper"

================
Comment at: include/clang/Sema/Sema.h:4493
@@ +4492,3 @@
+  /// \returns true if an error occurred, false otherwise.
+  bool ActOnMsSuperScopeSpecifier(Scope *S, SourceLocation SuperLoc,
+                                  SourceLocation ColonColonLoc,
----------------
"ActOnSuperSpecifier"

================
Comment at: lib/AST/ASTContext.cpp:4199
@@ -4199,1 +4198,3 @@
+  case NestedNameSpecifier::MsSuper:
+    // The global specifier and __super specifer are canonical and unique.
     return NNS;
----------------
The super specifier isn't unique. I think we can canonicalize them similarly to how namespace specifiers are canonicalized: get the original CXXRecordDecl.

Unfortunately, I'm not sure how to test this.

================
Comment at: lib/AST/ItaniumMangle.cpp:1462
@@ -1458,2 +1461,3 @@
   case NestedNameSpecifier::Global:
+  case NestedNameSpecifier::MsSuper:
     // nothing
----------------
This should be an assertion. We can't mangle __super, it is dependent.

================
Comment at: lib/Sema/SemaCXXScopeSpec.cpp:256-259
@@ +255,6 @@
+  CXXRecordDecl *RD = nullptr;
+  if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(S->getEntity()))
+    RD = MD->getParent();
+  else
+    RD = dyn_cast<CXXRecordDecl>(S->getEntity());
+
----------------
I wonder if there is a better way to find the enclosing class scope.  What about this test case:
  struct B { typedef int T; };
  struct A : B { enum C { X = sizeof(__super::T) }; };

================
Comment at: test/SemaCXX/MicrosoftExtensions.cpp:404
@@ +403,3 @@
+struct Errors {
+  using __super::foo; // expected-error {{__super cannot be used}}
+  __super::XXX x; // expected-error {{invalid use of '__super'}} expected-error {{expected}}
----------------
"with a using declaration" :)

================
Comment at: test/SemaCXX/MicrosoftExtensions.cpp:512
@@ +511,3 @@
+  }
+};
+
----------------
Can you add some tests with more nested DeclContexts? enums form a DeclContext, so those are handy and can go inside records and functions.

You can also use inner classes like:
  struct Base { typedef int T; };
  struct Outer { struct Inner : Base { static const int x = sizeof(__super::T); }; };

I bet __super also misbehaves inside a lambda. I won't insist on actually handling this case in this patch, but we should at least have test coverage that shows we don't crash.

http://reviews.llvm.org/D4468






More information about the cfe-commits mailing list