Anastasia updated this revision to Diff 179469.
Anastasia added a comment.

- Changed to store DeclSpec only when quals are present.
- Renamed to MethodQualifiers.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55948/new/

https://reviews.llvm.org/D55948

Files:
  include/clang/Sema/DeclSpec.h
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseDeclCXX.cpp
  lib/Parse/ParseExpr.cpp
  lib/Parse/ParseExprCXX.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaLambda.cpp
  lib/Sema/SemaType.cpp

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,
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/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/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/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/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/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/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/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<ParsedType, 2> 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: 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());
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to