aboutsummaryrefslogtreecommitdiff
path: root/lib/AST
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST')
-rw-r--r--lib/AST/ASTContext.cpp3
-rw-r--r--lib/AST/ExprCXX.cpp71
-rw-r--r--lib/AST/NestedNameSpecifier.cpp2
-rw-r--r--lib/AST/StmtPrinter.cpp13
-rw-r--r--lib/AST/TemplateName.cpp2
5 files changed, 86 insertions, 5 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 780b1fdc42..30e4234956 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -3319,7 +3319,8 @@ TemplateName ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS,
/// template name such as \c MetaFun::template apply.
TemplateName ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS,
const IdentifierInfo *Name) {
- assert(NNS->isDependent() && "Nested name specifier must be dependent");
+ assert((!NNS || NNS->isDependent()) &&
+ "Nested name specifier must be dependent");
llvm::FoldingSetNodeID ID;
DependentTemplateName::Profile(ID, NNS, Name);
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 86c522795e..7c36caad58 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -523,6 +523,77 @@ Stmt::child_iterator CXXUnresolvedConstructExpr::child_end() {
return child_iterator(reinterpret_cast<Stmt **>(this + 1) + NumArgs);
}
+CXXUnresolvedMemberExpr::CXXUnresolvedMemberExpr(ASTContext &C,
+ Expr *Base, bool IsArrow,
+ SourceLocation OperatorLoc,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ NamedDecl *FirstQualifierFoundInScope,
+ DeclarationName Member,
+ SourceLocation MemberLoc,
+ bool HasExplicitTemplateArgs,
+ SourceLocation LAngleLoc,
+ const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs,
+ SourceLocation RAngleLoc)
+ : Expr(CXXUnresolvedMemberExprClass, C.DependentTy, true, true),
+ Base(Base), IsArrow(IsArrow),
+ HasExplicitTemplateArgumentList(HasExplicitTemplateArgs),
+ OperatorLoc(OperatorLoc),
+ Qualifier(Qualifier), QualifierRange(QualifierRange),
+ FirstQualifierFoundInScope(FirstQualifierFoundInScope),
+ Member(Member), MemberLoc(MemberLoc)
+{
+ if (HasExplicitTemplateArgumentList) {
+ ExplicitTemplateArgumentList *ETemplateArgs
+ = getExplicitTemplateArgumentList();
+ ETemplateArgs->LAngleLoc = LAngleLoc;
+ ETemplateArgs->RAngleLoc = RAngleLoc;
+ ETemplateArgs->NumTemplateArgs = NumTemplateArgs;
+
+ TemplateArgument *SavedTemplateArgs = ETemplateArgs->getTemplateArgs();
+ for (unsigned I = 0; I < NumTemplateArgs; ++I)
+ new (SavedTemplateArgs + I) TemplateArgument(TemplateArgs[I]);
+ }
+}
+
+CXXUnresolvedMemberExpr *
+CXXUnresolvedMemberExpr::Create(ASTContext &C,
+ Expr *Base, bool IsArrow,
+ SourceLocation OperatorLoc,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ NamedDecl *FirstQualifierFoundInScope,
+ DeclarationName Member,
+ SourceLocation MemberLoc,
+ bool HasExplicitTemplateArgs,
+ SourceLocation LAngleLoc,
+ const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs,
+ SourceLocation RAngleLoc)
+{
+ if (!HasExplicitTemplateArgs)
+ return new (C) CXXUnresolvedMemberExpr(C, Base, IsArrow, OperatorLoc,
+ Qualifier, QualifierRange,
+ FirstQualifierFoundInScope,
+ Member, MemberLoc);
+
+ void *Mem = C.Allocate(sizeof(CXXUnresolvedMemberExpr) +
+ sizeof(ExplicitTemplateArgumentList) +
+ sizeof(TemplateArgument) * NumTemplateArgs,
+ llvm::alignof<CXXUnresolvedMemberExpr>());
+ return new (Mem) CXXUnresolvedMemberExpr(C, Base, IsArrow, OperatorLoc,
+ Qualifier, QualifierRange,
+ FirstQualifierFoundInScope,
+ Member,
+ MemberLoc,
+ HasExplicitTemplateArgs,
+ LAngleLoc,
+ TemplateArgs,
+ NumTemplateArgs,
+ RAngleLoc);
+}
+
Stmt::child_iterator CXXUnresolvedMemberExpr::child_begin() {
return child_iterator(&Base);
}
diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp
index 24fb752420..2ed8eb0099 100644
--- a/lib/AST/NestedNameSpecifier.cpp
+++ b/lib/AST/NestedNameSpecifier.cpp
@@ -42,7 +42,7 @@ NestedNameSpecifier *
NestedNameSpecifier::Create(ASTContext &Context, NestedNameSpecifier *Prefix,
IdentifierInfo *II) {
assert(II && "Identifier cannot be NULL");
- assert(Prefix && Prefix->isDependent() && "Prefix must be dependent");
+ assert((!Prefix || Prefix->isDependent()) && "Prefix must be dependent");
NestedNameSpecifier Mockup;
Mockup.Prefix.setPointer(Prefix);
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 317486cd71..7a0d6d6349 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -493,12 +493,10 @@ void StmtPrinter::VisitTemplateIdRefExpr(TemplateIdRefExpr *Node) {
if (Node->getQualifier())
Node->getQualifier()->print(OS, Policy);
Node->getTemplateName().print(OS, Policy, true);
- OS << '<';
OS << TemplateSpecializationType::PrintTemplateArgumentList(
Node->getTemplateArgs(),
Node->getNumTemplateArgs(),
Policy);
- OS << '>';
}
void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
@@ -1154,7 +1152,18 @@ void StmtPrinter::VisitCXXUnresolvedMemberExpr(CXXUnresolvedMemberExpr *Node) {
OS << (Node->isArrow() ? "->" : ".");
if (NestedNameSpecifier *Qualifier = Node->getQualifier())
Qualifier->print(OS, Policy);
+ else if (Node->hasExplicitTemplateArgumentList())
+ // FIXME: Track use of "template" keyword explicitly?
+ OS << "template ";
+
OS << Node->getMember().getAsString();
+
+ if (Node->hasExplicitTemplateArgumentList()) {
+ OS << TemplateSpecializationType::PrintTemplateArgumentList(
+ Node->getTemplateArgs(),
+ Node->getNumTemplateArgs(),
+ Policy);
+ }
}
static const char *getTypeTraitName(UnaryTypeTrait UTT) {
diff --git a/lib/AST/TemplateName.cpp b/lib/AST/TemplateName.cpp
index 3913121b09..92c741b35d 100644
--- a/lib/AST/TemplateName.cpp
+++ b/lib/AST/TemplateName.cpp
@@ -67,7 +67,7 @@ TemplateName::print(llvm::raw_ostream &OS, const PrintingPolicy &Policy,
OS << "template ";
OS << QTN->getDecl()->getNameAsString();
} else if (DependentTemplateName *DTN = getAsDependentTemplateName()) {
- if (!SuppressNNS)
+ if (!SuppressNNS && DTN->getQualifier())
DTN->getQualifier()->print(OS, Policy);
OS << "template ";
// FIXME: Shouldn't we have a more general kind of name?