[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