diff options
Diffstat (limited to 'lib/AST/Type.cpp')
-rw-r--r-- | lib/AST/Type.cpp | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 3f6a094..abefae4 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -288,6 +288,28 @@ QualType QualType::IgnoreParens(QualType T) { return T; } +/// \brief This will check for a TypedefType by removing any existing sugar +/// until it reaches a TypedefType or a non-sugared type. +template <> const TypedefType *Type::getAs() const { + const Type *Cur = this; + + while (true) { + if (const TypedefType *TDT = dyn_cast<TypedefType>(Cur)) + return TDT; + switch (Cur->getTypeClass()) { +#define ABSTRACT_TYPE(Class, Parent) +#define TYPE(Class, Parent) \ + case Class: { \ + const Class##Type *Ty = cast<Class##Type>(Cur); \ + if (!Ty->isSugared()) return 0; \ + Cur = Ty->desugar().getTypePtr(); \ + break; \ + } +#include "clang/AST/TypeNodes.def" + } + } +} + /// getUnqualifiedDesugaredType - Pull any qualifiers and syntactic /// sugar off the given type. This should produce an object of the /// same dynamic type as the canonical type. @@ -895,6 +917,14 @@ bool Type::isIncompleteType(NamedDecl **Def) const { } bool QualType::isPODType(ASTContext &Context) const { + // C++11 has a more relaxed definition of POD. + if (Context.getLangOpts().CPlusPlus0x) + return isCXX11PODType(Context); + + return isCXX98PODType(Context); +} + +bool QualType::isCXX98PODType(ASTContext &Context) const { // The compiler shouldn't query this for incomplete types, but the user might. // We return false for that case. Except for incomplete arrays of PODs, which // are PODs according to the standard. @@ -902,7 +932,7 @@ bool QualType::isPODType(ASTContext &Context) const { return 0; if ((*this)->isIncompleteArrayType()) - return Context.getBaseElementType(*this).isPODType(Context); + return Context.getBaseElementType(*this).isCXX98PODType(Context); if ((*this)->isIncompleteType()) return false; @@ -929,7 +959,7 @@ bool QualType::isPODType(ASTContext &Context) const { case Type::VariableArray: case Type::ConstantArray: // IncompleteArray is handled above. - return Context.getBaseElementType(*this).isPODType(Context); + return Context.getBaseElementType(*this).isCXX98PODType(Context); case Type::ObjCObjectPointer: case Type::BlockPointer: @@ -1417,7 +1447,7 @@ const char *Type::getTypeClassName() const { llvm_unreachable("Invalid type class."); } -const char *BuiltinType::getName(const PrintingPolicy &Policy) const { +StringRef BuiltinType::getName(const PrintingPolicy &Policy) const { switch (getKind()) { case Void: return "void"; case Bool: return Policy.Bool ? "bool" : "_Bool"; @@ -1554,6 +1584,11 @@ FunctionProtoType::FunctionProtoType(QualType result, const QualType *args, slot[1] = epi.ExceptionSpecTemplate; // This exception specification doesn't make the type dependent, because // it's not instantiated as part of instantiating the type. + } else if (getExceptionSpecType() == EST_Unevaluated) { + // Store the function decl from which we will resolve our + // exception specification. + FunctionDecl **slot = reinterpret_cast<FunctionDecl**>(argSlot + numArgs); + slot[0] = epi.ExceptionSpecDecl; } if (epi.ConsumedArguments) { @@ -1637,7 +1672,8 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result, ID.AddPointer(epi.Exceptions[i].getAsOpaquePtr()); } else if (epi.ExceptionSpecType == EST_ComputedNoexcept && epi.NoexceptExpr){ epi.NoexceptExpr->Profile(ID, Context, false); - } else if (epi.ExceptionSpecType == EST_Uninstantiated) { + } else if (epi.ExceptionSpecType == EST_Uninstantiated || + epi.ExceptionSpecType == EST_Unevaluated) { ID.AddPointer(epi.ExceptionSpecDecl->getCanonicalDecl()); } if (epi.ConsumedArguments) { @@ -1832,8 +1868,7 @@ TemplateSpecializationType(TemplateName T, Canon.isNull()? T.isDependent() : Canon->isInstantiationDependentType(), false, - Canon.isNull()? T.containsUnexpandedParameterPack() - : Canon->containsUnexpandedParameterPack()), + T.containsUnexpandedParameterPack()), Template(T), NumArgs(NumArgs), TypeAlias(!AliasedType.isNull()) { assert(!T.getAsDependentTemplateName() && "Use DependentTemplateSpecializationType for dependent template-name"); @@ -1858,6 +1893,8 @@ TemplateSpecializationType(TemplateName T, // arguments is. Given: // template<typename T> using U = int; // U<T> is always non-dependent, irrespective of the type T. + // However, U<Ts> contains an unexpanded parameter pack, even though + // its expansion (and thus its desugared type) doesn't. if (Canon.isNull() && Args[Arg].isDependent()) setDependent(); else if (Args[Arg].isInstantiationDependent()) @@ -1866,7 +1903,7 @@ TemplateSpecializationType(TemplateName T, if (Args[Arg].getKind() == TemplateArgument::Type && Args[Arg].getAsType()->isVariablyModifiedType()) setVariablyModified(); - if (Canon.isNull() && Args[Arg].containsUnexpandedParameterPack()) + if (Args[Arg].containsUnexpandedParameterPack()) setContainsUnexpandedParameterPack(); new (&TemplateArgs[Arg]) TemplateArgument(Args[Arg]); |