diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/DeclSpec.cpp | 53 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 32 | ||||
-rw-r--r-- | clang/lib/Sema/SemaLambda.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 27 |
5 files changed, 69 insertions, 53 deletions
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp index 2efa0a7fd1d..8b002dac134 100644 --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -156,14 +156,8 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, unsigned NumParams, SourceLocation EllipsisLoc, SourceLocation RParenLoc, - unsigned TypeQuals, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, - SourceLocation ConstQualifierLoc, - SourceLocation - VolatileQualifierLoc, - SourceLocation - RestrictQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, @@ -178,8 +172,9 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, - TypeResult TrailingReturnType) { - assert(!(TypeQuals & DeclSpec::TQ_atomic) && + TypeResult TrailingReturnType, + DeclSpec *MethodQualifiers) { + assert(!(MethodQualifiers && MethodQualifiers->getTypeQualifiers() & DeclSpec::TQ_atomic) && "function cannot have _Atomic qualifier"); DeclaratorChunk I; @@ -193,14 +188,10 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding(); I.Fun.RParenLoc = RParenLoc.getRawEncoding(); I.Fun.DeleteParams = false; - I.Fun.TypeQuals = TypeQuals; I.Fun.NumParams = NumParams; I.Fun.Params = nullptr; I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef; I.Fun.RefQualifierLoc = RefQualifierLoc.getRawEncoding(); - I.Fun.ConstQualifierLoc = ConstQualifierLoc.getRawEncoding(); - I.Fun.VolatileQualifierLoc = VolatileQualifierLoc.getRawEncoding(); - I.Fun.RestrictQualifierLoc = RestrictQualifierLoc.getRawEncoding(); I.Fun.MutableLoc = MutableLoc.getRawEncoding(); I.Fun.ExceptionSpecType = ESpecType; I.Fun.ExceptionSpecLocBeg = ESpecRange.getBegin().getRawEncoding(); @@ -211,8 +202,21 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, I.Fun.HasTrailingReturnType = TrailingReturnType.isUsable() || TrailingReturnType.isInvalid(); I.Fun.TrailingReturnType = TrailingReturnType.get(); + I.Fun.MethodQualifiers = nullptr; + I.Fun.QualAttrFactory = nullptr; + + if (MethodQualifiers && (MethodQualifiers->getTypeQualifiers() || + MethodQualifiers->getAttributes().size())) { + auto &attrs = MethodQualifiers->getAttributes(); + I.Fun.MethodQualifiers = new DeclSpec(attrs.getPool().getFactory()); + MethodQualifiers->forEachCVRUQualifier( + [&](DeclSpec::TQ TypeQual, StringRef PrintName, SourceLocation SL) { + I.Fun.MethodQualifiers->SetTypeQual(TypeQual, SL); + }); + I.Fun.MethodQualifiers->getAttributes().takeAllFrom(attrs); + I.Fun.MethodQualifiers->getAttributePool().takeAllFrom(attrs.getPool()); + } - assert(I.Fun.TypeQuals == TypeQuals && "bitfield overflow"); assert(I.Fun.ExceptionSpecType == ESpecType && "bitfield overflow"); // new[] a parameter array if needed. @@ -403,6 +407,24 @@ bool Declarator::isCtorOrDtor() { (getName().getKind() == UnqualifiedIdKind::IK_DestructorName); } +void DeclSpec::forEachCVRUQualifier( + llvm::function_ref<void(TQ, StringRef, SourceLocation)> Handle) { + if (TypeQualifiers & TQ_const) + Handle(TQ_const, "const", TQ_constLoc); + if (TypeQualifiers & TQ_volatile) + Handle(TQ_volatile, "volatile", TQ_volatileLoc); + if (TypeQualifiers & TQ_restrict) + Handle(TQ_restrict, "restrict", TQ_restrictLoc); + if (TypeQualifiers & TQ_unaligned) + Handle(TQ_unaligned, "unaligned", TQ_unalignedLoc); +} + +void DeclSpec::forEachQualifier( + llvm::function_ref<void(TQ, StringRef, SourceLocation)> Handle) { + forEachCVRUQualifier(Handle); + // FIXME: Add code below to iterate through the attributes and call Handle. +} + bool DeclSpec::hasTagDefinition() const { if (!TypeSpecOwned) return false; @@ -862,6 +884,11 @@ bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, IsExtension = false; return BadSpecifier(T, T, PrevSpec, DiagID, IsExtension); } + + return SetTypeQual(T, Loc); +} + +bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc) { TypeQualifiers |= T; switch (T) { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index f607873a73c..2b88955285f 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -13508,12 +13508,8 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, /*NumParams=*/0, /*EllipsisLoc=*/NoLoc, /*RParenLoc=*/NoLoc, - /*TypeQuals=*/0, /*RefQualifierIsLvalueRef=*/true, /*RefQualifierLoc=*/NoLoc, - /*ConstQualifierLoc=*/NoLoc, - /*VolatileQualifierLoc=*/NoLoc, - /*RestrictQualifierLoc=*/NoLoc, /*MutableLoc=*/NoLoc, EST_None, /*ESpecRange=*/SourceRange(), /*Exceptions=*/nullptr, diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 4ab220fd03f..e19b68718e5 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -8174,16 +8174,12 @@ QualType Sema::CheckConstructorDeclarator(Declarator &D, QualType R, } DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo(); - if (FTI.TypeQuals != 0) { - if (FTI.TypeQuals & Qualifiers::Const) - Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor) - << "const" << SourceRange(D.getIdentifierLoc()); - if (FTI.TypeQuals & Qualifiers::Volatile) - Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor) - << "volatile" << SourceRange(D.getIdentifierLoc()); - if (FTI.TypeQuals & Qualifiers::Restrict) - Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor) - << "restrict" << SourceRange(D.getIdentifierLoc()); + if (FTI.hasMethodTypeQualifiers()) { + FTI.MethodQualifiers->forEachQualifier( + [&](DeclSpec::TQ TypeQual, StringRef QualName, SourceLocation SL) { + Diag(SL, diag::err_invalid_qualified_constructor) + << QualName << SourceRange(SL); + }); D.setInvalidType(); } @@ -8364,16 +8360,12 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R, } DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo(); - if (FTI.TypeQuals != 0 && !D.isInvalidType()) { - if (FTI.TypeQuals & Qualifiers::Const) - Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor) - << "const" << SourceRange(D.getIdentifierLoc()); - if (FTI.TypeQuals & Qualifiers::Volatile) - Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor) - << "volatile" << SourceRange(D.getIdentifierLoc()); - if (FTI.TypeQuals & Qualifiers::Restrict) - Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor) - << "restrict" << SourceRange(D.getIdentifierLoc()); + if (FTI.hasMethodTypeQualifiers() && !D.isInvalidType()) { + FTI.MethodQualifiers->forEachQualifier( + [&](DeclSpec::TQ TypeQual, StringRef QualName, SourceLocation SL) { + Diag(SL, diag::err_invalid_qualified_destructor) + << QualName << SourceRange(SL); + }); D.setInvalidType(); } diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index c1c4572aa27..10f5e7b7bcf 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -884,8 +884,10 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, // This function call operator is declared const (9.3.1) if and only if // the lambda-expression's parameter-declaration-clause is not followed // by mutable. It is neither virtual nor declared volatile. [...] - if (!FTI.hasMutableQualifier()) - FTI.TypeQuals |= DeclSpec::TQ_const; + if (!FTI.hasMutableQualifier()) { + FTI.getOrCreateMethodQualifiers().SetTypeQual(DeclSpec::TQ_const, + SourceLocation()); + } MethodTyInfo = GetTypeForDeclarator(ParamInfo, CurScope); assert(MethodTyInfo && "no type from lambda-declarator"); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index bd4a0e1407c..bf2bfda9ce3 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -724,12 +724,8 @@ static void maybeSynthesizeBlockSignature(TypeProcessingState &state, /*NumArgs=*/0, /*EllipsisLoc=*/NoLoc, /*RParenLoc=*/NoLoc, - /*TypeQuals=*/0, /*RefQualifierIsLvalueRef=*/true, /*RefQualifierLoc=*/NoLoc, - /*ConstQualifierLoc=*/NoLoc, - /*VolatileQualifierLoc=*/NoLoc, - /*RestrictQualifierLoc=*/NoLoc, /*MutableLoc=*/NoLoc, EST_None, /*ESpecRange=*/SourceRange(), /*Exceptions=*/nullptr, @@ -737,8 +733,7 @@ static void maybeSynthesizeBlockSignature(TypeProcessingState &state, /*NumExceptions=*/0, /*NoexceptExpr=*/nullptr, /*ExceptionSpecTokens=*/nullptr, - /*DeclsInPrototype=*/None, - loc, loc, declarator)); + /*DeclsInPrototype=*/None, loc, loc, declarator)); // For consistency, make sure the state still has us as processing // the decl spec. @@ -4460,7 +4455,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, // does not have a K&R-style identifier list), then the arguments are part // of the type, otherwise the argument list is (). const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun; - IsQualifiedFunction = FTI.TypeQuals || FTI.hasRefQualifier(); + IsQualifiedFunction = + FTI.hasMethodTypeQualifiers() || FTI.hasRefQualifier(); // Check for auto functions and trailing return type and adjust the // return type accordingly. @@ -4698,7 +4694,9 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, EPI.ExtInfo = EI; EPI.Variadic = FTI.isVariadic; EPI.HasTrailingReturn = FTI.hasTrailingReturnType(); - EPI.TypeQuals.addCVRUQualifiers(FTI.TypeQuals); + EPI.TypeQuals.addCVRUQualifiers( + FTI.MethodQualifiers ? FTI.MethodQualifiers->getTypeQualifiers() + : 0); EPI.RefQualifier = !FTI.hasRefQualifier()? RQ_None : FTI.RefQualifierIsLValueRef? RQ_LValue : RQ_RValue; @@ -5024,14 +5022,15 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, SmallVector<SourceLocation, 4> RemovalLocs; const DeclaratorChunk &Chunk = D.getTypeObject(I); assert(Chunk.Kind == DeclaratorChunk::Function); + if (Chunk.Fun.hasRefQualifier()) RemovalLocs.push_back(Chunk.Fun.getRefQualifierLoc()); - if (Chunk.Fun.TypeQuals & Qualifiers::Const) - RemovalLocs.push_back(Chunk.Fun.getConstQualifierLoc()); - if (Chunk.Fun.TypeQuals & Qualifiers::Volatile) - RemovalLocs.push_back(Chunk.Fun.getVolatileQualifierLoc()); - if (Chunk.Fun.TypeQuals & Qualifiers::Restrict) - RemovalLocs.push_back(Chunk.Fun.getRestrictQualifierLoc()); + + if (Chunk.Fun.hasMethodTypeQualifiers()) + Chunk.Fun.MethodQualifiers->forEachQualifier( + [&](DeclSpec::TQ TypeQual, StringRef QualName, + SourceLocation SL) { RemovalLocs.push_back(SL); }); + if (!RemovalLocs.empty()) { llvm::sort(RemovalLocs, BeforeThanCompare<SourceLocation>(S.getSourceManager())); |