Skip to content

Commit 009f9e8

Browse files
committedJan 24, 2019
[Sema] Fix Modified Type in address_space AttributedType
This is a fix for https://reviews.llvm.org/D51229 where we pass the address_space qualified type as the modified type of an AttributedType. This change now instead wraps the AttributedType with either the address_space qualifier or a DependentAddressSpaceType. Differential Revision: https://reviews.llvm.org/D55447 llvm-svn: 351997
1 parent ec02630 commit 009f9e8

File tree

8 files changed

+119
-31
lines changed

8 files changed

+119
-31
lines changed
 

‎clang/docs/ReleaseNotes.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,11 @@ clang-format
162162
libclang
163163
--------
164164

165-
...
165+
- When `CINDEXTEST_INCLUDE_ATTRIBUTED_TYPES` is not provided when making a
166+
CXType, the equivalent type of the AttributedType is returned instead of the
167+
modified type if the user does not want attribute sugar. The equivalent type
168+
represents the minimally-desugared type which the AttributedType is
169+
canonically equivalent to.
166170

167171

168172
Static Analyzer

‎clang/include/clang/Sema/Sema.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,6 +1411,10 @@ class Sema {
14111411
QualType BuildVectorType(QualType T, Expr *VecSize, SourceLocation AttrLoc);
14121412
QualType BuildExtVectorType(QualType T, Expr *ArraySize,
14131413
SourceLocation AttrLoc);
1414+
QualType BuildAddressSpaceAttr(QualType &T, LangAS ASIdx, Expr *AddrSpace,
1415+
SourceLocation AttrLoc);
1416+
1417+
/// Same as above, but constructs the AddressSpace index if not provided.
14141418
QualType BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
14151419
SourceLocation AttrLoc);
14161420

‎clang/lib/AST/Type.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3205,6 +3205,7 @@ bool AttributedType::isQualifier() const {
32053205
case attr::TypeNullable:
32063206
case attr::TypeNullUnspecified:
32073207
case attr::LifetimeBound:
3208+
case attr::AddressSpace:
32083209
return true;
32093210

32103211
// All other type attributes aren't qualifiers; they rewrite the modified

‎clang/lib/AST/TypePrinter.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,11 +257,17 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,
257257
case Type::FunctionProto:
258258
case Type::FunctionNoProto:
259259
case Type::Paren:
260-
case Type::Attributed:
261260
case Type::PackExpansion:
262261
case Type::SubstTemplateTypeParm:
263262
CanPrefixQualifiers = false;
264263
break;
264+
265+
case Type::Attributed: {
266+
// We still want to print the address_space before the type if it is an
267+
// address_space attribute.
268+
const auto *AttrTy = cast<AttributedType>(T);
269+
CanPrefixQualifiers = AttrTy->getAttrKind() == attr::AddressSpace;
270+
}
265271
}
266272

267273
return CanPrefixQualifiers;
@@ -1377,7 +1383,10 @@ void TypePrinter::printAttributedBefore(const AttributedType *T,
13771383
if (T->getAttrKind() == attr::ObjCKindOf)
13781384
OS << "__kindof ";
13791385

1380-
printBefore(T->getModifiedType(), OS);
1386+
if (T->getAttrKind() == attr::AddressSpace)
1387+
printBefore(T->getEquivalentType(), OS);
1388+
else
1389+
printBefore(T->getModifiedType(), OS);
13811390

13821391
if (T->isMSTypeSpec()) {
13831392
switch (T->getAttrKind()) {

‎clang/lib/Sema/SemaType.cpp

Lines changed: 71 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5787,28 +5787,27 @@ ParsedType Sema::ActOnObjCInstanceType(SourceLocation Loc) {
57875787
// Type Attribute Processing
57885788
//===----------------------------------------------------------------------===//
57895789

5790-
/// BuildAddressSpaceAttr - Builds a DependentAddressSpaceType if an expression
5791-
/// is uninstantiated. If instantiated it will apply the appropriate address space
5792-
/// to the type. This function allows dependent template variables to be used in
5793-
/// conjunction with the address_space attribute
5794-
QualType Sema::BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
5795-
SourceLocation AttrLoc) {
5790+
/// Build an AddressSpace index from a constant expression and diagnose any
5791+
/// errors related to invalid address_spaces. Returns true on successfully
5792+
/// building an AddressSpace index.
5793+
static bool BuildAddressSpaceIndex(Sema &S, LangAS &ASIdx,
5794+
const Expr *AddrSpace,
5795+
SourceLocation AttrLoc) {
57965796
if (!AddrSpace->isValueDependent()) {
5797-
57985797
llvm::APSInt addrSpace(32);
5799-
if (!AddrSpace->isIntegerConstantExpr(addrSpace, Context)) {
5800-
Diag(AttrLoc, diag::err_attribute_argument_type)
5798+
if (!AddrSpace->isIntegerConstantExpr(addrSpace, S.Context)) {
5799+
S.Diag(AttrLoc, diag::err_attribute_argument_type)
58015800
<< "'address_space'" << AANT_ArgumentIntegerConstant
58025801
<< AddrSpace->getSourceRange();
5803-
return QualType();
5802+
return false;
58045803
}
58055804

58065805
// Bounds checking.
58075806
if (addrSpace.isSigned()) {
58085807
if (addrSpace.isNegative()) {
5809-
Diag(AttrLoc, diag::err_attribute_address_space_negative)
5808+
S.Diag(AttrLoc, diag::err_attribute_address_space_negative)
58105809
<< AddrSpace->getSourceRange();
5811-
return QualType();
5810+
return false;
58125811
}
58135812
addrSpace.setIsSigned(false);
58145813
}
@@ -5817,14 +5816,28 @@ QualType Sema::BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
58175816
max =
58185817
Qualifiers::MaxAddressSpace - (unsigned)LangAS::FirstTargetAddressSpace;
58195818
if (addrSpace > max) {
5820-
Diag(AttrLoc, diag::err_attribute_address_space_too_high)
5819+
S.Diag(AttrLoc, diag::err_attribute_address_space_too_high)
58215820
<< (unsigned)max.getZExtValue() << AddrSpace->getSourceRange();
5822-
return QualType();
5821+
return false;
58235822
}
58245823

5825-
LangAS ASIdx =
5824+
ASIdx =
58265825
getLangASFromTargetAS(static_cast<unsigned>(addrSpace.getZExtValue()));
5826+
return true;
5827+
}
58275828

5829+
// Default value for DependentAddressSpaceTypes
5830+
ASIdx = LangAS::Default;
5831+
return true;
5832+
}
5833+
5834+
/// BuildAddressSpaceAttr - Builds a DependentAddressSpaceType if an expression
5835+
/// is uninstantiated. If instantiated it will apply the appropriate address
5836+
/// space to the type. This function allows dependent template variables to be
5837+
/// used in conjunction with the address_space attribute
5838+
QualType Sema::BuildAddressSpaceAttr(QualType &T, LangAS ASIdx, Expr *AddrSpace,
5839+
SourceLocation AttrLoc) {
5840+
if (!AddrSpace->isValueDependent()) {
58285841
if (DiagnoseMultipleAddrSpaceAttributes(*this, T.getAddressSpace(), ASIdx,
58295842
AttrLoc))
58305843
return QualType();
@@ -5845,6 +5858,14 @@ QualType Sema::BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
58455858
return Context.getDependentAddressSpaceType(T, AddrSpace, AttrLoc);
58465859
}
58475860

5861+
QualType Sema::BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
5862+
SourceLocation AttrLoc) {
5863+
LangAS ASIdx;
5864+
if (!BuildAddressSpaceIndex(*this, ASIdx, AddrSpace, AttrLoc))
5865+
return QualType();
5866+
return BuildAddressSpaceAttr(T, ASIdx, AddrSpace, AttrLoc);
5867+
}
5868+
58485869
/// HandleAddressSpaceTypeAttribute - Process an address_space attribute on the
58495870
/// specified type. The attribute contains 1 argument, the id of the address
58505871
/// space for the type.
@@ -5890,19 +5911,41 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
58905911
ASArgExpr = static_cast<Expr *>(Attr.getArgAsExpr(0));
58915912
}
58925913

5893-
// Create the DependentAddressSpaceType or append an address space onto
5894-
// the type.
5895-
QualType T = S.BuildAddressSpaceAttr(Type, ASArgExpr, Attr.getLoc());
5914+
LangAS ASIdx;
5915+
if (!BuildAddressSpaceIndex(S, ASIdx, ASArgExpr, Attr.getLoc())) {
5916+
Attr.setInvalid();
5917+
return;
5918+
}
58965919

5897-
if (!T.isNull()) {
5898-
ASTContext &Ctx = S.Context;
5899-
auto *ASAttr = ::new (Ctx) AddressSpaceAttr(
5900-
Attr.getRange(), Ctx, Attr.getAttributeSpellingListIndex(),
5901-
static_cast<unsigned>(T.getQualifiers().getAddressSpace()));
5902-
Type = State.getAttributedType(ASAttr, T, T);
5920+
ASTContext &Ctx = S.Context;
5921+
auto *ASAttr = ::new (Ctx) AddressSpaceAttr(
5922+
Attr.getRange(), Ctx, Attr.getAttributeSpellingListIndex(),
5923+
static_cast<unsigned>(ASIdx));
5924+
5925+
// If the expression is not value dependent (not templated), then we can
5926+
// apply the address space qualifiers just to the equivalent type.
5927+
// Otherwise, we make an AttributedType with the modified and equivalent
5928+
// type the same, and wrap it in a DependentAddressSpaceType. When this
5929+
// dependent type is resolved, the qualifier is added to the equivalent type
5930+
// later.
5931+
QualType T;
5932+
if (!ASArgExpr->isValueDependent()) {
5933+
QualType EquivType =
5934+
S.BuildAddressSpaceAttr(Type, ASIdx, ASArgExpr, Attr.getLoc());
5935+
if (EquivType.isNull()) {
5936+
Attr.setInvalid();
5937+
return;
5938+
}
5939+
T = State.getAttributedType(ASAttr, Type, EquivType);
59035940
} else {
5904-
Attr.setInvalid();
5941+
T = State.getAttributedType(ASAttr, Type, Type);
5942+
T = S.BuildAddressSpaceAttr(T, ASIdx, ASArgExpr, Attr.getLoc());
59055943
}
5944+
5945+
if (!T.isNull())
5946+
Type = T;
5947+
else
5948+
Attr.setInvalid();
59065949
} else {
59075950
// The keyword-based type attributes imply which address space to use.
59085951
ASIdx = Attr.asOpenCLLangAS();
@@ -7346,9 +7389,11 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
73467389
if (!IsTypeAttr)
73477390
continue;
73487391
}
7349-
} else if (TAL != TAL_DeclChunk) {
7392+
} else if (TAL != TAL_DeclChunk &&
7393+
attr.getKind() != ParsedAttr::AT_AddressSpace) {
73507394
// Otherwise, only consider type processing for a C++11 attribute if
73517395
// it's actually been applied to a type.
7396+
// We also allow C++11 address_space attributes to pass through.
73527397
continue;
73537398
}
73547399
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %clang_cc1 %s -ast-dump | FileCheck %s
2+
3+
// Veryify the ordering of the address_space attribute still comes before the
4+
// type whereas other attributes are still printed after.
5+
6+
template <int I>
7+
void func() {
8+
// CHECK: VarDecl {{.*}} x '__attribute__((address_space(1))) int *'
9+
__attribute__((address_space(1))) int *x;
10+
11+
// CHECK: VarDecl {{.*}} a 'int * __attribute__((noderef))'
12+
int __attribute__((noderef)) * a;
13+
14+
// CHECK: VarDecl {{.*}} y '__attribute__((address_space(2))) int *'
15+
__attribute__((address_space(I))) int *y;
16+
17+
// CHECK: VarDecl {{.*}} z '__attribute__((address_space(3))) int *'
18+
[[clang::address_space(3)]] int *z;
19+
}
20+
21+
void func2() {
22+
func<2>();
23+
}

‎clang/test/Index/print-type.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@ -(SomeType)generic;
1919
// CHECK: ObjCInstanceMethodDecl=methodIn:andOut::5:10 (variadic) [Bycopy,] [type=] [typekind=Invalid] [resulttype=id] [resulttypekind=ObjCId] [args= [int] [Int] [short *] [Pointer]] [isPOD=0]
2020
// CHECK: ParmDecl=i:5:27 (Definition) [In,] [type=int] [typekind=Int] [isPOD=1]
2121
// CHECK: ParmDecl=j:5:49 (Definition) [Out,] [type=short *] [typekind=Pointer] [isPOD=1] [pointeetype=short] [pointeekind=Short]
22-
// CHECK: ParmDecl=p:6:36 (Definition) [type=__kindof Foo *] [typekind=ObjCObjectPointer] [canonicaltype=__kindof Foo *] [canonicaltypekind=ObjCObjectPointer] [basetype=Foo] [basekind=ObjCInterface] [isPOD=1] [pointeetype=Foo] [pointeekind=ObjCInterface]
22+
// CHECK: ParmDecl=p:6:36 (Definition) [type=__kindof Foo *] [typekind=ObjCObjectPointer] [canonicaltype=__kindof Foo *] [canonicaltypekind=ObjCObjectPointer] [basetype=Foo] [basekind=ObjCInterface] [isPOD=1] [pointeetype=__kindof Foo] [pointeekind=ObjCObject]
2323
// CHECK: ObjCPropertyDecl=classProp:7:23 [class,] [type=int] [typekind=Int] [isPOD=1]
2424
// CHECK: ObjCInstanceMethodDecl=generic:11:12 [type=] [typekind=Invalid] [resulttype=SomeType] [resulttypekind=ObjCTypeParam] [isPOD=0]

‎clang/tools/libclang/CXType.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,9 @@ CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
128128
// Handle attributed types as the original type
129129
if (auto *ATT = T->getAs<AttributedType>()) {
130130
if (!(TU->ParsingOptions & CXTranslationUnit_IncludeAttributedTypes)) {
131-
return MakeCXType(ATT->getModifiedType(), TU);
131+
// Return the equivalent type which represents the canonically
132+
// equivalent type.
133+
return MakeCXType(ATT->getEquivalentType(), TU);
132134
}
133135
}
134136
// Handle paren types as the original type

0 commit comments

Comments
 (0)
Please sign in to comment.