summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2009-10-15 03:50:32 +0000
committerJohn McCall <rjmccall@apple.com>2009-10-15 03:50:32 +0000
commit33815690af25a41f6739ff9a5cc71bde389f2363 (patch)
tree71cd77e97d60c5143c2aaf6a11a6aea1071e2cdb /clang/lib
parentbf186694b0840670c02242c54d16faa2abe9e945 (diff)
downloadbcm5719-llvm-33815690af25a41f6739ff9a5cc71bde389f2363.tar.gz
bcm5719-llvm-33815690af25a41f6739ff9a5cc71bde389f2363.zip
Better living through metaprogramming. Create a base class which abstracts
most of the unsafe boilerplate out of TypeLoc. Create a QualifiedLoc class to represent the idea that we *might* start representing source locations of qualifiers. Dealing with qualifiers explicitly like this also lets us efficiently ignore them in all the concrete cases. This should make it obvious and easy to add new TypeLoc subclasses. llvm-svn: 84168
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/TypeLoc.cpp213
-rw-r--r--clang/lib/Frontend/PCHReaderDecl.cpp5
-rw-r--r--clang/lib/Frontend/PCHWriterDecl.cpp5
-rw-r--r--clang/lib/Sema/SemaType.cpp3
4 files changed, 40 insertions, 186 deletions
diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp
index c24477ae81c..04e708370af 100644
--- a/clang/lib/AST/TypeLoc.cpp
+++ b/clang/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/clang/lib/Frontend/PCHReaderDecl.cpp b/clang/lib/Frontend/PCHReaderDecl.cpp
index 353a6464b18..b6732561dff 100644
--- a/clang/lib/Frontend/PCHReaderDecl.cpp
+++ b/clang/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/clang/lib/Frontend/PCHWriterDecl.cpp b/clang/lib/Frontend/PCHWriterDecl.cpp
index 4527bb1f901..ef7c5ec4b1a 100644
--- a/clang/lib/Frontend/PCHWriterDecl.cpp
+++ b/clang/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/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 3cdf6154232..9603ca8a51c 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/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) {
OpenPOWER on IntegriCloud