diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/DeclSpec.cpp | 17 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 17 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateVariadic.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 58 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 29 |
10 files changed, 131 insertions, 2 deletions
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp index d664d870400..6f6c4ca5848 100644 --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -270,6 +270,7 @@ bool Declarator::isDeclarationOfFunction() const { case DeclaratorChunk::Array: case DeclaratorChunk::BlockPointer: case DeclaratorChunk::MemberPointer: + case DeclaratorChunk::Pipe: return false; } llvm_unreachable("Invalid type chunk"); @@ -713,6 +714,22 @@ bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, return false; } +bool DeclSpec::SetTypePipe(bool isPipe, SourceLocation Loc, + const char *&PrevSpec, unsigned &DiagID, + const PrintingPolicy &Policy) { + + if (TypeSpecType != TST_unspecified) { + PrevSpec = DeclSpec::getSpecifierName((TST)TypeSpecType, Policy); + DiagID = diag::err_invalid_decl_spec_combination; + return true; + } + + if (isPipe) { + TypeSpecPipe = TSP_pipe; + } + return false; +} + bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy) { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 0864984c063..66c0e059d4b 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -8256,6 +8256,23 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, for (auto Param : NewFD->params()) checkIsValidOpenCLKernelParameter(*this, D, Param, ValidTypes); } + for (FunctionDecl::param_iterator PI = NewFD->param_begin(), + PE = NewFD->param_end(); PI != PE; ++PI) { + ParmVarDecl *Param = *PI; + QualType PT = Param->getType(); + + // OpenCL 2.0 pipe restrictions forbids pipe packet types to be non-value + // types. + if (getLangOpts().OpenCLVersion >= 200) { + if(const PipeType *PipeTy = PT->getAs<PipeType>()) { + QualType ElemTy = PipeTy->getElementType(); + if (ElemTy->isReferenceType() || ElemTy->isPointerType()) { + Diag(Param->getTypeSpecStartLoc(), diag::err_reference_pipe_type ); + D.setInvalidType(); + } + } + } + } MarkUnusedFileScopedDecl(NewFD); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 02091a7bd53..4b03baf32ac 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -7000,6 +7000,7 @@ void Sema::CheckConversionDeclarator(Declarator &D, QualType &R, case DeclaratorChunk::BlockPointer: case DeclaratorChunk::Reference: case DeclaratorChunk::MemberPointer: + case DeclaratorChunk::Pipe: extendLeft(Before, Chunk.getSourceRange()); break; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 76d0ca56c0c..361b0a1b72d 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -13140,6 +13140,7 @@ bool Sema::tryCaptureVariable( case Type::ObjCObject: case Type::ObjCInterface: case Type::ObjCObjectPointer: + case Type::Pipe: llvm_unreachable("type class is never variably-modified!"); case Type::Adjusted: QTy = cast<AdjustedType>(Ty)->getOriginalType(); diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 481ae6cd55b..1d7b15c35d1 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -2616,6 +2616,9 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) { case Type::Atomic: T = cast<AtomicType>(T)->getValueType().getTypePtr(); continue; + case Type::Pipe: + T = cast<PipeType>(T)->getElementType().getTypePtr(); + continue; } if (Queue.empty()) diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 9775e4d940a..57156078c80 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -4184,6 +4184,10 @@ bool UnnamedLocalNoLinkageFinder::VisitAtomicType(const AtomicType* T) { return Visit(T->getValueType()); } +bool UnnamedLocalNoLinkageFinder::VisitPipeType(const PipeType* T) { + return false; +} + bool UnnamedLocalNoLinkageFinder::VisitTagDecl(const TagDecl *Tag) { if (Tag->getDeclContext()->isFunctionOrMethod()) { S.Diag(SR.getBegin(), diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index cd54920b08c..71faafc6bc1 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -1652,6 +1652,7 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, case Type::Auto: case Type::DependentTemplateSpecialization: case Type::PackExpansion: + case Type::Pipe: // No template argument deduction for these types return Sema::TDK_Success; } @@ -4964,6 +4965,7 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T, case Type::ObjCObject: case Type::ObjCObjectPointer: case Type::UnresolvedUsing: + case Type::Pipe: #define TYPE(Class, Base) #define ABSTRACT_TYPE(Class, Base) #define DEPENDENT_TYPE(Class, Base) diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp index 61052f06c83..cb67d71f9e5 100644 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -750,6 +750,7 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) { case DeclaratorChunk::Pointer: case DeclaratorChunk::Reference: case DeclaratorChunk::Paren: + case DeclaratorChunk::Pipe: case DeclaratorChunk::BlockPointer: // These declarator chunks cannot contain any parameter packs. break; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index c70568c23b5..f6ad132cde8 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -335,6 +335,7 @@ static DeclaratorChunk *maybeMovePastReturnType(Declarator &declarator, case DeclaratorChunk::Array: case DeclaratorChunk::Reference: case DeclaratorChunk::MemberPointer: + case DeclaratorChunk::Pipe: return result; // If we do find a function declarator, scan inwards from that, @@ -347,6 +348,7 @@ static DeclaratorChunk *maybeMovePastReturnType(Declarator &declarator, case DeclaratorChunk::Array: case DeclaratorChunk::Function: case DeclaratorChunk::Reference: + case DeclaratorChunk::Pipe: continue; case DeclaratorChunk::MemberPointer: @@ -427,6 +429,7 @@ static void distributeObjCPointerTypeAttr(TypeProcessingState &state, // Don't walk through these. case DeclaratorChunk::Reference: case DeclaratorChunk::MemberPointer: + case DeclaratorChunk::Pipe: goto error; } } @@ -459,6 +462,7 @@ distributeObjCPointerTypeAttrFromDeclarator(TypeProcessingState &state, case DeclaratorChunk::MemberPointer: case DeclaratorChunk::Paren: case DeclaratorChunk::Array: + case DeclaratorChunk::Pipe: continue; case DeclaratorChunk::Function: @@ -520,6 +524,7 @@ static void distributeFunctionTypeAttr(TypeProcessingState &state, case DeclaratorChunk::Array: case DeclaratorChunk::Reference: case DeclaratorChunk::MemberPointer: + case DeclaratorChunk::Pipe: continue; } } @@ -1272,6 +1277,10 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { // value being declared, poison it as invalid so we don't get chains of // errors. declarator.setInvalidType(true); + } else if (S.getLangOpts().OpenCLVersion >= 200 && DS.isTypeSpecPipe()){ + S.Diag(DeclLoc, diag::err_missing_actual_pipe_type) + << DS.getSourceRange(); + declarator.setInvalidType(true); } else { S.Diag(DeclLoc, diag::ext_missing_type_specifier) << DS.getSourceRange(); @@ -1564,7 +1573,9 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { // Apply any type attributes from the decl spec. This may cause the // list of type attributes to be temporarily saved while the type // attributes are pushed around. - processTypeAttrs(state, Result, TAL_DeclSpec, DS.getAttributes().getList()); + // pipe attributes will be handled later ( at GetFullTypeForDeclarator ) + if (!DS.isTypeSpecPipe()) + processTypeAttrs(state, Result, TAL_DeclSpec, DS.getAttributes().getList()); // Apply const/volatile/restrict qualifiers to T. if (unsigned TypeQuals = DS.getTypeQualifiers()) { @@ -1924,6 +1935,21 @@ QualType Sema::BuildReferenceType(QualType T, bool SpelledAsLValue, return Context.getRValueReferenceType(T); } +/// \brief Build a Pipe type. +/// +/// \param T The type to which we'll be building a Pipe. +/// +/// \param Loc We do not use it for now. +/// +/// \returns A suitable pipe type, if there are no errors. Otherwise, returns a +/// NULL type. +QualType Sema::BuildPipeType(QualType T, SourceLocation Loc) { + assert(!T->isObjCObjectType() && "Should build ObjCObjectPointerType"); + + // Build the pipe type. + return Context.getPipeType(T); +} + /// Check whether the specified array size makes the array type a VLA. If so, /// return true, if not, return the size of the array in SizeVal. static bool isArraySizeVLA(Sema &S, Expr *ArraySize, llvm::APSInt &SizeVal) { @@ -2393,6 +2419,7 @@ static void inferARCWriteback(TypeProcessingState &state, case DeclaratorChunk::Array: // suppress if written (id[])? case DeclaratorChunk::Function: case DeclaratorChunk::MemberPointer: + case DeclaratorChunk::Pipe: return; } } @@ -2532,6 +2559,7 @@ static void diagnoseRedundantReturnTypeQualifiers(Sema &S, QualType RetTy, case DeclaratorChunk::Reference: case DeclaratorChunk::Array: case DeclaratorChunk::MemberPointer: + case DeclaratorChunk::Pipe: // FIXME: We can't currently provide an accurate source location and a // fix-it hint for these. unsigned AtomicQual = RetTy->isAtomicType() ? DeclSpec::TQ_atomic : 0; @@ -3057,6 +3085,7 @@ static PointerDeclaratorKind classifyPointerDeclarator(Sema &S, switch (chunk.Kind) { case DeclaratorChunk::Array: case DeclaratorChunk::Function: + case DeclaratorChunk::Pipe: break; case DeclaratorChunk::BlockPointer: @@ -3305,6 +3334,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, case DeclaratorChunk::Array: DiagKind = 2; break; + case DeclaratorChunk::Pipe: + break; } S.Diag(DeclChunk.Loc, DiagId) << DiagKind; @@ -3370,6 +3401,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, switch (chunk.Kind) { case DeclaratorChunk::Array: case DeclaratorChunk::Function: + case DeclaratorChunk::Pipe: break; case DeclaratorChunk::BlockPointer: @@ -3689,6 +3721,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, break; case DeclaratorChunk::Function: case DeclaratorChunk::BlockPointer: + case DeclaratorChunk::Pipe: // These are invalid anyway, so just ignore. break; } @@ -4038,7 +4071,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, break; } - case DeclaratorChunk::MemberPointer: + case DeclaratorChunk::MemberPointer: { // The scope spec must refer to a class, or be dependent. CXXScopeSpec &SS = DeclType.Mem.Scope(); QualType ClsType; @@ -4098,6 +4131,12 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, break; } + case DeclaratorChunk::Pipe: { + T = S.BuildPipeType(T, DeclType.Loc ); + break; + } + } + if (T.isNull()) { D.setInvalidType(true); T = Context.IntTy; @@ -4392,6 +4431,7 @@ static void transferARCOwnership(TypeProcessingState &state, case DeclaratorChunk::Function: case DeclaratorChunk::MemberPointer: + case DeclaratorChunk::Pipe: return; } } @@ -4682,6 +4722,14 @@ namespace { } } + void VisitPipeTypeLoc(PipeTypeLoc TL) { + TL.setKWLoc(DS.getTypeSpecTypeLoc()); + + TypeSourceInfo *TInfo = 0; + Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo); + TL.getValueLoc().initializeFullCopy(TInfo->getTypeLoc()); + } + void VisitTypeLoc(TypeLoc TL) { // FIXME: add other typespec types and change this to an assert. TL.initialize(Context, DS.getTypeSpecTypeLoc()); @@ -4802,6 +4850,10 @@ namespace { TL.setLParenLoc(Chunk.Loc); TL.setRParenLoc(Chunk.EndLoc); } + void VisitPipeTypeLoc(PipeTypeLoc TL) { + assert(Chunk.Kind == DeclaratorChunk::Pipe); + TL.setKWLoc(Chunk.Loc); + } void VisitTypeLoc(TypeLoc TL) { llvm_unreachable("unsupported TypeLoc kind in declarator!"); @@ -4815,6 +4867,7 @@ static void fillAtomicQualLoc(AtomicTypeLoc ATL, const DeclaratorChunk &Chunk) { case DeclaratorChunk::Function: case DeclaratorChunk::Array: case DeclaratorChunk::Paren: + case DeclaratorChunk::Pipe: llvm_unreachable("cannot be _Atomic qualified"); case DeclaratorChunk::Pointer: @@ -5738,6 +5791,7 @@ static bool distributeNullabilityTypeAttr(TypeProcessingState &state, // Don't walk through these. case DeclaratorChunk::Reference: + case DeclaratorChunk::Pipe: return false; } } diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index e97a2626387..b8f977c16bb 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1046,6 +1046,9 @@ public: /// Subclasses may override this routine to provide different behavior. QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc); + /// \brief Build a new pipe type given its value type. + QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc); + /// \brief Build a new template name given a nested name specifier, a flag /// indicating whether the "template" keyword was provided, and the template /// that the template name refers to. @@ -5324,6 +5327,26 @@ QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB, return Result; } +template <typename Derived> +QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB, + PipeTypeLoc TL) { + QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc()); + if (ValueType.isNull()) + return QualType(); + + QualType Result = TL.getType(); + if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) { + Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc()); + if (Result.isNull()) + return QualType(); + } + + PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(Result); + NewTL.setKWLoc(TL.getKWLoc()); + + return Result; +} + /// \brief Simple iterator that traverses the template arguments in a /// container that provides a \c getArgLoc() member function. /// @@ -11350,6 +11373,12 @@ QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType, } template<typename Derived> +QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType, + SourceLocation KWLoc) { + return SemaRef.BuildPipeType(ValueType, KWLoc); +} + +template<typename Derived> TemplateName TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS, bool TemplateKW, |