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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits