Author: Aaron Ballman Date: 2021-04-05T17:52:17-04:00 New Revision: 9711118d2edf7aed133616de1eb7f633c263c4b5
URL: https://github.com/llvm/llvm-project/commit/9711118d2edf7aed133616de1eb7f633c263c4b5 DIFF: https://github.com/llvm/llvm-project/commit/9711118d2edf7aed133616de1eb7f633c263c4b5.diff LOG: Rework the way statement attributes are processed; NFC This changes our approach to processing statement attributes to be more similar to how we process declaration attributes. Namely, ActOnAttributedStmt() now calls ProcessStmtAttributes() instead of vice-versa, and there is now an interface split between building an attributed statement where you already have a list of semantic attributes and building an attributed statement with attributes from the parser. This should make it easier to support statement attributes that are dependent on a template. In that case, you would add a TransformFooAttr() function in TreeTransform.h to perform the semantic checking (morally similar to how Sema::InstantiateAttrs() already works for declaration attributes) when transforming the semantic attribute at instantiation time. Added: Modified: clang/include/clang/Sema/Sema.h clang/lib/Parse/ParseStmt.cpp clang/lib/Sema/SemaStmt.cpp clang/lib/Sema/SemaStmtAttr.cpp clang/lib/Sema/TreeTransform.h Removed: ################################################################################ diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 8f6e6baaea62..b8029b670747 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -4296,10 +4296,11 @@ class Sema final { /// Valid types should not have multiple attributes with diff erent CCs. const AttributedType *getCallingConvAttributedType(QualType T) const; - /// Stmt attributes - this routine is the top level dispatcher. - StmtResult ProcessStmtAttributes(Stmt *Stmt, - const ParsedAttributesView &Attrs, - SourceRange Range); + /// Process the attributes before creating an attributed statement. Returns + /// the semantic attributes that have been processed. + void ProcessStmtAttributes(Stmt *Stmt, + const ParsedAttributesWithRange &InAttrs, + SmallVectorImpl<const Attr *> &OutAttrs); void WarnConflictingTypedMethods(ObjCMethodDecl *Method, ObjCMethodDecl *MethodDecl, @@ -4638,8 +4639,9 @@ class Sema final { StmtResult ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl, SourceLocation ColonLoc, Stmt *SubStmt); - StmtResult ActOnAttributedStmt(SourceLocation AttrLoc, - ArrayRef<const Attr*> Attrs, + StmtResult BuildAttributedStmt(SourceLocation AttrsLoc, + ArrayRef<const Attr *> Attrs, Stmt *SubStmt); + StmtResult ActOnAttributedStmt(const ParsedAttributesWithRange &AttrList, Stmt *SubStmt); class ConditionResult; diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index bcda3560ce63..d4863d1e3abd 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -120,7 +120,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, if (Attrs.empty() || Res.isInvalid()) return Res; - return Actions.ProcessStmtAttributes(Res.get(), Attrs, Attrs.Range); + return Actions.ActOnAttributedStmt(Attrs, Res.get()); } namespace { @@ -657,8 +657,7 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs, SubStmt = ParseStatementOrDeclarationAfterAttributes(Stmts, StmtCtx, nullptr, TempAttrs); if (!TempAttrs.empty() && !SubStmt.isInvalid()) - SubStmt = Actions.ProcessStmtAttributes(SubStmt.get(), TempAttrs, - TempAttrs.Range); + SubStmt = Actions.ActOnAttributedStmt(TempAttrs, SubStmt.get()); } else { Diag(Tok, diag::err_expected_after) << "__attribute__" << tok::semi; } @@ -1144,7 +1143,7 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { ExpectAndConsumeSemi(diag::err_expected_semi_after_expr); R = handleExprStmt(Res, SubStmtCtx); if (R.isUsable()) - R = Actions.ProcessStmtAttributes(R.get(), attrs, attrs.Range); + R = Actions.ActOnAttributedStmt(attrs, R.get()); } } diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index ceba83bcd814..174679a14f24 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -555,12 +555,22 @@ Sema::ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl, return LS; } -StmtResult Sema::ActOnAttributedStmt(SourceLocation AttrLoc, - ArrayRef<const Attr*> Attrs, +StmtResult Sema::BuildAttributedStmt(SourceLocation AttrsLoc, + ArrayRef<const Attr *> Attrs, Stmt *SubStmt) { - // Fill in the declaration and return it. - AttributedStmt *LS = AttributedStmt::Create(Context, AttrLoc, Attrs, SubStmt); - return LS; + return AttributedStmt::Create(Context, AttrsLoc, Attrs, SubStmt); +} + +StmtResult Sema::ActOnAttributedStmt(const ParsedAttributesWithRange &Attrs, + Stmt *SubStmt) { + SmallVector<const Attr *, 1> SemanticAttrs; + ProcessStmtAttributes(SubStmt, Attrs, SemanticAttrs); + if (!SemanticAttrs.empty()) + return BuildAttributedStmt(Attrs.Range.getBegin(), SemanticAttrs, SubStmt); + // If none of the attributes applied, that's fine, we can recover by + // returning the substatement directly instead of making an AttributedStmt + // with no attributes on it. + return SubStmt; } namespace { diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index 39c684cbd6da..f914f1273f71 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -413,19 +413,13 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A, } } -StmtResult Sema::ProcessStmtAttributes(Stmt *S, - const ParsedAttributesView &AttrList, - SourceRange Range) { - SmallVector<const Attr*, 8> Attrs; - for (const ParsedAttr &AL : AttrList) { - if (Attr *a = ProcessStmtAttribute(*this, S, AL, Range)) - Attrs.push_back(a); +void Sema::ProcessStmtAttributes(Stmt *S, + const ParsedAttributesWithRange &InAttrs, + SmallVectorImpl<const Attr *> &OutAttrs) { + for (const ParsedAttr &AL : InAttrs) { + if (const Attr *A = ProcessStmtAttribute(*this, S, AL, InAttrs.Range)) + OutAttrs.push_back(A); } - CheckForIncompatibleAttributes(*this, Attrs); - - if (Attrs.empty()) - return S; - - return ActOnAttributedStmt(Range.getBegin(), Attrs, S); + CheckForIncompatibleAttributes(*this, OutAttrs); } diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index b5080c6ef5a1..cbc91561d6ed 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1311,9 +1311,9 @@ class TreeTransform { /// By default, performs semantic analysis to build the new statement. /// Subclasses may override this routine to provide diff erent behavior. StmtResult RebuildAttributedStmt(SourceLocation AttrLoc, - ArrayRef<const Attr*> Attrs, + ArrayRef<const Attr *> Attrs, Stmt *SubStmt) { - return SemaRef.ActOnAttributedStmt(AttrLoc, Attrs, SubStmt); + return SemaRef.BuildAttributedStmt(AttrLoc, Attrs, SubStmt); } /// Build a new "if" statement. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits