diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-06-30 09:48:50 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-06-30 09:48:50 +0000 |
commit | ac974a3c76fbe2cc9d05adde3455ef42abd18d95 (patch) | |
tree | c654e46ea179c497f8b55942f387588b518c35cc /clang/lib/Sema/SemaOverload.cpp | |
parent | 7aa8c2fd99545c2c4357751dcdf515c812d54c98 (diff) | |
download | bcm5719-llvm-ac974a3c76fbe2cc9d05adde3455ef42abd18d95.tar.gz bcm5719-llvm-ac974a3c76fbe2cc9d05adde3455ef42abd18d95.zip |
Reinstate r185229, reverted in r185256, with a tweak: further ignore the
standard's rule that an extern "C" declaration conflicts with any entity in the
global scope with the same name. Now we only care if the global scope entity is
a variable declaration (and so might have the same mangled name as the extern
"C" declaration). This has been reported as a standard defect.
Original commit message:
PR7927, PR16247: Reimplement handling of matching extern "C" declarations
across scopes.
When we declare an extern "C" name that is not a redeclaration of an entity in
the same scope, check whether it redeclares some extern "C" entity from another
scope, and if not, check whether it conflicts with a (non-extern-"C") entity in
the translation unit.
When we declare a name in the translation unit that is not a redeclaration,
check whether it conflicts with any extern "C" entities (possibly from other
scopes).
llvm-svn: 185281
Diffstat (limited to 'clang/lib/Sema/SemaOverload.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 48 |
1 files changed, 13 insertions, 35 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 3f7ab1c90f1..42eced466ec 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -977,21 +977,12 @@ Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old, return Ovl_Overload; } -static bool canBeOverloaded(const FunctionDecl &D) { - if (D.getAttr<OverloadableAttr>()) - return true; - if (D.isExternC()) - return false; - - // Main cannot be overloaded (basic.start.main). - if (D.isMain()) +bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, + bool UseUsingDeclRules) { + // C++ [basic.start.main]p2: This function shall not be overloaded. + if (New->isMain()) return false; - return true; -} - -static bool shouldTryToOverload(Sema &S, FunctionDecl *New, FunctionDecl *Old, - bool UseUsingDeclRules) { FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate(); FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate(); @@ -1002,8 +993,8 @@ static bool shouldTryToOverload(Sema &S, FunctionDecl *New, FunctionDecl *Old, return true; // Is the function New an overload of the function Old? - QualType OldQType = S.Context.getCanonicalType(Old->getType()); - QualType NewQType = S.Context.getCanonicalType(New->getType()); + QualType OldQType = Context.getCanonicalType(Old->getType()); + QualType NewQType = Context.getCanonicalType(New->getType()); // Compare the signatures (C++ 1.3.10) of the two functions to // determine whether they are overloads. If we find any mismatch @@ -1024,7 +1015,7 @@ static bool shouldTryToOverload(Sema &S, FunctionDecl *New, FunctionDecl *Old, if (OldQType != NewQType && (OldType->getNumArgs() != NewType->getNumArgs() || OldType->isVariadic() != NewType->isVariadic() || - !S.FunctionArgTypesAreEqual(OldType, NewType))) + !FunctionArgTypesAreEqual(OldType, NewType))) return true; // C++ [temp.over.link]p4: @@ -1040,9 +1031,9 @@ static bool shouldTryToOverload(Sema &S, FunctionDecl *New, FunctionDecl *Old, // However, we don't consider either of these when deciding whether // a member introduced by a shadow declaration is hidden. if (!UseUsingDeclRules && NewTemplate && - (!S.TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(), - OldTemplate->getTemplateParameters(), - false, S.TPL_TemplateMatch) || + (!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(), + OldTemplate->getTemplateParameters(), + false, TPL_TemplateMatch) || OldType->getResultType() != NewType->getResultType())) return true; @@ -1068,9 +1059,9 @@ static bool shouldTryToOverload(Sema &S, FunctionDecl *New, FunctionDecl *Old, // declarations with the same name, the same parameter-type-list, and // the same template parameter lists cannot be overloaded if any of // them, but not all, have a ref-qualifier (8.3.5). - S.Diag(NewMethod->getLocation(), diag::err_ref_qualifier_overload) + Diag(NewMethod->getLocation(), diag::err_ref_qualifier_overload) << NewMethod->getRefQualifier() << OldMethod->getRefQualifier(); - S.Diag(OldMethod->getLocation(), diag::note_previous_declaration); + Diag(OldMethod->getLocation(), diag::note_previous_declaration); } return true; } @@ -1080,7 +1071,7 @@ static bool shouldTryToOverload(Sema &S, FunctionDecl *New, FunctionDecl *Old, // or non-static member function). Add it now, on the assumption that this // is a redeclaration of OldMethod. unsigned NewQuals = NewMethod->getTypeQualifiers(); - if (!S.getLangOpts().CPlusPlus1y && NewMethod->isConstexpr() && + if (!getLangOpts().CPlusPlus1y && NewMethod->isConstexpr() && !isa<CXXConstructorDecl>(NewMethod)) NewQuals |= Qualifiers::Const; if (OldMethod->getTypeQualifiers() != NewQuals) @@ -1091,19 +1082,6 @@ static bool shouldTryToOverload(Sema &S, FunctionDecl *New, FunctionDecl *Old, return false; } -bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, - bool UseUsingDeclRules) { - if (!shouldTryToOverload(*this, New, Old, UseUsingDeclRules)) - return false; - - // If both of the functions are extern "C", then they are not - // overloads. - if (!canBeOverloaded(*Old) && !canBeOverloaded(*New)) - return false; - - return true; -} - /// \brief Checks availability of the function depending on the current /// function context. Inside an unavailable function, unavailability is ignored. /// |