Index: cfe/trunk/lib/CodeGen/CGStmt.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGStmt.cpp +++ cfe/trunk/lib/CodeGen/CGStmt.cpp @@ -45,7 +45,7 @@ } } -void CodeGenFunction::EmitStmt(const Stmt *S) { +void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef Attrs) { assert(S && "Null statement?"); PGO.setCurrentStmt(S); @@ -131,16 +131,16 @@ case Stmt::IndirectGotoStmtClass: EmitIndirectGotoStmt(cast(*S)); break; - case Stmt::IfStmtClass: EmitIfStmt(cast(*S)); break; - case Stmt::WhileStmtClass: EmitWhileStmt(cast(*S)); break; - case Stmt::DoStmtClass: EmitDoStmt(cast(*S)); break; - case Stmt::ForStmtClass: EmitForStmt(cast(*S)); break; - - case Stmt::ReturnStmtClass: EmitReturnStmt(cast(*S)); break; - - case Stmt::SwitchStmtClass: EmitSwitchStmt(cast(*S)); break; - case Stmt::GCCAsmStmtClass: // Intentional fall-through. - case Stmt::MSAsmStmtClass: EmitAsmStmt(cast(*S)); break; + case Stmt::IfStmtClass: EmitIfStmt(cast(*S)); break; + case Stmt::WhileStmtClass: EmitWhileStmt(cast(*S), Attrs); break; + case Stmt::DoStmtClass: EmitDoStmt(cast(*S), Attrs); break; + case Stmt::ForStmtClass: EmitForStmt(cast(*S), Attrs); break; + + case Stmt::ReturnStmtClass: EmitReturnStmt(cast(*S)); break; + + case Stmt::SwitchStmtClass: EmitSwitchStmt(cast(*S)); break; + case Stmt::GCCAsmStmtClass: // Intentional fall-through. + case Stmt::MSAsmStmtClass: EmitAsmStmt(cast(*S)); break; case Stmt::CoroutineBodyStmtClass: EmitCoroutineBody(cast(*S)); break; @@ -178,7 +178,7 @@ EmitCXXTryStmt(cast(*S)); break; case Stmt::CXXForRangeStmtClass: - EmitCXXForRangeStmt(cast(*S)); + EmitCXXForRangeStmt(cast(*S), Attrs); break; case Stmt::SEHTryStmtClass: EmitSEHTryStmt(cast(*S)); @@ -555,23 +555,7 @@ } void CodeGenFunction::EmitAttributedStmt(const AttributedStmt &S) { - const Stmt *SubStmt = S.getSubStmt(); - switch (SubStmt->getStmtClass()) { - case Stmt::DoStmtClass: - EmitDoStmt(cast(*SubStmt), S.getAttrs()); - break; - case Stmt::ForStmtClass: - EmitForStmt(cast(*SubStmt), S.getAttrs()); - break; - case Stmt::WhileStmtClass: - EmitWhileStmt(cast(*SubStmt), S.getAttrs()); - break; - case Stmt::CXXForRangeStmtClass: - EmitCXXForRangeStmt(cast(*SubStmt), S.getAttrs()); - break; - default: - EmitStmt(SubStmt); - } + EmitStmt(S.getSubStmt(), S.getAttrs()); } void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) { Index: cfe/trunk/lib/CodeGen/CodeGenFunction.h =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.h +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h @@ -2534,7 +2534,7 @@ /// This function may clear the current insertion point; callers should use /// EnsureInsertPoint if they wish to subsequently generate code without first /// calling EmitBlock, EmitBranch, or EmitStmt. - void EmitStmt(const Stmt *S); + void EmitStmt(const Stmt *S, ArrayRef Attrs = None); /// EmitSimpleStmt - Try to emit a "simple" statement which does not /// necessarily require an insertion point or debug information; typically Index: cfe/trunk/test/CodeGen/debug-info-attributed-stmt.c =================================================================== --- cfe/trunk/test/CodeGen/debug-info-attributed-stmt.c +++ cfe/trunk/test/CodeGen/debug-info-attributed-stmt.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple x86_64-unk-unk -debug-info-kind=limited -emit-llvm %s -o - | FileCheck %s + +void f(_Bool b) +{ +#pragma nounroll + while (b); +} + +// CHECK: br label %while.cond, !dbg ![[NUM:[0-9]+]] +// CHECK: br i1 %tobool, label %while.body, label %while.end, !dbg ![[NUM]] +// CHECK: br label %while.cond, !dbg ![[NUM]], !llvm.loop +// CHECK: ![[NUM]] = !DILocation(line: 6,