@@ -5787,28 +5787,27 @@ ParsedType Sema::ActOnObjCInstanceType(SourceLocation Loc) {
5787
5787
// Type Attribute Processing
5788
5788
// ===----------------------------------------------------------------------===//
5789
5789
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) {
5796
5796
if (!AddrSpace->isValueDependent ()) {
5797
-
5798
5797
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)
5801
5800
<< " 'address_space'" << AANT_ArgumentIntegerConstant
5802
5801
<< AddrSpace->getSourceRange ();
5803
- return QualType () ;
5802
+ return false ;
5804
5803
}
5805
5804
5806
5805
// Bounds checking.
5807
5806
if (addrSpace.isSigned ()) {
5808
5807
if (addrSpace.isNegative ()) {
5809
- Diag (AttrLoc, diag::err_attribute_address_space_negative)
5808
+ S. Diag (AttrLoc, diag::err_attribute_address_space_negative)
5810
5809
<< AddrSpace->getSourceRange ();
5811
- return QualType () ;
5810
+ return false ;
5812
5811
}
5813
5812
addrSpace.setIsSigned (false );
5814
5813
}
@@ -5817,14 +5816,28 @@ QualType Sema::BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
5817
5816
max =
5818
5817
Qualifiers::MaxAddressSpace - (unsigned )LangAS::FirstTargetAddressSpace;
5819
5818
if (addrSpace > max) {
5820
- Diag (AttrLoc, diag::err_attribute_address_space_too_high)
5819
+ S. Diag (AttrLoc, diag::err_attribute_address_space_too_high)
5821
5820
<< (unsigned )max.getZExtValue () << AddrSpace->getSourceRange ();
5822
- return QualType () ;
5821
+ return false ;
5823
5822
}
5824
5823
5825
- LangAS ASIdx =
5824
+ ASIdx =
5826
5825
getLangASFromTargetAS (static_cast <unsigned >(addrSpace.getZExtValue ()));
5826
+ return true ;
5827
+ }
5827
5828
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 ()) {
5828
5841
if (DiagnoseMultipleAddrSpaceAttributes (*this , T.getAddressSpace (), ASIdx,
5829
5842
AttrLoc))
5830
5843
return QualType ();
@@ -5845,6 +5858,14 @@ QualType Sema::BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
5845
5858
return Context.getDependentAddressSpaceType (T, AddrSpace, AttrLoc);
5846
5859
}
5847
5860
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
+
5848
5869
// / HandleAddressSpaceTypeAttribute - Process an address_space attribute on the
5849
5870
// / specified type. The attribute contains 1 argument, the id of the address
5850
5871
// / space for the type.
@@ -5890,19 +5911,41 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
5890
5911
ASArgExpr = static_cast <Expr *>(Attr.getArgAsExpr (0 ));
5891
5912
}
5892
5913
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
+ }
5896
5919
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);
5903
5940
} else {
5904
- Attr.setInvalid ();
5941
+ T = State.getAttributedType (ASAttr, Type, Type);
5942
+ T = S.BuildAddressSpaceAttr (T, ASIdx, ASArgExpr, Attr.getLoc ());
5905
5943
}
5944
+
5945
+ if (!T.isNull ())
5946
+ Type = T;
5947
+ else
5948
+ Attr.setInvalid ();
5906
5949
} else {
5907
5950
// The keyword-based type attributes imply which address space to use.
5908
5951
ASIdx = Attr.asOpenCLLangAS ();
@@ -7346,9 +7389,11 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
7346
7389
if (!IsTypeAttr)
7347
7390
continue ;
7348
7391
}
7349
- } else if (TAL != TAL_DeclChunk) {
7392
+ } else if (TAL != TAL_DeclChunk &&
7393
+ attr.getKind () != ParsedAttr::AT_AddressSpace) {
7350
7394
// Otherwise, only consider type processing for a C++11 attribute if
7351
7395
// it's actually been applied to a type.
7396
+ // We also allow C++11 address_space attributes to pass through.
7352
7397
continue ;
7353
7398
}
7354
7399
}
0 commit comments