forked from OSchip/llvm-project
Some fixes for PCH (de-)serialization of Objective-C AST nodes:
- Deal with the Receiver/ClassInfo shared storage in ObjCMessageExpr - Implement PCH support for ImplicitParamDecl - Fix the handling of the body of an ObjCMethodDecl - Several cast -> cast_or_null fixes - Make Selector::getIdentifierInfoForSlot work for 1-argument, NULL selectors. - Make Selector::getAsString() work with NULL selectors. - Fix the names of VisitObjCAtCatchStmt and VisitObjCAtFinallyStmt in the PCH reader and writer; these were never getting called. At this point, all of the pch-test tests pass for C and Objective-C. llvm-svn: 70163
This commit is contained in:
parent
4e2ab55502
commit
70091b8f43
|
@ -300,8 +300,8 @@ public:
|
|||
return SourceRange(getBase()->getLocStart(), Loc);
|
||||
return SourceRange(ClassLoc, Loc);
|
||||
}
|
||||
const Expr *getBase() const { return cast<Expr>(Base); }
|
||||
Expr *getBase() { return cast<Expr>(Base); }
|
||||
const Expr *getBase() const { return cast_or_null<Expr>(Base); }
|
||||
Expr *getBase() { return cast_or_null<Expr>(Base); }
|
||||
void setBase(Expr *base) { Base = base; }
|
||||
|
||||
SourceLocation getLocation() const { return Loc; }
|
||||
|
@ -375,7 +375,7 @@ public:
|
|||
Expr **ArgExprs, unsigned NumArgs);
|
||||
|
||||
explicit ObjCMessageExpr(EmptyShell Empty)
|
||||
: Expr(ObjCMessageExprClass, Empty) {}
|
||||
: Expr(ObjCMessageExprClass, Empty), SubExprs(0), NumArgs(0) {}
|
||||
|
||||
~ObjCMessageExpr() {
|
||||
delete [] SubExprs;
|
||||
|
@ -418,7 +418,13 @@ public:
|
|||
|
||||
/// getNumArgs - Return the number of actual arguments to this call.
|
||||
unsigned getNumArgs() const { return NumArgs; }
|
||||
void setNumArgs(unsigned nArgs) { NumArgs = nArgs; }
|
||||
void setNumArgs(unsigned nArgs) {
|
||||
NumArgs = nArgs;
|
||||
// FIXME: should always allocate SubExprs via the ASTContext's
|
||||
// allocator.
|
||||
if (!SubExprs)
|
||||
SubExprs = new Stmt* [NumArgs + 1];
|
||||
}
|
||||
|
||||
/// getArg - Return the specified argument.
|
||||
Expr *getArg(unsigned Arg) {
|
||||
|
|
|
@ -412,6 +412,10 @@ public:
|
|||
void *getAsOpaquePtr() const {
|
||||
return reinterpret_cast<void*>(InfoPtr);
|
||||
}
|
||||
|
||||
/// \brief Determine whether this is the empty selector.
|
||||
bool isNull() const { return InfoPtr == 0; }
|
||||
|
||||
// Predicates to identify the selector type.
|
||||
bool isKeywordSelector() const {
|
||||
return getIdentifierInfoFlag() != ZeroArg;
|
||||
|
|
|
@ -412,6 +412,8 @@ namespace clang {
|
|||
DECL_FIELD,
|
||||
/// \brief A VarDecl record.
|
||||
DECL_VAR,
|
||||
/// \brief An ImplicitParamDecl record.
|
||||
DECL_IMPLICIT_PARAM,
|
||||
/// \brief A ParmVarDecl record.
|
||||
DECL_PARM_VAR,
|
||||
/// \brief An OriginalParmVarDecl record.
|
||||
|
|
|
@ -315,9 +315,9 @@ unsigned Selector::getNumArgs() const {
|
|||
}
|
||||
|
||||
IdentifierInfo *Selector::getIdentifierInfoForSlot(unsigned argIndex) const {
|
||||
if (IdentifierInfo *II = getAsIdentifierInfo()) {
|
||||
if (getIdentifierInfoFlag()) {
|
||||
assert(argIndex == 0 && "illegal keyword index");
|
||||
return II;
|
||||
return getAsIdentifierInfo();
|
||||
}
|
||||
// We point to a MultiKeywordSelector (pointer doesn't contain any flags).
|
||||
MultiKeywordSelector *SI = reinterpret_cast<MultiKeywordSelector *>(InfoPtr);
|
||||
|
@ -346,6 +346,9 @@ std::string MultiKeywordSelector::getName() const {
|
|||
}
|
||||
|
||||
std::string Selector::getAsString() const {
|
||||
if (InfoPtr == 0)
|
||||
return "<null selector>";
|
||||
|
||||
if (InfoPtr & ArgFlags) {
|
||||
IdentifierInfo *II = getAsIdentifierInfo();
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ namespace {
|
|||
void VisitFunctionDecl(FunctionDecl *FD);
|
||||
void VisitFieldDecl(FieldDecl *FD);
|
||||
void VisitVarDecl(VarDecl *VD);
|
||||
void VisitImplicitParamDecl(ImplicitParamDecl *PD);
|
||||
void VisitParmVarDecl(ParmVarDecl *PD);
|
||||
void VisitOriginalParmVarDecl(OriginalParmVarDecl *PD);
|
||||
void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD);
|
||||
|
@ -200,7 +201,7 @@ void PCHDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
|
|||
if (Record[Idx++]) {
|
||||
// In practice, this won't be executed (since method definitions
|
||||
// don't occur in header files).
|
||||
MD->setBody(cast<CompoundStmt>(Reader.GetStmt(Record[Idx++])));
|
||||
MD->setBody(cast<CompoundStmt>(Reader.ReadStmt()));
|
||||
MD->setSelfDecl(cast<ImplicitParamDecl>(Reader.GetDecl(Record[Idx++])));
|
||||
MD->setCmdDecl(cast<ImplicitParamDecl>(Reader.GetDecl(Record[Idx++])));
|
||||
}
|
||||
|
@ -376,6 +377,10 @@ void PCHDeclReader::VisitVarDecl(VarDecl *VD) {
|
|||
VD->setInit(Reader.ReadExpr());
|
||||
}
|
||||
|
||||
void PCHDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) {
|
||||
VisitVarDecl(PD);
|
||||
}
|
||||
|
||||
void PCHDeclReader::VisitParmVarDecl(ParmVarDecl *PD) {
|
||||
VisitVarDecl(PD);
|
||||
PD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
|
||||
|
@ -504,8 +509,8 @@ namespace {
|
|||
unsigned VisitObjCSuperExpr(ObjCSuperExpr *E);
|
||||
|
||||
unsigned VisitObjCForCollectionStmt(ObjCForCollectionStmt *);
|
||||
unsigned VisitObjCCatchStmt(ObjCAtCatchStmt *);
|
||||
unsigned VisitObjCFinallyStmt(ObjCAtFinallyStmt *);
|
||||
unsigned VisitObjCAtCatchStmt(ObjCAtCatchStmt *);
|
||||
unsigned VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *);
|
||||
unsigned VisitObjCAtTryStmt(ObjCAtTryStmt *);
|
||||
unsigned VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *);
|
||||
unsigned VisitObjCAtThrowStmt(ObjCAtThrowStmt *);
|
||||
|
@ -1112,10 +1117,13 @@ unsigned PCHStmtReader::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
|
|||
|
||||
unsigned PCHStmtReader::VisitObjCKVCRefExpr(ObjCKVCRefExpr *E) {
|
||||
VisitExpr(E);
|
||||
E->setGetterMethod(cast<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
|
||||
E->setSetterMethod(cast<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
|
||||
E->setClassProp(cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
|
||||
E->setBase(cast<Expr>(StmtStack.back()));
|
||||
E->setGetterMethod(
|
||||
cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
|
||||
E->setSetterMethod(
|
||||
cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
|
||||
E->setClassProp(
|
||||
cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
|
||||
E->setBase(cast_or_null<Expr>(StmtStack.back()));
|
||||
E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
|
||||
E->setClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
|
||||
return 1;
|
||||
|
@ -1129,13 +1137,15 @@ unsigned PCHStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) {
|
|||
E->setSelector(Reader.GetSelector(Record, Idx));
|
||||
E->setMethodDecl(cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
|
||||
|
||||
ObjCMessageExpr::ClassInfo CI;
|
||||
CI.first = cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++]));
|
||||
CI.second = Reader.GetIdentifierInfo(Record, Idx);
|
||||
if (E->getMethodDecl() == 0)
|
||||
E->setReceiver(
|
||||
cast_or_null<Expr>(StmtStack[StmtStack.size() - E->getNumArgs() - 1]));
|
||||
if (!E->getReceiver()) {
|
||||
ObjCMessageExpr::ClassInfo CI;
|
||||
CI.first = cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++]));
|
||||
CI.second = Reader.GetIdentifierInfo(Record, Idx);
|
||||
E->setClassInfo(CI);
|
||||
|
||||
E->setReceiver(cast<Expr>(StmtStack[StmtStack.size() - E->getNumArgs() - 1]));
|
||||
}
|
||||
|
||||
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
|
||||
E->setArg(I, cast<Expr>(StmtStack[StmtStack.size() - N + I]));
|
||||
return E->getNumArgs() + 1;
|
||||
|
@ -1157,7 +1167,7 @@ unsigned PCHStmtReader::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
|
|||
return 3;
|
||||
}
|
||||
|
||||
unsigned PCHStmtReader::VisitObjCCatchStmt(ObjCAtCatchStmt *S) {
|
||||
unsigned PCHStmtReader::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
|
||||
VisitStmt(S);
|
||||
S->setCatchBody(cast_or_null<Stmt>(StmtStack[StmtStack.size() - 2]));
|
||||
S->setNextCatchStmt(cast_or_null<Stmt>(StmtStack[StmtStack.size() - 1]));
|
||||
|
@ -1167,7 +1177,7 @@ unsigned PCHStmtReader::VisitObjCCatchStmt(ObjCAtCatchStmt *S) {
|
|||
return 2;
|
||||
}
|
||||
|
||||
unsigned PCHStmtReader::VisitObjCFinallyStmt(ObjCAtFinallyStmt *S) {
|
||||
unsigned PCHStmtReader::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
|
||||
VisitStmt(S);
|
||||
S->setFinallyBody(StmtStack.back());
|
||||
S->setAtFinallyLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
|
||||
|
@ -2519,11 +2529,14 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
|
|||
break;
|
||||
}
|
||||
|
||||
case pch::DECL_VAR: {
|
||||
case pch::DECL_VAR:
|
||||
D = VarDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
|
||||
VarDecl::None, SourceLocation());
|
||||
break;
|
||||
}
|
||||
|
||||
case pch::DECL_IMPLICIT_PARAM:
|
||||
D = ImplicitParamDecl::Create(Context, 0, SourceLocation(), 0, QualType());
|
||||
break;
|
||||
|
||||
case pch::DECL_PARM_VAR: {
|
||||
D = ParmVarDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
|
||||
|
|
|
@ -260,6 +260,7 @@ namespace {
|
|||
void VisitFunctionDecl(FunctionDecl *D);
|
||||
void VisitFieldDecl(FieldDecl *D);
|
||||
void VisitVarDecl(VarDecl *D);
|
||||
void VisitImplicitParamDecl(ImplicitParamDecl *D);
|
||||
void VisitParmVarDecl(ParmVarDecl *D);
|
||||
void VisitOriginalParmVarDecl(OriginalParmVarDecl *D);
|
||||
void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
|
||||
|
@ -548,6 +549,11 @@ void PCHDeclWriter::VisitVarDecl(VarDecl *D) {
|
|||
Code = pch::DECL_VAR;
|
||||
}
|
||||
|
||||
void PCHDeclWriter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
|
||||
VisitVarDecl(D);
|
||||
Code = pch::DECL_IMPLICIT_PARAM;
|
||||
}
|
||||
|
||||
void PCHDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
|
||||
VisitVarDecl(D);
|
||||
Record.push_back(D->getObjCDeclQualifier()); // FIXME: stable encoding
|
||||
|
@ -680,8 +686,8 @@ namespace {
|
|||
|
||||
// Objective-C Statements
|
||||
void VisitObjCForCollectionStmt(ObjCForCollectionStmt *);
|
||||
void VisitObjCCatchStmt(ObjCAtCatchStmt *);
|
||||
void VisitObjCFinallyStmt(ObjCAtFinallyStmt *);
|
||||
void VisitObjCAtCatchStmt(ObjCAtCatchStmt *);
|
||||
void VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *);
|
||||
void VisitObjCAtTryStmt(ObjCAtTryStmt *);
|
||||
void VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *);
|
||||
void VisitObjCAtThrowStmt(ObjCAtThrowStmt *);
|
||||
|
@ -1249,12 +1255,14 @@ void PCHStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
|
|||
Writer.AddSourceLocation(E->getRightLoc(), Record);
|
||||
Writer.AddSelectorRef(E->getSelector(), Record);
|
||||
Writer.AddDeclRef(E->getMethodDecl(), Record); // optional
|
||||
|
||||
ObjCMessageExpr::ClassInfo CI = E->getClassInfo();
|
||||
Writer.WriteSubStmt(E->getReceiver());
|
||||
Writer.AddDeclRef(CI.first, Record);
|
||||
Writer.AddIdentifierRef(CI.second, Record);
|
||||
|
||||
|
||||
if (!E->getReceiver()) {
|
||||
ObjCMessageExpr::ClassInfo CI = E->getClassInfo();
|
||||
Writer.AddDeclRef(CI.first, Record);
|
||||
Writer.AddIdentifierRef(CI.second, Record);
|
||||
}
|
||||
|
||||
for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
|
||||
Arg != ArgEnd; ++Arg)
|
||||
Writer.WriteSubStmt(*Arg);
|
||||
|
@ -1277,7 +1285,7 @@ void PCHStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
|
|||
Code = pch::STMT_OBJC_FOR_COLLECTION;
|
||||
}
|
||||
|
||||
void PCHStmtWriter::VisitObjCCatchStmt(ObjCAtCatchStmt *S) {
|
||||
void PCHStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
|
||||
Writer.WriteSubStmt(S->getCatchBody());
|
||||
Writer.WriteSubStmt(S->getNextCatchStmt());
|
||||
Writer.AddDeclRef(S->getCatchParamDecl(), Record);
|
||||
|
@ -1286,7 +1294,7 @@ void PCHStmtWriter::VisitObjCCatchStmt(ObjCAtCatchStmt *S) {
|
|||
Code = pch::STMT_OBJC_CATCH;
|
||||
}
|
||||
|
||||
void PCHStmtWriter::VisitObjCFinallyStmt(ObjCAtFinallyStmt *S) {
|
||||
void PCHStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
|
||||
Writer.WriteSubStmt(S->getFinallyBody());
|
||||
Writer.AddSourceLocation(S->getAtFinallyLoc(), Record);
|
||||
Code = pch::STMT_OBJC_FINALLY;
|
||||
|
|
|
@ -7,26 +7,30 @@
|
|||
use POSIX;
|
||||
|
||||
$exitcode = 0;
|
||||
|
||||
sub testfiles($$) {
|
||||
my $suffix = shift;
|
||||
my $language = shift;
|
||||
my $passed = 0;
|
||||
my $failed = 0;
|
||||
my $skipped = 0;
|
||||
|
||||
@files = `ls test/*/*.$suffix`;
|
||||
foreach $file (@files) {
|
||||
chomp($file);
|
||||
print(".");
|
||||
my $code = system("clang-cc -fsyntax-only -x $language $file > /dev/null 2>&1");
|
||||
if ($code == 0) {
|
||||
print(".");
|
||||
$code = system("clang-cc -emit-pch -x $language -o $file.pch $file > /dev/null 2>&1");
|
||||
if ($code == 0) {
|
||||
$code = system("clang-cc -include-pch $file.pch -x $language -ast-dump-full /dev/null > /dev/null 2>&1");
|
||||
if ($code == 0) {
|
||||
$passed++;
|
||||
} elsif (($code & 0xFF) == SIGINT) {
|
||||
exit($exitcode);
|
||||
} else {
|
||||
print("\n---Failed to dump AST file for \"$file\"---\n");
|
||||
$exitcode = 1;
|
||||
$failed++;
|
||||
}
|
||||
unlink "$file.pch";
|
||||
} elsif (($code & 0xFF) == SIGINT) {
|
||||
|
@ -34,11 +38,19 @@ sub testfiles($$) {
|
|||
} else {
|
||||
print("\n---Failed to build PCH file for \"$file\"---\n");
|
||||
$exitcode = 1;
|
||||
$failed++;
|
||||
}
|
||||
} elsif (($code & 0xFF) == SIGINT) {
|
||||
exit($exitcode);
|
||||
} else {
|
||||
print("x");
|
||||
$skipped++;
|
||||
}
|
||||
}
|
||||
|
||||
print("\n\n$passed tests passed\n");
|
||||
print("$failed tests failed\n");
|
||||
print("$skipped tests skipped ('x')\n")
|
||||
}
|
||||
|
||||
printf("-----Testing precompiled headers for C-----\n");
|
||||
|
|
Loading…
Reference in New Issue