Finish up saving original parameter type and

using it in ObjC's method parameter encoding.

llvm-svn: 61293
This commit is contained in:
Fariborz Jahanian
2008-12-20 23:29:59 +00:00
parent 5ad3c91b27
commit a0befc0a6f
7 changed files with 65 additions and 20 deletions

View File

@@ -472,10 +472,10 @@ class ParmVarDecl : public VarDecl {
/// Default argument, if any. [C++ Only]
Expr *DefaultArg;
protected:
ParmVarDecl(DeclContext *DC, SourceLocation L,
ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType T, StorageClass S,
Expr *DefArg, ScopedDecl *PrevDecl)
: VarDecl(ParmVar, DC, L, Id, T, S, PrevDecl),
: VarDecl(DK, DC, L, Id, T, S, PrevDecl),
objcDeclQualifier(OBJC_TQ_None), DefaultArg(DefArg) {}
public:
@@ -495,8 +495,13 @@ public:
Expr *getDefaultArg() { return DefaultArg; }
void setDefaultArg(Expr *defarg) { DefaultArg = defarg; }
QualType getOriginalType() const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == ParmVar; }
static bool classof(const Decl *D) {
return (D->getKind() == ParmVar ||
D->getKind() == OriginalParmVar);
}
static bool classof(const ParmVarDecl *D) { return true; }
protected:
@@ -514,22 +519,23 @@ protected:
/// parameter to the function with its original type.
///
class ParmVarWithOriginalTypeDecl : public ParmVarDecl {
private:
friend class ParmVarDecl;
protected:
QualType OriginalType;
private:
ParmVarWithOriginalTypeDecl(DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType T,
QualType OT, StorageClass S,
Expr *DefArg, ScopedDecl *PrevDecl)
: ParmVarDecl(DC, L, Id, T, S, DefArg, PrevDecl), OriginalType(OT) {}
: ParmVarDecl(OriginalParmVar,
DC, L, Id, T, S, DefArg, PrevDecl), OriginalType(OT) {}
public:
static ParmVarWithOriginalTypeDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,IdentifierInfo *Id,
QualType T, QualType OT,
StorageClass S, Expr *DefArg,
ScopedDecl *PrevDecl);
QualType getQualType() const { return OriginalType; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == OriginalParmVar; }
static bool classof(const ParmVarWithOriginalTypeDecl *D) { return true; }

View File

@@ -59,6 +59,7 @@ public:
DISPATCH_CASE(Function,FunctionDecl)
DISPATCH_CASE(Var,VarDecl)
DISPATCH_CASE(ParmVar,ParmVarDecl) // FIXME: (same)
DISPATCH_CASE(OriginalParmVar,ParmVarWithOriginalTypeDecl) // FIXME: (same)
DISPATCH_CASE(ImplicitParam,ImplicitParamDecl)
DISPATCH_CASE(EnumConstant,EnumConstantDecl)
DISPATCH_CASE(Typedef,TypedefDecl)
@@ -71,6 +72,7 @@ public:
DEFAULT_DISPATCH(VarDecl)
DEFAULT_DISPATCH(FunctionDecl)
DEFAULT_DISPATCH_VARDECL(ParmVarWithOriginalTypeDecl)
DEFAULT_DISPATCH_VARDECL(ParmVarDecl)
DEFAULT_DISPATCH(ImplicitParamDecl)
DEFAULT_DISPATCH(EnumConstantDecl)

View File

@@ -1638,11 +1638,17 @@ void ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
// Argument types.
ParmOffset = 2 * PtrSize;
for (int i = 0; i < NumOfParams; i++) {
QualType PType = Decl->getParamDecl(i)->getType();
ParmVarDecl *PVDecl = Decl->getParamDecl(i);
QualType PType = PVDecl->getOriginalType();
if (const ArrayType *AT =
dyn_cast<ArrayType>(PType->getCanonicalTypeInternal()))
// Use array's original type only if it has known number of
// elements.
if (!dyn_cast<ConstantArrayType>(AT))
PType = PVDecl->getType();
// Process argument qualifiers for user supplied arguments; such as,
// 'in', 'inout', etc.
getObjCEncodingForTypeQualifier(
Decl->getParamDecl(i)->getObjCDeclQualifier(), S);
getObjCEncodingForTypeQualifier(PVDecl->getObjCDeclQualifier(), S);
getObjCEncodingForType(PType, S);
S += llvm::utostr(ParmOffset);
ParmOffset += getObjCEncodingTypeSize(PType);

View File

@@ -54,7 +54,14 @@ ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC,
QualType T, StorageClass S,
Expr *DefArg, ScopedDecl *PrevDecl) {
void *Mem = C.getAllocator().Allocate<ParmVarDecl>();
return new (Mem) ParmVarDecl(DC, L, Id, T, S, DefArg, PrevDecl);
return new (Mem) ParmVarDecl(ParmVar, DC, L, Id, T, S, DefArg, PrevDecl);
}
QualType ParmVarDecl::getOriginalType() const {
if (const ParmVarWithOriginalTypeDecl *PVD =
dyn_cast<ParmVarWithOriginalTypeDecl>(this))
return PVD->OriginalType;
return getType();
}
ParmVarWithOriginalTypeDecl *ParmVarWithOriginalTypeDecl::Create(

View File

@@ -399,7 +399,8 @@ void ParmVarDecl::EmitImpl(llvm::Serializer& S) const {
ParmVarDecl* ParmVarDecl::CreateImpl(Deserializer& D, ASTContext& C) {
void *Mem = C.getAllocator().Allocate<ParmVarDecl>();
ParmVarDecl* decl = new (Mem)
ParmVarDecl(0, SourceLocation(), NULL, QualType(), None, NULL, NULL);
ParmVarDecl(ParmVar,
0, SourceLocation(), NULL, QualType(), None, NULL, NULL);
decl->VarDecl::ReadImpl(D, C);
decl->objcDeclQualifier = static_cast<ObjCDeclQualifier>(D.ReadInt());

View File

@@ -1236,21 +1236,31 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration(
for (unsigned i = 0; i < Sel.getNumArgs(); i++) {
// FIXME: arg->AttrList must be stored too!
QualType argType;
QualType argType, originalArgType;
if (ArgTypes[i]) {
argType = QualType::getFromOpaquePtr(ArgTypes[i]);
// Perform the default array/function conversions (C99 6.7.5.3p[7,8]).
if (argType->isArrayType()) // (char *[]) -> (char **)
if (argType->isArrayType()) { // (char *[]) -> (char **)
originalArgType = argType;
argType = Context.getArrayDecayedType(argType);
}
else if (argType->isFunctionType())
argType = Context.getPointerType(argType);
} else
argType = Context.getObjCIdType();
ParmVarDecl* Param = ParmVarDecl::Create(Context, ObjCMethod,
SourceLocation(/*FIXME*/),
ArgNames[i], argType,
VarDecl::None, 0, 0);
ParmVarDecl* Param;
if (originalArgType.isNull())
Param = ParmVarDecl::Create(Context, ObjCMethod,
SourceLocation(/*FIXME*/),
ArgNames[i], argType,
VarDecl::None, 0, 0);
else
Param = ParmVarWithOriginalTypeDecl::Create(Context, ObjCMethod,
SourceLocation(/*FIXME*/),
ArgNames[i], argType, originalArgType,
VarDecl::None, 0, 0);
Param->setObjCDeclQualifier(
CvtQTToAstBitMask(ArgQT[i].getObjCDeclQualifier()));
Params.push_back(Param);

View File

@@ -1,7 +1,8 @@
// RUN: clang -fnext-runtime -emit-llvm -o %t %s &&
// RUN: grep -e "\^{Innermost=CC}" %t | count 1 &&
// RUN: grep -e "{Derived=#ib32b8b3b8sb16b8b8b2b8ccb6}" %t | count 1 &&
// RUN: grep -e "{B1=#@c}" %t | count 1
// RUN: grep -e "{B1=#@c}" %t | count 1 &&
// RUN: grep -e "v12@0:4\[3\[4{Test=i}]]8" %t | count 1
@class Int1;
@@ -60,6 +61,18 @@ struct Innermost {
@implementation B1
@end
@interface Test
{
int ivar;
}
-(void) test3: (Test [3] [4])b ;
@end
@implementation Test
-(void) test3: (Test [3] [4])b {}
@end
int main()
{
const char *en = @encode(Derived);