]> granicus.if.org Git - clang/commitdiff
Support DependentScopeDeclRefExpr for PCH.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 28 Jun 2010 09:31:56 +0000 (09:31 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 28 Jun 2010 09:31:56 +0000 (09:31 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106998 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ExprCXX.h
include/clang/Frontend/PCHBitCodes.h
lib/AST/ExprCXX.cpp
lib/Frontend/PCHReaderStmt.cpp
lib/Frontend/PCHWriterStmt.cpp
test/PCH/cxx-templates.h

index 534ffa4e55d7318afe37cb7df24f1090e7d232a3..4305adbddca5b7784ad9fdd8b04f1500914a6b25 100644 (file)
@@ -1656,18 +1656,25 @@ public:
                                            SourceLocation NameLoc,
                               const TemplateArgumentListInfo *TemplateArgs = 0);
 
+  static DependentScopeDeclRefExpr *CreateEmpty(ASTContext &C,
+                                                unsigned NumTemplateArgs);
+
   /// \brief Retrieve the name that this expression refers to.
   DeclarationName getDeclName() const { return Name; }
+  void setDeclName(DeclarationName N) { Name =  N; }
 
   /// \brief Retrieve the location of the name within the expression.
   SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
 
   /// \brief Retrieve the source range of the nested-name-specifier.
   SourceRange getQualifierRange() const { return QualifierRange; }
+  void setQualifierRange(SourceRange R) { QualifierRange = R; }
 
   /// \brief Retrieve the nested-name-specifier that qualifies this
   /// declaration.
   NestedNameSpecifier *getQualifier() const { return Qualifier; }
+  void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
 
   /// Determines whether this lookup had explicit template arguments.
   bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
@@ -1676,6 +1683,11 @@ public:
   // nodes, users are *forbidden* from calling these methods on objects
   // without explicit template arguments.
 
+  ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
+    assert(hasExplicitTemplateArgs());
+    return *reinterpret_cast<ExplicitTemplateArgumentList*>(this + 1);
+  }
+
   /// Gets a reference to the explicit template argument list.
   const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
     assert(hasExplicitTemplateArgs());
index 0abe65747592694a0ea73f9573951e2b6b45f699..31864183d3fcda9e0c8630314b322659ac4e82ca 100644 (file)
@@ -772,6 +772,7 @@ namespace clang {
       EXPR_CXX_EXPR_WITH_TEMPORARIES, // CXXExprWithTemporaries
       
       EXPR_CXX_DEPENDENT_SCOPE_MEMBER, // CXXDependentScopeMemberExpr
+      EXPR_CXX_DEPENDENT_SCOPE_DECL_REF,   // DependentScopeDeclRefExpr
       EXPR_CXX_UNRESOLVED_CONSTRUCT, // CXXUnresolvedConstructExpr
       EXPR_CXX_UNRESOLVED_MEMBER,    // UnresolvedMemberExpr
       EXPR_CXX_UNRESOLVED_LOOKUP     // UnresolvedLookupExpr
index b31c448ff0eba065f58952d373e7f82c31a1630f..08d8ae46b460188c68dee203b5bc9799ac628b3c 100644 (file)
@@ -290,6 +290,19 @@ DependentScopeDeclRefExpr::Create(ASTContext &C,
   return DRE;
 }
 
+DependentScopeDeclRefExpr *
+DependentScopeDeclRefExpr::CreateEmpty(ASTContext &C,
+                                       unsigned NumTemplateArgs) {
+  std::size_t size = sizeof(DependentScopeDeclRefExpr);
+  if (NumTemplateArgs)
+    size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
+  void *Mem = C.Allocate(size);
+
+  return new (Mem) DependentScopeDeclRefExpr(QualType(), 0, SourceRange(),
+                                             DeclarationName(),SourceLocation(),
+                                             NumTemplateArgs != 0);
+}
+
 StmtIterator DependentScopeDeclRefExpr::child_begin() {
   return child_iterator();
 }
index a2334d7330baf321127bc30965b6ca084fed95f9..5f9ee3b25f8ec95a4a26cebabb3d844bb8c8c6dd 100644 (file)
@@ -147,6 +147,7 @@ namespace {
     unsigned VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E);
     
     unsigned VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
+    unsigned VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
     unsigned VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
 
     unsigned VisitOverloadExpr(OverloadExpr *E);
@@ -1184,6 +1185,26 @@ PCHStmtReader::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
   return NumExprs + 1;
 }
 
+unsigned
+PCHStmtReader::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
+  VisitExpr(E);
+  unsigned NumExprs = 0;
+  
+  unsigned NumTemplateArgs = Record[Idx++];
+  assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() &&
+         "Read wrong record during creation ?");
+  if (E->hasExplicitTemplateArgs())
+    NumExprs
+      = ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(),
+                                         NumTemplateArgs, StmtStack.end());
+
+  E->setDeclName(Reader.ReadDeclarationName(Record, Idx));
+  E->setLocation(Reader.ReadSourceLocation(Record, Idx));
+  E->setQualifierRange(Reader.ReadSourceRange(Record, Idx));
+  E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx));
+  return NumExprs;
+}
+
 unsigned
 PCHStmtReader::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
   VisitExpr(E);
@@ -1635,6 +1656,11 @@ Stmt *PCHReader::ReadStmt(llvm::BitstreamCursor &Cursor) {
                       /*NumTemplateArgs=*/Record[PCHStmtReader::NumExprFields]);
       break;
       
+    case pch::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF:
+      S = DependentScopeDeclRefExpr::CreateEmpty(*Context,
+                      /*NumTemplateArgs=*/Record[PCHStmtReader::NumExprFields]);
+      break;
+      
     case pch::EXPR_CXX_UNRESOLVED_CONSTRUCT:
       S = CXXUnresolvedConstructExpr::CreateEmpty(*Context,
                               /*NumArgs=*/Record[PCHStmtReader::NumExprFields]);
index a3f18dea39a3caa617301a8b684a11b9fcc9fd48..d3e1e1aab74e46e6766e6412590e27dd54bb366d 100644 (file)
@@ -137,6 +137,7 @@ namespace {
 
     void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E);
     void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
+    void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
     void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
 
     void VisitOverloadExpr(OverloadExpr *E);
@@ -1103,6 +1104,29 @@ PCHStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
   Code = pch::EXPR_CXX_DEPENDENT_SCOPE_MEMBER;
 }
 
+void
+PCHStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
+  VisitExpr(E);
+  
+  // Don't emit anything here, NumTemplateArgs must be emitted first.
+
+  if (E->hasExplicitTemplateArgs()) {
+    const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs();
+    assert(Args.NumTemplateArgs &&
+           "Num of template args was zero! PCH reading will mess up!");
+    Record.push_back(Args.NumTemplateArgs);
+    AddExplicitTemplateArgumentList(Args);
+  } else {
+    Record.push_back(0);
+  }
+
+  Writer.AddDeclarationName(E->getDeclName(), Record);
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Writer.AddSourceRange(E->getQualifierRange(), Record);
+  Writer.AddNestedNameSpecifier(E->getQualifier(), Record);
+  Code = pch::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF;
+}
+
 void
 PCHStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
   VisitExpr(E);
index ca4a29fde771f039c62abcf34cbe9c9d682dd68f..bfc0def146a371ac7bf688bb032493985ae20620 100644 (file)
@@ -51,5 +51,6 @@ struct Dep {
 
 template<typename T, typename A1>
 inline T make_a(const A1& a1) {
+  T::depend_declref();
   return T(a1);
 }