diff options
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'.  | 

