namespace { template T source(); template T* indirect_source(); void sink(...); } typedef unsigned int UINT; typedef long LONG; typedef void* LPVOID; typedef void* PVOID; typedef bool BOOL; typedef char* PSTR, *LPSTR; typedef const char* LPCTSTR; typedef unsigned short WORD; typedef unsigned long DWORD; typedef void* HANDLE; typedef LONG HRESULT; typedef unsigned long ULONG; typedef const char* LPCSTR; typedef wchar_t OLECHAR; typedef OLECHAR* LPOLESTR; typedef const LPOLESTR LPCOLESTR; typedef OLECHAR* BSTR; typedef wchar_t* LPWSTR, *PWSTR; typedef BSTR* LPBSTR; typedef unsigned short USHORT; typedef char *LPTSTR; struct __POSITION { int unused; }; typedef __POSITION* POSITION; typedef WORD ATL_URL_PORT; enum ATL_URL_SCHEME{ ATL_URL_SCHEME_UNKNOWN = -1, ATL_URL_SCHEME_FTP = 0, ATL_URL_SCHEME_GOPHER = 1, ATL_URL_SCHEME_HTTP = 2, ATL_URL_SCHEME_HTTPS = 3, ATL_URL_SCHEME_FILE = 4, ATL_URL_SCHEME_NEWS = 5, ATL_URL_SCHEME_MAILTO = 6, ATL_URL_SCHEME_SOCKS = 7 }; using HINSTANCE = void*; using size_t = decltype(sizeof(int)); using SIZE_T = size_t; #define NULL nullptr typedef struct tagSAFEARRAYBOUND { ULONG cElements; LONG lLbound; } SAFEARRAYBOUND, *LPSAFEARRAYBOUND; typedef struct tagVARIANT { /* ... */ } VARIANT; typedef struct tagSAFEARRAY { USHORT cDims; USHORT fFeatures; ULONG cbElements; ULONG cLocks; PVOID pvData; SAFEARRAYBOUND rgsabound[1]; } SAFEARRAY, *LPSAFEARRAY; struct _U_STRINGorID { _U_STRINGorID(UINT nID); _U_STRINGorID(LPCTSTR lpString); LPCTSTR m_lpstr; }; void test__U_STRINGorID() { { UINT x = source(); _U_STRINGorID u(x); sink(u.m_lpstr); // $ ir } { LPCTSTR y = indirect_source(); _U_STRINGorID u(y); sink(u.m_lpstr); // $ ir } } template struct CA2AEX { LPSTR m_psz; char m_szBuffer[t_nBufferLength]; CA2AEX(LPCSTR psz, UINT nCodePage); CA2AEX(LPCSTR psz); ~CA2AEX(); operator LPSTR() const throw(); }; void test_CA2AEX() { { LPSTR x = indirect_source(); CA2AEX<128> a(x); sink(static_cast(a)); // $ ir sink(a.m_psz); // $ ir sink(a.m_szBuffer); // $ ir } { LPSTR x = indirect_source(); CA2AEX<128> a(x, 0); sink(static_cast(a)); // $ ir sink(a.m_psz); // $ ir sink(a.m_szBuffer); // $ ir } } template struct CA2CAEX { CA2CAEX(LPCSTR psz, UINT nCodePage) ; CA2CAEX(LPCSTR psz) ; ~CA2CAEX() throw(); operator LPCSTR() const throw(); LPCSTR m_psz; }; void test_CA2CAEX() { LPCSTR x = indirect_source(); { CA2CAEX<128> a(x); sink(static_cast(a)); // $ ir sink(a.m_psz); // $ ir sink(a.m_psz); // $ ir } { CA2CAEX<128> a(x, 0); sink(static_cast(a)); // $ ir sink(a.m_psz); // $ ir sink(a.m_psz); // $ ir } } template struct CA2WEX { CA2WEX(LPCSTR psz, UINT nCodePage) ; CA2WEX(LPCSTR psz) ; ~CA2WEX() throw(); operator LPWSTR() const throw(); LPWSTR m_psz; wchar_t m_szBuffer[t_nBufferLength]; }; void test_CA2WEX() { LPCSTR x = indirect_source(); { CA2WEX<128> a(x); sink(static_cast(a)); // $ ir sink(a.m_psz); // $ ir sink(a.m_psz); // $ ir } { CA2WEX<128> a(x, 0); sink(static_cast(a)); // $ ir sink(a.m_psz); // $ ir sink(a.m_psz); // $ ir } } template struct CElementTraitsBase { typedef const T& INARGTYPE; typedef T& OUTARGTYPE; static void CopyElements(T* pDest, const T* pSrc, size_t nElements); static void RelocateElements(T* pDest, T* pSrc, size_t nElements); }; template struct CDefaultElementTraits : public CElementTraitsBase {}; template struct CElementTraits : public CDefaultElementTraits {}; template> struct CAtlArray { using INARGTYPE = typename ETraits::INARGTYPE; using OUTARGTYPE = typename ETraits::OUTARGTYPE; CAtlArray() throw(); ~CAtlArray() throw(); size_t Add(INARGTYPE element); size_t Add(); size_t Append(const CAtlArray& aSrc); void Copy(const CAtlArray& aSrc); const E& GetAt(size_t iElement) const throw(); E& GetAt(size_t iElement) throw(); size_t GetCount() const throw(); E* GetData() throw(); const E* GetData() const throw(); void InsertArrayAt(size_t iStart, const CAtlArray* paNew); void InsertAt(size_t iElement, INARGTYPE element, size_t nCount); bool IsEmpty() const throw(); void RemoveAll() throw(); void RemoveAt(size_t iElement, size_t nCount); void SetAt(size_t iElement, INARGTYPE element); void SetAtGrow(size_t iElement, INARGTYPE element); bool SetCount(size_t nNewSize, int nGrowBy); E& operator[](size_t ielement) throw(); const E& operator[](size_t ielement) const throw(); }; void test_CAtlArray() { int x = source(); { CAtlArray a; a.Add(x); sink(a[0]); // $ ir a.Add(0); sink(a[0]); // $ ir CAtlArray a2; sink(a2[0]); a2.Append(a); sink(a2[0]); // $ ir CAtlArray a3; sink(a3[0]); a3.Copy(a2); sink(a3[0]); // $ ir sink(a3.GetAt(0)); // $ ir sink(*a3.GetData()); // $ ir CAtlArray a4; sink(a4.GetAt(0)); a4.InsertArrayAt(0, &a3); sink(a4.GetAt(0)); // $ ir } { CAtlArray a5; a5.InsertAt(0, source(), 1); sink(a5[0]); // $ ir CAtlArray a6; a6.SetAtGrow(0, source()); sink(a6[0]); // $ ir } } template> struct CAtlList { using INARGTYPE = typename ETraits::INARGTYPE; CAtlList(UINT nBlockSize) throw(); ~CAtlList() throw(); POSITION AddHead(); POSITION AddHead(INARGTYPE element); void AddHeadList(const CAtlList* plNew); POSITION AddTail(); POSITION AddTail(INARGTYPE element); void AddTailList(const CAtlList* plNew); POSITION Find(INARGTYPE element, POSITION posStartAfter) const throw(); POSITION FindIndex(size_t iElement) const throw(); E& GetAt(POSITION pos) throw(); const E& GetAt(POSITION pos) const throw(); size_t GetCount() const throw(); E& GetHead() throw(); const E& GetHead() const throw(); POSITION GetHeadPosition() const throw(); E& GetNext(POSITION& pos) throw(); const E& GetNext(POSITION& pos) const throw(); E& GetPrev(POSITION& pos) throw(); const E& GetPrev(POSITION& pos) const throw(); E& GetTail() throw(); const E& GetTail() const throw(); POSITION GetTailPosition() const throw(); POSITION InsertAfter(POSITION pos, INARGTYPE element); POSITION InsertBefore(POSITION pos, INARGTYPE element); bool IsEmpty() const throw(); void MoveToHead(POSITION pos) throw(); void MoveToTail(POSITION pos) throw(); void RemoveAll() throw(); void RemoveAt(POSITION pos) throw(); E RemoveHead(); void RemoveHeadNoReturn() throw(); E RemoveTail(); void RemoveTailNoReturn() throw(); void SetAt(POSITION pos, INARGTYPE element); void SwapElements(POSITION pos1, POSITION pos2) throw(); }; void test_CAtlList() { int x = source(); { CAtlList list(10); sink(list.GetHead()); list.AddHead(x); sink(list.GetHead()); // $ ir CAtlList list2(10); list2.AddHeadList(&list); sink(list2.GetHead()); // $ ir CAtlList list3(10); list3.AddTail(x); sink(list3.GetHead()); // $ ir CAtlList list4(10); list4.AddTailList(&list3); sink(list4.GetHead()); // $ ir { CAtlList list5(10); auto pos = list5.Find(x, list5.GetHeadPosition()); sink(list5.GetAt(pos)); // $ MISSING: ir } { CAtlList list6(10); list6.AddHead(x); auto pos = list6.FindIndex(0); sink(list6.GetAt(pos)); // $ ir } { CAtlList list7(10); auto pos = list7.GetTailPosition(); list7.InsertAfter(pos, x); sink(list7.GetHead()); // $ ir } { CAtlList list8(10); auto pos = list8.GetTailPosition(); list8.InsertBefore(pos, x); sink(list8.GetHead()); // $ ir } { CAtlList list9(10); list9.SetAt(list9.GetHeadPosition(), x); sink(list9.GetHead()); // $ ir } } int* p = indirect_source(); { CAtlList list(10); sink(list.GetHead()); list.AddHead(p); sink(list.GetHead()); // $ ir CAtlList list2(10); list2.AddHeadList(&list); sink(list2.GetHead()); // $ ir CAtlList list3(10); list3.AddTail(p); sink(list3.GetHead()); // $ ir CAtlList list4(10); list4.AddTailList(&list3); sink(list4.GetHead()); // $ ir { CAtlList list5(10); auto pos = list5.Find(p, list5.GetHeadPosition()); sink(list5.GetAt(pos)); // $ MISSING: ir } { CAtlList list6(10); list6.AddHead(p); auto pos = list6.FindIndex(0); sink(list6.GetAt(pos)); // $ ir } { CAtlList list7(10); auto pos = list7.GetTailPosition(); list7.InsertAfter(pos, p); sink(list7.GetHead()); // $ ir } { CAtlList list8(10); auto pos = list8.GetTailPosition(); list8.InsertBefore(pos, p); sink(list8.GetHead()); // $ ir } { CAtlList list9(10); list9.SetAt(list9.GetHeadPosition(), p); sink(list9.GetHead()); // $ ir } } } struct IUnknown { }; struct ISequentialStream : public IUnknown { }; struct IStream : public ISequentialStream { }; struct CComBSTR { CComBSTR() throw(); CComBSTR(const CComBSTR& src); CComBSTR(int nSize); CComBSTR(int nSize, LPCOLESTR sz); CComBSTR(int nSize, LPCSTR sz); CComBSTR(LPCOLESTR pSrc); CComBSTR(LPCSTR pSrc); CComBSTR(CComBSTR&& src) throw(); ~CComBSTR(); HRESULT Append(const CComBSTR& bstrSrc) throw(); HRESULT Append(wchar_t ch) throw(); HRESULT Append(char ch) throw(); HRESULT Append(LPCOLESTR lpsz) throw(); HRESULT Append(LPCSTR lpsz) throw(); HRESULT Append(LPCOLESTR lpsz, int nLen) throw(); HRESULT AppendBSTR(BSTR p) throw(); HRESULT AppendBytes(const char* lpsz, int nLen) throw(); HRESULT ArrayToBSTR(const SAFEARRAY* pSrc) throw(); HRESULT AssignBSTR(const BSTR bstrSrc) throw(); void Attach(BSTR src) throw(); HRESULT BSTRToArray(LPSAFEARRAY* ppArray) throw(); unsigned int ByteLength() const throw(); BSTR Copy() const throw(); HRESULT CopyTo(BSTR* pbstr) throw(); HRESULT CopyTo(VARIANT* pvarDest) throw(); BSTR Detach() throw(); void Empty() throw(); unsigned int Length() const throw(); bool LoadString(HINSTANCE hInst, UINT nID) throw(); bool LoadString(UINT nID) throw(); HRESULT ReadFromStream(IStream* pStream) throw(); HRESULT ToUpper() throw(); HRESULT WriteToStream(IStream* pStream) throw(); operator BSTR() const throw(); BSTR* operator&() throw(); CComBSTR& operator+= (const CComBSTR& bstrSrc); CComBSTR& operator+= (const LPCOLESTR pszSrc); BSTR m_str; }; LPSAFEARRAY getSafeArray() { SAFEARRAY* safe = new SAFEARRAY; safe->pvData = indirect_source(); return safe; } void test_CComBSTR() { char* x = indirect_source(); { CComBSTR b(x); sink(b.m_str); // $ ir CComBSTR b2(b); sink(b2.m_str); // $ ir } { CComBSTR b(10, x); sink(b.m_str); // $ ir } { CComBSTR b(x); CComBSTR b2; sink(b2.m_str); b2 += b; sink(b2.m_str); // $ ir CComBSTR b3; b3 += x; sink(b3.m_str); // $ ir sink(static_cast(b3)); // $ ir sink(**&b3); // $ ir CComBSTR b4; b4.Append(source()); sink(b4.m_str); // $ ir CComBSTR b5; b5.AppendBSTR(b4.m_str); sink(b5.m_str); // $ ir CComBSTR b6; b6.AppendBytes(x, 10); sink(b6.m_str); // $ ir CComBSTR b7; b7.ArrayToBSTR(getSafeArray()); sink(b7.m_str); // $ ir CComBSTR b8; b8.AssignBSTR(b7.m_str); sink(b8.m_str); // $ ir CComBSTR b9; LPSAFEARRAY safe; b9.Append(source()); b9.BSTRToArray(&safe); sink(safe->pvData); // $ ir sink(b9.Copy()); // $ ir } wchar_t* w = indirect_source(); { CComBSTR b(w); sink(b.m_str); // $ ir CComBSTR b2; b2.Attach(w); sink(b2.m_str); // $ ir } { CComBSTR b(10, w); sink(b.m_str); // $ ir } } template struct CComSafeArray { CComSafeArray(); CComSafeArray(const SAFEARRAYBOUND& bound); CComSafeArray(ULONG ulCount, LONG lLBound); CComSafeArray(const SAFEARRAYBOUND* pBound, UINT uDims); CComSafeArray(const CComSafeArray& saSrc); CComSafeArray(const SAFEARRAY& saSrc); CComSafeArray(const SAFEARRAY* psaSrc); ~CComSafeArray() throw(); HRESULT Add(const SAFEARRAY* psaSrc); HRESULT Add(ULONG ulCount, const T* pT, BOOL bCopy); HRESULT Add(const T& t, BOOL bCopy); HRESULT Attach(const SAFEARRAY* psaSrc); HRESULT CopyFrom(LPSAFEARRAY* ppArray); HRESULT CopyTo(LPSAFEARRAY* ppArray); HRESULT Create(const SAFEARRAYBOUND* pBound, UINT uDims); HRESULT Create(ULONG ulCount, LONG lLBound); HRESULT Destroy(); LPSAFEARRAY Detach(); T& GetAt(LONG lIndex) const; ULONG GetCount(UINT uDim) const; UINT GetDimensions() const; LONG GetLowerBound(UINT uDim) const; LPSAFEARRAY GetSafeArrayPtr() throw(); LONG GetUpperBound(UINT uDim) const; bool IsSizable() const; HRESULT MultiDimGetAt(const LONG* alIndex, T& t); HRESULT MultiDimSetAt(const LONG* alIndex, const T& t); HRESULT Resize(const SAFEARRAYBOUND* pBound); HRESULT Resize(ULONG ulCount, LONG lLBound); HRESULT SetAt(LONG lIndex, const T& t, BOOL bCopy); operator LPSAFEARRAY() const; T& operator[](long lindex) const; T& operator[](int nindex) const; LPSAFEARRAY m_psa; }; void test_CComSafeArray() { LPSAFEARRAY safe = getSafeArray(); sink(safe->pvData); // $ ir { CComSafeArray c(safe); sink(c[0]); // $ ir sink(c.GetAt(0)); // $ ir sink(c.GetSafeArrayPtr()->pvData); // $ ir sink(c.m_psa->pvData); // $ ir } { CComSafeArray c; sink(c[0]); sink(c.GetAt(0)); sink(c.GetSafeArrayPtr()->pvData); c.Add(safe); sink(c[0]); // $ ir sink(c.GetAt(0)); // $ ir sink(c.GetSafeArrayPtr()->pvData); // $ ir sink(static_cast(c)->pvData); // $ ir } { CComSafeArray c; c.Add(source(), true); sink(c[0]); // $ ir sink(c.GetAt(0)); // $ ir sink(c.GetSafeArrayPtr()->pvData); // $ ir } { CComSafeArray c; c.SetAt(0, source(), true); sink(c[0]); // $ ir sink(c[0L]); // $ ir } } template struct CPathT { typedef StringType PCXSTR; // simplified CPathT(PCXSTR pszPath); CPathT(const CPathT& path); CPathT() throw(); void AddBackslash(); BOOL AddExtension(PCXSTR pszExtension); BOOL Append(PCXSTR pszMore); void BuildRoot(int iDrive); void Canonicalize(); void Combine(PCXSTR pszDir, PCXSTR pszFile); CPathT CommonPrefix(PCXSTR pszOther); BOOL CompactPathEx(UINT nMaxChars, DWORD dwFlags); BOOL FileExists() const; int FindExtension() const; int FindFileName() const; int GetDriveNumber() const; StringType GetExtension() const; BOOL IsDirectory() const; BOOL IsFileSpec() const; BOOL IsPrefix(PCXSTR pszPrefix) const; BOOL IsRelative() const; BOOL IsRoot() const; BOOL IsSameRoot(PCXSTR pszOther) const; BOOL IsUNC() const; BOOL IsUNCServer() const; BOOL IsUNCServerShare() const; BOOL MakePretty(); BOOL MatchSpec(PCXSTR pszSpec) const; void QuoteSpaces(); BOOL RelativePathTo( PCXSTR pszFrom, DWORD dwAttrFrom, PCXSTR pszTo, DWORD dwAttrTo); void RemoveArgs(); void RemoveBackslash(); void RemoveBlanks(); void RemoveExtension(); BOOL RemoveFileSpec(); BOOL RenameExtension(PCXSTR pszExtension); int SkipRoot() const; void StripPath(); BOOL StripToRoot(); void UnquoteSpaces(); operator const StringType&() const throw(); operator PCXSTR() const throw(); operator StringType&() throw(); CPathT& operator+=(PCXSTR pszMore); StringType m_strPath; }; using CPath = CPathT; void test_CPathT() { char* x = indirect_source(); CPath p(x); sink(static_cast(p)); // $ MISSING: ir sink(p.m_strPath); // $ ir CPath p2(p); sink(p2.m_strPath); // $ ir { CPath p; p.AddExtension(x); sink(p.m_strPath); // $ ir } { CPath p; p.Append(x); sink(p.m_strPath); // $ ir CPath p2; p2 += p; sink(p2.m_strPath); // $ MISSING: ir // this requires flow through `operator StringType&()` which we can't yet model in MaD CPath p3; p3 += x; sink(p3.m_strPath); // $ ir } { CPath p; p.Combine(x, nullptr); sink(p.m_strPath); // $ ir } { CPath p; p.Combine(nullptr, x); sink(p.m_strPath); // $ ir } { CPath p; auto p2 = p.CommonPrefix(x); sink(p2.m_strPath); // $ ir sink(p2.GetExtension()); // $ ir } } template struct CSimpleArray { CSimpleArray(const CSimpleArray& src); CSimpleArray(); ~CSimpleArray(); BOOL Add(const T& t); int Find(const T& t) const; T* GetData() const; int GetSize() const; BOOL Remove(const T& t); void RemoveAll(); BOOL RemoveAt(int nIndex); BOOL SetAtIndex( int nIndex, const T& t); T& operator[](int nindex); CSimpleArray & operator=(const CSimpleArray& src); }; void test_CSimpleArray() { int x = source(); { CSimpleArray a; a.Add(x); sink(a[0]); // $ ir a.Add(0); sink(a[0]); // $ ir CSimpleArray a2; sink(a2[0]); a2 = a; sink(a2[0]); // $ ir } { CSimpleArray a; a.Add(x); sink(a.GetData()); // $ ir CSimpleArray a2; int pos = a2.Find(x); sink(a2[pos]); // $ MISSING: ir } } template struct CSimpleMap { CSimpleMap(); ~CSimpleMap(); BOOL Add(const TKey& key, const TVal& val); int FindKey(const TKey& key) const; int FindVal(const TVal& val) const; TKey& GetKeyAt(int nIndex) const; int GetSize() const; TVal& GetValueAt(int nIndex) const; TVal Lookup(const TKey& key) const; BOOL Remove(const TKey& key); void RemoveAll(); BOOL RemoveAt(int nIndex); TKey ReverseLookup(const TVal& val) const; BOOL SetAt(const TKey& key, const TVal& val); BOOL SetAtIndex(int nIndex, const TKey& key, const TVal& val); }; void test_CSimpleMap() { wchar_t* x = source(); { CSimpleMap a; a.Add("hello", x); sink(a.Lookup("hello")); // $ ir } { CSimpleMap a; auto pos = a.FindKey("hello"); sink(a.GetValueAt(pos)); // clean } { CSimpleMap a; auto pos = a.FindVal(x); sink(a.GetValueAt(pos)); // $ MISSING: ir } { CSimpleMap a; auto key = a.ReverseLookup(x); sink(key); sink(a.Lookup(key)); // $ MISSING: ir } { CSimpleMap a; a.SetAt("hello", x); sink(a.Lookup("hello")); // $ ir } { CSimpleMap a; a.SetAtIndex(0, "hello", x); sink(a.Lookup("hello")); // $ ir } } struct CUrl { CUrl& operator= (const CUrl& urlThat) throw(); CUrl() throw(); CUrl(const CUrl& urlThat) throw(); ~CUrl() throw(); inline BOOL Canonicalize(DWORD dwFlags) throw(); inline void Clear() throw(); BOOL CrackUrl(LPCTSTR lpszUrl, DWORD dwFlags) throw(); inline BOOL CreateUrl(LPTSTR lpszUrl, DWORD* pdwMaxLength, DWORD dwFlags) const throw(); inline LPCTSTR GetExtraInfo() const throw(); inline DWORD GetExtraInfoLength() const throw(); inline LPCTSTR GetHostName() const throw(); inline DWORD GetHostNameLength() const throw(); inline LPCTSTR GetPassword() const throw(); inline DWORD GetPasswordLength() const throw(); inline ATL_URL_PORT GetPortNumber() const throw(); inline ATL_URL_SCHEME GetScheme() const throw(); inline LPCTSTR GetSchemeName() const throw(); inline DWORD GetSchemeNameLength() const throw(); inline DWORD GetUrlLength() const throw(); inline LPCTSTR GetUrlPath() const throw(); inline DWORD GetUrlPathLength() const throw(); inline LPCTSTR GetUserName() const throw(); inline DWORD GetUserNameLength() const throw(); inline BOOL SetExtraInfo(LPCTSTR lpszInfo) throw(); inline BOOL SetHostName(LPCTSTR lpszHost) throw(); inline BOOL SetPassword(LPCTSTR lpszPass) throw(); inline BOOL SetPortNumber(ATL_URL_PORT nPrt) throw(); inline BOOL SetScheme(ATL_URL_SCHEME nScheme) throw(); inline BOOL SetSchemeName(LPCTSTR lpszSchm) throw(); inline BOOL SetUrlPath(LPCTSTR lpszPath) throw(); inline BOOL SetUserName(LPCTSTR lpszUser) throw(); }; void test_CUrl() { char* x = indirect_source(); CUrl url; url.CrackUrl(x, 0); sink(url); // $ ir sink(url.GetExtraInfo()); // $ ir sink(url.GetHostName()); // $ ir sink(url.GetPassword()); // $ ir sink(url.GetSchemeName()); // $ ir sink(url.GetUrlPath()); // $ ir sink(url.GetUserName()); // $ ir { CUrl url2; DWORD len; char buffer[1024]; url2.CrackUrl(x, 0); url2.CreateUrl(buffer, &len, 0); sink(buffer); // $ ast ir } { CUrl url2; url2.SetExtraInfo(x); sink(url2); // $ ir } { CUrl url2; url2.SetHostName(x); sink(url2); // $ ir } { CUrl url2; url2.SetPassword(x); sink(url2); // $ ir } { CUrl url2; url2.SetSchemeName(x); sink(url2); // $ ir } { CUrl url2; url2.SetUrlPath(x); sink(url2); // $ ir } { CUrl url2; url2.SetUserName(x); sink(url2); // $ ir } }