aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/Decl.cpp52
-rw-r--r--lib/AST/ItaniumMangle.cpp42
-rw-r--r--lib/Sema/SemaDecl.cpp4
-rw-r--r--lib/Sema/SemaOverload.cpp2
4 files changed, 35 insertions, 65 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 5c489273d2..433e76767c 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1217,20 +1217,20 @@ SourceRange VarDecl::getSourceRange() const {
template<typename T>
static LanguageLinkage getLanguageLinkageTemplate(const T &D) {
- // Language linkage is a C++ concept, but saying that everything in C has
+ // C++ [dcl.link]p1: All function types, function names with external linkage,
+ // and variable names with external linkage have a language linkage.
+ if (!isExternalLinkage(D.getLinkage()))
+ return NoLanguageLinkage;
+
+ // Language linkage is a C++ concept, but saying that everything else in C has
// C language linkage fits the implementation nicely.
ASTContext &Context = D.getASTContext();
if (!Context.getLangOpts().CPlusPlus)
return CLanguageLinkage;
- // dcl.link 1: All function types, function names with external linkage, and
- // variable names with external linkage have a language linkage.
- if (!isExternalLinkage(D.getLinkage()))
- return NoLanguageLinkage;
-
- // 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.
+ // C++ [dcl.link]p4: 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 CXXLanguageLinkage;
@@ -1248,20 +1248,6 @@ LanguageLinkage VarDecl::getLanguageLinkage() const {
return getLanguageLinkageTemplate(*this);
}
-bool VarDecl::isExternC() const {
- if (getLinkage() != ExternalLinkage)
- return false;
-
- const DeclContext *DC = getDeclContext();
- if (DC->isRecord())
- return false;
-
- ASTContext &Context = getASTContext();
- if (!Context.getLangOpts().CPlusPlus)
- return true;
- return DC->isExternCContext();
-}
-
VarDecl *VarDecl::getCanonicalDecl() {
return getFirstDeclaration();
}
@@ -1780,24 +1766,6 @@ LanguageLinkage FunctionDecl::getLanguageLinkage() const {
return getLanguageLinkageTemplate(*this);
}
-bool FunctionDecl::isExternC() const {
- if (getLinkage() != ExternalLinkage)
- return false;
-
- if (getAttr<OverloadableAttr>())
- return false;
-
- const DeclContext *DC = getDeclContext();
- if (DC->isRecord())
- return false;
-
- ASTContext &Context = getASTContext();
- if (!Context.getLangOpts().CPlusPlus)
- return true;
-
- return isMain() || DC->isExternCContext();
-}
-
bool FunctionDecl::isGlobal() const {
if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(this))
return Method->isStatic();
@@ -2466,7 +2434,7 @@ unsigned FunctionDecl::getMemoryFunctionKind() const {
return Builtin::BIstrlen;
default:
- if (hasCLanguageLinkage()) {
+ if (isExternC()) {
if (FnInfo->isStr("memset"))
return Builtin::BImemset;
else if (FnInfo->isStr("memcpy"))
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index a7fc16aae3..e9a3b03483 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -366,20 +366,34 @@ bool ItaniumMangleContext::shouldMangleDeclName(const NamedDecl *D) {
if (D->hasAttr<AsmLabelAttr>())
return true;
- // Clang's "overloadable" attribute extension to C/C++ implies name mangling
- // (always) as does passing a C++ member function and a function
- // whose name is not a simple identifier.
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
- if (FD && (FD->hasAttr<OverloadableAttr>() || isa<CXXMethodDecl>(FD) ||
- !FD->getDeclName().isIdentifier()))
- return true;
+ if (FD) {
+ LanguageLinkage L = FD->getLanguageLinkage();
+ // Overloadable functions need mangling.
+ if (FD->hasAttr<OverloadableAttr>())
+ return true;
+
+ // C functions and "main" are not mangled.
+ if (FD->isMain() || L == CLanguageLinkage)
+ return false;
+
+ // C++ functions and those whose names are not a simple identifier need
+ // mangling.
+ if (!FD->getDeclName().isIdentifier() || L == CXXLanguageLinkage)
+ return true;
+ }
// Otherwise, no mangling is done outside C++ mode.
if (!getASTContext().getLangOpts().CPlusPlus)
return false;
- // Variables at global scope with non-internal linkage are not mangled
- if (!FD) {
+ const VarDecl *VD = dyn_cast<VarDecl>(D);
+ if (VD) {
+ // C variables are not mangled.
+ if (VD->isExternC())
+ return false;
+
+ // Variables at global scope with non-internal linkage are not mangled
const DeclContext *DC = getEffectiveDeclContext(D);
// Check for extern variable declared locally.
if (DC->isFunctionOrMethod() && D->hasLinkage())
@@ -389,18 +403,6 @@ bool ItaniumMangleContext::shouldMangleDeclName(const NamedDecl *D) {
return false;
}
- // Class members are always mangled.
- if (getEffectiveDeclContext(D)->isRecord())
- return true;
-
- // C functions and "main" are not mangled.
- if (FD)
- return !FD->isMain() && !FD->hasCLanguageLinkage();
-
- // C variables are not mangled.
- if (const VarDecl *VD = dyn_cast<VarDecl>(D))
- return !VD->hasCLanguageLinkage();
-
return true;
}
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 9c7fb6b4b2..d2b4697ee3 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -4860,7 +4860,7 @@ void Sema::CheckShadow(Scope *S, VarDecl *D) {
template<typename T>
static bool mayConflictWithNonVisibleExternC(const T *ND) {
VarDecl::StorageClass SC = ND->getStorageClass();
- if (ND->hasCLanguageLinkage() && (SC == SC_Extern || SC == SC_PrivateExtern))
+ if (ND->isExternC() && (SC == SC_Extern || SC == SC_PrivateExtern))
return true;
return ND->getDeclContext()->isTranslationUnit();
}
@@ -6581,7 +6581,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
// If this function is declared as being extern "C", then check to see if
// the function returns a UDT (class, struct, or union type) that is not C
// compatible, and if it does, warn the user.
- if (NewFD->hasCLanguageLinkage()) {
+ if (NewFD->isExternC()) {
QualType R = NewFD->getResultType();
if (R->isIncompleteType() && !R->isVoidType())
Diag(NewFD->getLocation(), diag::warn_return_value_udt_incomplete)
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index c2e0d6f809..9bba5f6c78 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -967,7 +967,7 @@ Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old,
static bool canBeOverloaded(const FunctionDecl &D) {
if (D.getAttr<OverloadableAttr>())
return true;
- if (D.hasCLanguageLinkage())
+ if (D.isExternC())
return false;
// Main cannot be overloaded (basic.start.main).