diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-11-11 02:02:15 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-11-11 02:02:15 +0000 |
commit | e301ba2b489106cc31b5f3a4e0cd558f90f07cba (patch) | |
tree | 545ee49277a4a4dab3f659d9033c04ac8ddec3d1 /clang/lib/Parse | |
parent | a543f77bdb6db7f7caa9a853843d5f141ff50a05 (diff) | |
download | bcm5719-llvm-e301ba2b489106cc31b5f3a4e0cd558f90f07cba.tar.gz bcm5719-llvm-e301ba2b489106cc31b5f3a4e0cd558f90f07cba.zip |
Add support for GCC's '__auto_type' extension, per the GCC manual:
https://gcc.gnu.org/onlinedocs/gcc/Typeof.html
Differences from the GCC extension:
* __auto_type is also permitted in C++ (but only in places where
it could appear in C), allowing its use in headers that might
be shared across C and C++, or used from C++98
* __auto_type can be combined with a declarator, as with C++ auto
(for instance, "__auto_type *p")
* multiple variables can be declared in a single __auto_type
declaration, with the C++ semantics (the deduced type must be
the same in each case)
This patch also adds a missing restriction on applying typeof to
a bit-field, which GCC has historically rejected in C (due to
lack of clarity as to whether the operand should be promoted).
The same restriction also applies to __auto_type in C (in both
GCC and Clang).
This also fixes PR25449.
Patch by Nicholas Allegra!
llvm-svn: 252690
Diffstat (limited to 'clang/lib/Parse')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Parse/ParseObjc.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Parse/ParseTentative.cpp | 3 |
3 files changed, 10 insertions, 0 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 51b4eee24e6..cf3189a91a9 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -3138,6 +3138,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, PrevSpec, DiagID, Policy); isStorageClass = true; break; + case tok::kw___auto_type: + Diag(Tok, diag::ext_auto_type); + isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto_type, Loc, PrevSpec, + DiagID, Policy); + break; case tok::kw_register: isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc, PrevSpec, DiagID, Policy); @@ -4440,6 +4445,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { case tok::kw___private_extern__: case tok::kw_static: case tok::kw_auto: + case tok::kw___auto_type: case tok::kw_register: case tok::kw___thread: case tok::kw_thread_local: diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 4ac8f42f136..698c38f9c31 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -1127,6 +1127,7 @@ IdentifierInfo *Parser::ParseObjCSelectorPiece(SourceLocation &SelectorLoc) { case tok::kw__Bool: case tok::kw__Complex: case tok::kw___alignof: + case tok::kw___auto_type: IdentifierInfo *II = Tok.getIdentifierInfo(); SelectorLoc = ConsumeToken(); return II; diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index 9d2a2b931e8..6fbcfd9bd21 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -1089,6 +1089,7 @@ public: /// [GNU] typeof-specifier /// [GNU] '_Complex' /// [C++11] 'auto' +/// [GNU] '__auto_type' /// [C++11] 'decltype' ( expression ) /// [C++1y] 'decltype' ( 'auto' ) /// @@ -1262,6 +1263,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult, case tok::kw_restrict: case tok::kw__Complex: case tok::kw___attribute: + case tok::kw___auto_type: return TPResult::True; // Microsoft @@ -1515,6 +1517,7 @@ bool Parser::isCXXDeclarationSpecifierAType() { case tok::kw_double: case tok::kw_void: case tok::kw___unknown_anytype: + case tok::kw___auto_type: return true; case tok::kw_auto: |