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/AST | |
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/AST')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 10 | ||||
-rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 2 | ||||
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 6 | ||||
-rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 2 | ||||
-rw-r--r-- | clang/lib/AST/Type.cpp | 2 | ||||
-rw-r--r-- | clang/lib/AST/TypePrinter.cpp | 6 |
6 files changed, 18 insertions, 10 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 4009915619d..18240e79d80 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -3983,20 +3983,20 @@ QualType ASTContext::getUnaryTransformType(QualType BaseType, /// getAutoType - Return the uniqued reference to the 'auto' type which has been /// deduced to the given type, or to the canonical undeduced 'auto' type, or the /// canonical deduced-but-dependent 'auto' type. -QualType ASTContext::getAutoType(QualType DeducedType, bool IsDecltypeAuto, +QualType ASTContext::getAutoType(QualType DeducedType, AutoTypeKeyword Keyword, bool IsDependent) const { - if (DeducedType.isNull() && !IsDecltypeAuto && !IsDependent) + if (DeducedType.isNull() && Keyword == AutoTypeKeyword::Auto && !IsDependent) return getAutoDeductType(); // Look in the folding set for an existing type. void *InsertPos = nullptr; llvm::FoldingSetNodeID ID; - AutoType::Profile(ID, DeducedType, IsDecltypeAuto, IsDependent); + AutoType::Profile(ID, DeducedType, Keyword, IsDependent); if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(AT, 0); AutoType *AT = new (*this, TypeAlignment) AutoType(DeducedType, - IsDecltypeAuto, + Keyword, IsDependent); Types.push_back(AT); if (InsertPos) @@ -4036,7 +4036,7 @@ QualType ASTContext::getAtomicType(QualType T) const { QualType ASTContext::getAutoDeductType() const { if (AutoDeductTy.isNull()) AutoDeductTy = QualType( - new (*this, TypeAlignment) AutoType(QualType(), /*decltype(auto)*/false, + new (*this, TypeAlignment) AutoType(QualType(), AutoTypeKeyword::Auto, /*dependent*/false), 0); return AutoDeductTy; diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index ccc6931a5ff..824cc180109 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -1746,7 +1746,7 @@ QualType ASTNodeImporter::VisitAutoType(const AutoType *T) { return QualType(); } - return Importer.getToContext().getAutoType(ToDeduced, T->isDecltypeAuto(), + return Importer.getToContext().getAutoType(ToDeduced, T->getKeyword(), /*IsDependent*/false); } diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index c3432839c2e..7f2ef495a20 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -2653,9 +2653,11 @@ void CXXNameMangler::mangleType(const UnaryTransformType *T) { void CXXNameMangler::mangleType(const AutoType *T) { QualType D = T->getDeducedType(); // <builtin-type> ::= Da # dependent auto - if (D.isNull()) + if (D.isNull()) { + assert(T->getKeyword() != AutoTypeKeyword::GNUAutoType && + "shouldn't need to mangle __auto_type!"); Out << (T->isDecltypeAuto() ? "Dc" : "Da"); - else + } else mangleType(D); } diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 5c30ae28b34..01e17588feb 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -1818,6 +1818,8 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T, Out << '?'; mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false); Out << '?'; + assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType && + "shouldn't need to mangle __auto_type!"); mangleSourceName(AT->isDecltypeAuto() ? "<decltype-auto>" : "<auto>"); Out << '@'; } else { diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 40fe903feab..611218ff917 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -948,7 +948,7 @@ public: == T->getDeducedType().getAsOpaquePtr()) return QualType(T, 0); - return Ctx.getAutoType(deducedType, T->isDecltypeAuto(), + return Ctx.getAutoType(deducedType, T->getKeyword(), T->isDependentType()); } diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 0bb50c6ba81..b4810d63c80 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -835,7 +835,11 @@ void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) { if (!T->getDeducedType().isNull()) { printBefore(T->getDeducedType(), OS); } else { - OS << (T->isDecltypeAuto() ? "decltype(auto)" : "auto"); + switch (T->getKeyword()) { + case AutoTypeKeyword::Auto: OS << "auto"; break; + case AutoTypeKeyword::DecltypeAuto: OS << "decltype(auto)"; break; + case AutoTypeKeyword::GNUAutoType: OS << "__auto_type"; break; + } spaceBeforePlaceHolder(OS); } } |