4.1. Migrating Source Code with Clang-Tidy¶
To aid the migration process from the cl2000 compiler to the c29clang compiler, you can use the c29clang-tidy utility either from the command line or within Code Composer Studio (CCS) Theia. This tool performs various checks of your source code and identifies code that uses cl2000-specific syntax that should be modified.
The general procedure for using the c29clang-tidy utility is as follows:
Make initial code changes to reduce the number of compiler errors and false positives that will occur when running c29clang-tidy. These code changes should include:
Remove any definitions of the fixed width types
int8_t
anduint8_t
.Remove any
extern
declarations of C28 builtin functions.Change any use of C28-only macros such as
__TMS320C28XX__
to C29-macros such as__C29__
.
Run the c29clang-tidy utility using either the command line (see Running the c29clang-tidy Utility from the Command Line) or CCS Theia (see Running the c29clang-tidy Utility from CCS Theia).
Make changes to your code based on the diagnostics provided.
Run the c29clang-tidy utility iteratively as needed.
4.1.1. Running the c29clang-tidy Utility from the Command Line¶
The c29clang-tidy command line is similar to the c29clang command line.
For example, suppose your c29clang command line is as follows:
c29clang file.c -I./include -mcpu=c29.c0
The corresponding c29clang-tidy command line would be as follows:
c29clang-tidy --checks=-*,c29migration* -header-filter=.* file.c -- -I./include -mcpu=c29.c0
Everything on the command line after
--
is treated as a normal compiler argument. Those options can be moved and duplicated as-is.The
--checks
determines which checks are disabled and/or enabled. In this example, the initial-*
turns off all checks. This is followed byc29migration*
, which enables all checks that begin with “c29migration”, which includes the C28-C29 migration checks.The
-header-filter
option tells clang-tidy which header files to check. By default, it checks none of them. In this example,.*
says to check all header files using regex.
You can use the -list-checks
option to list all the enabled checks. For example:
c29clang-tidy -list-checks \\ list default checks
c29clang-tidy -list-checks --checks=-*,c29* \\ list all C29 checks
c29clang-tidy -list-checks --checks=* \\ list all available checks
See the Clang-Tidy documentation for additional command line options that may be supported by c29clang-tidy. The -fix
flag is not supported. You may use a .clang-tidy file as described in that documentation to configure the actions performed by c29clang-tidy.
4.1.2. Running the c29clang-tidy Utility from CCS Theia¶
To run the c29clang-tidy utility within CCS Theia, follow these steps:
Make initial code changes to reduce the number of compiler errors and false positives that will occur when running c29clang-tidy. These code changes should include:
Remove any definitions of the fixed width types
int8_t
anduint8_t
.Remove any
extern
declarations of C28 builtin functions.Change any use of C28-only macros such as
__TMS320C28XX__
to C29-macros such as__C29__
.
The c29clang-tidy utility runs in the background for actions such as project creation, project import, and file modification. By default, the c29migration-c28-builtins, c29migration-c28-pragmas, and c29migration-c28-stdlib checks are run.
A list of diagnostics found by the c29clang-tidy utility is shown in the Problems view. For example:
Diagnostic messages are added to your source files. For example:
Make changes to your code based on the diagnostics provided.
4.1.3. Limitations¶
The c29clang-tidy utility does not analyze assembly code (.asm or inline asm() directives)
As with all static analyzers, false positives are possible and expected. You will need to inspect the code that results in a diagnostic message to determine whether it is a real issue.
4.1.4. Checks Performed¶
By default, the following checks are performed:
c29migration-c28-builtins
c29migration-c28-pragmas
c29migration-c28-stdlib
The other checks provided have a higher chance of returning false positives, so you will need to examine the code flagged in the diagnostics more carefully.
The c29clang-tidy utility provides the following checks:
4.1.4.1. c29migration-c28-builtins¶
This check looks for use of C28 intrinsics such as __fmax and __byte. It suggests alternatives if they are available. For example:
void test___add(int * m, int b) {
__add(m, b);
}
The diagnostic warning states that the call to __add
is a C28 intrinsic, which is not supported by this compiler. It suggests that you refer to the C29 intrinsic documentation to find an equivalent. In this case, it suggests using __builtin_c29_i32_add32_rm_d(b, m)
.
In order to use this check, you must pre-include the c28_builtins.h
file on the command line.
Builtin functions are declared internally. Since they are only declared for C28, these builtin functions are treated as undefined identifiers by the C29 compiler. This is not an issue using the C89 standard, but causes errors with C99 and later and with all C++ standards. To resolve this issue, the compiler tools supply a header file that declares all C28 builtins. This file, c28-builtins.h
, can be pre-included by clang-tidy. Using the command line above, add the --include
option as follows:
c29clang-tidy --checks=-*,c29migration* -header-filter=.* file.c -- -I./include -mcpu=c29.c0 --include c28-builtins.h
This check is performed by default by CCS Theia. It has a low chance of returning false positives.
4.1.4.2. c29migration-c28-char-range¶
This check detects operations on char
typed expressions that would be out of range for an 8-bit type. Because the unsigned char
type is 16 bits on C28 and 8 bits on C29, overflows may occur. For example:
int ret_pos_cast(char x) {
return (char)(x + 10000);
}
The diagnostic warning states that the cast to ‘char’ receives an out-of-range value from code that may assume a 16-bit byte type. It notes that the result of the expression is calculated as 10000.
To correct this issue, choose either C28 behavior by using a fixed-width 16-bit type (uint16_t) or accept C29 behavior and use a fixed-width 8-bit type (uint8_t).
This check is not performed by default by CCS Theia. It has a medium-to-high chance of returning false positives.
4.1.4.3. c29migration-c28-int-decls¶
This check suggests replacing the int
and unsigned int
types with int16_t
and uint16_t
types. For example:
void foo(int x) { int y;}
The diagnostic warning states that you should consider using a fixed-width 16-bit type to avoid issues with the increased width of int on C29 devices.
A fix-it is available that replaces int/unsigned int types with int16_t/uint16_t types and includes <stdint.h> if it is not already included.
This check is not performed by default by CCS Theia. It has a medium-to-high chance of returning false positives.
4.1.4.4. c29migration-c28-pragmas¶
This check looks for use of C28 pragmas such as #pragma DATA_SECTION. It suggests alternatives if they are available. For example:
#pragma WEAK(weakx)
int weakx;
The diagnostic warning states that the WEAK pragma is a legacy TI pragma that is not supported by this compiler. It suggests that you use __attribute__((weak))
instead.
This check is performed by default by CCS Theia. It has a low chance of returning false positives.
4.1.4.5. c29migration-c28-stdlib¶
This check looks for calls to library functions that take a number of bytes argument where the argument is not scaled by a sizeof
expression. For example:
void malloc_c_pos() {
malloc((1+23));
}
The diagnostic warning states that the call to malloc has a byte-size argument without a sizeof
expression. It suggests that you scale the size of the argument by a factor of ‘sizeof’ to avoid issues with changing byte sizes between C28 and C29.
Calls to the following library functions are checked:
aligned_alloc
calloc
malloc
realloc
memccpy
memchr
memcmp
memcpy
memmove
memset
strncmp
strncpy
fread
fwrite
This check is performed by default by CCS Theia. It has a low chance of returning false positives.
4.1.4.6. c29migration-c28-suspicious-dereference¶
This check detects dereferences (*) of pointers, where the source expression is integer-typed and contains an additive operation. For example:
int main() {
*(int*)(x + 10) = 12;}
The diagnostic warning states that the pointer cast has a suspicious integer expression incremented by bytes, which are 16 bits on C28 and 8 bits on C29. It suggests that you inspect the intent of the address and scale it accordingly if needed.
This check is not performed by default by CCS Theia. It has a medium-to-high chance of returning false positives.
4.1.4.7. c29migration-c28-types¶
This check detects pointer arithmetic on char/int-based pointers, whose bit stride changes between C28 to C29. For example:
extern void foo(char *);void test_plus(char* x) {
foo(x + 2);}
The diagnostic warning states that pointer arithmetic is performed on an expression with type ‘char’. Since ‘char’ is 16 bits on C28 and 8 bits on C29, you should choose either C28 behavior by using a fixed-width 16-bit type (uint16_t), or accept C29 behavior and use a fixed-width 8-bit type (uint8_t).
This check is not performed by default by CCS Theia. It has a high chance of returning false positives. This is an overly cautious check, and all matches should be individually vetted for intent and behavior.