aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaType.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2009-10-18 01:05:36 +0000
committerJohn McCall <rjmccall@apple.com>2009-10-18 01:05:36 +0000
commit51bd803fbdade51d674598ed45da3d54190a656c (patch)
tree6a0f7a2881033be64625cb432e7b7e96eb0729fa /lib/Sema/SemaType.cpp
parenta47dd191719e88e41ce82555685869d2054178e1 (diff)
Clone the full Type hierarchy into the TypeLoc hierarchy. Normalize
TypeLoc class names to be $(Type classname)Loc. Rewrite the visitor. Provide skeleton implementations for all the new TypeLocs. Handle all cases in PCH. Handle a few more cases when inserting location information in SemaType. It should be extremely straightforward to add new location information to existing TypeLoc objects now. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84386 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaType.cpp')
-rw-r--r--lib/Sema/SemaType.cpp165
1 files changed, 92 insertions, 73 deletions
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 99b2a51ce7..117f595d92 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -17,6 +17,7 @@
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/TypeLoc.h"
+#include "clang/AST/TypeLocVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Parse/DeclSpec.h"
@@ -1298,100 +1299,118 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
return T;
}
-static void FillTypeSpecLoc(TypeLoc TSL, const DeclSpec &DS) {
- if (TSL.isNull()) return;
+namespace {
+ class TypeSpecLocFiller : public TypeLocVisitor<TypeSpecLocFiller> {
+ const DeclSpec &DS;
- if (TypedefLoc *TL = dyn_cast<TypedefLoc>(&TSL)) {
- TL->setNameLoc(DS.getTypeSpecTypeLoc());
+ public:
+ TypeSpecLocFiller(const DeclSpec &DS) : DS(DS) {}
- } else if (ObjCInterfaceLoc *TL = dyn_cast<ObjCInterfaceLoc>(&TSL)) {
- TL->setNameLoc(DS.getTypeSpecTypeLoc());
+ void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
+ Visit(TL.getUnqualifiedLoc());
+ }
+ void VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+ TL.setNameLoc(DS.getTypeSpecTypeLoc());
+ }
+ void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
+ TL.setNameLoc(DS.getTypeSpecTypeLoc());
+ }
+ void VisitObjCProtocolListTypeLoc(ObjCProtocolListTypeLoc TL) {
+ assert(TL.getNumProtocols() == DS.getNumProtocolQualifiers());
+ TL.setLAngleLoc(DS.getProtocolLAngleLoc());
+ TL.setRAngleLoc(DS.getSourceRange().getEnd());
+ for (unsigned i = 0; i != DS.getNumProtocolQualifiers(); ++i)
+ TL.setProtocolLoc(i, DS.getProtocolLocs()[i]);
+
+ TypeLoc BaseLoc = TL.getBaseTypeLoc();
+ if (BaseLoc)
+ Visit(TL.getBaseTypeLoc());
+ }
+ void VisitTypeLoc(TypeLoc TL) {
+ // FIXME: add other typespec types and change this to an assert.
+ TL.initialize(DS.getTypeSpecTypeLoc());
+ }
+ };
- } else if (ObjCProtocolListLoc *PLL = dyn_cast<ObjCProtocolListLoc>(&TSL)) {
- assert(PLL->getNumProtocols() == DS.getNumProtocolQualifiers());
- PLL->setLAngleLoc(DS.getProtocolLAngleLoc());
- PLL->setRAngleLoc(DS.getSourceRange().getEnd());
- for (unsigned i = 0; i != DS.getNumProtocolQualifiers(); ++i)
- PLL->setProtocolLoc(i, DS.getProtocolLocs()[i]);
- FillTypeSpecLoc(PLL->getBaseTypeLoc(), DS);
+ class DeclaratorLocFiller : public TypeLocVisitor<DeclaratorLocFiller> {
+ const DeclaratorChunk &Chunk;
- } else {
- //FIXME: Other typespecs.
- DefaultTypeSpecLoc &DTL = cast<DefaultTypeSpecLoc>(TSL);
- DTL.setStartLoc(DS.getSourceRange().getBegin());
- }
-}
+ public:
+ DeclaratorLocFiller(const DeclaratorChunk &Chunk) : Chunk(Chunk) {}
-/// \brief Create and instantiate a DeclaratorInfo with type source information.
-///
-/// \param T QualType referring to the type as written in source code.
-DeclaratorInfo *
-Sema::GetDeclaratorInfoForDeclarator(Declarator &D, QualType T, unsigned Skip) {
- DeclaratorInfo *DInfo = Context.CreateDeclaratorInfo(T);
- TypeLoc CurrTL = DInfo->getTypeLoc();
-
- for (unsigned i = Skip, e = D.getNumTypeObjects(); i != e; ++i) {
- assert(!CurrTL.isNull());
-
- // Don't bother recording source locations for qualifiers.
- CurrTL = CurrTL.getUnqualifiedLoc();
+ void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
+ llvm::llvm_unreachable("qualified type locs not expected here!");
+ }
- DeclaratorChunk &DeclType = D.getTypeObject(i);
- switch (DeclType.Kind) {
- default: assert(0 && "Unknown decltype!");
- case DeclaratorChunk::BlockPointer: {
- BlockPointerLoc &BPL = cast<BlockPointerLoc>(CurrTL);
- BPL.setCaretLoc(DeclType.Loc);
- break;
+ void VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
+ assert(Chunk.Kind == DeclaratorChunk::BlockPointer);
+ TL.setCaretLoc(Chunk.Loc);
}
- case DeclaratorChunk::Pointer: {
- //FIXME: ObjCObject pointers.
- PointerLoc &PL = cast<PointerLoc>(CurrTL);
- PL.setStarLoc(DeclType.Loc);
- break;
+ void VisitPointerTypeLoc(PointerTypeLoc TL) {
+ assert(Chunk.Kind == DeclaratorChunk::Pointer);
+ TL.setStarLoc(Chunk.Loc);
}
- case DeclaratorChunk::Reference: {
- ReferenceLoc &RL = cast<ReferenceLoc>(CurrTL);
- RL.setAmpLoc(DeclType.Loc);
- break;
+ void VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
+ assert(Chunk.Kind == DeclaratorChunk::Pointer);
+ TL.setStarLoc(Chunk.Loc);
}
- case DeclaratorChunk::Array: {
- DeclaratorChunk::ArrayTypeInfo &ATI = DeclType.Arr;
- ArrayLoc &AL = cast<ArrayLoc>(CurrTL);
- AL.setLBracketLoc(DeclType.Loc);
- AL.setRBracketLoc(DeclType.EndLoc);
- AL.setSizeExpr(static_cast<Expr*>(ATI.NumElts));
- //FIXME: Star location for [*].
- break;
+ void VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
+ assert(Chunk.Kind == DeclaratorChunk::MemberPointer);
+ TL.setStarLoc(Chunk.Loc);
+ // FIXME: nested name specifier
}
- case DeclaratorChunk::Function: {
- const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
- FunctionLoc &FL = cast<FunctionLoc>(CurrTL);
- FL.setLParenLoc(DeclType.Loc);
- FL.setRParenLoc(DeclType.EndLoc);
+ void VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
+ assert(Chunk.Kind == DeclaratorChunk::Reference);
+ assert(Chunk.Ref.LValueRef);
+ TL.setAmpLoc(Chunk.Loc);
+ }
+ void VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
+ assert(Chunk.Kind == DeclaratorChunk::Reference);
+ assert(!Chunk.Ref.LValueRef);
+ TL.setAmpAmpLoc(Chunk.Loc);
+ }
+ void VisitArrayTypeLoc(ArrayTypeLoc TL) {
+ assert(Chunk.Kind == DeclaratorChunk::Array);
+ TL.setLBracketLoc(Chunk.Loc);
+ TL.setRBracketLoc(Chunk.EndLoc);
+ TL.setSizeExpr(static_cast<Expr*>(Chunk.Arr.NumElts));
+ }
+ void VisitFunctionTypeLoc(FunctionTypeLoc TL) {
+ assert(Chunk.Kind == DeclaratorChunk::Function);
+ TL.setLParenLoc(Chunk.Loc);
+ TL.setRParenLoc(Chunk.EndLoc);
+
+ const DeclaratorChunk::FunctionTypeInfo &FTI = Chunk.Fun;
for (unsigned i = 0, e = FTI.NumArgs, tpi = 0; i != e; ++i) {
ParmVarDecl *Param = FTI.ArgInfo[i].Param.getAs<ParmVarDecl>();
if (Param) {
- assert(tpi < FL.getNumArgs());
- FL.setArg(tpi++, Param);
+ assert(tpi < TL.getNumArgs());
+ TL.setArg(tpi++, Param);
}
}
- break;
- //FIXME: Exception specs.
- }
- case DeclaratorChunk::MemberPointer: {
- MemberPointerLoc &MPL = cast<MemberPointerLoc>(CurrTL);
- MPL.setStarLoc(DeclType.Loc);
- //FIXME: Class location.
- break;
+ // FIXME: exception specs
}
+ void VisitTypeLoc(TypeLoc TL) {
+ llvm::llvm_unreachable("unsupported TypeLoc kind in declarator!");
}
+ };
+}
- CurrTL = CurrTL.getNextTypeLoc();
+/// \brief Create and instantiate a DeclaratorInfo with type source information.
+///
+/// \param T QualType referring to the type as written in source code.
+DeclaratorInfo *
+Sema::GetDeclaratorInfoForDeclarator(Declarator &D, QualType T, unsigned Skip) {
+ DeclaratorInfo *DInfo = Context.CreateDeclaratorInfo(T);
+ UnqualTypeLoc CurrTL = DInfo->getTypeLoc().getUnqualifiedLoc();
+
+ for (unsigned i = Skip, e = D.getNumTypeObjects(); i != e; ++i) {
+ DeclaratorLocFiller(D.getTypeObject(i)).Visit(CurrTL);
+ CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc();
}
- FillTypeSpecLoc(CurrTL, D.getDeclSpec());
+ TypeSpecLocFiller(D.getDeclSpec()).Visit(CurrTL);
return DInfo;
}