Hi aaron.ballman, rnk, rsmith,
This is a re-based version of Martin's patch from the bug report with few minor
changes by me.
I don't think that we have to implement this feature identically to msvc, but
I'm not opposed to it. I'd like to implement it in such a way that allows us to
compile MFC code that depends on it. With that said here are some open
questions.
- MSDN says that __super can't be used with using declarations but current
patch doesn't emit a diagnostic in this case. I'd say that we don't have to
because since msvc doesn't allow this there's no code written that does it.
- MSDN says that all accessible base class methods are considered during
overload resolution with best one being selected. This is different from normal
C++ rules where ordinary name lookup results in ambiguity. Current patch
doesn't implement this logic (second test case fails) but similarly to my
previous observation we might not need it as MFC doesn't use multiple
inheritance. Client's might run into this issue in their classes, but in that
case they can fix the code and move away from this extension.
What are your thoughts on this?
http://reviews.llvm.org/D4468
Files:
include/clang/AST/ASTContext.h
include/clang/AST/DataRecursiveASTVisitor.h
include/clang/AST/NestedNameSpecifier.h
include/clang/AST/RecursiveASTVisitor.h
include/clang/Basic/TokenKinds.def
include/clang/Sema/DeclSpec.h
include/clang/Sema/Sema.h
lib/AST/ASTContext.cpp
lib/AST/ASTImporter.cpp
lib/AST/ItaniumMangle.cpp
lib/AST/NestedNameSpecifier.cpp
lib/Parse/ParseExpr.cpp
lib/Parse/ParseExprCXX.cpp
lib/Parse/Parser.cpp
lib/Sema/DeclSpec.cpp
lib/Sema/SemaCXXScopeSpec.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaLookup.cpp
lib/Sema/SemaTemplate.cpp
lib/Sema/SemaType.cpp
lib/Sema/TreeTransform.h
lib/Serialization/ASTReader.cpp
lib/Serialization/ASTWriter.cpp
test/SemaCXX/MicrosoftExtensions.cpp
tools/libclang/CIndex.cpp
tools/libclang/IndexTypeSourceInfo.cpp
Index: include/clang/AST/ASTContext.h
===================================================================
--- include/clang/AST/ASTContext.h
+++ include/clang/AST/ASTContext.h
@@ -133,6 +133,7 @@
/// This set is managed by the NestedNameSpecifier class.
mutable llvm::FoldingSet<NestedNameSpecifier> NestedNameSpecifiers;
mutable NestedNameSpecifier *GlobalNestedNameSpecifier;
+ mutable NestedNameSpecifier *MsSuperNestedNameSpecifier;
friend class NestedNameSpecifier;
/// \brief A cache mapping from RecordDecls to ASTRecordLayouts.
Index: include/clang/AST/DataRecursiveASTVisitor.h
===================================================================
--- include/clang/AST/DataRecursiveASTVisitor.h
+++ include/clang/AST/DataRecursiveASTVisitor.h
@@ -623,6 +623,7 @@
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::MsSuper:
return true;
case NestedNameSpecifier::TypeSpec:
@@ -647,6 +648,7 @@
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::MsSuper:
return true;
case NestedNameSpecifier::TypeSpec:
Index: include/clang/AST/NestedNameSpecifier.h
===================================================================
--- include/clang/AST/NestedNameSpecifier.h
+++ include/clang/AST/NestedNameSpecifier.h
@@ -67,6 +67,8 @@
/// specifier as encoded within the prefix.
void* Specifier;
+ static char MsSuperSpecifierId;
+
public:
/// \brief The kind of specifier that completes this nested name
/// specifier.
@@ -83,7 +85,9 @@
/// stored as a Type*.
TypeSpecWithTemplate,
/// \brief The global specifier '::'. There is no stored value.
- Global
+ Global,
+ /// \brief The Microsoft's '__super' keyword. There is no stored value.
+ MsSuper
};
private:
@@ -143,6 +147,9 @@
/// scope.
static NestedNameSpecifier *GlobalSpecifier(const ASTContext &Context);
+ /// \brief Returns the nested name specifier representing the __super keyword.
+ static NestedNameSpecifier *MsSuperSpecifier(const ASTContext &Context);
+
/// \brief Return the prefix of this nested name specifier.
///
/// The prefix contains all of the parts of the nested name
@@ -422,6 +429,11 @@
/// nested-name-specifier '::'.
void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
+ /// \brief Turn this (empty) nested-name-specifier into the Microsoft's
+ /// '__super' specifier.
+ void MakeMsSuper(ASTContext &Context, SourceLocation MsSuperLoc,
+ SourceLocation ColonColonLoc);
+
/// \brief Make a new nested-name-specifier from incomplete source-location
/// information.
///
Index: include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -689,6 +689,7 @@
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::MsSuper:
return true;
case NestedNameSpecifier::TypeSpec:
@@ -713,7 +714,8 @@
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
- return true;
+ case NestedNameSpecifier::MsSuper:
+ return true;
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate:
Index: include/clang/Basic/TokenKinds.def
===================================================================
--- include/clang/Basic/TokenKinds.def
+++ include/clang/Basic/TokenKinds.def
@@ -459,6 +459,7 @@
KEYWORD(__thiscall , KEYALL)
KEYWORD(__forceinline , KEYMS)
KEYWORD(__unaligned , KEYMS)
+KEYWORD(__super , KEYMS)
// OpenCL address space qualifiers
KEYWORD(__global , KEYOPENCL)
Index: include/clang/Sema/DeclSpec.h
===================================================================
--- include/clang/Sema/DeclSpec.h
+++ include/clang/Sema/DeclSpec.h
@@ -141,6 +141,11 @@
/// nested-name-specifier '::'.
void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
+ /// \brief Turn this (empty) nested-name-specifier into the Microsoft's
+ /// '__super' specifier.
+ void MakeMsSuper(ASTContext &Context, SourceLocation MsSuperLoc,
+ SourceLocation ColonColonLoc);
+
/// \brief Make a new nested-name-specifier from incomplete source-location
/// information.
///
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -2578,6 +2578,8 @@
bool AllowBuiltinCreation = false);
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
bool InUnqualifiedLookup = false);
+ bool LookupInBaseClasses(LookupResult &R, CXXRecordDecl *LookupRec,
+ bool InUnqualifiedLookup = false);
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS,
bool AllowBuiltinCreation = false,
bool EnteringContext = false);
@@ -3354,6 +3356,9 @@
CorrectionCandidateCallback *CCC = nullptr,
bool IsInlineAsmIdentifier = false);
+ ExprResult ActOnMsSuperIdExpression(Scope *S, CXXScopeSpec &SS,
+ const DeclarationNameInfo &NameInfo);
+
void DecomposeUnqualifiedId(const UnqualifiedId &Id,
TemplateArgumentListInfo &Buffer,
DeclarationNameInfo &NameInfo,
@@ -4447,6 +4452,9 @@
bool ActOnCXXGlobalScopeSpecifier(Scope *S, SourceLocation CCLoc,
CXXScopeSpec &SS);
+ bool ActOnCXXMsSuperScopeSpecifier(Scope *S, SourceLocation SuperLoc,
+ SourceLocation CCLoc, CXXScopeSpec &SS);
+
bool isAcceptableNestedNameSpecifier(const NamedDecl *SD);
NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS);
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -730,6 +730,7 @@
DependentTemplateSpecializationTypes(this_()),
SubstTemplateTemplateParmPacks(this_()),
GlobalNestedNameSpecifier(nullptr),
+ MsSuperNestedNameSpecifier(nullptr),
Int128Decl(nullptr), UInt128Decl(nullptr), Float128StubDecl(nullptr),
BuiltinVaListDecl(nullptr),
ObjCIdDecl(nullptr), ObjCSelDecl(nullptr), ObjCClassDecl(nullptr),
@@ -4190,7 +4191,8 @@
}
case NestedNameSpecifier::Global:
- // The global specifier is canonical and unique.
+ case NestedNameSpecifier::MsSuper:
+ // Both the global and the __super specifier are canonical and unique.
return NNS;
}
Index: lib/AST/ASTImporter.cpp
===================================================================
--- lib/AST/ASTImporter.cpp
+++ lib/AST/ASTImporter.cpp
@@ -4760,6 +4760,9 @@
case NestedNameSpecifier::Global:
return NestedNameSpecifier::GlobalSpecifier(ToContext);
+ case NestedNameSpecifier::MsSuper:
+ return NestedNameSpecifier::MsSuperSpecifier(ToContext);
+
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate: {
QualType T = Import(QualType(FromNNS->getAsType(), 0u));
Index: lib/AST/ItaniumMangle.cpp
===================================================================
--- lib/AST/ItaniumMangle.cpp
+++ lib/AST/ItaniumMangle.cpp
@@ -801,6 +801,9 @@
// <base-unresolved-name>
switch (qualifier->getKind()) {
+ case NestedNameSpecifier::MsSuper:
+ // nothing
+ return;
case NestedNameSpecifier::Global:
Out << "gs";
@@ -1456,6 +1459,7 @@
void CXXNameMangler::manglePrefix(NestedNameSpecifier *qualifier) {
switch (qualifier->getKind()) {
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::MsSuper:
// nothing
return;
Index: lib/AST/NestedNameSpecifier.cpp
===================================================================
--- lib/AST/NestedNameSpecifier.cpp
+++ lib/AST/NestedNameSpecifier.cpp
@@ -24,6 +24,8 @@
using namespace clang;
+char NestedNameSpecifier::MsSuperSpecifierId;
+
NestedNameSpecifier *
NestedNameSpecifier::FindOrInsert(const ASTContext &Context,
const NestedNameSpecifier &Mockup) {
@@ -118,10 +120,25 @@
return Context.GlobalNestedNameSpecifier;
}
+NestedNameSpecifier *
+NestedNameSpecifier::MsSuperSpecifier(const ASTContext &Context) {
+ if (!Context.MsSuperNestedNameSpecifier) {
+ Context.MsSuperNestedNameSpecifier =
+ new (Context, llvm::alignOf<NestedNameSpecifier>())
+ NestedNameSpecifier();
+ Context.MsSuperNestedNameSpecifier->Specifier = &MsSuperSpecifierId;
+ }
+
+ return Context.MsSuperNestedNameSpecifier;
+}
+
NestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const {
if (!Specifier)
return Global;
+ if (Specifier == &MsSuperSpecifierId)
+ return MsSuper;
+
switch (Prefix.getInt()) {
case StoredIdentifier:
return Identifier;
@@ -170,6 +187,7 @@
case Namespace:
case NamespaceAlias:
case Global:
+ case MsSuper:
return false;
case TypeSpec:
@@ -191,6 +209,7 @@
case Namespace:
case NamespaceAlias:
case Global:
+ case MsSuper:
return false;
case TypeSpec:
@@ -209,6 +228,7 @@
case Namespace:
case NamespaceAlias:
case Global:
+ case MsSuper:
return false;
case TypeSpec:
@@ -246,6 +266,10 @@
case Global:
break;
+ case MsSuper:
+ OS << "__super";
+ break;
+
case TypeSpecWithTemplate:
OS << "template ";
// Fall through to print the type.
@@ -304,6 +328,7 @@
case NestedNameSpecifier::Identifier:
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
+ case NestedNameSpecifier::MsSuper:
// The location of the identifier or namespace name.
Length += sizeof(unsigned);
break;
@@ -369,6 +394,7 @@
case NestedNameSpecifier::Identifier:
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
+ case NestedNameSpecifier::MsSuper:
return SourceRange(LoadSourceLocation(Data, Offset),
LoadSourceLocation(Data, Offset + sizeof(unsigned)));
@@ -556,6 +582,17 @@
SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
}
+void NestedNameSpecifierLocBuilder::MakeMsSuper(ASTContext &Context,
+ SourceLocation MsSuperLoc,
+ SourceLocation ColonColonLoc) {
+ assert(!Representation && "Already have a nested-name-specifier!?");
+ Representation = NestedNameSpecifier::MsSuperSpecifier(Context);
+
+ // Push source-location info into the buffer.
+ SaveSourceLocation(MsSuperLoc, Buffer, BufferSize, BufferCapacity);
+ SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
+}
+
void NestedNameSpecifierLocBuilder::MakeTrivial(ASTContext &Context,
NestedNameSpecifier *Qualifier,
SourceRange R) {
@@ -573,6 +610,7 @@
case NestedNameSpecifier::Identifier:
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
+ case NestedNameSpecifier::MsSuper:
SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity);
break;
Index: lib/Parse/ParseExpr.cpp
===================================================================
--- lib/Parse/ParseExpr.cpp
+++ lib/Parse/ParseExpr.cpp
@@ -695,6 +695,7 @@
assert(Tok.isNot(tok::kw_decltype));
return ParseCastExpression(isUnaryExpression, isAddressOfOperand);
+ case tok::kw___super:
case tok::identifier: { // primary-expression: identifier
// unqualified-id: identifier
// constant: enumeration-constant
Index: lib/Parse/ParseExprCXX.cpp
===================================================================
--- lib/Parse/ParseExprCXX.cpp
+++ lib/Parse/ParseExprCXX.cpp
@@ -224,6 +224,16 @@
CheckForLParenAfterColonColon();
HasScopeSpecifier = true;
+ } else if (Tok.is(tok::kw___super)) {
+ SourceLocation SuperLoc = ConsumeToken();
+ if (Tok.isNot(tok::coloncolon)) {
+ // XXX: Diagnose
+ return true;
+ }
+ if (Actions.ActOnCXXMsSuperScopeSpecifier(getCurScope(), SuperLoc,
+ ConsumeToken(), SS))
+ return true;
+ HasScopeSpecifier = true;
}
bool CheckForDestructor = false;
Index: lib/Parse/Parser.cpp
===================================================================
--- lib/Parse/Parser.cpp
+++ lib/Parse/Parser.cpp
@@ -1484,7 +1484,8 @@
bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext, bool NeedType) {
assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon)
|| Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope)
- || Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id))
+ || Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id)
+ || Tok.is(tok::kw___super))
&& "Cannot be a type or scope token!");
if (Tok.is(tok::kw_typename)) {
Index: lib/Sema/DeclSpec.cpp
===================================================================
--- lib/Sema/DeclSpec.cpp
+++ lib/Sema/DeclSpec.cpp
@@ -113,6 +113,17 @@
"NestedNameSpecifierLoc range computation incorrect");
}
+void CXXScopeSpec::MakeMsSuper(ASTContext &Context, SourceLocation MsSuperLoc,
+ SourceLocation ColonColonLoc) {
+ Builder.MakeMsSuper(Context, MsSuperLoc, ColonColonLoc);
+
+ Range.setBegin(MsSuperLoc);
+ Range.setEnd(ColonColonLoc);
+
+ assert(Range == Builder.getSourceRange() &&
+ "NestedNameSpecifierLoc range computation incorrect");
+}
+
void CXXScopeSpec::MakeTrivial(ASTContext &Context,
NestedNameSpecifier *Qualifier, SourceRange R) {
Builder.MakeTrivial(Context, Qualifier, R);
Index: lib/Sema/SemaCXXScopeSpec.cpp
===================================================================
--- lib/Sema/SemaCXXScopeSpec.cpp
+++ lib/Sema/SemaCXXScopeSpec.cpp
@@ -148,11 +148,21 @@
case NestedNameSpecifier::Global:
return Context.getTranslationUnitDecl();
+
+ case NestedNameSpecifier::MsSuper:
+ return nullptr;
}
llvm_unreachable("Invalid NestedNameSpecifier::Kind!");
}
+bool Sema::ActOnCXXMsSuperScopeSpecifier(Scope *S, SourceLocation SuperLoc,
+ SourceLocation CCLoc,
+ CXXScopeSpec &SS) {
+ SS.MakeMsSuper(Context, SuperLoc, CCLoc);
+ return false;
+}
+
bool Sema::isDependentScopeSpecifier(const CXXScopeSpec &SS) {
if (!SS.isSet() || SS.isInvalid())
return false;
@@ -936,6 +946,7 @@
switch (Qualifier->getKind()) {
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::MsSuper:
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
// These are always namespace scopes. We never want to enter a
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -1943,6 +1943,24 @@
return true;
}
+ExprResult Sema::ActOnMsSuperIdExpression(Scope *S, CXXScopeSpec &SS,
+ const DeclarationNameInfo &NameInfo) {
+ Scope *FnScope = S->getFnParent();
+ CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnScope->getEntity());
+ CXXRecordDecl *Rec = Method->getParent();
+ LookupResult R(*this, NameInfo, LookupOrdinaryName);
+ if (LookupInBaseClasses(R, Rec)) {
+ // if (R.getAmbiguityKind() == LookupResult::AmbiguousBaseSubobjectTypes) {
+ // Do overload resolution?
+ // }
+
+ return BuildImplicitMemberExpr(SS, SourceLocation(), R, nullptr, true);
+ }
+
+ Diag(R.getNameLoc(), diag::err_no_member) << R.getLookupName() << Rec;
+ return ExprError();
+}
+
/// In Microsoft mode, if we are inside a template class whose parent class has
/// dependent base classes, and we can't resolve an unqualified identifier, then
/// assume the identifier is a member of a dependent base class. We can only
@@ -2010,6 +2028,10 @@
const TemplateArgumentListInfo *TemplateArgs;
DecomposeUnqualifiedId(Id, TemplateArgsBuffer, NameInfo, TemplateArgs);
+ const NestedNameSpecifier *NNS = SS.getScopeRep();
+ if (NNS && NNS->getKind() == NestedNameSpecifier::MsSuper)
+ return ActOnMsSuperIdExpression(S, SS, NameInfo);
+
DeclarationName Name = NameInfo.getName();
IdentifierInfo *II = Name.getAsIdentifierInfo();
SourceLocation NameLoc = NameInfo.getLoc();
@@ -2506,7 +2528,8 @@
// x = 17; // error: ambiguous base subobjects
// Derived1::x = 17; // okay, pick the Base subobject of Derived1
// }
- if (Qualifier && Qualifier->getAsType()) {
+ if (Qualifier && Qualifier->getAsType() &&
+ Qualifier->getKind() != NestedNameSpecifier::MsSuper) {
QualType QType = QualType(Qualifier->getAsType(), 0);
assert(QType->isRecordType() && "lookup done with non-record type");
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -69,6 +69,7 @@
case NestedNameSpecifier::Global:
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
+ case NestedNameSpecifier::MsSuper:
llvm_unreachable("Nested name specifier is not a type for inheriting ctor");
}
@@ -356,6 +357,7 @@
case NestedNameSpecifier::Global:
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
+ case NestedNameSpecifier::MsSuper:
return false;
}
Index: lib/Sema/SemaLookup.cpp
===================================================================
--- lib/Sema/SemaLookup.cpp
+++ lib/Sema/SemaLookup.cpp
@@ -1638,6 +1638,11 @@
if (!LookupRec || !LookupRec->getDefinition())
return false;
+ return LookupInBaseClasses(R, LookupRec, InUnqualifiedLookup);
+}
+
+bool Sema::LookupInBaseClasses(LookupResult &R, CXXRecordDecl *LookupRec,
+ bool InUnqualifiedLookup) {
// If we're performing qualified name lookup into a dependent class,
// then we are actually looking into a current instantiation. If we have any
// dependent base classes, then we either have to delay lookup until
@@ -3314,6 +3319,7 @@
break;
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::MsSuper:
return;
}
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -4124,6 +4124,7 @@
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::MsSuper:
return false;
case NestedNameSpecifier::TypeSpec:
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -3019,6 +3019,7 @@
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::MsSuper:
llvm_unreachable("Nested-name-specifier must name a type");
case NestedNameSpecifier::TypeSpec:
@@ -3715,6 +3716,7 @@
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::MsSuper:
llvm_unreachable("Nested-name-specifier must name a type");
}
Index: lib/Sema/TreeTransform.h
===================================================================
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -3064,6 +3064,12 @@
SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc());
break;
+ case NestedNameSpecifier::MsSuper:
+ // There is no meaningful transformation that one could perform on the
+ // __super specifier.
+ SS.MakeMsSuper(SemaRef.Context, Q.getBeginLoc(), Q.getEndLoc());
+ break;
+
case NestedNameSpecifier::TypeSpecWithTemplate:
case NestedNameSpecifier::TypeSpec: {
TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType,
Index: lib/Serialization/ASTReader.cpp
===================================================================
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -7800,6 +7800,12 @@
// No associated value, and there can't be a prefix.
break;
}
+
+ case NestedNameSpecifier::MsSuper: {
+ NNS = NestedNameSpecifier::MsSuperSpecifier(Context);
+ break;
+ }
+
}
Prev = NNS;
}
@@ -7856,6 +7862,13 @@
Builder.MakeGlobal(Context, ColonColonLoc);
break;
}
+
+ case NestedNameSpecifier::MsSuper: {
+ SourceRange Range = ReadSourceRange(F, Record, Idx);
+ Builder.MakeMsSuper(Context, Range.getBegin(), Range.getEnd());
+ break;
+ }
+
}
}
Index: lib/Serialization/ASTWriter.cpp
===================================================================
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -5048,6 +5048,7 @@
break;
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::MsSuper:
// Don't need to write an associated value.
break;
}
@@ -5097,6 +5098,7 @@
break;
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::MsSuper:
AddSourceLocation(NNS.getLocalSourceRange().getEnd(), Record);
break;
}
Index: test/SemaCXX/MicrosoftExtensions.cpp
===================================================================
--- test/SemaCXX/MicrosoftExtensions.cpp
+++ test/SemaCXX/MicrosoftExtensions.cpp
@@ -421,3 +421,24 @@
_Static_assert(__alignof(s1) == 8, "");
_Static_assert(__alignof(s2) == 4, "");
}
+
+namespace super {
+struct A {
+ void foo(int) {}
+};
+
+struct B {
+ void foo(char) {}
+};
+
+struct C : A {
+ void foo(int i) {
+ __super::foo(i);
+ }
+};
+
+struct D : A, B {
+ void foo() {
+ __super::foo('x');
+ }
+}
Index: tools/libclang/CIndex.cpp
===================================================================
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -1256,6 +1256,7 @@
case NestedNameSpecifier::TypeSpecWithTemplate:
case NestedNameSpecifier::Global:
case NestedNameSpecifier::Identifier:
+ case NestedNameSpecifier::MsSuper:
break;
}
@@ -1297,6 +1298,7 @@
case NestedNameSpecifier::Global:
case NestedNameSpecifier::Identifier:
+ case NestedNameSpecifier::MsSuper:
break;
}
}
Index: tools/libclang/IndexTypeSourceInfo.cpp
===================================================================
--- tools/libclang/IndexTypeSourceInfo.cpp
+++ tools/libclang/IndexTypeSourceInfo.cpp
@@ -129,6 +129,7 @@
switch (NNS.getNestedNameSpecifier()->getKind()) {
case NestedNameSpecifier::Identifier:
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::MsSuper:
break;
case NestedNameSpecifier::Namespace:
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits