[cfe-commits] r106996 - in /cfe/trunk: include/clang/Frontend/PCHReader.h include/clang/Frontend/PCHWriter.h lib/Frontend/PCHReader.cpp lib/Frontend/PCHReaderStmt.cpp lib/Frontend/PCHWriter.cpp lib/Frontend/PCHWriterStmt.cpp test/PCH/cxx-templates.h
Argyrios Kyrtzidis
akyrtzi at gmail.com
Mon Jun 28 02:31:42 PDT 2010
Author: akirtzidis
Date: Mon Jun 28 04:31:42 2010
New Revision: 106996
URL: http://llvm.org/viewvc/llvm-project?rev=106996&view=rev
Log:
Fix PCH emitting/reading for template arguments that contain expressions.
Modified:
cfe/trunk/include/clang/Frontend/PCHReader.h
cfe/trunk/include/clang/Frontend/PCHWriter.h
cfe/trunk/lib/Frontend/PCHReader.cpp
cfe/trunk/lib/Frontend/PCHReaderStmt.cpp
cfe/trunk/lib/Frontend/PCHWriter.cpp
cfe/trunk/lib/Frontend/PCHWriterStmt.cpp
cfe/trunk/test/PCH/cxx-templates.h
Modified: cfe/trunk/include/clang/Frontend/PCHReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHReader.h?rev=106996&r1=106995&r2=106996&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHReader.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHReader.h Mon Jun 28 04:31:42 2010
@@ -563,6 +563,19 @@
/// \brief Read preprocessed entities into the
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
/// given TemplateArgument kind.
TemplateArgumentLocInfo
@@ -571,6 +584,11 @@
/// \brief Reads a TemplateArgumentLoc.
TemplateArgumentLoc ReadTemplateArgumentLoc(const RecordData &Record,
+ unsigned &Idx,
+ ExprReader &ExprRdr);
+
+ /// \brief Reads a TemplateArgumentLoc.
+ TemplateArgumentLoc ReadTemplateArgumentLoc(const RecordData &Record,
unsigned &Idx);
/// \brief Reads a declarator info from the given record.
@@ -701,6 +719,10 @@
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.
TemplateArgument ReadTemplateArgument(const RecordData &Record,unsigned &Idx);
/// \brief Read a template parameter list.
Modified: cfe/trunk/include/clang/Frontend/PCHWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHWriter.h?rev=106996&r1=106995&r2=106996&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHWriter.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHWriter.h Mon Jun 28 04:31:42 2010
@@ -211,6 +211,9 @@
/// file.
unsigned NumVisibleDeclContexts;
+ /// \brief True when we are in Stmts emitting mode.
+ bool EmittingStmts;
+
void WriteBlockInfoBlock();
void WriteMetadata(ASTContext &Context, const char *isysroot);
void WriteLanguageOptions(const LangOptions &LangOpts);
@@ -355,7 +358,12 @@
/// type or declaration has been written, call FlushStmts() to write
/// the corresponding statements just after the type or
/// 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.
void WriteSubStmt(Stmt *S);
Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=106996&r1=106995&r2=106996&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Mon Jun 28 04:31:42 2010
@@ -321,6 +321,18 @@
// 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,
const char *isysroot)
: Listener(new PCHValidator(PP, *this)), SourceMgr(PP.getSourceManager()),
@@ -2499,19 +2511,16 @@
TemplateArgumentLocInfo
PCHReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
const RecordData &Record,
- unsigned &Index) {
+ unsigned &Index, ExprReader &ExprRdr) {
switch (Kind) {
case TemplateArgument::Expression:
- return ReadDeclExpr();
+ return ExprRdr.Read();
case TemplateArgument::Type:
return GetTypeSourceInfo(Record, Index);
case TemplateArgument::Template: {
- SourceLocation
- QualStart = SourceLocation::getFromRawEncoding(Record[Index++]),
- QualEnd = SourceLocation::getFromRawEncoding(Record[Index++]),
- TemplateNameLoc = SourceLocation::getFromRawEncoding(Record[Index++]);
- return TemplateArgumentLocInfo(SourceRange(QualStart, QualEnd),
- TemplateNameLoc);
+ SourceRange QualifierRange = ReadSourceRange(Record, Index);
+ SourceLocation TemplateNameLoc = ReadSourceLocation(Record, Index);
+ return TemplateArgumentLocInfo(QualifierRange, TemplateNameLoc);
}
case TemplateArgument::Null:
case TemplateArgument::Integral:
@@ -2523,11 +2532,32 @@
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) {
- TemplateArgument Arg = ReadTemplateArgument(Record, Index);
+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));
+ Record, Index,
+ ExprRdr));
+}
+
+TemplateArgumentLoc
+PCHReader::ReadTemplateArgumentLoc(const RecordData &Record, unsigned &Index) {
+ DeclExprReader DeclExprReader(*this);
+ return ReadTemplateArgumentLoc(Record, Index, DeclExprReader);
}
Decl *PCHReader::GetExternalDecl(uint32_t ID) {
@@ -2995,7 +3025,7 @@
return Context->getDependentTemplateName(NNS,
GetIdentifierInfo(Record, Idx));
return Context->getDependentTemplateName(NNS,
- (OverloadedOperatorKind)Record[Idx++]);
+ (OverloadedOperatorKind)Record[Idx++]);
}
}
@@ -3004,7 +3034,8 @@
}
TemplateArgument
-PCHReader::ReadTemplateArgument(const RecordData &Record, unsigned &Idx) {
+PCHReader::ReadTemplateArgument(const RecordData &Record, unsigned &Idx,
+ ExprReader &ExprRdr) {
switch ((TemplateArgument::ArgKind)Record[Idx++]) {
case TemplateArgument::Null:
return TemplateArgument();
@@ -3020,13 +3051,13 @@
case TemplateArgument::Template:
return TemplateArgument(ReadTemplateName(Record, Idx));
case TemplateArgument::Expression:
- return TemplateArgument(ReadDeclExpr());
+ return TemplateArgument(ExprRdr.Read());
case TemplateArgument::Pack: {
unsigned NumArgs = Record[Idx++];
llvm::SmallVector<TemplateArgument, 8> Args;
Args.reserve(NumArgs);
while (NumArgs--)
- Args.push_back(ReadTemplateArgument(Record, Idx));
+ Args.push_back(ReadTemplateArgument(Record, Idx, ExprRdr));
TemplateArgument TemplArg;
TemplArg.setArgumentPack(Args.data(), Args.size(), /*CopyArgs=*/true);
return TemplArg;
@@ -3037,6 +3068,12 @@
return TemplateArgument();
}
+TemplateArgument
+PCHReader::ReadTemplateArgument(const RecordData &Record, unsigned &Idx) {
+ DeclExprReader DeclExprReader(*this);
+ return ReadTemplateArgument(Record, Idx, DeclExprReader);
+}
+
TemplateParameterList *
PCHReader::ReadTemplateParameterList(const RecordData &Record, unsigned &Idx) {
SourceLocation TemplateLoc = ReadSourceLocation(Record, Idx);
Modified: cfe/trunk/lib/Frontend/PCHReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderStmt.cpp?rev=106996&r1=106995&r2=106996&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderStmt.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderStmt.cpp Mon Jun 28 04:31:42 2010
@@ -18,6 +18,15 @@
using namespace clang;
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> {
PCHReader &Reader;
const PCHReader::RecordData &Record;
@@ -1124,6 +1133,7 @@
unsigned
PCHStmtReader::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
VisitExpr(E);
+ unsigned NumExprs = 0;
unsigned NumTemplateArgs = Record[Idx++];
assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() &&
@@ -1132,8 +1142,17 @@
TemplateArgumentListInfo ArgInfo;
ArgInfo.setLAngleLoc(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)
- ArgInfo.addArgument(Reader.ReadTemplateArgumentLoc(Record, Idx));
+ ArgInfo.addArgument(Reader.ReadTemplateArgumentLoc(Record, Idx,
+ ExprReader));
+
E->initializeTemplateArgumentsFrom(ArgInfo);
}
@@ -1148,7 +1167,7 @@
E->setMember(Reader.ReadDeclarationName(Record, Idx));
E->setMemberLoc(Reader.ReadSourceLocation(Record, Idx));
- return 1;
+ return NumExprs + 1;
}
unsigned
@@ -1167,6 +1186,7 @@
unsigned PCHStmtReader::VisitOverloadExpr(OverloadExpr *E) {
VisitExpr(E);
+ unsigned NumExprs = 0;
unsigned NumTemplateArgs = Record[Idx++];
assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() &&
@@ -1175,8 +1195,17 @@
TemplateArgumentListInfo ArgInfo;
ArgInfo.setLAngleLoc(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)
- ArgInfo.addArgument(Reader.ReadTemplateArgumentLoc(Record, Idx));
+ ArgInfo.addArgument(Reader.ReadTemplateArgumentLoc(Record, Idx,
+ ExprReader));
+
E->getExplicitTemplateArgs().initializeFrom(ArgInfo);
}
@@ -1193,25 +1222,25 @@
E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx));
E->setQualifierRange(Reader.ReadSourceRange(Record, Idx));
E->setNameLoc(Reader.ReadSourceLocation(Record, Idx));
- return 0;
+ return NumExprs;
}
unsigned PCHStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
- VisitOverloadExpr(E);
+ unsigned NumExprs = VisitOverloadExpr(E);
E->setArrow(Record[Idx++]);
E->setHasUnresolvedUsing(Record[Idx++]);
E->setBase(cast_or_null<Expr>(StmtStack.back()));
E->setBaseType(Reader.GetType(Record[Idx++]));
E->setOperatorLoc(Reader.ReadSourceLocation(Record, Idx));
- return 1;
+ return NumExprs + 1;
}
unsigned PCHStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
- VisitOverloadExpr(E);
+ unsigned NumExprs = VisitOverloadExpr(E);
E->setRequiresADL(Record[Idx++]);
E->setOverloaded(Record[Idx++]);
E->setNamingClass(cast_or_null<CXXRecordDecl>(Reader.GetDecl(Record[Idx++])));
- return 0;
+ return NumExprs;
}
Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=106996&r1=106995&r2=106996&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Mon Jun 28 04:31:42 2010
@@ -2057,7 +2057,7 @@
PCHWriter::PCHWriter(llvm::BitstreamWriter &Stream)
: Stream(Stream), NextTypeID(pch::NUM_PREDEF_TYPE_IDS),
NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0),
- NumVisibleDeclContexts(0) { }
+ NumVisibleDeclContexts(0), EmittingStmts(false) { }
void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
const char *isysroot) {
@@ -2302,10 +2302,8 @@
AddTypeSourceInfo(Arg.getAsTypeSourceInfo(), Record);
break;
case TemplateArgument::Template:
- Record.push_back(
- Arg.getTemplateQualifierRange().getBegin().getRawEncoding());
- Record.push_back(Arg.getTemplateQualifierRange().getEnd().getRawEncoding());
- Record.push_back(Arg.getTemplateNameLoc().getRawEncoding());
+ AddSourceRange(Arg.getTemplateQualifierRange(), Record);
+ AddSourceLocation(Arg.getTemplateNameLoc(), Record);
break;
case TemplateArgument::Null:
case TemplateArgument::Integral:
@@ -2318,6 +2316,14 @@
void PCHWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg,
RecordData &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(),
Record);
}
Modified: cfe/trunk/lib/Frontend/PCHWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriterStmt.cpp?rev=106996&r1=106995&r2=106996&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriterStmt.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriterStmt.cpp Mon Jun 28 04:31:42 2010
@@ -1025,6 +1025,40 @@
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
PCHStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
VisitExpr(E);
@@ -1035,6 +1069,8 @@
Record.push_back(E->getNumTemplateArgs());
Writer.AddSourceLocation(E->getLAngleLoc(), Record);
Writer.AddSourceLocation(E->getRAngleLoc(), Record);
+ Record.push_back(NumExprsContainedIn(E->getTemplateArgs(),
+ E->getNumTemplateArgs()));
for (int i=0, e = E->getNumTemplateArgs(); i != e; ++i)
Writer.AddTemplateArgumentLoc(E->getTemplateArgs()[i], Record);
} else {
@@ -1080,6 +1116,8 @@
Record.push_back(Args.NumTemplateArgs);
Writer.AddSourceLocation(Args.LAngleLoc, Record);
Writer.AddSourceLocation(Args.RAngleLoc, Record);
+ Record.push_back(NumExprsContainedIn(Args.getTemplateArgs(),
+ Args.NumTemplateArgs));
for (unsigned i=0; i != Args.NumTemplateArgs; ++i)
Writer.AddTemplateArgumentLoc(Args.getTemplateArgs()[i], Record);
} else {
@@ -1178,6 +1216,8 @@
void PCHWriter::FlushStmts() {
RecordData Record;
PCHStmtWriter Writer(*this, Record);
+
+ EmittingStmts = true;
for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
++NumStatements;
@@ -1209,5 +1249,7 @@
Stream.EmitRecord(pch::STMT_STOP, Record);
}
+ EmittingStmts = false;
+
StmtsToEmit.clear();
}
Modified: cfe/trunk/test/PCH/cxx-templates.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-templates.h?rev=106996&r1=106995&r2=106996&view=diff
==============================================================================
--- cfe/trunk/test/PCH/cxx-templates.h (original)
+++ cfe/trunk/test/PCH/cxx-templates.h Mon Jun 28 04:31:42 2010
@@ -15,9 +15,13 @@
static void explicit_special();
};
+template <int x>
+int tmpl_f2() { return x; }
+
template <typename T, int y>
T templ_f(T x) {
int z = templ_f<int, 5>(3);
+ z = tmpl_f2<y+2>();
return x+y;
}
More information about the cfe-commits
mailing list