diff options
Diffstat (limited to 'include/clang/AST/TemplateBase.h')
-rw-r--r-- | include/clang/AST/TemplateBase.h | 92 |
1 files changed, 60 insertions, 32 deletions
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h index 5047028..1c0abde 100644 --- a/include/clang/AST/TemplateBase.h +++ b/include/clang/AST/TemplateBase.h @@ -28,11 +28,11 @@ namespace llvm { namespace clang { -class Decl; class DiagnosticBuilder; class Expr; struct PrintingPolicy; class TypeSourceInfo; +class ValueDecl; /// \brief Represents a template argument within a class template /// specialization. @@ -43,12 +43,14 @@ public: /// \brief Represents an empty template argument, e.g., one that has not /// been deduced. Null = 0, - /// The template argument is a type. Its value is stored in the - /// TypeOrValue field. + /// The template argument is a type. Type, - /// The template argument is a declaration that was provided for a pointer - /// or reference non-type template parameter. + /// The template argument is a declaration that was provided for a pointer, + /// reference, or pointer to member non-type template parameter. Declaration, + /// The template argument is a null pointer or null pointer to member that + /// was provided for a non-type template parameter. + NullPtr, /// The template argument is an integral value stored in an llvm::APSInt /// that was provided for an integral non-type template parameter. Integral, @@ -73,6 +75,10 @@ private: union { uintptr_t TypeOrValue; struct { + ValueDecl *D; + bool ForRefParam; + } DeclArg; + struct { // We store a decomposed APSInt with the data allocated by ASTContext if // BitWidth > 64. The memory may be shared between multiple // TemplateArgument instances. @@ -101,15 +107,18 @@ public: TemplateArgument() : Kind(Null), TypeOrValue(0) { } /// \brief Construct a template type argument. - TemplateArgument(QualType T) : Kind(Type) { + TemplateArgument(QualType T, bool isNullPtr = false) + : Kind(isNullPtr ? NullPtr : Type) { TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr()); } /// \brief Construct a template argument that refers to a /// declaration, which is either an external declaration or a /// template declaration. - TemplateArgument(Decl *D) : Kind(Declaration) { - TypeOrValue = reinterpret_cast<uintptr_t>(D); + TemplateArgument(ValueDecl *D, bool ForRefParam) : Kind(Declaration) { + assert(D && "Expected decl"); + DeclArg.D = D; + DeclArg.ForRefParam = ForRefParam; } /// \brief Construct an integral constant template argument. The memory to @@ -177,6 +186,10 @@ public: this->Args.NumArgs = NumArgs; } + static TemplateArgument getEmptyPack() { + return TemplateArgument((TemplateArgument*)0, 0); + } + /// \brief Create a new template argument pack by copying the given set of /// template arguments. static TemplateArgument CreatePackCopy(ASTContext &Context, @@ -205,34 +218,43 @@ public: /// \brief Determine whether this template argument is a pack expansion. bool isPackExpansion() const; - /// \brief Retrieve the template argument as a type. + /// \brief Retrieve the type for a type template argument. QualType getAsType() const { - if (Kind != Type) - return QualType(); - + assert(Kind == Type && "Unexpected kind"); return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue)); } - /// \brief Retrieve the template argument as a declaration. - Decl *getAsDecl() const { - if (Kind != Declaration) - return 0; - return reinterpret_cast<Decl *>(TypeOrValue); + /// \brief Retrieve the declaration for a declaration non-type + /// template argument. + ValueDecl *getAsDecl() const { + assert(Kind == Declaration && "Unexpected kind"); + return DeclArg.D; + } + + /// \brief Retrieve whether a declaration is binding to a + /// reference parameter in a declaration non-type template argument. + bool isDeclForReferenceParam() const { + assert(Kind == Declaration && "Unexpected kind"); + return DeclArg.ForRefParam; } - /// \brief Retrieve the template argument as a template name. + /// \brief Retrieve the type for null non-type template argument. + QualType getNullPtrType() const { + assert(Kind == NullPtr && "Unexpected kind"); + return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue)); + } + + /// \brief Retrieve the template name for a template name argument. TemplateName getAsTemplate() const { - if (Kind != Template) - return TemplateName(); - + assert(Kind == Template && "Unexpected kind"); return TemplateName::getFromVoidPointer(TemplateArg.Name); } /// \brief Retrieve the template argument as a template name; if the argument /// is a pack expansion, return the pattern as a template name. TemplateName getAsTemplateOrTemplatePattern() const { - if (Kind != Template && Kind != TemplateExpansion) - return TemplateName(); + assert((Kind == Template || Kind == TemplateExpansion) && + "Unexpected kind"); return TemplateName::getFromVoidPointer(TemplateArg.Name); } @@ -244,6 +266,7 @@ public: /// \brief Retrieve the template argument as an integral value. // FIXME: Provide a way to read the integral data without copying the value. llvm::APSInt getAsIntegral() const { + assert(Kind == Integral && "Unexpected kind"); using namespace llvm; if (Integer.BitWidth <= 64) return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned); @@ -255,23 +278,18 @@ public: /// \brief Retrieve the type of the integral value. QualType getIntegralType() const { - if (Kind != Integral) - return QualType(); - + assert(Kind == Integral && "Unexpected kind"); return QualType::getFromOpaquePtr(Integer.Type); } void setIntegralType(QualType T) { - assert(Kind == Integral && - "Cannot set the integral type of a non-integral template argument"); + assert(Kind == Integral && "Unexpected kind"); Integer.Type = T.getAsOpaquePtr(); } /// \brief Retrieve the template argument as an expression. Expr *getAsExpr() const { - if (Kind != Expression) - return 0; - + assert(Kind == Expression && "Unexpected kind"); return reinterpret_cast<Expr *>(TypeOrValue); } @@ -436,7 +454,17 @@ public: assert(Argument.getKind() == TemplateArgument::Declaration); return LocInfo.getAsExpr(); } - + + Expr *getSourceNullPtrExpression() const { + assert(Argument.getKind() == TemplateArgument::NullPtr); + return LocInfo.getAsExpr(); + } + + Expr *getSourceIntegralExpression() const { + assert(Argument.getKind() == TemplateArgument::Integral); + return LocInfo.getAsExpr(); + } + NestedNameSpecifierLoc getTemplateQualifierLoc() const { assert(Argument.getKind() == TemplateArgument::Template || Argument.getKind() == TemplateArgument::TemplateExpansion); |