|
@@ -2954,8 +2954,7 @@ static void handleVecTypeHint(Sema &S, Decl *D, const ParsedAttr &AL) {
|
|
if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() &&
|
|
if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() &&
|
|
(ParmType->isBooleanType() ||
|
|
(ParmType->isBooleanType() ||
|
|
!ParmType->isIntegralType(S.getASTContext()))) {
|
|
!ParmType->isIntegralType(S.getASTContext()))) {
|
|
- S.Diag(AL.getLoc(), diag::err_attribute_argument_vec_type_hint)
|
|
|
|
- << ParmType;
|
|
|
|
|
|
+ S.Diag(AL.getLoc(), diag::err_attribute_invalid_argument) << 3 << AL;
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -4555,6 +4554,67 @@ static void handleSuppressAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
|
|
DiagnosticIdentifiers.size(), AL.getAttributeSpellingListIndex()));
|
|
DiagnosticIdentifiers.size(), AL.getAttributeSpellingListIndex()));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void handleLifetimeCategoryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
|
|
|
|
+ TypeSourceInfo *DerefTypeLoc = nullptr;
|
|
|
|
+ QualType ParmType;
|
|
|
|
+ if (AL.hasParsedType()) {
|
|
|
|
+ ParmType = S.GetTypeFromParser(AL.getTypeArg(), &DerefTypeLoc);
|
|
|
|
+
|
|
|
|
+ unsigned SelectIdx = ~0U;
|
|
|
|
+ if (ParmType->isVoidType())
|
|
|
|
+ SelectIdx = 0;
|
|
|
|
+ else if (ParmType->isReferenceType())
|
|
|
|
+ SelectIdx = 1;
|
|
|
|
+ else if (ParmType->isArrayType())
|
|
|
|
+ SelectIdx = 2;
|
|
|
|
+
|
|
|
|
+ if (SelectIdx != ~0U) {
|
|
|
|
+ S.Diag(AL.getLoc(), diag::err_attribute_invalid_argument)
|
|
|
|
+ << SelectIdx << AL;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // To check if earlier decl attributes do not conflict the newly parsed ones
|
|
|
|
+ // we always add (and check) the attribute to the cannonical decl.
|
|
|
|
+ D = D->getCanonicalDecl();
|
|
|
|
+ if (AL.getKind() == ParsedAttr::AT_Owner) {
|
|
|
|
+ if (checkAttrMutualExclusion<PointerAttr>(S, D, AL))
|
|
|
|
+ return;
|
|
|
|
+ if (const auto *OAttr = D->getAttr<OwnerAttr>()) {
|
|
|
|
+ const Type *ExistingDerefType = OAttr->getDerefTypeLoc()
|
|
|
|
+ ? OAttr->getDerefType().getTypePtr()
|
|
|
|
+ : nullptr;
|
|
|
|
+ if (ExistingDerefType != ParmType.getTypePtrOrNull()) {
|
|
|
|
+ S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
|
|
|
|
+ << AL << OAttr;
|
|
|
|
+ S.Diag(OAttr->getLocation(), diag::note_conflicting_attribute);
|
|
|
|
+ }
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ D->addAttr(::new (S.Context)
|
|
|
|
+ OwnerAttr(AL.getRange(), S.Context, DerefTypeLoc,
|
|
|
|
+ AL.getAttributeSpellingListIndex()));
|
|
|
|
+ } else {
|
|
|
|
+ if (checkAttrMutualExclusion<OwnerAttr>(S, D, AL))
|
|
|
|
+ return;
|
|
|
|
+ if (const auto *PAttr = D->getAttr<PointerAttr>()) {
|
|
|
|
+ const Type *ExistingDerefType = PAttr->getDerefTypeLoc()
|
|
|
|
+ ? PAttr->getDerefType().getTypePtr()
|
|
|
|
+ : nullptr;
|
|
|
|
+ if (ExistingDerefType != ParmType.getTypePtrOrNull()) {
|
|
|
|
+ S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
|
|
|
|
+ << AL << PAttr;
|
|
|
|
+ S.Diag(PAttr->getLocation(), diag::note_conflicting_attribute);
|
|
|
|
+ }
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ D->addAttr(::new (S.Context)
|
|
|
|
+ PointerAttr(AL.getRange(), S.Context, DerefTypeLoc,
|
|
|
|
+ AL.getAttributeSpellingListIndex()));
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
|
|
bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
|
|
const FunctionDecl *FD) {
|
|
const FunctionDecl *FD) {
|
|
if (Attrs.isInvalid())
|
|
if (Attrs.isInvalid())
|
|
@@ -7158,6 +7218,10 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|
case ParsedAttr::AT_Suppress:
|
|
case ParsedAttr::AT_Suppress:
|
|
handleSuppressAttr(S, D, AL);
|
|
handleSuppressAttr(S, D, AL);
|
|
break;
|
|
break;
|
|
|
|
+ case ParsedAttr::AT_Owner:
|
|
|
|
+ case ParsedAttr::AT_Pointer:
|
|
|
|
+ handleLifetimeCategoryAttr(S, D, AL);
|
|
|
|
+ break;
|
|
case ParsedAttr::AT_OpenCLKernel:
|
|
case ParsedAttr::AT_OpenCLKernel:
|
|
handleSimpleAttribute<OpenCLKernelAttr>(S, D, AL);
|
|
handleSimpleAttribute<OpenCLKernelAttr>(S, D, AL);
|
|
break;
|
|
break;
|