================
@@ -49,6 +49,135 @@ namespace clang {
   class Sema;
   class Declarator;
   struct TemplateIdAnnotation;
+  class Parser;
+
+  /// A set of tokens that has been cached for later parsing.
+  typedef SmallVector<Token, 4> CachedTokens;
+
+  /// [class.mem]p1: "... the class is regarded as complete within
+  /// - function bodies
+  /// - default arguments
+  /// - exception-specifications (TODO: C++0x)
+  /// - and brace-or-equal-initializers for non-static data members
+  /// (including such things in nested classes)."
+  /// LateParsedDeclarations build the tree of those elements so they can
+  /// be parsed after parsing the top-level class.
+  class LateParsedDeclaration {
+  public:
+    virtual ~LateParsedDeclaration();
+
+    virtual void ParseLexedMethodDeclarations();
+    virtual void ParseLexedMemberInitializers();
+    virtual void ParseLexedMethodDefs();
+    virtual void ParseLexedAttributes();
+    virtual void ParseLexedTypeAttributes();
+    virtual void ParseLexedPragmas();
+  };
+
+  /// Contains the lexed tokens of an attribute with arguments that
+  /// may reference member variables and so need to be parsed at the
+  /// end of the class declaration after parsing all other member
+  /// member declarations.
+  /// FIXME: Perhaps we should change the name of LateParsedDeclaration to
+  /// LateParsedTokens.
+  struct LateParsedAttribute : public LateParsedDeclaration {
+
+    enum LPA_Kind {
+      LPA_Declaration,
+      LPA_Type,
+    };
+
+    Parser *Self;
+    CachedTokens Toks;
+    IdentifierInfo &AttrName;
+    IdentifierInfo *MacroII = nullptr;
+    SourceLocation AttrNameLoc;
+    SmallVector<Decl *, 2> Decls;
+
+  private:
+    LPA_Kind Kind;
+
+  public:
+    explicit LateParsedAttribute(Parser *P, IdentifierInfo &Name,
+                                 SourceLocation Loc,
+                                 LPA_Kind Kind = LPA_Declaration)
+        : Self(P), AttrName(Name), AttrNameLoc(Loc), Kind(Kind) {}
+
+    void ParseLexedAttributes() override;
+
+    void addDecl(Decl *D) { Decls.push_back(D); }
+
+    LPA_Kind getKind() const { return Kind; }
+
+    // LLVM-style RTTI support
+    static bool classof(const LateParsedAttribute *LA) {
+      // LateParsedAttribute matches both Declaration and Type kinds
+      return LA->getKind() == LPA_Declaration || LA->getKind() == LPA_Type;
+    }
+  };
+
+  /// Contains the lexed tokens of an attribute with arguments that
+  /// may reference member variables and so need to be parsed at the
+  /// end of the class declaration after parsing all other member
+  /// member declarations.
+  /// FIXME: Perhaps we should change the name of LateParsedDeclaration to
+  /// LateParsedTokens.
+  struct LateParsedTypeAttribute : public LateParsedAttribute {
+
+    explicit LateParsedTypeAttribute(Parser *P, IdentifierInfo &Name,
+                                     SourceLocation Loc)
+        : LateParsedAttribute(P, Name, Loc, LPA_Type) {}
+
+    void ParseLexedAttributes() override;
+    void ParseLexedTypeAttributes() override;
+
+    /// Parse this late-parsed type attribute and store results in OutAttrs.
+    /// This method can be called from Sema during type transformation to
+    /// parse the cached tokens and produce the final attribute.
+    void ParseInto(ParsedAttributes &OutAttrs);
+
+    // LLVM-style RTTI support
+    static bool classof(const LateParsedAttribute *LA) {
+      return LA->getKind() == LPA_Type;
+    }
+  };
+
+  // A list of late-parsed attributes.  Used by ParseGNUAttributes.
+  class LateParsedAttrList : public SmallVector<LateParsedAttribute *, 2> {
+  public:
+    LateParsedAttrList(bool PSoon = false,
+                       bool LateAttrParseExperimentalExtOnly = false,
+                       bool LateAttrParseTypeAttrOnly = false)
+        : ParseSoon(PSoon),
+          LateAttrParseExperimentalExtOnly(LateAttrParseExperimentalExtOnly),
+          LateAttrParseTypeAttrOnly(LateAttrParseTypeAttrOnly) {}
+
+    bool parseSoon() { return ParseSoon; }
+    /// returns true iff the attribute to be parsed should only be late parsed
+    /// if it is annotated with `LateAttrParseExperimentalExt`
+    bool lateAttrParseExperimentalExtOnly() {
+      return LateAttrParseExperimentalExtOnly;
+    }
+
+    bool lateAttrParseTypeAttrOnly() { return LateAttrParseTypeAttrOnly; }
+
+    void takeTypeAttrsAppendingFrom(LateParsedAttrList &Other) {
+      auto it = std::remove_if(
----------------
zmodem wrote:

nit: move out-of-line?

https://github.com/llvm/llvm-project/pull/179612
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to