summaryrefslogtreecommitdiffstats
path: root/lib/AST/ASTContext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/ASTContext.cpp')
-rw-r--r--lib/AST/ASTContext.cpp104
1 files changed, 70 insertions, 34 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 76ec852..c1bc709 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1200,43 +1200,58 @@ QualType ASTContext::getObjCGCQualType(QualType T,
return getExtQualType(TypeNode, Quals);
}
-QualType ASTContext::getNoReturnType(QualType T, bool AddNoReturn) {
+static QualType getNoReturnCallConvType(ASTContext& Context, QualType T,
+ bool AddNoReturn,
+ CallingConv CallConv) {
QualType ResultType;
if (const PointerType *Pointer = T->getAs<PointerType>()) {
QualType Pointee = Pointer->getPointeeType();
- ResultType = getNoReturnType(Pointee, AddNoReturn);
+ ResultType = getNoReturnCallConvType(Context, Pointee, AddNoReturn,
+ CallConv);
if (ResultType == Pointee)
return T;
-
- ResultType = getPointerType(ResultType);
+
+ ResultType = Context.getPointerType(ResultType);
} else if (const BlockPointerType *BlockPointer
= T->getAs<BlockPointerType>()) {
QualType Pointee = BlockPointer->getPointeeType();
- ResultType = getNoReturnType(Pointee, AddNoReturn);
+ ResultType = getNoReturnCallConvType(Context, Pointee, AddNoReturn,
+ CallConv);
if (ResultType == Pointee)
return T;
-
- ResultType = getBlockPointerType(ResultType);
- } else if (const FunctionType *F = T->getAs<FunctionType>()) {
- if (F->getNoReturnAttr() == AddNoReturn)
+
+ ResultType = Context.getBlockPointerType(ResultType);
+ } else if (const FunctionType *F = T->getAs<FunctionType>()) {
+ if (F->getNoReturnAttr() == AddNoReturn && F->getCallConv() == CallConv)
return T;
-
+
if (const FunctionNoProtoType *FNPT = dyn_cast<FunctionNoProtoType>(F)) {
- ResultType = getFunctionNoProtoType(FNPT->getResultType(), AddNoReturn);
+ ResultType = Context.getFunctionNoProtoType(FNPT->getResultType(),
+ AddNoReturn, 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(),
- AddNoReturn);
+ = Context.getFunctionType(FPT->getResultType(), FPT->arg_type_begin(),
+ FPT->getNumArgs(), FPT->isVariadic(),
+ FPT->getTypeQuals(),
+ FPT->hasExceptionSpec(),
+ FPT->hasAnyExceptionSpec(),
+ FPT->getNumExceptions(),
+ FPT->exception_begin(),
+ AddNoReturn, CallConv);
}
} else
return T;
-
- return getQualifiedType(ResultType, T.getLocalQualifiers());
+
+ return Context.getQualifiedType(ResultType, T.getLocalQualifiers());
+}
+
+QualType ASTContext::getNoReturnType(QualType T, bool AddNoReturn) {
+ return getNoReturnCallConvType(*this, T, AddNoReturn, T.getCallConv());
+}
+
+QualType ASTContext::getCallConvType(QualType T, CallingConv CallConv) {
+ return getNoReturnCallConvType(*this, T, T.getNoReturnAttr(), CallConv);
}
/// getComplexType - Return the uniqued reference to the type for a complex
@@ -1679,9 +1694,16 @@ QualType ASTContext::getDependentSizedExtVectorType(QualType vecType,
return QualType(New, 0);
}
+static CallingConv getCanonicalCallingConv(CallingConv CC) {
+ if (CC == CC_C)
+ return CC_Default;
+ return CC;
+}
+
/// 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;
@@ -1693,8 +1715,10 @@ QualType ASTContext::getFunctionNoProtoType(QualType ResultTy, bool NoReturn) {
return QualType(FT, 0);
QualType Canonical;
- if (!ResultTy.isCanonical()) {
- Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy), NoReturn);
+ if (!ResultTy.isCanonical() ||
+ getCanonicalCallingConv(CallConv) != CallConv) {
+ Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy), NoReturn,
+ getCanonicalCallingConv(CallConv));
// Get the new insert position for the node we care about.
FunctionNoProtoType *NewIP =
@@ -1715,7 +1739,8 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray,
unsigned NumArgs, bool isVariadic,
unsigned TypeQuals, bool hasExceptionSpec,
bool hasAnyExceptionSpec, unsigned NumExs,
- const QualType *ExArray, bool NoReturn) {
+ const QualType *ExArray, bool NoReturn,
+ CallingConv CallConv) {
// Unique functions, to guarantee there is only one function of a particular
// structure.
llvm::FoldingSetNodeID ID;
@@ -1737,7 +1762,7 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray,
// If this type isn't canonical, get the canonical version of it.
// The exception spec is not part of the canonical type.
QualType Canonical;
- if (!isCanonical) {
+ if (!isCanonical || getCanonicalCallingConv(CallConv) != CallConv) {
llvm::SmallVector<QualType, 16> CanonicalArgs;
CanonicalArgs.reserve(NumArgs);
for (unsigned i = 0; i != NumArgs; ++i)
@@ -1746,7 +1771,8 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray,
Canonical = getFunctionType(getCanonicalType(ResultTy),
CanonicalArgs.data(), NumArgs,
isVariadic, TypeQuals, false,
- false, 0, 0, NoReturn);
+ false, 0, 0, NoReturn,
+ getCanonicalCallingConv(CallConv));
// Get the new insert position for the node we care about.
FunctionProtoType *NewIP =
@@ -1763,7 +1789,7 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray,
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);
@@ -2101,7 +2127,8 @@ QualType ASTContext::getObjCObjectPointerType(QualType InterfaceT,
// No Match;
ObjCObjectPointerType *QType = new (*this, TypeAlignment)
- ObjCObjectPointerType(Canonical, InterfaceT, Protocols, NumProtocols);
+ ObjCObjectPointerType(*this, Canonical, InterfaceT, Protocols,
+ NumProtocols);
Types.push_back(QType);
ObjCObjectPointerTypes.InsertNode(QType, InsertPos);
@@ -2135,7 +2162,7 @@ QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
}
ObjCInterfaceType *QType = new (*this, TypeAlignment)
- ObjCInterfaceType(Canonical, const_cast<ObjCInterfaceDecl*>(Decl),
+ ObjCInterfaceType(*this, Canonical, const_cast<ObjCInterfaceDecl*>(Decl),
Protocols, NumProtocols);
Types.push_back(QType);
@@ -3733,8 +3760,8 @@ void ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) {
/// \brief Retrieve the template name that corresponds to a non-empty
/// lookup.
-TemplateName ASTContext::getOverloadedTemplateName(NamedDecl * const *Begin,
- NamedDecl * const *End) {
+TemplateName ASTContext::getOverloadedTemplateName(UnresolvedSetIterator Begin,
+ UnresolvedSetIterator End) {
unsigned size = End - Begin;
assert(size > 1 && "set is not overloaded!");
@@ -3743,7 +3770,7 @@ TemplateName ASTContext::getOverloadedTemplateName(NamedDecl * const *Begin,
OverloadedTemplateStorage *OT = new(memory) OverloadedTemplateStorage(size);
NamedDecl **Storage = OT->getStorage();
- for (NamedDecl * const *I = Begin; I != End; ++I) {
+ for (UnresolvedSetIterator I = Begin; I != End; ++I) {
NamedDecl *D = *I;
assert(isa<FunctionTemplateDecl>(D) ||
(isa<UsingShadowDecl>(D) &&
@@ -4211,6 +4238,10 @@ bool ASTContext::typesAreCompatible(QualType LHS, QualType RHS) {
return !mergeTypes(LHS, RHS).isNull();
}
+static bool isSameCallingConvention(CallingConv lcc, CallingConv rcc) {
+ return (getCanonicalCallingConv(lcc) == getCanonicalCallingConv(rcc));
+}
+
QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) {
const FunctionType *lbase = lhs->getAs<FunctionType>();
const FunctionType *rbase = rhs->getAs<FunctionType>();
@@ -4232,6 +4263,11 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) {
allLTypes = false;
if (NoReturn != rbase->getNoReturnAttr())
allRTypes = false;
+ CallingConv lcc = lbase->getCallConv();
+ CallingConv rcc = rbase->getCallConv();
+ // Compatible functions must have compatible calling conventions
+ if (!isSameCallingConvention(lcc, rcc))
+ return QualType();
if (lproto && rproto) { // two C99 style function prototypes
assert(!lproto->hasExceptionSpec() && !rproto->hasExceptionSpec() &&
@@ -4267,7 +4303,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) {
if (allRTypes) return rhs;
return getFunctionType(retType, types.begin(), types.size(),
lproto->isVariadic(), lproto->getTypeQuals(),
- NoReturn);
+ NoReturn, lcc);
}
if (lproto) allRTypes = false;
@@ -4294,12 +4330,12 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) {
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) {
OpenPOWER on IntegriCloud