]> granicus.if.org Git - clang/commitdiff
Added hack when serializing DeclRefExprs. This should probably be fixed.
authorTed Kremenek <kremenek@apple.com>
Thu, 15 Nov 2007 18:26:39 +0000 (18:26 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 15 Nov 2007 18:26:39 +0000 (18:26 +0000)
Some FunctionDecls do not appear at the top-level or are owned by a DeclStmt.
In calls to implicitly defined functions, a FunctionDecl is created, but only
the DeclRefExprs reference them. Since an implicitly defined function may be
called multiple times, there is no clear ownership model for such objects.

Temporary solution: when serializing out DeclRefExprs, emit an ownership bit
for the Decl. This bit is determined by querying the serializer to see if the
Decl has already been serialized. If it hasn't, emit the Decl as an owned
pointer.

I repeat: this is a hack.  This should be fixed.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44176 91177308-0d34-0410-b5e6-96231b3b80d8

AST/StmtSerialization.cpp

index a1fdcec0f75f52c64d93ab49750b159966074eb9..63861d2a210ffe461f3e712fc6ff46a259495242 100644 (file)
@@ -375,15 +375,40 @@ void DeclStmt::EmitImpl(Serializer& S) const {
 void DeclRefExpr::EmitImpl(Serializer& S) const {
   S.Emit(Loc);
   S.Emit(getType());
-  S.EmitPtr(getDecl());
+  
+  // Some DeclRefExprs can actually hold the owning reference to a decl.
+  // This occurs when an implicitly defined function is called, and
+  // the decl does not appear in the source file.  We thus check if the
+  // decl pointer has been registered, and if not, emit an owned pointer.
+
+  // FIXME: While this will work for serialization, it won't work for
+  //  memory management.  The only reason this works for serialization is
+  //  because we are tracking all serialized pointers.  Either DeclRefExpr
+  //  needs an explicit bit indicating that it owns the the object,
+  //  or we need a different ownership model.
+  
+  if (S.isRegistered(getDecl())) {
+    S.EmitBool(false);
+    S.EmitPtr(getDecl());
+  }
+  else {
+    S.EmitBool(true);
+    S.EmitOwnedPtr(cast<Decl>(getDecl()));
+  }    
 }
 
 DeclRefExpr* DeclRefExpr::CreateImpl(Deserializer& D) {
   SourceLocation Loc = SourceLocation::ReadVal(D);
-  QualType T = QualType::ReadVal(D);
-  DeclRefExpr* dr = new DeclRefExpr(NULL,T,Loc);
-  D.ReadPtr(dr->D,false);  
-  return dr;
+  QualType T = QualType::ReadVal(D);  
+  bool OwnsDecl = D.ReadBool();
+  ValueDecl* decl;
+  
+  if (!OwnsDecl)
+    D.ReadPtr(decl,false); // No backpatching.
+  else
+    decl = cast<ValueDecl>(D.ReadOwnedPtr<Decl>());
+  
+  return new DeclRefExpr(decl,T,Loc);
 }