diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -3401,7 +3401,8 @@ CXType_OCLIntelSubgroupAVCImeDualRefStreamin = 175, CXType_ExtVector = 176, - CXType_Atomic = 177 + CXType_Atomic = 177, + CXType_BTFTagAttributed = 178 }; /** diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -264,6 +264,7 @@ mutable llvm::FoldingSet PipeTypes; mutable llvm::FoldingSet BitIntTypes; mutable llvm::FoldingSet DependentBitIntTypes; + llvm::FoldingSet BTFTagAttributedTypes; mutable llvm::FoldingSet QualifiedTemplateNames; mutable llvm::FoldingSet DependentTemplateNames; @@ -1592,6 +1593,8 @@ QualType modifiedType, QualType equivalentType); + QualType getBTFTagAttributedType(BTFTypeTagAttr *Attr, QualType Wrapped); + QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced, QualType Replacement) const; QualType getSubstTemplateTypeParmPackType( diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h --- a/clang/include/clang/AST/ASTNodeTraverser.h +++ b/clang/include/clang/AST/ASTNodeTraverser.h @@ -386,6 +386,9 @@ // FIXME: AttrKind Visit(T->getModifiedType()); } + void VisitBTFTagAttributedType(const BTFTagAttributedType *T) { + Visit(T->getWrappedType()); + } void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) { Visit(T->getReplacedParameter()); } diff --git a/clang/include/clang/AST/PropertiesBase.td b/clang/include/clang/AST/PropertiesBase.td --- a/clang/include/clang/AST/PropertiesBase.td +++ b/clang/include/clang/AST/PropertiesBase.td @@ -75,6 +75,7 @@ def APValue : PropertyType { let PassByReference = 1; } def APValueKind : EnumPropertyType<"APValue::ValueKind">; def ArraySizeModifier : EnumPropertyType<"ArrayType::ArraySizeModifier">; +def Attr : PropertyType<"Attr *">; def AttrKind : EnumPropertyType<"attr::Kind">; def AutoTypeKeyword : EnumPropertyType; def Bool : PropertyType<"bool">; diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -1036,6 +1036,9 @@ DEF_TRAVERSE_TYPE(AttributedType, { TRY_TO(TraverseType(T->getModifiedType())); }) +DEF_TRAVERSE_TYPE(BTFTagAttributedType, + { TRY_TO(TraverseType(T->getWrappedType())); }) + DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); }) DEF_TRAVERSE_TYPE(MacroQualifiedType, @@ -1322,6 +1325,9 @@ DEF_TRAVERSE_TYPELOC(AttributedType, { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); }) +DEF_TRAVERSE_TYPELOC(BTFTagAttributedType, + { TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); }) + DEF_TRAVERSE_TYPELOC(ElaboratedType, { if (TL.getQualifierLoc()) { TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc())); diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -57,6 +57,7 @@ namespace clang { +class BTFTypeTagAttr; class ExtQuals; class QualType; class ConceptDecl; @@ -4786,6 +4787,40 @@ } }; +class BTFTagAttributedType : public Type, public llvm::FoldingSetNode { +private: + friend class ASTContext; // ASTContext creates these + + QualType WrappedType; + BTFTypeTagAttr *Attr; + + BTFTagAttributedType(QualType canon, QualType wrapped, + BTFTypeTagAttr *attr) + : Type(BTFTagAttributed, canon, wrapped->getDependence()), + WrappedType(wrapped), Attr(attr) {} + +public: + QualType getWrappedType() const { return WrappedType; } + BTFTypeTagAttr *getAttr() const { return Attr; } + + bool isSugared() const { return true; } + QualType desugar() const { return getWrappedType(); } + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, WrappedType, Attr); + } + + static void Profile(llvm::FoldingSetNodeID &ID, QualType Wrapped, + BTFTypeTagAttr *Attr) { + ID.AddPointer(Wrapped.getAsOpaquePtr()); + ID.AddPointer(Attr); + } + + static bool classof(const Type *T) { + return T->getTypeClass() == BTFTagAttributed; + } +}; + class TemplateTypeParmType : public Type, public llvm::FoldingSetNode { friend class ASTContext; // ASTContext creates these @@ -7220,6 +7255,8 @@ while (Ty) { if (const auto *A = dyn_cast(Ty)) Ty = A->getModifiedType().getTypePtr(); + else if (const auto *A = dyn_cast(Ty)) + Ty = A->getWrappedType().getTypePtr(); else if (const auto *E = dyn_cast(Ty)) Ty = E->desugar().getTypePtr(); else if (const auto *P = dyn_cast(Ty)) diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -901,6 +901,34 @@ } }; +struct BTFTagAttributedLocInfo { + const Attr *TypeAttr; +}; + +/// Type source information for an btf_tag attributed type. +class BTFTagAttributedTypeLoc + : public ConcreteTypeLoc { +public: + TypeLoc getWrappedLoc() const { return getInnerTypeLoc(); } + + /// The type attribute. + const Attr *getAttr() const { return getLocalData()->TypeAttr; } + void setAttr(const Attr *A) { getLocalData()->TypeAttr = A; } + + template const T *getAttrAs() { + return dyn_cast_or_null(getAttr()); + } + + SourceRange getLocalSourceRange() const; + + void initializeLocal(ASTContext &Context, SourceLocation loc) { + setAttr(nullptr); + } + + QualType getInnerType() const { return getTypePtr()->getWrappedType(); } +}; + struct ObjCObjectTypeLocInfo { SourceLocation TypeArgsLAngleLoc; SourceLocation TypeArgsRAngleLoc; @@ -2589,6 +2617,8 @@ Cur = PTL.getInnerLoc(); else if (auto ATL = Cur.getAs()) Cur = ATL.getModifiedLoc(); + else if (auto ATL = Cur.getAs()) + Cur = ATL.getWrappedLoc(); else if (auto ETL = Cur.getAs()) Cur = ETL.getNamedTypeLoc(); else if (auto ATL = Cur.getAs()) diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td --- a/clang/include/clang/AST/TypeProperties.td +++ b/clang/include/clang/AST/TypeProperties.td @@ -619,6 +619,19 @@ }]>; } +let Class = BTFTagAttributedType in { + def : Property<"attr", Attr> { + let Read = [{ node->getAttr() }]; + } + def : Property<"wrappedType", QualType> { + let Read = [{ node->getWrappedType() }]; + } + + def : Creator<[{ + return ctx.getBTFTagAttributedType(cast(attr), wrappedType); + }]>; +} + let Class = DependentAddressSpaceType in { def : Property<"pointeeType", QualType> { let Read = [{ node->getPointeeType() }]; diff --git a/clang/include/clang/Basic/TypeNodes.td b/clang/include/clang/Basic/TypeNodes.td --- a/clang/include/clang/Basic/TypeNodes.td +++ b/clang/include/clang/Basic/TypeNodes.td @@ -91,6 +91,7 @@ def EnumType : TypeNode, LeafType; def ElaboratedType : TypeNode, NeverCanonical; def AttributedType : TypeNode, NeverCanonical; +def BTFTagAttributedType : TypeNode, NeverCanonical; def TemplateTypeParmType : TypeNode, AlwaysDependent, LeafType; def SubstTemplateTypeParmType : TypeNode, NeverCanonical; def SubstTemplateTypeParmPackType : TypeNode, AlwaysDependent; diff --git a/clang/include/clang/Serialization/ASTRecordWriter.h b/clang/include/clang/Serialization/ASTRecordWriter.h --- a/clang/include/clang/Serialization/ASTRecordWriter.h +++ b/clang/include/clang/Serialization/ASTRecordWriter.h @@ -123,6 +123,9 @@ AddStmt(const_cast(S)); } + /// Write an Attr object. + void writeAttr(Attr *attr) { AddAttr(attr); } + /// Add a definition for the given function to the queue of statements /// to emit. void AddFunctionDefinition(const FunctionDecl *FD); diff --git a/clang/include/clang/Serialization/TypeBitCodes.def b/clang/include/clang/Serialization/TypeBitCodes.def --- a/clang/include/clang/Serialization/TypeBitCodes.def +++ b/clang/include/clang/Serialization/TypeBitCodes.def @@ -63,5 +63,6 @@ TYPE_BIT_CODE(ConstantMatrix, CONSTANT_MATRIX, 52) TYPE_BIT_CODE(DependentSizedMatrix, DEPENDENT_SIZE_MATRIX, 53) TYPE_BIT_CODE(Using, USING, 54) +TYPE_BIT_CODE(BTFTagAttributed, BTFTAG_ATTRIBUTED, 55) #undef TYPE_BIT_CODE diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2377,6 +2377,10 @@ return getTypeInfo( cast(T)->getEquivalentType().getTypePtr()); + case Type::BTFTagAttributed: + return getTypeInfo( + cast(T)->getWrappedType().getTypePtr()); + case Type::Atomic: { // Start with the base type information. TypeInfo Info = getTypeInfo(cast(T)->getValueType()); @@ -4683,6 +4687,27 @@ return QualType(type, 0); } +QualType ASTContext::getBTFTagAttributedType(BTFTypeTagAttr *attr, + QualType wrappedType) { + llvm::FoldingSetNodeID id; + BTFTagAttributedType::Profile(id, wrappedType, attr); + + void *insertPos = nullptr; + BTFTagAttributedType *type = + BTFTagAttributedTypes.FindNodeOrInsertPos(id, insertPos); + if (type) + return QualType(type, 0); + + QualType canon = getCanonicalType(wrappedType); + type = new (*this, TypeAlignment) + BTFTagAttributedType(canon, wrappedType, attr); + + Types.push_back(type); + BTFTagAttributedTypes.InsertNode(type, insertPos); + + return QualType(type, 0); +} + /// Retrieve a substitution-result type. QualType ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm, diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp --- a/clang/lib/AST/ASTStructuralEquivalence.cpp +++ b/clang/lib/AST/ASTStructuralEquivalence.cpp @@ -932,6 +932,13 @@ return false; break; + case Type::BTFTagAttributed: + if (!IsStructurallyEquivalent(Context, + cast(T1)->getWrappedType(), + cast(T2)->getWrappedType())) + return false; + break; + case Type::Paren: if (!IsStructurallyEquivalent(Context, cast(T1)->getInnerType(), cast(T2)->getInnerType())) diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -2286,6 +2286,7 @@ case Type::FunctionNoProto: case Type::Paren: case Type::Attributed: + case Type::BTFTagAttributed: case Type::Auto: case Type::DeducedTemplateSpecialization: case Type::PackExpansion: diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -507,6 +507,10 @@ return getAttr() ? getAttr()->getRange() : SourceRange(); } +SourceRange BTFTagAttributedTypeLoc::getLocalSourceRange() const { + return getAttr() ? getAttr()->getRange() : SourceRange(); +} + void TypeOfTypeLoc::initializeLocal(ASTContext &Context, SourceLocation Loc) { TypeofLikeTypeLoc @@ -683,6 +687,10 @@ return Visit(T.getModifiedLoc()); } + TypeLoc VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc T) { + return Visit(T.getWrappedLoc()); + } + TypeLoc VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc T) { return Visit(T.getInnerLoc()); } diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -235,6 +235,7 @@ case Type::Pipe: case Type::BitInt: case Type::DependentBitInt: + case Type::BTFTagAttributed: CanPrefixQualifiers = true; break; @@ -1689,6 +1690,9 @@ #include "clang/Basic/AttrList.inc" llvm_unreachable("non-type attribute attached to type"); + case attr::BTFTypeTag: + llvm_unreachable("BTFTypeTag attribute handled separately"); + case attr::OpenCLPrivateAddressSpace: case attr::OpenCLGlobalAddressSpace: case attr::OpenCLGlobalDeviceAddressSpace: @@ -1763,13 +1767,21 @@ case attr::ArmMveStrictPolymorphism: OS << "__clang_arm_mve_strict_polymorphism"; break; - case attr::BTFTypeTag: - OS << "btf_type_tag"; - break; } OS << "))"; } +void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T, + raw_ostream &OS) { + printBefore(T->getWrappedType(), OS); + OS << " btf_type_tag(" << T->getAttr()->getBTFTypeTag() << ")"; +} + +void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T, + raw_ostream &OS) { + printAfter(T->getWrappedType(), OS); +} + void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T, raw_ostream &OS) { OS << T->getDecl()->getName(); diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -177,19 +177,16 @@ llvm::DIType *CreateType(const ComplexType *Ty); llvm::DIType *CreateType(const AutoType *Ty); llvm::DIType *CreateType(const BitIntType *Ty); - llvm::DIType *CreateQualifiedType(QualType Ty, llvm::DIFile *Fg, - TypeLoc TL = TypeLoc()); + llvm::DIType *CreateQualifiedType(QualType Ty, llvm::DIFile *Fg); llvm::DIType *CreateQualifiedType(const FunctionProtoType *Ty, llvm::DIFile *Fg); llvm::DIType *CreateType(const TypedefType *Ty, llvm::DIFile *Fg); llvm::DIType *CreateType(const TemplateSpecializationType *Ty, llvm::DIFile *Fg); llvm::DIType *CreateType(const ObjCObjectPointerType *Ty, llvm::DIFile *F); - llvm::DIType *CreateType(const PointerType *Ty, llvm::DIFile *F, - TypeLoc TL = TypeLoc()); + llvm::DIType *CreateType(const PointerType *Ty, llvm::DIFile *F); llvm::DIType *CreateType(const BlockPointerType *Ty, llvm::DIFile *F); - llvm::DIType *CreateType(const FunctionType *Ty, llvm::DIFile *F, - TypeLoc TL = TypeLoc()); + llvm::DIType *CreateType(const FunctionType *Ty, llvm::DIFile *F); /// Get structure or union type. llvm::DIType *CreateType(const RecordType *Tyg); llvm::DIType *CreateTypeDefinition(const RecordType *Ty); @@ -244,8 +241,7 @@ /// \return namespace descriptor for the given namespace decl. llvm::DINamespace *getOrCreateNamespace(const NamespaceDecl *N); llvm::DIType *CreatePointerLikeType(llvm::dwarf::Tag Tag, const Type *Ty, - QualType PointeeTy, llvm::DIFile *F, - TypeLoc TL = TypeLoc()); + QualType PointeeTy, llvm::DIFile *F); llvm::DIType *getOrCreateStructPtrType(StringRef Name, llvm::DIType *&Cache); /// A helper function to create a subprogram for a single member @@ -311,8 +307,7 @@ uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit, llvm::DIScope *scope, const RecordDecl *RD = nullptr, - llvm::DINodeArray Annotations = nullptr, - TypeLoc TL = TypeLoc()); + llvm::DINodeArray Annotations = nullptr); llvm::DIType *createFieldType(StringRef name, QualType type, SourceLocation loc, AccessSpecifier AS, @@ -640,8 +635,7 @@ Optional Source); /// Get the type from the cache or create a new type if necessary. - llvm::DIType *getOrCreateType(QualType Ty, llvm::DIFile *Fg, - TypeLoc TL = TypeLoc()); + llvm::DIType *getOrCreateType(QualType Ty, llvm::DIFile *Fg); /// Get a reference to a clang module. If \p CreateSkeletonCU is true, /// this also creates a split dwarf skeleton compile unit. @@ -656,8 +650,7 @@ llvm::DICompositeType *getOrCreateLimitedType(const RecordType *Ty); /// Create type metadata for a source language type. - llvm::DIType *CreateTypeNode(QualType Ty, llvm::DIFile *Fg, - TypeLoc TL = TypeLoc()); + llvm::DIType *CreateTypeNode(QualType Ty, llvm::DIFile *Fg); /// Create new member and increase Offset by FType's size. llvm::DIType *CreateMemberType(llvm::DIFile *Unit, QualType FType, diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -927,28 +927,8 @@ return (llvm::dwarf::Tag)0; } -// Strip MacroQualifiedTypeLoc and AttributedTypeLoc -// as their corresponding types will be ignored -// during code generation. Stripping them allows -// to maintain proper TypeLoc for a given type -// during code generation. -static TypeLoc StripMacroAttributed(TypeLoc TL) { - if (!TL) - return TL; - - while (true) { - if (auto MTL = TL.getAs()) - TL = MTL.getInnerLoc(); - else if (auto ATL = TL.getAs()) - TL = ATL.getModifiedLoc(); - else - break; - } - return TL; -} - -llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile *Unit, - TypeLoc TL) { +llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty, + llvm::DIFile *Unit) { QualifierCollector Qc; const Type *T = Qc.strip(Ty); @@ -962,15 +942,7 @@ return getOrCreateType(QualType(T, 0), Unit); } - QualType NextTy = Qc.apply(CGM.getContext(), T); - TypeLoc NextTL; - if (NextTy.hasQualifiers()) - NextTL = TL; - else if (TL) { - if (auto QTL = TL.getAs()) - NextTL = StripMacroAttributed(QTL.getNextTypeLoc()); - } - auto *FromTy = getOrCreateType(NextTy, Unit, NextTL); + auto *FromTy = getOrCreateType(Qc.apply(CGM.getContext(), T), Unit); // No need to fill in the Name, Line, Size, Alignment, Offset in case of // CVR derived types. @@ -1014,10 +986,10 @@ Ty->getPointeeType(), Unit); } -llvm::DIType *CGDebugInfo::CreateType(const PointerType *Ty, llvm::DIFile *Unit, - TypeLoc TL) { +llvm::DIType *CGDebugInfo::CreateType(const PointerType *Ty, + llvm::DIFile *Unit) { return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty, - Ty->getPointeeType(), Unit, TL); + Ty->getPointeeType(), Unit); } /// \return whether a C++ mangling exists for the type defined by TD. @@ -1158,8 +1130,7 @@ llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag, const Type *Ty, QualType PointeeTy, - llvm::DIFile *Unit, - TypeLoc TL) { + llvm::DIFile *Unit) { // Bit size, align and offset of the type. // Size is always the size of a pointer. We can't use getTypeSize here // because that does not return the correct value for references. @@ -1169,52 +1140,33 @@ Optional DWARFAddressSpace = CGM.getTarget().getDWARFAddressSpace(AddressSpace); - llvm::DINodeArray Annotations = nullptr; - TypeLoc NextTL; - if (TL) { - SmallVector Annots; - NextTL = TL.getNextTypeLoc(); - if (NextTL) { - // Traverse all MacroQualifiedTypeLoc, QualifiedTypeLoc and - // AttributedTypeLoc type locations so we can collect - // BTFTypeTag attributes for this pointer. - while (true) { - if (auto MTL = NextTL.getAs()) { - NextTL = MTL.getInnerLoc(); - } else if (auto QTL = NextTL.getAs()) { - NextTL = QTL.getNextTypeLoc(); - } else if (auto ATL = NextTL.getAs()) { - if (const auto *A = ATL.getAttrAs()) { - StringRef BTFTypeTag = A->getBTFTypeTag(); - if (!BTFTypeTag.empty()) { - llvm::Metadata *Ops[2] = { - llvm::MDString::get(CGM.getLLVMContext(), - StringRef("btf_type_tag")), - llvm::MDString::get(CGM.getLLVMContext(), BTFTypeTag)}; - Annots.insert(Annots.begin(), - llvm::MDNode::get(CGM.getLLVMContext(), Ops)); - } - } - NextTL = ATL.getModifiedLoc(); - } else { - break; - } - } + SmallVector Annots; + auto BTFTagAttrTy = dyn_cast(PointeeTy); + while (BTFTagAttrTy) { + StringRef Tag = BTFTagAttrTy->getAttr()->getBTFTypeTag(); + if (!Tag.empty()) { + llvm::Metadata *Ops[2] = { + llvm::MDString::get(CGM.getLLVMContext(), StringRef("btf_type_tag")), + llvm::MDString::get(CGM.getLLVMContext(), Tag)}; + Annots.insert(Annots.begin(), + llvm::MDNode::get(CGM.getLLVMContext(), Ops)); } - - NextTL = StripMacroAttributed(TL.getNextTypeLoc()); - if (Annots.size() > 0) - Annotations = DBuilder.getOrCreateArray(Annots); + BTFTagAttrTy = + dyn_cast(BTFTagAttrTy->getWrappedType()); } + llvm::DINodeArray Annotations = nullptr; + if (Annots.size() > 0) + Annotations = DBuilder.getOrCreateArray(Annots); + if (Tag == llvm::dwarf::DW_TAG_reference_type || Tag == llvm::dwarf::DW_TAG_rvalue_reference_type) return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit), Size, Align, DWARFAddressSpace); else - return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit, NextTL), - Size, Align, DWARFAddressSpace, - StringRef(), Annotations); + return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size, + Align, DWARFAddressSpace, StringRef(), + Annotations); } llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name, @@ -1331,11 +1283,8 @@ llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile *Unit) { - TypeLoc TL; - if (const TypeSourceInfo *TSI = Ty->getDecl()->getTypeSourceInfo()) - TL = TSI->getTypeLoc(); llvm::DIType *Underlying = - getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit, TL); + getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit); if (Ty->getDecl()->hasAttr()) return Underlying; @@ -1409,7 +1358,7 @@ } llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty, - llvm::DIFile *Unit, TypeLoc TL) { + llvm::DIFile *Unit) { const auto *FPT = dyn_cast(Ty); if (FPT) { if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit)) @@ -1421,12 +1370,7 @@ SmallVector EltTys; // Add the result type at least. - TypeLoc RetTL; - if (TL) { - if (auto FTL = TL.getAs()) - RetTL = FTL.getReturnLoc(); - } - EltTys.push_back(getOrCreateType(Ty->getReturnType(), Unit, RetTL)); + EltTys.push_back(getOrCreateType(Ty->getReturnType(), Unit)); llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; // Set up remainder of arguments if there is a prototype. @@ -1435,30 +1379,8 @@ EltTys.push_back(DBuilder.createUnspecifiedParameter()); } else { Flags = getRefFlags(FPT); - bool DoneWithTL = false; - if (TL) { - if (auto FTL = TL.getAs()) { - DoneWithTL = true; - unsigned Idx = 0; - unsigned FTL_NumParams = FTL.getNumParams(); - for (const QualType &ParamType : FPT->param_types()) { - TypeLoc ParamTL; - if (Idx < FTL_NumParams) { - if (ParmVarDecl *Param = FTL.getParam(Idx)) { - if (const TypeSourceInfo *TSI = Param->getTypeSourceInfo()) - ParamTL = TSI->getTypeLoc(); - } - } - EltTys.push_back(getOrCreateType(ParamType, Unit, ParamTL)); - Idx++; - } - } - } - - if (!DoneWithTL) { - for (const QualType &ParamType : FPT->param_types()) - EltTys.push_back(getOrCreateType(ParamType, Unit)); - } + for (const QualType &ParamType : FPT->param_types()) + EltTys.push_back(getOrCreateType(ParamType, Unit)); if (FPT->isVariadic()) EltTys.push_back(DBuilder.createUnspecifiedParameter()); } @@ -1534,8 +1456,8 @@ AccessSpecifier AS, uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit, llvm::DIScope *scope, const RecordDecl *RD, - llvm::DINodeArray Annotations, TypeLoc TL) { - llvm::DIType *debugType = getOrCreateType(type, tunit, TL); + llvm::DINodeArray Annotations) { + llvm::DIType *debugType = getOrCreateType(type, tunit); // Get the location for the field. llvm::DIFile *file = getOrCreateFile(loc); @@ -1643,12 +1565,9 @@ } else { auto Align = getDeclAlignIfRequired(field, CGM.getContext()); llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field); - TypeLoc TL; - if (const TypeSourceInfo *TSI = field->getTypeSourceInfo()) - TL = TSI->getTypeLoc(); FieldType = createFieldType(name, type, field->getLocation(), field->getAccess(), OffsetInBits, Align, tunit, - RecordTy, RD, Annotations, TL); + RecordTy, RD, Annotations); } elements.push_back(FieldType); @@ -3348,6 +3267,9 @@ case Type::Attributed: T = cast(T)->getEquivalentType(); break; + case Type::BTFTagAttributed: + T = cast(T)->getWrappedType(); + break; case Type::Elaborated: T = cast(T)->getNamedType(); break; @@ -3409,8 +3331,7 @@ RetainedTypes.push_back(CGM.getContext().getRecordType(&D).getAsOpaquePtr()); } -llvm::DIType *CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile *Unit, - TypeLoc TL) { +llvm::DIType *CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile *Unit) { if (Ty.isNull()) return nullptr; @@ -3427,7 +3348,7 @@ if (auto *T = getTypeOrNull(Ty)) return T; - llvm::DIType *Res = CreateTypeNode(Ty, Unit, TL); + llvm::DIType *Res = CreateTypeNode(Ty, Unit); void *TyPtr = Ty.getAsOpaquePtr(); // And update the type cache. @@ -3471,11 +3392,10 @@ return nullptr; } -llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit, - TypeLoc TL) { +llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) { // Handle qualifiers, which recursively handles what they refer to. if (Ty.hasLocalQualifiers()) - return CreateQualifiedType(Ty, Unit, TL); + return CreateQualifiedType(Ty, Unit); // Work out details of type. switch (Ty->getTypeClass()) { @@ -3504,7 +3424,7 @@ case Type::Complex: return CreateType(cast(Ty)); case Type::Pointer: - return CreateType(cast(Ty), Unit, TL); + return CreateType(cast(Ty), Unit); case Type::BlockPointer: return CreateType(cast(Ty), Unit); case Type::Typedef: @@ -3515,7 +3435,7 @@ return CreateEnumType(cast(Ty)); case Type::FunctionProto: case Type::FunctionNoProto: - return CreateType(cast(Ty), Unit, TL); + return CreateType(cast(Ty), Unit); case Type::ConstantArray: case Type::VariableArray: case Type::IncompleteArray: @@ -3542,6 +3462,7 @@ case Type::Auto: case Type::Attributed: + case Type::BTFTagAttributed: case Type::Adjusted: case Type::Decayed: case Type::DeducedTemplateSpecialization: @@ -4064,12 +3985,7 @@ getDwarfCC(CC)); } - TypeLoc TL; - if (const auto *FD = dyn_cast(D)) { - if (const TypeSourceInfo *TSI = FD->getTypeSourceInfo()) - TL = TSI->getTypeLoc(); - } - return cast(getOrCreateType(FnType, F, TL)); + return cast(getOrCreateType(FnType, F)); } QualType @@ -4471,12 +4387,8 @@ uint64_t XOffset = 0; if (VD->hasAttr()) Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType; - else { - TypeLoc TL; - if (const TypeSourceInfo *TSI = VD->getTypeSourceInfo()) - TL = TSI->getTypeLoc(); - Ty = getOrCreateType(VD->getType(), Unit, TL); - } + else + Ty = getOrCreateType(VD->getType(), Unit); // If there is no debug info for this type then do not emit debug info // for this variable. @@ -5347,14 +5259,10 @@ } AppendAddressSpaceXDeref(AddressSpace, Expr); - TypeLoc TL; - if (const TypeSourceInfo *TSI = D->getTypeSourceInfo()) - TL = TSI->getTypeLoc(); - llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D); GVE = DBuilder.createGlobalVariableExpression( DContext, DeclName, LinkageName, Unit, LineNo, - getOrCreateType(T, Unit, TL), Var->hasLocalLinkage(), true, + getOrCreateType(T, Unit), Var->hasLocalLinkage(), true, Expr.empty() ? nullptr : DBuilder.createExpression(Expr), getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters, Align, Annotations); diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -2310,6 +2310,7 @@ case Type::TypeOf: case Type::UnaryTransform: case Type::Attributed: + case Type::BTFTagAttributed: case Type::SubstTemplateTypeParm: case Type::MacroQualified: // Keep walking after single level desugaring. diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4469,6 +4469,7 @@ case Type::TypeOf: case Type::UnaryTransform: case Type::Attributed: + case Type::BTFTagAttributed: case Type::SubstTemplateTypeParm: case Type::MacroQualified: // Keep walking after single level desugaring. diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -266,6 +266,11 @@ return T; } + /// Get a BTFTagAttributed type for the btf_type_tag attribute. + QualType getBTFTagAttributedType(BTFTypeTagAttr *A, QualType WrappedType) { + return sema.Context.getBTFTagAttributedType(A, WrappedType); + } + /// Completely replace the \c auto in \p TypeWithAuto by /// \p Replacement. Also replace \p TypeWithAuto in \c TypeAttrPair if /// necessary. @@ -5899,6 +5904,10 @@ TL.setAttr(State.takeAttrForAttributedType(TL.getTypePtr())); } +static void fillBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) { + TL.setAttr(TL.getTypePtr()->getAttr()); +} + namespace { class TypeSpecLocFiller : public TypeLocVisitor { Sema &SemaRef; @@ -5915,6 +5924,10 @@ Visit(TL.getModifiedLoc()); fillAttributedTypeLoc(TL, State); } + void VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) { + Visit(TL.getWrappedLoc()); + fillBTFTagAttributedTypeLoc(TL); + } void VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) { Visit(TL.getInnerLoc()); TL.setExpansionLoc( @@ -6141,6 +6154,9 @@ void VisitAttributedTypeLoc(AttributedTypeLoc TL) { fillAttributedTypeLoc(TL, State); } + void VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) { + fillBTFTagAttributedTypeLoc(TL); + } void VisitAdjustedTypeLoc(AdjustedTypeLoc TL) { // nothing } @@ -6556,8 +6572,8 @@ ASTContext &Ctx = S.Context; StringRef BTFTypeTag = StrLiteral->getString(); - Type = State.getAttributedType( - ::new (Ctx) BTFTypeTagAttr(Ctx, Attr, BTFTypeTag), Type, Type); + Type = State.getBTFTagAttributedType( + ::new (Ctx) BTFTypeTagAttr(Ctx, Attr, BTFTypeTag), Type); } /// HandleAddressSpaceTypeAttribute - Process an address_space attribute on the diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -6865,6 +6865,24 @@ return result; } +template +QualType TreeTransform::TransformBTFTagAttributedType( + TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) { + const BTFTagAttributedType *oldType = TL.getTypePtr(); + QualType wrappedType = getDerived().TransformType(TLB, TL.getWrappedLoc()); + if (wrappedType.isNull()) + return QualType(); + + BTFTypeTagAttr *Attr = oldType->getAttr(); + QualType result = TL.getType(); + if (getDerived().AlwaysRebuild() || wrappedType != oldType->getWrappedType()) + result = SemaRef.Context.getBTFTagAttributedType(Attr, wrappedType); + + BTFTagAttributedTypeLoc newTL = TLB.push(result); + newTL.setAttr(Attr); + return result; +} + template QualType TreeTransform::TransformParenType(TypeLocBuilder &TLB, diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -6695,6 +6695,10 @@ TL.setAttr(ReadAttr()); } +void TypeLocReader::VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) { + TL.setAttr(ReadAttr()); +} + void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { TL.setNameLoc(readSourceLocation()); } diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -479,6 +479,10 @@ Record.AddAttr(TL.getAttr()); } +void TypeLocWriter::VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) { + Record.AddAttr(TL.getAttr()); +} + void TypeLocWriter::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { Record.AddSourceLocation(TL.getNameLoc()); } diff --git a/clang/test/CodeGen/attr-btf_type_tag-similar-type.c b/clang/test/CodeGen/attr-btf_type_tag-similar-type.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/attr-btf_type_tag-similar-type.c @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -debug-info-kind=limited -S -emit-llvm -o - %s | FileCheck %s + +struct map_value { + int __attribute__((btf_type_tag("tag1"))) __attribute__((btf_type_tag("tag3"))) *a; + int __attribute__((btf_type_tag("tag2"))) __attribute__((btf_type_tag("tag4"))) *b; +}; + +struct map_value *func(void); + +int test(struct map_value *arg) +{ + return *arg->a; +} + +// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "map_value", file: ![[#]], line: [[#]], size: [[#]], elements: ![[L14:[0-9]+]] +// CHECK: ![[L14]] = !{![[L15:[0-9]+]], ![[L20:[0-9]+]]} +// CHECK: ![[L15]] = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[L16:[0-9]+]] +// CHECK: ![[L16]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[#]], size: [[#]], annotations: ![[L17:[0-9]+]] +// CHECK: ![[L17]] = !{![[L18:[0-9]+]], ![[L19:[0-9]+]]} +// CHECK: ![[L18]] = !{!"btf_type_tag", !"tag1"} +// CHECK: ![[L19]] = !{!"btf_type_tag", !"tag3"} +// CHECK: ![[L20]] = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[L21:[0-9]+]] +// CHECK: ![[L21:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[#]], size: [[#]], annotations: ![[L22:[0-9]+]] +// CHECK: ![[L22]] = !{![[L23:[0-9]+]], ![[L24:[0-9]+]]} +// CHECK: ![[L23]] = !{!"btf_type_tag", !"tag2"} +// CHECK: ![[L24]] = !{!"btf_type_tag", !"tag4"} diff --git a/clang/test/PCH/btf_type_tag_attr.c b/clang/test/PCH/btf_type_tag_attr.c new file mode 100644 --- /dev/null +++ b/clang/test/PCH/btf_type_tag_attr.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -triple aarch64-linux-gnu -include-pch %t \ +// RUN: -fsyntax-only -verify %s + +// expected-no-diagnostics + +int __attribute__((btf_type_tag("tag1"))) __attribute__((btf_type_tag("tag2"))) *p; diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -1672,6 +1672,10 @@ return Visit(TL.getModifiedLoc()); } +bool CursorVisitor::VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) { + return Visit(TL.getWrappedLoc()); +} + bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType) { if (!SkipResultType && Visit(TL.getReturnLoc())) diff --git a/clang/tools/libclang/CXType.cpp b/clang/tools/libclang/CXType.cpp --- a/clang/tools/libclang/CXType.cpp +++ b/clang/tools/libclang/CXType.cpp @@ -116,6 +116,7 @@ TKCASE(Elaborated); TKCASE(Pipe); TKCASE(Attributed); + TKCASE(BTFTagAttributed); TKCASE(Atomic); default: return CXType_Unexposed; @@ -136,6 +137,10 @@ return MakeCXType(ATT->getEquivalentType(), TU); } } + if (auto *ATT = T->getAs()) { + if (!(TU->ParsingOptions & CXTranslationUnit_IncludeAttributedTypes)) + return MakeCXType(ATT->getWrappedType(), TU); + } // Handle paren types as the original type if (auto *PTT = T->getAs()) { return MakeCXType(PTT->getInnerType(), TU); @@ -610,6 +615,7 @@ TKIND(Elaborated); TKIND(Pipe); TKIND(Attributed); + TKIND(BTFTagAttributed); TKIND(BFloat16); #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) TKIND(Id); #include "clang/Basic/OpenCLImageTypes.def" @@ -1051,6 +1057,9 @@ if (auto *ATT = T->getAs()) return MakeCXType(ATT->getModifiedType(), GetTU(CT)); + if (auto *ATT = T->getAs()) + return MakeCXType(ATT->getWrappedType(), GetTU(CT)); + return MakeCXType(QualType(), GetTU(CT)); }