r351997 - [Sema] Fix Modified Type in address_space AttributedType
Leonard Chan via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 23 16:11:35 PST 2019
Author: leonardchan
Date: Wed Jan 23 16:11:35 2019
New Revision: 351997
URL: http://llvm.org/viewvc/llvm-project?rev=351997&view=rev
Log:
[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
Added:
cfe/trunk/test/AST/address_space_attribute.cpp
Modified:
cfe/trunk/docs/ReleaseNotes.rst
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/AST/TypePrinter.cpp
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/test/Index/print-type.m
cfe/trunk/tools/libclang/CXType.cpp
Modified: cfe/trunk/docs/ReleaseNotes.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ReleaseNotes.rst?rev=351997&r1=351996&r2=351997&view=diff
==============================================================================
--- cfe/trunk/docs/ReleaseNotes.rst (original)
+++ cfe/trunk/docs/ReleaseNotes.rst Wed Jan 23 16:11:35 2019
@@ -162,7 +162,11 @@ clang-format
libclang
--------
-...
+- When `CINDEXTEST_INCLUDE_ATTRIBUTED_TYPES` is not provided when making a
+ CXType, the equivalent type of the AttributedType is returned instead of the
+ modified type if the user does not want attribute sugar. The equivalent type
+ represents the minimally-desugared type which the AttributedType is
+ canonically equivalent to.
Static Analyzer
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=351997&r1=351996&r2=351997&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Jan 23 16:11:35 2019
@@ -1411,6 +1411,10 @@ public:
QualType BuildVectorType(QualType T, Expr *VecSize, SourceLocation AttrLoc);
QualType BuildExtVectorType(QualType T, Expr *ArraySize,
SourceLocation AttrLoc);
+ QualType BuildAddressSpaceAttr(QualType &T, LangAS ASIdx, Expr *AddrSpace,
+ SourceLocation AttrLoc);
+
+ /// Same as above, but constructs the AddressSpace index if not provided.
QualType BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
SourceLocation AttrLoc);
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=351997&r1=351996&r2=351997&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Wed Jan 23 16:11:35 2019
@@ -3205,6 +3205,7 @@ bool AttributedType::isQualifier() const
case attr::TypeNullable:
case attr::TypeNullUnspecified:
case attr::LifetimeBound:
+ case attr::AddressSpace:
return true;
// All other type attributes aren't qualifiers; they rewrite the modified
Modified: cfe/trunk/lib/AST/TypePrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=351997&r1=351996&r2=351997&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TypePrinter.cpp (original)
+++ cfe/trunk/lib/AST/TypePrinter.cpp Wed Jan 23 16:11:35 2019
@@ -257,11 +257,17 @@ bool TypePrinter::canPrefixQualifiers(co
case Type::FunctionProto:
case Type::FunctionNoProto:
case Type::Paren:
- case Type::Attributed:
case Type::PackExpansion:
case Type::SubstTemplateTypeParm:
CanPrefixQualifiers = false;
break;
+
+ case Type::Attributed: {
+ // We still want to print the address_space before the type if it is an
+ // address_space attribute.
+ const auto *AttrTy = cast<AttributedType>(T);
+ CanPrefixQualifiers = AttrTy->getAttrKind() == attr::AddressSpace;
+ }
}
return CanPrefixQualifiers;
@@ -1377,7 +1383,10 @@ void TypePrinter::printAttributedBefore(
if (T->getAttrKind() == attr::ObjCKindOf)
OS << "__kindof ";
- printBefore(T->getModifiedType(), OS);
+ if (T->getAttrKind() == attr::AddressSpace)
+ printBefore(T->getEquivalentType(), OS);
+ else
+ printBefore(T->getModifiedType(), OS);
if (T->isMSTypeSpec()) {
switch (T->getAttrKind()) {
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=351997&r1=351996&r2=351997&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Wed Jan 23 16:11:35 2019
@@ -5787,28 +5787,27 @@ ParsedType Sema::ActOnObjCInstanceType(S
// Type Attribute Processing
//===----------------------------------------------------------------------===//
-/// BuildAddressSpaceAttr - Builds a DependentAddressSpaceType if an expression
-/// is uninstantiated. If instantiated it will apply the appropriate address space
-/// to the type. This function allows dependent template variables to be used in
-/// conjunction with the address_space attribute
-QualType Sema::BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
- SourceLocation AttrLoc) {
+/// Build an AddressSpace index from a constant expression and diagnose any
+/// errors related to invalid address_spaces. Returns true on successfully
+/// building an AddressSpace index.
+static bool BuildAddressSpaceIndex(Sema &S, LangAS &ASIdx,
+ const Expr *AddrSpace,
+ SourceLocation AttrLoc) {
if (!AddrSpace->isValueDependent()) {
-
llvm::APSInt addrSpace(32);
- if (!AddrSpace->isIntegerConstantExpr(addrSpace, Context)) {
- Diag(AttrLoc, diag::err_attribute_argument_type)
+ if (!AddrSpace->isIntegerConstantExpr(addrSpace, S.Context)) {
+ S.Diag(AttrLoc, diag::err_attribute_argument_type)
<< "'address_space'" << AANT_ArgumentIntegerConstant
<< AddrSpace->getSourceRange();
- return QualType();
+ return false;
}
// Bounds checking.
if (addrSpace.isSigned()) {
if (addrSpace.isNegative()) {
- Diag(AttrLoc, diag::err_attribute_address_space_negative)
+ S.Diag(AttrLoc, diag::err_attribute_address_space_negative)
<< AddrSpace->getSourceRange();
- return QualType();
+ return false;
}
addrSpace.setIsSigned(false);
}
@@ -5817,14 +5816,28 @@ QualType Sema::BuildAddressSpaceAttr(Qua
max =
Qualifiers::MaxAddressSpace - (unsigned)LangAS::FirstTargetAddressSpace;
if (addrSpace > max) {
- Diag(AttrLoc, diag::err_attribute_address_space_too_high)
+ S.Diag(AttrLoc, diag::err_attribute_address_space_too_high)
<< (unsigned)max.getZExtValue() << AddrSpace->getSourceRange();
- return QualType();
+ return false;
}
- LangAS ASIdx =
+ ASIdx =
getLangASFromTargetAS(static_cast<unsigned>(addrSpace.getZExtValue()));
+ return true;
+ }
+
+ // Default value for DependentAddressSpaceTypes
+ ASIdx = LangAS::Default;
+ return true;
+}
+/// BuildAddressSpaceAttr - Builds a DependentAddressSpaceType if an expression
+/// is uninstantiated. If instantiated it will apply the appropriate address
+/// space to the type. This function allows dependent template variables to be
+/// used in conjunction with the address_space attribute
+QualType Sema::BuildAddressSpaceAttr(QualType &T, LangAS ASIdx, Expr *AddrSpace,
+ SourceLocation AttrLoc) {
+ if (!AddrSpace->isValueDependent()) {
if (DiagnoseMultipleAddrSpaceAttributes(*this, T.getAddressSpace(), ASIdx,
AttrLoc))
return QualType();
@@ -5845,6 +5858,14 @@ QualType Sema::BuildAddressSpaceAttr(Qua
return Context.getDependentAddressSpaceType(T, AddrSpace, AttrLoc);
}
+QualType Sema::BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
+ SourceLocation AttrLoc) {
+ LangAS ASIdx;
+ if (!BuildAddressSpaceIndex(*this, ASIdx, AddrSpace, AttrLoc))
+ return QualType();
+ return BuildAddressSpaceAttr(T, ASIdx, AddrSpace, AttrLoc);
+}
+
/// HandleAddressSpaceTypeAttribute - Process an address_space attribute on the
/// specified type. The attribute contains 1 argument, the id of the address
/// space for the type.
@@ -5890,19 +5911,41 @@ static void HandleAddressSpaceTypeAttrib
ASArgExpr = static_cast<Expr *>(Attr.getArgAsExpr(0));
}
- // Create the DependentAddressSpaceType or append an address space onto
- // the type.
- QualType T = S.BuildAddressSpaceAttr(Type, ASArgExpr, Attr.getLoc());
-
- if (!T.isNull()) {
- ASTContext &Ctx = S.Context;
- auto *ASAttr = ::new (Ctx) AddressSpaceAttr(
- Attr.getRange(), Ctx, Attr.getAttributeSpellingListIndex(),
- static_cast<unsigned>(T.getQualifiers().getAddressSpace()));
- Type = State.getAttributedType(ASAttr, T, T);
- } else {
+ LangAS ASIdx;
+ if (!BuildAddressSpaceIndex(S, ASIdx, ASArgExpr, Attr.getLoc())) {
Attr.setInvalid();
+ return;
}
+
+ ASTContext &Ctx = S.Context;
+ auto *ASAttr = ::new (Ctx) AddressSpaceAttr(
+ Attr.getRange(), Ctx, Attr.getAttributeSpellingListIndex(),
+ static_cast<unsigned>(ASIdx));
+
+ // If the expression is not value dependent (not templated), then we can
+ // apply the address space qualifiers just to the equivalent type.
+ // Otherwise, we make an AttributedType with the modified and equivalent
+ // type the same, and wrap it in a DependentAddressSpaceType. When this
+ // dependent type is resolved, the qualifier is added to the equivalent type
+ // later.
+ QualType T;
+ if (!ASArgExpr->isValueDependent()) {
+ QualType EquivType =
+ S.BuildAddressSpaceAttr(Type, ASIdx, ASArgExpr, Attr.getLoc());
+ if (EquivType.isNull()) {
+ Attr.setInvalid();
+ return;
+ }
+ T = State.getAttributedType(ASAttr, Type, EquivType);
+ } else {
+ T = State.getAttributedType(ASAttr, Type, Type);
+ T = S.BuildAddressSpaceAttr(T, ASIdx, ASArgExpr, Attr.getLoc());
+ }
+
+ if (!T.isNull())
+ Type = T;
+ else
+ Attr.setInvalid();
} else {
// The keyword-based type attributes imply which address space to use.
ASIdx = Attr.asOpenCLLangAS();
@@ -7346,9 +7389,11 @@ static void processTypeAttrs(TypeProcess
if (!IsTypeAttr)
continue;
}
- } else if (TAL != TAL_DeclChunk) {
+ } else if (TAL != TAL_DeclChunk &&
+ attr.getKind() != ParsedAttr::AT_AddressSpace) {
// Otherwise, only consider type processing for a C++11 attribute if
// it's actually been applied to a type.
+ // We also allow C++11 address_space attributes to pass through.
continue;
}
}
Added: cfe/trunk/test/AST/address_space_attribute.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/AST/address_space_attribute.cpp?rev=351997&view=auto
==============================================================================
--- cfe/trunk/test/AST/address_space_attribute.cpp (added)
+++ cfe/trunk/test/AST/address_space_attribute.cpp Wed Jan 23 16:11:35 2019
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 %s -ast-dump | FileCheck %s
+
+// Veryify the ordering of the address_space attribute still comes before the
+// type whereas other attributes are still printed after.
+
+template <int I>
+void func() {
+ // CHECK: VarDecl {{.*}} x '__attribute__((address_space(1))) int *'
+ __attribute__((address_space(1))) int *x;
+
+ // CHECK: VarDecl {{.*}} a 'int * __attribute__((noderef))'
+ int __attribute__((noderef)) * a;
+
+ // CHECK: VarDecl {{.*}} y '__attribute__((address_space(2))) int *'
+ __attribute__((address_space(I))) int *y;
+
+ // CHECK: VarDecl {{.*}} z '__attribute__((address_space(3))) int *'
+ [[clang::address_space(3)]] int *z;
+}
+
+void func2() {
+ func<2>();
+}
Modified: cfe/trunk/test/Index/print-type.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/print-type.m?rev=351997&r1=351996&r2=351997&view=diff
==============================================================================
--- cfe/trunk/test/Index/print-type.m (original)
+++ cfe/trunk/test/Index/print-type.m Wed Jan 23 16:11:35 2019
@@ -19,6 +19,6 @@
// CHECK: ObjCInstanceMethodDecl=methodIn:andOut::5:10 (variadic) [Bycopy,] [type=] [typekind=Invalid] [resulttype=id] [resulttypekind=ObjCId] [args= [int] [Int] [short *] [Pointer]] [isPOD=0]
// CHECK: ParmDecl=i:5:27 (Definition) [In,] [type=int] [typekind=Int] [isPOD=1]
// CHECK: ParmDecl=j:5:49 (Definition) [Out,] [type=short *] [typekind=Pointer] [isPOD=1] [pointeetype=short] [pointeekind=Short]
-// 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]
+// 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]
// CHECK: ObjCPropertyDecl=classProp:7:23 [class,] [type=int] [typekind=Int] [isPOD=1]
// CHECK: ObjCInstanceMethodDecl=generic:11:12 [type=] [typekind=Invalid] [resulttype=SomeType] [resulttypekind=ObjCTypeParam] [isPOD=0]
Modified: cfe/trunk/tools/libclang/CXType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXType.cpp?rev=351997&r1=351996&r2=351997&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXType.cpp (original)
+++ cfe/trunk/tools/libclang/CXType.cpp Wed Jan 23 16:11:35 2019
@@ -128,7 +128,9 @@ CXType cxtype::MakeCXType(QualType T, CX
// Handle attributed types as the original type
if (auto *ATT = T->getAs<AttributedType>()) {
if (!(TU->ParsingOptions & CXTranslationUnit_IncludeAttributedTypes)) {
- return MakeCXType(ATT->getModifiedType(), TU);
+ // Return the equivalent type which represents the canonically
+ // equivalent type.
+ return MakeCXType(ATT->getEquivalentType(), TU);
}
}
// Handle paren types as the original type
More information about the cfe-commits
mailing list