Skip to content

Commit 5dc620b

Browse files
author
Martin Vejnar
committed
Basis support for MS __super. No templates, diagnostics, result set
merging.
1 parent 6c58b6b commit 5dc620b

18 files changed

+137
-5
lines changed

include/clang/AST/ASTContext.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
138138
/// This set is managed by the NestedNameSpecifier class.
139139
mutable llvm::FoldingSet<NestedNameSpecifier> NestedNameSpecifiers;
140140
mutable NestedNameSpecifier *GlobalNestedNameSpecifier;
141+
mutable NestedNameSpecifier *MsSuperNestedNameSpecifier;
141142
friend class NestedNameSpecifier;
142143

143144
/// ASTRecordLayouts - A cache mapping from RecordDecls to ASTRecordLayouts.

include/clang/AST/NestedNameSpecifier.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ class NestedNameSpecifier : public llvm::FoldingSetNode {
6767
/// specifier as encoded within the prefix.
6868
void* Specifier;
6969

70+
static char MsSuperSpecifierId;
71+
7072
public:
7173
/// \brief The kind of specifier that completes this nested name
7274
/// specifier.
@@ -83,7 +85,9 @@ class NestedNameSpecifier : public llvm::FoldingSetNode {
8385
/// stored as a Type*.
8486
TypeSpecWithTemplate,
8587
/// \brief The global specifier '::'. There is no stored value.
86-
Global
88+
Global,
89+
/// \brief The Microsoft's '__super' keyword. There is no stored value.
90+
MsSuper
8791
};
8892

8993
private:
@@ -143,6 +147,9 @@ class NestedNameSpecifier : public llvm::FoldingSetNode {
143147
/// scope.
144148
static NestedNameSpecifier *GlobalSpecifier(const ASTContext &Context);
145149

150+
/// \brief Returns the nested name specifier representing the __super keyword.
151+
static NestedNameSpecifier *MsSuperSpecifier(const ASTContext &Context);
152+
146153
/// \brief Return the prefix of this nested name specifier.
147154
///
148155
/// The prefix contains all of the parts of the nested name
@@ -417,6 +424,10 @@ class NestedNameSpecifierLocBuilder {
417424
/// nested-name-specifier '::'.
418425
void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
419426

427+
/// \brief Turn this (empty) nested-name-specifier into the Microsoft's
428+
/// '__super' specifier.
429+
void MakeMsSuper(ASTContext &Context, SourceLocation MsSuperLoc, SourceLocation ColonColonLoc);
430+
420431
/// \brief Make a new nested-name-specifier from incomplete source-location
421432
/// information.
422433
///

include/clang/AST/RecursiveASTVisitor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,7 @@ bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
636636
case NestedNameSpecifier::Namespace:
637637
case NestedNameSpecifier::NamespaceAlias:
638638
case NestedNameSpecifier::Global:
639+
case NestedNameSpecifier::MsSuper:
639640
return true;
640641

641642
case NestedNameSpecifier::TypeSpec:
@@ -660,6 +661,7 @@ bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
660661
case NestedNameSpecifier::Namespace:
661662
case NestedNameSpecifier::NamespaceAlias:
662663
case NestedNameSpecifier::Global:
664+
case NestedNameSpecifier::MsSuper:
663665
return true;
664666

665667
case NestedNameSpecifier::TypeSpec:

include/clang/Basic/TokenKinds.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,7 @@ KEYWORD(__fastcall , KEYALL)
424424
KEYWORD(__thiscall , KEYALL)
425425
KEYWORD(__forceinline , KEYALL)
426426
KEYWORD(__unaligned , KEYMS)
427+
KEYWORD(__super , KEYMS)
427428

428429
// OpenCL-specific keywords
429430
KEYWORD(__kernel , KEYOPENCL)

include/clang/Sema/DeclSpec.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ class CXXScopeSpec {
141141
/// nested-name-specifier '::'.
142142
void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
143143

144+
/// \brief Turn this (empty) nested-name-specifier into the Microsoft's
145+
/// '__super' specifier.
146+
void MakeMsSuper(ASTContext &Context, SourceLocation MsSuperLoc, SourceLocation ColonColonLoc);
147+
144148
/// \brief Make a new nested-name-specifier from incomplete source-location
145149
/// information.
146150
///

include/clang/Sema/Sema.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2091,6 +2091,8 @@ class Sema {
20912091
bool AllowBuiltinCreation = false);
20922092
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
20932093
bool InUnqualifiedLookup = false);
2094+
bool LookupInBaseClasses(LookupResult &R, CXXRecordDecl *LookupRec,
2095+
bool InUnqualifiedLookup = false);
20942096
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS,
20952097
bool AllowBuiltinCreation = false,
20962098
bool EnteringContext = false);
@@ -2759,6 +2761,9 @@ class Sema {
27592761
bool HasTrailingLParen, bool IsAddressOfOperand,
27602762
CorrectionCandidateCallback *CCC = 0);
27612763

2764+
ExprResult ActOnMsSuperIdExpression(Scope *S, const DeclarationNameInfo &NameInfo,
2765+
const TemplateArgumentListInfo *TemplateArgs);
2766+
27622767
void DecomposeUnqualifiedId(const UnqualifiedId &Id,
27632768
TemplateArgumentListInfo &Buffer,
27642769
DeclarationNameInfo &NameInfo,
@@ -3841,6 +3846,9 @@ class Sema {
38413846
bool ActOnCXXGlobalScopeSpecifier(Scope *S, SourceLocation CCLoc,
38423847
CXXScopeSpec &SS);
38433848

3849+
bool ActOnCXXMsSuperScopeSpecifier(Scope *S, SourceLocation SuperLoc,
3850+
SourceLocation CCLoc, CXXScopeSpec &SS);
3851+
38443852
bool isAcceptableNestedNameSpecifier(NamedDecl *SD);
38453853
NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS);
38463854

lib/AST/ASTContext.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ ASTContext::ASTContext(LangOptions& LOpts, SourceManager &SM,
329329
DependentTemplateSpecializationTypes(this_()),
330330
SubstTemplateTemplateParmPacks(this_()),
331331
GlobalNestedNameSpecifier(0),
332+
MsSuperNestedNameSpecifier(0),
332333
Int128Decl(0), UInt128Decl(0),
333334
BuiltinVaListDecl(0),
334335
ObjCIdDecl(0), ObjCSelDecl(0), ObjCClassDecl(0), ObjCProtocolClassDecl(0),
@@ -3502,7 +3503,8 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
35023503
}
35033504

35043505
case NestedNameSpecifier::Global:
3505-
// The global specifier is canonical and unique.
3506+
case NestedNameSpecifier::MsSuper:
3507+
// Bot the global and the __super specifier are canonical and unique.
35063508
return NNS;
35073509
}
35083510

lib/AST/ASTImporter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4331,6 +4331,9 @@ NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
43314331
case NestedNameSpecifier::Global:
43324332
return NestedNameSpecifier::GlobalSpecifier(ToContext);
43334333

4334+
case NestedNameSpecifier::MsSuper:
4335+
return NestedNameSpecifier::MsSuperSpecifier(ToContext);
4336+
43344337
case NestedNameSpecifier::TypeSpec:
43354338
case NestedNameSpecifier::TypeSpecWithTemplate: {
43364339
QualType T = Import(QualType(FromNNS->getAsType(), 0u));

lib/AST/NestedNameSpecifier.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323

2424
using namespace clang;
2525

26+
char NestedNameSpecifier::MsSuperSpecifierId;
27+
2628
NestedNameSpecifier *
2729
NestedNameSpecifier::FindOrInsert(const ASTContext &Context,
2830
const NestedNameSpecifier &Mockup) {
@@ -111,10 +113,22 @@ NestedNameSpecifier::GlobalSpecifier(const ASTContext &Context) {
111113
return Context.GlobalNestedNameSpecifier;
112114
}
113115

116+
NestedNameSpecifier *
117+
NestedNameSpecifier::MsSuperSpecifier(const ASTContext &Context) {
118+
if (!Context.MsSuperNestedNameSpecifier) {
119+
Context.MsSuperNestedNameSpecifier = new (Context, 4) NestedNameSpecifier();
120+
Context.MsSuperNestedNameSpecifier->Specifier = &MsSuperSpecifierId;
121+
}
122+
return Context.MsSuperNestedNameSpecifier;
123+
}
124+
114125
NestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const {
115126
if (Specifier == 0)
116127
return Global;
117128

129+
if (Specifier == &MsSuperSpecifierId)
130+
return MsSuper;
131+
118132
switch (Prefix.getInt()) {
119133
case StoredIdentifier:
120134
return Identifier;
@@ -163,6 +177,7 @@ bool NestedNameSpecifier::isDependent() const {
163177
case Namespace:
164178
case NamespaceAlias:
165179
case Global:
180+
case MsSuper:
166181
return false;
167182

168183
case TypeSpec:
@@ -184,6 +199,7 @@ bool NestedNameSpecifier::isInstantiationDependent() const {
184199
case Namespace:
185200
case NamespaceAlias:
186201
case Global:
202+
case MsSuper:
187203
return false;
188204

189205
case TypeSpec:
@@ -202,6 +218,7 @@ bool NestedNameSpecifier::containsUnexpandedParameterPack() const {
202218
case Namespace:
203219
case NamespaceAlias:
204220
case Global:
221+
case MsSuper:
205222
return false;
206223

207224
case TypeSpec:
@@ -239,6 +256,10 @@ NestedNameSpecifier::print(raw_ostream &OS,
239256
case Global:
240257
break;
241258

259+
case MsSuper:
260+
OS << "__super";
261+
break;
262+
242263
case TypeSpecWithTemplate:
243264
OS << "template ";
244265
// Fall through to print the type.
@@ -301,6 +322,7 @@ NestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier *Qualifier) {
301322
case NestedNameSpecifier::Identifier:
302323
case NestedNameSpecifier::Namespace:
303324
case NestedNameSpecifier::NamespaceAlias:
325+
case NestedNameSpecifier::MsSuper:
304326
// The location of the identifier or namespace name.
305327
Length += sizeof(unsigned);
306328
break;
@@ -366,6 +388,7 @@ SourceRange NestedNameSpecifierLoc::getLocalSourceRange() const {
366388
case NestedNameSpecifier::Identifier:
367389
case NestedNameSpecifier::Namespace:
368390
case NestedNameSpecifier::NamespaceAlias:
391+
case NestedNameSpecifier::MsSuper:
369392
return SourceRange(LoadSourceLocation(Data, Offset),
370393
LoadSourceLocation(Data, Offset + sizeof(unsigned)));
371394

@@ -553,6 +576,17 @@ void NestedNameSpecifierLocBuilder::MakeGlobal(ASTContext &Context,
553576
SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
554577
}
555578

579+
void NestedNameSpecifierLocBuilder::MakeMsSuper(ASTContext &Context,
580+
SourceLocation MsSuperLoc,
581+
SourceLocation ColonColonLoc) {
582+
assert(!Representation && "Already have a nested-name-specifier!?");
583+
Representation = NestedNameSpecifier::MsSuperSpecifier(Context);
584+
585+
// Push source-location info into the buffer.
586+
SaveSourceLocation(MsSuperLoc, Buffer, BufferSize, BufferCapacity);
587+
SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
588+
}
589+
556590
void NestedNameSpecifierLocBuilder::MakeTrivial(ASTContext &Context,
557591
NestedNameSpecifier *Qualifier,
558592
SourceRange R) {
@@ -571,6 +605,7 @@ void NestedNameSpecifierLocBuilder::MakeTrivial(ASTContext &Context,
571605
case NestedNameSpecifier::Identifier:
572606
case NestedNameSpecifier::Namespace:
573607
case NestedNameSpecifier::NamespaceAlias:
608+
case NestedNameSpecifier::MsSuper:
574609
SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity);
575610
break;
576611

lib/Parse/ParseExpr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
730730
ConsumeToken();
731731
break;
732732

733+
case tok::kw___super:
733734
case tok::kw_decltype:
734735
case tok::identifier: { // primary-expression: identifier
735736
// unqualified-id: identifier

lib/Parse/ParseExprCXX.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,17 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
150150
}
151151

152152
bool HasScopeSpecifier = false;
153+
if (Tok.is(tok::kw___super)) {
154+
SourceLocation SuperLoc = ConsumeToken();
155+
if (Tok.isNot(tok::coloncolon)) {
156+
// XXX: Diagnose
157+
return true;
158+
}
153159

154-
if (Tok.is(tok::coloncolon)) {
160+
if (Actions.ActOnCXXMsSuperScopeSpecifier(getCurScope(), SuperLoc, ConsumeToken(), SS))
161+
return true;
162+
HasScopeSpecifier = true;
163+
} else if (Tok.is(tok::coloncolon)) {
155164
// ::new and ::delete aren't nested-name-specifiers.
156165
tok::TokenKind NextKind = NextToken().getKind();
157166
if (NextKind == tok::kw_new || NextKind == tok::kw_delete)

lib/Parse/Parser.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1293,7 +1293,8 @@ TemplateIdAnnotation *Parser::takeTemplateIdAnnotation(const Token &tok) {
12931293
bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext, bool NeedType) {
12941294
assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon)
12951295
|| Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope)
1296-
|| Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id))
1296+
|| Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id)
1297+
|| Tok.is(tok::kw___super))
12971298
&& "Cannot be a type or scope token!");
12981299

12991300
if (Tok.is(tok::kw_typename)) {

lib/Sema/DeclSpec.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,18 @@ void CXXScopeSpec::MakeGlobal(ASTContext &Context,
111111
"NestedNameSpecifierLoc range computation incorrect");
112112
}
113113

114+
void CXXScopeSpec::MakeMsSuper(ASTContext &Context,
115+
SourceLocation MsSuperLoc,
116+
SourceLocation ColonColonLoc) {
117+
Builder.MakeMsSuper(Context, MsSuperLoc, ColonColonLoc);
118+
119+
Range.setBegin(MsSuperLoc);
120+
Range.setEnd(ColonColonLoc);
121+
122+
assert(Range == Builder.getSourceRange() &&
123+
"NestedNameSpecifierLoc range computation incorrect");
124+
}
125+
114126
void CXXScopeSpec::MakeTrivial(ASTContext &Context,
115127
NestedNameSpecifier *Qualifier, SourceRange R) {
116128
Builder.MakeTrivial(Context, Qualifier, R);

lib/Sema/SemaCXXScopeSpec.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS,
155155

156156
case NestedNameSpecifier::Global:
157157
return Context.getTranslationUnitDecl();
158+
159+
case NestedNameSpecifier::MsSuper:
160+
return 0;
158161
}
159162

160163
llvm_unreachable("Invalid NestedNameSpecifier::Kind!");
@@ -267,6 +270,12 @@ bool Sema::ActOnCXXGlobalScopeSpecifier(Scope *S, SourceLocation CCLoc,
267270
return false;
268271
}
269272

273+
bool Sema::ActOnCXXMsSuperScopeSpecifier(Scope *S, SourceLocation SuperLoc,
274+
SourceLocation CCLoc, CXXScopeSpec &SS) {
275+
SS.MakeMsSuper(Context, SuperLoc, CCLoc);
276+
return false;
277+
}
278+
270279
/// \brief Determines whether the given declaration is an valid acceptable
271280
/// result for name lookup of a nested-name-specifier.
272281
bool Sema::isAcceptableNestedNameSpecifier(NamedDecl *SD) {

lib/Sema/SemaExpr.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1657,6 +1657,11 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
16571657
return true;
16581658
}
16591659

1660+
ExprResult Sema::ActOnMsSuperIdExpression(Scope *S, const DeclarationNameInfo &NameInfo,
1661+
const TemplateArgumentListInfo *TemplateArgs) {
1662+
return ExprResult();
1663+
}
1664+
16601665
ExprResult Sema::ActOnIdExpression(Scope *S,
16611666
CXXScopeSpec &SS,
16621667
SourceLocation TemplateKWLoc,
@@ -1669,6 +1674,7 @@ ExprResult Sema::ActOnIdExpression(Scope *S,
16691674

16701675
if (SS.isInvalid())
16711676
return ExprError();
1677+
const NestedNameSpecifier * NNS = SS.getScopeRep();
16721678

16731679
TemplateArgumentListInfo TemplateArgsBuffer;
16741680

@@ -1677,6 +1683,20 @@ ExprResult Sema::ActOnIdExpression(Scope *S,
16771683
const TemplateArgumentListInfo *TemplateArgs;
16781684
DecomposeUnqualifiedId(Id, TemplateArgsBuffer, NameInfo, TemplateArgs);
16791685

1686+
if (NNS && NNS->getKind() == NestedNameSpecifier::MsSuper) {
1687+
Scope * FnScope = S->getFnParent();
1688+
DeclContext * DC = static_cast<DeclContext *>(FnScope->getEntity());
1689+
FunctionDecl * Fn = llvm::dyn_cast<FunctionDecl>(DC);
1690+
CXXMethodDecl * Method = llvm::dyn_cast_or_null<CXXMethodDecl>(Fn);
1691+
CXXRecordDecl * Rec = Method->getParent();
1692+
1693+
LookupResult R(*this, NameInfo, LookupOrdinaryName);
1694+
if (!LookupInBaseClasses(R, Rec))
1695+
return ExprError();
1696+
1697+
return BuildImplicitMemberExpr(SS, SourceLocation(), R, /*TemplateArgs=*/0, /*IsDefiniteInstance=*/true);
1698+
}
1699+
16801700
DeclarationName Name = NameInfo.getName();
16811701
IdentifierInfo *II = Name.getAsIdentifierInfo();
16821702
SourceLocation NameLoc = NameInfo.getLoc();
@@ -2087,7 +2107,7 @@ Sema::PerformObjectMemberConversion(Expr *From,
20872107
// x = 17; // error: ambiguous base subobjects
20882108
// Derived1::x = 17; // okay, pick the Base subobject of Derived1
20892109
// }
2090-
if (Qualifier) {
2110+
if (Qualifier && Qualifier->getKind() != NestedNameSpecifier::MsSuper) {
20912111
QualType QType = QualType(Qualifier->getAsType(), 0);
20922112
assert(!QType.isNull() && "lookup done with dependent qualifier?");
20932113
assert(QType->isRecordType() && "lookup done with non-record type");

lib/Sema/SemaLookup.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,6 +1445,11 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
14451445
if (!LookupRec || !LookupRec->getDefinition())
14461446
return false;
14471447

1448+
return LookupInBaseClasses(R, LookupRec, InUnqualifiedLookup);
1449+
}
1450+
1451+
bool Sema::LookupInBaseClasses(LookupResult &R, CXXRecordDecl *LookupRec,
1452+
bool InUnqualifiedLookup) {
14481453
// If we're performing qualified name lookup into a dependent class,
14491454
// then we are actually looking into a current instantiation. If we have any
14501455
// dependent base classes, then we either have to delay lookup until
@@ -3306,6 +3311,7 @@ static void getNestedNameSpecifierIdentifiers(
33063311
break;
33073312

33083313
case NestedNameSpecifier::Global:
3314+
case NestedNameSpecifier::MsSuper:
33093315
return;
33103316
}
33113317

0 commit comments

Comments
 (0)