[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