// Test without serialization: // RUN: %clang_cc1 -std=gnu11 -ast-dump %s \ // RUN: | FileCheck -strict-whitespace %s // // Test with serialization: // RUN: %clang_cc1 -std=gnu11 -emit-pch -o %t %s // RUN: %clang_cc1 -x c -std=gnu11 -include-pch %t -ast-dump-all /dev/null \ // RUN: | sed -e "s/ //" -e "s/ imported//" \ // RUN: | FileCheck -strict-whitespace %s int TestLocation = 0; // CHECK: VarDecl{{.*}}TestLocation // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 0 int TestIndent = 1 + (1); // CHECK: VarDecl{{.*}}TestIndent // CHECK-NEXT: {{^}}| `-BinaryOperator{{[^()]*$}} // CHECK-NEXT: {{^}}| |-IntegerLiteral{{.*0[^()]*$}} // CHECK-NEXT: {{^}}| `-ParenExpr{{.*0[^()]*$}} // CHECK-NEXT: {{^}}| `-IntegerLiteral{{.*0[^()]*$}} void TestDeclStmt() { int x = 0; int y, z; } // CHECK: FunctionDecl{{.*}}TestDeclStmt // CHECK-NEXT: CompoundStmt // CHECK-NEXT: DeclStmt // CHECK-NEXT: VarDecl{{.*}}x // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: DeclStmt // CHECK-NEXT: VarDecl{{.*}}y // CHECK-NEXT: VarDecl{{.*}}z int TestOpaqueValueExpr = 0 ?: 1; // CHECK: VarDecl{{.*}}TestOpaqueValueExpr // CHECK-NEXT: BinaryConditionalOperator // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: OpaqueValueExpr // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: OpaqueValueExpr // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: IntegerLiteral void TestUnaryOperatorExpr(void) { char T1 = 1; int T2 = 1; T1++; T2++; // CHECK: UnaryOperator{{.*}}postfix '++' cannot overflow // CHECK-NEXT: DeclRefExpr{{.*}}'T1' 'char' // CHECK-NOT: UnaryOperator{{.*}}postfix '++' cannot overflow // CHECK: DeclRefExpr{{.*}}'T2' 'int' -T1; -T2; // CHECK: UnaryOperator{{.*}}prefix '-' cannot overflow // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr{{.*}}'T1' 'char' // CHECK-NOT: UnaryOperator{{.*}}prefix '-' cannot overflow // CHECK: ImplicitCastExpr // CHECK: DeclRefExpr{{.*}}'T2' 'int' ~T1; ~T2; // CHECK: UnaryOperator{{.*}}prefix '~' cannot overflow // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr{{.*}}'T1' 'char' // CHECK: UnaryOperator{{.*}}prefix '~' cannot overflow // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr{{.*}}'T2' 'int' } void TestGenericSelectionExpressions(int i) { _Generic(i, int : 12); // CHECK: GenericSelectionExpr 0x{{[^ ]*}} 'int' // CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}} // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} 'int' lvalue ParmVar 0x{{[^ ]*}} 'i' 'int' // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int' // FIXME: note that the following test line has a spurious whitespace. // CHECK-NEXT: case 'int' selected // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int' // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 12 _Generic(i, int : 12, default : 0); // CHECK: GenericSelectionExpr 0x{{[^ ]*}} 'int' // CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}} // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} 'int' lvalue ParmVar 0x{{[^ ]*}} 'i' 'int' // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int' // FIXME: note that the following test line has a spurious whitespace. // CHECK-NEXT: case 'int' selected // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int' // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 12 // CHECK-NEXT: default // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 0 _Generic(i, default : 0, int : 12); // CHECK: GenericSelectionExpr 0x{{[^ ]*}} 'int' // CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}} // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} 'int' lvalue ParmVar 0x{{[^ ]*}} 'i' 'int' // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int' // CHECK-NEXT: default // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 0 // FIXME: note that the following test line has a spurious whitespace. // CHECK-NEXT: case 'int' selected // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int' // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 12 _Generic(i, int : 12, float : 10, default : 100); // CHECK: GenericSelectionExpr 0x{{[^ ]*}} 'int' // CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}} // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} 'int' lvalue ParmVar 0x{{[^ ]*}} 'i' 'int' // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int' // FIXME: note that the following test line has a spurious whitespace. // CHECK-NEXT: case 'int' selected // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int' // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 12 // FIXME: note that the following test line has a spurious whitespace. // CHECK-NEXT: case 'float' // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'float' // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 10 // CHECK-NEXT: default // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 100 int j = _Generic(i, int : 12); // CHECK: DeclStmt 0x{{[^ ]*}} // CHECK-NEXT: VarDecl 0x{{[^ ]*}} col:7 j 'int' cinit // CHECK-NEXT: GenericSelectionExpr 0x{{[^ ]*}} 'int' // CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}} // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} 'int' lvalue ParmVar 0x{{[^ ]*}} 'i' 'int' // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int' // FIXME: note that the following test line has a spurious whitespace. // CHECK-NEXT: case 'int' selected // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int' // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 12 } void TestLabelsAndGoto(void) { // Note: case and default labels are handled by TestSwitch(). label1: ; // CHECK: LabelStmt 0x{{[^ ]*}} 'label1' // CHECK-NEXT: NullStmt 0x{{[^ ]*}} goto label2; // CHECK-NEXT: GotoStmt 0x{{[^ ]*}} 'label2' 0x{{[^ ]*}} label2: 0; // CHECK-NEXT: LabelStmt 0x{{[^ ]*}} 'label2' // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 0 void *ptr = &&label1; // CHECK-NEXT: DeclStmt // CHECK-NEXT: VarDecl // CHECK-NEXT: AddrLabelExpr 0x{{[^ ]*}} 'void *' label1 0x{{[^ ]*}} goto *ptr; // CHECK-NEXT: IndirectGotoStmt 0x{{[^ ]*}} // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} 'void *' lvalue Var 0x{{[^ ]*}} 'ptr' 'void *' } void TestSwitch(int i) { switch (i) { // CHECK: SwitchStmt 0x{{[^ ]*}} // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} 'int' lvalue ParmVar 0x{{[^ ]*}} 'i' 'int' // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} case 0: break; // CHECK-NEXT: CaseStmt 0x{{[^ ]*}} // CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 0 // CHECK-NEXT: BreakStmt 0x{{[^ ]*}} case 1: case 2: break; // CHECK-NEXT: CaseStmt 0x{{[^ ]*}} // CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 1 // CHECK-NEXT: CaseStmt 0x{{[^ ]*}} // CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 2 // CHECK-NEXT: BreakStmt 0x{{[^ ]*}} default: break; // CHECK-NEXT: DefaultStmt 0x{{[^ ]*}} // CHECK-NEXT: BreakStmt 0x{{[^ ]*}} case 3 ... 5: break; // CHECK-NEXT: CaseStmt 0x{{[^ ]*}} gnu_range // CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 3 // CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 5 // CHECK-NEXT: BreakStmt 0x{{[^ ]*}} } } void TestIf(_Bool b) { if (b) ; // CHECK: IfStmt 0x{{[^ ]*}} // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool' // CHECK-NEXT: NullStmt if (b) {} // CHECK: IfStmt 0x{{[^ ]*}} // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool' // CHECK-NEXT: CompoundStmt if (b) ; else ; // CHECK: IfStmt 0x{{[^ ]*}} has_else // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool' // CHECK-NEXT: NullStmt 0x{{[^ ]*}} // CHECK-NEXT: NullStmt 0x{{[^ ]*}} if (b) {} else {} // CHECK: IfStmt 0x{{[^ ]*}} has_else // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool' // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} if (b) ; else if (b) ; // CHECK: IfStmt 0x{{[^ ]*}} has_else // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool' // CHECK-NEXT: NullStmt 0x{{[^ ]*}} // CHECK-NEXT: IfStmt 0x{{[^ ]*}} // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool' // CHECK-NEXT: NullStmt 0x{{[^ ]*}} if (b) ; else if (b) ; else ; // CHECK: IfStmt 0x{{[^ ]*}} has_else // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool' // CHECK-NEXT: NullStmt 0x{{[^ ]*}} // CHECK-NEXT: IfStmt 0x{{[^ ]*}} has_else // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool' // CHECK-NEXT: NullStmt 0x{{[^ ]*}} // CHECK-NEXT: NullStmt 0x{{[^ ]*}} } void TestIteration(_Bool b) { while (b) ; // CHECK: WhileStmt 0x{{[^ ]*}} // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool' // CHECK-NEXT: NullStmt 0x{{[^ ]*}} do ; while (b); // CHECK: DoStmt 0x{{[^ ]*}} // CHECK-NEXT: NullStmt 0x{{[^ ]*}} // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool' for (int i = 0; i < 10; ++i) ; // CHECK: ForStmt 0x{{[^ ]*}} // CHECK-NEXT: DeclStmt // CHECK-NEXT: VarDecl 0x{{[^ ]*}} col:12 used i 'int' cinit // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 0 // CHECK-NEXT: <<>> // CHECK-NEXT: BinaryOperator 0x{{[^ ]*}} 'int' '<' // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} 'int' lvalue Var 0x{{[^ ]*}} 'i' 'int' // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 10 // CHECK-NEXT: UnaryOperator 0x{{[^ ]*}} 'int' prefix '++' // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} 'int' lvalue Var 0x{{[^ ]*}} 'i' 'int' // CHECK-NEXT: NullStmt for (b; b; b) ; // CHECK: ForStmt 0x{{[^ ]*}} // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool' // CHECK-NEXT: <<>> // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool' // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool' // CHECK-NEXT: NullStmt for (; b; b = !b) ; // CHECK: ForStmt 0x{{[^ ]*}} // CHECK-NEXT: <<>> // CHECK-NEXT: <<>> // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool' // CHECK-NEXT: BinaryOperator 0x{{[^ ]*}} '_Bool' '=' // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool' // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: UnaryOperator 0x{{[^ ]*}} 'int' prefix '!' cannot overflow // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool' // CHECK-NEXT: NullStmt for (; b;) ; // CHECK: ForStmt 0x{{[^ ]*}} // CHECK-NEXT: <<>> // CHECK-NEXT: <<>> // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool' // CHECK-NEXT: <<>> // CHECK-NEXT: NullStmt for (;; b = !b) ; // CHECK: ForStmt 0x{{[^ ]*}} // CHECK-NEXT: <<>> // CHECK-NEXT: <<>> // CHECK-NEXT: <<>> // CHECK-NEXT: BinaryOperator 0x{{[^ ]*}} '_Bool' '=' // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool' // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: UnaryOperator 0x{{[^ ]*}} 'int' prefix '!' cannot overflow // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool' // CHECK-NEXT: NullStmt for (;;) ; // CHECK: ForStmt 0x{{[^ ]*}} // CHECK-NEXT: <<>> // CHECK-NEXT: <<>> // CHECK-NEXT: <<>> // CHECK-NEXT: <<>> // CHECK-NEXT: NullStmt } void TestJumps(void) { // goto and computed goto was tested in TestLabelsAndGoto(). while (1) { continue; // CHECK: ContinueStmt 0x{{[^ ]*}} break; // CHECK: BreakStmt 0x{{[^ ]*}} } return; // CHECK: ReturnStmt 0x{{[^ ]*}} return TestSwitch(1); // CHECK: ReturnStmt 0x{{[^ ]*}} // CHECK-NEXT: CallExpr 0x{{[^ ]*}} 'void' } void TestMiscStmts(void) { ({int a = 10; a;}); // CHECK: StmtExpr 0x{{[^ ]*}} 'int' // CHECK-NEXT: CompoundStmt // CHECK-NEXT: DeclStmt // CHECK-NEXT: VarDecl 0x{{[^ ]*}} col:9 used a 'int' cinit // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 10 // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} 'int' lvalue Var 0x{{[^ ]*}} 'a' 'int' ({int a = 10; a;;; }); // CHECK-NEXT: StmtExpr 0x{{[^ ]*}} 'int' // CHECK-NEXT: CompoundStmt // CHECK-NEXT: DeclStmt // CHECK-NEXT: VarDecl 0x{{[^ ]*}} col:9 used a 'int' cinit // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 10 // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} 'int' lvalue Var 0x{{[^ ]*}} 'a' 'int' // CHECK-NEXT: NullStmt // CHECK-NEXT: NullStmt }