aboutsummaryrefslogtreecommitdiffstats
path: root/include/clang/AST
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2009-10-23 14:22:18 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2009-10-23 14:22:18 +0000
commit73490b890977362d28dd6326843a1ecae413921d (patch)
tree3fdd91eae574e32453a4baf462961c742df2691a /include/clang/AST
parenta5f348eb914e67b51914117fac117c18c1f8d650 (diff)
downloadsrc-73490b890977362d28dd6326843a1ecae413921d.tar.gz
src-73490b890977362d28dd6326843a1ecae413921d.zip
Update clang to r84949.vendor/clang/clang-r84949
Notes
Notes: svn path=/vendor/clang/dist/; revision=198398 svn path=/vendor/clang/clang-r84949/; revision=198399; tag=vendor/clang/clang-r84949
Diffstat (limited to 'include/clang/AST')
-rw-r--r--include/clang/AST/ASTContext.h82
-rw-r--r--include/clang/AST/Attr.h1
-rw-r--r--include/clang/AST/CXXInheritance.h3
-rw-r--r--include/clang/AST/CanonicalType.h26
-rw-r--r--include/clang/AST/Decl.h50
-rw-r--r--include/clang/AST/DeclBase.h36
-rw-r--r--include/clang/AST/DeclObjC.h36
-rw-r--r--include/clang/AST/Expr.h25
-rw-r--r--include/clang/AST/Type.h255
-rw-r--r--include/clang/AST/TypeLoc.h690
-rw-r--r--include/clang/AST/TypeLocBuilder.h122
-rw-r--r--include/clang/AST/TypeLocNodes.def46
-rw-r--r--include/clang/AST/TypeLocVisitor.h44
-rw-r--r--include/clang/AST/TypeNodes.def5
14 files changed, 907 insertions, 514 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 106d568c9b24..30896c91a143 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -81,12 +81,12 @@ class ASTContext {
llvm::FoldingSet<DependentTypeOfExprType> DependentTypeOfExprTypes;
llvm::FoldingSet<DependentDecltypeType> DependentDecltypeTypes;
llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
+ llvm::FoldingSet<SubstTemplateTypeParmType> SubstTemplateTypeParmTypes;
llvm::FoldingSet<TemplateSpecializationType> TemplateSpecializationTypes;
llvm::FoldingSet<QualifiedNameType> QualifiedNameTypes;
llvm::FoldingSet<TypenameType> TypenameTypes;
llvm::FoldingSet<ObjCInterfaceType> ObjCInterfaceTypes;
llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
- llvm::FoldingSet<ObjCProtocolListType> ObjCProtocolListTypes;
llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
@@ -143,6 +143,12 @@ class ASTContext {
/// \brief The type for the C sigjmp_buf type.
TypeDecl *sigjmp_bufDecl;
+ /// \brief Type for the Block descriptor for Blocks CodeGen.
+ RecordDecl *BlockDescriptorType;
+
+ /// \brief Type for the Block descriptor for Blocks CodeGen.
+ RecordDecl *BlockDescriptorExtendedType;
+
/// \brief Keeps track of all declaration attributes.
///
/// Since so few decls have attrs, we keep them in a hash map instead of
@@ -390,9 +396,47 @@ public:
/// of the specified type.
QualType getBlockPointerType(QualType T);
+ /// This gets the struct used to keep track of the descriptor for pointer to
+ /// blocks.
+ QualType getBlockDescriptorType();
+
+ // Set the type for a Block descriptor type.
+ void setBlockDescriptorType(QualType T);
+ /// Get the BlockDescriptorType type, or NULL if it hasn't yet been built.
+ QualType getRawBlockdescriptorType() {
+ if (BlockDescriptorType)
+ return getTagDeclType(BlockDescriptorType);
+ return QualType();
+ }
+
+ /// This gets the struct used to keep track of the extended descriptor for
+ /// pointer to blocks.
+ QualType getBlockDescriptorExtendedType();
+
+ // Set the type for a Block descriptor extended type.
+ void setBlockDescriptorExtendedType(QualType T);
+ /// Get the BlockDescriptorExtendedType type, or NULL if it hasn't yet been
+ /// built.
+ QualType getRawBlockdescriptorExtendedType() {
+ if (BlockDescriptorExtendedType)
+ return getTagDeclType(BlockDescriptorExtendedType);
+ return QualType();
+ }
+
+ /// This gets the struct used to keep track of pointer to blocks, complete
+ /// with captured variables.
+ QualType getBlockParmType(bool BlockHasCopyDispose,
+ llvm::SmallVector<const Expr *, 8> &BDRDs);
+
+ /// This builds the struct used for __block variables.
+ QualType BuildByRefType(const char *DeclName, QualType Ty);
+
+ /// Returns true iff we need copy/dispose helpers for the given type.
+ bool BlockRequiresCopying(QualType Ty);
+
/// getLValueReferenceType - Return the uniqued reference to the type for an
/// lvalue reference to the specified type.
- QualType getLValueReferenceType(QualType T);
+ QualType getLValueReferenceType(QualType T, bool SpelledAsLValue = true);
/// getRValueReferenceType - Return the uniqued reference to the type for an
/// rvalue reference to the specified type.
@@ -431,22 +475,6 @@ public:
ArrayType::ArraySizeModifier ASM,
unsigned EltTypeQuals);
- /// getConstantArrayWithExprType - Return a reference to the type for a
- /// constant array of the specified element type.
- QualType getConstantArrayWithExprType(QualType EltTy,
- const llvm::APInt &ArySize,
- Expr *ArySizeExpr,
- ArrayType::ArraySizeModifier ASM,
- unsigned EltTypeQuals,
- SourceRange Brackets);
-
- /// getConstantArrayWithoutExprType - Return a reference to the type
- /// for a constant array of the specified element type.
- QualType getConstantArrayWithoutExprType(QualType EltTy,
- const llvm::APInt &ArySize,
- ArrayType::ArraySizeModifier ASM,
- unsigned EltTypeQuals);
-
/// getVectorType - Return the unique reference to a vector type of
/// the specified element type and size. VectorType must be a built-in type.
QualType getVectorType(QualType VectorType, unsigned NumElts);
@@ -485,6 +513,9 @@ public:
/// specified typename decl.
QualType getTypedefType(TypedefDecl *Decl);
+ QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
+ QualType Replacement);
+
QualType getTemplateTypeParmType(unsigned Depth, unsigned Index,
bool ParameterPack,
IdentifierInfo *Name = 0);
@@ -515,10 +546,6 @@ public:
ObjCProtocolDecl **ProtocolList = 0,
unsigned NumProtocols = 0);
- QualType getObjCProtocolListType(QualType T,
- ObjCProtocolDecl **Protocols,
- unsigned NumProtocols);
-
/// getTypeOfType - GCC extension.
QualType getTypeOfExprType(Expr *e);
QualType getTypeOfType(QualType t);
@@ -815,6 +842,12 @@ public:
return T->getCanonicalTypeInternal().getTypePtr();
}
+ /// getCanonicalParamType - Return the canonical parameter type
+ /// corresponding to the specific potentially non-canonical one.
+ /// Qualifiers are stripped off, functions are turned into function
+ /// pointers, and arrays decay one level into pointers.
+ CanQualType getCanonicalParamType(QualType T);
+
/// \brief Determine whether the given types are equivalent.
bool hasSameType(QualType T1, QualType T2) {
return getCanonicalType(T1) == getCanonicalType(T2);
@@ -1047,7 +1080,10 @@ public:
/// \param T the type that will be the basis for type source info. This type
/// should refer to how the declarator was written in source code, not to
/// what type semantic analysis resolved the declarator to.
- DeclaratorInfo *CreateDeclaratorInfo(QualType T);
+ ///
+ /// \param Size the size of the type info to create, or 0 if the size
+ /// should be calculated based on the type.
+ DeclaratorInfo *CreateDeclaratorInfo(QualType T, unsigned Size = 0);
private:
ASTContext(const ASTContext&); // DO NOT IMPLEMENT
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 6a5e3666a92c..f7a47364a7f6 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -185,7 +185,6 @@ class AlignedAttr : public Attr {
public:
AlignedAttr(unsigned alignment) : Attr(Aligned), Alignment(alignment) {}
- // FIXME: Should use addressable units, not bits, to match llvm
/// getAlignment - The specified alignment in bits.
unsigned getAlignment() const { return Alignment; }
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index a57bcc184a93..7c826fe75d11 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -63,7 +63,8 @@ struct CXXBasePathElement {
/// structure, which captures both the link from a derived class to one of its
/// direct bases and identification describing which base class
/// subobject is being used.
-struct CXXBasePath : public llvm::SmallVector<CXXBasePathElement, 4> {
+class CXXBasePath : public llvm::SmallVector<CXXBasePathElement, 4> {
+public:
/// \brief The set of declarations found inside this base class
/// subobject.
DeclContext::lookup_result Decls;
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index d7ac76dd32e4..8b84bc267997 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -487,30 +487,6 @@ struct CanProxyAdaptor<ConstantArrayType>
};
template<>
-struct CanProxyAdaptor<ConstantArrayWithExprType>
- : public CanProxyBase<ConstantArrayWithExprType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
- getSizeModifier)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
-};
-
-template<>
-struct CanProxyAdaptor<ConstantArrayWithoutExprType>
- : public CanProxyBase<ConstantArrayWithoutExprType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
- getSizeModifier)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize)
-};
-
-template<>
struct CanProxyAdaptor<IncompleteArrayType>
: public CanProxyBase<IncompleteArrayType> {
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
@@ -684,7 +660,7 @@ CanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) {
template<typename T>
CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
- assert((Other.isNull() || Other->isCanonical()) && "Type is not canonical!");
+ assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!");
assert((Other.isNull() || isa<T>(Other.getTypePtr())) &&
"Dynamic type does not meet the static type's requires");
CanQual<T> Result;
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index f21541c3e710..72ce0d852cfc 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -47,6 +47,9 @@ class DeclaratorInfo {
friend class ASTContext;
DeclaratorInfo(QualType ty) : Ty(ty) { }
public:
+ /// \brief Return the type wrapped by this type source info.
+ QualType getType() const { return Ty; }
+
/// \brief Return the TypeLoc wrapper for the type source info.
TypeLoc getTypeLoc() const;
};
@@ -93,28 +96,43 @@ public:
/// name (C++ constructor, Objective-C selector, etc.).
IdentifierInfo *getIdentifier() const { return Name.getAsIdentifierInfo(); }
+ /// getName - Get the name of identifier for this declaration as a StringRef.
+ /// This requires that the declaration have a name and that it be a simple
+ /// identifier.
+ llvm::StringRef getName() const {
+ assert(Name.isIdentifier() && "Name is not a simple identifier");
+ return getIdentifier() ? getIdentifier()->getName() : "";
+ }
+
/// getNameAsCString - Get the name of identifier for this declaration as a
/// C string (const char*). This requires that the declaration have a name
/// and that it be a simple identifier.
+ //
+ // FIXME: Deprecated, move clients to getName().
const char *getNameAsCString() const {
- assert(getIdentifier() && "Name is not a simple identifier");
- return getIdentifier()->getName();
+ assert(Name.isIdentifier() && "Name is not a simple identifier");
+ return getIdentifier() ? getIdentifier()->getNameStart() : "";
}
- /// getDeclName - Get the actual, stored name of the declaration,
- /// which may be a special name.
- DeclarationName getDeclName() const { return Name; }
-
- /// \brief Set the name of this declaration.
- void setDeclName(DeclarationName N) { Name = N; }
-
/// getNameAsString - Get a human-readable name for the declaration, even if
/// it is one of the special kinds of names (C++ constructor, Objective-C
/// selector, etc). Creating this name requires expensive string
/// manipulation, so it should be called only when performance doesn't matter.
/// For simple declarations, getNameAsCString() should suffice.
+ //
+ // FIXME: This function should be renamed to indicate that it is not just an
+ // alternate form of getName(), and clients should move as appropriate.
+ //
+ // FIXME: Deprecated, move clients to getName().
std::string getNameAsString() const { return Name.getAsString(); }
+ /// getDeclName - Get the actual, stored name of the declaration,
+ /// which may be a special name.
+ DeclarationName getDeclName() const { return Name; }
+
+ /// \brief Set the name of this declaration.
+ void setDeclName(DeclarationName N) { Name = N; }
+
/// getQualifiedNameAsString - Returns human-readable qualified name for
/// declaration, like A::B::i, for i being member of namespace A::B.
/// If declaration is not member of context which can be named (record,
@@ -604,7 +622,8 @@ public:
/// \brief For a static data member that was instantiated from a static
/// data member of a class template, set the template specialiation kind.
- void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
+ void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
+ SourceLocation PointOfInstantiation = SourceLocation());
/// isFileVarDecl - Returns true for file scoped variable declaration.
bool isFileVarDecl() const {
@@ -1170,7 +1189,16 @@ public:
/// \brief Determine what kind of template instantiation this function
/// represents.
- void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
+ void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
+ SourceLocation PointOfInstantiation = SourceLocation());
+
+ /// \brief Retrieve the (first) point of instantiation of a function template
+ /// specialization or a member of a class template specialization.
+ ///
+ /// \returns the first point of instantiation, if this function was
+ /// 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.
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 9e88871565f1..10db7030db18 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -166,6 +166,15 @@ private:
bool Used : 1;
protected:
+ /// Access - Used by C++ decls for the access specifier.
+ // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
+ unsigned Access : 2;
+ friend class CXXClassMemberWrapper;
+
+ // PCHLevel - the "level" of precompiled header/AST file from which this
+ // declaration was built.
+ unsigned PCHLevel : 2;
+
/// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
unsigned IdentifierNamespace : 16;
@@ -177,16 +186,13 @@ private:
#endif
protected:
- /// Access - Used by C++ decls for the access specifier.
- // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
- unsigned Access : 2;
- friend class CXXClassMemberWrapper;
Decl(Kind DK, DeclContext *DC, SourceLocation L)
: NextDeclInContext(0), DeclCtx(DC),
Loc(L), DeclKind(DK), InvalidDecl(0),
HasAttrs(false), Implicit(false), Used(false),
- IdentifierNamespace(getIdentifierNamespaceForKind(DK)), Access(AS_none) {
+ Access(AS_none), PCHLevel(0),
+ IdentifierNamespace(getIdentifierNamespaceForKind(DK)) {
if (Decl::CollectingStats()) addDeclKind(DK);
}
@@ -274,6 +280,26 @@ public:
bool isUsed() const { return Used; }
void setUsed(bool U = true) { Used = U; }
+ /// \brief Retrieve the level of precompiled header from which this
+ /// declaration was generated.
+ ///
+ /// The PCH level of a declaration describes where the declaration originated
+ /// from. A PCH level of 0 indicates that the declaration was not from a
+ /// precompiled header. A PCH level of 1 indicates that the declaration was
+ /// from a top-level precompiled header; 2 indicates that the declaration
+ /// comes from a precompiled header on which the top-level precompiled header
+ /// depends, and so on.
+ unsigned getPCHLevel() const { return PCHLevel; }
+
+ /// \brief The maximum PCH level that any declaration may have.
+ static const unsigned MaxPCHLevel = 3;
+
+ /// \brief Set the PCH level of this declaration.
+ void setPCHLevel(unsigned Level) {
+ assert(Level < MaxPCHLevel && "PCH level exceeds the maximum");
+ PCHLevel = Level;
+ }
+
unsigned getIdentifierNamespace() const {
return IdentifierNamespace;
}
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 2b12bb5c1b6d..729a2f138303 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -944,16 +944,29 @@ public:
ObjCCategoryDecl *getCategoryClass() const;
+ /// getName - Get the name of identifier for the class interface associated
+ /// with this implementation as a StringRef.
+ //
+ // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
+ // something different.
+ llvm::StringRef getName() const {
+ return Id ? Id->getNameStart() : "";
+ }
+
/// getNameAsCString - Get the name of identifier for the class
/// interface associated with this implementation as a C string
/// (const char*).
+ //
+ // FIXME: Deprecated, move clients to getName().
const char *getNameAsCString() const {
- return Id ? Id->getName() : "";
+ return Id ? Id->getNameStart() : "";
}
/// @brief Get the name of the class associated with this interface.
+ //
+ // FIXME: Deprecated, move clients to getName().
std::string getNameAsString() const {
- return Id ? Id->getName() : "";
+ return getName();
}
static bool classof(const Decl *D) { return D->getKind() == ObjCCategoryImpl;}
@@ -995,17 +1008,30 @@ public:
return getClassInterface()->getIdentifier();
}
+ /// getName - Get the name of identifier for the class interface associated
+ /// with this implementation as a StringRef.
+ //
+ // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
+ // something different.
+ llvm::StringRef getName() const {
+ assert(getIdentifier() && "Name is not a simple identifier");
+ return getIdentifier()->getName();
+ }
+
/// getNameAsCString - Get the name of identifier for the class
/// interface associated with this implementation as a C string
/// (const char*).
+ //
+ // FIXME: Move to StringRef API.
const char *getNameAsCString() const {
- assert(getIdentifier() && "Name is not a simple identifier");
- return getIdentifier()->getName();
+ return getName().data();
}
/// @brief Get the name of the class associated with this interface.
+ //
+ // FIXME: Move to StringRef API.
std::string getNameAsString() const {
- return getClassInterface()->getNameAsString();
+ return getName();
}
const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index d5dff5065d49..0d09ea325c31 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -1399,7 +1399,27 @@ public:
CK_IntegralToPointer,
/// CK_PointerToIntegral - Pointer to integral
- CK_PointerToIntegral
+ CK_PointerToIntegral,
+
+ /// CK_ToVoid - Cast to void.
+ CK_ToVoid,
+
+ /// CK_VectorSplat - Casting from an integer/floating type to an extended
+ /// vector type with the same element type as the src type. Splats the
+ /// src expression into the destination expression.
+ CK_VectorSplat,
+
+ /// CK_IntegralCast - Casting between integral types of different size.
+ CK_IntegralCast,
+
+ /// CK_IntegralToFloating - Integral to floating point.
+ CK_IntegralToFloating,
+
+ /// CK_FloatingToIntegral - Floating point to integral.
+ CK_FloatingToIntegral,
+
+ /// CK_FloatingCast - Casting between floating types of different size.
+ CK_FloatingCast
};
private:
@@ -1665,7 +1685,8 @@ public:
/// predicates to categorize the respective opcodes.
bool isMultiplicativeOp() const { return Opc >= Mul && Opc <= Rem; }
bool isAdditiveOp() const { return Opc == Add || Opc == Sub; }
- bool isShiftOp() const { return Opc == Shl || Opc == Shr; }
+ 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 isRelationalOp(Opcode Opc) { return Opc >= LT && Opc <= GE; }
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 89776b91fe4a..db02a68a984d 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -443,6 +443,9 @@ public:
return getTypePtr();
}
+ bool isCanonical() const;
+ bool isCanonicalAsParam() const;
+
/// isNull - Return true if this QualType doesn't point to a type yet.
bool isNull() const {
return Value.getPointer().isNull();
@@ -702,7 +705,9 @@ protected:
public:
TypeClass getTypeClass() const { return static_cast<TypeClass>(TC); }
- bool isCanonical() const { return CanonicalType.getTypePtr() == this; }
+ bool isCanonicalUnqualified() const {
+ return CanonicalType.getTypePtr() == this;
+ }
/// Types are partitioned into 3 broad categories (C99 6.2.5p1):
/// object types, function types, and incomplete types.
@@ -1089,19 +1094,50 @@ public:
class ReferenceType : public Type, public llvm::FoldingSetNode {
QualType PointeeType;
+ /// True if the type was originally spelled with an lvalue sigil.
+ /// This is never true of rvalue references but can also be false
+ /// on lvalue references because of C++0x [dcl.typedef]p9,
+ /// as follows:
+ ///
+ /// typedef int &ref; // lvalue, spelled lvalue
+ /// typedef int &&rvref; // rvalue
+ /// ref &a; // lvalue, inner ref, spelled lvalue
+ /// ref &&a; // lvalue, inner ref
+ /// rvref &a; // lvalue, inner ref, spelled lvalue
+ /// rvref &&a; // rvalue, inner ref
+ bool SpelledAsLValue;
+
+ /// True if the inner type is a reference type. This only happens
+ /// in non-canonical forms.
+ bool InnerRef;
+
protected:
- ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef) :
+ ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef,
+ bool SpelledAsLValue) :
Type(tc, CanonicalRef, Referencee->isDependentType()),
- PointeeType(Referencee) {
+ PointeeType(Referencee), SpelledAsLValue(SpelledAsLValue),
+ InnerRef(Referencee->isReferenceType()) {
}
public:
- QualType getPointeeType() const { return PointeeType; }
+ bool isSpelledAsLValue() const { return SpelledAsLValue; }
+
+ QualType getPointeeTypeAsWritten() const { return PointeeType; }
+ QualType getPointeeType() const {
+ // FIXME: this might strip inner qualifiers; okay?
+ const ReferenceType *T = this;
+ while (T->InnerRef)
+ T = T->PointeeType->getAs<ReferenceType>();
+ return T->PointeeType;
+ }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPointeeType());
+ Profile(ID, PointeeType, SpelledAsLValue);
}
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Referencee) {
+ static void Profile(llvm::FoldingSetNodeID &ID,
+ QualType Referencee,
+ bool SpelledAsLValue) {
ID.AddPointer(Referencee.getAsOpaquePtr());
+ ID.AddBoolean(SpelledAsLValue);
}
static bool classof(const Type *T) {
@@ -1114,9 +1150,10 @@ public:
/// LValueReferenceType - C++ [dcl.ref] - Lvalue reference
///
class LValueReferenceType : public ReferenceType {
- LValueReferenceType(QualType Referencee, QualType CanonicalRef) :
- ReferenceType(LValueReference, Referencee, CanonicalRef) {
- }
+ LValueReferenceType(QualType Referencee, QualType CanonicalRef,
+ bool SpelledAsLValue) :
+ ReferenceType(LValueReference, Referencee, CanonicalRef, SpelledAsLValue)
+ {}
friend class ASTContext; // ASTContext creates these
public:
virtual void getAsStringInternal(std::string &InnerString,
@@ -1135,7 +1172,7 @@ public:
///
class RValueReferenceType : public ReferenceType {
RValueReferenceType(QualType Referencee, QualType CanonicalRef) :
- ReferenceType(RValueReference, Referencee, CanonicalRef) {
+ ReferenceType(RValueReference, Referencee, CanonicalRef, false) {
}
friend class ASTContext; // ASTContext creates these
public:
@@ -1239,8 +1276,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == ConstantArray ||
- T->getTypeClass() == ConstantArrayWithExpr ||
- T->getTypeClass() == ConstantArrayWithoutExpr ||
T->getTypeClass() == VariableArray ||
T->getTypeClass() == IncompleteArray ||
T->getTypeClass() == DependentSizedArray;
@@ -1285,86 +1320,11 @@ public:
ID.AddInteger(TypeQuals);
}
static bool classof(const Type *T) {
- return T->getTypeClass() == ConstantArray ||
- T->getTypeClass() == ConstantArrayWithExpr ||
- T->getTypeClass() == ConstantArrayWithoutExpr;
+ return T->getTypeClass() == ConstantArray;
}
static bool classof(const ConstantArrayType *) { return true; }
};
-/// ConstantArrayWithExprType - This class represents C arrays with a
-/// constant size specified by means of an integer constant expression.
-/// For example 'int A[sizeof(int)]' has ConstantArrayWithExprType where
-/// the element type is 'int' and the size expression is 'sizeof(int)'.
-/// These types are non-canonical.
-class ConstantArrayWithExprType : public ConstantArrayType {
- /// SizeExpr - The ICE occurring in the concrete syntax.
- Expr *SizeExpr;
- /// Brackets - The left and right array brackets.
- SourceRange Brackets;
-
- ConstantArrayWithExprType(QualType et, QualType can,
- const llvm::APInt &size, Expr *e,
- ArraySizeModifier sm, unsigned tq,
- SourceRange brackets)
- : ConstantArrayType(ConstantArrayWithExpr, et, can, size, sm, tq),
- SizeExpr(e), Brackets(brackets) {}
- friend class ASTContext; // ASTContext creates these.
- virtual void Destroy(ASTContext& C);
-
-public:
- Expr *getSizeExpr() const { return SizeExpr; }
- SourceRange getBracketsRange() const { return Brackets; }
- SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
- SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
-
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == ConstantArrayWithExpr;
- }
- static bool classof(const ConstantArrayWithExprType *) { return true; }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- assert(0 && "Cannot unique ConstantArrayWithExprTypes.");
- }
-};
-
-/// ConstantArrayWithoutExprType - This class represents C arrays with a
-/// constant size that was not specified by an integer constant expression,
-/// but inferred by static semantics.
-/// For example 'int A[] = { 0, 1, 2 }' has ConstantArrayWithoutExprType.
-/// These types are non-canonical: the corresponding canonical type,
-/// having the size specified in an APInt object, is a ConstantArrayType.
-class ConstantArrayWithoutExprType : public ConstantArrayType {
-
- ConstantArrayWithoutExprType(QualType et, QualType can,
- const llvm::APInt &size,
- ArraySizeModifier sm, unsigned tq)
- : ConstantArrayType(ConstantArrayWithoutExpr, et, can, size, sm, tq) {}
- friend class ASTContext; // ASTContext creates these.
-
-public:
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == ConstantArrayWithoutExpr;
- }
- static bool classof(const ConstantArrayWithoutExprType *) { return true; }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- assert(0 && "Cannot unique ConstantArrayWithoutExprTypes.");
- }
-};
-
/// IncompleteArrayType - This class represents C arrays with an unspecified
/// size. For example 'int A[]' has an IncompleteArrayType where the element
/// type is 'int' and the size is unspecified.
@@ -2219,6 +2179,59 @@ public:
static bool classof(const TemplateTypeParmType *T) { return true; }
};
+/// \brief Represents the result of substituting a type for a template
+/// type parameter.
+///
+/// Within an instantiated template, all template type parameters have
+/// been replaced with these. They are used solely to record that a
+/// type was originally written as a template type parameter;
+/// therefore they are never canonical.
+class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
+ // The original type parameter.
+ const TemplateTypeParmType *Replaced;
+
+ SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon)
+ : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType()),
+ Replaced(Param) { }
+
+ friend class ASTContext;
+
+public:
+ IdentifierInfo *getName() const { return Replaced->getName(); }
+
+ /// Gets the template parameter that was substituted for.
+ const TemplateTypeParmType *getReplacedParameter() const {
+ return Replaced;
+ }
+
+ /// Gets the type that was substituted for the template
+ /// parameter.
+ QualType getReplacementType() const {
+ return getCanonicalTypeInternal();
+ }
+
+ virtual void getAsStringInternal(std::string &InnerString,
+ const PrintingPolicy &Policy) const;
+
+ bool isSugared() const { return true; }
+ QualType desugar() const { return getReplacementType(); }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getReplacedParameter(), getReplacementType());
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID,
+ const TemplateTypeParmType *Replaced,
+ QualType Replacement) {
+ ID.AddPointer(Replaced);
+ ID.AddPointer(Replacement.getAsOpaquePtr());
+ }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == SubstTemplateTypeParm;
+ }
+ static bool classof(const SubstTemplateTypeParmType *T) { return true; }
+};
+
/// \brief Represents the type of a template specialization as written
/// in the source code.
///
@@ -2453,9 +2466,9 @@ class ObjCInterfaceType : public Type, public llvm::FoldingSetNode {
// List is sorted on protocol name. No protocol is enterred more than once.
llvm::SmallVector<ObjCProtocolDecl*, 4> Protocols;
- ObjCInterfaceType(ObjCInterfaceDecl *D,
+ ObjCInterfaceType(QualType Canonical, ObjCInterfaceDecl *D,
ObjCProtocolDecl **Protos, unsigned NumP) :
- Type(ObjCInterface, QualType(), /*Dependent=*/false),
+ Type(ObjCInterface, Canonical, /*Dependent=*/false),
Decl(D), Protocols(Protos, Protos+NumP) { }
friend class ASTContext; // ASTContext creates these.
public:
@@ -2501,8 +2514,9 @@ class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
// List is sorted on protocol name. No protocol is entered more than once.
llvm::SmallVector<ObjCProtocolDecl*, 8> Protocols;
- ObjCObjectPointerType(QualType T, ObjCProtocolDecl **Protos, unsigned NumP) :
- Type(ObjCObjectPointer, QualType(), /*Dependent=*/false),
+ ObjCObjectPointerType(QualType Canonical, QualType T,
+ ObjCProtocolDecl **Protos, unsigned NumP) :
+ Type(ObjCObjectPointer, Canonical, /*Dependent=*/false),
PointeeType(T), Protocols(Protos, Protos+NumP) { }
friend class ASTContext; // ASTContext creates these.
@@ -2567,49 +2581,6 @@ public:
static bool classof(const ObjCObjectPointerType *) { return true; }
};
-/// \brief An ObjC Protocol list that qualifies a type.
-///
-/// This is used only for keeping detailed type source information, it should
-/// not participate in the semantics of the type system.
-/// The protocol list is not canonicalized.
-class ObjCProtocolListType : public Type, public llvm::FoldingSetNode {
- QualType BaseType;
-
- // List of protocols for this protocol conforming object type.
- llvm::SmallVector<ObjCProtocolDecl*, 4> Protocols;
-
- ObjCProtocolListType(QualType T, ObjCProtocolDecl **Protos, unsigned NumP) :
- Type(ObjCProtocolList, QualType(), /*Dependent=*/false),
- BaseType(T), Protocols(Protos, Protos+NumP) { }
- friend class ASTContext; // ASTContext creates these.
-
-public:
- QualType getBaseType() const { return BaseType; }
-
- /// \brief Provides access to the list of protocols qualifying the base type.
- typedef llvm::SmallVector<ObjCProtocolDecl*, 4>::const_iterator qual_iterator;
-
- qual_iterator qual_begin() const { return Protocols.begin(); }
- qual_iterator qual_end() const { return Protocols.end(); }
- bool qual_empty() const { return Protocols.size() == 0; }
-
- /// \brief Return the number of qualifying protocols.
- unsigned getNumProtocols() const { return Protocols.size(); }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID);
- static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
- ObjCProtocolDecl **protocols, unsigned NumProtocols);
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
- static bool classof(const Type *T) {
- return T->getTypeClass() == ObjCProtocolList;
- }
- static bool classof(const ObjCProtocolListType *) { return true; }
-};
-
/// A qualifier set is used to build a set of qualifiers.
class QualifierCollector : public Qualifiers {
ASTContext *Context;
@@ -2646,6 +2617,20 @@ public:
// Inline function definitions.
+inline bool QualType::isCanonical() const {
+ const Type *T = getTypePtr();
+ if (hasQualifiers())
+ return T->isCanonicalUnqualified() && !isa<ArrayType>(T);
+ return T->isCanonicalUnqualified();
+}
+
+inline bool QualType::isCanonicalAsParam() const {
+ if (hasQualifiers()) return false;
+ const Type *T = getTypePtr();
+ return T->isCanonicalUnqualified() &&
+ !isa<FunctionType>(T) && !isa<ArrayType>(T);
+}
+
inline void QualType::removeConst() {
removeFastQualifiers(Qualifiers::Const);
}
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 3735eee47629..1d7181b531f8 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -18,10 +18,15 @@
namespace clang {
class ParmVarDecl;
- class TypeSpecLoc;
class DeclaratorInfo;
class UnqualTypeLoc;
+// Predeclare all the type nodes.
+#define ABSTRACT_TYPELOC(Class, Base)
+#define TYPELOC(Class, Base) \
+ class Class##TypeLoc;
+#include "clang/AST/TypeLocNodes.def"
+
/// \brief Base wrapper for a particular "section" of type source info.
///
/// A client should use the TypeLoc subclasses through cast/dyn_cast in order to
@@ -34,12 +39,28 @@ protected:
void *Data;
public:
+ /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum,
+ /// except it also defines a Qualified enum that corresponds to the
+ /// QualifiedLoc class.
+ enum TypeLocClass {
+#define ABSTRACT_TYPE(Class, Base)
+#define TYPE(Class, Base) \
+ Class = Type::Class,
+#include "clang/AST/TypeNodes.def"
+ Qualified
+ };
+
TypeLoc() : Ty(0), Data(0) { }
TypeLoc(QualType ty, void *opaqueData)
: Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
TypeLoc(Type *ty, void *opaqueData)
: Ty(ty), Data(opaqueData) { }
+ TypeLocClass getTypeLocClass() const {
+ if (getType().hasQualifiers()) return Qualified;
+ return (TypeLocClass) getType()->getTypeClass();
+ }
+
bool isNull() const { return !Ty; }
operator bool() const { return Ty; }
@@ -48,35 +69,45 @@ public:
/// \brief Get the type for which this source info wrapper provides
/// information.
- QualType getSourceType() const { return QualType::getFromOpaquePtr(Ty); }
+ QualType getType() const {
+ return QualType::getFromOpaquePtr(Ty);
+ }
- Type *getSourceTypePtr() const {
+ Type *getTypePtr() const {
return QualType::getFromOpaquePtr(Ty).getTypePtr();
}
/// \brief Get the pointer where source information is stored.
- void *getOpaqueData() const { return Data; }
-
- SourceRange getSourceRange() const;
-
- /// \brief Find the TypeSpecLoc that is part of this TypeLoc.
- TypeSpecLoc getTypeSpecLoc() const;
+ void *getOpaqueData() const {
+ return Data;
+ }
- /// \brief Find the TypeSpecLoc that is part of this TypeLoc and return its
- /// SourceRange.
- SourceRange getTypeSpecRange() const;
+ SourceRange getSourceRange() const {
+ return getSourceRangeImpl(*this);
+ }
/// \brief Returns the size of the type source info data block.
unsigned getFullDataSize() const {
- return getFullDataSizeForType(getSourceType());
+ return getFullDataSizeForType(getType());
}
/// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
/// TypeLoc is a PointerLoc and next TypeLoc is for "int".
- TypeLoc getNextTypeLoc() const;
+ TypeLoc getNextTypeLoc() const {
+ return getNextTypeLocImpl(*this);
+ }
/// \brief Skips past any qualifiers, if this is qualified.
- UnqualTypeLoc getUnqualifiedLoc() const;
+ UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
+
+ /// \brief Initializes this to state that every location in this
+ /// type is the given location.
+ ///
+ /// This method exists to provide a simple transition for code that
+ /// relies on location-less types.
+ void initialize(SourceLocation Loc) const {
+ initializeImpl(*this, Loc);
+ }
friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
@@ -87,6 +118,11 @@ public:
}
static bool classof(const TypeLoc *TL) { return true; }
+
+private:
+ static void initializeImpl(TypeLoc TL, SourceLocation Loc);
+ static TypeLoc getNextTypeLocImpl(TypeLoc TL);
+ static SourceRange getSourceRangeImpl(TypeLoc TL);
};
/// \brief Wrapper of type source information for a type with
@@ -96,12 +132,16 @@ public:
UnqualTypeLoc() {}
UnqualTypeLoc(Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
- Type *getSourceTypePtr() const {
+ Type *getTypePtr() const {
return reinterpret_cast<Type*>(Ty);
}
+ TypeLocClass getTypeLocClass() const {
+ return (TypeLocClass) getTypePtr()->getTypeClass();
+ }
+
static bool classof(const TypeLoc *TL) {
- return !TL->getSourceType().hasQualifiers();
+ return !TL->getType().hasQualifiers();
}
static bool classof(const UnqualTypeLoc *TL) { return true; }
};
@@ -111,14 +151,24 @@ public:
///
/// Currently, we intentionally do not provide source location for
/// type qualifiers.
-class QualifiedLoc : public TypeLoc {
+class QualifiedTypeLoc : public TypeLoc {
public:
SourceRange getSourceRange() const {
return SourceRange();
}
UnqualTypeLoc getUnqualifiedLoc() const {
- return UnqualTypeLoc(getSourceTypePtr(), Data);
+ return UnqualTypeLoc(getTypePtr(), Data);
+ }
+
+ /// Initializes the local data of this type source info block to
+ /// provide no information.
+ void initializeLocal(SourceLocation Loc) {
+ // do nothing
+ }
+
+ TypeLoc getNextTypeLoc() const {
+ return getUnqualifiedLoc();
}
/// \brief Returns the size of the type source info data block that is
@@ -132,52 +182,21 @@ public:
/// \brief Returns the size of the type source info data block.
unsigned getFullDataSize() const {
return getLocalDataSize() +
- getFullDataSizeForType(getSourceType().getUnqualifiedType());
+ getFullDataSizeForType(getType().getUnqualifiedType());
}
static bool classof(const TypeLoc *TL) {
- return TL->getSourceType().hasQualifiers();
+ return TL->getType().hasQualifiers();
}
- static bool classof(const QualifiedLoc *TL) { return true; }
+ static bool classof(const QualifiedTypeLoc *TL) { return true; }
};
inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
- if (isa<QualifiedLoc>(this))
- return cast<QualifiedLoc>(this)->getUnqualifiedLoc();
+ if (isa<QualifiedTypeLoc>(this))
+ return cast<QualifiedTypeLoc>(this)->getUnqualifiedLoc();
return cast<UnqualTypeLoc>(*this);
}
-/// \brief Base wrapper of type source info data for type-spec types.
-class TypeSpecLoc : public UnqualTypeLoc {
-public:
- static bool classof(const TypeLoc *TL) {
- return (UnqualTypeLoc::classof(TL) &&
- classof(static_cast<const UnqualTypeLoc*>(TL)));
- }
- static bool classof(const UnqualTypeLoc *TL);
- static bool classof(const TypeSpecLoc *TL) { return true; }
-};
-
-inline SourceRange TypeLoc::getTypeSpecRange() const {
- return getTypeSpecLoc().getSourceRange();
-}
-
-/// \brief Base wrapper of type source info data for types part of a declarator,
-/// excluding type-spec types.
-class DeclaratorLoc : public UnqualTypeLoc {
-public:
- /// \brief Find the TypeSpecLoc that is part of this DeclaratorLoc.
- TypeSpecLoc getTypeSpecLoc() const;
-
- static bool classof(const TypeLoc *TL) {
- return (UnqualTypeLoc::classof(TL) &&
- classof(static_cast<const UnqualTypeLoc*>(TL)));
- }
- static bool classof(const UnqualTypeLoc *TL);
- static bool classof(const DeclaratorLoc *TL) { return true; }
-};
-
-
/// A metaprogramming base class for TypeLoc classes which correspond
/// to a particular Type subclass. It is accepted for a single
/// TypeLoc class to correspond to multiple Type classes.
@@ -196,9 +215,19 @@ public:
/// getExtraLocalDataSize(); getExtraLocalData() will then point to
/// this extra memory.
///
-/// TypeLocs with an inner type should override hasInnerType() and
-/// getInnerType(); getInnerTypeLoc() will then point to this inner
-/// type's location data.
+/// TypeLocs with an inner type should define
+/// QualType getInnerType() const
+/// and getInnerTypeLoc() will then point to this inner type's
+/// location data.
+///
+/// A word about hierarchies: this template is not designed to be
+/// derived from multiple times in a hierarchy. It is also not
+/// designed to be used for classes where subtypes might provide
+/// different amounts of source information. It should be subclassed
+/// only at the deepest portion of the hierarchy where all children
+/// have identical source information; if that's an abstract type,
+/// then further descendents should inherit from
+/// InheritingConcreteTypeLoc instead.
template <class Base, class Derived, class TypeClass, class LocalData>
class ConcreteTypeLoc : public Base {
@@ -215,25 +244,19 @@ public:
return asDerived()->getLocalDataSize() + getInnerTypeSize();
}
- static bool classof(const TypeLoc *TL) {
- return Derived::classofType(TL->getSourceTypePtr());
- }
- static bool classof(const UnqualTypeLoc *TL) {
- return Derived::classofType(TL->getSourceTypePtr());
- }
- static bool classof(const Derived *TL) {
- return true;
- }
-
static bool classofType(const Type *Ty) {
return TypeClass::classof(Ty);
}
-protected:
+ TypeLoc getNextTypeLoc() const {
+ return getNextTypeLoc(asDerived()->getInnerType());
+ }
+
TypeClass *getTypePtr() const {
- return cast<TypeClass>(Base::getSourceTypePtr());
+ return cast<TypeClass>(Base::getTypePtr());
}
+protected:
unsigned getExtraLocalDataSize() const {
return 0;
}
@@ -253,136 +276,151 @@ protected:
return static_cast<char*>(Base::Data) + asDerived()->getLocalDataSize();
}
- bool hasInnerType() const {
- return false;
- }
+ struct HasNoInnerType {};
+ HasNoInnerType getInnerType() const { return HasNoInnerType(); }
TypeLoc getInnerTypeLoc() const {
- assert(asDerived()->hasInnerType());
return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
}
private:
unsigned getInnerTypeSize() const {
- if (asDerived()->hasInnerType())
- return getInnerTypeLoc().getFullDataSize();
+ return getInnerTypeSize(asDerived()->getInnerType());
+ }
+
+ unsigned getInnerTypeSize(HasNoInnerType _) const {
return 0;
}
- // Required here because my metaprogramming is too weak to avoid it.
- QualType getInnerType() const {
- assert(0 && "getInnerType() not overridden");
- return QualType();
+ unsigned getInnerTypeSize(QualType _) const {
+ return getInnerTypeLoc().getFullDataSize();
}
-};
+ TypeLoc getNextTypeLoc(HasNoInnerType _) const {
+ return TypeLoc();
+ }
-struct DefaultTypeSpecLocInfo {
- SourceLocation StartLoc;
+ TypeLoc getNextTypeLoc(QualType T) const {
+ return TypeLoc(T, getNonLocalData());
+ }
};
-/// \brief The default wrapper for type-spec types that are not handled by
-/// another specific wrapper.
-class DefaultTypeSpecLoc : public ConcreteTypeLoc<TypeSpecLoc,
- DefaultTypeSpecLoc,
- Type,
- DefaultTypeSpecLocInfo> {
+/// A metaprogramming class designed for concrete subtypes of abstract
+/// types where all subtypes share equivalently-structured source
+/// information. See the note on ConcreteTypeLoc.
+template <class Base, class Derived, class TypeClass>
+class InheritingConcreteTypeLoc : public Base {
public:
- SourceLocation getStartLoc() const {
- return getLocalData()->StartLoc;
+ static bool classof(const TypeLoc *TL) {
+ return Derived::classofType(TL->getTypePtr());
}
- void setStartLoc(SourceLocation Loc) {
- getLocalData()->StartLoc = Loc;
+ static bool classof(const UnqualTypeLoc *TL) {
+ return Derived::classofType(TL->getTypePtr());
}
- SourceRange getSourceRange() const {
- return SourceRange(getStartLoc(), getStartLoc());
+ static bool classof(const Derived *TL) {
+ return true;
}
- static bool classofType(const Type *T);
+ TypeClass *getTypePtr() const {
+ return cast<TypeClass>(Base::getTypePtr());
+ }
};
-
-struct TypedefLocInfo {
+struct TypeSpecLocInfo {
SourceLocation NameLoc;
};
-/// \brief Wrapper for source info for typedefs.
-class TypedefLoc : public ConcreteTypeLoc<TypeSpecLoc,TypedefLoc,
- TypedefType,TypedefLocInfo> {
+/// \brief A reasonable base class for TypeLocs that correspond to
+/// types that are written as a type-specifier.
+template <class Derived, class TypeClass, class LocalData = TypeSpecLocInfo>
+class TypeSpecTypeLoc
+ : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
public:
SourceLocation getNameLoc() const {
- return getLocalData()->NameLoc;
+ return this->getLocalData()->NameLoc;
}
void setNameLoc(SourceLocation Loc) {
- getLocalData()->NameLoc = Loc;
+ this->getLocalData()->NameLoc = Loc;
}
SourceRange getSourceRange() const {
return SourceRange(getNameLoc(), getNameLoc());
}
+ void initializeLocal(SourceLocation Loc) {
+ setNameLoc(Loc);
+ }
+};
+/// \brief Wrapper for source info for typedefs.
+class TypedefTypeLoc : public TypeSpecTypeLoc<TypedefTypeLoc,TypedefType> {
+public:
TypedefDecl *getTypedefDecl() const {
return getTypePtr()->getDecl();
}
};
-struct ObjCInterfaceLocInfo {
- SourceLocation NameLoc;
+/// \brief Wrapper for source info for builtin types.
+class BuiltinTypeLoc : public TypeSpecTypeLoc<BuiltinTypeLoc,
+ BuiltinType> {
};
-/// \brief Wrapper for source info for ObjC interfaces.
-class ObjCInterfaceLoc : public ConcreteTypeLoc<TypeSpecLoc,
- ObjCInterfaceLoc,
- ObjCInterfaceType,
- ObjCInterfaceLocInfo> {
-public:
- SourceLocation getNameLoc() const {
- return getLocalData()->NameLoc;
- }
- void setNameLoc(SourceLocation Loc) {
- getLocalData()->NameLoc = Loc;
- }
- SourceRange getSourceRange() const {
- return SourceRange(getNameLoc(), getNameLoc());
- }
+/// \brief Wrapper for template type parameters.
+class TemplateTypeParmTypeLoc : public TypeSpecTypeLoc<TemplateTypeParmTypeLoc,
+ TemplateTypeParmType> {
+};
- ObjCInterfaceDecl *getIFaceDecl() const {
- return getTypePtr()->getDecl();
- }
+/// \brief Wrapper for substituted template type parameters.
+class SubstTemplateTypeParmTypeLoc :
+ public TypeSpecTypeLoc<SubstTemplateTypeParmTypeLoc,
+ SubstTemplateTypeParmType> {
};
struct ObjCProtocolListLocInfo {
- SourceLocation LAngleLoc, RAngleLoc;
+ SourceLocation LAngleLoc;
+ SourceLocation RAngleLoc;
};
-/// \brief Wrapper for source info for ObjC protocol lists.
-class ObjCProtocolListLoc : public ConcreteTypeLoc<TypeSpecLoc,
- ObjCProtocolListLoc,
- ObjCProtocolListType,
- ObjCProtocolListLocInfo> {
+// A helper class for defining ObjC TypeLocs that can qualified with
+// protocols.
+//
+// TypeClass basically has to be either ObjCInterfaceType or
+// ObjCObjectPointerType.
+template <class Derived, class TypeClass, class LocalData>
+class ObjCProtocolListTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+ Derived,
+ TypeClass,
+ LocalData> {
// SourceLocations are stored after Info, one for each Protocol.
SourceLocation *getProtocolLocArray() const {
- return (SourceLocation*) getExtraLocalData();
+ return (SourceLocation*) this->getExtraLocalData();
+ }
+
+protected:
+ void initializeLocalBase(SourceLocation Loc) {
+ setLAngleLoc(Loc);
+ setRAngleLoc(Loc);
+ for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
+ setProtocolLoc(i, Loc);
}
public:
SourceLocation getLAngleLoc() const {
- return getLocalData()->LAngleLoc;
+ return this->getLocalData()->LAngleLoc;
}
void setLAngleLoc(SourceLocation Loc) {
- getLocalData()->LAngleLoc = Loc;
+ this->getLocalData()->LAngleLoc = Loc;
}
SourceLocation getRAngleLoc() const {
- return getLocalData()->RAngleLoc;
+ return this->getLocalData()->RAngleLoc;
}
void setRAngleLoc(SourceLocation Loc) {
- getLocalData()->RAngleLoc = Loc;
+ this->getLocalData()->RAngleLoc = Loc;
}
unsigned getNumProtocols() const {
- return getTypePtr()->getNumProtocols();
+ return this->getTypePtr()->getNumProtocols();
}
SourceLocation getProtocolLoc(unsigned i) const {
@@ -396,165 +434,229 @@ public:
ObjCProtocolDecl *getProtocol(unsigned i) const {
assert(i < getNumProtocols() && "Index is out of bounds!");
- return *(getTypePtr()->qual_begin() + i);
+ return *(this->getTypePtr()->qual_begin() + i);
}
- TypeLoc getBaseTypeLoc() const {
- return getInnerTypeLoc();
- }
-
SourceRange getSourceRange() const {
return SourceRange(getLAngleLoc(), getRAngleLoc());
}
- /// \brief Returns the size of the type source info data block that is
- /// specific to this type.
- unsigned getExtraLocalDataSize() const {
- return getNumProtocols() * sizeof(SourceLocation);
+ void initializeLocal(SourceLocation Loc) {
+ initializeLocalBase(Loc);
}
- bool hasInnerType() const { return true; }
- QualType getInnerType() const { return getTypePtr()->getBaseType(); }
+ unsigned getExtraLocalDataSize() const {
+ return this->getNumProtocols() * sizeof(SourceLocation);
+ }
};
-struct PointerLocInfo {
- SourceLocation StarLoc;
+struct ObjCInterfaceLocInfo : ObjCProtocolListLocInfo {
+ SourceLocation NameLoc;
};
-/// \brief Wrapper for source info for pointers.
-class PointerLoc : public ConcreteTypeLoc<DeclaratorLoc,
- PointerLoc,
- PointerType,
- PointerLocInfo> {
+/// \brief Wrapper for source info for ObjC interfaces.
+class ObjCInterfaceTypeLoc :
+ public ObjCProtocolListTypeLoc<ObjCInterfaceTypeLoc,
+ ObjCInterfaceType,
+ ObjCInterfaceLocInfo> {
public:
- SourceLocation getStarLoc() const {
- return getLocalData()->StarLoc;
- }
- void setStarLoc(SourceLocation Loc) {
- getLocalData()->StarLoc = Loc;
+ ObjCInterfaceDecl *getIFaceDecl() const {
+ return getTypePtr()->getDecl();
}
- TypeLoc getPointeeLoc() const {
- return getInnerTypeLoc();
+ SourceLocation getNameLoc() const {
+ return getLocalData()->NameLoc;
}
- /// \brief Find the TypeSpecLoc that is part of this PointerLoc.
- TypeSpecLoc getTypeSpecLoc() const {
- return getPointeeLoc().getTypeSpecLoc();
+ void setNameLoc(SourceLocation Loc) {
+ getLocalData()->NameLoc = Loc;
}
SourceRange getSourceRange() const {
- return SourceRange(getStarLoc(), getStarLoc());
+ if (getNumProtocols())
+ return SourceRange(getNameLoc(), getRAngleLoc());
+ else
+ return SourceRange(getNameLoc(), getNameLoc());
}
- bool hasInnerType() const { return true; }
- QualType getInnerType() const { return getTypePtr()->getPointeeType(); }
+ void initializeLocal(SourceLocation Loc) {
+ initializeLocalBase(Loc);
+ setNameLoc(Loc);
+ }
};
-struct BlockPointerLocInfo {
- SourceLocation CaretLoc;
+struct ObjCObjectPointerLocInfo : ObjCProtocolListLocInfo {
+ SourceLocation StarLoc;
+ bool HasProtocols;
+ bool HasBaseType;
};
-/// \brief Wrapper for source info for block pointers.
-class BlockPointerLoc : public ConcreteTypeLoc<DeclaratorLoc,
- BlockPointerLoc,
- BlockPointerType,
- BlockPointerLocInfo> {
+/// Wraps an ObjCPointerType with source location information. Note
+/// that not all ObjCPointerTypes actually have a star location; nor
+/// are protocol locations necessarily written in the source just
+/// because they're present on the type.
+class ObjCObjectPointerTypeLoc :
+ public ObjCProtocolListTypeLoc<ObjCObjectPointerTypeLoc,
+ ObjCObjectPointerType,
+ ObjCObjectPointerLocInfo> {
public:
- SourceLocation getCaretLoc() const {
- return getLocalData()->CaretLoc;
+ bool hasProtocolsAsWritten() const {
+ return getLocalData()->HasProtocols;
}
- void setCaretLoc(SourceLocation Loc) {
- getLocalData()->CaretLoc = Loc;
+
+ void setHasProtocolsAsWritten(bool HasProtocols) {
+ getLocalData()->HasProtocols = HasProtocols;
}
- TypeLoc getPointeeLoc() const {
- return getInnerTypeLoc();
+ bool hasBaseTypeAsWritten() const {
+ return getLocalData()->HasBaseType;
}
- /// \brief Find the TypeSpecLoc that is part of this BlockPointerLoc.
- TypeSpecLoc getTypeSpecLoc() const {
- return getPointeeLoc().getTypeSpecLoc();
+ void setHasBaseTypeAsWritten(bool HasBaseType) {
+ getLocalData()->HasBaseType = HasBaseType;
+ }
+
+ SourceLocation getStarLoc() const {
+ return getLocalData()->StarLoc;
+ }
+
+ void setStarLoc(SourceLocation Loc) {
+ getLocalData()->StarLoc = Loc;
}
SourceRange getSourceRange() const {
- return SourceRange(getCaretLoc(), getCaretLoc());
+ // Being written with protocols is incompatible with being written
+ // with a star.
+ if (hasProtocolsAsWritten())
+ return SourceRange(getLAngleLoc(), getRAngleLoc());
+ else
+ return SourceRange(getStarLoc(), getStarLoc());
+ }
+
+ void initializeLocal(SourceLocation Loc) {
+ initializeLocalBase(Loc);
+ setHasProtocolsAsWritten(false);
+ setHasBaseTypeAsWritten(false);
+ setStarLoc(Loc);
+ }
+
+ TypeLoc getBaseTypeLoc() const {
+ return getInnerTypeLoc();
}
- bool hasInnerType() const { return true; }
- QualType getInnerType() const { return getTypePtr()->getPointeeType(); }
+ QualType getInnerType() const {
+ return getTypePtr()->getPointeeType();
+ }
};
-struct MemberPointerLocInfo {
+struct PointerLikeLocInfo {
SourceLocation StarLoc;
};
-/// \brief Wrapper for source info for member pointers.
-class MemberPointerLoc : public ConcreteTypeLoc<DeclaratorLoc,
- MemberPointerLoc,
- MemberPointerType,
- MemberPointerLocInfo> {
-public:
- SourceLocation getStarLoc() const {
- return getLocalData()->StarLoc;
+/// A base class for
+template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
+class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
+ TypeClass, LocalData> {
+public:
+ SourceLocation getSigilLoc() const {
+ return this->getLocalData()->StarLoc;
}
- void setStarLoc(SourceLocation Loc) {
- getLocalData()->StarLoc = Loc;
+ void setSigilLoc(SourceLocation Loc) {
+ this->getLocalData()->StarLoc = Loc;
}
TypeLoc getPointeeLoc() const {
- return getInnerTypeLoc();
+ return this->getInnerTypeLoc();
}
- /// \brief Find the TypeSpecLoc that is part of this MemberPointerLoc.
- TypeSpecLoc getTypeSpecLoc() const {
- return getPointeeLoc().getTypeSpecLoc();
+ SourceRange getSourceRange() const {
+ return SourceRange(getSigilLoc(), getSigilLoc());
}
- SourceRange getSourceRange() const {
- return SourceRange(getStarLoc(), getStarLoc());
+ void initializeLocal(SourceLocation Loc) {
+ setSigilLoc(Loc);
}
- bool hasInnerType() const { return true; }
- QualType getInnerType() const { return getTypePtr()->getPointeeType(); }
+ QualType getInnerType() const {
+ return this->getTypePtr()->getPointeeType();
+ }
};
-struct ReferenceLocInfo {
- SourceLocation AmpLoc;
+/// \brief Wrapper for source info for pointers.
+class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
+ PointerType> {
+public:
+ SourceLocation getStarLoc() const {
+ return getSigilLoc();
+ }
+ void setStarLoc(SourceLocation Loc) {
+ setSigilLoc(Loc);
+ }
};
-/// \brief Wrapper for source info for references.
-class ReferenceLoc : public ConcreteTypeLoc<DeclaratorLoc,
- ReferenceLoc,
- ReferenceType,
- ReferenceLocInfo> {
+
+/// \brief Wrapper for source info for block pointers.
+class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
+ BlockPointerType> {
public:
- SourceLocation getAmpLoc() const {
- return getLocalData()->AmpLoc;
+ SourceLocation getCaretLoc() const {
+ return getSigilLoc();
}
- void setAmpLoc(SourceLocation Loc) {
- getLocalData()->AmpLoc = Loc;
+ void setCaretLoc(SourceLocation Loc) {
+ setSigilLoc(Loc);
}
+};
- TypeLoc getPointeeLoc() const {
- return TypeLoc(getTypePtr()->getPointeeType(), getNonLocalData());
+
+/// \brief Wrapper for source info for member pointers.
+class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
+ MemberPointerType> {
+public:
+ SourceLocation getStarLoc() const {
+ return getSigilLoc();
+ }
+ void setStarLoc(SourceLocation Loc) {
+ setSigilLoc(Loc);
}
+};
- /// \brief Find the TypeSpecLoc that is part of this ReferenceLoc.
- TypeSpecLoc getTypeSpecLoc() const {
- return getPointeeLoc().getTypeSpecLoc();
+
+class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
+ ReferenceType> {
+public:
+ QualType getInnerType() const {
+ return getTypePtr()->getPointeeTypeAsWritten();
}
+};
- SourceRange getSourceRange() const {
- return SourceRange(getAmpLoc(), getAmpLoc());
+class LValueReferenceTypeLoc :
+ public InheritingConcreteTypeLoc<ReferenceTypeLoc,
+ LValueReferenceTypeLoc,
+ LValueReferenceType> {
+public:
+ SourceLocation getAmpLoc() const {
+ return getSigilLoc();
+ }
+ void setAmpLoc(SourceLocation Loc) {
+ setSigilLoc(Loc);
}
+};
- bool hasInnerType() const { return true; }
- QualType getInnerType() const { return getTypePtr()->getPointeeType(); }
+class RValueReferenceTypeLoc :
+ public InheritingConcreteTypeLoc<ReferenceTypeLoc,
+ RValueReferenceTypeLoc,
+ RValueReferenceType> {
+public:
+ SourceLocation getAmpAmpLoc() const {
+ return getSigilLoc();
+ }
+ void setAmpAmpLoc(SourceLocation Loc) {
+ setSigilLoc(Loc);
+ }
};
@@ -563,10 +665,10 @@ struct FunctionLocInfo {
};
/// \brief Wrapper for source info for functions.
-class FunctionLoc : public ConcreteTypeLoc<DeclaratorLoc,
- FunctionLoc,
- FunctionType,
- FunctionLocInfo> {
+class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+ FunctionTypeLoc,
+ FunctionType,
+ FunctionLocInfo> {
// ParmVarDecls* are stored after Info, one for each argument.
ParmVarDecl **getParmArray() const {
return (ParmVarDecl**) getExtraLocalData();
@@ -601,24 +703,38 @@ public:
return getInnerTypeLoc();
}
- /// \brief Find the TypeSpecLoc that is part of this FunctionLoc.
- TypeSpecLoc getTypeSpecLoc() const {
- return getResultLoc().getTypeSpecLoc();
- }
SourceRange getSourceRange() const {
return SourceRange(getLParenLoc(), getRParenLoc());
}
+ void initializeLocal(SourceLocation Loc) {
+ setLParenLoc(Loc);
+ setRParenLoc(Loc);
+ for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
+ setArg(i, NULL);
+ }
+
/// \brief Returns the size of the type source info data block that is
/// specific to this type.
unsigned getExtraLocalDataSize() const {
return getNumArgs() * sizeof(ParmVarDecl*);
}
- bool hasInnerType() const { return true; }
QualType getInnerType() const { return getTypePtr()->getResultType(); }
};
+class FunctionProtoTypeLoc :
+ public InheritingConcreteTypeLoc<FunctionTypeLoc,
+ FunctionProtoTypeLoc,
+ FunctionProtoType> {
+};
+
+class FunctionNoProtoTypeLoc :
+ public InheritingConcreteTypeLoc<FunctionTypeLoc,
+ FunctionNoProtoTypeLoc,
+ FunctionNoProtoType> {
+};
+
struct ArrayLocInfo {
SourceLocation LBracketLoc, RBracketLoc;
@@ -626,10 +742,10 @@ struct ArrayLocInfo {
};
/// \brief Wrapper for source info for arrays.
-class ArrayLoc : public ConcreteTypeLoc<DeclaratorLoc,
- ArrayLoc,
- ArrayType,
- ArrayLocInfo> {
+class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+ ArrayTypeLoc,
+ ArrayType,
+ ArrayLocInfo> {
public:
SourceLocation getLBracketLoc() const {
return getLocalData()->LBracketLoc;
@@ -656,18 +772,108 @@ public:
return getInnerTypeLoc();
}
- /// \brief Find the TypeSpecLoc that is part of this ArrayLoc.
- TypeSpecLoc getTypeSpecLoc() const {
- return getElementLoc().getTypeSpecLoc();
- }
SourceRange getSourceRange() const {
return SourceRange(getLBracketLoc(), getRBracketLoc());
}
- bool hasInnerType() const { return true; }
+ void initializeLocal(SourceLocation Loc) {
+ setLBracketLoc(Loc);
+ setRBracketLoc(Loc);
+ setSizeExpr(NULL);
+ }
+
QualType getInnerType() const { return getTypePtr()->getElementType(); }
};
+class ConstantArrayTypeLoc :
+ public InheritingConcreteTypeLoc<ArrayTypeLoc,
+ ConstantArrayTypeLoc,
+ ConstantArrayType> {
+};
+
+class IncompleteArrayTypeLoc :
+ public InheritingConcreteTypeLoc<ArrayTypeLoc,
+ IncompleteArrayTypeLoc,
+ IncompleteArrayType> {
+};
+
+class DependentSizedArrayTypeLoc :
+ public InheritingConcreteTypeLoc<ArrayTypeLoc,
+ DependentSizedArrayTypeLoc,
+ DependentSizedArrayType> {
+
+};
+
+class VariableArrayTypeLoc :
+ public InheritingConcreteTypeLoc<ArrayTypeLoc,
+ VariableArrayTypeLoc,
+ VariableArrayType> {
+};
+
+// None of these types have proper implementations yet.
+
+class VectorTypeLoc : public TypeSpecTypeLoc<VectorTypeLoc, VectorType> {
+};
+
+class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
+ ExtVectorTypeLoc,
+ ExtVectorType> {
+};
+
+// For some reason, this isn't a subtype of VectorType.
+class DependentSizedExtVectorTypeLoc :
+ public TypeSpecTypeLoc<DependentSizedExtVectorTypeLoc,
+ DependentSizedExtVectorType> {
+};
+
+class FixedWidthIntTypeLoc : public TypeSpecTypeLoc<FixedWidthIntTypeLoc,
+ FixedWidthIntType> {
+};
+
+class ComplexTypeLoc : public TypeSpecTypeLoc<ComplexTypeLoc,
+ ComplexType> {
+};
+
+class TypeOfExprTypeLoc : public TypeSpecTypeLoc<TypeOfExprTypeLoc,
+ TypeOfExprType> {
+};
+
+class TypeOfTypeLoc : public TypeSpecTypeLoc<TypeOfTypeLoc, TypeOfType> {
+};
+
+class DecltypeTypeLoc : public TypeSpecTypeLoc<DecltypeTypeLoc, DecltypeType> {
+};
+
+class TagTypeLoc : public TypeSpecTypeLoc<TagTypeLoc, TagType> {
+};
+
+class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
+ RecordTypeLoc,
+ RecordType> {
+};
+
+class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
+ EnumTypeLoc,
+ EnumType> {
+};
+
+class ElaboratedTypeLoc : public TypeSpecTypeLoc<ElaboratedTypeLoc,
+ ElaboratedType> {
+};
+
+class TemplateSpecializationTypeLoc
+ : public TypeSpecTypeLoc<TemplateSpecializationTypeLoc,
+ TemplateSpecializationType> {
+};
+
+class QualifiedNameTypeLoc : public TypeSpecTypeLoc<QualifiedNameTypeLoc,
+ QualifiedNameType> {
+};
+
+class TypenameTypeLoc : public TypeSpecTypeLoc<TypenameTypeLoc,
+ TypenameType> {
+};
+
}
#endif
diff --git a/include/clang/AST/TypeLocBuilder.h b/include/clang/AST/TypeLocBuilder.h
new file mode 100644
index 000000000000..4e1fbaaf4c5e
--- /dev/null
+++ b/include/clang/AST/TypeLocBuilder.h
@@ -0,0 +1,122 @@
+//===--- TypeLocBuilder.h - Type Source Info collector ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This files defines TypeLocBuilder, a class for building TypeLocs
+// bottom-up.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TYPELOCBUILDER_H
+#define LLVM_CLANG_AST_TYPELOCBUILDER_H
+
+#include "clang/AST/TypeLoc.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+
+class TypeLocBuilder {
+ enum { InlineCapacity = 8 * sizeof(SourceLocation) };
+
+ /// The underlying location-data buffer. Data grows from the end
+ /// of the buffer backwards.
+ char *Buffer;
+
+ /// The capacity of the current buffer.
+ size_t Capacity;
+
+ /// The index of the first occupied byte in the buffer.
+ size_t Index;
+
+#ifndef NDEBUG
+ /// The last type pushed on this builder.
+ QualType LastTy;
+#endif
+
+ /// The inline buffer.
+ char InlineBuffer[InlineCapacity];
+
+ public:
+ TypeLocBuilder()
+ : Buffer(InlineBuffer), Capacity(InlineCapacity), Index(InlineCapacity)
+ {}
+
+ ~TypeLocBuilder() {
+ if (Buffer != InlineBuffer)
+ delete[] Buffer;
+ }
+
+ /// Ensures that this buffer has at least as much capacity as described.
+ void reserve(size_t Requested) {
+ if (Requested > Capacity)
+ // For now, match the request exactly.
+ grow(Requested);
+ }
+
+ /// Pushes space for a new TypeLoc onto the given type. Invalidates
+ /// any TypeLocs previously retrieved from this builder.
+ template <class TyLocType> TyLocType push(QualType T) {
+#ifndef NDEBUG
+ QualType TLast = TypeLoc(T, 0).getNextTypeLoc().getType();
+ assert(TLast == LastTy &&
+ "mismatch between last type and new type's inner type");
+ LastTy = T;
+#endif
+
+ size_t LocalSize = cast<TyLocType>(TypeLoc(T, 0)).getLocalDataSize();
+
+ // If we need to grow, grow by a factor of 2.
+ if (LocalSize > Index) {
+ size_t RequiredCapacity = Capacity + (LocalSize - Index);
+ size_t NewCapacity = Capacity * 2;
+ while (RequiredCapacity > NewCapacity)
+ NewCapacity *= 2;
+ grow(NewCapacity);
+ }
+
+ Index -= LocalSize;
+
+ return cast<TyLocType>(TypeLoc(T, &Buffer[Index]));
+ }
+
+ /// Creates a DeclaratorInfo for the given type.
+ DeclaratorInfo *getDeclaratorInfo(ASTContext& Context, QualType T) {
+#ifndef NDEBUG
+ assert(T == LastTy && "type doesn't match last type pushed!");
+#endif
+
+ size_t FullDataSize = Capacity - Index;
+ DeclaratorInfo *DI = Context.CreateDeclaratorInfo(T, FullDataSize);
+ memcpy(DI->getTypeLoc().getOpaqueData(), &Buffer[Index], FullDataSize);
+ return DI;
+ }
+
+ private:
+ /// Grow to the given capacity.
+ void grow(size_t NewCapacity) {
+ assert(NewCapacity > Capacity);
+
+ // Allocate the new buffer and copy the old data into it.
+ char *NewBuffer = new char[NewCapacity];
+ unsigned NewIndex = Index + NewCapacity - Capacity;
+ memcpy(&NewBuffer[NewIndex],
+ &Buffer[Index],
+ Capacity - Index);
+
+ if (Buffer != InlineBuffer)
+ delete[] Buffer;
+
+ Buffer = NewBuffer;
+ Capacity = NewCapacity;
+ Index = NewIndex;
+ }
+};
+
+}
+
+#endif
diff --git a/include/clang/AST/TypeLocNodes.def b/include/clang/AST/TypeLocNodes.def
index ecf7cc5c2995..4590e489e3f7 100644
--- a/include/clang/AST/TypeLocNodes.def
+++ b/include/clang/AST/TypeLocNodes.def
@@ -7,54 +7,32 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines the TypeLoc info database. Each node is
-// enumerated by providing its name (e.g., "PointerLoc" or "ArrayLoc"),
-// base class (e.g., "TypeSpecLoc" or "DeclaratorLoc"), and the Type subclass
-// that the TypeLoc is associated with.
+// This file defines the TypeLoc info database. Each node is
+// enumerated by providing its core name (e.g., "Pointer" for "PointerTypeLoc")
+// and base class (e.g., "DeclaratorLoc"). All nodes except QualifiedTypeLoc
+// are associated
//
-// TYPELOC(Class, Base) - A TypeLoc subclass.
+// TYPELOC(Class, Base) - A TypeLoc subclass. If UNQUAL_TYPELOC is
+// provided, there will be exactly one of these, Qualified.
//
// UNQUAL_TYPELOC(Class, Base, Type) - An UnqualTypeLoc subclass.
//
// ABSTRACT_TYPELOC(Class) - Refers to TypeSpecLoc and DeclaratorLoc.
//
-// TYPESPEC_TYPELOC(Class, Type) - A TypeLoc referring to a type-spec type.
-//
-// DECLARATOR_TYPELOC(Class, Type) - A TypeLoc referring to a type part of
-// a declarator, excluding type-spec types.
-//
//===----------------------------------------------------------------------===//
#ifndef UNQUAL_TYPELOC
-# define UNQUAL_TYPELOC(Class, Base, Type) TYPELOC(Class, Base)
+# define UNQUAL_TYPELOC(Class, Base) TYPELOC(Class, Base)
#endif
#ifndef ABSTRACT_TYPELOC
-# define ABSTRACT_TYPELOC(Class) TYPELOC(Class, TypeLoc)
-#endif
-
-#ifndef TYPESPEC_TYPELOC
-# define TYPESPEC_TYPELOC(Class, Type) UNQUAL_TYPELOC(Class, TypeSpecLoc, Type)
+# define ABSTRACT_TYPELOC(Class, Base) UNQUAL_TYPELOC(Class, Base)
#endif
-#ifndef DECLARATOR_TYPELOC
-# define DECLARATOR_TYPELOC(Class, Type) UNQUAL_TYPELOC(Class, DeclaratorLoc, Type)
-#endif
-
-TYPESPEC_TYPELOC(DefaultTypeSpecLoc, Type)
-TYPESPEC_TYPELOC(TypedefLoc, TypedefType)
-TYPESPEC_TYPELOC(ObjCInterfaceLoc, ObjCInterfaceType)
-TYPESPEC_TYPELOC(ObjCProtocolListLoc, ObjCProtocolListType)
-DECLARATOR_TYPELOC(PointerLoc, PointerType)
-DECLARATOR_TYPELOC(BlockPointerLoc, BlockPointerType)
-DECLARATOR_TYPELOC(MemberPointerLoc, MemberPointerType)
-DECLARATOR_TYPELOC(ReferenceLoc, ReferenceType)
-DECLARATOR_TYPELOC(FunctionLoc, FunctionType)
-DECLARATOR_TYPELOC(ArrayLoc, ArrayType)
-ABSTRACT_TYPELOC(DeclaratorLoc)
-ABSTRACT_TYPELOC(TypeSpecLoc)
-TYPELOC(QualifiedLoc, TypeLoc)
-
+TYPELOC(Qualified, TypeLoc)
+#define TYPE(Class, Base) UNQUAL_TYPELOC(Class, Base##Loc)
+#define ABSTRACT_TYPE(Class, Base) ABSTRACT_TYPELOC(Class, Base##Loc)
+#include "clang/AST/TypeNodes.def"
#undef DECLARATOR_TYPELOC
#undef TYPESPEC_TYPELOC
diff --git a/include/clang/AST/TypeLocVisitor.h b/include/clang/AST/TypeLocVisitor.h
index a96757f123e8..a62bb3f853bc 100644
--- a/include/clang/AST/TypeLocVisitor.h
+++ b/include/clang/AST/TypeLocVisitor.h
@@ -15,46 +15,38 @@
#include "clang/AST/TypeLoc.h"
#include "clang/AST/TypeVisitor.h"
+#include "llvm/Support/ErrorHandling.h"
namespace clang {
-#define DISPATCH(CLASS) \
- return static_cast<ImplClass*>(this)->Visit ## CLASS(cast<CLASS>(TyLoc))
+#define DISPATCH(CLASSNAME) \
+ return static_cast<ImplClass*>(this)-> \
+ Visit##CLASSNAME(cast<CLASSNAME>(TyLoc))
template<typename ImplClass, typename RetTy=void>
class TypeLocVisitor {
- class TypeDispatch : public TypeVisitor<TypeDispatch, RetTy> {
- ImplClass *Impl;
- UnqualTypeLoc TyLoc;
-
- public:
- TypeDispatch(ImplClass *impl, UnqualTypeLoc &tyLoc)
- : Impl(impl), TyLoc(tyLoc) { }
-#define TYPELOC(CLASS, BASE)
-#define ABSTRACT_TYPELOC(CLASS)
-#define UNQUAL_TYPELOC(CLASS, PARENT, TYPE) \
- RetTy Visit##TYPE(TYPE *) { \
- return Impl->Visit##CLASS(reinterpret_cast<CLASS&>(TyLoc)); \
- }
-#include "clang/AST/TypeLocNodes.def"
- };
-
public:
RetTy Visit(TypeLoc TyLoc) {
- if (isa<QualifiedLoc>(TyLoc))
- return static_cast<ImplClass*>(this)->
- VisitQualifiedLoc(cast<QualifiedLoc>(TyLoc));
-
- return Visit(cast<UnqualTypeLoc>(TyLoc));
+ switch (TyLoc.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+ case TypeLoc::CLASS: DISPATCH(CLASS##TypeLoc);
+#include "clang/AST/TypeLocNodes.def"
+ }
+ llvm::llvm_unreachable("unexpected type loc class!");
}
RetTy Visit(UnqualTypeLoc TyLoc) {
- TypeDispatch TD(static_cast<ImplClass*>(this), TyLoc);
- return TD.Visit(TyLoc.getSourceTypePtr());
+ switch (TyLoc.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+ case TypeLoc::CLASS: DISPATCH(CLASS##TypeLoc);
+#include "clang/AST/TypeLocNodes.def"
+ }
}
#define TYPELOC(CLASS, PARENT) \
- RetTy Visit##CLASS(CLASS TyLoc) { \
+ RetTy Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
DISPATCH(PARENT); \
}
#include "clang/AST/TypeLocNodes.def"
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index 6c6bd20e8528..c2721236af02 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -62,8 +62,6 @@ TYPE(RValueReference, ReferenceType)
TYPE(MemberPointer, Type)
ABSTRACT_TYPE(Array, Type)
TYPE(ConstantArray, ArrayType)
-NON_CANONICAL_TYPE(ConstantArrayWithExpr, ConstantArrayType)
-NON_CANONICAL_TYPE(ConstantArrayWithoutExpr, ConstantArrayType)
TYPE(IncompleteArray, ArrayType)
TYPE(VariableArray, ArrayType)
DEPENDENT_TYPE(DependentSizedArray, ArrayType)
@@ -82,12 +80,12 @@ TYPE(Record, TagType)
TYPE(Enum, TagType)
NON_CANONICAL_TYPE(Elaborated, Type)
DEPENDENT_TYPE(TemplateTypeParm, Type)
+NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
TYPE(TemplateSpecialization, Type)
NON_CANONICAL_TYPE(QualifiedName, Type)
DEPENDENT_TYPE(Typename, Type)
TYPE(ObjCInterface, Type)
TYPE(ObjCObjectPointer, Type)
-NON_CANONICAL_TYPE(ObjCProtocolList, Type)
// These types are always leaves in the type hierarchy.
#ifdef LEAF_TYPE
@@ -95,7 +93,6 @@ LEAF_TYPE(Enum)
LEAF_TYPE(Builtin)
LEAF_TYPE(FixedWidthInt)
LEAF_TYPE(ObjCInterface)
-LEAF_TYPE(ObjCObjectPointer)
LEAF_TYPE(TemplateTypeParm)
#undef LEAF_TYPE
#endif