aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/TypeLoc.h509
-rw-r--r--include/clang/AST/TypeLocNodes.def46
-rw-r--r--include/clang/AST/TypeLocVisitor.h44
-rw-r--r--include/clang/Index/ASTLocation.h2
-rw-r--r--lib/AST/Decl.cpp11
-rw-r--r--lib/AST/TypeLoc.cpp210
-rw-r--r--lib/Frontend/PCHReader.cpp147
-rw-r--r--lib/Frontend/PCHWriter.cpp147
-rw-r--r--lib/Index/ASTLocation.cpp2
-rw-r--r--lib/Index/ASTVisitor.h8
-rw-r--r--lib/Index/DeclReferenceMap.cpp8
-rw-r--r--lib/Index/ResolveLocation.cpp20
-rw-r--r--lib/Sema/SemaType.cpp165
13 files changed, 684 insertions, 635 deletions
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 22837d8048..fb202a5a50 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,36 @@ 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.
@@ -99,6 +121,8 @@ public:
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
@@ -108,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; }
};
@@ -123,14 +151,14 @@ 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
@@ -154,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.
@@ -222,6 +219,15 @@ public:
/// 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 {
@@ -238,16 +244,6 @@ 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);
}
@@ -256,11 +252,11 @@ public:
return getNextTypeLoc(asDerived()->getInnerType());
}
-protected:
TypeClass *getTypePtr() const {
- return cast<TypeClass>(Base::getSourceTypePtr());
+ return cast<TypeClass>(Base::getTypePtr());
}
+protected:
unsigned getExtraLocalDataSize() const {
return 0;
}
@@ -309,88 +305,70 @@ private:
}
};
-
-struct DefaultTypeSpecLocInfo {
- SourceLocation StartLoc;
-};
-
-/// \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;
}
- void initializeLocal(SourceLocation Loc) {
- setStartLoc(Loc);
+ TypeClass *getTypePtr() const {
+ return cast<TypeClass>(Base::getTypePtr());
}
-
- static bool classofType(const Type *T);
};
-
-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> {
+class ObjCInterfaceTypeLoc : public TypeSpecTypeLoc<ObjCInterfaceTypeLoc,
+ ObjCInterfaceType> {
public:
- SourceLocation getNameLoc() const {
- return getLocalData()->NameLoc;
- }
- void setNameLoc(SourceLocation Loc) {
- getLocalData()->NameLoc = Loc;
- }
- SourceRange getSourceRange() const {
- return SourceRange(getNameLoc(), getNameLoc());
- }
-
- void initializeLocal(SourceLocation Loc) {
- setNameLoc(Loc);
- }
-
ObjCInterfaceDecl *getIFaceDecl() const {
return getTypePtr()->getDecl();
}
@@ -402,10 +380,11 @@ struct ObjCProtocolListLocInfo {
};
/// \brief Wrapper for source info for ObjC protocol lists.
-class ObjCProtocolListLoc : public ConcreteTypeLoc<TypeSpecLoc,
- ObjCProtocolListLoc,
- ObjCProtocolListType,
- ObjCProtocolListLocInfo> {
+class ObjCProtocolListTypeLoc
+ : public ConcreteTypeLoc<UnqualTypeLoc,
+ ObjCProtocolListTypeLoc,
+ ObjCProtocolListType,
+ ObjCProtocolListLocInfo> {
// SourceLocations are stored after Info, one for each Protocol.
SourceLocation *getProtocolLocArray() const {
return (SourceLocation*) getExtraLocalData();
@@ -469,155 +448,119 @@ public:
};
-struct PointerLocInfo {
+
+struct PointerLikeLocInfo {
SourceLocation StarLoc;
};
-/// \brief Wrapper for source info for pointers.
-class PointerLoc : public ConcreteTypeLoc<DeclaratorLoc,
- PointerLoc,
- PointerType,
- PointerLocInfo> {
-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> {
+protected:
+ SourceLocation getSigilLoc() const {
+ return this->getLocalData()->StarLoc;
}
- void setStarLoc(SourceLocation Loc) {
- getLocalData()->StarLoc = Loc;
+ void setSigilLoc(SourceLocation Loc) {
+ this->getLocalData()->StarLoc = Loc;
}
+public:
TypeLoc getPointeeLoc() const {
- return getInnerTypeLoc();
- }
-
- /// \brief Find the TypeSpecLoc that is part of this PointerLoc.
- TypeSpecLoc getTypeSpecLoc() const {
- return getPointeeLoc().getTypeSpecLoc();
+ return this->getInnerTypeLoc();
}
SourceRange getSourceRange() const {
- return SourceRange(getStarLoc(), getStarLoc());
+ return SourceRange(getSigilLoc(), getSigilLoc());
}
void initializeLocal(SourceLocation Loc) {
- setStarLoc(Loc);
+ setSigilLoc(Loc);
}
- QualType getInnerType() const { return getTypePtr()->getPointeeType(); }
+ QualType getInnerType() const {
+ return this->getTypePtr()->getPointeeType();
+ }
};
-struct BlockPointerLocInfo {
- SourceLocation CaretLoc;
+/// \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 block pointers.
-class BlockPointerLoc : public ConcreteTypeLoc<DeclaratorLoc,
- BlockPointerLoc,
- BlockPointerType,
- BlockPointerLocInfo> {
+class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
+ BlockPointerType> {
public:
SourceLocation getCaretLoc() const {
- return getLocalData()->CaretLoc;
+ return getSigilLoc();
}
void setCaretLoc(SourceLocation Loc) {
- getLocalData()->CaretLoc = Loc;
+ setSigilLoc(Loc);
}
-
- TypeLoc getPointeeLoc() const {
- return getInnerTypeLoc();
- }
-
- /// \brief Find the TypeSpecLoc that is part of this BlockPointerLoc.
- TypeSpecLoc getTypeSpecLoc() const {
- return getPointeeLoc().getTypeSpecLoc();
- }
-
- SourceRange getSourceRange() const {
- return SourceRange(getCaretLoc(), getCaretLoc());
- }
-
- void initializeLocal(SourceLocation Loc) {
- setCaretLoc(Loc);
- }
-
- QualType getInnerType() const { return getTypePtr()->getPointeeType(); }
};
-struct MemberPointerLocInfo {
- SourceLocation StarLoc;
-};
-
/// \brief Wrapper for source info for member pointers.
-class MemberPointerLoc : public ConcreteTypeLoc<DeclaratorLoc,
- MemberPointerLoc,
- MemberPointerType,
- MemberPointerLocInfo> {
+class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
+ MemberPointerType> {
public:
SourceLocation getStarLoc() const {
- return getLocalData()->StarLoc;
+ return getSigilLoc();
}
void setStarLoc(SourceLocation Loc) {
- getLocalData()->StarLoc = Loc;
- }
-
- TypeLoc getPointeeLoc() const {
- return getInnerTypeLoc();
- }
-
- /// \brief Find the TypeSpecLoc that is part of this MemberPointerLoc.
- TypeSpecLoc getTypeSpecLoc() const {
- return getPointeeLoc().getTypeSpecLoc();
- }
-
- SourceRange getSourceRange() const {
- return SourceRange(getStarLoc(), getStarLoc());
- }
-
- void initializeLocal(SourceLocation Loc) {
- setStarLoc(Loc);
+ setSigilLoc(Loc);
}
-
- QualType getInnerType() const { return getTypePtr()->getPointeeType(); }
};
-struct ReferenceLocInfo {
- SourceLocation AmpLoc;
+class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
+ ReferenceType> {
};
-/// \brief Wrapper for source info for references.
-class ReferenceLoc : public ConcreteTypeLoc<DeclaratorLoc,
- ReferenceLoc,
- ReferenceType,
- ReferenceLocInfo> {
+class LValueReferenceTypeLoc : public PointerLikeTypeLoc<LValueReferenceTypeLoc,
+ LValueReferenceType> {
public:
SourceLocation getAmpLoc() const {
- return getLocalData()->AmpLoc;
+ return getSigilLoc();
}
void setAmpLoc(SourceLocation Loc) {
- getLocalData()->AmpLoc = Loc;
+ setSigilLoc(Loc);
}
+};
- TypeLoc getPointeeLoc() const {
- return TypeLoc(getTypePtr()->getPointeeType(), getNonLocalData());
+class RValueReferenceTypeLoc : public PointerLikeTypeLoc<RValueReferenceTypeLoc,
+ RValueReferenceType> {
+public:
+ SourceLocation getAmpAmpLoc() const {
+ return getSigilLoc();
}
-
- /// \brief Find the TypeSpecLoc that is part of this ReferenceLoc.
- TypeSpecLoc getTypeSpecLoc() const {
- return getPointeeLoc().getTypeSpecLoc();
+ void setAmpAmpLoc(SourceLocation Loc) {
+ setSigilLoc(Loc);
}
+};
- SourceRange getSourceRange() const {
- return SourceRange(getAmpLoc(), getAmpLoc());
+/// Wraps an ObjCPointerType with source location information. Note
+/// that not all ObjCPointerTypes actually have a star location.
+class ObjCObjectPointerTypeLoc :
+ public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
+ ObjCObjectPointerType> {
+public:
+ SourceLocation getStarLoc() const {
+ return getSigilLoc();
}
-
- void initializeLocal(SourceLocation Loc) {
- setAmpLoc(Loc);
+ void setStarLoc(SourceLocation Loc) {
+ setSigilLoc(Loc);
}
-
- QualType getInnerType() const { return getTypePtr()->getPointeeType(); }
};
@@ -626,10 +569,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();
@@ -664,10 +607,6 @@ 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());
}
@@ -688,6 +627,18 @@ public:
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;
@@ -695,10 +646,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;
@@ -725,10 +676,6 @@ 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());
}
@@ -742,6 +689,100 @@ public:
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 TemplateTypeParmTypeLoc : public TypeSpecTypeLoc<TemplateTypeParmTypeLoc,
+ TemplateTypeParmType> {
+};
+
+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/TypeLocNodes.def b/include/clang/AST/TypeLocNodes.def
index ecf7cc5c29..4590e489e3 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 a96757f123..a62bb3f853 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/Index/ASTLocation.h b/include/clang/Index/ASTLocation.h
index 0fec84152b..fc18dae1a2 100644
--- a/include/clang/Index/ASTLocation.h
+++ b/include/clang/Index/ASTLocation.h
@@ -91,7 +91,7 @@ public:
ASTLocation(const Decl *parentDecl, TypeLoc tyLoc)
: ParentDecl(const_cast<Decl*>(parentDecl), N_Type) {
if (tyLoc) {
- Ty.TyPtr = tyLoc.getSourceType().getAsOpaquePtr();
+ Ty.TyPtr = tyLoc.getType().getAsOpaquePtr();
Ty.Data = tyLoc.getOpaqueData();
} else
ParentDecl.setPointer(0);
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 9d7d3d087c..0c413f6742 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -336,8 +336,15 @@ NamedDecl *NamedDecl::getUnderlyingDecl() {
//===----------------------------------------------------------------------===//
SourceLocation DeclaratorDecl::getTypeSpecStartLoc() const {
- if (DeclInfo)
- return DeclInfo->getTypeLoc().getTypeSpecRange().getBegin();
+ if (DeclInfo) {
+ TypeLoc TL = DeclInfo->getTypeLoc();
+ while (true) {
+ TypeLoc NextTL = TL.getNextTypeLoc();
+ if (!NextTL)
+ return TL.getSourceRange().getBegin();
+ TL = NextTL;
+ }
+ }
return SourceLocation();
}
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp
index c216a29e64..7e6b110bf5 100644
--- a/lib/AST/TypeLoc.cpp
+++ b/lib/AST/TypeLoc.cpp
@@ -20,55 +20,32 @@ using namespace clang;
//===----------------------------------------------------------------------===//
namespace {
-
-/// \brief Return the source range for the visited TypeSpecLoc.
-class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
-public:
-#define ABSTRACT_TYPELOC(CLASS)
+ class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
+ public:
+#define ABST