[clang] [llvm] [LLVM][Clang][AArch64] Implement AArch64 build attributes (PR #118771)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 13 10:25:03 PST 2025


================
@@ -7806,6 +7815,261 @@ bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(SMLoc L, bool Paired,
   return false;
 }
 
+bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) {
+  // Expecting 3 AsmToken::Identifier after '.aeabi_subsection', a name and 2
+  // parameters, e.g.: .aeabi_subsection (1)aeabi_feature_and_bits, (2)optional,
+  // (3)uleb128 separated by 2 commas.
+  MCAsmParser &Parser = getParser();
+
+  bool HasActiveSubsection = true;
+  std::unique_ptr<MCELFStreamer::AttributeSubSection> ActiveSubsection =
+      getTargetStreamer().getActiveAtributesSubsection();
+  if (nullptr == ActiveSubsection) {
+    HasActiveSubsection = false;
+  }
+
+  // Consume the name (subsection name)
+  StringRef SubsectionName;
+  AArch64BuildAttributes::VendorID SubsectionNameID;
+  if (Parser.getTok().is(AsmToken::Identifier)) {
+    SubsectionName = Parser.getTok().getIdentifier();
+    SubsectionNameID = AArch64BuildAttributes::getVendorID(SubsectionName);
+  } else {
+    Error(Parser.getTok().getLoc(), "Expecting subsection name");
+    return true;
+  }
+  Parser.Lex();
+  // consume a comma
+  // parseComma() return *false* on success, and call Lex(), no need to call
+  // Lex() again.
+  if (Parser.parseComma()) {
+    return true;
+  }
+
+  // Consume the first parameter (optionality parameter)
+  AArch64BuildAttributes::SubsectionOptional IsOptional;
+  // options: optional/required
+  if (Parser.getTok().is(AsmToken::Identifier)) {
+    StringRef Optinality = Parser.getTok().getIdentifier();
+    IsOptional = AArch64BuildAttributes::getOptionalID(Optinality);
+    if (AArch64BuildAttributes::OPTIONAL_NOT_FOUND == IsOptional) {
+      Error(Parser.getTok().getLoc(),
+            AArch64BuildAttributes::getSubsectionOptionalUnknownError() + ": " +
+                Optinality);
+      return true;
+    }
+    if (HasActiveSubsection &&
+        (SubsectionName == ActiveSubsection->VendorName)) {
+      if (IsOptional != ActiveSubsection->IsOptional) {
+        Error(Parser.getTok().getLoc(),
+              "Optinality mismatch! Subsection " + SubsectionName +
+                  " allready exists with optinality defined as '" +
+                  Twine(ActiveSubsection->IsOptional) + "' and not '" +
+                  Twine(IsOptional) + "'! (0: required, 1: optional)");
+        return true;
+      }
+    }
+  } else {
+    Error(
+        Parser.getTok().getLoc(),
+        "Expecitng optionality parameter \n Hint: use 'optional' | 'required'");
+    return true;
+  }
+  // Check for possible IsOptional unaccepted values for known subsections
+  if (AArch64BuildAttributes::AEABI_FEATURE_AND_BITS == SubsectionNameID) {
+    if (AArch64BuildAttributes::REQUIRED == IsOptional) {
+      Error(Parser.getTok().getLoc(),
+            "aeabi_feature_and_bits must be marked as optional");
+      return true;
+    }
+  }
+  if (AArch64BuildAttributes::AEABI_PAUTHABI == SubsectionNameID) {
+    if (AArch64BuildAttributes::OPTIONAL == IsOptional) {
+      Error(Parser.getTok().getLoc(),
+            "aeabi_pauthabi must be marked as required");
+      return true;
+    }
+  }
+  Parser.Lex();
+  // consume a comma
+  if (Parser.parseComma()) {
+    return true;
+  }
+
+  // Consume the second parameter (type parameter)
+  AArch64BuildAttributes::SubsectionType Type;
+  if (Parser.getTok().is(AsmToken::Identifier)) {
+    StringRef Name = Parser.getTok().getIdentifier();
+    Type = AArch64BuildAttributes::getTypeID(Name);
+    if (AArch64BuildAttributes::TYPE_NOT_FOUND == Type) {
+      Error(Parser.getTok().getLoc(),
+            AArch64BuildAttributes::getSubsectionTypeUnknownError() + ": " +
+                Name);
+      return true;
+    }
+    if (HasActiveSubsection &&
+        (SubsectionName == ActiveSubsection->VendorName)) {
+      if (Type != ActiveSubsection->ParameterType) {
+        Error(Parser.getTok().getLoc(),
+              "Type mismatch! Subsection " + SubsectionName +
+                  " allready exists with Type defined as '" +
+                  Twine(ActiveSubsection->ParameterType) + "' and not '" +
+                  Twine(Type) + "'! (0: uleb128, 1: ntbs)");
+        return true;
+      }
+    }
+  } else {
+    Error(Parser.getTok().getLoc(), "Expecitng type parameter");
+    return true;
+  }
+  // Check for possible Type unaccepted values for known subsections
+  if (AArch64BuildAttributes::AEABI_FEATURE_AND_BITS == SubsectionNameID ||
+      AArch64BuildAttributes::AEABI_PAUTHABI == SubsectionNameID) {
+    if (AArch64BuildAttributes::NTBS == Type) {
+      Error(Parser.getTok().getLoc(),
+            SubsectionName + " must be marked as ULEB128");
+      return true;
+    }
+  }
+  Parser.Lex();
+  // Parsing finished, check for trailing tokens.
+  if (Parser.getTok().isNot(llvm::AsmToken::EndOfStatement)) {
+    Error(Parser.getTok().getLoc(), "unexpected token for AArch64 build "
+                                    "attributes subsection header directive");
+    return true;
+  }
+
+  getTargetStreamer().emitAtributesSubsection(SubsectionName, IsOptional, Type);
+
+  return false;
+}
+
+bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
+  // Expecting 2 Tokens: after '.aeabi_attribute', e.g.:
+  // .aeabi_attribute	(1)Tag_Feature_BTI, (2)[uleb128|ntbs]
+  // separated by a comma.
+  MCAsmParser &Parser = getParser();
+
+  std::unique_ptr<MCELFStreamer::AttributeSubSection> ActiveSubsection =
+      getTargetStreamer().getActiveAtributesSubsection();
+  if (nullptr == ActiveSubsection) {
+    Error(Parser.getTok().getLoc(),
----------------
sivan-shani wrote:

test case added

https://github.com/llvm/llvm-project/pull/118771


More information about the llvm-commits mailing list