forked from OSchip/llvm-project
[Attr] Fix a btf_type_tag AST generation
Current ASTContext.getAttributedType() takes attribute kind, ModifiedType and EquivType as the hash to decide whether an AST node has been generated or note. But this is not enough for btf_type_tag as the attribute might have the same ModifiedType and EquivType, but still have different string associated with attribute. For example, for a data structure like below, 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; }; The current ASTContext.getAttributedType() will produce an AST similar to below: struct map_value { int __attribute__((btf_type_tag("tag1"))) __attribute__((btf_type_tag("tag3"))) *a; int __attribute__((btf_type_tag("tag1"))) __attribute__((btf_type_tag("tag3"))) *b; }; and this is incorrect. It is very difficult to use the current AttributedType as it is hard to get the tag information. To fix the problem, this patch introduced BTFTagAttributedType which is similar to AttributedType in many ways but with an additional BTFTypeTagAttr. The tag itself can be retrieved with BTFTypeTagAttr. With the new BTFTagAttributed type, the debuginfo code can be greatly simplified compared to previous TypeLoc based approach. Differential Revision: https://reviews.llvm.org/D120296
This commit is contained in:
parent
c7dc9dbaff
commit
3251ba2d0f
|
@ -3401,7 +3401,8 @@ enum CXTypeKind {
|
|||
CXType_OCLIntelSubgroupAVCImeDualRefStreamin = 175,
|
||||
|
||||
CXType_ExtVector = 176,
|
||||
CXType_Atomic = 177
|
||||
CXType_Atomic = 177,
|
||||
CXType_BTFTagAttributed = 178
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -264,6 +264,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
|||
mutable llvm::FoldingSet<PipeType> PipeTypes;
|
||||
mutable llvm::FoldingSet<BitIntType> BitIntTypes;
|
||||
mutable llvm::FoldingSet<DependentBitIntType> DependentBitIntTypes;
|
||||
llvm::FoldingSet<BTFTagAttributedType> BTFTagAttributedTypes;
|
||||
|
||||
mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
|
||||
mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
|
||||
|
@ -1592,6 +1593,9 @@ public:
|
|||
QualType modifiedType,
|
||||
QualType equivalentType);
|
||||
|
||||
QualType getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr,
|
||||
QualType Wrapped);
|
||||
|
||||
QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
|
||||
QualType Replacement) const;
|
||||
QualType getSubstTemplateTypeParmPackType(
|
||||
|
|
|
@ -386,6 +386,9 @@ public:
|
|||
// FIXME: AttrKind
|
||||
Visit(T->getModifiedType());
|
||||
}
|
||||
void VisitBTFTagAttributedType(const BTFTagAttributedType *T) {
|
||||
Visit(T->getWrappedType());
|
||||
}
|
||||
void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
|
||||
Visit(T->getReplacedParameter());
|
||||
}
|
||||
|
|
|
@ -79,6 +79,7 @@ def AttrKind : EnumPropertyType<"attr::Kind">;
|
|||
def AutoTypeKeyword : EnumPropertyType;
|
||||
def Bool : PropertyType<"bool">;
|
||||
def BuiltinTypeKind : EnumPropertyType<"BuiltinType::Kind">;
|
||||
def BTFTypeTagAttr : PropertyType<"const BTFTypeTagAttr *">;
|
||||
def CallingConv : EnumPropertyType;
|
||||
def DeclarationName : PropertyType;
|
||||
def DeclarationNameKind : EnumPropertyType<"DeclarationName::NameKind">;
|
||||
|
|
|
@ -1036,6 +1036,9 @@ DEF_TRAVERSE_TYPE(InjectedClassNameType, {})
|
|||
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(MacroQualifiedType,
|
|||
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()));
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
|
||||
namespace clang {
|
||||
|
||||
class BTFTypeTagAttr;
|
||||
class ExtQuals;
|
||||
class QualType;
|
||||
class ConceptDecl;
|
||||
|
@ -4789,6 +4790,40 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class BTFTagAttributedType : public Type, public llvm::FoldingSetNode {
|
||||
private:
|
||||
friend class ASTContext; // ASTContext creates these
|
||||
|
||||
QualType WrappedType;
|
||||
const BTFTypeTagAttr *BTFAttr;
|
||||
|
||||
BTFTagAttributedType(QualType Canon, QualType Wrapped,
|
||||
const BTFTypeTagAttr *BTFAttr)
|
||||
: Type(BTFTagAttributed, Canon, Wrapped->getDependence()),
|
||||
WrappedType(Wrapped), BTFAttr(BTFAttr) {}
|
||||
|
||||
public:
|
||||
QualType getWrappedType() const { return WrappedType; }
|
||||
const BTFTypeTagAttr *getAttr() const { return BTFAttr; }
|
||||
|
||||
bool isSugared() const { return true; }
|
||||
QualType desugar() const { return getWrappedType(); }
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) {
|
||||
Profile(ID, WrappedType, BTFAttr);
|
||||
}
|
||||
|
||||
static void Profile(llvm::FoldingSetNodeID &ID, QualType Wrapped,
|
||||
const BTFTypeTagAttr *BTFAttr) {
|
||||
ID.AddPointer(Wrapped.getAsOpaquePtr());
|
||||
ID.AddPointer(BTFAttr);
|
||||
}
|
||||
|
||||
static bool classof(const Type *T) {
|
||||
return T->getTypeClass() == BTFTagAttributed;
|
||||
}
|
||||
};
|
||||
|
||||
class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
|
||||
friend class ASTContext; // ASTContext creates these
|
||||
|
||||
|
@ -7229,6 +7264,8 @@ template <typename T> const T *Type::getAsAdjusted() const {
|
|||
while (Ty) {
|
||||
if (const auto *A = dyn_cast<AttributedType>(Ty))
|
||||
Ty = A->getModifiedType().getTypePtr();
|
||||
else if (const auto *A = dyn_cast<BTFTagAttributedType>(Ty))
|
||||
Ty = A->getWrappedType().getTypePtr();
|
||||
else if (const auto *E = dyn_cast<ElaboratedType>(Ty))
|
||||
Ty = E->desugar().getTypePtr();
|
||||
else if (const auto *P = dyn_cast<ParenType>(Ty))
|
||||
|
|
|
@ -901,6 +901,29 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
struct BTFTagAttributedLocInfo {}; // Nothing.
|
||||
|
||||
/// Type source information for an btf_tag attributed type.
|
||||
class BTFTagAttributedTypeLoc
|
||||
: public ConcreteTypeLoc<UnqualTypeLoc, BTFTagAttributedTypeLoc,
|
||||
BTFTagAttributedType, BTFTagAttributedLocInfo> {
|
||||
public:
|
||||
TypeLoc getWrappedLoc() const { return getInnerTypeLoc(); }
|
||||
|
||||
/// The btf_type_tag attribute.
|
||||
const BTFTypeTagAttr *getAttr() const { return getTypePtr()->getAttr(); }
|
||||
|
||||
template <typename T> T *getAttrAs() {
|
||||
return dyn_cast_or_null<T>(getAttr());
|
||||
}
|
||||
|
||||
SourceRange getLocalSourceRange() const;
|
||||
|
||||
void initializeLocal(ASTContext &Context, SourceLocation loc) {}
|
||||
|
||||
QualType getInnerType() const { return getTypePtr()->getWrappedType(); }
|
||||
};
|
||||
|
||||
struct ObjCObjectTypeLocInfo {
|
||||
SourceLocation TypeArgsLAngleLoc;
|
||||
SourceLocation TypeArgsRAngleLoc;
|
||||
|
@ -2589,6 +2612,8 @@ inline T TypeLoc::getAsAdjusted() const {
|
|||
Cur = PTL.getInnerLoc();
|
||||
else if (auto ATL = Cur.getAs<AttributedTypeLoc>())
|
||||
Cur = ATL.getModifiedLoc();
|
||||
else if (auto ATL = Cur.getAs<BTFTagAttributedTypeLoc>())
|
||||
Cur = ATL.getWrappedLoc();
|
||||
else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>())
|
||||
Cur = ETL.getNamedTypeLoc();
|
||||
else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
|
||||
|
|
|
@ -619,6 +619,19 @@ let Class = AttributedType in {
|
|||
}]>;
|
||||
}
|
||||
|
||||
let Class = BTFTagAttributedType in {
|
||||
def : Property<"attr", BTFTypeTagAttr> {
|
||||
let Read = [{ node->getAttr() }];
|
||||
}
|
||||
def : Property<"wrappedType", QualType> {
|
||||
let Read = [{ node->getWrappedType() }];
|
||||
}
|
||||
|
||||
def : Creator<[{
|
||||
return ctx.getBTFTagAttributedType(attr, wrappedType);
|
||||
}]>;
|
||||
}
|
||||
|
||||
let Class = DependentAddressSpaceType in {
|
||||
def : Property<"pointeeType", QualType> {
|
||||
let Read = [{ node->getPointeeType() }];
|
||||
|
|
|
@ -91,6 +91,7 @@ def RecordType : TypeNode<TagType>, LeafType;
|
|||
def EnumType : TypeNode<TagType>, LeafType;
|
||||
def ElaboratedType : TypeNode<Type>, NeverCanonical;
|
||||
def AttributedType : TypeNode<Type>, NeverCanonical;
|
||||
def BTFTagAttributedType : TypeNode<Type>, NeverCanonical;
|
||||
def TemplateTypeParmType : TypeNode<Type>, AlwaysDependent, LeafType;
|
||||
def SubstTemplateTypeParmType : TypeNode<Type>, NeverCanonical;
|
||||
def SubstTemplateTypeParmPackType : TypeNode<Type>, AlwaysDependent;
|
||||
|
|
|
@ -326,6 +326,11 @@ public:
|
|||
/// Reads attributes from the current stream position, advancing Idx.
|
||||
void readAttributes(AttrVec &Attrs);
|
||||
|
||||
/// Read an BTFTypeTagAttr object.
|
||||
BTFTypeTagAttr *readBTFTypeTagAttr() {
|
||||
return cast<BTFTypeTagAttr>(readAttr());
|
||||
}
|
||||
|
||||
/// Reads a token out of a record, advancing Idx.
|
||||
Token readToken() {
|
||||
return Reader->ReadToken(*F, Record, Idx);
|
||||
|
|
|
@ -123,6 +123,9 @@ public:
|
|||
AddStmt(const_cast<Stmt*>(S));
|
||||
}
|
||||
|
||||
/// Write an BTFTypeTagAttr object.
|
||||
void writeBTFTypeTagAttr(const BTFTypeTagAttr *A) { AddAttr(A); }
|
||||
|
||||
/// Add a definition for the given function to the queue of statements
|
||||
/// to emit.
|
||||
void AddFunctionDefinition(const FunctionDecl *FD);
|
||||
|
|
|
@ -63,5 +63,6 @@ TYPE_BIT_CODE(DependentBitInt, DEPENDENT_BIT_INT, 51)
|
|||
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
|
||||
|
|
|
@ -2380,6 +2380,10 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
|
|||
return getTypeInfo(
|
||||
cast<AttributedType>(T)->getEquivalentType().getTypePtr());
|
||||
|
||||
case Type::BTFTagAttributed:
|
||||
return getTypeInfo(
|
||||
cast<BTFTagAttributedType>(T)->getWrappedType().getTypePtr());
|
||||
|
||||
case Type::Atomic: {
|
||||
// Start with the base type information.
|
||||
TypeInfo Info = getTypeInfo(cast<AtomicType>(T)->getValueType());
|
||||
|
@ -4686,6 +4690,26 @@ QualType ASTContext::getAttributedType(attr::Kind attrKind,
|
|||
return QualType(type, 0);
|
||||
}
|
||||
|
||||
QualType ASTContext::getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr,
|
||||
QualType Wrapped) {
|
||||
llvm::FoldingSetNodeID ID;
|
||||
BTFTagAttributedType::Profile(ID, Wrapped, BTFAttr);
|
||||
|
||||
void *InsertPos = nullptr;
|
||||
BTFTagAttributedType *Ty =
|
||||
BTFTagAttributedTypes.FindNodeOrInsertPos(ID, InsertPos);
|
||||
if (Ty)
|
||||
return QualType(Ty, 0);
|
||||
|
||||
QualType Canon = getCanonicalType(Wrapped);
|
||||
Ty = new (*this, TypeAlignment) BTFTagAttributedType(Canon, Wrapped, BTFAttr);
|
||||
|
||||
Types.push_back(Ty);
|
||||
BTFTagAttributedTypes.InsertNode(Ty, InsertPos);
|
||||
|
||||
return QualType(Ty, 0);
|
||||
}
|
||||
|
||||
/// Retrieve a substitution-result type.
|
||||
QualType
|
||||
ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm,
|
||||
|
|
|
@ -932,6 +932,13 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
|||
return false;
|
||||
break;
|
||||
|
||||
case Type::BTFTagAttributed:
|
||||
if (!IsStructurallyEquivalent(
|
||||
Context, cast<BTFTagAttributedType>(T1)->getWrappedType(),
|
||||
cast<BTFTagAttributedType>(T2)->getWrappedType()))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case Type::Paren:
|
||||
if (!IsStructurallyEquivalent(Context, cast<ParenType>(T1)->getInnerType(),
|
||||
cast<ParenType>(T2)->getInnerType()))
|
||||
|
|
|
@ -2286,6 +2286,7 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
|
|||
case Type::FunctionNoProto:
|
||||
case Type::Paren:
|
||||
case Type::Attributed:
|
||||
case Type::BTFTagAttributed:
|
||||
case Type::Auto:
|
||||
case Type::DeducedTemplateSpecialization:
|
||||
case Type::PackExpansion:
|
||||
|
|
|
@ -507,6 +507,10 @@ SourceRange AttributedTypeLoc::getLocalSourceRange() const {
|
|||
return getAttr() ? getAttr()->getRange() : SourceRange();
|
||||
}
|
||||
|
||||
SourceRange BTFTagAttributedTypeLoc::getLocalSourceRange() const {
|
||||
return getAttr() ? getAttr()->getRange() : SourceRange();
|
||||
}
|
||||
|
||||
void TypeOfTypeLoc::initializeLocal(ASTContext &Context,
|
||||
SourceLocation Loc) {
|
||||
TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo>
|
||||
|
@ -683,6 +687,10 @@ namespace {
|
|||
return Visit(T.getModifiedLoc());
|
||||
}
|
||||
|
||||
TypeLoc VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc T) {
|
||||
return Visit(T.getWrappedLoc());
|
||||
}
|
||||
|
||||
TypeLoc VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc T) {
|
||||
return Visit(T.getInnerLoc());
|
||||
}
|
||||
|
|
|
@ -235,6 +235,7 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,
|
|||
case Type::Pipe:
|
||||
case Type::BitInt:
|
||||
case Type::DependentBitInt:
|
||||
case Type::BTFTagAttributed:
|
||||
CanPrefixQualifiers = true;
|
||||
break;
|
||||
|
||||
|
@ -1689,6 +1690,9 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
|
|||
#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 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
|
|||
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();
|
||||
|
|
|
@ -928,28 +928,8 @@ static llvm::dwarf::Tag getNextQualifier(Qualifiers &Q) {
|
|||
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<MacroQualifiedTypeLoc>())
|
||||
TL = MTL.getInnerLoc();
|
||||
else if (auto ATL = TL.getAs<AttributedTypeLoc>())
|
||||
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);
|
||||
|
||||
|
@ -963,15 +943,7 @@ llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile *Unit,
|
|||
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<QualifiedTypeLoc>())
|
||||
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.
|
||||
|
@ -1015,10 +987,10 @@ llvm::DIType *CGDebugInfo::CreateType(const ObjCObjectPointerType *Ty,
|
|||
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.
|
||||
|
@ -1159,8 +1131,7 @@ CGDebugInfo::getOrCreateRecordFwdDecl(const RecordType *Ty,
|
|||
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.
|
||||
|
@ -1170,52 +1141,32 @@ llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
|
|||
Optional<unsigned> DWARFAddressSpace =
|
||||
CGM.getTarget().getDWARFAddressSpace(AddressSpace);
|
||||
|
||||
llvm::DINodeArray Annotations = nullptr;
|
||||
TypeLoc NextTL;
|
||||
if (TL) {
|
||||
SmallVector<llvm::Metadata *, 4> 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<MacroQualifiedTypeLoc>()) {
|
||||
NextTL = MTL.getInnerLoc();
|
||||
} else if (auto QTL = NextTL.getAs<QualifiedTypeLoc>()) {
|
||||
NextTL = QTL.getNextTypeLoc();
|
||||
} else if (auto ATL = NextTL.getAs<AttributedTypeLoc>()) {
|
||||
if (const auto *A = ATL.getAttrAs<BTFTypeTagAttr>()) {
|
||||
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<llvm::Metadata *, 4> Annots;
|
||||
auto *BTFAttrTy = dyn_cast<BTFTagAttributedType>(PointeeTy);
|
||||
while (BTFAttrTy) {
|
||||
StringRef Tag = BTFAttrTy->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);
|
||||
BTFAttrTy = dyn_cast<BTFTagAttributedType>(BTFAttrTy->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,
|
||||
|
@ -1332,11 +1283,8 @@ llvm::DIType *CGDebugInfo::CreateType(const TemplateSpecializationType *Ty,
|
|||
|
||||
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<NoDebugAttr>())
|
||||
return Underlying;
|
||||
|
@ -1410,7 +1358,7 @@ static llvm::DINode::DIFlags getRefFlags(const FunctionProtoType *Func) {
|
|||
}
|
||||
|
||||
llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty,
|
||||
llvm::DIFile *Unit, TypeLoc TL) {
|
||||
llvm::DIFile *Unit) {
|
||||
const auto *FPT = dyn_cast<FunctionProtoType>(Ty);
|
||||
if (FPT) {
|
||||
if (llvm::DIType *QTy = CreateQualifiedType(FPT, Unit))
|
||||
|
@ -1422,12 +1370,7 @@ llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty,
|
|||
SmallVector<llvm::Metadata *, 16> EltTys;
|
||||
|
||||
// Add the result type at least.
|
||||
TypeLoc RetTL;
|
||||
if (TL) {
|
||||
if (auto FTL = TL.getAs<FunctionTypeLoc>())
|
||||
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.
|
||||
|
@ -1436,30 +1379,8 @@ llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty,
|
|||
EltTys.push_back(DBuilder.createUnspecifiedParameter());
|
||||
} else {
|
||||
Flags = getRefFlags(FPT);
|
||||
bool DoneWithTL = false;
|
||||
if (TL) {
|
||||
if (auto FTL = TL.getAs<FunctionTypeLoc>()) {
|
||||
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());
|
||||
}
|
||||
|
@ -1530,13 +1451,11 @@ llvm::DIType *CGDebugInfo::createBitFieldType(const FieldDecl *BitFieldDecl,
|
|||
Flags, DebugType, Annotations);
|
||||
}
|
||||
|
||||
llvm::DIType *
|
||||
CGDebugInfo::createFieldType(StringRef name, QualType type, SourceLocation loc,
|
||||
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::DIType *CGDebugInfo::createFieldType(
|
||||
StringRef name, QualType type, SourceLocation loc, AccessSpecifier AS,
|
||||
uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
|
||||
llvm::DIScope *scope, const RecordDecl *RD, llvm::DINodeArray Annotations) {
|
||||
llvm::DIType *debugType = getOrCreateType(type, tunit);
|
||||
|
||||
// Get the location for the field.
|
||||
llvm::DIFile *file = getOrCreateFile(loc);
|
||||
|
@ -1644,12 +1563,9 @@ void CGDebugInfo::CollectRecordNormalField(
|
|||
} 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);
|
||||
FieldType =
|
||||
createFieldType(name, type, field->getLocation(), field->getAccess(),
|
||||
OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
|
||||
}
|
||||
|
||||
elements.push_back(FieldType);
|
||||
|
@ -3366,6 +3282,9 @@ static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C) {
|
|||
case Type::Attributed:
|
||||
T = cast<AttributedType>(T)->getEquivalentType();
|
||||
break;
|
||||
case Type::BTFTagAttributed:
|
||||
T = cast<BTFTagAttributedType>(T)->getWrappedType();
|
||||
break;
|
||||
case Type::Elaborated:
|
||||
T = cast<ElaboratedType>(T)->getNamedType();
|
||||
break;
|
||||
|
@ -3427,8 +3346,7 @@ void CGDebugInfo::completeUnusedClass(const CXXRecordDecl &D) {
|
|||
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;
|
||||
|
||||
|
@ -3445,7 +3363,7 @@ llvm::DIType *CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile *Unit,
|
|||
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.
|
||||
|
@ -3489,11 +3407,10 @@ llvm::DIModule *CGDebugInfo::getParentModuleOrNull(const Decl *D) {
|
|||
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()) {
|
||||
|
@ -3522,7 +3439,7 @@ llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit,
|
|||
case Type::Complex:
|
||||
return CreateType(cast<ComplexType>(Ty));
|
||||
case Type::Pointer:
|
||||
return CreateType(cast<PointerType>(Ty), Unit, TL);
|
||||
return CreateType(cast<PointerType>(Ty), Unit);
|
||||
case Type::BlockPointer:
|
||||
return CreateType(cast<BlockPointerType>(Ty), Unit);
|
||||
case Type::Typedef:
|
||||
|
@ -3533,7 +3450,7 @@ llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit,
|
|||
return CreateEnumType(cast<EnumType>(Ty));
|
||||
case Type::FunctionProto:
|
||||
case Type::FunctionNoProto:
|
||||
return CreateType(cast<FunctionType>(Ty), Unit, TL);
|
||||
return CreateType(cast<FunctionType>(Ty), Unit);
|
||||
case Type::ConstantArray:
|
||||
case Type::VariableArray:
|
||||
case Type::IncompleteArray:
|
||||
|
@ -3560,6 +3477,7 @@ llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit,
|
|||
|
||||
case Type::Auto:
|
||||
case Type::Attributed:
|
||||
case Type::BTFTagAttributed:
|
||||
case Type::Adjusted:
|
||||
case Type::Decayed:
|
||||
case Type::DeducedTemplateSpecialization:
|
||||
|
@ -4082,12 +4000,7 @@ llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(const Decl *D,
|
|||
getDwarfCC(CC));
|
||||
}
|
||||
|
||||
TypeLoc TL;
|
||||
if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
if (const TypeSourceInfo *TSI = FD->getTypeSourceInfo())
|
||||
TL = TSI->getTypeLoc();
|
||||
}
|
||||
return cast<llvm::DISubroutineType>(getOrCreateType(FnType, F, TL));
|
||||
return cast<llvm::DISubroutineType>(getOrCreateType(FnType, F));
|
||||
}
|
||||
|
||||
QualType
|
||||
|
@ -4489,12 +4402,8 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
|
|||
uint64_t XOffset = 0;
|
||||
if (VD->hasAttr<BlocksAttr>())
|
||||
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.
|
||||
|
@ -5365,14 +5274,10 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
|
|||
}
|
||||
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,
|
||||
DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
|
||||
Var->hasLocalLinkage(), true,
|
||||
Expr.empty() ? nullptr : DBuilder.createExpression(Expr),
|
||||
getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
|
||||
Align, Annotations);
|
||||
|
|
|
@ -177,19 +177,16 @@ class CGDebugInfo {
|
|||
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 @@ class CGDebugInfo {
|
|||
/// \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 @@ class CGDebugInfo {
|
|||
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 @@ private:
|
|||
Optional<StringRef> 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 @@ private:
|
|||
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,
|
||||
|
|
|
@ -2310,6 +2310,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
|
|||
case Type::TypeOf:
|
||||
case Type::UnaryTransform:
|
||||
case Type::Attributed:
|
||||
case Type::BTFTagAttributed:
|
||||
case Type::SubstTemplateTypeParm:
|
||||
case Type::MacroQualified:
|
||||
// Keep walking after single level desugaring.
|
||||
|
|
|
@ -4513,6 +4513,7 @@ static void captureVariablyModifiedType(ASTContext &Context, QualType T,
|
|||
case Type::TypeOf:
|
||||
case Type::UnaryTransform:
|
||||
case Type::Attributed:
|
||||
case Type::BTFTagAttributed:
|
||||
case Type::SubstTemplateTypeParm:
|
||||
case Type::MacroQualified:
|
||||
// Keep walking after single level desugaring.
|
||||
|
|
|
@ -266,6 +266,12 @@ namespace {
|
|||
return T;
|
||||
}
|
||||
|
||||
/// Get a BTFTagAttributed type for the btf_type_tag attribute.
|
||||
QualType getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr,
|
||||
QualType WrappedType) {
|
||||
return sema.Context.getBTFTagAttributedType(BTFAttr, WrappedType);
|
||||
}
|
||||
|
||||
/// Completely replace the \c auto in \p TypeWithAuto by
|
||||
/// \p Replacement. Also replace \p TypeWithAuto in \c TypeAttrPair if
|
||||
/// necessary.
|
||||
|
@ -5918,6 +5924,9 @@ namespace {
|
|||
Visit(TL.getModifiedLoc());
|
||||
fillAttributedTypeLoc(TL, State);
|
||||
}
|
||||
void VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) {
|
||||
Visit(TL.getWrappedLoc());
|
||||
}
|
||||
void VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
|
||||
Visit(TL.getInnerLoc());
|
||||
TL.setExpansionLoc(
|
||||
|
@ -6144,6 +6153,9 @@ namespace {
|
|||
void VisitAttributedTypeLoc(AttributedTypeLoc TL) {
|
||||
fillAttributedTypeLoc(TL, State);
|
||||
}
|
||||
void VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) {
|
||||
// nothing
|
||||
}
|
||||
void VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
|
||||
// nothing
|
||||
}
|
||||
|
@ -6559,8 +6571,8 @@ static void HandleBTFTypeTagAttribute(QualType &Type, const ParsedAttr &Attr,
|
|||
|
||||
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
|
||||
|
|
|
@ -6865,6 +6865,13 @@ QualType TreeTransform<Derived>::TransformAttributedType(
|
|||
return result;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
|
||||
TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
|
||||
// The BTFTagAttributedType is available for C only.
|
||||
llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
QualType
|
||||
TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
|
||||
|
|
|
@ -6695,6 +6695,10 @@ void TypeLocReader::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
|
|||
TL.setAttr(ReadAttr());
|
||||
}
|
||||
|
||||
void TypeLocReader::VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
|
||||
TL.setNameLoc(readSourceLocation());
|
||||
}
|
||||
|
|
|
@ -479,6 +479,10 @@ void TypeLocWriter::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
|
|||
Record.AddAttr(TL.getAttr());
|
||||
}
|
||||
|
||||
void TypeLocWriter::VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
void TypeLocWriter::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
|
||||
Record.AddSourceLocation(TL.getNameLoc());
|
||||
}
|
||||
|
|
|
@ -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"}
|
|
@ -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;
|
|
@ -23,3 +23,19 @@ struct t {
|
|||
int __tag4 * __tag5 * __tag6 *foo1(struct t __tag1 * __tag2 * __tag3 *a1) {
|
||||
return (int __tag4 * __tag5 * __tag6 *)a1[0][0]->d;
|
||||
}
|
||||
|
||||
// The btf_type_tag attribute will be ignored during _Generic type matching
|
||||
int g1 = _Generic((int *)0, int __tag1 *: 0);
|
||||
int g2 = _Generic((int __tag1 *)0, int *: 0);
|
||||
int g3 = _Generic(0,
|
||||
int __tag1 * : 0, // expected-note {{compatible type 'int btf_type_tag(tag1)*' (aka 'int *') specified here}}
|
||||
int * : 0, // expected-error {{type 'int *' in generic association compatible with previously specified type 'int btf_type_tag(tag1)*' (aka 'int *')}}
|
||||
default : 0);
|
||||
|
||||
// The btf_type_tag attribute will be ignored during overloadable type matching
|
||||
void bar2(int __tag1 *a) __attribute__((overloadable)) { asm volatile (""); } // expected-note {{previous definition is here}}
|
||||
void bar2(int *a) __attribute__((overloadable)) { asm volatile (""); } // expected-error {{redefinition of 'bar2'}}
|
||||
void foo2(int __tag1 *a, int *b) {
|
||||
bar2(a);
|
||||
bar2(b);
|
||||
}
|
||||
|
|
|
@ -1672,6 +1672,10 @@ bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
|
|||
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()))
|
||||
|
|
|
@ -116,6 +116,7 @@ static CXTypeKind GetTypeKind(QualType T) {
|
|||
TKCASE(Elaborated);
|
||||
TKCASE(Pipe);
|
||||
TKCASE(Attributed);
|
||||
TKCASE(BTFTagAttributed);
|
||||
TKCASE(Atomic);
|
||||
default:
|
||||
return CXType_Unexposed;
|
||||
|
@ -136,6 +137,10 @@ CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
|
|||
return MakeCXType(ATT->getEquivalentType(), TU);
|
||||
}
|
||||
}
|
||||
if (auto *ATT = T->getAs<BTFTagAttributedType>()) {
|
||||
if (!(TU->ParsingOptions & CXTranslationUnit_IncludeAttributedTypes))
|
||||
return MakeCXType(ATT->getWrappedType(), TU);
|
||||
}
|
||||
// Handle paren types as the original type
|
||||
if (auto *PTT = T->getAs<ParenType>()) {
|
||||
return MakeCXType(PTT->getInnerType(), TU);
|
||||
|
@ -610,6 +615,7 @@ CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
|
|||
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 @@ CXType clang_Type_getModifiedType(CXType CT) {
|
|||
if (auto *ATT = T->getAs<AttributedType>())
|
||||
return MakeCXType(ATT->getModifiedType(), GetTU(CT));
|
||||
|
||||
if (auto *ATT = T->getAs<BTFTagAttributedType>())
|
||||
return MakeCXType(ATT->getWrappedType(), GetTU(CT));
|
||||
|
||||
return MakeCXType(QualType(), GetTU(CT));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue