mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 12:26:52 +08:00
Finish up saving original parameter type and
using it in ObjC's method parameter encoding. llvm-svn: 61293
This commit is contained in:
@@ -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; }
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user