Hi,
This patch encodes calling conventions into FunctionType objects. Right
now, only cdecl, stdcall, and fastcall are supported. No real users yet,
but I went through and fixed all the users of
ASTContext::getFunctionType() and friends to respect the calling convention.
Next up: applying calling convention attributes to the function types.
Chip
Index: include/clang/AST/ASTContext.h
===================================================================
--- include/clang/AST/ASTContext.h (revision 91549)
+++ include/clang/AST/ASTContext.h (working copy)
@@ -399,6 +399,11 @@
/// BlockPointer.
QualType getNoReturnType(QualType T, bool AddNoReturn = true);
+ /// getCallConvType - Adds the specified calling convention attribute to
+ /// the given type, which must be a FunctionType or a pointer to an
+ /// allowable type.
+ QualType getCallConvType(QualType T, unsigned CallConv);
+
/// getComplexType - Return the uniqued reference to the type for a complex
/// number with the specified element type.
QualType getComplexType(QualType T);
@@ -515,7 +520,8 @@
/// getFunctionNoProtoType - Return a K&R style C function type like 'int()'.
///
- QualType getFunctionNoProtoType(QualType ResultTy, bool NoReturn = false);
+ QualType getFunctionNoProtoType(QualType ResultTy, bool NoReturn = false,
+ unsigned CallConv = 0);
/// getFunctionType - Return a normal function type with a typed argument
/// list. isVariadic indicates whether the argument list includes '...'.
@@ -524,7 +530,7 @@
unsigned TypeQuals, bool hasExceptionSpec = false,
bool hasAnyExceptionSpec = false,
unsigned NumExs = 0, const QualType *ExArray = 0,
- bool NoReturn = false);
+ bool NoReturn = false, unsigned CallConv = 0);
/// getTypeDeclType - Return the unique reference to the type for
/// the specified type declaration.
Index: include/clang/AST/Type.h
===================================================================
--- include/clang/AST/Type.h (revision 91549)
+++ include/clang/AST/Type.h (working copy)
@@ -1708,21 +1708,26 @@
/// NoReturn - Indicates if the function type is attribute noreturn.
unsigned NoReturn : 1;
+ /// CallConv - The calling convention used by the function. Is 0
+ /// for default, 1 for C, 2 for stdcall, and 3 for fastcall.
+ unsigned CallConv : 2;
+
// The type returned by the function.
QualType ResultType;
protected:
FunctionType(TypeClass tc, QualType res, bool SubclassInfo,
unsigned typeQuals, QualType Canonical, bool Dependent,
- bool noReturn = false)
+ bool noReturn = false, unsigned callConv = 0)
: Type(tc, Canonical, Dependent),
SubClassData(SubclassInfo), TypeQuals(typeQuals), NoReturn(noReturn),
- ResultType(res) {}
+ CallConv(callConv), ResultType(res) {}
bool getSubClassData() const { return SubClassData; }
unsigned getTypeQuals() const { return TypeQuals; }
public:
QualType getResultType() const { return ResultType; }
bool getNoReturnAttr() const { return NoReturn; }
+ unsigned getCallConv() const { return CallConv; }
static bool classof(const Type *T) {
return T->getTypeClass() == FunctionNoProto ||
@@ -1735,9 +1740,9 @@
/// no information available about its arguments.
class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
FunctionNoProtoType(QualType Result, QualType Canonical,
- bool NoReturn = false)
+ bool NoReturn = false, unsigned CallConv = 0)
: FunctionType(FunctionNoProto, Result, false, 0, Canonical,
- /*Dependent=*/false, NoReturn) {}
+ /*Dependent=*/false, NoReturn, CallConv) {}
friend class ASTContext; // ASTContext creates these.
public:
// No additional state past what FunctionType provides.
@@ -1779,10 +1784,12 @@
FunctionProtoType(QualType Result, const QualType *ArgArray, unsigned
numArgs,
bool isVariadic, unsigned typeQuals, bool hasExs,
bool hasAnyExs, const QualType *ExArray,
- unsigned numExs, QualType Canonical, bool NoReturn)
+ unsigned numExs, QualType Canonical, bool NoReturn,
+ unsigned CallConv = 0)
: FunctionType(FunctionProto, Result, isVariadic, typeQuals, Canonical,
(Result->isDependentType() ||
- hasAnyDependentType(ArgArray, numArgs)), NoReturn),
+ hasAnyDependentType(ArgArray, numArgs)), NoReturn,
+ CallConv),
NumArgs(numArgs), NumExceptions(numExs), HasExceptionSpec(hasExs),
AnyExceptionSpec(hasAnyExs) {
// Fill in the trailing argument array.
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp (revision 91549)
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp (working copy)
@@ -1523,7 +1523,8 @@
Proto->hasAnyExceptionSpec(),
Exceptions.size(),
Exceptions.data(),
- Proto->getNoReturnAttr()));
+ Proto->getNoReturnAttr(),
+ Proto->getCallConv()));
}
return false;
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp (revision 91549)
+++ lib/AST/ASTContext.cpp (working copy)
@@ -1222,7 +1222,8 @@
return T;
if (const FunctionNoProtoType *FNPT = dyn_cast<FunctionNoProtoType>(F)) {
- ResultType = getFunctionNoProtoType(FNPT->getResultType(), AddNoReturn);
+ ResultType = getFunctionNoProtoType(FNPT->getResultType(), AddNoReturn,
+ FNPT->getCallConv());
} else {
const FunctionProtoType *FPT = cast<FunctionProtoType>(F);
ResultType
@@ -1231,7 +1232,7 @@
FPT->getTypeQuals(),
FPT->hasExceptionSpec(), FPT->hasAnyExceptionSpec(),
FPT->getNumExceptions(), FPT->exception_begin(),
- AddNoReturn);
+ AddNoReturn, FPT->getCallConv());
}
} else
return T;
@@ -1239,6 +1240,38 @@
return getQualifiedType(ResultType, T.getLocalQualifiers());
}
+QualType ASTContext::getCallConvType(QualType T, unsigned CallConv) {
+ QualType ResultType;
+ if (const PointerType *Pointer = T->getAs<PointerType>()) {
+ QualType Pointee = Pointer->getPointeeType();
+ ResultType = getCallConvType(Pointee, CallConv);
+ if (ResultType == Pointee)
+ return T;
+
+ ResultType = getPointerType(ResultType);
+ } else if (const FunctionType *F = T->getAs<FunctionType>()) {
+ if (F->getCallConv() == CallConv)
+ return T;
+
+ if (const FunctionNoProtoType *FNPT = dyn_cast<FunctionNoProtoType>(F)) {
+ ResultType = getFunctionNoProtoType(FNPT->getResultType(),
+ FNPT->getNoReturn(), CallConv);
+ } else {
+ const FunctionProtoType *FPT = cast<FunctionProtoType>(F);
+ ResultType
+ = getFunctionType(FPT->getResultType(), FPT->arg_type_begin(),
+ FPT->getNumArgs(), FPT->isVariadic(),
+ FPT->getTypeQuals(),
+ FPT->hasExceptionSpec(), FPT->hasAnyExceptionSpec(),
+ FPT->getNumExceptions(), FPT->exception_begin(),
+ FPT->getNoReturn(), CallConv);
+ }
+ } else
+ return T;
+
+ return getQualifiedType(ResultType, T.getLocalQualifiers());
+}
+
/// getComplexType - Return the uniqued reference to the type for a complex
/// number with the specified element type.
QualType ASTContext::getComplexType(QualType T) {
@@ -1690,7 +1723,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,
+ unsigned CallConv) {
// Unique functions, to guarantee there is only one function of a particular
// structure.
llvm::FoldingSetNodeID ID;
@@ -1703,7 +1737,8 @@
QualType Canonical;
if (!ResultTy.isCanonical()) {
- Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy), NoReturn);
+ Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy), NoReturn,
+ CallConv);
// Get the new insert position for the node we care about.
FunctionNoProtoType *NewIP =
@@ -1724,7 +1759,8 @@
unsigned NumArgs, bool isVariadic,
unsigned TypeQuals, bool hasExceptionSpec,
bool hasAnyExceptionSpec, unsigned NumExs,
- const QualType *ExArray, bool NoReturn) {
+ const QualType *ExArray, bool NoReturn,
+ unsigned CallConv) {
// Unique functions, to guarantee there is only one function of a particular
// structure.
llvm::FoldingSetNodeID ID;
@@ -1755,7 +1791,7 @@
Canonical = getFunctionType(getCanonicalType(ResultTy),
CanonicalArgs.data(), NumArgs,
isVariadic, TypeQuals, false,
- false, 0, 0, NoReturn);
+ false, 0, 0, NoReturn, CallConv);
// Get the new insert position for the node we care about.
FunctionProtoType *NewIP =
@@ -1772,7 +1808,7 @@
NumExs*sizeof(QualType), TypeAlignment);
new (FTP) FunctionProtoType(ResultTy, ArgArray, NumArgs, isVariadic,
TypeQuals, hasExceptionSpec, hasAnyExceptionSpec,
- ExArray, NumExs, Canonical, NoReturn);
+ ExArray, NumExs, Canonical, NoReturn, CallConv);
Types.push_back(FTP);
FunctionProtoTypes.InsertNode(FTP, InsertPos);
return QualType(FTP, 0);
@@ -4213,6 +4249,11 @@
allLTypes = false;
if (NoReturn != rbase->getNoReturnAttr())
allRTypes = false;
+ unsigned lcc = lbase->getCallConv();
+ unsigned rcc = rbase->getCallConv();
+ // Compatible functions must have the same calling convention
+ if((lcc == 0 || rcc != 0) && lcc != rcc)
+ return QualType();
if (lproto && rproto) { // two C99 style function prototypes
assert(!lproto->hasExceptionSpec() && !rproto->hasExceptionSpec() &&
@@ -4248,7 +4289,7 @@
if (allRTypes) return rhs;
return getFunctionType(retType, types.begin(), types.size(),
lproto->isVariadic(), lproto->getTypeQuals(),
- NoReturn);
+ NoReturn, lcc);
}
if (lproto) allRTypes = false;
@@ -4275,12 +4316,12 @@
if (allRTypes) return rhs;
return getFunctionType(retType, proto->arg_type_begin(),
proto->getNumArgs(), proto->isVariadic(),
- proto->getTypeQuals(), NoReturn);
+ proto->getTypeQuals(), NoReturn, lcc);
}
if (allLTypes) return lhs;
if (allRTypes) return rhs;
- return getFunctionNoProtoType(retType, NoReturn);
+ return getFunctionNoProtoType(retType, NoReturn, lcc);
}
QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits