/// 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:
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:
/// 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; }
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)
DEFAULT_DISPATCH(VarDecl)
DEFAULT_DISPATCH(FunctionDecl)
+ DEFAULT_DISPATCH_VARDECL(ParmVarWithOriginalTypeDecl)
DEFAULT_DISPATCH_VARDECL(ParmVarDecl)
DEFAULT_DISPATCH(ImplicitParamDecl)
DEFAULT_DISPATCH(EnumConstantDecl)
// 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);
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(
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());
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);
// 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;
@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);