diff options
author | Christopher Di Bella <cjdb@google.com> | 2022-08-22 00:27:10 +0000 |
---|---|---|
committer | Christopher Di Bella <cjdb@google.com> | 2022-08-22 03:03:32 +0000 |
commit | e9ef45635b77598fc9ce0cd38d7d3f8c9d88a49d (patch) | |
tree | 8efe48cde4ea5365183924ac3cd27c962e29dd3f /clang/lib/Parse/ParseDecl.cpp | |
parent | d2d77e050b32ce3f917688aeeb9e6f8f3c209560 (diff) | |
download | llvm-e9ef45635b77598fc9ce0cd38d7d3f8c9d88a49d.zip llvm-e9ef45635b77598fc9ce0cd38d7d3f8c9d88a49d.tar.gz llvm-e9ef45635b77598fc9ce0cd38d7d3f8c9d88a49d.tar.bz2 |
[clang] adds unary type transformations as compiler built-ins
Adds
* `__add_lvalue_reference`
* `__add_pointer`
* `__add_rvalue_reference`
* `__decay`
* `__make_signed`
* `__make_unsigned`
* `__remove_all_extents`
* `__remove_extent`
* `__remove_const`
* `__remove_volatile`
* `__remove_cv`
* `__remove_pointer`
* `__remove_reference`
* `__remove_cvref`
These are all compiler built-in equivalents of the unary type traits
found in [[meta.trans]][1]. The compiler already has all of the
information it needs to answer these transformations, so we can skip
needing to make partial specialisations in standard library
implementations (we already do this for a lot of the query traits). This
will hopefully improve compile times, as we won't need use as much
memory in such a base part of the standard library.
[1]: http://wg21.link/meta.trans
Co-authored-by: zoecarver
Reviewed By: aaron.ballman, rsmith
Differential Revision: https://reviews.llvm.org/D116203
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 769809c..97a856a 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -3472,7 +3472,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // typedef-name case tok::kw___super: case tok::kw_decltype: - case tok::identifier: { + case tok::identifier: + ParseIdentifier: { // This identifier can only be a typedef name if we haven't already seen // a type-specifier. Without this check we misparse: // typedef int X; struct Y { short X; }; as 'short int'. @@ -3665,7 +3666,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, } } ConsumedEnd = Tok.getLocation(); - DS.setTypeofParensRange(Tracker.getRange()); + DS.setTypeArgumentRange(Tracker.getRange()); // Even if something went wrong above, continue as if we've seen // `decltype(auto)`. isInvalid = DS.SetTypeSpecType(TST_decltype_auto, Loc, PrevSpec, @@ -4207,8 +4208,13 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, HandlePragmaMSPointersToMembers(); continue; - case tok::kw___underlying_type: - ParseUnderlyingTypeSpecifier(DS); +#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: +#include "clang/Basic/TransformTypeTraits.def" + // HACK: libstdc++ already uses '__remove_cv' as an alias template so we + // work around this by expecting all transform type traits to be suffixed + // with '('. They're an identifier otherwise. + if (!MaybeParseTypeTransformTypeSpecifier(DS)) + goto ParseIdentifier; continue; case tok::kw__Atomic: @@ -7446,7 +7452,7 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) { ExprResult Operand = Actions.CorrectDelayedTyposInExpr( ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange)); if (hasParens) - DS.setTypeofParensRange(CastRange); + DS.setTypeArgumentRange(CastRange); if (CastRange.getEnd().isInvalid()) // FIXME: Not accurate, the range gets one token more than it should. @@ -7516,7 +7522,7 @@ void Parser::ParseAtomicSpecifier(DeclSpec &DS) { if (T.getCloseLocation().isInvalid()) return; - DS.setTypeofParensRange(T.getRange()); + DS.setTypeArgumentRange(T.getRange()); DS.SetRangeEnd(T.getCloseLocation()); const char *PrevSpec = nullptr; |