llvm/clang/utils/TableGen/ClangAttrEmitter.cpp

//===- ClangAttrEmitter.cpp - Generate Clang attribute handling =-*- C++ -*--=//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// These tablegen backends emit Clang attribute processing code
//
//===----------------------------------------------------------------------===//

#include "TableGenBackends.h"
#include "ASTTableGen.h"

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/StringMatcher.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstddef>
#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

usingnamespacellvm;

namespace {

class FlattenedSpelling {};

struct FlattenedSpellingInfo {};
FSIVecTy;

} // end anonymous namespace

static bool GenerateTargetSpecificAttrChecks(const Record *R,
                                             std::vector<StringRef> &Arches,
                                             std::string &Test,
                                             std::string *FnName);
static bool isStringLiteralArgument(const Record *Arg);
static bool isVariadicStringLiteralArgument(const Record *Arg);

static std::vector<FlattenedSpelling>
GetFlattenedSpellings(const Record &Attr) {}

static std::string ReadPCHRecord(StringRef type) {}

// Get a type that is suitable for storing an object of the specified type.
static StringRef getStorageType(StringRef type) {}

// Assumes that the way to get the value is SA->getname()
static std::string WritePCHRecord(StringRef type, StringRef name) {}

// Normalize attribute name by removing leading and trailing
// underscores. For example, __foo, foo__, __foo__ would
// become foo.
static StringRef NormalizeAttrName(StringRef AttrName) {}

// Normalize the name by removing any and all leading and trailing underscores.
// This is different from NormalizeAttrName in that it also handles names like
// _pascal and __pascal.
static StringRef NormalizeNameForSpellingComparison(StringRef Name) {}

// Normalize the spelling of a GNU attribute (i.e. "x" in "__attribute__((x))"),
// removing "__" if it appears at the beginning and end of the attribute's name.
static StringRef NormalizeGNUAttrSpelling(StringRef AttrSpelling) {}

ParsedAttrMap;

static ParsedAttrMap getParsedAttrList(const RecordKeeper &Records,
                                       ParsedAttrMap *Dupes = nullptr,
                                       bool SemaOnly = true) {}

namespace {

  class Argument {};

  class SimpleArgument : public Argument {};

  class DefaultSimpleArgument : public SimpleArgument {};

  class StringArgument : public Argument {};

  class AlignedArgument : public Argument {};

  class VariadicArgument : public Argument {};

  class VariadicOMPInteropInfoArgument : public VariadicArgument {};

  class VariadicParamIdxArgument : public VariadicArgument {};

  struct VariadicParamOrParamIdxArgument : public VariadicArgument {};

  // Unique the enums, but maintain the original declaration ordering.
  std::vector<StringRef>
  uniqueEnumsInOrder(const std::vector<StringRef> &enums) {}

  class EnumArgument : public Argument {};

  class VariadicEnumArgument: public VariadicArgument {};

  class VersionArgument : public Argument {};

  class ExprArgument : public SimpleArgument {};

  class VariadicExprArgument : public VariadicArgument {};

  class VariadicIdentifierArgument : public VariadicArgument {};

  class VariadicStringArgument : public VariadicArgument {};

  class TypeArgument : public SimpleArgument {};

  class WrappedAttr : public SimpleArgument {};

  } // end anonymous namespace

static std::unique_ptr<Argument>
createArgument(const Record &Arg, StringRef Attr,
               const Record *Search = nullptr) {}

static void writeAvailabilityValue(raw_ostream &OS) {}

static void writeDeprecatedAttrValue(raw_ostream &OS, std::string &Variety) {}

static void writeGetSpellingFunction(const Record &R, raw_ostream &OS) {}

static void
writePrettyPrintFunction(const Record &R,
                         const std::vector<std::unique_ptr<Argument>> &Args,
                         raw_ostream &OS) {}

/// Return the index of a spelling in a spelling list.
static unsigned
getSpellingListIndex(const std::vector<FlattenedSpelling> &SpellingList,
                     const FlattenedSpelling &Spelling) {}

static void writeAttrAccessorDefinition(const Record &R, raw_ostream &OS) {}

static bool
SpellingNamesAreCommon(const std::vector<FlattenedSpelling>& Spellings) {}

SemanticSpellingMap;
static std::string
CreateSemanticSpellings(const std::vector<FlattenedSpelling> &Spellings,
                        SemanticSpellingMap &Map) {}

void WriteSemanticSpellingSwitch(const std::string &VarName,
                                 const SemanticSpellingMap &Map,
                                 raw_ostream &OS) {}

// Note: these values need to match the values used by LateAttrParseKind in
// `Attr.td`
enum class LateAttrParseKind {};

static LateAttrParseKind getLateAttrParseKind(const Record *Attr) {}

// Emits the LateParsed property for attributes.
static void emitClangAttrLateParsedListImpl(const RecordKeeper &Records,
                                            raw_ostream &OS,
                                            LateAttrParseKind LateParseMode) {}

static void emitClangAttrLateParsedList(const RecordKeeper &Records,
                                        raw_ostream &OS) {}

static void emitClangAttrLateParsedExperimentalList(const RecordKeeper &Records,
                                                    raw_ostream &OS) {}

static bool hasGNUorCXX11Spelling(const Record &Attribute) {}

namespace {

struct AttributeSubjectMatchRule {};

const char *AttributeSubjectMatchRule::EnumName =;

struct PragmaClangAttributeSupport {};

} // end anonymous namespace

static bool isSupportedPragmaClangAttributeSubject(const Record &Subject) {}

static bool doesDeclDeriveFrom(const Record *D, const Record *Base) {}

PragmaClangAttributeSupport::PragmaClangAttributeSupport(
    const RecordKeeper &Records) {}

static PragmaClangAttributeSupport &
getPragmaAttributeSupport(const RecordKeeper &Records) {}

void PragmaClangAttributeSupport::emitMatchRuleList(raw_ostream &OS) {}

bool PragmaClangAttributeSupport::isAttributedSupported(
    const Record &Attribute) {}

static std::string GenerateTestExpression(ArrayRef<const Record *> LangOpts) {}

void
PragmaClangAttributeSupport::generateStrictConformsTo(const Record &Attr,
                                                      raw_ostream &OS) {}

void PragmaClangAttributeSupport::generateParsingHelpers(raw_ostream &OS) {}

template <typename Fn> static void forEachSpelling(const Record &Attr, Fn &&F) {}

std::map<std::string, std::vector<const Record *>> NameToAttrsMap;

/// Build a map from the attribute name to the Attrs that use that name. If more
/// than one Attr use a name, the arguments could be different so a more complex
/// check is needed in the generated switch.
void generateNameToAttrsMap(const RecordKeeper &Records) {}

/// Generate the info needed to produce the case values in case more than one
/// attribute has the same name. Store the info in a map that can be processed
/// after all attributes are seen.
static void generateFlattenedSpellingInfo(const Record &Attr,
                                          std::map<std::string, FSIVecTy> &Map,
                                          uint32_t ArgMask = 0) {}

static bool nameAppliesToOneAttribute(std::string Name) {}

static bool emitIfSimpleValue(std::string Name, uint32_t ArgMask,
                              raw_ostream &OS) {}

static void emitSingleCondition(const FlattenedSpellingInfo &FSI,
                                raw_ostream &OS) {}

static void emitStringSwitchCases(std::map<std::string, FSIVecTy> &Map,
                                  raw_ostream &OS) {}

static bool isTypeArgument(const Record *Arg) {}

/// Emits the first-argument-is-type property for attributes.
static void emitClangAttrTypeArgList(const RecordKeeper &Records,
                                     raw_ostream &OS) {}

/// Emits the parse-arguments-in-unevaluated-context property for
/// attributes.
static void emitClangAttrArgContextList(const RecordKeeper &Records,
                                        raw_ostream &OS) {}

static bool isIdentifierArgument(const Record *Arg) {}

static bool isVariadicIdentifierArgument(const Record *Arg) {}

static bool isVariadicExprArgument(const Record *Arg) {}

static bool isStringLiteralArgument(const Record *Arg) {}

static bool isVariadicStringLiteralArgument(const Record *Arg) {}

static void emitClangAttrVariadicIdentifierArgList(const RecordKeeper &Records,
                                                   raw_ostream &OS) {}

// Emits the list of arguments that should be parsed as unevaluated string
// literals for each attribute.
static void
emitClangAttrUnevaluatedStringLiteralList(const RecordKeeper &Records,
                                          raw_ostream &OS) {}

// Emits the first-argument-is-identifier property for attributes.
static void emitClangAttrIdentifierArgList(const RecordKeeper &Records,
                                           raw_ostream &OS) {}

// Emits the list for attributes having StrictEnumParameters.
static void emitClangAttrStrictIdentifierArgList(const RecordKeeper &Records,
                                                 raw_ostream &OS) {}

static bool keywordThisIsaIdentifierInArgument(const Record *Arg) {}

static void emitClangAttrThisIsaIdentifierArgList(const RecordKeeper &Records,
                                                  raw_ostream &OS) {}

static void emitClangAttrAcceptsExprPack(const RecordKeeper &Records,
                                         raw_ostream &OS) {}

static bool isRegularKeywordAttribute(const FlattenedSpelling &S) {}

static void emitFormInitializer(raw_ostream &OS,
                                const FlattenedSpelling &Spelling,
                                StringRef SpellingIndex) {}

static void emitAttributes(const RecordKeeper &Records, raw_ostream &OS,
                           bool Header) {}
// Emits the class definitions for attributes.
void clang::EmitClangAttrClass(const RecordKeeper &Records, raw_ostream &OS) {}

// Emits the class method definitions for attributes.
void clang::EmitClangAttrImpl(const RecordKeeper &Records, raw_ostream &OS) {}

static void emitAttrList(raw_ostream &OS, StringRef Class,
                         ArrayRef<const Record *> AttrList) {}

// Determines if an attribute has a Pragma spelling.
static bool AttrHasPragmaSpelling(const Record *R) {}

namespace {

  struct AttrClassDescriptor {};

} // end anonymous namespace

static const AttrClassDescriptor AttrClassDescriptors[] =;

static void emitDefaultDefine(raw_ostream &OS, StringRef name,
                              const char *superName) {}

namespace {

  /// A class of attributes.
  struct AttrClass {};

  /// The entire hierarchy of attribute classes.
  class AttrClassHierarchy {};

} // end anonymous namespace

namespace clang {

// Emits the enumeration list for attributes.
void EmitClangAttrList(const RecordKeeper &Records, raw_ostream &OS) {}

// Emits the enumeration list for attributes.
void EmitClangAttrSubjectMatchRuleList(const RecordKeeper &Records,
                                       raw_ostream &OS) {}

// Emits the code to read an attribute from a precompiled header.
void EmitClangAttrPCHRead(const RecordKeeper &Records, raw_ostream &OS) {}

// Emits the code to write an attribute to a precompiled header.
void EmitClangAttrPCHWrite(const RecordKeeper &Records, raw_ostream &OS) {}

} // namespace clang

// Helper function for GenerateTargetSpecificAttrChecks that alters the 'Test'
// parameter with only a single check type, if applicable.
static bool GenerateTargetSpecificAttrCheck(const Record *R, std::string &Test,
                                            std::string *FnName,
                                            StringRef ListName,
                                            StringRef CheckAgainst,
                                            StringRef Scope) {}

// Generate a conditional expression to check if the current target satisfies
// the conditions for a TargetSpecificAttr record, and append the code for
// those checks to the Test string. If the FnName string pointer is non-null,
// append a unique suffix to distinguish this set of target checks from other
// TargetSpecificAttr records.
static bool GenerateTargetSpecificAttrChecks(const Record *R,
                                             std::vector<StringRef> &Arches,
                                             std::string &Test,
                                             std::string *FnName) {}

static void GenerateHasAttrSpellingStringSwitch(
    const std::vector<std::pair<const Record *, FlattenedSpelling>> &Attrs,
    raw_ostream &OS, const std::string &Variety,
    const std::string &Scope = "") {}

namespace clang {

// Emits list of regular keyword attributes with info about their arguments.
void EmitClangRegularKeywordAttributeInfo(const RecordKeeper &Records,
                                          raw_ostream &OS) {}

// Emits the list of spellings for attributes.
void EmitClangAttrHasAttrImpl(const RecordKeeper &Records, raw_ostream &OS) {}

void EmitClangAttrSpellingListIndex(const RecordKeeper &Records,
                                    raw_ostream &OS) {}

// Emits code used by RecursiveASTVisitor to visit attributes
void EmitClangAttrASTVisitor(const RecordKeeper &Records, raw_ostream &OS) {}

void EmitClangAttrTemplateInstantiateHelper(ArrayRef<const Record *> Attrs,
                                            raw_ostream &OS,
                                            bool AppliesToDecl) {}

// Emits code to instantiate dependent attributes on templates.
void EmitClangAttrTemplateInstantiate(const RecordKeeper &Records,
                                      raw_ostream &OS) {}

// Emits the list of parsed attributes.
void EmitClangAttrParsedAttrList(const RecordKeeper &Records, raw_ostream &OS) {}

static bool isArgVariadic(const Record &R, StringRef AttrName) {}

static void emitArgInfo(const Record &R, raw_ostream &OS) {}

static std::string GetDiagnosticSpelling(const Record &R) {}

static std::string CalculateDiagnostic(const Record &S) {}

static std::string GetSubjectWithSuffix(const Record *R) {}

static std::string functionNameForCustomAppertainsTo(const Record &Subject) {}

static void GenerateCustomAppertainsTo(const Record &Subject, raw_ostream &OS) {}

static void GenerateAppertainsTo(const Record &Attr, raw_ostream &OS) {}

// Generates the mutual exclusion checks. The checks for parsed attributes are
// written into OS and the checks for merging declaration attributes are
// written into MergeOS.
static void GenerateMutualExclusionsChecks(const Record &Attr,
                                           const RecordKeeper &Records,
                                           raw_ostream &OS,
                                           raw_ostream &MergeDeclOS,
                                           raw_ostream &MergeStmtOS) {}

static void
emitAttributeMatchRules(PragmaClangAttributeSupport &PragmaAttributeSupport,
                        raw_ostream &OS) {}

static void GenerateLangOptRequirements(const Record &R,
                                        raw_ostream &OS) {}

static void GenerateTargetRequirements(const Record &Attr,
                                       const ParsedAttrMap &Dupes,
                                       raw_ostream &OS) {}

static void
GenerateSpellingTargetRequirements(const Record &Attr,
                                   ArrayRef<const Record *> TargetSpellings,
                                   raw_ostream &OS) {}

static void GenerateSpellingIndexToSemanticSpelling(const Record &Attr,
                                                    raw_ostream &OS) {}

static void GenerateHandleDeclAttribute(const Record &Attr, raw_ostream &OS) {}

static bool isParamExpr(const Record *Arg) {}

void GenerateIsParamExpr(const Record &Attr, raw_ostream &OS) {}

void GenerateHandleAttrWithDelayedArgs(const RecordKeeper &Records,
                                       raw_ostream &OS) {}

static bool IsKnownToGCC(const Record &Attr) {}

/// Emits the parsed attribute helpers
void EmitClangAttrParsedAttrImpl(const RecordKeeper &Records, raw_ostream &OS) {}

// Emits the kind list of parsed attributes
void EmitClangAttrParsedAttrKinds(const RecordKeeper &Records,
                                  raw_ostream &OS) {}

// Emits the code to dump an attribute.
void EmitClangAttrTextNodeDump(const RecordKeeper &Records, raw_ostream &OS) {}

void EmitClangAttrNodeTraverse(const RecordKeeper &Records, raw_ostream &OS) {}

void EmitClangAttrParserStringSwitches(const RecordKeeper &Records,
                                       raw_ostream &OS) {}

void EmitClangAttrSubjectMatchRulesParserStringSwitches(
    const RecordKeeper &Records, raw_ostream &OS) {}

void EmitClangAttrDocTable(const RecordKeeper &Records, raw_ostream &OS) {}

enum class SpellingKind : size_t {};
static const size_t NumSpellingKinds =;

class SpellingList {};

class DocumentationData {};

static void WriteCategoryHeader(const Record *DocCategory,
                                raw_ostream &OS) {}

static std::pair<std::string, SpellingList>
GetAttributeHeadingAndSpellings(const Record &Documentation,
                                const Record &Attribute,
                                StringRef Cat) {}

static void WriteDocumentation(const RecordKeeper &Records,
                               const DocumentationData &Doc, raw_ostream &OS) {}

void EmitClangAttrDocs(const RecordKeeper &Records, raw_ostream &OS) {}

void EmitTestPragmaAttributeSupportedAttributes(const RecordKeeper &Records,
                                                raw_ostream &OS) {}

} // end namespace clang