Fix PCH emitting/reading for template arguments that contain expressions.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106996 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Argyrios Kyrtzidis 2010-06-28 09:31:42 +00:00
Родитель dc767e3684
Коммит 17cfdeda47
7 изменённых файлов: 177 добавлений и 29 удалений

Просмотреть файл

@ -563,12 +563,30 @@ public:
/// \brief Read preprocessed entities into the /// \brief Read preprocessed entities into the
virtual void ReadPreprocessedEntities(); virtual void ReadPreprocessedEntities();
/// \brief Abstract interface for reading expressions.
class ExprReader {
public:
virtual Expr *Read();
};
/// \brief Reads a TemplateArgumentLocInfo appropriate for the
/// given TemplateArgument kind.
TemplateArgumentLocInfo
GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
const RecordData &Record, unsigned &Idx,
ExprReader &ExprRdr);
/// \brief Reads a TemplateArgumentLocInfo appropriate for the /// \brief Reads a TemplateArgumentLocInfo appropriate for the
/// given TemplateArgument kind. /// given TemplateArgument kind.
TemplateArgumentLocInfo TemplateArgumentLocInfo
GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
const RecordData &Record, unsigned &Idx); const RecordData &Record, unsigned &Idx);
/// \brief Reads a TemplateArgumentLoc.
TemplateArgumentLoc ReadTemplateArgumentLoc(const RecordData &Record,
unsigned &Idx,
ExprReader &ExprRdr);
/// \brief Reads a TemplateArgumentLoc. /// \brief Reads a TemplateArgumentLoc.
TemplateArgumentLoc ReadTemplateArgumentLoc(const RecordData &Record, TemplateArgumentLoc ReadTemplateArgumentLoc(const RecordData &Record,
unsigned &Idx); unsigned &Idx);
@ -700,6 +718,10 @@ public:
/// \brief Read a template name. /// \brief Read a template name.
TemplateName ReadTemplateName(const RecordData &Record, unsigned &Idx); TemplateName ReadTemplateName(const RecordData &Record, unsigned &Idx);
/// \brief Read a template argument.
TemplateArgument ReadTemplateArgument(const RecordData &Record,unsigned &Idx,
ExprReader &ExprRdr);
/// \brief Read a template argument. /// \brief Read a template argument.
TemplateArgument ReadTemplateArgument(const RecordData &Record,unsigned &Idx); TemplateArgument ReadTemplateArgument(const RecordData &Record,unsigned &Idx);

Просмотреть файл

@ -211,6 +211,9 @@ private:
/// file. /// file.
unsigned NumVisibleDeclContexts; unsigned NumVisibleDeclContexts;
/// \brief True when we are in Stmts emitting mode.
bool EmittingStmts;
void WriteBlockInfoBlock(); void WriteBlockInfoBlock();
void WriteMetadata(ASTContext &Context, const char *isysroot); void WriteMetadata(ASTContext &Context, const char *isysroot);
void WriteLanguageOptions(const LangOptions &LangOpts); void WriteLanguageOptions(const LangOptions &LangOpts);
@ -355,7 +358,12 @@ public:
/// type or declaration has been written, call FlushStmts() to write /// type or declaration has been written, call FlushStmts() to write
/// the corresponding statements just after the type or /// the corresponding statements just after the type or
/// declaration. /// declaration.
void AddStmt(Stmt *S) { StmtsToEmit.push_back(S); } void AddStmt(Stmt *S) {
if (EmittingStmts)
WriteSubStmt(S);
else
StmtsToEmit.push_back(S);
}
/// \brief Write the given subexpression to the bitstream. /// \brief Write the given subexpression to the bitstream.
void WriteSubStmt(Stmt *S); void WriteSubStmt(Stmt *S);

Просмотреть файл

@ -321,6 +321,18 @@ void PCHValidator::ReadCounter(unsigned Value) {
// PCH reader implementation // PCH reader implementation
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Give ExprReader's VTable a home.
Expr *PCHReader::ExprReader::Read() { return 0; }
namespace {
class DeclExprReader : public PCHReader::ExprReader {
PCHReader &Reader;
public:
DeclExprReader(PCHReader &reader) : Reader(reader) { }
virtual Expr *Read() { return Reader.ReadDeclExpr(); }
};
} // anonymous namespace
PCHReader::PCHReader(Preprocessor &PP, ASTContext *Context, PCHReader::PCHReader(Preprocessor &PP, ASTContext *Context,
const char *isysroot) const char *isysroot)
: Listener(new PCHValidator(PP, *this)), SourceMgr(PP.getSourceManager()), : Listener(new PCHValidator(PP, *this)), SourceMgr(PP.getSourceManager()),
@ -2499,19 +2511,16 @@ QualType PCHReader::GetType(pch::TypeID ID) {
TemplateArgumentLocInfo TemplateArgumentLocInfo
PCHReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, PCHReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
const RecordData &Record, const RecordData &Record,
unsigned &Index) { unsigned &Index, ExprReader &ExprRdr) {
switch (Kind) { switch (Kind) {
case TemplateArgument::Expression: case TemplateArgument::Expression:
return ReadDeclExpr(); return ExprRdr.Read();
case TemplateArgument::Type: case TemplateArgument::Type:
return GetTypeSourceInfo(Record, Index); return GetTypeSourceInfo(Record, Index);
case TemplateArgument::Template: { case TemplateArgument::Template: {
SourceLocation SourceRange QualifierRange = ReadSourceRange(Record, Index);
QualStart = SourceLocation::getFromRawEncoding(Record[Index++]), SourceLocation TemplateNameLoc = ReadSourceLocation(Record, Index);
QualEnd = SourceLocation::getFromRawEncoding(Record[Index++]), return TemplateArgumentLocInfo(QualifierRange, TemplateNameLoc);
TemplateNameLoc = SourceLocation::getFromRawEncoding(Record[Index++]);
return TemplateArgumentLocInfo(SourceRange(QualStart, QualEnd),
TemplateNameLoc);
} }
case TemplateArgument::Null: case TemplateArgument::Null:
case TemplateArgument::Integral: case TemplateArgument::Integral:
@ -2523,11 +2532,32 @@ PCHReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
return TemplateArgumentLocInfo(); return TemplateArgumentLocInfo();
} }
TemplateArgumentLocInfo
PCHReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
const RecordData &Record,
unsigned &Index) {
DeclExprReader DeclExprReader(*this);
return GetTemplateArgumentLocInfo(Kind, Record, Index, DeclExprReader);
}
TemplateArgumentLoc
PCHReader::ReadTemplateArgumentLoc(const RecordData &Record, unsigned &Index,
ExprReader &ExprRdr) {
TemplateArgument Arg = ReadTemplateArgument(Record, Index, ExprRdr);
if (Arg.getKind() == TemplateArgument::Expression) {
if (Record[Index++]) // bool InfoHasSameExpr.
return TemplateArgumentLoc(Arg, TemplateArgumentLocInfo(Arg.getAsExpr()));
}
return TemplateArgumentLoc(Arg, GetTemplateArgumentLocInfo(Arg.getKind(),
Record, Index,
ExprRdr));
}
TemplateArgumentLoc TemplateArgumentLoc
PCHReader::ReadTemplateArgumentLoc(const RecordData &Record, unsigned &Index) { PCHReader::ReadTemplateArgumentLoc(const RecordData &Record, unsigned &Index) {
TemplateArgument Arg = ReadTemplateArgument(Record, Index); DeclExprReader DeclExprReader(*this);
return TemplateArgumentLoc(Arg, GetTemplateArgumentLocInfo(Arg.getKind(), return ReadTemplateArgumentLoc(Record, Index, DeclExprReader);
Record, Index));
} }
Decl *PCHReader::GetExternalDecl(uint32_t ID) { Decl *PCHReader::GetExternalDecl(uint32_t ID) {
@ -2995,7 +3025,7 @@ PCHReader::ReadTemplateName(const RecordData &Record, unsigned &Idx) {
return Context->getDependentTemplateName(NNS, return Context->getDependentTemplateName(NNS,
GetIdentifierInfo(Record, Idx)); GetIdentifierInfo(Record, Idx));
return Context->getDependentTemplateName(NNS, return Context->getDependentTemplateName(NNS,
(OverloadedOperatorKind)Record[Idx++]); (OverloadedOperatorKind)Record[Idx++]);
} }
} }
@ -3004,7 +3034,8 @@ PCHReader::ReadTemplateName(const RecordData &Record, unsigned &Idx) {
} }
TemplateArgument TemplateArgument
PCHReader::ReadTemplateArgument(const RecordData &Record, unsigned &Idx) { PCHReader::ReadTemplateArgument(const RecordData &Record, unsigned &Idx,
ExprReader &ExprRdr) {
switch ((TemplateArgument::ArgKind)Record[Idx++]) { switch ((TemplateArgument::ArgKind)Record[Idx++]) {
case TemplateArgument::Null: case TemplateArgument::Null:
return TemplateArgument(); return TemplateArgument();
@ -3020,13 +3051,13 @@ PCHReader::ReadTemplateArgument(const RecordData &Record, unsigned &Idx) {
case TemplateArgument::Template: case TemplateArgument::Template:
return TemplateArgument(ReadTemplateName(Record, Idx)); return TemplateArgument(ReadTemplateName(Record, Idx));
case TemplateArgument::Expression: case TemplateArgument::Expression:
return TemplateArgument(ReadDeclExpr()); return TemplateArgument(ExprRdr.Read());
case TemplateArgument::Pack: { case TemplateArgument::Pack: {
unsigned NumArgs = Record[Idx++]; unsigned NumArgs = Record[Idx++];
llvm::SmallVector<TemplateArgument, 8> Args; llvm::SmallVector<TemplateArgument, 8> Args;
Args.reserve(NumArgs); Args.reserve(NumArgs);
while (NumArgs--) while (NumArgs--)
Args.push_back(ReadTemplateArgument(Record, Idx)); Args.push_back(ReadTemplateArgument(Record, Idx, ExprRdr));
TemplateArgument TemplArg; TemplateArgument TemplArg;
TemplArg.setArgumentPack(Args.data(), Args.size(), /*CopyArgs=*/true); TemplArg.setArgumentPack(Args.data(), Args.size(), /*CopyArgs=*/true);
return TemplArg; return TemplArg;
@ -3037,6 +3068,12 @@ PCHReader::ReadTemplateArgument(const RecordData &Record, unsigned &Idx) {
return TemplateArgument(); return TemplateArgument();
} }
TemplateArgument
PCHReader::ReadTemplateArgument(const RecordData &Record, unsigned &Idx) {
DeclExprReader DeclExprReader(*this);
return ReadTemplateArgument(Record, Idx, DeclExprReader);
}
TemplateParameterList * TemplateParameterList *
PCHReader::ReadTemplateParameterList(const RecordData &Record, unsigned &Idx) { PCHReader::ReadTemplateParameterList(const RecordData &Record, unsigned &Idx) {
SourceLocation TemplateLoc = ReadSourceLocation(Record, Idx); SourceLocation TemplateLoc = ReadSourceLocation(Record, Idx);

Просмотреть файл

@ -18,6 +18,15 @@
using namespace clang; using namespace clang;
namespace { namespace {
class StmtStackExprReader : public PCHReader::ExprReader {
llvm::SmallVectorImpl<Stmt *>::iterator StmtI;
public:
StmtStackExprReader(const llvm::SmallVectorImpl<Stmt *>::iterator &stmtI)
: StmtI(stmtI) { }
virtual Expr *Read() { return cast_or_null<Expr>(*StmtI++); }
};
class PCHStmtReader : public StmtVisitor<PCHStmtReader, unsigned> { class PCHStmtReader : public StmtVisitor<PCHStmtReader, unsigned> {
PCHReader &Reader; PCHReader &Reader;
const PCHReader::RecordData &Record; const PCHReader::RecordData &Record;
@ -1124,6 +1133,7 @@ unsigned PCHStmtReader::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
unsigned unsigned
PCHStmtReader::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){ PCHStmtReader::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
VisitExpr(E); VisitExpr(E);
unsigned NumExprs = 0;
unsigned NumTemplateArgs = Record[Idx++]; unsigned NumTemplateArgs = Record[Idx++];
assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() && assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() &&
@ -1132,8 +1142,17 @@ PCHStmtReader::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
TemplateArgumentListInfo ArgInfo; TemplateArgumentListInfo ArgInfo;
ArgInfo.setLAngleLoc(Reader.ReadSourceLocation(Record, Idx)); ArgInfo.setLAngleLoc(Reader.ReadSourceLocation(Record, Idx));
ArgInfo.setRAngleLoc(Reader.ReadSourceLocation(Record, Idx)); ArgInfo.setRAngleLoc(Reader.ReadSourceLocation(Record, Idx));
NumExprs = Record[Idx++];
llvm::SmallVectorImpl<Stmt *>::iterator
StartOfExprs = StmtStack.end() - NumExprs;
if (isa<UnresolvedMemberExpr>(E))
--StartOfExprs; // UnresolvedMemberExpr contains an Expr;
StmtStackExprReader ExprReader(StartOfExprs);
for (unsigned i = 0; i != NumTemplateArgs; ++i) for (unsigned i = 0; i != NumTemplateArgs; ++i)
ArgInfo.addArgument(Reader.ReadTemplateArgumentLoc(Record, Idx)); ArgInfo.addArgument(Reader.ReadTemplateArgumentLoc(Record, Idx,
ExprReader));
E->initializeTemplateArgumentsFrom(ArgInfo); E->initializeTemplateArgumentsFrom(ArgInfo);
} }
@ -1148,7 +1167,7 @@ PCHStmtReader::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
E->setMember(Reader.ReadDeclarationName(Record, Idx)); E->setMember(Reader.ReadDeclarationName(Record, Idx));
E->setMemberLoc(Reader.ReadSourceLocation(Record, Idx)); E->setMemberLoc(Reader.ReadSourceLocation(Record, Idx));
return 1; return NumExprs + 1;
} }
unsigned unsigned
@ -1167,6 +1186,7 @@ PCHStmtReader::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
unsigned PCHStmtReader::VisitOverloadExpr(OverloadExpr *E) { unsigned PCHStmtReader::VisitOverloadExpr(OverloadExpr *E) {
VisitExpr(E); VisitExpr(E);
unsigned NumExprs = 0;
unsigned NumTemplateArgs = Record[Idx++]; unsigned NumTemplateArgs = Record[Idx++];
assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() && assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() &&
@ -1175,8 +1195,17 @@ unsigned PCHStmtReader::VisitOverloadExpr(OverloadExpr *E) {
TemplateArgumentListInfo ArgInfo; TemplateArgumentListInfo ArgInfo;
ArgInfo.setLAngleLoc(Reader.ReadSourceLocation(Record, Idx)); ArgInfo.setLAngleLoc(Reader.ReadSourceLocation(Record, Idx));
ArgInfo.setRAngleLoc(Reader.ReadSourceLocation(Record, Idx)); ArgInfo.setRAngleLoc(Reader.ReadSourceLocation(Record, Idx));
NumExprs = Record[Idx++];
llvm::SmallVectorImpl<Stmt *>::iterator
StartOfExprs = StmtStack.end() - NumExprs;
if (isa<UnresolvedMemberExpr>(E))
--StartOfExprs; // UnresolvedMemberExpr contains an Expr;
StmtStackExprReader ExprReader(StartOfExprs);
for (unsigned i = 0; i != NumTemplateArgs; ++i) for (unsigned i = 0; i != NumTemplateArgs; ++i)
ArgInfo.addArgument(Reader.ReadTemplateArgumentLoc(Record, Idx)); ArgInfo.addArgument(Reader.ReadTemplateArgumentLoc(Record, Idx,
ExprReader));
E->getExplicitTemplateArgs().initializeFrom(ArgInfo); E->getExplicitTemplateArgs().initializeFrom(ArgInfo);
} }
@ -1193,25 +1222,25 @@ unsigned PCHStmtReader::VisitOverloadExpr(OverloadExpr *E) {
E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx)); E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx));
E->setQualifierRange(Reader.ReadSourceRange(Record, Idx)); E->setQualifierRange(Reader.ReadSourceRange(Record, Idx));
E->setNameLoc(Reader.ReadSourceLocation(Record, Idx)); E->setNameLoc(Reader.ReadSourceLocation(Record, Idx));
return 0; return NumExprs;
} }
unsigned PCHStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { unsigned PCHStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
VisitOverloadExpr(E); unsigned NumExprs = VisitOverloadExpr(E);
E->setArrow(Record[Idx++]); E->setArrow(Record[Idx++]);
E->setHasUnresolvedUsing(Record[Idx++]); E->setHasUnresolvedUsing(Record[Idx++]);
E->setBase(cast_or_null<Expr>(StmtStack.back())); E->setBase(cast_or_null<Expr>(StmtStack.back()));
E->setBaseType(Reader.GetType(Record[Idx++])); E->setBaseType(Reader.GetType(Record[Idx++]));
E->setOperatorLoc(Reader.ReadSourceLocation(Record, Idx)); E->setOperatorLoc(Reader.ReadSourceLocation(Record, Idx));
return 1; return NumExprs + 1;
} }
unsigned PCHStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) { unsigned PCHStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
VisitOverloadExpr(E); unsigned NumExprs = VisitOverloadExpr(E);
E->setRequiresADL(Record[Idx++]); E->setRequiresADL(Record[Idx++]);
E->setOverloaded(Record[Idx++]); E->setOverloaded(Record[Idx++]);
E->setNamingClass(cast_or_null<CXXRecordDecl>(Reader.GetDecl(Record[Idx++]))); E->setNamingClass(cast_or_null<CXXRecordDecl>(Reader.GetDecl(Record[Idx++])));
return 0; return NumExprs;
} }

Просмотреть файл

@ -2057,7 +2057,7 @@ void PCHWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) {
PCHWriter::PCHWriter(llvm::BitstreamWriter &Stream) PCHWriter::PCHWriter(llvm::BitstreamWriter &Stream)
: Stream(Stream), NextTypeID(pch::NUM_PREDEF_TYPE_IDS), : Stream(Stream), NextTypeID(pch::NUM_PREDEF_TYPE_IDS),
NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0), NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0),
NumVisibleDeclContexts(0) { } NumVisibleDeclContexts(0), EmittingStmts(false) { }
void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls, void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
const char *isysroot) { const char *isysroot) {
@ -2302,10 +2302,8 @@ void PCHWriter::AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
AddTypeSourceInfo(Arg.getAsTypeSourceInfo(), Record); AddTypeSourceInfo(Arg.getAsTypeSourceInfo(), Record);
break; break;
case TemplateArgument::Template: case TemplateArgument::Template:
Record.push_back( AddSourceRange(Arg.getTemplateQualifierRange(), Record);
Arg.getTemplateQualifierRange().getBegin().getRawEncoding()); AddSourceLocation(Arg.getTemplateNameLoc(), Record);
Record.push_back(Arg.getTemplateQualifierRange().getEnd().getRawEncoding());
Record.push_back(Arg.getTemplateNameLoc().getRawEncoding());
break; break;
case TemplateArgument::Null: case TemplateArgument::Null:
case TemplateArgument::Integral: case TemplateArgument::Integral:
@ -2318,6 +2316,14 @@ void PCHWriter::AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
void PCHWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg, void PCHWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg,
RecordData &Record) { RecordData &Record) {
AddTemplateArgument(Arg.getArgument(), Record); AddTemplateArgument(Arg.getArgument(), Record);
if (Arg.getArgument().getKind() == TemplateArgument::Expression) {
bool InfoHasSameExpr
= Arg.getArgument().getAsExpr() == Arg.getLocInfo().getAsExpr();
Record.push_back(InfoHasSameExpr);
if (InfoHasSameExpr)
return; // Avoid storing the same expr twice.
}
AddTemplateArgumentLocInfo(Arg.getArgument().getKind(), Arg.getLocInfo(), AddTemplateArgumentLocInfo(Arg.getArgument().getKind(), Arg.getLocInfo(),
Record); Record);
} }

Просмотреть файл

@ -1025,6 +1025,40 @@ void PCHStmtWriter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
Code = pch::EXPR_CXX_EXPR_WITH_TEMPORARIES; Code = pch::EXPR_CXX_EXPR_WITH_TEMPORARIES;
} }
/// \brief Return the number of Exprs contained in the given TemplateArgument.
static unsigned NumExprsContainedIn(const TemplateArgument Arg) {
switch (Arg.getKind()) {
default: break;
case TemplateArgument::Expression:
return 1;
case TemplateArgument::Pack: {
unsigned Count = 0;
for (TemplateArgument::pack_iterator I=Arg.pack_begin(), E=Arg.pack_end();
I != E; ++I)
Count += NumExprsContainedIn(*I);
return Count;
}
}
return 0;
}
/// \brief Return the number of Exprs contained in the given
/// TemplateArgumentLoc.
static
unsigned NumExprsContainedIn(const TemplateArgumentLoc *Args,unsigned NumArgs) {
unsigned Count = 0;
for (unsigned i=0; i != NumArgs; ++i) {
const TemplateArgument &TemplA = Args[i].getArgument();
Count += NumExprsContainedIn(TemplA);
if (TemplA.getKind() == TemplateArgument::Expression &&
TemplA.getAsExpr() != Args[i].getLocInfo().getAsExpr())
++Count; // 1 in TemplateArgumentLocInfo.
}
return Count;
}
void void
PCHStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){ PCHStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
VisitExpr(E); VisitExpr(E);
@ -1035,6 +1069,8 @@ PCHStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
Record.push_back(E->getNumTemplateArgs()); Record.push_back(E->getNumTemplateArgs());
Writer.AddSourceLocation(E->getLAngleLoc(), Record); Writer.AddSourceLocation(E->getLAngleLoc(), Record);
Writer.AddSourceLocation(E->getRAngleLoc(), Record); Writer.AddSourceLocation(E->getRAngleLoc(), Record);
Record.push_back(NumExprsContainedIn(E->getTemplateArgs(),
E->getNumTemplateArgs()));
for (int i=0, e = E->getNumTemplateArgs(); i != e; ++i) for (int i=0, e = E->getNumTemplateArgs(); i != e; ++i)
Writer.AddTemplateArgumentLoc(E->getTemplateArgs()[i], Record); Writer.AddTemplateArgumentLoc(E->getTemplateArgs()[i], Record);
} else { } else {
@ -1080,6 +1116,8 @@ void PCHStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
Record.push_back(Args.NumTemplateArgs); Record.push_back(Args.NumTemplateArgs);
Writer.AddSourceLocation(Args.LAngleLoc, Record); Writer.AddSourceLocation(Args.LAngleLoc, Record);
Writer.AddSourceLocation(Args.RAngleLoc, Record); Writer.AddSourceLocation(Args.RAngleLoc, Record);
Record.push_back(NumExprsContainedIn(Args.getTemplateArgs(),
Args.NumTemplateArgs));
for (unsigned i=0; i != Args.NumTemplateArgs; ++i) for (unsigned i=0; i != Args.NumTemplateArgs; ++i)
Writer.AddTemplateArgumentLoc(Args.getTemplateArgs()[i], Record); Writer.AddTemplateArgumentLoc(Args.getTemplateArgs()[i], Record);
} else { } else {
@ -1178,6 +1216,8 @@ void PCHWriter::WriteSubStmt(Stmt *S) {
void PCHWriter::FlushStmts() { void PCHWriter::FlushStmts() {
RecordData Record; RecordData Record;
PCHStmtWriter Writer(*this, Record); PCHStmtWriter Writer(*this, Record);
EmittingStmts = true;
for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) { for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
++NumStatements; ++NumStatements;
@ -1209,5 +1249,7 @@ void PCHWriter::FlushStmts() {
Stream.EmitRecord(pch::STMT_STOP, Record); Stream.EmitRecord(pch::STMT_STOP, Record);
} }
EmittingStmts = false;
StmtsToEmit.clear(); StmtsToEmit.clear();
} }

Просмотреть файл

@ -15,9 +15,13 @@ struct S<int, float> {
static void explicit_special(); static void explicit_special();
}; };
template <int x>
int tmpl_f2() { return x; }
template <typename T, int y> template <typename T, int y>
T templ_f(T x) { T templ_f(T x) {
int z = templ_f<int, 5>(3); int z = templ_f<int, 5>(3);
z = tmpl_f2<y+2>();
return x+y; return x+y;
} }