Make AttributedTypes for GC-qualified types and fix some miscellaneous

bugs with such types.  Not sure this is quite how I want the desugaring
and a.k.a. logic to go, but it suffices.

llvm-svn: 126986
This commit is contained in:
John McCall 2011-03-04 04:00:19 +00:00
parent e2017b6f2e
commit 4223a9ee7a
4 changed files with 89 additions and 10 deletions

View File

@ -43,6 +43,11 @@ static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) {
QT = ST->desugar();
continue;
}
// ...or an attributed type...
if (const AttributedType *AT = dyn_cast<AttributedType>(Ty)) {
QT = AT->desugar();
continue;
}
// ... or an auto type.
if (const AutoType *AT = dyn_cast<AutoType>(Ty)) {
if (!AT->isSugared())

View File

@ -760,10 +760,14 @@ void TypePrinter::printPackExpansion(const PackExpansionType *T,
void TypePrinter::printAttributed(const AttributedType *T,
std::string &S) {
// Prefer the macro forms of the GC qualifiers.
if (T->getAttrKind() == AttributedType::attr_objc_gc)
return print(T->getEquivalentType(), S);
print(T->getModifiedType(), S);
// TODO: not all attributes are GCC-style attributes.
S += "__attribute__((";
S += " __attribute__((";
switch (T->getAttrKind()) {
case AttributedType::attr_address_space:
S += "address_space(";
@ -1032,20 +1036,18 @@ std::string Qualifiers::getAsString() const {
void Qualifiers::getAsStringInternal(std::string &S,
const PrintingPolicy&) const {
AppendTypeQualList(S, getCVRQualifiers());
if (unsigned AddressSpace = getAddressSpace()) {
if (unsigned addrspace = getAddressSpace()) {
if (!S.empty()) S += ' ';
S += "__attribute__((address_space(";
S += llvm::utostr_32(AddressSpace);
S += llvm::utostr_32(addrspace);
S += ")))";
}
if (Qualifiers::GC GCAttrType = getObjCGCAttr()) {
if (Qualifiers::GC gc = getObjCGCAttr()) {
if (!S.empty()) S += ' ';
S += "__attribute__((objc_gc(";
if (GCAttrType == Qualifiers::Weak)
S += "weak";
if (gc == Qualifiers::Weak)
S += "__weak";
else
S += "strong";
S += ")))";
S += "__strong";
}
}

View File

@ -1364,6 +1364,7 @@ static QualType UnwrapTypeForDebugInfo(QualType T) {
break;
case Type::Attributed:
T = cast<AttributedType>(T)->getEquivalentType();
break;
case Type::Elaborated:
T = cast<ElaboratedType>(T)->getNamedType();
break;

View File

@ -2126,6 +2126,60 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
return GetTypeSourceInfoForDeclarator(D, T, ReturnTypeInfo);
}
/// Map an AttributedType::Kind to an AttributeList::Kind.
static AttributeList::Kind getAttrListKind(AttributedType::Kind kind) {
switch (kind) {
case AttributedType::attr_address_space:
return AttributeList::AT_address_space;
case AttributedType::attr_regparm:
return AttributeList::AT_regparm;
case AttributedType::attr_vector_size:
return AttributeList::AT_vector_size;
case AttributedType::attr_neon_vector_type:
return AttributeList::AT_neon_vector_type;
case AttributedType::attr_neon_polyvector_type:
return AttributeList::AT_neon_polyvector_type;
case AttributedType::attr_objc_gc:
return AttributeList::AT_objc_gc;
case AttributedType::attr_noreturn:
return AttributeList::AT_noreturn;
case AttributedType::attr_cdecl:
return AttributeList::AT_cdecl;
case AttributedType::attr_fastcall:
return AttributeList::AT_fastcall;
case AttributedType::attr_stdcall:
return AttributeList::AT_stdcall;
case AttributedType::attr_thiscall:
return AttributeList::AT_thiscall;
case AttributedType::attr_pascal:
return AttributeList::AT_pascal;
}
llvm_unreachable("unexpected attribute kind!");
return AttributeList::Kind();
}
static void fillAttributedTypeLoc(AttributedTypeLoc TL,
const AttributeList *attrs) {
AttributedType::Kind kind = TL.getAttrKind();
assert(attrs && "no type attributes in the expected location!");
AttributeList::Kind parsedKind = getAttrListKind(kind);
while (attrs->getKind() != parsedKind) {
attrs = attrs->getNext();
assert(attrs && "no matching attribute in expected location!");
}
TL.setAttrNameLoc(attrs->getLoc());
if (TL.hasAttrExprOperand())
TL.setAttrExprOperand(attrs->getArg(0));
else if (TL.hasAttrEnumOperand())
TL.setAttrEnumOperandLoc(attrs->getParameterLoc());
// FIXME: preserve this information to here.
if (TL.hasAttrOperand())
TL.setAttrOperandParensRange(SourceRange());
}
namespace {
class TypeSpecLocFiller : public TypeLocVisitor<TypeSpecLocFiller> {
ASTContext &Context;
@ -2135,6 +2189,10 @@ namespace {
TypeSpecLocFiller(ASTContext &Context, const DeclSpec &DS)
: Context(Context), DS(DS) {}
void VisitAttributedTypeLoc(AttributedTypeLoc TL) {
fillAttributedTypeLoc(TL, DS.getAttributes().getList());
Visit(TL.getModifiedLoc());
}
void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
Visit(TL.getUnqualifiedLoc());
}
@ -2376,6 +2434,12 @@ Sema::GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
}
for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) {
while (isa<AttributedTypeLoc>(CurrTL)) {
AttributedTypeLoc TL = cast<AttributedTypeLoc>(CurrTL);
fillAttributedTypeLoc(TL, D.getTypeObject(i).getAttrs());
CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
}
DeclaratorLocFiller(D.getTypeObject(i)).Visit(CurrTL);
CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc();
}
@ -2545,7 +2609,14 @@ static bool handleObjCGCTypeAttr(TypeProcessingState &state,
return true;
}
type = S.Context.getObjCGCQualType(type, GCAttr);
QualType origType = type;
type = S.Context.getObjCGCQualType(origType, GCAttr);
// Make an attributed type to preserve the source information.
if (attr.getLoc().isValid())
type = S.Context.getAttributedType(AttributedType::attr_objc_gc,
origType, type);
return true;
}