diff options
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r-- | lib/AST/Decl.cpp | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 85ab002485..92b1e4abf2 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -1177,6 +1177,32 @@ SourceRange VarDecl::getSourceRange() const { return DeclaratorDecl::getSourceRange(); } +template<typename decl_type> +static bool hasCLanguageLinkageTemplate(const decl_type &D) { + // Language linkage is a C++ concept, but saying that everything in C has + // C language linkage fits the implementation nicelly. + ASTContext &Context = D.getASTContext(); + if (!Context.getLangOpts().CPlusPlus) + return true; + + // dcl.link 4: A C language linkage is ignored in determining the language + // linkage of the names of class members and the function type of class member + // functions. + const DeclContext *DC = D.getDeclContext(); + if (DC->isRecord()) + return false; + + // If the first decl is in an extern "C" context, any other redeclaration + // will have C language linkage. If the first one is not in an extern "C" + // context, we would have reported an error for any other decl being in one. + const decl_type *First = D.getFirstDeclaration(); + return First->getDeclContext()->isExternCContext(); +} + +bool VarDecl::hasCLanguageLinkage() const { + return hasCLanguageLinkageTemplate(*this); +} + bool VarDecl::isExternC() const { if (getLinkage() != ExternalLinkage) return false; @@ -1702,6 +1728,10 @@ bool FunctionDecl::isReservedGlobalPlacementOperator() const { return (proto->getArgType(1).getCanonicalType() == Context.VoidPtrTy); } +bool FunctionDecl::hasCLanguageLinkage() const { + return hasCLanguageLinkageTemplate(*this); +} + bool FunctionDecl::isExternC() const { if (getLinkage() != ExternalLinkage) return false; |