When deciding how to parse "= something" as part of a member
declaration, determine whether the declaration will end up declaring a
function using semantic criteria (e.g., it will have function type)
rather than purely syntactic criteria (e.g., it has the form of a
function declarator). Fixes <rdar://problem/9670557>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133854 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
index f1e8b4e..d450a32 100644
--- a/lib/Sema/DeclSpec.cpp
+++ b/lib/Sema/DeclSpec.cpp
@@ -13,8 +13,10 @@
#include "clang/Parse/ParseDiagnostic.h" // FIXME: remove this back-dependency!
#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/LocInfoType.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Lex/Preprocessor.h"
@@ -213,6 +215,59 @@
return I;
}
+bool Declarator::isDeclarationOfFunction() const {
+ if (isFunctionDeclarator())
+ return true;
+
+ switch (DS.getTypeSpecType()) {
+ case TST_auto:
+ case TST_bool:
+ case TST_char:
+ case TST_char16:
+ case TST_char32:
+ case TST_class:
+ case TST_decimal128:
+ case TST_decimal32:
+ case TST_decimal64:
+ case TST_double:
+ case TST_enum:
+ case TST_error:
+ case TST_float:
+ case TST_int:
+ case TST_struct:
+ case TST_union:
+ case TST_unknown_anytype:
+ case TST_unspecified:
+ case TST_void:
+ case TST_wchar:
+ return false;
+
+ case TST_decltype:
+ case TST_typeofExpr:
+ if (Expr *E = DS.getRepAsExpr())
+ return E->getType()->isFunctionType();
+ return false;
+
+ case TST_underlyingType:
+ case TST_typename:
+ case TST_typeofType: {
+ QualType QT = DS.getRepAsType().get();
+ if (QT.isNull())
+ return false;
+
+ if (const LocInfoType *LIT = dyn_cast<LocInfoType>(QT))
+ QT = LIT->getType();
+
+ if (QT.isNull())
+ return false;
+
+ return QT->isFunctionType();
+ }
+ }
+
+ return false;
+}
+
/// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
/// declaration specifier includes.
///