Index: include/clang/Sema/DeclSpec.h =================================================================== --- include/clang/Sema/DeclSpec.h +++ include/clang/Sema/DeclSpec.h @@ -683,6 +683,8 @@ ExprRep = Rep; } + bool SetTypeQual(TQ T, SourceLocation Loc); + bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const LangOptions &Lang); @@ -1250,10 +1252,6 @@ /// Otherwise, it's an rvalue reference. unsigned RefQualifierIsLValueRef : 1; - /// The type qualifiers: const/volatile/restrict/__unaligned - /// The qualifier bitmask values are the same as in QualType. - unsigned TypeQuals : 4; - /// ExceptionSpecType - An ExceptionSpecificationType value. unsigned ExceptionSpecType : 4; @@ -1287,21 +1285,6 @@ /// If this is an invalid location, there is no ref-qualifier. unsigned RefQualifierLoc; - /// The location of the const-qualifier, if any. - /// - /// If this is an invalid location, there is no const-qualifier. - unsigned ConstQualifierLoc; - - /// The location of the volatile-qualifier, if any. - /// - /// If this is an invalid location, there is no volatile-qualifier. - unsigned VolatileQualifierLoc; - - /// The location of the restrict-qualifier, if any. - /// - /// If this is an invalid location, there is no restrict-qualifier. - unsigned RestrictQualifierLoc; - /// The location of the 'mutable' qualifer in a lambda-declarator, if /// any. unsigned MutableLoc; @@ -1317,6 +1300,9 @@ /// there are no parameters specified. ParamInfo *Params; + /// DeclSpec for the function with the qualifier related info. + DeclSpec *MethodQualifiers; + union { /// Pointer to a new[]'d array of TypeAndRange objects that /// contain the types in the function's dynamic exception specification @@ -1356,6 +1342,7 @@ void destroy() { freeParams(); + delete MethodQualifiers; switch (getExceptionSpecType()) { default: break; @@ -1372,6 +1359,13 @@ } } + void createMethodQualifiers() { + if (!MethodQualifiers) { + AttributeFactory AttrFactory; + MethodQualifiers = new DeclSpec(AttrFactory); + } + } + /// isKNRPrototype - Return true if this is a K&R style identifier list, /// like "void foo(a,b,c)". In a function definition, this will be followed /// by the parameter type definitions. @@ -1408,17 +1402,17 @@ /// Retrieve the location of the 'const' qualifier, if any. SourceLocation getConstQualifierLoc() const { - return SourceLocation::getFromRawEncoding(ConstQualifierLoc); + return MethodQualifiers->getConstSpecLoc(); } /// Retrieve the location of the 'volatile' qualifier, if any. SourceLocation getVolatileQualifierLoc() const { - return SourceLocation::getFromRawEncoding(VolatileQualifierLoc); + return MethodQualifiers->getVolatileSpecLoc(); } /// Retrieve the location of the 'restrict' qualifier, if any. SourceLocation getRestrictQualifierLoc() const { - return SourceLocation::getFromRawEncoding(RestrictQualifierLoc); + return MethodQualifiers->getRestrictSpecLoc(); } /// Retrieve the location of the 'mutable' qualifier, if any. @@ -1426,6 +1420,27 @@ return SourceLocation::getFromRawEncoding(MutableLoc); } + /// Determine whether this function declaration contains a + /// const qualifier. + bool hasConstQualifier() const { + return MethodQualifiers && + (MethodQualifiers->getTypeQualifiers() & Qualifiers::Const); + } + + /// Determine whether this function declaration contains a + /// volatile qualifier. + bool hasVolatileQualifier() const { + return MethodQualifiers && + (MethodQualifiers->getTypeQualifiers() & Qualifiers::Volatile); + } + + /// Determine whether this function declaration contains a + /// restrict qualifier. + bool hasRestrictQualifier() const { + return MethodQualifiers && + (MethodQualifiers->getTypeQualifiers() & Qualifiers::Restrict); + } + /// Determine whether this function declaration contains a /// ref-qualifier. bool hasRefQualifier() const { return getRefQualifierLoc().isValid(); } @@ -1574,12 +1589,8 @@ ParamInfo *Params, unsigned NumParams, SourceLocation EllipsisLoc, SourceLocation RParenLoc, - unsigned TypeQuals, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, - SourceLocation ConstQualifierLoc, - SourceLocation VolatileQualifierLoc, - SourceLocation RestrictQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, SourceRange ESpecRange, @@ -1592,6 +1603,7 @@ SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, + DeclSpec& MethodQualifiers, TypeResult TrailingReturnType = TypeResult()); Index: lib/Parse/ParseDecl.cpp =================================================================== --- lib/Parse/ParseDecl.cpp +++ lib/Parse/ParseDecl.cpp @@ -6072,9 +6072,6 @@ DeclSpec DS(AttrFactory); bool RefQualifierIsLValueRef = true; SourceLocation RefQualifierLoc; - SourceLocation ConstQualifierLoc; - SourceLocation VolatileQualifierLoc; - SourceLocation RestrictQualifierLoc; ExceptionSpecificationType ESpecType = EST_None; SourceRange ESpecRange; SmallVector DynamicExceptions; @@ -6137,9 +6134,6 @@ })); if (!DS.getSourceRange().getEnd().isInvalid()) { EndLoc = DS.getSourceRange().getEnd(); - ConstQualifierLoc = DS.getConstSpecLoc(); - VolatileQualifierLoc = DS.getVolatileSpecLoc(); - RestrictQualifierLoc = DS.getRestrictSpecLoc(); } // Parse ref-qualifier[opt]. @@ -6239,15 +6233,13 @@ D.AddTypeInfo(DeclaratorChunk::getFunction( HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(), ParamInfo.size(), EllipsisLoc, RParenLoc, - DS.getTypeQualifiers(), RefQualifierIsLValueRef, - RefQualifierLoc, ConstQualifierLoc, VolatileQualifierLoc, - RestrictQualifierLoc, - /*MutableLoc=*/SourceLocation(), ESpecType, ESpecRange, - DynamicExceptions.data(), DynamicExceptionRanges.data(), - DynamicExceptions.size(), + RefQualifierIsLValueRef, RefQualifierLoc, + /*MutableLoc=*/SourceLocation(), + ESpecType, ESpecRange, DynamicExceptions.data(), + DynamicExceptionRanges.data(), DynamicExceptions.size(), NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr, ExceptionSpecTokens, DeclsInPrototype, StartLoc, - LocalEndLoc, D, TrailingReturnType), + LocalEndLoc, D, DS, TrailingReturnType), std::move(FnAttrs), EndLoc); } Index: lib/Parse/ParseDeclCXX.cpp =================================================================== --- lib/Parse/ParseDeclCXX.cpp +++ lib/Parse/ParseDeclCXX.cpp @@ -2346,18 +2346,18 @@ if (D.isFunctionDeclarator()) { auto &Function = D.getFunctionTypeInfo(); if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) { - auto DeclSpecCheck = [&] (DeclSpec::TQ TypeQual, - const char *FixItName, - SourceLocation SpecLoc, - unsigned* QualifierLoc) { + auto DeclSpecCheck = [&](DeclSpec::TQ TypeQual, const char *FixItName, + SourceLocation SpecLoc) { FixItHint Insertion; if (DS.getTypeQualifiers() & TypeQual) { - if (!(Function.TypeQuals & TypeQual)) { + if (!(Function.MethodQualifiers && + (Function.MethodQualifiers->getTypeQualifiers() & TypeQual))) { std::string Name(FixItName); Name += " "; Insertion = FixItHint::CreateInsertion(VS.getFirstLocation(), Name); - Function.TypeQuals |= TypeQual; - *QualifierLoc = SpecLoc.getRawEncoding(); + if (!Function.MethodQualifiers) + Function.createMethodQualifiers(); + Function.MethodQualifiers->SetTypeQual(TypeQual, SpecLoc); } Diag(SpecLoc, diag::err_declspec_after_virtspec) << FixItName @@ -2366,12 +2366,9 @@ << Insertion; } }; - DeclSpecCheck(DeclSpec::TQ_const, "const", DS.getConstSpecLoc(), - &Function.ConstQualifierLoc); - DeclSpecCheck(DeclSpec::TQ_volatile, "volatile", DS.getVolatileSpecLoc(), - &Function.VolatileQualifierLoc); - DeclSpecCheck(DeclSpec::TQ_restrict, "restrict", DS.getRestrictSpecLoc(), - &Function.RestrictQualifierLoc); + DeclSpecCheck(DeclSpec::TQ_const, "const", DS.getConstSpecLoc()); + DeclSpecCheck(DeclSpec::TQ_volatile, "volatile", DS.getVolatileSpecLoc()); + DeclSpecCheck(DeclSpec::TQ_restrict, "restrict", DS.getRestrictSpecLoc()); } // Parse ref-qualifiers. Index: lib/Parse/ParseExpr.cpp =================================================================== --- lib/Parse/ParseExpr.cpp +++ lib/Parse/ParseExpr.cpp @@ -3004,6 +3004,7 @@ } else { // Otherwise, pretend we saw (void). SourceLocation NoLoc; + DeclSpec NoDS(AttrFactory); ParamInfo.AddTypeInfo( DeclaratorChunk::getFunction(/*HasProto=*/true, /*IsAmbiguous=*/false, @@ -3012,12 +3013,8 @@ /*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, @@ -3026,7 +3023,7 @@ /*NoexceptExpr=*/nullptr, /*ExceptionSpecTokens=*/nullptr, /*DeclsInPrototype=*/None, CaretLoc, - CaretLoc, ParamInfo), + CaretLoc, ParamInfo, NoDS), CaretLoc); MaybeParseGNUAttributes(ParamInfo); Index: lib/Parse/ParseExprCXX.cpp =================================================================== --- lib/Parse/ParseExprCXX.cpp +++ lib/Parse/ParseExprCXX.cpp @@ -1202,22 +1202,19 @@ WarnIfHasCUDATargetAttr(); SourceLocation NoLoc; + DeclSpec NoDS(AttrFactory); D.AddTypeInfo(DeclaratorChunk::getFunction( /*hasProto=*/true, /*isAmbiguous=*/false, LParenLoc, ParamInfo.data(), ParamInfo.size(), EllipsisLoc, RParenLoc, - DS.getTypeQualifiers(), /*RefQualifierIsLValueRef=*/true, - /*RefQualifierLoc=*/NoLoc, - /*ConstQualifierLoc=*/NoLoc, - /*VolatileQualifierLoc=*/NoLoc, - /*RestrictQualifierLoc=*/NoLoc, MutableLoc, ESpecType, + /*RefQualifierLoc=*/NoLoc, MutableLoc, ESpecType, ESpecRange, DynamicExceptions.data(), DynamicExceptionRanges.data(), DynamicExceptions.size(), NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr, /*ExceptionSpecTokens*/ nullptr, /*DeclsInPrototype=*/None, LParenLoc, FunLocalRangeEnd, D, - TrailingReturnType), + NoDS, TrailingReturnType), std::move(Attr), DeclEndLoc); } else if (Tok.isOneOf(tok::kw_mutable, tok::arrow, tok::kw___attribute, tok::kw_constexpr) || @@ -1265,6 +1262,7 @@ WarnIfHasCUDATargetAttr(); SourceLocation NoLoc; + DeclSpec NoDS(AttrFactory); D.AddTypeInfo(DeclaratorChunk::getFunction( /*hasProto=*/true, /*isAmbiguous=*/false, @@ -1273,19 +1271,15 @@ /*NumParams=*/0, /*EllipsisLoc=*/NoLoc, /*RParenLoc=*/NoLoc, - /*TypeQuals=*/0, /*RefQualifierIsLValueRef=*/true, - /*RefQualifierLoc=*/NoLoc, - /*ConstQualifierLoc=*/NoLoc, - /*VolatileQualifierLoc=*/NoLoc, - /*RestrictQualifierLoc=*/NoLoc, MutableLoc, EST_None, + /*RefQualifierLoc=*/NoLoc, MutableLoc, EST_None, /*ESpecRange=*/SourceRange(), /*Exceptions=*/nullptr, /*ExceptionRanges=*/nullptr, /*NumExceptions=*/0, /*NoexceptExpr=*/nullptr, /*ExceptionSpecTokens=*/nullptr, - /*DeclsInPrototype=*/None, DeclLoc, DeclEndLoc, D, + /*DeclsInPrototype=*/None, DeclLoc, DeclEndLoc, D, NoDS, TrailingReturnType), std::move(Attr), DeclEndLoc); } Index: lib/Sema/DeclSpec.cpp =================================================================== --- lib/Sema/DeclSpec.cpp +++ lib/Sema/DeclSpec.cpp @@ -156,14 +156,8 @@ 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 @@ SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, + DeclSpec& MethodQualifiers, TypeResult TrailingReturnType) { - assert(!(TypeQuals & DeclSpec::TQ_atomic) && + assert(!(MethodQualifiers.getTypeQualifiers() & DeclSpec::TQ_atomic) && "function cannot have _Atomic qualifier"); DeclaratorChunk I; @@ -193,14 +188,10 @@ 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(); @@ -212,7 +203,27 @@ TrailingReturnType.isInvalid(); I.Fun.TrailingReturnType = TrailingReturnType.get(); - assert(I.Fun.TypeQuals == TypeQuals && "bitfield overflow"); + if (MethodQualifiers.getTypeQualifiers() || + MethodQualifiers.getAttributes().size()) { + auto &attrs = MethodQualifiers.getAttributes(); + I.Fun.MethodQualifiers = new DeclSpec(attrs.getPool().getFactory()); + if (MethodQualifiers.getTypeQualifiers() & DeclSpec::TQ_const) + I.Fun.MethodQualifiers->SetTypeQual(DeclSpec::TQ_const, + MethodQualifiers.getConstSpecLoc()); + if (MethodQualifiers.getTypeQualifiers() & DeclSpec::TQ_volatile) + I.Fun.MethodQualifiers->SetTypeQual( + DeclSpec::TQ_volatile, MethodQualifiers.getVolatileSpecLoc()); + if (MethodQualifiers.getTypeQualifiers() & DeclSpec::TQ_restrict) + I.Fun.MethodQualifiers->SetTypeQual( + DeclSpec::TQ_restrict, MethodQualifiers.getRestrictSpecLoc()); + if (MethodQualifiers.getTypeQualifiers() & DeclSpec::TQ_unaligned) + I.Fun.MethodQualifiers->SetTypeQual( + DeclSpec::TQ_unaligned, MethodQualifiers.getUnalignedSpecLoc()); + I.Fun.MethodQualifiers->getAttributes().takeAllFrom(attrs); + I.Fun.MethodQualifiers->getAttributePool().takeAllFrom(attrs.getPool()); + } else + I.Fun.MethodQualifiers = nullptr; + assert(I.Fun.ExceptionSpecType == ESpecType && "bitfield overflow"); // new[] a parameter array if needed. @@ -862,6 +873,11 @@ IsExtension = false; return BadSpecifier(T, T, PrevSpec, DiagID, IsExtension); } + + return SetTypeQual(T, Loc); +} + +bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc) { TypeQualifiers |= T; switch (T) { Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -13505,6 +13505,7 @@ (void)Error; // Silence warning. assert(!Error && "Error setting up implicit decl!"); SourceLocation NoLoc; + DeclSpec NoDS(attrFactory); Declarator D(DS, DeclaratorContext::BlockContext); D.AddTypeInfo(DeclaratorChunk::getFunction(/*HasProto=*/false, /*IsAmbiguous=*/false, @@ -13513,12 +13514,8 @@ /*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, @@ -13527,7 +13524,7 @@ /*NoexceptExpr=*/nullptr, /*ExceptionSpecTokens=*/nullptr, /*DeclsInPrototype=*/None, Loc, - Loc, D), + Loc, D, NoDS), std::move(DS.getAttributes()), SourceLocation()); D.SetIdentifier(&II, Loc); Index: lib/Sema/SemaDeclCXX.cpp =================================================================== --- lib/Sema/SemaDeclCXX.cpp +++ lib/Sema/SemaDeclCXX.cpp @@ -8172,16 +8172,16 @@ } DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo(); - if (FTI.TypeQuals != 0) { - if (FTI.TypeQuals & Qualifiers::Const) + if (FTI.MethodQualifiers && FTI.MethodQualifiers->getTypeQualifiers() != 0) { + if (FTI.hasConstQualifier()) Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor) - << "const" << SourceRange(D.getIdentifierLoc()); - if (FTI.TypeQuals & Qualifiers::Volatile) + << "const" << SourceRange(D.getIdentifierLoc()); + if (FTI.hasVolatileQualifier()) Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor) - << "volatile" << SourceRange(D.getIdentifierLoc()); - if (FTI.TypeQuals & Qualifiers::Restrict) + << "volatile" << SourceRange(D.getIdentifierLoc()); + if (FTI.hasRestrictQualifier()) Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor) - << "restrict" << SourceRange(D.getIdentifierLoc()); + << "restrict" << SourceRange(D.getIdentifierLoc()); D.setInvalidType(); } @@ -8361,16 +8361,17 @@ } DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo(); - if (FTI.TypeQuals != 0 && !D.isInvalidType()) { - if (FTI.TypeQuals & Qualifiers::Const) + if (FTI.MethodQualifiers && FTI.MethodQualifiers->getTypeQualifiers() != 0 && + !D.isInvalidType()) { + if (FTI.hasConstQualifier()) Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor) - << "const" << SourceRange(D.getIdentifierLoc()); - if (FTI.TypeQuals & Qualifiers::Volatile) + << "const" << SourceRange(D.getIdentifierLoc()); + if (FTI.hasVolatileQualifier()) Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor) - << "volatile" << SourceRange(D.getIdentifierLoc()); - if (FTI.TypeQuals & Qualifiers::Restrict) + << "volatile" << SourceRange(D.getIdentifierLoc()); + if (FTI.hasRestrictQualifier()) Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor) - << "restrict" << SourceRange(D.getIdentifierLoc()); + << "restrict" << SourceRange(D.getIdentifierLoc()); D.setInvalidType(); } Index: lib/Sema/SemaLambda.cpp =================================================================== --- lib/Sema/SemaLambda.cpp +++ lib/Sema/SemaLambda.cpp @@ -884,8 +884,11 @@ // 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()) { + if (!FTI.MethodQualifiers) + FTI.createMethodQualifiers(); + FTI.MethodQualifiers->SetTypeQual(DeclSpec::TQ_const, SourceLocation()); + } MethodTyInfo = GetTypeForDeclarator(ParamInfo, CurScope); assert(MethodTyInfo && "no type from lambda-declarator"); Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -716,6 +716,8 @@ // ...and *prepend* it to the declarator. SourceLocation NoLoc; + AttributeFactory attrFactory; + DeclSpec NoDS(attrFactory); declarator.AddInnermostTypeInfo(DeclaratorChunk::getFunction( /*HasProto=*/true, /*IsAmbiguous=*/false, @@ -724,12 +726,8 @@ /*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 +735,7 @@ /*NumExceptions=*/0, /*NoexceptExpr=*/nullptr, /*ExceptionSpecTokens=*/nullptr, - /*DeclsInPrototype=*/None, - loc, loc, declarator)); + /*DeclsInPrototype=*/None, loc, loc, declarator, NoDS)); // For consistency, make sure the state still has us as processing // the decl spec. @@ -4460,7 +4457,9 @@ // 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.MethodQualifiers && FTI.MethodQualifiers->getTypeQualifiers()) || + FTI.hasRefQualifier(); // Check for auto functions and trailing return type and adjust the // return type accordingly. @@ -4698,7 +4697,9 @@ 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; @@ -5026,11 +5027,11 @@ assert(Chunk.Kind == DeclaratorChunk::Function); if (Chunk.Fun.hasRefQualifier()) RemovalLocs.push_back(Chunk.Fun.getRefQualifierLoc()); - if (Chunk.Fun.TypeQuals & Qualifiers::Const) + if (Chunk.Fun.hasConstQualifier()) RemovalLocs.push_back(Chunk.Fun.getConstQualifierLoc()); - if (Chunk.Fun.TypeQuals & Qualifiers::Volatile) + if (Chunk.Fun.hasVolatileQualifier()) RemovalLocs.push_back(Chunk.Fun.getVolatileQualifierLoc()); - if (Chunk.Fun.TypeQuals & Qualifiers::Restrict) + if (Chunk.Fun.hasRestrictQualifier()) RemovalLocs.push_back(Chunk.Fun.getRestrictQualifierLoc()); if (!RemovalLocs.empty()) { llvm::sort(RemovalLocs,