summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/ASTContext.cpp25
-rw-r--r--clang/lib/AST/ASTImporter.cpp11
-rw-r--r--clang/lib/AST/TypeLoc.cpp1
-rw-r--r--clang/lib/AST/TypePrinter.cpp78
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'.
OpenPOWER on IntegriCloud