]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Foundation/Include/EfiStdArg.h
EdkCompatibilityPkg VA_LIST: Fix build issue with GCC 4.4
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Include / EfiStdArg.h
CommitLineData
3eb9473e 1/*++\r
2\r
f57387d5
HT
3Copyright (c) 2004, Intel Corporation. All rights reserved.<BR>\r
4This program and the accompanying materials \r
3eb9473e 5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 EfiStdArg.h\r
15\r
16Abstract:\r
17\r
18 Support for variable length argument lists using the ANSI standard.\r
19 \r
20 Since we are using the ANSI standard we used the standard nameing and\r
21 did not folow the coding convention\r
22\r
23 VA_LIST - typedef for argument list.\r
24 VA_START (VA_LIST Marker, argument before the ...) - Init Marker for use.\r
25 VA_END (VA_LIST Marker) - Clear Marker\r
26 VA_ARG (VA_LIST Marker, var arg size) - Use Marker to get an argumnet from\r
27 the ... list. You must know the size and pass it in this macro.\r
28\r
29 example:\r
30\r
31 UINTN\r
32 ExampleVarArg (\r
33 IN UINTN NumberOfArgs,\r
34 ...\r
35 )\r
36 {\r
37 VA_LIST Marker;\r
38 UINTN Index;\r
39 UINTN Result;\r
40\r
41 //\r
42 // Initialize the Marker\r
43 //\r
44 VA_START (Marker, NumberOfArgs);\r
45 for (Index = 0, Result = 0; Index < NumberOfArgs; Index++) {\r
46 //\r
47 // The ... list is a series of UINTN values, so average them up.\r
48 //\r
49 Result += VA_ARG (Marker, UINTN);\r
50 }\r
51\r
52 VA_END (Marker);\r
53 return Result\r
54 }\r
55\r
56--*/\r
57\r
58#ifndef _EFISTDARG_H_\r
59#define _EFISTDARG_H_\r
60\r
5f68233c 61/**\r
62 Return the size of argument that has been aligned to sizeof (UINTN).\r
63\r
64 @param n The parameter size to be aligned.\r
65\r
66 @return The aligned size.\r
67**/\r
68#define _INT_SIZE_OF(n) ((sizeof (n) + sizeof (UINTN) - 1) &~(sizeof (UINTN) - 1))\r
3eb9473e 69\r
1afe0401
A
70#if defined(__CC_ARM)\r
71//\r
72// RVCT ARM variable argument list support.\r
73//\r
74\r
75///\r
76/// Variable used to traverse the list of arguments. This type can vary by \r
77/// implementation and could be an array or structure. \r
78///\r
79#ifdef __APCS_ADSABI\r
80 typedef int *va_list[1];\r
81 #define VA_LIST va_list\r
82#else\r
83 typedef struct __va_list { void *__ap; } va_list;\r
84 #define VA_LIST va_list\r
85#endif\r
86\r
87#define VA_START(Marker, Parameter) __va_start(Marker, Parameter)\r
88\r
89#define VA_ARG(Marker, TYPE) __va_arg(Marker, TYPE)\r
90\r
91#define VA_END(Marker) ((void)0)\r
92\r
5f68233c 93#elif defined(__GNUC__) && !defined(NO_BUILTIN_VA_FUNCS)\r
e8de4680
A
94//\r
95// Use GCC built-in macros for variable argument lists.\r
96//\r
97\r
98///\r
99/// Variable used to traverse the list of arguments. This type can vary by \r
100/// implementation and could be an array or structure. \r
101///\r
102typedef __builtin_va_list VA_LIST;\r
103\r
104#define VA_START(Marker, Parameter) __builtin_va_start (Marker, Parameter)\r
105\r
106#define VA_ARG(Marker, TYPE) ((sizeof (TYPE) < sizeof (UINTN)) ? (TYPE)(__builtin_va_arg (Marker, UINTN)) : (TYPE)(__builtin_va_arg (Marker, TYPE)))\r
107\r
108#define VA_END(Marker) __builtin_va_end (Marker)\r
109\r
110#else\r
5f68233c 111///\r
112/// Variable used to traverse the list of arguments. This type can vary by \r
113/// implementation and could be an array or structure. \r
114///\r
115typedef CHAR8 *VA_LIST;\r
e8de4680 116\r
5f68233c 117/**\r
118 Retrieves a pointer to the beginning of a variable argument list, based on \r
119 the name of the parameter that immediately precedes the variable argument list. \r
3eb9473e 120\r
5f68233c 121 This function initializes Marker to point to the beginning of the variable \r
122 argument list that immediately follows Parameter. The method for computing the \r
123 pointer to the next argument in the argument list is CPU-specific following the \r
124 EFIAPI ABI.\r
3eb9473e 125\r
5f68233c 126 @param Marker The VA_LIST used to traverse the list of arguments.\r
127 @param Parameter The name of the parameter that immediately precedes \r
128 the variable argument list.\r
129 \r
130 @return A pointer to the beginning of a variable argument list.\r
131\r
132**/\r
133#define VA_START(Marker, Parameter) (Marker = (VA_LIST) & (Parameter) + _INT_SIZE_OF (Parameter))\r
e8de4680 134\r
5f68233c 135/**\r
136 Returns an argument of a specified type from a variable argument list and updates \r
137 the pointer to the variable argument list to point to the next argument. \r
138\r
139 This function returns an argument of the type specified by TYPE from the beginning \r
140 of the variable argument list specified by Marker. Marker is then updated to point \r
141 to the next argument in the variable argument list. The method for computing the \r
142 pointer to the next argument in the argument list is CPU-specific following the EFIAPI ABI.\r
143\r
144 @param Marker VA_LIST used to traverse the list of arguments.\r
145 @param TYPE The type of argument to retrieve from the beginning \r
146 of the variable argument list.\r
147 \r
148 @return An argument of the type specified by TYPE.\r
149\r
150**/\r
151#define VA_ARG(Marker, TYPE) (*(TYPE *) ((Marker += _INT_SIZE_OF (TYPE)) - _INT_SIZE_OF (TYPE)))\r
152\r
153/**\r
154 Terminates the use of a variable argument list.\r
155\r
156 This function initializes Marker so it can no longer be used with VA_ARG(). \r
157 After this macro is used, the only way to access the variable argument list is \r
158 by using VA_START() again.\r
159\r
160 @param Marker VA_LIST used to traverse the list of arguments.\r
161 \r
162**/\r
163#define VA_END(Marker) (Marker = (VA_LIST) 0)\r
e8de4680 164\r
3eb9473e 165#endif\r
166\r
167#endif\r