WikiStart: clang_bgq_r157921-20120603.patch

File clang_bgq_r157921-20120603.patch, 141.6 KB (added by hfinkel, 5 years ago)
  • docs/LanguageExtensions.html

    diff --git a/docs/LanguageExtensions.html b/docs/LanguageExtensions.html
    index 92db81f..ba095da 100644
    a b  
    141141    <li><a href="#ts_slr"><tt>shared_locks_required(...)</tt></a></li>    
    142142    </ul> 
    143143</li> 
     144<li><a href="#type_safety">Type Safety Checking</a> 
     145  <ul> 
     146  <li><a href="#argument_with_type_tag"><tt>argument_with_type_tag(...)</tt></a></li> 
     147  <li><a href="#pointer_with_type_tag"><tt>pointer_with_type_tag(...)</tt></a></li> 
     148  <li><a href="#type_tag_for_datatype"><tt>type_tag_for_datatype(...)</tt></a></li> 
     149  </ul> 
     150</li> 
    144151</ul> 
    145152 
    146153<!-- ======================================================================= --> 
     
    18661873shared locks. Arguments must be lockable type, and there must be at  
    18671874least one argument.</p>  
    18681875 
     1876<!-- ======================================================================= --> 
     1877<h2 id="type_safety">Type Safety Checking</h2> 
     1878<!-- ======================================================================= --> 
     1879 
     1880<p>Clang supports additional attributes to enable checking type safety 
     1881properties that can't be enforced by C type system.  Usecases include:</p> 
     1882<ul> 
     1883<li>MPI library implementations, where these attributes enable checking that 
     1884    buffer type matches the passed <tt>MPI_Datatype</tt>;</li> 
     1885<li>for HDF5 library there is a similar usecase as MPI;</li> 
     1886<li>checking types of variadic functions' arguments for functions like 
     1887    <tt>fcntl()</tt> and <tt>ioctl()</tt>.</li> 
     1888</ul> 
     1889 
     1890<p>You can detect support for these attributes with __has_attribute().  For 
     1891example:</p> 
     1892 
     1893<blockquote> 
     1894<pre> 
     1895#if defined(__has_attribute) 
     1896#  if __has_attribute(argument_with_type_tag) &amp;&amp; \ 
     1897      __has_attribute(pointer_with_type_tag) &amp;&amp; \ 
     1898      __has_attribute(type_tag_for_datatype) 
     1899#    define ATTR_MPI_PWT(buffer_idx, type_idx) __attribute__((pointer_with_type_tag(mpi,buffer_idx,type_idx))) 
     1900/* ... other macros ... */ 
     1901#  endif 
     1902#endif 
     1903 
     1904#if !defined(ATTR_MPI_PWT) 
     1905#define ATTR_MPI_PWT(buffer_idx, type_idx) 
     1906#endif 
     1907 
     1908int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */) 
     1909    ATTR_MPI_PWT(1,3); 
     1910</pre> 
     1911</blockquote> 
     1912 
     1913<h3 id="argument_with_type_tag"><tt>argument_with_type_tag(...)</tt></h3> 
     1914 
     1915<p>Use <tt>__attribute__((argument_with_type_tag(arg_kind, arg_idx, 
     1916type_tag_idx)))</tt> on a function declaration to specify that the function 
     1917accepts a type tag that determines the type of some other argument. 
     1918<tt>arg_kind</tt> is an identifier that should be used when annotating all 
     1919applicable type tags.</p> 
     1920 
     1921<p>This attribute is primarily useful for checking arguments of variadic 
     1922functions (<tt>pointer_with_type_tag</tt> can be used in most of non-variadic 
     1923cases).</p> 
     1924 
     1925<p>For example:</p> 
     1926<blockquote> 
     1927<pre> 
     1928int fcntl(int fd, int cmd, ...) 
     1929      __attribute__(( argument_with_type_tag(fcntl,3,2) )); 
     1930</pre> 
     1931</blockquote> 
     1932 
     1933<h3 id="pointer_with_type_tag"><tt>pointer_with_type_tag(...)</tt></h3> 
     1934 
     1935<p>Use <tt>__attribute__((pointer_with_type_tag(ptr_kind, ptr_idx, 
     1936type_tag_idx)))</tt> on a function declaration to specify that the 
     1937function a type tag that determines the pointee type of some other pointer 
     1938argument.</p> 
     1939 
     1940<p>For example:</p> 
     1941<blockquote> 
     1942<pre> 
     1943int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */) 
     1944    __attribute__(( pointer_with_type_tag(mpi,1,3) )); 
     1945</pre> 
     1946</blockquote> 
     1947 
     1948<h3 id="type_tag_for_datatype"><tt>type_tag_for_datatype(...)</tt></h3> 
     1949 
     1950<p>Clang supports annotating type tags of two forms.</p> 
     1951 
     1952<ul> 
     1953<li><b>Type tag that is an expression containing a reference to some declared 
     1954identifier.</b> Use <tt>__attribute__((type_tag_for_datatype(kind, type)))</tt> 
     1955on a declaration with that identifier: 
     1956 
     1957<blockquote> 
     1958<pre> 
     1959extern struct mpi_datatype mpi_datatype_int 
     1960    __attribute__(( type_tag_for_datatype(mpi,int) )); 
     1961#define MPI_INT ((MPI_Datatype) &amp;mpi_datatype_int) 
     1962</pre> 
     1963</blockquote></li> 
     1964 
     1965<li><b>Type tag that is an integral literal.</b>  Introduce a <tt>static 
     1966const</tt> variable with a corresponding initializer value and attach 
     1967<tt>__attribute__((type_tag_for_datatype(kind, type)))</tt> on that 
     1968declaration, for example: 
     1969 
     1970<blockquote> 
     1971<pre> 
     1972#define MPI_INT ((MPI_Datatype) 42) 
     1973static const MPI_Datatype mpi_datatype_int 
     1974    __attribute__(( type_tag_for_datatype(mpi,int) )) = 42 
     1975</pre> 
     1976</blockquote></li> 
     1977</ul> 
     1978 
     1979<p>The attribute also accepts an optional third argument that determines how 
     1980the expression is compared to the type tag.  There are two supported flags:</p> 
     1981 
     1982<ul><li><tt>layout_compatible</tt> will cause types to be compared according to 
     1983layout-compatibility rules (C++11 [class.mem] p&nbsp;17, 18).  This is 
     1984implemented to support annotating types like <tt>MPI_DOUBLE_INT</tt>. 
     1985 
     1986<p>For example:</p> 
     1987<blockquote> 
     1988<pre> 
     1989/* In mpi.h */ 
     1990struct internal_mpi_double_int { double d; int i; }; 
     1991extern struct mpi_datatype mpi_datatype_double_int 
     1992    __attribute__(( type_tag_for_datatype(mpi, struct internal_mpi_double_int, 
     1993                                          layout_compatible) )); 
     1994 
     1995#define MPI_DOUBLE_INT ((MPI_Datatype) &amp;mpi_datatype_double_int) 
     1996 
     1997/* In user code */ 
     1998struct my_pair { double a; int b; }; 
     1999struct my_pair *buffer; 
     2000MPI_Send(buffer, 1, MPI_DOUBLE_INT /*, ... */); // no warning 
     2001 
     2002struct my_int_pair { int a; int b; } 
     2003struct my_int_pair *buffer2; 
     2004MPI_Send(buffer2, 1, MPI_DOUBLE_INT /*, ... */); // warning: actual buffer element 
     2005                                                 // type 'struct my_int_pair' 
     2006                                                 // doesn't match specified MPI_Datatype 
     2007</pre> 
     2008</blockquote> 
     2009</li> 
     2010 
     2011<li><tt>must_be_null</tt> specifies that the expression should be a null 
     2012pointer constant, for example: 
     2013 
     2014<blockquote> 
     2015<pre> 
     2016/* In mpi.h */ 
     2017extern struct mpi_datatype mpi_datatype_null 
     2018    __attribute__(( type_tag_for_datatype(mpi, void, must_be_null) )); 
     2019 
     2020#define MPI_DATATYPE_NULL ((MPI_Datatype) &amp;mpi_datatype_null) 
     2021 
     2022/* In user code */ 
     2023MPI_Send(buffer, 1, MPI_DATATYPE_NULL /*, ... */); // warning: MPI_DATATYPE_NULL 
     2024                                                   // was specified but buffer 
     2025                                                   // is not a null pointer 
     2026</pre> 
     2027</blockquote> 
     2028</li> 
     2029</ul> 
     2030 
    18692031</div> 
    18702032</body> 
    18712033</html> 
  • include/clang/Basic/Attr.td

    diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
    index 2e23c64..7f57c7c 100644
    a b  
    810810  let TemplateDependent = 1; 
    811811} 
    812812 
     813// Type safety attributes for `void *' pointers and type tags. 
     814 
     815def ArgumentWithTypeTag : InheritableAttr { 
     816  let Spellings = ["argument_with_type_tag"]; 
     817  let Args = [IdentifierArgument<"ArgumentKind">, 
     818              UnsignedArgument<"ArgumentIdx">, 
     819              UnsignedArgument<"TypeTagIdx">]; 
     820  let Subjects = [Function]; 
     821} 
     822 
     823def PointerWithTypeTag : InheritableAttr { 
     824  let Spellings = ["pointer_with_type_tag"]; 
     825  let Args = [IdentifierArgument<"PointerKind">, 
     826              UnsignedArgument<"PointerIdx">, 
     827              UnsignedArgument<"TypeTagIdx">]; 
     828  let Subjects = [Function]; 
     829} 
     830 
     831def TypeTagForDatatype : InheritableAttr { 
     832  let Spellings = ["type_tag_for_datatype"]; 
     833  let Args = [IdentifierArgument<"PointerKind">, 
     834              TypeArgument<"MatchingCType">, 
     835              BoolArgument<"LayoutCompatible">, 
     836              BoolArgument<"MustBeNull">]; 
     837  let Subjects = [Var]; 
     838} 
     839 
    813840// Microsoft-related attributes 
    814841 
    815842def MsStruct : InheritableAttr { 
     
    846873 
    847874def VirtualInheritance : InheritableAttr { 
    848875  let Spellings = ["__virtual_inheritance"]; 
    849 } 
    850  No newline at end of file 
     876} 
     877 
  • include/clang/Basic/BuiltinsPPC.def

    diff --git a/include/clang/Basic/BuiltinsPPC.def b/include/clang/Basic/BuiltinsPPC.def
    index 8a751e4..b89c673 100644
    a b  
    206206 
    207207// FIXME: Obviously incomplete. 
    208208 
     209BUILTIN(__builtin_fp2_fpadd, "V2dV2dV2d", "") 
     210BUILTIN(__builtin_fp2_fpsub, "V2dV2dV2d", "") 
     211 
     212BUILTIN(__builtin_fp2_fpre, "V2dV2d", "") 
     213BUILTIN(__builtin_fp2_fprsqrte, "V2dV2d", "") 
     214 
     215BUILTIN(__builtin_fp2_fpmul, "V2dV2dV2d", "") 
     216BUILTIN(__builtin_fp2_fxmul, "V2dV2dV2d", "") 
     217BUILTIN(__builtin_fp2_fxpmul, "V2dV2dV2d", "") 
     218BUILTIN(__builtin_fp2_fxsmul, "V2dV2dV2d", "") 
     219 
     220BUILTIN(__builtin_fp2_fpmadd, "V2dV2dV2dV2d", "") 
     221BUILTIN(__builtin_fp2_fpnmadd, "V2dV2dV2dV2d", "") 
     222BUILTIN(__builtin_fp2_fpmsub, "V2dV2dV2dV2d", "") 
     223BUILTIN(__builtin_fp2_fpnmsub, "V2dV2dV2dV2d", "") 
     224BUILTIN(__builtin_fp2_fxmadd, "V2dV2dV2dV2d", "") 
     225BUILTIN(__builtin_fp2_fxnmadd, "V2dV2dV2dV2d", "") 
     226BUILTIN(__builtin_fp2_fxmsub, "V2dV2dV2dV2d", "") 
     227BUILTIN(__builtin_fp2_fxnmsub, "V2dV2dV2dV2d", "") 
     228BUILTIN(__builtin_fp2_fxcpmadd, "V2dV2dV2dV2d", "") 
     229BUILTIN(__builtin_fp2_fxcsmadd, "V2dV2dV2dV2d", "") 
     230BUILTIN(__builtin_fp2_fxcpnmadd, "V2dV2dV2dV2d", "") 
     231BUILTIN(__builtin_fp2_fxcsnmadd, "V2dV2dV2dV2d", "") 
     232BUILTIN(__builtin_fp2_fxcpmsub, "V2dV2dV2dV2d", "") 
     233BUILTIN(__builtin_fp2_fxcsmsub, "V2dV2dV2dV2d", "") 
     234BUILTIN(__builtin_fp2_fxcpnmsub, "V2dV2dV2dV2d", "") 
     235BUILTIN(__builtin_fp2_fxcsnmsub, "V2dV2dV2dV2d", "") 
     236 
     237BUILTIN(__builtin_fp2_fxcpnpma, "V2dV2dV2dV2d", "") 
     238BUILTIN(__builtin_fp2_fxcsnpma, "V2dV2dV2dV2d", "") 
     239BUILTIN(__builtin_fp2_fxcpnsma, "V2dV2dV2dV2d", "") 
     240BUILTIN(__builtin_fp2_fxcsnsma, "V2dV2dV2dV2d", "") 
     241 
     242BUILTIN(__builtin_fp2_fxcxnpma, "V2dV2dV2dV2d", "") 
     243BUILTIN(__builtin_fp2_fxcxnsma, "V2dV2dV2dV2d", "") 
     244BUILTIN(__builtin_fp2_fxcxma, "V2dV2dV2dV2d", "") 
     245BUILTIN(__builtin_fp2_fxcxnms, "V2dV2dV2dV2d", "") 
     246 
     247BUILTIN(__builtin_fp2_fpsel, "V2dV2dV2dV2d", "") 
     248 
     249BUILTIN(__builtin_fp2_fpctiw, "V2dV2d", "") 
     250BUILTIN(__builtin_fp2_fpctiwz, "V2dV2d", "") 
     251BUILTIN(__builtin_fp2_fprsp, "V2dV2d", "") 
     252 
     253BUILTIN(__builtin_fp2_fpneg, "V2dV2d", "") 
     254BUILTIN(__builtin_fp2_fpabs, "V2dV2d", "") 
     255BUILTIN(__builtin_fp2_fpnabs, "V2dV2d", "") 
     256BUILTIN(__builtin_fp2_fxmr, "V2dV2d", "") 
     257 
     258BUILTIN(__builtin_fp2_lfps, "V2dfC*", "") 
     259BUILTIN(__builtin_fp2_lfxs, "V2dfC*", "") 
     260BUILTIN(__builtin_fp2_lfpd, "V2ddC*", "") 
     261BUILTIN(__builtin_fp2_lfxd, "V2ddC*", "") 
     262 
     263BUILTIN(__builtin_fp2_stfps, "vV2df*", "") 
     264BUILTIN(__builtin_fp2_stfxs, "vV2df*", "") 
     265BUILTIN(__builtin_fp2_stfpd, "vV2dd*", "") 
     266BUILTIN(__builtin_fp2_stfxd, "vV2dd*", "") 
     267BUILTIN(__builtin_fp2_stfpiw, "vV2di*", "") 
     268 
     269BUILTIN(__builtin_qpx_qvfabs, "V4dV4d", "") 
     270BUILTIN(__builtin_qpx_qvfctid, "V4dV4d", "") 
     271BUILTIN(__builtin_qpx_qvfcfid, "V4dV4d", "") 
     272BUILTIN(__builtin_qpx_qvfcfidu, "V4dV4d", "") 
     273BUILTIN(__builtin_qpx_qvfctidu, "V4dV4d", "") 
     274BUILTIN(__builtin_qpx_qvfctiduz, "V4dV4d", "") 
     275BUILTIN(__builtin_qpx_qvfctidz, "V4dV4d", "") 
     276BUILTIN(__builtin_qpx_qvfctiw, "V4dV4d", "") 
     277BUILTIN(__builtin_qpx_qvfctiwu, "V4dV4d", "") 
     278BUILTIN(__builtin_qpx_qvfctiwuz, "V4dV4d", "") 
     279BUILTIN(__builtin_qpx_qvfctiwz, "V4dV4d", "") 
     280BUILTIN(__builtin_qpx_qvfnabs, "V4dV4d", "") 
     281BUILTIN(__builtin_qpx_qvfneg, "V4dV4d", "") 
     282BUILTIN(__builtin_qpx_qvfre, "V4dV4d", "") 
     283BUILTIN(__builtin_qpx_qvfres, "V4dV4d", "") 
     284BUILTIN(__builtin_qpx_qvfrim, "V4dV4d", "") 
     285BUILTIN(__builtin_qpx_qvfrin, "V4dV4d", "") 
     286BUILTIN(__builtin_qpx_qvfrip, "V4dV4d", "") 
     287BUILTIN(__builtin_qpx_qvfriz, "V4dV4d", "") 
     288BUILTIN(__builtin_qpx_qvfrsp, "V4dV4d", "") 
     289BUILTIN(__builtin_qpx_qvfrsqrte, "V4dV4d", "") 
     290BUILTIN(__builtin_qpx_qvfrsqrtes, "V4dV4d", "") 
     291 
     292BUILTIN(__builtin_qpx_qvfadd, "V4dV4dV4d", "") 
     293BUILTIN(__builtin_qpx_qvfcmpeq, "V4dV4dV4d", "") 
     294BUILTIN(__builtin_qpx_qvfcmpgt, "V4dV4dV4d", "") 
     295BUILTIN(__builtin_qpx_qvfcmplt, "V4dV4dV4d", "") 
     296BUILTIN(__builtin_qpx_qvfcpsgn, "V4dV4dV4d", "") 
     297BUILTIN(__builtin_qpx_qvfmadd, "V4dV4dV4dV4d", "") 
     298BUILTIN(__builtin_qpx_qvfmsub, "V4dV4dV4dV4d", "") 
     299BUILTIN(__builtin_qpx_qvfmul, "V4dV4dV4d", "") 
     300BUILTIN(__builtin_qpx_qvfnmadd, "V4dV4dV4dV4d", "") 
     301BUILTIN(__builtin_qpx_qvfnmsub, "V4dV4dV4dV4d", "") 
     302BUILTIN(__builtin_qpx_qvfsel, "V4dV4dV4dV4d", "") 
     303BUILTIN(__builtin_qpx_qvfsub, "V4dV4dV4d", "") 
     304BUILTIN(__builtin_qpx_qvftstnan, "V4dV4dV4d", "") 
     305BUILTIN(__builtin_qpx_qvfxmadd, "V4dV4dV4dV4d", "") 
     306BUILTIN(__builtin_qpx_qvfxmul, "V4dV4dV4d", "") 
     307BUILTIN(__builtin_qpx_qvfxxcpnmadd, "V4dV4dV4dV4d", "") 
     308BUILTIN(__builtin_qpx_qvfxxmadd, "V4dV4dV4dV4d", "") 
     309BUILTIN(__builtin_qpx_qvfxxnpmadd, "V4dV4dV4dV4d", "") 
     310 
     311BUILTIN(__builtin_qpx_qvflogical, "V4dV4dV4dIi", "") 
     312 
     313BUILTIN(__builtin_qpx_qvfperm, "V4dV4dV4dV4d", "") 
     314BUILTIN(__builtin_qpx_qvlpcld, "V4ddC*", "") 
     315BUILTIN(__builtin_qpx_qvlpcls, "V4dfC*", "") 
     316BUILTIN(__builtin_qpx_qvlpcrd, "V4ddC*", "") 
     317BUILTIN(__builtin_qpx_qvlpcrs, "V4dfC*", "") 
     318BUILTIN(__builtin_qpx_qvgpci, "V4dIi", "") 
     319 
     320BUILTIN(__builtin_qpx_qvlfcda, "V4dXdC*", "") 
     321BUILTIN(__builtin_qpx_qvlfcd, "V4dXdC*", "") 
     322BUILTIN(__builtin_qpx_qvlfcsa, "V4dXfC*", "") 
     323BUILTIN(__builtin_qpx_qvlfcs, "V4dXfC*", "") 
     324BUILTIN(__builtin_qpx_qvlfda, "V4ddC*", "") 
     325BUILTIN(__builtin_qpx_qvlfd, "V4ddC*", "") 
     326BUILTIN(__builtin_qpx_qvlfiwaa, "V4diC*", "") 
     327BUILTIN(__builtin_qpx_qvlfiwa, "V4diC*", "") 
     328BUILTIN(__builtin_qpx_qvlfiwza, "V4dUiC*", "") 
     329BUILTIN(__builtin_qpx_qvlfiwz, "V4dUiC*", "") 
     330BUILTIN(__builtin_qpx_qvlfsa, "V4dfC*", "") 
     331BUILTIN(__builtin_qpx_qvlfs, "V4dfC*", "") 
     332 
     333BUILTIN(__builtin_qpx_qvstfcda, "vV4dXd*", "") 
     334BUILTIN(__builtin_qpx_qvstfcd, "vV4dXd*", "") 
     335BUILTIN(__builtin_qpx_qvstfcsa, "vV4dXf*", "") 
     336BUILTIN(__builtin_qpx_qvstfcs, "vV4dXf*", "") 
     337BUILTIN(__builtin_qpx_qvstfda, "vV4dd*", "") 
     338BUILTIN(__builtin_qpx_qvstfd, "vV4dd*", "") 
     339BUILTIN(__builtin_qpx_qvstfiwa, "vV4dUi*", "") 
     340BUILTIN(__builtin_qpx_qvstfiw, "vV4dUi*", "") 
     341BUILTIN(__builtin_qpx_qvstfsa, "vV4df*", "") 
     342BUILTIN(__builtin_qpx_qvstfs, "vV4df*", "") 
     343 
    209344#undef BUILTIN 
  • include/clang/Basic/DiagnosticDriverKinds.td

    diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
    index 469c822..fdd3ff5 100644
    a b  
    9797  "-fobjc-arc is not supported on current deployment target">; 
    9898def err_drv_mg_requires_m_or_mm : Error< 
    9999  "option '-MG' requires '-M' or '-MM'">; 
     100def err_drv_asan_android_requires_pie : Error< 
     101  "AddressSanitizer on Android requires '-pie'">; 
    100102 
    101103def warn_c_kext : Warning< 
    102104  "ignoring -fapple-kext which is valid for c++ and objective-c++ only">; 
  • include/clang/Basic/DiagnosticGroups.td

    diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
    index f48eee4..a84c060 100644
    a b  
    327327def Format2 : DiagGroup<"format=2", 
    328328                        [FormatNonLiteral, FormatSecurity, FormatY2K]>; 
    329329 
     330def TypeSafety : DiagGroup<"type-safety">; 
     331 
    330332def Extra : DiagGroup<"extra", [ 
    331333    MissingFieldInitializers, 
    332334    IgnoredQualifiers, 
  • include/clang/Basic/DiagnosticParseKinds.td

    diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
    index a5057c9..f469b45 100644
    a b  
    659659  "'unavailable' availability overrides all other availability information">, 
    660660  InGroup<Availability>; 
    661661 
     662// Type safety attributes 
     663def err_type_safety_unknown_flag : Error< 
     664  "%0 is not a type comparison flag; use 'layout_compatible' or 'must_be_null'">; 
     665 
    662666// Language specific pragmas 
    663667// - Generic warnings 
    664668def warn_pragma_expected_lparen : Warning< 
  • include/clang/Basic/DiagnosticSemaKinds.td

    diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
    index d3d8238..bb08aeb 100644
    a b  
    15051505  "'%0' attribute requires parameter %1 to be an integer constant">; 
    15061506def err_attribute_argument_n_not_string : Error< 
    15071507  "'%0' attribute requires parameter %1 to be a string">; 
     1508def err_attribute_argument_n_not_identifier : Error< 
     1509  "'%0' attribute requires parameter %1 to be an identifier">; 
    15081510def err_attribute_argument_out_of_bounds : Error< 
    15091511  "'%0' attribute parameter %1 is out of bounds">; 
    15101512def err_attribute_requires_objc_interface : Error< 
     
    16921694  "%0 attribute can only be applied to value declarations">; 
    16931695def warn_attribute_not_on_decl : Error< 
    16941696  "%0 attribute ignored when parsing type">; 
    1695  
     1697def err_pointer_with_type_tag_not_pointer : Error< 
     1698  "pointer argument is not of a pointer type">; 
    16961699 
    16971700// Availability attribute 
    16981701def warn_availability_unknown_platform : Warning< 
     
    52115214  "unspecified (use strncmp instead)">, 
    52125215  InGroup<DiagGroup<"string-compare">>; 
    52135216 
     5217// Type safety attributes 
     5218def warn_type_tag_for_datatype_not_ice : Warning< 
     5219  "'type_tag_for_datatype' attribute requires the initializer to be " 
     5220  "an %select{integer|integral}0 constant expression; " 
     5221  "initializer ignored by attribute">, InGroup<TypeSafety>; 
     5222def warn_type_tag_for_datatype_wrong_kind : Warning< 
     5223  "this type tag was not designed to be used with this function">, 
     5224  InGroup<TypeSafety>; 
     5225def warn_type_safety_type_mismatch : Warning< 
     5226  "argument type %0 doesn't match specified %1 type tag " 
     5227  "%select{that requires %3|}2">, InGroup<TypeSafety>; 
     5228def warn_type_safety_pointee_type_mismatch : Warning< 
     5229  "pointee type %0 doesn't match specified %1 type tag " 
     5230  "%select{that requires %3|}2">, InGroup<TypeSafety>; 
     5231def warn_type_safety_null_pointer_required : Warning< 
     5232  "specified %0 type tag requires a null pointer">, InGroup<TypeSafety>; 
     5233 
    52145234// Generic selections. 
    52155235def err_assoc_type_incomplete : Error< 
    52165236  "type %0 in generic association incomplete">; 
  • include/clang/Parse/Parser.h

    diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
    index 07d6320..c3dad4e 100644
    a b  
    18761876                                  ParsedAttributes &Attrs, 
    18771877                                  SourceLocation *EndLoc); 
    18781878 
     1879  void ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName, 
     1880                                        SourceLocation AttrNameLoc, 
     1881                                        ParsedAttributes &Attrs, 
     1882                                        SourceLocation *EndLoc); 
    18791883 
    18801884  void ParseTypeofSpecifier(DeclSpec &DS); 
    18811885  SourceLocation ParseDecltypeSpecifier(DeclSpec &DS); 
  • include/clang/Sema/AttributeList.h

    diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
    index ef6cf1c..8a9d95f 100644
    a b  
    1919#include "llvm/ADT/SmallVector.h" 
    2020#include "clang/Basic/SourceLocation.h" 
    2121#include "clang/Basic/VersionTuple.h" 
     22#include "clang/Sema/Ownership.h" 
    2223#include <cassert> 
    2324 
    2425namespace clang { 
     
    8081  /// availability attribute. 
    8182  unsigned IsAvailability : 1; 
    8283 
     84  /// True if this has extra information associated with a 
     85  /// type_tag_for_datatype attribute. 
     86  unsigned IsTypeTagForDatatype : 1; 
     87 
    8388  unsigned AttrKind : 8; 
    8489 
    8590  /// \brief The location of the 'unavailable' keyword in an 
     
    112117    return reinterpret_cast<const AvailabilityChange*>(this+1)[index]; 
    113118  } 
    114119 
     120public: 
     121  struct TypeTagForDatatypeData { 
     122    ParsedType *MatchingCType; 
     123    unsigned LayoutCompatible : 1; 
     124    unsigned MustBeNull : 1; 
     125  }; 
     126 
     127private: 
     128  TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() { 
     129    return *reinterpret_cast<TypeTagForDatatypeData *>(this + 1); 
     130  } 
     131 
     132  const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const { 
     133    return *reinterpret_cast<const TypeTagForDatatypeData *>(this + 1); 
     134  } 
     135 
    115136  AttributeList(const AttributeList &); // DO NOT IMPLEMENT 
    116137  void operator=(const AttributeList &); // DO NOT IMPLEMENT 
    117138  void operator delete(void *); // DO NOT IMPLEMENT 
     
    119140 
    120141  size_t allocated_size() const; 
    121142 
     143  /// Constructor for attributes with expression arguments. 
    122144  AttributeList(IdentifierInfo *attrName, SourceRange attrRange, 
    123145                IdentifierInfo *scopeName, SourceLocation scopeLoc, 
    124146                IdentifierInfo *parmName, SourceLocation parmLoc, 
     
    128150      AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), 
    129151      NumArgs(numArgs), 
    130152      DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false), 
    131       UsedAsTypeAttr(false), IsAvailability(false),  
    132       NextInPosition(0), NextInPool(0) { 
     153      UsedAsTypeAttr(false), IsAvailability(false), 
     154      IsTypeTagForDatatype(false), NextInPosition(0), NextInPool(0) { 
    133155    if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(Expr*)); 
    134156    AttrKind = getKind(getName(), getScopeName()); 
    135157  } 
    136158 
     159  /// Constructor for availability attributes. 
    137160  AttributeList(IdentifierInfo *attrName, SourceRange attrRange, 
    138161                IdentifierInfo *scopeName, SourceLocation scopeLoc, 
    139162                IdentifierInfo *parmName, SourceLocation parmLoc, 
     
    147170      AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), 
    148171      NumArgs(0), DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), 
    149172      Invalid(false), UsedAsTypeAttr(false), IsAvailability(true), 
     173      IsTypeTagForDatatype(false), 
    150174      UnavailableLoc(unavailable), MessageExpr(messageExpr), 
    151175      NextInPosition(0), NextInPool(0) { 
    152176    new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced); 
     
    155179    AttrKind = getKind(getName(), getScopeName()); 
    156180  } 
    157181 
     182  /// Constructor for type_tag_for_datatype attribute. 
     183  AttributeList(IdentifierInfo *attrName, SourceRange attrRange, 
     184                IdentifierInfo *scopeName, SourceLocation scopeLoc, 
     185                IdentifierInfo *pointerKindName, 
     186                SourceLocation pointerKindLoc, 
     187                ParsedType matchingCType, bool layoutCompatible, 
     188                bool mustBeNull, bool cxx0x) 
     189    : AttrName(attrName), ScopeName(scopeName), ParmName(pointerKindName), 
     190      AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(pointerKindLoc), 
     191      NumArgs(0), DeclspecAttribute(false), CXX0XAttribute(cxx0x), 
     192      Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), 
     193      IsTypeTagForDatatype(true), NextInPosition(NULL), NextInPool(NULL) { 
     194    TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot(); 
     195    new (&ExtraData.MatchingCType) ParsedType(matchingCType); 
     196    ExtraData.LayoutCompatible = layoutCompatible; 
     197    ExtraData.MustBeNull = mustBeNull; 
     198    AttrKind = getKind(getName(), getScopeName()); 
     199  } 
     200 
    158201  friend class AttributePool; 
    159202  friend class AttributeFactory; 
    160203 
     
    268311    assert(getKind() == AT_availability && "Not an availability attribute"); 
    269312    return MessageExpr; 
    270313  } 
     314 
     315  const ParsedType &getMatchingCType() const { 
     316    assert(getKind() == AT_type_tag_for_datatype && 
     317           "Not a type_tag_for_datatype attribute"); 
     318    return *getTypeTagForDatatypeDataSlot().MatchingCType; 
     319  } 
     320 
     321  bool getLayoutCompatible() const { 
     322    assert(getKind() == AT_type_tag_for_datatype && 
     323           "Not a type_tag_for_datatype attribute"); 
     324    return getTypeTagForDatatypeDataSlot().LayoutCompatible; 
     325  } 
     326 
     327  bool getMustBeNull() const { 
     328    assert(getKind() == AT_type_tag_for_datatype && 
     329           "Not a type_tag_for_datatype attribute"); 
     330    return getTypeTagForDatatypeDataSlot().MustBeNull; 
     331  } 
    271332}; 
    272333 
    273334/// A factory, from which one makes pools, from which one creates 
     
    283344    AvailabilityAllocSize = 
    284345      sizeof(AttributeList) 
    285346      + ((3 * sizeof(AvailabilityChange) + sizeof(void*) - 1) 
    286          / sizeof(void*) * sizeof(void*)) 
     347         / sizeof(void*) * sizeof(void*)), 
     348    TypeTagForDatatypeAllocSize = 
     349      sizeof(AttributeList) 
     350      + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) - 1) 
     351        / sizeof(void*) * sizeof(void*) 
    287352  }; 
    288353 
    289354private: 
     
    402467 
    403468  AttributeList *createIntegerAttribute(ASTContext &C, IdentifierInfo *Name, 
    404469                                        SourceLocation TokLoc, int Arg); 
     470 
     471  AttributeList *createTypeTagForDatatype( 
     472                    IdentifierInfo *attrName, SourceRange attrRange, 
     473                    IdentifierInfo *scopeName, SourceLocation scopeLoc, 
     474                    IdentifierInfo *pointerKindName, 
     475                    SourceLocation pointerKindLoc, 
     476                    ParsedType matchingCType, bool layoutCompatible, 
     477                    bool mustBeNull, bool cxx0x) { 
     478    void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize); 
     479    return add(new (memory) AttributeList(attrName, attrRange, 
     480                                          scopeName, scopeLoc, 
     481                                          pointerKindName, pointerKindLoc, 
     482                                          matchingCType, layoutCompatible, 
     483                                          mustBeNull, cxx0x)); 
     484  } 
    405485}; 
    406486 
    407487/// addAttributeLists - Add two AttributeLists together 
     
    494574  /// dependencies on this method, it may not be long-lived. 
    495575  AttributeList *&getListRef() { return list; } 
    496576 
    497  
     577  /// Add attribute with expression arguments. 
    498578  AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange, 
    499579                        IdentifierInfo *scopeName, SourceLocation scopeLoc, 
    500580                        IdentifierInfo *parmName, SourceLocation parmLoc, 
     
    507587    return attr; 
    508588  } 
    509589 
     590  /// Add availability attribute. 
    510591  AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange, 
    511592                        IdentifierInfo *scopeName, SourceLocation scopeLoc, 
    512593                        IdentifierInfo *parmName, SourceLocation parmLoc, 
     
    525606    return attr; 
    526607  } 
    527608 
     609  /// Add type_tag_for_datatype attribute. 
     610  AttributeList *addNewTypeTagForDatatype( 
     611                        IdentifierInfo *attrName, SourceRange attrRange, 
     612                        IdentifierInfo *scopeName, SourceLocation scopeLoc, 
     613                        IdentifierInfo *pointerKindName, 
     614                        SourceLocation pointerKindLoc, 
     615                        ParsedType matchingCType, bool layoutCompatible, 
     616                        bool mustBeNull, bool cxx0x = false) { 
     617    AttributeList *attr = 
     618      pool.createTypeTagForDatatype(attrName, attrRange, 
     619                                    scopeName, scopeLoc, 
     620                                    pointerKindName, pointerKindLoc, 
     621                                    matchingCType, layoutCompatible, 
     622                                    mustBeNull, cxx0x); 
     623    add(attr); 
     624    return attr; 
     625  } 
     626 
    528627  AttributeList *addNewInteger(ASTContext &C, IdentifierInfo *name, 
    529628                               SourceLocation loc, int arg) { 
    530629    AttributeList *attr = 
  • include/clang/Sema/Sema.h

    diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
    index d7bc2bf..92886f8 100644
    a b  
    4141#include "llvm/ADT/SmallVector.h" 
    4242#include <deque> 
    4343#include <string> 
     44#include <map> 
    4445 
    4546namespace llvm { 
    4647  class APSInt; 
     
    70587059  void CheckBitFieldInitialization(SourceLocation InitLoc, FieldDecl *Field, 
    70597060                                   Expr *Init); 
    70607061 
     7062public: 
     7063  /// \brief Register a magic integral constant to be used as a type tag. 
     7064  void RegisterTypeTagForDatatype(StringRef PointerKind, uint64_t MagicValue, 
     7065                                  QualType Type, bool LayoutCompatible, 
     7066                                  bool MustBeNull); 
     7067 
     7068  struct TypeTagData { 
     7069    TypeTagData() {} 
     7070 
     7071    TypeTagData(QualType Type, bool LayoutCompatible, bool MustBeNull) : 
     7072        Type(Type), LayoutCompatible(LayoutCompatible), 
     7073        MustBeNull(MustBeNull) 
     7074    {} 
     7075 
     7076    QualType Type; 
     7077 
     7078    /// If true, Type should be compared with other expression's types for 
     7079    /// layout-compatibility. 
     7080    unsigned LayoutCompatible : 1; 
     7081    unsigned MustBeNull : 1; 
     7082  }; 
     7083 
     7084  /// \brief A map from magic value to associated dataype.  We can not use 
     7085  /// DenseMap here because it reserves two key values for its internal needs. 
     7086  typedef std::map<uint64_t, TypeTagData> TypeTagForDatatypeMagicValuesType; 
     7087 
     7088private: 
     7089  /// \brief A map from ArgumentKind identifier name to registered magic 
     7090  /// values. 
     7091  OwningPtr<llvm::StringMap<TypeTagForDatatypeMagicValuesType> > 
     7092      TypeTagForDatatypeMagicValues; 
     7093 
     7094  /// \brief Peform checks on a call of a function with argument_with_type_tag 
     7095  /// or pointer_with_type_tag attributes. 
     7096  void CheckArgumentWithTypeTag(const InheritableAttr *Attr, 
     7097                                const Expr * const *ExprArgs); 
     7098 
    70617099  /// \brief The parser's current scope. 
    70627100  /// 
    70637101  /// The parser maintains this state here. 
  • lib/Basic/Targets.cpp

    diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
    index c4a80dd..15a15fe 100644
    a b  
    335335  } 
    336336}; 
    337337 
     338// CNK target 
     339template<typename Target> 
     340class CNKTargetInfo : public OSTargetInfo<Target> { 
     341protected: 
     342  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 
     343                            MacroBuilder &Builder) const { 
     344    // CNK defines; list based off of gcc output 
     345    DefineStd(Builder, "unix", Opts); 
     346    DefineStd(Builder, "cnk", Opts); 
     347    Builder.defineMacro("__gnu_cnk__"); 
     348    Builder.defineMacro("__ELF__"); 
     349    if (Opts.POSIXThreads) 
     350      Builder.defineMacro("_REENTRANT"); 
     351    if (Opts.CPlusPlus) 
     352      Builder.defineMacro("_GNU_SOURCE"); 
     353  } 
     354public: 
     355  CNKTargetInfo(const std::string& triple) 
     356    : OSTargetInfo<Target>(triple) { 
     357    this->UserLabelPrefix = ""; 
     358    this->WIntType = TargetInfo::UnsignedInt; 
     359  } 
     360}; 
     361 
    338362// NetBSD Target 
    339363template<typename Target> 
    340364class NetBSDTargetInfo : public OSTargetInfo<Target> { 
     
    575599  static const Builtin::Info BuiltinInfo[]; 
    576600  static const char * const GCCRegNames[]; 
    577601  static const TargetInfo::GCCRegAlias GCCRegAliases[]; 
     602  std::string CPU; 
    578603public: 
    579604  PPCTargetInfo(const std::string& triple) : TargetInfo(triple) { 
    580605    LongDoubleWidth = LongDoubleAlign = 128; 
    581606    LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble; 
    582607  } 
    583608 
     609  virtual bool setCPU(const std::string &Name) { 
     610    if (Name == "440" || Name == "450") { 
     611      CPU = Name; 
     612      return true; 
     613    } else if (Name == "440fp2" || Name == "440d") { 
     614      CPU = "440fp2"; 
     615      return true; 
     616    } else if (Name == "450fp2" || Name == "450d") { 
     617      CPU = "450fp2"; 
     618      return true; 
     619    } else if (Name == "a2" || Name == "a2q") { 
     620      CPU = Name; 
     621      return true; 
     622    } 
     623 
     624    return false; 
     625  } 
     626 
    584627  virtual void getTargetBuiltins(const Builtin::Info *&Records, 
    585628                                 unsigned &NumRecords) const { 
    586629    Records = BuiltinInfo; 
     
    744787    Builder.defineMacro("__VEC__", "10206"); 
    745788    Builder.defineMacro("__ALTIVEC__"); 
    746789  } 
     790 
     791  if (CPU == "440") { 
     792    Builder.defineMacro("_ARCH_440"); 
     793  } else if (CPU == "450") { 
     794    Builder.defineMacro("_ARCH_440"); 
     795    Builder.defineMacro("_ARCH_450"); 
     796  } else if (CPU == "440fp2") { 
     797    Builder.defineMacro("_ARCH_440"); 
     798    Builder.defineMacro("_ARCH_440D"); 
     799    Builder.defineMacro("_ARCH_440FP2"); 
     800  } else if (CPU == "450fp2") { 
     801    Builder.defineMacro("_ARCH_440"); 
     802    Builder.defineMacro("_ARCH_440D"); 
     803    Builder.defineMacro("_ARCH_440FP2"); 
     804    Builder.defineMacro("_ARCH_450"); 
     805    Builder.defineMacro("_ARCH_450D"); 
     806    Builder.defineMacro("_ARCH_450FP2"); 
     807  } else if (CPU == "a2q") { 
     808    Builder.defineMacro("_ARCH_QP"); 
     809  } 
     810 
     811  bool isBG = false; 
     812  if (getTriple().getVendor() == llvm::Triple::BGP) { 
     813    isBG = true; 
     814    Builder.defineMacro("__bgp__"); 
     815    Builder.defineMacro("__TOS_BGP__"); 
     816  } else if (getTriple().getVendor() == llvm::Triple::BGQ) { 
     817    isBG = true; 
     818    Builder.defineMacro("__bgq__"); 
     819    Builder.defineMacro("__TOS_BGQ__"); 
     820  } 
     821  if (isBG) { 
     822    Builder.defineMacro("__bg__"); 
     823    Builder.defineMacro("__THW_BLUEGENE__"); 
     824  } 
    747825} 
    748826 
    749827bool PPCTargetInfo::hasFeature(StringRef Feature) const { 
     
    40644142    switch (os) { 
    40654143    case llvm::Triple::Linux: 
    40664144      return new LinuxTargetInfo<PPC32TargetInfo>(T); 
     4145    case llvm::Triple::CNK: 
     4146      return new CNKTargetInfo<PPC32TargetInfo>(T); 
    40674147    case llvm::Triple::FreeBSD: 
    40684148      return new FreeBSDTargetInfo<PPC32TargetInfo>(T); 
    40694149    case llvm::Triple::NetBSD: 
  • lib/CodeGen/CGBuiltin.cpp

    diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
    index a3d4af7..6c868d6 100644
    a b  
    51215121    llvm::Function *F = CGM.getIntrinsic(ID); 
    51225122    return Builder.CreateCall(F, Ops, ""); 
    51235123  } 
     5124 
     5125  // FP2 (Double Hummer) 
     5126  case PPC::BI__builtin_fp2_fpadd: 
     5127  case PPC::BI__builtin_fp2_fpsub: 
     5128  case PPC::BI__builtin_fp2_fpre: 
     5129  case PPC::BI__builtin_fp2_fprsqrte: 
     5130  case PPC::BI__builtin_fp2_fpmul: 
     5131  case PPC::BI__builtin_fp2_fxmul: 
     5132  case PPC::BI__builtin_fp2_fxpmul: 
     5133  case PPC::BI__builtin_fp2_fxsmul: 
     5134  case PPC::BI__builtin_fp2_fpmadd: 
     5135  case PPC::BI__builtin_fp2_fpnmadd: 
     5136  case PPC::BI__builtin_fp2_fpmsub: 
     5137  case PPC::BI__builtin_fp2_fpnmsub: 
     5138  case PPC::BI__builtin_fp2_fxmadd: 
     5139  case PPC::BI__builtin_fp2_fxnmadd: 
     5140  case PPC::BI__builtin_fp2_fxmsub: 
     5141  case PPC::BI__builtin_fp2_fxnmsub: 
     5142  case PPC::BI__builtin_fp2_fxcpmadd: 
     5143  case PPC::BI__builtin_fp2_fxcsmadd: 
     5144  case PPC::BI__builtin_fp2_fxcpnmadd: 
     5145  case PPC::BI__builtin_fp2_fxcsnmadd: 
     5146  case PPC::BI__builtin_fp2_fxcpmsub: 
     5147  case PPC::BI__builtin_fp2_fxcsmsub: 
     5148  case PPC::BI__builtin_fp2_fxcpnmsub: 
     5149  case PPC::BI__builtin_fp2_fxcsnmsub: 
     5150  case PPC::BI__builtin_fp2_fxcpnpma: 
     5151  case PPC::BI__builtin_fp2_fxcsnpma: 
     5152  case PPC::BI__builtin_fp2_fxcpnsma: 
     5153  case PPC::BI__builtin_fp2_fxcsnsma: 
     5154  case PPC::BI__builtin_fp2_fxcxnpma: 
     5155  case PPC::BI__builtin_fp2_fxcxnsma: 
     5156  case PPC::BI__builtin_fp2_fxcxma: 
     5157  case PPC::BI__builtin_fp2_fxcxnms: 
     5158  case PPC::BI__builtin_fp2_fpsel: 
     5159  case PPC::BI__builtin_fp2_fpctiw: 
     5160  case PPC::BI__builtin_fp2_fpctiwz: 
     5161  case PPC::BI__builtin_fp2_fprsp: 
     5162  case PPC::BI__builtin_fp2_fpneg: 
     5163  case PPC::BI__builtin_fp2_fpabs: 
     5164  case PPC::BI__builtin_fp2_fpnabs: 
     5165  case PPC::BI__builtin_fp2_fxmr: 
     5166  case PPC::BI__builtin_fp2_lfps: 
     5167  case PPC::BI__builtin_fp2_lfxs: 
     5168  case PPC::BI__builtin_fp2_lfpd: 
     5169  case PPC::BI__builtin_fp2_lfxd: 
     5170  case PPC::BI__builtin_fp2_stfps: 
     5171  case PPC::BI__builtin_fp2_stfxs: 
     5172  case PPC::BI__builtin_fp2_stfpd: 
     5173  case PPC::BI__builtin_fp2_stfxd: 
     5174  case PPC::BI__builtin_fp2_stfpiw: 
     5175  { 
     5176    switch (BuiltinID) { 
     5177    default: llvm_unreachable("Unsupported fp2 intrinsic!"); 
     5178    case PPC::BI__builtin_fp2_fpadd: 
     5179      ID = Intrinsic::ppc_fp2_fpadd; 
     5180      break; 
     5181    case PPC::BI__builtin_fp2_fpsub: 
     5182      ID = Intrinsic::ppc_fp2_fpsub; 
     5183      break; 
     5184    case PPC::BI__builtin_fp2_fpre: 
     5185      ID = Intrinsic::ppc_fp2_fpre; 
     5186      break; 
     5187    case PPC::BI__builtin_fp2_fprsqrte: 
     5188      ID = Intrinsic::ppc_fp2_fprsqrte; 
     5189      break; 
     5190    case PPC::BI__builtin_fp2_fpmul: 
     5191      ID = Intrinsic::ppc_fp2_fpmul; 
     5192      break; 
     5193    case PPC::BI__builtin_fp2_fxmul: 
     5194      ID = Intrinsic::ppc_fp2_fxmul; 
     5195      break; 
     5196    case PPC::BI__builtin_fp2_fxpmul: 
     5197      ID = Intrinsic::ppc_fp2_fxpmul; 
     5198      break; 
     5199    case PPC::BI__builtin_fp2_fxsmul: 
     5200      ID = Intrinsic::ppc_fp2_fxsmul; 
     5201      break; 
     5202    case PPC::BI__builtin_fp2_fpmadd: 
     5203      ID = Intrinsic::ppc_fp2_fpmadd; 
     5204      break; 
     5205    case PPC::BI__builtin_fp2_fpnmadd: 
     5206      ID = Intrinsic::ppc_fp2_fpnmadd; 
     5207      break; 
     5208    case PPC::BI__builtin_fp2_fpmsub: 
     5209      ID = Intrinsic::ppc_fp2_fpmsub; 
     5210      break; 
     5211    case PPC::BI__builtin_fp2_fpnmsub: 
     5212      ID = Intrinsic::ppc_fp2_fpnmsub; 
     5213      break; 
     5214    case PPC::BI__builtin_fp2_fxmadd: 
     5215      ID = Intrinsic::ppc_fp2_fxmadd; 
     5216      break; 
     5217    case PPC::BI__builtin_fp2_fxnmadd: 
     5218      ID = Intrinsic::ppc_fp2_fxnmadd; 
     5219      break; 
     5220    case PPC::BI__builtin_fp2_fxmsub: 
     5221      ID = Intrinsic::ppc_fp2_fxmsub; 
     5222      break; 
     5223    case PPC::BI__builtin_fp2_fxnmsub: 
     5224      ID = Intrinsic::ppc_fp2_fxnmsub; 
     5225      break; 
     5226    case PPC::BI__builtin_fp2_fxcpmadd: 
     5227      ID = Intrinsic::ppc_fp2_fxcpmadd; 
     5228      break; 
     5229    case PPC::BI__builtin_fp2_fxcsmadd: 
     5230      ID = Intrinsic::ppc_fp2_fxcsmadd; 
     5231      break; 
     5232    case PPC::BI__builtin_fp2_fxcpnmadd: 
     5233      ID = Intrinsic::ppc_fp2_fxcpnmadd; 
     5234      break; 
     5235    case PPC::BI__builtin_fp2_fxcsnmadd: 
     5236      ID = Intrinsic::ppc_fp2_fxcsnmadd; 
     5237      break; 
     5238    case PPC::BI__builtin_fp2_fxcpmsub: 
     5239      ID = Intrinsic::ppc_fp2_fxcpmsub; 
     5240      break; 
     5241    case PPC::BI__builtin_fp2_fxcsmsub: 
     5242      ID = Intrinsic::ppc_fp2_fxcsmsub; 
     5243      break; 
     5244    case PPC::BI__builtin_fp2_fxcpnmsub: 
     5245      ID = Intrinsic::ppc_fp2_fxcpnmsub; 
     5246      break; 
     5247    case PPC::BI__builtin_fp2_fxcsnmsub: 
     5248      ID = Intrinsic::ppc_fp2_fxcsnmsub; 
     5249      break; 
     5250    case PPC::BI__builtin_fp2_fxcpnpma: 
     5251      ID = Intrinsic::ppc_fp2_fxcpnpma; 
     5252      break; 
     5253    case PPC::BI__builtin_fp2_fxcsnpma: 
     5254      ID = Intrinsic::ppc_fp2_fxcsnpma; 
     5255      break; 
     5256    case PPC::BI__builtin_fp2_fxcpnsma: 
     5257      ID = Intrinsic::ppc_fp2_fxcpnsma; 
     5258      break; 
     5259    case PPC::BI__builtin_fp2_fxcsnsma: 
     5260      ID = Intrinsic::ppc_fp2_fxcsnsma; 
     5261      break; 
     5262    case PPC::BI__builtin_fp2_fxcxnpma: 
     5263      ID = Intrinsic::ppc_fp2_fxcxnpma; 
     5264      break; 
     5265    case PPC::BI__builtin_fp2_fxcxnsma: 
     5266      ID = Intrinsic::ppc_fp2_fxcxnsma; 
     5267      break; 
     5268    case PPC::BI__builtin_fp2_fxcxma: 
     5269      ID = Intrinsic::ppc_fp2_fxcxma; 
     5270      break; 
     5271    case PPC::BI__builtin_fp2_fxcxnms: 
     5272      ID = Intrinsic::ppc_fp2_fxcxnms; 
     5273      break; 
     5274    case PPC::BI__builtin_fp2_fpsel: 
     5275      ID = Intrinsic::ppc_fp2_fpsel; 
     5276      break; 
     5277    case PPC::BI__builtin_fp2_fpctiw: 
     5278      ID = Intrinsic::ppc_fp2_fpctiw; 
     5279      break; 
     5280    case PPC::BI__builtin_fp2_fpctiwz: 
     5281      ID = Intrinsic::ppc_fp2_fpctiwz; 
     5282      break; 
     5283    case PPC::BI__builtin_fp2_fprsp: 
     5284      ID = Intrinsic::ppc_fp2_fprsp; 
     5285      break; 
     5286    case PPC::BI__builtin_fp2_fpneg: 
     5287      ID = Intrinsic::ppc_fp2_fpneg; 
     5288      break; 
     5289    case PPC::BI__builtin_fp2_fpabs: 
     5290      ID = Intrinsic::ppc_fp2_fpabs; 
     5291      break; 
     5292    case PPC::BI__builtin_fp2_fpnabs: 
     5293      ID = Intrinsic::ppc_fp2_fpnabs; 
     5294      break; 
     5295    case PPC::BI__builtin_fp2_fxmr: 
     5296      ID = Intrinsic::ppc_fp2_fxmr; 
     5297      break; 
     5298    case PPC::BI__builtin_fp2_lfps: 
     5299      ID = Intrinsic::ppc_fp2_lfps; 
     5300      break; 
     5301    case PPC::BI__builtin_fp2_lfxs: 
     5302      ID = Intrinsic::ppc_fp2_lfxs; 
     5303      break; 
     5304    case PPC::BI__builtin_fp2_lfpd: 
     5305      ID = Intrinsic::ppc_fp2_lfpd; 
     5306      break; 
     5307    case PPC::BI__builtin_fp2_lfxd: 
     5308      ID = Intrinsic::ppc_fp2_lfxd; 
     5309      break; 
     5310    case PPC::BI__builtin_fp2_stfps: 
     5311      ID = Intrinsic::ppc_fp2_stfps; 
     5312      break; 
     5313    case PPC::BI__builtin_fp2_stfxs: 
     5314      ID = Intrinsic::ppc_fp2_stfxs; 
     5315      break; 
     5316    case PPC::BI__builtin_fp2_stfpd: 
     5317      ID = Intrinsic::ppc_fp2_stfpd; 
     5318      break; 
     5319    case PPC::BI__builtin_fp2_stfxd: 
     5320      ID = Intrinsic::ppc_fp2_stfxd; 
     5321      break; 
     5322    case PPC::BI__builtin_fp2_stfpiw: 
     5323      ID = Intrinsic::ppc_fp2_stfpiw; 
     5324      break; 
     5325    } 
     5326    llvm::Function *F = CGM.getIntrinsic(ID); 
     5327    return Builder.CreateCall(F, Ops, ""); 
     5328  } 
     5329 
     5330  // QPX 
     5331  case PPC::BI__builtin_qpx_qvfabs: 
     5332  case PPC::BI__builtin_qpx_qvfctid: 
     5333  case PPC::BI__builtin_qpx_qvfcfid: 
     5334  case PPC::BI__builtin_qpx_qvfcfidu: 
     5335  case PPC::BI__builtin_qpx_qvfctidu: 
     5336  case PPC::BI__builtin_qpx_qvfctiduz: 
     5337  case PPC::BI__builtin_qpx_qvfctidz: 
     5338  case PPC::BI__builtin_qpx_qvfctiw: 
     5339  case PPC::BI__builtin_qpx_qvfctiwu: 
     5340  case PPC::BI__builtin_qpx_qvfctiwuz: 
     5341  case PPC::BI__builtin_qpx_qvfctiwz: 
     5342  case PPC::BI__builtin_qpx_qvfnabs: 
     5343  case PPC::BI__builtin_qpx_qvfneg: 
     5344  case PPC::BI__builtin_qpx_qvfre: 
     5345  case PPC::BI__builtin_qpx_qvfres: 
     5346  case PPC::BI__builtin_qpx_qvfrim: 
     5347  case PPC::BI__builtin_qpx_qvfrin: 
     5348  case PPC::BI__builtin_qpx_qvfrip: 
     5349  case PPC::BI__builtin_qpx_qvfriz: 
     5350  case PPC::BI__builtin_qpx_qvfrsp: 
     5351  case PPC::BI__builtin_qpx_qvfrsqrte: 
     5352  case PPC::BI__builtin_qpx_qvfrsqrtes: 
     5353  case PPC::BI__builtin_qpx_qvfadd: 
     5354  case PPC::BI__builtin_qpx_qvfcmpeq: 
     5355  case PPC::BI__builtin_qpx_qvfcmpgt: 
     5356  case PPC::BI__builtin_qpx_qvfcmplt: 
     5357  case PPC::BI__builtin_qpx_qvfcpsgn: 
     5358  case PPC::BI__builtin_qpx_qvfmadd: 
     5359  case PPC::BI__builtin_qpx_qvfmsub: 
     5360  case PPC::BI__builtin_qpx_qvfmul: 
     5361  case PPC::BI__builtin_qpx_qvfnmadd: 
     5362  case PPC::BI__builtin_qpx_qvfnmsub: 
     5363  case PPC::BI__builtin_qpx_qvfsel: 
     5364  case PPC::BI__builtin_qpx_qvfsub: 
     5365  case PPC::BI__builtin_qpx_qvftstnan: 
     5366  case PPC::BI__builtin_qpx_qvfxmadd: 
     5367  case PPC::BI__builtin_qpx_qvfxmul: 
     5368  case PPC::BI__builtin_qpx_qvfxxcpnmadd: 
     5369  case PPC::BI__builtin_qpx_qvfxxmadd: 
     5370  case PPC::BI__builtin_qpx_qvfxxnpmadd: 
     5371  case PPC::BI__builtin_qpx_qvflogical: 
     5372  case PPC::BI__builtin_qpx_qvfperm: 
     5373  case PPC::BI__builtin_qpx_qvlpcld: 
     5374  case PPC::BI__builtin_qpx_qvlpcls: 
     5375  case PPC::BI__builtin_qpx_qvlpcrd: 
     5376  case PPC::BI__builtin_qpx_qvlpcrs: 
     5377  case PPC::BI__builtin_qpx_qvgpci: 
     5378  case PPC::BI__builtin_qpx_qvlfcda: 
     5379  case PPC::BI__builtin_qpx_qvlfcd: 
     5380  case PPC::BI__builtin_qpx_qvlfcsa: 
     5381  case PPC::BI__builtin_qpx_qvlfcs: 
     5382  case PPC::BI__builtin_qpx_qvlfda: 
     5383  case PPC::BI__builtin_qpx_qvlfd: 
     5384  case PPC::BI__builtin_qpx_qvlfiwaa: 
     5385  case PPC::BI__builtin_qpx_qvlfiwa: 
     5386  case PPC::BI__builtin_qpx_qvlfiwza: 
     5387  case PPC::BI__builtin_qpx_qvlfiwz: 
     5388  case PPC::BI__builtin_qpx_qvlfsa: 
     5389  case PPC::BI__builtin_qpx_qvlfs: 
     5390  case PPC::BI__builtin_qpx_qvstfcda: 
     5391  case PPC::BI__builtin_qpx_qvstfcd: 
     5392  case PPC::BI__builtin_qpx_qvstfcsa: 
     5393  case PPC::BI__builtin_qpx_qvstfcs: 
     5394  case PPC::BI__builtin_qpx_qvstfda: 
     5395  case PPC::BI__builtin_qpx_qvstfd: 
     5396  case PPC::BI__builtin_qpx_qvstfiwa: 
     5397  case PPC::BI__builtin_qpx_qvstfiw: 
     5398  case PPC::BI__builtin_qpx_qvstfsa: 
     5399  case PPC::BI__builtin_qpx_qvstfs: 
     5400  { 
     5401    switch (BuiltinID) { 
     5402    default: llvm_unreachable("Unsupported qpx intrinsic!"); 
     5403    case PPC::BI__builtin_qpx_qvfabs: 
     5404      ID = Intrinsic::ppc_qpx_qvfabs; 
     5405      break; 
     5406    case PPC::BI__builtin_qpx_qvfctid: 
     5407      ID = Intrinsic::ppc_qpx_qvfctid; 
     5408      break; 
     5409    case PPC::BI__builtin_qpx_qvfcfid: 
     5410      ID = Intrinsic::ppc_qpx_qvfcfid; 
     5411      break; 
     5412    case PPC::BI__builtin_qpx_qvfcfidu: 
     5413      ID = Intrinsic::ppc_qpx_qvfcfidu; 
     5414      break; 
     5415    case PPC::BI__builtin_qpx_qvfctidu: 
     5416      ID = Intrinsic::ppc_qpx_qvfctidu; 
     5417      break; 
     5418    case PPC::BI__builtin_qpx_qvfctiduz: 
     5419      ID = Intrinsic::ppc_qpx_qvfctiduz; 
     5420      break; 
     5421    case PPC::BI__builtin_qpx_qvfctidz: 
     5422      ID = Intrinsic::ppc_qpx_qvfctidz; 
     5423      break; 
     5424    case PPC::BI__builtin_qpx_qvfctiw: 
     5425      ID = Intrinsic::ppc_qpx_qvfctiw; 
     5426      break; 
     5427    case PPC::BI__builtin_qpx_qvfctiwu: 
     5428      ID = Intrinsic::ppc_qpx_qvfctiwu; 
     5429      break; 
     5430    case PPC::BI__builtin_qpx_qvfctiwuz: 
     5431      ID = Intrinsic::ppc_qpx_qvfctiwuz; 
     5432      break; 
     5433    case PPC::BI__builtin_qpx_qvfctiwz: 
     5434      ID = Intrinsic::ppc_qpx_qvfctiwz; 
     5435      break; 
     5436    case PPC::BI__builtin_qpx_qvfnabs: 
     5437      ID = Intrinsic::ppc_qpx_qvfnabs; 
     5438      break; 
     5439    case PPC::BI__builtin_qpx_qvfneg: 
     5440      ID = Intrinsic::ppc_qpx_qvfneg; 
     5441      break; 
     5442    case PPC::BI__builtin_qpx_qvfre: 
     5443      ID = Intrinsic::ppc_qpx_qvfre; 
     5444      break; 
     5445    case PPC::BI__builtin_qpx_qvfres: 
     5446      ID = Intrinsic::ppc_qpx_qvfres; 
     5447      break; 
     5448    case PPC::BI__builtin_qpx_qvfrim: 
     5449      ID = Intrinsic::ppc_qpx_qvfrim; 
     5450      break; 
     5451    case PPC::BI__builtin_qpx_qvfrin: 
     5452      ID = Intrinsic::ppc_qpx_qvfrin; 
     5453      break; 
     5454    case PPC::BI__builtin_qpx_qvfrip: 
     5455      ID = Intrinsic::ppc_qpx_qvfrip; 
     5456      break; 
     5457    case PPC::BI__builtin_qpx_qvfriz: 
     5458      ID = Intrinsic::ppc_qpx_qvfriz; 
     5459      break; 
     5460    case PPC::BI__builtin_qpx_qvfrsp: 
     5461      ID = Intrinsic::ppc_qpx_qvfrsp; 
     5462      break; 
     5463    case PPC::BI__builtin_qpx_qvfrsqrte: 
     5464      ID = Intrinsic::ppc_qpx_qvfrsqrte; 
     5465      break; 
     5466    case PPC::BI__builtin_qpx_qvfrsqrtes: 
     5467      ID = Intrinsic::ppc_qpx_qvfrsqrtes; 
     5468      break; 
     5469    case PPC::BI__builtin_qpx_qvfadd: 
     5470      ID = Intrinsic::ppc_qpx_qvfadd; 
     5471      break; 
     5472    case PPC::BI__builtin_qpx_qvfcmpeq: 
     5473      ID = Intrinsic::ppc_qpx_qvfcmpeq; 
     5474      break; 
     5475    case PPC::BI__builtin_qpx_qvfcmpgt: 
     5476      ID = Intrinsic::ppc_qpx_qvfcmpgt; 
     5477      break; 
     5478    case PPC::BI__builtin_qpx_qvfcmplt: 
     5479      ID = Intrinsic::ppc_qpx_qvfcmplt; 
     5480      break; 
     5481    case PPC::BI__builtin_qpx_qvfcpsgn: 
     5482      ID = Intrinsic::ppc_qpx_qvfcpsgn; 
     5483      break; 
     5484    case PPC::BI__builtin_qpx_qvfmadd: 
     5485      ID = Intrinsic::ppc_qpx_qvfmadd; 
     5486      break; 
     5487    case PPC::BI__builtin_qpx_qvfmsub: 
     5488      ID = Intrinsic::ppc_qpx_qvfmsub; 
     5489      break; 
     5490    case PPC::BI__builtin_qpx_qvfmul: 
     5491      ID = Intrinsic::ppc_qpx_qvfmul; 
     5492      break; 
     5493    case PPC::BI__builtin_qpx_qvfnmadd: 
     5494      ID = Intrinsic::ppc_qpx_qvfnmadd; 
     5495      break; 
     5496    case PPC::BI__builtin_qpx_qvfnmsub: 
     5497      ID = Intrinsic::ppc_qpx_qvfnmsub; 
     5498      break; 
     5499    case PPC::BI__builtin_qpx_qvfsel: 
     5500      ID = Intrinsic::ppc_qpx_qvfsel; 
     5501      break; 
     5502    case PPC::BI__builtin_qpx_qvfsub: 
     5503      ID = Intrinsic::ppc_qpx_qvfsub; 
     5504      break; 
     5505    case PPC::BI__builtin_qpx_qvftstnan: 
     5506      ID = Intrinsic::ppc_qpx_qvftstnan; 
     5507      break; 
     5508    case PPC::BI__builtin_qpx_qvfxmadd: 
     5509      ID = Intrinsic::ppc_qpx_qvfxmadd; 
     5510      break; 
     5511    case PPC::BI__builtin_qpx_qvfxmul: 
     5512      ID = Intrinsic::ppc_qpx_qvfxmul; 
     5513      break; 
     5514    case PPC::BI__builtin_qpx_qvfxxcpnmadd: 
     5515      ID = Intrinsic::ppc_qpx_qvfxxcpnmadd; 
     5516      break; 
     5517    case PPC::BI__builtin_qpx_qvfxxmadd: 
     5518      ID = Intrinsic::ppc_qpx_qvfxxmadd; 
     5519      break; 
     5520    case PPC::BI__builtin_qpx_qvfxxnpmadd: 
     5521      ID = Intrinsic::ppc_qpx_qvfxxnpmadd; 
     5522      break; 
     5523    case PPC::BI__builtin_qpx_qvflogical: 
     5524      ID = Intrinsic::ppc_qpx_qvflogical; 
     5525      break; 
     5526    case PPC::BI__builtin_qpx_qvfperm: 
     5527      ID = Intrinsic::ppc_qpx_qvfperm; 
     5528      break; 
     5529    case PPC::BI__builtin_qpx_qvlpcld: 
     5530      ID = Intrinsic::ppc_qpx_qvlpcld; 
     5531      break; 
     5532    case PPC::BI__builtin_qpx_qvlpcls: 
     5533      ID = Intrinsic::ppc_qpx_qvlpcls; 
     5534      break; 
     5535    case PPC::BI__builtin_qpx_qvlpcrd: 
     5536      ID = Intrinsic::ppc_qpx_qvlpcrd; 
     5537      break; 
     5538    case PPC::BI__builtin_qpx_qvlpcrs: 
     5539      ID = Intrinsic::ppc_qpx_qvlpcrs; 
     5540      break; 
     5541    case PPC::BI__builtin_qpx_qvgpci: 
     5542      ID = Intrinsic::ppc_qpx_qvgpci; 
     5543      break; 
     5544    case PPC::BI__builtin_qpx_qvlfcda: 
     5545      ID = Intrinsic::ppc_qpx_qvlfcda; 
     5546      break; 
     5547    case PPC::BI__builtin_qpx_qvlfcd: 
     5548      ID = Intrinsic::ppc_qpx_qvlfcd; 
     5549      break; 
     5550    case PPC::BI__builtin_qpx_qvlfcsa: 
     5551      ID = Intrinsic::ppc_qpx_qvlfcsa; 
     5552      break; 
     5553    case PPC::BI__builtin_qpx_qvlfcs: 
     5554      ID = Intrinsic::ppc_qpx_qvlfcs; 
     5555      break; 
     5556    case PPC::BI__builtin_qpx_qvlfda: 
     5557      ID = Intrinsic::ppc_qpx_qvlfda; 
     5558      break; 
     5559    case PPC::BI__builtin_qpx_qvlfd: 
     5560      ID = Intrinsic::ppc_qpx_qvlfd; 
     5561      break; 
     5562    case PPC::BI__builtin_qpx_qvlfiwaa: 
     5563      ID = Intrinsic::ppc_qpx_qvlfiwaa; 
     5564      break; 
     5565    case PPC::BI__builtin_qpx_qvlfiwa: 
     5566      ID = Intrinsic::ppc_qpx_qvlfiwa; 
     5567      break; 
     5568    case PPC::BI__builtin_qpx_qvlfiwza: 
     5569      ID = Intrinsic::ppc_qpx_qvlfiwza; 
     5570      break; 
     5571    case PPC::BI__builtin_qpx_qvlfiwz: 
     5572      ID = Intrinsic::ppc_qpx_qvlfiwz; 
     5573      break; 
     5574    case PPC::BI__builtin_qpx_qvlfsa: 
     5575      ID = Intrinsic::ppc_qpx_qvlfsa; 
     5576      break; 
     5577    case PPC::BI__builtin_qpx_qvlfs: 
     5578      ID = Intrinsic::ppc_qpx_qvlfs; 
     5579      break; 
     5580    case PPC::BI__builtin_qpx_qvstfcda: 
     5581      ID = Intrinsic::ppc_qpx_qvstfcda; 
     5582      break; 
     5583    case PPC::BI__builtin_qpx_qvstfcd: 
     5584      ID = Intrinsic::ppc_qpx_qvstfcd; 
     5585      break; 
     5586    case PPC::BI__builtin_qpx_qvstfcsa: 
     5587      ID = Intrinsic::ppc_qpx_qvstfcsa; 
     5588      break; 
     5589    case PPC::BI__builtin_qpx_qvstfcs: 
     5590      ID = Intrinsic::ppc_qpx_qvstfcs; 
     5591      break; 
     5592    case PPC::BI__builtin_qpx_qvstfda: 
     5593      ID = Intrinsic::ppc_qpx_qvstfda; 
     5594      break; 
     5595    case PPC::BI__builtin_qpx_qvstfd: 
     5596      ID = Intrinsic::ppc_qpx_qvstfd; 
     5597      break; 
     5598    case PPC::BI__builtin_qpx_qvstfiwa: 
     5599      ID = Intrinsic::ppc_qpx_qvstfiwa; 
     5600      break; 
     5601    case PPC::BI__builtin_qpx_qvstfiw: 
     5602      ID = Intrinsic::ppc_qpx_qvstfiw; 
     5603      break; 
     5604    case PPC::BI__builtin_qpx_qvstfsa: 
     5605      ID = Intrinsic::ppc_qpx_qvstfsa; 
     5606      break; 
     5607    case PPC::BI__builtin_qpx_qvstfs: 
     5608      ID = Intrinsic::ppc_qpx_qvstfs; 
     5609      break; 
     5610    } 
     5611    llvm::Function *F = CGM.getIntrinsic(ID); 
     5612    return Builder.CreateCall(F, Ops, ""); 
     5613  } 
    51245614  } 
    51255615} 
  • lib/Driver/Driver.cpp

    diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
    index 9a73da6..7086999 100644
    a b  
    17421742    case llvm::Triple::Minix: 
    17431743      TC = new toolchains::Minix(*this, Target, Args); 
    17441744      break; 
     1745    case llvm::Triple::CNK: 
     1746      // fall through: same as Linux 
    17451747    case llvm::Triple::Linux: 
    17461748      if (Target.getArch() == llvm::Triple::hexagon) 
    17471749        TC = new toolchains::Hexagon_TC(*this, Target); 
  • lib/Driver/ToolChains.cpp

    diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
    index 53b78d2..6463dd9 100644
    a b  
    19681968Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) 
    19691969  : Generic_ELF(D, Triple, Args) { 
    19701970  llvm::Triple::ArchType Arch = Triple.getArch(); 
     1971 
    19711972  const std::string &SysRoot = getDriver().SysRoot; 
    19721973 
    19731974  // OpenSuse stores the linker with the compiler, add that to the search 
    1974   // path. 
     1975  // path. This is needed for the BG/P as well. 
    19751976  ToolChain::path_list &PPaths = getProgramPaths(); 
    19761977  PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" + 
    19771978                         GCCInstallation.getTriple().str() + "/bin").str()); 
  • lib/Driver/Tools.cpp

    diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
    index 31626b3..e7cd149 100644
    a b  
    902902  } 
    903903} 
    904904 
     905void Clang::AddPPCTargetArgs(const ArgList &Args, 
     906                             ArgStringList &CmdArgs) const { 
     907  // Set target cpu. 
     908  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { 
     909    const char *CPUName; 
     910    CPUName = A->getValue(Args); 
     911 
     912    CmdArgs.push_back("-target-cpu"); 
     913    CmdArgs.push_back(CPUName); 
     914  } 
     915} 
     916  
     917  
    905918void Clang::AddSparcTargetArgs(const ArgList &Args, 
    906919                             ArgStringList &CmdArgs) const { 
    907920  const Driver &D = getToolChain().getDriver(); 
     
    12901303    return; 
    12911304  if(TC.getTriple().getEnvironment() == llvm::Triple::ANDROIDEABI) { 
    12921305    if (!Args.hasArg(options::OPT_shared)) { 
     1306      if (!Args.hasArg(options::OPT_pie)) 
     1307        TC.getDriver().Diag(diag::err_drv_asan_android_requires_pie); 
    12931308      // For an executable, we add a .preinit_array stub. 
    12941309      CmdArgs.push_back("-u"); 
    12951310      CmdArgs.push_back("__asan_preinit"); 
     
    17761791    AddMIPSTargetArgs(Args, CmdArgs); 
    17771792    break; 
    17781793 
     1794  case llvm::Triple::ppc: 
     1795  case llvm::Triple::ppc64: 
     1796    AddPPCTargetArgs(Args, CmdArgs); 
     1797    break; 
     1798 
    17791799  case llvm::Triple::sparc: 
    17801800    AddSparcTargetArgs(Args, CmdArgs); 
    17811801    break; 
  • lib/Driver/Tools.h

    diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h
    index 651a8f2..aa15f35 100644
    a b  
    3939    void AddARMTargetArgs(const ArgList &Args, ArgStringList &CmdArgs, 
    4040                          bool KernelOrKext) const; 
    4141    void AddMIPSTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const; 
     42    void AddPPCTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const; 
    4243    void AddSparcTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const; 
    4344    void AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const; 
    4445    void AddHexagonTargetArgs (const ArgList &Args, ArgStringList &CmdArgs) const; 
  • (a) /dev/null vs. (b) b/lib/Headers/fp2intrin.h

    diff --git a/lib/Headers/fp2intrin.h b/lib/Headers/fp2intrin.h
    new file mode 100644
    index 0000000..1f59249
    a b  
     1/*===---- fp2intrin.h - PPC FP2 (Double Hummer) intrinsics -----------------=== 
     2 * 
     3 * Permission is hereby granted, free of charge, to any person obtaining a copy 
     4 * of this software and associated documentation files (the "Software"), to deal 
     5 * in the Software without restriction, including without limitation the rights 
     6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
     7 * copies of the Software, and to permit persons to whom the Software is 
     8 * furnished to do so, subject to the following conditions: 
     9 * 
     10 * The above copyright notice and this permission notice shall be included in 
     11 * all copies or substantial portions of the Software. 
     12 * 
     13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
     14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
     15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
     16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
     17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
     18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
     19 * THE SOFTWARE. 
     20 * 
     21 *===-----------------------------------------------------------------------=== 
     22 */ 
     23 
     24#ifndef _FP2INTRIN_H_INCLUDED 
     25#define _FP2INTRIN_H_INCLUDED 
     26 
     27typedef double __v2df __attribute__((__vector_size__(16))); 
     28 
     29static __inline__ float _Complex __attribute__((__always_inline__, __nodebug__)) 
     30__cmplxf (float a, float b) { 
     31  float _Complex r = { a, b }; 
     32  return r; 
     33} 
     34 
     35static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     36__cmplx (double a, double b) { 
     37  double _Complex r = { a, b }; 
     38  return r; 
     39} 
     40 
     41static __inline__ long double _Complex __attribute__((__always_inline__, __nodebug__)) 
     42__cmplxl (long double a, long double b) { 
     43  long double _Complex r = { a, b }; 
     44  return r; 
     45} 
     46 
     47static __inline__ float __attribute__((__always_inline__, __nodebug__)) 
     48__crealf (float _Complex a) { 
     49  return __real__ a; 
     50} 
     51 
     52static __inline__ double __attribute__((__always_inline__, __nodebug__)) 
     53__creal (double _Complex a) { 
     54  return __real__ a; 
     55} 
     56 
     57static __inline__ long double __attribute__((__always_inline__, __nodebug__)) 
     58__creall (long double _Complex a) { 
     59  return __real__ a; 
     60} 
     61 
     62static __inline__ float __attribute__((__always_inline__, __nodebug__)) 
     63__cimagf (float _Complex a) { 
     64  return __imag__ a; 
     65} 
     66 
     67static __inline__ double __attribute__((__always_inline__, __nodebug__)) 
     68__cimag (double _Complex a) { 
     69  return __imag__ a; 
     70} 
     71 
     72static __inline__ long double __attribute__((__always_inline__, __nodebug__)) 
     73__cimagl (long double _Complex a) { 
     74  return __imag__ a; 
     75} 
     76 
     77static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     78__lfps (const float * a) { 
     79  __v2df b_ = __builtin_fp2_lfps(a); 
     80  return *((double _Complex *) &b_); 
     81} 
     82 
     83static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     84__lfxs (const float * a) { 
     85  __v2df b_ = __builtin_fp2_lfxs(a); 
     86  return *((double _Complex *) &b_); 
     87} 
     88 
     89static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     90__lfpd (const double * a) { 
     91  __v2df b_ = __builtin_fp2_lfpd(a); 
     92  return *((double _Complex *) &b_); 
     93} 
     94 
     95static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     96__lfxd (const double * a) { 
     97  __v2df b_ = __builtin_fp2_lfxd(a); 
     98  return *((double _Complex *) &b_); 
     99} 
     100 
     101static __inline__ void __attribute__((__always_inline__, __nodebug__)) 
     102__stfps (float * b, double _Complex a) { 
     103  __builtin_fp2_stfps(*((__v2df *) &a), b); 
     104} 
     105 
     106static __inline__ void __attribute__((__always_inline__, __nodebug__)) 
     107__stfxs (float * b, double _Complex a) { 
     108  __builtin_fp2_stfxs(*((__v2df *) &a), b); 
     109} 
     110 
     111static __inline__ void __attribute__((__always_inline__, __nodebug__)) 
     112__stfpd (double * b, double _Complex a) { 
     113  __builtin_fp2_stfpd(*((__v2df *) &a), b); 
     114} 
     115 
     116static __inline__ void __attribute__((__always_inline__, __nodebug__)) 
     117__stfxd (double * b, double _Complex a) { 
     118  __builtin_fp2_stfxd(*((__v2df *) &a), b); 
     119} 
     120 
     121static __inline__ void __attribute__((__always_inline__, __nodebug__)) 
     122__stfpiw (int * b, double _Complex a) { 
     123  __builtin_fp2_stfpiw(*((__v2df *) &a), b); 
     124} 
     125 
     126static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     127__fxmr (double _Complex a) { 
     128  __v2df b_ = __builtin_fp2_fxmr(*((__v2df *) &a)); 
     129  return *((double _Complex *) &b_); 
     130} 
     131 
     132static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     133__fpctiw (double _Complex a) { 
     134  __v2df b_ = __builtin_fp2_fpctiw(*((__v2df *) &a)); 
     135  return *((double _Complex *) &b_); 
     136} 
     137 
     138static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     139__fpctiwz (double _Complex a) { 
     140  __v2df b_ = __builtin_fp2_fpctiwz(*((__v2df *) &a)); 
     141  return *((double _Complex *) &b_); 
     142} 
     143 
     144static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     145__fprsp (double _Complex a) { 
     146  __v2df b_ = __builtin_fp2_fprsp(*((__v2df *) &a)); 
     147  return *((double _Complex *) &b_); 
     148} 
     149 
     150static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     151__fpre (double _Complex a) { 
     152  __v2df b_ = __builtin_fp2_fpre(*((__v2df *) &a)); 
     153  return *((double _Complex *) &b_); 
     154} 
     155 
     156static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     157__fprsqrte (double _Complex a) { 
     158  __v2df b_ = __builtin_fp2_fprsqrte(*((__v2df *) &a)); 
     159  return *((double _Complex *) &b_); 
     160} 
     161 
     162static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     163__fpneg (double _Complex a) { 
     164  __v2df b_ = __builtin_fp2_fpneg(*((__v2df *) &a)); 
     165  return *((double _Complex *) &b_); 
     166} 
     167 
     168static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     169__fpabs (double _Complex a) { 
     170  __v2df b_ = __builtin_fp2_fpabs(*((__v2df *) &a)); 
     171  return *((double _Complex *) &b_); 
     172} 
     173 
     174static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     175__fpnabs (double _Complex a) { 
     176  __v2df b_ = __builtin_fp2_fpnabs(*((__v2df *) &a)); 
     177  return *((double _Complex *) &b_); 
     178} 
     179 
     180static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     181__fpadd (double _Complex a, double _Complex b) { 
     182  __v2df c_ = __builtin_fp2_fpadd(*((__v2df *) &a), *((__v2df *) &b)); 
     183  return *((double _Complex *) &c_); 
     184} 
     185 
     186static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     187__fpsub (double _Complex a, double _Complex b) { 
     188  __v2df c_ = __builtin_fp2_fpsub(*((__v2df *) &a), *((__v2df *) &b)); 
     189  return *((double _Complex *) &c_); 
     190} 
     191 
     192static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     193__fpmul (double _Complex a, double _Complex b) { 
     194  __v2df c_ = __builtin_fp2_fpmul(*((__v2df *) &a), *((__v2df *) &b)); 
     195  return *((double _Complex *) &c_); 
     196} 
     197 
     198static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     199__fxmul (double _Complex a, double _Complex b) { 
     200  __v2df c_ = __builtin_fp2_fxmul(*((__v2df *) &a), *((__v2df *) &b)); 
     201  return *((double _Complex *) &c_); 
     202} 
     203 
     204static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     205__fxpmul (double _Complex a, double _Complex b) { 
     206  __v2df c_ = __builtin_fp2_fxpmul(*((__v2df *) &a), *((__v2df *) &b)); 
     207  return *((double _Complex *) &c_); 
     208} 
     209 
     210static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     211__fxsmul (double _Complex a, double _Complex b) { 
     212  __v2df c_ = __builtin_fp2_fxsmul(*((__v2df *) &a), *((__v2df *) &b)); 
     213  return *((double _Complex *) &c_); 
     214} 
     215 
     216static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     217__fpmadd (double _Complex a, double _Complex b, double _Complex c) { 
     218  __v2df d_ = __builtin_fp2_fpmadd(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     219  return *((double _Complex *) &d_); 
     220} 
     221 
     222static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     223__fpnmadd (double _Complex a, double _Complex b, double _Complex c) { 
     224  __v2df d_ = __builtin_fp2_fpnmadd(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     225  return *((double _Complex *) &d_); 
     226} 
     227 
     228static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     229__fpmsub (double _Complex a, double _Complex b, double _Complex c) { 
     230  __v2df d_ = __builtin_fp2_fpmsub(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     231  return *((double _Complex *) &d_); 
     232} 
     233 
     234static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     235__fpnmsub (double _Complex a, double _Complex b, double _Complex c) { 
     236  __v2df d_ = __builtin_fp2_fpnmsub(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     237  return *((double _Complex *) &d_); 
     238} 
     239 
     240static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     241__fxmadd (double _Complex a, double _Complex b, double _Complex c) { 
     242  __v2df d_ = __builtin_fp2_fxmadd(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     243  return *((double _Complex *) &d_); 
     244} 
     245 
     246static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     247__fxnmadd (double _Complex a, double _Complex b, double _Complex c) { 
     248  __v2df d_ = __builtin_fp2_fxnmadd(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     249  return *((double _Complex *) &d_); 
     250} 
     251 
     252static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     253__fxmsub (double _Complex a, double _Complex b, double _Complex c) { 
     254  __v2df d_ = __builtin_fp2_fxmsub(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     255  return *((double _Complex *) &d_); 
     256} 
     257 
     258static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     259__fxnmsub (double _Complex a, double _Complex b, double _Complex c) { 
     260  __v2df d_ = __builtin_fp2_fxnmsub(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     261  return *((double _Complex *) &d_); 
     262} 
     263 
     264static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     265__fxcpmadd (double _Complex a, double _Complex b, double _Complex c) { 
     266  __v2df d_ = __builtin_fp2_fxcpmadd(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     267  return *((double _Complex *) &d_); 
     268} 
     269 
     270static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     271__fxcsmadd (double _Complex a, double _Complex b, double _Complex c) { 
     272  __v2df d_ = __builtin_fp2_fxcsmadd(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     273  return *((double _Complex *) &d_); 
     274} 
     275 
     276static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     277__fxcpnmadd (double _Complex a, double _Complex b, double _Complex c) { 
     278  __v2df d_ = __builtin_fp2_fxcpnmadd(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     279  return *((double _Complex *) &d_); 
     280} 
     281 
     282static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     283__fxcsnmadd (double _Complex a, double _Complex b, double _Complex c) { 
     284  __v2df d_ = __builtin_fp2_fxcsnmadd(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     285  return *((double _Complex *) &d_); 
     286} 
     287 
     288static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     289__fxcpmsub (double _Complex a, double _Complex b, double _Complex c) { 
     290  __v2df d_ = __builtin_fp2_fxcpmsub(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     291  return *((double _Complex *) &d_); 
     292} 
     293 
     294static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     295__fxcsmsub (double _Complex a, double _Complex b, double _Complex c) { 
     296  __v2df d_ = __builtin_fp2_fxcsmsub(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     297  return *((double _Complex *) &d_); 
     298} 
     299 
     300static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     301__fxcpnmsub (double _Complex a, double _Complex b, double _Complex c) { 
     302  __v2df d_ = __builtin_fp2_fxcpnmsub(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     303  return *((double _Complex *) &d_); 
     304} 
     305 
     306static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     307__fxcsnmsub (double _Complex a, double _Complex b, double _Complex c) { 
     308  __v2df d_ = __builtin_fp2_fxcsnmsub(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     309  return *((double _Complex *) &d_); 
     310} 
     311 
     312static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     313__fxcpnpma (double _Complex a, double _Complex b, double _Complex c) { 
     314  __v2df d_ = __builtin_fp2_fxcpnpma(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     315  return *((double _Complex *) &d_); 
     316} 
     317 
     318static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     319__fxcsnpma (double _Complex a, double _Complex b, double _Complex c) { 
     320  __v2df d_ = __builtin_fp2_fxcsnpma(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     321  return *((double _Complex *) &d_); 
     322} 
     323 
     324static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     325__fxcpnsma (double _Complex a, double _Complex b, double _Complex c) { 
     326  __v2df d_ = __builtin_fp2_fxcpnsma(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     327  return *((double _Complex *) &d_); 
     328} 
     329 
     330static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     331__fxcsnsma (double _Complex a, double _Complex b, double _Complex c) { 
     332  __v2df d_ = __builtin_fp2_fxcsnsma(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     333  return *((double _Complex *) &d_); 
     334} 
     335 
     336static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     337__fxcxma (double _Complex a, double _Complex b, double _Complex c) { 
     338  __v2df d_ = __builtin_fp2_fxcxma(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     339  return *((double _Complex *) &d_); 
     340} 
     341 
     342static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     343__fxcxnms (double _Complex a, double _Complex b, double _Complex c) { 
     344  __v2df d_ = __builtin_fp2_fxcxnms(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     345  return *((double _Complex *) &d_); 
     346} 
     347 
     348static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     349__fxcxnpma (double _Complex a, double _Complex b, double _Complex c) { 
     350  __v2df d_ = __builtin_fp2_fxcxnpma(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     351  return *((double _Complex *) &d_); 
     352} 
     353 
     354static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     355__fxcxnsma (double _Complex a, double _Complex b, double _Complex c) { 
     356  __v2df d_ = __builtin_fp2_fxcxnsma(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     357  return *((double _Complex *) &d_); 
     358} 
     359 
     360static __inline__ double _Complex __attribute__((__always_inline__, __nodebug__)) 
     361__fpsel (double _Complex a, double _Complex b, double _Complex c) { 
     362  __v2df d_ = __builtin_fp2_fpsel(*((__v2df *) &a), *((__v2df *) &b), *((__v2df *) &c)); 
     363  return *((double _Complex *) &d_); 
     364} 
     365 
     366#endif 
     367 
  • (a) /dev/null vs. (b) b/lib/Headers/qpxintrin.h

    diff --git a/lib/Headers/qpxintrin.h b/lib/Headers/qpxintrin.h
    new file mode 100644
    index 0000000..99ea3d4
    a b  
     1/*===---- qpxintrin.h - PPC QPX intrinsics ---------------------------------=== 
     2 * 
     3 * Permission is hereby granted, free of charge, to any person obtaining a copy 
     4 * of this software and associated documentation files (the "Software"), to deal 
     5 * in the Software without restriction, including without limitation the rights 
     6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
     7 * copies of the Software, and to permit persons to whom the Software is 
     8 * furnished to do so, subject to the following conditions: 
     9 * 
     10 * The above copyright notice and this permission notice shall be included in 
     11 * all copies or substantial portions of the Software. 
     12 * 
     13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
     14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
     15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
     16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
     17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
     18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
     19 * THE SOFTWARE. 
     20 * 
     21 *===-----------------------------------------------------------------------=== 
     22 */ 
     23 
     24#ifndef _QPXINTRIN_H_INCLUDED 
     25#define _QPXINTRIN_H_INCLUDED 
     26 
     27typedef double vector4double __attribute__((__vector_size__(32))); 
     28 
     29#ifndef __VECTOR4DOUBLE__  
     30#define __VECTOR4DOUBLE__ 1 
     31#endif 
     32 
     33static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     34vec_ld (long a, long *b) { 
     35  return __builtin_qpx_qvlfd((double *) &((char *) b)[a]); 
     36} 
     37 
     38static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     39vec_lda (long a, long *b) { 
     40  return __builtin_qpx_qvlfda((double *) &((char *) b)[a]); 
     41} 
     42 
     43static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     44vec_ld (long a, unsigned long *b) { 
     45  return __builtin_qpx_qvlfd((double *) &((char *) b)[a]); 
     46} 
     47 
     48static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     49vec_lda (long a, unsigned long *b) { 
     50  return __builtin_qpx_qvlfda((double *) &((char *) b)[a]); 
     51} 
     52 
     53static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     54vec_ld (long a, long long *b) { 
     55  return __builtin_qpx_qvlfd((double *) &((char *) b)[a]); 
     56} 
     57 
     58static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     59vec_lda (long a, long long *b) { 
     60  return __builtin_qpx_qvlfda((double *) &((char *) b)[a]); 
     61} 
     62 
     63static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     64vec_ld (long a, unsigned long long *b) { 
     65  return __builtin_qpx_qvlfd((double *) &((char *) b)[a]); 
     66} 
     67 
     68static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     69vec_lda (long a, unsigned long long *b) { 
     70  return __builtin_qpx_qvlfda((double *) &((char *) b)[a]); 
     71} 
     72 
     73static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     74vec_ld (long a, float *b) { 
     75  return __builtin_qpx_qvlfs((float *) &((char *) b)[a]); 
     76} 
     77 
     78static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     79vec_lda (long a, float *b) { 
     80  return __builtin_qpx_qvlfsa((float *) &((char *) b)[a]); 
     81} 
     82 
     83static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     84vec_ld (long a, float _Complex *b) { 
     85  return __builtin_qpx_qvlfs((float *) &((char *) b)[a]); 
     86} 
     87 
     88static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     89vec_lda (long a, float _Complex *b) { 
     90  return __builtin_qpx_qvlfsa((float *) &((char *) b)[a]); 
     91} 
     92 
     93static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     94vec_ld (long a, double *b) { 
     95  return __builtin_qpx_qvlfd((double *) &((char *) b)[a]); 
     96} 
     97 
     98static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     99vec_lda (long a, double *b) { 
     100  return __builtin_qpx_qvlfda((double *) &((char *) b)[a]); 
     101} 
     102 
     103static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     104vec_ld (long a, double _Complex *b) { 
     105  return __builtin_qpx_qvlfd((double *) &((char *) b)[a]); 
     106} 
     107 
     108static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     109vec_lda (long a, double _Complex *b) { 
     110  return __builtin_qpx_qvlfda((double *) &((char *) b)[a]); 
     111} 
     112 
     113static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     114vec_ldia (long a, int *b) { 
     115  return __builtin_qpx_qvlfiwa((int *) &((char *) b)[a]); 
     116} 
     117 
     118static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     119vec_ldiaa (long a, int *b) { 
     120  return __builtin_qpx_qvlfiwaa((int *) &((char *) b)[a]); 
     121} 
     122 
     123static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     124vec_ldiz (long a, unsigned *b) { 
     125  return __builtin_qpx_qvlfiwz((unsigned *) &((char *) b)[a]); 
     126} 
     127 
     128static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     129vec_ldiza (long a, unsigned *b) { 
     130  return __builtin_qpx_qvlfiwza((unsigned *) &((char *) b)[a]); 
     131} 
     132 
     133static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     134vec_lds (long a, float *b) { 
     135  return (vector4double) { (double) *((float *) &((char *) b)[a]) }; 
     136} 
     137 
     138static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     139vec_lds (long a, double *b) { 
     140  return (vector4double) { *((double *) &((char *) b)[a]) }; 
     141} 
     142 
     143static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     144vec_lds (long a, float _Complex *b) { 
     145  return __builtin_qpx_qvlfcs((float _Complex *) &((char *) b)[a]); 
     146} 
     147 
     148static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     149vec_ldsa (long a, float _Complex *b) { 
     150  return __builtin_qpx_qvlfcsa((float _Complex *) &((char *) b)[a]); 
     151} 
     152 
     153static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     154vec_lds (long a, double _Complex *b) { 
     155  return __builtin_qpx_qvlfcd((double _Complex *) &((char *) b)[a]); 
     156} 
     157 
     158static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     159vec_ldsa (long a, double _Complex *b) { 
     160  return __builtin_qpx_qvlfcda((double _Complex *) &((char *) b)[a]); 
     161} 
     162 
     163static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     164vec_ld2 (long a, float *b) { 
     165  return __builtin_qpx_qvlfcs((float _Complex *) &((char *) b)[a]); 
     166} 
     167 
     168static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     169vec_ld2a (long a, float *b) { 
     170  return __builtin_qpx_qvlfcsa((float _Complex *) &((char *) b)[a]); 
     171} 
     172 
     173static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     174vec_ld2 (long a, double *b) { 
     175  return __builtin_qpx_qvlfcd((double _Complex *) &((char *) b)[a]); 
     176} 
     177 
     178static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     179vec_ld2a (long a, double *b) { 
     180  return __builtin_qpx_qvlfcda((double _Complex *) &((char *) b)[a]); 
     181} 
     182 
     183static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     184vec_st (vector4double a, long b, int *c) { 
     185  return __builtin_qpx_qvstfiw(a, (unsigned *) &((char *) c)[b]); 
     186} 
     187 
     188static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     189vec_sta (vector4double a, long b, int *c) { 
     190  return __builtin_qpx_qvstfiwa(a, (unsigned *) &((char *) c)[b]); 
     191} 
     192 
     193static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     194vec_st (vector4double a, long b, unsigned *c) { 
     195  return __builtin_qpx_qvstfiw(a, (unsigned *) &((char *) c)[b]); 
     196} 
     197 
     198static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     199vec_sta (vector4double a, long b, unsigned *c) { 
     200  return __builtin_qpx_qvstfiwa(a, (unsigned *) &((char *) c)[b]); 
     201} 
     202 
     203static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     204vec_st (vector4double a, long b, long *c) { 
     205  return __builtin_qpx_qvstfd(a, (double *) &((char *) c)[b]); 
     206} 
     207 
     208static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     209vec_sta (vector4double a, long b, long *c) { 
     210  return __builtin_qpx_qvstfda(a, (double *) &((char *) c)[b]); 
     211} 
     212 
     213static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     214vec_st (vector4double a, long b, unsigned long *c) { 
     215  return __builtin_qpx_qvstfd(a, (double *) &((char *) c)[b]); 
     216} 
     217 
     218static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     219vec_sta (vector4double a, long b, unsigned long *c) { 
     220  return __builtin_qpx_qvstfda(a, (double *) &((char *) c)[b]); 
     221} 
     222 
     223static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     224vec_st (vector4double a, long b, long long *c) { 
     225  return __builtin_qpx_qvstfd(a, (double *) &((char *) c)[b]); 
     226} 
     227 
     228static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     229vec_sta (vector4double a, long b, long long *c) { 
     230  return __builtin_qpx_qvstfda(a, (double *) &((char *) c)[b]); 
     231} 
     232 
     233static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     234vec_st (vector4double a, long b, unsigned long long *c) { 
     235  return __builtin_qpx_qvstfd(a, (double *) &((char *) c)[b]); 
     236} 
     237 
     238static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     239vec_sta (vector4double a, long b, unsigned long long *c) { 
     240  return __builtin_qpx_qvstfda(a, (double *) &((char *) c)[b]); 
     241} 
     242 
     243static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     244vec_st (vector4double a, long b, float *c) { 
     245  return __builtin_qpx_qvstfs(a, (float *) &((char *) c)[b]); 
     246} 
     247 
     248static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     249vec_sta (vector4double a, long b, float *c) { 
     250  return __builtin_qpx_qvstfsa(a, (float *) &((char *) c)[b]); 
     251} 
     252 
     253static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     254vec_st (vector4double a, long b, float _Complex *c) { 
     255  return __builtin_qpx_qvstfs(a, (float *) &((char *) c)[b]); 
     256} 
     257 
     258static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     259vec_sta (vector4double a, long b, float _Complex *c) { 
     260  return __builtin_qpx_qvstfsa(a, (float *) &((char *) c)[b]); 
     261} 
     262 
     263static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     264vec_st (vector4double a, long b, double *c) { 
     265  return __builtin_qpx_qvstfd(a, (double *) &((char *) c)[b]); 
     266} 
     267 
     268static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     269vec_sta (vector4double a, long b, double *c) { 
     270  return __builtin_qpx_qvstfda(a, (double *) &((char *) c)[b]); 
     271} 
     272 
     273static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     274vec_st (vector4double a, long b, double _Complex *c) { 
     275  return __builtin_qpx_qvstfd(a, (double *) &((char *) c)[b]); 
     276} 
     277 
     278static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     279vec_sta (vector4double a, long b, double _Complex *c) { 
     280  return __builtin_qpx_qvstfda(a, (double *) &((char *) c)[b]); 
     281} 
     282 
     283static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     284vec_sts (vector4double a, long b, float *c) { 
     285  *((float *) &((char *) c)[b]) = (float) a[0]; 
     286} 
     287 
     288static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     289vec_sts (vector4double a, long b, double *c) { 
     290  *((double *) &((char *) c)[b]) = a[0]; 
     291} 
     292 
     293static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     294vec_sts (vector4double a, long b, float _Complex *c) { 
     295  return __builtin_qpx_qvstfcs(a, (float _Complex *) &((char *) c)[b]); 
     296} 
     297 
     298static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     299vec_stsa (vector4double a, long b, float _Complex *c) { 
     300  return __builtin_qpx_qvstfcsa(a, (float _Complex *) &((char *) c)[b]); 
     301} 
     302 
     303static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     304vec_sts (vector4double a, long b, double _Complex *c) { 
     305  return __builtin_qpx_qvstfcd(a, (double _Complex *) &((char *) c)[b]); 
     306} 
     307 
     308static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     309vec_stsa (vector4double a, long b, double _Complex *c) { 
     310  return __builtin_qpx_qvstfcda(a, (double _Complex *) &((char *) c)[b]); 
     311} 
     312 
     313static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     314vec_st2 (vector4double a, long b, float *c) { 
     315  return __builtin_qpx_qvstfcs(a, (float _Complex *) &((char *) c)[b]); 
     316} 
     317 
     318static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     319vec_st2a (vector4double a, long b, float *c) { 
     320  return __builtin_qpx_qvstfcsa(a, (float _Complex *) &((char *) c)[b]); 
     321} 
     322 
     323static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     324vec_st2 (vector4double a, long b, double *c) { 
     325  return __builtin_qpx_qvstfcd(a, (double _Complex *) &((char *) c)[b]); 
     326} 
     327 
     328static __inline__ void __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     329vec_st2a (vector4double a, long b, double *c) { 
     330  return __builtin_qpx_qvstfcda(a, (double _Complex *) &((char *) c)[b]); 
     331} 
     332 
     333static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     334vec_abs (vector4double a) { 
     335  return __builtin_qpx_qvfabs(a); 
     336} 
     337 
     338static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     339vec_neg (vector4double a) { 
     340  return __builtin_qpx_qvfneg(a); 
     341} 
     342 
     343static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     344vec_nabs (vector4double a) { 
     345  return __builtin_qpx_qvfnabs(a); 
     346} 
     347 
     348static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     349vec_re (vector4double a) { 
     350  return __builtin_qpx_qvfre(a); 
     351} 
     352 
     353static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     354vec_res (vector4double a) { 
     355  return __builtin_qpx_qvfres(a); 
     356} 
     357 
     358static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     359vec_rsqrte (vector4double a) { 
     360  return __builtin_qpx_qvfrsqrte(a); 
     361} 
     362 
     363static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     364vec_rsqrtes (vector4double a) { 
     365  return __builtin_qpx_qvfrsqrtes(a); 
     366} 
     367 
     368static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     369vec_swsqrt (vector4double a) { 
     370  return (vector4double) 
     371         { __builtin_sqrt(a[0]), __builtin_sqrt(a[1]), 
     372           __builtin_sqrt(a[2]), __builtin_sqrt(a[3]) }; 
     373} 
     374 
     375static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     376vec_swsqrt_nochk (vector4double a) { 
     377  return (vector4double) 
     378         { __builtin_sqrt(a[0]), __builtin_sqrt(a[1]), 
     379           __builtin_sqrt(a[2]), __builtin_sqrt(a[3]) }; 
     380} 
     381 
     382static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     383vec_swsqrts (vector4double a) { 
     384  return (vector4double) 
     385         { __builtin_sqrtf((float) a[0]), __builtin_sqrtf((float) a[1]), 
     386           __builtin_sqrtf((float) a[2]), __builtin_sqrtf((float) a[3]) }; 
     387} 
     388 
     389static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     390vec_swsqrts_nochk (vector4double a) { 
     391  return (vector4double) 
     392         { __builtin_sqrtf((float) a[0]), __builtin_sqrtf((float) a[1]), 
     393           __builtin_sqrtf((float) a[2]), __builtin_sqrtf((float) a[3]) }; 
     394} 
     395 
     396static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     397vec_add (vector4double a, vector4double b) { 
     398  return __builtin_qpx_qvfadd(a, b); 
     399} 
     400 
     401static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     402vec_cpsgn (vector4double a, vector4double b) { 
     403  return __builtin_qpx_qvfcpsgn(a, b); 
     404} 
     405 
     406static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     407vec_mul (vector4double a, vector4double b) { 
     408  return __builtin_qpx_qvfmul(a, b); 
     409} 
     410 
     411static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     412vec_sub (vector4double a, vector4double b) { 
     413  return __builtin_qpx_qvfsub(a, b); 
     414} 
     415 
     416static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     417vec_swdiv (vector4double a, vector4double b) { 
     418  return (vector4double) { a[0]/b[0], a[1]/b[1], a[2]/b[2], a[3]/b[3] }; 
     419} 
     420 
     421static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     422vec_swdiv_nochk (vector4double a, vector4double b) { 
     423  return (vector4double) { a[0]/b[0], a[1]/b[1], a[2]/b[2], a[3]/b[3] }; 
     424} 
     425 
     426static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     427vec_swdivs (vector4double a, vector4double b) { 
     428 
     429  return (vector4double) 
     430         { (double) ((float) a[0]/ (float) b[0]), 
     431           (double) ((float) a[1]/ (float) b[1]), 
     432           (double) ((float) a[2]/ (float) b[2]), 
     433           (double) ((float) a[3]/ (float) b[3]) }; 
     434} 
     435 
     436static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     437vec_swdivs_nochk (vector4double a, vector4double b) { 
     438  return (vector4double) 
     439         { (double) ((float) a[0]/ (float) b[0]), 
     440           (double) ((float) a[1]/ (float) b[1]), 
     441           (double) ((float) a[2]/ (float) b[2]), 
     442           (double) ((float) a[3]/ (float) b[3]) }; 
     443} 
     444 
     445static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     446vec_xmul (vector4double a, vector4double b) { 
     447  return __builtin_qpx_qvfxmul(a, b); 
     448} 
     449 
     450static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     451vec_madd (vector4double a, vector4double b, vector4double c) { 
     452  return __builtin_qpx_qvfmadd(a, b, c); 
     453} 
     454 
     455static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     456vec_msub (vector4double a, vector4double b, vector4double c) { 
     457  return __builtin_qpx_qvfmsub(a, b, c); 
     458} 
     459 
     460static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     461vec_nmadd (vector4double a, vector4double b, vector4double c) { 
     462  return __builtin_qpx_qvfnmadd(a, b, c); 
     463} 
     464 
     465static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     466vec_nmsub (vector4double a, vector4double b, vector4double c) { 
     467  return __builtin_qpx_qvfnmsub(a, b, c); 
     468} 
     469 
     470static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     471vec_xmadd (vector4double a, vector4double b, vector4double c) { 
     472  return __builtin_qpx_qvfxmadd(a, b, c); 
     473} 
     474 
     475static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     476vec_xxmadd (vector4double a, vector4double b, vector4double c) { 
     477  return __builtin_qpx_qvfxxmadd(a, b, c); 
     478} 
     479 
     480static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     481vec_xxcpnmadd (vector4double a, vector4double b, vector4double c) { 
     482  return __builtin_qpx_qvfxxcpnmadd(a, b, c); 
     483} 
     484 
     485static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     486vec_xxnpmadd (vector4double a, vector4double b, vector4double c) { 
     487  return __builtin_qpx_qvfxxnpmadd(a, b, c); 
     488} 
     489 
     490static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     491vec_ceil (vector4double a) { 
     492  return __builtin_qpx_qvfrip(a); 
     493} 
     494 
     495static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     496vec_floor (vector4double a) { 
     497  return __builtin_qpx_qvfrim(a); 
     498} 
     499 
     500static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     501vec_round (vector4double a) { 
     502  return __builtin_qpx_qvfrin(a); 
     503} 
     504 
     505static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     506vec_rsp (vector4double a) { 
     507  return __builtin_qpx_qvfrsp(a); 
     508} 
     509 
     510static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     511vec_trunc (vector4double a) { 
     512  return __builtin_qpx_qvfriz(a); 
     513} 
     514 
     515static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     516vec_cfid (vector4double a) { 
     517  return __builtin_qpx_qvfcfid(a); 
     518} 
     519 
     520static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     521vec_cfidu (vector4double a) { 
     522  return __builtin_qpx_qvfcfidu(a); 
     523} 
     524 
     525static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     526vec_ctid (vector4double a) { 
     527  return __builtin_qpx_qvfctid(a); 
     528} 
     529 
     530static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     531vec_ctidu (vector4double a) { 
     532  return __builtin_qpx_qvfctidu(a); 
     533} 
     534 
     535static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     536vec_ctidz (vector4double a) { 
     537  return __builtin_qpx_qvfctidz(a); 
     538} 
     539 
     540static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     541vec_ctiduz (vector4double a) { 
     542  return __builtin_qpx_qvfctiduz(a); 
     543} 
     544 
     545static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     546vec_ctiw (vector4double a) { 
     547  return __builtin_qpx_qvfctiw(a); 
     548} 
     549 
     550static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     551vec_ctiwu (vector4double a) { 
     552  return __builtin_qpx_qvfctiwu(a); 
     553} 
     554 
     555static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     556vec_ctiwz (vector4double a) { 
     557  return __builtin_qpx_qvfctiwz(a); 
     558} 
     559 
     560static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     561vec_ctiwuz (vector4double a) { 
     562  return __builtin_qpx_qvfctiwuz(a); 
     563} 
     564 
     565static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     566vec_cmpgt (vector4double a, vector4double b) { 
     567  return __builtin_qpx_qvfcmpgt(a, b); 
     568} 
     569 
     570static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     571vec_cmplt (vector4double a, vector4double b) { 
     572  return __builtin_qpx_qvfcmplt(a, b); 
     573} 
     574 
     575static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     576vec_cmpeq (vector4double a, vector4double b) { 
     577  return __builtin_qpx_qvfcmpeq(a, b); 
     578} 
     579 
     580static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     581vec_sel (vector4double a, vector4double b, vector4double c) { 
     582  return __builtin_qpx_qvfsel(a, b, c); 
     583} 
     584 
     585static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     586vec_tstnan (vector4double a, vector4double b) { 
     587  return __builtin_qpx_qvftstnan(a, b); 
     588} 
     589 
     590static __inline__ double __attribute__((__always_inline__, __nodebug__)) 
     591vec_extract (vector4double a, int b) { 
     592  return a[b & 3]; 
     593} 
     594 
     595static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     596vec_insert (double a, vector4double b, int c) { 
     597  vector4double r = b; 
     598  r[c & 3] = a; 
     599  return r; 
     600} 
     601 
     602#define vec_gpci(a) __builtin_qpx_qvgpci(a) 
     603 
     604static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     605vec_lvsl (long a, float *b) { 
     606  return __builtin_qpx_qvlpcls((float *) &((char *) b)[a]); 
     607} 
     608 
     609static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     610vec_lvsl (long a, float _Complex *b) { 
     611  return __builtin_qpx_qvlpcls((float *) &((char *) b)[a]); 
     612} 
     613 
     614static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     615vec_lvsl (long a, double *b) { 
     616  return __builtin_qpx_qvlpcld((double *) &((char *) b)[a]); 
     617} 
     618 
     619static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     620vec_lvsl (long a, double _Complex *b) { 
     621  return __builtin_qpx_qvlpcld((double *) &((char *) b)[a]); 
     622} 
     623 
     624static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     625vec_lvsr (long a, float *b) { 
     626  return __builtin_qpx_qvlpcrs((float *) &((char *) b)[a]); 
     627} 
     628 
     629static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     630vec_lvsr (long a, float _Complex *b) { 
     631  return __builtin_qpx_qvlpcrs((float *) &((char *) b)[a]); 
     632} 
     633 
     634static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     635vec_lvsr (long a, double *b) { 
     636  return __builtin_qpx_qvlpcrd((double *) &((char *) b)[a]); 
     637} 
     638 
     639static __inline__ vector4double __attribute__((__overloadable__, __always_inline__, __nodebug__)) 
     640vec_lvsr (long a, double _Complex *b) { 
     641  return __builtin_qpx_qvlpcrd((double *) &((char *) b)[a]); 
     642} 
     643 
     644static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     645vec_perm (vector4double a, vector4double b, vector4double c) { 
     646  return __builtin_qpx_qvfperm(a, b, c); 
     647} 
     648 
     649static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     650vec_promote (double a, int b) { 
     651  vector4double r; 
     652  r[b & 3] = a; 
     653  return r; 
     654} 
     655 
     656#define vec_sldw(a, b, c) __builtin_shufflevector(a, b, c, (c)+1, (c)+2, (c)+3); 
     657 
     658static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     659vec_splat (vector4double a, int b) { 
     660  return (vector4double) { a[b] }; 
     661} 
     662 
     663static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     664vec_splats (double a) { 
     665  return (vector4double) { a }; 
     666} 
     667 
     668static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     669vec_and (vector4double a, vector4double b) { 
     670  return __builtin_qpx_qvflogical(a, b, 0x1); 
     671} 
     672 
     673static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     674vec_andc (vector4double a, vector4double b) { 
     675  return __builtin_qpx_qvflogical(a, b, 0x4); 
     676} 
     677 
     678#define vec_logical(a, b, c) __builtin_qpx_qvflogical(a, b, c) 
     679 
     680static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     681vec_nand (vector4double a, vector4double b) { 
     682  return __builtin_qpx_qvflogical(a, b, 0xE); 
     683} 
     684 
     685static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     686vec_nor (vector4double a, vector4double b) { 
     687  return __builtin_qpx_qvflogical(a, b, 0x8); 
     688} 
     689 
     690static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     691vec_not (vector4double a) { 
     692  return vec_nor(a, a); 
     693} 
     694 
     695static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     696vec_or (vector4double a, vector4double b) { 
     697  return __builtin_qpx_qvflogical(a, b, 0x7); 
     698} 
     699 
     700static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     701vec_orc (vector4double a, vector4double b) { 
     702  return __builtin_qpx_qvflogical(a, b, 0xD); 
     703} 
     704 
     705static __inline__ vector4double __attribute__((__always_inline__, __nodebug__)) 
     706vec_xor (vector4double a, vector4double b) { 
     707  return __builtin_qpx_qvflogical(a, b, 0x6); 
     708} 
     709 
     710#if !QPXINTRIN_DONT_DEFINE_DCBT 
     711static __inline__ void __attribute__((__always_inline__, __nodebug__)) 
     712__dcbt (void *p) { 
     713  __builtin_prefetch(p); 
     714} 
     715#endif 
     716 
     717#endif 
     718 
  • lib/Parse/ParseDecl.cpp

    diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
    index ac63780..99d92b7 100644
    a b  
    6868        .Default(false); 
    6969} 
    7070 
    71  
    7271/// ParseGNUAttributes - Parse a non-empty attributes list. 
    7372/// 
    7473/// [GNU] attributes: 
     
    193192    ParseThreadSafetyAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc); 
    194193    return; 
    195194  } 
     195  // Type safety attributes have their own grammar. 
     196  if (AttrName->isStr("type_tag_for_datatype")) { 
     197    ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc); 
     198    return; 
     199  } 
    196200 
    197201  ConsumeParen(); // ignore the left paren loc for now 
    198202 
     
    911915    *EndLoc = T.getCloseLocation(); 
    912916} 
    913917 
     918void Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName, 
     919                                              SourceLocation AttrNameLoc, 
     920                                              ParsedAttributes &Attrs, 
     921                                              SourceLocation *EndLoc) { 
     922  assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('"); 
     923 
     924  BalancedDelimiterTracker T(*this, tok::l_paren); 
     925  T.consumeOpen(); 
     926 
     927  if (Tok.isNot(tok::identifier)) { 
     928    Diag(Tok, diag::err_expected_ident); 
     929    T.skipToEnd(); 
     930    return; 
     931  } 
     932  IdentifierInfo *PointerKind = Tok.getIdentifierInfo(); 
     933  SourceLocation PointerKindLoc = ConsumeToken(); 
     934 
     935  if (Tok.isNot(tok::comma)) { 
     936    Diag(Tok, diag::err_expected_comma); 
     937    T.skipToEnd(); 
     938    return; 
     939  } 
     940  ConsumeToken(); 
     941 
     942  SourceRange MatchingCTypeRange; 
     943  TypeResult MatchingCType = ParseTypeName(&MatchingCTypeRange); 
     944  if (MatchingCType.isInvalid()) { 
     945    T.skipToEnd(); 
     946    return; 
     947  } 
     948 
     949  bool LayoutCompatible = false; 
     950  bool MustBeNull = false; 
     951  while (Tok.is(tok::comma)) { 
     952    ConsumeToken(); 
     953    if (Tok.isNot(tok::identifier)) { 
     954      Diag(Tok, diag::err_expected_ident); 
     955      T.skipToEnd(); 
     956      return; 
     957    } 
     958    IdentifierInfo *Flag = Tok.getIdentifierInfo(); 
     959    if (Flag->isStr("layout_compatible")) 
     960      LayoutCompatible = true; 
     961    else if (Flag->isStr("must_be_null")) 
     962      MustBeNull = true; 
     963    else { 
     964      Diag(Tok, diag::err_type_safety_unknown_flag) << Flag; 
     965      T.skipToEnd(); 
     966      return; 
     967    } 
     968    ConsumeToken(); // consume flag 
     969  } 
     970 
     971  if (!T.consumeClose()) { 
     972    Attrs.addNewTypeTagForDatatype(&AttrName, AttrNameLoc, 0, AttrNameLoc, 
     973                                   PointerKind, PointerKindLoc, 
     974                                   MatchingCType.release(), LayoutCompatible, 
     975                                   MustBeNull); 
     976  } 
     977 
     978  if (EndLoc) 
     979    *EndLoc = T.getCloseLocation(); 
     980} 
     981 
    914982/// DiagnoseProhibitedCXX11Attribute - We have found the opening square brackets 
    915983/// of a C++11 attribute-specifier in a location where an attribute is not 
    916984/// permitted. By C++11 [dcl.attr.grammar]p6, this is ill-formed. Diagnose this 
  • lib/Sema/AttributeList.cpp

    diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp
    index 8e70293..6d51d08 100644
    a b  
    2020 
    2121size_t AttributeList::allocated_size() const { 
    2222  if (IsAvailability) return AttributeFactory::AvailabilityAllocSize; 
     23  else if (IsTypeTagForDatatype) 
     24    return AttributeFactory::TypeTagForDatatypeAllocSize; 
    2325  return (sizeof(AttributeList) + NumArgs * sizeof(Expr*)); 
    2426} 
    2527 
  • lib/Sema/SemaChecking.cpp

    diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
    index e35f45b..d3ba3df 100644
    a b  
    447447                          TheCall->getCallee()->getLocStart()); 
    448448  } 
    449449 
     450  // Type safety checking. 
     451  for (specific_attr_iterator<ArgumentWithTypeTagAttr> 
     452         i = FDecl->specific_attr_begin<ArgumentWithTypeTagAttr>(), 
     453         e = FDecl->specific_attr_end<ArgumentWithTypeTagAttr>(); i != e; ++i) { 
     454    CheckArgumentWithTypeTag(*i, TheCall->getArgs()); 
     455  } 
     456 
     457  for (specific_attr_iterator<PointerWithTypeTagAttr> 
     458         i = FDecl->specific_attr_begin<PointerWithTypeTagAttr>(), 
     459         e = FDecl->specific_attr_end<PointerWithTypeTagAttr>(); i != e; ++i) { 
     460    CheckArgumentWithTypeTag(*i, TheCall->getArgs()); 
     461  } 
     462 
    450463  unsigned CMId = FDecl->getMemoryFunctionKind(); 
    451464  if (CMId == 0) 
    452465    return false; 
     
    52405253    Diag(NBody->getSemiLoc(), diag::note_empty_body_on_separate_line); 
    52415254  } 
    52425255} 
     5256 
     5257//===--- Layout compatibility ----------------------------------------------// 
     5258 
     5259namespace { 
     5260 
     5261bool isLayoutCompatible(ASTContext &C, QualType T1, QualType T2); 
     5262 
     5263/// \brief Check if two enumeration types are layout-compatible. 
     5264bool isLayoutCompatible(ASTContext &C, EnumDecl *ED1, EnumDecl *ED2) { 
     5265  // C++11 [dcl.enum] p8: 
     5266  // Two enumeration types are layout-compatible if they have the same 
     5267  // underlying type. 
     5268  return ED1->isComplete() && ED2->isComplete() && 
     5269         C.hasSameType(ED1->getIntegerType(), ED2->getIntegerType()); 
     5270} 
     5271 
     5272/// \brief Check if two fields are layout-compatible. 
     5273bool isLayoutCompatible(ASTContext &C, FieldDecl *Field1, FieldDecl *Field2) { 
     5274  if (!isLayoutCompatible(C, Field1->getType(), Field2->getType())) 
     5275    return false; 
     5276 
     5277  if (Field1->isBitField() != Field2->isBitField()) 
     5278    return false; 
     5279 
     5280  if (Field1->isBitField()) { 
     5281    // Make sure that the bit-fields are the same length. 
     5282    unsigned Bits1 = Field1->getBitWidthValue(C); 
     5283    unsigned Bits2 = Field2->getBitWidthValue(C); 
     5284 
     5285    if (Bits1 != Bits2) 
     5286      return false; 
     5287  } 
     5288 
     5289  return true; 
     5290} 
     5291 
     5292/// \brief Check if two standard-layout structs are layout-compatible. 
     5293/// (C++11 [class.mem] p17) 
     5294bool isLayoutCompatibleStruct(ASTContext &C, 
     5295                              RecordDecl *RD1, 
     5296                              RecordDecl *RD2) { 
     5297  // If both records are C++ classes, check that base classes match. 
     5298  if (const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1)) { 
     5299    if (const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2)) { 
     5300      // Check number of base classes. 
     5301      if (D1CXX->getNumBases() != D2CXX->getNumBases()) 
     5302        return false; 
     5303 
     5304      // Check the base classes. 
     5305      for (CXXRecordDecl::base_class_const_iterator 
     5306                 Base1 = D1CXX->bases_begin(), 
     5307             BaseEnd1 = D1CXX->bases_end(), 
     5308                Base2 = D2CXX->bases_begin(); 
     5309           Base1 != BaseEnd1; 
     5310           ++Base1, ++Base2) { 
     5311        if (!isLayoutCompatible(C, Base1->getType(), Base2->getType())) 
     5312          return false; 
     5313      } 
     5314    } else if (D1CXX->getNumBases() > 0) { 
     5315      // If only RD1 is a C++ class, it should have zero base classes. 
     5316      return false; 
     5317    } 
     5318  } else if (const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2)) { 
     5319    // If only RD2 is a C++ class, it should have zero base classes. 
     5320    if (D2CXX->getNumBases() > 0) 
     5321      return false; 
     5322  } 
     5323 
     5324  // Check the fields. 
     5325  RecordDecl::field_iterator Field2 = RD2->field_begin(), 
     5326                             Field2End = RD2->field_end(), 
     5327                             Field1 = RD1->field_begin(), 
     5328                             Field1End = RD1->field_end(); 
     5329  for ( ; Field1 != Field1End && Field2 != Field2End; ++Field1, ++Field2) { 
     5330    if (!isLayoutCompatible(C, &*Field1, &*Field2)) 
     5331      return false; 
     5332  } 
     5333  if (Field1 != Field1End || Field2 != Field2End) 
     5334    return false; 
     5335 
     5336  return true; 
     5337} 
     5338 
     5339/// \brief Check if two standard-layout unions are layout-compatible. 
     5340/// (C++11 [class.mem] p18) 
     5341bool isLayoutCompatibleUnion(ASTContext &C, 
     5342                             RecordDecl *RD1, 
     5343                             RecordDecl *RD2) { 
     5344  llvm::SmallPtrSet<FieldDecl *, 8> UnmatchedFields; 
     5345  for (RecordDecl::field_iterator Field2 = RD2->field_begin(), 
     5346                                  Field2End = RD2->field_end(); 
     5347       Field2 != Field2End; ++Field2) { 
     5348    UnmatchedFields.insert(&*Field2); 
     5349  } 
     5350 
     5351  for (RecordDecl::field_iterator Field1 = RD1->field_begin(), 
     5352                                  Field1End = RD1->field_end(); 
     5353       Field1 != Field1End; ++Field1) { 
     5354    llvm::SmallPtrSet<FieldDecl *, 8>::iterator 
     5355        I = UnmatchedFields.begin(), 
     5356        E = UnmatchedFields.end(); 
     5357 
     5358    for ( ; I != E; ++I) { 
     5359      if (isLayoutCompatible(C, &*Field1, *I)) { 
     5360        bool Result = UnmatchedFields.erase(*I); 
     5361        (void) Result; 
     5362        assert(Result); 
     5363        break; 
     5364      } 
     5365    } 
     5366    if (I == E) 
     5367      return false; 
     5368  } 
     5369 
     5370  return UnmatchedFields.empty(); 
     5371} 
     5372 
     5373bool isLayoutCompatible(ASTContext &C, RecordDecl *RD1, RecordDecl *RD2) { 
     5374  if (RD1->isUnion() != RD2->isUnion()) 
     5375    return false; 
     5376 
     5377  if (RD1->isUnion()) 
     5378    return isLayoutCompatibleUnion(C, RD1, RD2); 
     5379  else 
     5380    return isLayoutCompatibleStruct(C, RD1, RD2); 
     5381} 
     5382 
     5383/// \brief Check if two types are layout-compatible in C++11 sense. 
     5384bool isLayoutCompatible(ASTContext &C, QualType T1, QualType T2) { 
     5385  if (T1.isNull() || T2.isNull()) 
     5386    return false; 
     5387 
     5388  // C++11 [basic.types] p11: 
     5389  // If two types T1 and T2 are the same type, then T1 and T2 are 
     5390  // layout-compatible types. 
     5391  if (C.hasSameType(T1, T2)) 
     5392    return true; 
     5393 
     5394  T1 = T1.getCanonicalType().getUnqualifiedType(); 
     5395  T2 = T2.getCanonicalType().getUnqualifiedType(); 
     5396 
     5397  const Type::TypeClass TC1 = T1->getTypeClass(); 
     5398  const Type::TypeClass TC2 = T2->getTypeClass(); 
     5399 
     5400  if (TC1 != TC2) 
     5401    return false; 
     5402 
     5403  if (TC1 == Type::Enum) { 
     5404    return isLayoutCompatible(C, 
     5405                              cast<EnumType>(T1)->getDecl(), 
     5406                              cast<EnumType>(T2)->getDecl()); 
     5407  } else if (TC1 == Type::Record) { 
     5408    if (!T1->isStandardLayoutType() || !T2->isStandardLayoutType()) 
     5409      return false; 
     5410 
     5411    return isLayoutCompatible(C, 
     5412                              cast<RecordType>(T1)->getDecl(), 
     5413                              cast<RecordType>(T2)->getDecl()); 
     5414  } 
     5415 
     5416  return false; 
     5417} 
     5418} 
     5419 
     5420//===--- CHECK: pointer_with_type_tag attribute: datatypes should match ----// 
     5421 
     5422namespace { 
     5423/// \brief Given a type tag expression find the type tag itself. 
     5424/// 
     5425/// \param TypeExpr Type tag expression, as it appears in user's code. 
     5426/// 
     5427/// \param VD Declaration of an identifier that appears in a type tag. 
     5428/// 
     5429/// \param MagicValue Type tag magic value. 
     5430bool FindTypeTagExpr(const Expr *TypeExpr, const ASTContext &Ctx, 
     5431                     const ValueDecl **VD, uint64_t *MagicValue) { 
     5432  while(true) { 
     5433    if (!TypeExpr) 
     5434      return false; 
     5435 
     5436    TypeExpr = TypeExpr->IgnoreParenImpCasts()->IgnoreParenCasts(); 
     5437 
     5438    switch (TypeExpr->getStmtClass()) { 
     5439    case Stmt::UnaryOperatorClass: { 
     5440      const UnaryOperator *UO = cast<UnaryOperator>(TypeExpr); 
     5441      if (UO->getOpcode() == UO_AddrOf || UO->getOpcode() == UO_Deref) { 
     5442        TypeExpr = UO->getSubExpr(); 
     5443        continue; 
     5444      } 
     5445      return false; 
     5446    } 
     5447 
     5448    case Stmt::DeclRefExprClass: { 
     5449      const DeclRefExpr *DRE = cast<DeclRefExpr>(TypeExpr); 
     5450      *VD = DRE->getDecl(); 
     5451      return true; 
     5452    } 
     5453 
     5454    case Stmt::IntegerLiteralClass: { 
     5455      const IntegerLiteral *IL = cast<IntegerLiteral>(TypeExpr); 
     5456      llvm::APInt MagicValueAPInt = IL->getValue(); 
     5457      if (MagicValueAPInt.getBitWidth() <= 64) { 
     5458        *MagicValue = MagicValueAPInt.getZExtValue(); 
     5459        return true; 
     5460      } else 
     5461        return false; 
     5462    } 
     5463 
     5464    case Stmt::BinaryConditionalOperatorClass: 
     5465    case Stmt::ConditionalOperatorClass: { 
     5466      const AbstractConditionalOperator *ACO = 
     5467          cast<AbstractConditionalOperator>(TypeExpr); 
     5468      bool Result; 
     5469      if (ACO->getCond()->EvaluateAsBooleanCondition(Result, Ctx)) { 
     5470        if (Result) 
     5471          TypeExpr = ACO->getTrueExpr(); 
     5472        else 
     5473          TypeExpr = ACO->getFalseExpr(); 
     5474        continue; 
     5475      } 
     5476    } 
     5477 
     5478    case Stmt::BinaryOperatorClass: { 
     5479      const BinaryOperator *BO = cast<BinaryOperator>(TypeExpr); 
     5480      if (BO->getOpcode() == BO_Comma) { 
     5481        TypeExpr = BO->getRHS(); 
     5482        continue; 
     5483      } 
     5484    } 
     5485 
     5486    default: 
     5487      return false; 
     5488    } 
     5489  } 
     5490} 
     5491 
     5492/// \brief Retrieve the C type corresponding to type tag TypeExpr. 
     5493/// 
     5494/// \param TypeExpr Expression that specifies a type tag. 
     5495/// 
     5496/// \param MagicValues Registered magic values. 
     5497/// 
     5498/// \param FoundWrongKind Set to true if a type tag was found, but of a wrong 
     5499///        kind. 
     5500/// 
     5501/// \param TypeInfo Information about the corresponding C type. 
     5502/// 
     5503/// \returns true if the corresponding C type was found. 
     5504bool GetMatchingCType( 
     5505        const IdentifierInfo *PointerKind, 
     5506        const Expr *TypeExpr, const ASTContext &Ctx, 
     5507        const llvm::StringMap<Sema::TypeTagForDatatypeMagicValuesType> *MagicValues, 
     5508        bool &FoundWrongKind, 
     5509        Sema::TypeTagData &TypeInfo) { 
     5510  FoundWrongKind = false; 
     5511 
     5512  // Variable declaration that has type_tag_for_datatype attribute. 
     5513  const ValueDecl *VD = NULL; 
     5514 
     5515  uint64_t MagicValue; 
     5516 
     5517  if (!FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue)) 
     5518    return false; 
     5519 
     5520  if (VD) { 
     5521    for (specific_attr_iterator<TypeTagForDatatypeAttr> 
     5522             I = VD->specific_attr_begin<TypeTagForDatatypeAttr>(), 
     5523             E = VD->specific_attr_end<TypeTagForDatatypeAttr>(); 
     5524         I != E; ++I) { 
     5525      if (I->getPointerKind() != PointerKind) { 
     5526        FoundWrongKind = true; 
     5527        return false; 
     5528      } 
     5529      TypeInfo.Type = I->getMatchingCType(); 
     5530      TypeInfo.LayoutCompatible = I->getLayoutCompatible(); 
     5531      TypeInfo.MustBeNull = I->getMustBeNull(); 
     5532      return true; 
     5533    } 
     5534    return false; 
     5535  } else { 
     5536    if (!MagicValues) 
     5537      return false; 
     5538 
     5539    // Find a map for this PointerKind. 
     5540    llvm::StringMap<Sema::TypeTagForDatatypeMagicValuesType>::const_iterator it1 = 
     5541        MagicValues->find(PointerKind->getName()); 
     5542    if (it1 == MagicValues->end()) 
     5543      return false; 
     5544 
     5545    Sema::TypeTagForDatatypeMagicValuesType::const_iterator it2 = 
     5546        it1->second.find(MagicValue); 
     5547    if (it2 == it1->second.end()) 
     5548      return false; 
     5549 
     5550    TypeInfo = it2->second; 
     5551    return true; 
     5552  } 
     5553} 
     5554} // unnamed namespace 
     5555 
     5556void Sema::RegisterTypeTagForDatatype(StringRef PointerKind, 
     5557                                      uint64_t MagicValue, QualType Type, 
     5558                                      bool LayoutCompatible, bool MustBeNull) { 
     5559  if (!TypeTagForDatatypeMagicValues) 
     5560    TypeTagForDatatypeMagicValues.reset( 
     5561        new llvm::StringMap<TypeTagForDatatypeMagicValuesType>); 
     5562  (*TypeTagForDatatypeMagicValues)[PointerKind][MagicValue] = 
     5563      TypeTagData(Type, LayoutCompatible, MustBeNull); 
     5564} 
     5565 
     5566void Sema::CheckArgumentWithTypeTag(const InheritableAttr *Attr, 
     5567                                    const Expr * const *ExprArgs) { 
     5568  const IdentifierInfo *ArgumentKind; 
     5569  unsigned TypeTagIdx; 
     5570  unsigned ArgumentIdx; 
     5571  bool IsPointerAttr; 
     5572  if (const ArgumentWithTypeTagAttr *A = 
     5573          dyn_cast<ArgumentWithTypeTagAttr>(Attr)) { 
     5574    ArgumentKind = A->getArgumentKind(); 
     5575    TypeTagIdx = A->getTypeTagIdx(); 
     5576    ArgumentIdx = A->getArgumentIdx(); 
     5577    IsPointerAttr = false; 
     5578  } else if (const PointerWithTypeTagAttr *A = 
     5579          dyn_cast<PointerWithTypeTagAttr>(Attr)) { 
     5580    ArgumentKind = A->getPointerKind(); 
     5581    TypeTagIdx = A->getTypeTagIdx(); 
     5582    ArgumentIdx = A->getPointerIdx(); 
     5583    IsPointerAttr = true; 
     5584  } else 
     5585    llvm_unreachable("invalid attribute passed"); 
     5586 
     5587  const Expr *TypeTagExpr = ExprArgs[TypeTagIdx]; 
     5588  bool FoundWrongKind; 
     5589  TypeTagData TypeInfo; 
     5590  if (!GetMatchingCType(ArgumentKind, TypeTagExpr, Context, 
     5591                        TypeTagForDatatypeMagicValues.get(), 
     5592                        FoundWrongKind, TypeInfo)) { 
     5593    if (FoundWrongKind) 
     5594      Diag(TypeTagExpr->getExprLoc(), 
     5595           diag::warn_type_tag_for_datatype_wrong_kind) 
     5596        << TypeTagExpr->getSourceRange(); 
     5597    return; 
     5598  } 
     5599 
     5600  const Expr *ArgumentExpr = ExprArgs[ArgumentIdx]; 
     5601  if (IsPointerAttr) { 
     5602    // Skip implicit cast of pointer to `void *' (as a function argument). 
     5603    if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr)) 
     5604      if (ICE->getType()->isVoidPointerType()) 
     5605        ArgumentExpr = ICE->getSubExpr(); 
     5606  } 
     5607  QualType ArgumentType = ArgumentExpr->getType(); 
     5608 
     5609  // Passing a `void*' pointer shouldn't trigger a warning. 
     5610  if (IsPointerAttr && ArgumentType->isVoidPointerType()) 
     5611    return; 
     5612 
     5613  // For pointer_with_type_tag attribute, compare the pointee type. 
     5614  if (IsPointerAttr) 
     5615    ArgumentType = ArgumentType->getPointeeType(); 
     5616 
     5617  if (TypeInfo.MustBeNull) { 
     5618    // Type tag with matching void type requires a null pointer. 
     5619    if (!ArgumentExpr->isNullPointerConstant(Context, 
     5620                                             Expr::NPC_ValueDependentIsNotNull)) { 
     5621      Diag(ArgumentExpr->getExprLoc(), 
     5622           diag::warn_type_safety_null_pointer_required) 
     5623          << ArgumentKind->getName() 
     5624          << ArgumentExpr->getSourceRange() 
     5625          << TypeTagExpr->getSourceRange(); 
     5626    } 
     5627    return; 
     5628  } 
     5629 
     5630  QualType RequiredType = TypeInfo.Type; 
     5631  bool mismatch = false; 
     5632  if (!TypeInfo.LayoutCompatible) { 
     5633    mismatch = !Context.hasSameType(ArgumentType, RequiredType); 
     5634 
     5635    // C++11 [basic.fundamental] p1: 
     5636    // Plain char, signed char, and unsigned char are three distinct types. 
     5637    // 
     5638    // But we treat plain `char' as equivalent to `signed char' or `unsigned 
     5639    // char' depending on the current char signedness mode. 
     5640    if(mismatch && 
     5641       isa<BuiltinType>(ArgumentType) && isa<BuiltinType>(RequiredType)) { 
     5642      BuiltinType::Kind PointeeKind = cast<BuiltinType>(ArgumentType)->getKind(); 
     5643      BuiltinType::Kind RequiredKind = cast<BuiltinType>(RequiredType)->getKind(); 
     5644      if((PointeeKind == BuiltinType::SChar  && RequiredKind == BuiltinType::Char_S) || 
     5645         (PointeeKind == BuiltinType::UChar  && RequiredKind == BuiltinType::Char_U) || 
     5646         (PointeeKind == BuiltinType::Char_U && RequiredKind == BuiltinType::UChar) || 
     5647         (PointeeKind == BuiltinType::Char_S && RequiredKind == BuiltinType::SChar)) 
     5648        mismatch = false; 
     5649    } 
     5650  } else 
     5651    mismatch = !isLayoutCompatible(Context, ArgumentType, RequiredType); 
     5652 
     5653  if (mismatch) 
     5654    Diag(ArgumentExpr->getExprLoc(), 
     5655         IsPointerAttr ? diag::warn_type_safety_pointee_type_mismatch 
     5656                       : diag::warn_type_safety_type_mismatch) 
     5657        << ArgumentType << ArgumentKind->getName() 
     5658        << TypeInfo.LayoutCompatible << RequiredType 
     5659        << ArgumentExpr->getSourceRange() 
     5660        << TypeTagExpr->getSourceRange(); 
     5661} 
     5662 
  • lib/Sema/SemaDecl.cpp

    diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
    index d194d9f..0d81b68 100644
    a b  
    69366936Sema::FinalizeDeclaration(Decl *ThisDecl) { 
    69376937  // Note that we are no longer parsing the initializer for this declaration. 
    69386938  ParsingInitForAutoVars.erase(ThisDecl); 
     6939 
     6940  // Now we have parsed the initializer and can update the table of magic 
     6941  // tag values. 
     6942  if (ThisDecl && ThisDecl->hasAttr<TypeTagForDatatypeAttr>()) { 
     6943    const VarDecl *VD = dyn_cast<VarDecl>(ThisDecl); 
     6944    if (VD && VD->getType()->isIntegralOrEnumerationType()) { 
     6945      for (specific_attr_iterator<TypeTagForDatatypeAttr> 
     6946               I = ThisDecl->specific_attr_begin<TypeTagForDatatypeAttr>(), 
     6947               E = ThisDecl->specific_attr_end<TypeTagForDatatypeAttr>(); 
     6948           I != E; ++I) { 
     6949        const Expr *MagicValueExpr = VD->getInit(); 
     6950        if (!MagicValueExpr) { 
     6951          continue; 
     6952        } 
     6953        llvm::APSInt MagicValueInt; 
     6954        if (!MagicValueExpr->isIntegerConstantExpr(MagicValueInt, Context)) { 
     6955          Diag(I->getRange().getBegin(), 
     6956               diag::warn_type_tag_for_datatype_not_ice) 
     6957            << LangOpts.CPlusPlus << MagicValueExpr->getSourceRange(); 
     6958          continue; 
     6959        } 
     6960        uint64_t MagicValue = MagicValueInt.getZExtValue(); 
     6961        RegisterTypeTagForDatatype(I->getPointerKind()->getName(), 
     6962                                   MagicValue, 
     6963                                   I->getMatchingCType(), 
     6964                                   I->getLayoutCompatible(), 
     6965                                   I->getMustBeNull()); 
     6966      } 
     6967    } 
     6968  } 
    69396969} 
    69406970 
    69416971Sema::DeclGroupPtrTy 
  • lib/Sema/SemaDeclAttr.cpp

    diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
    index 0f95747..89cde44 100644
    a b  
    220220  return true; 
    221221} 
    222222 
     223/// \brief Check if IdxExpr is a valid argument index for a function or 
     224/// instance method D. May output an error. 
     225/// 
     226/// \returns true if IdxExpr is a valid index. 
     227static bool checkFunctionOrMethodArgumentIndex(Sema &S, const Decl *D, 
     228                                               StringRef AttrName, 
     229                                               SourceLocation AttrLoc, 
     230                                               unsigned AttrArgNum, 
     231                                               const Expr *IdxExpr, 
     232                                               uint64_t &Idx) 
     233{ 
     234  assert(isFunctionOrMethod(D) && hasFunctionProto(D)); 
     235 
     236  // In C++ the implicit 'this' function parameter also counts. 
     237  // Parameters are counted from one. 
     238  const bool HasImplicitThisParam = isInstanceMethod(D); 
     239  const unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 
     240  const unsigned FirstIdx = 1; 
     241 
     242  llvm::APSInt IdxInt; 
     243  if (!IdxExpr->isIntegerConstantExpr(IdxInt, S.Context)) { 
     244    S.Diag(AttrLoc, diag::err_attribute_argument_n_not_int) 
     245      << AttrName << AttrArgNum << IdxExpr->getSourceRange(); 
     246    return false; 
     247  } 
     248 
     249  Idx = IdxInt.getLimitedValue(); 
     250  if (Idx < FirstIdx || (!isFunctionOrMethodVariadic(D) && Idx > NumArgs)) { 
     251    S.Diag(AttrLoc, diag::err_attribute_argument_out_of_bounds) 
     252      << AttrName << AttrArgNum << IdxExpr->getSourceRange(); 
     253    return false; 
     254  } 
     255  Idx--; // Convert to zero-based. 
     256  if (HasImplicitThisParam) { 
     257    if (Idx == 0) { 
     258      S.Diag(AttrLoc, 
     259             diag::err_attribute_invalid_implicit_this_argument) 
     260        << AttrName << IdxExpr->getSourceRange(); 
     261      return false; 
     262    } 
     263    --Idx; 
     264  } 
     265 
     266  return true; 
     267} 
     268 
    223269/// 
    224270/// \brief Check if passed in Decl is a field or potentially shared global var 
    225271/// \return true if the Decl is a field or potentially shared global variable 
     
    35083554  } 
    35093555} 
    35103556 
     3557static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D, 
     3558                                         const AttributeList &Attr, 
     3559                                         bool Pointer) { 
     3560  StringRef AttrName = Attr.getName()->getName(); 
     3561  if (!Attr.getParameterName()) { 
     3562    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_identifier) 
     3563      << Attr.getName() << 1; 
     3564    return; 
     3565  } 
     3566 
     3567  if (Attr.getNumArgs() != 2) { 
     3568    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 
     3569    return; 
     3570  } 
     3571 
     3572  IdentifierInfo *PointerKind = Attr.getParameterName(); 
     3573 
     3574  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 
     3575    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 
     3576      << Attr.getName() << ExpectedFunctionOrMethod; 
     3577    return; 
     3578  } 
     3579 
     3580  uint64_t PointerIdx; 
     3581  if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName, 
     3582                                          Attr.getLoc(), 1, 
     3583                                          Attr.getArg(0), PointerIdx)) 
     3584    return; 
     3585 
     3586  uint64_t TypeTagIdx; 
     3587  if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName, 
     3588                                          Attr.getLoc(), 2, 
     3589                                          Attr.getArg(1), TypeTagIdx)) 
     3590    return; 
     3591 
     3592  if (Pointer) { 
     3593    // Ensure that buffer has a pointer type. 
     3594    QualType BufferTy = getFunctionOrMethodArgType(D, PointerIdx); 
     3595    if (!BufferTy->isPointerType()) { 
     3596      S.Diag(Attr.getLoc(), diag::err_pointer_with_type_tag_not_pointer); 
     3597    } 
     3598  } 
     3599 
     3600  if (Pointer) 
     3601    D->addAttr(::new (S.Context) PointerWithTypeTagAttr(Attr.getRange(), 
     3602                                                        S.Context, 
     3603                                                        PointerKind, 
     3604                                                        PointerIdx, 
     3605                                                        TypeTagIdx)); 
     3606  else 
     3607    D->addAttr(::new (S.Context) ArgumentWithTypeTagAttr(Attr.getRange(), 
     3608                                                         S.Context, 
     3609                                                         PointerKind, 
     3610                                                         PointerIdx, 
     3611                                                         TypeTagIdx)); 
     3612} 
     3613 
     3614static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D, 
     3615                                         const AttributeList &Attr) { 
     3616  IdentifierInfo *PointerKind = Attr.getParameterName(); 
     3617  if (!PointerKind) { 
     3618    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_identifier) 
     3619      << "type_tag_for_datatype" << 1; 
     3620    return; 
     3621  } 
     3622 
     3623  QualType MatchingCType = S.GetTypeFromParser(Attr.getMatchingCType(), NULL); 
     3624 
     3625  D->addAttr(::new (S.Context) TypeTagForDatatypeAttr( 
     3626                                  Attr.getRange(), 
     3627                                  S.Context, 
     3628                                  PointerKind, 
     3629                                  MatchingCType, 
     3630                                  Attr.getLayoutCompatible(), 
     3631                                  Attr.getMustBeNull())); 
     3632} 
     3633 
    35113634//===----------------------------------------------------------------------===// 
    35123635// Checker-specific attribute handlers. 
    35133636//===----------------------------------------------------------------------===// 
     
    41424265    handleAcquireOrderAttr(S, D, Attr, /*before = */false); 
    41434266    break; 
    41444267 
     4268  // Type safety attributes. 
     4269  case AttributeList::AT_argument_with_type_tag: 
     4270    handleArgumentWithTypeTagAttr(S, D, Attr, /*Pointer = */false); 
     4271    break; 
     4272  case AttributeList::AT_pointer_with_type_tag: 
     4273    handleArgumentWithTypeTagAttr(S, D, Attr, /*Pointer = */true); 
     4274    break; 
     4275  case AttributeList::AT_type_tag_for_datatype: 
     4276    handleTypeTagForDatatypeAttr(S, D, Attr); 
     4277    break; 
     4278 
    41454279  default: 
    41464280    // Ask target about the attribute. 
    41474281    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 
  • test/Sema/128bitint.c

    diff --git a/test/Sema/128bitint.c b/test/Sema/128bitint.c
    index ddad835..43760f4 100644
    a b  
    1818unsigned long long UnsignedTooBig = 123456789012345678901234567890; // expected-warning {{integer constant is too large for its type}} 
    1919__uint128_t Unsigned128 = 123456789012345678901234567890Ui128; 
    2020unsigned long long Unsigned64 = 123456789012345678901234567890Ui128; // expected-warning {{implicit conversion from 'unsigned __int128' to 'unsigned long long' changes value from 123456789012345678901234567890 to 14083847773837265618}} 
     21 
     22// Ensure we don't crash when user passes 128-bit values to type safety 
     23// attributes. 
     24void pointer_with_type_tag_arg_num_1(void *buf, int datatype) 
     25    __attribute__(( pointer_with_type_tag(mpi,0x10000000000000001i128,1) )); // expected-error {{attribute parameter 1 is out of bounds}} 
     26 
     27void pointer_with_type_tag_arg_num_2(void *buf, int datatype) 
     28    __attribute__(( pointer_with_type_tag(mpi,1,0x10000000000000001i128) )); // expected-error {{attribute parameter 2 is out of bounds}} 
     29 
     30void MPI_Send(void *buf, int datatype) __attribute__(( pointer_with_type_tag(mpi,1,2) )); 
     31 
     32static const int mpi_int __attribute__(( type_tag_for_datatype(mpi,int) )) = 10; 
     33 
     34void test(int *buf) 
     35{ 
     36  MPI_Send(buf, 0x10000000000000001i128); // expected-warning {{implicit conversion from '__int128' to 'int' changes value}} 
     37} 
     38 
  • (a) /dev/null vs. (b) b/test/Sema/warn-type-safety-mpi-hdf5.c

    diff --git a/test/Sema/warn-type-safety-mpi-hdf5.c b/test/Sema/warn-type-safety-mpi-hdf5.c
    new file mode 100644
    index 0000000..70e5c1b
    a b  
     1// RUN: %clang_cc1 -std=c99 -DOPEN_MPI -fsyntax-only -verify %s 
     2// RUN: %clang_cc1 -std=c99 -DMPICH -fsyntax-only -verify %s 
     3// RUN: %clang_cc1 -x c++ -std=c++98 -DOPEN_MPI -fsyntax-only -verify %s 
     4// RUN: %clang_cc1 -x c++ -std=c++98 -DMPICH -fsyntax-only -verify %s 
     5 
     6//===--- limits.h mock ----------------------------------------------------===// 
     7 
     8#ifdef __CHAR_UNSIGNED__  /* -funsigned-char */ 
     9#define CHAR_MIN 0 
     10#define CHAR_MAX (__SCHAR_MAX__*2  +1) 
     11#else 
     12#define CHAR_MIN (-__SCHAR_MAX__-1) 
     13#define CHAR_MAX __SCHAR_MAX__ 
     14#endif 
     15 
     16//===--- mpi.h mock -------------------------------------------------------===// 
     17 
     18#define NULL ((void *)0) 
     19 
     20#ifdef OPEN_MPI 
     21typedef struct ompi_datatype_t *MPI_Datatype; 
     22#endif 
     23 
     24#ifdef MPICH 
     25typedef int MPI_Datatype; 
     26#endif 
     27 
     28int MPI_Send(void *buf, int count, MPI_Datatype datatype) 
     29    __attribute__(( pointer_with_type_tag(mpi,1,3) )); 
     30 
     31int MPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype, 
     32               void *recvbuf, int recvcount, MPI_Datatype recvtype) 
     33               __attribute__(( pointer_with_type_tag(mpi,1,3), pointer_with_type_tag(mpi,4,6) )); 
     34 
     35#ifdef OPEN_MPI 
     36// OpenMPI and LAM/MPI-style datatype definitions 
     37 
     38#define OMPI_PREDEFINED_GLOBAL(type, global) ((type) &(global)) 
     39 
     40#define MPI_DATATYPE_NULL OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_datatype_null) 
     41#define MPI_FLOAT         OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_float) 
     42#define MPI_INT           OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_int) 
     43#define MPI_LONG          OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_long) 
     44#define MPI_LONG_LONG_INT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_long_long_int) 
     45#define MPI_CHAR          OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_char) 
     46 
     47#define MPI_FLOAT_INT     OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_float_int) 
     48#define MPI_2INT          OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_2int) 
     49 
     50#define MPI_IN_PLACE ((void *) 1) 
     51 
     52extern struct ompi_predefined_datatype_t ompi_mpi_datatype_null __attribute__(( type_tag_for_datatype(mpi,void,must_be_null) )); 
     53extern struct ompi_predefined_datatype_t ompi_mpi_float         __attribute__(( type_tag_for_datatype(mpi,float) )); 
     54extern struct ompi_predefined_datatype_t ompi_mpi_int           __attribute__(( type_tag_for_datatype(mpi,int) )); 
     55extern struct ompi_predefined_datatype_t ompi_mpi_long          __attribute__(( type_tag_for_datatype(mpi,long) )); 
     56extern struct ompi_predefined_datatype_t ompi_mpi_long_long_int __attribute__(( type_tag_for_datatype(mpi,long long int) )); 
     57extern struct ompi_predefined_datatype_t ompi_mpi_char          __attribute__(( type_tag_for_datatype(mpi,char) )); 
     58 
     59struct ompi_struct_mpi_float_int {float f; int i;}; 
     60extern struct ompi_predefined_datatype_t ompi_mpi_float_int     __attribute__(( type_tag_for_datatype(mpi, struct ompi_struct_mpi_float_int, layout_compatible) )); 
     61 
     62struct ompi_struct_mpi_2int {int i1; int i2;}; 
     63extern struct ompi_predefined_datatype_t ompi_mpi_2int          __attribute__(( type_tag_for_datatype(mpi, struct ompi_struct_mpi_2int, layout_compatible) )); 
     64#endif 
     65 
     66#ifdef MPICH 
     67// MPICH2 and MVAPICH2-style datatype definitions 
     68 
     69#define MPI_COMM_WORLD ((MPI_Comm) 0x44000000) 
     70 
     71#define MPI_DATATYPE_NULL ((MPI_Datatype) 0xa0000000) 
     72#define MPI_FLOAT         ((MPI_Datatype) 0xa0000001) 
     73#define MPI_INT           ((MPI_Datatype) 0xa0000002) 
     74#define MPI_LONG          ((MPI_Datatype) 0xa0000003) 
     75#define MPI_LONG_LONG_INT ((MPI_Datatype) 0xa0000004) 
     76#define MPI_CHAR          ((MPI_Datatype) 0xa0000005) 
     77 
     78#define MPI_FLOAT_INT     ((MPI_Datatype) 0xa0000006) 
     79#define MPI_2INT          ((MPI_Datatype) 0xa0000007) 
     80 
     81#define MPI_IN_PLACE  (void *) -1 
     82 
     83static const MPI_Datatype mpich_mpi_datatype_null __attribute__(( type_tag_for_datatype(mpi,void,must_be_null) )) = 0xa0000000; 
     84static const MPI_Datatype mpich_mpi_float         __attribute__(( type_tag_for_datatype(mpi,float) ))             = 0xa0000001; 
     85static const MPI_Datatype mpich_mpi_int           __attribute__(( type_tag_for_datatype(mpi,int) ))               = 0xa0000002; 
     86static const MPI_Datatype mpich_mpi_long          __attribute__(( type_tag_for_datatype(mpi,long) ))              = 0xa0000003; 
     87static const MPI_Datatype mpich_mpi_long_long_int __attribute__(( type_tag_for_datatype(mpi,long long int) ))     = 0xa0000004; 
     88static const MPI_Datatype mpich_mpi_char          __attribute__(( type_tag_for_datatype(mpi,char) ))              = 0xa0000005; 
     89 
     90struct mpich_struct_mpi_float_int { float f; int i; }; 
     91struct mpich_struct_mpi_2int { int i1; int i2; }; 
     92static const MPI_Datatype mpich_mpi_float_int     __attribute__(( type_tag_for_datatype(mpi, struct mpich_struct_mpi_float_int, layout_compatible) )) = 0xa0000006; 
     93static const MPI_Datatype mpich_mpi_2int          __attribute__(( type_tag_for_datatype(mpi, struct mpich_struct_mpi_2int, layout_compatible) )) = 0xa0000007; 
     94#endif 
     95 
     96//===--- HDF5 headers mock ------------------------------------------------===// 
     97 
     98typedef int hid_t; 
     99void H5open(void); 
     100 
     101#ifndef HDF_PRIVATE 
     102#define H5OPEN  H5open(), 
     103#else 
     104#define H5OPEN 
     105#endif 
     106 
     107#define H5T_NATIVE_CHAR         (CHAR_MIN?H5T_NATIVE_SCHAR:H5T_NATIVE_UCHAR) 
     108#define H5T_NATIVE_SCHAR        (H5OPEN H5T_NATIVE_SCHAR_g) 
     109#define H5T_NATIVE_UCHAR        (H5OPEN H5T_NATIVE_UCHAR_g) 
     110#define H5T_NATIVE_INT          (H5OPEN H5T_NATIVE_INT_g) 
     111#define H5T_NATIVE_LONG         (H5OPEN H5T_NATIVE_LONG_g) 
     112 
     113hid_t H5T_NATIVE_SCHAR_g __attribute__(( type_tag_for_datatype(hdf5,signed char) )); 
     114hid_t H5T_NATIVE_UCHAR_g __attribute__(( type_tag_for_datatype(hdf5,unsigned char) )); 
     115hid_t H5T_NATIVE_INT_g   __attribute__(( type_tag_for_datatype(hdf5,int) )); 
     116hid_t H5T_NATIVE_LONG_g  __attribute__(( type_tag_for_datatype(hdf5,long) )); 
     117 
     118void H5Dwrite(hid_t mem_type_id, const void *buf) __attribute__(( pointer_with_type_tag(hdf5,2,1) )); 
     119 
     120//===--- Tests ------------------------------------------------------------===// 
     121 
     122//===--- MPI 
     123 
     124struct pair_float_int 
     125{ 
     126  float f; int i; 
     127}; 
     128 
     129struct pair_int_int 
     130{ 
     131  int i1; int i2; 
     132}; 
     133 
     134void test_mpi_predefined_types( 
     135    int *int_buf, 
     136    long *long_buf1, 
     137    long *long_buf2, 
     138    void *void_buf, 
     139    struct pair_float_int *pfi, 
     140    struct pair_int_int *pii) 
     141{ 
     142  char char_buf[255]; 
     143 
     144  // Layout-compatible scalar types. 
     145  MPI_Send(int_buf,   1, MPI_INT); // no-warning 
     146 
     147  // Layout-compatible class types. 
     148  MPI_Send(pfi, 1, MPI_FLOAT_INT); // no-warning 
     149  MPI_Send(pii, 1, MPI_2INT); // no-warning 
     150 
     151  // Layout-incompatible scalar types. 
     152  MPI_Send(long_buf1, 1, MPI_INT); // expected-warning {{pointee type 'long' doesn't match specified mpi type tag that requires 'int'}} 
     153 
     154  // Layout-incompatible class types. 
     155  MPI_Send(pii, 1, MPI_FLOAT_INT); // expected-warning {{pointee type 'struct pair_int_int' doesn't match specified mpi type tag}} 
     156  MPI_Send(pfi, 1, MPI_2INT); // expected-warning {{pointee type 'struct pair_float_int' doesn't match specified mpi type tag}} 
     157 
     158  // Layout-incompatible class-scalar types. 
     159  MPI_Send(long_buf1, 1, MPI_2INT); // expected-warning {{pointee type 'long' doesn't match specified mpi type tag}} 
     160 
     161  // Function with two buffers. 
     162  MPI_Gather(long_buf1, 1, MPI_INT,  // expected-warning {{pointee type 'long' doesn't match specified mpi type tag that requires 'int'}} 
     163             long_buf2, 1, MPI_INT); // expected-warning {{pointee type 'long' doesn't match specified mpi type tag that requires 'int'}} 
     164 
     165  // Array buffers should work like pointer buffers. 
     166  MPI_Send(char_buf,  255, MPI_CHAR); // no-warning 
     167 
     168  // Explicit casts should not be dropped. 
     169  MPI_Send((int *) char_buf,  255, MPI_INT); // no-warning 
     170  MPI_Send((int *) char_buf,  255, MPI_CHAR); // expected-warning {{pointee type 'int' doesn't match specified mpi type tag that requires 'char'}} 
     171 
     172  // `void*' buffer should never warn. 
     173  MPI_Send(void_buf,  255, MPI_CHAR); // no-warning 
     174 
     175  // We expect that MPI_IN_PLACE is `void*', shouldn't warn. 
     176  MPI_Gather(MPI_IN_PLACE, 0, MPI_INT, 
     177             int_buf,      1, MPI_INT); 
     178 
     179  // Special handling for MPI_DATATYPE_NULL: buffer pointer should be either 
     180  // a `void*' pointer or a null pointer constant. 
     181  MPI_Gather(NULL,    0, MPI_DATATYPE_NULL, // no-warning 
     182             int_buf, 1, MPI_INT); 
     183 
     184  MPI_Gather(int_buf, 0, MPI_DATATYPE_NULL, // expected-warning {{specified mpi type tag requires a null pointer}} 
     185             int_buf, 1, MPI_INT); 
     186} 
     187 
     188MPI_Datatype my_int_datatype __attribute__(( type_tag_for_datatype(mpi,int) )); 
     189 
     190struct S1 { int a; int b; }; 
     191MPI_Datatype my_s1_datatype __attribute__(( type_tag_for_datatype(mpi,struct S1) )); 
     192 
     193// Layout-compatible to S1, but should be treated as a different type. 
     194struct S2 { int a; int b; }; 
     195MPI_Datatype my_s2_datatype __attribute__(( type_tag_for_datatype(mpi,struct S2) )); 
     196 
     197void test_user_types(int *int_buf, 
     198                     long *long_buf, 
     199                     struct S1 *s1_buf, 
     200                     struct S2 *s2_buf) 
     201{ 
     202  MPI_Send(int_buf,  1, my_int_datatype); // no-warning 
     203  MPI_Send(long_buf, 1, my_int_datatype); // expected-warning {{pointee type 'long' doesn't match specified mpi type tag that requires 'int'}} 
     204 
     205  MPI_Send(s1_buf, 1, my_s1_datatype); // no-warning 
     206  MPI_Send(s1_buf, 1, my_s2_datatype); // expected-warning {{pointee type 'struct S1' doesn't match specified mpi type tag that requires 'struct S2'}} 
     207 
     208  MPI_Send(long_buf, 1, my_s1_datatype); // expected-warning {{pointee type 'long' doesn't match specified mpi type tag that requires 'struct S1'}} 
     209  MPI_Send(s1_buf, 1, MPI_INT); // expected-warning {{pointee type 'struct S1' doesn't match specified mpi type tag that requires 'int'}} 
     210} 
     211 
     212MPI_Datatype my_unknown_datatype; 
     213 
     214void test_not_annotated(int *int_buf, 
     215                        long *long_buf, 
     216                        MPI_Datatype type) 
     217{ 
     218  // Using 'MPI_Datatype's without attributes should not produce warnings. 
     219  MPI_Send(long_buf, 1, my_unknown_datatype); // no-warning 
     220  MPI_Send(int_buf, 1, type); // no-warning 
     221} 
     222 
     223struct S1_compat { int a; int b; }; 
     224MPI_Datatype my_s1_compat_datatype 
     225    __attribute__(( type_tag_for_datatype(mpi, struct S1_compat, layout_compatible) )); 
     226 
     227struct S3        { int a; long b; double c; double d; struct S1 s1; }; 
     228struct S3_compat { int a; long b; double c; double d; struct S2 s2; }; 
     229MPI_Datatype my_s3_compat_datatype 
     230    __attribute__(( type_tag_for_datatype(mpi, struct S3_compat, layout_compatible) )); 
     231 
     232union U1        { int a; long b; double c; double d; struct S1 s1; }; 
     233union U1_compat { long b; double c; struct S2 s; int a; double d; }; 
     234MPI_Datatype my_u1_compat_datatype 
     235    __attribute__(( type_tag_for_datatype(mpi, union U1_compat, layout_compatible) )); 
     236 
     237union U2 { int a; long b; double c; struct S1 s1; }; 
     238MPI_Datatype my_u2_datatype 
     239    __attribute__(( type_tag_for_datatype(mpi, union U2, layout_compatible) )); 
     240 
     241void test_layout_compatibility(struct S1 *s1_buf, struct S3 *s3_buf, 
     242                               union U1 *u1_buf, union U2 *u2_buf) 
     243{ 
     244  MPI_Send(s1_buf, 1, my_s1_compat_datatype); // no-warning 
     245  MPI_Send(s3_buf, 1, my_s3_compat_datatype); // no-warning 
     246  MPI_Send(s1_buf, 1, my_s3_compat_datatype); // expected-warning {{pointee type 'struct S1' doesn't match specified mpi type tag}} 
     247  MPI_Send(u1_buf, 1, my_u1_compat_datatype); // no-warning 
     248  MPI_Send(u1_buf, 1, my_u2_datatype);        // expected-warning {{pointee type 'union U1' doesn't match specified mpi type tag}} 
     249  MPI_Send(u2_buf, 1, my_u1_compat_datatype); // expected-warning {{pointee type 'union U2' doesn't match specified mpi type tag}} 
     250} 
     251 
     252// There is an MPI_REAL predefined in MPI, but some existing MPI programs do 
     253// this. 
     254typedef float real; 
     255#define MPI_REAL MPI_FLOAT 
     256 
     257void test_mpi_real_user_type(real *real_buf, float *float_buf) 
     258{ 
     259  MPI_Send(real_buf,  1, MPI_REAL);  // no-warning 
     260  MPI_Send(real_buf,  1, MPI_FLOAT); // no-warning 
     261  MPI_Send(float_buf, 1, MPI_REAL);  // no-warning 
     262  MPI_Send(float_buf, 1, MPI_FLOAT); // no-warning 
     263} 
     264 
     265//===--- HDF5 
     266 
     267void test_hdf5(char *char_buf, 
     268               signed char *schar_buf, 
     269               int *int_buf, 
     270               long *long_buf) 
     271{ 
     272  H5Dwrite(H5T_NATIVE_CHAR,  char_buf);  // no-warning 
     273  H5Dwrite(H5T_NATIVE_SCHAR, schar_buf); // no-warning 
     274  H5Dwrite(H5T_NATIVE_INT,   int_buf);   // no-warning 
     275  H5Dwrite(H5T_NATIVE_LONG,  long_buf);  // no-warning 
     276 
     277  H5Dwrite(H5T_NATIVE_CHAR,  int_buf);  // expected-warning {{pointee type 'int' doesn't match specified hdf5 type tag that requires 'signed char'}} 
     278  H5Dwrite(H5T_NATIVE_INT,   long_buf); // expected-warning {{pointee type 'long' doesn't match specified hdf5 type tag that requires 'int'}} 
     279 
     280  // FIXME: we should warn here, but it will cause false positives because 
     281  // different kinds may use same magic values. 
     282  //H5Dwrite(MPI_INT, int_buf); 
     283} 
     284 
  • (a) /dev/null vs. (b) b/test/Sema/warn-type-safety.c

    diff --git a/test/Sema/warn-type-safety.c b/test/Sema/warn-type-safety.c
    new file mode 100644
    index 0000000..272d0c9
    a b  
     1// RUN: %clang_cc1 -std=c99 -fsyntax-only -verify %s 
     2// RUN: %clang_cc1 -x c++ -std=c++98 -fsyntax-only -verify %s 
     3 
     4struct A {}; 
     5 
     6typedef struct A *MPI_Datatype; 
     7 
     8int wrong1(void *buf, MPI_Datatype datatype) 
     9    __attribute__(( pointer_with_type_tag )); // expected-error {{attribute requires parameter 1 to be an identifier}} 
     10 
     11int wrong2(void *buf, MPI_Datatype datatype) 
     12    __attribute__(( pointer_with_type_tag(mpi,0,7) )); // expected-error {{attribute parameter 1 is out of bounds}} 
     13 
     14int wrong3(void *buf, MPI_Datatype datatype) 
     15    __attribute__(( pointer_with_type_tag(mpi,3,7) )); // expected-error {{attribute parameter 1 is out of bounds}} 
     16 
     17int wrong4(void *buf, MPI_Datatype datatype) 
     18    __attribute__(( pointer_with_type_tag(mpi,1,0) )); // expected-error {{attribute parameter 2 is out of bounds}} 
     19 
     20int wrong5(void *buf, MPI_Datatype datatype) 
     21    __attribute__(( pointer_with_type_tag(mpi,1,3) )); // expected-error {{attribute parameter 2 is out of bounds}} 
     22 
     23int wrong6(void *buf, MPI_Datatype datatype) 
     24    __attribute__(( pointer_with_type_tag(mpi,0x8000000000000001ULL,1) )); // expected-error {{attribute parameter 1 is out of bounds}} 
     25 
     26extern int x; 
     27 
     28int wrong7(void *buf, MPI_Datatype datatype) 
     29    __attribute__(( pointer_with_type_tag(mpi,x,2) )); // expected-error {{attribute requires parameter 1 to be an integer constant}} 
     30 
     31int wrong8(void *buf, MPI_Datatype datatype) 
     32    __attribute__(( pointer_with_type_tag(mpi,1,x) )); // expected-error {{attribute requires parameter 2 to be an integer constant}} 
     33 
     34int wrong9 __attribute__(( pointer_with_type_tag(mpi,1,2) )); // expected-error {{attribute only applies to functions and methods}} 
     35 
     36int wrong10(double buf, MPI_Datatype type) 
     37    __attribute__(( pointer_with_type_tag(mpi,1,2) )); // expected-error {{pointer argument is not of a pointer type}} 
     38 
     39 
     40extern struct A datatype_wrong1 
     41    __attribute__(( type_tag_for_datatype )); // expected-error {{attribute requires parameter 1 to be an identifier}} 
     42 
     43extern struct A datatype_wrong2 
     44    __attribute__(( type_tag_for_datatype(mpi,1,2) )); // expected-error {{expected a type}} 
     45 
     46extern struct A datatype_wrong3 
     47    __attribute__(( type_tag_for_datatype(mpi,not_a_type) )); // expected-error {{unknown type name 'not_a_type'}} 
     48 
     49extern struct A datatype_wrong4 
     50    __attribute__(( type_tag_for_datatype(mpi,int,int) )); // expected-error {{expected identifier}} 
     51 
     52extern struct A datatype_wrong5 
     53    __attribute__(( type_tag_for_datatype(mpi,int,not_a_flag) )); // expected-error {{'not_a_flag' is not a type comparison flag}} 
     54 
     55extern struct A datatype_wrong6 
     56    __attribute__(( type_tag_for_datatype(mpi,int,layout_compatible,not_a_flag) )); // expected-error {{'not_a_flag' is not a type comparison flag}} 
     57 
     58 
     59// Using a tag with kind A in a place where the function requires kind B should 
     60// warn. 
     61 
     62void A_func(void *ptr, void *tag) __attribute__(( pointer_with_type_tag(a,1,2) )); 
     63 
     64extern struct A A_tag __attribute__(( type_tag_for_datatype(a,int) )); 
     65extern struct A B_tag __attribute__(( type_tag_for_datatype(b,int) )); 
     66 
     67void C_func(void *ptr, int tag) __attribute__(( pointer_with_type_tag(c,1,2) )); 
     68 
     69static const int C_tag __attribute__(( type_tag_for_datatype(c,int) )) = 10; 
     70static const int D_tag __attribute__(( type_tag_for_datatype(d,int) )) = 20; 
     71 
     72void test_tag_mismatch(int *ptr) 
     73{ 
     74  A_func(ptr, &A_tag); // no-warning 
     75  A_func(ptr, &B_tag); // expected-warning {{this type tag was not designed to be used with this function}} 
     76  C_func(ptr, C_tag); // no-warning 
     77  C_func(ptr, D_tag); // expected-warning {{this type tag was not designed to be used with this function}} 
     78  C_func(ptr, 10); // no-warning 
     79  C_func(ptr, 20); // should warn, but may cause false positives 
     80} 
     81 
     82// Tests for argument_with_type_tag. 
     83 
     84#define F_DUPFD 10 
     85#define F_SETLK 20 
     86 
     87struct flock { }; 
     88 
     89static const int F_DUPFD_tag __attribute__(( type_tag_for_datatype(fcntl,int) )) = F_DUPFD; 
     90static const int F_SETLK_tag __attribute__(( type_tag_for_datatype(fcntl,struct flock *) )) = F_SETLK; 
     91 
     92int fcntl(int fd, int cmd, ...) __attribute__(( argument_with_type_tag(fcntl,3,2) )); 
     93 
     94void test_argument_with_type_tag(struct flock *f) 
     95{ 
     96  fcntl(0, F_DUPFD, 10); // no-warning 
     97  fcntl(0, F_SETLK, f);  // no-warning 
     98 
     99  fcntl(0, F_SETLK, 10); // expected-warning {{argument type 'int' doesn't match specified fcntl type tag that requires 'struct flock *'}} 
     100  fcntl(0, F_DUPFD, f);  // expected-warning {{argument type 'struct flock *' doesn't match specified fcntl type tag that requires 'int'}} 
     101} 
     102 
     103// Check that using 64-bit magic values as tags works and tag values do not 
     104// overflow internally. 
     105void E_func(void *ptr, unsigned long long tag) __attribute__(( 
     106      pointer_with_type_tag(e,1,2) )); 
     107 
     108static const unsigned long long E_tag1 __attribute__(( type_tag_for_datatype(e,int) )) = 0xFFFFFFFFFFFFFFFFULL; 
     109static const unsigned long long E_tag2 __attribute__(( type_tag_for_datatype(e,float) )) = 0xFFFFFFFFULL; 
     110 
     111void test_64bit_magic(int *int_ptr, float *float_ptr) 
     112{ 
     113  E_func(int_ptr,   0xFFFFFFFFFFFFFFFFULL); 
     114  E_func(int_ptr,   0xFFFFFFFFULL);         // expected-warning {{pointee type 'int' doesn't match specified e type tag that requires 'float'}} 
     115  E_func(float_ptr, 0xFFFFFFFFFFFFFFFFULL); // expected-warning {{pointee type 'float' doesn't match specified e type tag that requires 'int'}} 
     116  E_func(float_ptr, 0xFFFFFFFFULL); 
     117} 
     118 
  • (a) /dev/null vs. (b) b/test/Sema/warn-type-safety.cpp

    diff --git a/test/Sema/warn-type-safety.cpp b/test/Sema/warn-type-safety.cpp
    new file mode 100644
    index 0000000..ab7c535
    a b  
     1// RUN: %clang_cc1 -fsyntax-only -verify %s 
     2 
     3typedef struct ompi_datatype_t *MPI_Datatype; 
     4 
     5#define OMPI_PREDEFINED_GLOBAL(type, global) ((type) &(global)) 
     6 
     7#define MPI_FLOAT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_float) 
     8#define MPI_INT   OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_int) 
     9 
     10extern struct ompi_predefined_datatype_t ompi_mpi_float __attribute__(( type_tag_for_datatype(mpi,float) )); 
     11extern struct ompi_predefined_datatype_t ompi_mpi_int   __attribute__(( type_tag_for_datatype(mpi,int) )); 
     12 
     13int f(int x) { return x; } 
     14static const int wrong_init __attribute__(( type_tag_for_datatype(zzz,int) )) = f(100); // expected-warning-re {{'type_tag_for_datatype' attribute requires the initializer to be an integral constant expression; initializer ignored by attribute}} 
     15 
     16//===--- Tests ------------------------------------------------------------===// 
     17// Check that hidden 'this' is handled correctly. 
     18 
     19class C 
     20{ 
     21public: 
     22  void f1(void *buf, int count, MPI_Datatype datatype) 
     23       __attribute__(( pointer_with_type_tag(mpi,5,6) )); // expected-error {{attribute parameter 1 is out of bounds}} 
     24 
     25  void f2(void *buf, int count, MPI_Datatype datatype) 
     26       __attribute__(( pointer_with_type_tag(mpi,2,5) )); // expected-error {{attribute parameter 2 is out of bounds}} 
     27 
     28  void f3(void *buf, int count, MPI_Datatype datatype) 
     29       __attribute__(( pointer_with_type_tag(mpi,1,5) )); // expected-error {{attribute is invalid for the implicit this argument}} 
     30 
     31  void f4(void *buf, int count, MPI_Datatype datatype) 
     32       __attribute__(( pointer_with_type_tag(mpi,2,1) )); // expected-error {{attribute is invalid for the implicit this argument}} 
     33 
     34  void MPI_Send(void *buf, int count, MPI_Datatype datatype) 
     35       __attribute__(( pointer_with_type_tag(mpi,2,4) )); // no-error 
     36}; 
     37 
     38class OperatorIntStar 
     39{ 
     40public: 
     41  operator int*(); 
     42}; 
     43 
     44void test1(C *c, int *int_buf) 
     45{ 
     46  c->MPI_Send(int_buf, 1, MPI_INT); // no-warning 
     47  c->MPI_Send(int_buf, 1, MPI_FLOAT); // expected-warning {{pointee type 'int' doesn't match specified mpi type tag that requires 'float'}} 
     48 
     49  OperatorIntStar i; 
     50  c->MPI_Send(i, 1, MPI_INT); // no-warning 
     51  c->MPI_Send(i, 1, MPI_FLOAT); // expected-warning {{pointee type 'int' doesn't match specified mpi type tag that requires 'float'}} 
     52} 
     53