diff options
author | dim <dim@FreeBSD.org> | 2015-06-21 14:00:56 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-06-21 14:00:56 +0000 |
commit | 9dd834653b811ad20382e98a87dff824980c9916 (patch) | |
tree | a764184c2fc9486979b074250b013a0937ee64e5 /lib/Sema/SemaDeclAttr.cpp | |
parent | bb9760db9b86e93a638ed430d0a14785f7ff9064 (diff) | |
download | FreeBSD-src-9dd834653b811ad20382e98a87dff824980c9916.zip FreeBSD-src-9dd834653b811ad20382e98a87dff824980c9916.tar.gz |
Vendor import of clang trunk r240225:
https://llvm.org/svn/llvm-project/cfe/trunk@240225
Diffstat (limited to 'lib/Sema/SemaDeclAttr.cpp')
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 118 |
1 files changed, 103 insertions, 15 deletions
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 1d04159..43790c2 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -2397,6 +2397,28 @@ static void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) { D->addAttr(NewAttr); } +// Check for things we'd like to warn about, no errors or validation for now. +// TODO: Validation should use a backend target library that specifies +// the allowable subtarget features and cpus. We could use something like a +// TargetCodeGenInfo hook here to do validation. +void Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) { + for (auto Str : {"tune=", "fpmath="}) + if (AttrStr.find(Str) != StringRef::npos) + Diag(LiteralLoc, diag::warn_unsupported_target_attribute) << Str; +} + +static void handleTargetAttr(Sema &S, Decl *D, const AttributeList &Attr) { + StringRef Str; + SourceLocation LiteralLoc; + if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &LiteralLoc)) + return; + S.checkTargetAttr(LiteralLoc, Str); + unsigned Index = Attr.getAttributeSpellingListIndex(); + TargetAttr *NewAttr = + ::new (S.Context) TargetAttr(Attr.getRange(), S.Context, Str, Index); + D->addAttr(NewAttr); +} + static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) { VarDecl *VD = cast<VarDecl>(D); @@ -3132,16 +3154,22 @@ static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) { return; } - if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) + // Base type can also be a vector type (see PR17453). + // Distinguish between base type and base element type. + QualType OldElemTy = OldTy; + if (const VectorType *VT = OldTy->getAs<VectorType>()) + OldElemTy = VT->getElementType(); + + if (!OldElemTy->getAs<BuiltinType>() && !OldElemTy->isComplexType()) S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); else if (IntegerMode) { - if (!OldTy->isIntegralOrEnumerationType()) + if (!OldElemTy->isIntegralOrEnumerationType()) S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); } else if (ComplexMode) { - if (!OldTy->isComplexType()) + if (!OldElemTy->isComplexType()) S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); } else { - if (!OldTy->isFloatingType()) + if (!OldElemTy->isFloatingType()) S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); } @@ -3154,21 +3182,40 @@ static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) { return; } - QualType NewTy; + QualType NewElemTy; if (IntegerMode) - NewTy = S.Context.getIntTypeForBitwidth(DestWidth, - OldTy->isSignedIntegerType()); + NewElemTy = S.Context.getIntTypeForBitwidth( + DestWidth, OldElemTy->isSignedIntegerType()); else - NewTy = S.Context.getRealTypeForBitwidth(DestWidth); + NewElemTy = S.Context.getRealTypeForBitwidth(DestWidth); - if (NewTy.isNull()) { + if (NewElemTy.isNull()) { S.Diag(Attr.getLoc(), diag::err_machine_mode) << 1 /*Unsupported*/ << Name; return; } if (ComplexMode) { - NewTy = S.Context.getComplexType(NewTy); + NewElemTy = S.Context.getComplexType(NewElemTy); + } + + QualType NewTy = NewElemTy; + if (const VectorType *OldVT = OldTy->getAs<VectorType>()) { + // Complex machine mode does not support base vector types. + if (ComplexMode) { + S.Diag(Attr.getLoc(), diag::err_complex_mode_vector_type); + return; + } + unsigned NumElements = S.Context.getTypeSize(OldElemTy) * + OldVT->getNumElements() / + S.Context.getTypeSize(NewElemTy); + NewTy = + S.Context.getVectorType(NewElemTy, NumElements, OldVT->getVectorKind()); + } + + if (NewTy.isNull()) { + S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); + return; } // Install the new type. @@ -3683,10 +3730,31 @@ static void handleNSReturnsRetainedAttr(Sema &S, Decl *D, returnType = PD->getType(); else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) returnType = FD->getReturnType(); - else { + else if (auto *Param = dyn_cast<ParmVarDecl>(D)) { + returnType = Param->getType()->getPointeeType(); + if (returnType.isNull()) { + S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type) + << Attr.getName() << /*pointer-to-CF*/2 + << Attr.getRange(); + return; + } + } else { + AttributeDeclKind ExpectedDeclKind; + switch (Attr.getKind()) { + default: llvm_unreachable("invalid ownership attribute"); + case AttributeList::AT_NSReturnsRetained: + case AttributeList::AT_NSReturnsAutoreleased: + case AttributeList::AT_NSReturnsNotRetained: + ExpectedDeclKind = ExpectedFunctionOrMethod; + break; + + case AttributeList::AT_CFReturnsRetained: + case AttributeList::AT_CFReturnsNotRetained: + ExpectedDeclKind = ExpectedFunctionMethodOrParameter; + break; + } S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) - << Attr.getRange() << Attr.getName() - << ExpectedFunctionOrMethod; + << Attr.getRange() << Attr.getName() << ExpectedDeclKind; return; } @@ -3713,8 +3781,25 @@ static void handleNSReturnsRetainedAttr(Sema &S, Decl *D, } if (!typeOK) { - S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type) - << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf; + if (isa<ParmVarDecl>(D)) { + S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type) + << Attr.getName() << /*pointer-to-CF*/2 + << Attr.getRange(); + } else { + // Needs to be kept in sync with warn_ns_attribute_wrong_return_type. + enum : unsigned { + Function, + Method, + Property + } SubjectKind = Function; + if (isa<ObjCMethodDecl>(D)) + SubjectKind = Method; + else if (isa<ObjCPropertyDecl>(D)) + SubjectKind = Property; + S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type) + << Attr.getName() << SubjectKind << cf + << Attr.getRange(); + } return; } @@ -4716,6 +4801,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_Section: handleSectionAttr(S, D, Attr); break; + case AttributeList::AT_Target: + handleTargetAttr(S, D, Attr); + break; case AttributeList::AT_Unavailable: handleAttrWithMessage<UnavailableAttr>(S, D, Attr); break; |