145a40c16SStephen Tozer // RUN: %clang++ -std=gnu++11 -O2 -g %s -o %t
21364750dSJames Henderson // RUN: %dexter --fail-lt 1.0 -w \
345a40c16SStephen Tozer // RUN:     --binary %t --debugger 'lldb' -v -- %s
445a40c16SStephen Tozer // RUN: %clang++ -std=gnu++11 -O0 -g %s -o %t
51364750dSJames Henderson // RUN: %dexter --fail-lt 1.0 -w \
645a40c16SStephen Tozer // RUN:     --binary %t --debugger 'lldb' -- %s
71364750dSJames Henderson 
81364750dSJames Henderson // REQUIRES: lldb
9*43d70e46SStephen Tozer // Currently getting intermittent failures on darwin.
10*43d70e46SStephen Tozer // UNSUPPORTED: system-windows, system-darwin
111364750dSJames Henderson 
121364750dSJames Henderson //// Check that the debugging experience with __attribute__((optnone)) at O2
131364750dSJames Henderson //// matches O0. Test simple structs and methods.
141364750dSJames Henderson 
151364750dSJames Henderson long a_global_ptr[] = { 0xCAFEBABEL, 0xFEEDBEEFL };
161364750dSJames Henderson 
171364750dSJames Henderson namespace {
181364750dSJames Henderson 
191364750dSJames Henderson struct A {
201364750dSJames Henderson   int a;
211364750dSJames Henderson   float b;
221364750dSJames Henderson 
231364750dSJames Henderson   enum B {
241364750dSJames Henderson     A_VALUE = 0x1,
251364750dSJames Henderson     B_VALUE = 0x2
261364750dSJames Henderson   };
271364750dSJames Henderson 
281364750dSJames Henderson   struct some_data {
291364750dSJames Henderson     enum B other_b;
301364750dSJames Henderson     enum B other_other_b;
311364750dSJames Henderson   };
321364750dSJames Henderson 
331364750dSJames Henderson   struct other_data {
341364750dSJames Henderson     union {
351364750dSJames Henderson       void *raw_ptr;
361364750dSJames Henderson       long  *long_ptr;
371364750dSJames Henderson       float *float_ptr;
381364750dSJames Henderson     } a;
391364750dSJames Henderson     struct some_data b;
401364750dSJames Henderson     struct some_data c;
411364750dSJames Henderson   };
421364750dSJames Henderson private:
431364750dSJames Henderson   struct other_data _data;
441364750dSJames Henderson 
451364750dSJames Henderson public:
getOtherData__anone12a1d630111::A461364750dSJames Henderson   struct other_data *getOtherData() { return &_data; }
471364750dSJames Henderson 
481364750dSJames Henderson   __attribute__((always_inline,nodebug))
setSomeData1__anone12a1d630111::A491364750dSJames Henderson   void setSomeData1(A::B value, A::B other_value) {
501364750dSJames Henderson     struct other_data *data = getOtherData();
511364750dSJames Henderson     data->b.other_b = value;
521364750dSJames Henderson     data->b.other_other_b = other_value;
531364750dSJames Henderson   }
541364750dSJames Henderson 
551364750dSJames Henderson   __attribute__((always_inline))
setSomeData2__anone12a1d630111::A561364750dSJames Henderson   void setSomeData2(A::B value, A::B other_value) {
571364750dSJames Henderson     struct other_data *data = getOtherData();
581364750dSJames Henderson     data->c.other_b = value;
591364750dSJames Henderson     data->c.other_other_b = other_value;
601364750dSJames Henderson   }
611364750dSJames Henderson 
setOtherData__anone12a1d630111::A621364750dSJames Henderson   void setOtherData() {
631364750dSJames Henderson     setSomeData2(A_VALUE, B_VALUE);
641364750dSJames Henderson     getOtherData()->a.long_ptr = &a_global_ptr[0];
651364750dSJames Henderson   }
661364750dSJames Henderson 
671364750dSJames Henderson   __attribute__((optnone))
A__anone12a1d630111::A681364750dSJames Henderson   A() {
691364750dSJames Henderson     __builtin_memset(this, 0xFF, sizeof(*this));
701364750dSJames Henderson   } //DexLabel('break_0')
711364750dSJames Henderson   // DexExpectWatchValue('a', '-1', on_line=ref('break_0'))
721364750dSJames Henderson   //// Check b is NaN by comparing it to itself.
731364750dSJames Henderson   // DexExpectWatchValue('this->b == this->b', 'false', on_line=ref('break_0'))
741364750dSJames Henderson   // DexExpectWatchValue('_data.a.raw_ptr == -1', 'true', on_line=ref('break_0'))
751364750dSJames Henderson   // DexExpectWatchValue('_data.a.float_ptr == -1', 'true', on_line=ref('break_0'))
761364750dSJames Henderson   // DexExpectWatchValue('_data.a.float_ptr == -1', 'true', on_line=ref('break_0'))
771364750dSJames Henderson   // DexExpectWatchValue('a_global_ptr[0]', 0xcafebabe, on_line=ref('break_0'))
781364750dSJames Henderson   // DexExpectWatchValue('a_global_ptr[1]', 0xfeedbeef, on_line=ref('break_0'))
791364750dSJames Henderson 
801364750dSJames Henderson   __attribute__((optnone))
~A__anone12a1d630111::A811364750dSJames Henderson   ~A() {
821364750dSJames Henderson     *getOtherData()->a.long_ptr = 0xADDF00DL;
831364750dSJames Henderson   } //DexLabel('break_1')
841364750dSJames Henderson   // DexExpectWatchValue('_data.a.raw_ptr == a_global_ptr', 'true', on_line=ref('break_1'))
851364750dSJames Henderson   // DexExpectWatchValue('a_global_ptr[0]', 0xaddf00d, on_line=ref('break_1'))
861364750dSJames Henderson 
871364750dSJames Henderson   __attribute__((optnone))
getData__anone12a1d630111::A881364750dSJames Henderson   long getData() {
891364750dSJames Henderson     setSomeData1(B_VALUE, A_VALUE);
901364750dSJames Henderson     setOtherData();
911364750dSJames Henderson     return getOtherData()->a.long_ptr[1]; //DexLabel('break_2')
921364750dSJames Henderson   }
931364750dSJames Henderson   // DexExpectWatchValue('_data.b.other_b', 'B_VALUE', on_line=ref('break_2'))
941364750dSJames Henderson   // DexExpectWatchValue('_data.b.other_other_b', 'A_VALUE', on_line=ref('break_2'))
951364750dSJames Henderson };
961364750dSJames Henderson 
971364750dSJames Henderson } // anonymous namespace
981364750dSJames Henderson 
main()991364750dSJames Henderson int main() {
1001364750dSJames Henderson   int result = 0;
1011364750dSJames Henderson   {
1021364750dSJames Henderson     A a;
1031364750dSJames Henderson     result = a.getData();
1041364750dSJames Henderson   }
1051364750dSJames Henderson   return result;
1061364750dSJames Henderson }
107