summaryrefslogtreecommitdiffstats
path: root/include/clang/AST
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST')
-rw-r--r--include/clang/AST/ASTContext.h74
-rw-r--r--include/clang/AST/CanonicalType.h19
-rw-r--r--include/clang/AST/Decl.h91
-rw-r--r--include/clang/AST/DeclGroup.h2
-rw-r--r--include/clang/AST/DeclNodes.def1
-rw-r--r--include/clang/AST/DeclObjC.h14
-rw-r--r--include/clang/AST/DeclTemplate.h380
-rw-r--r--include/clang/AST/Expr.h272
-rw-r--r--include/clang/AST/ExprCXX.h58
-rw-r--r--include/clang/AST/RecordLayout.h2
-rw-r--r--include/clang/AST/Redeclarable.h5
-rw-r--r--include/clang/AST/StmtIterator.h2
-rw-r--r--include/clang/AST/StmtNodes.def1
-rw-r--r--include/clang/AST/TemplateBase.h366
-rw-r--r--include/clang/AST/TemplateName.h81
-rw-r--r--include/clang/AST/Type.h8
-rw-r--r--include/clang/AST/TypeLoc.h135
17 files changed, 1049 insertions, 462 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 30896c9..7392170 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -16,6 +16,7 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/OperatorKinds.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/NestedNameSpecifier.h"
@@ -301,22 +302,22 @@ public:
const char *getCommentForDecl(const Decl *D);
// Builtin Types.
- QualType VoidTy;
- QualType BoolTy;
- QualType CharTy;
- QualType WCharTy; // [C++ 3.9.1p5], integer type in C99.
- QualType Char16Ty; // [C++0x 3.9.1p5], integer type in C99.
- QualType Char32Ty; // [C++0x 3.9.1p5], integer type in C99.
- QualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty;
- QualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
- QualType UnsignedLongLongTy, UnsignedInt128Ty;
- QualType FloatTy, DoubleTy, LongDoubleTy;
- QualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
- QualType VoidPtrTy, NullPtrTy;
- QualType OverloadTy;
- QualType DependentTy;
- QualType UndeducedAutoTy;
- QualType ObjCBuiltinIdTy, ObjCBuiltinClassTy;
+ CanQualType VoidTy;
+ CanQualType BoolTy;
+ CanQualType CharTy;
+ CanQualType WCharTy; // [C++ 3.9.1p5], integer type in C99.
+ CanQualType Char16Ty; // [C++0x 3.9.1p5], integer type in C99.
+ CanQualType Char32Ty; // [C++0x 3.9.1p5], integer type in C99.
+ CanQualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty;
+ CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
+ CanQualType UnsignedLongLongTy, UnsignedInt128Ty;
+ CanQualType FloatTy, DoubleTy, LongDoubleTy;
+ CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
+ CanQualType VoidPtrTy, NullPtrTy;
+ CanQualType OverloadTy;
+ CanQualType DependentTy;
+ CanQualType UndeducedAutoTy;
+ CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy;
ASTContext(const LangOptions& LOpts, SourceManager &SM, TargetInfo &t,
IdentifierTable &idents, SelectorTable &sels,
@@ -387,10 +388,16 @@ public:
/// getComplexType - Return the uniqued reference to the type for a complex
/// number with the specified element type.
QualType getComplexType(QualType T);
+ CanQualType getComplexType(CanQualType T) {
+ return CanQualType::CreateUnsafe(getComplexType((QualType) T));
+ }
/// getPointerType - Return the uniqued reference to the type for a pointer to
/// the specified type.
QualType getPointerType(QualType T);
+ CanQualType getPointerType(CanQualType T) {
+ return CanQualType::CreateUnsafe(getPointerType((QualType) T));
+ }
/// getBlockPointerType - Return the uniqued reference to the type for a block
/// of the specified type.
@@ -525,6 +532,11 @@ public:
unsigned NumArgs,
QualType Canon = QualType());
+ QualType getTemplateSpecializationType(TemplateName T,
+ const TemplateArgumentLoc *Args,
+ unsigned NumArgs,
+ QualType Canon = QualType());
+
QualType getQualifiedNameType(NestedNameSpecifier *NNS,
QualType NamedType);
QualType getTypenameType(NestedNameSpecifier *NNS,
@@ -728,6 +740,8 @@ public:
TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
const IdentifierInfo *Name);
+ TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
+ OverloadedOperatorKind Operator);
enum GetBuiltinTypeError {
GE_None, //< No error
@@ -739,7 +753,7 @@ public:
QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error);
private:
- QualType getFromTargetType(unsigned Type) const;
+ CanQualType getFromTargetType(unsigned Type) const;
//===--------------------------------------------------------------------===//
// Type Predicates.
@@ -826,6 +840,8 @@ public:
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
unsigned CountSynthesizedIvars(const ObjCInterfaceDecl *OI);
unsigned CountProtocolSynthesizedIvars(const ObjCProtocolDecl *PD);
+ void CollectInheritedProtocols(const Decl *CDecl,
+ llvm::SmallVectorImpl<ObjCProtocolDecl*> &Protocols);
//===--------------------------------------------------------------------===//
// Type Operators
@@ -1013,7 +1029,9 @@ public:
bool canAssignObjCInterfaces(const ObjCInterfaceType *LHS,
const ObjCInterfaceType *RHS);
bool areComparableObjCPointerTypes(QualType LHS, QualType RHS);
-
+ QualType areCommonBaseCompatible(const ObjCObjectPointerType *LHSOPT,
+ const ObjCObjectPointerType *RHSOPT);
+
// Functions for calculating composite types
QualType mergeTypes(QualType, QualType);
QualType mergeFunctionTypes(QualType, QualType);
@@ -1085,12 +1103,18 @@ public:
/// should be calculated based on the type.
DeclaratorInfo *CreateDeclaratorInfo(QualType T, unsigned Size = 0);
+ /// \brief Allocate a DeclaratorInfo where all locations have been
+ /// initialized to a given location, which defaults to the empty
+ /// location.
+ DeclaratorInfo *
+ getTrivialDeclaratorInfo(QualType T, SourceLocation Loc = SourceLocation());
+
private:
ASTContext(const ASTContext&); // DO NOT IMPLEMENT
void operator=(const ASTContext&); // DO NOT IMPLEMENT
void InitBuiltinTypes();
- void InitBuiltinType(QualType &R, BuiltinType::Kind K);
+ void InitBuiltinType(CanQualType &R, BuiltinType::Kind K);
// Return the ObjC type encoding for a given type.
void getObjCEncodingForTypeImpl(QualType t, std::string &S,
@@ -1103,6 +1127,18 @@ private:
const ASTRecordLayout &getObjCLayout(const ObjCInterfaceDecl *D,
const ObjCImplementationDecl *Impl);
};
+
+/// @brief Utility function for constructing a nullary selector.
+static inline Selector GetNullarySelector(const char* name, ASTContext& Ctx) {
+ IdentifierInfo* II = &Ctx.Idents.get(name);
+ return Ctx.Selectors.getSelector(0, &II);
+}
+
+/// @brief Utility function for constructing an unary selector.
+static inline Selector GetUnarySelector(const char* name, ASTContext& Ctx) {
+ IdentifierInfo* II = &Ctx.Idents.get(name);
+ return Ctx.Selectors.getSelector(1, &II);
+}
} // end namespace clang
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 8b84bc2..a775051 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -64,15 +64,6 @@ public:
CanQual(const CanQual<U>& Other,
typename llvm::enable_if<llvm::is_base_of<T, U>, int>::type = 0);
- /// \brief Implicit conversion to the underlying pointer.
- ///
- /// Also provides the ability to use canonical types in a boolean context,
- /// e.g.,
- /// @code
- /// if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... }
- /// @endcode
- operator const T*() const { return getTypePtr(); }
-
/// \brief Retrieve the underlying type pointer, which refers to a
/// canonical type.
T *getTypePtr() const { return cast_or_null<T>(Stored.getTypePtr()); }
@@ -80,6 +71,10 @@ public:
/// \brief Implicit conversion to a qualified type.
operator QualType() const { return Stored; }
+ bool isNull() const {
+ return Stored.isNull();
+ }
+
/// \brief Retrieve a canonical type pointer with a different static type,
/// upcasting or downcasting as needed.
///
@@ -125,8 +120,10 @@ public:
/// \brief Retrieve the unqualified form of this type.
CanQual<T> getUnqualifiedType() const;
- CanQual<T> getQualifiedType(unsigned TQs) const {
- return CanQual<T>::CreateUnsafe(QualType(getTypePtr(), TQs));
+ /// \brief Retrieves a version of this type with const applied.
+ /// Note that this does not always yield a canonical type.
+ QualType withConst() const {
+ return Stored.withConst();
}
/// \brief Determines whether this canonical type is more qualified than
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 72ce0d8..813e83a 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -605,6 +605,9 @@ public:
/// \brief Determine whether this is or was instantiated from an out-of-line
/// definition of a static data member.
bool isOutOfLine() const;
+
+ /// \brief If this is a static data member, find its out-of-line definition.
+ VarDecl *getOutOfLineDefinition();
/// \brief If this variable is an instantiated static data member of a
/// class template specialization, returns the templated static data member
@@ -768,7 +771,11 @@ public:
Init = (UnparsedDefaultArgument *)0;
}
- QualType getOriginalType() const;
+ QualType getOriginalType() const {
+ if (getDeclaratorInfo())
+ return getDeclaratorInfo()->getType();
+ return getType();
+ }
/// setOwningFunction - Sets the function declaration that owns this
/// ParmVarDecl. Since ParmVarDecls are often created before the
@@ -778,41 +785,11 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
- return (D->getKind() == ParmVar ||
- D->getKind() == OriginalParmVar);
+ return (D->getKind() == ParmVar);
}
static bool classof(const ParmVarDecl *D) { return true; }
};
-/// OriginalParmVarDecl - Represent a parameter to a function, when
-/// the type of the parameter has been promoted. This node represents the
-/// parameter to the function with its original type.
-///
-class OriginalParmVarDecl : public ParmVarDecl {
- friend class ParmVarDecl;
-protected:
- QualType OriginalType;
-private:
- OriginalParmVarDecl(DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T,
- DeclaratorInfo *DInfo,
- QualType OT, StorageClass S,
- Expr *DefArg)
- : ParmVarDecl(OriginalParmVar, DC, L, Id, T, DInfo, S, DefArg),
- OriginalType(OT) {}
-public:
- static OriginalParmVarDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,IdentifierInfo *Id,
- QualType T, DeclaratorInfo *DInfo,
- QualType OT, StorageClass S, Expr *DefArg);
-
- void setOriginalType(QualType T) { OriginalType = T; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return D->getKind() == OriginalParmVar; }
- static bool classof(const OriginalParmVarDecl *D) { return true; }
-};
-
/// FunctionDecl - An instance of this class is created to represent a
/// function declaration or definition.
///
@@ -1067,9 +1044,18 @@ public:
StorageClass getStorageClass() const { return StorageClass(SClass); }
void setStorageClass(StorageClass SC) { SClass = SC; }
- bool isInline() const { return IsInline; }
- void setInline(bool I) { IsInline = I; }
+ /// \brief Determine whether the "inline" keyword was specified for this
+ /// function.
+ bool isInlineSpecified() const { return IsInline; }
+
+ /// Set whether the "inline" keyword was specified for this function.
+ void setInlineSpecified(bool I) { IsInline = I; }
+ /// \brief Determine whether this function should be inlined, because it is
+ /// either marked "inline" or is a member function of a C++ class that
+ /// was defined in the class body.
+ bool isInlined() const;
+
bool isInlineDefinitionExternallyVisible() const;
/// isOverloadedOperator - Whether this function declaration
@@ -1146,7 +1132,17 @@ public:
return TemplateOrSpecialization.
dyn_cast<FunctionTemplateSpecializationInfo*>();
}
-
+
+ /// \brief Determines whether this function is a function template
+ /// specialization or a member of a class template specialization that can
+ /// be implicitly instantiated.
+ bool isImplicitlyInstantiable() const;
+
+ /// \brief Retrieve the function declaration from which this function could
+ /// be instantiated, if it is an instantiation (rather than a non-template
+ /// or a specialization, for example).
+ FunctionDecl *getTemplateInstantiationPattern() const;
+
/// \brief Retrieve the primary template that this function template
/// specialization either specializes or was instantiated from.
///
@@ -1199,7 +1195,7 @@ public:
/// instantiated from a template; otherwie, returns an invalid source
/// location.
SourceLocation getPointOfInstantiation() const;
-
+
/// \brief Determine whether this is or was instantiated from an out-of-line
/// definition of a member function.
bool isOutOfLine() const;
@@ -1337,20 +1333,29 @@ public:
class TypedefDecl : public TypeDecl {
/// UnderlyingType - This is the type the typedef is set to.
- QualType UnderlyingType;
+ DeclaratorInfo *DInfo;
+
TypedefDecl(DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T)
- : TypeDecl(Typedef, DC, L, Id), UnderlyingType(T) {}
+ IdentifierInfo *Id, DeclaratorInfo *DInfo)
+ : TypeDecl(Typedef, DC, L, Id), DInfo(DInfo) {}
virtual ~TypedefDecl() {}
public:
static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,IdentifierInfo *Id,
- QualType T);
+ SourceLocation L, IdentifierInfo *Id,
+ DeclaratorInfo *DInfo);
+
+ DeclaratorInfo *getTypeDeclaratorInfo() const {
+ return DInfo;
+ }
- QualType getUnderlyingType() const { return UnderlyingType; }
- void setUnderlyingType(QualType newType) { UnderlyingType = newType; }
+ QualType getUnderlyingType() const {
+ return DInfo->getType();
+ }
+ void setTypeDeclaratorInfo(DeclaratorInfo *newType) {
+ DInfo = newType;
+ }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == Typedef; }
diff --git a/include/clang/AST/DeclGroup.h b/include/clang/AST/DeclGroup.h
index 790ea3c..e1fae8f 100644
--- a/include/clang/AST/DeclGroup.h
+++ b/include/clang/AST/DeclGroup.h
@@ -14,7 +14,7 @@
#ifndef LLVM_CLANG_AST_DECLGROUP_H
#define LLVM_CLANG_AST_DECLGROUP_H
-#include "llvm/Support/DataTypes.h"
+#include "llvm/System/DataTypes.h"
#include <cassert>
namespace clang {
diff --git a/include/clang/AST/DeclNodes.def b/include/clang/AST/DeclNodes.def
index 79a0d36..3ef3cc3 100644
--- a/include/clang/AST/DeclNodes.def
+++ b/include/clang/AST/DeclNodes.def
@@ -103,7 +103,6 @@ ABSTRACT_DECL(Named, Decl)
DECL(Var, DeclaratorDecl)
DECL(ImplicitParam, VarDecl)
DECL(ParmVar, VarDecl)
- DECL(OriginalParmVar, ParmVarDecl)
DECL(NonTypeTemplateParm, VarDecl)
DECL(Template, NamedDecl)
DECL(FunctionTemplate, TemplateDecl)
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 729a2f1..bcd28ea 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -347,6 +347,8 @@ public:
ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
+ ObjCPropertyDecl *FindPropertyVisibleInPrimaryClass(
+ IdentifierInfo *PropertyId) const;
// Marks the end of the container.
SourceLocation getAtEndLoc() const { return AtEndLoc; }
@@ -862,7 +864,7 @@ public:
};
class ObjCImplDecl : public ObjCContainerDecl {
- /// Class interface for this category implementation
+ /// Class interface for this class/category implementation
ObjCInterfaceDecl *ClassInterface;
protected:
@@ -935,14 +937,20 @@ public:
SourceLocation L, IdentifierInfo *Id,
ObjCInterfaceDecl *classInterface);
- /// getIdentifier - Get the identifier that names the class
+ /// getIdentifier - Get the identifier that names the category
/// interface associated with this implementation.
+ /// FIXME: This is a bad API, we are overriding the NamedDecl::getIdentifier()
+ /// to mean something different. For example:
+ /// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier()
+ /// returns the class interface name, whereas
+ /// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier()
+ /// returns the category name.
IdentifierInfo *getIdentifier() const {
return Id;
}
void setIdentifier(IdentifierInfo *II) { Id = II; }
- ObjCCategoryDecl *getCategoryClass() const;
+ ObjCCategoryDecl *getCategoryDecl() const;
/// getName - Get the name of identifier for the class interface associated
/// with this implementation as a StringRef.
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 8d44676..f1a2793 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -15,8 +15,7 @@
#define LLVM_CLANG_AST_DECLTEMPLATE_H
#include "clang/AST/DeclCXX.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/FoldingSet.h"
+#include "clang/AST/TemplateBase.h"
#include "llvm/ADT/PointerUnion.h"
#include <limits>
@@ -91,6 +90,13 @@ public:
/// arguments or if there is a parameter pack.
unsigned getMinRequiredArguments() const;
+ /// \brief Get the depth of this template parameter list in the set of
+ /// template parameter lists.
+ ///
+ /// The first template parameter list in a declaration will have depth 0,
+ /// the second template parameter list will have depth 1, etc.
+ unsigned getDepth() const;
+
SourceLocation getTemplateLoc() const { return TemplateLoc; }
SourceLocation getLAngleLoc() const { return LAngleLoc; }
SourceLocation getRAngleLoc() const { return RAngleLoc; }
@@ -100,251 +106,6 @@ public:
}
};
-/// \brief Represents a template argument within a class template
-/// specialization.
-class TemplateArgument {
- union {
- uintptr_t TypeOrValue;
- struct {
- char Value[sizeof(llvm::APSInt)];
- void *Type;
- } Integer;
- struct {
- TemplateArgument *Args;
- unsigned NumArgs;
- bool CopyArgs;
- } Args;
- };
-
- /// \brief Location of the beginning of this template argument.
- SourceLocation StartLoc;
-
-public:
- /// \brief The type of template argument we're storing.
- enum ArgKind {
- Null = 0,
- /// The template argument is a type. Its value is stored in the
- /// TypeOrValue field.
- Type = 1,
- /// The template argument is a declaration
- Declaration = 2,
- /// The template argument is an integral value stored in an llvm::APSInt.
- Integral = 3,
- /// The template argument is a value- or type-dependent expression
- /// stored in an Expr*.
- Expression = 4,
-
- /// The template argument is actually a parameter pack. Arguments are stored
- /// in the Args struct.
- Pack = 5
- } Kind;
-
- /// \brief Construct an empty, invalid template argument.
- TemplateArgument() : TypeOrValue(0), StartLoc(), Kind(Null) { }
-
- /// \brief Construct a template type argument.
- TemplateArgument(SourceLocation Loc, QualType T) : Kind(Type) {
- TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
- StartLoc = Loc;
- }
-
- /// \brief Construct a template argument that refers to a
- /// declaration, which is either an external declaration or a
- /// template declaration.
- TemplateArgument(SourceLocation Loc, Decl *D) : Kind(Declaration) {
- // FIXME: Need to be sure we have the "canonical" declaration!
- TypeOrValue = reinterpret_cast<uintptr_t>(D);
- StartLoc = Loc;
- }
-
- /// \brief Construct an integral constant template argument.
- TemplateArgument(SourceLocation Loc, const llvm::APSInt &Value,
- QualType Type)
- : Kind(Integral) {
- new (Integer.Value) llvm::APSInt(Value);
- Integer.Type = Type.getAsOpaquePtr();
- StartLoc = Loc;
- }
-
- /// \brief Construct a template argument that is an expression.
- ///
- /// This form of template argument only occurs in template argument
- /// lists used for dependent types and for expression; it will not
- /// occur in a non-dependent, canonical template argument list.
- TemplateArgument(Expr *E);
-
- /// \brief Copy constructor for a template argument.
- TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
- if (Kind == Integral) {
- new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
- Integer.Type = Other.Integer.Type;
- } else if (Kind == Pack) {
- Args.NumArgs = Other.Args.NumArgs;
- Args.Args = new TemplateArgument[Args.NumArgs];
- for (unsigned I = 0; I != Args.NumArgs; ++I)
- Args.Args[I] = Other.Args.Args[I];
- }
- else
- TypeOrValue = Other.TypeOrValue;
- StartLoc = Other.StartLoc;
- }
-
- TemplateArgument& operator=(const TemplateArgument& Other) {
- // FIXME: Does not provide the strong guarantee for exception
- // safety.
- using llvm::APSInt;
-
- // FIXME: Handle Packs
- assert(Kind != Pack && "FIXME: Handle packs");
- assert(Other.Kind != Pack && "FIXME: Handle packs");
-
- if (Kind == Other.Kind && Kind == Integral) {
- // Copy integral values.
- *this->getAsIntegral() = *Other.getAsIntegral();
- Integer.Type = Other.Integer.Type;
- } else {
- // Destroy the current integral value, if that's what we're holding.
- if (Kind == Integral)
- getAsIntegral()->~APSInt();
-
- Kind = Other.Kind;
-
- if (Other.Kind == Integral) {
- new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
- Integer.Type = Other.Integer.Type;
- } else
- TypeOrValue = Other.TypeOrValue;
- }
- StartLoc = Other.StartLoc;
-
- return *this;
- }
-
- ~TemplateArgument() {
- using llvm::APSInt;
-
- if (Kind == Integral)
- getAsIntegral()->~APSInt();
- else if (Kind == Pack && Args.CopyArgs)
- delete[] Args.Args;
- }
-
- /// \brief Return the kind of stored template argument.
- ArgKind getKind() const { return Kind; }
-
- /// \brief Determine whether this template argument has no value.
- bool isNull() const { return Kind == Null; }
-
- /// \brief Retrieve the template argument as a type.
- QualType getAsType() const {
- if (Kind != Type)
- return QualType();
-
- 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 template argument as an integral value.
- llvm::APSInt *getAsIntegral() {
- if (Kind != Integral)
- return 0;
- return reinterpret_cast<llvm::APSInt*>(&Integer.Value[0]);
- }
-
- const llvm::APSInt *getAsIntegral() const {
- return const_cast<TemplateArgument*>(this)->getAsIntegral();
- }
-
- /// \brief Retrieve the type of the integral value.
- QualType getIntegralType() const {
- if (Kind != Integral)
- return QualType();
-
- return QualType::getFromOpaquePtr(Integer.Type);
- }
-
- void setIntegralType(QualType T) {
- assert(Kind == Integral &&
- "Cannot set the integral type of a non-integral template argument");
- Integer.Type = T.getAsOpaquePtr();
- };
-
- /// \brief Retrieve the template argument as an expression.
- Expr *getAsExpr() const {
- if (Kind != Expression)
- return 0;
-
- return reinterpret_cast<Expr *>(TypeOrValue);
- }
-
- /// \brief Iterator that traverses the elements of a template argument pack.
- typedef const TemplateArgument * pack_iterator;
-
- /// \brief Iterator referencing the first argument of a template argument
- /// pack.
- pack_iterator pack_begin() const {
- assert(Kind == Pack);
- return Args.Args;
- }
-
- /// \brief Iterator referencing one past the last argument of a template
- /// argument pack.
- pack_iterator pack_end() const {
- assert(Kind == Pack);
- return Args.Args + Args.NumArgs;
- }
-
- /// \brief The number of template arguments in the given template argument
- /// pack.
- unsigned pack_size() const {
- assert(Kind == Pack);
- return Args.NumArgs;
- }
-
- /// \brief Retrieve the location where the template argument starts.
- SourceLocation getLocation() const { return StartLoc; }
-
- /// \brief Construct a template argument pack.
- void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
-
- /// \brief Used to insert TemplateArguments into FoldingSets.
- void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context) const {
- ID.AddInteger(Kind);
- switch (Kind) {
- case Null:
- break;
-
- case Type:
- getAsType().Profile(ID);
- break;
-
- case Declaration:
- ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
- break;
-
- case Integral:
- getAsIntegral()->Profile(ID);
- getIntegralType().Profile(ID);
- break;
-
- case Expression:
- getAsExpr()->Profile(ID, Context, true);
- break;
-
- case Pack:
- ID.AddInteger(Args.NumArgs);
- for (unsigned I = 0; I != Args.NumArgs; ++I)
- Args.Args[I].Profile(ID, Context);
- }
- }
-};
-
/// \brief A helper class for making template argument lists.
class TemplateArgumentListBuilder {
TemplateArgument *StructuredArgs;
@@ -811,11 +572,8 @@ class TemplateTypeParmDecl : public TypeDecl {
/// \brief Whether this is a parameter pack.
bool ParameterPack : 1;
- /// \brief The location of the default argument, if any.
- SourceLocation DefaultArgumentLoc;
-
/// \brief The default template argument, if any.
- QualType DefaultArgument;
+ DeclaratorInfo *DefaultArgument;
TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
bool Typename, QualType Type, bool ParameterPack)
@@ -837,13 +595,16 @@ public:
/// \brief Determine whether this template parameter has a default
/// argument.
- bool hasDefaultArgument() const { return !DefaultArgument.isNull(); }
+ bool hasDefaultArgument() const { return DefaultArgument != 0; }
/// \brief Retrieve the default argument, if any.
- QualType getDefaultArgument() const { return DefaultArgument; }
+ QualType getDefaultArgument() const { return DefaultArgument->getType(); }
- /// \brief Retrieve the location of the default argument, if any.
- SourceLocation getDefaultArgumentLoc() const { return DefaultArgumentLoc; }
+ /// \brief Retrieves the default argument's source information, if any.
+ DeclaratorInfo *getDefaultArgumentInfo() const { return DefaultArgument; }
+
+ /// \brief Retrieves the location of the default argument declaration.
+ SourceLocation getDefaultArgumentLoc() const;
/// \brief Determines whether the default argument was inherited
/// from a previous declaration of this template.
@@ -852,13 +613,23 @@ public:
/// \brief Set the default argument for this template parameter, and
/// whether that default argument was inherited from another
/// declaration.
- void setDefaultArgument(QualType DefArg, SourceLocation DefArgLoc,
- bool Inherited) {
+ void setDefaultArgument(DeclaratorInfo *DefArg, bool Inherited) {
DefaultArgument = DefArg;
- DefaultArgumentLoc = DefArgLoc;
InheritedDefault = Inherited;
}
+ /// \brief Removes the default argument of this template parameter.
+ void removeDefaultArgument() {
+ DefaultArgument = 0;
+ InheritedDefault = false;
+ }
+
+ /// \brief Retrieve the depth of the template parameter.
+ unsigned getDepth() const;
+
+ /// \brief Retrieve the index of the template parameter.
+ unsigned getIndex() const;
+
/// \brief Returns whether this is a parameter pack.
bool isParameterPack() const { return ParameterPack; }
@@ -1150,17 +921,32 @@ class ClassTemplatePartialSpecializationDecl
/// \brief The list of template parameters
TemplateParameterList* TemplateParams;
+ /// \brief The source info for the template arguments as written.
+ TemplateArgumentLoc *ArgsAsWritten;
+ unsigned NumArgsAsWritten;
+
+ /// \brief The class template partial specialization from which this
+ /// class template partial specialization was instantiated.
+ ///
+ /// The boolean value will be true to indicate that this class template
+ /// partial specialization was specialized at this level.
+ llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
+ InstantiatedFromMember;
+
ClassTemplatePartialSpecializationDecl(ASTContext &Context,
DeclContext *DC, SourceLocation L,
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
+ TemplateArgumentLoc *ArgInfos,
+ unsigned NumArgInfos,
ClassTemplatePartialSpecializationDecl *PrevDecl)
: ClassTemplateSpecializationDecl(Context,
ClassTemplatePartialSpecialization,
DC, L, SpecializedTemplate, Builder,
PrevDecl),
- TemplateParams(Params) { }
+ TemplateParams(Params), ArgsAsWritten(ArgInfos),
+ NumArgsAsWritten(NumArgInfos), InstantiatedFromMember(0, false) { }
public:
static ClassTemplatePartialSpecializationDecl *
@@ -1168,6 +954,8 @@ public:
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
+ TemplateArgumentLoc *ArgInfos,
+ unsigned NumArgInfos,
ClassTemplatePartialSpecializationDecl *PrevDecl);
/// Get the list of template parameters
@@ -1175,6 +963,80 @@ public:
return TemplateParams;
}
+ /// Get the template arguments as written.
+ TemplateArgumentLoc *getTemplateArgsAsWritten() const {
+ return ArgsAsWritten;
+ }
+
+ /// Get the number of template arguments as written.
+ unsigned getNumTemplateArgsAsWritten() const {
+ return NumArgsAsWritten;
+ }
+
+ /// \brief Retrieve the member class template partial specialization from
+ /// which this particular class template partial specialization was
+ /// instantiated.
+ ///
+ /// \code
+ /// template<typename T>
+ /// struct Outer {
+ /// template<typename U> struct Inner;
+ /// template<typename U> struct Inner<U*> { }; // #1
+ /// };
+ ///
+ /// Outer<float>::Inner<int*> ii;
+ /// \endcode
+ ///
+ /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
+ /// end up instantiating the partial specialization
+ /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
+ /// template partial specialization \c Outer<T>::Inner<U*>. Given
+ /// \c Outer<float>::Inner<U*>, this function would return
+ /// \c Outer<T>::Inner<U*>.
+ ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() {
+ ClassTemplatePartialSpecializationDecl *First
+ = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
+ return First->InstantiatedFromMember.getPointer();
+ }
+
+ void setInstantiatedFromMember(
+ ClassTemplatePartialSpecializationDecl *PartialSpec) {
+ ClassTemplatePartialSpecializationDecl *First
+ = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
+ First->InstantiatedFromMember.setPointer(PartialSpec);
+ }
+
+ /// \brief Determines whether this class template partial specialization
+ /// template was a specialization of a member partial specialization.
+ ///
+ /// In the following example, the member template partial specialization
+ /// \c X<int>::Inner<T*> is a member specialization.
+ ///
+ /// \code
+ /// template<typename T>
+ /// struct X {
+ /// template<typename U> struct Inner;
+ /// template<typename U> struct Inner<U*>;
+ /// };
+ ///
+ /// template<> template<typename T>
+ /// struct X<int>::Inner<T*> { /* ... */ };
+ /// \endcode
+ bool isMemberSpecialization() {
+ ClassTemplatePartialSpecializationDecl *First
+ = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
+ return First->InstantiatedFromMember.getInt();
+ }
+
+ /// \brief Note that this member template is a specialization.
+ void setMemberSpecialization() {
+ ClassTemplatePartialSpecializationDecl *First
+ = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
+ assert(First->InstantiatedFromMember.getPointer() &&
+ "Only member templates can be member template specializations");
+ return First->InstantiatedFromMember.setInt(true);
+ }
+
// FIXME: Add Profile support!
static bool classof(const Decl *D) {
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 0d09ea3..2a87f58 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -34,6 +34,7 @@ namespace clang {
class BlockDecl;
class CXXOperatorCallExpr;
class CXXMemberCallExpr;
+ class TemplateArgumentLoc;
/// Expr - This represents one expression. Note that Expr's are subclasses of
/// Stmt. This allows an expression to be transparently used any place a Stmt
@@ -134,7 +135,7 @@ public:
/// with location to warn on and the source range[s] to report with the
/// warning.
bool isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
- SourceRange &R2) const;
+ SourceRange &R2, ASTContext &Ctx) const;
/// isLvalue - C99 6.3.2.1: an lvalue is an expression with an object type or
/// incomplete type other than void. Nonarray expressions that can be lvalues:
@@ -241,6 +242,10 @@ public:
/// in Result.
bool Evaluate(EvalResult &Result, ASTContext &Ctx) const;
+ /// EvaluateAsAny - The same as Evaluate, except that it also succeeds on
+ /// stack based objects.
+ bool EvaluateAsAny(EvalResult &Result, ASTContext &Ctx) const;
+
/// isEvaluatable - Call Evaluate to see if this expression can be constant
/// folded, but discard the result.
bool isEvaluatable(ASTContext &Ctx) const;
@@ -322,47 +327,221 @@ public:
// Primary Expressions.
//===----------------------------------------------------------------------===//
+/// \brief Represents the qualifier that may precede a C++ name, e.g., the
+/// "std::" in "std::sort".
+struct NameQualifier {
+ /// \brief The nested name specifier.
+ NestedNameSpecifier *NNS;
+
+ /// \brief The source range covered by the nested name specifier.
+ SourceRange Range;
+};
+
+/// \brief Represents an explicit template argument list in C++, e.g.,
+/// the "<int>" in "sort<int>".
+struct ExplicitTemplateArgumentList {
+ /// \brief The source location of the left angle bracket ('<');
+ SourceLocation LAngleLoc;
+
+ /// \brief The source location of the right angle bracket ('>');
+ SourceLocation RAngleLoc;
+
+ /// \brief The number of template arguments in TemplateArgs.
+ /// The actual template arguments (if any) are stored after the
+ /// ExplicitTemplateArgumentList structure.
+ unsigned NumTemplateArgs;
+
+ /// \brief Retrieve the template arguments
+ TemplateArgumentLoc *getTemplateArgs() {
+ return reinterpret_cast<TemplateArgumentLoc *> (this + 1);
+ }
+
+ /// \brief Retrieve the template arguments
+ const TemplateArgumentLoc *getTemplateArgs() const {
+ return reinterpret_cast<const TemplateArgumentLoc *> (this + 1);
+ }
+};
+
/// DeclRefExpr - [C99 6.5.1p2] - A reference to a declared variable, function,
/// enum, etc.
class DeclRefExpr : public Expr {
- NamedDecl *D;
+ enum {
+ // Flag on DecoratedD that specifies when this declaration reference
+ // expression has a C++ nested-name-specifier.
+ HasQualifierFlag = 0x01,
+ // Flag on DecoratedD that specifies when this declaration reference
+ // expression has an explicit C++ template argument list.
+ HasExplicitTemplateArgumentListFlag = 0x02
+ };
+
+ // DecoratedD - The declaration that we are referencing, plus two bits to
+ // indicate whether (1) the declaration's name was explicitly qualified and
+ // (2) the declaration's name was followed by an explicit template
+ // argument list.
+ llvm::PointerIntPair<NamedDecl *, 2> DecoratedD;
+
+ // Loc - The location of the declaration name itself.
SourceLocation Loc;
+ /// \brief Retrieve the qualifier that preceded the declaration name, if any.
+ NameQualifier *getNameQualifier() {
+ if ((DecoratedD.getInt() & HasQualifierFlag) == 0)
+ return 0;
+
+ return reinterpret_cast<NameQualifier *> (this + 1);
+ }
+
+ /// \brief Retrieve the qualifier that preceded the member name, if any.
+ const NameQualifier *getNameQualifier() const {
+ return const_cast<DeclRefExpr *>(this)->getNameQualifier();
+ }
+
+ /// \brief Retrieve the explicit template argument list that followed the
+ /// member template name, if any.
+ ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() {
+ if ((DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag) == 0)
+ return 0;
+
+ if ((DecoratedD.getInt() & HasQualifierFlag) == 0)
+ return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
+
+ return reinterpret_cast<ExplicitTemplateArgumentList *>(
+ getNameQualifier() + 1);
+ }
+
+ /// \brief Retrieve the explicit template argument list that followed the
+ /// member template name, if any.
+ const ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() const {
+ return const_cast<DeclRefExpr *>(this)->getExplicitTemplateArgumentList();
+ }
+
+ DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
+ NamedDecl *D, SourceLocation NameLoc,
+ bool HasExplicitTemplateArgumentList,
+ SourceLocation LAngleLoc,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
+ SourceLocation RAngleLoc,
+ QualType T, bool TD, bool VD);
+
protected:
// FIXME: Eventually, this constructor will go away and all subclasses
// will have to provide the type- and value-dependent flags.
DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l) :
- Expr(SC, t), D(d), Loc(l) {}
+ Expr(SC, t), DecoratedD(d, 0), Loc(l) {}
DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l, bool TD,
bool VD) :
- Expr(SC, t, TD, VD), D(d), Loc(l) {}
+ Expr(SC, t, TD, VD), DecoratedD(d, 0), Loc(l) {}
public:
// FIXME: Eventually, this constructor will go away and all clients
// will have to provide the type- and value-dependent flags.
DeclRefExpr(NamedDecl *d, QualType t, SourceLocation l) :
- Expr(DeclRefExprClass, t), D(d), Loc(l) {}
+ Expr(DeclRefExprClass, t), DecoratedD(d, 0), Loc(l) {}
DeclRefExpr(NamedDecl *d, QualType t, SourceLocation l, bool TD, bool VD) :
- Expr(DeclRefExprClass, t, TD, VD), D(d), Loc(l) {}
+ Expr(DeclRefExprClass, t, TD, VD), DecoratedD(d, 0), Loc(l) {}
/// \brief Construct an empty declaration reference expression.
explicit DeclRefExpr(EmptyShell Empty)
: Expr(DeclRefExprClass, Empty) { }
- NamedDecl *getDecl() { return D; }
- const NamedDecl *getDecl() const { return D; }
- void setDecl(NamedDecl *NewD) { D = NewD; }
+ static DeclRefExpr *Create(ASTContext &Context,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ NamedDecl *D,
+ SourceLocation NameLoc,
+ QualType T, bool TD, bool VD);
+
+ static DeclRefExpr *Create(ASTContext &Context,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ NamedDecl *D,
+ SourceLocation NameLoc,
+ bool HasExplicitTemplateArgumentList,
+ SourceLocation LAngleLoc,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
+ SourceLocation RAngleLoc,
+ QualType T, bool TD, bool VD);
+
+ NamedDecl *getDecl() { return DecoratedD.getPointer(); }
+ const NamedDecl *getDecl() const { return DecoratedD.getPointer(); }
+ void setDecl(NamedDecl *NewD) { DecoratedD.setPointer(NewD); }
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
- virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+ virtual SourceRange getSourceRange() const;
+ /// \brief Determine whether this declaration reference was preceded by a
+ /// C++ nested-name-specifier, e.g., \c N::foo.
+ bool hasQualifier() const { return DecoratedD.getInt() & HasQualifierFlag; }
+
+ /// \brief If the name was qualified, retrieves the source range of
+ /// the nested-name-specifier that precedes the name. Otherwise,
+ /// returns an empty source range.
+ SourceRange getQualifierRange() const {
+ if (!hasQualifier())
+ return SourceRange();
+
+ return getNameQualifier()->Range;
+ }
+
+ /// \brief If the name was qualified, retrieves the nested-name-specifier
+ /// that precedes the name. Otherwise, returns NULL.
+ NestedNameSpecifier *getQualifier() const {
+ if (!hasQualifier())
+ return 0;
+
+ return getNameQualifier()->NNS;
+ }
+
+ /// \brief Determines whether this member expression actually had a C++
+ /// template argument list explicitly specified, e.g., x.f<int>.
+ bool hasExplicitTemplateArgumentList() const {
+ return DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag;
+ }
+
+ /// \brief Retrieve the location of the left angle bracket following the
+ /// member name ('<'), if any.
+ SourceLocation getLAngleLoc() const {
+ if (!hasExplicitTemplateArgumentList())
+ return SourceLocation();
+
+ return getExplicitTemplateArgumentList()->LAngleLoc;
+ }
+
+ /// \brief Retrieve the template arguments provided as part of this
+ /// template-id.
+ const TemplateArgumentLoc *getTemplateArgs() const {
+ if (!hasExplicitTemplateArgumentList())
+ return 0;
+
+ return getExplicitTemplateArgumentList()->getTemplateArgs();
+ }
+
+ /// \brief Retrieve the number of template arguments provided as part of this
+ /// template-id.
+ unsigned getNumTemplateArgs() const {
+ if (!hasExplicitTemplateArgumentList())
+ return 0;
+
+ return getExplicitTemplateArgumentList()->NumTemplateArgs;
+ }
+
+ /// \brief Retrieve the location of the right angle bracket following the
+ /// template arguments ('>').
+ SourceLocation getRAngleLoc() const {
+ if (!hasExplicitTemplateArgumentList())
+ return SourceLocation();
+
+ return getExplicitTemplateArgumentList()->RAngleLoc;
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == DeclRefExprClass ||
- T->getStmtClass() == CXXConditionDeclExprClass ||
- T->getStmtClass() == QualifiedDeclRefExprClass;
+ T->getStmtClass() == CXXConditionDeclExprClass;
}
static bool classof(const DeclRefExpr *) { return true; }
@@ -797,7 +976,7 @@ class SizeOfAlignOfExpr : public Expr {
bool isSizeof : 1; // true if sizeof, false if alignof.
bool isType : 1; // true if operand is a type, false if an expression
union {
- void *Ty;
+ DeclaratorInfo *Ty;
Stmt *Ex;
} Argument;
SourceLocation OpLoc, RParenLoc;
@@ -806,15 +985,15 @@ protected:
virtual void DoDestroy(ASTContext& C);
public:
- SizeOfAlignOfExpr(bool issizeof, QualType T,
+ SizeOfAlignOfExpr(bool issizeof, DeclaratorInfo *DInfo,
QualType resultType, SourceLocation op,
SourceLocation rp) :
Expr(SizeOfAlignOfExprClass, resultType,
false, // Never type-dependent (C++ [temp.dep.expr]p3).
// Value-dependent if the argument is type-dependent.
- T->isDependentType()),
+ DInfo->getType()->isDependentType()),
isSizeof(issizeof), isType(true), OpLoc(op), RParenLoc(rp) {
- Argument.Ty = T.getAsOpaquePtr();
+ Argument.Ty = DInfo;
}
SizeOfAlignOfExpr(bool issizeof, Expr *E,
@@ -837,8 +1016,11 @@ public:
bool isArgumentType() const { return isType; }
QualType getArgumentType() const {
+ return getArgumentTypeInfo()->getType();
+ }
+ DeclaratorInfo *getArgumentTypeInfo() const {
assert(isArgumentType() && "calling getArgumentType() when arg is expr");
- return QualType::getFromOpaquePtr(Argument.Ty);
+ return Argument.Ty;
}
Expr *getArgumentExpr() {
assert(!isArgumentType() && "calling getArgumentExpr() when arg is type");
@@ -849,8 +1031,8 @@ public:
}
void setArgument(Expr *E) { Argument.Ex = E; isType = false; }
- void setArgument(QualType T) {
- Argument.Ty = T.getAsOpaquePtr();
+ void setArgument(DeclaratorInfo *DInfo) {
+ Argument.Ty = DInfo;
isType = true;
}
@@ -1062,41 +1244,6 @@ public:
virtual child_iterator child_end();
};
-/// \brief Represents the qualifier that may precede a C++ name, e.g., the
-/// "std::" in "std::sort".
-struct NameQualifier {
- /// \brief The nested name specifier.
- NestedNameSpecifier *NNS;
-
- /// \brief The source range covered by the nested name specifier.
- SourceRange Range;
-};
-
-/// \brief Represents an explicit template argument list in C++, e.g.,
-/// the "<int>" in "sort<int>".
-struct ExplicitTemplateArgumentList {
- /// \brief The source location of the left angle bracket ('<');
- SourceLocation LAngleLoc;
-
- /// \brief The source location of the right angle bracket ('>');
- SourceLocation RAngleLoc;
-
- /// \brief The number of template arguments in TemplateArgs.
- /// The actual template arguments (if any) are stored after the
- /// ExplicitTemplateArgumentList structure.
- unsigned NumTemplateArgs;
-
- /// \brief Retrieve the template arguments
- TemplateArgument *getTemplateArgs() {
- return reinterpret_cast<TemplateArgument *> (this + 1);
- }
-
- /// \brief Retrieve the template arguments
- const TemplateArgument *getTemplateArgs() const {
- return reinterpret_cast<const TemplateArgument *> (this + 1);
- }
-};
-
/// MemberExpr - [C99 6.5.2.3] Structure and Union Members. X->F and X.F.
///
class MemberExpr : public Expr {
@@ -1161,7 +1308,7 @@ class MemberExpr : public Expr {
MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual,
SourceRange qualrange, NamedDecl *memberdecl, SourceLocation l,
bool has_explicit, SourceLocation langle,
- const TemplateArgument *targs, unsigned numtargs,
+ const TemplateArgumentLoc *targs, unsigned numtargs,
SourceLocation rangle, QualType ty);
public:
@@ -1183,7 +1330,7 @@ public:
SourceLocation l,
bool has_explicit,
SourceLocation langle,
- const TemplateArgument *targs,
+ const TemplateArgumentLoc *targs,
unsigned numtargs,
SourceLocation rangle,
QualType ty);
@@ -1240,7 +1387,7 @@ public:
/// \brief Retrieve the template arguments provided as part of this
/// template-id.
- const TemplateArgument *getTemplateArgs() const {
+ const TemplateArgumentLoc *getTemplateArgs() const {
if (!HasExplicitTemplateArgumentList)
return 0;
@@ -1388,6 +1535,10 @@ public:
/// member pointer in derived class.
CK_BaseToDerivedMemberPointer,
+ /// CK_DerivedToBaseMemberPointer - Member pointer in derived class to
+ /// member pointer in base class.
+ CK_DerivedToBaseMemberPointer,
+
/// CK_UserDefinedConversion - Conversion using a user defined type
/// conversion function.
CK_UserDefinedConversion,
@@ -1687,7 +1838,9 @@ public:
bool isAdditiveOp() const { return Opc == Add || Opc == Sub; }
static bool isShiftOp(Opcode Opc) { return Opc == Shl || Opc == Shr; }
bool isShiftOp() const { return isShiftOp(Opc); }
- bool isBitwiseOp() const { return Opc >= And && Opc <= Or; }
+
+ static bool isBitwiseOp(Opcode Opc) { return Opc >= And && Opc <= Or; }
+ bool isBitwiseOp() const { return isBitwiseOp(Opc); }
static bool isRelationalOp(Opcode Opc) { return Opc >= LT && Opc <= GE; }
bool isRelationalOp() const { return isRelationalOp(Opc); }
@@ -1695,6 +1848,9 @@ public:
static bool isEqualityOp(Opcode Opc) { return Opc == EQ || Opc == NE; }
bool isEqualityOp() const { return isEqualityOp(Opc); }
+ static bool isComparisonOp(Opcode Opc) { return Opc >= LT && Opc <= NE; }
+ bool isComparisonOp() const { return isComparisonOp(Opc); }
+
static bool isLogicalOp(Opcode Opc) { return Opc == LAnd || Opc == LOr; }
bool isLogicalOp() const { return isLogicalOp(Opc); }
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 3f66b1f..5931a3f 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -1061,46 +1061,11 @@ public:
virtual child_iterator child_end();
};
-/// QualifiedDeclRefExpr - A reference to a declared variable,
-/// function, enum, etc., that includes a qualification, e.g.,
-/// "N::foo".
-class QualifiedDeclRefExpr : public DeclRefExpr {
- /// QualifierRange - The source range that covers the
- /// nested-name-specifier.
- SourceRange QualifierRange;
-
- /// \brief The nested-name-specifier that qualifies this declaration
- /// name.
- NestedNameSpecifier *NNS;
-
-public:
- QualifiedDeclRefExpr(NamedDecl *d, QualType t, SourceLocation l, bool TD,
- bool VD, SourceRange R, NestedNameSpecifier *NNS)
- : DeclRefExpr(QualifiedDeclRefExprClass, d, t, l, TD, VD),
- QualifierRange(R), NNS(NNS) { }
-
- /// \brief Retrieve the source range of the nested-name-specifier.
- SourceRange getQualifierRange() const { return QualifierRange; }
-
- /// \brief Retrieve the nested-name-specifier that qualifies this
- /// declaration.
- NestedNameSpecifier *getQualifier() const { return NNS; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(QualifierRange.getBegin(), getLocation());
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == QualifiedDeclRefExprClass;
- }
- static bool classof(const QualifiedDeclRefExpr *) { return true; }
-};
-
/// \brief A qualified reference to a name whose declaration cannot
/// yet be resolved.
///
-/// UnresolvedDeclRefExpr is similar to QualifiedDeclRefExpr in that
-/// it expresses a qualified reference to a declaration such as
+/// UnresolvedDeclRefExpr is similar to eclRefExpr in that
+/// it expresses a reference to a declaration such as
/// X<T>::value. The difference, however, is that an
/// UnresolvedDeclRefExpr node is used only within C++ templates when
/// the qualification (e.g., X<T>::) refers to a dependent type. In
@@ -1108,8 +1073,8 @@ public:
/// declaration will differ from on instantiation of X<T> to the
/// next. Therefore, UnresolvedDeclRefExpr keeps track of the
/// qualifier (X<T>::) and the name of the entity being referenced
-/// ("value"). Such expressions will instantiate to
-/// QualifiedDeclRefExprs.
+/// ("value"). Such expressions will instantiate to a DeclRefExpr once the
+/// declaration can be found.
class UnresolvedDeclRefExpr : public Expr {
/// The name of the entity we will be referencing.
DeclarationName Name;
@@ -1126,6 +1091,7 @@ class UnresolvedDeclRefExpr : public Expr {
NestedNameSpecifier *NNS;
/// \brief Whether this expr is an address of (&) operand.
+ /// FIXME: Stash this bit into NNS!
bool IsAddressOfOperand;
public:
@@ -1195,7 +1161,7 @@ class TemplateIdRefExpr : public Expr {
NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
TemplateName Template, SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
+ const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc);
@@ -1206,7 +1172,7 @@ public:
Create(ASTContext &Context, QualType T,
NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
TemplateName Template, SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc, const TemplateArgument *TemplateArgs,
+ SourceLocation LAngleLoc, const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs, SourceLocation RAngleLoc);
/// \brief Retrieve the nested name specifier used to qualify the name of
@@ -1232,8 +1198,8 @@ public:
/// \brief Retrieve the template arguments provided as part of this
/// template-id.
- const TemplateArgument *getTemplateArgs() const {
- return reinterpret_cast<const TemplateArgument *>(this + 1);
+ const TemplateArgumentLoc *getTemplateArgs() const {
+ return reinterpret_cast<const TemplateArgumentLoc *>(this + 1);
}
/// \brief Retrieve the number of template arguments provided as part of this
@@ -1477,7 +1443,7 @@ class CXXUnresolvedMemberExpr : public Expr {
SourceLocation MemberLoc,
bool HasExplicitTemplateArgs,
SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
+ const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc);
@@ -1508,7 +1474,7 @@ public:
SourceLocation MemberLoc,
bool HasExplicitTemplateArgs,
SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
+ const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc);
@@ -1576,7 +1542,7 @@ public:
/// \brief Retrieve the template arguments provided as part of this
/// template-id.
- const TemplateArgument *getTemplateArgs() const {
+ const TemplateArgumentLoc *getTemplateArgs() const {
if (!HasExplicitTemplateArgumentList)
return 0;
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
index 7490b1d..5f318ba 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -14,7 +14,7 @@
#ifndef LLVM_CLANG_AST_LAYOUTINFO_H
#define LLVM_CLANG_AST_LAYOUTINFO_H
-#include "llvm/Support/DataTypes.h"
+#include "llvm/System/DataTypes.h"
namespace clang {
class ASTContext;
diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h
index 458af1f..1e6871f 100644
--- a/include/clang/AST/Redeclarable.h
+++ b/include/clang/AST/Redeclarable.h
@@ -88,6 +88,11 @@ public:
return D;
}
+ /// \brief Returns the most recent (re)declaration of this declaration.
+ const decl_type *getMostRecentDeclaration() const {
+ return getFirstDeclaration()->RedeclLink.getNext();
+ }
+
/// \brief Set the previous declaration. If PrevDecl is NULL, set this as the
/// first and only declaration.
void setPreviousDeclaration(decl_type *PrevDecl) {
diff --git a/include/clang/AST/StmtIterator.h b/include/clang/AST/StmtIterator.h
index 2d523ff..f1aa2cd5 100644
--- a/include/clang/AST/StmtIterator.h
+++ b/include/clang/AST/StmtIterator.h
@@ -14,7 +14,7 @@
#ifndef LLVM_CLANG_AST_STMT_ITR_H
#define LLVM_CLANG_AST_STMT_ITR_H
-#include "llvm/Support/DataTypes.h"
+#include "llvm/System/DataTypes.h"
#include <cassert>
#include <iterator>
diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def
index 8d7e4b5..034029a 100644
--- a/include/clang/AST/StmtNodes.def
+++ b/include/clang/AST/StmtNodes.def
@@ -127,7 +127,6 @@ EXPR(CXXDeleteExpr , Expr)
EXPR(CXXPseudoDestructorExpr, Expr)
EXPR(UnresolvedFunctionNameExpr , Expr)
EXPR(UnaryTypeTraitExpr , Expr)
-EXPR(QualifiedDeclRefExpr , DeclRefExpr)
EXPR(UnresolvedDeclRefExpr , Expr)
EXPR(TemplateIdRefExpr , Expr)
EXPR(CXXConstructExpr , Expr)
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
new file mode 100644
index 0000000..bb14c62
--- /dev/null
+++ b/include/clang/AST/TemplateBase.h
@@ -0,0 +1,366 @@
+//===-- TemplateBase.h - Core classes for C++ templates ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides definitions which are common for all kinds of
+// template representation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
+#define LLVM_CLANG_AST_TEMPLATEBASE_H
+
+#include "llvm/ADT/APSInt.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "clang/AST/Type.h"
+
+namespace llvm {
+ class FoldingSetNodeID;
+}
+
+namespace clang {
+
+class Decl;
+class Expr;
+class DeclaratorInfo;
+
+/// \brief Represents a template argument within a class template
+/// specialization.
+class TemplateArgument {
+ union {
+ uintptr_t TypeOrValue;
+ struct {
+ char Value[sizeof(llvm::APSInt)];
+ void *Type;
+ } Integer;
+ struct {
+ TemplateArgument *Args;
+ unsigned NumArgs;
+ bool CopyArgs;
+ } Args;
+ };
+
+public:
+ /// \brief The type of template argument we're storing.
+ enum ArgKind {
+ Null = 0,
+ /// The template argument is a type. Its value is stored in the
+ /// TypeOrValue field.
+ Type = 1,
+ /// The template argument is a declaration
+ Declaration = 2,
+ /// The template argument is an integral value stored in an llvm::APSInt.
+ Integral = 3,
+ /// The template argument is a value- or type-dependent expression
+ /// stored in an Expr*.
+ Expression = 4,
+
+ /// The template argument is actually a parameter pack. Arguments are stored
+ /// in the Args struct.
+ Pack = 5
+ } Kind;
+
+ /// \brief Construct an empty, invalid template argument.
+ TemplateArgument() : TypeOrValue(0), Kind(Null) { }
+
+ /// \brief Construct a template type argument.
+ TemplateArgument(QualType T) : Kind(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) {
+ // FIXME: Need to be sure we have the "canonical" declaration!
+ TypeOrValue = reinterpret_cast<uintptr_t>(D);
+ }
+
+ /// \brief Construct an integral constant template argument.
+ TemplateArgument(const llvm::APSInt &Value, QualType Type)
+ : Kind(Integral) {
+ new (Integer.Value) llvm::APSInt(Value);
+ Integer.Type = Type.getAsOpaquePtr();
+ }
+
+ /// \brief Construct a template argument that is an expression.
+ ///
+ /// This form of template argument only occurs in template argument
+ /// lists used for dependent types and for expression; it will not
+ /// occur in a non-dependent, canonical template argument list.
+ TemplateArgument(Expr *E) : Kind(Expression) {
+ TypeOrValue = reinterpret_cast<uintptr_t>(E);
+ }
+
+ /// \brief Copy constructor for a template argument.
+ TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
+ if (Kind == Integral) {
+ new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
+ Integer.Type = Other.Integer.Type;
+ } else if (Kind == Pack) {
+ Args.NumArgs = Other.Args.NumArgs;
+ Args.Args = new TemplateArgument[Args.NumArgs];
+ for (unsigned I = 0; I != Args.NumArgs; ++I)
+ Args.Args[I] = Other.Args.Args[I];
+ }
+ else
+ TypeOrValue = Other.TypeOrValue;
+ }
+
+ TemplateArgument& operator=(const TemplateArgument& Other) {
+ // FIXME: Does not provide the strong guarantee for exception
+ // safety.
+ using llvm::APSInt;
+
+ // FIXME: Handle Packs
+ assert(Kind != Pack && "FIXME: Handle packs");
+ assert(Other.Kind != Pack && "FIXME: Handle packs");
+
+ if (Kind == Other.Kind && Kind == Integral) {
+ // Copy integral values.
+ *this->getAsIntegral() = *Other.getAsIntegral();
+ Integer.Type = Other.Integer.Type;
+ } else {
+ // Destroy the current integral value, if that's what we're holding.
+ if (Kind == Integral)
+ getAsIntegral()->~APSInt();
+
+ Kind = Other.Kind;
+
+ if (Other.Kind == Integral) {
+ new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
+ Integer.Type = Other.Integer.Type;
+ } else
+ TypeOrValue = Other.TypeOrValue;
+ }
+
+ return *this;
+ }
+
+ ~TemplateArgument() {
+ using llvm::APSInt;
+
+ if (Kind == Integral)
+ getAsIntegral()->~APSInt();
+ else if (Kind == Pack && Args.CopyArgs)
+ delete[] Args.Args;
+ }
+
+ /// \brief Return the kind of stored template argument.
+ ArgKind getKind() const { return Kind; }
+
+ /// \brief Determine whether this template argument has no value.
+ bool isNull() const { return Kind == Null; }
+
+ /// \brief Retrieve the template argument as a type.
+ QualType getAsType() const {
+ if (Kind != Type)
+ return QualType();
+
+ 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 template argument as an integral value.
+ llvm::APSInt *getAsIntegral() {
+ if (Kind != Integral)
+ return 0;
+ return reinterpret_cast<llvm::APSInt*>(&Integer.Value[0]);
+ }
+
+ const llvm::APSInt *getAsIntegral() const {
+ return const_cast<TemplateArgument*>(this)->getAsIntegral();
+ }
+
+ /// \brief Retrieve the type of the integral value.
+ QualType getIntegralType() const {
+ if (Kind != Integral)
+ return QualType();
+
+ return QualType::getFromOpaquePtr(Integer.Type);
+ }
+
+ void setIntegralType(QualType T) {
+ assert(Kind == Integral &&
+ "Cannot set the integral type of a non-integral template argument");
+ Integer.Type = T.getAsOpaquePtr();
+ };
+
+ /// \brief Retrieve the template argument as an expression.
+ Expr *getAsExpr() const {
+ if (Kind != Expression)
+ return 0;
+
+ return reinterpret_cast<Expr *>(TypeOrValue);
+ }
+
+ /// \brief Iterator that traverses the elements of a template argument pack.
+ typedef const TemplateArgument * pack_iterator;
+
+ /// \brief Iterator referencing the first argument of a template argument
+ /// pack.
+ pack_iterator pack_begin() const {
+ assert(Kind == Pack);
+ return Args.Args;
+ }
+
+ /// \brief Iterator referencing one past the last argument of a template
+ /// argument pack.
+ pack_iterator pack_end() const {
+ assert(Kind == Pack);
+ return Args.Args + Args.NumArgs;
+ }
+
+ /// \brief The number of template arguments in the given template argument
+ /// pack.
+ unsigned pack_size() const {
+ assert(Kind == Pack);
+ return Args.NumArgs;
+ }
+
+ /// \brief Construct a template argument pack.
+ void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
+
+ /// \brief Used to insert TemplateArguments into FoldingSets.
+ void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context) const;
+};
+
+/// Location information for a TemplateArgument.
+struct TemplateArgumentLocInfo {
+private:
+ union {
+ Expr *Expression;
+ DeclaratorInfo *Declarator;
+ };
+
+#ifndef NDEBUG
+ enum Kind {
+ K_None,
+ K_DeclaratorInfo,
+ K_Expression
+ } Kind;
+#endif
+
+public:
+ TemplateArgumentLocInfo()
+ : Expression(0)
+#ifndef NDEBUG
+ , Kind(K_None)
+#endif
+ {}
+
+ TemplateArgumentLocInfo(DeclaratorInfo *DInfo)
+ : Declarator(DInfo)
+#ifndef NDEBUG
+ , Kind(K_DeclaratorInfo)
+#endif
+ {}
+
+ TemplateArgumentLocInfo(Expr *E)
+ : Expression(E)
+#ifndef NDEBUG
+ , Kind(K_Expression)
+#endif
+ {}
+
+ DeclaratorInfo *getAsDeclaratorInfo() const {
+ assert(Kind == K_DeclaratorInfo);
+ return Declarator;
+ }
+
+ Expr *getAsExpr() const {
+ assert(Kind == K_Expression);
+ return Expression;
+ }
+
+#ifndef NDEBUG
+ void validateForArgument(const TemplateArgument &Arg) {
+ switch (Arg.getKind()) {
+ case TemplateArgument::Type:
+ assert(Kind == K_DeclaratorInfo);
+ break;
+ case TemplateArgument::Expression:
+ case TemplateArgument::Declaration:
+ assert(Kind == K_Expression);
+ break;
+ case TemplateArgument::Integral:
+ case TemplateArgument::Pack:
+ assert(Kind == K_None);
+ break;
+ case TemplateArgument::Null:
+ llvm::llvm_unreachable("source info for null template argument?");
+ }
+ }
+#endif
+};
+
+/// Location wrapper for a TemplateArgument. TemplateArgument is to
+/// TemplateArgumentLoc as Type is to TypeLoc.
+class TemplateArgumentLoc {
+ TemplateArgument Argument;
+ TemplateArgumentLocInfo LocInfo;
+
+public:
+ TemplateArgumentLoc() {}
+
+ TemplateArgumentLoc(const TemplateArgument &Argument,
+ TemplateArgumentLocInfo Opaque)
+ : Argument(Argument), LocInfo(Opaque) {
+ }
+
+ TemplateArgumentLoc(const TemplateArgument &Argument, DeclaratorInfo *DInfo)
+ : Argument(Argument), LocInfo(DInfo) {
+ assert(Argument.getKind() == TemplateArgument::Type);
+ }
+
+ TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
+ : Argument(Argument), LocInfo(E) {
+ assert(Argument.getKind() == TemplateArgument::Expression);
+ }
+
+ /// \brief - Fetches the start location of the argument.
+ SourceLocation getLocation() const {
+ return getSourceRange().getBegin();
+ }
+
+ /// \brief - Fetches the full source range of the argument.
+ SourceRange getSourceRange() const;
+
+ const TemplateArgument &getArgument() const {
+ return Argument;
+ }
+
+ TemplateArgumentLocInfo getLocInfo() const {
+ return LocInfo;
+ }
+
+ DeclaratorInfo *getSourceDeclaratorInfo() const {
+ assert(Argument.getKind() == TemplateArgument::Type);
+ return LocInfo.getAsDeclaratorInfo();
+ }
+
+ Expr *getSourceExpression() const {
+ assert(Argument.getKind() == TemplateArgument::Expression);
+ return LocInfo.getAsExpr();
+ }
+
+ Expr *getSourceDeclExpression() const {
+ assert(Argument.getKind() == TemplateArgument::Declaration);
+ return LocInfo.getAsExpr();
+ }
+};
+
+}
+
+#endif
diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h
index 66ff34c..8ef8fb5 100644
--- a/include/clang/AST/TemplateName.h
+++ b/include/clang/AST/TemplateName.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerUnion.h"
+#include "clang/Basic/OperatorKinds.h"
namespace llvm {
class raw_ostream;
@@ -224,10 +225,24 @@ public:
class DependentTemplateName : public llvm::FoldingSetNode {
/// \brief The nested name specifier that qualifies the template
/// name.
- NestedNameSpecifier *Qualifier;
+ ///
+ /// The bit stored in this qualifier describes whether the \c Name field
+ /// is interpreted as an IdentifierInfo pointer (when clear) or as an
+ /// overloaded operator kind (when set).
+ llvm::PointerIntPair<NestedNameSpecifier *, 1, bool> Qualifier;
/// \brief The dependent template name.
- const IdentifierInfo *Name;
+ union {
+ /// \brief The identifier template name.
+ ///
+ /// Only valid when the bit on \c Qualifier is clear.
+ const IdentifierInfo *Identifier;
+
+ /// \brief The overloaded operator name.
+ ///
+ /// Only valid when the bit on \c Qualifier is set.
+ OverloadedOperatorKind Operator;
+ };
/// \brief The canonical template name to which this dependent
/// template name refers.
@@ -240,30 +255,70 @@ class DependentTemplateName : public llvm::FoldingSetNode {
friend class ASTContext;
DependentTemplateName(NestedNameSpecifier *Qualifier,
- const IdentifierInfo *Name)
- : Qualifier(Qualifier), Name(Name), CanonicalTemplateName(this) { }
+ const IdentifierInfo *Identifier)
+ : Qualifier(Qualifier, false), Identifier(Identifier),
+ CanonicalTemplateName(this) { }
DependentTemplateName(NestedNameSpecifier *Qualifier,
- const IdentifierInfo *Name,
+ const IdentifierInfo *Identifier,
TemplateName Canon)
- : Qualifier(Qualifier), Name(Name), CanonicalTemplateName(Canon) { }
+ : Qualifier(Qualifier, false), Identifier(Identifier),
+ CanonicalTemplateName(Canon) { }
+ DependentTemplateName(NestedNameSpecifier *Qualifier,
+ OverloadedOperatorKind Operator)
+ : Qualifier(Qualifier, true), Operator(Operator),
+ CanonicalTemplateName(this) { }
+
+ DependentTemplateName(NestedNameSpecifier *Qualifier,
+ OverloadedOperatorKind Operator,
+ TemplateName Canon)
+ : Qualifier(Qualifier, true), Operator(Operator),
+ CanonicalTemplateName(Canon) { }
+
public:
/// \brief Return the nested name specifier that qualifies this name.
- NestedNameSpecifier *getQualifier() const { return Qualifier; }
+ NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
- /// \brief Return the name to which this dependent template name
- /// refers.
- const IdentifierInfo *getName() const { return Name; }
+ /// \brief Determine whether this template name refers to an identifier.
+ bool isIdentifier() const { return !Qualifier.getInt(); }
+ /// \brief Returns the identifier to which this template name refers.
+ const IdentifierInfo *getIdentifier() const {
+ assert(isIdentifier() && "Template name isn't an identifier?");
+ return Identifier;
+ }
+
+ /// \brief Determine whether this template name refers to an overloaded
+ /// operator.
+ bool isOverloadedOperator() const { return Qualifier.getInt(); }
+
+ /// \brief Return the overloaded operator to which this template name refers.
+ OverloadedOperatorKind getOperator() const {
+ assert(isOverloadedOperator() &&
+ "Template name isn't an overloaded operator?");
+ return Operator;
+ }
+
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getQualifier(), getName());
+ if (isIdentifier())
+ Profile(ID, getQualifier(), getIdentifier());
+ else
+ Profile(ID, getQualifier(), getOperator());
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
+ const IdentifierInfo *Identifier) {
+ ID.AddPointer(NNS);
+ ID.AddBoolean(false);
+ ID.AddPointer(Identifier);
}
static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
- const IdentifierInfo *Name) {
+ OverloadedOperatorKind Operator) {
ID.AddPointer(NNS);
- ID.AddPointer(Name);
+ ID.AddBoolean(true);
+ ID.AddInteger(Operator);
}
};
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index db02a68..daa8147 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -81,6 +81,7 @@ namespace clang {
class SourceLocation;
class StmtIteratorBase;
class TemplateArgument;
+ class TemplateArgumentLoc;
class QualifiedNameType;
struct PrintingPolicy;
@@ -2275,12 +2276,19 @@ public:
static bool anyDependentTemplateArguments(const TemplateArgument *Args,
unsigned NumArgs);
+ static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args,
+ unsigned NumArgs);
+
/// \brief Print a template argument list, including the '<' and '>'
/// enclosing the template arguments.
static std::string PrintTemplateArgumentList(const TemplateArgument *Args,
unsigned NumArgs,
const PrintingPolicy &Policy);
+ static std::string PrintTemplateArgumentList(const TemplateArgumentLoc *Args,
+ unsigned NumArgs,
+ const PrintingPolicy &Policy);
+
typedef const TemplateArgument * iterator;
iterator begin() const { return getArgs(); }
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 1d7181b..da78578 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_TYPELOC_H
#include "clang/AST/Type.h"
+#include "clang/AST/TemplateBase.h"
namespace clang {
class ParmVarDecl;
@@ -82,6 +83,19 @@ public:
return Data;
}
+ /// \brief Get the full source range.
+ SourceRange getFullSourceRange() const {
+ SourceLocation End = getSourceRange().getEnd();
+ TypeLoc Cur = *this;
+ while (true) {
+ TypeLoc Next = Cur.getNextTypeLoc();
+ if (Next.isNull()) break;
+ Cur = Next;
+ }
+ return SourceRange(Cur.getSourceRange().getBegin(), End);
+ }
+
+ /// \brief Get the local source range.
SourceRange getSourceRange() const {
return getSourceRangeImpl(*this);
}
@@ -761,6 +775,10 @@ public:
getLocalData()->RBracketLoc = Loc;
}
+ SourceRange getBracketsRange() const {
+ return SourceRange(getLBracketLoc(), getRBracketLoc());
+ }
+
Expr *getSizeExpr() const {
return getLocalData()->Size;
}
@@ -810,6 +828,118 @@ class VariableArrayTypeLoc :
VariableArrayType> {
};
+
+// Location information for a TemplateName. Rudimentary for now.
+struct TemplateNameLocInfo {
+ SourceLocation NameLoc;
+};
+
+struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
+ SourceLocation LAngleLoc;
+ SourceLocation RAngleLoc;
+};
+
+class TemplateSpecializationTypeLoc :
+ public ConcreteTypeLoc<UnqualTypeLoc,
+ TemplateSpecializationTypeLoc,
+ TemplateSpecializationType,
+ TemplateSpecializationLocInfo> {
+public:
+ SourceLocation getLAngleLoc() const {
+ return getLocalData()->LAngleLoc;
+ }
+ void setLAngleLoc(SourceLocation Loc) {
+ getLocalData()->LAngleLoc = Loc;
+ }
+
+ SourceLocation getRAngleLoc() const {
+ return getLocalData()->RAngleLoc;
+ }
+ void setRAngleLoc(SourceLocation Loc) {
+ getLocalData()->RAngleLoc = Loc;
+ }
+
+ unsigned getNumArgs() const {
+ return getTypePtr()->getNumArgs();
+ }
+ void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
+#ifndef NDEBUG
+ AI.validateForArgument(getTypePtr()->getArg(i));
+#endif
+ getArgInfos()[i] = AI;
+ }
+ TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
+ return getArgInfos()[i];
+ }
+
+ TemplateArgumentLoc getArgLoc(unsigned i) const {
+ return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
+ }
+
+ SourceLocation getTemplateNameLoc() const {
+ return getLocalData()->NameLoc;
+ }
+ void setTemplateNameLoc(SourceLocation Loc) {
+ getLocalData()->NameLoc = Loc;
+ }
+
+ /// \brief - Copy the location information from the given info.
+ void copy(TemplateSpecializationTypeLoc Loc) {
+ unsigned size = getFullDataSize();
+ assert(size == Loc.getFullDataSize());
+
+ // We're potentially copying Expr references here. We don't
+ // bother retaining them because DeclaratorInfos live forever, so
+ // as long as the Expr was retained when originally written into
+ // the TypeLoc, we're okay.
+ memcpy(Data, Loc.Data, size);
+ }
+
+ SourceRange getSourceRange() const {
+ return SourceRange(getTemplateNameLoc(), getRAngleLoc());
+ }
+
+ void initializeLocal(SourceLocation Loc) {
+ setLAngleLoc(Loc);
+ setRAngleLoc(Loc);
+ setTemplateNameLoc(Loc);
+
+ for (unsigned i = 0, e = getNumArgs(); i != e; ++i) {
+ TemplateArgumentLocInfo Info;
+#ifndef NDEBUG
+ // If asserts are enabled, be sure to initialize the argument
+ // loc with the right kind of pointer.
+ switch (getTypePtr()->getArg(i).getKind()) {
+ case TemplateArgument::Expression:
+ case TemplateArgument::Declaration:
+ Info = TemplateArgumentLocInfo((Expr*) 0);
+ break;
+
+ case TemplateArgument::Type:
+ Info = TemplateArgumentLocInfo((DeclaratorInfo*) 0);
+ break;
+
+ case TemplateArgument::Integral:
+ case TemplateArgument::Pack:
+ case TemplateArgument::Null:
+ // K_None is fine.
+ break;
+ }
+#endif
+ getArgInfos()[i] = Info;
+ }
+ }
+
+ unsigned getExtraLocalDataSize() const {
+ return getNumArgs() * sizeof(TemplateArgumentLocInfo);
+ }
+
+private:
+ TemplateArgumentLocInfo *getArgInfos() const {
+ return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
+ }
+};
+
// None of these types have proper implementations yet.
class VectorTypeLoc : public TypeSpecTypeLoc<VectorTypeLoc, VectorType> {
@@ -861,11 +991,6 @@ class ElaboratedTypeLoc : public TypeSpecTypeLoc<ElaboratedTypeLoc,
ElaboratedType> {
};
-class TemplateSpecializationTypeLoc
- : public TypeSpecTypeLoc<TemplateSpecializationTypeLoc,
- TemplateSpecializationType> {
-};
-
class QualifiedNameTypeLoc : public TypeSpecTypeLoc<QualifiedNameTypeLoc,
QualifiedNameType> {
};
OpenPOWER on IntegriCloud