From: Ted Kremenek Date: Thu, 15 Nov 2007 18:26:39 +0000 (+0000) Subject: Added hack when serializing DeclRefExprs. This should probably be fixed. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=767dd4b8306c81ab16d9c428ed1d5d39678315bb;p=clang Added hack when serializing DeclRefExprs. This should probably be fixed. 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 --- diff --git a/AST/StmtSerialization.cpp b/AST/StmtSerialization.cpp index a1fdcec0f7..63861d2a21 100644 --- a/AST/StmtSerialization.cpp +++ b/AST/StmtSerialization.cpp @@ -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(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(D.ReadOwnedPtr()); + + return new DeclRefExpr(decl,T,Loc); }