Category Archives: TCC 源码分析

TCC – string index from char str[1] to str[len]

Check TokenSym declaration firstly, TokenSym is to store a single token info.

1
2
3
4
5
6
7
8
9
10
typedef struct TokenSym {
    struct TokenSym *hash_next;
    struct Sym *sym_define; /* direct pointer to define */
    struct Sym *sym_label; /* direct pointer to label */
    struct Sym *sym_struct; /* direct pointer to structure */
    struct Sym *sym_identifier; /* direct pointer to identifier */
    int tok; /* token number */
    int len;
    char str[1];
} TokenSym;

when malloc memory, it will alloc TokenSym+len.

1
ts = tcc_malloc(sizeof(TokenSym) + len);

the later on, memcpy copy str with len to str memory.
Of course, str[1] will be out of range, but extra len memory is appended.
therefore, str[1] is expanded to str[len].

This is very popular within TCC’s struct declaration.

1
2
memcpy(ts->str, str, len);
ts->str[len] = '\0';

TCC – struct CString for string process in compiler

struct CString is major struct for string process in TCC.
It also works some api such as cstr_reset(…),cstr_ccat(…).
Here is example on how to convert “char *” to s.data.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  struct CString s;
 
  static char buf[STRING_MAX_SIZE + 1];
 
  char *p = "Test";
  char *p1 = p;
  char *p2 = p; 
 
  cstr_reset(&s);
 
  for(;;){
    if(*p2 != '\0')
      {
        p2++;
      }
    else
      break;
  }
 
  s.data = buf;  
 
  while (p1 < p2) {
    cstr_ccat(&s, *p1);
    p1++;
  }
 
  printf("%s",(char *)s.data);

preprocess_new () at tccpp.c:3199 tcc的预处理

// 这些函数算是比较基本的了,看看就明白

static inline int is_space(int ch)
{
return ch == ‘ ‘ || ch == ‘\t’ || ch == ‘\v’ || ch == ‘\f’ || ch == ‘\r’;
}
static inline int isid(int c)
{
return (c >= ‘a’ && c <= ‘z’) || (c >= ‘A’ && c <= ‘Z’) || c == ‘_’;
}
static inline int isnum(int c)
{
return c >= ‘0’ && c <= ‘9’;
}
static inline int isoct(int c)
{
return c >= ‘0’ && c <= ‘7’;
}
static inline int toup(int c)
{
return (c >= ‘a’ && c <= ‘z’) ? c – ‘a’ + ‘A’ : c;
}

preprocess_new () at tccpp.c:3199

初始化isidnum表

/* init isid table */
for(i=CH_EOF;i<256;i++)
isidnum_table[i-CH_EOF] = isid(i) || isnum(i);

// 该函数剩下几行把tcc的关键字插入 ptable (代码如下)

[code]

static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
{
TokenSym *ts, **ptable;
[/code]

[code]

//在头文件tcctok.h定义了tcc的关键字

static const char tcc_keywords[] =
#define DEF(id, str) str “\0”
#include “tcctok.h”
#undef DEF
;
[/code]

ST_FUNC TokenSym *tok_alloc(const char *str, int len)