[cfe-commits] [PATCH] Encoding calling conventions in FunctionTypes
Douglas Gregor
dgregor at apple.com
Wed Jan 6 11:19:39 PST 2010
Hi Chip,
On Jan 4, 2010, at 3:13 PM, Charles Davis wrote:
> Ping...
>
> Patch is reattached, rebased against current TOT.
Thanks for your patience; comments below.
With future patches, could you tweak Thunderbird to avoid inline
attachments? There's rationale + directions here:
http://llvm.org/docs/DeveloperPolicy.html#patches
> /// isMoreQualifiedThan - Determine whether this type is more
> /// qualified than the Other type. For example, "const volatile int"
> /// is more qualified than "const int", "volatile int", and
> Index: lib/Frontend/PCHWriter.cpp
> ===================================================================
> --- lib/Frontend/PCHWriter.cpp (revision 92538)
> +++ lib/Frontend/PCHWriter.cpp (working copy)
> @@ -139,6 +139,7 @@
> void PCHTypeWriter::VisitFunctionType(const FunctionType *T) {
> Writer.AddTypeRef(T->getResultType(), Record);
> Record.push_back(T->getNoReturnAttr());
> + Record.push_back(T->getCallConv());
> }
could you add a "// FIXME: stable encoding for calling convention" at
the end of that push_back line? Some day, we'll need to divorce the
bit encodings of all of our enums from the enum values (but not today!).
> Index: lib/AST/ASTContext.cpp
> ===================================================================
> --- lib/AST/ASTContext.cpp (revision 92538)
> +++ lib/AST/ASTContext.cpp (working copy)
> @@ -1681,7 +1696,8 @@
>
> /// getFunctionNoProtoType - Return a K&R style C function type like
> 'int()'.
> ///
> -QualType ASTContext::getFunctionNoProtoType(QualType ResultTy, bool
> NoReturn) {
> +QualType ASTContext::getFunctionNoProtoType(QualType ResultTy, bool
> NoReturn,
> + CallingConv CallConv) {
> // Unique functions, to guarantee there is only one function of a
> particular
> // structure.
> llvm::FoldingSetNodeID ID;
> @@ -1694,7 +1710,8 @@
>
> QualType Canonical;
> if (!ResultTy.isCanonical()) {
> - Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy),
> NoReturn);
> + Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy),
> NoReturn,
> + CallConv);
I'm not convinced that this is the correct formulation of the
canonical type, because we may have to cope with the fact that the
default calling convention is the same as the cdecl calling convention
(always? for some targets? I don't know when). Here's a C++ example
that should illustrate the issue:
void __attribute__((cdecl)) f();
void (*fp)() = &f;
Here, the variable fp has the default calling convention but the its
initializer, &f, has the cdecl calling convention. G++ accepts this
code (but rejects similar code where the calling convention of f is
stdcall), which indicates that it's considering the two types to be
equivalent. So, we need to make sure that the canonical function type
has a canonical representation of the calling convention, e.g., with a
function like
CallingConv ASTContext::getCanonicalCallingConv(CallingConv CC) {
if (CC == CC_C)
return CC_Default;
return CC;
}
then, to build the canonical type, use
if (!ResultTy.isCanonical() || getCanonicalCallingConv(CallConv) !=
CallConv)
Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy),
NoReturn, getCanonicalCallingConv(CallConv));
> @@ -1746,7 +1764,7 @@
> Canonical = getFunctionType(getCanonicalType(ResultTy),
> CanonicalArgs.data(), NumArgs,
> isVariadic, TypeQuals, false,
> - false, 0, 0, NoReturn);
> + false, 0, 0, NoReturn, CallConv);
I have the same comment about using getCanonicalCallingConv here as
above.
> +static bool isCompatibleCallingConvention(CallingConv lcc,
> CallingConv rcc) {
> + // Here are the rules (as I see them) for compatibility of calling
> + // conventions:
> + // - If they're the same, they're compatible.
> + // - If the first one is not the default and the second one is,
> then
> + // they're compatible (and the second declaration assumes the
> calling
> + // convention of the first).
> + // - Otherwise, they're not compatible.
> + return (lcc == rcc || (lcc != CC_Default && rcc == CC_Default));
> +}
The order dependency on lcc/rcc doesn't make sense to me, since the
definition of compatibility for types is commutative. I think the
right implementation for this function is to compare the canonical
calling conventions.
Aside from the canonical-types issue, I think this patch is ready to
go in. Do you have commit access?
- Doug
More information about the cfe-commits
mailing list