From 1eb71a1ba7b627ef50ac6b179676815237ac6a19 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Thu, 6 Dec 2012 18:59:10 +0000 Subject: [PATCH] Add a bit on FunctionDecl/ObjCMethodDecl to indicate if there was a body that was skipped by the parser. llvm-svn: 169531 --- clang/include/clang/AST/Decl.h | 8 ++++++++ clang/include/clang/AST/DeclObjC.h | 7 +++++++ clang/include/clang/Sema/Sema.h | 1 + clang/lib/Parse/ParseStmt.cpp | 4 ++-- clang/lib/Sema/SemaDecl.cpp | 8 ++++++++ clang/lib/Serialization/ASTReaderDecl.cpp | 2 ++ clang/lib/Serialization/ASTWriterDecl.cpp | 2 ++ 7 files changed, 30 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index a8ce7df5b2ee..9758db1298c2 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -1472,6 +1472,10 @@ private: bool IsLateTemplateParsed : 1; bool IsConstexpr : 1; + /// \brief Indicates if the function was a definition but its body was + /// skipped. + unsigned HasSkippedBody : 1; + /// \brief End part of this FunctionDecl's source range. /// /// We could compute the full range in getSourceRange(). However, when we're @@ -1782,6 +1786,10 @@ public: /// \brief Determines whether this is a global function. bool isGlobal() const; + /// \brief True if the function was a definition but its body was skipped. + bool hasSkippedBody() const { return HasSkippedBody; } + void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; } + void setPreviousDeclaration(FunctionDecl * PrevDecl); virtual const FunctionDecl *getCanonicalDecl() const; diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index 13155f060669..6ceb066267c2 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -159,6 +159,9 @@ private: /// method in the interface or its categories. unsigned IsOverriding : 1; + /// \brief Indicates if the method was a definition but its body was skipped. + unsigned HasSkippedBody : 1; + // Result type of this method. QualType MethodDeclType; @@ -429,6 +432,10 @@ public: void getOverriddenMethods( SmallVectorImpl &Overridden) const; + /// \brief True if the method was a definition but its body was skipped. + bool hasSkippedBody() const { return HasSkippedBody; } + void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; } + /// \brief Returns the property associated with this method's selector. /// /// Note that even if this particular method is not marked as a property diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index cc638e7d912f..59013d56d60a 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -1412,6 +1412,7 @@ public: void computeNRVO(Stmt *Body, sema::FunctionScopeInfo *Scope); Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body); Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body, bool IsInstantiation); + Decl *ActOnSkippedFunctionBody(Decl *Decl); /// ActOnFinishDelayedAttribute - Invoked when we have finished parsing an /// attribute for which parsing is delayed. diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index f6f5afe46714..8c33bd6de802 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -2006,7 +2006,7 @@ Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) { if (SkipFunctionBodies && Actions.canSkipFunctionBody(Decl) && trySkippingFunctionBody()) { BodyScope.Exit(); - return Actions.ActOnFinishFunctionBody(Decl, 0); + return Actions.ActOnSkippedFunctionBody(Decl); } PrettyDeclStackTraceEntry CrashInfo(Actions, Decl, LBraceLoc, @@ -2049,7 +2049,7 @@ Decl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) { if (SkipFunctionBodies && Actions.canSkipFunctionBody(Decl) && trySkippingFunctionBody()) { BodyScope.Exit(); - return Actions.ActOnFinishFunctionBody(Decl, 0); + return Actions.ActOnSkippedFunctionBody(Decl); } SourceLocation LBraceLoc = Tok.getLocation(); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 102a6ae9a237..9dd77795379b 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -8016,6 +8016,14 @@ bool Sema::canSkipFunctionBody(Decl *D) { return !FD->isConstexpr(); } +Decl *Sema::ActOnSkippedFunctionBody(Decl *Decl) { + if (FunctionDecl *FD = dyn_cast(Decl)) + FD->setHasSkippedBody(); + else if (ObjCMethodDecl *MD = dyn_cast(Decl)) + MD->setHasSkippedBody(); + return ActOnFinishFunctionBody(Decl, 0); +} + Decl *Sema::ActOnFinishFunctionBody(Decl *D, Stmt *BodyArg) { return ActOnFinishFunctionBody(D, BodyArg, false); } diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 6693416b4a90..d201f539fab7 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -528,6 +528,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { FD->IsExplicitlyDefaulted = Record[Idx++]; FD->HasImplicitReturnZero = Record[Idx++]; FD->IsConstexpr = Record[Idx++]; + FD->HasSkippedBody = Record[Idx++]; FD->EndRangeLoc = ReadSourceLocation(Record, Idx); switch ((FunctionDecl::TemplatedKind)Record[Idx++]) { @@ -652,6 +653,7 @@ void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) { MD->setPropertyAccessor(Record[Idx++]); MD->setDefined(Record[Idx++]); MD->IsOverriding = Record[Idx++]; + MD->HasSkippedBody = Record[Idx++]; MD->IsRedeclaration = Record[Idx++]; MD->HasRedeclaration = Record[Idx++]; diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 777b1eab2839..dfafc16511d8 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -328,6 +328,7 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { Record.push_back(D->isExplicitlyDefaulted()); Record.push_back(D->hasImplicitReturnZero()); Record.push_back(D->isConstexpr()); + Record.push_back(D->HasSkippedBody); Writer.AddSourceLocation(D->getLocEnd(), Record); Record.push_back(D->getTemplatedKind()); @@ -419,6 +420,7 @@ void ASTDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) { Record.push_back(D->isPropertyAccessor()); Record.push_back(D->isDefined()); Record.push_back(D->IsOverriding); + Record.push_back(D->HasSkippedBody); Record.push_back(D->IsRedeclaration); Record.push_back(D->HasRedeclaration);