Update copyright to LGPL on all files
[dyninst.git] / testsuite / src / symtab / test_anno_basic_types.C
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 #include "symtab_comp.h"
33 #include "test_lib.h"
34
35 #include "Annotatable.h"
36
37 using namespace Dyninst;
38 //using namespace SymtabAPI;
39
40 class test_anno_basic_types_Mutator : public SymtabMutator 
41 {
42    public:
43       test_anno_basic_types_Mutator() { };
44    virtual test_results_t executeTest();
45 };
46
47 extern "C" DLLEXPORT TestMutator* test_anno_basic_types_factory()
48 {
49    return new test_anno_basic_types_Mutator();
50 }
51
52 class TestClass
53 {
54    public:
55       TestClass() {}
56       
57       int somestuff1;
58       long somestuff2;
59       float somestuff3;
60       char *somestuff4;
61 };
62
63 class TestClassSparse : public TestClass, public AnnotatableSparse
64 {
65    public:
66       TestClassSparse() {}
67       ~TestClassSparse() {}
68 };
69
70 class TestClassDense : public TestClass, public AnnotatableDense
71 {
72    public:
73    TestClassDense() {}
74    ~TestClassDense() {}
75 };
76
77 template <class TC, class T>
78 void remove_anno(TC &tcs, const char *anno_prefix_to_use = NULL) THROW_SPEC (LocErr)
79 {
80         std::string an(typeid(T).name());
81
82         if (anno_prefix_to_use)
83         {
84                 std::string prefix(anno_prefix_to_use);
85                 an = prefix + an;
86         }
87
88    AnnotationClass<T> my_ac(an);
89
90    if (!tcs.removeAnnotation(my_ac))
91       EFAIL("failed to remove annotation here");
92
93    //  try to get the annotation now.
94    //  if its still there, then we have a failure
95    
96    T *out = NULL;
97
98    if (tcs.getAnnotation(out, my_ac))
99       EFAIL("failed to get annotation here");
100 }
101
102 template <class TC, class T>
103 void verify_anno(TC &tcs, const T &test_val, 
104                 const char *anno_prefix_to_use = NULL) THROW_SPEC (LocErr)
105 {
106         std::string an(typeid(T).name());
107
108         if (anno_prefix_to_use)
109         {
110                 std::string prefix(anno_prefix_to_use);
111                 an = prefix + an;
112         }
113
114    AnnotationClass<T> my_ac(an);
115
116    T *out = NULL;
117
118    if (!tcs.getAnnotation(out, my_ac))
119       EFAIL("failed to get annotation here");
120
121    if (!out)
122       EFAIL("failed to get annotation here");
123
124    if ((*out) != test_val)
125       EFAIL("failed to get annotation here");
126 }
127
128 template <class TC, class T>
129 void add_get_and_verify_anno(TC &tcs, const T &test_val, 
130                 const char *anno_prefix_to_use = NULL) THROW_SPEC(LocErr)
131 {
132
133    //  A very simple function that adds an annotation of type T to the given class
134    //  then just verifies that it can retrieve the annotation and then checks that
135    //  the value of the annotation is the same as was provided.
136
137         std::string an(typeid(T).name());
138
139         if (anno_prefix_to_use)
140         {
141                 std::string prefix(anno_prefix_to_use);
142                 an = prefix + an;
143         }
144
145    AnnotationClass<T> my_ac(an);
146
147    if (!tcs.addAnnotation(&test_val, my_ac))
148       EFAIL("failed to add annotation here");
149
150    T *out = NULL;
151
152    if (!tcs.getAnnotation(out, my_ac))
153       EFAIL("failed to get annotation here");
154
155    if (!out)
156       EFAIL("failed to get annotation here");
157
158    if ((*out) != test_val)
159       EFAIL("failed to get annotation here");
160
161    //else 
162    //{
163    //   cerr <<  an << ":" << (*out) << " == " << test_val << endl;
164    //}
165
166 }
167
168 template <class TC, class T>
169 void add_verify_dispatch(TC &tcs, const T &test_val, bool do_add, 
170       const char *anno_prefix_to_use = NULL) THROW_SPEC (LocErr)
171 {
172    if (do_add)
173    {
174       add_get_and_verify_anno(tcs, test_val, anno_prefix_to_use);
175    }
176    else
177    {
178       verify_anno(tcs, test_val, anno_prefix_to_use);
179    }
180 }
181
182 template <class T>
183 void test_for_annotatable() THROW_SPEC (LocErr)
184 {
185    T tc;
186    bool do_add = false;
187
188    do {
189       //  First pass (do_add = true) adds and verifies annotation
190       //  Second pass (do_add = false) just verifies existing annotation
191       //  ...  ie, makes sure nothing got unexpectedly clobbered
192
193       do_add = !do_add;
194
195       add_verify_dispatch<T, int>(tc, -5000, do_add);
196       add_verify_dispatch<T, unsigned int>(tc, 5001, do_add);
197       add_verify_dispatch<T, char>(tc, -1*'c', do_add);
198       add_verify_dispatch<T, unsigned char>(tc, 'd', do_add);
199       add_verify_dispatch<T, short>(tc, -24, do_add);
200       add_verify_dispatch<T, unsigned short>(tc, 50, do_add);
201       add_verify_dispatch<T, long>(tc, -500000, do_add);
202       add_verify_dispatch<T, unsigned long>(tc, 500001, do_add);
203       add_verify_dispatch<T, float>(tc, -5e5, do_add);
204       add_verify_dispatch<T, double>(tc, -5e50, do_add);
205
206       //  Add more annotations of the same set of types, but under 
207       //  different annotation names -- unspecified annotation names
208       //  are later derived from the typename for this test
209
210       add_verify_dispatch<T, int>(tc, -6000, do_add, "auxname1");
211       add_verify_dispatch<T, unsigned int>(tc, 6001, do_add,"auxname2");
212       add_verify_dispatch<T, char>(tc, -1*'e', do_add,"auxname3");
213       add_verify_dispatch<T, unsigned char>(tc, 'f', do_add,"auxname4");
214       add_verify_dispatch<T, short>(tc, -34, do_add,"auxname5");
215       add_verify_dispatch<T, unsigned short>(tc, 60, do_add,"auxname6");
216       add_verify_dispatch<T, long>(tc, -600000, do_add,"auxname7");
217       add_verify_dispatch<T, unsigned long>(tc, 600001, do_add,"auxname8");
218       add_verify_dispatch<T, float>(tc, -6e5, do_add,"auxname9");
219       add_verify_dispatch<T, double>(tc, -6e50, do_add,"auxname10");
220
221           if (!do_add)
222           {
223                   //  remove first set
224                   remove_anno<T, int>(tc);
225                   remove_anno<T, unsigned int>(tc);
226                   remove_anno<T, char>(tc);
227                   remove_anno<T, unsigned char>(tc);
228                   remove_anno<T, short>(tc);
229                   remove_anno<T, unsigned short>(tc);
230                   remove_anno<T, long>(tc);
231                   remove_anno<T, unsigned long>(tc);
232                   remove_anno<T, float>(tc);
233                   remove_anno<T, double>(tc);
234
235                   //  verify that second set remains
236                   add_verify_dispatch<T, int>(tc, -6000, do_add, "auxname1");
237                   add_verify_dispatch<T, unsigned int>(tc, 6001, do_add,"auxname2");
238                   add_verify_dispatch<T, char>(tc, -1*'e', do_add,"auxname3");
239                   add_verify_dispatch<T, unsigned char>(tc, 'f', do_add,"auxname4");
240                   add_verify_dispatch<T, short>(tc, -34, do_add,"auxname5");
241                   add_verify_dispatch<T, unsigned short>(tc, 60, do_add,"auxname6");
242                   add_verify_dispatch<T, long>(tc, -600000, do_add,"auxname7");
243                   add_verify_dispatch<T, unsigned long>(tc, 600001, do_add,"auxname8");
244                   add_verify_dispatch<T, float>(tc, -6e5, do_add,"auxname9");
245                   add_verify_dispatch<T, double>(tc, -6e50, do_add,"auxname10");
246           }
247    } while (do_add);
248 }
249
250 test_results_t test_anno_basic_types_Mutator::executeTest()
251 {
252
253    //  Sparse annotation class should not add any size to child classes
254    if (sizeof(TestClass) != sizeof(TestClassSparse))
255    {
256       fprintf(stderr, "%s[%d]:  ERROR, size creep in sparse annotation class\n", 
257             FILE__, __LINE__);
258       fprintf(stderr, "sizeof(TestClass) = %d, sizeof(TestClassSparse) = %d\n", 
259             sizeof(TestClass), sizeof(TestClassSparse));
260       return FAILED;
261    }
262
263    //  Dense annotation class should add size of one pointer
264    if ((sizeof(TestClass) + sizeof(void *)) != sizeof(TestClassDense))
265    {
266       fprintf(stderr, "%s[%d]:  ERROR, size creep in dense annotation class\n", 
267             FILE__, __LINE__);
268       fprintf(stderr, "sizeof(TestClass) + sizeof(void *)= %d, sizeof(TestClassDense) = %d\n", 
269             sizeof(TestClass) + sizeof(void *), sizeof(TestClassDense));
270       return FAILED;
271    }
272
273    try 
274    {
275      test_for_annotatable<TestClassSparse>();
276      test_for_annotatable<TestClassDense>();
277    } REPORT_EFAIL;
278
279    return PASSED;
280
281 }
282