diff options
| author | John McCall <rjmccall@apple.com> | 2011-01-06 01:58:22 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2011-01-06 01:58:22 +0000 |
| commit | 8190451ddc7ee3021939ade3707cc5f6d7510188 (patch) | |
| tree | a22a3173b7b062e0a7f42f0c95dfcdb40fab520c /clang/lib/AST | |
| parent | 4072e59189fe077ffae359e99268193af8cedb1c (diff) | |
| download | bcm5719-llvm-8190451ddc7ee3021939ade3707cc5f6d7510188.tar.gz bcm5719-llvm-8190451ddc7ee3021939ade3707cc5f6d7510188.zip | |
Introduce an AttributedType, but don't actually use it anywhere yet.
The initial TreeTransform is a cop-out, but it's more-or-less equivalent
to what we were doing before, or rather what we're doing now and might
eventually stop doing in favor of using this type.
I am simultaneously intrigued by the possibilities of rebuilding a
dependent Attri
llvm-svn: 122942
Diffstat (limited to 'clang/lib/AST')
| -rw-r--r-- | clang/lib/AST/ASTContext.cpp | 25 | ||||
| -rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 11 | ||||
| -rw-r--r-- | clang/lib/AST/TypeLoc.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/AST/TypePrinter.cpp | 78 |
4 files changed, 114 insertions, 1 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 6e7f7c31ea5..e76238cb221 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -844,6 +844,10 @@ ASTContext::getTypeInfo(const Type *T) { case Type::Elaborated: return getTypeInfo(cast<ElaboratedType>(T)->getNamedType().getTypePtr()); + case Type::Attributed: + return getTypeInfo( + cast<AttributedType>(T)->getEquivalentType().getTypePtr()); + case Type::TemplateSpecialization: assert(getCanonicalType(T) != T && "Cannot request the size of a dependent type"); @@ -1875,6 +1879,27 @@ QualType ASTContext::getEnumType(const EnumDecl *Decl) { return QualType(Decl->TypeForDecl, 0); } +QualType ASTContext::getAttributedType(AttributedType::Kind attrKind, + QualType modifiedType, + QualType equivalentType) { + llvm::FoldingSetNodeID id; + AttributedType::Profile(id, attrKind, modifiedType, equivalentType); + + void *insertPos = 0; + AttributedType *type = AttributedTypes.FindNodeOrInsertPos(id, insertPos); + if (type) return QualType(type, 0); + + QualType canon = getCanonicalType(equivalentType); + type = new (*this, TypeAlignment) + AttributedType(canon, attrKind, modifiedType, equivalentType); + + Types.push_back(type); + AttributedTypes.InsertNode(type, insertPos); + + return QualType(type, 0); +} + + /// \brief Retrieve a substitution-result type. QualType ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm, diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 5a94de90201..60ea7d9081b 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -557,6 +557,17 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, return false; break; + + case Type::Attributed: + if (!IsStructurallyEquivalent(Context, + cast<AttributedType>(T1)->getModifiedType(), + cast<AttributedType>(T2)->getModifiedType())) + return false; + if (!IsStructurallyEquivalent(Context, + cast<AttributedType>(T1)->getEquivalentType(), + cast<AttributedType>(T2)->getEquivalentType())) + return false; + break; case Type::Paren: if (!IsStructurallyEquivalent(Context, diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index 6dd5543966b..08fe267b1d1 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -229,4 +229,3 @@ TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) { TL = PTL->getInnerLoc(); return TL; } - diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index bd0467d246b..7e719be4e90 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -674,6 +674,84 @@ void TypePrinter::printPackExpansion(const PackExpansionType *T, S += "..."; } +void TypePrinter::printAttributed(const AttributedType *T, + std::string &S) { + print(T->getModifiedType(), S); + + // TODO: not all attributes are GCC-style attributes. + S += "__attribute__(("; + switch (T->getAttrKind()) { + case AttributedType::address_space: + S += "address_space("; + S += T->getEquivalentType().getAddressSpace(); + S += ")"; + break; + + case AttributedType::vector_size: { + S += "__vector_size__("; + if (const VectorType *vector =T->getEquivalentType()->getAs<VectorType>()) { + S += vector->getNumElements(); + S += " * sizeof("; + + std::string tmp; + print(vector->getElementType(), tmp); + S += tmp; + S += ")"; + } + S += ")"; + break; + } + + case AttributedType::neon_vector_type: + case AttributedType::neon_polyvector_type: { + if (T->getAttrKind() == AttributedType::neon_vector_type) + S += "neon_vector_type("; + else + S += "neon_polyvector_type("; + const VectorType *vector = T->getEquivalentType()->getAs<VectorType>(); + S += llvm::utostr_32(vector->getNumElements()); + S += ")"; + break; + } + + case AttributedType::regparm: { + S += "regparm("; + QualType t = T->getEquivalentType(); + while (!t->isFunctionType()) + t = t->getPointeeType(); + S += t->getAs<FunctionType>()->getRegParmType(); + S += ")"; + break; + } + + case AttributedType::objc_gc: { + S += "objc_gc("; + + QualType tmp = T->getEquivalentType(); + while (tmp.getObjCGCAttr() == Qualifiers::GCNone) { + QualType next = tmp->getPointeeType(); + if (next == tmp) break; + tmp = next; + } + + if (tmp.isObjCGCWeak()) + S += "weak"; + else + S += "strong"; + S += ")"; + break; + } + + case AttributedType::noreturn: S += "noreturn"; break; + case AttributedType::cdecl: S += "cdecl"; break; + case AttributedType::fastcall: S += "fastcall"; break; + case AttributedType::stdcall: S += "stdcall"; break; + case AttributedType::thiscall: S += "thiscall"; break; + case AttributedType::pascal: S += "pascal"; break; + } + S += "))"; +} + void TypePrinter::printObjCInterface(const ObjCInterfaceType *T, std::string &S) { if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'. |

