[clang] 9711118 - Rework the way statement attributes are processed; NFC
Aaron Ballman via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 5 14:52:32 PDT 2021
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.
More information about the cfe-commits
mailing list