leonardchan updated this revision to Diff 182092.
leonardchan marked an inline comment as done.
Repository:
rC Clang
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D55447/new/
https://reviews.llvm.org/D55447
Files:
clang/docs/ReleaseNotes.rst
clang/include/clang/Sema/Sema.h
clang/lib/AST/Type.cpp
clang/lib/AST/TypePrinter.cpp
clang/lib/Sema/SemaType.cpp
clang/test/AST/address_space_attribute.cpp
clang/test/Index/print-type.m
clang/tools/libclang/CXType.cpp
Index: clang/tools/libclang/CXType.cpp
===================================================================
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -129,7 +129,9 @@
// 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
Index: clang/test/Index/print-type.m
===================================================================
--- clang/test/Index/print-type.m
+++ clang/test/Index/print-type.m
@@ -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]
Index: clang/test/AST/address_space_attribute.cpp
===================================================================
--- /dev/null
+++ clang/test/AST/address_space_attribute.cpp
@@ -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>();
+}
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -5756,28 +5756,27 @@
// 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);
}
@@ -5786,14 +5785,28 @@
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 this type is already address space qualified with a different
// address space, reject it.
// ISO/IEC TR 18037 S5.3 (amending C99 6.7.3): "No type shall be qualified
@@ -5824,6 +5837,14 @@
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.
@@ -5869,19 +5890,41 @@
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());
+ LangAS ASIdx;
+ if (!BuildAddressSpaceIndex(S, ASIdx, ASArgExpr, Attr.getLoc())) {
+ Attr.setInvalid();
+ return;
+ }
- 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);
+ 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 {
- Attr.setInvalid();
+ 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.
switch (Attr.getKind()) {
@@ -7342,9 +7385,11 @@
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;
}
}
Index: clang/lib/AST/TypePrinter.cpp
===================================================================
--- clang/lib/AST/TypePrinter.cpp
+++ clang/lib/AST/TypePrinter.cpp
@@ -258,11 +258,17 @@
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;
@@ -1378,7 +1384,10 @@
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()) {
Index: clang/lib/AST/Type.cpp
===================================================================
--- clang/lib/AST/Type.cpp
+++ clang/lib/AST/Type.cpp
@@ -3206,6 +3206,7 @@
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
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -1408,6 +1408,10 @@
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);
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -261,7 +261,11 @@
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
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits