|
10 | 10 | // |
11 | 11 | //===----------------------------------------------------------------------===// |
12 | 12 |
|
| 13 | +#include "clang/AST/APValue.h" |
13 | 14 | #include "clang/AST/ASTConsumer.h" |
14 | 15 | #include "clang/AST/ASTContext.h" |
15 | 16 | #include "clang/AST/ASTMutationListener.h" |
|
58 | 59 | #include "clang/Sema/SemaSwift.h" |
59 | 60 | #include "clang/Sema/SemaWasm.h" |
60 | 61 | #include "clang/Sema/SemaX86.h" |
| 62 | +#include "llvm/ADT/APSInt.h" |
61 | 63 | #include "llvm/ADT/STLExtras.h" |
62 | 64 | #include "llvm/ADT/StringExtras.h" |
63 | 65 | #include "llvm/Demangle/Demangle.h" |
@@ -2156,29 +2158,51 @@ static void handleUnusedAttr(Sema &S, Decl *D, const ParsedAttr &AL) { |
2156 | 2158 | D->addAttr(::new (S.Context) UnusedAttr(S.Context, AL)); |
2157 | 2159 | } |
2158 | 2160 |
|
| 2161 | +static ExprResult sharedGetConstructorDestructorAttrExpr(Sema &S, |
| 2162 | + const ParsedAttr &AL) { |
| 2163 | + // If no Expr node exists on the attribute, return a nullptr result (default |
| 2164 | + // priority to be used). If Expr node exists but is not valid, return an |
| 2165 | + // invalid result. Otherwise, return the Expr. |
| 2166 | + Expr *E = nullptr; |
| 2167 | + if (AL.getNumArgs() == 1) { |
| 2168 | + E = AL.getArgAsExpr(0); |
| 2169 | + if (E->isValueDependent()) { |
| 2170 | + if (!E->isTypeDependent() && !E->getType()->isIntegerType()) { |
| 2171 | + S.Diag(AL.getLoc(), diag::err_attribute_argument_type) |
| 2172 | + << AL << AANT_ArgumentIntegerConstant << E->getSourceRange(); |
| 2173 | + return ExprError(); |
| 2174 | + } |
| 2175 | + } else { |
| 2176 | + uint32_t priority; |
| 2177 | + if (!S.checkUInt32Argument(AL, AL.getArgAsExpr(0), priority)) { |
| 2178 | + return ExprError(); |
| 2179 | + } |
| 2180 | + return ConstantExpr::Create(S.Context, E, |
| 2181 | + APValue(llvm::APSInt::getUnsigned(priority))); |
| 2182 | + } |
| 2183 | + } |
| 2184 | + return E; |
| 2185 | +} |
| 2186 | + |
2159 | 2187 | static void handleConstructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) { |
2160 | | - uint32_t priority = ConstructorAttr::DefaultPriority; |
2161 | 2188 | if (S.getLangOpts().HLSL && AL.getNumArgs()) { |
2162 | 2189 | S.Diag(AL.getLoc(), diag::err_hlsl_init_priority_unsupported); |
2163 | 2190 | return; |
2164 | 2191 | } |
2165 | | - if (AL.getNumArgs() && |
2166 | | - !S.checkUInt32Argument(AL, AL.getArgAsExpr(0), priority)) |
| 2192 | + ExprResult E = sharedGetConstructorDestructorAttrExpr(S, AL); |
| 2193 | + if (E.isInvalid()) |
2167 | 2194 | return; |
2168 | 2195 | S.Diag(D->getLocation(), diag::warn_global_constructor) |
2169 | 2196 | << D->getSourceRange(); |
2170 | | - |
2171 | | - D->addAttr(::new (S.Context) ConstructorAttr(S.Context, AL, priority)); |
| 2197 | + D->addAttr(ConstructorAttr::Create(S.Context, E.get(), AL)); |
2172 | 2198 | } |
2173 | 2199 |
|
2174 | 2200 | static void handleDestructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) { |
2175 | | - uint32_t priority = DestructorAttr::DefaultPriority; |
2176 | | - if (AL.getNumArgs() && |
2177 | | - !S.checkUInt32Argument(AL, AL.getArgAsExpr(0), priority)) |
| 2201 | + ExprResult E = sharedGetConstructorDestructorAttrExpr(S, AL); |
| 2202 | + if (E.isInvalid()) |
2178 | 2203 | return; |
2179 | 2204 | S.Diag(D->getLocation(), diag::warn_global_destructor) << D->getSourceRange(); |
2180 | | - |
2181 | | - D->addAttr(::new (S.Context) DestructorAttr(S.Context, AL, priority)); |
| 2205 | + D->addAttr(DestructorAttr::Create(S.Context, E.get(), AL)); |
2182 | 2206 | } |
2183 | 2207 |
|
2184 | 2208 | template <typename AttrTy> |
|
0 commit comments