---
title: Guía completa de Clang/LLVM
short_title: Compilador Clang
subtitle: Instalación, configuración y uso del compilador Clang
---

## Introducción a Clang y LLVM

Clang es un compilador de C, C++ y Objective-C de código abierto construido
sobre la infraestructura LLVM (Low Level Virtual Machine). Desarrollado
originalmente por Apple y ahora mantenido por la comunidad LLVM, se ha
convertido en una alternativa moderna y robusta a GCC.

### Arquitectura de LLVM / Clang

LLVM utiliza una arquitectura modular de tres fases (Frontend, Optimizador y
Backend) que se diferencia de los compiladores tradicionales monolíticos. A
continuación podés observar el flujo de compilación detallado:

:::{figure} images/arquitectura_llvm.svg
:alt: Diagrama de la arquitectura de compilación de LLVM. Se detallan las tres fases secuenciales: el Frontend de Clang (que toma el archivo fuente y genera el árbol sintáctico AST y la Representación Intermedia LLVM IR), el Optimizador independiente de la plataforma (que aplica optimizaciones sobre el código IR), y el Backend de Codegen junto con el Enlazador lld (que transforman el IR en código ensamblador y finalmente en el archivo binario ejecutable final para la máquina host).
:align: center
:width: 100%

Arquitectura modular de compilación en tres fases de LLVM / Clang.

:::
<!-- {figure} images/arquitectura_llvm.svg -->

#### Descripción de las Fases

1.  **Frontend (Clang):** Procesa tu código fuente (.c/.cpp). Realiza el
    análisis léxico (descomposición en tokens), el análisis sintáctico
    (construcción del AST - Árbol de Sintaxis Abstracta) y la validación
    semántica (chequeo de tipos y reglas del lenguaje). Finalmente, genera la
    **Representación Intermedia de LLVM (LLVM IR)**.
2.  **Representación Intermedia (LLVM IR):** Es un lenguaje de ensamblador
    universal, independiente de la arquitectura de destino. Permite que el
    optimizador trabaje sobre un estándar unificado.
3.  **Optimizador (opt):** Aplica transformaciones sobre el LLVM IR para mejorar
    el rendimiento y reducir el tamaño del ejecutable (ej: eliminación de código
    muerto, desenrollado de lazos, inlining de funciones). Es totalmente
    independiente del procesador del host.
4.  **Backend (Codegen / llc):** Toma el LLVM IR optimizado y lo traduce al
    lenguaje ensamblador específico de tu procesador (ej: x86-64).
5.  **Enlazador (lld):** Une los archivos de código objeto generados con las
    bibliotecas del sistema (como la UCRT de Windows o la glibc de Linux) para
    producir el archivo binario ejecutable final.

### ¿Por qué usar Clang?

- **Mensajes de error superiores**: Clang es famoso por sus mensajes de error
  claros y útiles, con sugerencias específicas de cómo corregir problemas.
- **Velocidad de compilación**: Generalmente más rápido que GCC, especialmente
  en proyectos grandes.
- **Arquitectura modular**: Diseñado desde cero como una biblioteca
  reutilizable, facilitando la creación de herramientas auxiliares.
- **Herramientas integradas**: Incluye clang-format, clang-tidy, clangd
  (language server) y más.
- **Análisis estático avanzado**: Mejor detección de bugs potenciales durante la
  compilación.
- **Soporte multiplataforma**: Funciona idénticamente en Linux, macOS y Windows.

:::{note}

**Historia**

Clang fue iniciado en 2007 por Chris Lattner en Apple como reemplazo de GCC en
el ecosistema de desarrollo de Apple. Desde entonces, ha crecido hasta
convertirse en el compilador por defecto en macOS, iOS, y es usado por Google en
Android y Chrome. LLVM (el backend) ganó el premio ACM Software System Award en
2012, reconociendo su impacto en la industria del software.

:::
<!-- {note} -->

## Instalación de Clang

### Linux

#### Ubuntu/Debian

Clang está disponible en los repositorios oficiales. Podés instalar la versión
estable o la más reciente:

```{code-block} bash
:linenos:
# Versión estable del repositorio (puede ser antigua)
sudo apt update
sudo apt install clang

# Instalar versión específica (recomendado)
# Las versiones actuales son 14, 15, 16, 17, 18
sudo apt install clang-18

# Verificar instalación
clang --version
clang-18 --version

```
<!-- {code-block} bash -->

**Instalación desde repositorio oficial de LLVM** (para última versión):

```{code-block} bash
:linenos:
# Descargar e instalar script de LLVM
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh

# Instalar versión específica (ejemplo: 18)
sudo ./llvm.sh 18

# Instalar todas las herramientas LLVM
sudo apt install clang-18 clangd-18 clang-tidy-18 clang-format-18 \
                 libc++-18-dev libc++abi-18-dev \
                 lldb-18 lld-18

# Configurar alternativas para usar clang-18 como 'clang'
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-18 100
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-18 100
sudo update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-18 100

```
<!-- {code-block} bash -->

#### Fedora/RHEL/CentOS

```{code-block} bash
:linenos:
# Fedora
sudo dnf install clang clang-tools-extra

# RHEL/CentOS con EPEL
sudo yum install epel-release
sudo yum install clang

# Verificar instalación
clang --version

```
<!-- {code-block} bash -->

#### Arch Linux

``` bash
# Arch siempre tiene la última versión
sudo pacman -S clang llvm lld lldb

# Verificar instalación
clang --version
```
<!-- bash -->

### Windows

#### Instalador oficial (recomendado)

1. Visitá [releases.llvm.org](https://releases.llvm.org/)
2. Descargá el instalador para Windows (ej: `LLVM-18.1.8-win64.exe`)
3. Ejecutá el instalador
4. **Importante**: Durante la instalación, marcá:
   - ☑️ "Add LLVM to the system PATH for all users"
   - ☑️ "Add LLVM to the system PATH for current user"

``` powershell
# Verificar instalación (PowerShell o CMD)
clang --version
clang++ --version
clang-format --version
```
<!-- powershell -->

### Verificación de instalación

Independientemente del sistema operativo, verificá la instalación:

```{code-block} bash
:linenos:
# Versión de Clang
clang --version

# Ubicación del ejecutable
which clang     # Linux/macOS
where clang     # Windows

# Verificar herramientas adicionales
clang-format --version
clang-tidy --version
clangd --version

# Compilar programa de prueba
echo 'int main() { return 0; }' > test.c
clang test.c -o test
./test          # Linux/macOS
test.exe        # Windows
echo $?         # Debe mostrar 0

```
<!-- {code-block} bash -->

## Uso básico de Clang

### Compilación simple

```{code-block} bash
:linenos:
# Compilar un programa básico
clang programa.c -o programa

# Especificar estándar de C
clang -std=c11 programa.c -o programa

# Con warnings habilitados (recomendado)
clang -Wall -Wextra -Wpedantic programa.c -o programa

```
<!-- {code-block} bash -->

### Comparación con GCC

Clang es compatible con las opciones de GCC. La mayoría de los flags funcionan
idénticamente:

``` bash
# Estas líneas funcionan igual con gcc o clang
clang -Wall -Wextra -std=c11 -g -O2 -o programa main.c utils.c
gcc  -Wall -Wextra -std=c11 -g -O2 -o programa main.c utils.c
```
<!-- bash -->

### Opciones de compilación comunes

#### Warnings (advertencias)

```{code-block} bash
:linenos:
# Warnings básicos (siempre usar)
clang -Wall -Wextra programa.c

# Pedantic: advierte sobre violaciones del estándar
clang -Wpedantic programa.c

# Todo como error (para CI/CD)
clang -Werror programa.c

# Warnings adicionales útiles
clang -Wconversion           # Conversiones implícitas peligrosas
clang -Wshadow               # Variables que ocultan otras
clang -Wformat=2             # Verificación estricta de printf/scanf
clang -Wcast-align           # Casts con problemas de alineación
clang -Wstrict-overflow=5    # Overflow en operaciones aritméticas

```
<!-- {code-block} bash -->

#### Niveles de optimización

```{code-block} bash
:linenos:
# Sin optimización (desarrollo/debug)
clang -O0 programa.c

# Optimización básica
clang -O1 programa.c

# Optimización estándar (recomendado para producción)
clang -O2 programa.c

# Optimización agresiva (puede incrementar tamaño)
clang -O3 programa.c

# Optimizar para tamaño
clang -Os programa.c

# Optimizar para tamaño (más agresivo)
clang -Oz programa.c

```
<!-- {code-block} bash -->

#### Información de debug

```{code-block} bash
:linenos:
# Información completa de debug para GDB/LLDB
clang -g programa.c

# Debug + sin optimizaciones (ideal para debugging)
clang -g -O0 programa.c

# Información de debug específica de LLVM
clang -glldb programa.c

```
<!-- {code-block} bash -->

#### Estándares de C

```{code-block} bash
:linenos:
# C89/C90 (ANSI C)
clang -std=c89 programa.c

# C99
clang -std=c99 programa.c

# C11 (recomendado)
clang -std=c11 programa.c

# C17/C18 (última versión estandarizada)
clang -std=c17 programa.c

# C23 (borrador, soporte parcial)
clang -std=c2x programa.c

```
<!-- {code-block} bash -->

### Compilación modular

Para proyectos con múltiples archivos:

```{code-block} bash
:linenos:
# Compilar todo en un paso
clang -Wall -Wextra -std=c11 -o programa main.c lista.c utils.c

# Compilar por separado (mejor para proyectos grandes)
clang -Wall -Wextra -std=c11 -c main.c   # genera main.o
clang -Wall -Wextra -std=c11 -c lista.c  # genera lista.o
clang -Wall -Wextra -std=c11 -c utils.c  # genera utils.o

# Linkear objetos
clang -o programa main.o lista.o utils.o

# Con bibliotecas del sistema
clang -o programa main.o lista.o utils.o -lm  # linkear libm (matemática)

```
<!-- {code-block} bash -->

### Proyectos complejos (CMake y Ninja)

Cuando tu proyecto crece y se divide en múltiples módulos, no es práctico
escribir comandos manuales en la consola. El entorno portable de la cátedra bajo
el subsistema CLANG64 de Windows incluye **CMake** y **Ninja** para la
automatización del proceso de compilación.

Podés definir un archivo `CMakeLists.txt` básico en la raíz de tu proyecto:

``` cmake
cmake_minimum_required(VERSION 3.20)
project(MiProyecto C)

set(CMAKE_C_STANDARD 11)

add_executable(programa main.c lista.c utils.c)
```
<!-- cmake -->

Y luego compilar desde tu consola ejecutando:

``` bash
# Configurar el directorio de construcción
cmake -G Ninja -B build

# Compilar el proyecto
cmake --build build
```
<!-- bash -->

Ninja utilizará el compilador Clang en paralelo para realizar compilaciones
incrementales ultrarrápidas, compilando únicamente los archivos modificados
desde la última compilación.

### Sanitizers: detectores de bugs en runtime

Una de las características más poderosas de Clang son los **sanitizers**:
herramientas que instrumentan el código para detectar bugs durante la ejecución.

#### AddressSanitizer (ASan)

Detecta:
- Buffer overflows (stack, heap, global)
- Use-after-free
- Use-after-return
- Double free
- Memory leaks

``` bash
# Compilar con AddressSanitizer
clang -fsanitize=address -g -O1 programa.c -o programa

# Ejecutar (mostrará error detallado si hay problema)
./programa
```
<!-- bash -->

**Ejemplo de output de ASan:**

```
=================================================================
==12345==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000eff4
READ of size 4 at 0x60300000eff4 thread T0
    #0 0x... in main programa.c:15
    #1 0x... in __libc_start_main
0x60300000eff4 is located 0 bytes to the right of 20-byte region
allocated by thread T0 here:
    #0 0x... in malloc
    #1 0x... in main programa.c:12
```

#### UndefinedBehaviorSanitizer (UBSan)

Detecta comportamiento indefinido:
- División por cero
- Overflow de enteros con signo
- Desreferenciación de punteros NULL
- Shifts inválidos
- Conversiones ilegales

``` bash
# Compilar con UBSan
clang -fsanitize=undefined -g programa.c -o programa

# Ejecutar
./programa
```
<!-- bash -->

#### MemorySanitizer (MSan)

Detecta uso de memoria no inicializada:

``` bash
# Compilar con MSan (solo Linux)
clang -fsanitize=memory -g -O1 programa.c -o programa

# Ejecutar
./programa
```
<!-- bash -->

#### ThreadSanitizer (TSan)

Detecta data races en programas multi-hilo:

``` bash
# Compilar con TSan
clang -fsanitize=thread -g programa.c -o programa -lpthread

# Ejecutar
./programa
```
<!-- bash -->

#### Combinar sanitizers

``` bash
# ASan + UBSan (combinación común)
clang -fsanitize=address,undefined -g programa.c -o programa

# Todos excepto TSan (TSan no se puede combinar con ASan/MSan)
clang -fsanitize=address,undefined,leak -g programa.c -o programa
```
<!-- bash -->

:::{important}

**Usar sanitizers en desarrollo**

Los sanitizers tienen un overhead de performance (2-5x más lento) y memoria
(2-3x más memoria). No son para producción, pero son invaluables durante
desarrollo y testing. Encontrarán bugs que son casi imposibles de detectar de
otra forma.

Un workflow recomendado:
1. Desarrollo normal con `-O0 -g`
2. Testing con `-fsanitize=address,undefined -g -O1`
3. Release con `-O2 -DNDEBUG` (sin sanitizers)

:::
<!-- {important} -->

## Análisis estático con Clang

Clang incluye herramientas de análisis estático que detectan bugs sin ejecutar
el código.

### Clang Static Analyzer

```{code-block} bash
:linenos:
# Análisis básico
clang --analyze programa.c

# Análisis con checks adicionales
clang --analyze -Xanalyzer -analyzer-checker=core,unix programa.c

# Ver todos los checkers disponibles
clang --analyze -Xanalyzer -analyzer-list-checkers

# Análisis completo de proyecto (con scan-build)
scan-build make

```
<!-- {code-block} bash -->

**Ejemplo de uso con proyecto:**

```{code-block} bash
:linenos:
# Limpiar compilación previa
make clean

# Compilar con análisis estático
scan-build -o analysis-results make

# Si encuentra bugs, generará reporte HTML
# Abrir con navegador:
firefox analysis-results/[fecha]/index.html

```
<!-- {code-block} bash -->

### clang-tidy: linter moderno

`clang-tidy` es una herramienta de análisis estático y refactoring que verifica
estilo y bugs potenciales.

```{code-block} bash
:linenos:
# Verificar un archivo
clang-tidy programa.c

# Con compile_commands.json (recomendado)
clang-tidy -p . programa.c

# Especificar checks
clang-tidy -checks='*' programa.c

# Checks específicos
clang-tidy -checks='bugprone-*,modernize-*,readability-*' programa.c

# Autofijar algunos problemas
clang-tidy -fix programa.c

```
<!-- {code-block} bash -->

**Archivo de configuración `.clang-tidy`:**

```{code-block} yaml
:linenos:
---
Checks: >
  -*,
  bugprone-*,
  cert-*,
  clang-analyzer-*,
  concurrency-*,
  cppcoreguidelines-*,
  misc-*,
  modernize-*,
  performance-*,
  portability-*,
  readability-*,
  -readability-magic-numbers,
  -cppcoreguidelines-avoid-magic-numbers

CheckOptions:
  - key: readability-identifier-naming.FunctionCase
    value: lower_case
  - key: readability-identifier-naming.VariableCase
    value: lower_case
  - key: readability-identifier-naming.ConstantCase
    value: UPPER_CASE

```
<!-- {code-block} yaml -->

### clang-format: formateo automático de código

`clang-format` formatea código C automáticamente según reglas configurables.

```{code-block} bash
:linenos:
# Formatear archivo (imprime a stdout)
clang-format programa.c

# Formatear in-place (modifica el archivo)
clang-format -i programa.c

# Formatear múltiples archivos
clang-format -i *.c *.h

# Usar estilo predefinido
clang-format -style=llvm programa.c
clang-format -style=google programa.c
clang-format -style=mozilla programa.c

```
<!-- {code-block} bash -->

**Archivo de configuración `.clang-format`:**

```{code-block} yaml
:linenos:
---
Language: Cpp
BasedOnStyle: LLVM
IndentWidth: 4
UseTab: Never
ColumnLimit: 100
BreakBeforeBraces: Linux
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: Never
IndentCaseLabels: false
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
PointerAlignment: Right

```
<!-- {code-block} yaml -->

Guardá este archivo en la raíz de tu proyecto. `clang-format` lo detectará
automáticamente.

``` bash
# Generar .clang-format con configuración interactiva
clang-format -style=llvm -dump-config > .clang-format

# Ahora editar .clang-format según preferencias
# Formatear respetando configuración local
clang-format -i programa.c
```
<!-- bash -->

### Integración en editor

La mayoría de los editores soportan ejecutar `clang-format` automáticamente:

**VS Code**: Instalar extensión "C/C++" y configurar en `settings.json`:

``` json
{
    "editor.formatOnSave": true,
    "C_Cpp.clang_format_style": "file"
}
```
<!-- json -->

**Vim/Neovim**: Con plugin ALE o vim-clang-format

**Emacs**: Con clang-format.el

## Herramientas avanzadas del ecosistema Clang

### clangd: Language Server

`clangd` es un language server que provee autocompletado, navegación de código,
diagnósticos en tiempo real, etc. para editores que soportan LSP (Language
Server Protocol).

```{code-block} bash
:linenos:
# Instalar clangd
sudo apt install clangd  # Linux
brew install llvm        # macOS (incluye clangd)
# Windows: incluido en instalador de LLVM

# Verificar
clangd --version

# Generar compile_commands.json para tu proyecto
# Con Make:
bear -- make

# Con CMake:
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 .

```
<!-- {code-block} bash -->

Ver la guía de VS Code en este mismo repositorio para configuración detallada de
clangd.

### LLDB: debugger de LLVM

LLDB es el debugger oficial del proyecto LLVM, alternativa a GDB.

```{code-block} bash
:linenos:
# Instalar LLDB
sudo apt install lldb       # Linux
brew install llvm           # macOS (incluye lldb)
# Windows: incluido en instalador LLVM

# Compilar con información de debug
clang -g programa.c -o programa

# Iniciar debugger
lldb programa

# Comandos básicos en LLDB
(lldb) breakpoint set --name main
(lldb) run
(lldb) next
(lldb) step
(lldb) print variable
(lldb) continue
(lldb) quit

```
<!-- {code-block} bash -->

**Comparación de comandos GDB vs LLDB:**

| Acción | GDB | LLDB |
|:-------|:----|:-----|
| Ejecutar | `run` | `run` |
| Breakpoint | `break main` | `breakpoint set --name main` o `b main` |
| Step over | `next` | `next` o `n` |
| Step into | `step` | `step` o `s` |
| Continue | `continue` | `continue` o `c` |
| Print variable | `print var` | `print var` o `p var` |
| Backtrace | `backtrace` | `thread backtrace` o `bt` |

### LLD: linker rápido

LLD es el linker de LLVM, significativamente más rápido que ld (linker
tradicional).

``` bash
# Usar LLD al compilar
clang -fuse-ld=lld programa.c -o programa

# En proyectos grandes, LLD puede reducir tiempo de linking de minutos a segundos
```
<!-- bash -->

## Diferencias y compatibilidad con GCC

### Opciones específicas de Clang

```{code-block} bash
:linenos:
# Warnings específicos de Clang
clang -Weverything programa.c  # TODOS los warnings (muy estricto)

# Colorear output (activado por defecto en terminal)
clang -fcolor-diagnostics programa.c

# Mostrar categoría de cada warning
clang -fdiagnostics-show-category=name programa.c

# Formato de diagnósticos
clang -fdiagnostics-format=vi programa.c  # Formato compatible con Vi

```
<!-- {code-block} bash -->

### Extensiones de GCC no soportadas

Algunas extensiones específicas de GCC pueden no funcionar en Clang:

```{code-block} c
:linenos:
// Nested functions (GCC extension, NO soportado en Clang)
void outer() {
    void inner() {  // ❌ Error en Clang
        printf("nested\n");
    }
    inner();
}

// Alternativa compatible:
void inner_impl() {
    printf("nested\n");
}
void outer() {
    inner_impl();
}

```
<!-- {code-block} c -->

### Pragmas y atributos

Clang soporta los atributos estándar de C11 y muchos de GCC:

```{code-block} c
:linenos:
// Atributos compatibles
__attribute__((unused)) int x;
__attribute__((warn_unused_result)) int funcion(void);

// Pragmas de Clang
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"
int x;  // No genera warning
#pragma clang diagnostic pop

```
<!-- {code-block} c -->

### Modo de compatibilidad

``` bash
# Emular versión específica de GCC (útil para compatibilidad)
clang -fgnuc-version=11 programa.c

# En Windows, emular MSVC
clang-cl programa.c  # Usa sintaxis de MSVC
```
<!-- bash -->

## Ejemplos prácticos

### Ejemplo 1: Compilación básica con buenas prácticas

```{code-block} bash
:linenos:
# Compilar programa simple con flags recomendados
clang -std=c11 \
      -Wall -Wextra -Wpedantic \
      -Wconversion -Wshadow \
      -O2 \
      -g \
      -o programa \
      programa.c

# Ejecutar
./programa

```
<!-- {code-block} bash -->

### Ejemplo 2: Proyecto con múltiples archivos

```{code-block} bash
:linenos:
# Estructura del proyecto:
# proyecto/
# +-- src/
# |   +-- main.c
# |   +-- lista.c
# |   +-- utils.c
# +-- include/
# |   +-- lista.h
# |   +-- utils.h
# +-- Makefile

# Makefile usando Clang:
cat > Makefile << 'EOF'
CC = clang
CFLAGS = -std=c11 -Wall -Wextra -Wpedantic -Iinclude
LDFLAGS = -lm
SRC = $(wildcard src/*.c)
OBJ = $(SRC:.c=.o)

programa: $(OBJ)
	$(CC) $(OBJ) $(LDFLAGS) -o $@

%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@

clean:
	rm -f $(OBJ) programa

.PHONY: clean
EOF

# Compilar
make

```
<!-- {code-block} bash -->

### Ejemplo 3: Detección de memory leaks con ASan

```{code-block} c
:linenos:
// leak.c - programa con memory leak intencional
#include <stdlib.h>

int main() {
    int *ptr = malloc(100 * sizeof(int));
    // ❌ Olvidamos hacer free(ptr)
    return 0;
}

```
<!-- {code-block} c -->

```{code-block} bash
:linenos:
# Compilar con AddressSanitizer (detecta leaks)
clang -fsanitize=address -g leak.c -o leak

# Ejecutar
./leak

# Output:
# =================================================================
# ==12345==ERROR: LeakSanitizer: detected memory leaks
# 
# Direct leak of 400 byte(s) in 1 object(s) allocated from:
#     #0 0x... in malloc
#     #1 0x... in main leak.c:4
# 
# SUMMARY: AddressSanitizer: 400 byte(s) leaked in 1 allocation(s).

```
<!-- {code-block} bash -->

### Ejemplo 4: Detección de undefined behavior

```{code-block} c
:linenos:
// ub.c - programa con comportamiento indefinido
#include <stdio.h>

int main() {
    int x = 2147483647;  // INT_MAX
    int y = x + 1;       // ❌ Overflow de entero con signo
    printf("%d\n", y);
    return 0;
}

```
<!-- {code-block} c -->

```{code-block} bash
:linenos:
# Compilar con UBSan
clang -fsanitize=undefined -g ub.c -o ub

# Ejecutar
./ub

# Output:
# ub.c:5:15: runtime error: signed integer overflow: 
# 2147483647 + 1 cannot be represented in type 'int'

```
<!-- {code-block} bash -->

### Ejemplo 5: Análisis de proyecto completo

```{code-block} bash
:linenos:
# Script para análisis completo de calidad de código

#!/bin/bash

# 1. Compilar con warnings estrictos
echo "=== Compilando con warnings estrictos ==="
clang -std=c11 -Wall -Wextra -Wpedantic -Werror programa.c -o programa

# 2. Análisis estático con clang-tidy
echo "=== Análisis estático (clang-tidy) ==="
clang-tidy programa.c -- -std=c11

# 3. Verificar formato
echo "=== Verificando formato ==="
clang-format --dry-run --Werror programa.c

# 4. Compilar con sanitizers y ejecutar tests
echo "=== Testing con AddressSanitizer ==="
clang -fsanitize=address,undefined -g programa.c -o programa-asan
./programa-asan < test_input.txt

echo "=== Análisis completo terminado ==="

```
<!-- {code-block} bash -->

### Ejemplo 6: Cross-compilation

Clang facilita la compilación cruzada (compilar en una plataforma para otra):

```{code-block} bash
:linenos:
# Compilar para otra arquitectura (en Linux)
# Ver targets disponibles:
clang --print-targets

# Compilar para ARM64
clang --target=aarch64-linux-gnu programa.c -o programa-arm64

# Compilar para Windows desde Linux
clang --target=x86_64-w64-mingw32 programa.c -o programa.exe

# Compilar para WebAssembly
clang --target=wasm32 programa.c -o programa.wasm

```
<!-- {code-block} bash -->

## Configuración para diferentes flujos de trabajo

### Para estudiantes/principiantes

```{code-block} bash
:linenos:
# Alias útiles para .bashrc o .zshrc

# Compilación básica con buenos defaults
alias cc11='clang -std=c11 -Wall -Wextra -Wpedantic -g'

# Compilación con sanitizers para detectar bugs
alias ccsan='clang -std=c11 -Wall -Wextra -fsanitize=address,undefined -g'

# Uso:
cc11 programa.c -o programa
ccsan programa.c -o programa

```
<!-- {code-block} bash -->

### Para desarrollo profesional

```{code-block} bash
:linenos:
# Makefile completo con múltiples targets

CC = clang
CFLAGS = -std=c11 -Wall -Wextra -Wpedantic -Iinclude
CFLAGS_DEBUG = $(CFLAGS) -g -O0 -DDEBUG
CFLAGS_RELEASE = $(CFLAGS) -O2 -DNDEBUG
CFLAGS_ASAN = $(CFLAGS_DEBUG) -fsanitize=address,undefined
LDFLAGS = -lm

SRC = $(wildcard src/*.c)
OBJ = $(SRC:src/%.c=build/%.o)
OBJ_DEBUG = $(SRC:src/%.c=build/debug/%.o)
OBJ_ASAN = $(SRC:src/%.c=build/asan/%.o)

all: release

release: CFLAGS = $(CFLAGS_RELEASE)
release: build/programa

debug: CFLAGS = $(CFLAGS_DEBUG)
debug: build/programa-debug

asan: CFLAGS = $(CFLAGS_ASAN)
asan: build/programa-asan

build/programa: $(OBJ)
	$(CC) $^ $(LDFLAGS) -o $@

build/programa-debug: $(OBJ_DEBUG)
	$(CC) $^ $(LDFLAGS) -o $@

build/programa-asan: $(OBJ_ASAN)
	$(CC) $^ $(LDFLAGS) -o $@

build/%.o: src/%.c | build
	$(CC) $(CFLAGS) -c $< -o $@

build/debug/%.o: src/%.c | build/debug
	$(CC) $(CFLAGS) -c $< -o $@

build/asan/%.o: src/%.c | build/asan
	$(CC) $(CFLAGS) -c $< -o $@

build build/debug build/asan:
	mkdir -p $@

clean:
	rm -rf build/

format:
	clang-format -i src/*.c include/*.h

tidy:
	clang-tidy src/*.c -- $(CFLAGS)

analyze:
	scan-build make

.PHONY: all release debug asan clean format tidy analyze

```
<!-- {code-block} bash -->

### Integración continua (CI/CD)

```{code-block} yaml
:linenos:
# .github/workflows/clang-ci.yml
# Ejemplo de CI con GitHub Actions

name: Clang CI

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Instalar Clang
      run: |
        wget https://apt.llvm.org/llvm.sh
        chmod +x llvm.sh
        sudo ./llvm.sh 18
    
    - name: Compilar con warnings estrictos
      run: |
        clang-18 -std=c11 -Wall -Wextra -Wpedantic -Werror \
                 src/*.c -o programa
    
    - name: Análisis estático (clang-tidy)
      run: |
        clang-tidy-18 src/*.c -- -std=c11
    
    - name: Verificar formato
      run: |
        clang-format-18 --dry-run --Werror src/*.c include/*.h
    
    - name: Tests con sanitizers
      run: |
        clang-18 -fsanitize=address,undefined -g src/*.c -o programa-asan
        ./programa-asan

```
<!-- {code-block} yaml -->

## Troubleshooting y problemas comunes

### Clang no encuentra headers del sistema

```{code-block} bash
:linenos:
# Ver directorios de búsqueda
clang -v -E -xc /dev/null

# En Linux, si faltan headers estándar
sudo apt install build-essential

# En macOS, instalar Xcode Command Line Tools
xcode-select --install

```
<!-- {code-block} bash -->

### Conflicto entre GCC y Clang

```{code-block} bash
:linenos:
# Verificar qué compilador se está usando
which cc
ls -la /usr/bin/cc

# Cambiar compilador por defecto (Linux)
sudo update-alternatives --config cc

# Forzar uso de Clang en Makefile
CC=clang make

```
<!-- {code-block} bash -->

### Errores de linkeo en Windows

```{code-block} powershell
:linenos:
# Asegurar que MSVC está instalado (Clang en Windows usa el linker de MSVC)
# O usar MinGW

# Con MSVC instalado
clang -o programa.exe programa.c

# Con MinGW
clang --target=x86_64-w64-mingw32 programa.c -o programa.exe

```
<!-- {code-block} powershell -->

### Sanitizers no funcionan

```{code-block} bash
:linenos:
# ASan requiere compilar SIN optimizaciones agresivas
clang -fsanitize=address -O1 -g programa.c -o programa

# NO usar -O2 o -O3 con sanitizers
# ❌ clang -fsanitize=address -O3 programa.c

# En macOS, puede requerir deshabilitar SIP
# (System Integrity Protection) para algunos casos

```
<!-- {code-block} bash -->

### Performance de clangd es lenta

```{code-block} bash
:linenos:
# Limitar uso de RAM
clangd --limit-results=20 --background-index-priority=low

# Excluir directorios grandes del índice
# Crear .clangd en raíz del proyecto:
cat > .clangd << 'EOF'
CompileFlags:
  Add: [-std=c11]
  Remove: [-W*]

Index:
  Background: Build
  
---
If:
  PathMatch: build/.*
Index:
  Background: Skip
EOF

```
<!-- {code-block} bash -->

## Recursos adicionales

### Documentación oficial

- [Clang Documentation](https://clang.llvm.org/docs/) - Documentación completa
  oficial
- [LLVM Documentation](https://llvm.org/docs/) - Documentación del proyecto LLVM
- [Clang Language
  Extensions](https://clang.llvm.org/docs/LanguageExtensions.html) - Extensiones
  y atributos
- [Clang Compiler User's Manual](https://clang.llvm.org/docs/UsersManual.html) -
  Manual del usuario

### Herramientas

- [Compiler Explorer (Godbolt)](https://godbolt.org/) - Ver código ensamblador
  generado online
- [clang-format configurator](https://zed0.co.uk/clang-format-configurator/) -
  Configurador visual de clang-format
- [C/C++ Sanitizer Guides](https://github.com/google/sanitizers) - Documentación
  de sanitizers

### Comparaciones y benchmarks

- [GCC vs Clang Benchmarks](https://www.phoronix.com/search/gcc%20clang) -
  Comparativas de performance
- [LLVM Weekly](https://llvmweekly.org/) - Newsletter con novedades

### Libros y artículos

- **Getting Started with LLVM Core Libraries** - Trabajar con la infraestructura
  LLVM
- **"Clang and LLVM Tricks"** - Blog oficial del proyecto
- **"Understanding Compilation"** series en LLVM blog

## Conclusión

Clang es una herramienta moderna y poderosa que ofrece ventajas significativas
para el desarrollo en C:

- **Mensajes de error claros** que aceleran el debugging
- **Sanitizers integrados** que detectan bugs difíciles de encontrar
- **Herramientas de calidad de código** (clang-tidy, clang-format) que mejoran
  la mantenibilidad
- **Análisis estático** que previene bugs antes de ejecutar el código
- **Velocidad de compilación** que mejora la productividad

Para estudiantes de programación, Clang es especialmente valioso: sus mensajes
de error educativos ayudan a entender qué está mal y cómo corregirlo, mientras
que los sanitizers detectan errores comunes (uso después de free, buffer
overflows, etc.) que son fundamentales de aprender a evitar.

:::{tip}

**Recomendación para el curso**

Usá Clang con estos flags durante el desarrollo:

``` bash
clang -std=c11 -Wall -Wextra -Wpedantic \
      -fsanitize=address,undefined \
      -g -O0 \
      programa.c -o programa
```
<!-- bash -->

Esto detectará la mayoría de los errores comunes automáticamente, permitiéndote
enfocarte en la lógica del programa en lugar de perseguir bugs sutiles.

:::
<!-- {tip} -->

¡Felicitaciones! Ya tenés el conocimiento para aprovechar al máximo Clang en tu
desarrollo en C.

```{code-block} bash
:linenos:
$ clang --version
clang version 18.1.8
Target: x86_64-pc-linux-gnu
Thread model: posix

$ echo "¡Listo para compilar con Clang!"
¡Listo para compilar con Clang!

```
<!-- {code-block} bash -->

---
