[clang] Type safety tweak for AttributeCommonInfo::Form
authorRichard Sandiford <richard.sandiford@arm.com>
Tue, 11 Apr 2023 16:58:56 +0000 (17:58 +0100)
committerRichard Sandiford <richard.sandiford@arm.com>
Thu, 13 Apr 2023 09:14:49 +0000 (10:14 +0100)
This patch adds static functions for constructing most
AttributeCommonInfo::Forms.  Direct construction is only retained where
all fields (currently the syntax and spelling) are specified explicitly.

This is a wash on its own.  The purpose is to allow extra fields
to be added to Form without disrupting all callers.  In particular,
it allows extra information to be stored about keywords without
affecting non-keyword uses.

No functional change intended.

Differential Revision: https://reviews.llvm.org/D148104

12 files changed:
clang/include/clang/Basic/AttributeCommonInfo.h
clang/lib/Parse/ParseCXXInlineMethods.cpp
clang/lib/Parse/ParseDecl.cpp
clang/lib/Parse/ParseDeclCXX.cpp
clang/lib/Parse/ParseHLSL.cpp
clang/lib/Parse/ParseObjc.cpp
clang/lib/Parse/ParsePragma.cpp
clang/lib/Parse/ParseStmt.cpp
clang/lib/Sema/SemaAttr.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaType.cpp
clang/utils/TableGen/ClangAttrEmitter.cpp

index 7b88ba1..a5ba571 100644 (file)
@@ -85,8 +85,7 @@ public:
   /// including its syntax and spelling.
   class Form {
   public:
-    constexpr Form(Syntax SyntaxUsed,
-                   unsigned SpellingIndex = SpellingNotCalculated)
+    constexpr Form(Syntax SyntaxUsed, unsigned SpellingIndex)
         : SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingIndex) {}
     constexpr Form(tok::TokenKind)
         : SyntaxUsed(AS_Keyword), SpellingIndex(SpellingNotCalculated) {}
@@ -94,7 +93,21 @@ public:
     Syntax getSyntax() const { return Syntax(SyntaxUsed); }
     unsigned getSpellingIndex() const { return SpellingIndex; }
 
+    static Form GNU() { return AS_GNU; }
+    static Form CXX11() { return AS_CXX11; }
+    static Form C2x() { return AS_C2x; }
+    static Form Declspec() { return AS_Declspec; }
+    static Form Microsoft() { return AS_Microsoft; }
+    static Form Keyword() { return AS_Keyword; }
+    static Form Pragma() { return AS_Pragma; }
+    static Form ContextSensitiveKeyword() { return AS_ContextSensitiveKeyword; }
+    static Form HLSLSemantic() { return AS_HLSLSemantic; }
+    static Form Implicit() { return AS_Implicit; }
+
   private:
+    constexpr Form(Syntax SyntaxUsed)
+        : SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated) {}
+
     unsigned SyntaxUsed : 4;
     unsigned SpellingIndex : 4;
   };
index 3a7f542..930bb81 100644 (file)
@@ -748,7 +748,7 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
       }
 
       ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr,
-                            nullptr, SourceLocation(), ParsedAttr::AS_GNU,
+                            nullptr, SourceLocation(), ParsedAttr::Form::GNU(),
                             nullptr);
 
       if (HasFunScope)
@@ -757,7 +757,7 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
       // If there are multiple decls, then the decl cannot be within the
       // function scope.
       ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr,
-                            nullptr, SourceLocation(), ParsedAttr::AS_GNU,
+                            nullptr, SourceLocation(), ParsedAttr::Form::GNU(),
                             nullptr);
     }
   } else {
index a61a3ef..1889718 100644 (file)
@@ -214,14 +214,14 @@ void Parser::ParseGNUAttributes(ParsedAttributes &Attrs,
 
       if (Tok.isNot(tok::l_paren)) {
         Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
-                     ParsedAttr::AS_GNU);
+                     ParsedAttr::Form::GNU());
         continue;
       }
 
       // Handle "parameterized" attributes
       if (!LateAttrs || !isAttributeLateParsed(*AttrName)) {
         ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, &EndLoc, nullptr,
-                              SourceLocation(), ParsedAttr::AS_GNU, D);
+                              SourceLocation(), ParsedAttr::Form::GNU(), D);
         continue;
       }
 
@@ -726,14 +726,14 @@ bool Parser::ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
     if (!HasInvalidAccessor)
       Attrs.addNewPropertyAttr(AttrName, AttrNameLoc, nullptr, SourceLocation(),
                                AccessorNames[AK_Get], AccessorNames[AK_Put],
-                               ParsedAttr::AS_Declspec);
+                               ParsedAttr::Form::Declspec());
     T.skipToEnd();
     return !HasInvalidAccessor;
   }
 
   unsigned NumArgs =
       ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, nullptr, nullptr,
-                               SourceLocation(), ParsedAttr::AS_Declspec);
+                               SourceLocation(), ParsedAttr::Form::Declspec());
 
   // If this attribute's args were parsed, and it was expected to have
   // arguments but none were provided, emit a diagnostic.
@@ -816,7 +816,7 @@ void Parser::ParseMicrosoftDeclSpecs(ParsedAttributes &Attrs) {
 
       if (!AttrHandled)
         Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
-                     ParsedAttr::AS_Declspec);
+                     ParsedAttr::Form::Declspec());
     }
     T.consumeClose();
     EndLoc = T.getCloseLocation();
index 61a077c..638cc76 100644 (file)
@@ -4354,19 +4354,19 @@ bool Parser::ParseCXX11AttributeArgs(
   assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list");
   SourceLocation LParenLoc = Tok.getLocation();
   const LangOptions &LO = getLangOpts();
-  ParsedAttr::Syntax Syntax =
-      LO.CPlusPlus ? ParsedAttr::AS_CXX11 : ParsedAttr::AS_C2x;
+  ParsedAttr::Form Form =
+      LO.CPlusPlus ? ParsedAttr::Form::CXX11() : ParsedAttr::Form::C2x();
 
   // Try parsing microsoft attributes
   if (getLangOpts().MicrosoftExt || getLangOpts().HLSL) {
     if (hasAttribute(AttributeCommonInfo::Syntax::AS_Microsoft, ScopeName,
                      AttrName, getTargetInfo(), getLangOpts()))
-      Syntax = ParsedAttr::AS_Microsoft;
+      Form = ParsedAttr::Form::Microsoft();
   }
 
   // If the attribute isn't known, we will not attempt to parse any
   // arguments.
-  if (Syntax != ParsedAttr::AS_Microsoft &&
+  if (Form.getSyntax() != ParsedAttr::AS_Microsoft &&
       !hasAttribute(LO.CPlusPlus ? AttributeCommonInfo::Syntax::AS_CXX11
                                  : AttributeCommonInfo::Syntax::AS_C2x,
                     ScopeName, AttrName, getTargetInfo(), getLangOpts())) {
@@ -4382,7 +4382,7 @@ bool Parser::ParseCXX11AttributeArgs(
     // GNU-scoped attributes have some special cases to handle GNU-specific
     // behaviors.
     ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
-                          ScopeLoc, Syntax, nullptr);
+                          ScopeLoc, Form, nullptr);
     return true;
   }
 
@@ -4402,10 +4402,10 @@ bool Parser::ParseCXX11AttributeArgs(
   // Some Clang-scoped attributes have some special parsing behavior.
   if (ScopeName && (ScopeName->isStr("clang") || ScopeName->isStr("_Clang")))
     NumArgs = ParseClangAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc,
-                                      ScopeName, ScopeLoc, Syntax);
+                                      ScopeName, ScopeLoc, Form);
   else
     NumArgs = ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
-                                       ScopeName, ScopeLoc, Syntax);
+                                       ScopeName, ScopeLoc, Form);
 
   if (!Attrs.empty() &&
       IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) {
@@ -4555,7 +4555,8 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs,
           AttrName,
           SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc, AttrLoc),
           ScopeName, ScopeLoc, nullptr, 0,
-          getLangOpts().CPlusPlus ? ParsedAttr::AS_CXX11 : ParsedAttr::AS_C2x);
+          getLangOpts().CPlusPlus ? ParsedAttr::Form::CXX11()
+                                  : ParsedAttr::Form::C2x());
       AttrParsed = true;
     }
 
@@ -4715,7 +4716,7 @@ void Parser::ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs) {
   if (!T.consumeClose()) {
     Attrs.addNew(UuidIdent, SourceRange(UuidLoc, T.getCloseLocation()), nullptr,
                  SourceLocation(), ArgExprs.data(), ArgExprs.size(),
-                 ParsedAttr::AS_Microsoft);
+                 ParsedAttr::Form::Microsoft());
   }
 }
 
@@ -4771,7 +4772,7 @@ void Parser::ParseMicrosoftAttributes(ParsedAttributes &Attrs) {
           }
           if (!AttrParsed) {
             Attrs.addNew(II, NameLoc, nullptr, SourceLocation(), nullptr, 0,
-                         ParsedAttr::AS_Microsoft);
+                         ParsedAttr::Form::Microsoft());
           }
         }
       }
index ebda84d..4fc6a22 100644 (file)
@@ -196,5 +196,5 @@ void Parser::ParseHLSLSemantics(ParsedAttributes &Attrs,
   }
 
   Attrs.addNew(II, Loc, nullptr, SourceLocation(), ArgExprs.data(),
-               ArgExprs.size(), ParsedAttr::AS_HLSLSemantic);
+               ArgExprs.size(), ParsedAttr::Form::HLSLSemantic());
 }
index 079bf9a..b21adb1 100644 (file)
@@ -408,7 +408,7 @@ static void addContextSensitiveTypeNullability(Parser &P,
   auto getNullabilityAttr = [&](AttributePool &Pool) -> ParsedAttr * {
     return Pool.create(P.getNullabilityKeyword(nullability),
                        SourceRange(nullabilityLoc), nullptr, SourceLocation(),
-                       nullptr, 0, ParsedAttr::AS_ContextSensitiveKeyword);
+                       nullptr, 0, ParsedAttr::Form::ContextSensitiveKeyword());
   };
 
   if (D.getNumTypeObjects() > 0) {
index 4c7ca8f..31d597a 100644 (file)
@@ -1850,11 +1850,12 @@ void Parser::HandlePragmaAttribute() {
 
       if (Tok.isNot(tok::l_paren))
         Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
-                     ParsedAttr::AS_GNU);
+                     ParsedAttr::Form::GNU());
       else
         ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, /*EndLoc=*/nullptr,
                               /*ScopeName=*/nullptr,
-                              /*ScopeLoc=*/SourceLocation(), ParsedAttr::AS_GNU,
+                              /*ScopeLoc=*/SourceLocation(),
+                              ParsedAttr::Form::GNU(),
                               /*Declarator=*/nullptr);
     } while (TryConsumeToken(tok::comma));
 
index b6b87e3..c02ad90 100644 (file)
@@ -2411,7 +2411,7 @@ StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
                             ArgsUnion(Hint.ValueExpr)};
     TempAttrs.addNew(Hint.PragmaNameLoc->Ident, Hint.Range, nullptr,
                      Hint.PragmaNameLoc->Loc, ArgHints, 4,
-                     ParsedAttr::AS_Pragma);
+                     ParsedAttr::Form::Pragma());
   }
 
   // Get the next statement.
index 46915c8..6dadf01 100644 (file)
@@ -860,7 +860,7 @@ void Sema::AddCFAuditedAttribute(Decl *D) {
     return;
 
   AttributeCommonInfo Info(Ident, SourceRange(Loc),
-                           AttributeCommonInfo::AS_Pragma);
+                           AttributeCommonInfo::Form::Pragma());
   D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Info));
 }
 
index 714456d..cc5edef 100644 (file)
@@ -19862,7 +19862,7 @@ void Sema::ActOnPragmaRedefineExtname(IdentifierInfo* Name,
   NamedDecl *PrevDecl = LookupSingleName(TUScope, Name, NameLoc,
                                          LookupOrdinaryName);
   AttributeCommonInfo Info(AliasName, SourceRange(AliasNameLoc),
-                           AttributeCommonInfo::AS_Pragma);
+                           AttributeCommonInfo::Form::Pragma());
   AsmLabelAttr *Attr = AsmLabelAttr::CreateImplicit(
       Context, AliasName->getName(), /*IsLiteralLabel=*/true, Info);
 
index 8a7c31a..3f798ad 100644 (file)
@@ -4893,12 +4893,12 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
 
     // If we're supposed to infer nullability, do so now.
     if (inferNullability && !inferNullabilityInnerOnlyComplete) {
-      ParsedAttr::Syntax syntax = inferNullabilityCS
-                                      ? ParsedAttr::AS_ContextSensitiveKeyword
-                                      : ParsedAttr::AS_Keyword;
+      ParsedAttr::Form form = inferNullabilityCS
+                                  ? ParsedAttr::Form::ContextSensitiveKeyword()
+                                  : ParsedAttr::Form::Keyword();
       ParsedAttr *nullabilityAttr = Pool.create(
           S.getNullabilityKeyword(*inferNullability), SourceRange(pointerLoc),
-          nullptr, SourceLocation(), nullptr, 0, syntax);
+          nullptr, SourceLocation(), nullptr, 0, form);
 
       attrs.addAtEnd(nullabilityAttr);
 
@@ -6014,7 +6014,7 @@ static void transferARCOwnershipToDeclaratorChunk(TypeProcessingState &state,
   ParsedAttr *attr = D.getAttributePool().create(
       &S.Context.Idents.get("objc_ownership"), SourceLocation(),
       /*scope*/ nullptr, SourceLocation(),
-      /*args*/ &Args, 1, ParsedAttr::AS_GNU);
+      /*args*/ &Args, 1, ParsedAttr::Form::GNU());
   chunk.getAttrs().addAtEnd(attr);
   // TODO: mark whether we did this inference?
 }
index 177d72f..d094e8b 100644 (file)
@@ -2621,7 +2621,7 @@ static void emitAttributes(RecordKeeper &Records, raw_ostream &OS,
         OS << "NoSemaHandlerAttribute";
 
       if (Spellings.size() == 0) {
-        OS << ", AttributeCommonInfo::AS_Implicit";
+        OS << ", AttributeCommonInfo::Form::Implicit()";
       } else if (Spellings.size() == 1) {
         OS << ", ";
         emitFormInitializer(OS, Spellings[0], "0");