aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-09-01 00:37:14 +0000
committerDouglas Gregor <dgregor@apple.com>2009-09-01 00:37:14 +0000
commitc4bf26fbdff42967d660f505a83f75a4df2cc752 (patch)
treed4d7ad9bdaef74905f2e3a439ea541c6ae92c9f9 /lib/Sema
parentfe9dcb345fa8347cea55142c0295b797fddeb30f (diff)
Preliminary AST representation and semantic analysis for
explicitly-specified template argument lists in member reference expressions, e.g., x->f<int>() git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80646 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/Sema.h20
-rw-r--r--lib/Sema/SemaExpr.cpp32
-rw-r--r--lib/Sema/SemaExprCXX.cpp15
-rw-r--r--lib/Sema/SemaOverload.cpp8
-rw-r--r--lib/Sema/SemaTemplate.cpp35
-rw-r--r--lib/Sema/TreeTransform.h2
6 files changed, 91 insertions, 21 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index a8cdb67bb3..63d2831fab 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1602,12 +1602,32 @@ public:
SourceLocation LLoc,
ExprArg Idx,
SourceLocation RLoc);
+
+ OwningExprResult BuildMemberReferenceExpr(Scope *S, ExprArg Base,
+ SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ SourceLocation MemberLoc,
+ DeclarationName MemberName,
+ DeclPtrTy ImplDecl,
+ const CXXScopeSpec *SS = 0) {
+ // FIXME: Temporary helper while we migrate existing calls to
+ // BuildMemberReferenceExpr to support explicitly-specified template
+ // arguments.
+ return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, MemberLoc,
+ MemberName, false, SourceLocation(), 0, 0,
+ SourceLocation(), ImplDecl, SS);
+ }
OwningExprResult BuildMemberReferenceExpr(Scope *S, ExprArg Base,
SourceLocation OpLoc,
tok::TokenKind OpKind,
SourceLocation MemberLoc,
DeclarationName MemberName,
+ bool HasExplicitTemplateArgs,
+ SourceLocation LAngleLoc,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
+ SourceLocation RAngleLoc,
DeclPtrTy ImplDecl,
const CXXScopeSpec *SS = 0);
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index df94f20af7..d272be9765 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -885,7 +885,10 @@ static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow,
if (SS && SS->isSet())
return MemberExpr::Create(C, Base, isArrow,
(NestedNameSpecifier *)SS->getScopeRep(),
- SS->getRange(), Member, Loc, Ty);
+ SS->getRange(), Member, Loc,
+ // FIXME: Explicit template argument lists
+ false, SourceLocation(), 0, 0, SourceLocation(),
+ Ty);
return new (C) MemberExpr(Base, isArrow, Member, Loc, Ty);
}
@@ -1980,6 +1983,11 @@ Action::OwningExprResult
Sema::BuildMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
tok::TokenKind OpKind, SourceLocation MemberLoc,
DeclarationName MemberName,
+ bool HasExplicitTemplateArgs,
+ SourceLocation LAngleLoc,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
+ SourceLocation RAngleLoc,
DeclPtrTy ObjCImpDecl, const CXXScopeSpec *SS) {
if (SS && SS->isInvalid())
return ExprError();
@@ -2153,14 +2161,34 @@ Sema::BuildMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
if (FunctionTemplateDecl *FunTmpl
= dyn_cast<FunctionTemplateDecl>(MemberDecl)) {
MarkDeclarationReferenced(MemberLoc, MemberDecl);
+
+ if (HasExplicitTemplateArgs)
+ return Owned(MemberExpr::Create(Context, BaseExpr, OpKind == tok::arrow,
+ (NestedNameSpecifier *)(SS? SS->getScopeRep() : 0),
+ SS? SS->getRange() : SourceRange(),
+ FunTmpl, MemberLoc, true,
+ LAngleLoc, ExplicitTemplateArgs,
+ NumExplicitTemplateArgs, RAngleLoc,
+ Context.OverloadTy));
+
return Owned(BuildMemberExpr(Context, BaseExpr, OpKind == tok::arrow, SS,
FunTmpl, MemberLoc,
Context.OverloadTy));
}
if (OverloadedFunctionDecl *Ovl
- = dyn_cast<OverloadedFunctionDecl>(MemberDecl))
+ = dyn_cast<OverloadedFunctionDecl>(MemberDecl)) {
+ if (HasExplicitTemplateArgs)
+ return Owned(MemberExpr::Create(Context, BaseExpr, OpKind == tok::arrow,
+ (NestedNameSpecifier *)(SS? SS->getScopeRep() : 0),
+ SS? SS->getRange() : SourceRange(),
+ Ovl, MemberLoc, true,
+ LAngleLoc, ExplicitTemplateArgs,
+ NumExplicitTemplateArgs, RAngleLoc,
+ Context.OverloadTy));
+
return Owned(BuildMemberExpr(Context, BaseExpr, OpKind == tok::arrow, SS,
Ovl, MemberLoc, Context.OverloadTy));
+ }
if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) {
MarkDeclarationReferenced(MemberLoc, MemberDecl);
return Owned(BuildMemberExpr(Context, BaseExpr, OpKind == tok::arrow, SS,
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index dc58ecc16c..35938260c6 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -1831,21 +1831,6 @@ 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)
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index f22c1177e6..1427d48bc2 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -4563,9 +4563,11 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
AddMethodCandidate(Method, ObjectArg, Args, NumArgs, CandidateSet,
/*SuppressUserConversions=*/false);
else
- AddMethodTemplateCandidate(cast<FunctionTemplateDecl>(*Func),
- /*FIXME:*/false, /*FIXME:*/0,
- /*FIXME:*/0, ObjectArg, Args, NumArgs,
+ AddMethodTemplateCandidate(cast<FunctionTemplateDecl>(*Func),
+ MemExpr->hasExplicitTemplateArgumentList(),
+ MemExpr->getTemplateArgs(),
+ MemExpr->getNumTemplateArgs(),
+ ObjectArg, Args, NumArgs,
CandidateSet,
/*SuppressUsedConversions=*/false);
}
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index fb25e99bc8..3985c1c0e0 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1084,6 +1084,41 @@ Sema::OwningExprResult Sema::ActOnTemplateIdExpr(TemplateTy TemplateD,
RAngleLoc);
}
+Sema::OwningExprResult
+Sema::ActOnMemberTemplateIdReferenceExpr(Scope *S, ExprArg Base,
+ SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ const CXXScopeSpec &SS,
+ TemplateTy TemplateD,
+ SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ ASTTemplateArgsPtr TemplateArgsIn,
+ SourceLocation *TemplateArgLocs,
+ SourceLocation RAngleLoc) {
+ TemplateName Template = TemplateD.getAsVal<TemplateName>();
+
+ // FIXME: We're going to end up looking up the template based on its name,
+ // twice!
+ DeclarationName Name;
+ if (TemplateDecl *ActualTemplate = Template.getAsTemplateDecl())
+ Name = ActualTemplate->getDeclName();
+ else if (OverloadedFunctionDecl *Ovl = Template.getAsOverloadedFunctionDecl())
+ Name = Ovl->getDeclName();
+ else
+ assert(false && "Cannot support dependent template names yet");
+
+ // Translate the parser's template argument list in our AST format.
+ llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
+ translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
+ TemplateArgsIn.release();
+
+ // Do we have the save the actual template name? We might need it...
+ return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, TemplateNameLoc,
+ Name, true, LAngleLoc,
+ TemplateArgs.data(), TemplateArgs.size(),
+ RAngleLoc, DeclPtrTy(), &SS);
+}
+
/// \brief Form a dependent template name.
///
/// This action forms a dependent template name given the template
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 3879b39e6e..386a2c6d80 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -2964,7 +2964,7 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
Qualifier
= getDerived().TransformNestedNameSpecifier(E->getQualifier(),
E->getQualifierRange());
- if (Qualifier == 0);
+ if (Qualifier == 0)
return SemaRef.ExprError();
}