2020-01-17 21:05:03 +08:00
|
|
|
// Copyright 2019 Google LLC
|
2019-03-19 00:21:48 +08:00
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
// Test file trying to cover as much of DWARF entry combinations as possible.
|
|
|
|
// Base for testing.
|
|
|
|
// As we are tracking types related to function calls, types of interest should
|
|
|
|
// be passed as arguments, returned by function or be part of structure
|
|
|
|
// dependency chain
|
|
|
|
|
|
|
|
#include "sandboxed_api/tools/generator2/testdata/tests.h"
|
|
|
|
|
|
|
|
namespace a {
|
|
|
|
namespace b {
|
|
|
|
|
|
|
|
class ExampleClass {
|
|
|
|
private:
|
|
|
|
int a_;
|
|
|
|
int b_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
int GetSum() const { return a_ + b_; }
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace b
|
|
|
|
} // namespace a
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
|
|
|
// Simple types
|
|
|
|
bool function_using_simple_types(unsigned char a1, // NOLINT
|
|
|
|
signed char a2, // NOLINT
|
|
|
|
unsigned short a3, // NOLINT
|
|
|
|
signed short a4, // NOLINT
|
|
|
|
unsigned int a5, // NOLINT
|
|
|
|
signed int a6, // NOLINT
|
|
|
|
unsigned long a7, // NOLINT
|
|
|
|
signed long a8, // NOLINT
|
|
|
|
unsigned long long a9, // NOLINT
|
|
|
|
signed long long a10 // NOLINT
|
|
|
|
) {
|
|
|
|
return a1 ? true : false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool function_using_simple_types_continued(float a1, double a2,
|
|
|
|
long double a3) {
|
|
|
|
return a1 ? true : false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Class usage
|
|
|
|
int function_using_class(const a::b::ExampleClass* ptr_to_class) {
|
|
|
|
return ptr_to_class->GetSum();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Typedef usage
|
|
|
|
typedef unsigned int uint;
|
|
|
|
typedef uint* uint_p;
|
|
|
|
typedef uint_p* uint_pp;
|
|
|
|
typedef char** char_pp;
|
|
|
|
typedef long int long_arr[8]; // NOLINT
|
|
|
|
typedef void (*function_p)(uint, uint_p, uint_pp);
|
|
|
|
typedef void (*function_p2)(void (*)(int, char), void*);
|
|
|
|
typedef int function_3(int a, int b);
|
|
|
|
|
|
|
|
typedef union {
|
|
|
|
int a;
|
|
|
|
char b;
|
|
|
|
} union_1;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
function_p a;
|
|
|
|
function_p2 b;
|
|
|
|
void (*c)(int, long); // NOLINT
|
|
|
|
uint d;
|
|
|
|
uint_pp e;
|
|
|
|
struct struct_2* f;
|
|
|
|
} struct_t;
|
|
|
|
|
|
|
|
// Using defined types so these end up in debug symbols
|
|
|
|
uint function_using_typedefs(uint_p a1, uint_pp a2, function_p a3,
|
|
|
|
function_p2* a4, struct_t* a5, char_pp a6,
|
|
|
|
long_arr* a7, function_3* a8) {
|
|
|
|
return 1337 + a5->d + a8(1, 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
int function_using_union(union_1* a1) { return a1->a; }
|
|
|
|
|
|
|
|
// Pointer usage
|
|
|
|
unsigned char* function_using_pointers(int* a1, unsigned char* a2,
|
|
|
|
unsigned char a3, const char* a4) {
|
|
|
|
return a2;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint* function_returning_pointer() { return reinterpret_cast<uint*>(0x1337); }
|
|
|
|
|
|
|
|
void function_returning_void(int* a) { *a = 1337; }
|
|
|
|
|
|
|
|
// Structures
|
|
|
|
struct __attribute__((__packed__)) struct_1 {
|
|
|
|
uint a;
|
|
|
|
char b;
|
|
|
|
uint c;
|
|
|
|
char d;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct struct_2 {
|
|
|
|
uint a;
|
|
|
|
char b;
|
|
|
|
uint c;
|
|
|
|
char d;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct struct_3 {
|
|
|
|
uint partially_defined_struct_so_field_is_invisible;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define COEF_BITS_SIZE 16
|
|
|
|
struct struct_4 {
|
|
|
|
char a[4];
|
|
|
|
int b;
|
|
|
|
union {
|
|
|
|
uint a;
|
|
|
|
char* b;
|
|
|
|
} c;
|
|
|
|
struct {
|
|
|
|
uint a;
|
|
|
|
char* b;
|
|
|
|
} d;
|
|
|
|
function_p func_1;
|
|
|
|
// tests for const + ptr issues
|
|
|
|
const char* const* const_1;
|
|
|
|
const char** const_2;
|
|
|
|
char* const* const_3;
|
|
|
|
int (*coef_bits)[COEF_BITS_SIZE];
|
|
|
|
};
|
|
|
|
|
|
|
|
int function_using_structures(struct struct_1* a1, struct struct_2* a2,
|
|
|
|
struct struct_3* a3, struct struct_4* a4) {
|
|
|
|
return a1->a + a2->a + a4->b;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tests type loop case typedef -> struct -> fn_ptr -> typedef
|
|
|
|
struct struct_6_def;
|
|
|
|
typedef struct struct_6_def struct_6;
|
|
|
|
typedef struct_6* struct_6p;
|
|
|
|
typedef void (*function_p3)(struct_6p);
|
|
|
|
struct struct_6_def {
|
|
|
|
function_p3 fn;
|
|
|
|
};
|
|
|
|
|
|
|
|
void function_using_type_loop(struct_6p a1) { a1->fn(a1); }
|
|
|
|
|
|
|
|
// Tests struct-in-struct case that fails if we generate forward declarations
|
|
|
|
// for every structure
|
|
|
|
struct struct_7_part_def {
|
|
|
|
int x;
|
|
|
|
int y;
|
|
|
|
void (*fn)(void);
|
|
|
|
};
|
|
|
|
typedef struct struct_7_part_def s7part;
|
|
|
|
|
|
|
|
struct struct_7_def {
|
|
|
|
s7part part;
|
|
|
|
int x;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct struct_7_def* s7p;
|
|
|
|
|
|
|
|
void function_using_incomplete(s7p a1) { a1->part.fn(); }
|
|
|
|
|
|
|
|
// Tests for enums
|
|
|
|
enum Enumeration { ONE, TWO, THREE };
|
|
|
|
typedef enum Numbers { UNKNOWN, FIVE = 5, SE7EN = 7 } Nums;
|
|
|
|
typedef enum { SIX = 6, TEN = 10 } SixOrTen;
|
|
|
|
enum class Color : long long { RED, GREEN = 20, BLUE }; // NOLINT
|
|
|
|
enum struct Direction { LEFT = 'l', RIGHT = 'r' };
|
|
|
|
|
|
|
|
int function_using_enums(Enumeration a1, SixOrTen a2, Color a3, Direction a4,
|
|
|
|
Nums a5) {
|
|
|
|
switch (a1) {
|
|
|
|
case Enumeration::ONE:
|
|
|
|
return Numbers::SE7EN;
|
|
|
|
case Enumeration::TWO:
|
|
|
|
return a2;
|
|
|
|
default:
|
|
|
|
return FIVE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} // extern "C"
|