// Encode type qualifer, 'in', 'inout', etc. for the parameter.
getObjCEncodingForTypeQualifier(QT, S);
// Encode parameter type.
- getObjCEncodingForTypeImpl(T, S, /*ExpandPointedToStructures=*/true,
- /*ExpandStructures=*/true, /*Field=*/nullptr,
- /*OutermostType=*/true,
- /*EncodingProperty=*/false,
- /*StructField=*/false,
- /*EncodeBlockParameters=*/Extended,
- /*EncodeClassNames=*/Extended);
+ ObjCEncOptions Options = ObjCEncOptions()
+ .setExpandPointedToStructures()
+ .setExpandStructures()
+ .setIsOutermostType();
+ if (Extended)
+ Options.setEncodeBlockParameters().setEncodeClassNames();
+ getObjCEncodingForTypeImpl(T, S, Options, /*Field=*/nullptr);
}
/// getObjCEncodingForMethodDecl - Return the encoded type for this method
// directly pointed to, and expanding embedded structures. Note that
// these rules are sufficient to prevent recursive encoding of the
// same type.
- getObjCEncodingForTypeImpl(T, S, /*ExpandPointedToStructures=*/true,
- /*ExpandStructures=*/true, Field,
- /*OutermostType=*/true, /*EncodingProperty=*/false,
- /*StructField=*/false,
- /*EncodeBlockParameters=*/false,
- /*EncodeClassNames=*/false,
- /*EncodePointerToObjCTypedef=*/false, NotEncodedT);
+ getObjCEncodingForTypeImpl(T, S,
+ ObjCEncOptions()
+ .setExpandPointedToStructures()
+ .setExpandStructures()
+ .setIsOutermostType(),
+ Field, NotEncodedT);
}
void ASTContext::getObjCEncodingForPropertyType(QualType T,
// Encode result type.
// GCC has some special rules regarding encoding of properties which
// closely resembles encoding of ivars.
- getObjCEncodingForTypeImpl(
- T, S, /*ExpandPointedToStructures=*/true, /*ExpandStructures=*/true,
- /*Field=*/nullptr, /*OutermostType=*/true, /*EncodingProperty=*/true);
+ getObjCEncodingForTypeImpl(T, S,
+ ObjCEncOptions()
+ .setExpandPointedToStructures()
+ .setExpandStructures()
+ .setIsOutermostType()
+ .setEncodingProperty(),
+ /*Field=*/nullptr);
}
static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
}
// FIXME: Use SmallString for accumulating string.
-void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
- bool ExpandPointedToStructures,
- bool ExpandStructures,
+void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S,
+ const ObjCEncOptions Options,
const FieldDecl *FD,
- bool OutermostType,
- bool EncodingProperty,
- bool StructField,
- bool EncodeBlockParameters,
- bool EncodeClassNames,
- bool EncodePointerToObjCTypedef,
QualType *NotEncodedT) const {
CanQualType CT = getCanonicalType(T);
switch (CT->getTypeClass()) {
case Type::Complex: {
const auto *CT = T->castAs<ComplexType>();
S += 'j';
- getObjCEncodingForTypeImpl(CT->getElementType(), S,
- /*ExpandPointedToStructures=*/false,
- /*ExpandStructures=*/false, /*Field=*/nullptr);
+ getObjCEncodingForTypeImpl(CT->getElementType(), S, ObjCEncOptions(),
+ /*Field=*/nullptr);
return;
}
case Type::Atomic: {
const auto *AT = T->castAs<AtomicType>();
S += 'A';
- getObjCEncodingForTypeImpl(AT->getValueType(), S,
- /*ExpandPointedToStructures=*/false,
- /*ExpandStructures=*/false, /*Field=*/nullptr);
+ getObjCEncodingForTypeImpl(AT->getValueType(), S, ObjCEncOptions(),
+ /*Field=*/nullptr);
return;
}
// the pointer itself gets ignored, _unless_ we are looking at a typedef!
// Also, do not emit the 'r' for anything but the outermost type!
if (isa<TypedefType>(T.getTypePtr())) {
- if (OutermostType && T.isConstQualified()) {
+ if (Options.IsOutermostType() && T.isConstQualified()) {
isReadOnly = true;
S += 'r';
}
- } else if (OutermostType) {
+ } else if (Options.IsOutermostType()) {
QualType P = PointeeTy;
while (P->getAs<PointerType>())
P = P->getAs<PointerType>()->getPointeeType();
S += '^';
getLegacyIntegralTypeEncoding(PointeeTy);
- getObjCEncodingForTypeImpl(
- PointeeTy, S, /*ExpandPointedToStructures=*/false,
- /*ExpandStructures=*/ExpandPointedToStructures, /*Field=*/nullptr,
- /*OutermostType=*/false, /*EncodingProperty=*/false,
- /*StructField=*/false, /*EncodeBlockParameters=*/false,
- /*EncodeClassNames=*/false, /*EncodePointerToObjCTypedef=*/false,
- NotEncodedT);
+ ObjCEncOptions NewOptions;
+ if (Options.ExpandPointedToStructures())
+ NewOptions.setExpandStructures();
+ getObjCEncodingForTypeImpl(PointeeTy, S, NewOptions,
+ /*Field=*/nullptr, NotEncodedT);
return;
}
case Type::VariableArray: {
const auto *AT = cast<ArrayType>(CT);
- if (isa<IncompleteArrayType>(AT) && !StructField) {
+ if (isa<IncompleteArrayType>(AT) && !Options.IsStructField()) {
// Incomplete arrays are encoded as a pointer to the array element.
S += '^';
- getObjCEncodingForTypeImpl(AT->getElementType(), S,
- /*ExpandPointedToStructures=*/false,
- ExpandStructures, FD);
+ getObjCEncodingForTypeImpl(
+ AT->getElementType(), S,
+ Options.keepingOnly(ObjCEncOptions().setExpandStructures()), FD);
} else {
S += '[';
getObjCEncodingForTypeImpl(
AT->getElementType(), S,
- /*ExpandPointedToStructures=*/false, ExpandStructures, FD,
- /*OutermostType=*/false,
- /*EncodingProperty=*/false, /*StructField=*/false,
- /*EncodeBlockParameters=*/false, /*EncodeClassNames=*/false,
- /*EncodePointerToObjCTypedef=*/false, NotEncodedT);
+ Options.keepingOnly(ObjCEncOptions().setExpandStructures()), FD,
+ NotEncodedT);
S += ']';
}
return;
} else {
S += '?';
}
- if (ExpandStructures) {
+ if (Options.ExpandStructures()) {
S += '=';
if (!RDecl->isUnion()) {
getObjCEncodingForStructureImpl(RDecl, S, FD, true, NotEncodedT);
// Special case bit-fields.
if (Field->isBitField()) {
getObjCEncodingForTypeImpl(Field->getType(), S,
- /*ExpandPointedToStructures=*/false,
- /*ExpandStructures=*/true, Field);
+ ObjCEncOptions().setExpandStructures(),
+ Field);
} else {
QualType qt = Field->getType();
getLegacyIntegralTypeEncoding(qt);
getObjCEncodingForTypeImpl(
- qt, S, /*ExpandPointedToStructures=*/false,
- /*ExpandStructures=*/true, FD, /*OutermostType=*/false,
- /*EncodingProperty=*/false,
- /*StructField=*/true, /*EncodeBlockParameters=*/false,
- /*EncodeClassNames=*/false,
- /*EncodePointerToObjCTypedef=*/false, NotEncodedT);
+ qt, S,
+ ObjCEncOptions().setExpandStructures().setIsStructField(), FD,
+ NotEncodedT);
}
}
}
case Type::BlockPointer: {
const auto *BT = T->castAs<BlockPointerType>();
S += "@?"; // Unlike a pointer-to-function, which is "^?".
- if (EncodeBlockParameters) {
+ if (Options.EncodeBlockParameters()) {
const auto *FT = BT->getPointeeType()->castAs<FunctionType>();
S += '<';
// Block return type
- getObjCEncodingForTypeImpl(
- FT->getReturnType(), S, ExpandPointedToStructures, ExpandStructures,
- FD, /*OutermostType=*/false, EncodingProperty,
- /*StructField=*/false, EncodeBlockParameters, EncodeClassNames,
- /*EncodePointerToObjCTypedef=*/false, NotEncodedT);
+ getObjCEncodingForTypeImpl(FT->getReturnType(), S,
+ Options.forComponentType(), FD, NotEncodedT);
// Block self
S += "@?";
// Block parameters
if (const auto *FPT = dyn_cast<FunctionProtoType>(FT)) {
for (const auto &I : FPT->param_types())
- getObjCEncodingForTypeImpl(
- I, S, ExpandPointedToStructures, ExpandStructures, FD,
- /*OutermostType=*/false, EncodingProperty,
- /*StructField=*/false, EncodeBlockParameters, EncodeClassNames,
- /*EncodePointerToObjCTypedef=*/false, NotEncodedT);
+ getObjCEncodingForTypeImpl(I, S, Options.forComponentType(), FD,
+ NotEncodedT);
}
S += '>';
}
ObjCInterfaceDecl *OI = T->castAs<ObjCObjectType>()->getInterface();
S += '{';
S += OI->getObjCRuntimeNameAsString();
- if (ExpandStructures) {
+ if (Options.ExpandStructures()) {
S += '=';
SmallVector<const ObjCIvarDecl*, 32> Ivars;
DeepCollectObjCIvars(OI, true, Ivars);
const FieldDecl *Field = Ivars[i];
if (Field->isBitField())
getObjCEncodingForTypeImpl(Field->getType(), S,
- /*ExpandPointedToStructures=*/false,
- /*ExpandStructures=*/true, Field);
- else
- getObjCEncodingForTypeImpl(
- Field->getType(), S,
- /*ExpandPointedToStructures=*/false,
- /*ExpandStructures=*/true, FD, /*OutermostType=*/false,
- /*EncodingProperty=*/false,
- /*StructField=*/false, /*EncodeBlockParameters=*/false,
- /*EncodeClassNames=*/false, EncodePointerToObjCTypedef,
- NotEncodedT);
+ ObjCEncOptions().setExpandStructures(),
+ Field);
+ else {
+ ObjCEncOptions NewOptions = ObjCEncOptions().setExpandStructures();
+ if (Options.EncodePointerToObjCTypedef())
+ NewOptions.setEncodePointerToObjCTypedef();
+ getObjCEncodingForTypeImpl(Field->getType(), S, NewOptions, FD,
+ NotEncodedT);
+ }
}
}
S += '}';
}
if (OPT->isObjCQualifiedIdType()) {
- getObjCEncodingForTypeImpl(getObjCIdType(), S,
- ExpandPointedToStructures,
- ExpandStructures, FD);
- if (FD || EncodingProperty || EncodeClassNames) {
+ getObjCEncodingForTypeImpl(
+ getObjCIdType(), S,
+ Options.keepingOnly(ObjCEncOptions()
+ .setExpandPointedToStructures()
+ .setExpandStructures()),
+ FD);
+ if (FD || Options.EncodingProperty() || Options.EncodeClassNames()) {
// Note that we do extended encoding of protocol qualifer list
// Only when doing ivar or property encoding.
S += '"';
}
QualType PointeeTy = OPT->getPointeeType();
- if (!EncodingProperty &&
+ if (!Options.EncodingProperty() &&
isa<TypedefType>(PointeeTy.getTypePtr()) &&
- !EncodePointerToObjCTypedef) {
+ !Options.EncodePointerToObjCTypedef()) {
// Another historical/compatibility reason.
// We encode the underlying type which comes out as
// {...};
}
}
}
- getObjCEncodingForTypeImpl(
- PointeeTy, S,
- /*ExpandPointedToStructures=*/false,
- /*ExpandStructures=*/ExpandPointedToStructures,
- /*Field=*/nullptr,
- /*OutermostType=*/false, /*EncodingProperty=*/false,
- /*StructField=*/false, /*EncodeBlockParameters=*/false,
- /*EncodeClassNames=*/false,
- /*EncodePointerToObjCTypedef=*/true);
+ ObjCEncOptions NewOptions =
+ ObjCEncOptions().setEncodePointerToObjCTypedef();
+ if (Options.ExpandPointedToStructures())
+ NewOptions.setExpandStructures();
+ getObjCEncodingForTypeImpl(PointeeTy, S, NewOptions, /*Field=*/nullptr);
return;
}
S += '@';
if (OPT->getInterfaceDecl() &&
- (FD || EncodingProperty || EncodeClassNames)) {
+ (FD || Options.EncodingProperty() || Options.EncodeClassNames())) {
S += '"';
S += OPT->getInterfaceDecl()->getObjCRuntimeNameAsString();
for (const auto *I : OPT->quals()) {
}
// gcc just blithely ignores member pointers.
- // FIXME: we shoul do better than that. 'M' is available.
+ // FIXME: we should do better than that. 'M' is available.
case Type::MemberPointer:
// This matches gcc's encoding, even though technically it is insufficient.
//FIXME. We should do a better job than gcc.
QualType qt = field->getType();
getLegacyIntegralTypeEncoding(qt);
getObjCEncodingForTypeImpl(
- qt, S, /*ExpandPointedToStructures=*/false,
- /*ExpandStructures=*/true, FD,
- /*OutermostType=*/false,
- /*EncodingProperty=*/false,
- /*StructField=*/true, /*EncodeBlockParameters=*/false,
- /*EncodeClassNames=*/false, /*EncodePointerToObjCTypedef=*/false,
- NotEncodedT);
+ qt, S, ObjCEncOptions().setExpandStructures().setIsStructField(),
+ FD, NotEncodedT);
#ifndef NDEBUG
CurOffs += getTypeSize(field->getType());
#endif