/// \brief Return a normal function type with a typed argument list.
QualType getFunctionType(QualType ResultTy, ArrayRef<QualType> Args,
- const FunctionProtoType::ExtProtoInfo &EPI) const;
+ const FunctionProtoType::ExtProtoInfo &EPI) const {
+ return getFunctionTypeInternal(ResultTy, Args, EPI, false);
+ }
+private:
+ /// \brief Return a normal function type with a typed argument list.
+ QualType getFunctionTypeInternal(QualType ResultTy, ArrayRef<QualType> Args,
+ const FunctionProtoType::ExtProtoInfo &EPI,
+ bool OnlyWantCanonical) const;
+
+public:
/// \brief Return the unique reference to the type for the specified type
/// declaration.
QualType getTypeDeclType(const TypeDecl *Decl,
return false;
}
-QualType
-ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray,
- const FunctionProtoType::ExtProtoInfo &EPI) const {
+QualType ASTContext::getFunctionTypeInternal(
+ QualType ResultTy, ArrayRef<QualType> ArgArray,
+ const FunctionProtoType::ExtProtoInfo &EPI, bool OnlyWantCanonical) const {
size_t NumArgs = ArgArray.size();
// Unique functions, to guarantee there is only one function of a particular
// If we find a pre-existing equivalent FunctionProtoType, we can just reuse
// it so long as our exception specification doesn't contain a dependent
- // noexcept expression. If it /does/, we're going to need to create a type
+ // noexcept expression, or we're just looking for a canonical type.
+ // Otherwise, we're going to need to create a type
// sugar node to hold the concrete expression.
- if (EPI.ExceptionSpec.Type != EST_ComputedNoexcept ||
+ if (OnlyWantCanonical || EPI.ExceptionSpec.Type != EST_ComputedNoexcept ||
EPI.ExceptionSpec.NoexceptExpr == FPT->getNoexceptExpr())
return Existing;
if (!ArgArray[i].isCanonicalAsParam())
isCanonical = false;
+ if (OnlyWantCanonical)
+ assert(isCanonical &&
+ "given non-canonical parameters constructing canonical type");
+
// If this type isn't canonical, get the canonical version of it if we don't
// already have it. The exception spec is only partially part of the
// canonical type, and only in C++17 onwards.
Value.getBoolValue() ? EST_BasicNoexcept : EST_None;
break;
}
- assert(isCanonicalExceptionSpecification(CanonicalEPI.ExceptionSpec,
- NoexceptInType));
} else {
CanonicalEPI.ExceptionSpec = FunctionProtoType::ExceptionSpecInfo();
}
// Adjust the canonical function result type.
CanQualType CanResultTy = getCanonicalFunctionResultType(ResultTy);
- Canonical = getFunctionType(CanResultTy, CanonicalArgs, CanonicalEPI);
+ Canonical =
+ getFunctionTypeInternal(CanResultTy, CanonicalArgs, CanonicalEPI, true);
// Get the new insert position for the node we care about.
FunctionProtoType *NewIP =