2013/6/5 Richard Smith <[email protected]>: > +/// Determine the declaration which an initialized entity ultimately refers > to, > +/// for the purpose of lifetime-extending a temporary bound to a reference in > +/// the initialization of \p Entity. > +static const ValueDecl * > +getDeclForTemporaryLifetimeExtension(const InitializedEntity &Entity, > + const ValueDecl *FallbackDecl = 0) { > + // C++11 [class.temporary]p5: > + switch (Entity.getKind()) { > + case InitializedEntity::EK_Variable: > + // The temporary [...] persists for the lifetime of the reference > + return Entity.getDecl(); > + > + case InitializedEntity::EK_Member: > + // For subobjects, we look at the complete object. > + if (Entity.getParent()) > + return getDeclForTemporaryLifetimeExtension(*Entity.getParent(), > + Entity.getDecl()); > + > + // except: > + // -- A temporary bound to a reference member in a constructor's > + // ctor-initializer persists until the constructor exits. > + return Entity.getDecl(); > + > + case InitializedEntity::EK_Parameter: > + // -- A temporary bound to a reference parameter in a function call > + // persists until the completion of the full-expression containing > + // the call. > + case InitializedEntity::EK_Result: > + // -- The lifetime of a temporary bound to the returned value in a > + // function return statement is not extended; the temporary is > + // destroyed at the end of the full-expression in the return > statement. > + case InitializedEntity::EK_New: > + // -- A temporary bound to a reference in a new-initializer persists > + // until the completion of the full-expression containing the > + // new-initializer. > + return 0; > + > + case InitializedEntity::EK_Temporary: > + case InitializedEntity::EK_CompoundLiteralInit: > + // We don't yet know the storage duration of the surrounding temporary. > + // Assume it's got full-expression duration for now, it will patch up our > + // storage duration if that's not correct. > + return 0; > + > + case InitializedEntity::EK_ArrayElement: > + // For subobjects, we look at the complete object. > + return getDeclForTemporaryLifetimeExtension(*Entity.getParent(), > + FallbackDecl); > + > + case InitializedEntity::EK_Base: > + case InitializedEntity::EK_Delegating: > + // We can reach this case for aggregate initialization in a constructor: > + // struct A { int &&r; }; > + // struct B : A { B() : A{0} {} }; > + // In this case, use the innermost field decl as the context. > + return FallbackDecl; > + > + case InitializedEntity::EK_BlockElement: > + case InitializedEntity::EK_LambdaCapture: > + case InitializedEntity::EK_Exception: > + case InitializedEntity::EK_VectorElement: > + case InitializedEntity::EK_ComplexElement: > + llvm_unreachable("should not materialize a temporary to initialize > this"); > + } > +}
gcc 4.6.3 gives the following warning on this code: In function ‘const clang::ValueDecl* getDeclForTemporaryLifetimeExtension(const clang::InitializedEntity&, const clang::ValueDecl*)’: tools/clang/lib/Sema/SemaInit.cpp:5196:1: warning: control reaches end of non-void function [-Wreturn-type] _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
