Finish up saving original parameter type and
using it in ObjC's method parameter encoding.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61293 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 8aaf5d6..aaae092 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -472,10 +472,10 @@
/// 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 @@
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 @@
/// 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; }
diff --git a/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h b/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h
index 322070b..e9228b6 100644
--- a/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h
+++ b/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h
@@ -59,6 +59,7 @@
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 @@
DEFAULT_DISPATCH(VarDecl)
DEFAULT_DISPATCH(FunctionDecl)
+ DEFAULT_DISPATCH_VARDECL(ParmVarWithOriginalTypeDecl)
DEFAULT_DISPATCH_VARDECL(ParmVarDecl)
DEFAULT_DISPATCH(ImplicitParamDecl)
DEFAULT_DISPATCH(EnumConstantDecl)
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index d03ed41..791e386 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1638,11 +1638,17 @@
// 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);
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 021becc..3edf8a0 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -54,7 +54,14 @@
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(
diff --git a/lib/AST/DeclSerialization.cpp b/lib/AST/DeclSerialization.cpp
index c09b0ed..7f6b504 100644
--- a/lib/AST/DeclSerialization.cpp
+++ b/lib/AST/DeclSerialization.cpp
@@ -399,7 +399,8 @@
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());
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index d4cef9b..7759bac 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -1236,21 +1236,31 @@
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);
diff --git a/test/CodeGenObjC/encode-test.m b/test/CodeGenObjC/encode-test.m
index 109f057..b07503d 100644
--- a/test/CodeGenObjC/encode-test.m
+++ b/test/CodeGenObjC/encode-test.m
@@ -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 @@
@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);