diff options
Diffstat (limited to 'lib/AST')
-rw-r--r-- | lib/AST/Decl.cpp | 27 | ||||
-rw-r--r-- | lib/AST/DeclBase.cpp | 9 | ||||
-rw-r--r-- | lib/AST/DeclCXX.cpp | 2 |
3 files changed, 29 insertions, 9 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 6b52a17a21..149938fc5c 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -953,6 +953,17 @@ bool FunctionDecl::isVariadic() const { return false; } +bool FunctionDecl::hasBody(const FunctionDecl *&Definition) const { + for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) { + if (I->Body) { + Definition = *I; + return true; + } + } + + return false; +} + Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const { for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) { if (I->Body) { @@ -1153,11 +1164,11 @@ bool FunctionDecl::isInlined() const { } const FunctionDecl *PatternDecl = getTemplateInstantiationPattern(); - Stmt *Pattern = 0; + bool HasPattern = false; if (PatternDecl) - Pattern = PatternDecl->getBody(PatternDecl); + HasPattern = PatternDecl->hasBody(PatternDecl); - if (Pattern && PatternDecl) + if (HasPattern && PatternDecl) return PatternDecl->isInlined(); return false; @@ -1302,15 +1313,15 @@ bool FunctionDecl::isImplicitlyInstantiable() const { // Find the actual template from which we will instantiate. const FunctionDecl *PatternDecl = getTemplateInstantiationPattern(); - Stmt *Pattern = 0; + bool HasPattern = false; if (PatternDecl) - Pattern = PatternDecl->getBody(PatternDecl); + HasPattern = PatternDecl->hasBody(PatternDecl); // C++0x [temp.explicit]p9: // Except for inline functions, other explicit instantiation declarations // have the effect of suppressing the implicit instantiation of the entity // to which they refer. - if (!Pattern || !PatternDecl) + if (!HasPattern || !PatternDecl) return true; return PatternDecl->isInlined(); @@ -1514,7 +1525,7 @@ bool FunctionDecl::isOutOfLine() const { // class template, check whether that member function was defined out-of-line. if (FunctionDecl *FD = getInstantiatedFromMemberFunction()) { const FunctionDecl *Definition; - if (FD->getBody(Definition)) + if (FD->hasBody(Definition)) return Definition->isOutOfLine(); } @@ -1522,7 +1533,7 @@ bool FunctionDecl::isOutOfLine() const { // check whether that function template was defined out-of-line. if (FunctionTemplateDecl *FunTmpl = getPrimaryTemplate()) { const FunctionDecl *Definition; - if (FunTmpl->getTemplatedDecl()->getBody(Definition)) + if (FunTmpl->getTemplatedDecl()->hasBody(Definition)) return Definition->isOutOfLine(); } diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 7a104f4d57..0821da3b87 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -452,6 +452,15 @@ CompoundStmt* Decl::getCompoundBody() const { } SourceLocation Decl::getBodyRBrace() const { + // Special handling of FunctionDecl to avoid de-serializing the body from PCH. + // FunctionDecl stores EndRangeLoc for this purpose. + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this)) { + const FunctionDecl *Definition; + if (FD->hasBody(Definition)) + return Definition->getSourceRange().getEnd(); + return SourceLocation(); + } + Stmt *Body = getBody(); if (!Body) return SourceLocation(); diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 19c3ac1011..dd0fe08979 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -743,7 +743,7 @@ bool CXXMethodDecl::hasInlineBody() const { CheckFn = this; const FunctionDecl *fn; - return CheckFn->getBody(fn) && !fn->isOutOfLine(); + return CheckFn->hasBody(fn) && !fn->isOutOfLine(); } CXXBaseOrMemberInitializer:: |