/// \brief Construct an empty declaration reference expression.
static DeclRefExpr *CreateEmpty(ASTContext &Context,
- bool HasQualifier, unsigned NumTemplateArgs);
+ bool HasQualifier,
+ bool HasExplicitTemplateArgs,
+ unsigned NumTemplateArgs);
ValueDecl *getDecl() { return DecoratedD.getPointer(); }
const ValueDecl *getDecl() const { return DecoratedD.getPointer(); }
UnresolvedSetIterator End);
static UnresolvedLookupExpr *CreateEmpty(ASTContext &C,
+ bool HasExplicitTemplateArgs,
unsigned NumTemplateArgs);
/// True if this declaration should be extended by
const TemplateArgumentListInfo *TemplateArgs = 0);
static DependentScopeDeclRefExpr *CreateEmpty(ASTContext &C,
+ bool HasExplicitTemplateArgs,
unsigned NumTemplateArgs);
/// \brief Retrieve the name that this expression refers to.
const TemplateArgumentListInfo *TemplateArgs);
static CXXDependentScopeMemberExpr *
- CreateEmpty(ASTContext &C, unsigned NumTemplateArgs);
+ CreateEmpty(ASTContext &C, bool HasExplicitTemplateArgs,
+ unsigned NumTemplateArgs);
/// \brief True if this is an implicit access, i.e. one in which the
/// member being accessed was not written in the source. The source
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
static UnresolvedMemberExpr *
- CreateEmpty(ASTContext &C, unsigned NumTemplateArgs);
+ CreateEmpty(ASTContext &C, bool HasExplicitTemplateArgs,
+ unsigned NumTemplateArgs);
/// \brief True if this is an implicit access, i.e. one in which the
/// member being accessed was not written in the source. The source
TemplateArgs, T, VK);
}
-DeclRefExpr *DeclRefExpr::CreateEmpty(ASTContext &Context, bool HasQualifier,
+DeclRefExpr *DeclRefExpr::CreateEmpty(ASTContext &Context,
+ bool HasQualifier,
+ bool HasExplicitTemplateArgs,
unsigned NumTemplateArgs) {
std::size_t Size = sizeof(DeclRefExpr);
if (HasQualifier)
Size += sizeof(NameQualifier);
- if (NumTemplateArgs)
+ if (HasExplicitTemplateArgs)
Size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
void *Mem = Context.Allocate(Size, llvm::alignOf<DeclRefExpr>());
}
UnresolvedLookupExpr *
-UnresolvedLookupExpr::CreateEmpty(ASTContext &C, unsigned NumTemplateArgs) {
+UnresolvedLookupExpr::CreateEmpty(ASTContext &C, bool HasExplicitTemplateArgs,
+ unsigned NumTemplateArgs) {
std::size_t size = sizeof(UnresolvedLookupExpr);
- if (NumTemplateArgs != 0)
+ if (HasExplicitTemplateArgs)
size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
void *Mem = C.Allocate(size, llvm::alignOf<UnresolvedLookupExpr>());
UnresolvedLookupExpr *E = new (Mem) UnresolvedLookupExpr(EmptyShell());
- E->HasExplicitTemplateArgs = NumTemplateArgs != 0;
+ E->HasExplicitTemplateArgs = HasExplicitTemplateArgs;
return E;
}
DependentScopeDeclRefExpr *
DependentScopeDeclRefExpr::CreateEmpty(ASTContext &C,
+ bool HasExplicitTemplateArgs,
unsigned NumTemplateArgs) {
std::size_t size = sizeof(DependentScopeDeclRefExpr);
- if (NumTemplateArgs)
+ if (HasExplicitTemplateArgs)
size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
void *Mem = C.Allocate(size);
- return new (Mem) DependentScopeDeclRefExpr(QualType(), 0, SourceRange(),
- DeclarationNameInfo(), 0);
+ DependentScopeDeclRefExpr *E
+ = new (Mem) DependentScopeDeclRefExpr(QualType(), 0, SourceRange(),
+ DeclarationNameInfo(), 0);
+ E->HasExplicitTemplateArgs = HasExplicitTemplateArgs;
+ return E;
}
StmtIterator DependentScopeDeclRefExpr::child_begin() {
CXXDependentScopeMemberExpr *
CXXDependentScopeMemberExpr::CreateEmpty(ASTContext &C,
+ bool HasExplicitTemplateArgs,
unsigned NumTemplateArgs) {
- if (NumTemplateArgs == 0)
+ if (!HasExplicitTemplateArgs)
return new (C) CXXDependentScopeMemberExpr(C, 0, QualType(),
0, SourceLocation(), 0,
SourceRange(), 0,
}
UnresolvedMemberExpr *
-UnresolvedMemberExpr::CreateEmpty(ASTContext &C, unsigned NumTemplateArgs) {
+UnresolvedMemberExpr::CreateEmpty(ASTContext &C, bool HasExplicitTemplateArgs,
+ unsigned NumTemplateArgs) {
std::size_t size = sizeof(UnresolvedMemberExpr);
- if (NumTemplateArgs != 0)
+ if (HasExplicitTemplateArgs)
size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
void *Mem = C.Allocate(size, llvm::alignOf<UnresolvedMemberExpr>());
UnresolvedMemberExpr *E = new (Mem) UnresolvedMemberExpr(EmptyShell());
- E->HasExplicitTemplateArgs = NumTemplateArgs != 0;
+ E->HasExplicitTemplateArgs = HasExplicitTemplateArgs;
return E;
}
VisitExpr(E);
bool HasQualifier = Record[Idx++];
- unsigned NumTemplateArgs = Record[Idx++];
+ bool HasExplicitTemplateArgs = Record[Idx++];
E->DecoratedD.setInt((HasQualifier? DeclRefExpr::HasQualifierFlag : 0) |
- (NumTemplateArgs ? DeclRefExpr::HasExplicitTemplateArgumentListFlag : 0));
+ (HasExplicitTemplateArgs
+ ? DeclRefExpr::HasExplicitTemplateArgumentListFlag : 0));
if (HasQualifier) {
E->getNameQualifier()->NNS = Reader.ReadNestedNameSpecifier(Record, Idx);
E->getNameQualifier()->Range = ReadSourceRange(Record, Idx);
}
- if (NumTemplateArgs)
+ if (HasExplicitTemplateArgs) {
+ unsigned NumTemplateArgs = Record[Idx++];
ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(),
NumTemplateArgs);
+ }
E->setDecl(cast<ValueDecl>(Reader.GetDecl(Record[Idx++])));
E->setLocation(ReadSourceLocation(Record, Idx));
ASTStmtReader::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
VisitExpr(E);
- unsigned NumTemplateArgs = Record[Idx++];
- assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() &&
- "Read wrong record during creation ?");
- if (E->hasExplicitTemplateArgs())
+ if (Record[Idx++])
ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(),
- NumTemplateArgs);
+ Record[Idx++]);
E->setBase(Reader.ReadSubExpr());
E->setBaseType(Reader.GetType(Record[Idx++]));
ASTStmtReader::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
VisitExpr(E);
- unsigned NumTemplateArgs = Record[Idx++];
- assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() &&
- "Read wrong record during creation ?");
- if (E->hasExplicitTemplateArgs())
- ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(),
- NumTemplateArgs);
-
+ if (Record[Idx++])
+ ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(),
+ Record[Idx++]);
+
ReadDeclarationNameInfo(E->NameInfo, Record, Idx);
E->setQualifierRange(ReadSourceRange(Record, Idx));
E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx));
void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) {
VisitExpr(E);
- unsigned NumTemplateArgs = Record[Idx++];
- assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() &&
- "Read wrong record during creation ?");
- if (E->hasExplicitTemplateArgs())
+ // Read the explicit template argument list, if available.
+ if (Record[Idx++])
ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(),
- NumTemplateArgs);
+ Record[Idx++]);
unsigned NumDecls = Record[Idx++];
UnresolvedSet<8> Decls;
case EXPR_DECL_REF:
S = DeclRefExpr::CreateEmpty(*Context,
/*HasQualifier=*/Record[ASTStmtReader::NumExprFields],
- /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 1]);
+ /*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 1],
+ /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 1]
+ ? Record[ASTStmtReader::NumExprFields + 2]
+ : 0);
break;
case EXPR_INTEGER_LITERAL:
}
TemplateArgumentListInfo ArgInfo;
- unsigned NumTemplateArgs = Record[Idx++];
- if (NumTemplateArgs) {
+ bool HasExplicitTemplateArgs = Record[Idx++];
+ if (HasExplicitTemplateArgs) {
+ unsigned NumTemplateArgs = Record[Idx++];
ArgInfo.setLAngleLoc(ReadSourceLocation(F, Record, Idx));
ArgInfo.setRAngleLoc(ReadSourceLocation(F, Record, Idx));
for (unsigned i = 0; i != NumTemplateArgs; ++i)
S = MemberExpr::Create(*Context, Base, IsArrow, NNS, QualifierRange,
MemberD, FoundDecl, MemberNameInfo,
- NumTemplateArgs ? &ArgInfo : 0, T, VK, OK);
+ HasExplicitTemplateArgs ? &ArgInfo : 0, T, VK, OK);
ReadDeclarationNameLoc(F, cast<MemberExpr>(S)->MemberDNLoc,
MemberD->getDeclName(), Record, Idx);
break;
case EXPR_CXX_DEPENDENT_SCOPE_MEMBER:
S = CXXDependentScopeMemberExpr::CreateEmpty(*Context,
- /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]);
+ /*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields],
+ /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
+ ? Record[ASTStmtReader::NumExprFields + 1]
+ : 0);
break;
case EXPR_CXX_DEPENDENT_SCOPE_DECL_REF:
S = DependentScopeDeclRefExpr::CreateEmpty(*Context,
- /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]);
+ /*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields],
+ /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
+ ? Record[ASTStmtReader::NumExprFields + 1]
+ : 0);
break;
case EXPR_CXX_UNRESOLVED_CONSTRUCT:
case EXPR_CXX_UNRESOLVED_MEMBER:
S = UnresolvedMemberExpr::CreateEmpty(*Context,
- /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]);
+ /*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields],
+ /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
+ ? Record[ASTStmtReader::NumExprFields + 1]
+ : 0);
break;
case EXPR_CXX_UNRESOLVED_LOOKUP:
S = UnresolvedLookupExpr::CreateEmpty(*Context,
- /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]);
+ /*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields],
+ /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
+ ? Record[ASTStmtReader::NumExprFields + 1]
+ : 0);
break;
case EXPR_CXX_UNARY_TYPE_TRAIT:
VisitExpr(E);
Record.push_back(E->hasQualifier());
- unsigned NumTemplateArgs = E->getNumTemplateArgs();
- assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() &&
- "Template args list with no args ?");
- Record.push_back(NumTemplateArgs);
+ Record.push_back(E->hasExplicitTemplateArgs());
if (E->hasQualifier()) {
Writer.AddNestedNameSpecifier(E->getQualifier(), Record);
Writer.AddSourceRange(E->getQualifierRange(), Record);
}
- if (NumTemplateArgs)
+ if (E->hasExplicitTemplateArgs()) {
+ unsigned NumTemplateArgs = E->getNumTemplateArgs();
+ Record.push_back(NumTemplateArgs);
AddExplicitTemplateArgumentList(E->getExplicitTemplateArgs());
+ }
Writer.AddDeclRef(E->getDecl(), Record);
Writer.AddSourceLocation(E->getLocation(), Record);
Writer.AddSourceRange(E->getQualifierRange(), Record);
}
- unsigned NumTemplateArgs = E->getNumTemplateArgs();
- assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() &&
- "Template args list with no args ?");
- Record.push_back(NumTemplateArgs);
- if (NumTemplateArgs) {
+ Record.push_back(E->hasExplicitTemplateArgs());
+ if (E->hasExplicitTemplateArgs()) {
+ unsigned NumTemplateArgs = E->getNumTemplateArgs();
+ Record.push_back(NumTemplateArgs);
Writer.AddSourceLocation(E->getLAngleLoc(), Record);
Writer.AddSourceLocation(E->getRAngleLoc(), Record);
for (unsigned i=0; i != NumTemplateArgs; ++i)
ASTStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
VisitExpr(E);
- // Don't emit anything here, NumTemplateArgs must be emitted first.
+ // Don't emit anything here, hasExplicitTemplateArgs() must be
+ // emitted first.
+ Record.push_back(E->hasExplicitTemplateArgs());
if (E->hasExplicitTemplateArgs()) {
const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs();
- assert(Args.NumTemplateArgs &&
- "Num of template args was zero! AST reading will mess up!");
Record.push_back(Args.NumTemplateArgs);
AddExplicitTemplateArgumentList(Args);
- } else {
- Record.push_back(0);
}
if (!E->isImplicitAccess())
ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
VisitExpr(E);
- // Don't emit anything here, NumTemplateArgs must be emitted first.
-
+ // Don't emit anything here, hasExplicitTemplateArgs() must be
+ // emitted first.
+ Record.push_back(E->hasExplicitTemplateArgs());
if (E->hasExplicitTemplateArgs()) {
const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs();
- assert(Args.NumTemplateArgs &&
- "Num of template args was zero! AST reading will mess up!");
Record.push_back(Args.NumTemplateArgs);
AddExplicitTemplateArgumentList(Args);
- } else {
- Record.push_back(0);
}
Writer.AddDeclarationNameInfo(E->NameInfo, Record);
void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
VisitExpr(E);
- // Don't emit anything here, NumTemplateArgs must be emitted first.
-
+ // Don't emit anything here, hasExplicitTemplateArgs() must be emitted first.
+ Record.push_back(E->hasExplicitTemplateArgs());
if (E->hasExplicitTemplateArgs()) {
const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs();
- assert(Args.NumTemplateArgs &&
- "Num of template args was zero! AST reading will mess up!");
Record.push_back(Args.NumTemplateArgs);
AddExplicitTemplateArgumentList(Args);
- } else {
- Record.push_back(0);
}
Record.push_back(E->getNumDecls());
template struct S4<int>;
S7<int[5]> s7_5;
+
+namespace ZeroLengthExplicitTemplateArgs {
+ template void f<X>(X*);
+}
template<unsigned N>
struct S7<int[N]> : S6<const int[N]> { };
+
+// Zero-length template argument lists
+namespace ZeroLengthExplicitTemplateArgs {
+ template<typename T> void h();
+
+ struct Y {
+ template<typename T> void f();
+ };
+
+ template<typename T>
+ void f(T *ptr) {
+ T::template g<>(17);
+ ptr->template g2<>(17);
+ h<T>();
+ h<int>();
+ Y y;
+ y.f<int>();
+ }
+
+ struct X {
+ template<typename T> static void g(T);
+ template<typename T> void g2(T);
+ };
+}