Compare commits

...

114 Commits

Author SHA1 Message Date
Bill Wendling
83f8b92b34 Merging r216572:
------------------------------------------------------------------------
r216572 | chandlerc | 2014-08-27 11:21:27 -0700 (Wed, 27 Aug 2014) | 3 lines

Fix PR20773 which I introduced with a silly edit mistake in r216531.
Trivial fix, and I've made the gentoo tests more representative. With
the changes, they would have caught this failure.
------------------------------------------------------------------------

llvm-svn: 216588
2014-08-27 20:07:31 +00:00
Bill Wendling
d2cd7c5902 Merging r216531:
------------------------------------------------------------------------
r216531 | chandlerc | 2014-08-27 01:41:41 -0700 (Wed, 27 Aug 2014) | 22 lines

Significantly fix Clang's header search for Ubuntu (and possibly other
modern Debian-based distributions) due to on-going multiarch madness.

It appears that when the multiarch heeader search support went into the
clang driver, it went in in a quite bad state. The order of includes
completely failed to match the order exhibited by GCC, and in a specific
case -- when the GCC triple and the multiarch triple don't match as with
i686-linux-gnu and i386-linux-gnu -- we would absolutely fail to find
the libstdc++ target-specific header files.

I assume that folks who have been using Clang on Ubuntu 32-bit systems
have been applying weird patches to hack around this. I can't imagine
how else it could have worked. This was originally reported by a 64-bit
operating system user who had a 32-bit crosscompiler installed. We tried
to use that rather than the bi-arch support of the 64-bit compiler, but
failed due to the triple differences.

I've corrected all the wrong orderings in the existing tests and added
a specific test for the multiarch triple strings that are different in
a significant way. This should significantly improve the usability of
Clang when checked out vanilla from upstream onto Ubuntu machines with
an i686 GCC installation for whatever reason.
------------------------------------------------------------------------

llvm-svn: 216587
2014-08-27 20:07:13 +00:00
Michael Wong
76d2581450 updated with clang openmp notes by Michael Wong
llvm-svn: 216578
2014-08-27 19:22:48 +00:00
Bill Wendling
13225a76de Use C++14 flags.
llvm-svn: 216287
2014-08-22 20:54:39 +00:00
Bill Wendling
368a2bed7b Merging r216064:
------------------------------------------------------------------------
r216064 | kongyi | 2014-08-20 03:40:20 -0700 (Wed, 20 Aug 2014) | 9 lines

ARM: Fix codegen for rbit intrinsic

LLVM generates illegal `rbit r0, #352` instruction for rbit intrinsic.
According to ARM ARM, rbit only takes register as argument, not immediate.
The correct instruction should be rbit <Rd>, <Rm>.

The bug was originally introduced in r211057.

Differential Revision: http://reviews.llvm.org/D4980
------------------------------------------------------------------------

llvm-svn: 216089
2014-08-20 17:42:35 +00:00
Bill Wendling
95959916e7 It fixes a regression with multiple address spaces in
OpenCL and blocks.

Patch by Pekka.

llvm-svn: 216049
2014-08-20 07:39:19 +00:00
Bill Wendling
7370495d29 Make 3.5 branch.
llvm-svn: 216046
2014-08-20 07:27:19 +00:00
Renato Golin
813999532a Merging r215295:
------------------------------------------------------------------------
r215295 | compnerd | 2014-08-09 21:17:37 +0100 (Sat, 09 Aug 2014) | 10 lines

builtins: correct __umodsi3, __udivsi3 on ARM

When building the builtins for a modern CPU (idiv support), __umodsi3 was
completely incorrect as it would behave as __udivmosi3, which takes a tertiary
parameter which is a pointer.

__udivsi3 was also incorrect, returning the remainder in r1.  Although this
would not result in any crash or invalid behaviour as r1 is a caller saved
register in AAPCS, this is unnecessary.  Simply perform the division ignoring
the remainder.
------------------------------------------------------------------------

llvm-svn: 216035
2014-08-19 23:30:32 +00:00
Bill Wendling
4c7a06eb9c Merging r215609:
------------------------------------------------------------------------
r215609 | majnemer | 2014-08-13 17:49:23 -0700 (Wed, 13 Aug 2014) | 3 lines

Sema: Permit nullptr template args in MSVC compat mode

This fixes a regression I caused back in r211766.
------------------------------------------------------------------------

llvm-svn: 215881
2014-08-18 05:18:35 +00:00
Bill Wendling
61c4ba945c Merging r215618:
------------------------------------------------------------------------
r215618 | majnemer | 2014-08-13 23:35:08 -0700 (Wed, 13 Aug 2014) | 7 lines

Parse: Don't attempt to act on #pragma init_seg when not targeting MSVC

It doesn't really make sense to try and do stuff with #pragma init_seg
when targeting non-Microsoft platforms; notions like library vs user
initializers don't exist for other targets.

This fixes PR20639.
------------------------------------------------------------------------

llvm-svn: 215880
2014-08-18 05:18:12 +00:00
Bill Wendling
562712ae80 Merging r215711:
------------------------------------------------------------------------
r215711 | wschmidt | 2014-08-15 06:51:57 -0700 (Fri, 15 Aug 2014) | 8 lines

[PPC64] Add test case for r215685.

I had deferred adding this test case until I could get it down to a
reasonable size.  That's done now.

Thanks,
Bill

------------------------------------------------------------------------

llvm-svn: 215879
2014-08-18 05:16:58 +00:00
Bill Wendling
ef492f7c44 Merging r215685:
------------------------------------------------------------------------
r215685 | wschmidt | 2014-08-14 18:25:26 -0700 (Thu, 14 Aug 2014) | 69 lines

[PPC64] Add missing dependency on X2 to LDinto_toc.

The LDinto_toc pattern has been part of 64-bit PowerPC for a long
time, and represents loading from a memory location into the TOC
register (X2).  However, this pattern doesn't explicitly record that
it modifies that register.  This patch adds the missing dependency.

It was very surprising to me that this has never shown up as a problem
in the past, and that we only saw this problem recently in a single
scenario when building a self-hosted clang.  It turns out that in most
cases we have another dependency present that keeps the LDinto_toc
instruction tied in place.  LDinto_toc is used for TOC restore
following a call site, so this is a typical sequence:

   BCTRL8 <regmask>, %CTR8<imp-use>, %RM<imp-use>, %X3<imp-use>, %X12<imp-use>, %X1<imp-def>, ...
   LDinto_toc 24, %X1
   ADJCALLSTACKUP 96, 0, %R1<imp-def>, %R1<imp-use>

Because the LDinto_toc is inserted prior to the ADJCALLSTACKUP, there
is a natural anti-dependency between the two that keeps it in place.

Therefore we don't usually see a problem.  However, in one particular
case, one call is followed immediately by another call, and the second
call requires a parameter that is a TOC-relative address.  This is the
code sequence:

  BCTRL8 <regmask>, %CTR8<imp-use>, %RM<imp-use>, %X3<imp-use>, %X4<imp-use>, %X5<imp-use>, %X12<imp-use>, %X1<imp-def>, ...
  LDinto_toc 24, %X1
  ADJCALLSTACKUP 96, 0, %R1<imp-def>, %R1<imp-use>
  ADJCALLSTACKDOWN 96, %R1<imp-def>, %R1<imp-use>
  %vreg39<def> = ADDIStocHA %X2, <ga:@.str>; G8RC_and_G8RC_NOX0:%vreg39
  %vreg40<def> = ADDItocL %vreg39<kill>, <ga:@.str>; G8RC:%vreg40 G8RC_and_G8RC_NOX0:%vreg39

Note that the back-to-back stack adjustments are the same size!  The
back end is smart enough to recognize this and optimize them away:

  BCTRL8 <regmask>, %CTR8<imp-use>, %RM<imp-use>, %X3<imp-use>, %X4<imp-use>, %X5<imp-use>, %X12<imp-use>, %X1<imp-def>, ...
  LDinto_toc 24, %X1
  %vreg39<def> = ADDIStocHA %X2, <ga:@.str>; G8RC_and_G8RC_NOX0:%vreg39
  %vreg40<def> = ADDItocL %vreg39<kill>, <ga:@.str>; G8RC:%vreg40 G8RC_and_G8RC_NOX0:%vreg39

Now there is nothing to prevent the ADDIStocHA instruction from moving
ahead of the LDinto_toc instruction, and because of the longest-path
heuristic, this is what happens.

With the accompanying patch, %X2 is represented as an implicit def:

  BCTRL8 <regmask>, %CTR8<imp-use>, %RM<imp-use>, %X3<imp-use>, %X4<imp-use>, %X5<imp-use>, %X12<imp-use>, %X1<imp-def>, ...
  LDinto_toc 24, %X1, %X2<imp-def,dead>
  ADJCALLSTACKUP 96, 0, %R1<imp-def,dead>, %R1<imp-use>
  ADJCALLSTACKDOWN 96, %R1<imp-def,dead>, %R1<imp-use>
  %vreg39<def> = ADDIStocHA %X2, <ga:@.str>; G8RC_and_G8RC_NOX0:%vreg39
  %vreg40<def> = ADDItocL %vreg39<kill>, <ga:@.str>; G8RC:%vreg40 G8RC_and_G8RC_NOX0:%vreg39

So now when the two stack adjustments are removed, ADDIStocHA is
prevented from being moved above LDinto_toc.

I have not yet created a test case for this, because the original
failure occurs on a relatively large function that needs reduction.
However, this is a fairly serious bug, despite its infrequency, and I
wanted to get this patch onto the list as soon as possible so that it
can be considered for a 3.5 backport.  I'll work on whittling down a
test case.

Have we missed the boat for 3.5 at this point?

Thanks,
Bill

------------------------------------------------------------------------

llvm-svn: 215878
2014-08-18 05:16:33 +00:00
Bill Wendling
3c78fb290a Merging r215808:
------------------------------------------------------------------------
r215808 | nicholas | 2014-08-15 19:14:37 -0700 (Fri, 15 Aug 2014) | 2 lines

Clarify.

------------------------------------------------------------------------

llvm-svn: 215877
2014-08-18 05:15:34 +00:00
Bill Wendling
4262851e1b Merging r215807:
------------------------------------------------------------------------
r215807 | nicholas | 2014-08-15 19:11:54 -0700 (Fri, 15 Aug 2014) | 2 lines

Try indenting to put all the text inside the block.

------------------------------------------------------------------------

llvm-svn: 215876
2014-08-18 05:15:18 +00:00
Bill Wendling
ff38e3da85 Merging r215806:
------------------------------------------------------------------------
r215806 | nicholas | 2014-08-15 19:09:42 -0700 (Fri, 15 Aug 2014) | 2 lines

Document what's experimental about __attribute__((enable_if)). PR20392

------------------------------------------------------------------------

llvm-svn: 215875
2014-08-18 05:15:02 +00:00
Bill Wendling
6bdbb229c0 Merging r215806:
------------------------------------------------------------------------

llvm-svn: 215874
2014-08-18 05:14:39 +00:00
Sylvestre Ledru
fcd989333f Fix the build. Match the declaration in trunk. Use clang::diag::Flavor::WarningOrError
llvm-svn: 215833
2014-08-17 11:59:37 +00:00
Sylvestre Ledru
e82b3c8f5f Document -Wabsolute-value with example
llvm-svn: 215652
2014-08-14 16:10:10 +00:00
Sylvestre Ledru
bc626ae563 Document -Wtautological-pointer-compare & -Wtautological-undefined-compare with example
llvm-svn: 215651
2014-08-14 16:09:45 +00:00
Sylvestre Ledru
4de5839c99 Document the new warning -Wabsolute-value
llvm-svn: 215525
2014-08-13 07:41:41 +00:00
Bill Wendling
5ba548388f Merging r214679:
------------------------------------------------------------------------
r214679 | chandlerc | 2014-08-03 17:54:28 -0700 (Sun, 03 Aug 2014) | 10 lines

[x86] Fix the test case added in r214670 and tweaked in r214674 further.

Fundamentally, there isn't a really portable way to test the constant
pool contents. Instead, pin this test to the bare-metal triple. This
also makes it a 64-bit triple which allows us to only match a single
constant pool rather than two. It can also just hard code the '.' prefix
as the format should be stable now that it has a fixed triple. Finally,
I've switched it to use CHECK-NEXT to be more precise in the instruction
sequence expected and to use variables rather than hard coding decisions
by the register allocator.
------------------------------------------------------------------------

llvm-svn: 215430
2014-08-12 05:41:35 +00:00
Bill Wendling
6036ee499c Merging r214674:
------------------------------------------------------------------------
r214674 | spatel | 2014-08-03 16:20:16 -0700 (Sun, 03 Aug 2014) | 2 lines

Account for possible leading '.' in label string.

------------------------------------------------------------------------

llvm-svn: 215429
2014-08-12 05:41:22 +00:00
Bill Wendling
0ee1c0452b Merging r214670:
------------------------------------------------------------------------
r214670 | spatel | 2014-08-03 15:48:23 -0700 (Sun, 03 Aug 2014) | 8 lines

fix for PR20354 - Miscompile of fabs due to vectorization

This is intended to be the minimal change needed to fix PR20354 ( http://llvm.org/bugs/show_bug.cgi?id=20354 ). The check for a vector operation was wrong; we need to check that the fabs itself is not a vector operation.

This patch will not generate the optimal code. A constant pool load and 'and' op will be generated instead of just returning a value that we can calculate in advance (as we do for the scalar case). I've put a 'TODO' comment for that here and expect to have that patch ready soon.

There is a very similar optimization that we can do in visitFNEG, so I've put another 'TODO' there and expect to have another patch for that too.

------------------------------------------------------------------------

llvm-svn: 215428
2014-08-12 05:41:11 +00:00
Bill Wendling
5a09dfa964 Merging r215229:
------------------------------------------------------------------------
r215229 | sylvestre | 2014-08-08 10:15:13 -0700 (Fri, 08 Aug 2014) | 11 lines

Fix a bug when scan-build is used in a cross-compilation environment with
the --use-cc option.

Instead, we will search in the PATH
For example:
 scan-build --use-cc=arm-none-eabi-gcc -o out make -e

Initially reported as a Debian Bug:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=748777


------------------------------------------------------------------------

llvm-svn: 215427
2014-08-12 05:38:53 +00:00
Bill Wendling
668c2339e1 Revert r.215058.
llvm-svn: 215426
2014-08-12 05:35:26 +00:00
Bill Wendling
2ffe33d726 Fix lldb build for 3.5 release. Patcy by Sylvestre Ladru.
llvm-svn: 215425
2014-08-12 05:32:50 +00:00
Sylvestre Ledru
3f0867ead3 Also describe the new check 'alpha.core.TestAfterDivZero'
llvm-svn: 215314
2014-08-10 12:41:40 +00:00
Sylvestre Ledru
c76f4b6602 Update of the release notes: '-z' is also forwarded to the linker
llvm-svn: 215313
2014-08-10 12:38:46 +00:00
Bob Wilson
28e01d94e1 Merge r215245: Change __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ for versions > 10.9.
llvm-svn: 215254
2014-08-08 22:59:37 +00:00
Sylvestre Ledru
192e2e2ca9 Fixed the build broken by the r215046 (same patch as abidh in trunk)
llvm-svn: 215130
2014-08-07 18:51:43 +00:00
Jim Cownie
c25f426db2 Update Branch3_5 to include new Cmake code and PowerPC64 buld fixes.
Branch_35 will then be the same as Rev 215093 on the trunk.

llvm-svn: 215098
2014-08-07 11:16:59 +00:00
Pekka Jaaskelainen
66671a5b81 Added pocl and TCE to the list of projects that work with Clang/LLVM 3.5.
llvm-svn: 215090
2014-08-07 09:06:53 +00:00
Bill Wendling
21bac108cf Merging r214481:
------------------------------------------------------------------------
r214481 | hfinkel | 2014-07-31 22:20:41 -0700 (Thu, 31 Jul 2014) | 38 lines

[PowerPC] Generate unaligned vector loads using intrinsics instead of regular loads

Altivec vector loads on PowerPC have an interesting property: They always load
from an aligned address (by rounding down the address actually provided if
necessary). In order to generate an actual unaligned load, you can generate two
load instructions, one with the original address, one offset by one vector
length, and use a special permutation to extract the bytes desired.

When this was originally implemented, I generated these two loads using regular
ISD::LOAD nodes, now marked as aligned. Unfortunately, there is a problem with
this:

The alignment of a load does not contribute to its identity, and SDNodes
are uniqued. So, imagine that we have some unaligned load, L1, that is not
aligned. The routine will create two loads, L1(aligned) and (L1+16)(aligned).
Further imagine that there had already existed a load (L1+16)(unaligned) with
the same chain operand as the load L1. When (L1+16)(aligned) is created as part
of the lowering of L1, this load *is* also the (L1+16)(unaligned) node, just
now marked as aligned (because the new alignment overwrites the old). But the
original users of (L1+16)(unaligned) now get the data intended for the
permutation yielding the data for L1, and (L1+16)(unaligned) no longer exists
to get its own permutation-based expansion. This was PR19991.

A second potential problem has to do with the MMOs on these loads, which can be
used by AA during instruction scheduling to break chain-based dependencies. If
the new "aligned" loads get the MMO from the original unaligned load, this does
not represent the fact that it will load data from below the original address.
Normally, this would not matter, but this load might be combined with another
load pair for a previous vector, and then the dependency on the otherwise-
ignored lower bytes can matter.

To fix both problems, instead of generating the necessary loads using regular
ISD::LOAD instructions, ppc_altivec_lvx intrinsics are used instead. These are
provided with MMOs with a conservative address range.

Unfortunately, I no longer have a failing test case (since PR19991 was
reported, other changes in CodeGen have forced this bug back into hiding it
again). Nevertheless, this should fix the underlying problem.
------------------------------------------------------------------------

llvm-svn: 215058
2014-08-07 04:52:45 +00:00
Bill Wendling
b625dc1f9e Merging r215046:
------------------------------------------------------------------------
r215046 | rsmith | 2014-08-06 17:24:21 -0700 (Wed, 06 Aug 2014) | 19 lines

Use -Rblah, not -Wblah, to control remark diagnostics. This was always the
intent when we added remark support, but was never implemented in the general
case, because the first -R flags didn't need it. (-Rpass= had special handling
to accomodate its argument.)

-Rno-foo, -Reverything, and -Rno-everything can be used to turn off a remark,
or to turn on or off all remarks. Per discussion on cfe-commits, -Weverything
does not affect remarks, and -Reverything does not affect warnings or errors.

The only "real" -R flag we have right now is -Rmodule-build; that flag is
effectively renamed from -Wmodule-build to -Rmodule-build by this change.

-Wpass and -Wno-pass (and their friends) are also renamed to -Rpass and
-Rno-pass by this change; it's not completely clear whether we intended to have
a -Rpass (with no =pattern), but that is unchanged by this commit, other than
the flag name. The default pattern is effectively one which matches no passes.
In future, we may want to make the default pattern be .*, so that -Reverything
works for -Rpass properly.

------------------------------------------------------------------------

llvm-svn: 215057
2014-08-07 04:51:51 +00:00
Bill Schmidt
ca6c6b95d5 Correct faulty merge of r214923 due to echristo's subversion changes in trunk
llvm-svn: 214927
2014-08-05 21:15:38 +00:00
Bill Schmidt
b2459060c8 Merging r214923:
------------------------------------------------------------------------
r214923 | wschmidt | 2014-08-05 15:47:25 -0500 (Tue, 05 Aug 2014) | 12 lines

[PowerPC] Swap arguments and adjust shift count for vsldoi on little endian

Commits r213915 and r214718 fix recognition of shuffle masks for vmrg*
and vpku*um instructions for a little-endian target, by swapping the
input arguments.  The vsldoi instruction requires similar treatment,
and also needs its shift count adjusted for little endian.

Reviewed by Ulrich Weigand.

This is a bug fix candidate for release 3.5 (and hopefully the last of
those for PowerPC).

------------------------------------------------------------------------

llvm-svn: 214926
2014-08-05 20:59:06 +00:00
Tom Stellard
0abd0b2d75 Merging r214865:
------------------------------------------------------------------------
r214865 | thomas.stellard | 2014-08-05 10:40:52 -0400 (Tue, 05 Aug 2014) | 5 lines

R600/SI: Avoid generating REGISTER_LOAD instructions.

SI doesn't use REGISTER_LOAD anymore, but it was still hitting this code
path for 8-bit and 16-bit private loads.

------------------------------------------------------------------------

llvm-svn: 214895
2014-08-05 17:38:25 +00:00
Tom Stellard
3e548d31e8 Merging r214463:
------------------------------------------------------------------------
r214463 | thomas.stellard | 2014-07-31 20:32:28 -0400 (Thu, 31 Jul 2014) | 7 lines

R600/SI: Fix incorrect commute operation in shrink instructions pass

We were commuting the instruction by still shrinking it using the
original opcode.

NOTE: This is a candidate for the 3.5 branch.

------------------------------------------------------------------------

llvm-svn: 214894
2014-08-05 17:38:23 +00:00
Bill Wendling
f48d9e60c0 Add blurb about LDC.
llvm-svn: 214842
2014-08-05 05:23:26 +00:00
Bill Wendling
904a8f6ac8 Merging r213799:
------------------------------------------------------------------------
r213799 | grosbach | 2014-07-23 13:41:38 -0700 (Wed, 23 Jul 2014) | 5 lines

X86: restrict combine to when type sizes are safe.

The folding of unary operations through a vector compare and mask operation
is only safe if the unary operation result is of the same size as its input.
For example, it's not safe for [su]itofp from v4i32 to v4f64.
------------------------------------------------------------------------

llvm-svn: 214841
2014-08-05 05:20:22 +00:00
Bill Wendling
20b8eb19ee Merging r214735:
------------------------------------------------------------------------
r214735 | ogoffart | 2014-08-04 10:28:11 -0700 (Mon, 04 Aug 2014) | 1 line

Fix crash when accessing a property of an invalid interface
------------------------------------------------------------------------

llvm-svn: 214840
2014-08-05 05:19:37 +00:00
Bill Wendling
13b8dc2040 Merging r214734:
------------------------------------------------------------------------
r214734 | ogoffart | 2014-08-04 10:28:05 -0700 (Mon, 04 Aug 2014) | 7 lines

Fix crash when assiging to a property with an invalid type

This is a regression from clang 3.4

Set the result to ExprError and returns true, rather than simply
returns false because errors have been reported already and returning
false show a confusing error
------------------------------------------------------------------------

llvm-svn: 214839
2014-08-05 05:19:17 +00:00
Bill Schmidt
6a183487cc Merging r214801:
------------------------------------------------------------------------
r214801 | wschmidt | 2014-08-04 18:21:26 -0500 (Mon, 04 Aug 2014) | 19 lines

[PPC64LE] Fix wrong IR for vec_sld and vec_vsldoi

My original LE implementation of the vsldoi instruction, with its
altivec.h interfaces vec_sld and vec_vsldoi, produces incorrect
shufflevector operations in the LLVM IR.  Correct code is generated
because the back end handles the incorrect shufflevector in a
consistent manner.

This patch and a companion patch for LLVM correct this problem by
removing the fixup from altivec.h and the corresponding fixup from the
PowerPC back end.  Several test cases are also modified to reflect the
now-correct LLVM IR.

The vec_sums and vec_vsumsws interfaces in altivec.h are also fixed,
because they used vec_perm calls intended to be recognized as vsldoi
instructions.  These vec_perm calls are now replaced with code that
more clearly shows the intent of the transformation.


------------------------------------------------------------------------

llvm-svn: 214823
2014-08-04 23:48:10 +00:00
Bill Schmidt
869abd3c4a Fix incorrectly resolved merge conflict
llvm-svn: 214822
2014-08-04 23:47:21 +00:00
Bill Schmidt
d7eab8630c Merging r214800:
------------------------------------------------------------------------
r214800 | wschmidt | 2014-08-04 18:21:01 -0500 (Mon, 04 Aug 2014) | 13 lines

[PPC64LE] Fix wrong IR for vec_sld and vec_vsldoi

My original LE implementation of the vsldoi instruction, with its
altivec.h interfaces vec_sld and vec_vsldoi, produces incorrect
shufflevector operations in the LLVM IR.  Correct code is generated
because the back end handles the incorrect shufflevector in a
consistent manner.

This patch and a companion patch for Clang correct this problem by
removing the fixup from altivec.h and the corresponding fixup from the
PowerPC back end.  Several test cases are also modified to reflect the
now-correct LLVM IR.

------------------------------------------------------------------------

llvm-svn: 214821
2014-08-04 23:44:59 +00:00
Bill Schmidt
3df9c41538 Merging r214721:
------------------------------------------------------------------------
r214721 | uweigand | 2014-08-04 09:55:26 -0500 (Mon, 04 Aug 2014) | 4 lines

[PowerPC] Add target triple to vec_urem_const.ll test case

This should hopefully fix build bots on other architectures.

------------------------------------------------------------------------

llvm-svn: 214820
2014-08-04 23:43:34 +00:00
Bill Schmidt
8338208af2 Merging r214718:
------------------------------------------------------------------------
r214718 | uweigand | 2014-08-04 08:53:40 -0500 (Mon, 04 Aug 2014) | 12 lines

[PowerPC] Swap arguments to vpkuhum/vpkuwum on little-endian

In commit r213915, Bill fixed little-endian usage of vmrgh* and vmrgl*
by swapping the input arguments.  As it turns out, the exact same fix
is also required for the vpkuhum/vpkuwum patterns.

This fixes another regression in llvmpipe when vector support is
enabled.

Reviewed by Bill Schmidt.


------------------------------------------------------------------------

llvm-svn: 214819
2014-08-04 23:42:09 +00:00
Bill Schmidt
b33695227a Merging r214716:
------------------------------------------------------------------------
r214716 | uweigand | 2014-08-04 08:27:12 -0500 (Mon, 04 Aug 2014) | 9 lines

[PowerPC] MULHU/MULHS are not legal for vector types

I ran into some test failures where common code changed vector division
by constant into a multiply-high operation (MULHU).  But these are not
implemented by the back-end, so we failed to recognize the insn.

Fixed by marking MULHU/MULHS as Expand for vector types.


------------------------------------------------------------------------

llvm-svn: 214818
2014-08-04 23:41:27 +00:00
Bill Schmidt
444a522e5d Merging r214714:
------------------------------------------------------------------------
r214714 | uweigand | 2014-08-04 08:13:57 -0500 (Mon, 04 Aug 2014) | 19 lines

[PowerPC] Fix and improve vector comparisons

This patch refactors code generation of vector comparisons.

This fixes a wrong code-gen bug for ISD::SETGE for floating-point types,
and improves generated code for vector comparisons in general.

Specifically, the patch moves all logic deciding how to implement vector
comparisons into getVCmpInst, which gets two extra boolean outputs
indicating to its caller whether its needs to swap the input operands
and/or negate the result of the comparison.  Apart from implementing
these two modifications as directed by getVCmpInst, there is no need
to ever implement vector comparisons in any other manner; in particular,
there is never a need to perform two separate comparisons (e.g. one for
equal and one for greater-than, as code used to do before this patch).

Reviewed by Bill Schmidt.


------------------------------------------------------------------------

llvm-svn: 214817
2014-08-04 23:37:33 +00:00
Hans Wennborg
9b74891142 Merging r214777:
Excluding the /Zp option, because that was added after the 3.5 branch.

------------------------------------------------------------------------
r214777 | hans | 2014-08-04 14:07:58 -0700 (Mon, 04 Aug 2014) | 1 line

UsersManual: update clang-cl options
------------------------------------------------------------------------

llvm-svn: 214778
2014-08-04 21:11:53 +00:00
Bill Wendling
5f262c819d Merging r214291:
------------------------------------------------------------------------
r214291 | sylvestre | 2014-07-30 01:33:21 -0700 (Wed, 30 Jul 2014) | 11 lines

Use __linux__ macro throughout, instead of ocasional __linux.

__linux is not universally defined across all standards versions, compilers and architectures. Specifically at C99 and up, it's not defined in GCC on powerpc platform.

See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=28314

Bugzilla: http://llvm.org/bugs/show_bug.cgi?id=20380

Patch by Dimitri John Ledkov <dimitri.ledkov@canonical.com>


------------------------------------------------------------------------

llvm-svn: 214766
2014-08-04 20:01:31 +00:00
Bill Wendling
569deba640 Merging r214060:
------------------------------------------------------------------------
r214060 | brad | 2014-07-27 18:57:32 -0700 (Sun, 27 Jul 2014) | 2 lines

Add missing override keyword to OpenBSD IsIntegratedAssemblerDefault().

------------------------------------------------------------------------

llvm-svn: 214765
2014-08-04 19:58:38 +00:00
Bill Wendling
2c74c29d92 Merging r214060:
------------------------------------------------------------------------

llvm-svn: 214764
2014-08-04 19:58:16 +00:00
Bill Wendling
c369220352 Merging r213834:
------------------------------------------------------------------------
r213834 | rsmith | 2014-07-23 19:27:39 -0700 (Wed, 23 Jul 2014) | 4 lines

Take the canonical type when forming a canonical template argument with
'nullptr' value. Fixes profiling of such template arguments to always give the
same value.

------------------------------------------------------------------------

llvm-svn: 214751
2014-08-04 18:38:09 +00:00
Bill Wendling
001a4b73cd Merging r213913:
------------------------------------------------------------------------
r213913 | rsmith | 2014-07-24 18:12:44 -0700 (Thu, 24 Jul 2014) | 4 lines

PR20445: Properly transform the initializer in a CXXNewExpr rather than running
it through the normal TreeTransform logic for Exprs (which will strip off
implicit parts of the initialization and never re-create them).

------------------------------------------------------------------------

llvm-svn: 214750
2014-08-04 18:37:31 +00:00
Bill Wendling
405f701d60 Merging r213966:
------------------------------------------------------------------------
r213966 | brad | 2014-07-25 12:28:44 -0700 (Fri, 25 Jul 2014) | 4 lines

Fix arc4random detection.

Patch by Pascal Stumpf.

------------------------------------------------------------------------

llvm-svn: 214749
2014-08-04 18:36:56 +00:00
Bill Wendling
dfb3dabbf1 Merging r213999:
------------------------------------------------------------------------
r213999 | tstellar | 2014-07-25 18:05:20 -0700 (Fri, 25 Jul 2014) | 1 line

R600: Add processor type for Mullins
------------------------------------------------------------------------

llvm-svn: 214748
2014-08-04 18:36:16 +00:00
Bill Wendling
c326e800f2 Merging r213999:
------------------------------------------------------------------------

llvm-svn: 214747
2014-08-04 18:35:56 +00:00
Bill Wendling
e3b981281d Merging r214119:
------------------------------------------------------------------------
r214119 | joerg | 2014-07-28 14:06:22 -0700 (Mon, 28 Jul 2014) | 7 lines

Change __INTx_TYPE__ to be always signed. This changes the value for
char-based types from "char" to "signed char". Adjust stdint.h to use
__INTx_TYPE__ directly without prefixing it with signed and to use
__UINTx_TYPE__ for unsigned ones.

The value of __INTx_TYPE__ now matches GCC.

------------------------------------------------------------------------

llvm-svn: 214746
2014-08-04 18:34:05 +00:00
Bill Wendling
12646940aa Merging r214222:
------------------------------------------------------------------------
r214222 | rsmith | 2014-07-29 14:20:12 -0700 (Tue, 29 Jul 2014) | 4 lines

PR20473: Don't "deduplicate" string literals with the same value but different
lengths! In passing, simplify string literal deduplication by relying on LLVM
to deduplicate the underlying constant values.

------------------------------------------------------------------------

llvm-svn: 214745
2014-08-04 18:33:13 +00:00
Bill Wendling
fe62b2b0a7 ------------------------------------------------------------------------
llvm-svn: 214744
2014-08-04 18:31:55 +00:00
Bill Wendling
f6c040eca0 Merging r214369:
------------------------------------------------------------------------
r214369 | rsmith | 2014-07-30 17:22:56 -0700 (Wed, 30 Jul 2014) | 2 lines

Rename this test so that it actually runs, and fix it so that it passes.

------------------------------------------------------------------------

llvm-svn: 214743
2014-08-04 18:28:36 +00:00
Bill Wendling
317fbe2805 Merging r214050:
------------------------------------------------------------------------
r214050 | rsmith | 2014-07-26 22:12:49 -0700 (Sat, 26 Jul 2014) | 7 lines

When looking for temporary dtors while building the CFG, do not walk into
lambda expressions (other than their capture initializers) nor blocks. Do walk
into default argument expressions and default initializer expressions.

These bugs were causing us to produce broken CFGs whenever a lambda expression
was used to initialize a libstdc++ std::function object!

------------------------------------------------------------------------

llvm-svn: 214742
2014-08-04 18:19:14 +00:00
Bill Wendling
fe82a366df Merging r214471:
------------------------------------------------------------------------
r214471 | rtrieu | 2014-07-31 18:42:01 -0700 (Thu, 31 Jul 2014) | 5 lines

Remove this pointer that is converted to bool.  In well-defined contexts, the
this pointer is always non-null.  If the this pointer is null, it is undefined
and the compiler may optimize it away by assuming it is non-null.  The null
checks are pushed into the callers.

------------------------------------------------------------------------

llvm-svn: 214741
2014-08-04 18:18:40 +00:00
Bill Wendling
75c7375ee8 Merging r214008:
------------------------------------------------------------------------
r214008 | rtrieu | 2014-07-25 19:10:52 -0700 (Fri, 25 Jul 2014) | 3 lines

If a template argument is non-evaluable expression, use the profile ID to see
if the two arguments are equal.

------------------------------------------------------------------------

llvm-svn: 214696
2014-08-04 04:36:40 +00:00
Bill Wendling
ec68271f06 Merging r213912:
------------------------------------------------------------------------
r213912 | rtrieu | 2014-07-24 17:24:02 -0700 (Thu, 24 Jul 2014) | 4 lines

Pass the PrintingPolicy when converting types to strings in template type
diffing.  This removes extra "struct"/"class" in the type names and gives
"bool" instead of "_Bool" for booleans.

------------------------------------------------------------------------

llvm-svn: 214695
2014-08-04 04:36:15 +00:00
Bill Wendling
4bd3da119e Merging r213902:
------------------------------------------------------------------------
r213902 | rtrieu | 2014-07-24 16:14:16 -0700 (Thu, 24 Jul 2014) | 3 lines

Print "(default)" for default template template arguments to match the
printing of other types.

------------------------------------------------------------------------

llvm-svn: 214694
2014-08-04 04:35:58 +00:00
Bill Wendling
009ef32ff2 Merging r213840:
------------------------------------------------------------------------
r213840 | rtrieu | 2014-07-23 21:24:50 -0700 (Wed, 23 Jul 2014) | 2 lines

Add support for nullptr template arguments to template type diffing.

------------------------------------------------------------------------

llvm-svn: 214693
2014-08-04 04:35:31 +00:00
Bill Wendling
3869e6a789 Merging r213613:
------------------------------------------------------------------------
r213613 | rtrieu | 2014-07-21 21:42:15 -0700 (Mon, 21 Jul 2014) | 2 lines

Fix '&' printing for template arguments in parentheses in template diffing.

------------------------------------------------------------------------

llvm-svn: 214692
2014-08-04 04:35:10 +00:00
Bill Wendling
d8f7f82712 Merging r213611:
------------------------------------------------------------------------
r213611 | rtrieu | 2014-07-21 21:06:54 -0700 (Mon, 21 Jul 2014) | 2 lines

More gracefully handle parentheses in templare arguments in template diffing.

------------------------------------------------------------------------

llvm-svn: 214691
2014-08-04 04:34:53 +00:00
Bill Wendling
aa124fa230 Merging r213609:
------------------------------------------------------------------------
r213609 | rtrieu | 2014-07-21 20:33:01 -0700 (Mon, 21 Jul 2014) | 3 lines

Fix a template diffing problem were an '&' is unexpectedly printed in
a template argument.

------------------------------------------------------------------------

llvm-svn: 214690
2014-08-04 04:34:27 +00:00
Bill Wendling
23513f4039 Merging r213665:
------------------------------------------------------------------------
r213665 | tnorthover | 2014-07-22 08:47:09 -0700 (Tue, 22 Jul 2014) | 11 lines

X86: drop relocations on __eh_frame sections globally.

Without this, we produce non-extern relocations when targeting older OS X
versions that ld64 can't cope with in the particular context of __eh_frame
sections (who'd want generic relocation-processing anyway?).

This means that an updated linker (ld64 from Xcode 3.2.6 or later) may be
needed when targeting such platforms with a modern version of LLVM, but this is
probably the case anyway and a reasonable requirement.

PR20212, rdar://problem/17544795
------------------------------------------------------------------------

llvm-svn: 214689
2014-08-04 04:29:47 +00:00
Bill Wendling
54f837917c Merging r213726:
------------------------------------------------------------------------
r213726 | nicholas | 2014-07-22 23:24:49 -0700 (Tue, 22 Jul 2014) | 2 lines

We may visit a call that uses an alloca multiple times in callUsesLocalStack, sometimes with IsNocapture true and sometimes with IsNocapture false. We accidentally skipped work we needed to do in the IsNocapture=false case if we were called with IsNocapture=true the first time. Fixes PR20405!

------------------------------------------------------------------------

llvm-svn: 214688
2014-08-04 04:28:45 +00:00
Bill Wendling
800eae7e0b Merging r213896:
------------------------------------------------------------------------
r213896 | compnerd | 2014-07-24 15:09:06 -0700 (Thu, 24 Jul 2014) | 6 lines

Target: invert condition for Windows

The Microsoft ABI and MSVCRT are considered the canonical C runtime and ABI.
The long double routines are not part of this environment.  However, cygwin and
MinGW both provide supplementary implementations.  Change the condition to
reflect this reality.
------------------------------------------------------------------------

llvm-svn: 214687
2014-08-04 04:28:05 +00:00
Bill Wendling
cdd225435f Merging r213883:
------------------------------------------------------------------------
r213883 | compnerd | 2014-07-24 10:46:36 -0700 (Thu, 24 Jul 2014) | 5 lines

X86: correct library call setup for Windows itanium

This target is identical to the Windows MSVC (and follows Microsoft ABI for C).
Correct the library call setup for this target.  The same set of library calls
are missing on this environment.
------------------------------------------------------------------------

llvm-svn: 214686
2014-08-04 04:27:37 +00:00
Bill Wendling
cd8406104c Merging r213899:
------------------------------------------------------------------------
r213899 | joerg | 2014-07-24 15:20:10 -0700 (Thu, 24 Jul 2014) | 2 lines

Don't use 128bit functions on PPC32.

------------------------------------------------------------------------

llvm-svn: 214685
2014-08-04 04:25:53 +00:00
Bill Wendling
87d61cf9aa Merging r214423:
------------------------------------------------------------------------
r214423 | hfinkel | 2014-07-31 12:13:38 -0700 (Thu, 31 Jul 2014) | 9 lines

Fix ScalarEvolutionExpander when creating a PHI in a block with duplicate predecessors

It seems that when I fixed this, almost exactly a year ago, I did not quite do
it correctly. When we have duplicate block predecessors, we can indeed not have
different incoming values for the same block, but we *must* have duplicate
entries. So, instead of skipping the duplicates, we explicitly add the
duplicate incoming values.

Fixes PR20442.
------------------------------------------------------------------------

llvm-svn: 214684
2014-08-04 04:22:44 +00:00
Bill Wendling
0e9a6b6dc0 Merging r214429:
------------------------------------------------------------------------
r214429 | willschm | 2014-07-31 12:50:53 -0700 (Thu, 31 Jul 2014) | 29 lines

Disable IsSub subregister assert.  pr18663.

This is a follow-up to the activity in the bug at
http://llvm.org/bugs/show_bug.cgi?id=18663 .  The underlying issue has
to do with how the KILL pseudo-instruction is handled.  I defer to
Hal/Jakob/Uli for additional details and background.

This will disable the (bad?) assert, add an associated fixme comment,
and add a pair of tests.

The code change and the pr18663-2.ll test are copied from the referenced
bug.  That test does not immediately fail in my environment, but I have
added the pr18663.ll test which does.

(Comment from Hal)
to provide everyone else with some context, this assert was not bad when
it was written. At that time, we only generated KILL pseudo instructions
around subregister copies. This logic, unfortunately, had its own problems.
In r199797, the relevant logic in MachineCopyPropagation was replaced to
generate KILLs for other kinds of copies too. This change in semantics broke
this now-problematic assumption in AggressiveAntiDepBreaker. The
AggressiveAntiDepBreaker really needs a proper cleanup to deal with the
change, but removing the assert (which just allows the function to return
false) is a safe conservative behavior, and should do for the time being.





------------------------------------------------------------------------

llvm-svn: 214683
2014-08-04 04:22:18 +00:00
Bill Wendling
832d6a68de Merging r214519:
------------------------------------------------------------------------
r214519 | rafael | 2014-08-01 07:57:05 -0700 (Fri, 01 Aug 2014) | 3 lines

Remove lto_codegen_set_attr.

It was never exported, so no functionality change.
------------------------------------------------------------------------

llvm-svn: 214682
2014-08-04 04:21:04 +00:00
Eric Fiselier
b0ca78fb51 [libcxx] Remove use of default function template parameters in type traits. Fixes DR20484
Summary: This patch moves the SFINAE for __is_destructor_welformed out of the function template parameters. type_traits must compile in c++03 mode since it is included in c++03 headers. 

Test Plan: No tests have been added.

Reviewers: danalbert, mclow.lists

Reviewed By: danalbert

Subscribers: K-ballo, cfe-commits

Differential Revision: http://reviews.llvm.org/D4735

llvm-svn: 214427
2014-07-31 19:35:37 +00:00
Bill Wendling
fc546f8627 Merging r213798:
------------------------------------------------------------------------
r213798 | grosbach | 2014-07-23 13:41:31 -0700 (Wed, 23 Jul 2014) | 7 lines

DAG: fp->int conversion for non-splat constants.

Constant fold the lanes of the input constant build_vector individually
so we correctly handle when the vector elements are not all the same
constant value.

PR20394
------------------------------------------------------------------------

llvm-svn: 214413
2014-07-31 18:17:04 +00:00
Justin Bogner
6b823ba449 Merging r214331:
------------------------------------------------------------------------
r214331 | arphaman | 2014-07-30 13:30:11 -0700 (Wed, 30 Jul 2014) | 4 lines

docs: update the command guide documentation for llvm-profdata.

Differential Revision: http://reviews.llvm.org/D4726

------------------------------------------------------------------------

llvm-svn: 214353
2014-07-30 22:43:59 +00:00
Justin Holewinski
9a45867caf Merging r213793:
------------------------------------------------------------------------
r213793 | jholewinski | 2014-07-23 16:23:47 -0400 (Wed, 23 Jul 2014) | 4 lines

[NVPTX] Silence a GCC warning found by the buildbots

The cast to NVPTXTargetLowering was missing a 'const', but let's
just access the right pointer through the subtarget anyway.
------------------------------------------------------------------------

llvm-svn: 214310
2014-07-30 14:53:00 +00:00
Justin Holewinski
94f35ea76f Merging r213773:
------------------------------------------------------------------------
r213773 | jholewinski | 2014-07-23 13:40:45 -0400 (Wed, 23 Jul 2014) | 5 lines

[NVPTX] Make sure we do not generate MULWIDE ISD nodes when optimizations are disabled

With optimizations disabled, we disable the isel patterns for mul.wide; but we
were still generating MULWIDE ISD nodes.  Now, we only try to generate MULWIDE
ISD nodes in DAGCombine if the optimization level is not zero.
------------------------------------------------------------------------

llvm-svn: 214309
2014-07-30 14:49:09 +00:00
Daniel Sanders
014e7b834f Merging r214180:
------------------------------------------------------------------------
r214180 | sstankovic | 2014-07-29 15:39:24 +0100 (Tue, 29 Jul 2014) | 5 lines

[mips] Don't use odd-numbered single precision registers for fastcc calling
convention if -mno-odd-spreg is used.

Differential Revision: http://reviews.llvm.org/D4682

------------------------------------------------------------------------

llvm-svn: 214304
2014-07-30 12:39:37 +00:00
Bill Wendling
0cec800e8d Merging r214287:
------------------------------------------------------------------------
r214287 | chandlerc | 2014-07-29 22:44:04 -0700 (Tue, 29 Jul 2014) | 9 lines

Don't manually (and forcibly) run the verifier on the entire module from
the jump instruction table pass. First, the verifier is already built
into all the tools. The test case is adapted to just run llvm-as
demonstrating that we still catch the broken module. Second, the
verifier is *extremely* slow. This was responsible for very significant
compile time regressions.

If you have deployed a Clang binary anywhere from r210280 to this
commit, you really want to re-deploy.
------------------------------------------------------------------------

llvm-svn: 214288
2014-07-30 06:21:43 +00:00
Bob Wilson
6323faf644 Merging r213993,213998:
llvm-svn: 214262
2014-07-30 00:07:54 +00:00
Hans Wennborg
d180cc9112 Merging r214129:
------------------------------------------------------------------------
r214129 | echristo | 2014-07-28 15:00:44 -0700 (Mon, 28 Jul 2014) | 2 lines

Regenerate autoconf, previous updates to the configury haven't
been updating configure.
------------------------------------------------------------------------

llvm-svn: 214261
2014-07-30 00:07:21 +00:00
Bob Wilson
81d4e6005c Merging r214208:
llvm-svn: 214257
2014-07-29 23:48:32 +00:00
Hans Wennborg
062184f19b Merging r213895:
------------------------------------------------------------------------
r213895 | mren | 2014-07-24 14:13:20 -0700 (Thu, 24 Jul 2014) | 2 lines

Feedback from Hans on r213815. No functionaility change.

------------------------------------------------------------------------

llvm-svn: 214254
2014-07-29 23:42:01 +00:00
Hans Wennborg
b3ff622079 Merging r213884:
------------------------------------------------------------------------
r213884 | mren | 2014-07-24 10:57:09 -0700 (Thu, 24 Jul 2014) | 1 line

Try to fix the bots again by moving test to X86 directory.
------------------------------------------------------------------------

llvm-svn: 214253
2014-07-29 23:40:11 +00:00
Hans Wennborg
6207270016 Merging r213880:
------------------------------------------------------------------------
r213880 | mren | 2014-07-24 10:18:33 -0700 (Thu, 24 Jul 2014) | 1 line

Try to fix the bots. If this does not work, I am going to move it to X86 directory.
------------------------------------------------------------------------

llvm-svn: 214252
2014-07-29 23:39:40 +00:00
Hans Wennborg
c7bfb6d36a Merging r213815:
------------------------------------------------------------------------
r213815 | mren | 2014-07-23 16:13:23 -0700 (Wed, 23 Jul 2014) | 17 lines

SimplifyCFG: fix a bug in switch to table conversion

We use gep to access the global array "switch.table", and the table index
should be treated as unsigned. When the highest bit is 1, this commit
zero-extends the index to an integer type with larger size.

For a switch on i2, we used to generate:
%switch.tableidx = sub i2 %0, -2
getelementptr inbounds [4 x i64]* @switch.table, i32 0, i2 %switch.tableidx

It is incorrect when %switch.tableidx is 2 or 3. The fix is to generate
%switch.tableidx = sub i2 %0, -2
%switch.tableidx.zext = zext i2 %switch.tableidx to i3
getelementptr inbounds [4 x i64]* @switch.table, i32 0, i3 %switch.tableidx.zext

rdar://17735071

------------------------------------------------------------------------

llvm-svn: 214251
2014-07-29 23:38:58 +00:00
Hans Wennborg
60c15ed5ff Merging r213894:
------------------------------------------------------------------------
r213894 | hans | 2014-07-24 14:09:45 -0700 (Thu, 24 Jul 2014) | 4 lines

Windows: Don't wildcard expand /? or -?

Even if there's a file called c:\a, we want /? to be preserved as
an option, not expanded to a filename.
------------------------------------------------------------------------

llvm-svn: 214248
2014-07-29 23:27:06 +00:00
Renato Golin
5975e88f88 Merging r213714:
------------------------------------------------------------------------
r213714 | compnerd | 2014-07-23 02:32:32 +0100 (Wed, 23 Jul 2014) | 4 lines

test: add an explicit target triple

Now that we support WoA, this test fails on ARM build bots as __va_start has a
different signature on different architectures.
------------------------------------------------------------------------

llvm-svn: 214110
2014-07-28 18:27:07 +00:00
Dan Liew
b8f0391a7c Add information about new CMake interface to LLVM and note
deprecation of llvm_map_components_to_libraries()

llvm-svn: 214083
2014-07-28 14:04:39 +00:00
Dan Liew
dddf67f5d5 Merging r214078:
------------------------------------------------------------------------
r214078 | delcypher | 2014-07-28 14:36:50 +0100 (Mon, 28 Jul 2014) | 6 lines

Emit a warning if llvm_map_components_to_libraries() is used noting that its
use is deprecated in favour of llvm_map_components_to_libnames()

Although message(DEPRECATION "msg") would probably be a better fit this
does nothing if CMAKE_ERROR_DEPRECATED and CMAKE_WARNING_DEPRECATED are
both off, which is the default.
------------------------------------------------------------------------

llvm-svn: 214080
2014-07-28 13:39:56 +00:00
Dan Liew
3c89b2c953 Merging r214077:
------------------------------------------------------------------------
r214077 | delcypher | 2014-07-28 14:36:37 +0100 (Mon, 28 Jul 2014) | 2 lines

Document the new LLVM CMake interface for building against LLVM
libraries. With many contributions from Brad King.
------------------------------------------------------------------------

llvm-svn: 214079
2014-07-28 13:39:33 +00:00
Dan Liew
ffd65c839c Document building Sphinx documentation in release notes.
llvm-svn: 214068
2014-07-28 11:47:23 +00:00
Dan Liew
aa9583d2ed Merging r213660:
------------------------------------------------------------------------
r213660 | delcypher | 2014-07-22 15:59:38 +0100 (Tue, 22 Jul 2014) | 1 line

Fix Sphinx warning.
------------------------------------------------------------------------

llvm-svn: 214066
2014-07-28 11:15:25 +00:00
Simon Atanasyan
5b15c0f87d Merging r213937:
------------------------------------------------------------------------
r213937 | atanasyan | 2014-07-25 15:20:21 +0400 (Fri, 25 Jul 2014) | 3 lines

[Driver][Mips] Remove "fp64" directories from the mips-mti-linux-gnu toolchain
directories description. Released version of this toolchain has not separate
libraries for -mfp64 command line option.
------------------------------------------------------------------------

llvm-svn: 214053
2014-07-27 09:19:33 +00:00
Bill Wendling
2fbdb127ea Merging r213915:
------------------------------------------------------------------------
r213915 | wschmidt | 2014-07-24 18:55:55 -0700 (Thu, 24 Jul 2014) | 21 lines

[PATCH][PPC64LE] Correct little-endian usage of vmrgh* and vmrgl*.

Because the PowerPC vmrgh* and vmrgl* instructions have a built-in
big-endian bias, it is necessary to swap their inputs in little-endian
mode when using them to implement a vector shuffle.  This was
previously missed in the vector LE implementation.

There was already logic to distinguish between unary and "normal"
vmrg* vector shuffles, so this patch extends that logic to use a third
option:  "swapped" vmrg* vector shuffles that are used for little
endian in place of the "normal" ones.

I've updated the vec-shuffle-le.ll test to check for the expected
register ordering on the generated instructions.

This bug was discovered when testing the LE and ELFv2 patches for
safety if they were backported to 3.4.  A different vectorization
decision was made in 3.4 than on mainline trunk, and that exposed the
problem.  I've verified this fix takes care of that issue.


------------------------------------------------------------------------

llvm-svn: 213961
2014-07-25 17:47:30 +00:00
Tim Northover
6b7ac2a98c [3.5] AArch64: docuemnt merge in release notes
llvm-svn: 213939
2014-07-25 11:51:48 +00:00
Sylvestre Ledru
e1dceeca1a Fix the version in the doc generation
llvm-svn: 213934
2014-07-25 10:16:56 +00:00
Filipe Cabecinhas
00cc493db6 Merge r213826
------------------------------------------------------------------------
r213826 | filcab | 2014-07-23 18:28:21 -0700 (Wed, 23 Jul 2014) | 7 lines

Fixed PR20411 - bug in getINSERTPS()

When we had a vector_shuffle where we had an input from each vector, we
could miscompile it because we were assuming the input from V2 wouldn't
be moved from where it was on the vector.

Added a test case.

llvm-svn: 213911
2014-07-25 00:00:11 +00:00
Daniel Sanders
9149bf6772 Merging r213749:
------------------------------------------------------------------------
r213749 | dsanders | 2014-07-23 13:59:26 +0100 (Wed, 23 Jul 2014) | 3 lines

Added release notes for MIPS.


------------------------------------------------------------------------

llvm-svn: 213849
2014-07-24 09:52:28 +00:00
Daniel Sanders
b4a2b91353 Merging r213847:
------------------------------------------------------------------------
r213847 | dsanders | 2014-07-24 10:47:14 +0100 (Thu, 24 Jul 2014) | 8 lines

[mips] Fix ll and sc instructions

Summary: The ll and sc instructions for r6 and non-r6 are misplaced. This patch fixes that.

Patch by Jyun-Yan You

Differential Revision: http://reviews.llvm.org/D4578

------------------------------------------------------------------------

llvm-svn: 213848
2014-07-24 09:48:54 +00:00
Yi Kong
2cabf384c2 Merging r213733:
------------------------------------------------------------------------
r213733 | kongyi | 2014-07-23 10:25:02 +0100 (Wed, 23 Jul 2014) | 5 lines

ARM: Add doc for ACLE memory barrier intrinsics

Add documentations for ACLE memory barrier intrinsics, describing their motion
barrier characteristics.

------------------------------------------------------------------------

llvm-svn: 213787
2014-07-23 19:55:09 +00:00
Dan Liew
a0911d3f03 Merging r213674:
------------------------------------------------------------------------
r213674 | delcypher | 2014-07-22 18:48:51 +0100 (Tue, 22 Jul 2014) | 5 lines

Add LLVM_TOOLS_BINARY_DIR variable to LLVMConfig.cmake so clients
of LLVM using CMake can easily find the tools directory.

LLVM_BUILD_TOOLS_BINARY_DIR was removed because it is now
superfluous.
------------------------------------------------------------------------

llvm-svn: 213766
2014-07-23 15:21:22 +00:00
Dan Liew
98ab17b1b3 Merging r213664:
------------------------------------------------------------------------
r213664 | delcypher | 2014-07-22 16:41:33 +0100 (Tue, 22 Jul 2014) | 3 lines

Export LLVM_ENABLE_RTTI and LLVM_ENABLE_EH in LLVMConfig.cmake so
clients of LLVM know if RTTI and/or EH were enabled in the build of
LLVM they are trying to link against.
------------------------------------------------------------------------

llvm-svn: 213765
2014-07-23 15:20:44 +00:00
Dan Liew
b79ae58145 Merging r213663:
------------------------------------------------------------------------
r213663 | delcypher | 2014-07-22 16:41:18 +0100 (Tue, 22 Jul 2014) | 4 lines

Added LLVM_ENABLE_RTTI and LLVM_ENABLE_EH options that allow RTTI and EH
to globally be controlled. Individual targets (e.g.  ExceptionDemo) can
still override this by using LLVM_REQUIRE_RTTI and LLVM_REQUIRE_EH if
they need to be compiled with RTTI or exception handling respectively.
------------------------------------------------------------------------

llvm-svn: 213764
2014-07-23 15:19:01 +00:00
Daniel Sanders
6e814ffb39 Merging r213653:
------------------------------------------------------------------------
r213653 | sstankovic | 2014-07-22 14:36:02 +0100 (Tue, 22 Jul 2014) | 7 lines

[mips] Fix two patterns that select i32's (for MIPS32r6) / i64's (for MIPS64r6)
from setne comparison with an i32.

The patterns that are fixed:
  * (select (i32 (setne i32, immZExt16)), i32, i32) (for MIPS32r6)
  * (select (i32 (setne i32, immZExt16)), i64, i64) (for MIPS64r6)

------------------------------------------------------------------------

llvm-svn: 213746
2014-07-23 12:45:33 +00:00
Daniel Sanders
e25ce394b0 Merging r213741:
------------------------------------------------------------------------
r213741 | dsanders | 2014-07-23 13:06:13 +0100 (Wed, 23 Jul 2014) | 5 lines

[mips] -mno-shared should only be given to the assembler when -fPIC/-fpic/-fPIE/-fpie is not in effect.

This fixes compiler recursion on MIPS32r2.


------------------------------------------------------------------------

llvm-svn: 213742
2014-07-23 12:11:45 +00:00
Bill Wendling
93c80e5bff Creating release_35 branch
llvm-svn: 213607
llvm-svn: 213606
llvm-svn: 213605
llvm-svn: 213604
llvm-svn: 213603
llvm-svn: 213602
llvm-svn: 213601
llvm-svn: 213598
llvm-svn: 213597
2014-07-22 03:16:41 +00:00
4307 changed files with 39224 additions and 118868 deletions

View File

@@ -1,6 +1,5 @@
add_subdirectory(clang-apply-replacements)
add_subdirectory(clang-modernize)
add_subdirectory(clang-rename)
add_subdirectory(modularize)
add_subdirectory(module-map-checker)
add_subdirectory(remove-cstr-calls)

View File

@@ -13,8 +13,8 @@ include $(CLANG_LEVEL)/../../Makefile.config
PARALLEL_DIRS := remove-cstr-calls tool-template modularize \
module-map-checker pp-trace
DIRS := clang-apply-replacements clang-modernize clang-rename clang-tidy \
clang-query unittests
DIRS := clang-apply-replacements clang-modernize clang-tidy clang-query \
unittests
include $(CLANG_LEVEL)/Makefile

View File

@@ -40,7 +40,7 @@ int AddOverrideTransform::apply(const CompilationDatabase &Database,
// Make Fixer available to handleBeginSource().
this->Fixer = &Fixer;
if (int result = AddOverrideTool.run(createActionFactory(Finder).get())) {
if (int result = AddOverrideTool.run(createActionFactory(Finder))) {
llvm::errs() << "Error encountered during translation.\n";
return result;
}

View File

@@ -116,8 +116,7 @@ private:
// checking for equality because it can also be part of the preamble if the
// preamble is the whole file.
unsigned Preamble =
Lexer::ComputePreamble(SM.getBuffer(Guard.FID)->getBuffer(), LangOpts)
.first;
Lexer::ComputePreamble(SM.getBuffer(Guard.FID), LangOpts).first;
unsigned IfndefOffset = SM.getFileOffset(Guard.IfndefLoc);
if (IfndefOffset > (Preamble + 1))
return;

View File

@@ -49,8 +49,7 @@ private:
FactoryAdaptor(MatchFinder &Finder, Transform &Owner)
: Finder(Finder), Owner(Owner) {}
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &,
StringRef) {
ASTConsumer *CreateASTConsumer(CompilerInstance &, StringRef) {
return Finder.newASTConsumer();
}
@@ -129,9 +128,8 @@ Transform::addReplacementForCurrentTU(const clang::tooling::Replacement &R) {
return true;
}
std::unique_ptr<FrontendActionFactory>
Transform::createActionFactory(MatchFinder &Finder) {
return llvm::make_unique<ActionFactory>(Finder, /*Owner=*/*this);
FrontendActionFactory *Transform::createActionFactory(MatchFinder &Finder) {
return new ActionFactory(Finder, /*Owner=*/ *this);
}
Version Version::getFromString(llvm::StringRef VersionStr) {

View File

@@ -208,8 +208,8 @@ protected:
///
/// The factory returned by this function is responsible for calling back to
/// Transform to call handleBeginSource() and handleEndSource().
std::unique_ptr<clang::tooling::FrontendActionFactory>
createActionFactory(clang::ast_matchers::MatchFinder &Finder);
clang::tooling::FrontendActionFactory *
createActionFactory(clang::ast_matchers::MatchFinder &Finder);
private:
const std::string Name;

View File

@@ -48,7 +48,7 @@ int LoopConvertTransform::apply(const CompilationDatabase &Database,
LFK_PseudoArray, /*Owner=*/ *this);
Finder.addMatcher(makePseudoArrayLoopMatcher(), &PseudoarrrayLoopFixer);
if (int result = LoopTool.run(createActionFactory(Finder).get())) {
if (int result = LoopTool.run(createActionFactory(Finder))) {
llvm::errs() << "Error encountered during translation.\n";
return result;
}

View File

@@ -35,7 +35,7 @@ int PassByValueTransform::apply(const tooling::CompilationDatabase &Database,
// make the replacer available to handleBeginSource()
this->Replacer = &Replacer;
if (Tool.run(createActionFactory(Finder).get())) {
if (Tool.run(createActionFactory(Finder))) {
llvm::errs() << "Error encountered during translation.\n";
return 1;
}

View File

@@ -34,7 +34,7 @@ ReplaceAutoPtrTransform::apply(const CompilationDatabase &Database,
Finder.addMatcher(makeAutoPtrUsingDeclMatcher(), &Replacer);
Finder.addMatcher(makeTransferOwnershipExprMatcher(), &Fixer);
if (Tool.run(createActionFactory(Finder).get())) {
if (Tool.run(createActionFactory(Finder))) {
llvm::errs() << "Error encountered during translation.\n";
return 1;
}

View File

@@ -36,7 +36,7 @@ int UseAutoTransform::apply(const clang::tooling::CompilationDatabase &Database,
Finder.addMatcher(makeIteratorDeclMatcher(), &ReplaceIterators);
Finder.addMatcher(makeDeclWithNewMatcher(), &ReplaceNew);
if (int Result = UseAutoTool.run(createActionFactory(Finder).get())) {
if (int Result = UseAutoTool.run(createActionFactory(Finder))) {
llvm::errs() << "Error encountered during translation.\n";
return Result;
}

View File

@@ -46,7 +46,8 @@ int UseNullptrTransform::apply(const CompilationDatabase &Database,
NullptrFixer Fixer(AcceptedChanges, MacroNames, /*Owner=*/ *this);
Finder.addMatcher(makeCastSequenceMatcher(), &Fixer);
if (int result = UseNullptrTool.run(createActionFactory(Finder).get())) {
if (int result = UseNullptrTool.run(createActionFactory(Finder))) {
llvm::errs() << "Error encountered during translation.\n";
return result;
}

View File

@@ -248,15 +248,14 @@ static CompilerVersions handleSupportedCompilers(const char *ProgName,
return RequiredVersions;
}
std::unique_ptr<CompilationDatabase>
autoDetectCompilations(std::string &ErrorMessage) {
CompilationDatabase *autoDetectCompilations(std::string &ErrorMessage) {
// Auto-detect a compilation database from BuildPath.
if (BuildPath.getNumOccurrences() > 0)
return CompilationDatabase::autoDetectFromDirectory(BuildPath,
ErrorMessage);
// Try to auto-detect a compilation database from the first source.
if (!SourcePaths.empty()) {
if (std::unique_ptr<CompilationDatabase> Compilations =
if (CompilationDatabase *Compilations =
CompilationDatabase::autoDetectFromSource(SourcePaths[0],
ErrorMessage)) {
// FIXME: just pass SourcePaths[0] once getCompileCommands supports
@@ -276,7 +275,7 @@ autoDetectCompilations(std::string &ErrorMessage) {
// If no compilation database can be detected from source then we create a
// fixed compilation database with c++11 support.
std::string CommandLine[] = { "-std=c++11" };
return llvm::make_unique<FixedCompilationDatabase>(".", CommandLine);
return new FixedCompilationDatabase(".", CommandLine);
}
ErrorMessage = "Could not determine sources to transform";
@@ -335,7 +334,7 @@ int main(int argc, const char **argv) {
if (!Compilations) {
std::string ErrorMessage;
Compilations = autoDetectCompilations(ErrorMessage);
Compilations.reset(autoDetectCompilations(ErrorMessage));
if (!Compilations) {
llvm::errs() << llvm::sys::path::filename(argv[0]) << ": " << ErrorMessage
<< "\n";

View File

@@ -157,12 +157,23 @@ QueryRef makeInvalidQueryFromDiagnostics(const Diagnostics &Diag) {
return new InvalidQuery(OS.str());
}
class QuerySessionSema : public Parser::RegistrySema {
public:
QuerySessionSema(const QuerySession &QS) : QS(QS) {}
ast_matchers::dynamic::VariantValue getNamedValue(StringRef Name) override {
return QS.NamedValues.lookup(Name);
}
private:
const QuerySession &QS;
};
} // namespace
QueryRef QueryParser::completeMatcherExpression() {
std::vector<MatcherCompletion> Comps = Parser::completeExpression(
StringRef(Begin, End - Begin), CompletionPos - Begin, nullptr,
&QS.NamedValues);
StringRef(Begin, End - Begin), CompletionPos - Begin);
for (std::vector<MatcherCompletion>::iterator I = Comps.begin(),
E = Comps.end();
I != E; ++I) {
@@ -183,6 +194,8 @@ QueryRef QueryParser::doParse() {
.Case("unlet", PQK_Unlet)
.Default(PQK_Invalid);
QuerySessionSema S(QS);
switch (QKind) {
case PQK_NoOp:
return new NoOpQuery;
@@ -201,8 +214,8 @@ QueryRef QueryParser::doParse() {
Diagnostics Diag;
ast_matchers::dynamic::VariantValue Value;
if (!Parser::parseExpression(StringRef(Begin, End - Begin), nullptr,
&QS.NamedValues, &Value, &Diag)) {
if (!Parser::parseExpression(StringRef(Begin, End - Begin), &S, &Value,
&Diag)) {
return makeInvalidQueryFromDiagnostics(Diag);
}
@@ -215,7 +228,7 @@ QueryRef QueryParser::doParse() {
Diagnostics Diag;
Optional<DynTypedMatcher> Matcher = Parser::parseMatcherExpression(
StringRef(Begin, End - Begin), nullptr, &QS.NamedValues, &Diag);
StringRef(Begin, End - Begin), &S, &Diag);
if (!Matcher) {
return makeInvalidQueryFromDiagnostics(Diag);
}

View File

@@ -30,7 +30,7 @@
#include "QueryParser.h"
#include "QuerySession.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/LineEditor/LineEditor.h"
#include "llvm/Support/CommandLine.h"
@@ -46,30 +46,45 @@ using namespace clang::query;
using namespace clang::tooling;
using namespace llvm;
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
static cl::OptionCategory ClangQueryCategory("clang-query options");
static cl::opt<std::string> BuildPath("b", cl::desc("Specify build path"),
cl::value_desc("<path>"));
static cl::list<std::string> Commands("c", cl::desc("Specify command to run"),
cl::value_desc("command"),
cl::cat(ClangQueryCategory));
cl::value_desc("<command>"));
static cl::list<std::string> CommandFiles("f",
cl::desc("Read commands from file"),
cl::value_desc("file"),
cl::cat(ClangQueryCategory));
cl::value_desc("<file>"));
static cl::list<std::string> SourcePaths(cl::Positional,
cl::desc("<source0> [... <sourceN>]"),
cl::OneOrMore);
int main(int argc, const char **argv) {
llvm::sys::PrintStackTraceOnErrorSignal();
CommonOptionsParser OptionsParser(argc, argv, ClangQueryCategory);
cl::ParseCommandLineOptions(argc, argv);
if (!Commands.empty() && !CommandFiles.empty()) {
llvm::errs() << argv[0] << ": cannot specify both -c and -f\n";
return 1;
}
ClangTool Tool(OptionsParser.getCompilations(),
OptionsParser.getSourcePathList());
std::unique_ptr<CompilationDatabase> Compilations(
FixedCompilationDatabase::loadFromCommandLine(argc, argv));
if (!Compilations) { // Couldn't find a compilation DB from the command line
std::string ErrorMessage;
Compilations.reset(
!BuildPath.empty() ?
CompilationDatabase::autoDetectFromDirectory(BuildPath, ErrorMessage) :
CompilationDatabase::autoDetectFromSource(SourcePaths[0], ErrorMessage)
);
// Still no compilation DB? - bail.
if (!Compilations)
llvm::report_fatal_error(ErrorMessage);
}
ClangTool Tool(*Compilations, SourcePaths);
std::vector<std::unique_ptr<ASTUnit>> ASTs;
if (Tool.buildASTs(ASTs) != 0)
return 1;

View File

@@ -1,20 +0,0 @@
set(LLVM_LINK_COMPONENTS support)
add_clang_executable(clang-rename
ClangRename.cpp
USRFinder.cpp
USRFindingAction.cpp
USRLocFinder.cpp
RenamingAction.cpp
)
target_link_libraries(clang-rename
clangAST
clangBasic
clangFrontend
clangIndex
clangRewrite
clangTooling
)
install(TARGETS clang-rename RUNTIME DESTINATION bin)

View File

@@ -1,151 +0,0 @@
//===--- tools/extra/clang-rename/ClangRename.cpp - Clang rename tool -----===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file implements a clang-rename tool that automatically finds and
/// renames symbols in C++ code.
///
//===----------------------------------------------------------------------===//
#include "USRFindingAction.h"
#include "RenamingAction.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Frontend/CommandLineSourceLoc.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/Lexer.h"
#include "clang/Parse/Parser.h"
#include "clang/Parse/ParseAST.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Refactoring.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/Support/Host.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include <string>
#include <vector>
using namespace llvm;
cl::OptionCategory ClangRenameCategory("Clang-rename options");
static cl::opt<std::string>
NewName(
"new-name",
cl::desc("The new name to change the symbol to."),
cl::cat(ClangRenameCategory));
static cl::opt<unsigned>
SymbolOffset(
"offset",
cl::desc("Locates the symbol by offset as opposed to <line>:<column>."),
cl::cat(ClangRenameCategory));
static cl::opt<bool>
Inplace(
"i",
cl::desc("Overwrite edited <file>s."),
cl::cat(ClangRenameCategory));
static cl::opt<bool>
PrintName(
"pn",
cl::desc("Print the found symbol's name prior to renaming to stderr."),
cl::cat(ClangRenameCategory));
static cl::opt<bool>
PrintLocations(
"pl",
cl::desc("Print the locations affected by renaming to stderr."),
cl::cat(ClangRenameCategory));
#define CLANG_RENAME_VERSION "0.0.1"
static void PrintVersion() {
outs() << "clang-rename version " << CLANG_RENAME_VERSION << "\n";
}
using namespace clang;
const char RenameUsage[] = "A tool to rename symbols in C/C++ code.\n\
clang-rename renames every occurrence of a symbol found at <offset> in\n\
<source0>. If -i is specified, the edited files are overwritten to disk.\n\
Otherwise, the results are written to stdout.\n";
int main(int argc, const char **argv) {
cl::SetVersionPrinter(PrintVersion);
tooling::CommonOptionsParser OP(argc, argv, ClangRenameCategory, RenameUsage);
// Check the arguments for correctness.
if (NewName.empty()) {
errs() << "clang-rename: no new name provided.\n\n";
cl::PrintHelpMessage();
exit(1);
}
// Get the USRs.
auto Files = OP.getSourcePathList();
tooling::RefactoringTool Tool(OP.getCompilations(), Files);
rename::USRFindingAction USRAction(SymbolOffset);
// Find the USRs.
Tool.run(tooling::newFrontendActionFactory(&USRAction).get());
const auto &USRs = USRAction.getUSRs();
const auto &PrevName = USRAction.getUSRSpelling();
if (PrevName.empty())
// An error should have already been printed.
exit(1);
if (PrintName)
errs() << "clang-rename: found name: " << PrevName;
// Perform the renaming.
rename::RenamingAction RenameAction(NewName, PrevName, USRs,
Tool.getReplacements(), PrintLocations);
auto Factory = tooling::newFrontendActionFactory(&RenameAction);
int res;
if (Inplace) {
res = Tool.runAndSave(Factory.get());
} else {
res = Tool.run(Factory.get());
// Write every file to stdout. Right now we just barf the files without any
// indication of which files start where, other than that we print the files
// in the same order we see them.
LangOptions DefaultLangOptions;
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts =
new DiagnosticOptions();
TextDiagnosticPrinter DiagnosticPrinter(errs(), &*DiagOpts);
DiagnosticsEngine Diagnostics(
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
&*DiagOpts, &DiagnosticPrinter, false);
auto &FileMgr = Tool.getFiles();
SourceManager Sources(Diagnostics, FileMgr);
Rewriter Rewrite(Sources, DefaultLangOptions);
Tool.applyAllReplacements(Rewrite);
for (const auto &File : Files) {
const auto *Entry = FileMgr.getFile(File);
auto ID = Sources.translateFile(Entry);
Rewrite.getEditBuffer(ID).write(outs());
}
}
exit(res);
}

View File

@@ -1,20 +0,0 @@
##===- tools/extra/clang-rename/Makefile -------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
CLANG_LEVEL := ../../..
TOOLNAME = clang-rename
include $(CLANG_LEVEL)/../../Makefile.config
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
USEDLIBS = clangFrontend.a clangSerialization.a clangDriver.a \
clangTooling.a clangParse.a clangSema.a clangIndex.a \
clangStaticAnalyzerFrontend.a clangStaticAnalyzerCheckers.a \
clangStaticAnalyzerCore.a clangAnalysis.a clangRewriteFrontend.a \
clangRewrite.a clangEdit.a clangAST.a clangLex.a clangBasic.a
include $(CLANG_LEVEL)/Makefile

View File

@@ -1,90 +0,0 @@
//===--- tools/extra/clang-rename/RenamingAction.cpp - Clang rename tool --===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Provides an action to rename every symbol at a point.
///
//===----------------------------------------------------------------------===//
#include "RenamingAction.h"
#include "USRLocFinder.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/Basic/FileManager.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/Lexer.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Refactoring.h"
#include "clang/Tooling/Tooling.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string>
#include <vector>
using namespace llvm;
namespace clang {
namespace rename {
class RenamingASTConsumer : public ASTConsumer {
public:
RenamingASTConsumer(const std::string &NewName,
const std::string &PrevName,
const std::vector<std::string> &USRs,
tooling::Replacements &Replaces,
bool PrintLocations)
: NewName(NewName), PrevName(PrevName), USRs(USRs), Replaces(Replaces),
PrintLocations(PrintLocations) {
}
void HandleTranslationUnit(ASTContext &Context) override {
const auto &SourceMgr = Context.getSourceManager();
std::vector<SourceLocation> RenamingCandidates;
std::vector<SourceLocation> NewCandidates;
for (const auto &USR : USRs) {
NewCandidates = getLocationsOfUSR(USR, Context.getTranslationUnitDecl());
RenamingCandidates.insert(RenamingCandidates.end(), NewCandidates.begin(),
NewCandidates.end());
NewCandidates.clear();
}
auto PrevNameLen = PrevName.length();
if (PrintLocations)
for (const auto &Loc : RenamingCandidates) {
FullSourceLoc FullLoc(Loc, SourceMgr);
errs() << "clang-rename: renamed at: " << SourceMgr.getFilename(Loc)
<< ":" << FullLoc.getSpellingLineNumber() << ":"
<< FullLoc.getSpellingColumnNumber() << "\n";
Replaces.insert(tooling::Replacement(SourceMgr, Loc, PrevNameLen,
NewName));
}
else
for (const auto &Loc : RenamingCandidates)
Replaces.insert(tooling::Replacement(SourceMgr, Loc, PrevNameLen,
NewName));
}
private:
const std::string &NewName, &PrevName;
const std::vector<std::string> &USRs;
tooling::Replacements &Replaces;
bool PrintLocations;
};
std::unique_ptr<ASTConsumer> RenamingAction::newASTConsumer() {
return llvm::make_unique<RenamingASTConsumer>(NewName, PrevName, USRs,
Replaces, PrintLocations);
}
}
}

View File

@@ -1,47 +0,0 @@
//===--- tools/extra/clang-rename/RenamingAction.h - Clang rename tool ----===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Provides an action to rename every symbol at a point.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_RENAMING_ACTION_H_
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_RENAMING_ACTION_H_
#include "clang/Tooling/Refactoring.h"
namespace clang {
class ASTConsumer;
class CompilerInstance;
namespace rename {
class RenamingAction {
public:
RenamingAction(const std::string &NewName, const std::string &PrevName,
const std::vector<std::string> &USRs,
tooling::Replacements &Replaces, bool PrintLocations = false)
: NewName(NewName), PrevName(PrevName), USRs(USRs), Replaces(Replaces),
PrintLocations(PrintLocations) {
}
std::unique_ptr<ASTConsumer> newASTConsumer();
private:
const std::string &NewName, &PrevName;
const std::vector<std::string> &USRs;
tooling::Replacements &Replaces;
bool PrintLocations;
};
}
}
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_RENAMING_ACTION_H_

View File

@@ -1,162 +0,0 @@
//===--- tools/extra/clang-rename/USRFinder.cpp - Clang rename tool -------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file Implements a recursive AST visitor that finds the USR of a symbol at a
/// point.
///
//===----------------------------------------------------------------------===//
#include "USRFinder.h"
#include "clang/AST/AST.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Lex/Lexer.h"
#include "clang/Index/USRGeneration.h"
#include "llvm/ADT/SmallVector.h"
using namespace llvm;
namespace clang {
namespace rename {
// NamedDeclFindingASTVisitor recursively visits each AST node to find the
// symbol underneath the cursor.
// FIXME: move to seperate .h/.cc file if this gets too large.
namespace {
class NamedDeclFindingASTVisitor
: public clang::RecursiveASTVisitor<NamedDeclFindingASTVisitor> {
public:
// \brief Finds the NamedDecl at a point in the source.
// \param Point the location in the source to search for the NamedDecl.
explicit NamedDeclFindingASTVisitor(const SourceManager &SourceMgr,
const SourceLocation Point)
: Result(nullptr), SourceMgr(SourceMgr),
Point(Point) {
}
// Declaration visitors:
// \brief Checks if the point falls within the NameDecl. This covers every
// declaration of a named entity that we may come across. Usually, just
// checking if the point lies within the length of the name of the declaration
// and the start location is sufficient.
bool VisitNamedDecl(const NamedDecl *Decl) {
return setResult(Decl, Decl->getLocation(),
Decl->getNameAsString().length());
}
// Expression visitors:
bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
// Check the namespace specifier first.
if (!checkNestedNameSpecifierLoc(Expr->getQualifierLoc()))
return false;
const auto *Decl = Expr->getFoundDecl();
return setResult(Decl, Expr->getLocation(),
Decl->getNameAsString().length());
}
bool VisitMemberExpr(const MemberExpr *Expr) {
const auto *Decl = Expr->getFoundDecl().getDecl();
return setResult(Decl, Expr->getMemberLoc(),
Decl->getNameAsString().length());
}
// Other:
const NamedDecl *getNamedDecl() {
return Result;
}
private:
// \brief Determines if a namespace qualifier contains the point.
// \returns false on success and sets Result.
bool checkNestedNameSpecifierLoc(NestedNameSpecifierLoc NameLoc) {
while (NameLoc) {
const auto *Decl = NameLoc.getNestedNameSpecifier()->getAsNamespace();
if (Decl && !setResult(Decl, NameLoc.getLocalBeginLoc(),
Decl->getNameAsString().length()))
return false;
NameLoc = NameLoc.getPrefix();
}
return true;
}
// \brief Sets Result to Decl if the Point is within Start and End.
// \returns false on success.
bool setResult(const NamedDecl *Decl, SourceLocation Start,
SourceLocation End) {
if (!Start.isValid() || !Start.isFileID() || !End.isValid() ||
!End.isFileID() || !isPointWithin(Start, End)) {
return true;
}
Result = Decl;
return false;
}
// \brief Sets Result to Decl if Point is within Loc and Loc + Offset.
// \returns false on success.
bool setResult(const NamedDecl *Decl, SourceLocation Loc,
unsigned Offset) {
// FIXME: Add test for Offset == 0. Add test for Offset - 1 (vs -2 etc).
return Offset == 0 ||
setResult(Decl, Loc, Loc.getLocWithOffset(Offset - 1));
}
// \brief Determines if the Point is within Start and End.
bool isPointWithin(const SourceLocation Start, const SourceLocation End) {
// FIXME: Add tests for Point == End.
return Point == Start || Point == End ||
(SourceMgr.isBeforeInTranslationUnit(Start, Point) &&
SourceMgr.isBeforeInTranslationUnit(Point, End));
}
const NamedDecl *Result;
const SourceManager &SourceMgr;
const SourceLocation Point; // The location to find the NamedDecl.
};
}
const NamedDecl *getNamedDeclAt(const ASTContext &Context,
const SourceLocation Point) {
const auto &SourceMgr = Context.getSourceManager();
const auto SearchFile = SourceMgr.getFilename(Point);
NamedDeclFindingASTVisitor Visitor(SourceMgr, Point);
// We only want to search the decls that exist in the same file as the point.
auto Decls = Context.getTranslationUnitDecl()->decls();
for (auto &CurrDecl : Decls) {
const auto FileLoc = CurrDecl->getLocStart();
const auto FileName = SourceMgr.getFilename(FileLoc);
// FIXME: Add test.
if (FileName == SearchFile) {
Visitor.TraverseDecl(CurrDecl);
if (const NamedDecl *Result = Visitor.getNamedDecl()) {
return Result;
}
}
}
return nullptr;
}
std::string getUSRForDecl(const Decl *Decl) {
llvm::SmallVector<char, 128> Buff;
// FIXME: Add test for the nullptr case.
if (Decl == nullptr || index::generateUSRForDecl(Decl, Buff))
return "";
return std::string(Buff.data(), Buff.size());
}
} // namespace clang
} // namespace rename

View File

@@ -1,39 +0,0 @@
//===--- tools/extra/clang-rename/USRFinder.h - Clang rename tool ---------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Methods for determining the USR of a symbol at a location in source
/// code.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDER_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDER_H
#include <string>
namespace clang {
class ASTContext;
class Decl;
class SourceLocation;
class NamedDecl;
namespace rename {
// Given an AST context and a point, returns a NamedDecl identifying the symbol
// at the point. Returns null if nothing is found at the point.
const NamedDecl *getNamedDeclAt(const ASTContext &Context,
const SourceLocation Point);
// Converts a Decl into a USR.
std::string getUSRForDecl(const Decl *Decl);
}
}
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDER_H

View File

@@ -1,118 +0,0 @@
//===--- tools/extra/clang-rename/USRFindingAction.cpp - Clang rename tool ===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Provides an action to rename every symbol at a point.
///
//===----------------------------------------------------------------------===//
#include "USRFindingAction.h"
#include "USRFinder.h"
#include "clang/AST/AST.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/Basic/FileManager.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/Lexer.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Refactoring.h"
#include "clang/Tooling/Tooling.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string>
#include <vector>
using namespace llvm;
namespace clang {
namespace rename {
// Get the USRs for the constructors of the class.
static std::vector<std::string> getAllConstructorUSRs(
const CXXRecordDecl *Decl) {
std::vector<std::string> USRs;
// We need to get the definition of the record (as opposed to any forward
// declarations) in order to find the constructor and destructor.
const auto *RecordDecl = Decl->getDefinition();
// Iterate over all the constructors and add their USRs.
for (const auto &CtorDecl : RecordDecl->ctors())
USRs.push_back(getUSRForDecl(CtorDecl));
// Ignore destructors. GetLocationsOfUSR will find the declaration of and
// explicit calls to a destructor through TagTypeLoc (and it is better for the
// purpose of renaming).
//
// For example, in the following code segment,
// 1 class C {
// 2 ~C();
// 3 };
// At line 3, there is a NamedDecl starting from '~' and a TagTypeLoc starting
// from 'C'.
return USRs;
}
struct NamedDeclFindingConsumer : public ASTConsumer {
void HandleTranslationUnit(ASTContext &Context) override {
const auto &SourceMgr = Context.getSourceManager();
// The file we look for the USR in will always be the main source file.
const auto Point = SourceMgr.getLocForStartOfFile(
SourceMgr.getMainFileID()).getLocWithOffset(SymbolOffset);
if (!Point.isValid())
return;
const NamedDecl *FoundDecl = getNamedDeclAt(Context, Point);
if (FoundDecl == nullptr) {
FullSourceLoc FullLoc(Point, SourceMgr);
errs() << "clang-rename: could not find symbol at "
<< SourceMgr.getFilename(Point) << ":"
<< FullLoc.getSpellingLineNumber() << ":"
<< FullLoc.getSpellingColumnNumber() << " (offset " << SymbolOffset
<< ").\n";
return;
}
// If the decl is a constructor or destructor, we want to instead take the
// decl of the parent record.
if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(FoundDecl))
FoundDecl = CtorDecl->getParent();
else if (const auto *DtorDecl = dyn_cast<CXXDestructorDecl>(FoundDecl))
FoundDecl = DtorDecl->getParent();
// If the decl is in any way relatedpp to a class, we want to make sure we
// search for the constructor and destructor as well as everything else.
if (const auto *Record = dyn_cast<CXXRecordDecl>(FoundDecl))
*USRs = getAllConstructorUSRs(Record);
USRs->push_back(getUSRForDecl(FoundDecl));
*SpellingName = FoundDecl->getNameAsString();
}
unsigned SymbolOffset;
std::string *SpellingName;
std::vector<std::string> *USRs;
};
std::unique_ptr<ASTConsumer>
USRFindingAction::newASTConsumer() {
std::unique_ptr<NamedDeclFindingConsumer> Consumer(
new NamedDeclFindingConsumer);
SpellingName = "";
Consumer->SymbolOffset = SymbolOffset;
Consumer->USRs = &USRs;
Consumer->SpellingName = &SpellingName;
return std::move(Consumer);
}
} // namespace rename
} // namespace clang

View File

@@ -1,50 +0,0 @@
//===--- tools/extra/clang-rename/USRFindingAction.h - Clang rename tool --===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Provides an action to find all relevent USRs at a point.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDING_ACTION_H_
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDING_ACTION_H_
#include "clang/Frontend/FrontendAction.h"
namespace clang {
class ASTConsumer;
class CompilerInstance;
class NamedDecl;
namespace rename {
struct USRFindingAction {
USRFindingAction(unsigned Offset) : SymbolOffset(Offset) {
}
std::unique_ptr<ASTConsumer> newASTConsumer();
// \brief get the spelling of the USR(s) as it would appear in source files.
const std::string &getUSRSpelling() {
return SpellingName;
}
const std::vector<std::string> &getUSRs() {
return USRs;
}
private:
unsigned SymbolOffset;
std::string SpellingName;
std::vector<std::string> USRs;
};
}
}
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDING_ACTION_H_

View File

@@ -1,103 +0,0 @@
//===--- tools/extra/clang-rename/USRLocFinder.cpp - Clang rename tool ----===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Mehtods for finding all instances of a USR. Our strategy is very
/// simple; we just compare the USR at every relevant AST node with the one
/// provided.
///
//===----------------------------------------------------------------------===//
#include "USRLocFinder.h"
#include "USRFinder.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Index/USRGeneration.h"
#include "llvm/ADT/SmallVector.h"
using namespace llvm;
namespace clang {
namespace rename {
namespace {
// \brief This visitor recursively searches for all instances of a USR in a
// translation unit and stores them for later usage.
class USRLocFindingASTVisitor
: public clang::RecursiveASTVisitor<USRLocFindingASTVisitor> {
public:
explicit USRLocFindingASTVisitor(const std::string USR) : USR(USR) {
}
// Declaration visitors:
bool VisitNamedDecl(const NamedDecl *Decl) {
if (getUSRForDecl(Decl) == USR) {
LocationsFound.push_back(Decl->getLocation());
}
return true;
}
// Expression visitors:
bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
const auto *Decl = Expr->getFoundDecl();
checkNestedNameSpecifierLoc(Expr->getQualifierLoc());
if (getUSRForDecl(Decl) == USR) {
LocationsFound.push_back(Expr->getLocation());
}
return true;
}
bool VisitMemberExpr(const MemberExpr *Expr) {
const auto *Decl = Expr->getFoundDecl().getDecl();
if (getUSRForDecl(Decl) == USR) {
LocationsFound.push_back(Expr->getMemberLoc());
}
return true;
}
// Non-visitors:
// \brief Returns a list of unique locations. Duplicate or overlapping
// locations are erroneous and should be reported!
const std::vector<clang::SourceLocation> &getLocationsFound() const {
return LocationsFound;
}
private:
// Namespace traversal:
void checkNestedNameSpecifierLoc(NestedNameSpecifierLoc NameLoc) {
while (NameLoc) {
const auto *Decl = NameLoc.getNestedNameSpecifier()->getAsNamespace();
if (Decl && getUSRForDecl(Decl) == USR)
LocationsFound.push_back(NameLoc.getLocalBeginLoc());
NameLoc = NameLoc.getPrefix();
}
}
// All the locations of the USR were found.
const std::string USR;
std::vector<clang::SourceLocation> LocationsFound;
};
} // namespace
std::vector<SourceLocation> getLocationsOfUSR(const std::string USR,
Decl *Decl) {
USRLocFindingASTVisitor visitor(USR);
visitor.TraverseDecl(Decl);
return visitor.getLocationsFound();
}
} // namespace rename
} // namespace clang

View File

@@ -1,35 +0,0 @@
//===--- tools/extra/clang-rename/USRLocFinder.h - Clang rename tool ------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Provides functionality for finding all instances of a USR in a given
/// AST.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_LOC_FINDER_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_LOC_FINDER_H
#include <string>
#include <vector>
namespace clang {
class Decl;
class SourceLocation;
namespace rename {
// FIXME: make this an AST matcher. Wouldn't that be awesome??? I agree!
std::vector<SourceLocation> getLocationsOfUSR(const std::string usr,
Decl *decl);
}
}
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_LOC_FINDER_H

View File

@@ -27,4 +27,3 @@ add_subdirectory(tool)
add_subdirectory(llvm)
add_subdirectory(google)
add_subdirectory(misc)
add_subdirectory(utils)

View File

@@ -179,10 +179,10 @@ private:
class ClangTidyASTConsumer : public MultiplexConsumer {
public:
ClangTidyASTConsumer(std::vector<std::unique_ptr<ASTConsumer>> Consumers,
ClangTidyASTConsumer(const SmallVectorImpl<ASTConsumer *> &Consumers,
std::unique_ptr<ast_matchers::MatchFinder> Finder,
std::vector<std::unique_ptr<ClangTidyCheck>> Checks)
: MultiplexConsumer(std::move(Consumers)), Finder(std::move(Finder)),
: MultiplexConsumer(Consumers), Finder(std::move(Finder)),
Checks(std::move(Checks)) {}
private:
@@ -203,8 +203,8 @@ ClangTidyASTConsumerFactory::ClangTidyASTConsumerFactory(
}
}
std::unique_ptr<clang::ASTConsumer>
ClangTidyASTConsumerFactory::CreateASTConsumer(
clang::ASTConsumer *ClangTidyASTConsumerFactory::CreateASTConsumer(
clang::CompilerInstance &Compiler, StringRef File) {
// FIXME: Move this to a separate method, so that CreateASTConsumer doesn't
// modify Compiler.
@@ -213,7 +213,7 @@ ClangTidyASTConsumerFactory::CreateASTConsumer(
Context.setASTContext(&Compiler.getASTContext());
std::vector<std::unique_ptr<ClangTidyCheck>> Checks;
GlobList &Filter = Context.getChecksFilter();
ChecksFilter &Filter = Context.getChecksFilter();
CheckFactories->createChecks(Filter, Checks);
std::unique_ptr<ast_matchers::MatchFinder> Finder(
@@ -224,7 +224,7 @@ ClangTidyASTConsumerFactory::CreateASTConsumer(
Check->registerPPCallbacks(Compiler);
}
std::vector<std::unique_ptr<ASTConsumer>> Consumers;
SmallVector<ASTConsumer *, 2> Consumers;
if (!Checks.empty())
Consumers.push_back(Finder->newASTConsumer());
@@ -240,23 +240,22 @@ ClangTidyASTConsumerFactory::CreateASTConsumer(
AnalyzerOptions->AnalysisDiagOpt = PD_NONE;
AnalyzerOptions->AnalyzeNestedBlocks = true;
AnalyzerOptions->eagerlyAssumeBinOpBifurcation = true;
std::unique_ptr<ento::AnalysisASTConsumer> AnalysisConsumer =
ento::CreateAnalysisConsumer(
Compiler.getPreprocessor(), Compiler.getFrontendOpts().OutputFile,
AnalyzerOptions, Compiler.getFrontendOpts().Plugins);
ento::AnalysisASTConsumer *AnalysisConsumer = ento::CreateAnalysisConsumer(
Compiler.getPreprocessor(), Compiler.getFrontendOpts().OutputFile,
AnalyzerOptions, Compiler.getFrontendOpts().Plugins);
AnalysisConsumer->AddDiagnosticConsumer(
new AnalyzerDiagnosticConsumer(Context));
Consumers.push_back(std::move(AnalysisConsumer));
Consumers.push_back(AnalysisConsumer);
}
return llvm::make_unique<ClangTidyASTConsumer>(
std::move(Consumers), std::move(Finder), std::move(Checks));
return new ClangTidyASTConsumer(Consumers, std::move(Finder),
std::move(Checks));
}
std::vector<std::string>
ClangTidyASTConsumerFactory::getCheckNames(GlobList &Filter) {
ClangTidyASTConsumerFactory::getCheckNames(ChecksFilter &Filter) {
std::vector<std::string> CheckNames;
for (const auto &CheckFactory : *CheckFactories) {
if (Filter.contains(CheckFactory.first))
if (Filter.isCheckEnabled(CheckFactory.first))
CheckNames.push_back(CheckFactory.first);
}
@@ -268,7 +267,7 @@ ClangTidyASTConsumerFactory::getCheckNames(GlobList &Filter) {
}
ClangTidyASTConsumerFactory::CheckersList
ClangTidyASTConsumerFactory::getCheckersControlList(GlobList &Filter) {
ClangTidyASTConsumerFactory::getCheckersControlList(ChecksFilter &Filter) {
CheckersList List;
bool AnalyzerChecksEnabled = false;
@@ -276,7 +275,7 @@ ClangTidyASTConsumerFactory::getCheckersControlList(GlobList &Filter) {
std::string Checker((AnalyzerCheckNamePrefix + CheckName).str());
AnalyzerChecksEnabled =
AnalyzerChecksEnabled ||
(!CheckName.startswith("debug") && Filter.contains(Checker));
(!CheckName.startswith("debug") && Filter.isCheckEnabled(Checker));
}
if (AnalyzerChecksEnabled) {
@@ -291,7 +290,7 @@ ClangTidyASTConsumerFactory::getCheckersControlList(GlobList &Filter) {
std::string Checker((AnalyzerCheckNamePrefix + CheckName).str());
if (CheckName.startswith("core") ||
(!CheckName.startswith("debug") && Filter.contains(Checker)))
(!CheckName.startswith("debug") && Filter.isCheckEnabled(Checker)))
List.push_back(std::make_pair(CheckName, true));
}
}
@@ -332,15 +331,16 @@ ClangTidyStats runClangTidy(ClangTidyOptionsProvider *OptionsProvider,
class ActionFactory : public FrontendActionFactory {
public:
ActionFactory(ClangTidyContext &Context) : ConsumerFactory(Context) {}
FrontendAction *create() override { return new Action(&ConsumerFactory); }
ActionFactory(ClangTidyASTConsumerFactory *ConsumerFactory)
: ConsumerFactory(ConsumerFactory) {}
FrontendAction *create() override { return new Action(ConsumerFactory); }
private:
class Action : public ASTFrontendAction {
public:
Action(ClangTidyASTConsumerFactory *Factory) : Factory(Factory) {}
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,
StringRef File) override {
ASTConsumer *CreateASTConsumer(CompilerInstance &Compiler,
StringRef File) override {
return Factory->CreateASTConsumer(Compiler, File);
}
@@ -348,11 +348,10 @@ ClangTidyStats runClangTidy(ClangTidyOptionsProvider *OptionsProvider,
ClangTidyASTConsumerFactory *Factory;
};
ClangTidyASTConsumerFactory ConsumerFactory;
ClangTidyASTConsumerFactory *ConsumerFactory;
};
ActionFactory Factory(Context);
Tool.run(&Factory);
Tool.run(new ActionFactory(new ClangTidyASTConsumerFactory(Context)));
*Errors = Context.getErrors();
return Context.getStats();
}

View File

@@ -99,15 +99,15 @@ public:
ClangTidyASTConsumerFactory(ClangTidyContext &Context);
/// \brief Returns an ASTConsumer that runs the specified clang-tidy checks.
std::unique_ptr<clang::ASTConsumer>
CreateASTConsumer(clang::CompilerInstance &Compiler, StringRef File);
clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &Compiler,
StringRef File);
/// \brief Get the list of enabled checks.
std::vector<std::string> getCheckNames(GlobList &Filter);
std::vector<std::string> getCheckNames(ChecksFilter &Filter);
private:
typedef std::vector<std::pair<std::string, bool> > CheckersList;
CheckersList getCheckersControlList(GlobList &Filter);
CheckersList getCheckersControlList(ChecksFilter &Filter);
ClangTidyContext &Context;
std::unique_ptr<ClangTidyCheckFactories> CheckFactories;

View File

@@ -146,18 +146,18 @@ static llvm::Regex ConsumeGlob(StringRef &GlobList) {
return llvm::Regex(RegexText);
}
GlobList::GlobList(StringRef Globs)
: Positive(!ConsumeNegativeIndicator(Globs)),
Regex(ConsumeGlob(Globs)),
NextGlob(Globs.empty() ? nullptr : new GlobList(Globs)) {}
ChecksFilter::ChecksFilter(StringRef GlobList)
: Positive(!ConsumeNegativeIndicator(GlobList)),
Regex(ConsumeGlob(GlobList)),
NextFilter(GlobList.empty() ? nullptr : new ChecksFilter(GlobList)) {}
bool GlobList::contains(StringRef S, bool Contains) {
if (Regex.match(S))
Contains = Positive;
bool ChecksFilter::isCheckEnabled(StringRef Name, bool Enabled) {
if (Regex.match(Name))
Enabled = Positive;
if (NextGlob)
Contains = NextGlob->contains(S, Contains);
return Contains;
if (NextFilter)
Enabled = NextFilter->isCheckEnabled(Name, Enabled);
return Enabled;
}
ClangTidyContext::ClangTidyContext(ClangTidyOptionsProvider *OptionsProvider)
@@ -202,7 +202,7 @@ void ClangTidyContext::setSourceManager(SourceManager *SourceMgr) {
void ClangTidyContext::setCurrentFile(StringRef File) {
CurrentFile = File;
CheckFilter.reset(new GlobList(getOptions().Checks));
CheckFilter.reset(new ChecksFilter(getOptions().Checks));
}
void ClangTidyContext::setASTContext(ASTContext *Context) {
@@ -217,7 +217,7 @@ const ClangTidyOptions &ClangTidyContext::getOptions() const {
return OptionsProvider->getOptions(CurrentFile);
}
GlobList &ClangTidyContext::getChecksFilter() {
ChecksFilter &ClangTidyContext::getChecksFilter() {
assert(CheckFilter != nullptr);
return *CheckFilter;
}
@@ -248,7 +248,7 @@ ClangTidyDiagnosticConsumer::ClangTidyDiagnosticConsumer(ClangTidyContext &Ctx)
void ClangTidyDiagnosticConsumer::finalizeLastError() {
if (!Errors.empty()) {
ClangTidyError &Error = Errors.back();
if (!Context.getChecksFilter().contains(Error.CheckName) &&
if (!Context.getChecksFilter().isCheckEnabled(Error.CheckName) &&
Error.DiagLevel != ClangTidyError::Error) {
++Context.Stats.ErrorsIgnoredCheckFilter;
Errors.pop_back();

View File

@@ -65,25 +65,24 @@ struct ClangTidyError {
Level DiagLevel;
};
/// \brief Read-only set of strings represented as a list of positive and
/// negative globs. Positive globs add all matched strings to the set, negative
/// globs remove them in the order of appearance in the list.
class GlobList {
/// \brief Filters checks by name.
class ChecksFilter {
public:
/// \brief \p GlobList is a comma-separated list of globs (only '*'
/// metacharacter is supported) with optional '-' prefix to denote exclusion.
GlobList(StringRef Globs);
ChecksFilter(StringRef GlobList);
/// \brief Returns \c true if the pattern matches \p S. The result is the last
/// matching glob's Positive flag.
bool contains(StringRef S) { return contains(S, false); }
/// \brief Returns \c true if the check with the specified \p Name should be
/// enabled. The result is the last matching glob's Positive flag. If \p Name
/// is not matched by any globs, the check is not enabled.
bool isCheckEnabled(StringRef Name) { return isCheckEnabled(Name, false); }
private:
bool contains(StringRef S, bool Contains);
bool isCheckEnabled(StringRef Name, bool Enabled);
bool Positive;
llvm::Regex Regex;
std::unique_ptr<GlobList> NextGlob;
std::unique_ptr<ChecksFilter> NextFilter;
};
/// \brief Contains displayed and ignored diagnostic counters for a ClangTidy
@@ -146,7 +145,7 @@ public:
StringRef getCheckName(unsigned DiagnosticID) const;
/// \brief Returns check filter for the \c CurrentFile.
GlobList &getChecksFilter();
ChecksFilter &getChecksFilter();
/// \brief Returns global options.
const ClangTidyGlobalOptions &getGlobalOptions() const;
@@ -180,7 +179,7 @@ private:
std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider;
std::string CurrentFile;
std::unique_ptr<GlobList> CheckFilter;
std::unique_ptr<ChecksFilter> CheckFilter;
ClangTidyStats Stats;

View File

@@ -27,9 +27,10 @@ void ClangTidyCheckFactories::addCheckFactory(StringRef Name,
}
void ClangTidyCheckFactories::createChecks(
GlobList &Filter, std::vector<std::unique_ptr<ClangTidyCheck>> &Checks) {
ChecksFilter &Filter,
std::vector<std::unique_ptr<ClangTidyCheck>> &Checks) {
for (const auto &Factory : Factories) {
if (Filter.contains(Factory.first)) {
if (Filter.isCheckEnabled(Factory.first)) {
ClangTidyCheck *Check = Factory.second->createCheck();
Check->setName(Factory.first);
Checks.emplace_back(Check);

View File

@@ -86,7 +86,7 @@ public:
/// store them in \p Checks.
///
/// The caller takes ownership of the return \c ClangTidyChecks.
void createChecks(GlobList &Filter,
void createChecks(ChecksFilter &Filter,
std::vector<std::unique_ptr<ClangTidyCheck>> &Checks);
typedef std::map<std::string, CheckFactoryBase *> FactoryMap;

View File

@@ -11,6 +11,6 @@ CLANG_LEVEL := ../../..
LIBRARYNAME := clangTidy
include $(CLANG_LEVEL)/../../Makefile.config
DIRS = utils llvm google misc tool
DIRS = llvm google misc tool
include $(CLANG_LEVEL)/Makefile

View File

@@ -60,12 +60,6 @@ bool pointedTypesAreEqual(QualType SourceType, QualType DestType) {
void AvoidCStyleCastsCheck::check(const MatchFinder::MatchResult &Result) {
const auto *CastExpr = Result.Nodes.getNodeAs<CStyleCastExpr>("cast");
auto ParenRange = CharSourceRange::getTokenRange(CastExpr->getLParenLoc(),
CastExpr->getRParenLoc());
// Ignore casts in macros.
if (ParenRange.getBegin().isMacroID() || ParenRange.getEnd().isMacroID())
return;
// Casting to void is an idiomatic way to mute "unused variable" and similar
// warnings.
if (CastExpr->getTypeAsWritten()->isVoidType())
@@ -75,6 +69,8 @@ void AvoidCStyleCastsCheck::check(const MatchFinder::MatchResult &Result) {
CastExpr->getSubExprAsWritten()->getType().getCanonicalType();
QualType DestType = CastExpr->getTypeAsWritten().getCanonicalType();
auto ParenRange = CharSourceRange::getTokenRange(CastExpr->getLParenLoc(),
CastExpr->getRParenLoc());
if (SourceType == DestType) {
diag(CastExpr->getLocStart(), "Redundant cast to the same type.")
<< FixItHint::CreateRemoval(ParenRange);
@@ -88,6 +84,8 @@ void AvoidCStyleCastsCheck::check(const MatchFinder::MatchResult &Result) {
auto ReplaceWithCast = [&](StringRef CastType) {
diag_builder << ("Use " + CastType + ".").str();
if (ParenRange.getBegin().isMacroID() || ParenRange.getEnd().isMacroID())
return;
const Expr *SubExpr = CastExpr->getSubExprAsWritten()->IgnoreImpCasts();
std::string CastText = (CastType + "<" + DestTypeString + ">").str();

View File

@@ -20,6 +20,15 @@ namespace ast_matchers {
AST_MATCHER(DeclRefExpr, hasExplicitTemplateArgs) {
return Node.hasExplicitTemplateArgs();
}
// FIXME: This should just be callee(ignoringImpCasts()) but it's not overloaded
// for Expr.
AST_MATCHER_P(CallExpr, calleeIgnoringParenImpCasts, internal::Matcher<Stmt>,
InnerMatcher) {
const Expr *ExprNode = Node.getCallee();
return (ExprNode != nullptr &&
InnerMatcher.matches(*ExprNode->IgnoreParenImpCasts(), Finder, Builder));
}
} // namespace ast_matchers
namespace tidy {
@@ -33,10 +42,10 @@ ExplicitMakePairCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
callExpr(unless(hasAncestor(decl(anyOf(
recordDecl(ast_matchers::isTemplateInstantiation()),
functionDecl(ast_matchers::isTemplateInstantiation()))))),
callee(expr(ignoringParenImpCasts(
calleeIgnoringParenImpCasts(
declRefExpr(hasExplicitTemplateArgs(),
to(functionDecl(hasName("::std::make_pair"))))
.bind("declref"))))).bind("call"),
.bind("declref"))).bind("call"),
this);
}

View File

@@ -37,14 +37,6 @@ void NamedParameterCheck::check(const MatchFinder::MatchResult &Result) {
if (Function->isImplicit())
return;
// Ignore declarations without a definition if we're not dealing with an
// overriden method.
const FunctionDecl *Definition = nullptr;
if (!Function->isDefined(Definition) &&
(!isa<CXXMethodDecl>(Function) ||
cast<CXXMethodDecl>(Function)->size_overridden_methods() == 0))
return;
// TODO: Handle overloads.
// TODO: We could check that all redeclarations use the same name for
// arguments in the same position.
@@ -78,34 +70,25 @@ void NamedParameterCheck::check(const MatchFinder::MatchResult &Result) {
"all parameters should be named in a function");
for (auto P : UnnamedParams) {
// Fallback to an unused marker.
StringRef NewName = "unused";
// If the method is overridden, try to copy the name from the base method
// into the overrider.
const ParmVarDecl *Parm = P.first->getParamDecl(P.second);
const auto *M = dyn_cast<CXXMethodDecl>(P.first);
if (M && M->size_overridden_methods() > 0) {
const ParmVarDecl *OtherParm =
(*M->begin_overridden_methods())->getParamDecl(P.second);
StringRef Name = OtherParm->getName();
if (!Name.empty())
NewName = Name;
std::string Name = OtherParm->getNameAsString();
if (!Name.empty()) {
D << FixItHint::CreateInsertion(Parm->getLocation(),
" /*" + Name + "*/");
continue;
}
}
// If the definition has a named parameter use that name.
if (Definition) {
const ParmVarDecl *DefParm = Definition->getParamDecl(P.second);
StringRef Name = DefParm->getName();
if (!Name.empty())
NewName = Name;
}
// Now insert the comment. Note that getLocation() points to the place
// where the name would be, this allows us to also get complex cases like
// function pointers right.
const ParmVarDecl *Parm = P.first->getParamDecl(P.second);
D << FixItHint::CreateInsertion(Parm->getLocation(),
" /*" + NewName.str() + "*/");
// Otherwise just insert an unused marker. Note that getLocation() points
// to the place where the name would be, this allows us to also get
// complex cases like function pointers right.
D << FixItHint::CreateInsertion(Parm->getLocation(), " /*unused*/");
}
}
}

View File

@@ -1,7 +1,6 @@
set(LLVM_LINK_COMPONENTS support)
add_clang_library(clangTidyLLVMModule
HeaderGuardCheck.cpp
IncludeOrderCheck.cpp
LLVMTidyModule.cpp
NamespaceCommentCheck.cpp
@@ -13,6 +12,4 @@ add_clang_library(clangTidyLLVMModule
clangBasic
clangLex
clangTidy
clangTidyUtils
clangTooling
)

View File

@@ -1,53 +0,0 @@
//===--- HeaderGuardCheck.cpp - clang-tidy --------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "HeaderGuardCheck.h"
namespace clang {
namespace tidy {
bool LLVMHeaderGuardCheck::shouldFixHeaderGuard(StringRef Filename) {
return Filename.endswith(".h");
}
std::string LLVMHeaderGuardCheck::getHeaderGuard(StringRef Filename,
StringRef OldGuard) {
std::string Guard = tooling::getAbsolutePath(Filename);
// Sanitize the path. There are some rules for compatibility with the historic
// style in include/llvm and include/clang which we want to preserve.
// We don't want _INCLUDE_ in our guards.
size_t PosInclude = Guard.rfind("include/");
if (PosInclude != StringRef::npos)
Guard = Guard.substr(PosInclude + std::strlen("include/"));
// For clang we drop the _TOOLS_.
size_t PosToolsClang = Guard.rfind("tools/clang/");
if (PosToolsClang != StringRef::npos)
Guard = Guard.substr(PosToolsClang + std::strlen("tools/"));
// The remainder is LLVM_FULL_PATH_TO_HEADER_H
size_t PosLLVM = Guard.rfind("llvm/");
if (PosLLVM != StringRef::npos)
Guard = Guard.substr(PosLLVM);
std::replace(Guard.begin(), Guard.end(), '/', '_');
std::replace(Guard.begin(), Guard.end(), '.', '_');
std::replace(Guard.begin(), Guard.end(), '-', '_');
// The prevalent style in clang is LLVM_CLANG_FOO_BAR_H
if (StringRef(Guard).startswith("clang"))
Guard = "LLVM_" + Guard;
return StringRef(Guard).upper();
}
} // namespace tidy
} // namespace clang

View File

@@ -1,29 +0,0 @@
//===--- HeaderGuardCheck.h - clang-tidy ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_HEADER_GUARD_CHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_HEADER_GUARD_CHECK_H
#include "../utils/HeaderGuard.h"
namespace clang {
namespace tidy {
/// Finds and fixes header guards that do not adhere to LLVM style.
class LLVMHeaderGuardCheck : public HeaderGuardCheck {
public:
bool shouldSuggestEndifComment(StringRef Filename) override { return false; }
bool shouldFixHeaderGuard(StringRef Filename) override;
std::string getHeaderGuard(StringRef Filename, StringRef OldGuard) override;
};
} // namespace tidy
} // namespace clang
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_HEADER_GUARD_CHECK_H

View File

@@ -18,148 +18,26 @@ namespace tidy {
namespace {
class IncludeOrderPPCallbacks : public PPCallbacks {
public:
explicit IncludeOrderPPCallbacks(ClangTidyCheck &Check, SourceManager &SM)
: LookForMainModule(true), Check(Check), SM(SM) {}
explicit IncludeOrderPPCallbacks(IncludeOrderCheck &Check) : Check(Check) {}
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
StringRef FileName, bool IsAngled,
CharSourceRange FilenameRange, const FileEntry *File,
StringRef SearchPath, StringRef RelativePath,
const Module *Imported) override;
void EndOfMainFile() override;
const Module *Imported) override {
// FIXME: This is a dummy implementation to show how to get at preprocessor
// information. Implement a real include order check.
Check.diag(HashLoc, "This is an include");
}
private:
struct IncludeDirective {
SourceLocation Loc; ///< '#' location in the include directive
CharSourceRange Range; ///< SourceRange for the file name
StringRef Filename; ///< Filename as a string
bool IsAngled; ///< true if this was an include with angle brackets
bool IsMainModule; ///< true if this was the first include in a file
};
std::vector<IncludeDirective> IncludeDirectives;
bool LookForMainModule;
ClangTidyCheck &Check;
SourceManager &SM;
IncludeOrderCheck &Check;
};
} // namespace
void IncludeOrderCheck::registerPPCallbacks(CompilerInstance &Compiler) {
Compiler.getPreprocessor().addPPCallbacks(
new IncludeOrderPPCallbacks(*this, Compiler.getSourceManager()));
}
static int getPriority(StringRef Filename, bool IsAngled, bool IsMainModule) {
// We leave the main module header at the top.
if (IsMainModule)
return 0;
// LLVM and clang headers are in the penultimate position.
if (Filename.startswith("llvm/") || Filename.startswith("llvm-c/") ||
Filename.startswith("clang/") || Filename.startswith("clang-c/"))
return 2;
// System headers are sorted to the end.
if (IsAngled || Filename.startswith("gtest/"))
return 3;
// Other headers are inserted between the main module header and LLVM headers.
return 1;
}
void IncludeOrderPPCallbacks::InclusionDirective(
SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File,
StringRef SearchPath, StringRef RelativePath, const Module *Imported) {
// We recognize the first include as a special main module header and want
// to leave it in the top position.
IncludeDirective ID = {HashLoc, FilenameRange, FileName, IsAngled, false};
if (LookForMainModule && !IsAngled) {
ID.IsMainModule = true;
LookForMainModule = false;
}
IncludeDirectives.push_back(std::move(ID));
}
void IncludeOrderPPCallbacks::EndOfMainFile() {
LookForMainModule = true;
if (IncludeDirectives.empty())
return;
// TODO: find duplicated includes.
// Form blocks of includes. We don't want to sort across blocks. This also
// implicitly makes us never reorder over #defines or #if directives.
// FIXME: We should be more careful about sorting below comments as we don't
// know if the comment refers to the next include or the whole block that
// follows.
std::vector<unsigned> Blocks(1, 0);
for (unsigned I = 1, E = IncludeDirectives.size(); I != E; ++I)
if (SM.getExpansionLineNumber(IncludeDirectives[I].Loc) !=
SM.getExpansionLineNumber(IncludeDirectives[I - 1].Loc) + 1)
Blocks.push_back(I);
Blocks.push_back(IncludeDirectives.size()); // Sentinel value.
// Get a vector of indices.
std::vector<unsigned> IncludeIndices;
for (unsigned I = 0, E = IncludeDirectives.size(); I != E; ++I)
IncludeIndices.push_back(I);
// Sort the includes. We first sort by priority, then lexicographically.
for (unsigned BI = 0, BE = Blocks.size() - 1; BI != BE; ++BI)
std::sort(IncludeIndices.begin() + Blocks[BI],
IncludeIndices.begin() + Blocks[BI + 1],
[this](unsigned LHSI, unsigned RHSI) {
IncludeDirective &LHS = IncludeDirectives[LHSI];
IncludeDirective &RHS = IncludeDirectives[RHSI];
int PriorityLHS =
getPriority(LHS.Filename, LHS.IsAngled, LHS.IsMainModule);
int PriorityRHS =
getPriority(RHS.Filename, RHS.IsAngled, RHS.IsMainModule);
return std::tie(PriorityLHS, LHS.Filename) <
std::tie(PriorityRHS, RHS.Filename);
});
// Emit a warning for each block and fixits for all changes within that block.
for (unsigned BI = 0, BE = Blocks.size() - 1; BI != BE; ++BI) {
// Find the first include that's not in the right position.
unsigned I, E;
for (I = Blocks[BI], E = Blocks[BI + 1]; I != E; ++I)
if (IncludeIndices[I] != I)
break;
if (I == E)
continue;
// Emit a warning.
auto D = Check.diag(IncludeDirectives[I].Loc,
"#includes are not sorted properly");
// Emit fix-its for all following includes in this block.
for (; I != E; ++I) {
if (IncludeIndices[I] == I)
continue;
const IncludeDirective &CopyFrom = IncludeDirectives[IncludeIndices[I]];
SourceLocation FromLoc = CopyFrom.Range.getBegin();
const char *FromData = SM.getCharacterData(FromLoc);
unsigned FromLen = std::strcspn(FromData, "\n");
StringRef FixedName(FromData, FromLen);
SourceLocation ToLoc = IncludeDirectives[I].Range.getBegin();
const char *ToData = SM.getCharacterData(ToLoc);
unsigned ToLen = std::strcspn(ToData, "\n");
auto ToRange =
CharSourceRange::getCharRange(ToLoc, ToLoc.getLocWithOffset(ToLen));
D << FixItHint::CreateReplacement(ToRange, FixedName);
}
}
IncludeDirectives.clear();
Compiler.getPreprocessor()
.addPPCallbacks(new IncludeOrderPPCallbacks(*this));
}
} // namespace tidy

View File

@@ -10,7 +10,6 @@
#include "../ClangTidy.h"
#include "../ClangTidyModule.h"
#include "../ClangTidyModuleRegistry.h"
#include "HeaderGuardCheck.h"
#include "IncludeOrderCheck.h"
#include "NamespaceCommentCheck.h"
#include "TwineLocalCheck.h"
@@ -21,8 +20,6 @@ namespace tidy {
class LLVMModule : public ClangTidyModule {
public:
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
CheckFactories.addCheckFactory(
"llvm-header-guard", new ClangTidyCheckFactory<LLVMHeaderGuardCheck>());
CheckFactories.addCheckFactory(
"llvm-include-order", new ClangTidyCheckFactory<IncludeOrderCheck>());
CheckFactories.addCheckFactory(

View File

@@ -8,6 +8,9 @@
//===----------------------------------------------------------------------===//
#include "ArgumentCommentCheck.h"
#include "../ClangTidy.h"
#include "../ClangTidyModule.h"
#include "../ClangTidyModuleRegistry.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Lex/Lexer.h"
@@ -22,15 +25,7 @@ ArgumentCommentCheck::ArgumentCommentCheck()
: IdentRE("^(/\\* *)([_A-Za-z][_A-Za-z0-9]*)( *= *\\*/)$") {}
void ArgumentCommentCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
callExpr(unless(operatorCallExpr()),
// NewCallback's arguments relate to the pointed function, don't
// check them against NewCallback's parameter names.
// FIXME: Make this configurable.
unless(hasDeclaration(functionDecl(anyOf(
hasName("NewCallback"), hasName("NewPermanentCallback"))))))
.bind("expr"),
this);
Finder->addMatcher(callExpr(unless(operatorCallExpr())).bind("expr"), this);
Finder->addMatcher(constructExpr().bind("expr"), this);
}
@@ -86,10 +81,10 @@ ArgumentCommentCheck::isLikelyTypo(llvm::ArrayRef<ParmVarDecl *> Params,
if (ThisED >= UpperBound)
return false;
for (unsigned I = 0, E = Params.size(); I != E; ++I) {
if (I == ArgIndex)
for (const auto &Param : Params) {
if (&Param - Params.begin() == ArgIndex)
continue;
IdentifierInfo *II = Params[I]->getIdentifier();
IdentifierInfo *II = Param->getIdentifier();
if (!II)
continue;

View File

@@ -24,9 +24,6 @@ AST_MATCHER(QualType, isBoolean) { return Node->isBooleanType(); }
namespace tidy {
void BoolPointerImplicitConversion::registerMatchers(MatchFinder *Finder) {
auto InTemplateInstantiation = hasAncestor(
decl(anyOf(recordDecl(ast_matchers::isTemplateInstantiation()),
functionDecl(ast_matchers::isTemplateInstantiation()))));
// Look for ifs that have an implicit bool* to bool conversion in the
// condition. Filter negations.
Finder->addMatcher(
@@ -35,8 +32,7 @@ void BoolPointerImplicitConversion::registerMatchers(MatchFinder *Finder) {
hasSourceExpression(expr(
hasType(pointerType(pointee(isBoolean()))),
ignoringParenImpCasts(declRefExpr().bind("expr")))),
isPointerToBoolean())))),
unless(InTemplateInstantiation)).bind("if"),
isPointerToBoolean()))))).bind("if"),
this);
}
@@ -45,10 +41,6 @@ BoolPointerImplicitConversion::check(const MatchFinder::MatchResult &Result) {
auto *If = Result.Nodes.getStmtAs<IfStmt>("if");
auto *Var = Result.Nodes.getStmtAs<DeclRefExpr>("expr");
// Ignore macros.
if (Var->getLocStart().isMacroID())
return;
// Only allow variable accesses for now, no function calls or member exprs.
// Check that we don't dereference the variable anywhere within the if. This
// avoids false positives for checks of the pointer for nullptr before it is

View File

@@ -6,8 +6,6 @@ add_clang_library(clangTidyMiscModule
MiscTidyModule.cpp
RedundantSmartptrGet.cpp
SwappedArgumentsCheck.cpp
UndelegatedConstructor.cpp
UnusedRAII.cpp
UseOverride.cpp
LINK_LIBS

View File

@@ -14,8 +14,6 @@
#include "BoolPointerImplicitConversion.h"
#include "RedundantSmartptrGet.h"
#include "SwappedArgumentsCheck.h"
#include "UndelegatedConstructor.h"
#include "UnusedRAII.h"
#include "UseOverride.h"
namespace clang {
@@ -36,12 +34,6 @@ public:
CheckFactories.addCheckFactory(
"misc-swapped-arguments",
new ClangTidyCheckFactory<SwappedArgumentsCheck>());
CheckFactories.addCheckFactory(
"misc-undelegated-constructor",
new ClangTidyCheckFactory<UndelegatedConstructorCheck>());
CheckFactories.addCheckFactory(
"misc-unused-raii",
new ClangTidyCheckFactory<UnusedRAIICheck>());
CheckFactories.addCheckFactory(
"misc-use-override",
new ClangTidyCheckFactory<UseOverride>());

View File

@@ -1,76 +0,0 @@
//===--- UndelegatedConstructor.cpp - clang-tidy --------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "UndelegatedConstructor.h"
#include "clang/AST/ASTContext.h"
#include "clang/Lex/Lexer.h"
using namespace clang::ast_matchers;
namespace clang {
namespace ast_matchers {
AST_MATCHER_P(Stmt, ignoringTemporaryExpr, internal::Matcher<Stmt>,
InnerMatcher) {
const Stmt *E = &Node;
for (;;) {
// Temporaries with non-trivial dtors.
if (const auto *EWC = dyn_cast<ExprWithCleanups>(E))
E = EWC->getSubExpr();
// Temporaries with zero or more than two ctor arguments.
else if (const auto *BTE = dyn_cast<CXXBindTemporaryExpr>(E))
E = BTE->getSubExpr();
// Temporaries with exactly one ctor argument.
else if (const auto *FCE = dyn_cast<CXXFunctionalCastExpr>(E))
E = FCE->getSubExpr();
else
break;
}
return InnerMatcher.matches(*E, Finder, Builder);
}
// Finds a node if it's a base of an already bound node.
AST_MATCHER_P(CXXRecordDecl, baseOfBoundNode, std::string, ID) {
return Builder->removeBindings([&](const internal::BoundNodesMap &Nodes) {
const auto *Derived = Nodes.getNodeAs<CXXRecordDecl>(ID);
return Derived != &Node && !Derived->isDerivedFrom(&Node);
});
}
} // namespace ast_matchers
namespace tidy {
void UndelegatedConstructorCheck::registerMatchers(MatchFinder *Finder) {
// We look for calls to constructors of the same type in constructors. To do
// this we have to look through a variety of nodes that occur in the path,
// depending on the type's destructor and the number of arguments on the
// constructor call, this is handled by ignoringTemporaryExpr. Ignore template
// instantiations to reduce the number of duplicated warnings.
Finder->addMatcher(
compoundStmt(
hasParent(constructorDecl(ofClass(recordDecl().bind("parent")))),
forEach(ignoringTemporaryExpr(
constructExpr(hasDeclaration(constructorDecl(ofClass(
recordDecl(baseOfBoundNode("parent"))))))
.bind("construct"))),
unless(hasAncestor(decl(
anyOf(recordDecl(ast_matchers::isTemplateInstantiation()),
functionDecl(ast_matchers::isTemplateInstantiation())))))),
this);
}
void UndelegatedConstructorCheck::check(const MatchFinder::MatchResult &Result) {
const auto *E = Result.Nodes.getStmtAs<CXXConstructExpr>("construct");
diag(E->getLocStart(), "did you intend to call a delegated constructor? "
"A temporary object is created here instead");
}
} // namespace tidy
} // namespace clang

View File

@@ -1,30 +0,0 @@
//===--- UndelegatedConstructor.h - clang-tidy ------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNDELEGATED_CONSTRUCTOR_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNDELEGATED_CONSTRUCTOR_H
#include "../ClangTidy.h"
namespace clang {
namespace tidy {
/// \brief Finds creation of temporary objects in constructors that look like a
/// function call to another constructor of the same class. The user most likely
/// meant to use a delegating constructor or base class initializer.
class UndelegatedConstructorCheck : public ClangTidyCheck {
public:
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
};
} // namespace tidy
} // namespace clang
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNDELEGATED_CONSTRUCTOR_H

View File

@@ -1,86 +0,0 @@
//===--- UnusedRAII.cpp - clang-tidy ---------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "UnusedRAII.h"
#include "clang/AST/ASTContext.h"
#include "clang/Lex/Lexer.h"
using namespace clang::ast_matchers;
namespace clang {
namespace ast_matchers {
AST_MATCHER(CXXRecordDecl, hasUserDeclaredDestructor) {
// TODO: If the dtor is there but empty we don't want to warn either.
return Node.hasDefinition() && Node.hasUserDeclaredDestructor();
}
} // namespace ast_matchers
namespace tidy {
void UnusedRAIICheck::registerMatchers(MatchFinder *Finder) {
// Look for temporaries that are constructed in-place and immediately
// destroyed. Look for temporaries created by a functional cast but not for
// those returned from a call.
auto BindTemp = bindTemporaryExpr(unless(has(callExpr()))).bind("temp");
Finder->addMatcher(
exprWithCleanups(
unless(hasAncestor(decl(
anyOf(recordDecl(ast_matchers::isTemplateInstantiation()),
functionDecl(ast_matchers::isTemplateInstantiation()))))),
hasParent(compoundStmt().bind("compound")),
hasType(recordDecl(hasUserDeclaredDestructor())),
anyOf(has(BindTemp), has(functionalCastExpr(has(BindTemp)))))
.bind("expr"),
this);
}
void UnusedRAIICheck::check(const MatchFinder::MatchResult &Result) {
const auto *E = Result.Nodes.getStmtAs<Expr>("expr");
// We ignore code expanded from macros to reduce the number of false
// positives.
if (E->getLocStart().isMacroID())
return;
// Don't emit a warning for the last statement in the surrounding compund
// statement.
const auto *CS = Result.Nodes.getStmtAs<CompoundStmt>("compound");
if (E == CS->body_back())
return;
// Emit a warning.
auto D = diag(E->getLocStart(), "object destroyed immediately after "
"creation; did you mean to name the object?");
const char *Replacement = " give_me_a_name";
// If this is a default ctor we have to remove the parens or we'll introduce a
// most vexing parse.
const auto *BTE = Result.Nodes.getStmtAs<CXXBindTemporaryExpr>("temp");
if (const auto *TOE = dyn_cast<CXXTemporaryObjectExpr>(BTE->getSubExpr()))
if (TOE->getNumArgs() == 0) {
D << FixItHint::CreateReplacement(
CharSourceRange::getTokenRange(TOE->getParenOrBraceRange()),
Replacement);
return;
}
// Otherwise just suggest adding a name. To find the place to insert the name
// find the first TypeLoc in the children of E, which always points to the
// written type.
auto Matches =
match(expr(hasDescendant(typeLoc().bind("t"))), *E, *Result.Context);
const auto *TL = selectFirst<TypeLoc>("t", Matches);
D << FixItHint::CreateInsertion(
Lexer::getLocForEndOfToken(TL->getLocEnd(), 0, *Result.SourceManager,
Result.Context->getLangOpts()),
Replacement);
}
} // namespace tidy
} // namespace clang

View File

@@ -1,47 +0,0 @@
//===--- UnusedRAII.h - clang-tidy ------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNUSED_RAII_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNUSED_RAII_H
#include "../ClangTidy.h"
namespace clang {
namespace tidy {
/// \brief Finds temporaries that look like RAII objects.
///
/// The canonical example for this is a scoped lock.
/// \code
/// {
/// scoped_lock(&global_mutex);
/// critical_section();
/// }
/// \endcode
/// The destructor of the scoped_lock is called before the critical_section is
/// entered, leaving it unprotected.
///
/// We apply a number of heuristics to reduce the false positive count of this
/// check:
/// - Ignore code expanded from macros. Testing frameworks make heavy use of
/// this.
/// - Ignore types with no user-declared constructor. Those are very unlikely
/// to be RAII objects.
/// - Ignore objects at the end of a compound statement (doesn't change behavior).
/// - Ignore objects returned from a call.
class UnusedRAIICheck : public ClangTidyCheck {
public:
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
};
} // namespace tidy
} // namespace clang
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNUSED_RAII_H

View File

@@ -74,8 +74,8 @@ void UseOverride::check(const MatchFinder::MatchResult &Result) {
DiagnosticBuilder Diag = diag(
Method->getLocation(),
OnlyVirtualSpecified
? "Prefer using 'override' or (rarely) 'final' instead of 'virtual'"
: "Annotate this function with 'override' or (rarely) 'final'");
? "Prefer using 'override' or 'final' instead of 'virtual'"
: "Use exactly one of 'virtual', 'override' or (rarely) 'final'");
CharSourceRange FileRange = Lexer::makeFileCharRange(
CharSourceRange::getTokenRange(Method->getSourceRange()), Sources,

View File

@@ -17,7 +17,7 @@ TOOL_NO_EXPORTS = 1
include $(CLANG_LEVEL)/../../Makefile.config
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
USEDLIBS = clangTidy.a clangTidyLLVMModule.a clangTidyGoogleModule.a \
clangTidyMiscModule.a clangTidyUtils.a \
clangTidyMiscModule.a \
clangStaticAnalyzerFrontend.a clangStaticAnalyzerCheckers.a \
clangStaticAnalyzerCore.a \
clangFormat.a clangASTMatchers.a clangTooling.a clangFrontend.a \

View File

@@ -1,12 +0,0 @@
set(LLVM_LINK_COMPONENTS support)
add_clang_library(clangTidyUtils
HeaderGuard.cpp
LINK_LIBS
clangAST
clangASTMatchers
clangBasic
clangLex
clangTidy
)

View File

@@ -1,257 +0,0 @@
//===--- HeaderGuard.cpp - clang-tidy -------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "HeaderGuard.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/Path.h"
namespace clang {
namespace tidy {
/// \brief canonicalize a path by removing ./ and ../ components.
// FIXME: Consider moving this to llvm::sys::path.
static std::string cleanPath(StringRef Path) {
SmallString<256> NewPath;
for (auto I = llvm::sys::path::begin(Path), E = llvm::sys::path::end(Path);
I != E; ++I) {
if (*I == ".")
continue;
if (*I == "..") {
// Drop the last component.
NewPath.resize(llvm::sys::path::parent_path(NewPath).size());
} else {
if (!NewPath.empty())
NewPath += '/';
NewPath += *I;
}
}
return NewPath.str();
}
namespace {
class HeaderGuardPPCallbacks : public PPCallbacks {
public:
explicit HeaderGuardPPCallbacks(Preprocessor *PP, HeaderGuardCheck *Check)
: PP(PP), Check(Check) {}
void FileChanged(SourceLocation Loc, FileChangeReason Reason,
SrcMgr::CharacteristicKind FileType,
FileID PrevFID) override {
// Record all files we enter. We'll need them to diagnose headers without
// guards.
SourceManager &SM = PP->getSourceManager();
if (Reason == EnterFile && FileType == SrcMgr::C_User) {
if (const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Loc))) {
std::string FileName = cleanPath(FE->getName());
Files[FileName] = FE;
}
}
}
void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
const MacroDirective *MD) override {
if (MD)
return;
// Record #ifndefs that succeeded. We also need the Location of the Name.
Ifndefs[MacroNameTok.getIdentifierInfo()] =
std::make_pair(Loc, MacroNameTok.getLocation());
}
void MacroDefined(const Token &MacroNameTok,
const MacroDirective *MD) override {
// Record all defined macros. We store the whole token to get info on the
// name later.
Macros.emplace_back(MacroNameTok, MD);
}
void Endif(SourceLocation Loc, SourceLocation IfLoc) override {
// Record all #endif and the corresponding #ifs (including #ifndefs).
EndIfs[IfLoc] = Loc;
}
void EndOfMainFile() override {
// Now that we have all this information from the preprocessor, use it!
SourceManager &SM = PP->getSourceManager();
for (const auto &MacroEntry : Macros) {
const MacroInfo *MI = MacroEntry.second->getMacroInfo();
// We use clang's header guard detection. This has the advantage of also
// emitting a warning for cases where a pseudo header guard is found but
// preceeded by something blocking the header guard optimization.
if (!MI->isUsedForHeaderGuard())
continue;
const FileEntry *FE =
SM.getFileEntryForID(SM.getFileID(MI->getDefinitionLoc()));
std::string FileName = cleanPath(FE->getName());
Files.erase(FileName);
// See if we should check and fix this header guard.
if (!Check->shouldFixHeaderGuard(FileName))
continue;
// Look up Locations for this guard.
SourceLocation Ifndef =
Ifndefs[MacroEntry.first.getIdentifierInfo()].second;
SourceLocation Define = MacroEntry.first.getLocation();
SourceLocation EndIf =
EndIfs[Ifndefs[MacroEntry.first.getIdentifierInfo()].first];
// If the macro Name is not equal to what we can compute, correct it in
// the
// #ifndef and #define.
StringRef CurHeaderGuard =
MacroEntry.first.getIdentifierInfo()->getName();
std::string NewGuard =
checkHeaderGuardDefinition(Ifndef, Define, FileName, CurHeaderGuard);
// Now look at the #endif. We want a comment with the header guard. Fix it
// at the slightest deviation.
if (Check->shouldSuggestEndifComment(FileName))
checkEndifComment(EndIf, NewGuard);
}
// Emit warnings for headers that are missing guards.
checkGuardlessHeaders();
// Clear all state.
Macros.clear();
Files.clear();
Ifndefs.clear();
EndIfs.clear();
}
/// \brief Look for header guards that don't match the preferred style. Emit
/// fix-its and return the suggested header guard (or the original if no
/// change was made.
std::string checkHeaderGuardDefinition(SourceLocation Ifndef,
SourceLocation Define,
StringRef FileName,
StringRef CurHeaderGuard) {
std::string CPPVar = Check->getHeaderGuard(FileName, CurHeaderGuard);
std::string CPPVarUnder = CPPVar + '_'; // Allow a trailing underscore.
if (Ifndef.isValid() && CurHeaderGuard != CPPVar &&
CurHeaderGuard != CPPVarUnder) {
Check->diag(Ifndef, "header guard does not follow preferred style")
<< FixItHint::CreateReplacement(
CharSourceRange::getTokenRange(
Ifndef, Ifndef.getLocWithOffset(CurHeaderGuard.size())),
CPPVar)
<< FixItHint::CreateReplacement(
CharSourceRange::getTokenRange(
Define, Define.getLocWithOffset(CurHeaderGuard.size())),
CPPVar);
return CPPVar;
}
return CurHeaderGuard;
}
/// \brief Checks the comment after the #endif of a header guard and fixes it
/// if it doesn't match \c HeaderGuard.
void checkEndifComment(SourceLocation EndIf, StringRef HeaderGuard) {
const char *EndIfData = PP->getSourceManager().getCharacterData(EndIf);
size_t EndIfLen = std::strcspn(EndIfData, "\r\n");
StringRef EndIfStr(EndIfData, EndIfLen);
if (EndIf.isValid() && !EndIfStr.endswith("// " + HeaderGuard.str())) {
std::string Correct = "endif // " + HeaderGuard.str();
Check->diag(EndIf, "#endif for a header guard should reference the "
"guard macro in a comment")
<< FixItHint::CreateReplacement(
CharSourceRange::getCharRange(EndIf,
EndIf.getLocWithOffset(EndIfLen)),
Correct);
}
}
/// \brief Looks for files that were visited but didn't have a header guard.
/// Emits a warning with fixits suggesting adding one.
void checkGuardlessHeaders() {
// Look for header files that didn't have a header guard. Emit a warning and
// fix-its to add the guard.
// TODO: Insert the guard after top comments.
for (const auto &FE : Files) {
StringRef FileName = FE.getKey();
if (!Check->shouldSuggestToAddHeaderGuard(FileName))
continue;
SourceManager &SM = PP->getSourceManager();
FileID FID = SM.translateFile(FE.getValue());
SourceLocation StartLoc = SM.getLocForStartOfFile(FID);
if (StartLoc.isInvalid())
continue;
std::string CPPVar = Check->getHeaderGuard(FileName);
std::string CPPVarUnder = CPPVar + '_'; // Allow a trailing underscore.
// If there is a header guard macro but it's not in the topmost position
// emit a plain warning without fix-its. This often happens when the guard
// macro is preceeded by includes.
// FIXME: Can we move it into the right spot?
bool SeenMacro = false;
for (const auto &MacroEntry : Macros) {
StringRef Name = MacroEntry.first.getIdentifierInfo()->getName();
SourceLocation DefineLoc = MacroEntry.first.getLocation();
if ((Name == CPPVar || Name == CPPVarUnder) &&
SM.isWrittenInSameFile(StartLoc, DefineLoc)) {
Check->diag(
DefineLoc,
"Header guard after code/includes. Consider moving it up.");
SeenMacro = true;
break;
}
}
if (SeenMacro)
continue;
Check->diag(StartLoc, "header is missing header guard")
<< FixItHint::CreateInsertion(
StartLoc, "#ifndef " + CPPVar + "\n#define " + CPPVar + "\n\n")
<< FixItHint::CreateInsertion(
SM.getLocForEndOfFile(FID),
Check->shouldSuggestEndifComment(FileName)
? "\n#endif // " + CPPVar + "\n"
: "\n#endif\n");
}
}
private:
std::vector<std::pair<Token, const MacroDirective *>> Macros;
llvm::StringMap<const FileEntry *> Files;
std::map<const IdentifierInfo *, std::pair<SourceLocation, SourceLocation>>
Ifndefs;
std::map<SourceLocation, SourceLocation> EndIfs;
Preprocessor *PP;
HeaderGuardCheck *Check;
};
} // namespace
void HeaderGuardCheck::registerPPCallbacks(CompilerInstance &Compiler) {
Compiler.getPreprocessor().addPPCallbacks(
new HeaderGuardPPCallbacks(&Compiler.getPreprocessor(), this));
}
bool HeaderGuardCheck::shouldSuggestEndifComment(StringRef FileName) {
return FileName.endswith(".h");
}
bool HeaderGuardCheck::shouldFixHeaderGuard(StringRef FileName) { return true; }
bool HeaderGuardCheck::shouldSuggestToAddHeaderGuard(StringRef FileName) {
return FileName.endswith(".h");
}
} // namespace tidy
} // namespace clang

View File

@@ -1,41 +0,0 @@
//===--- HeaderGuard.h - clang-tidy -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_HEADER_GUARD_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_HEADER_GUARD_H
#include "../ClangTidy.h"
namespace clang {
namespace tidy {
/// \brief Finds and fixes header guards.
class HeaderGuardCheck : public ClangTidyCheck {
public:
void registerPPCallbacks(CompilerInstance &Compiler) override;
/// \brief Returns true if the checker should suggest inserting a trailing
/// comment on the #endif of the header guard. It will use the same name as
/// returned by getHeaderGuard.
virtual bool shouldSuggestEndifComment(StringRef Filename);
/// \brief Returns true if the checker should suggest changing an existing
/// header guard to the string returned by getHeaderGuard.
virtual bool shouldFixHeaderGuard(StringRef Filename);
/// \brief Returns true if the checker should add a header guard to the file
/// if it has none.
virtual bool shouldSuggestToAddHeaderGuard(StringRef Filename);
/// \brief Get the canonical header guard for a file.
virtual std::string getHeaderGuard(StringRef Filename,
StringRef OldGuard = StringRef()) = 0;
};
} // namespace tidy
} // namespace clang
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_HEADER_GUARD_H

View File

@@ -1,12 +0,0 @@
##===- clang-tidy/google/Makefile --------------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
CLANG_LEVEL := ../../../..
LIBRARYNAME := clangTidyUtils
include $(CLANG_LEVEL)/Makefile

View File

@@ -652,10 +652,10 @@ public:
HadErrors(HadErrors) {}
protected:
std::unique_ptr<clang::ASTConsumer>
CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override {
return llvm::make_unique<CollectEntitiesConsumer>(
Entities, PPTracker, CI.getPreprocessor(), InFile, HadErrors);
virtual clang::ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) {
return new CollectEntitiesConsumer(Entities, PPTracker,
CI.getPreprocessor(), InFile, HadErrors);
}
private:
@@ -736,8 +736,8 @@ int main(int Argc, const char **Argv) {
ClangTool Tool(*Compilations, Headers);
Tool.appendArgumentsAdjuster(new AddDependenciesAdjuster(Dependencies));
int HadErrors = 0;
ModularizeFrontendActionFactory Factory(Entities, *PPTracker, HadErrors);
HadErrors |= Tool.run(&Factory);
HadErrors |= Tool.run(
new ModularizeFrontendActionFactory(Entities, *PPTracker, HadErrors));
// Create a place to save duplicate entity locations, separate bins per kind.
typedef SmallVector<Location, 8> LocationArray;

View File

@@ -178,10 +178,9 @@ public:
ModuleMapCheckerAction(ModuleMapChecker &Checker) : Checker(Checker) {}
protected:
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) override {
return llvm::make_unique<ModuleMapCheckerConsumer>(Checker,
CI.getPreprocessor());
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) {
return new ModuleMapCheckerConsumer(Checker, CI.getPreprocessor());
}
private:

View File

@@ -120,10 +120,9 @@ public:
: Ignore(Ignore), CallbackCalls(CallbackCalls) {}
protected:
std::unique_ptr<clang::ASTConsumer>
CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override {
return llvm::make_unique<PPTraceConsumer>(Ignore, CallbackCalls,
CI.getPreprocessor());
virtual clang::ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) {
return new PPTraceConsumer(Ignore, CallbackCalls, CI.getPreprocessor());
}
private:
@@ -200,8 +199,8 @@ int main(int Argc, const char **Argv) {
// Create the tool and run the compilation.
ClangTool Tool(*Compilations, SourcePaths);
PPTraceFrontendActionFactory Factory(Ignore, CallbackCalls);
int HadErrors = Tool.run(&Factory);
int HadErrors =
Tool.run(new PPTraceFrontendActionFactory(Ignore, CallbackCalls));
// If we had errors, exit early.
if (HadErrors)

View File

@@ -183,11 +183,11 @@ int main(int argc, const char **argv) {
cl::ParseCommandLineOptions(argc, argv);
if (!Compilations) {
std::string ErrorMessage;
Compilations =
CompilationDatabase::loadFromDirectory(BuildPath, ErrorMessage);
Compilations.reset(
CompilationDatabase::loadFromDirectory(BuildPath, ErrorMessage));
if (!Compilations)
llvm::report_fatal_error(ErrorMessage);
}
}
tooling::RefactoringTool Tool(*Compilations, SourcePaths);
ast_matchers::MatchFinder Finder;
FixCStrCall Callback(&Tool.getReplacements());

View File

@@ -37,7 +37,6 @@ set(CLANG_TOOLS_TEST_DEPS
# Individual tools we test.
clang-apply-replacements
clang-modernize
clang-rename
clang-query
clang-tidy
modularize

View File

@@ -60,7 +60,6 @@ lit.site.cfg: FORCE
Unit/lit.site.cfg: FORCE
@echo "Making Unit/lit.site.cfg for Clang extra tools..."
@$(MKDIR) $(dir $@)
@$(ECHOPATH) s=@LLVM_LIBS_DIR@=$(LibDir)=g >> lit.tmp
@$(ECHOPATH) s=@CLANG_TOOLS_BINARY_DIR@=$(PROJ_OBJ_DIR)/..=g >> lit.tmp
@$(ECHOPATH) s=@TARGET_TRIPLE@=$(TARGET_TRIPLE)=g >> lit.tmp
@$(ECHOPATH) s=@CLANG_TOOLS_SOURCE_DIR@=$(PROJ_SRC_DIR)/..=g >> lit.tmp

View File

@@ -1,7 +1,5 @@
# -*- Python -*-
import platform
import lit.formats
config.name = "Extra Tools Unit Tests"
@@ -14,6 +12,11 @@ if extra_tools_obj_dir is not None:
config.test_source_root = extra_tools_obj_dir
config.test_exec_root = config.test_source_root
# Win32 seeks DLLs along %PATH%.
if sys.platform in ['win32', 'cygwin'] and os.path.isdir(config.shlibdir):
config.environment['PATH'] = os.path.pathsep.join((
config.shlibdir, config.environment['PATH']))
# All GoogleTests are named to have 'Tests' as their suffix. The '.' option is
# a special value for GoogleTest indicating that it should look through the
# entire testsuite recursively for tests (alternatively, one could provide a
@@ -31,24 +34,3 @@ if config.test_exec_root is None:
raise SystemExit
# FIXME: Support out-of-tree builds? See clang/test/Unit/lit.cfg if we care.
shlibpath_var = ''
if platform.system() == 'Linux':
shlibpath_var = 'LD_LIBRARY_PATH'
elif platform.system() == 'Darwin':
shlibpath_var = 'DYLD_LIBRARY_PATH'
elif platform.system() == 'Windows':
shlibpath_var = 'PATH'
# Point the dynamic loader at dynamic libraries in 'lib'.
llvm_libs_dir = getattr(config, 'llvm_libs_dir', None)
if not llvm_libs_dir:
lit_config.fatal('No LLVM libs dir set!')
shlibpath = os.path.pathsep.join((llvm_libs_dir,
config.environment.get(shlibpath_var,'')))
# Win32 seeks DLLs along %PATH%.
if sys.platform in ['win32', 'cygwin'] and os.path.isdir(config.shlibdir):
shlibpath = os.path.pathsep.join((config.shlibdir, shlibpath))
config.environment[shlibpath_var] = shlibpath

View File

@@ -2,7 +2,6 @@
# Do not edit!
config.extra_tools_obj_dir = "@CLANG_TOOLS_BINARY_DIR@/unittests"
config.extra_tools_src_dir = "@CLANG_TOOLS_SOURCE_DIR@/unittests"
config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
config.shlibdir = "@SHLIBDIR@"
config.target_triple = "@TARGET_TRIPLE@"

View File

@@ -1,26 +0,0 @@
// RUN: cat %s > %t.cpp
// RUN: clang-rename -offset=170 -new-name=hector %t.cpp -i --
// RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
// REQUIRES: shell
namespace A {
int foo; // CHECK: int hector;
}
int foo; // CHECK: int foo;
int bar = foo; // CHECK: bar = foo;
int baz = A::foo; // CHECK: baz = A::hector;
void fun1() {
struct {
int foo; // CHECK: int foo;
} b = { 100 };
int foo = 100; // CHECK: int foo
baz = foo; // CHECK: baz = foo;
{
extern int foo; // CHECK: int foo;
baz = foo; // CHECK: baz = foo;
foo = A::foo + baz; // CHECK: foo = A::hector + baz;
A::foo = b.foo; // CHECK: A::hector = b.foo;
}
foo = b.foo; // CHECK: foo = b.foo;
}
// Use grep -FUbo 'foo;' <file> to get the correct offset of foo when changing
// this file.

View File

@@ -1,29 +1,21 @@
// RUN: clang-tidy --checks='-*,misc-argument-comment' %s -- -std=c++11 | FileCheck %s -implicit-check-not='{{warning:|error:}}'
// RUN: clang-tidy --checks='-*,misc-argument-comment' %s -- | FileCheck %s
// FIXME: clang-tidy should provide a -verify mode to make writing these checks
// easier and more accurate.
void ffff(int xxxx, int yyyy);
// CHECK-NOT: warning
void f(int x, int y);
void ffff(int xxxx, int yyyy);
void g() {
// CHECK: [[@LINE+5]]:5: warning: argument name 'y' in comment does not match parameter name 'x'
// CHECK: :[[@LINE-3]]:12: note: 'x' declared here
// CHECK: :8:12: note: 'x' declared here
// CHECK: [[@LINE+3]]:14: warning: argument name 'z' in comment does not match parameter name 'y'
// CHECK: :[[@LINE-5]]:19: note: 'y' declared here
// CHECK: :8:19: note: 'y' declared here
// CHECK-NOT: warning
f(/*y=*/0, /*z=*/0);
}
struct Closure {};
template <typename T1, typename T2>
Closure *NewCallback(void (*f)(T1, T2), T1 arg1, T2 arg2) { return nullptr; }
template <typename T1, typename T2>
Closure *NewPermanentCallback(void (*f)(T1, T2), T1 arg1, T2 arg2) { return nullptr; }
void h() {
(void)NewCallback(&ffff, /*xxxx=*/11, /*yyyy=*/22);
(void)NewPermanentCallback(&ffff, /*xxxx=*/11, /*yyyy=*/22);
}
// CHECK-NOT: warning

View File

@@ -105,6 +105,9 @@ void test_templates() {
#define CAST(type, value) (type)(value)
void macros(double d) {
int i = CAST(int, d);
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: C-style casts are discouraged. Use static_cast.
// CHECK-FIXES: #define CAST(type, value) (type)(value)
// CHECK-FIXES: int i = CAST(int, d);
}
enum E { E1 = 1 };

View File

@@ -1,34 +1,24 @@
#!/bin/sh
#
# Run clang-tidy in fix mode and verify the result.
# Usage:
# check_clang_tidy_fix.sh <source-file> <check-name> <temp-file> \
# [optional compiler arguments]
#
# Example:
# // RUN: $(dirname %s)/check_clang_tidy_fix.sh %s llvm-include-order %t -isystem $(dirname %s)/Inputs/Headers
# // REQUIRES: shell
INPUT_FILE=$1
CHECK_TO_RUN=$2
TEMPORARY_FILE=$3.cpp
# Feed the rest arguments to clang-tidy after --.
shift 3
set -o errexit
# Remove the contents of the CHECK lines to avoid CHECKs matching on themselves.
# We need to keep the comments to preserve line numbers while avoiding empty
# lines which could potentially trigger formatting-related checks.
sed 's#// *[A-Z-][A-Z-]*:.*#//#' ${INPUT_FILE} > ${TEMPORARY_FILE}
sed 's#// *[A-Z-]\+:.*#//#' ${INPUT_FILE} > ${TEMPORARY_FILE}
clang-tidy ${TEMPORARY_FILE} -fix --checks="-*,${CHECK_TO_RUN}" \
-- --std=c++11 $* > ${TEMPORARY_FILE}.msg 2>&1
clang-tidy ${TEMPORARY_FILE} -fix --checks="-*,${CHECK_TO_RUN}" -- --std=c++11 \
> ${TEMPORARY_FILE}.msg 2>&1
FileCheck -input-file=${TEMPORARY_FILE} ${INPUT_FILE} \
-check-prefix=CHECK-FIXES -strict-whitespace
-check-prefix=CHECK-FIXES -strict-whitespace || exit $?
if grep -q CHECK-MESSAGES ${INPUT_FILE}; then
FileCheck -input-file=${TEMPORARY_FILE}.msg ${INPUT_FILE} \
-check-prefix=CHECK-MESSAGES -implicit-check-not="{{warning|error}}:"
-check-prefix=CHECK-MESSAGES -implicit-check-not="{{warning|error}}:" \
|| exit $?
fi

View File

@@ -9,10 +9,10 @@ struct A {
// CHECK-NOT: warning
struct B : public A {
void placeholder_for_f() {}
// CHECK-SANITY: [[@LINE-1]]:8: warning: Annotate this
// CHECK: [[@LINE-2]]:8: warning: Annotate this
// CHECK-SANITY: [[@LINE-1]]:8: warning: Use exactly
// CHECK: [[@LINE-2]]:8: warning: Use exactly
void g() {}
// CHECK-SANITY: [[@LINE-1]]:8: warning: Annotate this
// CHECK-SANITY: [[@LINE-1]]:8: warning: Use exactly
// CHECK-NOT: warning:
};
// CHECK-SANITY-NOT: Suppressed

View File

@@ -4,57 +4,57 @@
void Method(char *) { /* */ }
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: all parameters should be named in a function
// CHECK-FIXES: void Method(char * /*unused*/) { /* */ }
void Method2(char *) {}
void Method2(char *);
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: all parameters should be named in a function
// CHECK-FIXES: void Method2(char * /*unused*/) {}
void Method3(char *, void *) {}
// CHECK-FIXES: void Method2(char * /*unused*/);
void Method3(char *, void *);
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: all parameters should be named in a function
// CHECK-FIXES: void Method3(char * /*unused*/, void * /*unused*/) {}
void Method4(char *, int /*unused*/) {}
// CHECK-FIXES: void Method3(char * /*unused*/, void * /*unused*/);
void Method4(char *, int /*unused*/);
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: all parameters should be named in a function
// CHECK-FIXES: void Method4(char * /*unused*/, int /*unused*/) {}
void operator delete[](void *) throw() {}
// CHECK-FIXES: void Method4(char * /*unused*/, int /*unused*/);
void operator delete[](void *) throw();
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: all parameters should be named in a function
// CHECK-FIXES: void operator delete[](void * /*unused*/) throw() {}
int Method5(int) { return 0; }
// CHECK-FIXES: void operator delete[](void * /*unused*/) throw();
int Method5(int);
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: all parameters should be named in a function
// CHECK-FIXES: int Method5(int /*unused*/) { return 0; }
// CHECK-FIXES: int Method5(int /*unused*/);
void Method6(void (*)(void *)) {}
// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: all parameters should be named in a function
// CHECK-FIXES: void Method6(void (* /*unused*/)(void *)) {}
template <typename T> void Method7(T) {}
template <typename T> void Method7(T);
// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: all parameters should be named in a function
// CHECK-FIXES: template <typename T> void Method7(T /*unused*/) {}
// CHECK-FIXES: template <typename T> void Method7(T /*unused*/);
// Don't warn in macros.
#define M void MethodM(int) {}
#define M void MethodM(int);
M
void operator delete(void *x) throw() {}
void operator delete(void *x) throw();
void Method7(char * /*x*/) {}
void Method8(char *x) {}
void Method8(char *x);
typedef void (*TypeM)(int x);
void operator delete[](void *x) throw();
void operator delete[](void * /*x*/) throw();
struct X {
X operator++(int) {}
X operator++(int);
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: all parameters should be named in a function
// CHECK-FIXES: X operator++(int /*unused*/) {}
X operator--(int /*unused*/) {}
// CHECK-FIXES: X operator++(int /*unused*/);
X operator--(int /*unused*/);
const int &i;
};
void (*Func1)(void *);
void Func2(void (*func)(void *)) {}
template <void Func(void *)> void Func3() {}
template <void Func(void *)> void Func3();
template <typename T>
struct Y {
void foo(T) {}
void foo(T);
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: all parameters should be named in a function
// CHECK-FIXES: void foo(T /*unused*/) {}
// CHECK-FIXES: void foo(T /*unused*/);
};
Y<int> y;
@@ -70,17 +70,3 @@ struct Derived : public Base {
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: all parameters should be named in a function
// CHECK-FIXES: void foo(int /*argname*/);
};
void FDef(int);
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: all parameters should be named in a function
// CHECK-FIXES: void FDef(int /*n*/);
void FDef(int n) {}
void FDef2(int, int);
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: all parameters should be named in a function
// CHECK-FIXES: void FDef2(int /*n*/, int /*unused*/);
void FDef2(int n, int) {}
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: all parameters should be named in a function
// CHECK-FIXES: void FDef2(int n, int /*unused*/) {}
void FNoDef(int);

View File

@@ -1,41 +0,0 @@
// RUN: $(dirname %s)/check_clang_tidy_fix.sh %s llvm-include-order %t -isystem %S/Inputs/Headers
// REQUIRES: shell
// FIXME: Investigating.
// XFAIL: win32
// CHECK-MESSAGES: [[@LINE+2]]:1: warning: #includes are not sorted properly
#include "j.h"
#include "gtest/foo.h"
#include "i.h"
#include <s.h>
#include "llvm/a.h"
#include "clang/b.h"
#include "clang-c/c.h" // hi
#include "llvm-c/d.h" // -c
// CHECK-FIXES: #include "j.h"
// CHECK-FIXES-NEXT: #include "i.h"
// CHECK-FIXES-NEXT: #include "clang-c/c.h" // hi
// CHECK-FIXES-NEXT: #include "clang/b.h"
// CHECK-FIXES-NEXT: #include "llvm-c/d.h" // -c
// CHECK-FIXES-NEXT: #include "llvm/a.h"
// CHECK-FIXES-NEXT: #include "gtest/foo.h"
// CHECK-FIXES-NEXT: #include <s.h>
#include "b.h"
#ifdef FOO
#include "a.h"
#endif
// CHECK-FIXES: #include "b.h"
// CHECK-FIXES-NEXT: #ifdef FOO
// CHECK-FIXES-NEXT: #include "a.h"
// CHECK-FIXES-NEXT: #endif
// CHECK-MESSAGES: [[@LINE+1]]:1: warning: #includes are not sorted properly
#include "b.h"
#include "a.h"
// CHECK-FIXES: #include "a.h"
// CHECK-FIXES-NEXT: #include "b.h"

View File

@@ -33,6 +33,10 @@ void foo() {
#define TESTMACRO if (b || F())
TESTMACRO {
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: dubious check of 'bool *' against 'nullptr'
// Can't fix this.
// CHECK-FIXES: #define TESTMACRO if (b || F())
// CHECK-FIXES: TESTMACRO {
}
t(b);
@@ -77,7 +81,4 @@ void foo() {
if (d.b)
(void)*d.b; // no-warning
#define CHECK(b) if (b) {}
CHECK(c)
}

View File

@@ -1,54 +0,0 @@
// RUN: clang-tidy -checks='-*,misc-undelegated-constructor' %s -- -std=c++11 2>&1 | FileCheck %s -implicit-check-not='{{warning:|error:}}'
struct Ctor;
Ctor foo();
struct Ctor {
Ctor();
Ctor(int);
Ctor(int, int);
Ctor(Ctor *i) {
Ctor();
// CHECK: :[[@LINE-1]]:5: warning: did you intend to call a delegated constructor? A temporary object is created here instead
Ctor(0);
// CHECK: :[[@LINE-1]]:5: warning: did you intend to call a delegated constructor? A temporary object is created here instead
Ctor(1, 2);
// CHECK: :[[@LINE-1]]:5: warning: did you intend to call a delegated constructor? A temporary object is created here instead
foo();
}
};
Ctor::Ctor() {
Ctor(1);
// CHECK: :[[@LINE-1]]:3: warning: did you intend to call a delegated constructor? A temporary object is created here instead
}
Ctor::Ctor(int i) : Ctor(i, 1) {} // properly delegated.
struct Dtor {
Dtor();
Dtor(int);
Dtor(int, int);
Dtor(Ctor *i) {
Dtor();
// CHECK: :[[@LINE-1]]:5: warning: did you intend to call a delegated constructor? A temporary object is created here instead
Dtor(0);
// CHECK: :[[@LINE-1]]:5: warning: did you intend to call a delegated constructor? A temporary object is created here instead
Dtor(1, 2);
// CHECK: :[[@LINE-1]]:5: warning: did you intend to call a delegated constructor? A temporary object is created here instead
}
~Dtor();
};
struct Base {};
struct Derived : public Base {
Derived() { Base(); }
// CHECK: :[[@LINE-1]]:15: warning: did you intend to call a delegated constructor? A temporary object is created here instead
};
template <typename T>
struct TDerived : public Base {
TDerived() { Base(); }
};
TDerived<int> t;

View File

@@ -1,61 +0,0 @@
// RUN: $(dirname %s)/check_clang_tidy_fix.sh %s misc-unused-raii %t
// REQUIRES: shell
struct Foo {
Foo();
Foo(int);
Foo(int, int);
~Foo();
};
struct Bar {
Bar();
Foo f;
};
template <typename T>
void qux() {
T(42);
}
template <typename T>
struct TFoo {
TFoo(T);
~TFoo();
};
Foo f();
struct Ctor {
Ctor(int);
Ctor() {
Ctor(0); // TODO: warn here.
}
};
void test() {
Foo(42);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: object destroyed immediately after creation; did you mean to name the object?
// CHECK-FIXES: Foo give_me_a_name(42);
Foo(23, 42);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: object destroyed immediately after creation; did you mean to name the object?
// CHECK-FIXES: Foo give_me_a_name(23, 42);
Foo();
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: object destroyed immediately after creation; did you mean to name the object?
// CHECK-FIXES: Foo give_me_a_name;
TFoo<int>(23);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: object destroyed immediately after creation; did you mean to name the object?
// CHECK-FIXES: TFoo<int> give_me_a_name(23);
Bar();
f();
qux<Foo>();
#define M Foo();
M
{
Foo();
}
Foo();
}

View File

@@ -32,11 +32,11 @@ struct Base {
struct SimpleCases : public Base {
public:
virtual ~SimpleCases();
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: Prefer using 'override' or (rarely) 'final' instead of 'virtual'
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: Prefer using 'override' or 'final' instead of 'virtual'
// CHECK-FIXES: {{^ ~SimpleCases\(\) override;}}
void a();
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: Annotate this
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: Use exactly
// CHECK-FIXES: {{^ void a\(\) override;}}
void b() override;
@@ -48,7 +48,7 @@ public:
// CHECK-FIXES: {{^ void c\(\) override;}}
virtual void d() override;
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Annotate this
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use exactly
// CHECK-FIXES: {{^ void d\(\) override;}}
virtual void e() = 0;
@@ -76,7 +76,7 @@ public:
// CHECK-FIXES: {{^ bool l\(\) override MUST_USE_RESULT;}}
virtual void m() override final;
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Annotate this
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use exactly
// CHECK-FIXES: {{^ void m\(\) final;}}
};
@@ -98,7 +98,7 @@ struct DefaultedDestructor : public Base {
struct FinalSpecified : public Base {
public:
virtual ~FinalSpecified() final;
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: Annotate this
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: Use exactly
// CHECK-FIXES: {{^ ~FinalSpecified\(\) final;}}
void b() final;
@@ -106,19 +106,19 @@ public:
// CHECK-FIXES: {{^ void b\(\) final;}}
virtual void d() final;
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Annotate this
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use exactly
// CHECK-FIXES: {{^ void d\(\) final;}}
virtual void e() final = 0;
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Annotate this
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use exactly
// CHECK-FIXES: {{^ void e\(\) final = 0;}}
virtual void j() const final;
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Annotate this
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use exactly
// CHECK-FIXES: {{^ void j\(\) const final;}}
virtual bool l() final MUST_USE_RESULT;
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Annotate this
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use exactly
// CHECK-FIXES: {{^ bool l\(\) final MUST_USE_RESULT;}}
};
@@ -129,7 +129,7 @@ public:
// CHECK-FIXES: {{^ ~InlineDefinitions\(\) override {}}}
void a() {}
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: Annotate this
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: Use exactly
// CHECK-FIXES: {{^ void a\(\) override {}}}
void b() override {}
@@ -141,7 +141,7 @@ public:
// CHECK-FIXES: {{^ void c\(\) override {}}}
virtual void d() override {}
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Annotate this
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use exactly
// CHECK-FIXES: {{^ void d\(\) override {}}}
virtual void j() const {}
@@ -161,7 +161,7 @@ struct Macros : public Base {
// Tests for 'virtual' and 'override' being defined through macros. Basically
// give up for now.
NOT_VIRTUAL void a() NOT_OVERRIDE;
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: Annotate this
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: Use exactly
// CHECK-FIXES: {{^ NOT_VIRTUAL void a\(\) override NOT_OVERRIDE;}}
VIRTUAL void b() NOT_OVERRIDE;
@@ -173,7 +173,7 @@ struct Macros : public Base {
// CHECK-FIXES: {{^ NOT_VIRTUAL void c\(\) OVERRIDE;}}
VIRTUAL void d() OVERRIDE;
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Annotate this
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use exactly
// CHECK-FIXES: {{^ VIRTUAL void d\(\) OVERRIDE;}}
#define FUNC(return_type, name) return_type name()
@@ -185,7 +185,7 @@ struct Macros : public Base {
// CHECK-FIXES: {{^ F}}
VIRTUAL void g() OVERRIDE final;
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Annotate this
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use exactly
// CHECK-FIXES: {{^ VIRTUAL void g\(\) final;}}
};

View File

@@ -39,7 +39,7 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Lex/Lexer.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/Refactoring.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/CommandLine.h"
@@ -56,11 +56,11 @@ class ToolTemplateCallback : public MatchFinder::MatchCallback {
public:
ToolTemplateCallback(Replacements *Replace) : Replace(Replace) {}
void run(const MatchFinder::MatchResult &Result) override {
// TODO: This routine will get called for each thing that the matchers find.
// At this point, you can examine the match, and do whatever you want,
// including replacing the matched text with other text
(void)Replace; // This to prevent an "unused member variable" warning;
virtual void run(const MatchFinder::MatchResult &Result) {
// TODO: This routine will get called for each thing that the matchers find.
// At this point, you can examine the match, and do whatever you want,
// including replacing the matched text with other text
(void) Replace; // This to prevent an "unused member variable" warning;
}
private:
@@ -69,20 +69,39 @@ class ToolTemplateCallback : public MatchFinder::MatchCallback {
} // end anonymous namespace
// Set up the command line options
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
static cl::OptionCategory ToolTemplateCategory("tool-template options");
cl::opt<std::string> BuildPath(
cl::Positional,
cl::desc("<build-path>"));
cl::list<std::string> SourcePaths(
cl::Positional,
cl::desc("<source0> [... <sourceN>]"),
cl::OneOrMore);
int main(int argc, const char **argv) {
llvm::sys::PrintStackTraceOnErrorSignal();
CommonOptionsParser OptionsParser(argc, argv, ToolTemplateCategory);
RefactoringTool Tool(OptionsParser.getCompilations(),
OptionsParser.getSourcePathList());
std::unique_ptr<CompilationDatabase> Compilations(
FixedCompilationDatabase::loadFromCommandLine(argc, argv));
cl::ParseCommandLineOptions(argc, argv);
if (!Compilations) { // Couldn't find a compilation DB from the command line
std::string ErrorMessage;
Compilations.reset(
!BuildPath.empty() ?
CompilationDatabase::autoDetectFromDirectory(BuildPath, ErrorMessage) :
CompilationDatabase::autoDetectFromSource(SourcePaths[0], ErrorMessage)
);
// Still no compilation DB? - bail.
if (!Compilations)
llvm::report_fatal_error(ErrorMessage);
}
RefactoringTool Tool(*Compilations, SourcePaths);
ast_matchers::MatchFinder Finder;
ToolTemplateCallback Callback(&Tool.getReplacements());
// TODO: Put your matchers here.
// Use Finder.addMatcher(...) to define the patterns in the AST that you
// want to match against. You are not limited to just one matcher!
// TODO: Put your matchers here.
// Use Finder.addMatcher(...) to define the patterns in the AST that you
// want to match against. You are not limited to just one matcher!
return Tool.run(newFrontendActionFactory(&Finder).get());
}

View File

@@ -7,6 +7,5 @@ endfunction()
add_subdirectory(clang-apply-replacements)
add_subdirectory(clang-modernize)
add_subdirectory(clang-rename)
add_subdirectory(clang-query)
add_subdirectory(clang-tidy)

View File

@@ -93,8 +93,8 @@ public:
};
struct ConsumerFactory {
std::unique_ptr<ASTConsumer> newASTConsumer() {
return llvm::make_unique<TimePassingASTConsumer>(&Called);
ASTConsumer *newASTConsumer() {
return new TimePassingASTConsumer(&Called);
}
bool Called;
};

View File

@@ -1,33 +0,0 @@
set(LLVM_LINK_COMPONENTS
support
)
get_filename_component(CLANG_RENAME_SOURCE_DIR
${CMAKE_CURRENT_SOURCE_DIR}/../../clang-rename REALPATH)
include_directories(
${CLANG_RENAME_SOURCE_DIR}
)
add_extra_unittest(ClangRenameTests
USRLocFindingTest.cpp
${CLANG_RENAME_SOURCE_DIR}/USRFinder.cpp
${CLANG_RENAME_SOURCE_DIR}/USRFindingAction.cpp
)
target_link_libraries(ClangRenameTests
clangAnalysis
clangAST
clangBasic
clangDriver
clangEdit
clangFrontend
clangFrontendTool
clangIndex
clangLex
clangParse
clangRewrite
clangRewriteFrontend
clangSerialization
clangSema
clangTooling
)

View File

@@ -1,24 +0,0 @@
##===- unittests/clang-rename/Makefile ---------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
CLANG_LEVEL = ../../../..
include $(CLANG_LEVEL)/../../Makefile.config
TESTNAME = ClangRenameTests
LINK_COMPONENTS := asmparser bitreader support MC MCParser option \
TransformUtils
USEDLIBS = clangAnalysis.a clangAST.a clangBasic.a clangDriver.a clangEdit.a \
clangFrontend.a clangFrontendTool.a clangIndex.a clangLex.a \
clangParse.a clangRewrite.a clangRewriteFrontend.a \
clangSerialization.a clangSema.a clangTooling.a
include $(CLANG_LEVEL)/Makefile
MAKEFILE_UNITTEST_NO_INCLUDE_COMMON := 1
CPP.Flags += -I(PROJ_SRC_DIR)/../../clang-rename
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest

View File

@@ -1,84 +0,0 @@
#include "USRFindingAction.h"
#include "gtest/gtest.h"
#include "clang/Tooling/Tooling.h"
#include <stdio.h>
#include <set>
#include <map>
#include <vector>
namespace clang {
namespace rename {
namespace test {
// Determines if the symbol group invariants hold. To recap, those invariants
// are:
// (1) All symbols in the same symbol group share the same USR.
// (2) Two symbols from two different groups do not share the same USR.
static void testOffsetGroups(const char *Code,
const std::vector<std::vector<unsigned>> Groups) {
std::set<std::string> AllUSRs, CurrUSR;
for (const auto &Group : Groups) {
// Groups the invariants do not hold then the value of USR is also invalid,
// but at that point the test has already failed and USR ceases to be
// useful.
std::string USR;
for (const auto &Offset : Group) {
USRFindingAction Action(Offset);
auto Factory = tooling::newFrontendActionFactory(&Action);
EXPECT_TRUE(tooling::runToolOnCode(Factory->create(), Code));
const auto &USRs = Action.getUSRs();
EXPECT_EQ(1u, USRs.size());
USR = USRs[0];
CurrUSR.insert(USR);
}
EXPECT_EQ(1u, CurrUSR.size());
CurrUSR.clear();
AllUSRs.insert(USR);
}
EXPECT_EQ(Groups.size(), AllUSRs.size());
}
TEST(USRLocFinding, FindsVarUSR) {
const char VarTest[] = "\n\
namespace A {\n\
int foo;\n\
}\n\
int foo;\n\
int bar = foo;\n\
int baz = A::foo;\n\
void fun1() {\n\
struct {\n\
int foo;\n\
} b = { 100 };\n\
int foo = 100;\n\
baz = foo;\n\
{\n\
extern int foo;\n\
baz = foo;\n\
foo = A::foo + baz;\n\
A::foo = b.foo;\n\
}\n\
foo = b.foo;\n\
}\n";
std::vector<std::vector<unsigned>> VarTestOffsets(3);
VarTestOffsets[0].push_back(19);
VarTestOffsets[0].push_back(63);
VarTestOffsets[0].push_back(205);
VarTestOffsets[0].push_back(223);
VarTestOffsets[1].push_back(30);
VarTestOffsets[1].push_back(45);
VarTestOffsets[1].push_back(172);
VarTestOffsets[1].push_back(187);
VarTestOffsets[2].push_back(129);
VarTestOffsets[2].push_back(148);
VarTestOffsets[2].push_back(242);
testOffsetGroups(VarTest, VarTestOffsets);
}
}
}
}

View File

@@ -28,57 +28,57 @@ TEST(ClangTidyDiagnosticConsumer, SortsErrors) {
EXPECT_EQ("variable []", Errors[1].Message.Message);
}
TEST(GlobList, Empty) {
GlobList Filter("");
TEST(ChecksFilter, Empty) {
ChecksFilter Filter("");
EXPECT_TRUE(Filter.contains(""));
EXPECT_FALSE(Filter.contains("aaa"));
EXPECT_TRUE(Filter.isCheckEnabled(""));
EXPECT_FALSE(Filter.isCheckEnabled("aaa"));
}
TEST(GlobList, Nothing) {
GlobList Filter("-*");
TEST(ChecksFilter, Nothing) {
ChecksFilter Filter("-*");
EXPECT_FALSE(Filter.contains(""));
EXPECT_FALSE(Filter.contains("a"));
EXPECT_FALSE(Filter.contains("-*"));
EXPECT_FALSE(Filter.contains("-"));
EXPECT_FALSE(Filter.contains("*"));
EXPECT_FALSE(Filter.isCheckEnabled(""));
EXPECT_FALSE(Filter.isCheckEnabled("a"));
EXPECT_FALSE(Filter.isCheckEnabled("-*"));
EXPECT_FALSE(Filter.isCheckEnabled("-"));
EXPECT_FALSE(Filter.isCheckEnabled("*"));
}
TEST(GlobList, Everything) {
GlobList Filter("*");
TEST(ChecksFilter, Everything) {
ChecksFilter Filter("*");
EXPECT_TRUE(Filter.contains(""));
EXPECT_TRUE(Filter.contains("aaaa"));
EXPECT_TRUE(Filter.contains("-*"));
EXPECT_TRUE(Filter.contains("-"));
EXPECT_TRUE(Filter.contains("*"));
EXPECT_TRUE(Filter.isCheckEnabled(""));
EXPECT_TRUE(Filter.isCheckEnabled("aaaa"));
EXPECT_TRUE(Filter.isCheckEnabled("-*"));
EXPECT_TRUE(Filter.isCheckEnabled("-"));
EXPECT_TRUE(Filter.isCheckEnabled("*"));
}
TEST(GlobList, Simple) {
GlobList Filter("aaa");
TEST(ChecksFilter, Simple) {
ChecksFilter Filter("aaa");
EXPECT_TRUE(Filter.contains("aaa"));
EXPECT_FALSE(Filter.contains(""));
EXPECT_FALSE(Filter.contains("aa"));
EXPECT_FALSE(Filter.contains("aaaa"));
EXPECT_FALSE(Filter.contains("bbb"));
EXPECT_TRUE(Filter.isCheckEnabled("aaa"));
EXPECT_FALSE(Filter.isCheckEnabled(""));
EXPECT_FALSE(Filter.isCheckEnabled("aa"));
EXPECT_FALSE(Filter.isCheckEnabled("aaaa"));
EXPECT_FALSE(Filter.isCheckEnabled("bbb"));
}
TEST(GlobList, Complex) {
GlobList Filter("*,-a.*,-b.*,a.1.*,-a.1.A.*,-..,-...,-..+,-*$,-*qwe*");
TEST(ChecksFilter, Complex) {
ChecksFilter Filter("*,-a.*,-b.*,a.1.*,-a.1.A.*,-..,-...,-..+,-*$,-*qwe*");
EXPECT_TRUE(Filter.contains("aaa"));
EXPECT_TRUE(Filter.contains("qqq"));
EXPECT_FALSE(Filter.contains("a."));
EXPECT_FALSE(Filter.contains("a.b"));
EXPECT_FALSE(Filter.contains("b."));
EXPECT_FALSE(Filter.contains("b.b"));
EXPECT_TRUE(Filter.contains("a.1.b"));
EXPECT_FALSE(Filter.contains("a.1.A.a"));
EXPECT_FALSE(Filter.contains("qwe"));
EXPECT_FALSE(Filter.contains("asdfqweasdf"));
EXPECT_TRUE(Filter.contains("asdfqwEasdf"));
EXPECT_TRUE(Filter.isCheckEnabled("aaa"));
EXPECT_TRUE(Filter.isCheckEnabled("qqq"));
EXPECT_FALSE(Filter.isCheckEnabled("a."));
EXPECT_FALSE(Filter.isCheckEnabled("a.b"));
EXPECT_FALSE(Filter.isCheckEnabled("b."));
EXPECT_FALSE(Filter.isCheckEnabled("b.b"));
EXPECT_TRUE(Filter.isCheckEnabled("a.1.b"));
EXPECT_FALSE(Filter.isCheckEnabled("a.1.A.a"));
EXPECT_FALSE(Filter.isCheckEnabled("qwe"));
EXPECT_FALSE(Filter.isCheckEnabled("asdfqweasdf"));
EXPECT_TRUE(Filter.isCheckEnabled("asdfqwEasdf"));
}
} // namespace test

View File

@@ -41,26 +41,22 @@ private:
template <typename T>
std::string runCheckOnCode(StringRef Code,
std::vector<ClangTidyError> *Errors = nullptr,
const Twine &Filename = "input.cc",
ArrayRef<std::string> ExtraArgs = None) {
std::vector<ClangTidyError> *Errors = nullptr) {
T Check;
ClangTidyContext Context(
new DefaultOptionsProvider(ClangTidyGlobalOptions(), ClangTidyOptions()));
ClangTidyDiagnosticConsumer DiagConsumer(Context);
Check.setContext(&Context);
std::vector<std::string> ArgCXX11(1, "-std=c++11");
ArgCXX11.insert(ArgCXX11.end(), ExtraArgs.begin(), ExtraArgs.end());
if (!tooling::runToolOnCodeWithArgs(new TestPPAction(Check, &Context), Code,
ArgCXX11, Filename))
ArgCXX11))
return "";
ast_matchers::MatchFinder Finder;
Check.registerMatchers(&Finder);
std::unique_ptr<tooling::FrontendActionFactory> Factory(
tooling::newFrontendActionFactory(&Finder));
if (!tooling::runToolOnCodeWithArgs(Factory->create(), Code, ArgCXX11,
Filename))
if (!tooling::runToolOnCodeWithArgs(Factory->create(), Code, ArgCXX11))
return "";
DiagConsumer.finish();
tooling::Replacements Fixes;

View File

@@ -1,5 +1,4 @@
#include "ClangTidyTest.h"
#include "llvm/HeaderGuardCheck.h"
#include "llvm/IncludeOrderCheck.h"
#include "llvm/NamespaceCommentCheck.h"
#include "gtest/gtest.h"
@@ -86,49 +85,6 @@ TEST(NamespaceCommentCheckTest, FixWrongComments) {
"} // namespace asdf"));
}
// FIXME: It seems this might be incompatible to dos path. Investigating.
#if !defined(_WIN32)
static std::string runHeaderGuardCheck(StringRef Code, const Twine &Filename) {
return test::runCheckOnCode<LLVMHeaderGuardCheck>(
Code, /*Errors=*/nullptr, Filename, std::string("-xc++-header"));
}
TEST(LLVMHeaderGuardCheckTest, FixHeaderGuards) {
EXPECT_EQ("#ifndef LLVM_ADT_FOO_H\n#define LLVM_ADT_FOO_H\n#endif\n",
runHeaderGuardCheck("#ifndef FOO\n#define FOO\n#endif\n",
"include/llvm/ADT/foo.h"));
// Allow trailing underscores.
EXPECT_EQ("#ifndef LLVM_ADT_FOO_H_\n#define LLVM_ADT_FOO_H_\n#endif\n",
runHeaderGuardCheck(
"#ifndef LLVM_ADT_FOO_H_\n#define LLVM_ADT_FOO_H_\n#endif\n",
"include/llvm/ADT/foo.h"));
EXPECT_EQ("#ifndef LLVM_CLANG_C_BAR_H\n#define LLVM_CLANG_C_BAR_H\n\n\n#endif\n",
runHeaderGuardCheck("", "./include/clang-c/bar.h"));
EXPECT_EQ("#ifndef LLVM_CLANG_LIB_CODEGEN_C_H\n#define "
"LLVM_CLANG_LIB_CODEGEN_C_H\n\n\n#endif\n",
runHeaderGuardCheck("", "tools/clang/lib/CodeGen/c.h"));
EXPECT_EQ("#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_X_H\n#define "
"LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_X_H\n\n\n#endif\n",
runHeaderGuardCheck("", "tools/clang/tools/extra/clang-tidy/x.h"));
EXPECT_EQ(
"int foo;\n#ifndef LLVM_CLANG_BAR_H\n#define LLVM_CLANG_BAR_H\n#endif\n",
runHeaderGuardCheck("int foo;\n#ifndef LLVM_CLANG_BAR_H\n"
"#define LLVM_CLANG_BAR_H\n#endif\n",
"include/clang/bar.h"));
EXPECT_EQ("#ifndef LLVM_CLANG_BAR_H\n#define LLVM_CLANG_BAR_H\n\n"
"int foo;\n#ifndef FOOLOLO\n#define FOOLOLO\n#endif\n\n#endif\n",
runHeaderGuardCheck(
"int foo;\n#ifndef FOOLOLO\n#define FOOLOLO\n#endif\n",
"include/clang/bar.h"));
}
#endif
} // namespace test
} // namespace tidy
} // namespace clang

View File

@@ -14,7 +14,7 @@ TESTNAME = ClangTidy
LINK_COMPONENTS := asmparser bitreader support MC MCParser option \
TransformUtils
USEDLIBS = clangTidy.a clangTidyLLVMModule.a clangTidyGoogleModule.a \
clangTidyMiscModule.a clangTidy.a clangTidyUtils.a \
clangTidyMiscModule.a clangTidy.a \
clangStaticAnalyzerFrontend.a clangStaticAnalyzerCheckers.a \
clangStaticAnalyzerCore.a \
clangFormat.a clangTooling.a clangFrontend.a clangSerialization.a \

View File

@@ -1086,7 +1086,6 @@ CursorKind.CUDACONSTANT_ATTR = CursorKind(412)
CursorKind.CUDADEVICE_ATTR = CursorKind(413)
CursorKind.CUDAGLOBAL_ATTR = CursorKind(414)
CursorKind.CUDAHOST_ATTR = CursorKind(415)
CursorKind.CUDASHARED_ATTR = CursorKind(416)
###
# Preprocessing
@@ -1177,23 +1176,15 @@ class Cursor(Structure):
"""
Return the display name for the entity referenced by this cursor.
The display name contains extra information that helps identify the
cursor, such as the parameters of a function or template or the
arguments of a class template specialization.
The display name contains extra information that helps identify the cursor,
such as the parameters of a function or template or the arguments of a
class template specialization.
"""
if not hasattr(self, '_displayname'):
self._displayname = conf.lib.clang_getCursorDisplayName(self)
return self._displayname
@property
def mangled_name(self):
"""Return the mangled name for the entity referenced by this cursor."""
if not hasattr(self, '_mangled_name'):
self._mangled_name = conf.lib.clang_Cursor_getMangling(self)
return self._mangled_name
@property
def location(self):
"""
@@ -2982,11 +2973,6 @@ functionList = [
_CXString,
_CXString.from_result),
("clang_Cursor_getMangling",
[Cursor],
_CXString,
_CXString.from_result),
# ("clang_getCXTUResourceUsage",
# [TranslationUnit],
# CXTUResourceUsage),

View File

@@ -252,17 +252,3 @@ def test_referenced():
if c.kind == CursorKind.CALL_EXPR:
assert c.referenced.spelling == foo.spelling
break
def test_mangled_name():
kInputForMangling = """\
int foo(int, int);
"""
tu = get_tu(kInputForMangling, lang='cpp')
foo = get_cursor(tu, 'foo')
# Since libclang does not link in targets, we cannot pass a triple to it
# and force the target. To enable this test to pass on all platforms, accept
# all valid manglings.
# [c-index-test handles this by running the source through clang, emitting
# an AST file and running libclang on that AST file]
assert foo.mangled_name in ('_Z3fooii', '__Z3fooii', '?foo@@YAHHH')

View File

@@ -33,43 +33,6 @@ The ``.clang-format`` file uses YAML format:
# A comment.
...
The configuration file can consist of several sections each having different
``Language:`` parameter denoting the programming language this section of the
configuration is targeted at. See the description of the **Language** option
below for the list of supported languages. The first section may have no
language set, it will set the default style options for all lanugages.
Configuration sections for specific language will override options set in the
default section.
When :program:`clang-format` formats a file, it auto-detects the language using
the file name. When formatting standard input or a file that doesn't have the
extension corresponding to its language, ``-assume-filename=`` option can be
used to override the file name :program:`clang-format` uses to detect the
language.
An example of a configuration file for multiple languages:
.. code-block:: yaml
---
# We'll use defaults from the LLVM style, but with 4 columns indentation.
BasedOnStyle: LLVM
IndentWidth: 4
---
Language: Cpp
# Force pointers to the type for C++.
DerivePointerAlignment: false
PointerAlignment: Left
---
Language: JavaScript
# Use 100 columns for JS.
ColumnLimit: 100
---
Language: Proto
# Don't format .proto files.
DisableFormat: true
...
An easy way to get a valid ``.clang-format`` file containing all configuration
options of a certain predefined style is:
@@ -170,13 +133,6 @@ the configuration (without a prefix: ``Auto``).
If ``true``, ``while (true) continue;`` can be put on a
single line.
**AlwaysBreakAfterDefinitionReturnType** (``bool``)
If ``true``, always break after function definition return types.
More truthfully called 'break before the identifier following the type
in a function definition'. PenaltyReturnTypeOnItsOwnLine becomes
irrelevant.
**AlwaysBreakBeforeMultilineStrings** (``bool``)
If ``true``, always break before multiline string literals.
@@ -202,7 +158,7 @@ the configuration (without a prefix: ``Auto``).
Like ``Attach``, but break before braces on function, namespace and
class definitions.
* ``BS_Stroustrup`` (in configuration: ``Stroustrup``)
Like ``Attach``, but break before function definitions, and 'else'.
Like ``Attach``, but break before function definitions.
* ``BS_Allman`` (in configuration: ``Allman``)
Always break before braces.
* ``BS_GNU`` (in configuration: ``GNU``)
@@ -257,7 +213,7 @@ the configuration (without a prefix: ``Auto``).
**DerivePointerAlignment** (``bool``)
If ``true``, analyze the formatted file for the most common
alignment of ``&`` and ``*``. ``PointerAlignment`` is then used only as fallback.
alignment of & and *. ``PointerAlignment`` is then used only as fallback.
**DisableFormat** (``bool``)
Disables formatting at all.

View File

@@ -1843,7 +1843,7 @@ iterations. Full unrolling is only possible if the loop trip count is known at
compile time. Partial unrolling replicates the loop body within the loop and
reduces the trip count.
If ``unroll(full)`` is specified the unroller will attempt to fully unroll the
If ``unroll(enable)`` is specified the unroller will attempt to fully unroll the
loop if the trip count is known at compile time. If the loop count is not known
or the fully unrolled code size is greater than the limit specified by the
`-pragma-unroll-threshold` command line option the loop will be partially
@@ -1851,7 +1851,7 @@ unrolled subject to the same limit.
.. code-block:: c++
#pragma clang loop unroll(full)
#pragma clang loop unroll(enable)
for(...) {
...
}

View File

@@ -319,16 +319,6 @@ usingDecl()
matches using X::x </pre></td></tr>
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('usingDirectiveDecl0')"><a name="usingDirectiveDecl0Anchor">usingDirectiveDecl</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1UsingDirectiveDecl.html">UsingDirectiveDecl</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="usingDirectiveDecl0"><pre>Matches using namespace declarations.
Given
namespace X { int x; }
using namespace X;
usingDirectiveDecl()
matches using namespace X </pre></td></tr>
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('varDecl0')"><a name="varDecl0Anchor">varDecl</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="varDecl0"><pre>Matches variable declarations.
@@ -365,14 +355,6 @@ nestedNameSpecifier()
</pre></td></tr>
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('CUDAKernelCallExpr0')"><a name="CUDAKernelCallExpr0Anchor">CUDAKernelCallExpr</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CUDAKernelCallExpr.html">CUDAKernelCallExpr</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="CUDAKernelCallExpr0"><pre>Matches CUDA kernel call expression.
Example matches,
kernel&lt;&lt;&lt;i,j&gt;&gt;&gt;();
</pre></td></tr>
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('arraySubscriptExpr0')"><a name="arraySubscriptExpr0Anchor">arraySubscriptExpr</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ArraySubscriptExpr.html">ArraySubscriptExpr</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="arraySubscriptExpr0"><pre>Matches array subscript expressions.
@@ -729,7 +711,7 @@ Given
int a[] = { 1, 2 };
struct B { int x, y; };
B b = { 5, 6 };
initListExpr()
initList()
matches "{ 1, 2 }" and "{ 5, 6 }"
</pre></td></tr>
@@ -894,18 +876,6 @@ Example matches "abcd", L"abcd"
</pre></td></tr>
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('substNonTypeTemplateParmExpr0')"><a name="substNonTypeTemplateParmExpr0Anchor">substNonTypeTemplateParmExpr</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1SubstNonTypeTemplateParmExpr.html">SubstNonTypeTemplateParmExpr</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="substNonTypeTemplateParmExpr0"><pre>Matches substitutions of non-type template parameters.
Given
template &lt;int N&gt;
struct A { static const int n = N; };
struct B : public A&lt;42&gt; {};
substNonTypeTemplateParmExpr()
matches "N" in the right-hand side of "static const int n = N;"
</pre></td></tr>
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('switchCase0')"><a name="switchCase0Anchor">switchCase</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1SwitchCase.html">SwitchCase</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="switchCase0"><pre>Matches case and default statements inside switch statements.
@@ -1299,7 +1269,6 @@ Given
int a[] = { 2, 3 }
int b[42];
int c[a[0]];
}
variableArrayType()
matches "int c[a[0]]"
</pre></td></tr>
@@ -1412,6 +1381,26 @@ constructorDecl(hasAnyConstructorInitializer(isWritten()))
</pre></td></tr>
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>&gt;</td><td class="name" onclick="toggle('hasOverloadedOperatorName0')"><a name="hasOverloadedOperatorName0Anchor">hasOverloadedOperatorName</a></td><td>StringRef Name</td></tr>
<tr><td colspan="4" class="doc" id="hasOverloadedOperatorName0"><pre>Matches overloaded operator names.
Matches overloaded operator names specified in strings without the
"operator" prefix: e.g. "&lt;&lt;".
Given:
class A { int operator*(); };
const A &amp;operator&lt;&lt;(const A &amp;a, const A &amp;b);
A a;
a &lt;&lt; a; &lt;-- This matches
operatorCallExpr(hasOverloadedOperatorName("&lt;&lt;"))) matches the specified
line and recordDecl(hasMethod(hasOverloadedOperatorName("*"))) matches
the declaration of A.
Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXOperatorCallExpr.html">CXXOperatorCallExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>&gt;
</pre></td></tr>
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>&gt;</td><td class="name" onclick="toggle('isConst0')"><a name="isConst0Anchor">isConst</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isConst0"><pre>Matches if the given method declaration is const.
@@ -1481,7 +1470,7 @@ operatorCallExpr(hasOverloadedOperatorName("&lt;&lt;"))) matches the specified
line and recordDecl(hasMethod(hasOverloadedOperatorName("*"))) matches
the declaration of A.
Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXOperatorCallExpr.html">CXXOperatorCallExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;
Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXOperatorCallExpr.html">CXXOperatorCallExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>&gt;
</pre></td></tr>
@@ -1612,30 +1601,10 @@ and reference to that variable declaration within a compound statement.
</pre></td></tr>
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('hasCudaDeviceAttr0')"><a name="hasCudaDeviceAttr0Anchor">hasCudaDeviceAttr</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="hasCudaDeviceAttr0"><pre>Matches declaration that has CUDA device attribute.
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('equalsNode0')"><a name="equalsNode0Anchor">equalsNode</a></td><td>Decl *Node</td></tr>
<tr><td colspan="4" class="doc" id="equalsNode0"><pre>Matches if a node equals another node.
Given
__attribute__((device)) void f() { ... }
matches the function declaration of f.
</pre></td></tr>
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('hasCudaGlobalAttr0')"><a name="hasCudaGlobalAttr0Anchor">hasCudaGlobalAttr</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="hasCudaGlobalAttr0"><pre>Matches declaration that has CUDA global attribute.
Given
__attribute__((global)) void f() { ... }
matches the function declaration of f.
</pre></td></tr>
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('hasCudaHostAttr0')"><a name="hasCudaHostAttr0Anchor">hasCudaHostAttr</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="hasCudaHostAttr0"><pre>Matches declaration that has CUDA host attribute.
Given
__attribute__((host)) void f() { ... }
matches the function declaration of f.
Decl has pointer identity in the AST.
</pre></td></tr>
@@ -1698,26 +1667,6 @@ Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Charac
</pre></td></tr>
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('hasOverloadedOperatorName0')"><a name="hasOverloadedOperatorName0Anchor">hasOverloadedOperatorName</a></td><td>StringRef Name</td></tr>
<tr><td colspan="4" class="doc" id="hasOverloadedOperatorName0"><pre>Matches overloaded operator names.
Matches overloaded operator names specified in strings without the
"operator" prefix: e.g. "&lt;&lt;".
Given:
class A { int operator*(); };
const A &amp;operator&lt;&lt;(const A &amp;a, const A &amp;b);
A a;
a &lt;&lt; a; &lt;-- This matches
operatorCallExpr(hasOverloadedOperatorName("&lt;&lt;"))) matches the specified
line and recordDecl(hasMethod(hasOverloadedOperatorName("*"))) matches
the declaration of A.
Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXOperatorCallExpr.html">CXXOperatorCallExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;
</pre></td></tr>
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('isDefinition2')"><a name="isDefinition2Anchor">isDefinition</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isDefinition2"><pre>Matches if a declaration has a body attached.
@@ -1733,17 +1682,6 @@ Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TagDec
</pre></td></tr>
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('isDeleted0')"><a name="isDeleted0Anchor">isDeleted</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isDeleted0"><pre>Matches deleted function declarations.
Given:
void Func();
void DeletedFunc() = delete;
functionDecl(isDeleted())
matches the declaration of DeletedFunc, but not Func.
</pre></td></tr>
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('isExplicitTemplateSpecialization0')"><a name="isExplicitTemplateSpecialization0Anchor">isExplicitTemplateSpecialization</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isExplicitTemplateSpecialization0"><pre>Matches explicit template specializations of function, class, or
static member variable template instantiations.
@@ -1962,6 +1900,14 @@ and reference to that variable declaration within a compound statement.
</pre></td></tr>
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('equalsNode1')"><a name="equalsNode1Anchor">equalsNode</a></td><td>Stmt *Node</td></tr>
<tr><td colspan="4" class="doc" id="equalsNode1"><pre>Matches if a node equals another node.
Stmt has pointer identity in the AST.
</pre></td></tr>
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TagDecl.html">TagDecl</a>&gt;</td><td class="name" onclick="toggle('isDefinition0')"><a name="isDefinition0Anchor">isDefinition</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isDefinition0"><pre>Matches if a declaration has a body attached.
@@ -2604,7 +2550,7 @@ given matcher.
Example matches y.x() (matcher = callExpr(callee(methodDecl(hasName("x")))))
class Y { public: void x(); };
void z() { Y y; y.x(); }
void z() { Y y; y.x();
</pre></td></tr>
@@ -3502,7 +3448,6 @@ Example matches X &amp;x and const X &amp;y
void a(X b) {
X &amp;x = b;
const X &amp;y = b;
}
};
</pre></td></tr>

View File

@@ -208,7 +208,7 @@ Modules are modeled as if each submodule were a separate translation unit, and a
.. note::
This behavior is currently only approximated when building a module with submodules. Entities within a submodule that has already been built are visible when building later submodules in that module. This can lead to fragile modules that depend on the build order used for the submodules of the module, and should not be relied upon. This behavior is subject to change.
This behavior is currently only approximated when building a module. Entities within a submodule that has already been built are visible when building later submodules in that module. This can lead to fragile modules that depend on the build order used for the submodules of the module, and should not be relied upon.
As an example, in C, this implies that if two structs are defined in different submodules with the same name, those two types are distinct types (but may be *compatible* types if their definitions match. In C++, two structs defined with the same name in different submodules are the *same* type, and must be equivalent under C++'s One Definition Rule.
@@ -216,8 +216,6 @@ As an example, in C, this implies that if two structs are defined in different s
Clang currently only performs minimal checking for violations of the One Definition Rule.
If any submodule of a module is imported into any part of a program, the entire top-level module is considered to be part of the program. As a consequence of this, Clang may diagnose conflicts between an entity declared in an unimported submodule and an entity declared in the current translation unit, and Clang may inline or devirtualize based on knowledge from unimported submodules.
Macros
------

View File

@@ -55,7 +55,16 @@ Major New Features
would return true when the attribute spelling was known, regardless of whether
the attribute was available to the specific target. Clang now returns true
only when the attribute pertains to the current compilation target.
- Clang 3.5 now has parsing and semantic-analysis support for all OpenMP 3.1
pragmas (except atomics and ordered). LLVM's OpenMP runtime library,
originally developed by Intel, has been modified to work on ARM, PowerPC,
as well as X86. Code generation support is minimal at this point and will
continue to be developed for 3.6, along with the rest of OpenMP 3.1.
Support for OpenMP 4.0 features, such as SIMD and target accelerator
directives, is also in progress. Contributors to this work include AMD,
Argonne National Lab., IBM, Intel, Texas Instruments, University of Houston
and many others.
Improvements to Clang's diagnostics
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -67,6 +76,65 @@ about them. The improvements since the 3.4 release include:
- GCC compatibility: Clang displays a warning on unsupported gcc
optimization flags instead of an error.
- New warning `-Wabsolute-value`: Clang warns about incorrect or useless usage
of the absolute functions (`abs`, `fabsf`, etc).
.. code-block:: c
#include <stdlib.h>
void foo() {
unsigned int i=0;
abs(i);
}
returns
`warning: taking the absolute value of unsigned type 'unsigned int' has no effect [-Wabsolute-value]`
or
.. code-block:: c
#include <stdlib.h>
void plop() {
long long i=0;
abs(i);
}
returns
`warning: absolute value function 'abs' given an argument of type 'long long' but has parameter of type 'int' which may cause truncation of value [-Wabsolute-value] use function 'llabs' instead`
- New warning `-Wtautological-pointer-compare`:
.. code-block:: c++
#include <stddef.h>
void foo() {
int arr[5];
int x;
// warn on these conditionals
if (foo);
if (arr);
if (&x);
if (foo == NULL);
if (arr == NULL);
if (&x == NULL);
}
returns
`warning: comparison of address of 'x' equal to a null pointer is always false [-Wtautological-pointer-compare]`
- New warning `-Wtautological-undefined-compare`:
.. code-block:: c++
#include <stddef.h>
void f(int &x) {
if (&x == nullptr) { }
}
returns
`warning: reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false [-Wtautological-undefined-compare]`
- ...
New Compiler Flags
@@ -100,7 +168,8 @@ passes via three new flags: `-Rpass`, `-Rpass-missed` and `-Rpass-analysis`.
These flags take a POSIX regular expression which indicates the name
of the pass (or passes) that should emit optimization remarks.
The option `-u` is forwarded to the linker on gnutools toolchains.
Options `-u` and `-z` are forwarded to the linker on gnutools toolchains.
New Pragmas in Clang
-----------------------
@@ -111,29 +180,12 @@ interleaving, and unrolling to be enabled or disabled. Vector width as well
as interleave and unrolling count can be manually specified. See language
extensions for details.
Clang now supports the `#pragma unroll` and `#pragma nounroll` directives to
specify loop unrolling optimization hints. Placed just prior to the desired
loop, `#pragma unroll` directs the loop unroller to attempt to fully unroll the
loop. The pragma may also be specified with a positive integer parameter
indicating the desired unroll count: `#pragma unroll _value_`. The unroll count
parameter can be optionally enclosed in parentheses. The directive `#pragma
nounroll` indicates that the loop should not be unrolled.
Windows Support
---------------
Clang's support for building native Windows programs, compatible with Visual
C++, has improved significantly since the previous release. This includes
correctly passing non-trivial objects by value, record layout, basic debug info,
`Address Sanitizer <AddressSanitizer.html>`_ support, RTTI, name mangling,
DLL attributes, and many many bug fixes. See
`MSVC Compatibility <MSVCCompatibility.html>`_ for details.
While still considered experimental, Clang's Windows support is good enough
that Clang can self-host on Windows, and projects such as Chromium and Firefox
have been built successfully using the
`/fallback <UsersManual.html#the-fallback-option>`_ option.
Clang now supports the `#pragma unroll` directive to specify loop unrolling
optimization hints. Placed just prior to the desired loop, `#pragma unroll`
directs the loop unroller to attempt to fully unroll the loop. The pragma may
also be specified with a positive integer parameter indicating the desired
unroll count: `#pragma unroll _value_`. The unroll count parameter can be
optionally enclosed in parentheses.
C Language Changes in Clang
---------------------------
@@ -165,6 +217,13 @@ OpenCL C Language Changes in Clang
...
OpenMP C/C++ Language Changes in Clang
--------------------------------------
- `Status of supported OpenMP constructs
<https://github.com/clang-omp/clang/wiki/Status-of-supported-OpenMP-constructs>`_.
Internal API Changes
--------------------
@@ -182,6 +241,16 @@ libclang
Static Analyzer
---------------
Check for code testing a variable for 0 after using it as a denominator.
This new checker, alpha.core.TestAfterDivZero, catches issues like this:
.. code:: c
int sum = ...
int avg = sum / count; // potential division by zero...
if (count == 0) { ... } // ...caught here
The `-analyzer-config` options are now passed from scan-build through to
ccc-analyzer and then to Clang.

Some files were not shown because too many files have changed in this diff Show More