Skip to content

Commit f2597f7

Browse files
committed
[clang] Extend pointer interpretation handling to track explicitness
We need a new type like DependentPointerType for non-dependent contexts that can track __capability applied to things like typeof(...) in order to have a corresponding TypeLoc for the qualifier, otherwise things like TypeSpecLocFiller get out of sync and, in some cases assert (in other cases silently use the wrong DeclSpec). However, this then exposes the fact TypePrinter's PrintingPolicy's SuppressCapabilityQualifier isn't always able to be set to the right value (e.g. when printing out a reinterpret_cast<T> to the user, or when dumping the AST), and so we end up with redundant __capability qualifiers appearing for purecap code in some cases, and so we need to track alongside the pointer interpretation whether it was explicit (which also needs care to ensure it doesn't mess with canonicalisation). Whilst the output is now noisier in cases where __capability is used in purecap code, this is more faithful to the source. The churn in the AST output due to __capability in the source always being sugar is an unfortunate side-effect, but this should disappear if llvm/llvm-project#65214 is merged. Fixes #710
1 parent 2f2dd31 commit f2597f7

File tree

72 files changed

+1515
-935
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+1515
-935
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 64 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
227227
mutable llvm::FoldingSet<DependentAddressSpaceType>
228228
DependentAddressSpaceTypes;
229229
mutable llvm::FoldingSet<DependentPointerType> DependentPointerTypes;
230+
mutable llvm::FoldingSet<PointerInterpretationType>
231+
PointerInterpretationTypes;
230232
mutable llvm::FoldingSet<VectorType> VectorTypes;
231233
mutable llvm::FoldingSet<DependentVectorType> DependentVectorTypes;
232234
mutable llvm::FoldingSet<ConstantMatrixType> MatrixTypes;
@@ -1340,19 +1342,42 @@ class ASTContext : public RefCountedBase<ASTContext> {
13401342

13411343
/// Get the default pointer interpretation in use.
13421344
PointerInterpretationKind getDefaultPointerInterpretation() const;
1345+
PointerInterpretationKindExplicit
1346+
getDefaultPointerInterpretationExplicit() const {
1347+
return PointerInterpretationKindExplicit(getDefaultPointerInterpretation(),
1348+
/*IsExplicit=*/false);
1349+
}
1350+
1351+
/// Canonicalise a PointerInterpretationKindExplicit, i.e. turn an explicit
1352+
/// default interpretation into an implicit one. Do not use when an explicit
1353+
/// default interpretation is meaningful.
1354+
PointerInterpretationKindExplicit getCanonicalPointerInterpretationExplicit(
1355+
PointerInterpretationKindExplicit PIKE) const {
1356+
if (PIKE.IsExplicit) {
1357+
if (PIKE.PIK == getDefaultPointerInterpretation())
1358+
return PointerInterpretationKindExplicit(PIKE.PIK,
1359+
/*IsExplicit=*/false);
1360+
} else {
1361+
assert(PIKE.PIK == getDefaultPointerInterpretation() &&
1362+
"Invalid implicit non-default pointer interpretation");
1363+
}
1364+
return PIKE;
1365+
}
13431366

13441367
/// Return the uniqued reference to the type for a pointer to
13451368
/// the specified type.
1369+
QualType getPointerType(QualType T,
1370+
PointerInterpretationKindExplicit PIKE) const;
13461371
QualType getPointerType(QualType T) const {
1347-
return getPointerType(T, getDefaultPointerInterpretation());
1372+
return getPointerType(T, getDefaultPointerInterpretationExplicit());
13481373
}
1349-
QualType getPointerType(QualType T, PointerInterpretationKind PIK) const;
1374+
// NB: PointerInterpretationKindExplicit-taking variant not present since the
1375+
// PIKE may not be canonical, and CanPointerInterpretationKindExplicit
1376+
// doesn't exist to ensure the right function is chosen between this and the
1377+
// plain QualType version (otherwise this will always be used in preference
1378+
// to the QualType one for a CanQualType).
13501379
CanQualType getPointerType(CanQualType T) const {
1351-
return getPointerType(T, getDefaultPointerInterpretation());
1352-
}
1353-
CanQualType getPointerType(CanQualType T,
1354-
PointerInterpretationKind PIK) const {
1355-
return CanQualType::CreateUnsafe(getPointerType((QualType) T, PIK));
1380+
return CanQualType::CreateUnsafe(getPointerType((QualType)T));
13561381
}
13571382

13581383
/// Return the uniqued reference to a type adjusted from the original
@@ -1436,18 +1461,18 @@ class ASTContext : public RefCountedBase<ASTContext> {
14361461
QualType getLValueReferenceType(QualType T,
14371462
bool SpelledAsLValue = true) const {
14381463
return getLValueReferenceType(T, SpelledAsLValue,
1439-
getDefaultPointerInterpretation());
1464+
getDefaultPointerInterpretationExplicit());
14401465
}
14411466
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue,
1442-
PointerInterpretationKind PIK) const;
1467+
PointerInterpretationKindExplicit PIKE) const;
14431468

14441469
/// Return the uniqued reference to the type for an rvalue reference
14451470
/// to the specified type.
14461471
QualType getRValueReferenceType(QualType T) const {
1447-
return getRValueReferenceType(T, getDefaultPointerInterpretation());
1472+
return getRValueReferenceType(T, getDefaultPointerInterpretationExplicit());
14481473
}
14491474
QualType getRValueReferenceType(QualType T,
1450-
PointerInterpretationKind PIK) const;
1475+
PointerInterpretationKindExplicit PIKE) const;
14511476

14521477
/// Return the uniqued reference to the type for a member pointer to
14531478
/// the specified type in the specified class.
@@ -1457,42 +1482,39 @@ class ASTContext : public RefCountedBase<ASTContext> {
14571482

14581483
/// Return a non-unique reference to the type for a variable array of
14591484
/// the specified element type.
1460-
QualType getVariableArrayType(QualType EltTy, Expr *NumElts,
1461-
ArrayType::ArraySizeModifier ASM,
1462-
unsigned IndexTypeQuals,
1463-
SourceRange Brackets,
1464-
llvm::Optional<PointerInterpretationKind>
1465-
PIK = llvm::None) const;
1485+
QualType
1486+
getVariableArrayType(QualType EltTy, Expr *NumElts,
1487+
ArrayType::ArraySizeModifier ASM,
1488+
unsigned IndexTypeQuals, SourceRange Brackets,
1489+
llvm::Optional<PointerInterpretationKindExplicit> PIKE =
1490+
llvm::None) const;
14661491

14671492
/// Return a non-unique reference to the type for a dependently-sized
14681493
/// array of the specified element type.
14691494
///
14701495
/// FIXME: We will need these to be uniqued, or at least comparable, at some
14711496
/// point.
1472-
QualType getDependentSizedArrayType(QualType EltTy, Expr *NumElts,
1473-
ArrayType::ArraySizeModifier ASM,
1474-
unsigned IndexTypeQuals,
1475-
SourceRange Brackets,
1476-
llvm::Optional<PointerInterpretationKind>
1477-
PIK = llvm::None) const;
1497+
QualType getDependentSizedArrayType(
1498+
QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM,
1499+
unsigned IndexTypeQuals, SourceRange Brackets,
1500+
llvm::Optional<PointerInterpretationKindExplicit> PIKE =
1501+
llvm::None) const;
14781502

14791503
/// Return a unique reference to the type for an incomplete array of
14801504
/// the specified element type.
1481-
QualType getIncompleteArrayType(QualType EltTy,
1482-
ArrayType::ArraySizeModifier ASM,
1483-
unsigned IndexTypeQuals,
1484-
llvm::Optional<PointerInterpretationKind>
1485-
PIK = llvm::None) const;
1486-
1505+
QualType getIncompleteArrayType(
1506+
QualType EltTy, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals,
1507+
llvm::Optional<PointerInterpretationKindExplicit> PIKE =
1508+
llvm::None) const;
14871509

14881510
/// Return the unique reference to the type for a constant array of
14891511
/// the specified element type.
1490-
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize,
1491-
const Expr *SizeExpr,
1492-
ArrayType::ArraySizeModifier ASM,
1493-
unsigned IndexTypeQuals,
1494-
llvm::Optional<PointerInterpretationKind>
1495-
PIK = llvm::None) const;
1512+
QualType
1513+
getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize,
1514+
const Expr *SizeExpr, ArrayType::ArraySizeModifier ASM,
1515+
unsigned IndexTypeQuals,
1516+
llvm::Optional<PointerInterpretationKindExplicit> PIKE =
1517+
llvm::None) const;
14961518

14971519
/// Return a type for a constant array for a string literal of the
14981520
/// specified element type and length.
@@ -1571,6 +1593,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
15711593
PointerInterpretationKind PIK,
15721594
SourceLocation QualifierLoc) const;
15731595

1596+
QualType getPointerInterpretationType(PointerInterpretationKind PIK,
1597+
SourceRange QualifierRange,
1598+
QualType ModifiedType,
1599+
QualType EquivalentType) const;
1600+
15741601
/// Return a K&R style C function type like 'int()'.
15751602
QualType getFunctionNoProtoType(QualType ResultTy,
15761603
const FunctionType::ExtInfo &Info) const;
@@ -2783,8 +2810,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
27832810
///
27842811
/// See C99 6.7.5.3p7 and C99 6.3.2.1p3.
27852812
QualType getArrayDecayedType(QualType T,
2786-
llvm::Optional<PointerInterpretationKind>
2787-
PIKFromBase = llvm::None) const;
2813+
llvm::Optional<PointerInterpretationKindExplicit>
2814+
PIKEFromBase = llvm::None) const;
27882815

27892816
/// Return the type that \p PromotableType will promote to: C99
27902817
/// 6.3.1.1p2, assuming that \p PromotableType is a promotable integer type.

clang/include/clang/AST/ASTNodeTraverser.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,12 @@ class ASTNodeTraverser
366366
Visit(T->getElementType());
367367
Visit(T->getSizeExpr());
368368
}
369+
void VisitDependentPointerType(const DependentPointerType *T) {
370+
Visit(T->getPointerType());
371+
}
372+
void VisitPointerInterpretationType(const PointerInterpretationType *T) {
373+
Visit(T->getModifiedType());
374+
}
369375
void VisitVectorType(const VectorType *T) { Visit(T->getElementType()); }
370376
void VisitFunctionType(const FunctionType *T) { Visit(T->getReturnType()); }
371377
void VisitFunctionProtoType(const FunctionProtoType *T) {

clang/include/clang/AST/Expr.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -986,9 +986,18 @@ class Expr : public ValueStmt {
986986
return skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
987987
}
988988

989+
/// Returns the PointerInterpretationKindExplicit for the underlying memory
990+
/// access of this expression, if accessing memory.
991+
llvm::Optional<PointerInterpretationKindExplicit>
992+
getUnderlyingPointerInterpretationExplicitOrNone() const;
993+
989994
/// Returns true if the underlying memory of this expression is
990995
/// accessed through a capability.
991-
bool hasUnderlyingCapability() const;
996+
bool hasUnderlyingCapability() const {
997+
llvm::Optional<PointerInterpretationKindExplicit> PIKE =
998+
getUnderlyingPointerInterpretationExplicitOrNone();
999+
return PIKE && PIKE->PIK == PIK_Capability;
1000+
}
9921001

9931002
/// XXXAR: Expr->getType() returns int for the initializers expression in
9941003
/// `void x(int& __capability arg) { int& a = arg }`

clang/include/clang/AST/PrettyPrinter.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ struct PrintingPolicy {
6565
SuppressInlineNamespace(true), SuppressInitializers(false),
6666
ConstantArraySizeAsWritten(false), AnonymousTagLocations(true),
6767
SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false),
68-
SuppressCapabilityQualifier(TI && TI->areAllPointersCapabilities()),
6968
SuppressTemplateArgsInCXXConstructors(false),
7069
SuppressDefaultTemplateArgs(true), Bool(LO.Bool),
7170
Nullptr(LO.CPlusPlus11), Restrict(LO.C99), Alignof(LO.CPlusPlus11),
@@ -182,9 +181,6 @@ struct PrintingPolicy {
182181
/// When true, suppress printing of lifetime qualifier in ARC.
183182
unsigned SuppressLifetimeQualifiers : 1;
184183

185-
/// When true, suppress printing of the __capability qualifier.
186-
unsigned SuppressCapabilityQualifier : 1;
187-
188184
/// When true, suppresses printing template arguments in names of C++
189185
/// constructors.
190186
unsigned SuppressTemplateArgsInCXXConstructors : 1;

clang/include/clang/AST/PropertiesBase.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ def NestedNameSpecifierKind :
127127
EnumPropertyType<"NestedNameSpecifier::SpecifierKind">;
128128
def OverloadedOperatorKind : EnumPropertyType;
129129
def PointerInterpretationKind : EnumPropertyType;
130+
def PointerInterpretationKindExplicit : PropertyType;
130131
def Qualifiers : PropertyType;
131132
def QualType : DefaultValuePropertyType;
132133
def RefQualifierKind : EnumPropertyType;

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,9 @@ DEF_TRAVERSE_TYPE(DependentPointerType, {
940940
TRY_TO(TraverseType(T->getPointerType()));
941941
})
942942

943+
DEF_TRAVERSE_TYPE(PointerInterpretationType,
944+
{ TRY_TO(TraverseType(T->getModifiedType())); })
945+
943946
DEF_TRAVERSE_TYPE(DependentVectorType, {
944947
if (T->getSizeExpr())
945948
TRY_TO(TraverseStmt(T->getSizeExpr()));
@@ -1199,6 +1202,9 @@ DEF_TRAVERSE_TYPELOC(DependentPointerType, {
11991202
TRY_TO(TraverseType(TL.getTypePtr()->getPointerType()));
12001203
})
12011204

1205+
DEF_TRAVERSE_TYPELOC(PointerInterpretationType,
1206+
{ TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
1207+
12021208
// FIXME: order? why not size expr first?
12031209
// FIXME: base VectorTypeLoc is unfinished
12041210
DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {

0 commit comments

Comments
 (0)