1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5
6#ifndef _CUSTOMATTRIBUTE_H_
7#define _CUSTOMATTRIBUTE_H_
8
9#include "fcall.h"
10#include "../md/compiler/custattr.h"
11
12struct CustomAttributeType;
13struct CustomAttributeValue;
14struct CustomAttributeArgument;
15struct CustomAttributeNamedArgument;
16
17typedef Array<CustomAttributeArgument> CaArgArray;
18typedef Array<CustomAttributeNamedArgument> CaNamedArgArray;
19typedef Array<CustomAttributeValue> CaValueArray;
20
21typedef DPTR(CaArgArray) PTR_CaArgArray;
22typedef DPTR(CaNamedArgArray) PTR_CaNamedArgArray;
23typedef DPTR(CaValueArray) PTR_CaValueArray;
24
25#ifdef USE_CHECKED_OBJECTREFS
26typedef REF<CaArgArray> CaArgArrayREF;
27typedef REF<CaNamedArgArray> CaNamedArgArrayREF;
28typedef REF<CaValueArray> CaValueArrayREF;
29#else
30typedef PTR_CaArgArray CaArgArrayREF;
31typedef PTR_CaNamedArgArray CaNamedArgArrayREF;
32typedef PTR_CaValueArray CaValueArrayREF;
33#endif
34
35
36#include <pshpack1.h>
37struct CustomAttributeType
38{
39 STRINGREF m_enumName;
40 CorSerializationType m_tag;
41 CorSerializationType m_enumType;
42 CorSerializationType m_arrayType;
43 CorSerializationType m_padding;
44};
45
46struct CustomAttributeValue
47{
48#ifdef _WIN64
49 // refs come before longs on win64
50 CaValueArrayREF m_value;
51 STRINGREF m_enumOrTypeName;
52 INT64 m_rawValue;
53#else
54 // longs come before refs on x86
55 INT64 m_rawValue;
56 CaValueArrayREF m_value;
57 STRINGREF m_enumOrTypeName;
58#endif
59 CustomAttributeType m_type;
60#if defined(FEATURE_64BIT_ALIGNMENT)
61 DWORD m_padding;
62#endif
63};
64
65struct CustomAttributeArgument
66{
67 CustomAttributeType m_type;
68#if (!defined(_WIN64) && (DATA_ALIGNMENT > 4)) || defined(FEATURE_64BIT_ALIGNMENT)
69 DWORD m_padding;
70#endif
71 CustomAttributeValue m_value;
72};
73
74struct CustomAttributeNamedArgument
75{
76 STRINGREF m_argumentName;
77 CorSerializationType m_propertyOrField;
78 CorSerializationType m_padding;
79#if !defined(_WIN64) && (DATA_ALIGNMENT > 4)
80 DWORD m_padding2;
81#endif
82 CustomAttributeType m_type;
83#if !defined(_WIN64) && (DATA_ALIGNMENT > 4)
84 DWORD m_padding3;
85#endif
86 CustomAttributeValue m_value;
87};
88#include <poppack.h>
89
90
91typedef struct {
92 STRINGREF string;
93 CaValueArrayREF array;
94} CustomAttributeManagedValues;
95
96typedef Factory< SArray<CaValue> > CaValueArrayFactory;
97
98class Attribute
99{
100public:
101 static FCDECL5(VOID, ParseAttributeArguments,
102 void* pCa,
103 INT32 cCa,
104 CaArgArrayREF* ppCustomAttributeArguments,
105 CaNamedArgArrayREF* ppCustomAttributeNamedArguments,
106 AssemblyBaseObject* pAssemblyUNSAFE);
107
108private:
109 static HRESULT ParseAttributeArgumentValues(
110 void* pCa,
111 INT32 cCa,
112 CaValueArrayFactory* pCaValueArrayFactory,
113 CaArg* pCaArgs,
114 COUNT_T cArgs,
115 CaNamedArg* pCaNamedArgs,
116 COUNT_T cNamedArgs,
117 DomainAssembly* pDomainAssembly);
118
119 static HRESULT ParseCaValue(
120 CustomAttributeParser &ca,
121 CaValue* pCaArg,
122 CaType* pCaParam,
123 CaValueArrayFactory* pCaValueArrayFactory,
124 DomainAssembly* pDomainAssembly);
125
126 static HRESULT ParseCaCtorArgs(
127 CustomAttributeParser &ca,
128 CaArg* pArgs,
129 ULONG cArgs,
130 CaValueArrayFactory* pCaValueArrayFactory,
131 DomainAssembly* pDomainAssembly);
132
133 static HRESULT ParseCaNamedArgs(
134 CustomAttributeParser &ca, // The Custom Attribute blob.
135 CaNamedArg *pNamedParams, // Array of argument descriptors.
136 ULONG cNamedParams,
137 CaValueArrayFactory* pCaValueArrayFactory,
138 DomainAssembly* pDomainAssembly);
139
140 static HRESULT InitCaType(
141 CustomAttributeType* pType,
142 Factory<SString>* pSstringFactory,
143 Factory<StackScratchBuffer>* pStackScratchBufferFactory,
144 CaType* pCaType);
145
146 static HRESULT ParseCaType(
147 CustomAttributeParser &ca,
148 CaType* pCaType,
149 DomainAssembly* pDomainAssembly,
150 StackSString* ss = NULL);
151
152 static TypeHandle GetTypeForEnum(
153 LPCUTF8 szEnumName,
154 COUNT_T cbEnumName,
155 DomainAssembly* pDomainAssembly);
156
157 static void SetBlittableCaValue(
158 CustomAttributeValue* pVal,
159 CaValue* pCaVal,
160 BOOL* pbAllBlittableCa);
161
162 static void SetManagedValue(
163 CustomAttributeManagedValues gc,
164 CustomAttributeValue* pValue);
165
166 static CustomAttributeManagedValues GetManagedCaValue(CaValue* pCaVal);
167};
168
169class COMCustomAttribute
170{
171public:
172
173 // custom attributes utility functions
174 static FCDECL5(VOID, ParseAttributeUsageAttribute, PVOID pData, ULONG cData, ULONG* pTargets, CLR_BOOL* pInherited, CLR_BOOL* pAllowMultiple);
175 static FCDECL6(LPVOID, CreateCaObject, ReflectModuleBaseObject* pAttributedModuleUNSAFE, ReflectClassBaseObject* pCaTypeUNSAFE, ReflectMethodObject *pMethodUNSAFE, BYTE** ppBlob, BYTE* pEndBlob, INT32* pcNamedArgs);
176 static FCDECL7(void, GetPropertyOrFieldData, ReflectModuleBaseObject *pModuleUNSAFE, BYTE** ppBlobStart, BYTE* pBlobEnd, STRINGREF* pName, CLR_BOOL* pbIsProperty, OBJECTREF* pType, OBJECTREF* value);
177 static FCDECL4(VOID, GetSecurityAttributes, ReflectModuleBaseObject *pModuleUNSAFE, DWORD tkToken, CLR_BOOL fAssembly, PTRARRAYREF* ppArray);
178
179private:
180
181 static TypeHandle GetTypeHandleFromBlob(
182 Assembly *pCtorAssembly,
183 CorSerializationType objType,
184 BYTE **pBlob,
185 const BYTE *endBlob,
186 Module *pModule);
187
188 static ARG_SLOT GetDataFromBlob(
189 Assembly *pCtorAssembly,
190 CorSerializationType type,
191 TypeHandle th,
192 BYTE **pBlob,
193 const BYTE *endBlob,
194 Module *pModule,
195 BOOL *bObjectCreated);
196
197 static void ReadArray(
198 Assembly *pCtorAssembly,
199 CorSerializationType arrayType,
200 int size,
201 TypeHandle th,
202 BYTE **pBlob,
203 const BYTE *endBlob,
204 Module *pModule,
205 BASEARRAYREF *pArray);
206
207 static int GetStringSize(
208 BYTE **pBlob,
209 const BYTE *endBlob);
210
211 template < typename T >
212 static BOOL CopyArrayVAL(
213 BASEARRAYREF pArray,
214 int nElements,
215 BYTE **pBlob,
216 const BYTE *endBlob);
217};
218
219#endif
220
221