aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Decl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r--lib/AST/Decl.cpp30
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;