aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/TypeLoc.h521
-rw-r--r--include/clang/AST/TypeLocNodes.def16
-rw-r--r--include/clang/AST/TypeLocVisitor.h25
-rw-r--r--lib/AST/TypeLoc.cpp213
-rw-r--r--lib/Frontend/PCHReaderDecl.cpp5
-rw-r--r--lib/Frontend/PCHWriterDecl.cpp5
-rw-r--r--lib/Sema/SemaType.cpp3
7 files changed, 396 insertions, 392 deletions
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index a6184375e0..ab23a7985c 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -20,6 +20,7 @@ namespace clang {
class ParmVarDecl;
class TypeSpecLoc;
class DeclaratorInfo;
+ class UnqualTypeLoc;
/// \brief Base wrapper for a particular "section" of type source info.
///
@@ -27,22 +28,31 @@ namespace clang {
/// get at the actual information.
class TypeLoc {
protected:
- QualType Ty;
+ // The correctness of this relies on the property that, for Type *Ty,
+ // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
+ void *Ty;
void *Data;
public:
- TypeLoc() : Data(0) { }
- TypeLoc(QualType ty, void *opaqueData) : Ty(ty), Data(opaqueData) { }
+ TypeLoc() : Ty(0), Data(0) { }
+ TypeLoc(QualType ty, void *opaqueData)
+ : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
+ TypeLoc(Type *ty, void *opaqueData)
+ : Ty(ty), Data(opaqueData) { }
- bool isNull() const { return Ty.isNull(); }
- operator bool() const { return !isNull(); }
+ bool isNull() const { return !Ty; }
+ operator bool() const { return Ty; }
/// \brief Returns the size of type source info data block for the given type.
static unsigned getFullDataSizeForType(QualType Ty);
/// \brief Get the type for which this source info wrapper provides
/// information.
- QualType getSourceType() const { return Ty; }
+ QualType getSourceType() const { return QualType::getFromOpaquePtr(Ty); }
+
+ Type *getSourceTypePtr() const {
+ return QualType::getFromOpaquePtr(Ty).getTypePtr();
+ }
/// \brief Get the pointer where source information is stored.
void *getOpaqueData() const { return Data; }
@@ -57,12 +67,17 @@ public:
SourceRange getTypeSpecRange() const;
/// \brief Returns the size of the type source info data block.
- unsigned getFullDataSize() const;
+ unsigned getFullDataSize() const {
+ return getFullDataSizeForType(getSourceType());
+ }
/// \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;
+ /// \brief Skips past any qualifiers, if this is qualified.
+ UnqualTypeLoc getUnqualifiedLoc() const;
+
friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
}
@@ -74,144 +89,296 @@ public:
static bool classof(const TypeLoc *TL) { return true; }
};
+/// \brief Wrapper of type source information for a type with
+/// no direct quqlaifiers.
+class UnqualTypeLoc : public TypeLoc {
+public:
+ UnqualTypeLoc() {}
+ UnqualTypeLoc(Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
+
+ Type *getSourceTypePtr() const {
+ return reinterpret_cast<Type*>(Ty);
+ }
+
+ static bool classof(const TypeLoc *TL) {
+ return !TL->getSourceType().hasQualifiers();
+ }
+ static bool classof(const UnqualTypeLoc *TL) { return true; }
+};
+
+/// \brief Wrapper of type source information for a type with
+/// non-trivial direct qualifiers.
+///
+/// Currently, we intentionally do not provide source location for
+/// type qualifiers.
+class QualifiedLoc : public TypeLoc {
+public:
+ SourceRange getSourceRange() const {
+ return SourceRange();
+ }
+
+ UnqualTypeLoc getUnqualifiedLoc() const {
+ return UnqualTypeLoc(getSourceTypePtr(), Data);
+ }
+
+ /// \brief Returns the size of the type source info data block that is
+ /// specific to this type.
+ unsigned getLocalDataSize() const {
+ // In fact, we don't currently preserve any location information
+ // for qualifiers.
+ return 0;
+ }
+
+ /// \brief Returns the size of the type source info data block.
+ unsigned getFullDataSize() const {
+ return getLocalDataSize() +
+ getFullDataSizeForType(getSourceType().getUnqualifiedType());
+ }
+
+ static bool classof(const TypeLoc *TL) {
+ return TL->getSourceType().hasQualifiers();
+ }
+ static bool classof(const QualifiedLoc *TL) { return true; }
+};
+
+inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
+ if (isa<QualifiedLoc>(this))
+ return cast<QualifiedLoc>(this)->getUnqualifiedLoc();
+ return cast<UnqualTypeLoc>(*this);
+}
+
/// \brief Base wrapper of type source info data for type-spec types.
-class TypeSpecLoc : public TypeLoc {
+class TypeSpecLoc : public UnqualTypeLoc {
public:
- static bool classof(const TypeLoc *TL);
+ 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 TypeLoc {
+class DeclaratorLoc : public UnqualTypeLoc {
public:
/// \brief Find the TypeSpecLoc that is part of this DeclaratorLoc.
TypeSpecLoc getTypeSpecLoc() const;
- static bool classof(const TypeLoc *TL);
+ 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.
+///
+/// \param Base a class from which to derive
+/// \param Derived the class deriving from this one
+/// \param TypeClass the concrete Type subclass which this
+/// \param LocalData the structure type of local location data for
+/// this type
+///
+/// sizeof(LocalData) needs to be a multiple of sizeof(void*) or
+/// else the world will end.
+///
+/// TypeLocs with non-constant amounts of local data should override
+/// getExtraLocalDataSize(); getExtraLocalData() will then point to
+/// this extra memory.
+///
+/// TypeLocs with an inner type should override ha
+template <class Base, class Derived, class TypeClass, class LocalData>
+class ConcreteTypeLoc : public Base {
+
+ const Derived *asDerived() const {
+ return static_cast<const Derived*>(this);
+ }
+
+public:
+ unsigned getLocalDataSize() const {
+ return sizeof(LocalData) + asDerived()->getExtraLocalDataSize();
+ }
+ // Give a default implementation that's useful for leaf types.
+ unsigned getFullDataSize() const {
+ 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:
+ TypeClass *getTypePtr() const {
+ return cast<TypeClass>(Base::getSourceTypePtr());
+ }
+
+ unsigned getExtraLocalDataSize() const {
+ return 0;
+ }
+
+ LocalData *getLocalData() const {
+ return static_cast<LocalData*>(Base::Data);
+ }
+
+ /// Gets a pointer past the Info structure; useful for classes with
+ /// local data that can't be captured in the Info (e.g. because it's
+ /// of variable size).
+ void *getExtraLocalData() const {
+ return getLocalData() + 1;
+ }
+
+ void *getNonLocalData() const {
+ return static_cast<char*>(Base::Data) + asDerived()->getLocalDataSize();
+ }
+
+ bool hasInnerType() const {
+ return false;
+ }
+
+ TypeLoc getInnerTypeLoc() const {
+ assert(asDerived()->hasInnerType());
+ return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
+ }
+
+private:
+ unsigned getInnerTypeSize() const {
+ if (asDerived()->hasInnerType())
+ return getInnerTypeLoc().getFullDataSize();
+ return 0;
+ }
+
+ // Required here because my metaprogramming is too weak to avoid it.
+ QualType getInnerType() const {
+ assert(0 && "getInnerType() not overridden");
+ return QualType();
+ }
+};
+
+
+struct DefaultTypeSpecLocInfo {
+ SourceLocation StartLoc;
+};
+
/// \brief The default wrapper for type-spec types that are not handled by
/// another specific wrapper.
-class DefaultTypeSpecLoc : public TypeSpecLoc {
- struct Info {
- SourceLocation StartLoc;
- };
-
+class DefaultTypeSpecLoc : public ConcreteTypeLoc<TypeSpecLoc,
+ DefaultTypeSpecLoc,
+ Type,
+ DefaultTypeSpecLocInfo> {
public:
SourceLocation getStartLoc() const {
- return static_cast<Info*>(Data)->StartLoc;
+ return getLocalData()->StartLoc;
}
void setStartLoc(SourceLocation Loc) {
- static_cast<Info*>(Data)->StartLoc = Loc;
+ getLocalData()->StartLoc = Loc;
}
SourceRange getSourceRange() const {
return SourceRange(getStartLoc(), getStartLoc());
}
- /// \brief Returns the size of the type source info data block that is
- /// specific to this type.
- unsigned getLocalDataSize() const { return sizeof(Info); }
+ static bool classofType(const Type *T);
+};
- /// \brief Returns the size of the type source info data block.
- unsigned getFullDataSize() const { return getLocalDataSize(); }
- static bool classof(const TypeLoc *TL);
- static bool classof(const DefaultTypeSpecLoc *TL) { return true; }
+struct TypedefLocInfo {
+ SourceLocation NameLoc;
};
/// \brief Wrapper for source info for typedefs.
-class TypedefLoc : public TypeSpecLoc {
- struct Info {
- SourceLocation NameLoc;
- };
-
+class TypedefLoc : public ConcreteTypeLoc<TypeSpecLoc,TypedefLoc,
+ TypedefType,TypedefLocInfo> {
public:
SourceLocation getNameLoc() const {
- return static_cast<Info*>(Data)->NameLoc;
+ return getLocalData()->NameLoc;
}
void setNameLoc(SourceLocation Loc) {
- static_cast<Info*>(Data)->NameLoc = Loc;
+ getLocalData()->NameLoc = Loc;
}
SourceRange getSourceRange() const {
return SourceRange(getNameLoc(), getNameLoc());
}
TypedefDecl *getTypedefDecl() const {
- return cast<TypedefType>(Ty)->getDecl();
+ return getTypePtr()->getDecl();
}
+};
- /// \brief Returns the size of the type source info data block that is
- /// specific to this type.
- unsigned getLocalDataSize() const { return sizeof(Info); }
-
- /// \brief Returns the size of the type source info data block.
- unsigned getFullDataSize() const { return getLocalDataSize(); }
- static bool classof(const TypeLoc *TL);
- static bool classof(const TypedefLoc *TL) { return true; }
+struct ObjCInterfaceLocInfo {
+ SourceLocation NameLoc;
};
/// \brief Wrapper for source info for ObjC interfaces.
-class ObjCInterfaceLoc : public TypeSpecLoc {
- struct Info {
- SourceLocation NameLoc;
- };
-
+class ObjCInterfaceLoc : public ConcreteTypeLoc<TypeSpecLoc,
+ ObjCInterfaceLoc,
+ ObjCInterfaceType,
+ ObjCInterfaceLocInfo> {
public:
SourceLocation getNameLoc() const {
- return static_cast<Info*>(Data)->NameLoc;
+ return getLocalData()->NameLoc;
}
void setNameLoc(SourceLocation Loc) {
- static_cast<Info*>(Data)->NameLoc = Loc;
+ getLocalData()->NameLoc = Loc;
}
SourceRange getSourceRange() const {
return SourceRange(getNameLoc(), getNameLoc());
}
ObjCInterfaceDecl *getIFaceDecl() const {
- return cast<ObjCInterfaceType>(Ty)->getDecl();
+ return getTypePtr()->getDecl();
}
+};
- /// \brief Returns the size of the type source info data block that is
- /// specific to this type.
- unsigned getLocalDataSize() const { return sizeof(Info); }
-
- /// \brief Returns the size of the type source info data block.
- unsigned getFullDataSize() const { return getLocalDataSize(); }
- static bool classof(const TypeLoc *TL);
- static bool classof(const TypedefLoc *TL) { return true; }
+struct ObjCProtocolListLocInfo {
+ SourceLocation LAngleLoc, RAngleLoc;
};
/// \brief Wrapper for source info for ObjC protocol lists.
-class ObjCProtocolListLoc : public TypeSpecLoc {
- struct Info {
- SourceLocation LAngleLoc, RAngleLoc;
- };
+class ObjCProtocolListLoc : public ConcreteTypeLoc<TypeSpecLoc,
+ ObjCProtocolListLoc,
+ ObjCProtocolListType,
+ ObjCProtocolListLocInfo> {
// SourceLocations are stored after Info, one for each Protocol.
SourceLocation *getProtocolLocArray() const {
- return reinterpret_cast<SourceLocation*>(static_cast<Info*>(Data) + 1);
+ return (SourceLocation*) getExtraLocalData();
}
public:
SourceLocation getLAngleLoc() const {
- return static_cast<Info*>(Data)->LAngleLoc;
+ return getLocalData()->LAngleLoc;
}
void setLAngleLoc(SourceLocation Loc) {
- static_cast<Info*>(Data)->LAngleLoc = Loc;
+ getLocalData()->LAngleLoc = Loc;
}
SourceLocation getRAngleLoc() const {
- return static_cast<Info*>(Data)->RAngleLoc;
+ return getLocalData()->RAngleLoc;
}
void setRAngleLoc(SourceLocation Loc) {
- static_cast<Info*>(Data)->RAngleLoc = Loc;
+ getLocalData()->RAngleLoc = Loc;
}
unsigned getNumProtocols() const {
- return cast<ObjCProtocolListType>(Ty)->getNumProtocols();
+ return getTypePtr()->getNumProtocols();
}
SourceLocation getProtocolLoc(unsigned i) const {
@@ -225,12 +392,11 @@ public:
ObjCProtocolDecl *getProtocol(unsigned i) const {
assert(i < getNumProtocols() && "Index is out of bounds!");
- return *(cast<ObjCProtocolListType>(Ty)->qual_begin() + i);
+ return *(getTypePtr()->qual_begin() + i);
}
TypeLoc getBaseTypeLoc() const {
- void *Next = static_cast<char*>(Data) + getLocalDataSize();
- return TypeLoc(cast<ObjCProtocolListType>(Ty)->getBaseType(), Next);
+ return getInnerTypeLoc();
}
SourceRange getSourceRange() const {
@@ -239,36 +405,34 @@ public:
/// \brief Returns the size of the type source info data block that is
/// specific to this type.
- unsigned getLocalDataSize() const {
- return sizeof(Info) + getNumProtocols() * sizeof(SourceLocation);
+ unsigned getExtraLocalDataSize() const {
+ return getNumProtocols() * sizeof(SourceLocation);
}
- /// \brief Returns the size of the type source info data block.
- unsigned getFullDataSize() const {
- return getLocalDataSize() + getBaseTypeLoc().getFullDataSize();
- }
+ bool hasInnerType() const { return true; }
+ QualType getInnerType() const { return getTypePtr()->getBaseType(); }
+};
- static bool classof(const TypeLoc *TL);
- static bool classof(const ObjCProtocolListLoc *TL) { return true; }
+
+struct PointerLocInfo {
+ SourceLocation StarLoc;
};
/// \brief Wrapper for source info for pointers.
-class PointerLoc : public DeclaratorLoc {
- struct Info {
- SourceLocation StarLoc;
- };
-
+class PointerLoc : public ConcreteTypeLoc<DeclaratorLoc,
+ PointerLoc,
+ PointerType,
+ PointerLocInfo> {
public:
SourceLocation getStarLoc() const {
- return static_cast<Info*>(Data)->StarLoc;
+ return getLocalData()->StarLoc;
}
void setStarLoc(SourceLocation Loc) {
- static_cast<Info*>(Data)->StarLoc = Loc;
+ getLocalData()->StarLoc = Loc;
}
TypeLoc getPointeeLoc() const {
- void *Next = static_cast<char*>(Data) + getLocalDataSize();
- return TypeLoc(cast<PointerType>(Ty)->getPointeeType(), Next);
+ return getInnerTypeLoc();
}
/// \brief Find the TypeSpecLoc that is part of this PointerLoc.
@@ -280,36 +444,30 @@ public:
return SourceRange(getStarLoc(), getStarLoc());
}
- /// \brief Returns the size of the type source info data block that is
- /// specific to this type.
- unsigned getLocalDataSize() const { return sizeof(Info); }
+ bool hasInnerType() const { return true; }
+ QualType getInnerType() const { return getTypePtr()->getPointeeType(); }
+};
- /// \brief Returns the size of the type source info data block.
- unsigned getFullDataSize() const {
- return getLocalDataSize() + getPointeeLoc().getFullDataSize();
- }
- static bool classof(const TypeLoc *TL);
- static bool classof(const PointerLoc *TL) { return true; }
+struct BlockPointerLocInfo {
+ SourceLocation CaretLoc;
};
/// \brief Wrapper for source info for block pointers.
-class BlockPointerLoc : public DeclaratorLoc {
- struct Info {
- SourceLocation CaretLoc;
- };
-
+class BlockPointerLoc : public ConcreteTypeLoc<DeclaratorLoc,
+ BlockPointerLoc,
+ BlockPointerType,
+ BlockPointerLocInfo> {
public:
SourceLocation getCaretLoc() const {
- return static_cast<Info*>(Data)->CaretLoc;
+ return getLocalData()->CaretLoc;
}
void setCaretLoc(SourceLocation Loc) {
- static_cast<Info*>(Data)->CaretLoc = Loc;
+ getLocalData()->CaretLoc = Loc;
}
TypeLoc getPointeeLoc() const {
- void *Next = static_cast<char*>(Data) + getLocalDataSize();
- return TypeLoc(cast<BlockPointerType>(Ty)->getPointeeType(), Next);
+ return getInnerTypeLoc();
}
/// \brief Find the TypeSpecLoc that is part of this BlockPointerLoc.
@@ -321,36 +479,30 @@ public:
return SourceRange(getCaretLoc(), getCaretLoc());
}
- /// \brief Returns the size of the type source info data block that is
- /// specific to this type.
- unsigned getLocalDataSize() const { return sizeof(Info); }
+ bool hasInnerType() const { return true; }
+ QualType getInnerType() const { return getTypePtr()->getPointeeType(); }
+};
- /// \brief Returns the size of the type source info data block.
- unsigned getFullDataSize() const {
- return getLocalDataSize() + getPointeeLoc().getFullDataSize();
- }
- static bool classof(const TypeLoc *TL);
- static bool classof(const BlockPointerLoc *TL) { return true; }
+struct MemberPointerLocInfo {
+ SourceLocation StarLoc;
};
/// \brief Wrapper for source info for member pointers.
-class MemberPointerLoc : public DeclaratorLoc {
- struct Info {
- SourceLocation StarLoc;
- };
-
+class MemberPointerLoc : public ConcreteTypeLoc<DeclaratorLoc,
+ MemberPointerLoc,
+ MemberPointerType,
+ MemberPointerLocInfo> {
public:
SourceLocation getStarLoc() const {
- return static_cast<Info*>(Data)->StarLoc;
+ return getLocalData()->StarLoc;
}
void setStarLoc(SourceLocation Loc) {
- static_cast<Info*>(Data)->StarLoc = Loc;
+ getLocalData()->StarLoc = Loc;
}
TypeLoc getPointeeLoc() const {
- void *Next = static_cast<char*>(Data) + getLocalDataSize();
- return TypeLoc(cast<MemberPointerType>(Ty)->getPointeeType(), Next);
+ return getInnerTypeLoc();
}
/// \brief Find the TypeSpecLoc that is part of this MemberPointerLoc.
@@ -362,36 +514,30 @@ public:
return SourceRange(getStarLoc(), getStarLoc());
}
- /// \brief Returns the size of the type source info data block that is
- /// specific to this type.
- unsigned getLocalDataSize() const { return sizeof(Info); }
+ bool hasInnerType() const { return true; }
+ QualType getInnerType() const { return getTypePtr()->getPointeeType(); }
+};
- /// \brief Returns the size of the type source info data block.
- unsigned getFullDataSize() const {
- return getLocalDataSize() + getPointeeLoc().getFullDataSize();
- }
- static bool classof(const TypeLoc *TL);
- static bool classof(const MemberPointerLoc *TL) { return true; }
+struct ReferenceLocInfo {
+ SourceLocation AmpLoc;
};
/// \brief Wrapper for source info for references.
-class ReferenceLoc : public DeclaratorLoc {
- struct Info {
- SourceLocation AmpLoc;
- };
-
+class ReferenceLoc : public ConcreteTypeLoc<DeclaratorLoc,
+ ReferenceLoc,
+ ReferenceType,
+ ReferenceLocInfo> {
public:
SourceLocation getAmpLoc() const {
- return static_cast<Info*>(Data)->AmpLoc;
+ return getLocalData()->AmpLoc;
}
void setAmpLoc(SourceLocation Loc) {
- static_cast<Info*>(Data)->AmpLoc = Loc;
+ getLocalData()->AmpLoc = Loc;
}
TypeLoc getPointeeLoc() const {
- void *Next = static_cast<char*>(Data) + getLocalDataSize();
- return TypeLoc(cast<ReferenceType>(Ty)->getPointeeType(), Next);
+ return TypeLoc(getTypePtr()->getPointeeType(), getNonLocalData());
}
/// \brief Find the TypeSpecLoc that is part of this ReferenceLoc.
@@ -403,48 +549,44 @@ public:
return SourceRange(getAmpLoc(), getAmpLoc());
}
- /// \brief Returns the size of the type source info data block that is
- /// specific to this type.
- unsigned getLocalDataSize() const { return sizeof(Info); }
+ bool hasInnerType() const { return true; }
+ QualType getInnerType() const { return getTypePtr()->getPointeeType(); }
+};
- /// \brief Returns the size of the type source info data block.
- unsigned getFullDataSize() const {
- return getLocalDataSize() + getPointeeLoc().getFullDataSize();
- }
- static bool classof(const TypeLoc *TL);
- static bool classof(const ReferenceLoc *TL) { return true; }
+struct FunctionLocInfo {
+ SourceLocation LParenLoc, RParenLoc;
};
/// \brief Wrapper for source info for functions.
-class FunctionLoc : public DeclaratorLoc {
- struct Info {
- SourceLocation LParenLoc, RParenLoc;
- };
+class FunctionLoc : public ConcreteTypeLoc<DeclaratorLoc,
+ FunctionLoc,
+ FunctionType,
+ FunctionLocInfo> {
// ParmVarDecls* are stored after Info, one for each argument.
ParmVarDecl **getParmArray() const {
- return reinterpret_cast<ParmVarDecl**>(static_cast<Info*>(Data) + 1);
+ return (ParmVarDecl**) getExtraLocalData();
}
public:
SourceLocation getLParenLoc() const {
- return static_cast<Info*>(Data)->LParenLoc;
+ return getLocalData()->LParenLoc;
}
void setLParenLoc(SourceLocation Loc) {
- static_cast<Info*>(Data)->LParenLoc = Loc;
+ getLocalData()->LParenLoc = Loc;
}
SourceLocation getRParenLoc() const {
- return static_cast<Info*>(Data)->RParenLoc;
+ return getLocalData()->RParenLoc;
}
void setRParenLoc(SourceLocation Loc) {
- static_cast<Info*>(Data)->RParenLoc = Loc;
+ getLocalData()->RParenLoc = Loc;
}
unsigned getNumArgs() const {
- if (isa<FunctionNoProtoType>(Ty))
+ if (isa<FunctionNoProtoType>(getTypePtr()))
return 0;
- return cast<FunctionProtoType>(Ty)->getNumArgs();
+ return cast<FunctionProtoType>(getTypePtr())->getNumArgs();
}
ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; }
void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
@@ -452,8 +594,7 @@ public:
TypeLoc getArgLoc(unsigned i) const;
TypeLoc getResultLoc() const {
- void *Next = static_cast<char*>(Data) + getLocalDataSize();
- return TypeLoc(cast<FunctionType>(Ty)->getResultType(), Next);
+ return getInnerTypeLoc();
}
/// \brief Find the TypeSpecLoc that is part of this FunctionLoc.
@@ -466,50 +607,49 @@ public:
/// \brief Returns the size of the type source info data block that is
/// specific to this type.
- unsigned getLocalDataSize() const {
- return sizeof(Info) + getNumArgs() * sizeof(ParmVarDecl*);
+ unsigned getExtraLocalDataSize() const {
+ return getNumArgs() * sizeof(ParmVarDecl*);
}
- /// \brief Returns the size of the type source info data block.
- unsigned getFullDataSize() const {
- return getLocalDataSize() + getResultLoc().getFullDataSize();
- }
+ bool hasInnerType() const { return true; }
+ QualType getInnerType() const { return getTypePtr()->getResultType(); }
+};
+
- static bool classof(const TypeLoc *TL);
- static bool classof(const FunctionLoc *TL) { return true; }
+struct ArrayLocInfo {
+ SourceLocation LBracketLoc, RBracketLoc;
+ Expr *Size;
};
/// \brief Wrapper for source info for arrays.
-class ArrayLoc : public DeclaratorLoc {
- struct Info {
- SourceLocation LBracketLoc, RBracketLoc;
- Expr *Size;
- };
+class ArrayLoc : public ConcreteTypeLoc<DeclaratorLoc,
+ ArrayLoc,
+ ArrayType,
+ ArrayLocInfo> {
public:
SourceLocation getLBracketLoc() const {
- return static_cast<Info*>(Data)->LBracketLoc;
+ return getLocalData()->LBracketLoc;
}
void setLBracketLoc(SourceLocation Loc) {
- static_cast<Info*>(Data)->LBracketLoc = Loc;
+ getLocalData()->LBracketLoc = Loc;
}
SourceLocation getRBracketLoc() const {
- return static_cast<Info*>(Data)->RBracketLoc;
+ return getLocalData()->RBracketLoc;
}
void setRBracketLoc(SourceLocation Loc) {
- static_cast<Info*>(Data)->RBracketLoc = Loc;
+ getLocalData()->RBracketLoc = Loc;
}
Expr *getSizeExpr() const {
- return static_cast<Info*>(Data)->Size;
+ return getLocalData()->Size;
}
void setSizeExpr(Expr *Size) {
- static_cast<Info*>(Data)->Size = Size;
+ getLocalData()->Size = Size;
}
TypeLoc getElementLoc() const {
- void *Next = static_cast<char*>(Data) + getLocalDataSize();
- return TypeLoc(cast<ArrayType>(Ty)->getElementType(), Next);
+ return getInnerTypeLoc();
}
/// \brief Find the TypeSpecLoc that is part of this ArrayLoc.
@@ -520,17 +660,8 @@ public:
return SourceRange(getLBracketLoc(), getRBracketLoc());
}
- /// \brief Returns the size of the type source info data block that is
- /// specific to this type.
- unsigned getLocalDataSize() const { return sizeof(Info); }
-
- /// \brief Returns the size of the type source info data block.
- unsigned getFullDataSize() const {
- return getLocalDataSize() + getElementLoc().getFullDataSize();
- }
-
- static bool classof(const TypeLoc *TL);
- static bool classof(const ArrayLoc *TL) { return true; }
+ bool hasInnerType() const { return true; }
+ QualType getInnerType() const { return getTypePtr()->getElementType(); }
};
}
diff --git a/include/clang/AST/TypeLocNodes.def b/include/clang/AST/TypeLocNodes.def
index 107ea85479..ecf7cc5c29 100644
--- a/include/clang/AST/TypeLocNodes.def
+++ b/include/clang/AST/TypeLocNodes.def
@@ -12,7 +12,9 @@
// base class (e.g., "TypeSpecLoc" or "DeclaratorLoc"), and the Type subclass
// that the TypeLoc is associated with.
//
-// TYPELOC(Class, Base, Type) - Description of the TypeLoc subclass.
+// TYPELOC(Class, Base) - A TypeLoc subclass.
+//
+// UNQUAL_TYPELOC(Class, Base, Type) - An UnqualTypeLoc subclass.
//
// ABSTRACT_TYPELOC(Class) - Refers to TypeSpecLoc and DeclaratorLoc.
//
@@ -23,16 +25,20 @@
//
//===----------------------------------------------------------------------===//
+#ifndef UNQUAL_TYPELOC
+# define UNQUAL_TYPELOC(Class, Base, Type) TYPELOC(Class, Base)
+#endif
+
#ifndef ABSTRACT_TYPELOC
-# define ABSTRACT_TYPELOC(Class) TYPELOC(Class, TypeLoc, Type)
+# define ABSTRACT_TYPELOC(Class) TYPELOC(Class, TypeLoc)
#endif
#ifndef TYPESPEC_TYPELOC
-# define TYPESPEC_TYPELOC(Class, Type) TYPELOC(Class, TypeSpecLoc, Type)
+# define TYPESPEC_TYPELOC(Class, Type) UNQUAL_TYPELOC(Class, TypeSpecLoc, Type)
#endif
#ifndef DECLARATOR_TYPELOC
-# define DECLARATOR_TYPELOC(Class, Type) TYPELOC(Class, DeclaratorLoc, Type)
+# define DECLARATOR_TYPELOC(Class, Type) UNQUAL_TYPELOC(Class, DeclaratorLoc, Type)
#endif
TYPESPEC_TYPELOC(DefaultTypeSpecLoc, Type)
@@ -47,9 +53,11 @@ DECLARATOR_TYPELOC(FunctionLoc, FunctionType)
DECLARATOR_TYPELOC(ArrayLoc, ArrayType)
ABSTRACT_TYPELOC(DeclaratorLoc)
ABSTRACT_TYPELOC(TypeSpecLoc)
+TYPELOC(QualifiedLoc, TypeLoc)
#undef DECLARATOR_TYPELOC
#undef TYPESPEC_TYPELOC
#undef ABSTRACT_TYPELOC
+#undef UNQUAL_TYPELOC
#undef TYPELOC
diff --git a/include/clang/AST/TypeLocVisitor.h b/include/clang/AST/TypeLocVisitor.h
index df386cab6f..a96757f123 100644
--- a/include/clang/AST/TypeLocVisitor.h
+++ b/include/clang/AST/TypeLocVisitor.h
@@ -25,12 +25,14 @@ template<typename ImplClass, typename RetTy=void>
class TypeLocVisitor {
class TypeDispatch : public TypeVisitor<TypeDispatch, RetTy> {
ImplClass *Impl;
- TypeLoc TyLoc;
+ UnqualTypeLoc TyLoc;
public:
- TypeDispatch(ImplClass *impl, TypeLoc &tyLoc) : Impl(impl), TyLoc(tyLoc) { }
+ TypeDispatch(ImplClass *impl, UnqualTypeLoc &tyLoc)
+ : Impl(impl), TyLoc(tyLoc) { }
+#define TYPELOC(CLASS, BASE)
#define ABSTRACT_TYPELOC(CLASS)
-#define TYPELOC(CLASS, PARENT, TYPE) \
+#define UNQUAL_TYPELOC(CLASS, PARENT, TYPE) \
RetTy Visit##TYPE(TYPE *) { \
return Impl->Visit##CLASS(reinterpret_cast<CLASS&>(TyLoc)); \
}
@@ -39,13 +41,22 @@ class TypeLocVisitor {
public:
RetTy Visit(TypeLoc TyLoc) {
+ if (isa<QualifiedLoc>(TyLoc))
+ return static_cast<ImplClass*>(this)->
+ VisitQualifiedLoc(cast<QualifiedLoc>(TyLoc));
+
+ return Visit(cast<UnqualTypeLoc>(TyLoc));
+ }
+
+ RetTy Visit(UnqualTypeLoc TyLoc) {
TypeDispatch TD(static_cast<ImplClass*>(this), TyLoc);
- return TD.Visit(TyLoc.getSourceType().getTypePtr());
+ return TD.Visit(TyLoc.getSourceTypePtr());
}
-#define TYPELOC(CLASS, PARENT, TYPE) RetTy Visit##CLASS(CLASS TyLoc) { \
- DISPATCH(PARENT); \
-}
+#define TYPELOC(CLASS, PARENT) \
+ RetTy Visit##CLASS(CLASS TyLoc) { \
+ DISPATCH(PARENT); \
+ }
#include "clang/AST/TypeLocNodes.def"
RetTy VisitTypeLoc(TypeLoc TyLoc) { return RetTy(); }
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp
index c24477ae81..04e708370a 100644
--- a/lib/AST/TypeLoc.cpp
+++ b/lib/AST/TypeLoc.cpp
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/Support/raw_ostream.h"
#include "clang/AST/TypeLocVisitor.h"
using namespace clang;
@@ -24,7 +25,7 @@ namespace {
class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
public:
#define ABSTRACT_TYPELOC(CLASS)
-#define TYPELOC(CLASS, PARENT, TYPE) \
+#define TYPELOC(CLASS, PARENT) \
SourceRange Visit##CLASS(CLASS TyLoc) { return TyLoc.getSourceRange(); }
#include "clang/AST/TypeLocNodes.def"
@@ -42,25 +43,14 @@ SourceRange TypeLoc::getSourceRange() const {
return TypeLocRanger().Visit(*this);
}
-/// \brief Returns the size of type source info data block for the given type.
-unsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
- return TypeLoc(Ty, 0).getFullDataSize();
-}
-
/// \brief Find the TypeSpecLoc that is part of this TypeLoc.
TypeSpecLoc TypeLoc::getTypeSpecLoc() const {
if (isNull())
return TypeSpecLoc();
-
- if (const DeclaratorLoc *DL = dyn_cast<DeclaratorLoc>(this))
+ UnqualTypeLoc Cur = getUnqualifiedLoc();
+ if (const DeclaratorLoc *DL = dyn_cast<DeclaratorLoc>(&Cur))
return DL->getTypeSpecLoc();
- return cast<TypeSpecLoc>(*this);
-}
-
-/// \brief Find the TypeSpecLoc that is part of this TypeLoc and return its
-/// SourceRange.
-SourceRange TypeLoc::getTypeSpecRange() const {
- return getTypeSpecLoc().getSourceRange();
+ return cast<TypeSpecLoc>(Cur);
}
namespace {
@@ -69,7 +59,7 @@ namespace {
class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
public:
#define ABSTRACT_TYPELOC(CLASS)
-#define TYPELOC(CLASS, PARENT, TYPE) \
+#define TYPELOC(CLASS, PARENT) \
unsigned Visit##CLASS(CLASS TyLoc) { return TyLoc.getFullDataSize(); }
#include "clang/AST/TypeLocNodes.def"
@@ -82,9 +72,9 @@ public:
}
/// \brief Returns the size of the type source info data block.
-unsigned TypeLoc::getFullDataSize() const {
- if (isNull()) return 0;
- return TypeSizer().Visit(*this);
+unsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
+ if (Ty.isNull()) return 0;
+ return TypeSizer().Visit(TypeLoc(Ty, 0));
}
namespace {
@@ -93,13 +83,16 @@ namespace {
/// TypeLoc is a PointerLoc and next TypeLoc is for "int".
class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {
public:
-#define TYPELOC(CLASS, PARENT, TYPE)
+#define TYPELOC(CLASS, PARENT)
#define DECLARATOR_TYPELOC(CLASS, TYPE) \
- TypeLoc Visit##CLASS(CLASS TyLoc);
+ TypeLoc Visit##CLASS(CLASS TyLoc);
#include "clang/AST/TypeLocNodes.def"
TypeLoc VisitTypeSpecLoc(TypeLoc TyLoc) { return TypeLoc(); }
TypeLoc VisitObjCProtocolListLoc(ObjCProtocolListLoc TL);
+ TypeLoc VisitQualifiedLoc(QualifiedLoc TyLoc) {
+ return TyLoc.getUnqualifiedLoc();
+ }
TypeLoc VisitTypeLoc(TypeLoc TyLoc) {
assert(0 && "A declarator loc wrapper was not handled!");
@@ -135,7 +128,10 @@ TypeLoc NextLoc::VisitArrayLoc(ArrayLoc TL) {
/// \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 TypeLoc::getNextTypeLoc() const {
- return NextLoc().Visit(*this);
+ //llvm::errs() << "getNextTypeLoc: Ty=" << Ty << ", Data=" << Data << "\n";
+ TypeLoc Tmp = NextLoc().Visit(*this);
+ //llvm::errs() << " result: Ty=" << Tmp.Ty << ", Data=" << Tmp.Data << "\n";
+ return Tmp;
}
//===----------------------------------------------------------------------===//
@@ -150,7 +146,7 @@ public:
}
-bool TypeSpecLoc::classof(const TypeLoc *TL) {
+bool TypeSpecLoc::classof(const UnqualTypeLoc *TL) {
return TypeSpecChecker().Visit(*TL);
}
@@ -163,7 +159,7 @@ namespace {
/// \brief Return the TypeSpecLoc for the visited DeclaratorLoc.
class TypeSpecGetter : public TypeLocVisitor<TypeSpecGetter, TypeSpecLoc> {
public:
-#define TYPELOC(CLASS, PARENT, TYPE)
+#define TYPELOC(CLASS, PARENT)
#define DECLARATOR_TYPELOC(CLASS, TYPE) \
TypeSpecLoc Visit##CLASS(CLASS TyLoc) { return TyLoc.getTypeSpecLoc(); }
#include "clang/AST/TypeLocNodes.def"
@@ -172,6 +168,10 @@ public:
assert(0 && "A declarator loc wrapper was not handled!");
return TypeSpecLoc();
}
+
+ TypeSpecLoc VisitQualifiedLoc(QualifiedLoc TyLoc) {
+ return Visit(TyLoc.getUnqualifiedLoc());
+ }
};
}
@@ -190,7 +190,7 @@ public:
}
-bool DeclaratorLoc::classof(const TypeLoc *TL) {
+bool DeclaratorLoc::classof(const UnqualTypeLoc *TL) {
return DeclaratorLocChecker().Visit(*TL);
}
@@ -208,163 +208,8 @@ public:
}
-bool DefaultTypeSpecLoc::classof(const TypeLoc *TL) {
- return DefaultTypeSpecLocChecker().Visit(*TL);
-}
-
-//===----------------------------------------------------------------------===//
-// TypedefLoc Implementation
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class TypedefLocChecker : public TypeLocVisitor<TypedefLocChecker, bool> {
-public:
- bool VisitTypedefLoc(TypedefLoc TyLoc) { return true; }
-};
-
-}
-
-bool TypedefLoc::classof(const TypeLoc *TL) {
- return TypedefLocChecker().Visit(*TL);
-}
-
-//===----------------------------------------------------------------------===//
-// ObjCInterfaceLoc Implementation
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class ObjCInterfaceLocChecker :
- public TypeLocVisitor<ObjCInterfaceLocChecker, bool> {
-public:
- bool VisitObjCInterfaceLoc(ObjCInterfaceLoc TyLoc) { return true; }
-};
-
-}
-
-bool ObjCInterfaceLoc::classof(const TypeLoc *TL) {
- return ObjCInterfaceLocChecker().Visit(*TL);
-}
-
-//===----------------------------------------------------------------------===//
-// ObjCProtocolListLoc Implementation
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class ObjCProtocolListLocChecker :
- public TypeLocVisitor<ObjCProtocolListLocChecker, bool> {
-public:
- bool VisitObjCProtocolListLoc(ObjCProtocolListLoc TyLoc) { return true; }
-};
-
-}
-
-bool ObjCProtocolListLoc::classof(const TypeLoc *TL) {
- return ObjCProtocolListLocChecker().Visit(*TL);
-}
-
-//===----------------------------------------------------------------------===//
-// PointerLoc Implementation
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class PointerLocChecker : public TypeLocVisitor<PointerLocChecker, bool> {
-public:
- bool VisitPointerLoc(PointerLoc TyLoc) { return true; }
-};
-
-}
-
-bool PointerLoc::classof(const TypeLoc *TL) {
- return PointerLocChecker().Visit(*TL);
-}
-
-//===----------------------------------------------------------------------===//
-// BlockPointerLoc Implementation
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class BlockPointerLocChecker :
- public TypeLocVisitor<BlockPointerLocChecker, bool> {
-public:
- bool VisitBlockPointerLoc(BlockPointerLoc TyLoc) { return true; }
-};
-
-}
-
-bool BlockPointerLoc::classof(const TypeLoc *TL) {
- return BlockPointerLocChecker().Visit(*TL);
-}
-
-//===----------------------------------------------------------------------===//
-// MemberPointerLoc Implementation
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class MemberPointerLocChecker :
- public TypeLocVisitor<MemberPointerLocChecker, bool> {
-public:
- bool VisitMemberPointerLoc(MemberPointerLoc TyLoc) { return true; }
-};
-
-}
-
-bool MemberPointerLoc::classof(const TypeLoc *TL) {
- return MemberPointerLocChecker().Visit(*TL);
-}
-
-//===----------------------------------------------------------------------===//
-// ReferenceLoc Implementation
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class ReferenceLocChecker : public TypeLocVisitor<ReferenceLocChecker, bool> {
-public:
- bool VisitReferenceLoc(ReferenceLoc TyLoc) { return true; }
-};
-
-}
-
-bool ReferenceLoc::classof(const TypeLoc *TL) {
- return ReferenceLocChecker().Visit(*TL);
-}
-
-//===----------------------------------------------------------------------===//
-// FunctionLoc Implementation
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class FunctionLocChecker : public TypeLocVisitor<FunctionLocChecker, bool> {
-public:
- bool VisitFunctionLoc(FunctionLoc TyLoc) { return true; }
-};
-
-}
-
-bool FunctionLoc::classof(const TypeLoc *TL) {
- return FunctionLocChecker().Visit(*TL);
-}
-
-//===----------------------------------------------------------------------===//
-// ArrayLoc Implementation
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class ArrayLocChecker : public TypeLocVisitor<ArrayLocChecker, bool> {
-public:
- bool VisitArrayLoc(ArrayLoc TyLoc) { return true; }
-};
-
-}
-
-bool ArrayLoc::classof(const TypeLoc *TL) {
- return ArrayLocChecker().Visit(*TL);
+bool DefaultTypeSpecLoc::classofType(const Type *Ty) {
+ return
+ DefaultTypeSpecLocChecker().Visit(UnqualTypeLoc(const_cast<Type*>(Ty), 0));
}
+
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp
index 353a6464b1..b6732561df 100644
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -162,7 +162,7 @@ public:
: Reader(Reader), Record(Record), Idx(Idx) { }
#define ABSTRACT_TYPELOC(CLASS)
-#define TYPELOC(CLASS, PARENT, TYPE) \
+#define TYPELOC(CLASS, PARENT) \
void Visit##CLASS(CLASS TyLoc);
#include "clang/AST/TypeLocNodes.def"
@@ -173,6 +173,9 @@ public:
}
+void TypeLocReader::VisitQualifiedLoc(QualifiedLoc TyLoc) {
+ // nothing to do
+}
void TypeLocReader::VisitDefaultTypeSpecLoc(DefaultTypeSpecLoc TyLoc) {
TyLoc.setStartLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
}
diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp
index 4527bb1f90..ef7c5ec4b1 100644
--- a/lib/Frontend/PCHWriterDecl.cpp
+++ b/lib/Frontend/PCHWriterDecl.cpp
@@ -160,7 +160,7 @@ public:
: Writer(Writer), Record(Record) { }
#define ABSTRACT_TYPELOC(CLASS)
-#define TYPELOC(CLASS, PARENT, TYPE) \
+#define TYPELOC(CLASS, PARENT) \
void Visit##CLASS(CLASS TyLoc);
#include "clang/AST/TypeLocNodes.def"
@@ -171,6 +171,9 @@ public:
}
+void TypeLocWriter::VisitQualifiedLoc(QualifiedLoc TyLoc) {
+ // nothing to do here
+}
void TypeLocWriter::VisitDefaultTypeSpecLoc(DefaultTypeSpecLoc TyLoc) {
Writer.AddSourceLocation(TyLoc.getStartLoc(), Record);
}
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 3cdf615423..9603ca8a51 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1333,6 +1333,9 @@ Sema::GetDeclaratorInfoForDeclarator(Declarator &D, QualType T, unsigned Skip) {
for (unsigned i = Skip, e = D.getNumTypeObjects(); i != e; ++i) {
assert(!CurrTL.isNull());
+
+ // Don't bother recording source locations for qualifiers.
+ CurrTL = CurrTL.getUnqualifiedLoc();
DeclaratorChunk &DeclType = D.getTypeObject(i);
switch (DeclType.Kind) {