diff options
author | John McCall <rjmccall@apple.com> | 2010-02-04 05:44:44 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-02-04 05:44:44 +0000 |
commit | f82b4e85b1219295cad4b5851b035575bc293010 (patch) | |
tree | 4169a0c441add772fb7b0858759981aab063ac69 /lib/Sema/SemaType.cpp | |
parent | 814e6b915450456eb2a1ba15d82fc7f8ae3bc8a6 (diff) |
Allow calling convention attributes to apply to types. Patch by Chip Davis!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95291 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaType.cpp')
-rw-r--r-- | lib/Sema/SemaType.cpp | 83 |
1 files changed, 76 insertions, 7 deletions
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 906576115a..8833792494 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -1241,7 +1241,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, // See if there are any attributes on this declarator chunk. if (const AttributeList *AL = DeclType.getAttrs()) - ProcessTypeAttributeList(T, AL); + ProcessTypeAttributeList(T, AL, true); } if (getLangOptions().CPlusPlus && T->isFunctionType()) { @@ -1274,7 +1274,10 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, // If there were any type attributes applied to the decl itself (not the // type, apply the type attribute to the type!) if (const AttributeList *Attrs = D.getAttributes()) - ProcessTypeAttributeList(T, Attrs); + ProcessTypeAttributeList(T, Attrs, true); + // Also look in the decl spec. + if (const AttributeList *Attrs = D.getDeclSpec().getAttributes()) + ProcessTypeAttributeList(T, Attrs, true, true); if (TInfo) { if (D.isInvalidType()) @@ -1612,6 +1615,36 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type, Type = S.Context.getAddrSpaceQualType(Type, ASIdx); } +/// HandleCDeclTypeAttribute - Process the cdecl attribute on the +/// specified type. The attribute contains 0 arguments. +static void HandleCDeclTypeAttribute(QualType &Type, + const AttributeList &Attr, Sema &S) { + if (Attr.getNumArgs() != 0) + return; + + // We only apply this to a pointer to function. + if (!Type->isFunctionPointerType() + && !Type->isFunctionType()) + return; + + Type = S.Context.getCallConvType(Type, CC_C); +} + +/// HandleFastCallTypeAttribute - Process the fastcall attribute on the +/// specified type. The attribute contains 0 arguments. +static void HandleFastCallTypeAttribute(QualType &Type, + const AttributeList &Attr, Sema &S) { + if (Attr.getNumArgs() != 0) + return; + + // We only apply this to a pointer to function. + if (!Type->isFunctionPointerType() + && !Type->isFunctionType()) + return; + + Type = S.Context.getCallConvType(Type, CC_X86FastCall); +} + /// HandleObjCGCTypeAttribute - Process an objc's gc attribute on the /// specified type. The attribute contains 1 argument, weak or strong. static void HandleObjCGCTypeAttribute(QualType &Type, @@ -1661,6 +1694,21 @@ static void HandleNoReturnTypeAttribute(QualType &Type, Type = S.Context.getNoReturnType(Type); } +/// HandleStdCallTypeAttribute - Process the stdcall attribute on the +/// specified type. The attribute contains 0 arguments. +static void HandleStdCallTypeAttribute(QualType &Type, + const AttributeList &Attr, Sema &S) { + if (Attr.getNumArgs() != 0) + return; + + // We only apply this to a pointer to function. + if (!Type->isFunctionPointerType() + && !Type->isFunctionType()) + return; + + Type = S.Context.getCallConvType(Type, CC_X86StdCall); +} + /// HandleVectorSizeAttribute - this attribute is only applicable to integral /// and float scalars, although arrays, pointers, and function return values are /// allowed in conjunction with this construct. Aggregates with this attribute @@ -1708,7 +1756,12 @@ static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr, S CurType = S.Context.getVectorType(CurType, vectorSize/typeSize); } -void Sema::ProcessTypeAttributeList(QualType &Result, const AttributeList *AL) { +void Sema::ProcessTypeAttributeList(QualType &Result, const AttributeList *AL, + bool HandleCallConvAttributes, + bool HandleOnlyCallConv) { + if(HandleOnlyCallConv) + assert(HandleCallConvAttributes && "Can't not handle call-conv attributes" + " while only handling them!"); // Scan through and apply attributes to this type where it makes sense. Some // attributes (such as __address_space__, __vector_size__, etc) apply to the // type, but others can be present in the type specifiers even though they @@ -1719,16 +1772,32 @@ void Sema::ProcessTypeAttributeList(QualType &Result, const AttributeList *AL) { switch (AL->getKind()) { default: break; case AttributeList::AT_address_space: - HandleAddressSpaceTypeAttribute(Result, *AL, *this); + if (!HandleOnlyCallConv) + HandleAddressSpaceTypeAttribute(Result, *AL, *this); + break; + case AttributeList::AT_cdecl: + if (HandleCallConvAttributes) + HandleCDeclTypeAttribute(Result, *AL, *this); + break; + case AttributeList::AT_fastcall: + if (HandleCallConvAttributes) + HandleFastCallTypeAttribute(Result, *AL, *this); break; case AttributeList::AT_objc_gc: - HandleObjCGCTypeAttribute(Result, *AL, *this); + if (!HandleOnlyCallConv) + HandleObjCGCTypeAttribute(Result, *AL, *this); break; case AttributeList::AT_noreturn: - HandleNoReturnTypeAttribute(Result, *AL, *this); + if (!HandleOnlyCallConv) + HandleNoReturnTypeAttribute(Result, *AL, *this); + break; + case AttributeList::AT_stdcall: + if (HandleCallConvAttributes) + HandleStdCallTypeAttribute(Result, *AL, *this); break; case AttributeList::AT_vector_size: - HandleVectorSizeAttr(Result, *AL, *this); + if (!HandleOnlyCallConv) + HandleVectorSizeAttr(Result, *AL, *this); break; } } |