jlebar updated this revision to Diff 76118.
jlebar added a comment.
Add WillHaveBody flag.
https://reviews.llvm.org/D25640
Files:
clang/include/clang/AST/Decl.h
clang/lib/AST/Decl.cpp
clang/lib/Sema/SemaDecl.cpp
clang/test/SemaCUDA/gnu-inline.cu
Index: clang/test/SemaCUDA/gnu-inline.cu
===================================================================
--- /dev/null
+++ clang/test/SemaCUDA/gnu-inline.cu
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#include "Inputs/cuda.h"
+
+// expected-no-diagnostics
+
+// Check that we can handle gnu_inline functions when compiling in CUDA mode.
+
+void foo();
+inline __attribute__((gnu_inline)) void bar() { foo(); }
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -5758,23 +5758,7 @@
return false;
// Okay, go ahead and call the relatively-more-expensive function.
-
-#ifndef NDEBUG
- // AST quite reasonably asserts that it's working on a function
- // definition. We don't really have a way to tell it that we're
- // currently defining the function, so just lie to it in +Asserts
- // builds. This is an awful hack.
- FD->setLazyBody(1);
-#endif
-
- bool isC99Inline =
- S.Context.GetGVALinkageForFunction(FD) == GVA_AvailableExternally;
-
-#ifndef NDEBUG
- FD->setLazyBody(0);
-#endif
-
- return isC99Inline;
+ return S.Context.GetGVALinkageForFunction(FD) == GVA_AvailableExternally;
}
/// Determine whether a variable is extern "C" prior to attaching
@@ -11494,6 +11478,11 @@
return D;
}
+ // Mark this function as "will have a body eventually". This lets users to
+ // call e.g. isInlineDefinitionExternallyVisible while we're still parsing
+ // this function.
+ FD->setWillHaveBody();
+
// If we are instantiating a generic lambda call operator, push
// a LambdaScopeInfo onto the function stack. But use the information
// that's already been calculated (ActOnLambdaExpr) to prime the current
Index: clang/lib/AST/Decl.cpp
===================================================================
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -2933,7 +2933,7 @@
/// of redeclarations of the given functions causes
/// isInlineDefinitionExternallyVisible to change from false to true.
bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const {
- assert(!doesThisDeclarationHaveABody() &&
+ assert(!doesThisDeclarationHaveABody() && !willHaveBody() &&
"Must have a declaration without a body.");
ASTContext &Context = getASTContext();
@@ -3048,7 +3048,8 @@
/// an externally visible symbol, but "extern inline" will not create an
/// externally visible symbol.
bool FunctionDecl::isInlineDefinitionExternallyVisible() const {
- assert(doesThisDeclarationHaveABody() && "Must have the function definition");
+ assert(doesThisDeclarationHaveABody() ||
+ willHaveBody() && "Must be a function definition");
assert(isInlined() && "Function must be inline");
ASTContext &Context = getASTContext();
Index: clang/include/clang/AST/Decl.h
===================================================================
--- clang/include/clang/AST/Decl.h
+++ clang/include/clang/AST/Decl.h
@@ -1632,6 +1632,11 @@
/// skipped.
unsigned HasSkippedBody : 1;
+ /// Indicates if the function declaration will have a body, once we're done
+ /// parsing it. (We don't set it to false when we're done parsing, in the
+ /// hopes this is simpler.)
+ unsigned WillHaveBody : 1;
+
/// \brief End part of this FunctionDecl's source range.
///
/// We could compute the full range in getSourceRange(). However, when we're
@@ -1701,25 +1706,21 @@
protected:
FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- StorageClass S, bool isInlineSpecified,
+ const DeclarationNameInfo &NameInfo, QualType T,
+ TypeSourceInfo *TInfo, StorageClass S, bool isInlineSpecified,
bool isConstexprSpecified)
- : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
- StartLoc),
- DeclContext(DK),
- redeclarable_base(C),
- ParamInfo(nullptr), Body(),
- SClass(S),
- IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified),
- IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
- HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),
- IsDefaulted(false), IsExplicitlyDefaulted(false),
- HasImplicitReturnZero(false), IsLateTemplateParsed(false),
- IsConstexpr(isConstexprSpecified), UsesSEHTry(false),
- HasSkippedBody(false), EndRangeLoc(NameInfo.getEndLoc()),
- TemplateOrSpecialization(),
- DNLoc(NameInfo.getInfo()) {}
+ : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
+ StartLoc),
+ DeclContext(DK), redeclarable_base(C), ParamInfo(nullptr), Body(),
+ SClass(S), IsInline(isInlineSpecified),
+ IsInlineSpecified(isInlineSpecified), IsVirtualAsWritten(false),
+ IsPure(false), HasInheritedPrototype(false), HasWrittenPrototype(true),
+ IsDeleted(false), IsTrivial(false), IsDefaulted(false),
+ IsExplicitlyDefaulted(false), HasImplicitReturnZero(false),
+ IsLateTemplateParsed(false), IsConstexpr(isConstexprSpecified),
+ UsesSEHTry(false), HasSkippedBody(false), WillHaveBody(false),
+ EndRangeLoc(NameInfo.getEndLoc()), TemplateOrSpecialization(),
+ DNLoc(NameInfo.getInfo()) {}
typedef Redeclarable<FunctionDecl> redeclarable_base;
FunctionDecl *getNextRedeclarationImpl() override {
@@ -2001,6 +2002,10 @@
bool hasSkippedBody() const { return HasSkippedBody; }
void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; }
+ /// True if this function will eventually have a body, once it's fully parsed.
+ bool willHaveBody() const { return WillHaveBody; }
+ void setWillHaveBody(bool V = true) { WillHaveBody = V; }
+
void setPreviousDeclaration(FunctionDecl * PrevDecl);
FunctionDecl *getCanonicalDecl() override;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits