SmallVectorImpl<BuiltinCandidateTypeSet> &CandidateTypes;
OverloadCandidateSet &CandidateSet;
- // Define some constants used to index and iterate over the arithemetic types
- // provided via the getArithmeticType() method below.
- // The "promoted arithmetic types" are the arithmetic
+ static constexpr int ArithmeticTypesCap = 24;
+ SmallVector<CanQualType, ArithmeticTypesCap> ArithmeticTypes;
+
+ // Define some indices used to iterate over the arithemetic types in
+ // ArithmeticTypes. The "promoted arithmetic types" are the arithmetic
// types are that preserved by promotion (C++ [over.built]p2).
- static const unsigned FirstIntegralType = 4;
- static const unsigned LastIntegralType = 21;
- static const unsigned FirstPromotedIntegralType = 4,
- LastPromotedIntegralType = 12;
- static const unsigned FirstPromotedArithmeticType = 0,
- LastPromotedArithmeticType = 12;
- static const unsigned NumArithmeticTypes = 21;
-
- /// \brief Get the canonical type for a given arithmetic type index.
- CanQualType getArithmeticType(unsigned index) {
- assert(index < NumArithmeticTypes);
- static CanQualType ASTContext::* const
- ArithmeticTypes[NumArithmeticTypes] = {
- // Start of promoted types.
- &ASTContext::FloatTy,
- &ASTContext::DoubleTy,
- &ASTContext::LongDoubleTy,
- &ASTContext::Float128Ty,
-
- // Start of integral types.
- &ASTContext::IntTy,
- &ASTContext::LongTy,
- &ASTContext::LongLongTy,
- &ASTContext::Int128Ty,
- &ASTContext::UnsignedIntTy,
- &ASTContext::UnsignedLongTy,
- &ASTContext::UnsignedLongLongTy,
- &ASTContext::UnsignedInt128Ty,
- // End of promoted types.
-
- &ASTContext::BoolTy,
- &ASTContext::CharTy,
- &ASTContext::WCharTy,
- &ASTContext::Char16Ty,
- &ASTContext::Char32Ty,
- &ASTContext::SignedCharTy,
- &ASTContext::ShortTy,
- &ASTContext::UnsignedCharTy,
- &ASTContext::UnsignedShortTy,
- // End of integral types.
- // FIXME: What about complex? What about half?
- };
- return S.Context.*ArithmeticTypes[index];
+ unsigned FirstIntegralType,
+ LastIntegralType;
+ unsigned FirstPromotedIntegralType,
+ LastPromotedIntegralType;
+ unsigned FirstPromotedArithmeticType,
+ LastPromotedArithmeticType;
+ unsigned NumArithmeticTypes;
+
+ void InitArithmeticTypes() {
+ // Start of promoted types.
+ FirstPromotedArithmeticType = 0;
+ ArithmeticTypes.push_back(S.Context.FloatTy);
+ ArithmeticTypes.push_back(S.Context.DoubleTy);
+ ArithmeticTypes.push_back(S.Context.LongDoubleTy);
+ if (S.Context.getTargetInfo().hasFloat128Type())
+ ArithmeticTypes.push_back(S.Context.Float128Ty);
+
+ // Start of integral types.
+ FirstIntegralType = ArithmeticTypes.size();
+ FirstPromotedIntegralType = ArithmeticTypes.size();
+ ArithmeticTypes.push_back(S.Context.IntTy);
+ ArithmeticTypes.push_back(S.Context.LongTy);
+ ArithmeticTypes.push_back(S.Context.LongLongTy);
+ if (S.Context.getTargetInfo().hasInt128Type())
+ ArithmeticTypes.push_back(S.Context.Int128Ty);
+ ArithmeticTypes.push_back(S.Context.UnsignedIntTy);
+ ArithmeticTypes.push_back(S.Context.UnsignedLongTy);
+ ArithmeticTypes.push_back(S.Context.UnsignedLongLongTy);
+ if (S.Context.getTargetInfo().hasInt128Type())
+ ArithmeticTypes.push_back(S.Context.UnsignedInt128Ty);
+ LastPromotedIntegralType = ArithmeticTypes.size();
+ LastPromotedArithmeticType = ArithmeticTypes.size();
+ // End of promoted types.
+
+ ArithmeticTypes.push_back(S.Context.BoolTy);
+ ArithmeticTypes.push_back(S.Context.CharTy);
+ ArithmeticTypes.push_back(S.Context.WCharTy);
+ ArithmeticTypes.push_back(S.Context.Char16Ty);
+ ArithmeticTypes.push_back(S.Context.Char32Ty);
+ ArithmeticTypes.push_back(S.Context.SignedCharTy);
+ ArithmeticTypes.push_back(S.Context.ShortTy);
+ ArithmeticTypes.push_back(S.Context.UnsignedCharTy);
+ ArithmeticTypes.push_back(S.Context.UnsignedShortTy);
+ LastIntegralType = ArithmeticTypes.size();
+ NumArithmeticTypes = ArithmeticTypes.size();
+ // End of integral types.
+ // FIXME: What about complex? What about half?
+
+ assert(ArithmeticTypes.size() <= ArithmeticTypesCap &&
+ "Enough inline storage for all arithmetic types.");
}
/// \brief Helper method to factor out the common pattern of adding overloads
HasArithmeticOrEnumeralCandidateType),
CandidateTypes(CandidateTypes),
CandidateSet(CandidateSet) {
- // Validate some of our static helper constants in debug builds.
- assert(getArithmeticType(FirstPromotedIntegralType) == S.Context.IntTy &&
- "Invalid first promoted integral type");
- assert(getArithmeticType(LastPromotedIntegralType - 1)
- == S.Context.UnsignedInt128Ty &&
- "Invalid last promoted integral type");
- assert(getArithmeticType(FirstPromotedArithmeticType)
- == S.Context.FloatTy &&
- "Invalid first promoted arithmetic type");
- assert(getArithmeticType(LastPromotedArithmeticType - 1)
- == S.Context.UnsignedInt128Ty &&
- "Invalid last promoted arithmetic type");
+
+ InitArithmeticTypes();
}
// C++ [over.built]p3:
for (unsigned Arith = (Op == OO_PlusPlus? 0 : 1);
Arith < NumArithmeticTypes; ++Arith) {
addPlusPlusMinusMinusStyleOverloads(
- getArithmeticType(Arith),
+ ArithmeticTypes[Arith],
VisibleTypeConversionsQuals.hasVolatile(),
VisibleTypeConversionsQuals.hasRestrict());
}
for (unsigned Arith = FirstPromotedArithmeticType;
Arith < LastPromotedArithmeticType; ++Arith) {
- QualType ArithTy = getArithmeticType(Arith);
+ QualType ArithTy = ArithmeticTypes[Arith];
S.AddBuiltinCandidate(&ArithTy, Args, CandidateSet);
}
for (unsigned Int = FirstPromotedIntegralType;
Int < LastPromotedIntegralType; ++Int) {
- QualType IntTy = getArithmeticType(Int);
+ QualType IntTy = ArithmeticTypes[Int];
S.AddBuiltinCandidate(&IntTy, Args, CandidateSet);
}
Left < LastPromotedArithmeticType; ++Left) {
for (unsigned Right = FirstPromotedArithmeticType;
Right < LastPromotedArithmeticType; ++Right) {
- QualType LandR[2] = { getArithmeticType(Left),
- getArithmeticType(Right) };
+ QualType LandR[2] = { ArithmeticTypes[Left],
+ ArithmeticTypes[Right] };
S.AddBuiltinCandidate(LandR, Args, CandidateSet);
}
}
Left < LastPromotedIntegralType; ++Left) {
for (unsigned Right = FirstPromotedIntegralType;
Right < LastPromotedIntegralType; ++Right) {
- QualType LandR[2] = { getArithmeticType(Left),
- getArithmeticType(Right) };
+ QualType LandR[2] = { ArithmeticTypes[Left],
+ ArithmeticTypes[Right] };
S.AddBuiltinCandidate(LandR, Args, CandidateSet);
}
}
for (unsigned Right = FirstPromotedArithmeticType;
Right < LastPromotedArithmeticType; ++Right) {
QualType ParamTypes[2];
- ParamTypes[1] = getArithmeticType(Right);
+ ParamTypes[1] = ArithmeticTypes[Right];
// Add this built-in operator as a candidate (VQ is empty).
ParamTypes[0] =
- S.Context.getLValueReferenceType(getArithmeticType(Left));
+ S.Context.getLValueReferenceType(ArithmeticTypes[Left]);
S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet,
/*IsAssigmentOperator=*/isEqualOp);
// Add this built-in operator as a candidate (VQ is 'volatile').
if (VisibleTypeConversionsQuals.hasVolatile()) {
ParamTypes[0] =
- S.Context.getVolatileType(getArithmeticType(Left));
+ S.Context.getVolatileType(ArithmeticTypes[Left]);
ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]);
S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet,
/*IsAssigmentOperator=*/isEqualOp);
for (unsigned Right = FirstPromotedIntegralType;
Right < LastPromotedIntegralType; ++Right) {
QualType ParamTypes[2];
- ParamTypes[1] = getArithmeticType(Right);
+ ParamTypes[1] = ArithmeticTypes[Right];
// Add this built-in operator as a candidate (VQ is empty).
ParamTypes[0] =
- S.Context.getLValueReferenceType(getArithmeticType(Left));
+ S.Context.getLValueReferenceType(ArithmeticTypes[Left]);
S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet);
if (VisibleTypeConversionsQuals.hasVolatile()) {
// Add this built-in operator as a candidate (VQ is 'volatile').
- ParamTypes[0] = getArithmeticType(Left);
+ ParamTypes[0] = ArithmeticTypes[Left];
ParamTypes[0] = S.Context.getVolatileType(ParamTypes[0]);
ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]);
S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet);