aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Parse/ParseExpr.cpp25
-rw-r--r--lib/Sema/Sema.h14
-rw-r--r--lib/Sema/SemaExpr.cpp2
-rw-r--r--lib/Sema/SemaExprCXX.cpp15
4 files changed, 54 insertions, 2 deletions
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index d00d6d2e33..36b6dd4a93 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -941,7 +941,7 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) {
ObjCImpDecl, &SS);
ConsumeToken();
} else if (getLang().CPlusPlus && Tok.is(tok::tilde)) {
- // We have a C++ pseudo-destructor.
+ // We have a C++ pseudo-destructor or a destructor call, e.g., t.~T()
// Consume the tilde.
ConsumeToken();
@@ -961,6 +961,8 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) {
&SS);
ConsumeToken();
} else if (getLang().CPlusPlus && Tok.is(tok::kw_operator)) {
+ // We have a reference to a member operator, e.g., t.operator int or
+ // t.operator+.
if (OverloadedOperatorKind Op = TryParseOperatorFunctionId()) {
if (!LHS.isInvalid())
LHS = Actions.ActOnOverloadedOperatorReferenceExpr(CurScope,
@@ -983,6 +985,27 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) {
// Don't emit a diagnostic; ParseConversionFunctionId does it for us
return ExprError();
}
+ } else if (getLang().CPlusPlus && Tok.is(tok::annot_template_id)) {
+ // We have a reference to a member template along with explicitly-
+ // specified template arguments, e.g., t.f<int>.
+ TemplateIdAnnotation *TemplateId
+ = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
+ if (!LHS.isInvalid()) {
+ ASTTemplateArgsPtr TemplateArgsPtr(Actions,
+ TemplateId->getTemplateArgs(),
+ TemplateId->getTemplateArgIsType(),
+ TemplateId->NumArgs);
+
+ LHS = Actions.ActOnMemberTemplateIdReferenceExpr(CurScope, move(LHS),
+ OpLoc, OpKind, SS,
+ TemplateTy::make(TemplateId->Template),
+ TemplateId->TemplateNameLoc,
+ TemplateId->LAngleLoc,
+ TemplateArgsPtr,
+ TemplateId->getTemplateArgLocations(),
+ TemplateId->RAngleLoc);
+ }
+ ConsumeToken();
} else {
if (getLang().CPlusPlus)
Actions.ActOnCXXExitMemberScope(CurScope, MemberSS);
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 2a2515ff11..ce56eb4637 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1598,6 +1598,7 @@ public:
DeclarationName MemberName,
DeclPtrTy ImplDecl,
const CXXScopeSpec *SS = 0);
+
virtual OwningExprResult ActOnMemberReferenceExpr(Scope *S, ExprArg Base,
SourceLocation OpLoc,
tok::TokenKind OpKind,
@@ -1972,6 +1973,19 @@ public:
TypeTy *Ty,
const CXXScopeSpec *SS = 0);
+ virtual OwningExprResult
+ ActOnMemberTemplateIdReferenceExpr(Scope *S, ExprArg Base,
+ SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ const CXXScopeSpec &SS,
+ // FIXME: "template" keyword?
+ TemplateTy Template,
+ SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ ASTTemplateArgsPtr TemplateArgs,
+ SourceLocation *TemplateArgLocs,
+ SourceLocation RAngleLoc);
+
/// MaybeCreateCXXExprWithTemporaries - If the list of temporaries is
/// non-empty, will create a new CXXExprWithTemporaries expression.
/// Otherwise, just returs the passed in expression.
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index f304ac3094..026ff43d2d 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -2005,7 +2005,7 @@ Sema::BuildMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
ImpCastExprToType(BaseExpr, BaseType);
}
} else if (BaseType->isObjCClassType() &&
- BaseType != Context.ObjCClassRedefinitionType) {
+ BaseType != Context.ObjCClassRedefinitionType) {
BaseType = Context.ObjCClassRedefinitionType;
ImpCastExprToType(BaseExpr, BaseType);
}
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 35938260c6..dc58ecc16c 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -1831,6 +1831,21 @@ Sema::ActOnConversionOperatorReferenceExpr(Scope *S, ExprArg Base,
ConvName, DeclPtrTy(), SS);
}
+Sema::OwningExprResult
+Sema::ActOnMemberTemplateIdReferenceExpr(Scope *S, ExprArg Base,
+ SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ const CXXScopeSpec &SS,
+ TemplateTy Template,
+ SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ ASTTemplateArgsPtr TemplateArgs,
+ SourceLocation *TemplateArgLocs,
+ SourceLocation RAngleLoc) {
+ // FIXME: Implement!
+ return ExprError();
+}
+
Sema::OwningExprResult Sema::ActOnFinishFullExpr(ExprArg Arg) {
Expr *FullExpr = Arg.takeAs<Expr>();
if (FullExpr)